yanghyo 09-27
뷰어 수정
@69609a072a39bf30080461c3dc2d301f91a94bda
html/onSejong/index.html
--- html/onSejong/index.html
+++ html/onSejong/index.html
@@ -438,10 +438,7 @@
                                     <li>[뷰어]수업설계
                                         <ul>
                                             <li>수업설계,manager/class/classViewer.html</li>
-                                            <li>수업설계-영상</li>
-                                            <li>수업설계-이미지,manager/class/classViewer_img.html</li>
-                                            <li>수업설계-판서,manager/class/classViewer_painter.html</li>
-                                            <li>수업설계-문서,manager/class/classViewer_painter_doc.html</li>
+                                            <li>수업설계(이미지/영상/문서),manager/class/classViewer_cont.html</li>
                                             <li>수업설계-링크,manager/class/classViewer_URL.html</li>
                                             <li>[팝업]파일 업로드,manager/class/pop_addFile.html</li>
                                             <li>[팝업]링크추가,manager/class/pop_addLink.html</li>
html/onSejong/manager/class/classViewer.html
--- html/onSejong/manager/class/classViewer.html
+++ html/onSejong/manager/class/classViewer.html
@@ -1,17 +1,17 @@
-<!DOCTYPE html>
+ <!DOCTYPE html>
 <html lang="ko">
     <head>
         <title>온세종학교</title>
 
-        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-        <meta name="Author" content="" />
-        <meta name="Keywords" content="" />
-        <meta name="Description" content="" />
-        <meta name="format-detection" content="telephone=no" />
-        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0" />
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <meta name="Author" content="">
+        <meta name="Keywords" content="">
+        <meta name="Description" content="">
+        <meta name="format-detection" content="telephone=no">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
 
-        <link href="/resources/front/site/SITE_00000/css/style.css" rel="stylesheet" />
+        <link href="/resources/front/site/SITE_00000/css/style.css" rel="stylesheet">
 
         <!-- 공통 plugin -->
         <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-3.6.0.min.js"></script>
@@ -19,6 +19,7 @@
         <!-- //공통 plugin -->
 
         <!-- 페이지 plugin-->
+        <script type="module" src="/resources/front/site/SITE_00000/js/common/module/colouredPenciles.js"></script>
         <!-- //페이지 plugin-->
 
         <!-- 공통 퍼블 layout: 개발시 삭제-->
@@ -92,7 +93,7 @@
                                     </div>
                                     <div class="nav-cont">
                                         <div class="img-area">
-                                            <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="" />
+                                            <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="">
                                         </div>
                                         <div class="txt-area">
                                             <div class="label-area"><span class="label-cont-video">영상</span></div>
@@ -133,44 +134,28 @@
                             <li>
                                 <button type="button" class="lnk-full">추가</button>
                                 <figure>
-                                    <img
-                                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-folder.svg"
-                                        alt=""
-                                        aria-hidden="true"
-                                    />
+                                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-folder.svg" alt="" aria-hidden="true">
                                 </figure>
                                 <span>파일 업로드</span>
                             </li>
                             <li>
                                 <button type="button" class="lnk-full">추가</button>
                                 <figure>
-                                    <img
-                                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-link.svg"
-                                        alt=""
-                                        aria-hidden="true"
-                                    />
+                                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-link.svg" alt="" aria-hidden="true">
                                 </figure>
                                 <span>링크 추가</span>
                             </li>
                             <li>
                                 <button type="button" class="lnk-full">추가</button>
                                 <figure>
-                                    <img
-                                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-filebox.svg"
-                                        alt=""
-                                        aria-hidden="true"
-                                    />
+                                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-filebox.svg" alt="" aria-hidden="true">
                                 </figure>
                                 <span>나의 보관함에서 선택</span>
                             </li>
                             <li>
                                 <button type="button" class="lnk-full">추가</button>
                                 <figure>
-                                    <img
-                                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-search.svg"
-                                        alt=""
-                                        aria-hidden="true"
-                                    />
+                                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-search.svg" alt="" aria-hidden="true">
                                 </figure>
                                 <span>콘텐츠에서 검색</span>
                             </li>
@@ -185,20 +170,12 @@
             <ul class="viewer-tool">
                 <li>
                     <button type="button" class="btn-painter-toggle lnk-full">판서</button>
-                    <img
-                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg"
-                        alt=""
-                        aria-hidden="true"
-                    />
+                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg" alt="" aria-hidden="true">
                     <strong>판서</strong>
                 </li>
                 <li>
                     <button type="button" class="lnk-full">채팅 열기&amp;닫기</button>
-                    <img
-                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg"
-                        alt=""
-                        aria-hidden="true"
-                    />
+                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg" alt="" aria-hidden="true">
                     <strong>채팅</strong>
                     <span class="badge min">새 채팅</span>
                 </li>
@@ -232,8 +209,6 @@
                     });
                 },
             });
-
-            
         </script>
     </body>
-</html>
+</html>
(파일 끝에 줄바꿈 문자 없음)
html/onSejong/manager/class/classViewer_URL.html
--- html/onSejong/manager/class/classViewer_URL.html
+++ html/onSejong/manager/class/classViewer_URL.html
@@ -1,136 +1,137 @@
 <!DOCTYPE html>
 <html lang="ko">
-    <head>
-        <title>온세종학교</title>
 
-        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-        <meta name="Author" content="" />
-        <meta name="Keywords" content="" />
-        <meta name="Description" content="" />
-        <meta name="format-detection" content="telephone=no" />
-        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0" />
+<head>
+    <title>온세종학교</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="Author" content="" />
+    <meta name="Keywords" content="" />
+    <meta name="Description" content="" />
+    <meta name="format-detection" content="telephone=no" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0" />
+    <link href="/resources/front/site/SITE_00000/css/style.css" rel="stylesheet" />
+    <!-- 공통 plugin -->
+    <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-3.6.0.min.js"></script>
+    <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-ui.min.js"></script>
+    <!-- //공통 plugin -->
+    <!-- 페이지 plugin-->
+    <script type="module" src="/resources/front/site/SITE_00000/js/common/module/colouredPenciles.js"></script>
+    <!-- //페이지 plugin-->
+    <!-- 공통 퍼블 layout: 개발시 삭제-->
+    <!-- <script src="/resources/front/site/SITE_00000/js/_layout.js"></script> -->
+    <!--//퍼블 layout-->
+    <!-- 공통 메뉴 js-->
+    <!-- //공통 메뉴 js -->
+    <!--공통 퍼블 js-->
+    <script src="/resources/front/site/SITE_00000/js/common.js"></script>
+    <script src="/resources/front/site/SITE_00000/js/common-custom.js"></script>
+    <!--//공통 퍼블 js-->
+</head>
 
-        <link href="/resources/front/site/SITE_00000/css/style.css" rel="stylesheet" />
-
-        <!-- 공통 plugin -->
-        <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-3.6.0.min.js"></script>
-        <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-ui.min.js"></script>
-        <!-- //공통 plugin -->
-
-        <!-- 페이지 plugin-->
-        <!-- //페이지 plugin-->
-
-        <!-- 공통 퍼블 layout: 개발시 삭제-->
-        <!-- <script src="/resources/front/site/SITE_00000/js/_layout.js"></script> -->
-        <!--//퍼블 layout-->
-
-        <!-- 공통 메뉴 js-->
-        <!-- //공통 메뉴 js -->
-
-        <!--공통 퍼블 js-->
-        <script src="/resources/front/site/SITE_00000/js/common.js"></script>
-        <script src="/resources/front/site/SITE_00000/js/common-custom.js"></script>
-        <!--//공통 퍼블 js-->
-    </head>
-
-    <body>
-        <section class="class-viewer">
-            <header class="viewer-header">
-                <div class="l-area">
-                    <button type="button" class="btn-class-viewer-menu btn circle ico-menu sm">메뉴</button>
-                    <div class="viewer-tit">
-                        <h1 class="">
-                            활동1) 무늬를 꾸며보는 방법 알아보기활동
-                        </h1>
-                    </div>
+<body>
+    <section class="class-viewer">
+        <header class="viewer-header">
+            <div class="l-area">
+                <button type="button" class="btn-class-viewer-menu btn circle ico-menu sm">메뉴</button>
+                <div class="viewer-tit">
+                    <h1 class=""> 활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법
+                        알아보기활동1) 무늬를 꾸며보는 방법 알아보기 </h1>
                 </div>
-                <div class="r-area pcta-flex">
-                    <div class="btn-group">
-                        <button type="button" class="btn sm primary"><i class="ico-save"></i> 저장</button>
-                        <button type="button" class="btn sm"><i class="ico-logout"></i> 나가기</button>
-                    </div>
+            </div>
+            <div class="r-area pcta-flex">
+                <div class="btn-group">
+                    <button type="button" class="btn sm primary"><i class="ico-save"></i> 저장</button>
+                    <button type="button" class="btn sm"><i class="ico-logout"></i> 나가기</button>
                 </div>
-                <div class="r-area mo-flex">
-                    <div class="etc-fnc-area">
-                        <button type="button" class="btn-etc-fnc btn-ico ico-more-vert">더보기</button>
-                        <ul class="etc-fnc">
-                            <li><button type="button">북마크</button></li>
-                            <li><button type="button">학생뷰어보기</button></li>
-                            <li><button type="button">저장</button></li>
-                            <li><button type="button">나가기</button></li>
-                        </ul>
-                    </div>
+            </div>
+            <div class="r-area mo-flex">
+                <div class="etc-fnc-area">
+                    <button type="button" class="btn-etc-fnc btn-ico ico-more-vert">더보기</button>
+                    <ul class="etc-fnc">
+                        <li><button type="button">북마크</button></li>
+                        <li><button type="button">학생뷰어보기</button></li>
+                        <li><button type="button">저장</button></li>
+                        <li><button type="button">나가기</button></li>
+                    </ul>
                 </div>
-            </header>
-            <div class="viewer-body">
-                <div class="viewer-menu-area">
-                    <div class="viewer-menu-header">
-                        <div class="menu-add-area">
-                            <button class="btn-menu-add"><span>추가</span></button>
-                            <div class="menu-add-option">
-                                <button type="button">파일 업로드</button>
-                                <button type="button">링크추가</button>
-                                <button type="button">나의 보관함에서 선택</button>
-                                <button type="button">콘텐츠에서 검색</button>
-                            </div>
+            </div>
+        </header>
+        <div class="viewer-body">
+            <div class="viewer-menu-area">
+                <div class="viewer-menu-header">
+                    <div class="menu-add-area">
+                        <button class="btn-menu-add"><span>추가</span></button>
+                        <div class="menu-add-option">
+                            <button type="button">파일 업로드</button>
+                            <button type="button">링크추가</button>
+                            <button type="button">나의 보관함에서 선택</button>
+                            <button type="button">콘텐츠에서 검색</button>
                         </div>
                     </div>
-                    <div class="viewer-menu-body">
-                        <nav class="viewer-nav">
-                            <ul>
-                                <li class="is-active">
-                                    <a href="#none" class="lnk-full">상세보기</a>
-                                    <div class="nav-info">
-                                        <span class="num">1</span>
-                                        <div class="fnc order-front">
-                                            <button type="button" class="ico-delete order-front">삭제</button>
-                                            <i class="ico-move">이동</i>
-                                        </div>
-                                    </div>
-                                    <div class="nav-cont">
-                                        <div class="img-area">
-                                            <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="" />
-                                        </div>
-                                        <div class="txt-area">
-                                            <div class="label-area"><span class="label-cont-url">링크</span></div>
-                                            <div class="txt">
-                                                파일명파일명
-                                                파일명파일명파일명파일명파일명파일명파일명파일명파일명파일명.mp4
-                                            </div>
-                                        </div>
-                                    </div>
-                                </li>
-                                <li>
-                                    <a href="#none" class="lnk-full">상세보기</a>
-                                    <div class="nav-info">
-                                        <span class="num">2</span>
-                                        <div class="fnc order-front">
-                                            <button type="button" class="ico-delete order-front">삭제</button>
-                                            <i class="ico-move">이동</i>
-                                        </div>
-                                    </div>
-                                    <div class="nav-cont">
-                                        <div class="txt-area">
-                                            <div class="label-area"><span class="label-cont-video">영상</span></div>
-                                            <div class="txt">파일명.mp4</div>
-                                        </div>
-                                    </div>
-                                </li>
-                            </ul>
-                        </nav>
-                    </div>
-                    <button type="button" class="btn-viewer-menu-toggle">
-                        <span class="txt-hide">메뉴 열기&amp;닫기</span>
-                    </button>
                 </div>
-                <div class="viewer-cont">
-                    <div class="wrap-xsm viewer-cont-url-area">
+                <div class="viewer-menu-body">
+                    <nav class="viewer-nav">
+                        <ul>
+                            <li class="is-active">
+                                <a href="#none" class="lnk-full">상세보기</a>
+                                <div class="nav-info">
+                                    <span class="num">1</span>
+                                    <div class="fnc order-front">
+                                        <button type="button" class="ico-delete order-front">삭제</button>
+                                        <i class="ico-move">이동</i>
+                                    </div>
+                                </div>
+                                <div class="nav-cont">
+                                    <div class="img-area">
+                                        <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="" />
+                                    </div>
+                                    <div class="txt-area">
+                                        <div class="label-area"><span class="label-cont-video">영상</span></div>
+                                        <div class="txt"> 파일명파일명 파일명파일명파일명파일명파일명파일명파일명파일명파일명파일명.mp4 </div>
+                                    </div>
+                                </div>
+                            </li>
+                            <li>
+                                <a href="#none" class="lnk-full">상세보기</a>
+                                <div class="nav-info">
+                                    <span class="num">2</span>
+                                    <div class="fnc order-front">
+                                        <button type="button" class="ico-delete order-front">삭제</button>
+                                        <i class="ico-move">이동</i>
+                                    </div>
+                                </div>
+                                <div class="nav-cont">
+                                    <div class="txt-area">
+                                        <div class="label-area"><span class="label-cont-video">영상</span></div>
+                                        <div class="txt">파일명.mp4</div>
+                                    </div>
+                                </div>
+                            </li>
+                        </ul>
+                    </nav>
+                </div>
+                <button type="button" class="btn-viewer-menu-toggle">
+                    <span class="txt-hide">메뉴 열기&amp;닫기</span>
+                </button>
+            </div>
+            <div class="viewer-cont">
+                <!-- content: 이미지, 비디오, iframe -->
+                <!-- <div class="viewer-cont-box">
+                    <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="">
+                    <video controls="controls">
+                        <source src="https://www.w3schools.com/tags/mov_bbb.mp4" type="video/mp4">
+                    </video>
+                    <iframe src="/resources/front/site/SITE_00000/images/temp/pdf.pdf"></iframe>
+                </div> -->
+                <!-- url -->
+                <div class="wrap-xsm viewer-cont-url-area">
                         <ul class="btn-box-list">
                             <li>
                                 <a href="#none" type="button" class="lnk-full" target="_blank" title="새창 열기">새창열기</a>
                                 <figure>
-                                    <img src="/resources/front/site/SITE_00000/images/custom/ico-cont/ico-cont-link.svg" alt="" aria-hidden="true">
+                                    <img src="/resources/front/site/SITE_00000/images/custom/ico-cont/ico-cont-link.svg" alt=""
+                                        aria-hidden="true">
                                 </figure>
                                 <span>www.naver.comwww.naver</span>
                                 <div class="fnc">
@@ -139,64 +140,55 @@
                             </li>
                         </ul>
                     </div>
-                    <div class="viewer-fnc-cont">
-                        <!-- 색연필 -->
-                        <div class="viewer-painter paint-target"></div>
-                    </div>
+                <div class="viewer-fnc-cont">
+                    <!-- 색연필 -->
+                    <div class="viewer-painter paint-target"></div>
                 </div>
             </div>
-            <ul class="viewer-tool">
-                <li>
-                    <button type="button" class="btn-painter-toggle lnk-full">판서</button>
-                    <img
-                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg"
-                        alt=""
-                        aria-hidden="true"
-                    />
-                    <strong>판서</strong>
-                </li>
-                <li>
-                    <button type="button" class="lnk-full">채팅 열기&amp;닫기</button>
-                    <img
-                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg"
-                        alt=""
-                        aria-hidden="true"
-                    />
-                    <strong>채팅</strong>
-                    <span class="badge min">새 채팅</span>
-                </li>
-            </ul>
-        </section>
+        </div>
+        <ul class="viewer-tool">
+            <li>
+                <button type="button" class="btn-painter-toggle lnk-full">판서</button>
+                <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg" alt=""
+                    aria-hidden="true">
+                <strong>판서</strong>
+            </li>
+            <li>
+                <button type="button" class="lnk-full">채팅 열기&amp;닫기</button>
+                <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg" alt=""
+                    aria-hidden="true">
+                <strong>채팅</strong>
+                <span class="badge min">새 채팅</span>
+            </li>
+        </ul>
+    </section>
+    <!--toast-->
+    <div class="toast"></div>
+    <script>
+        // 과정추가
+        $(document).on("click", ".btn-menu-add", function (e) {
+            e.stopPropagation();
+            $(".menu-add-area").toggleClass("is-active");
+        });
 
-        <!--toast-->
-        <div class="toast"></div>
+        $(document).on("click", function () {
+            $(".menu-add-area").removeClass("is-active");
+        });
 
-        <script>
-            // 과정추가
-            $(document).on("click", ".btn-menu-add", function (e) {
-                e.stopPropagation();
-                $(".menu-add-area").toggleClass("is-active");
-            });
+        //과정 순서 변경
+        $(".class-viewer-nav>ul").sortable({
+            handle: $(".class-viewer-nav>ul>li").find(".ico-move"),
+            containment: "parent",
+            update: function (event, ui) {
+                var $list = $(this).children("li");
+                $list.each(function () {
+                    var $li = $(this);
+                    var newVal = $(this).index() + 1;
+                    $(this).find(".num").html(newVal);
+                });
+            },
+        });
+    </script>
+</body>
 
-            $(document).on("click", function () {
-                $(".menu-add-area").removeClass("is-active");
-            });
-
-            //과정 순서 변경
-            $(".class-viewer-nav>ul").sortable({
-                handle: $(".class-viewer-nav>ul>li").find(".ico-move"),
-                containment: "parent",
-                update: function (event, ui) {
-                    var $list = $(this).children("li");
-                    $list.each(function () {
-                        var $li = $(this);
-                        var newVal = $(this).index() + 1;
-                        $(this).find(".num").html(newVal);
-                    });
-                },
-            });
-
-            
-        </script>
-    </body>
-</html>
+</html>
(파일 끝에 줄바꿈 문자 없음)
html/onSejong/manager/class/classViewer_cont.html (Renamed from html/onSejong/manager/class/classViewer_img.html)
--- html/onSejong/manager/class/classViewer_img.html
+++ html/onSejong/manager/class/classViewer_cont.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+ <!DOCTYPE html>
 <html lang="ko">
     <head>
         <title>온세종학교</title>
@@ -19,6 +19,7 @@
         <!-- //공통 plugin -->
 
         <!-- 페이지 plugin-->
+        <script type="module" src="/resources/front/site/SITE_00000/js/common/module/colouredPenciles.js"></script>
         <!-- //페이지 plugin-->
 
         <!-- 공통 퍼블 layout: 개발시 삭제-->
@@ -41,7 +42,9 @@
                     <button type="button" class="btn-class-viewer-menu btn circle ico-menu sm">메뉴</button>
                     <div class="viewer-tit">
                         <h1 class="">
-                            활동1) 무늬를 꾸며보는 방법 알아보기활동
+                            활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를
+                            꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법
+                            알아보기
                         </h1>
                     </div>
                 </div>
@@ -93,7 +96,7 @@
                                             <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="" />
                                         </div>
                                         <div class="txt-area">
-                                            <div class="label-area"><span class="label-cont-img">이미지</span></div>
+                                            <div class="label-area"><span class="label-cont-video">영상</span></div>
                                             <div class="txt">
                                                 파일명파일명
                                                 파일명파일명파일명파일명파일명파일명파일명파일명파일명파일명.mp4
@@ -125,9 +128,30 @@
                     </button>
                 </div>
                 <div class="viewer-cont">
-                    <figure>
+                    <!-- content: 이미지, 비디오, iframe -->
+                    <div class="viewer-cont-box">
                         <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="">
-                    </figure>
+                        <!-- <video controls="controls">
+                            <source src="https://www.w3schools.com/tags/mov_bbb.mp4" type="video/mp4">
+                        </video>
+                        <iframe src="/resources/front/site/SITE_00000/images/temp/pdf.pdf"></iframe> -->
+                    </div>
+                    <!-- url -->
+                    <!-- <div class="wrap-xsm viewer-cont-url-area">
+                        <ul class="btn-box-list">
+                            <li>
+                                <a href="#none" type="button" class="lnk-full" target="_blank" title="새창 열기">새창열기</a>
+                                <figure>
+                                    <img src="/resources/front/site/SITE_00000/images/custom/ico-cont/ico-cont-link.svg" alt=""
+                                        aria-hidden="true">
+                                </figure>
+                                <span>www.naver.comwww.naver</span>
+                                <div class="fnc">
+                                    <i class="ico-openinnew">새 창 열기</i>
+                                </div>
+                            </li>
+                        </ul>
+                    </div> -->
                     <div class="viewer-fnc-cont">
                         <!-- 색연필 -->
                         <div class="viewer-painter paint-target"></div>
@@ -137,20 +161,12 @@
             <ul class="viewer-tool">
                 <li>
                     <button type="button" class="btn-painter-toggle lnk-full">판서</button>
-                    <img
-                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg"
-                        alt=""
-                        aria-hidden="true"
-                    />
+                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg" alt="" aria-hidden="true">
                     <strong>판서</strong>
                 </li>
                 <li>
                     <button type="button" class="lnk-full">채팅 열기&amp;닫기</button>
-                    <img
-                        src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg"
-                        alt=""
-                        aria-hidden="true"
-                    />
+                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg" alt="" aria-hidden="true">
                     <strong>채팅</strong>
                     <span class="badge min">새 채팅</span>
                 </li>
@@ -184,8 +200,6 @@
                     });
                 },
             });
-
-            
         </script>
     </body>
-</html>
+</html>
(파일 끝에 줄바꿈 문자 없음)
 
