@nine-lab/nine-util 0.9.151 → 0.9.152

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/nine-util.js CHANGED
@@ -1483,7 +1483,7 @@ class UxSplitter extends HTMLElement {
1483
1483
  const htmlTmpl = document.createElement("template");
1484
1484
  htmlTmpl.innerHTML = `
1485
1485
  <style>
1486
- @import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@${"0.9.151"}/dist/css/nine-util.css";
1486
+ @import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@${"0.9.152"}/dist/css/nine-util.css";
1487
1487
  ${this.cssPath ? `@import "${this.cssPath}";` : ""}
1488
1488
  </style>
1489
1489
  ${gripTmpl}
@@ -1,2 +1,2 @@
1
- !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self)["nine-util"]={})}(this,function(t){"use strict";var n,e,i,o,s,r,a,l,c,d,h,u,p,g,f,m,v,w,y,b,x,$,k,M,E=Object.defineProperty,S=t=>{throw TypeError(t)},L=(t,n,e)=>((t,n,e)=>n in t?E(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e)(t,"symbol"!=typeof n?n+"":n,e),C=(t,n,e)=>n.has(t)||S("Cannot "+e),R=(t,n,e)=>(C(t,n,"read from private field"),e?e.call(t):n.get(t)),_=(t,n,e)=>n.has(t)?S("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(t):n.set(t,e),D=(t,n,e,i)=>(C(t,n,"write to private field"),i?i.call(t,e):n.set(t,e),e),O=(t,n,e)=>(C(t,n,"access private method"),e);class T extends HTMLElement{constructor(){super(),_(this,n),_(this,e),L(this,"showModal",()=>{R(this,e).showModal()}),L(this,"close",()=>{R(this,e).close(),this.remove()}),_(this,i,()=>{const t=this.querySelector(".head");t&&(t.addEventListener("mousedown",R(this,o)),t.addEventListener("touchstart",R(this,s))),this.querySelectorAll(".close, .close2, .cancel").forEach(t=>{t.onclick=()=>this.closeWithAnimation(null)}),this.querySelectorAll(".ok").forEach(t=>{})}),_(this,o,t=>{if(t.target.closest("buttons"))return;if(0!==t.button||t.altKey||t.ctrlKey||t.shiftKey)return;const i=R(this,e).getBoundingClientRect();D(this,n,{x:t.clientX-i.left,y:t.clientY-i.top});const o=t=>{R(this,e).style.position="fixed",R(this,e).style.margin="0",R(this,e).style.left=t.clientX-R(this,n).x+"px",R(this,e).style.top=t.clientY-R(this,n).y+"px"},s=()=>{document.removeEventListener("mousemove",o),document.removeEventListener("mouseup",s)};document.addEventListener("mousemove",o),document.addEventListener("mouseup",s)}),_(this,s,t=>{if(t.target.closest("buttons"))return;const i=R(this,e).getBoundingClientRect(),o=t.changedTouches[0];D(this,n,{x:o.pageX-i.left,y:o.pageY-i.top});const s=t=>{const i=t.changedTouches[0];R(this,e).style.position="fixed",R(this,e).style.margin="0",R(this,e).style.left=i.pageX-R(this,n).x+"px",R(this,e).style.top=i.pageY-R(this,n).y+"px"},r=()=>{document.removeEventListener("touchmove",s),document.removeEventListener("touchend",r)};document.addEventListener("touchmove",s),document.addEventListener("touchend",r)})}connectedCallback(){const t=this.innerHTML,n=this.getAttribute("subject")||"Details";this.innerHTML=`\n\t\t\t<style>\n\tdialog::backdrop {\n\t\tbackground: rgba(0, 0, 0, 0.3);\n\t}\n\t\n\tdialog:modal {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tpadding: 0;\n\t\toverflow: hidden;\n\t\tborder: 1px solid darkgreen;\n\t\toutline: none;\n\t\tresize: both;\n\t\tbox-shadow: 0 0 4px 0 darkgreen;\n width: 500px;\n height: fit-content;\n min-width: 330px;\n min-height: 60px;\n max-height: 100%;\n }\n \n \n \n \n\tdiv.head .rect1, div.head .rect2, div.head .rect3 {\n\t\tdisplay: none;\n\t\twidth: 50px;\n\t\theight: 100%;\n\t}\n\tdiv.head .rect1 {\n\t\tbackground-color: red;\n\t}\n\tdiv.head .rect2 {\n\t\tbackground-color: darkgreen;\n\t}\n\tdiv.head .rect3 {\n\t\tbackground-color: olive;\n\t}\n\t\n\tdiv.head {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\t--height: 30px;\n\t\tbackground-color: darkgreen;\n\t\tpadding: 4px;\n\t\tcursor: move;\n\t}\n\tdiv.head:hover {\n\t\tfilter: brightness(110%);\n\t}\n\t\n\tdiv.head span {\n\t\tfont-size: 12px;\n\t\tposition: relative;\n\t}\n\t\n\tdiv.head span.title {\n\t\tcolor: #ddd;\n\t\tmargin-left: 4px;\n\t\tfont-weight: bold;\n\t}\n\t\n\tdiv.head span.sub-title {\n\t\tcolor: #ccc;\n\t\tmargin-left: 8px;\n\t\tfont-style: italic;\n\t}\n\t\n\tdiv.head form {\n\t\tmargin: 0;\n\t}\n\tdiv.head button {\n\t\tmargin-right: 4px;\n\t\tbackground-color: transparent;\n\t\tborder: none;\n\t\tcolor: #ccc;\n\t\tfont-size: x-small;\n\t}\n\tdiv.head button:hover {\n\t\tcursor: pointer;\n\t}\n\t\n\tdiv.contents {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\toverflow: hidden;\n\t}\n\tdiv.left {\n\t\tposition: relative;\n\t\twidth: 16px;\n\t\theight: 100%;\n\t\tbackground-color: #ddd;\n\t\tdisplay: none;\n\t}\n\t\n\tdiv.left span {\n\t\twriting-mode: vertical-rl;\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t\tuser-select: none;\n\t\tcolor: #ccc;\n\t\tfont-weight: 700;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tmargin-left: 3px;\n\t\tmargin-top: 3px;\n\t}\n\tdiv.close2 {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\tright: 0;\n\t\ttop: 3px;\n\t\tcursor: pointer;\n\t\tcolor: #666;\n\t}\n\tdiv.close2 svg:hover {\n\t\tcolor: #999;\n\t}\n\t\n\tdiv.body {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: unset;\n\t\t--border: 3px solid #999;\n\t\t--border-top: none;\n\t\toverflow-x: hidden;\n\t\toverflow-y: auto;\n\t\tpadding: 10px;\n\t\tgap: 8px;\n\t\tflex-direction: column;\n\t}\n\t\n\t\n\t\n\t\n\tng-sphere.icon {\n\t\tmargin-left: 8px;\n\t}\n\t\n\t.buttons {\n\t\tdisplay: flex;\n\t\tposition: absolute;\n\t\tright: 4px;\n\t}\n\t\n\tng-sphere {\n\t\tposition: relative;\n\t\t--width: 16px;\n\t\t--height: 16px;\n\t\tcursor: pointer;\n\t\tmargin-right: 4px;\n\t\tdisplay: flex;\n\t}\n\tng-sphere:hover {\n\t\tfilter: brightness(90%);\n\t}\n\tng-sphere:active {\n\t\tfilter: brightness(80%);\n\t}\n\t\n\tng-sphere:hover::after {\n\t\tcontent: "";\n\t\tposition: absolute;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: center;\n\t}\n\tng-sphere.apply:hover::after {\n\t\tbackground-size: 14px 14px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><polyline points="2.5,7 6,10 11,3" style="fill:none;stroke:white;stroke-width:2px;" /></svg>');\n\t}\n\t\n\tng-sphere.reset:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true"><path d="M10 5h5V0"></path><path d="M15 8a6.957 6.957 0 0 1-7 7 6.957 6.957 0 0 1-7-7 6.957 6.957 0 0 1 7-7 6.87 6.87 0 0 1 6.3 4"></path></svg>');\n\t}\n\t\n\tng-sphere.close:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true" viewBox="0 0 16 16"><path d="M2 2l12 12M14 2L2 14"></path></svg>');\n\t}\n\t\n\t\n\tbutton {\n cursor: pointer;\n }\n \n .input-area {\n position: relative;\n height: 100%;\n --display: flex;\n textarea {\n width: 100%;\n height: 100%;\n min-height: 100px;\n padding: 8px;\n box-sizing: border-box;\n resize: none;\n border-radius: 2px;\n border-color: #ccc;\n }\n textarea:focus {\n border-color: green;\n outline: none; /* 브라우저 기본 파란색 테두리 제거 */\n }\n }\n \n .buttons-confirm {\n position: absolute;\n display: flex;\n justify-content: flex-end;\n bottom: 8px;\n right: 8px;\n }\n \n \n .buttons-confirm button {\n height: 32px;\n margin-right: 8px;\n border: none;\n outline: none;\n width: 60px;\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n }\n .buttons-confirm button:hover {\n filter: brightness(90%);\n }\n .buttons-confirm button:active {\n color: #ccc;\n }\n \n button.ok {\n --display: none;\n background-color: darkgreen;\n color: white;\n }\n button.cancel {\n color: white;\n background-color: #6c757d;\n }\n \n \n \n div.msg {\n position: relative;\n height: 100%;\n font-size: 14px;\n color: #333;\n padding-bottom: 48px;\n }\n \n .reset, .apply {\n display: none;\n }\n \n \n \n :host(.classic) dialog:modal {\n border: 1px solid #007bff;\n box-shadow: 0 0 4px 0 #007bff;\n }\n \n :host(.classic) div.head {\n background-color: #007bff;\n }\n :host(.classic) div.head:hover {\n filter: brightness(110%);\n }\n \n :host(.classic) div.head span {\n font-size: 12px;\n }\n \n :host(.classic) div.head span.title {\n color: #ddd;\n margin-left: 4px;\n font-weight: bold;\n }\n \n :host(.classic) div.head span.sub-title {\n color: #ccc;\n margin-left: 8px;\n font-style: italic;\n }\n :host(.classic) div.head button {\n margin-right: 4px;\n background-color: transparent;\n border: none;\n color: #ccc;\n font-size: x-small;\n }\n \n \n \n \n :host(.rgb) dialog:modal {\n border: none;\n box-shadow: unset;\n border-top: none;\n }\n \n :host(.rgb) div.left {\n display: block;\n background-color: #ddd;\n }\n :host(.rgb) div.left span {\n color: #ccc;\n }\n :host(.rgb) div.close2 {\n display: block;\n color: #666;\n }\n :host(.rgb) div.close2 svg:hover {\n color: #999;\n }\n :host(.rgb) div.head {\n height: 4px;\n background-color: #999;\n padding: 0;\n }\n :host(.rgb) div.contents {\n height: calc(100% - 4px);\n }\n \n :host(.rgb) div.head ng-sphere,\n :host(.rgb) div.head span,\n :host(.rgb) div.head .buttons {\n display: none;\n }\n \n :host(.rgb) div.head .rect1,\n :host(.rgb) div.head .rect2,\n :host(.rgb) div.head .rect3 {\n display: flex;\n }\n \n \n :host(.rgb) div.head:hover {\n filter: unset;\n }\n \n \n /* --- Animation Core --- */\n:host {\n --nx-duration: 0.4s;\n --nx-timing: cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n\n/* 🎯 수정: 애니메이션 클래스가 붙은 경우에만 초기 opacity를 0으로 설정 */\n:host(.fade) dialog,\n:host(.zoom) dialog,\n:host(.moveUp) dialog,\n:host(.moveDown) dialog,\n:host(.moveLeft) dialog,\n:host(.moveRight) dialog,\n:host(.roadRunner) dialog {\n opacity: 0;\n}\n\n/* shake는 애니메이션 내부에서 opacity를 다루므로 제외하거나 별도 처리 */\n:host(.shake) dialog { \n opacity: 1; \n}\n\n/* 1. Fade (서서히 나타남) */\n:host(.fade) dialog { animation: nx-fade-in var(--nx-duration) forwards; }\n@keyframes nx-fade-in { from { opacity: 0; } to { opacity: 1; } }\n\n/* 2. Zoom (커지며 나타남) */\n:host(.zoom) dialog { animation: nx-zoom-in var(--nx-duration) var(--nx-timing) forwards; }\n@keyframes nx-zoom-in { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } }\n\n/* 3. Slide (상하좌우) */\n:host(.moveUp) dialog { animation: nx-move-up var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveDown) dialog { animation: nx-move-down var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveLeft) dialog { animation: nx-move-left var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveRight) dialog { animation: nx-move-right var(--nx-duration) var(--nx-timing) forwards; }\n\n@keyframes nx-move-up { from { opacity: 0; transform: translateY(100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-down { from { opacity: 0; transform: translateY(-100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-left { from { opacity: 0; transform: translateX(100px); } to { opacity: 1; transform: translateX(0); } }\n@keyframes nx-move-right { from { opacity: 0; transform: translateX(-100px); } to { opacity: 1; transform: translateY(0); } }\n\n/* 4. Shake (상하좌우 격렬한 진동 - 에러 인지용) */\n:host(.shake) dialog { \n animation: nx-heavy-shake 0.5s cubic-bezier(.36,.07,.19,.97) both;\n opacity: 1; \n}\n\n@keyframes nx-heavy-shake {\n 10%, 90% { transform: translate3d(-1px, -2px, 0); }\n 20%, 80% { transform: translate3d(2px, 4px, 0); }\n 30%, 50%, 70% { transform: translate3d(-6px, -6px, 0); }\n 40%, 60% { transform: translate3d(6px, 6px, 0); }\n}\n\n/* 5. Road Runner (등장: 왼쪽에서 탄력 있게 / 퇴장: 움츠렸다가 광속 탈출) */\n:host(.roadRunner) dialog { \n animation: roadRunnerIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; \n}\n\n@keyframes roadRunnerIn {\n 0% { transform: translateX(-1500px) skewX(30deg); opacity: 1; }\n 70% { transform: translateX(30px) skewX(-10deg); opacity: 1; }\n 100% { transform: translateX(0) skewX(0deg); opacity: 1; }\n}\n\n/* --- Out Animations (닫힐 때) --- */\ndialog.out { pointer-events: none; }\n\n/* Road Runner 퇴장: 슥 움츠렸다가(Anticipation) 쌩~! */\n:host(.roadRunner) dialog.out { \n animation: roadRunnerOut 0.5s cubic-bezier(0.6, -0.28, 0.735, 0.045) forwards; \n}\n\n@keyframes roadRunnerOut {\n 0% { \n transform: translateX(0) scale(1) skewX(0deg); \n opacity: 1; \n }\n 30% { \n /* 예비 동작: 뒤로 살짝 갔다가 움츠러들기 */\n transform: translateX(50px) scaleX(1.2) scaleY(0.8) skewX(-20deg); \n opacity: 1; \n }\n 100% { \n /* 발사: 길게 늘어나며 광속 탈출 */\n transform: translateX(2000px) scaleX(4) scaleY(0.3) skewX(50deg); \n opacity: 0; \n filter: blur(10px); /* 👈 잔상 느낌 추가 */\n }\n}\n\n/* 일반 퇴장 (기본) */\ndialog.out { animation: nx-fade-out 0.3s forwards; }\n@keyframes nx-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.9); } }\n</style>\n\t\t\n\t\t\t<dialog>\n\t\t\t\t<div class="head">\n\t\t\t\t\t<div class="rect1"></div>\n\t\t\t\t\t<div class="rect2"></div>\n\t\t\t\t\t<div class="rect3"></div>\n\t\t\t\t\t<ng-sphere class="icon" end-fill="#666" size="8"></ng-sphere>\n\t\t\t\t\t<span class="title">${n}</span>\n\t\t\t\t\t<span class="sub-title"></span>\n\t\t\t\t\t<div class="buttons">\n\t\t\t\t\t\t<ng-sphere class="apply" start-fill="#cc6" end-fill="#660" size="16" title="apply"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="reset" start-fill="#99f" end-fill="#00f" size="16" title="reset"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="close" start-fill="#f99" end-fill="#f00" size="16" title="close"></ng-sphere>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="contents">\n\t\t\t\t\t<div class="left">\n\t\t\t\t\t\t<span>가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="body">\n\t\t\t\t\t\t${t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="close2">\n\t\t\t\t\t\t<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">\n\t\t\t\t\t\t\t<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</dialog>\n\t\t`,D(this,e,this.querySelector("dialog")),R(this,i).call(this)}closeWithAnimation(t){R(this,e).classList.add("out"),setTimeout(()=>{R(this,e).close(),this.dispatchEvent(new CustomEvent("closed",{detail:t})),this.remove()},300)}}n=new WeakMap,e=new WeakMap,i=new WeakMap,o=new WeakMap,s=new WeakMap;class B extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}static async open(t,n,e,i,o){var s,r,a;const l=t.tagName.toLowerCase(),c={"true-text":"확인","false-text":"취소",class:"classic",animation:"fade",...(null==(a=null==(r=null==(s=window.nine)?void 0:s.config)?void 0:r.ux)?void 0:a[l.replace("nine-","").replace("-popup","")])||{},...i};document.querySelectorAll(l).forEach(t=>t.remove());const d=document.createElement(l);c.class&&d.classList.add(c.class),c.animation&&d.classList.add(c.animation),document.body.appendChild(d),o(d,n,c);const h=d.shadowRoot.querySelector("nine-dialog");return e&&h.setAttribute("subject",e),new Promise(t=>{h.addEventListener("closed",n=>t(n.detail)),d.setupEvents(t,h),h.showModal()})}}customElements.get("nine-dialog")||customElements.define("nine-dialog",T);const A=class extends B{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(!0)}};L(A,"tagName","nine-confirm-popup"),L(A,"confirm",(t,n,e)=>B.open(A,t,n,e,(t,n,e)=>t.render(n,e)));let W=A;const z=class extends B{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">확인</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){}};L(z,"tagName","nine-alert-popup"),L(z,"alert",(t,n,e)=>B.open(z,t,n,e,(t,n,e)=>t.render(n,e)));let Y=z;customElements.get("nine-confirm-popup")||customElements.define("nine-confirm-popup",W),customElements.get("nine-alert-popup")||customElements.define("nine-alert-popup",Y);const N=class extends B{constructor(){super()}render(t,n){trace.log(this),trace.log(this.shadowRoot),this.shadowRoot.innerHTML=`\n\t\t\t<style>\n\t\t\t\tdialog {\n\t\t\t\t\theight: 300px !important;\n\t\t\t\t}\n\t\t\t\t.msg {\n\t\t\t\t\theight: unset !important;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="input-area">\n <textarea placeholder="내용을 입력하세요..."></textarea>\n </div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){const e=this.shadowRoot.querySelector("textarea");this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(e.value),requestAnimationFrame(()=>e.focus())}};L(N,"tagName","nine-prompt-popup"),L(N,"prompt",(t,n,e)=>B.open(N,t,n,e,(t,n,e)=>t.render(n,e)));let P=N;customElements.get("nine-prompt-popup")||customElements.define("nine-prompt-popup",P);const H=new Set,j={ux:{nativeOverride:!1,theme:"light"},board:{readOnly:!1},cssPath:"",debug:!1};"undefined"==typeof window||window.__NINE_GLOBAL_CONFIG__||(window.__NINE_GLOBAL_CONFIG__=j);const X="undefined"!=typeof window?window.__NINE_GLOBAL_CONFIG__:j,I=t=>(H.add(t),t("all",X),()=>H.delete(t)),F=new Proxy(X,{set:(t,n,e)=>(t[n]=e,H.forEach(e=>e(n,t)),!0),get:(t,n)=>t[n]}),q={config:F,get cssPath(){return this.config.cssPath||""},setup(t={}){Object.entries(t).forEach(([t,n])=>{"object"!=typeof n||null===n||Array.isArray(n)?this.config[t]=n:this.config[t]={...this.config[t],...n}}),"undefined"!=typeof window&&(window.nine=window.nine||this)}};function U(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var G,J={exports:{}};var K=(G||(G=1,J.exports=function(){var t=1e3,n=6e4,e=36e5,i="millisecond",o="second",s="minute",r="hour",a="day",l="week",c="month",d="quarter",h="year",u="date",p="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,f=/\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var n=["th","st","nd","rd"],e=t%100;return"["+t+(n[(e-20)%10]||n[e]||n[0])+"]"}},v=function(t,n,e){var i=String(t);return!i||i.length>=n?t:""+Array(n+1-i.length).join(e)+t},w={s:v,z:function(t){var n=-t.utcOffset(),e=Math.abs(n),i=Math.floor(e/60),o=e%60;return(n<=0?"+":"-")+v(i,2,"0")+":"+v(o,2,"0")},m:function t(n,e){if(n.date()<e.date())return-t(e,n);var i=12*(e.year()-n.year())+(e.month()-n.month()),o=n.clone().add(i,c),s=e-o<0,r=n.clone().add(i+(s?-1:1),c);return+(-(i+(e-o)/(s?o-r:r-o))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:h,w:l,d:a,D:u,h:r,m:s,s:o,ms:i,Q:d}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},y="en",b={};b[y]=m;var x="$isDayjsObject",$=function(t){return t instanceof S||!(!t||!t[x])},k=function t(n,e,i){var o;if(!n)return y;if("string"==typeof n){var s=n.toLowerCase();b[s]&&(o=s),e&&(b[s]=e,o=s);var r=n.split("-");if(!o&&r.length>1)return t(r[0])}else{var a=n.name;b[a]=n,o=a}return!i&&o&&(y=o),o||!i&&y},M=function(t,n){if($(t))return t.clone();var e="object"==typeof n?n:{};return e.date=t,e.args=arguments,new S(e)},E=w;E.l=k,E.i=$,E.w=function(t,n){return M(t,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var S=function(){function m(t){this.$L=k(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[x]=!0}var v=m.prototype;return v.parse=function(t){this.$d=function(t){var n=t.date,e=t.utc;if(null===n)return new Date(NaN);if(E.u(n))return new Date;if(n instanceof Date)return new Date(n);if("string"==typeof n&&!/Z$/i.test(n)){var i=n.match(g);if(i){var o=i[2]-1||0,s=(i[7]||"0").substring(0,3);return e?new Date(Date.UTC(i[1],o,i[3]||1,i[4]||0,i[5]||0,i[6]||0,s)):new Date(i[1],o,i[3]||1,i[4]||0,i[5]||0,i[6]||0,s)}}return new Date(n)}(t),this.init()},v.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},v.$utils=function(){return E},v.isValid=function(){return!(this.$d.toString()===p)},v.isSame=function(t,n){var e=M(t);return this.startOf(n)<=e&&e<=this.endOf(n)},v.isAfter=function(t,n){return M(t)<this.startOf(n)},v.isBefore=function(t,n){return this.endOf(n)<M(t)},v.$g=function(t,n,e){return E.u(t)?this[n]:this.set(e,t)},v.unix=function(){return Math.floor(this.valueOf()/1e3)},v.valueOf=function(){return this.$d.getTime()},v.startOf=function(t,n){var e=this,i=!!E.u(n)||n,d=E.p(t),p=function(t,n){var o=E.w(e.$u?Date.UTC(e.$y,n,t):new Date(e.$y,n,t),e);return i?o:o.endOf(a)},g=function(t,n){return E.w(e.toDate()[t].apply(e.toDate("s"),(i?[0,0,0,0]:[23,59,59,999]).slice(n)),e)},f=this.$W,m=this.$M,v=this.$D,w="set"+(this.$u?"UTC":"");switch(d){case h:return i?p(1,0):p(31,11);case c:return i?p(1,m):p(0,m+1);case l:var y=this.$locale().weekStart||0,b=(f<y?f+7:f)-y;return p(i?v-b:v+(6-b),m);case a:case u:return g(w+"Hours",0);case r:return g(w+"Minutes",1);case s:return g(w+"Seconds",2);case o:return g(w+"Milliseconds",3);default:return this.clone()}},v.endOf=function(t){return this.startOf(t,!1)},v.$set=function(t,n){var e,l=E.p(t),d="set"+(this.$u?"UTC":""),p=(e={},e[a]=d+"Date",e[u]=d+"Date",e[c]=d+"Month",e[h]=d+"FullYear",e[r]=d+"Hours",e[s]=d+"Minutes",e[o]=d+"Seconds",e[i]=d+"Milliseconds",e)[l],g=l===a?this.$D+(n-this.$W):n;if(l===c||l===h){var f=this.clone().set(u,1);f.$d[p](g),f.init(),this.$d=f.set(u,Math.min(this.$D,f.daysInMonth())).$d}else p&&this.$d[p](g);return this.init(),this},v.set=function(t,n){return this.clone().$set(t,n)},v.get=function(t){return this[E.p(t)]()},v.add=function(i,d){var u,p=this;i=Number(i);var g=E.p(d),f=function(t){var n=M(p);return E.w(n.date(n.date()+Math.round(t*i)),p)};if(g===c)return this.set(c,this.$M+i);if(g===h)return this.set(h,this.$y+i);if(g===a)return f(1);if(g===l)return f(7);var m=(u={},u[s]=n,u[r]=e,u[o]=t,u)[g]||1,v=this.$d.getTime()+i*m;return E.w(v,this)},v.subtract=function(t,n){return this.add(-1*t,n)},v.format=function(t){var n=this,e=this.$locale();if(!this.isValid())return e.invalidDate||p;var i=t||"YYYY-MM-DDTHH:mm:ssZ",o=E.z(this),s=this.$H,r=this.$m,a=this.$M,l=e.weekdays,c=e.months,d=e.meridiem,h=function(t,e,o,s){return t&&(t[e]||t(n,i))||o[e].slice(0,s)},u=function(t){return E.s(s%12||12,t,"0")},g=d||function(t,n,e){var i=t<12?"AM":"PM";return e?i.toLowerCase():i};return i.replace(f,function(t,i){return i||function(t){switch(t){case"YY":return String(n.$y).slice(-2);case"YYYY":return E.s(n.$y,4,"0");case"M":return a+1;case"MM":return E.s(a+1,2,"0");case"MMM":return h(e.monthsShort,a,c,3);case"MMMM":return h(c,a);case"D":return n.$D;case"DD":return E.s(n.$D,2,"0");case"d":return String(n.$W);case"dd":return h(e.weekdaysMin,n.$W,l,2);case"ddd":return h(e.weekdaysShort,n.$W,l,3);case"dddd":return l[n.$W];case"H":return String(s);case"HH":return E.s(s,2,"0");case"h":return u(1);case"hh":return u(2);case"a":return g(s,r,!0);case"A":return g(s,r,!1);case"m":return String(r);case"mm":return E.s(r,2,"0");case"s":return String(n.$s);case"ss":return E.s(n.$s,2,"0");case"SSS":return E.s(n.$ms,3,"0");case"Z":return o}return null}(t)||o.replace(":","")})},v.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},v.diff=function(i,u,p){var g,f=this,m=E.p(u),v=M(i),w=(v.utcOffset()-this.utcOffset())*n,y=this-v,b=function(){return E.m(f,v)};switch(m){case h:g=b()/12;break;case c:g=b();break;case d:g=b()/3;break;case l:g=(y-w)/6048e5;break;case a:g=(y-w)/864e5;break;case r:g=y/e;break;case s:g=y/n;break;case o:g=y/t;break;default:g=y}return p?g:E.a(g)},v.daysInMonth=function(){return this.endOf(c).$D},v.$locale=function(){return b[this.$L]},v.locale=function(t,n){if(!t)return this.$L;var e=this.clone(),i=k(t,n,!0);return i&&(e.$L=i),e},v.clone=function(){return E.w(this.$d,this)},v.toDate=function(){return new Date(this.valueOf())},v.toJSON=function(){return this.isValid()?this.toISOString():null},v.toISOString=function(){return this.$d.toISOString()},v.toString=function(){return this.$d.toUTCString()},m}(),L=S.prototype;return M.prototype=L,[["$ms",i],["$s",o],["$m",s],["$H",r],["$W",a],["$M",c],["$y",h],["$D",u]].forEach(function(t){L[t[1]]=function(n){return this.$g(n,t[0],t[1])}}),M.extend=function(t,n){return t.$i||(t(n,S,M),t.$i=!0),M},M.locale=k,M.isDayjs=$,M.unix=function(t){return M(1e3*t)},M.en=b[y],M.Ls=b,M.p={},M}()),J.exports);const V=U(K);class Z{constructor(){_(this,r),L(this,"alert",(t,n="Alert")=>O(this,r,a).call(this,"alert",t,n,"classic")),L(this,"confirm",(t,n="Confirm")=>O(this,r,a).call(this,"confirm",t,n,"classic")),L(this,"prompt",(t,n="Prompt")=>O(this,r,a).call(this,"prompt",t,n,"classic")),L(this,"formatDate",(t,n)=>V(t).format(n))}}r=new WeakSet,a=function(t,n,e,i){const o={class:i,animation:"fade"};let s=!1;const r={alert:Y,confirm:W,prompt:P}[t],a={rgb:()=>(o.class="rgb",a),classic:()=>(o.class="classic",a),shake:()=>(o.animation="shake",a),run:()=>(o.animation="roadRunner",a),zoom:()=>(o.animation="zoom",a),then:(i,a)=>(s=!0,r[t](n,e,o).then(i,a))};return Promise.resolve().then(()=>{s||(s=!0,r[t](n,e,o))}),a},L(Z,"cssPath","");const Q=new Z;Object.assign(q,Q);let tt=(p=class{constructor(t=null,n="green"){_(this,h),_(this,l),_(this,c),_(this,d,!0),D(this,l,t),D(this,c,n),O(this,h,u).call(this)}initBAK(t,n="green"){D(this,l,t),D(this,c,n)}init(t,n="green"){return D(this,l,t),D(this,c,n),this}get log(){const t=`color: ${R(this,c)}; font-weight: bold;`;return R(this,l)?console.log.bind(console,`%c[${R(this,l)}]`,t):console.log.bind(console)}get warn(){return R(this,d)?R(this,l)?console.warn.bind(console,`%c[${R(this,l)}]`,"color: cyan; font-weight: bold;"):console.warn.bind(console):()=>{}}get error(){return R(this,l)?console.error.bind(console,`%c[${R(this,l)}]`,"color: red; font-weight: bold;"):console.error.bind(console)}enable(){D(this,d,!0)}disable(){D(this,d,!1)}},l=new WeakMap,c=new WeakMap,d=new WeakMap,h=new WeakSet,u=function(){if("undefined"==typeof window)return;"localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.startsWith("192.168.")?this.enable():(this.disable(),console.log(`%c[${R(this,l)||"Trace"}]%c 운영 모드: 로그 비활성화. %ctrace.enable()%c 로 활성화 가능`,"color: #4CAF50; font-weight: bold;","","background: #333; color: yellow; padding: 2px 5px;",""))},p);const nt=new tt;"undefined"!=typeof window&&(window.trace=nt);g=new WeakMap,f=new WeakMap,m=new WeakMap,v=new WeakSet,w=function(){if(0===R(this,f).length)return;const t=R(this,f).splice(0,R(this,f).length),n=new Set;t.forEach(t=>{const e=`${t.func.name}_${JSON.stringify(t.args)}`;n.has(e)||(t.func(...t.args),n.add(e))}),D(this,g,null)};class et extends nt.constructor{constructor(){super(),this.init("nine-util","green")}}const it=new et;class ot{static show(){let t=document.getElementById("global-loading-overlay");if(!t&&(t=document.createElement("div"),t.id="global-loading-overlay",t.style.cssText="\n position: fixed; inset: 0; z-index: 9999;\n background: rgba(0, 0, 0, 0.4); display: flex; \n justify-content: center; align-items: center;\n backdrop-filter: blur(2px);\n ",t.innerHTML='<div class="loading-spinner"></div>',document.body.appendChild(t),!document.getElementById("nine-util-style"))){const t=document.createElement("style");t.id="nine-util-style",t.innerHTML="\n .loading-spinner {\n width: 48px; height: 48px;\n border: 5px solid rgba(255, 255, 255, 0.3);\n border-top-color: white; border-radius: 50%;\n animation: nine-spin 1s linear infinite;\n }\n @keyframes nine-spin { to { transform: rotate(360deg); } }\n ",document.head.appendChild(t)}t.style.display="flex"}static hide(){const t=document.getElementById("global-loading-overlay");t&&(t.style.display="none")}}const st=class{};y=new WeakMap,L(st,"BASE_URL",window.__API_BASE_URL__||""),_(st,y,(t,n,e={},i=!0)=>{const o=n.startsWith("http")?n:`${st.BASE_URL}${n}`;i&&ot.show();const s={};e instanceof FormData||(s["Content-Type"]="application/json");const r={method:t,headers:s};let a=o;return"GET"===t?a+=`?${new URLSearchParams(e)}`:r.body=e instanceof FormData?e:JSON.stringify(e),fetch(a,r).then(async t=>{if(!t.ok){const n=await t.text();throw new Error(`API 오류 (${t.status}): ${n}`)}return t.json()}).catch(n=>{throw it.error(`[IdeFetch.${t.toLowerCase()}] ${o} 실패:`,n),n}).finally(()=>{i&&ot.hide()})}),L(st,"get",(t,n={},e=!0)=>{var i;return R(i=st,y).call(i,"GET",t,n,e)}),L(st,"post",(t,n={},e=!0)=>{var i;return R(i=st,y).call(i,"POST",t,n,e)}),L(st,"postMultipart",async(t,n=[],e={})=>{const{fileKey:i="fileContents",filePartName:o="files",jsonPartName:s="dataList",chunkSize:r=10}=e;ot.show();let a=0,l=null;return(async()=>{for(let e=0;e<n.length;e+=r){const c=new FormData,d=n.slice(e,e+r),h=[];d.forEach(t=>{const{[i]:n,_fileObj:e,...s}=t;h.push(s),n instanceof File&&c.append(o,n)});const u=new Blob([JSON.stringify(h)],{type:"application/json"});if(c.append(s,u),l=await st.post(t,c,!1),!l||!l.success&&"OK"!==l.status)throw new Error(`청크 전송 실패: ${e}번째 섹션`);a+=d.length}return{...l,success:!0,totalCount:a}})().catch(t=>{throw it.error("[postChunk] Error:",t),t}).finally(()=>{ot.hide()})});let rt=st;const at=rt;class lt extends HTMLElement{constructor(){super(),_(this,b),_(this,x,t=>{const n=t.previousElementSibling,e=t.nextElementSibling;if(!n||!e)return void D(this,b,this.classList.contains("h")?"h":"v");const i=n.getBoundingClientRect(),o=e.getBoundingClientRect();this.classList.contains("h")?D(this,b,"h"):this.classList.contains("v")?D(this,b,"v"):D(this,b,Math.abs(i.top-o.top)<5?"h":"v")}),_(this,$,t=>{t.preventDefault(),t.stopPropagation();const n=this.getBoundingClientRect(),e="h"===R(this,b),i=e?t.clientX-n.left:t.clientY-n.top,o=document.createElement("div");o.className=`nx-splitter-drag-bar-${R(this,b)}`,Object.assign(o.style,{position:"absolute",zIndex:"999",background:"#666",opacity:"0.6",pointerEvents:"none"});const s=this.getRootNode({composed:!0}),r=s instanceof ShadowRoot?s.host:this.parentElement,a=this.previousElementSibling,l=this.nextElementSibling;if(!r||!a||!l)return void it.warn("Spliter's parent or siblings not found.");(r.shadowRoot||r).appendChild(o);const c=o.offsetParent.getBoundingClientRect(),d=a.getBoundingClientRect(),h=l.getBoundingClientRect(),u=(e?n.left-c.left:n.top-c.top)+i;e?(o.style.top="0",o.style.left=`${u}px`,o.style.width="2px",o.style.height="100%"):(o.style.left="0",o.style.top=`${u}px`,o.style.height="2px",o.style.width="100%"),o.style.mixBlendMode="difference",o.style.zIndex="99999";const p=e?d.left-c.left:d.top-c.top,g=e?h.right-c.left-n.width:h.bottom-c.top-n.height,f=t=>{const n=e?t.clientX:t.clientY,i=e?n-c.left:n-c.top,s=Math.max(p,Math.min(i,g));e?o.style.left=`${s}px`:o.style.top=`${s}px`},m=()=>{window.removeEventListener("mousemove",f),window.removeEventListener("mouseup",m),o.remove();const t=Array.from(r.children),n=t.filter(t=>"nx-splitter"!==t.tagName.toLowerCase()),i=window.getComputedStyle(r),s=e?i.getPropertyValue("column-gap"):i.getPropertyValue("row-gap"),c=parseFloat(s)||0,d=(t.length>1?t.length-1:0)*c,h=(e?parseFloat(o.style.left):parseFloat(o.style.top))-u,p=e?a.getBoundingClientRect().width:a.getBoundingClientRect().height,g=e?l.getBoundingClientRect().width:l.getBoundingClientRect().height;let v=p+h,w=g-h;v<0&&(w+=v,v=0),w<0&&(v+=w,w=0);const y=n.map(t=>e?t.getBoundingClientRect().width:t.getBoundingClientRect().height),b=t.reduce((t,n)=>"nx-splitter"===n.tagName.toLowerCase()?t+(e?n.getBoundingClientRect().width:n.getBoundingClientRect().height):t,0),x=(e?r.getBoundingClientRect().width:r.getBoundingClientRect().height)-b-d;let $=0;n.forEach((t,n)=>{let e;e=t===a?v:t===l?w:y[n];const i=e/x;it.log(t),t.classList.contains("sidebar")?t.style.flex=`0 0 ${e}px`:t.style.flex=`${i} ${i} 0`,$+=i}),it.log(`dragOffset: ${h}`),it.log(`Calculated FlexSum: ${$}`)};window.addEventListener("mousemove",f),window.addEventListener("mouseup",m)}),_(this,k,()=>{R(this,x).call(this,this),this.classList.add(R(this,b));const t=this.innerHTML.trim(),n=""===t?'<div class="grip"></div>':`<div class="grip"></div><div class="inner-container">${t}</div><div class="grip"></div>`;this.innerHTML="";const e=document.createElement("template");e.innerHTML=`\n\t\t\t<style>\n\t\t\t\t@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@0.9.151/dist/css/nine-util.css";\n\t\t\t\t${this.cssPath?`@import "${this.cssPath}";`:""}\n\t\t\t</style>\n\t\t\t${n}\n `,this.shadowRoot.appendChild(e.content.cloneNode(!0)),this.shadowRoot.querySelectorAll(".grip").forEach(t=>{t.addEventListener("mousedown",t=>R(this,$).call(this,t))}),R(this,M).call(this),window.addEventListener("resize",()=>R(this,M).call(this))}),_(this,M,()=>{const t="h"===R(this,b),n=this.parentElement,e=Array.from(n.children).filter(t=>"nx-splitter"!==t.tagName.toLowerCase());if(e.length<2)return;const i=n.getBoundingClientRect(),o=e.reduce((n,e)=>n+(t?e.getBoundingClientRect().width:e.getBoundingClientRect().height),0),s=t?i.width:i.height;e.forEach(n=>{const e=t?n.getBoundingClientRect().width:n.getBoundingClientRect().height,i=s*(e/o)/s;n.style.flex=`${i} ${i} 0`})}),this.attachShadow({mode:"open"})}connectedCallback(){R(this,k).call(this)}get cssPath(){return this.getAttribute("css-path")||Z.cssPath}}b=new WeakMap,x=new WeakMap,$=new WeakMap,k=new WeakMap,M=new WeakMap,customElements.get("nine-splitter")||customElements.define("nine-splitter",lt),q.safe=async t=>{try{return[await t,null]}catch(n){return[null,n]}},q.api=at,q.trace=nt,q.subscribeConfig=I,q.config=F||{},"undefined"!=typeof window&&(window.nine=q),t.Fetch=rt,t.NineUtil=Z,t.TaskDebouncer=class{constructor(t=50){_(this,v),_(this,g,null),_(this,f,[]),_(this,m),D(this,m,t)}exec(t,...n){R(this,f).push({func:t,args:n}),R(this,g)&&clearTimeout(R(this,g)),D(this,g,setTimeout(()=>O(this,v,w).call(this),R(this,m)))}execWithKey(t,n,...e){D(this,f,R(this,f).filter(n=>n.key!==t)),R(this,f).push({key:t,func:n,args:e}),R(this,g)&&clearTimeout(R(this,g)),D(this,g,setTimeout(()=>O(this,v,w).call(this),R(this,m)))}},t.Trace=tt,t.api=at,t.config=F,t.loading=ot,t.nine=q,t.nineAlertPopup=Y,t.nineConfirmPopup=W,t.nineDialog=T,t.ninePromptPopup=P,t.subscribeConfig=I,t.trace=nt,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
1
+ !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self)["nine-util"]={})}(this,function(t){"use strict";var n,e,i,o,s,r,a,l,c,d,h,u,p,g,f,m,v,w,y,b,x,$,k,M,E=Object.defineProperty,S=t=>{throw TypeError(t)},L=(t,n,e)=>((t,n,e)=>n in t?E(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e)(t,"symbol"!=typeof n?n+"":n,e),C=(t,n,e)=>n.has(t)||S("Cannot "+e),R=(t,n,e)=>(C(t,n,"read from private field"),e?e.call(t):n.get(t)),_=(t,n,e)=>n.has(t)?S("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(t):n.set(t,e),D=(t,n,e,i)=>(C(t,n,"write to private field"),i?i.call(t,e):n.set(t,e),e),O=(t,n,e)=>(C(t,n,"access private method"),e);class T extends HTMLElement{constructor(){super(),_(this,n),_(this,e),L(this,"showModal",()=>{R(this,e).showModal()}),L(this,"close",()=>{R(this,e).close(),this.remove()}),_(this,i,()=>{const t=this.querySelector(".head");t&&(t.addEventListener("mousedown",R(this,o)),t.addEventListener("touchstart",R(this,s))),this.querySelectorAll(".close, .close2, .cancel").forEach(t=>{t.onclick=()=>this.closeWithAnimation(null)}),this.querySelectorAll(".ok").forEach(t=>{})}),_(this,o,t=>{if(t.target.closest("buttons"))return;if(0!==t.button||t.altKey||t.ctrlKey||t.shiftKey)return;const i=R(this,e).getBoundingClientRect();D(this,n,{x:t.clientX-i.left,y:t.clientY-i.top});const o=t=>{R(this,e).style.position="fixed",R(this,e).style.margin="0",R(this,e).style.left=t.clientX-R(this,n).x+"px",R(this,e).style.top=t.clientY-R(this,n).y+"px"},s=()=>{document.removeEventListener("mousemove",o),document.removeEventListener("mouseup",s)};document.addEventListener("mousemove",o),document.addEventListener("mouseup",s)}),_(this,s,t=>{if(t.target.closest("buttons"))return;const i=R(this,e).getBoundingClientRect(),o=t.changedTouches[0];D(this,n,{x:o.pageX-i.left,y:o.pageY-i.top});const s=t=>{const i=t.changedTouches[0];R(this,e).style.position="fixed",R(this,e).style.margin="0",R(this,e).style.left=i.pageX-R(this,n).x+"px",R(this,e).style.top=i.pageY-R(this,n).y+"px"},r=()=>{document.removeEventListener("touchmove",s),document.removeEventListener("touchend",r)};document.addEventListener("touchmove",s),document.addEventListener("touchend",r)})}connectedCallback(){const t=this.innerHTML,n=this.getAttribute("subject")||"Details";this.innerHTML=`\n\t\t\t<style>\n\tdialog::backdrop {\n\t\tbackground: rgba(0, 0, 0, 0.3);\n\t}\n\t\n\tdialog:modal {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tpadding: 0;\n\t\toverflow: hidden;\n\t\tborder: 1px solid darkgreen;\n\t\toutline: none;\n\t\tresize: both;\n\t\tbox-shadow: 0 0 4px 0 darkgreen;\n width: 500px;\n height: fit-content;\n min-width: 330px;\n min-height: 60px;\n max-height: 100%;\n }\n \n \n \n \n\tdiv.head .rect1, div.head .rect2, div.head .rect3 {\n\t\tdisplay: none;\n\t\twidth: 50px;\n\t\theight: 100%;\n\t}\n\tdiv.head .rect1 {\n\t\tbackground-color: red;\n\t}\n\tdiv.head .rect2 {\n\t\tbackground-color: darkgreen;\n\t}\n\tdiv.head .rect3 {\n\t\tbackground-color: olive;\n\t}\n\t\n\tdiv.head {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\t--height: 30px;\n\t\tbackground-color: darkgreen;\n\t\tpadding: 4px;\n\t\tcursor: move;\n\t}\n\tdiv.head:hover {\n\t\tfilter: brightness(110%);\n\t}\n\t\n\tdiv.head span {\n\t\tfont-size: 12px;\n\t\tposition: relative;\n\t}\n\t\n\tdiv.head span.title {\n\t\tcolor: #ddd;\n\t\tmargin-left: 4px;\n\t\tfont-weight: bold;\n\t}\n\t\n\tdiv.head span.sub-title {\n\t\tcolor: #ccc;\n\t\tmargin-left: 8px;\n\t\tfont-style: italic;\n\t}\n\t\n\tdiv.head form {\n\t\tmargin: 0;\n\t}\n\tdiv.head button {\n\t\tmargin-right: 4px;\n\t\tbackground-color: transparent;\n\t\tborder: none;\n\t\tcolor: #ccc;\n\t\tfont-size: x-small;\n\t}\n\tdiv.head button:hover {\n\t\tcursor: pointer;\n\t}\n\t\n\tdiv.contents {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\toverflow: hidden;\n\t}\n\tdiv.left {\n\t\tposition: relative;\n\t\twidth: 16px;\n\t\theight: 100%;\n\t\tbackground-color: #ddd;\n\t\tdisplay: none;\n\t}\n\t\n\tdiv.left span {\n\t\twriting-mode: vertical-rl;\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t\tuser-select: none;\n\t\tcolor: #ccc;\n\t\tfont-weight: 700;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tmargin-left: 3px;\n\t\tmargin-top: 3px;\n\t}\n\tdiv.close2 {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\tright: 0;\n\t\ttop: 3px;\n\t\tcursor: pointer;\n\t\tcolor: #666;\n\t}\n\tdiv.close2 svg:hover {\n\t\tcolor: #999;\n\t}\n\t\n\tdiv.body {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: unset;\n\t\t--border: 3px solid #999;\n\t\t--border-top: none;\n\t\toverflow-x: hidden;\n\t\toverflow-y: auto;\n\t\tpadding: 10px;\n\t\tgap: 8px;\n\t\tflex-direction: column;\n\t}\n\t\n\t\n\t\n\t\n\tng-sphere.icon {\n\t\tmargin-left: 8px;\n\t}\n\t\n\t.buttons {\n\t\tdisplay: flex;\n\t\tposition: absolute;\n\t\tright: 4px;\n\t}\n\t\n\tng-sphere {\n\t\tposition: relative;\n\t\t--width: 16px;\n\t\t--height: 16px;\n\t\tcursor: pointer;\n\t\tmargin-right: 4px;\n\t\tdisplay: flex;\n\t}\n\tng-sphere:hover {\n\t\tfilter: brightness(90%);\n\t}\n\tng-sphere:active {\n\t\tfilter: brightness(80%);\n\t}\n\t\n\tng-sphere:hover::after {\n\t\tcontent: "";\n\t\tposition: absolute;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: center;\n\t}\n\tng-sphere.apply:hover::after {\n\t\tbackground-size: 14px 14px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><polyline points="2.5,7 6,10 11,3" style="fill:none;stroke:white;stroke-width:2px;" /></svg>');\n\t}\n\t\n\tng-sphere.reset:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true"><path d="M10 5h5V0"></path><path d="M15 8a6.957 6.957 0 0 1-7 7 6.957 6.957 0 0 1-7-7 6.957 6.957 0 0 1 7-7 6.87 6.87 0 0 1 6.3 4"></path></svg>');\n\t}\n\t\n\tng-sphere.close:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true" viewBox="0 0 16 16"><path d="M2 2l12 12M14 2L2 14"></path></svg>');\n\t}\n\t\n\t\n\tbutton {\n cursor: pointer;\n }\n \n .input-area {\n position: relative;\n height: 100%;\n --display: flex;\n textarea {\n width: 100%;\n height: 100%;\n min-height: 100px;\n padding: 8px;\n box-sizing: border-box;\n resize: none;\n border-radius: 2px;\n border-color: #ccc;\n }\n textarea:focus {\n border-color: green;\n outline: none; /* 브라우저 기본 파란색 테두리 제거 */\n }\n }\n \n .buttons-confirm {\n position: absolute;\n display: flex;\n justify-content: flex-end;\n bottom: 8px;\n right: 8px;\n }\n \n \n .buttons-confirm button {\n height: 32px;\n margin-right: 8px;\n border: none;\n outline: none;\n width: 60px;\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n }\n .buttons-confirm button:hover {\n filter: brightness(90%);\n }\n .buttons-confirm button:active {\n color: #ccc;\n }\n \n button.ok {\n --display: none;\n background-color: darkgreen;\n color: white;\n }\n button.cancel {\n color: white;\n background-color: #6c757d;\n }\n \n \n \n div.msg {\n position: relative;\n height: 100%;\n font-size: 14px;\n color: #333;\n padding-bottom: 48px;\n }\n \n .reset, .apply {\n display: none;\n }\n \n \n \n :host(.classic) dialog:modal {\n border: 1px solid #007bff;\n box-shadow: 0 0 4px 0 #007bff;\n }\n \n :host(.classic) div.head {\n background-color: #007bff;\n }\n :host(.classic) div.head:hover {\n filter: brightness(110%);\n }\n \n :host(.classic) div.head span {\n font-size: 12px;\n }\n \n :host(.classic) div.head span.title {\n color: #ddd;\n margin-left: 4px;\n font-weight: bold;\n }\n \n :host(.classic) div.head span.sub-title {\n color: #ccc;\n margin-left: 8px;\n font-style: italic;\n }\n :host(.classic) div.head button {\n margin-right: 4px;\n background-color: transparent;\n border: none;\n color: #ccc;\n font-size: x-small;\n }\n \n \n \n \n :host(.rgb) dialog:modal {\n border: none;\n box-shadow: unset;\n border-top: none;\n }\n \n :host(.rgb) div.left {\n display: block;\n background-color: #ddd;\n }\n :host(.rgb) div.left span {\n color: #ccc;\n }\n :host(.rgb) div.close2 {\n display: block;\n color: #666;\n }\n :host(.rgb) div.close2 svg:hover {\n color: #999;\n }\n :host(.rgb) div.head {\n height: 4px;\n background-color: #999;\n padding: 0;\n }\n :host(.rgb) div.contents {\n height: calc(100% - 4px);\n }\n \n :host(.rgb) div.head ng-sphere,\n :host(.rgb) div.head span,\n :host(.rgb) div.head .buttons {\n display: none;\n }\n \n :host(.rgb) div.head .rect1,\n :host(.rgb) div.head .rect2,\n :host(.rgb) div.head .rect3 {\n display: flex;\n }\n \n \n :host(.rgb) div.head:hover {\n filter: unset;\n }\n \n \n /* --- Animation Core --- */\n:host {\n --nx-duration: 0.4s;\n --nx-timing: cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n\n/* 🎯 수정: 애니메이션 클래스가 붙은 경우에만 초기 opacity를 0으로 설정 */\n:host(.fade) dialog,\n:host(.zoom) dialog,\n:host(.moveUp) dialog,\n:host(.moveDown) dialog,\n:host(.moveLeft) dialog,\n:host(.moveRight) dialog,\n:host(.roadRunner) dialog {\n opacity: 0;\n}\n\n/* shake는 애니메이션 내부에서 opacity를 다루므로 제외하거나 별도 처리 */\n:host(.shake) dialog { \n opacity: 1; \n}\n\n/* 1. Fade (서서히 나타남) */\n:host(.fade) dialog { animation: nx-fade-in var(--nx-duration) forwards; }\n@keyframes nx-fade-in { from { opacity: 0; } to { opacity: 1; } }\n\n/* 2. Zoom (커지며 나타남) */\n:host(.zoom) dialog { animation: nx-zoom-in var(--nx-duration) var(--nx-timing) forwards; }\n@keyframes nx-zoom-in { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } }\n\n/* 3. Slide (상하좌우) */\n:host(.moveUp) dialog { animation: nx-move-up var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveDown) dialog { animation: nx-move-down var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveLeft) dialog { animation: nx-move-left var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveRight) dialog { animation: nx-move-right var(--nx-duration) var(--nx-timing) forwards; }\n\n@keyframes nx-move-up { from { opacity: 0; transform: translateY(100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-down { from { opacity: 0; transform: translateY(-100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-left { from { opacity: 0; transform: translateX(100px); } to { opacity: 1; transform: translateX(0); } }\n@keyframes nx-move-right { from { opacity: 0; transform: translateX(-100px); } to { opacity: 1; transform: translateY(0); } }\n\n/* 4. Shake (상하좌우 격렬한 진동 - 에러 인지용) */\n:host(.shake) dialog { \n animation: nx-heavy-shake 0.5s cubic-bezier(.36,.07,.19,.97) both;\n opacity: 1; \n}\n\n@keyframes nx-heavy-shake {\n 10%, 90% { transform: translate3d(-1px, -2px, 0); }\n 20%, 80% { transform: translate3d(2px, 4px, 0); }\n 30%, 50%, 70% { transform: translate3d(-6px, -6px, 0); }\n 40%, 60% { transform: translate3d(6px, 6px, 0); }\n}\n\n/* 5. Road Runner (등장: 왼쪽에서 탄력 있게 / 퇴장: 움츠렸다가 광속 탈출) */\n:host(.roadRunner) dialog { \n animation: roadRunnerIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; \n}\n\n@keyframes roadRunnerIn {\n 0% { transform: translateX(-1500px) skewX(30deg); opacity: 1; }\n 70% { transform: translateX(30px) skewX(-10deg); opacity: 1; }\n 100% { transform: translateX(0) skewX(0deg); opacity: 1; }\n}\n\n/* --- Out Animations (닫힐 때) --- */\ndialog.out { pointer-events: none; }\n\n/* Road Runner 퇴장: 슥 움츠렸다가(Anticipation) 쌩~! */\n:host(.roadRunner) dialog.out { \n animation: roadRunnerOut 0.5s cubic-bezier(0.6, -0.28, 0.735, 0.045) forwards; \n}\n\n@keyframes roadRunnerOut {\n 0% { \n transform: translateX(0) scale(1) skewX(0deg); \n opacity: 1; \n }\n 30% { \n /* 예비 동작: 뒤로 살짝 갔다가 움츠러들기 */\n transform: translateX(50px) scaleX(1.2) scaleY(0.8) skewX(-20deg); \n opacity: 1; \n }\n 100% { \n /* 발사: 길게 늘어나며 광속 탈출 */\n transform: translateX(2000px) scaleX(4) scaleY(0.3) skewX(50deg); \n opacity: 0; \n filter: blur(10px); /* 👈 잔상 느낌 추가 */\n }\n}\n\n/* 일반 퇴장 (기본) */\ndialog.out { animation: nx-fade-out 0.3s forwards; }\n@keyframes nx-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.9); } }\n</style>\n\t\t\n\t\t\t<dialog>\n\t\t\t\t<div class="head">\n\t\t\t\t\t<div class="rect1"></div>\n\t\t\t\t\t<div class="rect2"></div>\n\t\t\t\t\t<div class="rect3"></div>\n\t\t\t\t\t<ng-sphere class="icon" end-fill="#666" size="8"></ng-sphere>\n\t\t\t\t\t<span class="title">${n}</span>\n\t\t\t\t\t<span class="sub-title"></span>\n\t\t\t\t\t<div class="buttons">\n\t\t\t\t\t\t<ng-sphere class="apply" start-fill="#cc6" end-fill="#660" size="16" title="apply"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="reset" start-fill="#99f" end-fill="#00f" size="16" title="reset"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="close" start-fill="#f99" end-fill="#f00" size="16" title="close"></ng-sphere>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="contents">\n\t\t\t\t\t<div class="left">\n\t\t\t\t\t\t<span>가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="body">\n\t\t\t\t\t\t${t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="close2">\n\t\t\t\t\t\t<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">\n\t\t\t\t\t\t\t<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</dialog>\n\t\t`,D(this,e,this.querySelector("dialog")),R(this,i).call(this)}closeWithAnimation(t){R(this,e).classList.add("out"),setTimeout(()=>{R(this,e).close(),this.dispatchEvent(new CustomEvent("closed",{detail:t})),this.remove()},300)}}n=new WeakMap,e=new WeakMap,i=new WeakMap,o=new WeakMap,s=new WeakMap;class B extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}static async open(t,n,e,i,o){var s,r,a;const l=t.tagName.toLowerCase(),c={"true-text":"확인","false-text":"취소",class:"classic",animation:"fade",...(null==(a=null==(r=null==(s=window.nine)?void 0:s.config)?void 0:r.ux)?void 0:a[l.replace("nine-","").replace("-popup","")])||{},...i};document.querySelectorAll(l).forEach(t=>t.remove());const d=document.createElement(l);c.class&&d.classList.add(c.class),c.animation&&d.classList.add(c.animation),document.body.appendChild(d),o(d,n,c);const h=d.shadowRoot.querySelector("nine-dialog");return e&&h.setAttribute("subject",e),new Promise(t=>{h.addEventListener("closed",n=>t(n.detail)),d.setupEvents(t,h),h.showModal()})}}customElements.get("nine-dialog")||customElements.define("nine-dialog",T);const A=class extends B{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(!0)}};L(A,"tagName","nine-confirm-popup"),L(A,"confirm",(t,n,e)=>B.open(A,t,n,e,(t,n,e)=>t.render(n,e)));let W=A;const z=class extends B{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">확인</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){}};L(z,"tagName","nine-alert-popup"),L(z,"alert",(t,n,e)=>B.open(z,t,n,e,(t,n,e)=>t.render(n,e)));let Y=z;customElements.get("nine-confirm-popup")||customElements.define("nine-confirm-popup",W),customElements.get("nine-alert-popup")||customElements.define("nine-alert-popup",Y);const N=class extends B{constructor(){super()}render(t,n){trace.log(this),trace.log(this.shadowRoot),this.shadowRoot.innerHTML=`\n\t\t\t<style>\n\t\t\t\tdialog {\n\t\t\t\t\theight: 300px !important;\n\t\t\t\t}\n\t\t\t\t.msg {\n\t\t\t\t\theight: unset !important;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="input-area">\n <textarea placeholder="내용을 입력하세요..."></textarea>\n </div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){const e=this.shadowRoot.querySelector("textarea");this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(e.value),requestAnimationFrame(()=>e.focus())}};L(N,"tagName","nine-prompt-popup"),L(N,"prompt",(t,n,e)=>B.open(N,t,n,e,(t,n,e)=>t.render(n,e)));let P=N;customElements.get("nine-prompt-popup")||customElements.define("nine-prompt-popup",P);const H=new Set,j={ux:{nativeOverride:!1,theme:"light"},board:{readOnly:!1},cssPath:"",debug:!1};"undefined"==typeof window||window.__NINE_GLOBAL_CONFIG__||(window.__NINE_GLOBAL_CONFIG__=j);const X="undefined"!=typeof window?window.__NINE_GLOBAL_CONFIG__:j,I=t=>(H.add(t),t("all",X),()=>H.delete(t)),F=new Proxy(X,{set:(t,n,e)=>(t[n]=e,H.forEach(e=>e(n,t)),!0),get:(t,n)=>t[n]}),q={config:F,get cssPath(){return this.config.cssPath||""},setup(t={}){Object.entries(t).forEach(([t,n])=>{"object"!=typeof n||null===n||Array.isArray(n)?this.config[t]=n:this.config[t]={...this.config[t],...n}}),"undefined"!=typeof window&&(window.nine=window.nine||this)}};function U(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var G,J={exports:{}};var K=(G||(G=1,J.exports=function(){var t=1e3,n=6e4,e=36e5,i="millisecond",o="second",s="minute",r="hour",a="day",l="week",c="month",d="quarter",h="year",u="date",p="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,f=/\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var n=["th","st","nd","rd"],e=t%100;return"["+t+(n[(e-20)%10]||n[e]||n[0])+"]"}},v=function(t,n,e){var i=String(t);return!i||i.length>=n?t:""+Array(n+1-i.length).join(e)+t},w={s:v,z:function(t){var n=-t.utcOffset(),e=Math.abs(n),i=Math.floor(e/60),o=e%60;return(n<=0?"+":"-")+v(i,2,"0")+":"+v(o,2,"0")},m:function t(n,e){if(n.date()<e.date())return-t(e,n);var i=12*(e.year()-n.year())+(e.month()-n.month()),o=n.clone().add(i,c),s=e-o<0,r=n.clone().add(i+(s?-1:1),c);return+(-(i+(e-o)/(s?o-r:r-o))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:h,w:l,d:a,D:u,h:r,m:s,s:o,ms:i,Q:d}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},y="en",b={};b[y]=m;var x="$isDayjsObject",$=function(t){return t instanceof S||!(!t||!t[x])},k=function t(n,e,i){var o;if(!n)return y;if("string"==typeof n){var s=n.toLowerCase();b[s]&&(o=s),e&&(b[s]=e,o=s);var r=n.split("-");if(!o&&r.length>1)return t(r[0])}else{var a=n.name;b[a]=n,o=a}return!i&&o&&(y=o),o||!i&&y},M=function(t,n){if($(t))return t.clone();var e="object"==typeof n?n:{};return e.date=t,e.args=arguments,new S(e)},E=w;E.l=k,E.i=$,E.w=function(t,n){return M(t,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var S=function(){function m(t){this.$L=k(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[x]=!0}var v=m.prototype;return v.parse=function(t){this.$d=function(t){var n=t.date,e=t.utc;if(null===n)return new Date(NaN);if(E.u(n))return new Date;if(n instanceof Date)return new Date(n);if("string"==typeof n&&!/Z$/i.test(n)){var i=n.match(g);if(i){var o=i[2]-1||0,s=(i[7]||"0").substring(0,3);return e?new Date(Date.UTC(i[1],o,i[3]||1,i[4]||0,i[5]||0,i[6]||0,s)):new Date(i[1],o,i[3]||1,i[4]||0,i[5]||0,i[6]||0,s)}}return new Date(n)}(t),this.init()},v.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},v.$utils=function(){return E},v.isValid=function(){return!(this.$d.toString()===p)},v.isSame=function(t,n){var e=M(t);return this.startOf(n)<=e&&e<=this.endOf(n)},v.isAfter=function(t,n){return M(t)<this.startOf(n)},v.isBefore=function(t,n){return this.endOf(n)<M(t)},v.$g=function(t,n,e){return E.u(t)?this[n]:this.set(e,t)},v.unix=function(){return Math.floor(this.valueOf()/1e3)},v.valueOf=function(){return this.$d.getTime()},v.startOf=function(t,n){var e=this,i=!!E.u(n)||n,d=E.p(t),p=function(t,n){var o=E.w(e.$u?Date.UTC(e.$y,n,t):new Date(e.$y,n,t),e);return i?o:o.endOf(a)},g=function(t,n){return E.w(e.toDate()[t].apply(e.toDate("s"),(i?[0,0,0,0]:[23,59,59,999]).slice(n)),e)},f=this.$W,m=this.$M,v=this.$D,w="set"+(this.$u?"UTC":"");switch(d){case h:return i?p(1,0):p(31,11);case c:return i?p(1,m):p(0,m+1);case l:var y=this.$locale().weekStart||0,b=(f<y?f+7:f)-y;return p(i?v-b:v+(6-b),m);case a:case u:return g(w+"Hours",0);case r:return g(w+"Minutes",1);case s:return g(w+"Seconds",2);case o:return g(w+"Milliseconds",3);default:return this.clone()}},v.endOf=function(t){return this.startOf(t,!1)},v.$set=function(t,n){var e,l=E.p(t),d="set"+(this.$u?"UTC":""),p=(e={},e[a]=d+"Date",e[u]=d+"Date",e[c]=d+"Month",e[h]=d+"FullYear",e[r]=d+"Hours",e[s]=d+"Minutes",e[o]=d+"Seconds",e[i]=d+"Milliseconds",e)[l],g=l===a?this.$D+(n-this.$W):n;if(l===c||l===h){var f=this.clone().set(u,1);f.$d[p](g),f.init(),this.$d=f.set(u,Math.min(this.$D,f.daysInMonth())).$d}else p&&this.$d[p](g);return this.init(),this},v.set=function(t,n){return this.clone().$set(t,n)},v.get=function(t){return this[E.p(t)]()},v.add=function(i,d){var u,p=this;i=Number(i);var g=E.p(d),f=function(t){var n=M(p);return E.w(n.date(n.date()+Math.round(t*i)),p)};if(g===c)return this.set(c,this.$M+i);if(g===h)return this.set(h,this.$y+i);if(g===a)return f(1);if(g===l)return f(7);var m=(u={},u[s]=n,u[r]=e,u[o]=t,u)[g]||1,v=this.$d.getTime()+i*m;return E.w(v,this)},v.subtract=function(t,n){return this.add(-1*t,n)},v.format=function(t){var n=this,e=this.$locale();if(!this.isValid())return e.invalidDate||p;var i=t||"YYYY-MM-DDTHH:mm:ssZ",o=E.z(this),s=this.$H,r=this.$m,a=this.$M,l=e.weekdays,c=e.months,d=e.meridiem,h=function(t,e,o,s){return t&&(t[e]||t(n,i))||o[e].slice(0,s)},u=function(t){return E.s(s%12||12,t,"0")},g=d||function(t,n,e){var i=t<12?"AM":"PM";return e?i.toLowerCase():i};return i.replace(f,function(t,i){return i||function(t){switch(t){case"YY":return String(n.$y).slice(-2);case"YYYY":return E.s(n.$y,4,"0");case"M":return a+1;case"MM":return E.s(a+1,2,"0");case"MMM":return h(e.monthsShort,a,c,3);case"MMMM":return h(c,a);case"D":return n.$D;case"DD":return E.s(n.$D,2,"0");case"d":return String(n.$W);case"dd":return h(e.weekdaysMin,n.$W,l,2);case"ddd":return h(e.weekdaysShort,n.$W,l,3);case"dddd":return l[n.$W];case"H":return String(s);case"HH":return E.s(s,2,"0");case"h":return u(1);case"hh":return u(2);case"a":return g(s,r,!0);case"A":return g(s,r,!1);case"m":return String(r);case"mm":return E.s(r,2,"0");case"s":return String(n.$s);case"ss":return E.s(n.$s,2,"0");case"SSS":return E.s(n.$ms,3,"0");case"Z":return o}return null}(t)||o.replace(":","")})},v.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},v.diff=function(i,u,p){var g,f=this,m=E.p(u),v=M(i),w=(v.utcOffset()-this.utcOffset())*n,y=this-v,b=function(){return E.m(f,v)};switch(m){case h:g=b()/12;break;case c:g=b();break;case d:g=b()/3;break;case l:g=(y-w)/6048e5;break;case a:g=(y-w)/864e5;break;case r:g=y/e;break;case s:g=y/n;break;case o:g=y/t;break;default:g=y}return p?g:E.a(g)},v.daysInMonth=function(){return this.endOf(c).$D},v.$locale=function(){return b[this.$L]},v.locale=function(t,n){if(!t)return this.$L;var e=this.clone(),i=k(t,n,!0);return i&&(e.$L=i),e},v.clone=function(){return E.w(this.$d,this)},v.toDate=function(){return new Date(this.valueOf())},v.toJSON=function(){return this.isValid()?this.toISOString():null},v.toISOString=function(){return this.$d.toISOString()},v.toString=function(){return this.$d.toUTCString()},m}(),L=S.prototype;return M.prototype=L,[["$ms",i],["$s",o],["$m",s],["$H",r],["$W",a],["$M",c],["$y",h],["$D",u]].forEach(function(t){L[t[1]]=function(n){return this.$g(n,t[0],t[1])}}),M.extend=function(t,n){return t.$i||(t(n,S,M),t.$i=!0),M},M.locale=k,M.isDayjs=$,M.unix=function(t){return M(1e3*t)},M.en=b[y],M.Ls=b,M.p={},M}()),J.exports);const V=U(K);class Z{constructor(){_(this,r),L(this,"alert",(t,n="Alert")=>O(this,r,a).call(this,"alert",t,n,"classic")),L(this,"confirm",(t,n="Confirm")=>O(this,r,a).call(this,"confirm",t,n,"classic")),L(this,"prompt",(t,n="Prompt")=>O(this,r,a).call(this,"prompt",t,n,"classic")),L(this,"formatDate",(t,n)=>V(t).format(n))}}r=new WeakSet,a=function(t,n,e,i){const o={class:i,animation:"fade"};let s=!1;const r={alert:Y,confirm:W,prompt:P}[t],a={rgb:()=>(o.class="rgb",a),classic:()=>(o.class="classic",a),shake:()=>(o.animation="shake",a),run:()=>(o.animation="roadRunner",a),zoom:()=>(o.animation="zoom",a),then:(i,a)=>(s=!0,r[t](n,e,o).then(i,a))};return Promise.resolve().then(()=>{s||(s=!0,r[t](n,e,o))}),a},L(Z,"cssPath","");const Q=new Z;Object.assign(q,Q);let tt=(p=class{constructor(t=null,n="green"){_(this,h),_(this,l),_(this,c),_(this,d,!0),D(this,l,t),D(this,c,n),O(this,h,u).call(this)}initBAK(t,n="green"){D(this,l,t),D(this,c,n)}init(t,n="green"){return D(this,l,t),D(this,c,n),this}get log(){const t=`color: ${R(this,c)}; font-weight: bold;`;return R(this,l)?console.log.bind(console,`%c[${R(this,l)}]`,t):console.log.bind(console)}get warn(){return R(this,d)?R(this,l)?console.warn.bind(console,`%c[${R(this,l)}]`,"color: cyan; font-weight: bold;"):console.warn.bind(console):()=>{}}get error(){return R(this,l)?console.error.bind(console,`%c[${R(this,l)}]`,"color: red; font-weight: bold;"):console.error.bind(console)}enable(){D(this,d,!0)}disable(){D(this,d,!1)}},l=new WeakMap,c=new WeakMap,d=new WeakMap,h=new WeakSet,u=function(){if("undefined"==typeof window)return;"localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.startsWith("192.168.")?this.enable():(this.disable(),console.log(`%c[${R(this,l)||"Trace"}]%c 운영 모드: 로그 비활성화. %ctrace.enable()%c 로 활성화 가능`,"color: #4CAF50; font-weight: bold;","","background: #333; color: yellow; padding: 2px 5px;",""))},p);const nt=new tt;"undefined"!=typeof window&&(window.trace=nt);g=new WeakMap,f=new WeakMap,m=new WeakMap,v=new WeakSet,w=function(){if(0===R(this,f).length)return;const t=R(this,f).splice(0,R(this,f).length),n=new Set;t.forEach(t=>{const e=`${t.func.name}_${JSON.stringify(t.args)}`;n.has(e)||(t.func(...t.args),n.add(e))}),D(this,g,null)};class et extends nt.constructor{constructor(){super(),this.init("nine-util","green")}}const it=new et;class ot{static show(){let t=document.getElementById("global-loading-overlay");if(!t&&(t=document.createElement("div"),t.id="global-loading-overlay",t.style.cssText="\n position: fixed; inset: 0; z-index: 9999;\n background: rgba(0, 0, 0, 0.4); display: flex; \n justify-content: center; align-items: center;\n backdrop-filter: blur(2px);\n ",t.innerHTML='<div class="loading-spinner"></div>',document.body.appendChild(t),!document.getElementById("nine-util-style"))){const t=document.createElement("style");t.id="nine-util-style",t.innerHTML="\n .loading-spinner {\n width: 48px; height: 48px;\n border: 5px solid rgba(255, 255, 255, 0.3);\n border-top-color: white; border-radius: 50%;\n animation: nine-spin 1s linear infinite;\n }\n @keyframes nine-spin { to { transform: rotate(360deg); } }\n ",document.head.appendChild(t)}t.style.display="flex"}static hide(){const t=document.getElementById("global-loading-overlay");t&&(t.style.display="none")}}const st=class{};y=new WeakMap,L(st,"BASE_URL",window.__API_BASE_URL__||""),_(st,y,(t,n,e={},i=!0)=>{const o=n.startsWith("http")?n:`${st.BASE_URL}${n}`;i&&ot.show();const s={};e instanceof FormData||(s["Content-Type"]="application/json");const r={method:t,headers:s};let a=o;return"GET"===t?a+=`?${new URLSearchParams(e)}`:r.body=e instanceof FormData?e:JSON.stringify(e),fetch(a,r).then(async t=>{if(!t.ok){const n=await t.text();throw new Error(`API 오류 (${t.status}): ${n}`)}return t.json()}).catch(n=>{throw it.error(`[IdeFetch.${t.toLowerCase()}] ${o} 실패:`,n),n}).finally(()=>{i&&ot.hide()})}),L(st,"get",(t,n={},e=!0)=>{var i;return R(i=st,y).call(i,"GET",t,n,e)}),L(st,"post",(t,n={},e=!0)=>{var i;return R(i=st,y).call(i,"POST",t,n,e)}),L(st,"postMultipart",async(t,n=[],e={})=>{const{fileKey:i="fileContents",filePartName:o="files",jsonPartName:s="dataList",chunkSize:r=10}=e;ot.show();let a=0,l=null;return(async()=>{for(let e=0;e<n.length;e+=r){const c=new FormData,d=n.slice(e,e+r),h=[];d.forEach(t=>{const{[i]:n,_fileObj:e,...s}=t;h.push(s),n instanceof File&&c.append(o,n)});const u=new Blob([JSON.stringify(h)],{type:"application/json"});if(c.append(s,u),l=await st.post(t,c,!1),!l||!l.success&&"OK"!==l.status)throw new Error(`청크 전송 실패: ${e}번째 섹션`);a+=d.length}return{...l,success:!0,totalCount:a}})().catch(t=>{throw it.error("[postChunk] Error:",t),t}).finally(()=>{ot.hide()})});let rt=st;const at=rt;class lt extends HTMLElement{constructor(){super(),_(this,b),_(this,x,t=>{const n=t.previousElementSibling,e=t.nextElementSibling;if(!n||!e)return void D(this,b,this.classList.contains("h")?"h":"v");const i=n.getBoundingClientRect(),o=e.getBoundingClientRect();this.classList.contains("h")?D(this,b,"h"):this.classList.contains("v")?D(this,b,"v"):D(this,b,Math.abs(i.top-o.top)<5?"h":"v")}),_(this,$,t=>{t.preventDefault(),t.stopPropagation();const n=this.getBoundingClientRect(),e="h"===R(this,b),i=e?t.clientX-n.left:t.clientY-n.top,o=document.createElement("div");o.className=`nx-splitter-drag-bar-${R(this,b)}`,Object.assign(o.style,{position:"absolute",zIndex:"999",background:"#666",opacity:"0.6",pointerEvents:"none"});const s=this.getRootNode({composed:!0}),r=s instanceof ShadowRoot?s.host:this.parentElement,a=this.previousElementSibling,l=this.nextElementSibling;if(!r||!a||!l)return void it.warn("Spliter's parent or siblings not found.");(r.shadowRoot||r).appendChild(o);const c=o.offsetParent.getBoundingClientRect(),d=a.getBoundingClientRect(),h=l.getBoundingClientRect(),u=(e?n.left-c.left:n.top-c.top)+i;e?(o.style.top="0",o.style.left=`${u}px`,o.style.width="2px",o.style.height="100%"):(o.style.left="0",o.style.top=`${u}px`,o.style.height="2px",o.style.width="100%"),o.style.mixBlendMode="difference",o.style.zIndex="99999";const p=e?d.left-c.left:d.top-c.top,g=e?h.right-c.left-n.width:h.bottom-c.top-n.height,f=t=>{const n=e?t.clientX:t.clientY,i=e?n-c.left:n-c.top,s=Math.max(p,Math.min(i,g));e?o.style.left=`${s}px`:o.style.top=`${s}px`},m=()=>{window.removeEventListener("mousemove",f),window.removeEventListener("mouseup",m),o.remove();const t=Array.from(r.children),n=t.filter(t=>"nx-splitter"!==t.tagName.toLowerCase()),i=window.getComputedStyle(r),s=e?i.getPropertyValue("column-gap"):i.getPropertyValue("row-gap"),c=parseFloat(s)||0,d=(t.length>1?t.length-1:0)*c,h=(e?parseFloat(o.style.left):parseFloat(o.style.top))-u,p=e?a.getBoundingClientRect().width:a.getBoundingClientRect().height,g=e?l.getBoundingClientRect().width:l.getBoundingClientRect().height;let v=p+h,w=g-h;v<0&&(w+=v,v=0),w<0&&(v+=w,w=0);const y=n.map(t=>e?t.getBoundingClientRect().width:t.getBoundingClientRect().height),b=t.reduce((t,n)=>"nx-splitter"===n.tagName.toLowerCase()?t+(e?n.getBoundingClientRect().width:n.getBoundingClientRect().height):t,0),x=(e?r.getBoundingClientRect().width:r.getBoundingClientRect().height)-b-d;let $=0;n.forEach((t,n)=>{let e;e=t===a?v:t===l?w:y[n];const i=e/x;it.log(t),t.classList.contains("sidebar")?t.style.flex=`0 0 ${e}px`:t.style.flex=`${i} ${i} 0`,$+=i}),it.log(`dragOffset: ${h}`),it.log(`Calculated FlexSum: ${$}`)};window.addEventListener("mousemove",f),window.addEventListener("mouseup",m)}),_(this,k,()=>{R(this,x).call(this,this),this.classList.add(R(this,b));const t=this.innerHTML.trim(),n=""===t?'<div class="grip"></div>':`<div class="grip"></div><div class="inner-container">${t}</div><div class="grip"></div>`;this.innerHTML="";const e=document.createElement("template");e.innerHTML=`\n\t\t\t<style>\n\t\t\t\t@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@0.9.152/dist/css/nine-util.css";\n\t\t\t\t${this.cssPath?`@import "${this.cssPath}";`:""}\n\t\t\t</style>\n\t\t\t${n}\n `,this.shadowRoot.appendChild(e.content.cloneNode(!0)),this.shadowRoot.querySelectorAll(".grip").forEach(t=>{t.addEventListener("mousedown",t=>R(this,$).call(this,t))}),R(this,M).call(this),window.addEventListener("resize",()=>R(this,M).call(this))}),_(this,M,()=>{const t="h"===R(this,b),n=this.parentElement,e=Array.from(n.children).filter(t=>"nx-splitter"!==t.tagName.toLowerCase());if(e.length<2)return;const i=n.getBoundingClientRect(),o=e.reduce((n,e)=>n+(t?e.getBoundingClientRect().width:e.getBoundingClientRect().height),0),s=t?i.width:i.height;e.forEach(n=>{const e=t?n.getBoundingClientRect().width:n.getBoundingClientRect().height,i=s*(e/o)/s;n.style.flex=`${i} ${i} 0`})}),this.attachShadow({mode:"open"})}connectedCallback(){R(this,k).call(this)}get cssPath(){return this.getAttribute("css-path")||Z.cssPath}}b=new WeakMap,x=new WeakMap,$=new WeakMap,k=new WeakMap,M=new WeakMap,customElements.get("nine-splitter")||customElements.define("nine-splitter",lt),q.safe=async t=>{try{return[await t,null]}catch(n){return[null,n]}},q.api=at,q.trace=nt,q.subscribeConfig=I,q.config=F||{},"undefined"!=typeof window&&(window.nine=q),t.Fetch=rt,t.NineUtil=Z,t.TaskDebouncer=class{constructor(t=50){_(this,v),_(this,g,null),_(this,f,[]),_(this,m),D(this,m,t)}exec(t,...n){R(this,f).push({func:t,args:n}),R(this,g)&&clearTimeout(R(this,g)),D(this,g,setTimeout(()=>O(this,v,w).call(this),R(this,m)))}execWithKey(t,n,...e){D(this,f,R(this,f).filter(n=>n.key!==t)),R(this,f).push({key:t,func:n,args:e}),R(this,g)&&clearTimeout(R(this,g)),D(this,g,setTimeout(()=>O(this,v,w).call(this),R(this,m)))}},t.Trace=tt,t.api=at,t.config=F,t.loading=ot,t.nine=q,t.nineAlertPopup=Y,t.nineConfirmPopup=W,t.nineDialog=T,t.ninePromptPopup=P,t.subscribeConfig=I,t.trace=nt,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=nine-util.umd.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nine-lab/nine-util",
3
- "version": "0.9.151",
3
+ "version": "0.9.152",
4
4
  "description": "Custom Element based Util Component for Real-time Collaboration",
5
5
  "type": "module",
6
6
  "main": "./dist/nine-util.umd.cjs",