html/onSejong/manager/class/classViewer_painter.html (deleted)
--- html/onSejong/manager/class/classViewer_painter.html
@@ -1,231 +0,0 @@
-<!DOCTYPE html>
-<html lang="ko">
-
-<head>
-    <title>온세종학교</title>
-
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    <meta name="Author" content="">
-    <meta name="Keywords" content="">
-    <meta name="Description" content="">
-    <meta name="format-detection" content="telephone=no">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
-
-    <link href="/resources/front/site/SITE_00000/css/style.css" rel="stylesheet">
-
-    <!-- 공통 plugin -->
-    <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-3.6.0.min.js"></script>
-    <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-ui.min.js"></script>
-    <!-- //공통 plugin -->
-        
-   <!-- 페이지 plugin-->
-   <!-- //페이지 plugin-->
-
-   <!-- 공통 퍼블 layout: 개발시 삭제-->
-   <!-- <script src="/resources/front/site/SITE_00000/js/_layout.js"></script> -->
-   <!--//퍼블 layout--> 
-   
- 	<!-- 공통 메뉴 js-->
-	<!-- //공통 메뉴 js -->
-    
-    <!--공통 퍼블 js-->
-    <script src="/resources/front/site/SITE_00000/js/common.js"></script>
-	<script src="/resources/front/site/SITE_00000/js/common-custom.js"></script>
-    <!--//공통 퍼블 js-->
-</head>
-
-<body>
-    <section class="class-viewer">
-        <header class="viewer-header">
-            <div class="l-area">
-                <!-- <button type="button" class="btn-viewer-menu btn circle ico-menu sm">메뉴</button> -->
-                <div class="viewer-tit">
-                    <h1 class="">활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기활동1) 무늬를 꾸며보는 방법 알아보기</h1>
-                </div>
-            </div>
-            <div class="r-area">
-                <div class="btn-group">
-                    <button type="button" class="btn sm primary"><i class="ico-save"></i> 저장</button>
-                    <button type="button" class="btn sm"><i class="ico-logout"></i> 나가기</button>
-                </div>
-            </div>    
-        </header>
-        <div class="viewer-body">
-            <div class="viewer-menu-area">
-                <div class="viewer-menu-header">
-                    <div class="menu-add-area">
-                        <button class="btn-menu-add"><span>과정추가</span></button>
-                        <div class="menu-add-option" >
-                            <button type="button">파일 업로드</button>
-                            <button type="button">링크추가</button>
-                            <button type="button">나의 보관함에서 선택</button>
-                            <button type="button">콘텐츠에서 검색</button>
-                        </div>
-                    </div>
-                </div>
-                <div class="viewer-menu-body">
-                    <nav class="viewer-nav">
-                        <ul>
-                            <li class="is-active">
-                                <a href="javascript:changeIfr(1)" class="lnk-full">상세보기</a>
-                                <div class="nav-info">
-                                    <span class="num">1</span>
-                                    <div class="fnc order-front">
-                                        <button type="button" class="ico-delete order-front">삭제</button>
-                                        <i class="ico-move">이동</i>
-                                    </div>
-                                </div>
-                                <div class="nav-cont">
-                                    <div class="img-area">
-                                        <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="">
-                                    </div>
-                                    <div class="txt-area">
-                                        <div class="label-area"><span class="label-cont-img">이미지</span></div>
-                                        <div class="txt">이미지</div>
-                                    </div>
-                                </div>
-                            </li>
-                            <li>
-                                <a href="javascript:changeIfr(2)" class="lnk-full">상세보기</a>
-                                <div class="nav-info">
-                                    <span class="num">2</span>
-                                    <div class="fnc order-front">
-                                        <button type="button" class="ico-delete order-front">삭제</button>
-                                        <i class="ico-move">이동</i>
-                                    </div>
-                                </div>
-                                <div class="nav-cont">
-                                    <div class="txt-area">
-                                        <div class="label-area"><span class="label-cont-video">영상</span></div>
-                                        <div class="txt">영상</div>
-                                    </div>
-                                </div>
-                            </li>
-                            <li>
-                                <a href="javascript:changeIfr(3)" class="lnk-full">상세보기</a>
-                                <div class="nav-info">
-                                    <span class="num">3</span>
-                                    <div class="fnc order-front">
-                                        <button type="button" class="ico-delete order-front">삭제</button>
-                                        <i class="ico-move">유튜브</i>
-                                    </div>
-                                </div>
-                                <div class="nav-cont">
-                                    <div class="txt-area">
-                                        <div class="label-area"><span class="label-cont-video">영상</span></div>
-                                        <div class="txt">유튜브</div>
-                                    </div>
-                                </div>
-                            </li>
-                            <li>
-                        </ul>
-                    </nav>
-                </div>
-                <button type="button" class="btn-viewer-menu-toggle"><span class="txt-hide">메뉴 열기&amp;닫기</span></button>
-            </div>
-            <div class="viewer-cont">
-                <figure>
-                    <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="">
-                </figure>
-                <!-- <div class="iframe-area">
-                    <iframe src="/resources/front/site/SITE_00000/images/temp/img1.jpg" class="view_iframe"></iframe>
-                </div> -->
-                <div class="viewer-cont-fnc-cont">
-                    <!-- 색연필 -->
-                    <div class="viewer-painter paint-target"></div>
-                </div>
-            </div>
-            <ul class="viewer-tool">
-                <li>
-                    <button type="button" class="btn-painter-toggle lnk-full">판서</button>
-                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg" alt="" aria-hidden="true">
-                    <strong>판서</strong>
-                </li>
-                <li>
-                    <button type="button" class="lnk-full">채팅 열기&amp;닫기</button>
-                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg" alt="" aria-hidden="true">
-                    <strong>채팅</strong>
-                    <span class="badge min">새 채팅</span>
-                </li>
-            </ul>
-        </div>
-    </section>
-
-    <!--toast-->
-    <div class="toast"></div>
-    
-    <!--popup-->
-    <script>
-        // 과정추가
-        $(document).on('click', '.btn-menu-add', function (e) {
-            e.stopPropagation();
-            $('.menu-add-area').toggleClass('is-active');
-        });
-    
-        $(document).on('click', function () {
-            $('.menu-add-area').removeClass('is-active');
-        });
-
-        //과정 순서 변경
-        $(".viewer-nav>ul").sortable({
-            handle: $(".viewer-nav>ul>li").find(".ico-move"),
-            axis: "y", 
-            //containment: "parent",
-            update: function (event, ui) {
-                var $list = $(this).children("li");
-                $list.each(function () {
-                    var $li = $(this);
-                    var newVal = $(this).index() + 1;
-                    $(this).find(".num").html(newVal);
-                });
-            },
-        });
-    </script>
-
-    
-    <!-- 모듈로 스크립트를 불러오기 -->
-    <script type="module">
-        import { initColouredPenciles } from '/resources/front/site/SITE_00000/js/custom/module/colouredPencilesSvg_pub.js';
-    </script>
-
-    <script>
-        // colouredPencilesSvg.js 데이터 전달 스크립트
-        const cpInstanceData = (data) => {
-            if (window.cpInstance) {
-                window.cpInstance.setDataParam(data);
-            } else {
-                // console.log('cpInstance 아직 정의되지 않음, 500ms 후 다시 시도.');
-                setTimeout(cpInstanceData, 500, data); // cpInstance 정의 전까지 500ms 간격으로 재시도
-            }
-        }
-        const cpInstanceSave = () => {
-            if (window.cpInstance) {
-                window.cpInstance.saveDrawing();
-            } else {
-                // console.log('cpInstance 아직 정의되지 않음, 500ms 후 다시 시도.');
-                setTimeout(cpInstanceSave, 500, data); // cpInstance 정의 전까지 500ms 간격으로 재시도
-            }
-        }
-
-         // 페이지 로드 시 사용자 키 및 콘텐츠 키 전달
-         window.addEventListener('DOMContentLoaded', () => {
-            const page = 0;
-            cpInstanceData({ userKey: 'testuser', contentsKey: `ifrCnt_${page}` }); // 사용자 키 설정
-        });
-        // 콘텐츠 변경 시, 콘텐츠 키 발행 및 전달
-        const changeIfr = (page) => {
-            cpInstanceSave(); // 페이지 이동 전 저장
-            const ifr = document.querySelector('.iframe-area iframe');
-            ifr.src = `ifrCnt/ifrCnt_${page}.html`;
-            cpInstanceData({ contentsKey: `ifrCnt_${page}` }); // 콘텐츠 키 설정
-        }
-
-        $('.viewer-nav li').on('click', function() {
-            $('.viewer-nav li').removeClass('is-active');
-            $(this).addClass('is-active');
-        });
-    </script>  
-</body>
-
-</html>(파일 끝에 줄바꿈 문자 없음)
 
html/onSejong/manager/class/classViewer_painter_doc.html (deleted)
--- html/onSejong/manager/class/classViewer_painter_doc.html
@@ -1,231 +0,0 @@
-<!DOCTYPE html>
-<html lang="ko">
-
-<head>
-    <title>온세종학교</title>
-
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    <meta name="Author" content="">
-    <meta name="Keywords" content="">
-    <meta name="Description" content="">
-    <meta name="format-detection" content="telephone=no">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
-
-    <link href="/resources/front/site/SITE_00000/css/style.css" rel="stylesheet">
-
-    <!-- 공통 plugin -->
-    <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-3.6.0.min.js"></script>
-    <script src="/resources/front/site/SITE_00000/js/common/jquery/jquery-ui.min.js"></script>
-    <!-- //공통 plugin -->
-        
-   <!-- 페이지 plugin-->
-   <!-- //페이지 plugin-->
-
-   <!-- 공통 퍼블 layout: 개발시 삭제-->
-   <!-- <script src="/resources/front/site/SITE_00000/js/_layout.js"></script> -->
-   <!--//퍼블 layout--> 
-   
- 	<!-- 공통 메뉴 js-->
-	<!-- //공통 메뉴 js -->
-    
-    <!--공통 퍼블 js-->
-    <script src="/resources/front/site/SITE_00000/js/common.js"></script>
-	<script src="/resources/front/site/SITE_00000/js/common-custom.js"></script>
-    <!--//공통 퍼블 js-->
-</head>
-
-<body>
-    <section class="class-viewer">
-        <header class="viewer-header">
-            <div class="l-area">
-                <!-- <button type="button" class="btn-viewer-menu btn circle ico-menu sm">메뉴</button> -->
-                <div class="viewer-tit">
-                    <h1 class="">활동1) 무늬를 꾸며보는 방법 알아보기</h1>
-                </div>
-            </div>
-            <div class="r-area">
-                <div class="btn-group">
-                    <button type="button" class="btn sm primary"><i class="ico-save"></i> 저장</button>
-                    <button type="button" class="btn sm"><i class="ico-logout"></i> 나가기</button>
-                </div>
-            </div>    
-        </header>
-        <div class="viewer-body">
-            <div class="viewer-menu-area">
-                <div class="viewer-menu-header">
-                    <div class="menu-add-area">
-                        <button class="btn-menu-add"><span>과정추가</span></button>
-                        <div class="menu-add-option" >
-                            <button type="button">파일 업로드</button>
-                            <button type="button">링크추가</button>
-                            <button type="button">나의 보관함에서 선택</button>
-                            <button type="button">콘텐츠에서 검색</button>
-                        </div>
-                    </div>
-                </div>
-                <div class="viewer-menu-body">
-                    <nav class="viewer-nav">
-                        <ul>
-                            <li class="is-active">
-                                <a href="javascript:changeIfr(1)" class="lnk-full">상세보기</a>
-                                <div class="nav-info">
-                                    <span class="num">1</span>
-                                    <div class="fnc order-front">
-                                        <button type="button" class="ico-delete order-front">삭제</button>
-                                        <i class="ico-move">이동</i>
-                                    </div>
-                                </div>
-                                <div class="nav-cont">
-                                    <div class="img-area">
-                                        <img src="/resources/front/site/SITE_00000/images/temp/img1.jpg" alt="">
-                                    </div>
-                                    <div class="txt-area">
-                                        <div class="label-area"><span class="label-cont-doc">문서</span></div>
-                                        <div class="txt">문서</div>
-                                    </div>
-                                </div>
-                            </li>
-                            <li>
-                                <a href="javascript:changeIfr(2)" class="lnk-full">상세보기</a>
-                                <div class="nav-info">
-                                    <span class="num">2</span>
-                                    <div class="fnc order-front">
-                                        <button type="button" class="ico-delete order-front">삭제</button>
-                                        <i class="ico-move">이동</i>
-                                    </div>
-                                </div>
-                                <div class="nav-cont">
-                                    <div class="txt-area">
-                                        <div class="label-area"><span class="label-cont-video">영상</span></div>
-                                        <div class="txt">영상</div>
-                                    </div>
-                                </div>
-                            </li>
-                            <li>
-                                <a href="javascript:changeIfr(3)" class="lnk-full">상세보기</a>
-                                <div class="nav-info">
-                                    <span class="num">3</span>
-                                    <div class="fnc order-front">
-                                        <button type="button" class="ico-delete order-front">삭제</button>
-                                        <i class="ico-move">유튜브</i>
-                                    </div>
-                                </div>
-                                <div class="nav-cont">
-                                    <div class="txt-area">
-                                        <div class="label-area"><span class="label-cont-video">영상</span></div>
-                                        <div class="txt">유튜브</div>
-                                    </div>
-                                </div>
-                            </li>
-                            <li>
-                        </ul>
-                    </nav>
-                </div>
-                <button type="button" class="btn-viewer-menu-toggle"><span class="txt-hide">메뉴 열기&amp;닫기</span></button>
-            </div>
-            <div class="viewer-cont">
-                <div class="iframe-area">
-                    <input type="hidden" id="d8f68ffff73a47ff9b9185caf2452b0c_1" value="https://devdcuai.cbe.go.kr/contents/classLesson/202504/20250402125701229/20250402125701229_0001.jpg">
-                    <input type="hidden" id="d8f68ffff73a47ff9b9185caf2452b0c_2" value="https://devdcuai.cbe.go.kr/contents/classLesson/202504/20250402125701229/20250402125701229_0002.jpg">
-                    <div class="iframe-doc-area">
-                        <iframe src="/resources/front/site/SITE_00000/images/temp/img-pdf.jpg" data-link="" class="view_iframe"></iframe>
-                        <div class="doc-fnc-area">
-                            <button class="btn circle ico-pv">이전</button>
-                            <button class="btn circle ico-fw">다음</button>
-                        </div>
-                    </div>
-                </div>
-            <ul class="viewer-tool">
-                <li>
-                    <button type="button" class="btn-painter-toggle lnk-full">판서</button>
-                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-pencil.svg" alt="" aria-hidden="true">
-                    <strong>판서</strong>
-                </li>
-                <li>
-                    <button type="button" class="lnk-full">채팅 열기&amp;닫기</button>
-                    <img src="/resources/front/site/SITE_00000/images/common/ico-img/ico-img-chat.svg" alt="" aria-hidden="true">
-                    <strong>채팅</strong>
-                    <span class="badge min">새 채팅</span>
-                </li>
-            </ul>
-        </div>
-    </section>
-
-    <!--toast-->
-    <div class="toast"></div>
-    
-    <!--popup-->
-    <script>
-        // 과정추가
-        $(document).on('click', '.btn-menu-add', function (e) {
-            e.stopPropagation();
-            $('.menu-add-area').toggleClass('is-active');
-        });
-    
-        $(document).on('click', function () {
-            $('.menu-add-area').removeClass('is-active');
-        });
-
-        //과정 순서 변경
-        $(".viewer-nav>ul").sortable({
-            handle: $(".viewer-nav>ul>li").find(".ico-move"),
-            axis: "y", 
-            //containment: "parent",
-            update: function (event, ui) {
-                var $list = $(this).children("li");
-                $list.each(function () {
-                    var $li = $(this);
-                    var newVal = $(this).index() + 1;
-                    $(this).find(".num").html(newVal);
-                });
-            },
-        });
-    </script>
-
-    
-    <!-- 모듈로 스크립트를 불러오기 -->
-    <script type="module">
-        import { initColouredPenciles } from '/resources/front/site/SITE_00000/js/custom/module/colouredPencilesSvg_pub.js';
-    </script>
-
-    <script>
-        // colouredPencilesSvg.js 데이터 전달 스크립트
-        const cpInstanceData = (data) => {
-            if (window.cpInstance) {
-                window.cpInstance.setDataParam(data);
-            } else {
-                // console.log('cpInstance 아직 정의되지 않음, 500ms 후 다시 시도.');
-                setTimeout(cpInstanceData, 500, data); // cpInstance 정의 전까지 500ms 간격으로 재시도
-            }
-        }
-        const cpInstanceSave = () => {
-            if (window.cpInstance) {
-                window.cpInstance.saveDrawing();
-            } else {
-                // console.log('cpInstance 아직 정의되지 않음, 500ms 후 다시 시도.');
-                setTimeout(cpInstanceSave, 500, data); // cpInstance 정의 전까지 500ms 간격으로 재시도
-            }
-        }
-
-         // 페이지 로드 시 사용자 키 및 콘텐츠 키 전달
-         window.addEventListener('DOMContentLoaded', () => {
-            const page = 0;
-            cpInstanceData({ userKey: 'testuser', contentsKey: `ifrCnt_${page}` }); // 사용자 키 설정
-        });
-        // 콘텐츠 변경 시, 콘텐츠 키 발행 및 전달
-        const changeIfr = (page) => {
-            cpInstanceSave(); // 페이지 이동 전 저장
-            const ifr = document.querySelector('.iframe-area iframe');
-            ifr.src = `ifrCnt/ifrCnt_${page}.html`;
-            cpInstanceData({ contentsKey: `ifrCnt_${page}` }); // 콘텐츠 키 설정
-        }
-
-        $('.viewer-nav li').on('click', function() {
-            $('.viewer-nav li').removeClass('is-active');
-            $(this).addClass('is-active');
-        });
-    </script>  
-</body>
-
-</html>(파일 끝에 줄바꿈 문자 없음)
resources/front/site/SITE_00000/css/common/viewer/_colouredPenciles.scss
--- resources/front/site/SITE_00000/css/common/viewer/_colouredPenciles.scss
+++ resources/front/site/SITE_00000/css/common/viewer/_colouredPenciles.scss
@@ -32,6 +32,7 @@
         bottom: 0;
         right: 0;
         width: 100% !important;
+        height: 100% !important;
         min-height: 100%;
         // height: 100% !important;
         cursor: url($url-img + 'common/common/img_painter.svg'), auto;
resources/front/site/SITE_00000/css/common/viewer/_viewer.scss
--- resources/front/site/SITE_00000/css/common/viewer/_viewer.scss
+++ resources/front/site/SITE_00000/css/common/viewer/_viewer.scss
@@ -246,9 +246,9 @@
         opacity: 0.3;
     }
     .btn-viewer-block-close {
-            position: absolute;
-            right: 4rem;
-            top: 1.6rem;
+		position: absolute;
+		right: 4rem;
+		top: 1.6rem;
     }
 }
 .viewer-cont {
@@ -263,6 +263,42 @@
     overflow-x: hidden;
     overflow-y: auto;
 }
+.viewer-cont-box {
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	background-color: $color-font-default-primary;
+	width: 100%;
+	height: 100%;
+	img,
+	video {
+		object-fit: contain;
+		max-width: 100%;
+		max-height: 100%;
+	}
+	video {
+        width: 100%;
+        max-height: 100%;
+    }
+	iframe {
+        display: block;
+        width: 100%;
+        height: 100%;
+    }
+}
+.viewer-painter {
+	position: absolute;
+	top: 0;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	z-index: -1;
+	opacity: 0;
+	&.is-active {
+		z-index: 1;
+		opacity: 1;
+	}
+}
 .viewer-wrap {
     min-height: calc(100% - 4rem);
     max-width: 144rem;
resources/front/site/SITE_00000/css/style.css
--- resources/front/site/SITE_00000/css/style.css
+++ resources/front/site/SITE_00000/css/style.css
@@ -20821,6 +20821,7 @@
   bottom: 0;
   right: 0;
   width: 100% !important;
+  height: 100% !important;
   min-height: 100%;
   cursor: url("../images/common/common/img_painter.svg"), auto;
   z-index: 10;
@@ -24360,6 +24361,51 @@
   overflow-y: auto;
 }
 
+.viewer-cont-box {
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-pack: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-box-align: center;
+      -ms-flex-align: center;
+          align-items: center;
+  background-color: var(--color-font-default-primary);
+  width: 100%;
+  height: 100%;
+}
+.viewer-cont-box img,
+.viewer-cont-box video {
+  -o-object-fit: contain;
+     object-fit: contain;
+  max-width: 100%;
+  max-height: 100%;
+}
+.viewer-cont-box video {
+  width: 100%;
+  max-height: 100%;
+}
+.viewer-cont-box iframe {
+  display: block;
+  width: 100%;
+  height: 100%;
+}
+
+.viewer-painter {
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  z-index: -1;
+  opacity: 0;
+}
+.viewer-painter.is-active {
+  z-index: 1;
+  opacity: 1;
+}
+
 .viewer-wrap {
   min-height: calc(100% - 4rem);
   max-width: 144rem;
resources/front/site/SITE_00000/css/style.css.map
--- resources/front/site/SITE_00000/css/style.css.map
+++ resources/front/site/SITE_00000/css/style.css.map
This diff is too big to display.
resources/front/site/SITE_00000/css/style.min.css
--- resources/front/site/SITE_00000/css/style.min.css
+++ resources/front/site/SITE_00000/css/style.min.css
This diff is too big to display.
resources/front/site/SITE_00000/css/style.min.css.map
--- resources/front/site/SITE_00000/css/style.min.css.map
+++ resources/front/site/SITE_00000/css/style.min.css.map
This diff is too big to display.
resources/front/site/SITE_00000/js/common.js
--- resources/front/site/SITE_00000/js/common.js
+++ resources/front/site/SITE_00000/js/common.js
@@ -476,9 +476,9 @@
     $('.btn-util-area').btnUtilFunc();
     $('.site-menu-area').siteMenuFunc();
 
-    $('input[type=date]').on('focus', function() {
-        this.showPicker();
-    });
+    // $('input[type=date]').on('focus', function() {
+    //     this.showPicker();
+    // });
 });
 
 $(document).on('keydown', '.site-header .gnb > ul > li > a, .site-header .gnb > ul > li > button', function (event) {
@@ -499,6 +499,7 @@
     $(this).showPicker();
 });
 
+//비밀번호 숨기기
 $(document).on('click', '.btn-pw-toggle', function () {
     const $btn = $(this);
     const $pwArea = $btn.closest('.input-pw-area');
 
resources/front/site/SITE_00000/js/common/module/colouredPenciles.ts (deleted)
--- resources/front/site/SITE_00000/js/common/module/colouredPenciles.ts
@@ -1,357 +0,0 @@
-/*
-* Copyright (c) FOX EDU CO., LTD ALL RIGHT RESERVED.
-* by flashkid
-* 25.OCT.2023(WED)
-*/
-
-class colouredPenciles {
-    private btnInit: HTMLElement;
-    private ctrlCon: HTMLElement;
-    private canvasCon: HTMLElement;
-
-    private canvas: HTMLCanvasElement;
-    private context: CanvasRenderingContext2D;
-    private eraseObj: HTMLInputElement;
-    private previewObj: HTMLElement;
-
-    private paint: boolean;
-
-    private points: object[] = [];
-    private dopoints: object[] = [];
-
-    private coloursArr: any;
-    private coloursSelect: number;
-    private sizeRange: object;
-    private size: number;
-    private erase: boolean = false;
-
-    constructor(btnInit, canvasCon, coloursArr, coloursSelect = 1, brushMin = 0.5, brushMax = 10) {
-        this.btnInit = btnInit;
-        this.canvasCon = canvasCon;
-        this.coloursArr = coloursArr.map(c => c.toLowerCase());
-        this.coloursSelect = coloursSelect - 1;
-        brushMax = brushMax > 60 ? 60 : brushMax;
-        this.sizeRange = {
-            min: brushMin,
-            max: brushMax
-        }
-        this.size = Math.round((brushMin + brushMax) / 2);
-        
-        this.btnInit.onclick = () => {
-            if(this.btnInit.classList.contains('is-active')) {
-                this.clearCanvas();
-            } else {
-                const canvas = document.createElement('canvas') as HTMLCanvasElement;
-                canvas.width = this.canvasCon.offsetWidth;
-                canvas.height = this.canvasCon.clientHeight;
-                const context = canvas.getContext("2d");
-                context.lineCap = 'round';
-                context.lineJoin = 'round';
-        
-                this.canvas = canvas;
-                this.canvas.id = 'painterCanvas';
-                this.context = context;
-                this.canvasCon.append(this.canvas);
-
-                this.uiUpdate();
-        
-                this.redraw();
-                this.createDrawEvents();
-            }
-        }
-    }
-
-    private uiUpdate = () => {
-        this.btnInit.classList.add('is-active');
-        this.canvasCon.classList.add('is-active');
-
-        this.ctrlCon = document.createElement('div');
-        this.ctrlCon.classList.add('painterbar');
-        this.canvasCon.append(this.ctrlCon);
-
-        const minBtn = document.createElement('button');
-        minBtn.type = "button";
-        minBtn.classList.add('btn-painterbar-size');
-        minBtn.textContent = '색연필 최소화';
-        this.ctrlCon.append(minBtn);
-        minBtn.onclick = () => {
-            this.ctrlCon.classList.toggle('min');
-        }
-
-        const previewCon = document.createElement('div');
-        previewCon.classList.add('pencil-ctrl-options', 'pencil-preview');
-        previewCon.style.width = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-        previewCon.style.height = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-        this.ctrlCon.append(previewCon);
-        this.previewObj = document.createElement('div');
-        previewCon.append(this.previewObj);
-
-        const sizeCon = document.createElement('div');
-        sizeCon.classList.add('pencil-ctrl-options', 'painterbar-stroke');
-        this.ctrlCon.append(sizeCon);
-
-        const range = document.createElement('input');
-        range.type = "range";
-        range.min = this.sizeRange['min'];
-        range.max = this.sizeRange['max'];
-        range.step = "0.1";
-        range.setAttribute("orient", "vertical");
-        range.value = this.size.toString();
-        sizeCon.append(range);
-        range.oninput = () => {
-            this.changeSize(range.value);
-        }
-
-        const fncCon = document.createElement('div');
-        fncCon.classList.add('pencil-ctrl-options', 'painterbar-fnc');
-        this.ctrlCon.append(fncCon);
-
-        const undo = document.createElement('button');
-        undo.type = "button";
-        undo.classList.add('undo');
-        undo.textContent = "undo";
-        fncCon.append(undo);
-        undo.addEventListener('click', this.undo);
-
-        const redo = document.createElement('button');
-        redo.type = "button";
-        redo.classList.add('redo');
-        redo.textContent = "redo";
-        fncCon.append(redo);
-        redo.addEventListener('click', this.redo);
-
-        this.eraseObj = document.createElement('input');
-        this.eraseObj.type = "checkbox";
-        this.eraseObj.id = "colouredPencils_eraser";
-        this.eraseObj.classList.add('clear');
-        this.eraseObj.checked = this.erase;
-        fncCon.append(this.eraseObj);
-        const eraserLB = document.createElement('label');
-        eraserLB.setAttribute("for", this.eraseObj.id);
-        eraserLB.textContent = "지우개";
-        fncCon.append(eraserLB);
-        this.eraseObj.onchange = () => {
-            this.switchEraser();
-        }
-
-        const reset = document.createElement('button');
-        reset.type = 'button';
-        reset.classList.add('reset');
-        reset.textContent = 'reset';
-        fncCon.append(reset);
-        reset.onclick = () => this.reset();
-
-        const colorDiv = document.createElement('div');
-        colorDiv.classList.add('pencil-ctrl-options', 'painterbar-color');
-        colorDiv.setAttribute('data-opt', this.coloursArr[this.coloursSelect]);
-        this.ctrlCon.append(colorDiv);
-        this.coloursArr.forEach ((el, i) => {
-            const radio = document.createElement('input');
-            radio.type = "radio";
-            radio.name = "colouredPencils_colour";
-            radio.id = "colouredPencils_colour_" + i;
-            radio.value = i.toString();
-            if (i == this.coloursSelect) radio.checked = true;
-            colorDiv.append(radio);
-            const label = document.createElement('label');
-            label.setAttribute("for", radio.id);
-            label.textContent = el;
-            label.style.backgroundColor = el;
-            if(el == '#ffffff') label.classList.add('white');
-            colorDiv.append(label);
-            radio.onchange = (e:Event) => {
-                this.changeColour(i);
-            }
-        });
-
-        const close = document.createElement('button');
-        close.type = "button";
-        close.classList.add('btn-viewer-painter-close');
-        close.textContent = "색연필 닫기";
-        this.ctrlCon.append(close);
-        close.onclick = () => {
-            this.clearCanvas();
-        }
-
-        this.updatePreview();
-    }
-
-    private undo = () => {
-        if (this.points.length == 0) return;
-        const arrKeys = this.points.map(el => el["mode"]);
-        const lastIndex = arrKeys.lastIndexOf(false);
-        const tempPoints = this.points.slice(lastIndex, this.points.length - 1);
-        this.dopoints = [...this.dopoints, ...tempPoints];
-        this.points = this.points.slice(0, lastIndex);
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.redraw();
-    }
-
-    private redo = () => {
-        if (this.dopoints.length == 0) return;
-        const arrKeys = this.dopoints.map(el => el["mode"]);
-        const lastIndex = arrKeys.lastIndexOf(false);
-        const tempPoints = this.dopoints.slice(lastIndex, this.dopoints.length - 1);
-        this.points = [...this.points, ...tempPoints];
-        this.dopoints = this.dopoints.slice(0, lastIndex);
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.redraw();
-    }
-
-    private reset = () => {
-        this.points = [];
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.redraw();
-        if(this.erase) {
-            this.switchEraser();
-        }
-    }
-
-    private changeSize = (size) => {
-        this.size = +size;
-        this.updatePreview();
-    }
-
-    private changeColour = (key) => {
-        this.coloursSelect = key;
-        if(this.erase) this.switchEraser();
-        this.updatePreview();
-    }
-
-    private switchEraser = () => {
-        this.erase = !this.erase;
-        this.eraseObj.checked = this.erase;
-        this.updatePreview();
-    }
-
-    private updatePreview = () => {
-        this.previewObj.style.cssText = `
-            width: ${this.size * 0.1}rem;
-            height: ${this.size * 0.1}rem;
-        `
-        if (this.coloursArr[this.coloursSelect] == '#ffffff') {
-            this.previewObj.classList.add('white');
-        } else {
-            this.previewObj.classList.remove('white');
-        }
-
-        if (this.erase) {
-            this.previewObj.classList.add('erase');
-        } else {
-            this.previewObj.classList.remove('erase');
-            this.previewObj.style.backgroundColor = `${this.coloursArr[this.coloursSelect]}`;
-        }
-    }
-
-    private clearCanvas = () => {
-        this.ctrlCon.remove();
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.points = [];
-        this.dopoints = [];
-        this.canvasCon.removeChild(this.canvas);
-        this.erase = false;
-
-        this.btnInit.classList.remove('is-active');
-        this.canvasCon.classList.remove('is-active');
-    }
-
-    private createDrawEvents = () => {
-        const canvas = this.canvas;
-
-        canvas.addEventListener("mousedown", this.pressEventHandler);
-        canvas.addEventListener("mousemove", this.dragEventHandler);
-        canvas.addEventListener("mouseup", this.releaseEventHandler);
-        canvas.addEventListener("mouseout", this.cancelEventHandler);
-
-        canvas.addEventListener("touchstart", this.pressEventHandler);
-        canvas.addEventListener("touchmove", this.dragEventHandler);
-        canvas.addEventListener("touchend", this.releaseEventHandler);
-        canvas.addEventListener("touchcancel", this.cancelEventHandler);
-    }
-
-    private redraw = () => {
-        const points = this.points;
-        if (points.length == 0) return;
-        const context = this.context;
-        context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        for (let i = 0; i < points.length; ++i) {
-            if (points[i]["erase"]) {
-                context.globalCompositeOperation = "destination-out";
-            } else {
-                context.globalCompositeOperation = "source-over";
-            }
-            context.beginPath();
-            if (points[i]["mode"] && i) {
-                context.moveTo(points[i - 1]["x"], points[i - 1]["y"]);
-            } else {
-                context.moveTo(points[i]["x"] - 1, points[i]["y"]);
-            }
-
-            context.lineTo(points[i]["x"], points[i]["y"]);
-            context.strokeStyle = points[i]["color"];
-            context.lineWidth = points[i]["size"];
-            context.stroke();
-        }
-        context.closePath();
-    }
-
-    private addClick = (x: number, y: number, color: string, size: number, dragging: boolean, erase: boolean) => {
-        this.points.push({ x: x, y: y, color: color, size: size, mode: dragging, erase: erase })
-    }
-
-    private releaseEventHandler = () => {
-        if (this.paint) {
-            this.paint = false;
-            this.redraw();
-        }
-    }
-
-    private cancelEventHandler = () => {
-        this.releaseEventHandler();
-    }
-
-    private pressEventHandler = (e: MouseEvent | TouchEvent) => {
-        this.dopoints = [];
-        let mouseX = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageX :
-            (e as MouseEvent).pageX;
-        let mouseY = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageY :
-            (e as MouseEvent).pageY;
-        mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-        mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-
-        this.paint = true;
-        this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, false, this.erase);
-        this.redraw();
-    }
-
-    private dragEventHandler = (e: MouseEvent | TouchEvent) => {
-        let mouseX = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageX :
-            (e as MouseEvent).pageX;
-        let mouseY = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageY :
-            (e as MouseEvent).pageY;
-        mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-        mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-
-        if (this.paint) {
-            this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, true, this.erase);
-            this.redraw();
-        }
-
-        e.preventDefault();
-    }
-}
-
-// 환경설정
-const colorArray = ["#222222","#fd4418","#ffce00","#00d56a","#2f77ff","#ffffff"];
-const defaultColor = 5;
-const brushMin = 0.5, brushMax = 40;
-// 대상 개체
-const btnInit = document.querySelector('.btn-painter-toggle') as HTMLElement;
-const targetObj = document.querySelector('.paint-target') as HTMLElement;
-// 구동 defaultColor, brushMin, brushMax 은 넘기지 않아도 기본 값에 의해 작동됨
-new colouredPenciles(btnInit, targetObj, colorArray, defaultColor, brushMin, brushMax);
-// new colouredPenciles(btnInit, targetObj, colorArray);
 
resources/front/site/SITE_00000/js/common/module/colouredPenciles_new.js (deleted)
--- resources/front/site/SITE_00000/js/common/module/colouredPenciles_new.js
@@ -1,356 +0,0 @@
-/*
-* Copyright (c) FOX EDU CO., LTD ALL RIGHT RESERVED.
-* by flashkid
-* 25.OCT.2023(WED)
-*/
-class colouredPenciles {
-    constructor(btnInit, canvasCon, coloursArr, coloursSelect = 1, brushMin = 0.5, brushMax = 10) {
-        this.points = [];
-        this.dopoints = [];
-        this.erase = false;
-        this.uiUpdate = () => {
-            this.btnInit.classList.add('is-active');
-            this.canvasCon.classList.add('is-active');
-            this.ctrlCon = document.createElement('div');
-            this.ctrlCon.classList.add('painterbar');
-            this.canvasCon.append(this.ctrlCon);
-            const minBtn = document.createElement('button');
-            minBtn.type = "button";
-            minBtn.classList.add('btn-painterbar-size');
-            minBtn.textContent = '색연필 최소화';
-            this.ctrlCon.append(minBtn);
-            minBtn.onclick = () => {
-                this.ctrlCon.classList.toggle('min');
-            };
-            const previewCon = document.createElement('div');
-            previewCon.classList.add('pencil-ctrl-options', 'pencil-preview');
-            previewCon.style.width = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            previewCon.style.height = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            this.ctrlCon.append(previewCon);
-            this.previewObj = document.createElement('div');
-            previewCon.append(this.previewObj);
-            const sizeCon = document.createElement('div');
-            sizeCon.classList.add('pencil-ctrl-options', 'painterbar-stroke');
-            this.ctrlCon.append(sizeCon);
-            const range = document.createElement('input');
-            range.type = "range";
-            range.min = this.sizeRange['min'];
-            range.max = this.sizeRange['max'];
-            range.step = "0.1";
-            range.setAttribute("orient", "vertical");
-            range.value = this.size.toString();
-            sizeCon.append(range);
-            range.oninput = () => {
-                this.changeSize(range.value);
-            };
-            const fncCon = document.createElement('div');
-            fncCon.classList.add('pencil-ctrl-options', 'painterbar-fnc');
-            this.ctrlCon.append(fncCon);
-            const undo = document.createElement('button');
-            undo.type = "button";
-            undo.classList.add('undo');
-            undo.textContent = "undo";
-            fncCon.append(undo);
-            undo.addEventListener('click', this.undo);
-            const redo = document.createElement('button');
-            redo.type = "button";
-            redo.classList.add('redo');
-            redo.textContent = "redo";
-            fncCon.append(redo);
-            redo.addEventListener('click', this.redo);
-            this.eraseObj = document.createElement('input');
-            this.eraseObj.type = "checkbox";
-            this.eraseObj.id = "colouredPencils_eraser";
-            this.eraseObj.classList.add('clear');
-            this.eraseObj.checked = this.erase;
-            fncCon.append(this.eraseObj);
-            const eraserLB = document.createElement('label');
-            eraserLB.setAttribute("for", this.eraseObj.id);
-            eraserLB.textContent = "지우개";
-            fncCon.append(eraserLB);
-            this.eraseObj.onchange = () => {
-                this.switchEraser();
-            };
-            const reset = document.createElement('button');
-            reset.type = 'button';
-            reset.classList.add('reset');
-            reset.textContent = 'reset';
-            fncCon.append(reset);
-            reset.onclick = () => this.reset();
-            const colorDiv = document.createElement('div');
-            colorDiv.classList.add('pencil-ctrl-options', 'painterbar-color');
-            colorDiv.setAttribute('data-opt', this.coloursArr[this.coloursSelect]);
-            this.ctrlCon.append(colorDiv);
-            this.coloursArr.forEach((el, i) => {
-                const radio = document.createElement('input');
-                radio.type = "radio";
-                radio.name = "colouredPencils_colour";
-                radio.id = "colouredPencils_colour_" + i;
-                radio.value = i.toString();
-                if (i == this.coloursSelect)
-                    radio.checked = true;
-                colorDiv.append(radio);
-                const label = document.createElement('label');
-                label.setAttribute("for", radio.id);
-                label.textContent = el;
-                label.style.backgroundColor = el;
-                if (el == '#ffffff')
-                    label.classList.add('white');
-                colorDiv.append(label);
-                radio.onchange = (e) => {
-                    this.changeColour(i);
-                };
-            });
-            const close = document.createElement('button');
-            close.type = "button";
-            close.classList.add('btn-viewer-painter-close');
-            close.textContent = "색연필 닫기";
-            this.ctrlCon.append(close);
-            close.onclick = () => {
-                this.clearCanvas();
-            };
-            this.updatePreview();
-        };
-        this.undo = () => {
-            if (this.points.length == 0)
-                return;
-            const arrKeys = this.points.map(el => el["mode"]);
-            const lastIndex = arrKeys.lastIndexOf(false);
-            const tempPoints = this.points.slice(lastIndex, this.points.length - 1);
-            this.dopoints = [...this.dopoints, ...tempPoints];
-            this.points = this.points.slice(0, lastIndex);
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-        };
-        this.redo = () => {
-            if (this.dopoints.length == 0)
-                return;
-            const arrKeys = this.dopoints.map(el => el["mode"]);
-            const lastIndex = arrKeys.lastIndexOf(false);
-            const tempPoints = this.dopoints.slice(lastIndex, this.dopoints.length - 1);
-            this.points = [...this.points, ...tempPoints];
-            this.dopoints = this.dopoints.slice(0, lastIndex);
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-        };
-        this.reset = () => {
-            this.points = [];
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-            if (this.erase) {
-                this.switchEraser();
-            }
-        };
-        this.changeSize = (size) => {
-            this.size = +size;
-            this.updatePreview();
-        };
-        this.changeColour = (key) => {
-            this.coloursSelect = key;
-            if (this.erase)
-                this.switchEraser();
-            this.updatePreview();
-        };
-        this.switchEraser = () => {
-            this.erase = !this.erase;
-            this.eraseObj.checked = this.erase;
-            this.updatePreview();
-            const area = document.querySelector('.paint-target');
-            if (this.erase) {
-                area.classList.add('is-eraser');
-            } else {
-                area.classList.remove('is-eraser');
-            }
-        };
-        this.updatePreview = () => {
-            this.previewObj.style.cssText = `
-            width: ${this.size * 0.1}rem;
-            height: ${this.size * 0.1}rem;
-        `;
-            if (this.coloursArr[this.coloursSelect] == '#ffffff') {
-                this.previewObj.classList.add('white');
-            }
-            else {
-                this.previewObj.classList.remove('white');
-            }
-            if (this.erase) {
-                this.previewObj.classList.add('erase');
-            }
-            else {
-                this.previewObj.classList.remove('erase');
-                this.previewObj.style.backgroundColor = `${this.coloursArr[this.coloursSelect]}`;
-            }
-        };
-        this.clearCanvas = () => {
-            this.ctrlCon.remove();
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.points = [];
-            this.dopoints = [];
-            this.canvasCon.removeChild(this.canvas);
-            this.erase = false;
-            this.btnInit.classList.remove('is-active');
-            this.canvasCon.classList.remove('is-active');
-        };
-        this.createDrawEvents = () => {
-            const canvas = this.canvas;
-            canvas.addEventListener("mousedown", this.pressEventHandler);
-            canvas.addEventListener("mousemove", this.dragEventHandler);
-            canvas.addEventListener("mouseup", this.releaseEventHandler);
-            canvas.addEventListener("mouseout", this.cancelEventHandler);
-            canvas.addEventListener("touchstart", this.pressEventHandler);
-            canvas.addEventListener("touchmove", this.dragEventHandler);
-            canvas.addEventListener("touchend", this.releaseEventHandler);
-            canvas.addEventListener("touchcancel", this.cancelEventHandler);
-        };
-        this.redraw = () => {
-            const points = this.points;
-            if (points.length == 0)
-                return;
-            const context = this.context;
-            context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            for (let i = 0; i < points.length; ++i) {
-                if (points[i]["erase"]) {
-                    context.globalCompositeOperation = "destination-out";
-                }
-                else {
-                    context.globalCompositeOperation = "source-over";
-                }
-                context.beginPath();
-                if (points[i]["mode"] && i) {
-                    context.moveTo(points[i - 1]["x"], points[i - 1]["y"]);
-                }
-                else {
-                    context.moveTo(points[i]["x"] - 1, points[i]["y"]);
-                }
-                context.lineTo(points[i]["x"], points[i]["y"]);
-                context.strokeStyle = points[i]["color"];
-                context.lineWidth = points[i]["size"];
-                context.stroke();
-            }
-            context.closePath();
-        };
-        this.addClick = (x, y, color, size, dragging, erase) => {
-            this.points.push({ x: x, y: y, color: color, size: size, mode: dragging, erase: erase });
-        };
-        this.releaseEventHandler = () => {
-            if (this.paint) {
-                this.paint = false;
-                this.redraw();
-            }
-        };
-        this.cancelEventHandler = () => {
-            this.releaseEventHandler();
-        };
-        this.pressEventHandler = (e) => {
-            this.dopoints = [];
-            let mouseX = e.changedTouches ?
-                e.changedTouches[0].pageX :
-                e.pageX;
-            let mouseY = e.changedTouches ?
-                e.changedTouches[0].pageY :
-                e.pageY;
-            mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-            mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-            this.paint = true;
-            this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, false, this.erase);
-            this.redraw();
-        };
-        this.dragEventHandler = (e) => {
-            let mouseX = e.changedTouches ?
-                e.changedTouches[0].pageX :
-                e.pageX;
-            let mouseY = e.changedTouches ?
-                e.changedTouches[0].pageY :
-                e.pageY;
-            mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-            mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-            if (this.paint) {
-                this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, true, this.erase);
-                this.redraw();
-            }
-            e.preventDefault();
-        };
-        this.btnInit = btnInit;
-        this.canvasCon = canvasCon;
-        this.coloursArr = coloursArr.map(c => c.toLowerCase());
-        this.coloursSelect = coloursSelect - 1;
-        brushMax = brushMax > 60 ? 60 : brushMax;
-        this.sizeRange = {
-            min: brushMin,
-            max: brushMax
-        };
-        this.size = Math.round((brushMin + brushMax) / 2);
-        // this.btnInit.onclick = () => {
-        //     if (this.btnInit.classList.contains('is-active')) {
-        //         this.clearCanvas();
-        //     }
-        //     else {
-        //         const canvas = document.createElement('canvas');
-        //         canvas.width = this.canvasCon.offsetWidth;
-        //         canvas.height = this.canvasCon.clientHeight;
-        //         const context = canvas.getContext("2d");
-        //         context.lineCap = 'round';
-        //         context.lineJoin = 'round';
-        //         this.canvas = canvas;
-        //         this.canvas.id = 'painterCanvas';
-        //         this.context = context;
-        //         this.canvasCon.append(this.canvas);
-        //         this.uiUpdate();
-        //         this.redraw();
-        //         this.createDrawEvents();
-        //     }
-        // };
-        this.btnInit.onclick = () => {
-            if (this.btnInit.classList.contains('is-active')) {
-                this.clearCanvas();
-            } else {
-                const canvas = document.createElement('canvas');
-                let width = this.canvasCon.clientWidth;
-                let height = this.canvasCon.clientHeight;
-                const isQuizViewer = this.canvasCon.closest('.quiz-viewer');
-                
-                if (isQuizViewer) {
-                    const wrap = isQuizViewer.querySelector('.quiz-viewer-wrap');
-                    if (wrap) {
-                        height = wrap.clientHeight;
-                    }
-                }
-        
-                // viewer-body 최소 높이 반영
-                const viewerBody = document.querySelector('.viewer-body');
-                if (viewerBody) {
-                    const viewerBodyHeight = viewerBody.clientHeight;
-                    height = Math.max(height, viewerBodyHeight); // 더 큰 값 사용
-                }
-        
-                canvas.width = width;
-                canvas.height = height;
-                canvas.style.width = width + 'px';
-                canvas.style.height = height + 'px';
-        
-                const context = canvas.getContext("2d");
-                context.lineCap = 'round';
-                context.lineJoin = 'round';
-        
-                this.canvas = canvas;
-                this.canvas.id = 'painterCanvas';
-                this.context = context;
-                this.canvasCon.append(this.canvas);
-                this.uiUpdate();
-                this.redraw();
-                this.createDrawEvents();
-            }
-        };
-        
-    }
-}
-// 환경설정
-const colorArray = ["#222222", "#fd4418", "#ffce00", "#00d56a", "#2f77ff", "#ffffff"];
-const defaultColor = 5;
-const brushMin = 0.5, brushMax = 40;
-// 대상 개체
-const btnInit = document.querySelector('.btn-painter-toggle');
-const targetObj = document.querySelector('.paint-target');
-// 구동 defaultColor, brushMin, brushMax 은 넘기지 않아도 기본 값에 의해 작동됨
-new colouredPenciles(btnInit, targetObj, colorArray, defaultColor, brushMin, brushMax);
-// new colouredPenciles(btnInit, targetObj, colorArray);
 
resources/front/site/SITE_00000/js/common/module/colouredPenciles_old.js (deleted)
--- resources/front/site/SITE_00000/js/common/module/colouredPenciles_old.js
@@ -1,314 +0,0 @@
-/*
-* Copyright (c) FOX EDU CO., LTD ALL RIGHT RESERVED.
-* by flashkid
-* 25.OCT.2023(WED)
-*/
-class colouredPenciles {
-    constructor(btnInit, canvasCon, coloursArr, coloursSelect = 1, brushMin = 0.5, brushMax = 10) {
-        this.points = [];
-        this.dopoints = [];
-        this.erase = false;
-        this.uiUpdate = () => {
-            this.btnInit.classList.add('is-active');
-            this.canvasCon.classList.add('is-active');
-            this.ctrlCon = document.createElement('div');
-            this.ctrlCon.classList.add('painterbar');
-            this.canvasCon.append(this.ctrlCon);
-            const minBtn = document.createElement('button');
-            minBtn.type = "button";
-            minBtn.classList.add('btn-painterbar-size');
-            minBtn.textContent = '색연필 최소화';
-            this.ctrlCon.append(minBtn);
-            minBtn.onclick = () => {
-                this.ctrlCon.classList.toggle('min');
-            };
-            const previewCon = document.createElement('div');
-            previewCon.classList.add('pencil-ctrl-options', 'pencil-preview');
-            previewCon.style.width = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            previewCon.style.height = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            this.ctrlCon.append(previewCon);
-            this.previewObj = document.createElement('div');
-            previewCon.append(this.previewObj);
-            const sizeCon = document.createElement('div');
-            sizeCon.classList.add('pencil-ctrl-options', 'painterbar-stroke');
-            this.ctrlCon.append(sizeCon);
-            const range = document.createElement('input');
-            range.type = "range";
-            range.min = this.sizeRange['min'];
-            range.max = this.sizeRange['max'];
-            range.step = "0.1";
-            range.setAttribute("orient", "vertical");
-            range.value = this.size.toString();
-            sizeCon.append(range);
-            range.oninput = () => {
-                this.changeSize(range.value);
-            };
-            const fncCon = document.createElement('div');
-            fncCon.classList.add('pencil-ctrl-options', 'painterbar-fnc');
-            this.ctrlCon.append(fncCon);
-            const undo = document.createElement('button');
-            undo.type = "button";
-            undo.classList.add('undo');
-            undo.textContent = "undo";
-            fncCon.append(undo);
-            undo.addEventListener('click', this.undo);
-            const redo = document.createElement('button');
-            redo.type = "button";
-            redo.classList.add('redo');
-            redo.textContent = "redo";
-            fncCon.append(redo);
-            redo.addEventListener('click', this.redo);
-            this.eraseObj = document.createElement('input');
-            this.eraseObj.type = "checkbox";
-            this.eraseObj.id = "colouredPencils_eraser";
-            this.eraseObj.classList.add('clear');
-            this.eraseObj.checked = this.erase;
-            fncCon.append(this.eraseObj);
-            const eraserLB = document.createElement('label');
-            eraserLB.setAttribute("for", this.eraseObj.id);
-            eraserLB.textContent = "지우개";
-            fncCon.append(eraserLB);
-            this.eraseObj.onchange = () => {
-                this.switchEraser();
-            };
-            const reset = document.createElement('button');
-            reset.type = 'button';
-            reset.classList.add('reset');
-            reset.textContent = 'reset';
-            fncCon.append(reset);
-            reset.onclick = () => this.reset();
-            const colorDiv = document.createElement('div');
-            colorDiv.classList.add('pencil-ctrl-options', 'painterbar-color');
-            colorDiv.setAttribute('data-opt', this.coloursArr[this.coloursSelect]);
-            this.ctrlCon.append(colorDiv);
-            this.coloursArr.forEach((el, i) => {
-                const radio = document.createElement('input');
-                radio.type = "radio";
-                radio.name = "colouredPencils_colour";
-                radio.id = "colouredPencils_colour_" + i;
-                radio.value = i.toString();
-                if (i == this.coloursSelect)
-                    radio.checked = true;
-                colorDiv.append(radio);
-                const label = document.createElement('label');
-                label.setAttribute("for", radio.id);
-                label.textContent = el;
-                label.style.backgroundColor = el;
-                if (el == '#ffffff')
-                    label.classList.add('white');
-                colorDiv.append(label);
-                radio.onchange = (e) => {
-                    this.changeColour(i);
-                };
-            });
-            const close = document.createElement('button');
-            close.type = "button";
-            close.classList.add('btn-viewer-painter-close');
-            close.textContent = "색연필 닫기";
-            this.ctrlCon.append(close);
-            close.onclick = () => {
-                this.clearCanvas();
-            };
-            this.updatePreview();
-        };
-        this.undo = () => {
-            if (this.points.length == 0)
-                return;
-            const arrKeys = this.points.map(el => el["mode"]);
-            const lastIndex = arrKeys.lastIndexOf(false);
-            const tempPoints = this.points.slice(lastIndex, this.points.length - 1);
-            this.dopoints = [...this.dopoints, ...tempPoints];
-            this.points = this.points.slice(0, lastIndex);
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-        };
-        this.redo = () => {
-            if (this.dopoints.length == 0)
-                return;
-            const arrKeys = this.dopoints.map(el => el["mode"]);
-            const lastIndex = arrKeys.lastIndexOf(false);
-            const tempPoints = this.dopoints.slice(lastIndex, this.dopoints.length - 1);
-            this.points = [...this.points, ...tempPoints];
-            this.dopoints = this.dopoints.slice(0, lastIndex);
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-        };
-        this.reset = () => {
-            this.points = [];
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-            if (this.erase) {
-                this.switchEraser();
-            }
-        };
-        this.changeSize = (size) => {
-            this.size = +size;
-            this.updatePreview();
-        };
-        this.changeColour = (key) => {
-            this.coloursSelect = key;
-            if (this.erase)
-                this.switchEraser();
-            this.updatePreview();
-        };
-        this.switchEraser = () => {
-            this.erase = !this.erase;
-            this.eraseObj.checked = this.erase;
-            this.updatePreview();
-            const area = document.querySelector('.paint-target');
-            if (this.erase) {
-                area.classList.add('is-eraser');
-            } else {
-                area.classList.remove('is-eraser');
-            }
-        };
-        this.updatePreview = () => {
-            this.previewObj.style.cssText = `
-            width: ${this.size * 0.1}rem;
-            height: ${this.size * 0.1}rem;
-        `;
-            if (this.coloursArr[this.coloursSelect] == '#ffffff') {
-                this.previewObj.classList.add('white');
-            }
-            else {
-                this.previewObj.classList.remove('white');
-            }
-            if (this.erase) {
-                this.previewObj.classList.add('erase');
-            }
-            else {
-                this.previewObj.classList.remove('erase');
-                this.previewObj.style.backgroundColor = `${this.coloursArr[this.coloursSelect]}`;
-            }
-        };
-        this.clearCanvas = () => {
-            this.ctrlCon.remove();
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.points = [];
-            this.dopoints = [];
-            this.canvasCon.removeChild(this.canvas);
-            this.erase = false;
-            this.btnInit.classList.remove('is-active');
-            this.canvasCon.classList.remove('is-active');
-        };
-        this.createDrawEvents = () => {
-            const canvas = this.canvas;
-            canvas.addEventListener("mousedown", this.pressEventHandler);
-            canvas.addEventListener("mousemove", this.dragEventHandler);
-            canvas.addEventListener("mouseup", this.releaseEventHandler);
-            canvas.addEventListener("mouseout", this.cancelEventHandler);
-            canvas.addEventListener("touchstart", this.pressEventHandler);
-            canvas.addEventListener("touchmove", this.dragEventHandler);
-            canvas.addEventListener("touchend", this.releaseEventHandler);
-            canvas.addEventListener("touchcancel", this.cancelEventHandler);
-        };
-        this.redraw = () => {
-            const points = this.points;
-            if (points.length == 0)
-                return;
-            const context = this.context;
-            context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            for (let i = 0; i < points.length; ++i) {
-                if (points[i]["erase"]) {
-                    context.globalCompositeOperation = "destination-out";
-                }
-                else {
-                    context.globalCompositeOperation = "source-over";
-                }
-                context.beginPath();
-                if (points[i]["mode"] && i) {
-                    context.moveTo(points[i - 1]["x"], points[i - 1]["y"]);
-                }
-                else {
-                    context.moveTo(points[i]["x"] - 1, points[i]["y"]);
-                }
-                context.lineTo(points[i]["x"], points[i]["y"]);
-                context.strokeStyle = points[i]["color"];
-                context.lineWidth = points[i]["size"];
-                context.stroke();
-            }
-            context.closePath();
-        };
-        this.addClick = (x, y, color, size, dragging, erase) => {
-            this.points.push({ x: x, y: y, color: color, size: size, mode: dragging, erase: erase });
-        };
-        this.releaseEventHandler = () => {
-            if (this.paint) {
-                this.paint = false;
-                this.redraw();
-            }
-        };
-        this.cancelEventHandler = () => {
-            this.releaseEventHandler();
-        };
-        this.pressEventHandler = (e) => {
-            this.dopoints = [];
-            let mouseX = e.changedTouches ?
-                e.changedTouches[0].pageX :
-                e.pageX;
-            let mouseY = e.changedTouches ?
-                e.changedTouches[0].pageY :
-                e.pageY;
-            mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-            mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-            this.paint = true;
-            this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, false, this.erase);
-            this.redraw();
-        };
-        this.dragEventHandler = (e) => {
-            let mouseX = e.changedTouches ?
-                e.changedTouches[0].pageX :
-                e.pageX;
-            let mouseY = e.changedTouches ?
-                e.changedTouches[0].pageY :
-                e.pageY;
-            mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-            mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-            if (this.paint) {
-                this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, true, this.erase);
-                this.redraw();
-            }
-            e.preventDefault();
-        };
-        this.btnInit = btnInit;
-        this.canvasCon = canvasCon;
-        this.coloursArr = coloursArr.map(c => c.toLowerCase());
-        this.coloursSelect = coloursSelect - 1;
-        brushMax = brushMax > 60 ? 60 : brushMax;
-        this.sizeRange = {
-            min: brushMin,
-            max: brushMax
-        };
-        this.size = Math.round((brushMin + brushMax) / 2);
-        this.btnInit.onclick = () => {
-            if (this.btnInit.classList.contains('is-active')) {
-                this.clearCanvas();
-            }
-            else {
-                const canvas = document.createElement('canvas');
-                canvas.width = this.canvasCon.offsetWidth;
-                canvas.height = this.canvasCon.clientHeight;
-                const context = canvas.getContext("2d");
-                context.lineCap = 'round';
-                context.lineJoin = 'round';
-                this.canvas = canvas;
-                this.canvas.id = 'painterCanvas';
-                this.context = context;
-                this.canvasCon.append(this.canvas);
-                this.uiUpdate();
-                this.redraw();
-                this.createDrawEvents();
-            }
-        };
-    }
-}
-// 환경설정
-const colorArray = ["#222222", "#fd4418", "#ffce00", "#00d56a", "#2f77ff", "#ffffff"];
-const defaultColor = 5;
-const brushMin = 0.5, brushMax = 40;
-// 대상 개체
-const btnInit = document.querySelector('.btn-painter-toggle');
-const targetObj = document.querySelector('.paint-target');
-// 구동 defaultColor, brushMin, brushMax 은 넘기지 않아도 기본 값에 의해 작동됨
-new colouredPenciles(btnInit, targetObj, colorArray, defaultColor, brushMin, brushMax);
-// new colouredPenciles(btnInit, targetObj, colorArray);
 
resources/front/site/SITE_00000/js/common/module/datePicker.js (deleted)
--- resources/front/site/SITE_00000/js/common/module/datePicker.js
@@ -1,204 +0,0 @@
-/**************************** 
- * datePicker.js
- * create
- * 2023.08.08
- * son tae-jin
-****************************/
-
-const dayArr = [
-    "일", "월", "화", "수", "목", "금", "토"
-];
-const month = [
-    "January",
-    "February",
-    "March",
-    "April",
-    "May",
-    "June",
-    "July",
-    "August",
-    "September",
-    "October",
-    "November",
-    "December"
-];
-
-const isValidDate = d => {
-    return d instanceof Date && !isNaN(d);
-}
-
-const detectOutsideClick = (caller, container, handler) => {
-    const clickOb = () => {
-        if(!container.contains(event.target) && caller != event.target) {
-            container.remove();
-            window.removeEventListener('click', clickOb, false);
-            handler();
-        }
-    }
-    window.addEventListener('click',clickOb, false);
-}
-
-const datePicker = (event) => {
-    if(event.target.dataset.picker) return;
-    const element = event.target;
-    element.dataset.picker = true;
-    const container = document.createElement('div');
-    container.classList.add('datepicker');
-    element.parentElement.append(container);
-    container.style.top = element.offsetTop + element.offsetHeight + 'px';
-    container.style.left = element.offsetLeft + 'px';
-    detectOutsideClick(element, container, () => {element.removeAttribute('data-picker')});
-
-    const dateObj = new Object();
-    const datePropertys = ['type', 'value', 'min', 'max', 'step'];
-    datePropertys.forEach(el => {
-        if(element[el]) dateObj[el] = element[el];
-    });
-
-    initDataPicker(container, dateObj);
-}
-
-const initDataPicker = (container,property) => {
-    console.log(container, property);
-
-    switch(property.type) {
-        default:
-            initCalendar(container, property);
-        break;
-        case "month":
-            initMonth(container, property);
-            break;
-    }
-}
-
-const generateCalendar = (container, property, date) => {
-    const ul = container.querySelector('.calendar-con') ? container.querySelector('.calendar-con') : document.createElement('ul');
-    if(ul.classList.contains('calendar-con')) {
-        ul.innerHTML = '';
-    } else {
-        ul.classList.add('calendar-con');
-        container.append(ul);
-    }
-
-    const today = new Date();
-    const ny = today.getFullYear(), nm = today.getMonth(), nd = today.getDate();
-    const cYear = date.getFullYear();
-    const cMonth = date.getMonth();
-    const lastDate = new Date(cYear, cMonth + 1, 0).getDate();
-    const startDay = new Date(cYear, cMonth, 1).getDay();
-    const beforeLastDate = new Date(cYear, cMonth, 0).getDate();
-
-    const selectedDate = property.value ? new Date(property.value) : null;
-    const selectedDateStr = selectedDate ? `${selectedDate.getFullYear()}-${selectedDate.getMonth().toString().padStart(2, '0')}-${selectedDate.getDate().toString().padStart(2, '0')}` : '';
-
-    const genDateLi = (date) => {
-        const li = document.createElement('li');
-        const dateNm = document.createElement('button');
-        dateNm.type = "button";
-        dateNm.textContent = new Date(date).getDate();
-        li.appendChild(dateNm);
-        dateNm.dataset.date = `${date.getFullYear()}-${date.getMonth().toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
-        return li;
-    }
-    // 이전달 날짜
-    for (let k = 0; k < startDay; k++) {
-        const date = new Date(cYear, cMonth-1, beforeLastDate - startDay + 1 + k);
-        const li = genDateLi(date);
-        ul.appendChild(li);
-        li.classList.add('before');
-    }
-    // 이번달 날짜 표시
-    for (let i = 0; i < lastDate; i++) {
-        const date = new Date(cYear, cMonth, i+1);
-        const li = genDateLi(date);
-        ul.appendChild(li);
-        if (selectedDate && selectedDateStr == li.querySelector('button').dataset.date) {
-            li.classList.add('selected');
-        } else if(!selectedDate) {
-            if (ny == cYear && nm == cMonth && nd == i + 1) {
-                li.classList.add('today');
-            } else if (nd == i + 1) {
-                li.classList.add('sameday');
-            }
-        }
-    }
-    // 다음달 날짜 표시
-    const leftAfterDates = 42 - ul.querySelectorAll('li').length;
-    for (let j = 0; j < leftAfterDates; j++){
-        const date = new Date(cYear, cMonth + 1, j+1);
-        const li = genDateLi(date);
-        ul.appendChild(li);
-        li.classList.add('after');
-    }
-
-    return ul;
-}
-
-const initCalendar = (container, property) => {
-    const valueDate = isValidDate(new Date(property.value)) ? new Date(property.value) : new Date();
-    const ymNavCon = document.createElement('div');
-    ymNavCon.classList.add('ym-nav-con');
-    container.append(ymNavCon);
-
-    const ymSelector = document.createElement('input');
-    ymSelector.type = 'month';
-    ymSelector.value = `${valueDate.getFullYear()}-${(valueDate.getMonth()+1).toString().padStart(2, '0')}`;
-    ymSelector.classList.add('custom-datepicker');
-    ymSelector.onchange = event => {
-        console.log('onchange', event.target);
-        generateCalendar(container, property, new Date(ymSelector.value));
-    }
-    ymSelector.onclick = event => datePicker(event);
-    ymNavCon.append(ymSelector);
-
-    const ymPrev = document.createElement('button');
-    ymPrev.type = "button";
-    ymPrev.textContent = "이전";
-    ymPrev.classList.add('btn','prev', 'ico-pv', 'icon-only');
-    ymNavCon.prepend(ymPrev);
-    ymPrev.onclick = () => ymNav();
-
-    const ymNext = document.createElement('button');
-    ymNext.type = "button";
-    ymNext.textContent = "다음";
-    ymNext.classList.add('btn','next', 'ico-fw', 'icon-only');
-    ymNavCon.append(ymNext);
-    ymNext.onclick = () => ymNav();
-
-    const ul = generateCalendar(container, property, new Date(ymSelector.value));
-}
-
-const ymNav = () => {
-    const ymInput = event.target.parentElement.querySelector('input');
-    const now = new Date(ymInput.value);
-    if(event.target.classList.contains('prev')) {
-        now.setMonth(now.getMonth() - 1);
-    } else {
-        now.setMonth(now.getMonth() + 1);
-    }
-    ymInput.value = `${now.getFullYear()}-${(now.getMonth()+1).toString().padStart(2, '0')}`;
-    ymInput.dispatchEvent(new Event('change'));
-}
-
-const initMonth = (container, property) => {
-    console.log(container, property);
-}
-
-document.querySelectorAll('input[type=date], input[type=time], input[type=month], input[type=week], input[type=datetime-local]').forEach(el => {
-    el.onchange = () => {
-        if(el.value == '') {
-            el.removeAttribute('value');
-        } else {
-            el.setAttribute('value',el.value);
-        }
-    }
-});
-document.querySelectorAll('input.custom-datepicker').forEach(el => {
-    el.onclick = (event) => {
-        datePicker(event);
-    }
-});
-
-// document.querySelectorAll('.custom-datepicker:not(input)').forEach(el => {
-//     initDataPicker(el);
-// })(파일 끝에 줄바꿈 문자 없음)
 
resources/front/site/SITE_00000/js/custom/module/colouredPenciles.js (deleted)
--- resources/front/site/SITE_00000/js/custom/module/colouredPenciles.js
@@ -1,314 +0,0 @@
-/*
-* Copyright (c) FOX EDU CO., LTD ALL RIGHT RESERVED.
-* by flashkid
-* 25.OCT.2023(WED)
-*/
-class colouredPenciles {
-    constructor(btnInit, canvasCon, coloursArr, coloursSelect = 1, brushMin = 0.5, brushMax = 10) {
-        this.points = [];
-        this.dopoints = [];
-        this.erase = false;
-        this.uiUpdate = () => {
-            this.btnInit.classList.add('is-active');
-            this.canvasCon.classList.add('is-active');
-            this.ctrlCon = document.createElement('div');
-            this.ctrlCon.classList.add('painterbar');
-            this.canvasCon.append(this.ctrlCon);
-            const minBtn = document.createElement('button');
-            minBtn.type = "button";
-            minBtn.classList.add('btn-painterbar-size');
-            minBtn.textContent = '색연필 최소화';
-            this.ctrlCon.append(minBtn);
-            minBtn.onclick = () => {
-                this.ctrlCon.classList.toggle('min');
-            };
-            const previewCon = document.createElement('div');
-            previewCon.classList.add('pencil-ctrl-options', 'pencil-preview');
-            previewCon.style.width = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            previewCon.style.height = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            this.ctrlCon.append(previewCon);
-            this.previewObj = document.createElement('div');
-            previewCon.append(this.previewObj);
-            const sizeCon = document.createElement('div');
-            sizeCon.classList.add('pencil-ctrl-options', 'painterbar-stroke');
-            this.ctrlCon.append(sizeCon);
-            const range = document.createElement('input');
-            range.type = "range";
-            range.min = this.sizeRange['min'];
-            range.max = this.sizeRange['max'];
-            range.step = "0.1";
-            range.setAttribute("orient", "vertical");
-            range.value = this.size.toString();
-            sizeCon.append(range);
-            range.oninput = () => {
-                this.changeSize(range.value);
-            };
-            const fncCon = document.createElement('div');
-            fncCon.classList.add('pencil-ctrl-options', 'painterbar-fnc');
-            this.ctrlCon.append(fncCon);
-            const undo = document.createElement('button');
-            undo.type = "button";
-            undo.classList.add('undo');
-            undo.textContent = "undo";
-            fncCon.append(undo);
-            undo.addEventListener('click', this.undo);
-            const redo = document.createElement('button');
-            redo.type = "button";
-            redo.classList.add('redo');
-            redo.textContent = "redo";
-            fncCon.append(redo);
-            redo.addEventListener('click', this.redo);
-            this.eraseObj = document.createElement('input');
-            this.eraseObj.type = "checkbox";
-            this.eraseObj.id = "colouredPencils_eraser";
-            this.eraseObj.classList.add('clear');
-            this.eraseObj.checked = this.erase;
-            fncCon.append(this.eraseObj);
-            const eraserLB = document.createElement('label');
-            eraserLB.setAttribute("for", this.eraseObj.id);
-            eraserLB.textContent = "지우개";
-            fncCon.append(eraserLB);
-            this.eraseObj.onchange = () => {
-                this.switchEraser();
-            };
-            const reset = document.createElement('button');
-            reset.type = 'button';
-            reset.classList.add('reset');
-            reset.textContent = 'reset';
-            fncCon.append(reset);
-            reset.onclick = () => this.reset();
-            const colorDiv = document.createElement('div');
-            colorDiv.classList.add('pencil-ctrl-options', 'painterbar-color');
-            colorDiv.setAttribute('data-opt', this.coloursArr[this.coloursSelect]);
-            this.ctrlCon.append(colorDiv);
-            this.coloursArr.forEach((el, i) => {
-                const radio = document.createElement('input');
-                radio.type = "radio";
-                radio.name = "colouredPencils_colour";
-                radio.id = "colouredPencils_colour_" + i;
-                radio.value = i.toString();
-                if (i == this.coloursSelect)
-                    radio.checked = true;
-                colorDiv.append(radio);
-                const label = document.createElement('label');
-                label.setAttribute("for", radio.id);
-                label.textContent = el;
-                label.style.backgroundColor = el;
-                if (el == '#ffffff')
-                    label.classList.add('white');
-                colorDiv.append(label);
-                radio.onchange = (e) => {
-                    this.changeColour(i);
-                };
-            });
-            const close = document.createElement('button');
-            close.type = "button";
-            close.classList.add('btn-viewer-painter-close');
-            close.textContent = "색연필 닫기";
-            this.ctrlCon.append(close);
-            close.onclick = () => {
-                this.clearCanvas();
-            };
-            this.updatePreview();
-        };
-        this.undo = () => {
-            if (this.points.length == 0)
-                return;
-            const arrKeys = this.points.map(el => el["mode"]);
-            const lastIndex = arrKeys.lastIndexOf(false);
-            const tempPoints = this.points.slice(lastIndex, this.points.length - 1);
-            this.dopoints = [...this.dopoints, ...tempPoints];
-            this.points = this.points.slice(0, lastIndex);
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-        };
-        this.redo = () => {
-            if (this.dopoints.length == 0)
-                return;
-            const arrKeys = this.dopoints.map(el => el["mode"]);
-            const lastIndex = arrKeys.lastIndexOf(false);
-            const tempPoints = this.dopoints.slice(lastIndex, this.dopoints.length - 1);
-            this.points = [...this.points, ...tempPoints];
-            this.dopoints = this.dopoints.slice(0, lastIndex);
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-        };
-        this.reset = () => {
-            this.points = [];
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.redraw();
-            if (this.erase) {
-                this.switchEraser();
-            }
-        };
-        this.changeSize = (size) => {
-            this.size = +size;
-            this.updatePreview();
-        };
-        this.changeColour = (key) => {
-            this.coloursSelect = key;
-            if (this.erase)
-                this.switchEraser();
-            this.updatePreview();
-        };
-        this.switchEraser = () => {
-            this.erase = !this.erase;
-            this.eraseObj.checked = this.erase;
-            this.updatePreview();
-            const area = document.querySelector('.paint-target');
-            if (this.erase) {
-                area.classList.add('is-eraser');
-            } else {
-                area.classList.remove('is-eraser');
-            }
-        };
-        this.updatePreview = () => {
-            this.previewObj.style.cssText = `
-            width: ${this.size * 0.1}rem;
-            height: ${this.size * 0.1}rem;
-        `;
-            if (this.coloursArr[this.coloursSelect] == '#ffffff') {
-                this.previewObj.classList.add('white');
-            }
-            else {
-                this.previewObj.classList.remove('white');
-            }
-            if (this.erase) {
-                this.previewObj.classList.add('erase');
-            }
-            else {
-                this.previewObj.classList.remove('erase');
-                this.previewObj.style.backgroundColor = `${this.coloursArr[this.coloursSelect]}`;
-            }
-        };
-        this.clearCanvas = () => {
-            this.ctrlCon.remove();
-            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            this.points = [];
-            this.dopoints = [];
-            this.canvasCon.removeChild(this.canvas);
-            this.erase = false;
-            this.btnInit.classList.remove('is-active');
-            this.canvasCon.classList.remove('is-active');
-        };
-        this.createDrawEvents = () => {
-            const canvas = this.canvas;
-            canvas.addEventListener("mousedown", this.pressEventHandler);
-            canvas.addEventListener("mousemove", this.dragEventHandler);
-            canvas.addEventListener("mouseup", this.releaseEventHandler);
-            canvas.addEventListener("mouseout", this.cancelEventHandler);
-            canvas.addEventListener("touchstart", this.pressEventHandler);
-            canvas.addEventListener("touchmove", this.dragEventHandler);
-            canvas.addEventListener("touchend", this.releaseEventHandler);
-            canvas.addEventListener("touchcancel", this.cancelEventHandler);
-        };
-        this.redraw = () => {
-            const points = this.points;
-            if (points.length == 0)
-                return;
-            const context = this.context;
-            context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-            for (let i = 0; i < points.length; ++i) {
-                if (points[i]["erase"]) {
-                    context.globalCompositeOperation = "destination-out";
-                }
-                else {
-                    context.globalCompositeOperation = "source-over";
-                }
-                context.beginPath();
-                if (points[i]["mode"] && i) {
-                    context.moveTo(points[i - 1]["x"], points[i - 1]["y"]);
-                }
-                else {
-                    context.moveTo(points[i]["x"] - 1, points[i]["y"]);
-                }
-                context.lineTo(points[i]["x"], points[i]["y"]);
-                context.strokeStyle = points[i]["color"];
-                context.lineWidth = points[i]["size"];
-                context.stroke();
-            }
-            context.closePath();
-        };
-        this.addClick = (x, y, color, size, dragging, erase) => {
-            this.points.push({ x: x, y: y, color: color, size: size, mode: dragging, erase: erase });
-        };
-        this.releaseEventHandler = () => {
-            if (this.paint) {
-                this.paint = false;
-                this.redraw();
-            }
-        };
-        this.cancelEventHandler = () => {
-            this.releaseEventHandler();
-        };
-        this.pressEventHandler = (e) => {
-            this.dopoints = [];
-            let mouseX = e.changedTouches ?
-                e.changedTouches[0].pageX :
-                e.pageX;
-            let mouseY = e.changedTouches ?
-                e.changedTouches[0].pageY :
-                e.pageY;
-            mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-            mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-            this.paint = true;
-            this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, false, this.erase);
-            this.redraw();
-        };
-        this.dragEventHandler = (e) => {
-            let mouseX = e.changedTouches ?
-                e.changedTouches[0].pageX :
-                e.pageX;
-            let mouseY = e.changedTouches ?
-                e.changedTouches[0].pageY :
-                e.pageY;
-            mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-            mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-            if (this.paint) {
-                this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, true, this.erase);
-                this.redraw();
-            }
-            e.preventDefault();
-        };
-        this.btnInit = btnInit;
-        this.canvasCon = canvasCon;
-        this.coloursArr = coloursArr.map(c => c.toLowerCase());
-        this.coloursSelect = coloursSelect - 1;
-        brushMax = brushMax > 60 ? 60 : brushMax;
-        this.sizeRange = {
-            min: brushMin,
-            max: brushMax
-        };
-        this.size = Math.round((brushMin + brushMax) / 2);
-        this.btnInit.onclick = () => {
-            if (this.btnInit.classList.contains('is-active')) {
-                this.clearCanvas();
-            }
-            else {
-                const canvas = document.createElement('canvas');
-                canvas.width = this.canvasCon.offsetWidth;
-                canvas.height = this.canvasCon.clientHeight;
-                const context = canvas.getContext("2d");
-                context.lineCap = 'round';
-                context.lineJoin = 'round';
-                this.canvas = canvas;
-                this.canvas.id = 'painterCanvas';
-                this.context = context;
-                this.canvasCon.append(this.canvas);
-                this.uiUpdate();
-                this.redraw();
-                this.createDrawEvents();
-            }
-        };
-    }
-}
-// 환경설정
-const colorArray = ["#222222", "#fd4418", "#ffce00", "#00d56a", "#2f77ff", "#ffffff"];
-const defaultColor = 5;
-const brushMin = 0.5, brushMax = 40;
-// 대상 개체
-const btnInit = document.querySelector('.btn-painter-toggle');
-const targetObj = document.querySelector('.paint-target');
-// 구동 defaultColor, brushMin, brushMax 은 넘기지 않아도 기본 값에 의해 작동됨
-new colouredPenciles(btnInit, targetObj, colorArray, defaultColor, brushMin, brushMax);
-// new colouredPenciles(btnInit, targetObj, colorArray);
 
resources/front/site/SITE_00000/js/custom/module/colouredPenciles.ts (deleted)
--- resources/front/site/SITE_00000/js/custom/module/colouredPenciles.ts
@@ -1,357 +0,0 @@
-/*
-* Copyright (c) FOX EDU CO., LTD ALL RIGHT RESERVED.
-* by flashkid
-* 25.OCT.2023(WED)
-*/
-
-class colouredPenciles {
-    private btnInit: HTMLElement;
-    private ctrlCon: HTMLElement;
-    private canvasCon: HTMLElement;
-
-    private canvas: HTMLCanvasElement;
-    private context: CanvasRenderingContext2D;
-    private eraseObj: HTMLInputElement;
-    private previewObj: HTMLElement;
-
-    private paint: boolean;
-
-    private points: object[] = [];
-    private dopoints: object[] = [];
-
-    private coloursArr: any;
-    private coloursSelect: number;
-    private sizeRange: object;
-    private size: number;
-    private erase: boolean = false;
-
-    constructor(btnInit, canvasCon, coloursArr, coloursSelect = 1, brushMin = 0.5, brushMax = 10) {
-        this.btnInit = btnInit;
-        this.canvasCon = canvasCon;
-        this.coloursArr = coloursArr.map(c => c.toLowerCase());
-        this.coloursSelect = coloursSelect - 1;
-        brushMax = brushMax > 60 ? 60 : brushMax;
-        this.sizeRange = {
-            min: brushMin,
-            max: brushMax
-        }
-        this.size = Math.round((brushMin + brushMax) / 2);
-        
-        this.btnInit.onclick = () => {
-            if(this.btnInit.classList.contains('is-active')) {
-                this.clearCanvas();
-            } else {
-                const canvas = document.createElement('canvas') as HTMLCanvasElement;
-                canvas.width = this.canvasCon.offsetWidth;
-                canvas.height = this.canvasCon.clientHeight;
-                const context = canvas.getContext("2d");
-                context.lineCap = 'round';
-                context.lineJoin = 'round';
-        
-                this.canvas = canvas;
-                this.canvas.id = 'painterCanvas';
-                this.context = context;
-                this.canvasCon.append(this.canvas);
-
-                this.uiUpdate();
-        
-                this.redraw();
-                this.createDrawEvents();
-            }
-        }
-    }
-
-    private uiUpdate = () => {
-        this.btnInit.classList.add('is-active');
-        this.canvasCon.classList.add('is-active');
-
-        this.ctrlCon = document.createElement('div');
-        this.ctrlCon.classList.add('painterbar');
-        this.canvasCon.append(this.ctrlCon);
-
-        const minBtn = document.createElement('button');
-        minBtn.type = "button";
-        minBtn.classList.add('btn-painterbar-size');
-        minBtn.textContent = '색연필 최소화';
-        this.ctrlCon.append(minBtn);
-        minBtn.onclick = () => {
-            this.ctrlCon.classList.toggle('min');
-        }
-
-        const previewCon = document.createElement('div');
-        previewCon.classList.add('pencil-ctrl-options', 'pencil-preview');
-        previewCon.style.width = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-        previewCon.style.height = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-        this.ctrlCon.append(previewCon);
-        this.previewObj = document.createElement('div');
-        previewCon.append(this.previewObj);
-
-        const sizeCon = document.createElement('div');
-        sizeCon.classList.add('pencil-ctrl-options', 'painterbar-stroke');
-        this.ctrlCon.append(sizeCon);
-
-        const range = document.createElement('input');
-        range.type = "range";
-        range.min = this.sizeRange['min'];
-        range.max = this.sizeRange['max'];
-        range.step = "0.1";
-        range.setAttribute("orient", "vertical");
-        range.value = this.size.toString();
-        sizeCon.append(range);
-        range.oninput = () => {
-            this.changeSize(range.value);
-        }
-
-        const fncCon = document.createElement('div');
-        fncCon.classList.add('pencil-ctrl-options', 'painterbar-fnc');
-        this.ctrlCon.append(fncCon);
-
-        const undo = document.createElement('button');
-        undo.type = "button";
-        undo.classList.add('undo');
-        undo.textContent = "undo";
-        fncCon.append(undo);
-        undo.addEventListener('click', this.undo);
-
-        const redo = document.createElement('button');
-        redo.type = "button";
-        redo.classList.add('redo');
-        redo.textContent = "redo";
-        fncCon.append(redo);
-        redo.addEventListener('click', this.redo);
-
-        this.eraseObj = document.createElement('input');
-        this.eraseObj.type = "checkbox";
-        this.eraseObj.id = "colouredPencils_eraser";
-        this.eraseObj.classList.add('clear');
-        this.eraseObj.checked = this.erase;
-        fncCon.append(this.eraseObj);
-        const eraserLB = document.createElement('label');
-        eraserLB.setAttribute("for", this.eraseObj.id);
-        eraserLB.textContent = "지우개";
-        fncCon.append(eraserLB);
-        this.eraseObj.onchange = () => {
-            this.switchEraser();
-        }
-
-        const reset = document.createElement('button');
-        reset.type = 'button';
-        reset.classList.add('reset');
-        reset.textContent = 'reset';
-        fncCon.append(reset);
-        reset.onclick = () => this.reset();
-
-        const colorDiv = document.createElement('div');
-        colorDiv.classList.add('pencil-ctrl-options', 'painterbar-color');
-        colorDiv.setAttribute('data-opt', this.coloursArr[this.coloursSelect]);
-        this.ctrlCon.append(colorDiv);
-        this.coloursArr.forEach ((el, i) => {
-            const radio = document.createElement('input');
-            radio.type = "radio";
-            radio.name = "colouredPencils_colour";
-            radio.id = "colouredPencils_colour_" + i;
-            radio.value = i.toString();
-            if (i == this.coloursSelect) radio.checked = true;
-            colorDiv.append(radio);
-            const label = document.createElement('label');
-            label.setAttribute("for", radio.id);
-            label.textContent = el;
-            label.style.backgroundColor = el;
-            if(el == '#ffffff') label.classList.add('white');
-            colorDiv.append(label);
-            radio.onchange = (e:Event) => {
-                this.changeColour(i);
-            }
-        });
-
-        const close = document.createElement('button');
-        close.type = "button";
-        close.classList.add('btn-viewer-painter-close');
-        close.textContent = "색연필 닫기";
-        this.ctrlCon.append(close);
-        close.onclick = () => {
-            this.clearCanvas();
-        }
-
-        this.updatePreview();
-    }
-
-    private undo = () => {
-        if (this.points.length == 0) return;
-        const arrKeys = this.points.map(el => el["mode"]);
-        const lastIndex = arrKeys.lastIndexOf(false);
-        const tempPoints = this.points.slice(lastIndex, this.points.length - 1);
-        this.dopoints = [...this.dopoints, ...tempPoints];
-        this.points = this.points.slice(0, lastIndex);
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.redraw();
-    }
-
-    private redo = () => {
-        if (this.dopoints.length == 0) return;
-        const arrKeys = this.dopoints.map(el => el["mode"]);
-        const lastIndex = arrKeys.lastIndexOf(false);
-        const tempPoints = this.dopoints.slice(lastIndex, this.dopoints.length - 1);
-        this.points = [...this.points, ...tempPoints];
-        this.dopoints = this.dopoints.slice(0, lastIndex);
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.redraw();
-    }
-
-    private reset = () => {
-        this.points = [];
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.redraw();
-        if(this.erase) {
-            this.switchEraser();
-        }
-    }
-
-    private changeSize = (size) => {
-        this.size = +size;
-        this.updatePreview();
-    }
-
-    private changeColour = (key) => {
-        this.coloursSelect = key;
-        if(this.erase) this.switchEraser();
-        this.updatePreview();
-    }
-
-    private switchEraser = () => {
-        this.erase = !this.erase;
-        this.eraseObj.checked = this.erase;
-        this.updatePreview();
-    }
-
-    private updatePreview = () => {
-        this.previewObj.style.cssText = `
-            width: ${this.size * 0.1}rem;
-            height: ${this.size * 0.1}rem;
-        `
-        if (this.coloursArr[this.coloursSelect] == '#ffffff') {
-            this.previewObj.classList.add('white');
-        } else {
-            this.previewObj.classList.remove('white');
-        }
-
-        if (this.erase) {
-            this.previewObj.classList.add('erase');
-        } else {
-            this.previewObj.classList.remove('erase');
-            this.previewObj.style.backgroundColor = `${this.coloursArr[this.coloursSelect]}`;
-        }
-    }
-
-    private clearCanvas = () => {
-        this.ctrlCon.remove();
-        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        this.points = [];
-        this.dopoints = [];
-        this.canvasCon.removeChild(this.canvas);
-        this.erase = false;
-
-        this.btnInit.classList.remove('is-active');
-        this.canvasCon.classList.remove('is-active');
-    }
-
-    private createDrawEvents = () => {
-        const canvas = this.canvas;
-
-        canvas.addEventListener("mousedown", this.pressEventHandler);
-        canvas.addEventListener("mousemove", this.dragEventHandler);
-        canvas.addEventListener("mouseup", this.releaseEventHandler);
-        canvas.addEventListener("mouseout", this.cancelEventHandler);
-
-        canvas.addEventListener("touchstart", this.pressEventHandler);
-        canvas.addEventListener("touchmove", this.dragEventHandler);
-        canvas.addEventListener("touchend", this.releaseEventHandler);
-        canvas.addEventListener("touchcancel", this.cancelEventHandler);
-    }
-
-    private redraw = () => {
-        const points = this.points;
-        if (points.length == 0) return;
-        const context = this.context;
-        context.clearRect(0, 0, this.canvas.width, this.canvas.height);
-        for (let i = 0; i < points.length; ++i) {
-            if (points[i]["erase"]) {
-                context.globalCompositeOperation = "destination-out";
-            } else {
-                context.globalCompositeOperation = "source-over";
-            }
-            context.beginPath();
-            if (points[i]["mode"] && i) {
-                context.moveTo(points[i - 1]["x"], points[i - 1]["y"]);
-            } else {
-                context.moveTo(points[i]["x"] - 1, points[i]["y"]);
-            }
-
-            context.lineTo(points[i]["x"], points[i]["y"]);
-            context.strokeStyle = points[i]["color"];
-            context.lineWidth = points[i]["size"];
-            context.stroke();
-        }
-        context.closePath();
-    }
-
-    private addClick = (x: number, y: number, color: string, size: number, dragging: boolean, erase: boolean) => {
-        this.points.push({ x: x, y: y, color: color, size: size, mode: dragging, erase: erase })
-    }
-
-    private releaseEventHandler = () => {
-        if (this.paint) {
-            this.paint = false;
-            this.redraw();
-        }
-    }
-
-    private cancelEventHandler = () => {
-        this.releaseEventHandler();
-    }
-
-    private pressEventHandler = (e: MouseEvent | TouchEvent) => {
-        this.dopoints = [];
-        let mouseX = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageX :
-            (e as MouseEvent).pageX;
-        let mouseY = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageY :
-            (e as MouseEvent).pageY;
-        mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-        mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-
-        this.paint = true;
-        this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, false, this.erase);
-        this.redraw();
-    }
-
-    private dragEventHandler = (e: MouseEvent | TouchEvent) => {
-        let mouseX = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageX :
-            (e as MouseEvent).pageX;
-        let mouseY = (e as TouchEvent).changedTouches ?
-            (e as TouchEvent).changedTouches[0].pageY :
-            (e as MouseEvent).pageY;
-        mouseX -= (this.canvasCon.getBoundingClientRect().left + window.pageXOffset);
-        mouseY -= (this.canvasCon.getBoundingClientRect().top + window.pageYOffset);
-
-        if (this.paint) {
-            this.addClick(mouseX, mouseY, this.coloursArr[this.coloursSelect], this.size, true, this.erase);
-            this.redraw();
-        }
-
-        e.preventDefault();
-    }
-}
-
-// 환경설정
-const colorArray = ["#222222","#fd4418","#ffce00","#00d56a","#2f77ff","#ffffff"];
-const defaultColor = 5;
-const brushMin = 0.5, brushMax = 40;
-// 대상 개체
-const btnInit = document.querySelector('.btn-painter-toggle') as HTMLElement;
-const targetObj = document.querySelector('.paint-target') as HTMLElement;
-// 구동 defaultColor, brushMin, brushMax 은 넘기지 않아도 기본 값에 의해 작동됨
-new colouredPenciles(btnInit, targetObj, colorArray, defaultColor, brushMin, brushMax);
-// new colouredPenciles(btnInit, targetObj, colorArray);
 
resources/front/site/SITE_00000/js/custom/module/colouredPencilesSvg.js (deleted)
--- resources/front/site/SITE_00000/js/custom/module/colouredPencilesSvg.js
@@ -1,863 +0,0 @@
-/*
-* Copyright (c) FOX EDU CO., LTD ALL RIGHT RESERVED.
-* by flashkid
-* 25.SEP.2024(WED)
-*/
-export class colouredPenciles {
-    constructor(btnInit, objArr, coloursArr, coloursSelect = 1, brushMin = 0.5, brushMax = 10, saveDataURL = '', loadDataURL = '', deleteDataURL = '', dataParam = {}) {
-        var _a;
-        this.svgNS = "http://www.w3.org/2000/svg";
-        this.ctrlCon = null;
-        this.targetCon = null;
-        this.targetArr = [];
-        this.ifrObj = null;
-        this.ifrDoc = null;
-        this.ifrContents = null;
-        this.ifrContentsType = "etc";
-        this.svg = null;
-        this.eraseObj = null;
-        this.previewObj = null;
-        this.loadedDrawingData = false;
-        this.drawingGroup = null;
-        this.maskingGroup = null;
-        this.drawPathElement = null;
-        this.eraserPathElement = null;
-        this.undoStack = [];
-        this.redoStack = [];
-        this.currentPath = [];
-        this.drawing = false;
-        this.isErasing = false;
-        this.detectTargetObj = () => {
-            let tobj, i = 0;
-            while (!tobj && i <= this.targetArr.length) {
-                tobj = document.querySelector(`.${this.targetArr[i]}`);
-                i++;
-            }
-            if (tobj) {
-                this.targetCon = tobj;
-                this.targetCon.classList.add('painter-target');
-            }
-        };
-        // Function to handle the scroll event
-        this.onScroll = () => {
-            var _a;
-            if (['img', 'iframe', 'etc', 'unknown'].includes(this.ifrContentsType) && ((_a = this.ifrObj) === null || _a === void 0 ? void 0 : _a.contentWindow) && this.targetCon) {
-                this.ifrObj.contentWindow.scrollTo(this.targetCon.scrollLeft, this.targetCon.scrollTop);
-            }
-            else if (this.ifrContents && this.targetCon) {
-                this.ifrContents.scrollTo(this.targetCon.scrollLeft, this.targetCon.scrollTop);
-            }
-        };
-        // 아이프레임 온로드
-        this.onIfrLoad = () => {
-            var _a, _b, _c;
-            if (this.btnInit.classList.contains('is-active')) {
-                this.closeDrawing();
-                this.onResize();
-            }
-            const ifrDoc = ((_b = (_a = this.ifrObj) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.document) || ((_c = this.ifrObj) === null || _c === void 0 ? void 0 : _c.contentDocument);
-            if (!ifrDoc)
-                return;
-            this.ifrDoc = ifrDoc;
-            // ifrContents 선언
-            this.ifrContents = this.ifrDoc.querySelector('#contents2') || this.ifrDoc.querySelector('.viewer .viewer-body .viewer-cont .quiz-viewer .quiz-viewer-body') || null;
-            if (this.ifrContents.classList.contains('quiz-viewer-body')) {
-                this.ifrContentsType = 'quiz';
-                this.setBaseSize({
-                    w: this.ifrContents.querySelector('.quiz-viewer-cont').clientWidth,
-                    h: this.ifrContents.scrollHeight
-                });
-                this.setBaseSize({
-                    x: -this.ifrContents.querySelector('.quiz-viewer-cont').clientWidth / 2,
-                    y: 0
-                });
-            }
-            else if (this.ifrContents.id === 'contents2') {
-                const video = this.ifrContents.querySelector('video');
-                const img = this.ifrContents.querySelector('img');
-                const iframe = this.ifrContents.querySelector('iframe');
-                const youtube = this.ifrContents.querySelector('input#tempCntntsUrl');
-                const whiteboard = this.ifrContents.querySelector('.whiteboard');
-                if (video) {
-                    // 비디오 태그가 있을 경우
-                    this.ifrContentsType = 'video';
-                    this.setBaseSize({ x: -video.videoWidth / 2, y: -video.videoHeight / 2, w: video.videoWidth, h: video.videoHeight });
-                }
-                else if (img) {
-                    // 이미지 태그가 있을 경우
-                    this.ifrContentsType = 'img';
-                    this.setBaseSize({ x: -img.naturalWidth / 2, y: -img.naturalHeight / 2, w: img.naturalWidth, h: img.naturalHeight });
-                }
-                else if (iframe) {
-                    // 아이프레임이 있을 경우
-                    this.ifrContentsType = 'iframe';
-                    this.setBaseSize({ x: -iframe.clientWidth / 2, y: 0, w: iframe.clientWidth, h: iframe.scrollHeight });
-                }
-                else if (youtube) {
-                    // 유튜브 프레임이 들어온 경우
-                    this.ifrContentsType = 'youtube';
-                    this.setBaseSize({ x: -960, y: -540, w: 1920, h: 1080 });
-                }
-                else if (whiteboard) {
-                    // 화이트보드가 있을 경우
-                    this.ifrContentsType = 'whiteboard';
-                    this.setBaseSize({ x: -whiteboard.clientWidth / 2, y: -whiteboard.clientHeight / 2, w: whiteboard.clientWidth, h: whiteboard.clientHeight });
-                }
-                else {
-                    this.ifrContentsType = 'etc';
-                    this.setBaseSize({ w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                    this.setBaseSize({
-                        x: -this.ifrContents.clientWidth / 2,
-                        y: 0
-                    });
-                }
-            }
-            else {
-                this.ifrContentsType = 'unknown';
-                this.setBaseSize({ w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                this.setBaseSize({
-                    x: -this.ifrContents.clientWidth / 2,
-                    y: 0
-                });
-            }
-        };
-        this.onResize = () => {
-            if (!this.ifrDoc || !this.svg || !this.ifrContents)
-                return;
-            const hasYScroll = this.ifrContents.scrollHeight > this.ifrContents.clientHeight;
-            if (hasYScroll) {
-                switch (this.ifrContentsType) {
-                    case 'img':
-                    // this.svg.style.height = `${this.ifrContents.scrollHeight}px`;
-                    // this.setViewBox(this.baseSize);
-                    // break;
-                    case 'quiz':
-                        this.svg.style.height = `${this.ifrContents.scrollHeight}px`;
-                        this.setViewBox(this.baseSize);
-                        break;
-                    case 'iframe':
-                    case 'unknown':
-                    case 'etc':
-                        this.setViewBox({ x: -this.ifrContents.clientWidth / 2, w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                        break;
-                    case 'video':
-                    case 'youtube':
-                    case 'whiteboard':     
-                    default:
-                        this.setViewBox(this.baseSize);
-                        break;
-                }
-            }
-            else {
-                this.svg.style.height = ``;
-                switch (this.ifrContentsType) {
-                    case 'quiz':
-                        this.svg.style.height = `${this.ifrContents.scrollHeight}px`;
-                        this.setViewBox({ h: this.ifrContents.scrollHeight });
-                        break;
-                    case 'iframe':
-                    case 'unknown':
-                    case 'etc':
-                        this.setViewBox({ x: -this.ifrContents.clientWidth / 2, w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                        break;
-                    case 'img':
-                    case 'video':
-                    case 'youtube':
-                    case 'whiteboard': 
-                    default:
-                        this.setViewBox(this.baseSize);
-                        break;
-                }
-            }
-        };
-        this.setBaseSize = (newBaseSize) => {
-            this.baseSize = Object.assign(Object.assign({}, this.baseSize), newBaseSize); // Merge with the existing baseSize
-        };
-        this.setViewBox = (newSize) => {
-            const newBaseSize = Object.assign(Object.assign({}, this.baseSize), newSize);
-            if (!this.svg)
-                return;
-            this.svg.setAttribute("viewBox", `${newBaseSize.x} ${newBaseSize.y} ${newBaseSize.w} ${newBaseSize.h}`);
-        };
-        this.createDrawingGroup = () => {
-            var _a;
-            const drawingGroup = document.createElementNS(this.svgNS, 'g');
-            (_a = this.svg) === null || _a === void 0 ? void 0 : _a.append(drawingGroup);
-            this.drawingGroup = drawingGroup;
-        };
-        this.createMaskingGroup = () => {
-            var _a, _b;
-            const maskingGroup = document.createElementNS(this.svgNS, 'mask');
-            maskingGroup.id = 'eraser-mask';
-            (_a = this.svg) === null || _a === void 0 ? void 0 : _a.append(maskingGroup);
-            this.maskingGroup = maskingGroup;
-            (_b = this.drawingGroup) === null || _b === void 0 ? void 0 : _b.setAttribute('mask', 'url(#eraser-mask)');
-            // 흰색 배경 (지우개 영역은 투명)
-            const maskRect = document.createElementNS(this.svgNS, "rect");
-            maskRect.setAttribute("fill", "white");
-            maskRect.setAttribute("x", `${this.baseSize.x * 100}`);
-            maskRect.setAttribute("y", `${this.baseSize.y * 100}`);
-            maskRect.setAttribute("width", `${this.baseSize.w * 100}`);
-            maskRect.setAttribute("height", `${this.baseSize.h * 100}`);
-            this.maskingGroup.appendChild(maskRect);
-        };
-        // 콘트롤 패널 드래그 앤 드롭 기능 추가
-        // this.enableDrag = (element) => {
-        //     let offsetX = 0;
-        //     let offsetY = 0;
-        //     let isDragging = false;
-        //     const onMouseDown = (e) => {
-        //         var _a;
-        //         e.preventDefault();
-        //         isDragging = true;
-        //         // 현재 요소의 fixed 위치 계산
-        //         const rect = element.getBoundingClientRect();
-        //         const targetConRect = (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
-        //         if (!targetConRect)
-        //             return;
-        //         // 마우스 포인터와 요소의 **오른쪽** 및 **위쪽** 경계와의 거리 계산
-        //         // offsetX = rect.right - e.clientX;
-        //         // offsetY = e.clientY - rect.top;
-        //         // // 요소의 스타일을 고정 위치에 맞추어 설정
-        //         // element.style.right = `${window.innerWidth - rect.right}px`; // right 기준으로 위치 지정
-        //         // element.style.top = `${rect.top}px`;
-        //         // element.style.left = 'auto'; // left 속성 제거
-        //         // element.style.transform = 'none'; // 기존 translateY 제거
-        //         // element.style.transition = 'none';
-        //     };
-        //     const onMouseMove = (e) => {
-        //         var _a;
-        //         if (!isDragging)
-        //             return;
-        //         e.preventDefault();
-        //         // painter-target 영역의 크기 가져오기
-        //         const containerRect = (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
-        //         if (!containerRect)
-        //             return;
-        //         // 새로운 위치 계산
-        //         // let right = window.innerWidth - e.clientX - offsetX;
-        //         // let y = e.clientY - offsetY;
-        //         // // 요소의 x, y 위치가 painter-target 영역을 넘지 않도록 제한
-        //         // right = Math.max(0, Math.min(right, window.innerWidth - containerRect.left - element.offsetWidth));
-        //         // y = Math.max(containerRect.top, Math.min(y, containerRect.bottom - element.offsetHeight));
-        //         // // 요소의 위치 업데이트 (오른쪽 기준)
-        //         // element.style.right = `${right}px`;
-        //         // element.style.top = `${y}px`;
-        //     };
-        //     const onMouseUp = () => {
-        //         isDragging = false;
-        //         element.style.transition = '';
-        //     };
-        //     // 이벤트 리스너 등록
-        //     element.addEventListener('mousedown', onMouseDown);
-        //     document.addEventListener('mousemove', onMouseMove);
-        //     document.addEventListener('mouseup', onMouseUp);
-        // };
-        this.uiUpdate = () => {
-            if (!this.targetCon)
-                return; // targetCon이 null인지 확인
-            this.btnInit.classList.add('is-active');
-            this.targetCon.classList.add('is-active');
-            this.ctrlCon = document.createElement('aside');
-            this.ctrlCon.classList.add('painterbar');
-            this.targetCon.append(this.ctrlCon);
-            // 드래그 기능 활성화
-            //this.enableDrag(this.ctrlCon);
-            const minBtn = document.createElement('button');
-            minBtn.type = "button";
-            minBtn.classList.add('btn-painterbar-size');
-            minBtn.textContent = '색연필 최소화';
-            this.ctrlCon.append(minBtn);
-            minBtn.onclick = () => {
-                var _a;
-                (_a = this.ctrlCon) === null || _a === void 0 ? void 0 : _a.classList.toggle('min'); // null 체크
-            };
-            const previewCon = document.createElement('div');
-            previewCon.classList.add('pencil-ctrl-options', 'pencil-preview');
-            previewCon.style.width = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            previewCon.style.height = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            this.ctrlCon.append(previewCon);
-            this.previewObj = document.createElement('div');
-            previewCon.append(this.previewObj);
-            const sizeCon = document.createElement('div');
-            sizeCon.classList.add('pencil-ctrl-options', 'painterbar-stroke');
-            this.ctrlCon.append(sizeCon);
-            const range = document.createElement('input');
-            range.type = "range";
-            range.min = this.sizeRange['min'].toString();
-            range.max = this.sizeRange['max'].toString();
-            range.step = "0.1";
-            range.setAttribute("orient", "vertical");
-            range.value = this.size.toString();
-            sizeCon.append(range);
-            // range input 이벤트에서 드래그 앤 드롭과 충돌 방지
-            range.addEventListener('mousedown', (e) => e.stopPropagation());
-            range.addEventListener('mousemove', (e) => e.stopPropagation());
-            range.addEventListener('mouseup', (e) => e.stopPropagation());
-            range.oninput = () => this.changeSize(Number(range.value)); // 값 변환
-            const fncCon = document.createElement('div');
-            fncCon.classList.add('pencil-ctrl-options', 'painterbar-fnc');
-            this.ctrlCon.append(fncCon);
-            const undo = document.createElement('button');
-            undo.type = "button";
-            undo.classList.add('undo');
-            undo.textContent = "undo";
-            fncCon.append(undo);
-            undo.addEventListener('click', this.undo);
-            const redo = document.createElement('button');
-            redo.type = "button";
-            redo.classList.add('redo');
-            redo.textContent = "redo";
-            fncCon.append(redo);
-            redo.addEventListener('click', this.redo);
-            this.eraseObj = document.createElement('input');
-            this.eraseObj.type = "checkbox";
-            this.eraseObj.id = "colouredPencils_eraser";
-            this.eraseObj.classList.add('clear');
-            this.eraseObj.checked = this.isErasing;
-            fncCon.append(this.eraseObj);
-            const eraserLB = document.createElement('label');
-            eraserLB.setAttribute("for", this.eraseObj.id);
-            eraserLB.textContent = "지우개";
-            fncCon.append(eraserLB);
-            this.eraseObj.onchange = () => {
-                this.switchEraser();
-            };
-            const reset = document.createElement('button');
-            reset.type = 'button';
-            reset.classList.add('reset');
-            reset.textContent = 'reset';
-            fncCon.append(reset);
-            reset.onclick = () => this.reset();
-            // const save = document.createElement('button');
-            // save.type = 'button';
-            // save.classList.add('save');
-            // save.textContent = 'save';
-            // fncCon.append(save);
-            // save.onclick = () => this.save();
-            const colorDiv = document.createElement('div');
-            colorDiv.classList.add('pencil-ctrl-options', 'painterbar-color');
-            colorDiv.setAttribute('data-opt', this.coloursArr[this.coloursSelect]);
-            this.ctrlCon.append(colorDiv);
-            this.coloursArr.forEach((el, i) => {
-                const radio = document.createElement('input');
-                radio.type = "radio";
-                radio.name = "colouredPencils_colour";
-                radio.id = "colouredPencils_colour_" + i;
-                radio.value = i.toString();
-                if (i === this.coloursSelect)
-                    radio.checked = true;
-                colorDiv.append(radio);
-                const label = document.createElement('label');
-                label.setAttribute("for", radio.id);
-                label.textContent = el;
-                label.style.backgroundColor = el;
-                if (el === '#ffffff')
-                    label.classList.add('white');
-                colorDiv.append(label);
-                radio.onchange = () => {
-                    this.changeColour(i);
-                };
-            });
-            const close = document.createElement('button');
-            close.type = "button";
-            close.classList.add('btn-viewer-painter-close');
-            close.textContent = "색연필 닫기";
-            this.ctrlCon.append(close);
-            close.onclick = () => {
-                this.save();
-                this.closeDrawing();
-            };
-            this.updatePreview();
-        };
-        this.undo = () => {
-            if (this.undoStack.length === 0)
-                return;
-            const paths = this.undoStack.pop();
-            if (!paths)
-                return;
-            Array.isArray(paths) ? paths.forEach(path => path.remove()) : {};
-            this.redoStack.push(paths);
-        };
-        this.redo = () => {
-            if (this.redoStack.length === 0)
-                return;
-            const paths = this.redoStack.pop();
-            if (!paths)
-                return;
-            // Check if drawingGroup and maskingGroup are not null
-            if (!this.drawingGroup || !this.maskingGroup)
-                return;
-            Array.isArray(paths)
-                ? paths.forEach(path => {
-                    if (path.dataset.use === 'draw') {
-                        this.drawingGroup.append(path); // Add null check with "!" to ensure not null
-                    }
-                    else {
-                        this.maskingGroup.append(path); // Add null check
-                    }
-                })
-                : {};
-            this.undoStack.push(paths);
-        };
-        this.switchEraser = () => {
-            this.isErasing = !this.isErasing;
-            if (this.eraseObj) {
-                this.eraseObj.checked = this.isErasing;
-            }
-            this.updatePreview();
-        };
-        this.reset = () => {
-            this.undoStack = [];
-            this.redoStack = [];
-            if (this.maskingGroup) {
-                const maskPaths = this.maskingGroup.querySelectorAll('path');
-                maskPaths.forEach(path => path.remove());
-            }
-            if (this.drawingGroup) {
-                const drawPaths = this.drawingGroup.querySelectorAll('path');
-                drawPaths.forEach(path => path.remove());
-            }
-        };
-        this.save = () => {
-            if (!this.drawingGroup)
-                return;
-            const paths = this.drawingGroup.querySelectorAll('path');
-            const drawingData = [];
-            paths.forEach(path => {
-                const pathData = [
-                    path.getAttribute('stroke'),
-                    parseFloat(path.getAttribute('stroke-width') || '0'),
-                    path.getAttribute('d'),
-                ];
-                drawingData.push(pathData);
-            });
-            if (drawingData.length === 0) {
-                if (this.loadedDrawingData) {
-                    // 그린 데이터가 없는데 로드된 데이터가 있으면 삭제
-                    this.deleteDrawingData();
-                }
-                return;
-            }
-            if (this.maskingGroup) {
-                const maskPaths = this.maskingGroup.querySelectorAll('path');
-                const maskData = [];
-                maskPaths.forEach(path => {
-                    const maskPathData = [
-                        path.getAttribute('stroke'),
-                        parseFloat(path.getAttribute('stroke-width') || '0'),
-                        path.getAttribute('d'),
-                    ];
-                    maskData.push(maskPathData);
-                });
-                this.saveDrawingData({ drawingData, maskData });
-            }
-        };
-        this.changeSize = (size) => {
-            this.size = Number(size); // Ensure the size is converted to a number
-            this.updatePreview();
-        };
-        this.changeColour = (key) => {
-            this.coloursSelect = key;
-            if (this.isErasing) {
-                this.switchEraser();
-            }
-            this.updatePreview();
-        };
-        this.updatePreview = () => {
-            if (this.previewObj) {
-                this.previewObj.style.width = `${this.size * 0.1}rem`;
-                this.previewObj.style.height = `${this.size * 0.1}rem`;
-                if (this.coloursArr[this.coloursSelect] === '#ffffff') {
-                    this.previewObj.classList.add('white');
-                }
-                else {
-                    this.previewObj.classList.remove('white');
-                }
-                if (this.isErasing) {
-                    this.previewObj.classList.add('erase');
-                }
-                else {
-                    this.previewObj.classList.remove('erase');
-                    this.previewObj.style.backgroundColor = `${this.coloursArr[this.coloursSelect]}`;
-                }
-            }
-        };
-        this.closeDrawing = () => {
-            var _a;
-            if (this.ctrlCon) {
-                this.ctrlCon.remove();
-                this.ctrlCon = null;
-            }
-            if (this.drawingGroup)
-                this.drawingGroup = null;
-            if (this.maskingGroup)
-                this.maskingGroup = null;
-            if (this.svg && this.targetCon) {
-                this.targetCon.removeChild(this.svg);
-                this.svg = null;
-            }
-            this.isErasing = false;
-            this.btnInit.classList.remove('is-active');
-            (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.classList.remove('is-active');
-            // resize 이벤트 리스너 제거
-            window.removeEventListener('resize', this.onResize);
-            // beforeunload 이벤트 리스너 제거
-            // window.removeEventListener('beforeunload', this.beforeUnloadHandler);
-        };
-        this.createDrawEvents = () => {
-            if (!this.svg)
-                return;
-            this.svg.addEventListener("mousedown", this.pressEventHandler);
-            this.svg.addEventListener("mousemove", this.dragEventHandler);
-            this.svg.addEventListener("mouseup", this.releaseEventHandler);
-            this.svg.addEventListener("mouseout", this.cancelEventHandler);
-            this.svg.addEventListener("touchstart", this.pressEventHandler);
-            this.svg.addEventListener("touchmove", this.dragEventHandler);
-            this.svg.addEventListener("touchend", this.releaseEventHandler);
-            this.svg.addEventListener("touchcancel", this.cancelEventHandler);
-        };
-        // line 대신 path 사용으로 메모리 사용량 최적화
-        this.releaseEventHandler = () => {
-            this.drawing = false;
-            if (this.drawPathElement) {
-                this.currentPath.push(this.drawPathElement);
-            }
-            if (this.eraserPathElement) {
-                this.currentPath.push(this.eraserPathElement);
-            }
-            if (this.currentPath.length > 0) {
-                this.undoStack.push(this.currentPath);
-                this.redoStack = [];
-            }
-            this.drawPathElement = null; // 현재 그리던 path 초기화
-            this.eraserPathElement = null; // 현재 그리던 path 초기화
-            this.currentPath = [];
-            // 드로잉이 끝나면 다시 기본 동작을 허용
-            this.preventPageInteractions(true);
-            // 드로잉이 끝나면 다시 painterbar의 pointer-events 활성
-            this.disablePointerEvents(this.ctrlCon, false);
-        };
-        this.cancelEventHandler = () => {
-            this.releaseEventHandler();
-        };
-        this.pressEventHandler = (e) => {
-            var _a;
-            this.drawing = true;
-            const newPoint = this.getMousePosition(e);
-            // 드로잉 중에는 페이지에서 텍스트 선택 및 드래그가 되지 않도록 차단
-            this.preventPageInteractions(false);
-            // 드로잉 중에는 painterbar의 pointer-events 비활성
-            this.disablePointerEvents(this.ctrlCon, true);
-            // 드로잉 또는 지우기 동작 처리
-            const strokeColor = this.isErasing ? 'black' : this.coloursArr[this.coloursSelect];
-            this.startDrawing(strokeColor, this.size, this.isErasing, newPoint);
-            // 마스킹 그룹에 path 가 있을 경우, 마스킹 그룹에도 path 추가
-            if (!this.isErasing && ((_a = this.maskingGroup) === null || _a === void 0 ? void 0 : _a.querySelector('path'))) {
-                this.startDrawing('white', this.size, true, newPoint);
-            }
-        };
-        this.dragEventHandler = (e) => {
-            if (!this.drawing)
-                return;
-            const newPoint = this.getMousePosition(e);
-            // 새로운 path 요소 그리기
-            if (this.drawPathElement) {
-                this.drawPath(`L ${newPoint.x} ${newPoint.y}`);
-            }
-            if (this.eraserPathElement) {
-                this.drawPath(`L ${newPoint.x} ${newPoint.y}`, true);
-            }
-            e.preventDefault();
-        };
-        // 새로운 path를 생성하고 시작 지점을 그리는 함수
-        this.startDrawing = (strokeColor, strokeWidth, eraser, point) => {
-            this.createNewPath(strokeColor, strokeWidth, eraser);
-            this.drawPath(`M ${point.x} ${point.y} L ${point.x + 0.01} ${point.y}`, eraser);
-        };
-        this.createNewPath = (strokeColor, strokeWidth, eraser = false) => {
-            var _a, _b;
-            // 새로운 path 요소 생성
-            const pathElement = document.createElementNS(this.svgNS, 'path');
-            pathElement.setAttribute('fill', 'none');
-            pathElement.setAttribute('stroke', strokeColor);
-            pathElement.setAttribute('stroke-width', `${strokeWidth}`);
-            pathElement.setAttribute('stroke-linecap', 'round');
-            pathElement.setAttribute('d', '');
-            if (!eraser) {
-                pathElement.setAttribute('data-use', 'draw');
-                (_a = this.drawingGroup) === null || _a === void 0 ? void 0 : _a.append(pathElement);
-                this.drawPathElement = pathElement;
-            }
-            else {
-                (_b = this.maskingGroup) === null || _b === void 0 ? void 0 : _b.append(pathElement);
-                this.eraserPathElement = pathElement;
-            }
-        };
-        this.drawPath = (d, eraser = false) => {
-            const pathElement = eraser ? this.eraserPathElement : this.drawPathElement;
-            // 새로운 path 요소 그리기
-            const od = pathElement.getAttribute('d');
-            pathElement.setAttribute('d', `${od} ${d}`);
-        };
-        this.getMousePosition = (e) => {
-            var _a;
-            if (!this.svg)
-                return new DOMPoint(0, 0); // Add a fallback value in case svg is null
-            const point = this.svg.createSVGPoint();
-            point.x = e.changedTouches ? e.changedTouches[0].clientX : e.clientX;
-            point.y = e.changedTouches ? e.changedTouches[0].clientY : e.clientY;
-            return point.matrixTransform((_a = this.svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse()); // Convert screen coordinates to SVG coordinates
-        };
-        // 페이지의 기본 선택 및 드래그 동작을 활성/비활성화하는 함수
-        this.preventPageInteractions = (state) => {
-            if (state) {
-                document.onselectstart = null; // 텍스트 선택 차단 해제
-                document.ondragstart = null; // 드래그 차단 해제
-            }
-            else {
-                document.onselectstart = () => false; // 텍스트 선택 차단
-                document.ondragstart = () => false; // 드래그 차단
-            }
-        };
-        // pointer-events를 활성/비활성화하는 함수
-        this.disablePointerEvents = (target, state) => {
-            if (!target)
-                return;
-            target.style.pointerEvents = state ? 'none' : '';
-        };
-        // 데이터 가져오기
-        this.loadDrawingData = () => {
-            if (this.loadDataUrl === '') {
-                // 세션스토리지에서 데이터 가져오기
-                const userKey = this.dataParam.userKey;
-                const contentsKey = this.dataParam.contentsKey;
-                if (userKey && contentsKey) {
-                    const storedData = sessionStorage.getItem(`drawingData-${userKey}-${contentsKey}`);
-                    if (storedData) {
-                        const parsedData = JSON.parse(storedData);
-                        const { drawingData, maskData } = parsedData;
-                        // 드로잉 데이터를 복원
-                        if (drawingData && this.drawingGroup) {
-                            drawingData.forEach((line) => {
-                                this.createNewPath(line[0], line[1]);
-                                this.drawPath(line[2]);
-                            });
-                        }
-                        // 마스크 데이터를 복원
-                        if (maskData && this.maskingGroup) {
-                            maskData.forEach((line) => {
-                                this.createNewPath(line[0], line[1], true);
-                                this.drawPath(line[2], true);
-                            });
-                        }
-                        this.loadedDrawingData = true;
-                        console.log('Data loaded from session storage');
-                    }
-                    else {
-                        this.loadedDrawingData = false;
-                        console.log('No data found in session storage');
-                    }
-                }
-                else {
-                    console.error('userKey or contentsKey is missing in dataParam');
-                }
-                return;
-            }
-            // fetch(this.loadDataUrl, {
-            //     method: 'GET',
-            //     headers: {
-            //         'Content-Type': 'application/json',
-            //     }
-            // })
-            fetch(this.loadDataUrl, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify(this.dataParam),
-            })
-                .then(response => response.json())
-                .then(data => {
-                const { drawingData, maskData } = data;
-                    if (!drawingData || drawingData && drawingData.length === 0) {
-                    this.loadedDrawingData = false;
-                    return;
-                }
-
-                if (drawingData && this.drawingGroup) {
-                    drawingData.forEach((line) => {
-                        this.createNewPath(line[0], line[1]);
-                        this.drawPath(line[2]);
-                    });
-                }
-                if (maskData && this.maskingGroup) {
-                    maskData.forEach((line) => {
-                        this.createNewPath(line[0], line[1], true);
-                        this.drawPath(line[2], true);
-                    });
-                }
-                this.loadedDrawingData = true;
-            })
-                .catch(error => console.error('Error loading drawing data:', error));
-        };
-        // 데이터 저장
-        this.saveDrawingData = (data) => {
-            const params = Object.assign(Object.assign({}, this.dataParam), data);
-            console.log('save data :', params);
-            console.log(this.dataParam);
-            // saveDataUrl이 비어 있으면 세션스토리지에 저장
-            if (this.saveDataUrl === '') {
-                if ('userKey' in params && 'contentsKey' in params) {
-                    sessionStorage.setItem(`drawingData-${params['userKey']}-${params['contentsKey']}`, JSON.stringify(params));
-                    console.log('Data saved to session storage');
-                }
-                else {
-                    console.error('userKey or contentsKey is missing in params');
-                }
-                return;
-            }
-            fetch(this.saveDataUrl, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify(params),
-            }).then(response => this.reset())
-                .catch(error => console.error('Error saving drawing data:', error));
-        };
-        // 저장된 데이터 삭제
-        this.deleteDrawingData = () => {
-            const params = Object.assign(Object.assign({}, this.dataParam));
-            // deleteDataUrl이 비어 있으면 세션스토리지를 확인하여 삭제
-            if (this.deleteDataUrl === '') {
-                if ('userKey' in params && 'contentsKey' in params) {
-                    sessionStorage.removeItem(`drawingData-${params['userKey']}-${params['contentsKey']}`);
-                    console.log('Data deleted to session storage');
-                }
-                else {
-                    console.error('userKey or contentsKey is missing in params');
-                }
-                return;
-            }
-            fetch(this.deleteDataUrl, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify(this.dataParam),
-            })
-                .then(response => {
-                    // 먼저 text로 받아서 확인
-                    return response.text().then(text => {
-                        console.log("서버 응답 내용:\n", text);
-                        try {
-                            return JSON.parse(text);
-                        } catch (err) {
-                            console.error("⚠ JSON 파싱 실패: ", err);
-                            throw new Error("서버에서 JSON이 아닌 HTML 응답을 받음");
-                        }
-                    });
-                })
-                .then(data => {
-                    console.log("정상적으로 파싱된 JSON:", data);
-                })
-                .catch(error => {
-                    console.error("Fetch 처리 중 에러:", error);
-                });
-        };
-        // 창 닫기 이벤트에서 save() 호출
-        this.beforeUnloadHandler = (event) => {
-            this.save();
-            event.preventDefault();
-            // // 경고 메시지 표시 (선택 사항)
-            // const confirmationMessage = '색연필로 작성한 내용이 저장되지 않을 수 있습니다.';
-            // event.returnValue = confirmationMessage;
-            // return confirmationMessage;
-        };
-        this.btnInit = btnInit;
-        this.targetArr = objArr;
-        this.coloursArr = coloursArr.map(c => c.toLowerCase());
-        this.coloursSelect = coloursSelect - 1;
-        this.baseSize = { x: -800, y: -450, w: 1600, h: 900 };
-        brushMax = brushMax > 60 ? 60 : brushMax;
-        this.sizeRange = {
-            min: brushMin,
-            max: brushMax
-        };
-        this.size = Math.round((brushMin + brushMax) / 3);
-        this.saveDataUrl = saveDataURL;
-        this.loadDataUrl = loadDataURL;
-        this.deleteDataUrl = deleteDataURL;
-        this.dataParam = dataParam;
-        this.btnInit.onclick = () => {
-            var _a, _b;
-            if (this.btnInit.classList.contains('is-active')) {
-                this.save();
-                this.closeDrawing();
-            }
-            else {
-                this.detectTargetObj();
-                const svg = document.createElementNS(this.svgNS, 'svg');
-                this.svg = svg;
-                this.svg.id = 'painterSvg';
-                this.svg.setAttribute("preserveAspectRatio", "xMidYMid meet");
-                (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.append(this.svg);
-                this.createDrawingGroup(); // 드로잉 그룹 생성
-                this.createMaskingGroup(); // 마스크 생성
-                this.uiUpdate();
-                this.createDrawEvents();
-                this.loadDrawingData();
-                this.onResize();
-                // Listen for scroll event
-                (_b = this.targetCon) === null || _b === void 0 ? void 0 : _b.addEventListener('scroll', this.onScroll);
-            }
-        };
-        const ifrObj = document.querySelector('.iframe-area iframe');
-        this.ifrObj = ifrObj;
-        (_a = this.ifrObj) === null || _a === void 0 ? void 0 : _a.addEventListener('load', this.onIfrLoad);
-        window.addEventListener('resize', this.onResize);
-        // 창을 닫거나 새로고침할 때 save() 호출
-        // window.addEventListener('beforeunload', this.beforeUnloadHandler);
-        //window.onbeforeunload = this.beforeUnloadHandler;
-        document.addEventListener("visibilitychange", (event) => {
-            if (document.visibilityState === 'hidden') {
-                this.beforeUnloadHandler(event); // 사용자가 페이지를 떠나면 저장
-            }
-        });
-    }
-    // Getter for dataParam
-    getDataParam() {
-        return this.dataParam;
-    }
-    // Setter for dataParam
-    setDataParam(newDataParam) {
-        this.dataParam = Object.assign(Object.assign({}, this.dataParam), newDataParam); // Merge with the existing dataParam
-    }
-    saveDrawing() {
-        this.save();
-    }
-}
-// Create the instance and attach it to the window object
-export function initColouredPenciles() {
-    window.addEventListener('DOMContentLoaded', () => {
-        const btnInit = document.querySelector('.btn-painter-toggle'); // 색연필 활성 버튼
-        if (!btnInit) {
-            // console.error('.btn-painter-toggle 요소를 찾을 수 없습니다.');
-            return;
-        }
-        const objArr = ['viewer-painter']; // 색연필 콘테이너 클래스명 - 여러개 지정 가능, 앞에 위치한 클래스명의 엘리먼트 우선
-        const colorArray = ["#222222", "#fd4418", "#ffce00", "#00d56a", "#2f77ff", "#ffffff"]; // 색상 팔레트 6색
-        const defaultColor = 5; // 기본 선 굵기
-        const brushMin = 0.5, brushMax = 43; // 최소, 최대 선 굵기
-        const saveDataUrl = '/classroom/insertClassLessonWrtng.json'; // save api url
-        const loadDataURL = '/classroom/selectClassLessonWrtng.json'; // load api url
-        const deleteDataURL = '/classroom/deleteClassLessonWrtng.json'; // delete api url
-        // const loadDataURL = 'lineData.json'; // test load api url
-        /** dataParam은 외부에서 설정, 사용 환경에 따라 key, value 자유 설정 가능 */
-        const dataParam = {};
-        // 인스턴스 생성 후 전역 window 객체에 저장
-        window.cpInstance = new colouredPenciles(btnInit, objArr, colorArray, defaultColor, brushMin, brushMax, saveDataUrl, loadDataURL, deleteDataURL, dataParam);
-    });
-}
-initColouredPenciles();
 
resources/front/site/SITE_00000/js/custom/module/colouredPencilesSvg_pub.js (deleted)
--- resources/front/site/SITE_00000/js/custom/module/colouredPencilesSvg_pub.js
@@ -1,852 +0,0 @@
-/*
-* Copyright (c) FOX EDU CO., LTD ALL RIGHT RESERVED.
-* by flashkid
-* 25.SEP.2024(WED)
-*/
-export class colouredPenciles {
-    constructor(btnInit, objArr, coloursArr, coloursSelect = 1, brushMin = 0.5, brushMax = 10, saveDataURL = '', loadDataURL = '', deleteDataURL = '', dataParam = {}) {
-        var _a;
-        this.svgNS = "http://www.w3.org/2000/svg";
-        this.ctrlCon = null;
-        this.targetCon = null;
-        this.targetArr = [];
-        this.ifrObj = null;
-        this.ifrDoc = null;
-        this.ifrContents = null;
-        this.ifrContentsType = "etc";
-        this.svg = null;
-        this.eraseObj = null;
-        this.previewObj = null;
-        this.loadedDrawingData = false;
-        this.drawingGroup = null;
-        this.maskingGroup = null;
-        this.drawPathElement = null;
-        this.eraserPathElement = null;
-        this.undoStack = [];
-        this.redoStack = [];
-        this.currentPath = [];
-        this.drawing = false;
-        this.isErasing = false;
-        this.detectTargetObj = () => {
-            let tobj, i = 0;
-            while (!tobj && i <= this.targetArr.length) {
-                tobj = document.querySelector(`.${this.targetArr[i]}`);
-                i++;
-            }
-            if (tobj) {
-                this.targetCon = tobj;
-                this.targetCon.classList.add('painter-target');
-            }
-        };
-        // Function to handle the scroll event
-        this.onScroll = () => {
-            var _a;
-            if (['img', 'iframe', 'etc', 'unknown'].includes(this.ifrContentsType) && ((_a = this.ifrObj) === null || _a === void 0 ? void 0 : _a.contentWindow) && this.targetCon) {
-                this.ifrObj.contentWindow.scrollTo(this.targetCon.scrollLeft, this.targetCon.scrollTop);
-            }
-            else if (this.ifrContents && this.targetCon) {
-                this.ifrContents.scrollTo(this.targetCon.scrollLeft, this.targetCon.scrollTop);
-            }
-        };
-        // 아이프레임 온로드
-        this.onIfrLoad = () => {
-            var _a, _b, _c;
-            if (this.btnInit.classList.contains('is-active')) {
-                this.closeDrawing();
-                this.onResize();
-            }
-            const ifrDoc = ((_b = (_a = this.ifrObj) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.document) || ((_c = this.ifrObj) === null || _c === void 0 ? void 0 : _c.contentDocument);
-            if (!ifrDoc)
-                return;
-            this.ifrDoc = ifrDoc;
-            // ifrContents 선언
-            this.ifrContents = this.ifrDoc.querySelector('#contents2') || this.ifrDoc.querySelector('.viewer .viewer-body .viewer-cont .quiz-viewer .quiz-viewer-body') || null;
-            if (this.ifrContents.classList.contains('quiz-viewer-body')) {
-                this.ifrContentsType = 'quiz';
-                this.setBaseSize({
-                    w: this.ifrContents.querySelector('.quiz-viewer-cont').clientWidth,
-                    h: this.ifrContents.scrollHeight
-                });
-                this.setBaseSize({
-                    x: -this.ifrContents.querySelector('.quiz-viewer-cont').clientWidth / 2,
-                    y: 0
-                });
-            }
-            else if (this.ifrContents.id === 'contents2') {
-                const video = this.ifrContents.querySelector('video');
-                const img = this.ifrContents.querySelector('img');
-                const iframe = this.ifrContents.querySelector('iframe');
-                const youtube = this.ifrContents.querySelector('input#tempCntntsUrl');
-                if (video) {
-                    // 비디오 태그가 있을 경우
-                    this.ifrContentsType = 'video';
-                    this.setBaseSize({ x: -video.videoWidth / 2, y: -video.videoHeight / 2, w: video.videoWidth, h: video.videoHeight });
-                }
-                else if (img) {
-                    // 이미지 태그가 있을 경우
-                    this.ifrContentsType = 'img';
-                    this.setBaseSize({ x: -img.naturalWidth / 2, y: -img.naturalHeight / 2, w: img.naturalWidth, h: img.naturalHeight });
-                }
-                else if (iframe) {
-                    // 아이프레임이 있을 경우
-                    this.ifrContentsType = 'iframe';
-                    this.setBaseSize({ x: -iframe.clientWidth / 2, y: 0, w: iframe.clientWidth, h: iframe.scrollHeight });
-                }
-                else if (youtube) {
-                    // 유튜브 프레임이 들어온 경우
-                    this.ifrContentsType = 'youtube';
-                    this.setBaseSize({ x: -960, y: -540, w: 1920, h: 1080 });
-                }
-                else {
-                    this.ifrContentsType = 'etc';
-                    this.setBaseSize({ w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                    this.setBaseSize({
-                        x: -this.ifrContents.clientWidth / 2,
-                        y: 0
-                    });
-                }
-            }
-            else {
-                this.ifrContentsType = 'unknown';
-                this.setBaseSize({ w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                this.setBaseSize({
-                    x: -this.ifrContents.clientWidth / 2,
-                    y: 0
-                });
-            }
-        };
-        this.onResize = () => {
-            if (!this.ifrDoc || !this.svg || !this.ifrContents)
-                return;
-            const hasYScroll = this.ifrContents.scrollHeight > this.ifrContents.clientHeight;
-            if (hasYScroll) {
-                switch (this.ifrContentsType) {
-                    case 'img':
-                    // this.svg.style.height = `${this.ifrContents.scrollHeight}px`;
-                    // this.setViewBox(this.baseSize);
-                    // break;
-                    case 'quiz':
-                        this.svg.style.height = `${this.ifrContents.scrollHeight}px`;
-                        this.setViewBox(this.baseSize);
-                        break;
-                    case 'iframe':
-                    case 'unknown':
-                    case 'etc':
-                        this.setViewBox({ x: -this.ifrContents.clientWidth / 2, w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                        break;
-                    case 'video':
-                    case 'youtube':
-                    default:
-                        this.setViewBox(this.baseSize);
-                        break;
-                }
-            }
-            else {
-                this.svg.style.height = ``;
-                switch (this.ifrContentsType) {
-                    case 'quiz':
-                        this.svg.style.height = `${this.ifrContents.scrollHeight}px`;
-                        this.setViewBox({ h: this.ifrContents.scrollHeight });
-                        break;
-                    case 'iframe':
-                    case 'unknown':
-                    case 'etc':
-                        this.setViewBox({ x: -this.ifrContents.clientWidth / 2, w: this.ifrContents.clientWidth, h: this.ifrContents.scrollHeight });
-                        break;
-                    case 'img':
-                    case 'video':
-                    case 'youtube':
-                    default:
-                        this.setViewBox(this.baseSize);
-                        break;
-                }
-            }
-        };
-        this.setBaseSize = (newBaseSize) => {
-            this.baseSize = Object.assign(Object.assign({}, this.baseSize), newBaseSize); // Merge with the existing baseSize
-        };
-        this.setViewBox = (newSize) => {
-            const newBaseSize = Object.assign(Object.assign({}, this.baseSize), newSize);
-            if (!this.svg)
-                return;
-            this.svg.setAttribute("viewBox", `${newBaseSize.x} ${newBaseSize.y} ${newBaseSize.w} ${newBaseSize.h}`);
-        };
-        this.createDrawingGroup = () => {
-            var _a;
-            const drawingGroup = document.createElementNS(this.svgNS, 'g');
-            (_a = this.svg) === null || _a === void 0 ? void 0 : _a.append(drawingGroup);
-            this.drawingGroup = drawingGroup;
-        };
-        this.createMaskingGroup = () => {
-            var _a, _b;
-            const maskingGroup = document.createElementNS(this.svgNS, 'mask');
-            maskingGroup.id = 'eraser-mask';
-            (_a = this.svg) === null || _a === void 0 ? void 0 : _a.append(maskingGroup);
-            this.maskingGroup = maskingGroup;
-            (_b = this.drawingGroup) === null || _b === void 0 ? void 0 : _b.setAttribute('mask', 'url(#eraser-mask)');
-            // 흰색 배경 (지우개 영역은 투명)
-            const maskRect = document.createElementNS(this.svgNS, "rect");
-            maskRect.setAttribute("fill", "white");
-            maskRect.setAttribute("x", `${this.baseSize.x * 100}`);
-            maskRect.setAttribute("y", `${this.baseSize.y * 100}`);
-            maskRect.setAttribute("width", `${this.baseSize.w * 100}`);
-            maskRect.setAttribute("height", `${this.baseSize.h * 100}`);
-            this.maskingGroup.appendChild(maskRect);
-        };
-        // 콘트롤 패널 드래그 앤 드롭 기능 추가
-        // this.enableDrag = (element) => {
-        //     let offsetX = 0;
-        //     let offsetY = 0;
-        //     let isDragging = false;
-        //     const onMouseDown = (e) => {
-        //         var _a;
-        //         e.preventDefault();
-        //         isDragging = true;
-        //         // 현재 요소의 fixed 위치 계산
-        //         const rect = element.getBoundingClientRect();
-        //         const targetConRect = (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
-        //         if (!targetConRect)
-        //             return;
-
-        //         // hyo: painterbar 위치 주석처리
-        //         // 마우스 포인터와 요소의 **오른쪽** 및 **위쪽** 경계와의 거리 계산
-        //         // offsetX = rect.right - e.clientX;
-        //         // offsetY = e.clientY - rect.top;
-        //         // // 요소의 스타일을 고정 위치에 맞추어 설정
-        //         // element.style.right = `${window.innerWidth - rect.right}px`; // right 기준으로 위치 지정
-        //         // element.style.top = `${rect.top}px`;
-        //         // element.style.left = 'auto'; // left 속성 제거
-        //         // element.style.transform = 'none'; // 기존 translateY 제거
-        //         // element.style.transition = 'none';
-        //     };
-        //     const onMouseMove = (e) => {
-        //         var _a;
-        //         if (!isDragging)
-        //             return;
-        //         e.preventDefault();
-        //         // painter-target 영역의 크기 가져오기
-        //         const containerRect = (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
-        //         if (!containerRect)
-        //             return;
-
-        //         // hyo: painterbar 위치 주석처리
-        //         // 새로운 위치 계산
-        //         // let right = window.innerWidth - e.clientX - offsetX;
-        //         // let y = e.clientY - offsetY;
-        //         // // 요소의 x, y 위치가 painter-target 영역을 넘지 않도록 제한
-        //         // right = Math.max(0, Math.min(right, window.innerWidth - containerRect.left - element.offsetWidth));
-        //         // y = Math.max(containerRect.top, Math.min(y, containerRect.bottom - element.offsetHeight));
-        //         // // 요소의 위치 업데이트 (오른쪽 기준)
-        //         // element.style.right = `${right}px`;
-        //         // element.style.top = `${y}px`;
-        //     };
-        //     const onMouseUp = () => {
-        //         isDragging = false;
-        //         element.style.transition = '';
-        //     };
-        //     // 이벤트 리스너 등록
-        //     element.addEventListener('mousedown', onMouseDown);
-        //     document.addEventListener('mousemove', onMouseMove);
-        //     document.addEventListener('mouseup', onMouseUp);
-        // };
-        this.uiUpdate = () => {
-            if (!this.targetCon)
-                return; // targetCon이 null인지 확인
-            this.btnInit.classList.add('is-active');
-            this.targetCon.classList.add('is-active');
-            this.ctrlCon = document.createElement('aside');
-            this.ctrlCon.classList.add('painterbar');
-            this.targetCon.append(this.ctrlCon);
-            // 드래그 기능 활성화
-            //this.enableDrag(this.ctrlCon);
-            const minBtn = document.createElement('button');
-            minBtn.type = "button";
-            minBtn.classList.add('btn-painterbar-size');
-            minBtn.textContent = '색연필 최소화';
-            this.ctrlCon.append(minBtn);
-            minBtn.onclick = () => {
-                var _a;
-                (_a = this.ctrlCon) === null || _a === void 0 ? void 0 : _a.classList.toggle('min'); // null 체크
-            };
-            const previewCon = document.createElement('div');
-            previewCon.classList.add('pencil-ctrl-options', 'pencil-preview');
-            previewCon.style.width = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            previewCon.style.height = `${this.sizeRange['max'] * 0.1 + 0.2}rem`;
-            this.ctrlCon.append(previewCon);
-            this.previewObj = document.createElement('div');
-            previewCon.append(this.previewObj);
-            const sizeCon = document.createElement('div');
-            sizeCon.classList.add('pencil-ctrl-options', 'painterbar-stroke');
-            this.ctrlCon.append(sizeCon);
-            const range = document.createElement('input');
-            range.type = "range";
-            range.min = this.sizeRange['min'].toString();
-            range.max = this.sizeRange['max'].toString();
-            range.step = "0.1";
-            range.setAttribute("orient", "vertical");
-            range.value = this.size.toString();
-            sizeCon.append(range);
-            // range input 이벤트에서 드래그 앤 드롭과 충돌 방지
-            range.addEventListener('mousedown', (e) => e.stopPropagation());
-            range.addEventListener('mousemove', (e) => e.stopPropagation());
-            range.addEventListener('mouseup', (e) => e.stopPropagation());
-            range.oninput = () => this.changeSize(Number(range.value)); // 값 변환
-            const fncCon = document.createElement('div');
-            fncCon.classList.add('pencil-ctrl-options', 'painterbar-fnc');
-            this.ctrlCon.append(fncCon);
-            const undo = document.createElement('button');
-            undo.type = "button";
-            undo.classList.add('undo');
-            undo.textContent = "undo";
-            fncCon.append(undo);
-            undo.addEventListener('click', this.undo);
-            const redo = document.createElement('button');
-            redo.type = "button";
-            redo.classList.add('redo');
-            redo.textContent = "redo";
-            fncCon.append(redo);
-            redo.addEventListener('click', this.redo);
-            this.eraseObj = document.createElement('input');
-            this.eraseObj.type = "checkbox";
-            this.eraseObj.id = "colouredPencils_eraser";
-            this.eraseObj.classList.add('clear');
-            this.eraseObj.checked = this.isErasing;
-            fncCon.append(this.eraseObj);
-            const eraserLB = document.createElement('label');
-            eraserLB.setAttribute("for", this.eraseObj.id);
-            eraserLB.textContent = "지우개";
-            fncCon.append(eraserLB);
-            this.eraseObj.onchange = () => {
-                this.switchEraser();
-            };
-            const reset = document.createElement('button');
-            reset.type = 'button';
-            reset.classList.add('reset');
-            reset.textContent = 'reset';
-            fncCon.append(reset);
-            reset.onclick = () => this.reset();
-            // const save = document.createElement('button');
-            // save.type = 'button';
-            // save.classList.add('save');
-            // save.textContent = 'save';
-            // fncCon.append(save);
-            // save.onclick = () => this.save();
-            const colorDiv = document.createElement('div');
-            colorDiv.classList.add('pencil-ctrl-options', 'painterbar-color');
-            colorDiv.setAttribute('data-opt', this.coloursArr[this.coloursSelect]);
-            this.ctrlCon.append(colorDiv);
-            this.coloursArr.forEach((el, i) => {
-                const radio = document.createElement('input');
-                radio.type = "radio";
-                radio.name = "colouredPencils_colour";
-                radio.id = "colouredPencils_colour_" + i;
-                radio.value = i.toString();
-                if (i === this.coloursSelect)
-                    radio.checked = true;
-                colorDiv.append(radio);
-                const label = document.createElement('label');
-                label.setAttribute("for", radio.id);
-                label.textContent = el;
-                label.style.backgroundColor = el;
-                if (el === '#ffffff')
-                    label.classList.add('white');
-                colorDiv.append(label);
-                radio.onchange = () => {
-                    this.changeColour(i);
-                };
-            });
-            const close = document.createElement('button');
-            close.type = "button";
-            close.classList.add('btn-viewer-painter-close');
-            close.textContent = "색연필 닫기";
-            this.ctrlCon.append(close);
-            close.onclick = () => {
-                this.save();
-                this.closeDrawing();
-            };
-            this.updatePreview();
-        };
-        this.undo = () => {
-            if (this.undoStack.length === 0)
-                return;
-            const paths = this.undoStack.pop();
-            if (!paths)
-                return;
-            Array.isArray(paths) ? paths.forEach(path => path.remove()) : {};
-            this.redoStack.push(paths);
-        };
-        this.redo = () => {
-            if (this.redoStack.length === 0)
-                return;
-            const paths = this.redoStack.pop();
-            if (!paths)
-                return;
-            // Check if drawingGroup and maskingGroup are not null
-            if (!this.drawingGroup || !this.maskingGroup)
-                return;
-            Array.isArray(paths)
-                ? paths.forEach(path => {
-                    if (path.dataset.use === 'draw') {
-                        this.drawingGroup.append(path); // Add null check with "!" to ensure not null
-                    }
-                    else {
-                        this.maskingGroup.append(path); // Add null check
-                    }
-                })
-                : {};
-            this.undoStack.push(paths);
-        };
-        this.switchEraser = () => {
-            this.isErasing = !this.isErasing;
-            if (this.eraseObj) {
-                this.eraseObj.checked = this.isErasing;
-            }
-            this.updatePreview();
-        };
-        this.reset = () => {
-            this.undoStack = [];
-            this.redoStack = [];
-            if (this.maskingGroup) {
-                const maskPaths = this.maskingGroup.querySelectorAll('path');
-                maskPaths.forEach(path => path.remove());
-            }
-            if (this.drawingGroup) {
-                const drawPaths = this.drawingGroup.querySelectorAll('path');
-                drawPaths.forEach(path => path.remove());
-            }
-        };
-        this.save = () => {
-            if (!this.drawingGroup)
-                return;
-            const paths = this.drawingGroup.querySelectorAll('path');
-            const drawingData = [];
-            paths.forEach(path => {
-                const pathData = [
-                    path.getAttribute('stroke'),
-                    parseFloat(path.getAttribute('stroke-width') || '0'),
-                    path.getAttribute('d'),
-                ];
-                drawingData.push(pathData);
-            });
-            if (drawingData.length === 0) {
-                if (this.loadedDrawingData) {
-                    // 그린 데이터가 없는데 로드된 데이터가 있으면 삭제
-                    this.deleteDrawingData();
-                }
-                return;
-            }
-            if (this.maskingGroup) {
-                const maskPaths = this.maskingGroup.querySelectorAll('path');
-                const maskData = [];
-                maskPaths.forEach(path => {
-                    const maskPathData = [
-                        path.getAttribute('stroke'),
-                        parseFloat(path.getAttribute('stroke-width') || '0'),
-                        path.getAttribute('d'),
-                    ];
-                    maskData.push(maskPathData);
-                });
-                this.saveDrawingData({ drawingData, maskData });
-            }
-        };
-        this.changeSize = (size) => {
-            this.size = Number(size); // Ensure the size is converted to a number
-            this.updatePreview();
-        };
-        this.changeColour = (key) => {
-            this.coloursSelect = key;
-            if (this.isErasing) {
-                this.switchEraser();
-            }
-            this.updatePreview();
-        };
-        this.updatePreview = () => {
-            if (this.previewObj) {
-                this.previewObj.style.width = `${this.size * 0.1}rem`;
-                this.previewObj.style.height = `${this.size * 0.1}rem`;
-                if (this.coloursArr[this.coloursSelect] === '#ffffff') {
-                    this.previewObj.classList.add('white');
-                }
-                else {
-                    this.previewObj.classList.remove('white');
-                }
-                if (this.isErasing) {
-                    this.previewObj.classList.add('erase');
-                }
-                else {
-                    this.previewObj.classList.remove('erase');
-                    this.previewObj.style.backgroundColor = `${this.coloursArr[this.coloursSelect]}`;
-                }
-            }
-        };
-        this.closeDrawing = () => {
-            var _a;
-            if (this.ctrlCon) {
-                this.ctrlCon.remove();
-                this.ctrlCon = null;
-            }
-            if (this.drawingGroup)
-                this.drawingGroup = null;
-            if (this.maskingGroup)
-                this.maskingGroup = null;
-            if (this.svg && this.targetCon) {
-                this.targetCon.removeChild(this.svg);
-                this.svg = null;
-            }
-            this.isErasing = false;
-            this.btnInit.classList.remove('is-active');
-            (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.classList.remove('is-active');
-            // resize 이벤트 리스너 제거
-            window.removeEventListener('resize', this.onResize);
-            // beforeunload 이벤트 리스너 제거
-            // window.removeEventListener('beforeunload', this.beforeUnloadHandler);
-        };
-        this.createDrawEvents = () => {
-            if (!this.svg)
-                return;
-            this.svg.addEventListener("mousedown", this.pressEventHandler);
-            this.svg.addEventListener("mousemove", this.dragEventHandler);
-            this.svg.addEventListener("mouseup", this.releaseEventHandler);
-            this.svg.addEventListener("mouseout", this.cancelEventHandler);
-            this.svg.addEventListener("touchstart", this.pressEventHandler);
-            this.svg.addEventListener("touchmove", this.dragEventHandler);
-            this.svg.addEventListener("touchend", this.releaseEventHandler);
-            this.svg.addEventListener("touchcancel", this.cancelEventHandler);
-        };
-        // line 대신 path 사용으로 메모리 사용량 최적화
-        this.releaseEventHandler = () => {
-            this.drawing = false;
-            if (this.drawPathElement) {
-                this.currentPath.push(this.drawPathElement);
-            }
-            if (this.eraserPathElement) {
-                this.currentPath.push(this.eraserPathElement);
-            }
-            if (this.currentPath.length > 0) {
-                this.undoStack.push(this.currentPath);
-                this.redoStack = [];
-            }
-            this.drawPathElement = null; // 현재 그리던 path 초기화
-            this.eraserPathElement = null; // 현재 그리던 path 초기화
-            this.currentPath = [];
-            // 드로잉이 끝나면 다시 기본 동작을 허용
-            this.preventPageInteractions(true);
-            // 드로잉이 끝나면 다시 painterbar의 pointer-events 활성
-            this.disablePointerEvents(this.ctrlCon, false);
-        };
-        this.cancelEventHandler = () => {
-            this.releaseEventHandler();
-        };
-        this.pressEventHandler = (e) => {
-            var _a;
-            this.drawing = true;
-            const newPoint = this.getMousePosition(e);
-            // 드로잉 중에는 페이지에서 텍스트 선택 및 드래그가 되지 않도록 차단
-            this.preventPageInteractions(false);
-            // 드로잉 중에는 painterbar의 pointer-events 비활성
-            this.disablePointerEvents(this.ctrlCon, true);
-            // 드로잉 또는 지우기 동작 처리
-            const strokeColor = this.isErasing ? 'black' : this.coloursArr[this.coloursSelect];
-            this.startDrawing(strokeColor, this.size, this.isErasing, newPoint);
-            // 마스킹 그룹에 path 가 있을 경우, 마스킹 그룹에도 path 추가
-            if (!this.isErasing && ((_a = this.maskingGroup) === null || _a === void 0 ? void 0 : _a.querySelector('path'))) {
-                this.startDrawing('white', this.size, true, newPoint);
-            }
-        };
-        this.dragEventHandler = (e) => {
-            if (!this.drawing)
-                return;
-            const newPoint = this.getMousePosition(e);
-            // 새로운 path 요소 그리기
-            if (this.drawPathElement) {
-                this.drawPath(`L ${newPoint.x} ${newPoint.y}`);
-            }
-            if (this.eraserPathElement) {
-                this.drawPath(`L ${newPoint.x} ${newPoint.y}`, true);
-            }
-            e.preventDefault();
-        };
-        // 새로운 path를 생성하고 시작 지점을 그리는 함수
-        this.startDrawing = (strokeColor, strokeWidth, eraser, point) => {
-            this.createNewPath(strokeColor, strokeWidth, eraser);
-            this.drawPath(`M ${point.x} ${point.y} L ${point.x + 0.01} ${point.y}`, eraser);
-        };
-        this.createNewPath = (strokeColor, strokeWidth, eraser = false) => {
-            var _a, _b;
-            // 새로운 path 요소 생성
-            const pathElement = document.createElementNS(this.svgNS, 'path');
-            pathElement.setAttribute('fill', 'none');
-            pathElement.setAttribute('stroke', strokeColor);
-            pathElement.setAttribute('stroke-width', `${strokeWidth}`);
-            pathElement.setAttribute('stroke-linecap', 'round');
-            pathElement.setAttribute('d', '');
-            if (!eraser) {
-                pathElement.setAttribute('data-use', 'draw');
-                (_a = this.drawingGroup) === null || _a === void 0 ? void 0 : _a.append(pathElement);
-                this.drawPathElement = pathElement;
-            }
-            else {
-                (_b = this.maskingGroup) === null || _b === void 0 ? void 0 : _b.append(pathElement);
-                this.eraserPathElement = pathElement;
-            }
-        };
-        this.drawPath = (d, eraser = false) => {
-            const pathElement = eraser ? this.eraserPathElement : this.drawPathElement;
-            // 새로운 path 요소 그리기
-            const od = pathElement.getAttribute('d');
-            pathElement.setAttribute('d', `${od} ${d}`);
-        };
-        this.getMousePosition = (e) => {
-            var _a;
-            if (!this.svg)
-                return new DOMPoint(0, 0); // Add a fallback value in case svg is null
-            const point = this.svg.createSVGPoint();
-            point.x = e.changedTouches ? e.changedTouches[0].clientX : e.clientX;
-            point.y = e.changedTouches ? e.changedTouches[0].clientY : e.clientY;
-            return point.matrixTransform((_a = this.svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse()); // Convert screen coordinates to SVG coordinates
-        };
-        // 페이지의 기본 선택 및 드래그 동작을 활성/비활성화하는 함수
-        this.preventPageInteractions = (state) => {
-            if (state) {
-                document.onselectstart = null; // 텍스트 선택 차단 해제
-                document.ondragstart = null; // 드래그 차단 해제
-            }
-            else {
-                document.onselectstart = () => false; // 텍스트 선택 차단
-                document.ondragstart = () => false; // 드래그 차단
-            }
-        };
-        // pointer-events를 활성/비활성화하는 함수
-        this.disablePointerEvents = (target, state) => {
-            if (!target)
-                return;
-            target.style.pointerEvents = state ? 'none' : '';
-        };
-        // 데이터 가져오기
-        this.loadDrawingData = () => {
-            if (this.loadDataUrl === '') {
-                // 세션스토리지에서 데이터 가져오기
-                const userKey = this.dataParam.userKey;
-                const contentsKey = this.dataParam.contentsKey;
-                if (userKey && contentsKey) {
-                    this.reset();
-                    const storedData = sessionStorage.getItem(`drawingData-${userKey}-${contentsKey}`);
-                    if (storedData) {
-                        const parsedData = JSON.parse(storedData);
-                        const { drawingData, maskData } = parsedData;
-                        // 드로잉 데이터를 복원
-                        if (drawingData && this.drawingGroup) {
-                            drawingData.forEach((line) => {
-                                this.createNewPath(line[0], line[1]);
-                                this.drawPath(line[2]);
-                            });
-                        }
-                        // 마스크 데이터를 복원
-                        if (maskData && this.maskingGroup) {
-                            maskData.forEach((line) => {
-                                this.createNewPath(line[0], line[1], true);
-                                this.drawPath(line[2], true);
-                            });
-                        }
-                        this.loadedDrawingData = true;
-                        console.log('Data loaded from session storage');
-                    }
-                    else {
-                        this.loadedDrawingData = false;
-                        console.log('No data found in session storage');
-                    }
-                }
-                else {
-                    console.error('userKey or contentsKey is missing in dataParam');
-                }
-                return;
-            }
-            // fetch(this.loadDataUrl, {
-            //     method: 'GET',
-            //     headers: {
-            //         'Content-Type': 'application/json',
-            //     }
-            // })
-            fetch(this.loadDataUrl, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify(this.dataParam),
-            })
-                .then(response => response.json())
-                .then(data => {
-                const { drawingData, maskData } = data;
-                if (!drawingData || drawingData && drawingData.length === 0) {
-                    // hyo: drawingData가 없으면 reset만 하고 종료
-                    this.reset();
-                    this.loadedDrawingData = false;
-                    return;
-                }
-
-                // hyo: 데이터가 있는 경우에만 초기화 후 복원 시작
-                this.reset();
-
-                if (drawingData && this.drawingGroup) {
-                    drawingData.forEach((line) => {
-                        this.createNewPath(line[0], line[1]);
-                        this.drawPath(line[2]);
-                    });
-                }
-                if (maskData && this.maskingGroup) {
-                    maskData.forEach((line) => {
-                        this.createNewPath(line[0], line[1], true);
-                        this.drawPath(line[2], true);
-                    });
-                }
-                this.loadedDrawingData = true;
-            })
-                .catch(error => console.error('Error loading drawing data:', error));
-        };
-        // 데이터 저장
-        this.saveDrawingData = (data) => {
-            const params = Object.assign(Object.assign({}, this.dataParam), data);
-            console.log('save data :', params);
-            console.log(this.dataParam);
-            // saveDataUrl이 비어 있으면 세션스토리지에 저장
-            if (this.saveDataUrl === '') {
-                if ('userKey' in params && 'contentsKey' in params) {
-                    sessionStorage.setItem(`drawingData-${params['userKey']}-${params['contentsKey']}`, JSON.stringify(params));
-                    console.log('Data saved to session storage');
-                }
-                else {
-                    console.error('userKey or contentsKey is missing in params');
-                }
-                return;
-            }
-            fetch(this.saveDataUrl, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify(params),
-            })
-                .catch(error => console.error('Error saving drawing data:', error));
-        };
-        // 저장된 데이터 삭제
-        this.deleteDrawingData = () => {
-            const params = this.dataParam;
-            // deleteDataUrl이 비어 있으면 세션스토리지를 확인하여 삭제
-            if (this.deleteDataUrl === '') {
-                if ('userKey' in params && 'contentsKey' in params) {
-                    sessionStorage.removeItem(`drawingData-${params['userKey']}-${params['contentsKey']}`);
-                    console.log('Data deleted to session storage');
-                }
-                else {
-                    console.error('userKey or contentsKey is missing in params');
-                }
-                return;
-            }
-            fetch(this.deleteDataUrl, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify(this.dataParam),
-            })
-                .then(response => response.json())
-                .then(data => {
-                console.log(data);
-            })
-                .catch(error => console.error('Error loading drawing data:', error));
-        };
-        // 창 닫기 이벤트에서 save() 호출
-        this.beforeUnloadHandler = (event) => {
-            this.save();
-            event.preventDefault();
-            // // 경고 메시지 표시 (선택 사항)
-            // const confirmationMessage = '색연필로 작성한 내용이 저장되지 않을 수 있습니다.';
-            // event.returnValue = confirmationMessage;
-            // return confirmationMessage;
-        };
-        this.btnInit = btnInit;
-        this.targetArr = objArr;
-        this.coloursArr = coloursArr.map(c => c.toLowerCase());
-        this.coloursSelect = coloursSelect - 1;
-        this.baseSize = { x: -800, y: -450, w: 1600, h: 900 };
-        brushMax = brushMax > 60 ? 60 : brushMax;
-        this.sizeRange = {
-            min: brushMin,
-            max: brushMax
-        };
-        this.size = Math.round((brushMin + brushMax) / 3);
-        this.saveDataUrl = saveDataURL;
-        this.loadDataUrl = loadDataURL;
-        this.deleteDataUrl = deleteDataURL;
-        this.dataParam = dataParam;
-        this.btnInit.onclick = () => {
-            var _a, _b;
-            if (this.btnInit.classList.contains('is-active')) {
-                this.save();
-                this.closeDrawing();
-            }
-            else {
-                this.detectTargetObj();
-                const svg = document.createElementNS(this.svgNS, 'svg');
-                this.svg = svg;
-                this.svg.id = 'painterSvg';
-                this.svg.setAttribute("preserveAspectRatio", "xMidYMid meet");
-                (_a = this.targetCon) === null || _a === void 0 ? void 0 : _a.append(this.svg);
-                this.createDrawingGroup(); // 드로잉 그룹 생성
-                this.createMaskingGroup(); // 마스크 생성
-                this.uiUpdate();
-                this.createDrawEvents();
-                this.loadDrawingData();
-                this.onResize();
-                // Listen for scroll event
-                (_b = this.targetCon) === null || _b === void 0 ? void 0 : _b.addEventListener('scroll', this.onScroll);
-            }
-        };
-        const ifrObj = document.querySelector('.iframe-area iframe');
-        this.ifrObj = ifrObj;
-        (_a = this.ifrObj) === null || _a === void 0 ? void 0 : _a.addEventListener('load', this.onIfrLoad);
-        window.addEventListener('resize', this.onResize);
-        // 창을 닫거나 새로고침할 때 save() 호출
-        // window.addEventListener('beforeunload', this.beforeUnloadHandler);
-        window.onbeforeunload = this.beforeUnloadHandler;
-        document.addEventListener("visibilitychange", (event) => {
-            if (document.visibilityState === 'hidden') {
-                this.beforeUnloadHandler(event); // 사용자가 페이지를 떠나면 저장
-            }
-        });
-    }
-    // Getter for dataParam
-    getDataParam() {
-        return this.dataParam;
-    }
-    // Setter for dataParam
-    setDataParam(newDataParam) {
-        this.dataParam = Object.assign(Object.assign({}, this.dataParam), newDataParam); // Merge with the existing dataParam
-    }
-    saveDrawing() {
-        this.save();
-    }
-}
-// Create the instance and attach it to the window object
-export function initColouredPenciles() {
-    window.addEventListener('DOMContentLoaded', () => {
-        const btnInit = document.querySelector('.btn-painter-toggle'); // 색연필 활성 버튼
-        if (!btnInit) {
-            // console.error('.btn-painter-toggle 요소를 찾을 수 없습니다.');
-            return;
-        }
-        const objArr = ['viewer-painter']; // 색연필 콘테이너 클래스명 - 여러개 지정 가능, 앞에 위치한 클래스명의 엘리먼트 우선
-        const colorArray = ["#222222", "#fd4418", "#ffce00", "#00d56a", "#2f77ff", "#ffffff"]; // 색상 팔레트 6색
-        const defaultColor = 5; // 기본 선 굵기
-        const brushMin = 0.5, brushMax = 43; // 최소, 최대 선 굵기
-        const saveDataUrl = ''; // save api url
-        const loadDataURL = ''; // load api url
-        const deleteDataURL = ''; // delete api url
-        // const loadDataURL = 'lineData.json'; // test load api url
-        /** dataParam은 외부에서 설정, 사용 환경에 따라 key, value 자유 설정 가능 */
-        const dataParam = {};
-        // 인스턴스 생성 후 전역 window 객체에 저장
-        window.cpInstance = new colouredPenciles(btnInit, objArr, colorArray, defaultColor, brushMin, brushMax, saveDataUrl, loadDataURL, deleteDataURL, dataParam);
-    });
-}
-initColouredPenciles();
 
resources/front/site/SITE_00000/js/custom/module/old_etc.js (deleted)
--- resources/front/site/SITE_00000/js/custom/module/old_etc.js
@@ -1,36 +0,0 @@
-//선긋기
-var drawPath = function (idL, idR, startL, startT, endL, endT) {
-    matchCanvas
-        .append("line")
-        .style("stroke", "black")  // colour the line
-        .style("stroke-width", 1)
-        .attr("x1", startLeft)     // x position of the first end of the line
-        .attr("y1", startTop)      // y position of the first end of the line
-        .attr("x2", endLeft)     // x position of the second end of the line
-        .attr("y2", endTop)
-        .attr("class", idL + " " + idR)
-        .attr("data-left", idL)
-        .attr("data-right", idR)
-
-    numLeft = null,
-        numRight = null;
-
-    idLeft = 0;
-    idRight = 0;
-}
-
-var viewEvaluationEvlInfo = function (el) {
-    let acsJsonList = JSON.parse($(el).closest(".info-fnc").find(".tempCodeList").val());
-    let html = "";
-    for (let a = 0; a < acsJsonList.length; a++) {
-        html += '<li>' +
-            '<ul class="info-list sm">' +
-            '<li>' +
-            '<cite>성취기준</cite>' +
-            '<div class="txt-area">[' + acsJsonList[a].acsCode + '] ' + acsJsonList[a].acsDc + '</div>' +
-            '</li>' +
-            '</ul></li>';
-    }
-    $('#evaluationInfoUl').html(html);
-    popupOpen("evaluationInfoPopup");
-}
Add a comment
List