@ninebone/datagrid 0.0.4 → 0.0.6
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/README.md +13 -9
- package/dist/nine-table.js +246 -269
- package/dist/nine-table.js.map +1 -1
- package/dist/nine-table.umd.js +16 -27
- package/dist/nine-table.umd.js.map +1 -1
- package/package.json +2 -1
package/dist/nine-table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nine-table.js","names":["traceOrigin","trace","GROUP_IDX","GROUP_IDX","start","end","mid","target","elementDebounceState","el","state","pointerEvent","pointerFn","debounceTime","dblClickEvent","dblClickFn","_text","stripHtml","tmp","html","canvas","context","_font","w","h","v","cleanText","metrics","ascent","descent","trace$1","trace","NINE_TABLE","ngRow","#parent","parent","#newrow","ngData","#host","host","#initialize","o","validRecords","#getValidRecords","at","targetRecord","colnm","idx","rowData","rowIndex","colIndex","value","#conv","fields","#defaultHeight","templateElements","#getDefaultMeta","loadData","dataSource","#invalidate","#nextId","rowid","jsonArray","arr","json","#json2Array","#defaultInsert","row","updateState","b","a","rowidx","targetId","item","COL_IDX","oldValue","isSingle","targetArr","result","i","ngDataManager","ds","rowIdx","nRow","#init","#fields","f","found","fieldName","fName","#adjust","map","name","type","rawTables","tbl","fieldType","attr","expr","lastIndex","targetField","NineTableSheets","NineTableSheetsFooter","#render","isMultiSelect","tabItem","index","#switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","isActive","clickedTab","activeTabs","targetSheet","tabsHtml","table","SheetTabItem","Toolbar","#bindEvents","#customContainer","#syncStateFromHost","isSimple","showToolbar","showMenu","caption","titleEl","link","currentCaption","menuBtn","element","text","NineTableHScrollBar","#owner","initWhenReady","#elements","#observeResize","#resizeObserver","#dragging","track","thumb","bodyWidth","tableWidth","needsHScroll","trackWidth","thumbWidth","currentLeft","maxScrollLeft","l","maxThumbLeft","trackBound","targetX","x","delayScroll","#interval1","#interval2","thumbLeft","#thumbMoveTo","pos","currentThumbLeft","clearTimer","evt","e","trackRect","onMouseMove","moveEvent","onMouseUp","NineTableVScrollBar","#sheet","viewRecords","totalCount","scrollHolder","rawContentHeight","MAX_BROWSER_HEIGHT","useScaling","scaleFactor","contentHeight","#getScaleInfo","fixedHeight","bodyHeight","viewHeight","needsVScroll","trackHeight","thumbHeight","currentScrollTop","maxScrollTop","thumbTop","maxThumbTop","#startY","#startThumbTop","deltaY","targetThumbTop","ratio","rowHeight","visibleRowCount","targetRow","clickY","scrollInterval","startContinuousScroll","scrollStep","$firstTr","direction","currentRow","stopContinuousScroll","GROUP_IDX$1","GroupingManager","#groupColumns","#groupMap","groupColumns","sourceTable","$cell","$tr","#isApplying","groupId","rowIds","dataManager","Grouping","validRaw","rawRecords","groupMap","nestedTree","#buildNestedMap","flatResult","renderItems","#flattenTree","counter","isLastLevel","depth","groupKey","subMapOrRecords","mapOrArray","parentId","#collectLeafRowIds","groupRecord","resultArr","#collectLeafRecords","record","remainingCols","records","key","subRecords","subVal","r","RowManager","#initResizeObserver","#templateRowHeights","sum","bodyViewport","#cachedTemplateHeight","#measureAndCacheHeight","#renderAllContainers","#handleScroll","force","#isGrouped","#handleGroupedScroll","scrollTop","templateLength","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","renderOffsetTop","firstTr","#element","currentStartIndex","$tbody","dataIndex","#bindRowData","allRenderItems","totalVirtualCount","bodyContent","getItemHeight","dataRowsHeight","groupHeightsTotal","itemHeights","viewportClientHeight","accumulatedHeight","offsetY","visibleRowsCount","dynamicBuffer","targetStart","targetEnd","renderedItems","container","selector","trs","itemIndex","chunkTrs","virtualIndex","isTrGroup","tr","subIdx","#bindGroupRowData","subRowIndex","matrixRow","indices","allRecords","childrenRecords","customComp","$el","#containerTemplates","tableEl","tbody","templateTrs","#sheetHeight","#isProgrammaticScroll","dataRow","targetScrollTop","rawTargetScrollTop","onRendered","trTemplates","fragment","renderedTrs","computedStyle","#updateRowCount","visibleRows","#BUFFER_ROW_COUNT","groupDepth","#cachedRowCount","#renderRows","#syncRowHeights","targetFixedType","clonedTr","targetTbody","tmpl","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","entry","entries","height","TableCompiler","$table","$srcTable","#syncColAttributes","fixed","$col","cols","grid","rowSpan","colSpan","c","CellSelection","#initEvents","sameGroupTrs","t","$td","col","r1","startRow","endRow","r2","c1","startCol","endCol","c2","containers","expanded","loopCount","#getMatrixRow","cell","cellEndRow","cellEndCol","nsR","neR","nsC","neC","#range","mainZone","lastMatrixRow","lastCol","targetCell","allCells","rect","targetTr","CellNavigation","#currentCell","#currentTr","#isCellLeftVisible","#isCellRightVisible","isVisible","#isCellBelowVisible","#isCellAboveVisible","scrollTopIndex","#getVisibleRowCount","currentCell","#findCell","nextCell","#getPreviousCell","#getNextCell","#getUpCell","#getDownCell","#moveCellH","#moveCellV","nextCol","cellCol","cellRect","viewportRect","theadHeight","bodyViewport2","viewportHeight","RESIZE_OFFSET","ColResizer","#panel","#tooltip","#onPointerMove","#onPointerDown","#onDblClick","containerType","firstColgroup","totalWidth","colWidths","colIdx","tables","targetCols","globalColIndex","firstContainer","resolvedContainerType","width","sourceCol","headerPart","offsetX","isLeftEdge","isRightEdge","prevCell","#targetCell","#targetContainerType","#getContainerType","baseColIndex","#targetColIndex","#checkIsAutoFit","#nextColIndex","nextColEl","#nextColStartWidth","targetRect","sheetRect","#startCellWidth","#startLeft","attrW","#startColWidth","#startX","#updatePositions","#onDragMove","#onDragEnd","diff","clientX","isAutoFit","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","finalWidth","newColWidth","newNextWidth","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","val","size","calculatedWidth","ColResizerPanel","#renderer","ColMover","#grip","#indi","root","y","nested","headerCells","hasStrictChildren","isValidGroup","parentGroupRange","subCell","subStart","subSpan","subEnd","isRealGroup","groupRange","#getColGroupRange","origTable","minLeft","maxRight","minTop","maxBottom","targetCells","cCol","cEnd","isGroup","groupWidth","groupHeight","headerContent","clonedCell","style","#checkIsMovable","startX","startY","cancelTimer","#timer","onPointerMovePending","#startDrag","#isDragging","preview","#createGroupHeaderPreview","#sourceCell","#sourceColIndex","#shiftX","bounds","relativeTop","fullHeight","#updateGripPosition","#onPointerUp","#getDeepElementFromPoint","targetColIndex","colMinLeft","colMaxRight","cRect","midX","calculatedTargetCol","indicatorLeft","sourceGroup","movingSpan","sourceRowStart","sourceRowEnd","targetRowStart","targetRowEnd","isRowSpanCompatible","isOutOfBoundsOfParent","pStart","pEnd","isDroppingInsideOtherGroup","spannedCells","sCell","sRowStart","sRowEnd","sStart","sEnd","moveEndCol","isSelfGroup","left","colgroup","targetCol","toColIndex","spanCount","isInRange","fromColIndex","targetViewportCol","fixedType","group","cells","targetRowCell","ColFixManager","baseCol","fixedAttr","targetBoundaryCol","theadTrs","cellBoundaryFound","cEndCol","action","fixType","cIdx","minBaseCol","maxEndCol","rSpan","rIdx","isBroken","isColFixed","NineTableFilterPanel","#closeHandler","#nineTable","#view","#onInput","#onSelectAll","#onOk","#button","filterBtn","panelWidth","top","searchBox","#loadVirtualFilterItems","path","filteredRecords","activeFilters","exprEngine","bindKey","colInfo","exprKey","filterKey","activeSelectedVals","uniqueMap","rawVal","displayVal","uniqueList","valA","valB","numA","numB","selectAllChk","filterRecords","checkedRecords","chk","filterParams","selectedVals","query","data2Idx","matchedValues","isChecked","chkIdx","NineTableFilterButton","#onClick","#columns","seen","uniqueKey","isFiltered","panel","Filtering","#filters","#initFilterPanel","#filterPanel","#isFiltering","#applyFiltering","oFilter","jsonFilter","k","sheetIndex","filterRules","targetKey","allowedValues","isExpr","isPass","recordIdx","allowedSet","Sorting","#handleSort","colName","exprVal","isAsc","isDesc","existingColIndex","m","ruleData","#applySorting","#syncHeaderUI","colRule","asc","SheetView","#cachedVisibleRecords","#viewIndexes","visibleRecords","#convSingle","filterSlot","#sortingColumns","groupResult","columns","rulesWithIdx","rule","idxA","idxB","isEmptyA","isEmptyB","strA","strB","PreCompiler","#ensureColgroup","#ensureThead","#ensureSectionTbodys","#ensureRowIndicator","#normalizeColAttributes","#createColIndicator","#normalizeCollapsibleAttributes","#generateCell","#initColExpanders","#initFilterButtons","#applyInitialCellWidths","thead","firstRow","cnt","td","#numToExcelCol","background","num","headTbody","footTbody","colCount","containerWidth","defaultWidth","widthVal","targetAttributes","autoIdCounter","$tbl","tagName","$datalist","$option","uniqueFuncName","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","rows","section","indicatorCell","startColIdx","targetIdx","NineTableSheet","#rowManager","#index","#colResizer","#filtering","#grouping","#colMover","#colFix","#cellSelection","#cellNavigation","#source","attrTrue","sourceTableTrue","#isSimple","#renderSplitContainers","#updateContainerWidths","#adjustOverlay","$thead","$overlay","#autoFit","enable","totalOriginalWidth","colList","collapsedTotalWidth","availableWidth","allocatedTotal","calculatedCols","exactWidth","baseWidth","remainderPixels","uncollapsedCols","finalSumWidth","#syncHeaderAndFooterHeights","#initRowHoverEvent","prefix","firstTable","#createSplitTable","offsetHeight","sheetBottom","tbodyBottom","bodyContainer","scrollLeft","#sorting","leftHeaderRows","bodyHeaderRows","rightHeaderRows","#applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","LayoutManager","owner","#applyAutoHeight","maxDisplayRows","maxRowHeight","toolbarEl","footerEl","toolbarHeight","footerHeight","calculatedHeight","isAutoHeight","sheetCount","sheetsHtml","className","sheetId","cssImports","ExprEngine","match","trimmedExpr","compiledExpr","evalFn","#exprCache","rowItem","NineTable","#shadowRoot","#dataManager","#templateCnt","#bindDynamicSetters","#layoutManager","#dispatchLoad","checkCount","checkTimer","loadSheetCnt","$sheet","idOrIndex","extractedMethodNames","matches","internalValue","methodName","newValue","BasicCellElement","exprCache","CellElement","#cell","#tr","#attr","fn","curRow","renderer","rawRecord","prop","updateRowState","defaultValue","\"display\"","data","cleanExpr","childRecords","funcName","field","acc","EditableCellElement","CellInputText","#target","#initEvent","#maxbyte","maxByteNum","event","CellInputNumber","#onKeyDown","#validate","#max","#min","#scale","str","selectionStart","scale","validKey","isNumKey","CellInputColor","#btn","#dataSource","datalistId","datalist","option","#rendererColor","#isValidColor","g","CellInputDate","#type","formattedVal","d","isValid","#isValidDate","year","month","day","isleap","hour","min","week","CellCheckbox","#label","#trueText","#falseText","#isRadio","trueValue","childHtml","displayText","#enable","#readonly","#visible","CellRadio","#rendererRadio","matchIndex","#radioList","codeVal","#keyName","nameVal","#valueName","label","input","span","CellComboPanel","grd","itemsAttr","fieldKeys","valueName","activeColumnCount","multi","formattedData","keyName","selectedKeys","separator","#isOpen","btnEl","btnRect","panelHeight","upwardTop","#initData","viewContainer","#onClickRow","keyword","CellCombo","#multi","#multiSeparator","#togglePanel","#targetBtn","#getDisplayText","#validateInput","keys","list","CellRenderer","CellButton","#cellButtonClick","customEvent","rawValue","CellRowIndicator","#mainTarget","#subTarget","#statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","ColExpand","singleWidth","currentW","splitWidth","ContextMenu","#tableHost","targetTable","#getTargetSheet","items","activeTableId","activeTable","containerElement","targetTableAttr","rootUl","parsedList","#traverseUl","ulEl","child","spanEl","n","subUl","useDefault","rawItems","customItems","#parseCustomMenuItems","fixManager","#getFixManager","currentFixState","isFixable","isHeaderCell","fixMenuItem","cleanedItems","targetParent","menuItems","#buildMenuItems","#handleMenuClick","#syncMenuStates","isFiltering","autoFit","showTitle","menuId","#onContextMenu","MenuPanel","#onCallback","callback","#appendItems","#bindClickEvents","cellRightX","wrapper","calculatedLeft","calculatedTop","li","condition","sep","parentUl"],"sources":["../src/core/protype.js","../src/external/NoPeer.js","../src/core/constants.js","../src/data/ngData.js","../src/data/ngDataManager.js","../src/data/Fields.js","../src/layout/nine-table-sheets.js","../src/layout/nine-table-sheets-footer.js","../src/layout/nine-table-toolbar.js","../src/layout/nine-table-hscrollbar.js","../src/layout/nine-table-vscrollbar.js","../src/data/Grouping.js","../src/layout/core/RowManager.js","../src/layout/core/TableCompiler.js","../src/cell-manager/CellSelection.js","../src/cell-manager/CellNavigation.js","../src/col/ColResizer.js","../src/col/ColMover.js","../src/col/ColFixManager.js","../src/data/Filtering.js","../src/data/Sorting.js","../src/data/SheetView.js","../src/layout/core/PreCompiler.js","../src/layout/nine-table-sheet.js","../src/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/core/nine-table.js","../src/cell/core/BasicCellElement.js","../src/cell/core/CellElement.js","../src/cell/cell-input-text.js","../src/cell/cell-input-number.js","../src/cell/cell-input-color.js","../src/cell/cell-input-date.js","../src/cell/cell-checkbox.js","../src/cell/cell-radio.js","../src/cell/cell-combo-panel.js","../src/cell/cell-combo.js","../src/cell/cell-renderer.js","../src/cell/cell-button.js","../src/cell/cell-row-indicator.js","../src/col/col-expand.js","../src/menu/nine-table-menu.js","../src/menu/nine-table-menu-panel.js"],"sourcesContent":["Array.prototype.nineBinarySearch = function(target) {\n //this.sort((a, b) => { return a > b ? 1 : -1; });\n\n let start = 0;\n let end = this.length - 1;\n let mid;\n\n while (start <= end) {\n mid = parseInt((start + end) / 2);\n\n if (target === this[mid]) {\n return mid;\n } else {\n if (target < this[mid]) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n }\n\n return -1;\n};\n\n// 엘리먼트별 디바운스/취소 상태를 격리하기 위한 WeakMap\nconst elementDebounceState = new WeakMap();\n\nHTMLElement.prototype.addDebounseEventListener = function(\n dblClickEvent,\n dblClickFn,\n pointerEvent,\n pointerFn,\n debounceTime = 500\n) {\n const el = this;\n\n if (!elementDebounceState.has(el)) {\n elementDebounceState.set(el, { timer: null, cancelFn: null });\n }\n const state = elementDebounceState.get(el);\n\n // 1. 포인터(다운) 이벤트: 즉시 실행하지 않고 debounceTime 동안 지연시킴\n el.addEventListener(pointerEvent, (e) => {\n e.actualTarget = e.target;\n\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n\n // 💡 500ms 동안 대기한 뒤에야 실제 pointerFn이 실행됨\n state.timer = setTimeout(() => {\n state.timer = null;\n state.cancelFn = pointerFn.call(el, e);\n }, debounceTime);\n });\n\n // 2. 더블클릭 이벤트: 대기 시간 내에 들어오면 예약되어 있던 pointerdown 자체를 원천 차단\n el.addEventListener(dblClickEvent, (e) => {\n //trace.log(e);\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null; // 💡 pointerdown 실행 예약이 아예 취소됨!\n }\n\n // 혹시 이미 실행되어 버린 경우의 안전장치 롤백\n if (state.cancelFn) {\n state.cancelFn();\n state.cancelFn = null;\n }\n\n dblClickFn.call(el, e);\n });\n};\n\n\nnine.measureTextSize = (_text, _font = '12px sans-serif') => {\n if (typeof _text === 'number') _text = _text + \"\";\n if (!_text) return { width: null, height: null };\n\n // 🎯 브라우저 DOM 파싱을 이용한 완벽한 HTML 태그 제거 함수\n const stripHtml = (html) => {\n const tmp = document.createElement(\"DIV\");\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || \"\";\n };\n\n // 줄바꿈 처리 전 HTML 정제 또는 줄바꿈 단위별 정제\n _text = _text.replaceAll(\"\\n\", \"<br>\");\n\n // 🎯 공용 숨김 캔버스를 querySelector로 찾거나 없으면 생성\n let canvas = document.body.querySelector('canvas#_nine_measure_canvas_');\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.id = '_nine_measure_canvas_';\n canvas.style.cssText = 'position: absolute; visibility: hidden; pointer-events: none; left: -9999px;';\n document.body.appendChild(canvas);\n }\n\n const context = canvas.getContext('2d');\n context.font = _font;\n\n let w = 0;\n let h = 0;\n\n for (let v of _text.split(\"<br>\")) {\n // 브라우저 파서로 HTML 태그를 완전히 제거한 순수 텍스트 획득\n const cleanText = stripHtml(v);\n const metrics = context.measureText(cleanText);\n\n //trace.log(cleanText);\n\n w = Math.max(w, metrics.width);\n\n const ascent = metrics.fontBoundingBoxAscent || 10;\n const descent = metrics.fontBoundingBoxDescent || 3;\n h += ascent + descent;\n }\n\n return {\n width: w,\n height: h\n };\n};","import { trace as traceOrigin } from '@ninebone/util';\n\n/**\n// 1. 내부 프라이빗 필드 문제를 피하기 위해 래퍼 객체 생성\nexport const trace = {\n init(prefix, color) {\n // 필요하다면 여기서 초기화 로직 수행 가능\n if (traceOrigin.init) {\n try { traceOrigin.init(prefix, color); } catch (e) {}\n }\n },\n log(...args) {\n return traceOrigin.log(...args);\n },\n warn(...args) {\n return traceOrigin.warn(...args);\n },\n error(...args) {\n return traceOrigin.error(...args);\n }\n};\n\n// 2. 모듈 로드 시점에 네임스페이스 초기화 시도\ntry {\n traceOrigin.init(\"nine-table\", \"green\");\n} catch (e) {}\n*/\n\n\nexport class Trace extends traceOrigin.constructor {\n constructor() {\n super();\n this.init(\"nine-table\", \"green\");\n }\n}\n\nexport const trace = new Trace();\n\n\n//trace.init(\"nine-table\", \"green\");","export const NINE_TABLE = {\n META: {\n INDEX: {\n ROWID: 0,\n FILTER: 1, // 멀티뷰 필터 통과 여부 (true/false)\n GROUP: 2,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 'EMPTY',\n NORMAL: 'NORMAL',\n INSERT: 'INSERT',\n UPDATE: 'UPDATE',\n DELETE: 'DELETE'\n },\n EVENT: {\n LOAD: \"load\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\n\r\nexport class ngRow {\r\n\t#parent;\r\n\t#newrow = -1;\r\n\r\n\tconstructor(parent) {\r\n\t\tthis.#parent = parent;\r\n\t}\r\n\r\n\tget at() {\r\n\t\treturn this.#newrow;\r\n\t}\r\n\tset at(v) {\r\n\t\tthis.#newrow = parseInt(v, 10);\r\n\t}\r\n\r\n\tcount = () => this.#parent.rawRecords.length;\r\n}\r\n\r\nexport class ngData {\r\n\t#host;\r\n\t#parent;\r\n\t#nextId = 0;\r\n\t#defaultHeight = [];\r\n\r\n\tstatic META_INDEX = {\r\n\t\tFILTER: 0, // 멀티뷰 필터 통과 여부 (true/false)\r\n\t\t// ── 추후 확장 예시 ──\r\n\t\t// GROUP: 1,\r\n\t\t// SELECT: 2,\r\n\t\t// EXPAND: 3\r\n\t};\r\n\r\n\t// 🎯 행 상태 정의 상수 내재화\r\n\tstatic ROW_STATE = {\r\n\t\tEMPTY: 'EMPTY',\r\n\t\tNORMAL: 'NORMAL',\r\n\t\tINSERT: 'INSERT',\r\n\t\tUPDATE: 'UPDATE',\r\n\t\tDELETE: 'DELETE'\r\n\t};\r\n\r\n\tconstructor(host, parent) {\r\n\t\tthis.#host = host;\r\n\t\tthis.#parent = parent;\r\n\t\tthis.#initialize();\r\n\t}\r\n\r\n\r\n\r\n\t/**\r\n\t * 🎯 [내부 공통] 삭제되지 않은 유효 레코드 목록 반환 (중복 제거 및 캡슐화)\r\n\t */\r\n\t#getValidRecords = () => {\r\n\t\tconst rawRecords = this.#parent.rawRecords || [];\r\n\t\treturn rawRecords.filter(o => !o.__ng?.deleted);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 행 개수 반환 (속성 및 메서드 형태 모두 지원)\r\n\t */\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tcount = () => {\r\n\t\treturn this.length;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [내부 엔진/고성능용] 변환 오버헤드 없이 순수 데이터(v 배열 등) 그대로 반환\r\n\t * - data.getArray() : 유효한 전체 내부 레코드 배열 반환\r\n\t * - data.getArray(at) : 특정 행의 내부 레코드 객체({ v: [...] }) 반환\r\n\t * - data.getArray(at, colnm) : 특정 행의 특정 컬럼 원시 값 반환\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn validRecords; // 변환 없이 배열 그대로 반환 (렌더링 최적화)\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord; // { v: [...], __ng: {...} } 원본 형태 반환\r\n\t};\r\n\r\n\tsetArray = (rowIndex, colIndex, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\r\n\t\tconst oldValue = rowData.v[colIndex];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\t// 변경 전 값 보존 우선 주석처리\r\n\t\t\t//rowData.o[colIndex] = value;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[colIndex] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\r\n\t/**\r\n\t * 🎯 [외부 개발자/비즈니스 로직용] 개발자가 활용하기 편한 JSON 객체 형태로 변환하여 반환\r\n\t * - data.get() : 전체 유효 데이터를 JSON 객체 배열로 변환\r\n\t * - data.get(at) : 특정 행을 JSON 객체로 변환\r\n\t * - data.get(at, colnm) : 특정 컬럼 값 반환\r\n\t */\r\n\tget = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn this.#conv(validRecords);\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#conv(targetRecord);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [저장/서버 전송용] 삭제된 행을 포함한 전체 원본 배열 반환\r\n\t */\r\n\tgetAll = () => {\r\n\t\treturn this.#parent.rawRecords || [];\r\n\t};\r\n\r\n\tgetHostFields = () => {\r\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\r\n\t};\r\n\r\n\t#initialize = () => {\r\n\t\tthis.#defaultHeight = [];\r\n\t\tconst templateElements = this.#host.template || [];\r\n\t\tArray.from(templateElements).forEach(el => {\r\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\r\n\t\t});\r\n\r\n\t\t(this.#parent.rawRecords || []).forEach(v => {\r\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\r\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\r\n\t\t});\r\n\t};\r\n\r\n\tget source() {\r\n\t\treturn this.#conv(this.#parent.rawRecords);\r\n\t}\r\n\tset source(v) {\r\n\t\tthis.set(v);\r\n\t\t//this.clear();\r\n\t\t//this.add(v, false);\r\n\t}\r\n\r\n\t#invalidate = () => {\r\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\r\n\t\t\t$el.invalidate();\r\n\t\t});\r\n\r\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\r\n\t};\r\n\r\n\tset = (dataSource) => {\r\n\r\n\t\tconst loadData = () => {\r\n\t\t\tthis.#host.loading = true;\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tthis.clear();\r\n\t\t\t\t\tthis.add(dataSource, false);\r\n\t\t\t\t\tthis.#invalidate();\r\n\t\t\t\t} finally {\r\n\t\t\t\t\tthis.#host.loading = false;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif (this.#host.loaded) {\r\n\t\t\tloadData();\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\r\n\t\t\t\tloadData();\r\n\t\t\t}, { once: true });\r\n\t\t}\r\n\t};\r\n\r\n\tget nextId() {\r\n\t\treturn this.#nextId++;\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.#getValidRecords().length;\r\n\t}\r\n\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tgetRowCount() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\t#getDefaultMeta = (rowid = 0) => {\r\n\t\treturn {\r\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\r\n\t\t\tdeleted: false,\r\n\t\t\tfiltered: false,\r\n\t\t\theight: this.#defaultHeight.slice(),\r\n\t\t\to: {},\r\n\t\t\tc: {},\r\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\r\n\t\t\t_: [rowid, [], ],\r\n\t\t};\r\n\t};\r\n\r\n\treset = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tclear = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tif (this.#parent.viewRecords?.reset) {\r\n\t\t\tthis.#parent.viewRecords.reset();\r\n\t\t}\r\n\r\n\t\tthis.#nextId = 0;\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\t#json2Array = (jsonArray) => {\r\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\r\n\r\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\r\n\t\tconst arr = [];\r\n\r\n\t\tjsonArray.forEach(json => {\r\n\t\t\tconst o = { v: [] };\r\n\t\t\tfields.forEach(colnm => {\r\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\r\n\t\t\t});\r\n\t\t\tarr.push(o);\r\n\t\t});\r\n\r\n\t\treturn arr;\r\n\t};\r\n\r\n\t#defaultInsert = (arr) => {\r\n\t\tif (!Array.isArray(arr)) arr = [arr];\r\n\t\tarr.forEach(o => {\r\n\t\t\tconst rowid = this.nextId;\r\n\r\n\t\t\to.m = this.#getDefaultMeta(rowid);\r\n\t\t\to.__ng = o.m;\r\n\t\t\to.__ng.rowid = rowid;\r\n\t\t\to.__ng.rowState = ngData.ROW_STATE.INSERT;\r\n\t\t\to.__ng._[0] = rowid;\r\n\t\t});\r\n\t\treturn arr;\r\n\t};\r\n\r\n\tadd = (dataSource, updateState = true) => {\r\n\t\tif (dataSource === undefined) dataSource = {};\r\n\t\tconst arr = this.#json2Array(dataSource);\r\n\r\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(this.#defaultInsert(arr));\r\n\r\n\t\tconst row = this.count() - 1;\r\n\t\tif (!updateState) {\r\n\t\t\tarr.forEach((_, idx) => {\r\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\r\n\t\t\t\tif (target) target.__ng.rowState = ngData.ROW_STATE.EMPTY;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#invalidate();\r\n\t\treturn row;\r\n\t};\r\n\r\n\tdelete = (at) => {\r\n\t\tlet arr = [];\r\n\t\tif (Array.isArray(at)) {\r\n\t\t\tarr = at;\r\n\t\t} else if (typeof at === \"undefined\") {\r\n\t\t\tarr = [this.#parent.host.row.at];\r\n\t\t} else {\r\n\t\t\tarr = [parseInt(at, 10)];\r\n\t\t}\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tarr.sort((a, b) => b - a).forEach(rowidx => {\r\n\t\t\tif (validRecords[rowidx]) {\r\n\t\t\t\tconst targetId = validRecords[rowidx].__ng.rowid;\r\n\t\t\t\tif (validRecords[rowidx].__ng.rowState === ngData.ROW_STATE.INSERT) {\r\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.__ng.rowid !== targetId);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\r\n\t\t\t\t\t\tif (item.__ng.rowid === targetId) {\r\n\t\t\t\t\t\t\titem.__ng.deleted = true;\r\n\t\t\t\t\t\t\titem.__ng.rowState = ngData.ROW_STATE.DELETE;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tsetValue = (rowIndex, colnm, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\trowIndex = parseInt(rowIndex, 10);\r\n\t\tconst fields = this.getHostFields();\r\n\t\tconst COL_IDX = fields.indexOf(colnm);\r\n\t\tif (COL_IDX < 0) return;\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\t\tif (!rowData) return;\r\n\r\n\r\n\r\n\t\tconst oldValue = rowData.v[COL_IDX];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\tif (!rowData.__ng.o.hasOwnProperty(colnm)) rowData.__ng.o[colnm] = oldValue;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[COL_IDX] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\t#conv = (arr) => {\r\n\t\tif (!arr) return arr;\r\n\r\n\t\tconst isSingle = !Array.isArray(arr);\r\n\t\tconst targetArr = isSingle ? [arr] : arr;\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\r\n\t\t\tconst t = {};\r\n\t\t\tfields.forEach((colnm, i) => {\r\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t\t});\r\n\t\t\tt.__ng = o.__ng;\r\n\t\t\treturn t;\r\n\t\t});\r\n\r\n\t\treturn isSingle ? result[0] : result;\r\n\t};\r\n}\r\n","import { ngRow, ngData } from \"./ngData.js\";\r\n\r\nexport class ngDataManager {\r\n\t#host;\r\n\r\n\tconstructor(host) {\r\n\t\tthis.#host = host;\r\n\r\n\t\tthis.row = new ngRow(this);\r\n\t\tthis.data = new ngData(this.#host, this);\r\n\r\n\t\tthis.rawRecords = [];\r\n\t\tthis.viewRecords = [];\r\n\t\tthis.delRecords = [];\r\n\t\tthis.pageCnt = 25;\r\n\r\n\t\tthis.viewRecords.reset = () => {\r\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\r\n\t\t};\r\n\r\n\t\tthis.setDataSource = (ds) => {\r\n\t\t\tif (this.data) this.data.reset();\r\n\r\n\t\t\tthis.rawRecords = [];\r\n\t\t\tthis.viewRecords = [];\r\n\t\t\tthis.delRecords = [];\r\n\r\n\t\t\tthis.data.set(ds || []);\r\n\t\t};\r\n\r\n\t\tthis.getRowState = (nRow) => {\r\n\t\t\tconst rowIdx = parseInt(nRow, 10);\r\n\t\t\tif (rowIdx >= this.data.count()) return;\r\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\r\n\t\t};\r\n\r\n\t\tthis.getRowPosition = () => this.row.at;\r\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\r\n\r\n\t\tthis.scrollTo_V1 = (nRow) => {\r\n\t\t\tif (nRow < 0) nRow = 0;\r\n\t\t\tif (nRow >= this.rawRecords.length) nRow = this.rawRecords.length - 1;\r\n\r\n\t\t\tthis.viewRecords.rawIndex = nRow;\r\n\t\t\tif (this.viewRecords.reset) this.viewRecords.reset();\r\n\r\n\t\t\treturn (nRow <= 0 || nRow >= this.rawRecords.length - 1) ? false : true;\r\n\t\t};\r\n\r\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\r\n\r\n\t\tthis.setColumn = (rowidx, colnm, v) => {\r\n\t\t\trowidx = parseInt(rowidx, 10);\r\n\t\t\tthis.data.setValue(rowidx, colnm, v);\r\n\t\t};\r\n\r\n\t\t// 초기 빈 데이터 바인딩\r\n\t\tthis.setDataSource([]);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\n\nexport class fields {\n\t#host;\n\t#fields = []; // 🎯 이제 { name: string, type: string } 객체들의 배열로 관리합니다.\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\t\tthis.#init();\n\t};\n\n\t// 🎯 기존에 필드 이름만 쓰던 곳들과의 호환을 위해 이름 배열만 리턴하는 메서드 유지\n\tget() {\n\t\treturn this.#fields.map(f => f.name);\n\t};\n\n\t// 🎯 내부 객체 통째로 얻기\n\tgetFields() {\n\t\treturn this.#fields;\n\t}\n\n\t// 🎯 특정 필드의 데이터 타입 조회\n\tgetType(fieldName) {\n\t\tconst found = this.#fields.find(f => f.name === fieldName);\n\t\treturn found ? found.type : 'string';\n\t}\n\n\tadd = (arr, type = 'string') => {\n\t\tarr.forEach(fName => {\n\t\t\tif (!this.#fields.some(f => f.name === fName)) {\n\t\t\t\tthis.#fields.push({ name: fName, type: type });\n\t\t\t}\n\t\t});\n\t\tthis.#adjust();\n\t};\n\n\tindexOf(v) {\n\t\treturn this.#fields.findIndex(f => f.name === v);\n\t};\n\n\tincludes(v) {\n\t\treturn this.#fields.some(f => f.name === v);\n\t};\n\n\t#adjust = () => {\n\t\t// 🎯 이름 기준으로 중복 제거 (Map을 활용하여 마지막에 들어온 타입 유지)\n\t\tconst map = new Map();\n\t\tthis.#fields.forEach(f => {\n\t\t\tmap.set(f.name, f.type);\n\t\t});\n\n\t\tthis.#fields = Array.from(map, ([name, type]) => ({ name, type }));\n\n\t\t// 🎯 빈 문자열이나 __ng 필터링\n\t\tthis.#fields = this.#fields.filter(f => f.name !== \"\" && f.name !== \"__ng\");\n\n\t\t// 🎯 긴 이름순 정렬\n\t\tthis.#fields.sort((a, b) => { return (a.name.length < b.name.length) ? 1 : -1; });\n\t};\n\n\t#init = () => {\n\t\tthis.#fields = [];\n\n\t\ttrace.log(this.#host.querySelectorAll(\"table\"));\n\n\t\tconst rawTables = Array.from(this.#host.querySelectorAll(\"table\"));\n\n\t\tif (!rawTables || rawTables.length === 0) return;\n\n\t\tfor (const tbl of rawTables) {\n\t\t\ttrace.log(tbl);\n\n\t\t\t// 1. [data-bind] 속성 탐색 및 타입 수집\n\t\t\ttbl.querySelectorAll('[data-bind]').forEach((el) => {\n\t\t\t\tconst fieldName = el.dataset.bind;\n\t\t\t\tconst fieldType = el.getAttribute(\"data-type\") || 'string';\n\n\t\t\t\tif (fieldName) {\n\t\t\t\t\tthis.#fields.push({ name: fieldName, type: fieldType });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// 2. 표현식 속성들 탐색 (순수 자바스크립트로 변환)\n\t\t\tconst exprAttrs = [\n\t\t\t\t\"data-expr\", \"background-color\", \"color\", \"tooltip\",\n\t\t\t\t\"visible\", \"readonly\", \"enable-button\", \"enable-check\",\n\t\t\t\t\"class-expr\", \"icon-color\", \"icon-src\"\n\t\t\t];\n\n\t\t\texprAttrs.forEach(attr => {\n\t\t\t\t// 💡 jQuery의 $([attr], tbl).each(...)를 순수 querySelectorAll로 대체\n\t\t\t\ttbl.querySelectorAll(`[${attr}]`).forEach((el) => {\n\t\t\t\t\tlet expr = el.getAttribute(attr);\n\t\t\t\t\tif (!expr) return;\n\n\t\t\t\t\tif (expr.indexOf(\"data.\") < 0) {\n\t\t\t\t\t\tconst lastIndex = expr.search(/[(]/g);\n\n\t\t\t\t\t\tif (lastIndex > 0) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\texpr = String(window[expr.substring(0, lastIndex).trim()]);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\texpr = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\texpr.split(\"data.\").forEach(v => {\n\t\t\t\t\t\tif (v.trim() != \"\") {\n\t\t\t\t\t\t\tconst lastIndex = v.search(/[^_A-Za-z0-9]/g);\n\t\t\t\t\t\t\tlet targetField = '';\n\n\t\t\t\t\t\t\tif (lastIndex >= 0) {\n\t\t\t\t\t\t\t\ttargetField = v.substring(0, lastIndex);\n\t\t\t\t\t\t\t} else if (expr.startsWith(\"data.\")) {\n\t\t\t\t\t\t\t\ttargetField = v.replace(\"data.\", \"\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (targetField) {\n\t\t\t\t\t\t\t\tthis.#fields.push({ name: targetField, type: 'string' });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tthis.#adjust();\n\t};\n};","export class NineTableSheets extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n #init = () => {\n\n };\n\n}\n\nif (!customElements.get('nine-table-sheets')) {\n customElements.define('nine-table-sheets', NineTableSheets);\n}","export class NineTableSheetsFooter extends HTMLElement {\n #host;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n refresh = () => {\n this.querySelector(\"#row-count\").innerHTML = this.#host.data.count().toLocaleString();\n };\n\n #init = () => {\n this.#host = this.getRootNode().host;\n\n this.#render();\n\n this.querySelector('.nine-tab-bar')?.addEventListener('click', (e) => {\n const isMultiSelect = e.ctrlKey || e.metaKey || e.shiftKey;\n const tabItem = e.target.closest('nt-sheets-tab-item');\n\n if (!tabItem) return;\n\n const index = parseInt(tabItem.dataset.index, 10);\n this.#switchSheet(index, isMultiSelect);\n });\n\n setTimeout(() => {\n this.#switchSheet(0, false);\n })\n };\n\n #switchSheet = (index, isMultiSelect = false) => {\n\n const updateSplitters = () => {\n const sheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet'));\n const splitters = Array.from(this.#host.shadowRoot.querySelectorAll('nine-splitter'));\n\n // 1. 모든 스플리터 일단 숨김 처리\n splitters.forEach(s => s.style.setProperty('display', 'none'));\n\n // 2. 현재 active 상태인 시트들을 인덱스 오름차순으로 정렬\n const activeSheets = sheets\n .map((sheet, idx) => ({ sheet, idx }))\n .filter(({ sheet }) => sheet.classList.contains('active'));\n\n if (activeSheets.length < 2) return;\n\n // 3. 인접한 활성화 시트 쌍 사이에 정확히 하나의 스플리터만 노출\n for (let i = 0; i < activeSheets.length - 1; i++) {\n const currentIdx = activeSheets[i].idx;\n\n const targetSplitter = this.#host.shadowRoot.querySelector(`nine-splitter[data-split-index=\"${currentIdx}\"]`);\n if (targetSplitter) {\n targetSplitter.style.setProperty('display', '');\n }\n }\n };\n\n const tabBar = this.querySelector('.nine-tab-bar');\n const body = this.#host.shadowRoot.querySelector('nine-table-sheets-body');\n const tabItems = tabBar.querySelectorAll('nt-sheets-tab-item');\n const sheetElements = body.querySelectorAll('nine-table-sheet');\n\n if (!tabItems[index]) return;\n\n if (!isMultiSelect) {\n tabItems.forEach((tab, idx) => {\n tab.setActive(idx === index);\n });\n\n sheetElements.forEach((sheet, idx) => {\n const isActive = idx === index;\n sheet.classList.toggle('active', isActive);\n sheet.style.flex = isActive ? '1 1 100%' : '';\n });\n } else {\n const clickedTab = tabItems[index];\n const activeTabs = tabBar.querySelectorAll('nt-sheets-tab-item.active');\n\n if (clickedTab.classList.contains('active') && activeTabs.length <= 1) {\n return;\n }\n\n clickedTab.classList.toggle('active');\n const targetSheet = body.querySelector(`nine-table-sheet[data-index=\"${index}\"]`);\n if (targetSheet) {\n targetSheet.classList.toggle('active');\n if (!targetSheet.classList.contains('active')) {\n targetSheet.style.flex = '';\n }\n }\n }\n\n const activeSheets = body.querySelectorAll('nine-table-sheet.active');\n\n activeSheets?.forEach(sheet => {\n sheet.style.flex = (activeSheets.length > 1) ? '1 1 0%' : '1 1 100%';\n\n if (typeof sheet.refreshLayout === 'function') {\n sheet.refreshLayout();\n } else {\n sheet.invalidate?.();\n }\n });\n\n updateSplitters();\n };\n\n #render() {\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE'));\n\n const tabsHtml = rawTables.map((table, idx) => {\n const className = idx === 0 ? 'active' : '';\n const tabName = table.getAttribute('caption') || `Sheet ${idx + 1}`;\n\n return `<nt-sheets-tab-item class=\"${className}\" data-index=\"${idx}\">${tabName}</nt-sheets-tab-item>`;\n }).join('');\n\n this.innerHTML = `\n <div class=\"nine-tab-bar\">${tabsHtml}</div>\n <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n `;\n };\n}\n\nexport class SheetTabItem extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n }\n\n setActive(isActive) {\n this.classList.toggle('active', isActive);\n }\n}\n\nif (!customElements.get('nt-sheets-tab-item')) {\n customElements.define('nt-sheets-tab-item', SheetTabItem);\n}\n\nif (!customElements.get('nine-table-sheets-footer')) {\n customElements.define('nine-table-sheets-footer', NineTableSheetsFooter);\n}","import { trace } from \"@nopeer\";\n\nexport class Toolbar extends HTMLElement {\n #host;\n #customContainer;\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#render();\n this.#bindEvents();\n }\n\n #render() {\n this.innerHTML = `\n <div class=\"ng-toolbar-left\">\n <button type=\"button\" class=\"ng-toolbar-menu-btn\" title=\"Menu\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#374151\" stroke-width=\"2\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n </svg>\n </button>\n <span class=\"ng-toolbar-title\"></span>\n </div>\n\n <div class=\"ng-toolbar-custom\" id=\"custom-container\"></div>\n `;\n\n this.#customContainer = this.querySelector('#custom-container');\n this.#syncStateFromHost();\n }\n\n #syncStateFromHost() {\n const isSimple = this.#host.getAttribute('theme') === 'simple' || this.#host.classList.contains('simple');\n const showToolbar = this.#host.getAttribute('show-toolbar') !== 'false';\n const showMenu = this.#host.getAttribute('show-menu') !== 'false';\n const caption = this.#host.getAttribute('caption') || '';\n\n if (isSimple || !showToolbar) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n\n this.setAttribute('show-menu', showMenu ? 'true' : 'false');\n this.updateCaption(caption);\n }\n\n #bindEvents() {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) {\n titleEl.addEventListener('dblclick', () => {\n const link = '<font color=\"green\">https://www.ninegrid.net</font>';\n const currentCaption = this.#host.getAttribute('caption') || '';\n titleEl.innerHTML = titleEl.innerHTML === link ? currentCaption : link;\n });\n }\n\n const menuBtn = this.querySelector('.ng-toolbar-menu-btn');\n if (menuBtn) {\n menuBtn.addEventListener('click', () => {\n this.#host.dispatchEvent(new CustomEvent('toolbar-menu-click', {\n bubbles: true,\n composed: true,\n detail: { targetTable: this.#host }\n }));\n });\n }\n }\n\n addCustomElement(element) {\n if (this.#customContainer) {\n this.#customContainer.append(element);\n }\n }\n\n updateCaption(text) {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) titleEl.textContent = text;\n }\n}\n\nif (!customElements.get('nine-table-toolbar')) {\n customElements.define('nine-table-toolbar', Toolbar);\n}","// ui/nine-table-hscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableHScrollBar extends HTMLElement {\n #owner;\n #dragging = false;\n #elements;\n #interval1;\n #interval2;\n #resizeObserver;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#owner = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n if (!this.#owner) return;\n\n this.innerHTML = `\n <button class='scroll-left' disabled><div class='scroll-icon'></div></button>\n <div class='scroll-track'><div class='scroll-thumb'></div></div>\n <button class='scroll-right' disabled><div class='scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container : body,\n track : this.querySelector(\".scroll-track\"),\n thumb : this.querySelector(\".scroll-thumb\"),\n left : this.querySelector(\".scroll-left\"),\n right : this.querySelector(\".scroll-right\"),\n };\n\n this.#init();\n this.#observeResize();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n disconnectedCallback() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n }\n\n #observeResize = () => {\n if (!this.#owner) return;\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) return;\n\n this.#resizeObserver = new ResizeObserver(() => {\n this.refresh();\n });\n this.#resizeObserver.observe(body);\n };\n\n refresh = () => {\n\n if (!this.#owner || !this.#elements || this.#dragging) return;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return;\n\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n\n //trace.log(bodyWidth, tableWidth, bodyWidth);\n\n // 🎯 [순수 클래스 연동] 인라인 스타일 조작 없이 오직 클래스 토글만 수행\n const needsHScroll = (bodyWidth !== 0 && tableWidth > bodyWidth);\n this.#owner.classList.toggle('hscroll-visible', needsHScroll);\n\n if (!needsHScroll) {\n return;\n }\n\n const trackWidth = track.clientWidth;\n if (trackWidth <= 0) return;\n\n const thumbWidth = Math.max(Math.min(trackWidth * (bodyWidth / tableWidth), trackWidth), 20);\n thumb.style.width = `${thumbWidth}px`;\n\n const currentLeft = body.scrollLeft;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n let l = 0;\n if (maxScrollLeft > 0) {\n l = parseInt((currentLeft / maxScrollLeft) * (trackWidth - thumbWidth), 10);\n }\n if (l < 0) l = 0;\n\n const maxThumbLeft = trackWidth - thumbWidth;\n if (l > maxThumbLeft) l = maxThumbLeft;\n\n thumb.style.left = `${l}px`;\n\n this.#elements.left.disabled = (l === 0);\n this.#elements.right.disabled = (l >= maxThumbLeft - 1);\n };\n\n #thumbMoveTo = (x) => {\n if (!this.#elements) return false;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return false;\n\n const trackBound = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n\n let targetX = x;\n if (targetX < 0) targetX = 0;\n const maxThumbLeft = trackBound.width - thumbWidth;\n if (targetX > maxThumbLeft) targetX = maxThumbLeft;\n targetX = parseInt(targetX, 10);\n\n this.#elements.thumb.style.left = `${targetX}px`;\n\n this.#elements.left.disabled = (targetX === 0);\n this.#elements.right.disabled = (targetX >= maxThumbLeft - 1);\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n if (maxThumbLeft > 0 && maxScrollLeft > 0) {\n const newScrollLeft = (targetX / maxThumbLeft) * maxScrollLeft;\n body.scrollLeft = newScrollLeft;\n }\n\n return (targetX > 0 && targetX < maxThumbLeft - 1);\n };\n\n #init = () => {\n const delayScroll = (pos) => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n\n const thumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n this.#thumbMoveTo(thumbLeft + pos);\n\n this.#interval1 = setInterval(() => {\n clearInterval(this.#interval1);\n\n this.#interval2 = setInterval(() => {\n const currentThumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n if (!this.#thumbMoveTo(currentThumbLeft + pos)) {\n clearInterval(this.#interval2);\n }\n }, 50);\n }, 500);\n };\n\n const clearTimer = () => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n };\n\n ['mouseup', 'mouseleave', 'touchend'].forEach(evt => {\n this.#elements.left.addEventListener(evt, clearTimer);\n this.#elements.right.addEventListener(evt, clearTimer);\n this.#elements.track.addEventListener(evt, clearTimer);\n });\n\n this.#elements.left.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(-20); });\n this.#elements.right.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(20); });\n this.#elements.left.addEventListener(\"touchstart\", () => delayScroll(-20));\n this.#elements.right.addEventListener(\"touchstart\", () => delayScroll(20));\n\n this.#elements.track.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.preventDefault();\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n this.#thumbMoveTo(e.clientX - trackRect.left - (thumbWidth / 2));\n });\n\n this.#elements.thumb.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n this.shiftX = e.clientX - this.#elements.thumb.getBoundingClientRect().left;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n this.#thumbMoveTo(moveEvent.clientX - trackRect.left - this.shiftX);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n clearTimer();\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n };\n}\n\nif (!customElements.get('nine-table-hscrollbar')) {\n customElements.define(\"nine-table-hscrollbar\", NineTableHScrollBar);\n}","// ui/nine-table-vscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableVScrollBar extends HTMLElement {\n #host;\n #sheet;\n #dragging = false;\n #elements;\n #startY = 0;\n #startScrollTop = 0;\n #startThumbTop = 0;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#sheet = this.closest(\"nine-table-sheet\");\n\n this.innerHTML = `\n <button class='scroll-top' disabled><div class='scroll-icon'></div></button>\n <div class='scroll-track'><div class='scroll-thumb'></div></div>\n <button class='scroll-bottom' disabled><div class='scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#sheet.querySelector(\".ng-sheet-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container: body,\n track: this.querySelector(\".scroll-track\"),\n thumb: this.querySelector(\".scroll-thumb\"),\n top: this.querySelector(\".scroll-top\"),\n bottom: this.querySelector(\".scroll-bottom\"),\n };\n\n this.#init();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n #getScaleInfo = () => {\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords ? viewRecords.length : 0;\n\n // 🎯 [핵심] 그룹핑이든 일반이든 스크롤홀더(scrollHolder)가 가진 실제 가상 총 높이를 최우선으로 반영\n const scrollHolder = this.#sheet.elements?.scrollHolder;\n let rawContentHeight = scrollHolder ? parseFloat(scrollHolder.style.height) || 0 : 0;\n\n if (!rawContentHeight || rawContentHeight <= 0) {\n const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n if (isGrouped && this.#sheet.rowManager) {\n // RowManager가 관리하는 누적 높이 활용 또는 fallback\n rawContentHeight = (body.scrollHeight > body.clientHeight) ? body.scrollHeight : (totalCount * 30);\n } else {\n const rowHeight = this.#sheet.getRowHeight() || 1;\n rawContentHeight = totalCount * rowHeight;\n }\n }\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawContentHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let contentHeight = rawContentHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawContentHeight;\n contentHeight = MAX_BROWSER_HEIGHT;\n }\n\n return { rawContentHeight, contentHeight, scaleFactor, useScaling, totalCount };\n };\n\n #getViewHeight = () => {\n const body = this.#elements.container;\n if (!body) return 0;\n\n const thead = this.#sheet.elements?.body?.thead?.offsetHeight || 0;\n const tfoot = this.#sheet.elements?.body?.tfoot?.offsetHeight || 0;\n const tbodyHead = this.#sheet.elements?.body?.tbody?.head?.offsetHeight || 0;\n const fixedHeight = thead + tfoot + tbodyHead;\n\n return body.clientHeight - fixedHeight;\n };\n\n refresh = () => {\n //trace.log(\"=================\", \"vscrollbar.refresh\");\n // 💡 드래그 중에는 refresh에 의한 썸 위치 덮어쓰기 차단\n if (this.#dragging) return;\n\n if (!this.#sheet || !this.#sheet.elements || !this.#elements) return;\n\n const body = this.#elements.container;\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n\n\n //const bodyHeight = this.#getViewHeight();\n const { contentHeight } = this.#getScaleInfo();\n\n\n\n const fixedHeight = (this.#sheet.querySelector('thead')?.offsetHeight || 0) +\n (this.#sheet.querySelector('tfoot')?.offsetHeight || 0) +\n (this.#sheet.querySelector('tbody.head')?.offsetHeight || 0);\n\n const bodyHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0);\n const viewHeight = bodyHeight - fixedHeight;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n const rawContentHeight = this.#sheet.getRowHeight() * totalCount;\n\n const needsVScroll = (rawContentHeight > viewHeight);\n\n // 1. 전체 실제 데이터의 높이 계산\n //const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n //trace.log(viewHeight, fixedHeight);\n\n //trace.log(rawContentHeight, bodyHeight);\n //trace.log(\"**************************************\", needsVScroll);\n\n this.#sheet.classList.toggle('vscroll-visible', needsVScroll);\n\n if (!needsVScroll) {\n return;\n }\n\n const trackHeight = track.clientHeight;\n if (trackHeight <= 0) return;\n\n //trace.log(body, body.scrollTop, bodyHeight, viewHeight, contentHeight);\n\n //trace.log(bodyHeight, rawContentHeight, contentHeight);\n\n const thumbHeight = Math.max(Math.min(trackHeight * (bodyHeight / rawContentHeight), trackHeight), 20);\n thumb.style.height = `${thumbHeight}px`;\n\n const currentScrollTop = body.scrollTop;\n //const maxScrollTop = Math.max(contentHeight - bodyHeight, 1);\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 1);\n\n let thumbTop = 0;\n if (maxScrollTop > 0) {\n thumbTop = (currentScrollTop / maxScrollTop) * (trackHeight - thumbHeight);\n }\n\n const maxThumbTop = trackHeight - thumbHeight;\n if (thumbTop < 0) thumbTop = 0;\n if (thumbTop > maxThumbTop) thumbTop = maxThumbTop;\n\n thumb.style.top = `${thumbTop}px`;\n\n /**\n // 🎯 [디버깅 로그] 스크롤바가 리프레시될 때 현재 상태 로깅\n trace.log(\"🔍 [VScroll Refresh]\", {\n isGrouped: this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false,\n totalCount,\n bodyScrollTop: currentScrollTop,\n maxScrollTop,\n thumbTop,\n maxThumbTop\n }); */\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n #init = () => {\n trace.log(\"nine-table-vscrollbar.#init\");\n\n const body = this.#elements.container;\n\n this.#elements.thumb.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n\n this.#startY = e.clientY;\n this.#startThumbTop = parseFloat(this.#elements.thumb.style.top) || 0;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const trackHeight = trackRect.height;\n const thumbHeight = this.#elements.thumb.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n if (maxThumbTop <= 0) return;\n\n //this.#elements.container.scrollTop = 0;\n\n const deltaY = moveEvent.clientY - this.#startY;\n let targetThumbTop = this.#startThumbTop + deltaY;\n\n if (targetThumbTop < 0) targetThumbTop = 0;\n if (targetThumbTop > maxThumbTop) targetThumbTop = maxThumbTop;\n\n // 썸 위치 즉시 고정\n this.#elements.thumb.style.top = `${targetThumbTop}px`;\n\n const ratio = targetThumbTop / maxThumbTop;\n\n const rowHeight =this.#sheet.getRowHeight();\n const viewHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0) -\n (this.#sheet.elements.body.thead?.offsetHeight || 0) -\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) -\n (this.#sheet.elements.body.tbody.head.offsetHeight || 0);\n\n const visibleRowCount = Math.floor(viewHeight / rowHeight);\n\n const { totalCount } = this.#getScaleInfo();\n //const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n const targetRow = Math.floor(ratio * (totalCount - visibleRowCount + 1));\n // 1000010 - 6\n this.#sheet.rowManager.scrollToDataRow(targetRow);\n\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n const currentScrollTop = this.#elements.container.scrollTop;\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 0);\n\n //trace.log(\"*****************\", visibleRowCount, ratio, totalCount, targetRow);\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n //this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n\n this.#elements.track.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0 || e.target === this.#elements.thumb) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbHeight = this.#elements.thumb.clientHeight;\n const trackHeight = this.#elements.track.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n if (maxThumbTop > 0) {\n const clickY = e.clientY - trackRect.top - (thumbHeight / 2);\n const ratio = Math.max(0, Math.min(1, clickY / maxThumbTop));\n\n const { totalCount } = this.#getScaleInfo();\n const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n\n trace.log(\"🎯 [VScroll Track Click]\", { ratio, clickY, totalCount, targetRow });\n\n if (targetRow >= 0 && this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n }\n this.refresh();\n });\n\n /**\n this.#elements.top.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = Math.max(0, currentTopRow - 1);\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n */\n /**\n this.#elements.bottom.addEventListener(\"click\", (e) => {\n\n const $firstTr = this.#sheet.querySelector(\"tbody.body tr\");\n const targetRow = parseInt($firstTr.dataset.row, 10) + 1;\n\n this.#sheet.rowManager.scrollToDataRow(targetRow + 1, null, () => {\n this.refresh();\n });\n }); */\n\n // 🎯 아래쪽 화살표 꾹 누를 때 연속 스크롤 처리\n // 🎯 상하 화살표 꾹 누를 때 연속 스크롤 공통 처리 함수\n let scrollInterval = null;\n\n const startContinuousScroll = (direction) => {\n if (scrollInterval) return;\n\n const scrollStep = () => {\n const $firstTr = this.#sheet.querySelector(\"tbody.body tr\");\n\n if (!$firstTr || $firstTr.dataset.row === undefined) {\n return;\n }\n\n trace.log(this.#sheet.isLastRow());\n if (direction === 'down' && this.#sheet.isLastRow()) {\n return;\n }\n\n const currentRow = parseInt($firstTr.dataset.row, 10);\n const targetRow = direction === 'down' ? currentRow+1 : Math.max(0, currentRow-1);\n\n this.#sheet.rowManager.scrollToDataRow(targetRow, null, () => {\n this.refresh();\n });\n };\n\n scrollStep();\n scrollInterval = setInterval(scrollStep, 200); // 100ms 간격 반복\n };\n\n const stopContinuousScroll = () => {\n if (scrollInterval) {\n clearInterval(scrollInterval);\n scrollInterval = null;\n }\n };\n\n // 1. 위쪽(top) 버튼 이벤트 바인딩\n this.#elements.top.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n startContinuousScroll('up');\n });\n\n // 2. 아래쪽(bottom) 버튼 이벤트 바인딩\n this.#elements.bottom.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n startContinuousScroll('down');\n });\n\n // 마우스가 떼어지거나 버튼 영역을 벗어났을 때 공통 정지\n document.addEventListener(\"mouseup\", stopContinuousScroll);\n this.#elements.top.addEventListener(\"mouseleave\", stopContinuousScroll);\n this.#elements.bottom.addEventListener(\"mouseleave\", stopContinuousScroll);\n };\n}\n\nif (!customElements.get('nine-table-vscrollbar')) {\n customElements.define(\"nine-table-vscrollbar\", NineTableVScrollBar);\n}","import { trace } from \"@nopeer\";\r\n\r\n// 💡 배열 인덱스 상수 정의\r\nexport const GROUP_IDX = {\r\n\tID: 0,\r\n\tDEPTH: 1,\r\n\tNAME: 2,\r\n\tCHILDREN: 3,\r\n};\r\n\r\nexport class GroupingManager {\r\n\t#sheet;\r\n\t#host;\r\n\t#groupColumns = [];\r\n\t#groupMap = new Map(); // 그룹별 자식 ID 매핑 관리용\r\n\t#isApplying = false;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t}\r\n\r\n\tget columns() {\r\n\t\treturn this.#groupColumns;\r\n\t}\r\n\r\n\tget groupMap() {\r\n\t\treturn this.#groupMap;\r\n\t}\r\n\r\n\tinitialize = () => {\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\t};\r\n\r\n\tapply() {\r\n\r\n\t\ttrace.log(\"==================\", \"Grouping.Apply\");\r\n\r\n\t\tif (this.#isApplying) return;\r\n\t\tthis.#isApplying = true;\r\n\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\r\n\t\t// 💡 데이터 캐시와 렌더링 아이템은 이제 SheetView 단일 파이프라인에서 관리하므로\r\n\t\t// 그룹핑 설정이 바뀌면 SheetView.refresh()를 호출해 전체 흐름을 일괄 재계산합니다.\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh(); // 🎯 SheetView에서 필터/정렬/그룹핑 일괄 처리\r\n\t}\r\n\r\n\tclear() {\r\n\t\tthis.#groupColumns = [];\r\n\t\tthis.#groupMap.clear();\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh();\r\n\t}\r\n\r\n\t// SheetView가 그룹핑 연산 후 groupMap을 공유할 수 있도록 설정 메서드 제공\r\n\tsetGroupMap(map) {\r\n\t\tthis.#groupMap = map;\r\n\t}\r\n\r\n\tgetChildrenRowIds(groupId) {\r\n\t\treturn this.#groupMap.get(groupId) || [];\r\n\t}\r\n\r\n\tgetChildrenRecords(groupId) {\r\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\r\n\t\tconst dataManager = this.#host.data;\r\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\r\n\t}\r\n}\r\n\r\nexport class Grouping {\r\n\r\n\tstatic apply(rawRecords, groupColumns = [], fields = []) {\r\n\t\tif (!groupColumns || groupColumns.length === 0) {\r\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\r\n\t\t}\r\n\r\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\r\n\t\tconst groupMap = new Map();\r\n\r\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\r\n\t\tconst flatResult = [];\r\n\t\tconst renderItems = [];\r\n\r\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\");\r\n\r\n\t\treturn { headers: flatResult, renderItems, groupMap };\r\n\t}\r\n\r\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId) {\r\n\t\tlet counter = 0;\r\n\t\tconst isLastLevel = (depth === groupColumns.length - 1); // 💡 연산자 수정 반영\r\n\r\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\r\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\r\n\r\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\r\n\t\t\tgroupMap.set(groupId, rowIds);\r\n\r\n\t\t\tconst groupRecord = [];\r\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\r\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\r\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\r\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\r\n\r\n\t\t\tgroupRecord.__isGroupHeader = true;\r\n\t\t\tgroupRecord.__groupId = groupId;\r\n\r\n\t\t\tresultArr.push(groupRecord);\r\n\r\n\t\t\trenderItems.push({\r\n\t\t\t\ttype: 'group',\r\n\t\t\t\trecord: groupRecord,\r\n\t\t\t\tgroupId: groupId\r\n\t\t\t});\r\n\r\n\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\r\n\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId);\r\n\t\t\t} else {\r\n\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\r\n\t\t\t\tleafRecords.forEach(record => {\r\n\t\t\t\t\trecord.__isGroupHeader = false;\r\n\t\t\t\t\trecord.__groupId = groupId;\r\n\t\t\t\t\tresultArr.push(record);\r\n\r\n\t\t\t\t\trenderItems.push({\r\n\t\t\t\t\t\ttype: 'data',\r\n\t\t\t\t\t\trecord: record,\r\n\t\t\t\t\t\tgroupId: groupId\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tstatic #buildNestedMap(records, groupColumns, fields) {\r\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\r\n\t\tconst remainingCols = groupColumns.slice(1);\r\n\t\tconst map = new Map();\r\n\r\n\t\trecords.forEach(record => {\r\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\r\n\t\t\tif (!map.has(key)) map.set(key, []);\r\n\t\t\tmap.get(key).push(record);\r\n\t\t});\r\n\r\n\t\tif (remainingCols.length > 0) {\r\n\t\t\tconst result = new Map();\r\n\t\t\tfor (let [key, subRecords] of map.entries()) {\r\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n\tstatic #collectLeafRowIds(subMapOrRecords) {\r\n\t\tlet rowIds = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\r\n\t\t}\r\n\t\treturn rowIds;\r\n\t}\r\n\r\n\tstatic #collectLeafRecords(subMapOrRecords) {\r\n\t\tlet records = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trecords = records.concat(subMapOrRecords);\r\n\t\t}\r\n\t\treturn records;\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { GROUP_IDX } from \"@/data/Grouping.js\";\n\nexport class RowManager {\n #BUFFER_ROW_COUNT = 3;\n\n #host;\n #sheet;\n #element;\n\n #containerTemplates = new Map();\n\n #templateRowHeights = []; // 💡 [추가] 템플릿 행별 개별 높이 보관 ([그룹1, 그룹2, 데이터])\n #cachedTemplateHeight = null;\n\n #resizeObserver = null;\n #sheetHeight = 0;\n #cachedRowCount;\n\n #isProgrammaticScroll = false;\n #isGrouped = false;\n\n constructor(sheet) {\n this.#host = sheet.getRootNode().host;\n this.#sheet = sheet;\n\n this.#initResizeObserver();\n }\n\n // ==========================================\n // 🎯 Public APIs & Getters\n // ==========================================\n\n getRowHeight() {\n return this.#templateRowHeights.reduce((sum, h) => sum + h, 0);//this.#cachedTemplateHeight;\n }\n\n\n refresh = (force = false) => {\n //trace.log(\"rowManager.refresh\", { force });\n\n //this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[group='true']\") ? true : false;\n\n if (!this.#sheet.classList.contains('active')) return;\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n const wasInvalidHeight = !this.#cachedTemplateHeight || this.#cachedTemplateHeight <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#cachedTemplateHeight && this.#cachedTemplateHeight > 0) {\n this.#renderAllContainers();\n }\n }\n\n\n //this.#updateFooterSpacing();\n\n this.#handleScroll(bodyViewport.scrollTop, force);\n\n this.#sheet.querySelector('nine-table-vscrollbar')?.refresh();\n };\n\n #handleScroll = (scrollTop, force = false) => {\n\n if (this.#isGrouped) {\n this.#handleGroupedScroll(scrollTop, force);\n return;\n }\n\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) return;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n if (totalCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n //const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight - (viewHeight - fixedHeight - rowHeight), 0);\n\n\n // 🎯 [핵심] 브라우저 DOM 최대 높이 제한 대응 (약 1,500만 픽셀 상한선)\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let totalVirtualHeight = rawTotalVirtualHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n totalVirtualHeight = MAX_BROWSER_HEIGHT;\n }\n //trace.log(totalCount, rowHeight, rawTotalVirtualHeight, MAX_BROWSER_HEIGHT);\n // 스크롤홀더에는 브라우저가 소화할 수 있는 최대 높이만 부여\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n //trace.log(\"*************\",this.#sheet.querySelector('.ng-sheet-body').clientHeight, this.#sheet.querySelector('.ng-sheet-body').offsetHeight, viewHeight, fixedHeight, rawTotalVirtualHeight, totalVirtualHeight);\n\n //trace.log(totalVirtualHeight);\n // 🎯 스크롤바 위치(scrollTop)를 실제 데이터 좌표계로 역환산\n const actualScrollTop = useScaling ? (scrollTop / scaleFactor) : scrollTop;\n\n const maxStartIndex = Math.max(0, totalCount - 1);\n const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n\n // 실제 데이터 좌표 기준으로 시작 인덱스 산출 (원하시는 -1 보정 유지)\n //const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight) - 1, maxStartIndex));\n\n //const calculatedIndexFloat = clampedScrollTop / rowHeight;\n //const startIndex = Math.max(0, Math.min(Math.floor(calculatedIndexFloat) - 1, maxStartIndex));\n const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n /**\n trace.log(\"🔍 [#handleScroll DEBUG]\", {\n scrollTop,\n actualScrollTop,\n clampedScrollTop,\n rowHeight,\n //calculatedIndexFloat,\n startIndex,\n firstTrDatasetRow: this.#element.firstTr?.dataset?.row\n }); */\n\n // 🎯 화면 렌더링 오프셋도 '실제 데이터 좌표(clampedScrollTop)' 기준의 모듈러 연산 적용\n const renderOffsetTop = clampedScrollTop % rowHeight;\n this.#sheet.elements.left.tbody.body.style.top =\n this.#sheet.elements.body.tbody.body.style.top =\n this.#sheet.elements.right.tbody.body.style.top = `-${renderOffsetTop}px`;\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.row !== undefined ? parseInt(firstTr.dataset.row, 10) : -1;\n\n if (!force && currentStartIndex === startIndex) {\n //trace.log(`[Perf ${getTimestamp()}] ⏭️ 인덱스 동일로 스킵! 총 소요: ${(performance.now() - startTime).toFixed(2)}ms`);\n return;\n }\n\n //trace.log(`${getTimestamp()}`);\n\n\n // [범인 구간 추적]\n [\n this.#sheet.elements.left.tbody.body,\n this.#sheet.elements.body.tbody.body,\n this.#sheet.elements.right.tbody.body\n ].forEach(($tbody, tbodyIdx) => {\n if (!$tbody) return;\n\n const rows = $tbody.querySelectorAll('tbody.body tr');\n\n //trace.log(`${getTimestamp()}`);\n\n rows.forEach(($tr, index) => {\n const dataIndex = startIndex + Math.floor(index / templateLength);\n\n if (dataIndex >= totalCount) {\n $tr.style.display = 'none';\n $tr.dataset.matrixRow = null;\n $tr.dataset.row = null;\n $tr.dataset.index = null;\n return;\n }\n\n // trace.log(`${getTimestamp()}`);\n const record = viewRecords[dataIndex];//this.#sheet.view.getArray(dataIndex);\n //trace.log(`${getTimestamp()}`);\n\n if (!record) {\n $tr.style.display = 'none';\n return;\n }\n\n const rowid = record.m._[NINE_TABLE.META.INDEX.ROWID];\n\n $tr.style.display = '';\n\n // 💡 만약 개별 바인딩 안에서 느린지 확인하려면 여기서 측정 가능\n this.#bindRowData($tr, record, rowid, dataIndex);\n });\n });\n\n // 셀렉션 갱신\n this.#sheet.selection.refresh();\n };\n\n\n #handleGroupedScroll = (scrollTop, force = false) => {\n\n trace.log(\"handleGroupdScroll() start\")\n\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n //trace.log(allRenderItems);\n\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.templateLength || 1;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH] || 0;\n // 💡 해당 뎁스 그룹 행의 높이가 정확히 잡히는지 확인 (없으면 첫 번째 템플릿 높이)\n const groupHeight = this.#templateRowHeights[depth] || this.#cachedTemplateHeight / templateLength;\n return groupHeight;\n } else {\n // 💡 데이터 행은 전체 템플릿 높이에서 그룹 TR들을 제외한 순수 데이터 TR들의 높이 합산이어야 합니다.\n // 만약 templateLength가 1이고 일반 행이라면 아래와 같이 처리\n let dataRowsHeight = 0;\n // templateRowHeights 전체 중에서 그룹이 아닌 데이터 행들의 높이만 합산하거나,\n // 단일 데이터 템플릿 높이를 정확히 반환해야 합니다.\n const templateLength = this.#sheet.templateLength || 1;\n\n // 간단하게 전체 캐시된 템플릿 높이에서 그룹 높이들을 뺀 나머지를 데이터 높이로 산정\n let groupHeightsTotal = 0;\n for(let i = 0; i < templateLength - 1; i++) {\n groupHeightsTotal += this.#templateRowHeights[i] || 0;\n }\n dataRowsHeight = this.#cachedTemplateHeight - groupHeightsTotal;\n\n return dataRowsHeight > 0 ? dataRowsHeight : this.#cachedTemplateHeight;\n }\n };\n\n\n let totalVirtualHeight = 0;\n const itemHeights = new Array(totalVirtualCount);\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = getItemHeight(allRenderItems[i]);\n itemHeights[i] = h;\n totalVirtualHeight += h;\n }\n\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n trace.log(\"*************\", totalVirtualHeight);\n\n const viewportClientHeight = this.#sheet.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = 0;\n\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = itemHeights[i];\n if (accumulatedHeight + h > scrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n //trace.log(startIndex);\n\n const offsetY = scrollTop - accumulatedHeight;\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.virtualIndex !== undefined\n ? parseInt(firstTr.dataset.virtualIndex, 10)\n : -1;\n\n if (!force && currentStartIndex === startIndex) {\n return;\n }\n\n const visibleRowsCount = Math.ceil(viewportClientHeight / (this.#cachedTemplateHeight / templateLength));\n const dynamicBuffer = (this.#sheet.grouping.columns?.length || 1) * 15;\n const targetStart = startIndex;\n const targetEnd = Math.min(totalVirtualCount, startIndex + visibleRowsCount + dynamicBuffer);\n\n\n\n\n const renderedItems = allRenderItems.slice(targetStart, targetEnd);\n\n //trace.log(\"handleGroupdScroll() 22\", renderedItems);\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const trs = Array.from(container.querySelectorAll('tbody.body tr'));\n\n for (let i = 0; i < trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = trs.slice(i, i + templateLength);\n\n if (!item || itemIndex >= renderedItems.length) {\n chunkTrs.forEach(tr => {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n });\n continue;\n }\n\n const dataIndex = startIndex + itemIndex;\n\n chunkTrs.forEach((tr, subIdx) => {\n const virtualIndex = startIndex + itemIndex;\n tr.dataset.virtualIndex = virtualIndex;\n tr.dataset.row = (item.type === 'data') ? dataIndex : '';\n\n const isTrGroup = tr.getAttribute('grouping') === 'true';\n\n if (item.type === 'group') {\n if (isTrGroup) {\n const depth = item.record[GROUP_IDX.DEPTH];\n if (subIdx === depth) {\n tr.style.display = '';\n this.#bindGroupRowData(tr, allRenderItems, item.record, virtualIndex);\n } else {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n }\n } else {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n }\n } else {\n if (isTrGroup) {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n } else {\n tr.style.display = '';\n\n //trace.log(item.record)\n const rowid = item.record.m?.rowid ?? 0;\n this.#bindRowData(tr, item.record, rowid, virtualIndex);\n }\n }\n });\n }\n });\n\n this.#sheet.selection.refresh();\n\n trace.log(\"handleGroupdScroll() end\")\n };\n\n #bindGroupRowData = ($tr, allRenderItems, groupRecord, virtualIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (virtualIndex * templateLength) + subRowIndex;\n\n const indices = groupRecord[GROUP_IDX.CHILDREN]; // 인덱스 배열이 들어있는 위치 (정확한 인덱스는 구조에 맞게 조절)\n const allRecords = this.#host.data.getArray();\n const childrenRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n // 필요하다면 groupRecord나 tr에 자식 레코드들을 캐싱해 둘 수도 있습니다.\n //groupRecord.childrenRecords = childrenRecords;\n\n //trace.log(allRecords, childrenRecords);\n\n\n $tr.dataset.virtualIndex = virtualIndex;\n $tr.dataset.row = '';\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = childrenRecords;//groupRecord;\n $tr.dataset.groupId = groupRecord[GROUP_IDX.ID];\n\n //trace.log(tr, groupRecord)\n\n Array.from($tr.cells).forEach(($cell) => {\n\n $cell.dataset.row = virtualIndex;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') || typeof $el.refresh === 'function'\n );\n\n //trace.log(customComp)\n\n if (customComp !== undefined && typeof customComp.refresh === 'function') {\n customComp?.refresh();\n }\n });\n };\n\n #bindRowData = ($tr, record, rowid, dataIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (dataIndex * templateLength) + subRowIndex;\n\n $tr.dataset.index = dataIndex;\n $tr.dataset.row = rowid;\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = record;\n\n Array.from($tr.cells).forEach(($cell) => {\n $cell.dataset.index = dataIndex;\n $cell.dataset.row = rowid;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.refresh === 'function'\n );\n\n customComp?.refresh();\n });\n };\n\n initialize = () => {\n //trace.log(\"rowManager.initialize\");\n\n this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n\n this.#cachedTemplateHeight = null;\n this.#containerTemplates.clear();\n\n this.#element = {\n scrollTables: this.#sheet.querySelectorAll('.ng-sheet-body table'),\n firstTr: this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body tr'),\n };\n\n // 컨테이너 템플릿 수집 부분도 tbody.body 기준으로 변경\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const tableEl = container.querySelector('table');\n if (!tableEl) return;\n\n const tbody = tableEl.querySelector('tbody.body'); // 👈 .bindable-tbody 대신 tbody.body\n if (!tbody) return;\n\n const trs = Array.from(tbody.querySelectorAll('tr'));\n const templateTrs = trs.map(tr => tr.cloneNode(true));\n this.#containerTemplates.set(selector, templateTrs);\n });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n if (bodyViewport) {\n this.#sheetHeight = bodyViewport.clientHeight;\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', (e) => {\n\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#cachedTemplateHeight || 0;\n const totalCount = this.#sheet.view.getArray()?.length || 0;\n const rawTotalVirtualHeight = totalCount * rowHeight;\n\n if (rawTotalVirtualHeight <= bodyViewport.clientHeight) {\n trace.log(rawTotalVirtualHeight, bodyViewport.clientHeight)\n return;\n }\n\n this.#handleScroll(bodyViewport.scrollTop);\n\n this.#sheet.querySelector('nine-table-vscrollbar').refresh();\n //this.#sheet.querySelector('nine-table-hscrollbar').refresh();\n }, { passive: true });\n }\n };\n\n scrollToDataRow(dataRow, align = 'top', onRendered) {\n //trace.log(\"🔍 [scrollToDataRow ENTER]\", { dataRow, isGrouped: this.#isGrouped });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords?.length || 0;\n\n const targetRow = Math.max(0, Math.min(dataRow, totalCount - 1));\n let targetScrollTop = 0;\n\n // 🎯 [핵심] 그룹핑 모드일 때는 실제 scrollHeight(또는 렌더링된 총 높이)를 기준으로 비율 계산\n if (this.#isGrouped) {\n const maxScrollTop = Math.max(bodyViewport.scrollHeight - bodyViewport.clientHeight, 1);\n // targetRow가 전체 totalCount에서 차지하는 비율(ratio)만큼 실제 스크롤 최대 높이에 곱해줌\n const ratio = targetRow / Math.max(totalCount - 1, 1);\n targetScrollTop = ratio * maxScrollTop;\n } else {\n /**\n const rowHeight = this.#cachedTemplateHeight;\n\n let rawTargetScrollTop = targetRow * rowHeight;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n //const rawTotalVirtualHeight = 0;\n\n trace.log(\"****************\", rawTotalVirtualHeight);\n\n //const rawTotalVirtualHeight = totalCount * rowHeight;\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n }\n\n targetScrollTop = rawTargetScrollTop * scaleFactor;\n */\n const rowHeight = this.#cachedTemplateHeight;\n const rawTargetScrollTop = targetRow * rowHeight;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = bodyViewport.offsetHeight || 0;\n\n // #handleScroll에서 사용하는 rawTotalVirtualHeight 공식과 정확히 일치시켜야 함\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + fixedHeight - viewHeight, 0);\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n }\n\n targetScrollTop = rawTargetScrollTop * scaleFactor;\n }\n\n //trace.log(\"🔍 [scrollToDataRow CALC FIXED]\", { targetRow, totalCount, targetScrollTop });\n\n trace.log(targetScrollTop);\n\n this.#isProgrammaticScroll = true;\n bodyViewport.scrollTop = targetScrollTop;\n this.#handleScroll(targetScrollTop);\n //trace.log(targetScrollTop);\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.#isProgrammaticScroll = false;\n if (typeof onRendered === 'function') onRendered();\n });\n });\n }\n\n\n\n destroy = () => {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n };\n\n #measureAndCacheHeight = () => {\n if (!this.#sheet.classList.contains('active')) return;\n\n if (!this.#sheet.sourceTable) return;\n\n const trTemplates = this.#sheet.sourceTable?.querySelectorAll('tbody.body tr');\n //trace.log(\"[DEBUG #measureAndCacheHeight] bodyTemplates count:\", trTemplates?.length);\n //if (!trTemplates || trTemplates.length === 0) return;\n\n const $tbody = this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body');\n //if (!tbody) return -1;\n\n $tbody.querySelectorAll('tr').forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n trTemplates.forEach($tr => fragment.appendChild($tr.cloneNode(true)));\n $tbody.appendChild(fragment);\n\n //let totalHeight = 0;\n const renderedTrs = $tbody.querySelectorAll('tr');\n\n this.#templateRowHeights = [];\n renderedTrs.forEach($tr => {\n //const h = $tr.offsetHeight;\n //trace.log(`[DEBUG #measureAndCacheHeight] tr[${idx}] height:`, h);\n //totalHeight += h;\n\n if ($tr?.offsetHeight === 2) {\n trace.log(\"================================\");\n trace.log(this.#sheet);\n trace.log($tr);\n trace.log($tr.cloneNode(true));\n\n const computedStyle = window.getComputedStyle($tr);\n //const rectHeight = parseFloat(computedStyle.height) || parseFloat(computedStyle.minHeight) || 0\n\n trace.log(\"================================\", computedStyle, computedStyle.height, computedStyle.minHeight);\n }\n\n this.#templateRowHeights.push(Math.max($tr.offsetHeight, 24));\n });\n\n renderedTrs.forEach(tr => tr.remove());\n\n this.#cachedTemplateHeight = this.#templateRowHeights.reduce((sum, h) => sum + h, 0);\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n trace.log(\"[DEBUG #updateRowCount] sheetHeight:\", this.#sheetHeight, \"cachedTemplateHeight:\", this.#cachedTemplateHeight);\n if (this.#sheetHeight > 0 && this.#cachedTemplateHeight > 0) {\n const visibleRows = Math.ceil(this.#sheetHeight / this.#cachedTemplateHeight);\n\n // 💡 [유연한 개선] 그룹화가 켜져 있다면 그룹 컬럼 깊이(다단 레벨)에 따라 버퍼를 동적으로 확장\n let dynamicBuffer = this.#BUFFER_ROW_COUNT;\n if (this.#isGrouped && this.#sheet.grouping) {\n const groupDepth = this.#sheet.grouping.columns?.length || 1;\n // 그룹 단계가 깊을수록 헤더 행이 많이 차지하므로 여유분을 비례해서 늘림 (예: 기본 버퍼 + (뎁스당 추가 여유))\n dynamicBuffer += (groupDepth * 15);\n }\n\n this.#cachedRowCount = visibleRows + dynamicBuffer;\n trace.log(\"[DEBUG #updateRowCount] calculated cachedRowCount:\", this.#host, this.#cachedRowCount);\n }\n };\n\n #renderAllContainers = () => {\n trace.log(\"rowManager.#renderAllContainers\");\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (container && container.querySelector('tbody')) {\n this.#renderRows(container); // selector 인자 제거!\n }\n });\n\n this.#syncRowHeights();\n };\n\n #renderRows = (container) => {\n let targetFixedType = null;\n if (container.classList.contains('ng-container-left')) targetFixedType = 'left';\n else if (container.classList.contains('ng-container-right')) targetFixedType = 'right';\n\n // 🎯 [수정] 원본 테이블에서 tbody.body에 해당하는 tr들만 복제\n const templateTrs = Array.from(this.#sheet.sourceTable.querySelectorAll('tbody.body tr')).map(tr => {\n const clonedTr = tr.cloneNode(true);\n\n if (targetFixedType === 'left') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'left') $cell.remove();\n });\n } else if (targetFixedType === 'right') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'right') $cell.remove();\n });\n } else {\n clonedTr.querySelectorAll('[fixed=left], [fixed=right]').forEach($cell => {\n $cell.remove();\n });\n }\n\n return clonedTr;\n });\n\n if (templateTrs.length === 0) return;\n\n // 🎯 [수정] targetTbody도 일반 tbody가 아니라 tbody.body를 정확히 타겟팅\n const targetTbody = container.querySelector('tbody.body');\n if (!targetTbody) return;\n\n targetTbody.querySelectorAll(\"tr\").forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < this.#cachedRowCount; i++) {\n templateTrs.forEach(tmpl => fragment.appendChild(tmpl.cloneNode(true)));\n }\n\n\n targetTbody.appendChild(fragment);\n\n if (container.classList.contains('ng-container-body')) {\n this.#element.firstTr = targetTbody.querySelector('tr');\n }\n };\n\n\n\n #syncRowHeights = () => {\n const leftTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-left table');\n const bodyTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-body table');\n const rightTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-right table');\n\n if (bodyTable) {\n const leftRows = leftTable ? Array.from(leftTable.querySelectorAll('tbody tr')) : [];\n const bodyRows = Array.from(bodyTable.querySelectorAll('tbody tr'));\n const rightRows = rightTable ? Array.from(rightTable.querySelectorAll('tbody tr')) : [];\n\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n }\n };\n\n #initResizeObserver = () => {\n\n if (!this.#sheet || !(this.#sheet instanceof HTMLElement)) return;\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n\n const sheetEl = entry.target;\n if (!sheetEl.classList.contains('active')) continue;\n\n const height = entry.contentRect.height;\n const width = entry.contentRect.width;\n\n if (width > 0 && this.#sheet.isAutoFitCol) {\n this.#sheet.autoFit(true);\n }\n\n if (height > 0 && this.#sheetHeight !== height) {\n this.#sheetHeight = height;\n this.#updateRowCount();\n\n if (this.#cachedTemplateHeight !== null) {\n this.#renderAllContainers();\n this.refresh();\n }\n }\n }\n });\n\n this.#resizeObserver.observe(this.#sheet);\n };\n}","import { trace } from \"@nopeer\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class TableCompiler {\n\n static compile($srcTable) {\n\n const $table = $srcTable.cloneNode(true);\n\n // 1. 헤더 컴파일\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n // 4. colgroup과 인덱스/fixed 속성 동기화\n TableCompiler.#syncColAttributes($table);\n\n /**\n setTimeout(() => {\n console.log(\"DEBUG------------------+++++++\", $table);\n\n const templateHeights = TableCompiler.#measureTemplateHeights($table);\n $table.__templateRowHeights = templateHeights;\n $table.__cachedTemplateHeight = templateHeights.reduce((sum, h) => sum + h, 0);\n\n console.log(\"DEBUG------------------\", $table.__templateRowHeights, $table.__cachedTemplateHeight);\n }); */\n\n return $table;\n }\n\n static recompile($table) {\n\n /** 너비조정은 필요없을듯 */\n /**\n const cols = Array.from($table.querySelectorAll('colgroup col'));\n cols.forEach((col, idx) => {\n //trace.log(col.cloneNode(true));\n\n col.setAttribute('data-col', idx);\n\n let w = col.getAttribute('width');\n if (!w || isNaN(parseFloat(w))) {\n w = parseFloat(col.style.width);\n }\n if (w && !isNaN(parseFloat(w))) {\n const numericWidth = Math.round(parseFloat(w));\n //trace.log(w, numericWidth);\n\n col.setAttribute('width', numericWidth);\n col.style.width = `${numericWidth}px`;\n }\n }); */\n\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n TableCompiler.#syncColAttributes($table);\n\n\n\n return $table;\n }\n\n static #measureTemplateHeights($table) {\n const trTemplates = $table.querySelectorAll('tbody tr');\n if (!trTemplates || trTemplates.length === 0) return [24]; // 방어 코드\n\n // 1. 화면에 영향을 주지 않는 숨겨진 측정용 임시 컨테이너 생성\n const measureBox = document.createElement('div');\n measureBox.style.cssText = 'position: absolute; visibility: hidden; pointer-events: none; top: -9999px; left: -9999px; width: 1000px;';\n\n const tempTable = document.createElement('table');\n const tempTbody = document.createElement('tbody');\n tempTbody.className = 'body';\n\n trTemplates.forEach($tr => {\n trace.log(\"DEBUG\", $tr);\n tempTbody.appendChild($tr.cloneNode(true));\n });\n tempTable.appendChild(tempTbody);\n measureBox.appendChild(tempTable);\n document.body.appendChild(measureBox);\n\n // 2. 브라우저 레이아웃 엔진을 통해 실제 렌더링 높이 측정\n const heights = [];\n tempTbody.querySelectorAll('tr').forEach($tr => {\n const h = $tr.getBoundingClientRect().height || $tr.offsetHeight;\n heights.push(h > 0 ? h : 24); // 0일 경우 최소 높이 24 보장\n });\n\n // 3. 측정 완료 후 즉시 DOM에서 제거 (메모리 누수 방지)\n document.body.removeChild(measureBox);\n\n return heights;\n }\n\n static #syncColAttributes($table) {\n\n $table.querySelectorAll('colgroup col').forEach(($col, i) => {\n $col.setAttribute('data-col', i);\n const fixed = $col.getAttribute('fixed');\n\n $table.querySelectorAll(`[data-col=\"${i}\"]`).forEach($el => {\n fixed ? $el.setAttribute('fixed', fixed) : $el.removeAttribute('fixed');\n });\n });\n }\n\n static resetColIndex($table, trs) {\n\n const cols = $table.querySelectorAll('colgroup col');\n const grid = Array.from({ length: trs.length }, () => Array(cols.length).fill(null));\n\n trs.forEach(($tr, index) => {\n\n $tr.dataset.subrow = index;\n\n let colIndex = 0;\n\n $tr.querySelectorAll('th, td').forEach($cell => {\n\n while (colIndex < cols.length && grid[index][colIndex] !== null) {\n colIndex++;\n }\n\n $cell.dataset.col = colIndex;\n\n const rowSpan = $cell.rowSpan || 1;\n const colSpan = $cell.colSpan || 1;\n\n for (let r = 0; r < rowSpan; r++) {\n for (let c = 0; c < colSpan; c++) {\n if (index + r < trs.length && colIndex + c < cols.length) {\n grid[index + r][colIndex + c] = $cell;\n }\n }\n }\n\n colIndex += colSpan;\n });\n });\n }\n\n\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellSelection {\r\n\t#sheet;\r\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#initEvents();\r\n\r\n\t\t/**\r\n\t\t// 🎯 [신규 구조 대응] .ng-sheet-body 및 내부 컨테이너 스크롤 감지\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (bodyViewport) {\r\n\t\t\tbodyViewport.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t} */\r\n\r\n\t\t/**\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}); */\r\n\r\n\t\ttrace.log(\"🎯 [CellSelection] Initialized (New Structure Compatible)\");\r\n\t}\r\n\r\n\t#getMatrixRow(tr) {\r\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst dataRow = parseInt(tr.dataset.index, 10);\r\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr'));\r\n\r\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.index, 10) === dataRow);\r\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\r\n\t\tconst templateLength = sameGroupTrs.length > 0 ? sameGroupTrs.length : 1;\r\n\r\n\t\tconst matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\r\n\r\n\t\treturn { dataRow, subRowIndex, matrixRow };\r\n\t}\r\n\r\n\tsetFocus(matrixRow, col) {\r\n\t\t// 1. 기존 포커스 클래스 제거\r\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {\r\n\t\t\t$tr.classList.remove(\"selected-start\");\r\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {\r\n\t\t\t\t$td.classList.remove(\"selected-start\");\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 [신규 구조 대응] data-matrix-row 탐색 경로 수정 (.ng-sheet-body-content 기준)\r\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!$td) return;\r\n\r\n\t\t$td.classList.add(\"selected-start\");\r\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\r\n\t}\r\n\r\n\tsetRange(startRow, startCol, endRow, endCol) {\r\n\t\tlet r1 = Math.min(startRow, endRow);\r\n\t\tlet r2 = Math.max(startRow, endRow);\r\n\t\tlet c1 = Math.min(startCol, endCol);\r\n\t\tlet c2 = Math.max(startCol, endCol);\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll('.ng-container-left, .ng-container-body, .ng-container-right');\r\n\r\n\t\tlet expanded = true;\r\n\t\tlet loopCount = 0;\r\n\r\n\t\twhile (expanded && loopCount < 5) {\r\n\t\t\texpanded = false;\r\n\t\t\tloopCount++;\r\n\r\n\r\n\r\n\t\t\tcontainers.forEach(container => {\r\n\r\n\t\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\r\n\t\t\t\t\treturn tr.style.display !== 'none'; // 혹은 tr.offsetHeight > 0 체크\r\n\t\t\t\t});\r\n\r\n\t\t\t\tvisibleTrs.forEach(tr => {\r\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\r\n\r\n\t\t\t\t\t\tif (isIntersecting) {\r\n\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\r\n\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\r\n\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\r\n\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\r\n\r\n\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\r\n\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\r\n\t\t\t\t\t\t\t\texpanded = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#range = { startRow: r1, startCol: c1, endRow: r2, endCol: c2 };\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trefresh = () => {\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trender = () => {\r\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-container-left, .ng-container-body, .ng-container-right'\r\n\t\t);\r\n\r\n\t\t/**\r\n\t\tconst selectedStartTr = this.#sheet.querySelector('tr.selected-start');\r\n\t\tconst selectedStartCell = this.#sheet.querySelector('th.selected-start,td.selected-start');\r\n\r\n\t\tconst selectedStartMatrixRow = parseInt(selectedStartTr?.dataset.matrixRow, 10);\r\n\t\tconst selectedStartIndex = parseInt(selectedStartCell?.dataset.index, 10);\r\n\t\tconst selectedStartCol = parseInt(selectedStartCell?.dataset.col, 10);\r\n\t\t*/\r\n\r\n\t\t// 1. 기존 선택 클래스 초기화\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\r\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\r\n\t\t\t});\r\n\r\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\r\n\t\t\t\ttr.classList.remove('selected-start');\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tif (startRow < 0 || startCol < 0) return;\r\n\r\n\t\t// 2. 범위 렌더링\r\n\t\tcontainers.forEach((container) => {\r\n\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\r\n\t\t\t\treturn tr.style.display !== 'none'; // 혹은 tr.offsetHeight > 0 체크\r\n\t\t\t});\r\n\r\n\t\t\tvisibleTrs.forEach(tr => {\r\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\r\n\t\t\t\t\tif (!isSelected) return;\r\n\r\n\t\t\t\t\tcell.classList.add('selected');\r\n\r\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\r\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\r\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\r\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t/**\r\n\t\ttrace.log(selectedStartMatrixRow, selectedStartCol);\r\n\t\t// 3. 포커스 셀 복구\r\n\t\tconst $focusTd = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${selectedStartMatrixRow}\"] td[data-col=\"${selectedStartCol}\"]`);\r\n\t\tif ($focusTd) {\r\n\t\t\t$focusTd.classList.add(\"selected-start\");\r\n\t\t}\r\n\r\n\t\tthis.#sheet.querySelectorAll(`.ng-sheet-body-content tr[data-matrix-row=\"${selectedStartMatrixRow}\"]`).forEach($tr => {\r\n\t\t\t$tr.classList.add(\"selected-start\");\r\n\t\t}); */\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!mainZone) {\r\n\t\t\ttrace.log(\"❌ [CellSelection] .ng-sheet-body not found!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmainZone.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\r\n\t\t\tthis.#sheet.style.userSelect = 'none';\r\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\r\n\r\n\t\t\tconst tr = cell.closest('tr');\r\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\r\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\r\n\r\n\t\t\tif (startRow < 0) {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tthis.setFocus(startRow, startCol);\r\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\r\n\r\n\t\t\tlet lastMatrixRow = startRow;\r\n\t\t\tlet lastCol = startCol;\r\n\r\n\t\t\tconst onMouseMove = (moveEvent) => {\r\n\t\t\t\tconst targetEl = document.elementFromPoint(moveEvent.clientX, moveEvent.clientY);\r\n\t\t\t\tlet targetCell = targetEl?.closest('td, th');\r\n\r\n\t\t\t\tif (!targetCell || !this.#sheet.contains(targetCell)) {\r\n\t\t\t\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr td, .ng-sheet-body-content tbody tr:not(.nodata) th');\r\n\t\t\t\t\tfor (const c of allCells) {\r\n\t\t\t\t\t\tconst rect = c.getBoundingClientRect();\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tmoveEvent.clientX >= rect.left &&\r\n\t\t\t\t\t\t\tmoveEvent.clientX <= rect.right &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY >= rect.top &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY <= rect.bottom\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\ttargetCell = c;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!targetCell) return;\r\n\t\t\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\r\n\r\n\t\t\t\tconst targetTr = targetCell.closest('tr');\r\n\t\t\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\r\n\t\t\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\r\n\r\n\t\t\t\tif (endRow < 0) return;\r\n\t\t\t\tif (lastMatrixRow === endRow && lastCol === endCol) return;\r\n\r\n\t\t\t\tlastMatrixRow = endRow;\r\n\t\t\t\tlastCol = endCol;\r\n\r\n\t\t\t\tthis.setRange(startRow, startCol, endRow, endCol);\r\n\t\t\t};\r\n\r\n\t\t\tconst onMouseUp = () => {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\r\n\t\t\t\tdocument.removeEventListener('mousemove', onMouseMove);\r\n\t\t\t\tdocument.removeEventListener('mouseup', onMouseUp);\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener('mousemove', onMouseMove);\r\n\t\t\tdocument.addEventListener('mouseup', onMouseUp);\r\n\t\t});\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellNavigation {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#currentCell = null;\r\n\t#currentTr = null;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.#initEvents();\r\n\t\ttrace.log(\"🎯 [CellNavigation] Initialized (Diagnostic Logging Restored)\");\r\n\t}\r\n\r\n\tget currentCell() {\r\n\t\treturn this.#currentCell;\r\n\t}\r\n\r\n\tset currentCell(cell) {\r\n\t\tif (!cell) return;\r\n\r\n\t\tthis.#currentCell = cell;\r\n\t\tcell.focus({ preventScroll: true });\r\n\r\n\t\tthis.#currentTr = cell.closest(\"tr\");\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);//this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\t//trace.log(`📌 [setCurCell] Active set -> dataRow: ${cell.dataset.index}, subrow: ${cell.closest('tr')?.dataset.subrow}, matrixRow: ${matrixRow}, col: ${cell.dataset.col}`);\r\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\r\n\t}\r\n\r\n\r\n\t#moveCellH = (e, cell) => {\r\n\r\n\t\tif (!cell) return;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\r\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (!this.#isCellRightVisible(cell)) {\r\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tif (!this.#isCellRightVisible(cell)) {\r\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\r\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tthis.currentCell = cell;\r\n\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\r\n\t};\r\n\r\n\t#moveCellV = (e, cell) => {\r\n\t\tif (cell) {\r\n\t\t\tlet isVisible = false;\r\n\t\t\tswitch (e.code) {\r\n\t\t\t\tcase \"Enter\":\r\n\t\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\r\n\t\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\r\n\t\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"ArrowDown\":\r\n\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\r\n\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"ArrowUp\":\r\n\t\t\t\t\tif (this.#isCellAboveVisible(cell)) {\r\n\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tif (isVisible) {\r\n\t\t\t\tthis.currentCell = cell;\r\n\t\t\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\r\n\t\tlet scrollTopIndex = -1;\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"Enter\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tconst visibleRowCount = this.#getVisibleRowCount();\r\n\t\t\t\t\tscrollTopIndex = Math.max(dataIndex - visibleRowCount + 0, 0);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tscrollTopIndex = Math.min(dataIndex, this.#sheet.view.count());\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tscrollTopIndex = Math.min(dataIndex, this.#sheet.view.count());\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tconst visibleRowCount = this.#getVisibleRowCount();\r\n\t\t\t\tscrollTopIndex = Math.max(dataIndex - visibleRowCount + 0, 0);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tif (scrollTopIndex < 0) return;\r\n\r\n\t\tlet matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst rowSpan = parseInt(this.#currentCell.rowSpan, 10) || 1;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tmatrixRow += rowSpan;\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tmatrixRow --;\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.rowManager.scrollToDataRow(scrollTopIndex, null, () => {\r\n\t\t\tconst currentCell = this.#findCell(matrixRow, col);\r\n\r\n\t\t\tif (currentCell) {\r\n\t\t\t\tthis.currentCell = currentCell;\r\n\t\t\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, currentCell.dataset.col, this.#currentTr.dataset.matrixRow, currentCell.dataset.col);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tmoveCell = (e) => {\r\n\r\n\t\tif (e.target.tagName === \"INPUT\") {\r\n\t\t\tif ([\"text\"].includes(e.target.type)) {\r\n\t\t\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Home\",\"End\"].includes(e.code)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif ([\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(e.target.type)) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#currentCell || !this.#currentTr) {\r\n\t\t\ttrace.log(\"⚠️ [moveCell] currentCell or currentTr is missing!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet nextCell;\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tnextCell = e.shiftKey ? this.#getPreviousCell() : this.#getNextCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tnextCell = this.#getNextCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tnextCell = this.#getPreviousCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Enter\":\r\n\t\t\t\tnextCell = e.shiftKey ? this.#getUpCell() : this.#getDownCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tnextCell = this.#getDownCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tnextCell = this.#getUpCell();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\te.preventDefault();\r\n\r\n\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Tab\"].includes(e.code)) {\r\n\t\t\tthis.#moveCellH(e, nextCell);\r\n\t\t}\r\n\t\telse if ([\"Enter\",\"ArrowUp\",\"ArrowDown\"].includes(e.code)) {\r\n\t\t\tthis.#moveCellV(e, nextCell);\r\n\t\t}\r\n\t}\r\n\r\n\t#getNextCell = () => {\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst colSpan = parseInt(this.#currentCell.colSpan, 10) || 1;\r\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\r\n\t\tconst nextCol = col + colSpan;\r\n\r\n\t\tlet nextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${nextCol}\"]`);\r\n\t\tif (!nextCell) {\r\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${nextCol}\"]`);\r\n\t\t}\r\n\r\n\t\treturn nextCell;\r\n\t}\r\n\r\n\t#getPreviousCell = () => {\r\n\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\r\n\t\tlet nextCell;\r\n\t\tfor (let i = col - 1; i >= 0; i--) {\r\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${i}\"]`);\r\n\t\t\tif (!nextCell) {\r\n\t\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${i}\"]`);\r\n\t\t\t}\r\n\r\n\t\t\tif (nextCell) break;\r\n\t\t}\r\n\r\n\t\treturn nextCell;\r\n\t}\r\n\r\n\r\n\r\n\t#findCell = (matrixRow, col) => {\r\n\r\n\t\tconst $tr = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"]`);\r\n\t\tif (!$tr) return;\r\n\r\n\t\tconst dataIndex = parseInt($tr.dataset.index, 10);\r\n\r\n\t\tlet targetCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!targetCell) {\r\n\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-matrix-row=\"${matrixRow}\"] td`).forEach($cell => {\r\n\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\r\n\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\r\n\r\n\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\r\n\t\t\t\t\ttargetCell = $cell;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tif (!targetCell) {\r\n\t\t\t\ttargetCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${col}\"]`);\r\n\r\n\t\t\t\tif (!targetCell) {\r\n\t\t\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-index=\"${dataIndex}\"] td`).forEach($cell => {\r\n\t\t\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\r\n\r\n\t\t\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\r\n\t\t\t\t\t\t\ttargetCell = $cell;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn targetCell;\r\n\t}\r\n\r\n\t#getUpCell = () => {\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\r\n\t\treturn this.#findCell(matrixRow - 1, col);\r\n\t}\r\n\r\n\t#getDownCell = () => {\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\t\tconst rowSpan = parseInt(this.#currentCell.rowSpan, 10) || 1;\r\n\r\n\t\treturn this.#findCell(matrixRow + rowSpan, col);\r\n\t}\r\n\r\n\t// 1. 위쪽 잘림 체크 (기준: bodyViewport)\r\n\t#isCellAboveVisible = (cell) => {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!bodyViewport || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\t\tconst theadHeight = bodyViewport.querySelector('thead')?.offsetHeight || 0;\r\n\r\n\t\t// 셀의 상단이 헤더 아래쪽보다 위에 있으면 잘린(안 보이는) 상태\r\n\t\treturn cellRect.top >= (viewportRect.top + theadHeight);\r\n\t}\r\n\r\n\t// 2. 아래쪽 잘림 체크 (기준: bodyViewport)\r\n\t#isCellBelowVisible = (cell) => {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!bodyViewport || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\r\n\t\t// 셀의 하단이 뷰포트 하단보다 아래에 있으면 잘린 상태\r\n\t\treturn cellRect.bottom <= viewportRect.bottom;\r\n\t}\r\n\r\n\t// 3. 왼쪽 잘림 체크 (기준: bodyViewport2)\r\n\t#isCellLeftVisible = (cell) => {\r\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body'); // 또는 좌우 스크롤을 담당하는 뷰포트\r\n\t\tif (!bodyViewport2 || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\r\n\r\n\t\t// 셀의 좌측이 뷰포트 좌측보다 왼쪽에 있으면 잘린 상태\r\n\t\treturn cellRect.left >= viewportRect.left;\r\n\t}\r\n\r\n\t// 4. 오른쪽 잘림 체크 (기준: bodyViewport2)\r\n\t#isCellRightVisible = (cell) => {\r\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body');\r\n\t\tif (!bodyViewport2 || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\r\n\r\n\t\t// 셀의 우측이 뷰포트 우측보다 오른쪽에 있으면 잘린 상태\r\n\t\treturn cellRect.right <= viewportRect.right;\r\n\t}\r\n\r\n\t// 💡 필요하다면 이 4개를 조합해서 전체 가시성을 판단하는 통합 함수도 쉽게 구성할 수 있습니다.\r\n\t#isCellVisible = (cell) => {\r\n\t\treturn this.#isCellAboveVisible(cell) &&\r\n\t\t\tthis.#isCellBelowVisible(cell) &&\r\n\t\t\tthis.#isCellLeftVisible(cell) &&\r\n\t\t\tthis.#isCellRightVisible(cell);\r\n\t}\r\n\r\n\t#getVisibleRowCount = () => {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tconst viewportHeight = bodyViewport.clientHeight - (bodyViewport.querySelector('thead')?.offsetHeight || 0);\r\n\t\tconst rowHeight = this.#sheet.rowManager.getRowHeight();\r\n\r\n\t\t// 뷰포트 높이에 들어오는 행 개수 계산 (소수점 버림)\r\n\t\treturn Math.max(1, Math.floor(viewportHeight / rowHeight));\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.index === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tthis.currentCell = cell;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\r\n\t\t\tif ([\"Enter\", \"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\r\n\t\t\t\tthis.moveCell(e);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}","// ui/col/ColResizer.js\nimport { trace } from \"@nopeer\";\nimport { COLLAPSED_WIDTH } from \"@/layout/core/TableCompiler.js\";\n\nconst RESIZE_OFFSET = 2; // 🎯 리사이즈 감지 영역 오프셋을 상단으로 추출\n\nexport class ColResizer {\n #sheet;\n #host;\n #panel;\n #tooltip;\n\n #targetColIndex = null;\n #nextColIndex = null;\n #targetContainerType = null;\n #targetCell = null;\n #startX = 0;\n #startColWidth = 0;\n #nextColStartWidth = 0;\n #startCellWidth = 0;\n #startLeft = 0;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#host = sheet.getRootNode().host;\n this.#panel = this.#sheet.querySelector('nine-table-col-resizer-panel');\n\n this.#tooltip = this.#panel.querySelector('.resizer-overlay');\n this.bindEvents();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointermove', this.#onPointerMove);\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n this.#sheet.removeEventListener('dblclick', this.#onDblClick);\n }\n\n refreshLayout(containerType = 'body') {\n const containers = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType}`));\n if (containers.length === 0) return;\n\n const isFixedContainer = containerType === 'left' || containerType === 'right';\n const isAutoFit = !isFixedContainer && (\n this.#sheet.isAutoFitCol ||\n containers[0].querySelector('table')?.getAttribute('auto-fit-col') === 'true'\n );\n\n if (!isAutoFit) {\n\n const firstColgroup = containers[0].querySelector('table colgroup');\n if (!firstColgroup) return;\n\n let totalWidth = 0;\n const colWidths = {};\n\n Array.from(firstColgroup.querySelectorAll('col')).forEach(col => {\n const colIdx = col.getAttribute('data-col');\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) {\n colWidths[colIdx] = w;\n totalWidth += w;\n }\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n\n trace.log(\"====================\", containers, containerType);\n\n if (containerType === 'body') {\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n //tbl.style.minWidth = `${totalWidth}px`;\n });\n } else {\n container.style.flex = `0 0 ${totalWidth}px`;\n container.style.width = `${totalWidth}px`;\n container.style.minWidth = `${totalWidth}px`;\n container.style.maxWidth = `${totalWidth}px`;\n\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n tbl.style.minWidth = `${totalWidth}px`;\n tbl.style.maxWidth = `${totalWidth}px`;\n\n Object.entries(colWidths).forEach(([colIdx, w]) => {\n tbl.querySelectorAll(`th[data-col=\"${colIdx}\"], td[data-col=\"${colIdx}\"]`).forEach(cell => {\n cell.style.width = `${w}px`;\n cell.style.minWidth = `${w}px`;\n cell.style.maxWidth = `${w}px`;\n });\n });\n });\n }\n });\n } else {\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n tables.forEach(tbl => {\n //tbl.style.width = '100%';\n //tbl.style.minWidth = '100%';\n //tbl.style.maxWidth = '';\n });\n });\n }\n\n this.#sheet.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n setColumnWidth(globalColIndex, width, containerType = null) {\n\n trace.log(\"setColumnWidth\");\n\n\n let targetCols = [];\n\n //if (containerType) {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType} table colgroup col[data-col=\"${globalColIndex}\"]`));\n //} else {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n //}\n targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n\n if (targetCols.length === 0) return;\n\n const firstContainer = targetCols[0].closest('.ng-container-left, .ng-container-body, .ng-container-right');\n const resolvedContainerType = containerType || (\n firstContainer?.classList.contains('ng-container-left') ? 'left' :\n firstContainer?.classList.contains('ng-container-right') ? 'right' : 'body'\n );\n\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n\n trace.log(col, width);\n });\n\n const sourceCol = this.#sheet.sourceTable?.querySelector(`colgroup col[data-col=\"${globalColIndex}\"]`);\n if (sourceCol) {\n sourceCol.setAttribute('width', width);\n sourceCol.style.width = `${width}px`;\n }\n\n\n\n this.refreshLayout(resolvedContainerType);\n\n // 🎯 [핵심] autoFit을 여기서 또 호출하면 루프가 돌거나 레이아웃 계산이 꼬입니다.\n // 바디 영역 리사이즈 시에는 body만 refreshLayout 해주면 됩니다!\n if (resolvedContainerType === 'left' || resolvedContainerType === 'right') {\n this.refreshLayout('body');\n }\n\n this.#sheet.rowManager?.refresh();\n }\n\n #checkIsAutoFit(targetCell) {\n if (this.#sheet.isAutoFitCol) return true;\n const table = targetCell?.closest('table');\n if (table && table.getAttribute('auto-fit-col') === 'true') return true;\n return false;\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointermove', this.#onPointerMove);\n //this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n //this.#sheet.addEventListener('dblclick', this.#onDblClick);\n\n this.#sheet.addDebounseEventListener('dblclick', this.#onDblClick, 'pointerdown', this.#onPointerDown);\n }\n\n #getContainerType(cell) {\n const container = cell.closest('.ng-container-left, .ng-container-body, .ng-container-right');\n if (!container) return null;\n if (container.classList.contains('ng-container-left')) return 'left';\n if (container.classList.contains('ng-container-right')) return 'right';\n return 'body';\n }\n\n #onPointerMove = (e) => {\n\n\n const headerPart = e.target.closest('thead');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n\n headerPart.querySelectorAll('.resizable-edge').forEach(el => {\n if (el !== cell) el.classList.remove('resizable-edge');\n });\n\n if (!cell || cell.dataset.col === undefined) return;\n if (cell.getAttribute('collapsed') === 'true') return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n const isLeftEdge = offsetX <= RESIZE_OFFSET;\n const isRightEdge = (rect.width - offsetX) <= RESIZE_OFFSET;\n\n if (isLeftEdge) {\n const prevCell = cell.previousElementSibling;\n if (!prevCell || prevCell.getAttribute('collapsed') === 'true') {\n cell.classList.remove('resizable-edge');\n return;\n }\n }\n\n if (isLeftEdge || isRightEdge) {\n cell.classList.add('resizable-edge');\n } else {\n cell.classList.remove('resizable-edge');\n }\n };\n\n #onPointerDown = (e) => {\n\n trace.log(\"onPointerDown\");\n\n const headerPart = e.actualTarget.closest('thead');\n if (!headerPart) return;\n\n const cell = e.actualTarget.closest('th, td');\n trace.log(cell, e.actualTarget);\n\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n\n\n e.preventDefault();\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n let targetCell = cell;\n\n if (offsetX <= RESIZE_OFFSET) {\n const prevCell = cell.previousElementSibling;\n if (prevCell && prevCell.dataset.col !== undefined && prevCell.getAttribute('collapsed') !== 'true') {\n targetCell = prevCell;\n } else if (!cell.previousElementSibling) {\n return;\n }\n }\n\n this.#targetCell = targetCell;\n this.#targetContainerType = this.#getContainerType(targetCell);\n\n const container = this.#sheet.querySelector(`.ng-container-${this.#targetContainerType}`);\n if (!container) return;\n\n const baseColIndex = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n this.#targetColIndex = baseColIndex + colSpan - 1;\n\n const isAutoFit = this.#checkIsAutoFit(targetCell);\n if (isAutoFit) {\n this.#nextColIndex = this.#targetColIndex + 1;\n const nextColEl = container.querySelector(`col[data-col=\"${this.#nextColIndex}\"]`);\n if (nextColEl) {\n this.#nextColStartWidth = parseInt(nextColEl.getAttribute('width'), 10) || 100;\n } else {\n this.#nextColIndex = null;\n }\n } else {\n this.#nextColIndex = null;\n }\n\n const targetRect = targetCell.getBoundingClientRect();\n const sheetRect = this.#sheet.getBoundingClientRect();\n\n this.#startCellWidth = targetRect.width;\n this.#startLeft = targetRect.left - sheetRect.left;\n\n const targetColEl = container.querySelector(`col[data-col=\"${this.#targetColIndex}\"]`);\n const attrW = targetColEl?.getAttribute('width');\n this.#startColWidth = (attrW && !isNaN(parseInt(attrW, 10))) ? parseInt(attrW, 10) : targetRect.width / colSpan;\n\n this.#startX = e.clientX;\n\n if (this.#panel) {\n this.#panel.classList.add('active');\n this.#updatePositions(e.clientX);\n }\n\n window.addEventListener('pointermove', this.#onDragMove);\n window.addEventListener('pointerup', this.#onDragEnd, { once: true });\n };\n\n #updatePositions(clientX) {\n let diff = clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxDiff = this.#nextColStartWidth - COLLAPSED_WIDTH;\n const minDiff = -(this.#startColWidth - COLLAPSED_WIDTH);\n diff = Math.max(minDiff, Math.min(diff, maxDiff));\n }\n\n const currentColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n\n const targetRect = this.#targetCell.getBoundingClientRect();\n let realCellWidth = clientX - targetRect.left;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxCellWidth = this.#startCellWidth + (this.#nextColStartWidth - COLLAPSED_WIDTH);\n realCellWidth = Math.min(realCellWidth, maxCellWidth);\n }\n\n const currentCellWidth = Math.max(COLLAPSED_WIDTH, realCellWidth);\n\n if (this.#panel) {\n this.#panel.style.setProperty('--col-resizer-tooltip-left', `${this.#startLeft}px`);\n this.#panel.style.setProperty('--col-resizer-tooltip-width', `${currentCellWidth}px`);\n }\n\n const sizeBadge = this.#tooltip?.querySelector('.size-badge');\n if (sizeBadge) {\n sizeBadge.textContent = `${Math.round(currentColWidth)}px`;\n }\n }\n\n #onDragMove = (e) => {\n trace.log(e);\n this.#updatePositions(e.clientX);\n };\n\n #onDragEnd = (e) => {\n window.removeEventListener('pointermove', this.#onDragMove);\n\n const diff = e.clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n let finalWidth = 0;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n let newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n let newNextWidth = this.#startColWidth + this.#nextColStartWidth - newColWidth;\n\n if (newNextWidth < COLLAPSED_WIDTH) {\n newNextWidth = COLLAPSED_WIDTH;\n newColWidth = this.#startColWidth + this.#nextColStartWidth - COLLAPSED_WIDTH;\n }\n\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n this.setColumnWidth(this.#nextColIndex, newNextWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n } else {\n const newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n if (this.#targetColIndex !== null && this.#targetContainerType) {\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n }\n }\n\n if (this.#targetCell) {\n const targetCell = this.#targetCell;\n if (targetCell.getAttribute('collapsed') !== 'true' && finalWidth > 20) {\n targetCell.dataset.expandWidth = String(finalWidth);\n }\n }\n\n if (this.#panel) {\n this.#tooltip?.classList.add('fade-out');\n setTimeout(() => {\n this.#panel.classList.remove('active');\n this.#tooltip?.classList.remove('fade-out');\n }, 150);\n }\n\n this.#targetColIndex = null;\n this.#nextColIndex = null;\n this.#targetContainerType = null;\n this.#targetCell = null;\n };\n\n #onDblClick = (e) => {\n\n const targetEl = e.target;\n let cell = targetEl.closest('th, td');\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n if (offsetX <= RESIZE_OFFSET) {\n cell = cell.previousElementSibling;\n }\n\n const baseColIndex = parseInt(cell.dataset.col, 10);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${baseColIndex}\"]`);\n if (!tbodyCell || !tbodyCell.dataset.bind || tbodyCell.classList.contains(\"CELL-RADIO\")) return;\n\n let extraPadding = 0;\n Array.from(tbodyCell.firstElementChild.children).forEach(($el) => {\n switch ($el.tagName) {\n case 'SPAN': extraPadding += 8; break;\n case 'DIV': extraPadding += 8; break;\n case 'BUTTON': extraPadding += 32; break;\n case 'SELECT': extraPadding += 32; break;\n case 'INPUT':\n switch (($el.type || 'text').toLowerCase()) {\n // 1. 체크박스 / 라디오 (비교적 좁은 영역)\n case 'checkbox':\n case 'radio':\n extraPadding += 12;\n break;\n\n // 2. 버튼 계열 input\n case 'button':\n case 'submit':\n case 'reset':\n case 'image':\n extraPadding += 16;\n break;\n\n // 3. 특수 위젯 (컬러, 파일, 슬라이더)\n case 'color':\n case 'file':\n case 'range':\n extraPadding += 24;\n break;\n\n // 4. 화면에 안 보이는 hidden 필드\n case 'hidden':\n extraPadding += 0;\n break;\n\n // 5. 텍스트 및 숫자, 날짜 등 일반 입력 필드 (기본값)\n case 'text':\n case 'search':\n case 'tel':\n case 'url':\n case 'email':\n case 'password':\n case 'number':\n case 'date':\n case 'time':\n case 'datetime-local':\n case 'month':\n case 'week':\n default:\n extraPadding += 16;\n break;\n }\n break;\n }\n });\n\n trace.log(extraPadding);\n\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n\n // 헤더 텍스트 길이 측정\n const headerText = cell.innerText || \"\";\n const headerSize = nine.measureTextSize(headerText, font);\n let maxTextWidth = (headerSize.width || 0) + 16;\n\n this.#host.execute(() => {\n\n this.#sheet.view.getArray().forEach((record, idx) => {\n const val = String(tbodyCell.dataset.expr ? this.#host.exprEngine.evaluate(tbodyCell.dataset.expr, record, idx) : record.v[fieldIdx] ?? \"\").trim();\n const size = nine.measureTextSize(val, font);\n if (size.width && size.width > maxTextWidth) {\n maxTextWidth = size.width;\n }\n });\n\n // 글자 수 당 대략적인 픽셀 계산 (기본 패딩 여백 포함, 최소 32px ~ 최대 400px 제한)\n const calculatedWidth = Math.max(32, Math.min(400, Math.ceil(maxTextWidth) + extraPadding));\n\n // 자동 계산된 너비 적용\n this.setColumnWidth(tbodyCell.dataset.col, calculatedWidth, this.#getContainerType(cell));\n })\n };\n}\n\n\nexport class ColResizerPanel extends HTMLElement {\n #target;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n this.#renderer();\n }\n\n #renderer = () => {\n this.innerHTML = `\n <div class=\"resizer-overlay\">\n <span class=\"size-badge\">0px</span>\n </div>\n `;\n };\n}\n\nif (!customElements.get('nine-table-col-resizer-panel')) {\n customElements.define(\"nine-table-col-resizer-panel\", ColResizerPanel);\n}\n","// ui/col/ColMover.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/layout/core/TableCompiler.js\";\n\nexport class ColMover {\n #sheet;\n #grip;\n #indi;\n\n #isDragging = false;\n #sourceCell = null;\n #sourceColIndex = null;\n #targetColIndex = null;\n #shiftX = 0;\n #timer = null;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#grip = this.#sheet.querySelector('.ng-col-mover-grip');\n this.#indi = this.#sheet.querySelector('.ng-col-mover-indi');\n this.bindEvents();\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n }\n\n #checkIsMovable() {\n const host = this.#sheet.getRootNode()?.host;\n return this.#sheet.getAttribute('col-movable') === 'true' || host?.getAttribute('col-movable') === 'true';\n }\n\n #getDeepElementFromPoint(x, y) {\n const root = this.#sheet.getRootNode();\n let el = root.elementFromPoint ? root.elementFromPoint(x, y) : document.elementFromPoint(x, y);\n\n while (el && el.shadowRoot && el.shadowRoot.elementFromPoint) {\n const nested = el.shadowRoot.elementFromPoint(x, y);\n if (!nested || nested === el) break;\n el = nested;\n }\n\n return el;\n }\n\n #getColGroupRange(cell) {\n if (!cell || cell.dataset.col === undefined) return null;\n\n const startCol = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const endCol = startCol + colSpan - 1;\n const rowIndex = cell.closest('tr')?.sectionRowIndex ?? 0;\n\n const table = cell.closest('table');\n if (!table) return { startCol, colSpan, endCol, rowIndex, isGroup: false, parentGroupRange: null, isValidGroup: true };\n\n const headerCells = table.querySelectorAll('thead th, thead td');\n let hasStrictChildren = false;\n let isValidGroup = true;\n let parentGroupRange = null;\n\n for (const subCell of headerCells) {\n if (subCell === cell || subCell.dataset.col === undefined) continue;\n\n const subStart = parseInt(subCell.dataset.col, 10);\n const subSpan = subCell.colSpan || 1;\n const subEnd = subStart + subSpan - 1;\n const subRowIndex = subCell.closest('tr')?.sectionRowIndex ?? 0;\n\n if (subRowIndex < rowIndex && subStart <= startCol && subEnd >= endCol && subSpan > colSpan) {\n if (!parentGroupRange) {\n parentGroupRange = { startCol: subStart, endCol: subEnd };\n } else {\n parentGroupRange.startCol = Math.max(parentGroupRange.startCol, subStart);\n parentGroupRange.endCol = Math.min(parentGroupRange.endCol, subEnd);\n }\n }\n\n const isOverlap = !(subEnd < startCol || subStart > endCol);\n if (isOverlap) {\n const isFullyContained = (subStart >= startCol && subEnd <= endCol);\n\n if (isFullyContained) {\n if (subSpan < colSpan) {\n hasStrictChildren = true;\n }\n } else if (subStart < startCol || subEnd > endCol) {\n if (!(subStart <= startCol && subEnd >= endCol)) {\n isValidGroup = false;\n }\n }\n }\n }\n\n const isRealGroup = hasStrictChildren && isValidGroup;\n\n return {\n startCol,\n colSpan: isRealGroup ? colSpan : 1,\n endCol: isRealGroup ? endCol : startCol,\n rowIndex,\n isGroup: isRealGroup,\n parentGroupRange,\n isValidGroup\n };\n }\n\n #createGroupHeaderPreview(cell) {\n const groupRange = this.#getColGroupRange(cell);\n if (!groupRange) return null;\n\n const { startCol, endCol, isGroup } = groupRange;\n\n // 핵심: 테이블이 여러 개인 구조이므로 cell이 속한 바로 그 테이블을 직접 가져옵니다.\n const origTable = cell.closest('table');\n if (!origTable) return null;\n\n let minLeft = Infinity, maxRight = -Infinity, minTop = Infinity, maxBottom = -Infinity;\n const targetCells = [];\n\n origTable.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n const isTarget = isGroup\n ? (cCol >= startCol && cEnd <= endCol)\n : (c === cell);\n\n if (isTarget) {\n const rect = c.getBoundingClientRect();\n minLeft = Math.min(minLeft, rect.left);\n maxRight = Math.max(maxRight, rect.right);\n minTop = Math.min(minTop, rect.top);\n maxBottom = Math.max(maxBottom, rect.bottom);\n\n const computedStyle = window.getComputedStyle(c);\n targetCells.push({ el: c, rect, style: computedStyle });\n }\n });\n\n if (targetCells.length === 0) return null;\n\n const groupWidth = maxRight - minLeft;\n const groupHeight = maxBottom - minTop;\n\n const headerContent = document.createElement('div');\n headerContent.className = 'grip-header-content';\n headerContent.style.position = 'relative';\n headerContent.style.width = `${groupWidth}px`;\n headerContent.style.height = `${groupHeight}px`;\n\n targetCells.forEach(({ el, rect, style }) => {\n const clonedCell = el.cloneNode(true);\n\n clonedCell.style.position = 'absolute';\n clonedCell.style.left = `${rect.left - minLeft}px`;\n clonedCell.style.top = `${rect.top - minTop}px`;\n\n clonedCell.style.width = `${rect.width}px`;\n clonedCell.style.minWidth = `${rect.width}px`;\n clonedCell.style.maxWidth = 'none';\n\n clonedCell.style.height = `${rect.height}px`;\n clonedCell.style.boxSizing = 'border-box';\n clonedCell.style.margin = '0';\n\n clonedCell.style.backgroundColor = style.backgroundColor !== 'transparent' && style.backgroundColor !== 'rgba(0, 0, 0, 0)'\n ? style.backgroundColor\n : '#f9fafb';\n clonedCell.style.color = style.color;\n clonedCell.style.font = style.font;\n clonedCell.style.fontWeight = style.fontWeight;\n clonedCell.style.fontSize = style.fontSize;\n clonedCell.style.textAlign = style.textAlign;\n clonedCell.style.padding = style.padding;\n clonedCell.style.border = style.border;\n clonedCell.style.borderRight = style.borderRight;\n clonedCell.style.borderBottom = style.borderBottom;\n clonedCell.style.display = 'flex';\n clonedCell.style.alignItems = 'center';\n clonedCell.style.justifyContent = style.textAlign === 'center' ? 'center' : (style.textAlign === 'right' ? 'flex-end' : 'flex-start');\n\n headerContent.appendChild(clonedCell);\n });\n\n return {\n element: headerContent,\n bounds: {\n left: minLeft,\n right: maxRight,\n top: minTop,\n bottom: maxBottom,\n width: groupWidth,\n height: groupHeight\n }\n };\n }\n\n #onPointerDown = (e) => {\n if (!this.#checkIsMovable()) return;\n\n const headerPart = e.target.closest('.ng-sheet-header');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n if (!cell || cell.classList.contains('resizable-edge') || ['INPUT', 'BUTTON'].includes(e.target.tagName)) return;\n if (cell.dataset.col === undefined) return;\n\n e.preventDefault();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cancelTimer = () => {\n if (this.#timer) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n window.removeEventListener('pointermove', onPointerMovePending);\n window.removeEventListener('pointerup', cancelTimer);\n window.removeEventListener('pointercancel', cancelTimer);\n };\n\n const onPointerMovePending = (moveEvent) => {\n const dist = Math.hypot(moveEvent.clientX - startX, moveEvent.clientY - startY);\n if (dist > 5) {\n cancelTimer();\n }\n };\n\n this.#timer = setTimeout(() => {\n cancelTimer();\n this.#startDrag(e, cell);\n }, 500);\n\n window.addEventListener('pointermove', onPointerMovePending);\n window.addEventListener('pointerup', cancelTimer, { once: true });\n window.addEventListener('pointercancel', cancelTimer, { once: true });\n };\n\n #startDrag(e, cell) {\n if (this.#isDragging) return;\n\n const preview = this.#createGroupHeaderPreview(cell);\n if (!preview) return;\n\n this.#isDragging = true;\n this.#sourceCell = cell;\n this.#sourceColIndex = parseInt(cell.dataset.col, 10);\n\n const sheetRect = this.#sheet.getBoundingClientRect();\n const { bounds, element } = preview;\n\n this.#shiftX = e.clientX - bounds.left;\n\n if (this.#grip) {\n this.#grip.replaceChildren(element);\n\n const relativeTop = bounds.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#grip.style.width = `${bounds.width}px`;\n this.#grip.style.height = `${fullHeight}px`;\n this.#grip.style.top = `${relativeTop}px`;\n this.#grip.style.display = 'block';\n\n this.#updateGripPosition(e.clientX);\n }\n\n document.body.style.cursor = 'move';\n\n window.addEventListener('pointermove', this.#onPointerMove);\n window.addEventListener('pointerup', this.#onPointerUp, { once: true });\n }\n\n #onPointerMove = (e) => {\n if (!this.#isDragging) return;\n\n this.#updateGripPosition(e.clientX);\n\n if (this.#grip) this.#grip.style.pointerEvents = 'none';\n if (this.#indi) this.#indi.style.pointerEvents = 'none';\n\n const targetElement = this.#getDeepElementFromPoint(e.clientX, e.clientY);\n const targetCell = targetElement?.closest('.ng-sheet-header th, .ng-sheet-header td');\n\n if (targetCell && targetCell.dataset.col !== undefined) {\n const targetColIndex = parseInt(targetCell.dataset.col, 10);\n const sheetRect = this.#sheet.getBoundingClientRect();\n const table = targetCell.closest('table');\n\n let colMinLeft = Infinity;\n let colMaxRight = -Infinity;\n\n if (table) {\n table.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n if (cCol <= targetColIndex && cEnd >= targetColIndex) {\n const cRect = c.getBoundingClientRect();\n colMinLeft = Math.min(colMinLeft, cRect.left);\n colMaxRight = Math.max(colMaxRight, cRect.right);\n }\n });\n }\n\n if (colMinLeft === Infinity) {\n const rect = targetCell.getBoundingClientRect();\n colMinLeft = rect.left;\n colMaxRight = rect.right;\n }\n\n const midX = colMinLeft + ((colMaxRight - colMinLeft) / 2);\n let calculatedTargetCol = 0;\n let indicatorLeft = 0;\n\n if (e.clientX < midX) {\n calculatedTargetCol = targetColIndex;\n indicatorLeft = colMinLeft - sheetRect.left;\n } else {\n const colSpan = targetCell.colSpan || 1;\n calculatedTargetCol = targetColIndex + colSpan;\n indicatorLeft = colMaxRight - sheetRect.left;\n }\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n const movingSpan = sourceGroup.colSpan;\n\n const sourceRowStart = sourceGroup.rowIndex;\n const sourceRowSpan = this.#sourceCell.rowSpan || 1;\n const sourceRowEnd = sourceRowStart + sourceRowSpan - 1;\n\n const targetRowStart = targetCell.closest('tr')?.sectionRowIndex ?? 0;\n const targetRowSpan = targetCell.rowSpan || 1;\n const targetRowEnd = targetRowStart + targetRowSpan - 1;\n\n const isRowSpanCompatible = !(sourceRowEnd < targetRowStart || sourceRowStart > targetRowEnd);\n\n let isOutOfBoundsOfParent = false;\n if (sourceGroup.parentGroupRange) {\n const { startCol: pStart, endCol: pEnd } = sourceGroup.parentGroupRange;\n if (calculatedTargetCol < pStart || (calculatedTargetCol + movingSpan - 1) > pEnd) {\n isOutOfBoundsOfParent = true;\n }\n }\n\n let isDroppingInsideOtherGroup = false;\n if (table) {\n const spannedCells = table.querySelectorAll('thead th[colspan], thead td[colspan]');\n\n for (const sCell of spannedCells) {\n if (sCell === this.#sourceCell) continue;\n\n const sRowStart = sCell.closest('tr')?.sectionRowIndex ?? 0;\n const sRowSpan = sCell.rowSpan || 1;\n const sRowEnd = sRowStart + sRowSpan - 1;\n\n const isVerticalOverlap = !(sourceRowEnd < sRowStart || sourceRowStart > sRowEnd);\n if (!isVerticalOverlap) continue;\n\n const sStart = parseInt(sCell.dataset.col, 10);\n const sSpan = sCell.colSpan || 1;\n const sEnd = sStart + sSpan - 1;\n\n if (calculatedTargetCol > sStart && calculatedTargetCol < sEnd + 1) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n\n const moveEndCol = calculatedTargetCol + movingSpan - 1;\n const isCrossIntersecting = (\n (calculatedTargetCol > sStart && calculatedTargetCol <= sEnd && moveEndCol > sEnd) ||\n (calculatedTargetCol < sStart && moveEndCol >= sStart && moveEndCol < sEnd)\n );\n\n if (isCrossIntersecting) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n }\n }\n\n const isSelfGroup = (\n calculatedTargetCol >= sourceGroup.startCol &&\n calculatedTargetCol <= sourceGroup.endCol + 1\n );\n\n const isInvalidMove = !isRowSpanCompatible || isSelfGroup || isOutOfBoundsOfParent || isDroppingInsideOtherGroup || !sourceGroup.isValidGroup;\n\n if (isInvalidMove) {\n this.#targetColIndex = null;\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n } else {\n this.#targetColIndex = calculatedTargetCol;\n if (this.#grip) this.#grip.classList.remove('invalid');\n\n if (this.#indi) {\n const headerPart = targetCell.closest('.ng-sheet-header');\n const headerRect = headerPart.getBoundingClientRect();\n const relativeTop = headerRect.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#indi.style.top = `${relativeTop}px`;\n this.#indi.style.height = `${fullHeight}px`;\n this.#indi.style.left = `${indicatorLeft - 1}px`;\n this.#indi.style.display = 'block';\n }\n }\n } else {\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n this.#targetColIndex = null;\n }\n };\n\n #updateGripPosition(clientX) {\n if (!this.#grip) return;\n const sheetRect = this.#sheet.getBoundingClientRect();\n const left = clientX - sheetRect.left - this.#shiftX;\n this.#grip.style.left = `${left}px`;\n }\n\n #onPointerUp = (e) => {\n if (!this.#isDragging) return;\n\n window.removeEventListener('pointermove', this.#onPointerMove);\n document.body.style.cursor = '';\n\n if (this.#grip) {\n this.#grip.style.display = 'none';\n this.#grip.replaceChildren();\n }\n if (this.#indi) this.#indi.style.display = 'none';\n\n if (\n this.#targetColIndex !== null &&\n this.#sourceColIndex !== null &&\n this.#targetColIndex !== this.#sourceColIndex &&\n this.#targetColIndex !== this.#sourceColIndex + 1\n ) {\n this.moveColumn(this.#sourceColIndex, this.#targetColIndex);\n }\n\n this.#isDragging = false;\n this.#sourceCell = null;\n this.#sourceColIndex = null;\n this.#targetColIndex = null;\n };\n\n moveColumn(fromColIndex, toColIndex) {\n\n trace.log(this.#sheet.sourceTable.cloneNode(true));\n\n const colgroup = this.#sheet.sourceTable.querySelector('colgroup');\n const targetCol = colgroup.querySelector(`col[data-col=\"${toColIndex}\"]`);\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n if (!sourceGroup || !sourceGroup.isValidGroup) return;\n\n const spanCount = sourceGroup.colSpan;\n const isInRange = (idx) => idx >= fromColIndex && idx < fromColIndex + spanCount;\n\n // 1. colgroup 내 <col> 이동 및 fixed 설정\n const targetViewportCol = this.#sheet.querySelector(`.ng-sheet-body-content col[data-col=\"${toColIndex}\"]`);\n const fixedType = targetViewportCol?.closest('.ng-container-left') ? 'left' : targetViewportCol?.closest('.ng-container-right') ? 'right' : null;\n\n colgroup.querySelectorAll('col').forEach(col => {\n if (isInRange(parseInt(col.getAttribute('data-col'), 10))) {\n fixedType ? col.setAttribute('fixed', fixedType) : col.removeAttribute('fixed');\n colgroup.insertBefore(col, targetCol);\n }\n });\n\n // 2. 테이블 행(tr) 내부의 셀(th, td) 순서 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n this.#sheet.sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n const cells = Array.from(tr.children);\n const targetRowCell = cells.find(c => parseInt(c.dataset.col, 10) >= toColIndex);\n\n cells.forEach(cell => {\n if (isInRange(parseInt(cell.dataset.col, 10))) {\n tr.insertBefore(cell, targetRowCell || null);\n }\n });\n });\n });\n\n this.#sheet.recompileAndRefresh();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n }\n}","// ui/col/ColFixManager.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/layout/core/TableCompiler.js\";\n\nexport class ColFixManager {\n #sheet;\n\n constructor(sheet) {\n this.#sheet = sheet;\n }\n\n /**\n * 🎯 현재 클릭된 셀의 고정 구역('left', 'right', 'none') 탐색\n */\n getFixState(targetCell, table) {\n if (!targetCell || !table) return 'none';\n\n // 🎯 [보정] 3분할 레이어 구조 내부의 컨테이너를 안전하게 탐색\n const container = targetCell.closest('.ng-container-left, .ng-container-right, .ng-container-body');\n if (container?.classList.contains('ng-container-left')) return 'left';\n if (container?.classList.contains('ng-container-right')) return 'right';\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n if (!isNaN(baseCol)) {\n const colEl = table.querySelector(`colgroup col[data-col=\"${baseCol}\"]`);\n const fixedAttr = colEl?.getAttribute('fixed');\n if (fixedAttr) return fixedAttr;\n }\n\n return 'none';\n }\n\n /**\n * 🎯 상하 멀티 헤더 경계선 일치 여부 검사 (Fix Column 가부 판별)\n */\n canFixColumn(targetCell, table) {\n if (!targetCell || targetCell.tagName !== 'TH' || !table) return false;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n if (isNaN(baseCol)) return false;\n\n const targetBoundaryCol = baseCol + colSpan - 1;\n const theadTrs = Array.from(table.querySelectorAll('thead tr'));\n\n if (theadTrs.length <= 1) return true;\n\n for (const tr of theadTrs) {\n const cells = Array.from(tr.querySelectorAll('th, td'));\n let cellBoundaryFound = false;\n\n for (const cell of cells) {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEndCol = cCol + cSpan - 1;\n\n // 목표 경계선이 특정 셀의 중간을 관통하는 경우 (Fix 불가능)\n if (cCol <= targetBoundaryCol && targetBoundaryCol < cEndCol) {\n return false;\n }\n\n if (cEndCol === targetBoundaryCol) {\n cellBoundaryFound = true;\n break;\n }\n }\n\n if (!cellBoundaryFound) return false;\n }\n\n return true;\n }\n\n /**\n * 🎯 [인스턴스 메서드] 배치 범위 고정 및 해제 처리\n * - 원본(`sourceTable`)의 구조(fixed 속성)를 직접 조작하므로 decompile은 절대 호출하지 않음!\n */\n executeFixToggle(action, targetCell, fixType = 'left') {\n if (!this.#sheet || !targetCell) return;\n\n const sourceTable = this.#sheet.sourceTable;\n if (!sourceTable) return;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n const targetColIndex = baseCol + colSpan - 1;\n\n if (isNaN(targetColIndex)) return;\n\n const colgroup = sourceTable.querySelector('colgroup');\n if (!colgroup) return;\n\n const cols = Array.from(colgroup.querySelectorAll('col'));\n\n if (action === 'fix-column') {\n // 🎯 Batch Fix: 0번부터 targetColIndex까지의 모든 <col>과 셀에 fixed 속성 일괄 부여\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx <= targetColIndex) {\n col.setAttribute('fixed', fixType);\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (!isNaN(cIdx) && cIdx <= targetColIndex) {\n cell.setAttribute('fixed', fixType);\n }\n });\n });\n });\n\n } else if (action === 'unfix-column') {\n let minBaseCol = baseCol;\n let maxEndCol = baseCol + colSpan - 1;\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach((tr, rIdx) => {\n Array.from(tr.children).forEach(cell => {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n const rSpan = cell.rowSpan || 1;\n const trIndex = tr.sectionRowIndex ?? rIdx;\n\n // 현재 클릭된 셀의 수직 범위와 겹치는 머지 셀이 있는지 검사\n const isVerticalOverlap = !(trIndex + rSpan - 1 < cell.closest('tr').sectionRowIndex || trIndex > (cell.closest('tr').sectionRowIndex + rSpan - 1));\n\n // 만약 기존에 고정(fixed)되어 있으면서 현재 클릭한 타겟 라인과 걸쳐있는 머지 셀이라면 범위를 확장합니다.\n const isHorizontalOverlap = !(cEnd < baseCol || cCol > targetColIndex);\n\n if (isHorizontalOverlap) {\n minBaseCol = Math.min(minBaseCol, cCol);\n maxEndCol = Math.max(maxEndCol, cEnd);\n }\n });\n });\n });\n\n // 🎯 2단계: 계산된 실제 머지 블록의 시작점(minBaseCol) 이상인 모든 <col> 속성 해제\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx >= minBaseCol) {\n col.removeAttribute('fixed');\n }\n });\n\n // 🎯 3단계: left 구역의 고정 연속성(체인) 검증\n let isBroken = false;\n cols.forEach(col => {\n if (isBroken) {\n col.removeAttribute('fixed');\n } else if (!col.getAttribute('fixed')) {\n isBroken = true;\n }\n });\n\n // 🎯 4단계: <col>들의 최종 fixed 상태를 기준으로 모든 thead, tbody, tfoot 셀(th, td)의 fixed 속성 완벽 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (isNaN(cIdx)) return;\n\n const correspondingCol = cols.find(c => parseInt(c.getAttribute('data-col'), 10) === cIdx);\n const isColFixed = correspondingCol?.getAttribute('fixed');\n\n if (isColFixed) {\n cell.setAttribute('fixed', isColFixed);\n } else {\n cell.removeAttribute('fixed');\n }\n });\n });\n });\n }\n\n trace.log(this.#sheet.sourceTable);\n\n // 🎯 recompileAndRefresh 단 1회 호출로 원본 정렬 및 뷰포트 재생성 완결\n this.#sheet.recompileAndRefresh?.();\n }\n}","import { NINE_TABLE } from '@/core/constants.js';\r\nimport { trace } from \"@nopeer\";\r\n\r\n/**\r\n * 🎯 [필터 패널 커스텀 엘리먼트 Light DOM 버전]\r\n */\r\nexport class NineTableFilterPanel extends HTMLElement {\r\n\t#sheet;\r\n\t#host;\r\n\t#nineTable;\r\n\t#view;\r\n\t#button;\r\n\tcurrentCol = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#init();\r\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\r\n\t}\r\n\r\n\t#init = () => {\r\n\t\t//setTimeout(() => {\r\n\t\t\tthis.#renderer();\r\n\r\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\r\n\t\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\r\n\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\r\n\t\t\t})\r\n\r\n\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t});\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\r\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\r\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\r\n\t\t//});\r\n\t}\r\n\r\n\t#renderer = () => {\r\n\t\tthis.innerHTML = `\r\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\r\n \r\n <nine-table-simple class=\"filter-list\" theme=\"simple\">\r\n <table auto-fit-col=\"true\">\r\n <colgroup>\r\n <col width=\"32\" fixed=\"left\" />\r\n <col width=\"180\" />\r\n <col width=\"0\" fixed=\"right\"/>\r\n </colgroup>\r\n <tbody>\r\n <tr>\r\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\r\n <td data-bind=\"DATA2\" html=\"true\"></td>\r\n <td data-bind=\"DATA\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </nine-table-simple>\r\n\r\n <div class=\"footer-section\">\r\n <div class=\"footer-btns\">\r\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\r\n <div class=\"btn-group\">\r\n <button id=\"btnOk\">Apply</button>\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n\t}\r\n\r\n\topen(filterBtn) {\r\n\t\tthis.#button = filterBtn;\r\n\r\n\t\tconst cell = filterBtn.closest(\"th, td\");\r\n\t\tthis.currentCol = cell?.dataset.col;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\r\n\r\n\t\tconst panelWidth = this.offsetWidth || 240;\r\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\r\n\t\tlet top = cellRect.bottom - sheetRect.top;\r\n\r\n\t\tif (left < 0) {\r\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\r\n\t\t}\r\n\r\n\t\tthis.style.left = `${left}px`;\r\n\t\tthis.style.top = `${top}px`;\r\n\r\n\t\tconst searchBox = this.querySelector(\".search-box\");\r\n\t\tsearchBox.value = \"\";\r\n\r\n\r\n\t\tthis.classList.add(\"active\");\r\n\t\tthis.classList.add(\"loading\");\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tthis.#loadVirtualFilterItems();\r\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\r\n\t\t\t\tsearchBox.focus();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.classList.remove(\"loading\");\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t#closeHandler = (e) => {\r\n\t\tconst path = e.composedPath ? e.composedPath() : [];\r\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.close();\r\n\t};\r\n\r\n\tclose() {\r\n\t\tthis.currentCol = null;\r\n\t\tthis.classList.remove(\"active\");\r\n\t\tthis.#button = null;\r\n\t}\r\n\r\n\t#loadVirtualFilterItems() {\r\n\t\tconst filteredRecords = this.#host.data.getArray();\r\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] 형태 배열\r\n\t\tconst fields = this.#host.fields.get() || [];\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst ds = targetCols.flatMap((colInfo) => {\r\n\t\t\tconst bindKey = colInfo.bind;\r\n\t\t\tconst exprKey = colInfo.expr;\r\n\r\n\t\t\tconst filterKey = bindKey || exprKey; // 실제 필터 파라미터 키로 사용\r\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\r\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\r\n\r\n\t\t\t// 1. Map을 이용한 O(N) 고속 유니크 추출 (DATA는 bind/원시값, DATA2는 expr 연산 결과)\r\n\t\t\tconst uniqueMap = new Map();\r\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\r\n\t\t\t\tconst record = filteredRecords[i];\r\n\t\t\t\tif (!record) continue;\r\n\r\n\t\t\t\t// DATA 기준이 될 원시 값 (bind가 있으면 필드 인덱스에서, 없으면 expr 결과)\r\n\t\t\t\tlet rawVal = undefined;\r\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\trawVal = record.v[fieldIdx];\r\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\r\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\r\n\t\t\t\t} else if (exprKey && exprEngine) {\r\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// DATA2에 출력될 화면 표시 값 (expr 수식 연산 결과, 없으면 rawVal)\r\n\t\t\t\tlet displayVal = rawVal;\r\n\t\t\t\tif (exprKey && exprEngine) {\r\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\r\n\t\t\t\t\tuniqueMap.set(displayVal, {\r\n\t\t\t\t\t\tv: rawVal, // 💡 필터링 비교 기준 (DATA)\r\n\t\t\t\t\t\tv2: displayVal // 💡 화면 출력 기준 (DATA2)\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst uniqueList = [...uniqueMap.values()];\r\n\r\n\t\t\t// 2. 출력값(v2) 기준 정렬\r\n\t\t\t// 2. 출력값(v2) 기준 정렬 (숫자와 문자열 분기 처리)\r\n\t\t\tuniqueList.sort((a, b) => {\r\n\t\t\t\tconst valA = a.v2;\r\n\t\t\t\tconst valB = b.v2;\r\n\r\n\t\t\t\t// 빈 값이나 null 처리를 위한 안전 장치\r\n\t\t\t\tif (valA === valB) return 0;\r\n\t\t\t\tif (valA === undefined || valA === null || valA === '') return 1;\r\n\t\t\t\tif (valB === undefined || valB === null || valB === '') return -1;\r\n\r\n\t\t\t\tconst numA = Number(valA);\r\n\t\t\t\tconst numB = Number(valB);\r\n\r\n\t\t\t\t// 둘 다 유효한 숫자일 경우 숫자 크기 비교\r\n\t\t\t\tconst isNumA = !isNaN(numA);\r\n\t\t\t\tconst isNumB = !isNaN(numB);\r\n\r\n\t\t\t\tif (isNumA && isNumB) {\r\n\t\t\t\t\treturn numA - numB;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// 그 외의 경우는 문자열(localeCompare) 비교\r\n\t\t\t\treturn String(valA).localeCompare(String(valB));\r\n\t\t\t});\r\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\r\n\r\n\t\t\treturn uniqueList.map(o => ({\r\n\t\t\t\tLVL: 2,\r\n\t\t\t\tDATA: o.v, // 필터링 비교용 값\r\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2, // 화면 출력용 값\r\n\t\t\t\tCOLNM: filterKey,\r\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v) >= 0 ? \"Y\" : \"N\"\r\n\t\t\t}));\r\n\t\t});\r\n\r\n\t\tthis.#nineTable.data.set(ds);\r\n\r\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\r\n\t\tif (selectAllChk) {\r\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\r\n\t\t}\r\n\t}\r\n\r\n\t#onOk = () => {\r\n\t\tthis.#host.loading = true;\r\n\r\n\t\tconst filterRecords = this.#view.view.getArray();\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\r\n\t\tconst checkedRecords = filterRecords.filter(record => {\r\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\r\n\t\t\treturn (chk === \"Y\" || chk === true);\r\n\t\t});\r\n\r\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\r\n\r\n\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\r\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\r\n\r\n\t\t\tif (selectedVals.length > 0) {\r\n\t\t\t\tfilterParams[filterKey] = selectedVals;\r\n\t\t\t} else {\r\n\t\t\t\tdelete filterParams[filterKey];\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tconst totalCount = this.#nineTable.data.count();\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tif (totalCount === checkedRecords.length) {\r\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\t\t\tbtn.updateFilteredState();\r\n\t\t\t\t});\r\n\r\n\t\t\t\tthis.#sheet.invalidate();\r\n\t\t\t\tthis.close();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.#host.loading = false;\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t#onInput = (e) => {\r\n\r\n\t\tconst query = e.target.value.toLowerCase().trim();\r\n\r\n\t\tif (!query) {\r\n\t\t\tthis.#view.filtering.clear();\r\n\t\t} else {\r\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\r\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\r\n\r\n\t\t\tconst matchedValues = [];\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\r\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\r\n\r\n\t\t\t\t// 💡 expr 연산 결과가 담긴 DATA2 텍스트와 검색어 비교\r\n\t\t\t\tif (textVal.includes(query)) {\r\n\t\t\t\t\tmatchedValues.push(val);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\ttrace.log(matchedValues);\r\n\r\n\t\t\tthis.#view.filtering.set({\r\n\t\t\t\tDATA2: [...new Set(matchedValues)]\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t#onSelectAll = (e) => {\r\n\t\tconst isChecked = e.target.checked;\r\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\r\n\r\n\t\tif (chkIdx >= 0) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#nineTable.refresh();\r\n\t};\r\n\r\n\t#onCancel = () => {\r\n\t\tthis.close();\r\n\t};\r\n}\r\n\r\nexport class NineTableFilterButton extends HTMLElement {\r\n\t#sheet;\r\n\t#columns = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\r\n\t\tthis.removeEventListener(\"click\", this.#onClick);\r\n\t\tthis.addEventListener(\"click\", this.#onClick);\r\n\t}\r\n\r\n\tget columns() {\r\n\t\tif (this.#columns) return this.#columns;\r\n\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst colIndex = cell?.dataset.col;\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\r\n\t\tconst cols = [];\r\n\t\tconst seen = new Set();\r\n\r\n\t\tif (sourceTable && colIndex !== undefined) {\r\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\t\tconst bindKey = $td.dataset.bind;\r\n\t\t\t\tconst exprKey = $td.dataset.expr;\r\n\r\n\t\t\t\tif (bindKey || exprKey) {\r\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\r\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\r\n\t\t\t\t\t\tseen.add(uniqueKey);\r\n\t\t\t\t\t\tcols.push({\r\n\t\t\t\t\t\t\tbind: bindKey,\r\n\t\t\t\t\t\t\texpr: exprKey,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#columns = cols;\r\n\t\treturn this.#columns;\r\n\t}\r\n\r\n\tupdateFilteredState = () => {\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst isFiltered = this.columns.some(colInfo => {\r\n\t\t\tconst key = colInfo.expr || colInfo.bind;\r\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\r\n\t\t});\r\n\t\tthis.classList.toggle('filtered', isFiltered);\r\n\t};\r\n\r\n\t#onClick = (e) => {\r\n\t\ttrace.log(e);\r\n\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst col = cell.dataset.col;\r\n\r\n\t\t//trace.log(panel, cell, col, panel.currentCol, panel.classList.contains('active'));\r\n\r\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\r\n\t\t\tpanel.close();\r\n\t\t} else if (panel) {\r\n\t\t\tpanel.open(this);\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class Filtering {\r\n\t#sheet;\r\n\t#host;\r\n\t#isFiltering = false;\r\n\t#filterPanel = null;\r\n\t#filters = {};\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t\tthis.#init();\r\n\t}\r\n\r\n\tget filters() {\r\n\t\treturn this.#filters;\r\n\t};\r\n\r\n\t#init = () => {\r\n\t\tthis.#initFilterPanel();\r\n\t}\r\n\r\n\t#initFilterPanel = () => {\r\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tif (!panel) {\r\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\r\n\t\t\tthis.#sheet.appendChild(panel);\r\n\t\t}\r\n\t\tthis.#filterPanel = panel;\r\n\t}\r\n\r\n\tisFiltering() {\r\n\t\treturn this.#isFiltering;\r\n\t}\r\n\r\n\tclear = (colnm) => {\r\n\t\tif (colnm) {\r\n\t\t\tdelete this.#filters[colnm];\r\n\t\t} else {\r\n\t\t\tthis.#filters = {};\r\n\t\t}\r\n\r\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\r\n\t\tthis.#applyFiltering();\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\tbtn.updateFilteredState();\r\n\t\t});\r\n\r\n\t\ttrace.log(`🔄 [NineTableFiltering] Filter cleared for ${colnm || 'all'}`);\r\n\t}\r\n\r\n\tset = (oFilter) => {\r\n\r\n\t\ttrace.log(oFilter);\r\n\r\n\t\tlet jsonFilter = Array.isArray(oFilter)\r\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\r\n\t\t\t: oFilter;\r\n\r\n\t\tthis.#filters = jsonFilter;\r\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\r\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\r\n\r\n\t\tthis.#applyFiltering();\r\n\t}\r\n\r\n\t#applyFiltering() {\r\n\t\tconst hostData = this.#host.data;\r\n\t\tconst rawRecords = hostData.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields();\r\n\t\tconst sheetIndex = this.#sheet.index;\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\r\n\r\n\t\tif (!hasFilters) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\tthis.#sheet.invalidate();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 💡 필터 규칙 빌드 (targetKey가 bind인지 expr 수식인지 판별)\r\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\r\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\r\n\t\t\treturn {\r\n\t\t\t\ttargetKey,\r\n\t\t\t\tisExpr,\r\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\r\n\t\t\t\tallowedSet: new Set(allowedValues)\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\trawRecords.forEach((record, recordIdx) => {\r\n\t\t\tif (!record) return;\r\n\r\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\r\n\t\t\t}\r\n\r\n\t\t\tlet isPass = true;\r\n\r\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\r\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\r\n\t\t\t\tlet val = undefined;\r\n\r\n\t\t\t\tif (isExpr && exprEngine) {\r\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\r\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\tval = record.v[fieldIdx];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!allowedSet.has(val)) {\r\n\t\t\t\t\tisPass = false;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.invalidate();\r\n\t}\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-panel')) {\r\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-button')) {\r\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\r\n}","// ui/data/Sorting.js (또는 정렬 관련 소스)\r\nimport { trace } from \"@nopeer\";\r\nimport { TableCompiler } from \"@/layout/core/TableCompiler.js\";\r\n\r\nexport class Sorting {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#columns = [];\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.#initEvents();\r\n\t\t}, 300);\r\n\t}\r\n\r\n\t#initEvents() {\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\r\n\r\n\t\t\t$el.addEventListener('dblclick', (e) => {\r\n\r\n\t\t\t\tconst cell = e.target.closest('th, td');\r\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\r\n\r\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\r\n\r\n\t\t\t\t// 🎯 [수정] 줄바꿈으로 깨져있던 마이너스 연산자를 한 줄로 정상 복구\r\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\r\n\r\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\r\n\r\n\t\t\t\thost.loading = true;\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tthis.#handleSort(e, cell);\r\n\t\t\t\t\t} finally {\r\n\t\t\t\t\t\t// 🎯 3. 작업이 끝나면 무조건 로딩바 끄기\r\n\t\t\t\t\t\thost.loading = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}); // 또는 requestAnimationF\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\ttrace.log(\"🎯 [NineTableSorting] Initialized\");\r\n\t}\r\n\r\n\t#handleSort(e, cell) {\r\n\t\tconst colIndex = cell.dataset.col;\r\n\t\tconst tr = cell.closest('tr');\r\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\r\n\r\n\t\tif (colIndex === undefined) return;\r\n\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (!sourceTable) return;\r\n\r\n\t\tlet colName = null;\r\n\t\tlet exprVal = null; // 💡 expr 속성 수집용 변수\r\n\r\n\t\t// 1. 🎯 데이터 바인딩 키(colName) 및 expr 탐지\r\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\tif ($td.dataset.bind) {\r\n\t\t\t\tcolName = $td.dataset.bind;\r\n\t\t\t}\r\n\t\t\t// 💡 셀에 선언된 expr 식 추출\r\n\t\t\tif ($td.dataset.expr) {\r\n\t\t\t\texprVal = $td.dataset.expr;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (!colName && !exprVal) return;\r\n\r\n\t\tconst isAsc = cell.classList.contains('asc');\r\n\t\tconst isDesc = cell.classList.contains('desc');\r\n\r\n\t\tif (!e.ctrlKey && !e.shiftKey) {\r\n\t\t\tthis.#columns = [];\r\n\t\t}\r\n\r\n\t\tconst existingColIndex = this.#columns.findIndex(\r\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\r\n\t\t);\r\n\r\n\t\t// 정렬 규칙 추가 시 expr 속성(`expr`) 함께 저장\r\n\t\tconst ruleData = {\r\n\t\t\tcolIndex,\r\n\t\t\tsubRowIndex,\r\n\t\t\tcolname: colName || exprVal,\r\n\t\t\tcolName: colName || exprVal,\r\n\t\t\texpr: exprVal, // 💡 expr 규칙 보관\r\n\t\t\tasc: true,\r\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\r\n\t\t};\r\n\r\n\t\tif (!isAsc && !isDesc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\r\n\t\t\t}\r\n\t\t} else if (isAsc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.#columns = this.#columns.filter(\r\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tthis.#applySorting();\r\n\t}\r\n\r\n\t#applySorting() {\r\n\t\tif (!this.#sheet.view) {\r\n\t\t\tconsole.warn(\"⚠️ [NineTableSorting] Sheet view (SheetView) is not initialized.\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.view.setSorting(this.#columns);\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.invalidate();\r\n\t\t//this.#sheet.rowManager?.refresh(true);\r\n\r\n\t\ttrace.log(\"🔄 [NineTableSorting] Sorting applied via RowManager.refresh(true)\");\r\n\t}\r\n\r\n\t#syncHeaderUI() {\r\n\t\t// 기존 UI 클래스 초기화\r\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\r\n\t\t\tel.classList.remove('asc', 'desc');\r\n\t\t});\r\n\r\n\t\tif (this.#columns.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 🎯 [핵심] tr[data-subrow] + [data-col] 조합으로 정밀 타겟팅\r\n\t\tthis.#columns.forEach(colRule => {\r\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\r\n\r\n\t\t\tif (colIndex !== undefined) {\r\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\r\n\t\t\t\tif (subRowIndex !== undefined) {\r\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\r\n\t\t\t\ttargetHeaderCells.forEach(cell => {\r\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t//TableCompiler.decompile(this.#sheet);\r\n\t}\r\n\r\n\trestore() {\r\n\t\tthis.#columns = [];\r\n\t\tif (this.#sheet.view) {\r\n\t\t\tthis.#sheet.view.resetSorting();\r\n\t\t}\r\n\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.rowManager?.refresh(true);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\nimport {Grouping} from \"@/data/Grouping.js\";\r\n\r\nexport class SheetView {\r\n\t#sheet;\r\n\t#host;\r\n\t#sortingColumns = []; // 정렬 규칙 [{ colname, asc, expr-func }]\r\n\t#filterRules = []; // 필터 규칙\r\n\t#viewIndexes = []; // 필터링 및 소팅이 반영된 유효 데이터 인덱스 버퍼\r\n\r\n\t#cachedVisibleRecords = null; // 💡 [추가] 캐싱된 유효 레코드 배열\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.refresh();\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [시트 뷰 전용 배열 조회] - 캐시 적용으로 성능 대폭 개선\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\t// 💡 캐시가 없거나 비어있을 때만 가져옴 (보통 refresh에서 갱신됨)\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords;\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.#host.data.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord;\r\n\t};\r\n\r\n\tcount = () => {\r\n\t\t// 💡 캐시가 없거나 비어있을 때만 가져옴 (보통 refresh에서 갱신됨)\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\treturn this.#cachedVisibleRecords.length;\r\n\t}\r\n\r\n\tget = (at, colnm) => {\r\n\t\tconst visibleRecords = this.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (!targetRecord) return null;\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#convSingle(targetRecord, fields);\r\n\t};\r\n\r\n\t#convSingle = (o, fields) => {\r\n\t\tif (!o) return null;\r\n\t\tconst t = {};\r\n\t\tfields.forEach((colnm, i) => {\r\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t});\r\n\t\tif (o.m) t.m = o.m;\r\n\t\tif (o._) t._ = o._;\r\n\t\treturn t;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 또는 정렬/필터 변경 시에만 실행되는 뷰 버퍼 재계산\r\n\t */\r\n\t\t// SheetView.refresh() 내부 예시\r\n\trefresh = () => {\r\n\r\n\t\tthis.#cachedVisibleRecords = null;\r\n\r\n\t\t// 1. 필터 적용\r\n\t\tconst rawRecords = this.#host.data.getArray();\r\n\t\tlet indices = [];\r\n\t\trawRecords.forEach((record, i) => {\r\n\t\t\tif (!record) return;\r\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\r\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\r\n\t\t\tindices.push(i);\r\n\t\t});\r\n\r\n\t\t// 2. 정렬 적용\r\n\t\tif (this.#sortingColumns.length > 0) {\r\n\t\t\tindices = this.#applySorting(indices, rawRecords);\r\n\t\t}\r\n\r\n\t\tthis.#viewIndexes = indices;\r\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\r\n\r\n\t\t//trace.log(this.#sheet.sourceTable);\r\n\t\t//const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\r\n\t\t//trace.log(\"#######\", isGrouped, this.#sheet.grouping?.columns);\r\n\t\tconst groupColumns = this.#sheet.grouping?.columns || [];\r\n\t\tif (groupColumns.length > 0) {\r\n\t\t\t//this.#sheet.grouping.apply();\r\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields());\r\n\t\t\t//const groupResult = Grouping.apply(validRecords);\r\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // 최종 렌더링 아이템\r\n\r\n\t\t\t//trace.log(\"2.============================\", groupColumns, this.#cachedVisibleRecords);\r\n\r\n\t\t\tthis.#sheet.grouping.setGroupMap(groupResult.groupMap); // 자식 매핑 공유\r\n\t\t} else {\r\n\t\t\tthis.#cachedVisibleRecords = validRecords;\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n\tsetSorting = (columns) => {\r\n\t\tthis.#sortingColumns = columns || [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\tgetSorting = () => {\r\n\t\treturn this.#sortingColumns;\r\n\t};\r\n\r\n\tresetSorting = () => {\r\n\t\tthis.#sortingColumns = [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\r\n\t#applySorting = (indices, validRecords) => {\r\n\t\ttrace.log(new Date());\r\n\r\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\r\n\r\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\r\n\t\t\t...rule,\r\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\r\n\t\t}));\r\n\r\n\t\treturn indices.sort((idxA, idxB) => {\r\n\t\t\tconst a = validRecords[idxA];\r\n\t\t\tconst b = validRecords[idxB];\r\n\r\n\t\t\tfor (const rule of rulesWithIdx) {\r\n\t\t\t\tconst isAsc = rule.asc;\r\n\t\t\t\tconst expr = rule.expr; // 💡 등록된 expr 수식\r\n\t\t\t\tlet valA, valB;\r\n\r\n\t\t\t\t// 💡 1. expr 수식이 존재하면 ExprEngine으로 연산된 결과값을 가져옴\r\n\t\t\t\tif (expr) {\r\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\r\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 2. 일반 바인딩 필드인 경우 원시 배열에서 추출\r\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\r\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\r\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\r\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\r\n\r\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\r\n\t\t\t\tif (isEmptyA) return 1;\r\n\t\t\t\tif (isEmptyB) return -1;\r\n\r\n\t\t\t\tif (valA !== valB) {\r\n\t\t\t\t\tlet diff = 0;\r\n\r\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\r\n\t\t\t\t\t\tdiff = valA - valB;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst strA = String(valA);\r\n\t\t\t\t\t\tconst strB = String(valB);\r\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (diff !== 0) {\r\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn idxA - idxB;\r\n\t\t});\r\n\r\n\t\ttrace.log(new Date());\r\n\t};\r\n}","import { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/layout/core/TableCompiler.js\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class PreCompiler {\n\n static initializeTable(host, tbl) {\n\n // 1. 기본 구조 보장 (colgroup, thead)\n PreCompiler.#ensureColgroup(tbl);\n PreCompiler.#ensureThead(tbl);\n PreCompiler.#ensureSectionTbodys(tbl);\n\n PreCompiler.#ensureRowIndicator(tbl);\n\n PreCompiler.#normalizeColAttributes(tbl);\n\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tfoot tr'));\n\n PreCompiler.#createColIndicator(tbl);\n\n // 2. 속성 정규화 (collapsed=\"true\" -> collapsible=\"true\" 보정)\n PreCompiler.#normalizeCollapsibleAttributes(tbl);\n\n // 3. 셀 커스텀 엘리먼트 생성\n PreCompiler.#generateCell(host, tbl);\n\n // 5. 초기 접힘/펼치기(expand) 버튼 및 너비 세팅\n PreCompiler.#initColExpanders(tbl);\n\n // 6. 필터 버튼 생성\n PreCompiler.#initFilterButtons(host, tbl);\n\n PreCompiler.#applyInitialCellWidths(tbl);\n //tbl.classList.add('nine-table-element');\n\n //trace.log(\"**************\", tbl.cloneNode(true));\n return tbl;\n }\n\n static #createColIndicator(tbl) {\n const thead = tbl.querySelector('thead');\n if (!thead || thead.querySelector('.col-indicator-rowgroup')) return;\n\n const tdTmpl = `<th data-col=\"@col\" class=\"col-indicator\" scope=\"col\"></th>`;\n\n // 맨 위에 인덱스용 row(tr) 삽입\n const tr = thead.insertRow(0);\n tr.setAttribute('role', 'row');\n tr.classList.add('col-indicator-rowgroup');\n tr.classList.add('collapse');\n\n const firstRow = tbl.querySelector('tbody tr');\n if (!firstRow) return;\n\n let cnt = 0;\n firstRow.querySelectorAll('th, td').forEach(td => {\n if (!td.classList.contains('dummy')) {\n const colSpan = td.colSpan || 1;\n for (let i = 0; i < colSpan; i++) {\n const html = tdTmpl.replace('@col', cnt).replace('@text', PreCompiler.#numToExcelCol(cnt++));\n tr.insertAdjacentHTML('beforeend', html);\n }\n }\n });\n\n // 🎯 colgroup의 모든 스타일 및 속성 동기화\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n tr.querySelectorAll('.col-indicator').forEach((el, i) => {\n const background = cols[i].getAttribute('background');\n if (background) {\n el.style.background = background;\n }\n });\n }\n\n // 엑셀 스타일 알파벳 변환 유틸 (A, B, C ... Z, AA, AB ...)\n static #numToExcelCol(num) {\n let text = '';\n for (let n = num; n >= 0; n = Math.floor(n / 26) - 1) {\n text = String.fromCharCode(65 + (n % 26)) + text;\n }\n return text;\n }\n\n static #ensureSectionTbodys(tbl) {\n let tbody = tbl.querySelector('tbody:not(.head):not(.foot)');\n\n if (!tbody) return;\n\n tbody.classList.add('body');\n\n // 🎯 이미 존재하지 않을 때만 생성\n if (!tbl.querySelector('tbody.head')) {\n const headTbody = document.createElement('tbody');\n headTbody.classList.add('head');\n tbody.before(headTbody);\n }\n\n if (!tbl.querySelector('tbody.foot')) {\n const footTbody = document.createElement('tbody');\n footTbody.classList.add('foot');\n tbody.after(footTbody);\n }\n }\n\n static #ensureColgroup(tbl) {\n let colgroup = tbl.querySelector('colgroup');\n if (!colgroup) {\n colgroup = document.createElement('colgroup');\n tbl.prepend(colgroup);\n }\n\n // 🎯 <col> 엘리먼트 자체가 없다면 행 기준으로 생성\n if (colgroup.querySelectorAll('col').length === 0) {\n const firstRow = tbl.querySelector('tbody tr');\n let colCount = 1;\n if (firstRow) {\n colCount = Array.from(firstRow.querySelectorAll('th, td')).reduce((sum, cell) => {\n return sum + (parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1);\n }, 0);\n }\n colCount = Math.max(colCount, 1);\n\n for (let i = 0; i < colCount; i++) {\n const col = document.createElement('col');\n colgroup.appendChild(col);\n }\n }\n\n // 🎯 col 속성 및 너비 정리는 별도 함수로 분리\n //PreCompiler.#normalizeColAttributes(tbl);\n }\n\n // 🎯 <col>들의 data-col, width, style.width 속성 정리를 전담하는 메서드\n static #normalizeColAttributes(tbl) {\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n if (cols.length === 0) return;\n\n const containerWidth = tbl.clientWidth || 0;\n const defaultWidth = Math.max(Math.floor(containerWidth / cols.length), 100);\n\n cols.forEach((col, i) => {\n // 1. data-col 인덱스 보장\n if (!col.hasAttribute('data-col')) {\n col.setAttribute('data-col', i);\n }\n\n // 2. width 속성 및 style.width 정규화\n const width = col.getAttribute('width') || parseInt(col.style.width, 10) || defaultWidth;\n col.setAttribute('width', width);\n\n const widthVal = String(width).includes('px') ? width : `${width}px`;\n col.style.width = widthVal;\n });\n }\n\n static #ensureThead(tbl) {\n if (tbl.querySelector('thead')) return;\n\n const thead = document.createElement('thead');\n const colgroup = tbl.querySelector('colgroup');\n\n if (colgroup) {\n colgroup.after(thead);\n } else {\n tbl.prepend(thead);\n }\n }\n\n static #normalizeCollapsibleAttributes(tbl) {\n const headers = tbl.querySelectorAll('thead th, thead td');\n headers.forEach(cell => {\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n if (isCollapsed && cell.getAttribute('collapsible') !== 'true') {\n cell.setAttribute('collapsible', 'true');\n }\n });\n }\n\n static #generateCell(host, $tbl) {\n\n const targetAttributes = ['data-bind', 'data-expr', 'type'];\n let autoIdCounter = 0;\n\n $tbl.querySelectorAll('tbody th, tbody td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type') || \"renderer\";\n const tagName = `cell-${cellType}`;\n\n const $datalist = $cell.querySelector(\"datalist\");\n\n if ($datalist) {\n let l = [];\n $datalist.querySelectorAll('option').forEach($option => {\n l.push({\n k: $option.getAttribute(\"k\"),\n v: $option.getAttribute(\"v\"),\n value: $option.getAttribute(\"value\"),\n });\n });\n\n // 🎯 1. 절대 겹치지 않는 유니크한 가상 함수 이름 생성\n const uniqueFuncName = `__ds_${Date.now()}_${++autoIdCounter}`;\n\n // 🎯 2. 호스트(NineTable)에 해당 데이터를 반환하는 클로저 함수 등록\n if (host) {\n host[uniqueFuncName] = () => l;\n }\n\n // 🎯 3. 셀에 data-source 자동 장착 (정규식/세터 스캔기가 알아서 캐치함)\n $cell.setAttribute(\"data-source\", `host.${uniqueFuncName}()`);\n\n // 🎯 4. 사용이 끝난 정적 datalist 엘리먼트는 DOM에서 제거\n $datalist.remove();\n }\n\n const expr = $cell.dataset.expr;\n if (expr) {\n $cell.setAttribute('data-expr', host.exprEngine.precompile(expr));\n }\n\n // 💡 2. 기타 속성들 중 표현식이 포함된 경우 프리컴파일\n Array.from($cell.attributes).forEach(attr => {\n if (['data-bind', 'data-expr', 'cell-type', 'validator'].includes(attr.name)) return;\n if (attr.value.includes(\"data.\") || attr.value.includes(\"host.\")) {\n $cell.setAttribute(attr.name, host.exprEngine.precompile(attr.value));\n }\n });\n\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')}></${tagName}>`;\n $cell.setAttribute('tabindex', '0');\n });\n\n $tbl.querySelectorAll('thead th, thead td, tfoot th, tfoot td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type');\n if (cellType) {\n const originalContent = $cell.innerHTML;\n const tagName = `cell-${cellType}`;\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')} content=\"${originalContent}\"></${tagName}>`;\n }\n });\n }\n\n static #initFilterButtons(host, tbl) {\n const hostFilter = host.getAttribute('filtering') === 'true';\n const tableFilter = tbl.getAttribute('filtering') === 'true';\n\n // 🎯 인덱스 행을 제외한 실제 헤더 셀들만 타겟팅\n tbl.querySelectorAll('thead tr:not(.col-indicator-rowgroup) th, thead tr:not(.col-indicator-rowgroup) td').forEach(cell => {\n const finalFiltering = cell.getAttribute('filtering') === 'true' || tableFilter || hostFilter;\n\n cell.setAttribute('filtering', finalFiltering ? 'true' : 'false');\n\n if (finalFiltering) {\n cell.appendChild(document.createElement('nine-table-filter-button'));\n }\n });\n }\n\n static #initColExpanders(tbl) {\n /** 작동하나? */\n tbl.querySelectorAll('thead th, thead td').forEach(cell => {\n const isCollapsible = cell.getAttribute('collapsible') === 'true' || cell.getAttribute('expandable') === 'true';\n if (!isCollapsible) return;\n\n const colIndex = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const col = tbl.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n\n const currentWidth = col ? (parseInt(col.getAttribute('width'), 10) || 100) : 100;\n\n if (!cell.dataset.expandWidth || parseInt(cell.dataset.expandWidth, 10) <= COLLAPSED_WIDTH) {\n cell.dataset.expandWidth = String(currentWidth > COLLAPSED_WIDTH ? currentWidth : 100);\n }\n\n let expandBtn = cell.querySelector('nine-table-col-expand');\n if (!expandBtn) {\n expandBtn = document.createElement('nine-table-col-expand');\n cell.insertBefore(expandBtn, cell.firstChild);\n }\n\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n expandBtn.classList.add('collapsed');\n expandBtn.classList.remove('expand');\n expandBtn.setAttribute('collapsed', 'true');\n cell.style.color = 'transparent';\n\n const targetWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n if (!isNaN(colIndex)) {\n for (let i = 0; i < colSpan; i++) {\n const targetCol = tbl.querySelector(`colgroup col[data-col=\"${colIndex + i}\"]`);\n if (targetCol) {\n targetCol.setAttribute('width', targetWidth);\n targetCol.style.width = `${targetWidth}px`;\n }\n }\n }\n } else {\n expandBtn.classList.remove('collapsed');\n expandBtn.classList.add('expand');\n expandBtn.setAttribute('collapsed', 'false');\n cell.style.color = '';\n }\n });\n }\n\n static #ensureRowIndicator(tbl, host) {\n // 1. colgroup에 인디케이터용 <col> 추가\n const w = tbl.getAttribute(\"row-indicator\") === 'true' ? 48 : 0;\n\n const colgroup = tbl.querySelector('colgroup');\n\n //if (colgroup && !colgroup.querySelector('col.row-indicator-col')) {\n const col = document.createElement('col');\n //col.className = 'row-indicator-col';\n col.setAttribute('fixed', 'left');\n col.setAttribute('width', w);\n col.style.width = `${w}px`;\n colgroup.prepend(col);\n //}\n\n // 2. thead, tbody, tfoot 각 섹션별로 첫 번째 tr에 인디케이터 생성 및 rowSpan 부여\n //const sections = tbl.querySelectorAll('thead, tbody, tfoot');\n\n tbl.querySelectorAll('thead, tbody, tfoot').forEach(section => {\n const rows = Array.from(section.querySelectorAll('tr'));\n if (rows.length === 0) return;\n\n const firstTr = rows[0];\n\n const indicatorCell = document.createElement('th');\n indicatorCell.className = 'row-indicator';\n indicatorCell.setAttribute('cell-type', 'row-indicator');\n //indicatorCell.setAttribute('filtering', 'false');\n\n // 💡 섹션 내 행이 여러 개면(멀티 라인 템플릿 등) 전체를 아우르도록 rowSpan 설정\n if (rows.length > 1) {\n indicatorCell.rowSpan = rows.length;\n }\n\n firstTr.insertBefore(indicatorCell, firstTr.firstElementChild);\n });\n }\n\n static #applyInitialCellWidths(tbl) {\n // 🎯 컬럼 기준이 아닌 셀(th, td) 기준으로 순회하여 colspan 반영\n tbl.querySelectorAll('th[data-col], td[data-col]').forEach(cell => {\n\n const startColIdx = parseInt(cell.getAttribute('data-col'), 10);\n if (isNaN(startColIdx)) return;\n\n // 셀의 실제 colspan 값 추출 (기본값 1)\n const colSpan = parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1;\n let totalWidth = 0;\n\n // colspan 만큼 다음 컬럼들의 너비를 누적 합산\n for (let i = 0; i < colSpan; i++) {\n const targetIdx = startColIdx + i;\n const col = tbl.querySelector(`colgroup col[data-col=\"${targetIdx}\"]`);\n if (col) {\n totalWidth += parseInt(col.getAttribute('width'), 10) || 100;\n }\n }\n\n if (totalWidth > 0) {\n const widthVal = `${totalWidth}px`;\n cell.style.width = widthVal;\n cell.style.minWidth = widthVal;\n cell.style.maxWidth = widthVal;\n }\n });\n }\n}","// NineTableSheet.js (필터 버튼 레이아웃 및 패딩 스타일 완벽 통합본)\n\nimport { trace } from \"@nopeer\";\nimport './nine-table-hscrollbar.js';\nimport './nine-table-vscrollbar.js';\nimport { RowManager } from './core/RowManager.js';\nimport { TableCompiler } from \"./core/TableCompiler.js\";\nimport { CellSelection } from \"@/cell-manager/CellSelection.js\";\nimport { CellNavigation } from \"@/cell-manager/CellNavigation.js\";\n\nimport { ColResizer } from \"@/col/ColResizer.js\";\nimport { ColMover } from \"@/col/ColMover.js\";\nimport { ColFixManager } from \"@/col/ColFixManager.js\";\n\nimport { Filtering } from \"@/data/Filtering.js\";\nimport {Grouping, GroupingManager} from \"@/data/Grouping.js\";\nimport { Sorting } from \"@/data/Sorting.js\";\nimport { SheetView } from \"@/data/SheetView.js\";\n\nimport { PreCompiler } from \"@/layout/core/PreCompiler.js\";\n\nexport class NineTableSheet extends HTMLElement {\n #index;\n #host;\n #rowManager;\n #cellSelection;\n #cellNavigation;\n #colResizer;\n #colMover;\n #colFix;\n #sorting;\n #filtering;\n #grouping;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n static SCROLLBAR_SIZE = 16;\n\n constructor() {\n super();\n\n this.#host = this.getRootNode().host;\n this.#rowManager = new RowManager(this);\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get index() { return this.#index; }\n get colResizer() { return this.#colResizer; }\n get filtering() { return this.#filtering; }\n get grouping() { return this.#grouping; }\n get colMover() { return this.#colMover; }\n get colFix() { return this.#colFix; }\n get rowManager() { return this.#rowManager; }\n get selection() { return this.#cellSelection; }\n get navigation() { return this.#cellNavigation; }\n get templateLength() { return this.#source.tbody.tr.length || 0; }\n\n get elements() { return this.#elements; }\n\n get isAutoFitCol() {\n const attrTrue = this.getAttribute('auto-fit-col') === 'true' || this.#host?.getAttribute('auto-fit-col') === 'true';\n const sourceTableTrue = this.#source.table?.getAttribute('auto-fit-col') === 'true';\n return attrTrue || sourceTableTrue;\n }\n\n get sourceTable() {\n return this.#source.table;\n }\n\n get source() {\n return this.#source;\n }\n\n get #isSimple() {\n return this.#host.hasAttribute('simple') || this.#host.getAttribute('theme') === 'simple';\n }\n\n recompileAndRefresh() {\n if (!this.#source.table) return;\n\n TableCompiler.recompile(this.#source.table);\n\n ['left', 'right', 'body'].forEach(type => {\n ['header', 'body', 'footer'].forEach(section => {\n const container = this.querySelector(`.ng-sheet-${section} .ng-container-${type}`);\n if (!container) return;\n container.querySelectorAll('table').forEach(tbl => tbl.remove());\n });\n });\n\n this.#renderSplitContainers();\n\n this.#updateContainerWidths();\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n requestAnimationFrame(() => {\n this.#updateContainerWidths();\n this.#rowManager?.refresh();\n });\n }\n\n refreshLayout() {\n\n requestAnimationFrame(() => {\n trace.log(\"*************************\", this.classList, this.#source.table);\n\n if (!this.classList.contains('active') || !this.#source.table) return;\n\n this.#updateContainerWidths();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n this.#adjustOverlay();\n\n this.#colResizer?.refreshLayout();\n\n this.#rowManager?.refresh();\n });\n }\n\n #adjustOverlay = () => {\n // 3분할된 영역 중 중앙(body) 또는 좌측 영역의 thead를 타겟팅하여 높이 측정\n const $thead = this.querySelector('.ng-container-body thead');\n const $overlay = this.querySelector('.nodata-overlay');\n $overlay.style.top = `${$thead.offsetHeight}px`;\n\n trace.log(\"***************************************\", $thead);\n trace.log($thead.offsetHeight);\n }\n\n get view() {\n if (!this.#view && this.#host?.data) {\n this.#view = new SheetView(this);\n }\n return this.#view;\n }\n\n invalidate = () => {\n\n this.view.refresh();\n\n this.#rowManager.refresh(true);\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n }\n };\n\n autoFit = (enable = true) => {\n requestAnimationFrame(() => {\n this.#autoFit?.(enable);\n });\n };\n\n #autoFit = (enable = true) => {\n trace.log(\"***************** autoFit\", this);\n\n const container = this.querySelector('.ng-sheet-body .ng-container-body');\n if (!container) return;\n\n //const tables = container.querySelectorAll('table');\n const firstColgroup = this.querySelector('.ng-container-body table colgroup');\n if (!firstColgroup) return;\n\n if (enable) {\n this.setAttribute('auto-fit-col', 'true');\n const containerWidth = container.clientWidth;\n if (containerWidth <= 0) return;\n\n let totalOriginalWidth = 0;\n const colList = [];\n\n // 1단계: 접힌 컬럼(16px 고정)과 일반 컬럼을 분리해서 수집\n firstColgroup.querySelectorAll('col').forEach(col => {\n const globalColIndex = col.getAttribute('data-col');\n const headerCell = this.querySelector(`thead th[data-col=\"${globalColIndex}\"]`);\n const isCollapsed = headerCell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n colList.unshift({ globalColIndex, width: 16, isCollapsed: true });\n trace.log(`[AutoFit Col] Index ${globalColIndex}: COLLAPSED (forced 16px)`);\n } else {\n const w = parseInt(col.getAttribute('width'), 10) || 100;\n colList.push({ globalColIndex, width: w, isCollapsed: false });\n totalOriginalWidth += w;\n trace.log(`[AutoFit Col] Index ${globalColIndex}: NORMAL (original width: ${w}px)`);\n }\n });\n\n trace.log(`[AutoFit] Total Original Width of Normal Cols: ${totalOriginalWidth}px`);\n\n // 접힌 컬럼들이 차지하는 총 너비 계산\n const collapsedTotalWidth = colList\n .filter(c => c.isCollapsed)\n .reduce((sum, c) => sum + c.width, 0);\n\n // 남은 컨테이너 너비를 펼쳐진 컬럼들에게만 배분 (오류 수정)\n const availableWidth = Math.max(0, containerWidth - collapsedTotalWidth);\n trace.log(`[AutoFit] Collapsed Total Width: ${collapsedTotalWidth}px | Available Width for Normal Cols: ${availableWidth}px`);\n\n if (totalOriginalWidth > 0 && colList.length > 0) {\n let allocatedTotal = 0;\n\n const calculatedCols = colList.map(item => {\n if (item.isCollapsed) {\n return { globalColIndex: item.globalColIndex, remainder: 0, width: 16 };\n }\n\n // 연산자 오류 수정 (* 와 - 추가)\n const exactWidth = (item.width * availableWidth) / totalOriginalWidth;\n const baseWidth = Math.max(30, Math.floor(exactWidth));\n allocatedTotal += baseWidth;\n return {\n globalColIndex: item.globalColIndex,\n remainder: exactWidth - Math.floor(exactWidth),\n width: baseWidth\n };\n });\n\n // 잔여 픽셀 보정 (오류 수정)\n let remainderPixels = availableWidth - allocatedTotal;\n trace.log(`[AutoFit] Initial Allocated Total: ${allocatedTotal}px | Remainder Pixels to distribute: ${remainderPixels}`);\n\n const uncollapsedCols = calculatedCols.filter(c => !colList.find(item => item.globalColIndex === c.globalColIndex)?.isCollapsed);\n\n if (remainderPixels > 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => b.remainder - a.remainder);\n for (let i = 0; i < remainderPixels; i++) {\n uncollapsedCols[i % uncollapsedCols.length].width += 1;\n }\n } else if (remainderPixels < 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => a.remainder - b.remainder);\n for (let i = 0; i < Math.abs(remainderPixels); i++) {\n const target = uncollapsedCols[i % uncollapsedCols.length];\n if (target.width > 30) target.width -= 1;\n }\n }\n\n const finalSumWidth = calculatedCols.reduce((sum, c) => sum + c.width, 0);\n trace.log(`[AutoFit Verification] Target Container Width: ${containerWidth}px | Sum of All Calculated Cols: ${finalSumWidth}px`);\n\n if (containerWidth !== finalSumWidth) {\n trace.log(`⚠️ [AutoFit Mismatch Warning!] 오차 발생: ${containerWidth - finalSumWidth}px 차이가 납니다.`);\n } else {\n trace.log(`✅ [AutoFit Success] 완벽하게 일치합니다!`);\n }\n\n // 최종 적용\n calculatedCols.forEach(({ globalColIndex, width }) => {\n trace.log(`[AutoFit Apply] Col Index ${globalColIndex} -> ${width}px`);\n this.#colResizer?.setColumnWidth(globalColIndex, width, 'body');\n });\n }\n } else {\n this.removeAttribute('auto-fit-col');\n }\n\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n generate = ($table, index) => {\n\n $table.style.display = 'none';\n\n this.#index = index;\n\n PreCompiler.initializeTable(this.#host, $table);\n\n $table.style.display = '';\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n this.#renderSplitContainers();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#updateContainerWidths();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#syncHeaderAndFooterHeights();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //\n this.#initRowHoverEvent();\n\n ['left', 'body', 'right'].forEach(type => {\n const prefix = `.ng-container-${type}`;\n this.#elements[type] = {\n thead: this.querySelector(`${prefix} thead`),\n tbody: {\n head: this.querySelector(`${prefix} tbody.head`),\n body: this.querySelector(`${prefix} tbody.body`),\n foot: this.querySelector(`${prefix} tbody.foot`),\n },\n tfoot: this.querySelector(`${prefix} tfoot`),\n };\n });\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //trace.log(\"********1\", this.#source.table)\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar').refresh();\n }\n\n //this.#grouping = new GroupingManager(this);\n this.#grouping.initialize();\n\n this.loaded = true;\n };\n\n\n #updateContainerWidths = () => {\n const isAutoFit = this.isAutoFitCol;\n\n ['left', 'right', 'body'].forEach(type => {\n const containers = this.querySelectorAll(`.ng-container-${type}`);\n if (containers.length === 0) return;\n\n const firstTable = containers[0].querySelector('table');\n if (!firstTable) return;\n\n let width = 0;\n firstTable.querySelectorAll('col').forEach(col => {\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) width += w;\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n if (type === 'body') {\n container.style.flex = `1`;\n tables.forEach(tbl => {\n //tbl.style.width = isAutoFit ? `100%` : `${width}px`;\n //tbl.style.minWidth = isAutoFit ? `100%` : `${width}px`;\n });\n } else {\n container.style.flex = `0 0 ${width}px`;\n container.style.width = `${width}px`;\n container.style.minWidth = `${width}px`;\n container.style.maxWidth = `${width}px`;\n tables.forEach(tbl => {\n //tbl.style.width = `${width}px`;\n //tbl.style.minWidth = `${width}px`;\n });\n }\n });\n });\n };\n\n #renderSplitContainers = () => {\n const colTypes = [\n { selector: '.ng-container-left', type: 'left' },\n { selector: '.ng-container-body', type: null },\n { selector: '.ng-container-right', type: 'right' }\n ];\n\n colTypes.forEach(({ selector, type }) => {\n this.querySelector(`.ng-sheet-body ${selector}`).appendChild(this.#createSplitTable(type));\n });\n };\n\n #createSplitTable = (targetFixedType) => {\n\n const $tbl = this.#source.table.cloneNode(true);\n\n if (targetFixedType === 'left') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"left\") $el.remove();\n });\n } else if (targetFixedType === 'right') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"right\") $el.remove();\n });\n } else {\n $tbl.querySelectorAll(\"[fixed=left], [fixed=right]\").forEach($el => {\n $el.remove();\n });\n }\n\n return $tbl;\n };\n\n getRowHeight = () => {\n return this.#rowManager.getRowHeight();\n };\n\n /**\n * this.#elements = {\n * mainBody: this.querySelector('.ng-sheet-body .ng-container-body'),\n * hscrollbar: this.querySelector('nine-table-hscrollbar'),\n * vscrollbar: this.querySelector('nine-table-vscrollbar'),\n * content: this.querySelector('.ng-sheet-body .ng-sheet-body-content'),\n * scrollHolder: this.querySelector('.ng-sheet-body .ng-virtual-height-holder'),\n * }\n * @returns {*}\n */\n\n getViewHeight = () => {\n\n const viewHeight = this.#elements.content.offsetHeight || 0;\n\n const fixedHeight = (this.#elements.body.thead?.offsetHeight || 0) +\n (this.#elements.body.tfoot?.offsetHeight || 0) +\n (this.#elements.body.tbody.head.offsetHeight || 0);\n\n return viewHeight - fixedHeight;\n };\n\n isLastRow = () => {\n\n // 1. 시트(뷰포트) 엘리먼트와 마지막 tr 찾기\n const sheet = this.querySelector('.ng-sheet-body');\n const tbody = this.querySelector(\".ng-container-body tbody.body\");\n\n const offsetHeight = (this.#elements.body.tfoot?.offsetHeight || 0);\n\n const sheetBottom = sheet.getBoundingClientRect().bottom;\n const tbodyBottom = tbody.getBoundingClientRect().bottom;\n\n trace.log(sheetBottom, tbodyBottom, offsetHeight);\n\n // 💡 tbody의 하단이 sheet의 하단보다 위에 있는지(안 보이는지/덜 채워졌는지) 확인\n return (sheetBottom - offsetHeight) >= tbodyBottom;\n };\n\n scrollToX = (scrollLeft) => {\n const bodyContainer = this.querySelector('.ng-sheet-body .ng-container-body');\n if (bodyContainer) bodyContainer.scrollLeft = scrollLeft;\n };\n\n scrollToY = (scrollTop) => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (bodyViewport) bodyViewport.scrollTop = scrollTop;\n };\n\n #init = () => {\n\n this.#render();\n\n this.#cellSelection = new CellSelection(this);\n this.#cellNavigation = new CellNavigation(this);\n this.#colResizer = new ColResizer(this);\n this.#colMover = new ColMover(this);\n this.#colFix = new ColFixManager(this);\n\n this.#view = new SheetView(this);\n this.#filtering = new Filtering(this);\n this.#grouping = new GroupingManager(this);\n\n if (!this.#isSimple) {\n this.#sorting = new Sorting(this);\n }\n\n this.#elements.mainBody.addEventListener('scroll', () => {\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n\n this.innerHTML = `\n <div class=\"ng-sheet-body\">\n <div class=\"ng-sheet-body-content\">\n <div class=\"ng-container-left\"></div>\n <div class=\"ng-container-body\"></div>\n <div class=\"ng-container-right\"></div>\n </div>\n <div class=\"ng-virtual-height-holder\"></div>\n </div>\n\n <div class=\"nodata-overlay\">Data Not Found</div>\n\n <!-- [Grid Row 1, Col 2] 세로 스크롤바 -->\n <nine-table-vscrollbar></nine-table-vscrollbar>\n\n <!-- [Grid Row 2, Col 1] 가로 스크롤바 -->\n <nine-table-hscrollbar></nine-table-hscrollbar>\n\n <!-- [Grid Row 2, Col 2] 우하단 엣지 -->\n <div class=\"scroll-edge\"></div>\n \n <!-- 리사이저 및 드래그 패널들 -->\n <nine-table-col-resizer-panel></nine-table-col-resizer-panel>\n <!--\n <div class=\"ng-col-resizer-panel\">\n <div class=\"resizer-overlay\">\n <span class=\"size-badge\">0px</span>\n </div>\n </div> ->\n \n <div class=\"ng-col-mover-grip\"></div>\n <div class=\"ng-col-mover-indi\"></div>\n `;\n\n //let fixedHeight = this.#sheet.querySelector('.ng-container-body thead').offsetHeight + this.#sheet.querySelector('.ng-container-body tfoot').offsetHeight;\n\n this.#elements = {\n mainBody: this.querySelector('.ng-sheet-body .ng-container-body'),\n hscrollbar: this.querySelector('nine-table-hscrollbar'),\n vscrollbar: this.querySelector('nine-table-vscrollbar'),\n content: this.querySelector('.ng-sheet-body .ng-sheet-body-content'),\n scrollHolder: this.querySelector('.ng-sheet-body .ng-virtual-height-holder'),\n }\n trace.log(\"444*****************\");\n };\n\n #syncHeaderAndFooterHeights = () => {\n trace.log(\"**********************\", \"#syncHeaderAndFooterHeights\");\n\n //requestAnimationFrame(() => {\n // requestAnimationFrame(() => {\n const leftTable = this.querySelector('.ng-container-left table');\n const bodyTable = this.querySelector('.ng-container-body table');\n const rightTable = this.querySelector('.ng-container-right table');\n\n // 1. 헤더(thead) 행 높이 싱크 (인덱스 행 제외)\n const leftHeaderRows = Array.from(leftTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const bodyHeaderRows = Array.from(bodyTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const rightHeaderRows = Array.from(rightTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n\n this.#applyMaxHeights(leftHeaderRows, bodyHeaderRows, rightHeaderRows);\n\n // 2. 푸터(tfoot) 행 높이 싱크\n const leftFooterRows = Array.from(leftTable.querySelectorAll('tfoot tr'));\n const bodyFooterRows = Array.from(bodyTable.querySelectorAll('tfoot tr'));\n const rightFooterRows = Array.from(rightTable.querySelectorAll('tfoot tr'));\n\n this.#applyMaxHeights(leftFooterRows, bodyFooterRows, rightFooterRows);\n // });\n //});\n };\n\n// 공통 최대 높이 적용 헬퍼 메서드\n #applyMaxHeights = (leftRows, bodyRows, rightRows) => {\n /** 바닐라에서 setTimeout 없으면 높이계산이 가끔 안됨 */\n setTimeout(() => {\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n trace.log(this.#host);\n for (let i = 0; i < maxRows; i++) {\n trace.log(maxRows);\n\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n trace.log(heights, maxHeight);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n });\n };\n\n #initRowHoverEvent = () => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n let activeRowIndex = null;\n\n // 마우스 진입 (모든 컨테이너 탐색)\n bodyViewport.addEventListener('mouseover', (e) => {\n const tr = e.target.closest('tr');\n if (!tr || !tr.dataset.row && tr.dataset.row !== '0') return;\n\n const rowIndex = tr.dataset.row;\n if (activeRowIndex === rowIndex) return;\n activeRowIndex = rowIndex;\n\n // 좌측, 본문, 우측 컨테이너에서 동일한 data-row를 가진 tr들을 모두 찾아 .hover 부여\n bodyViewport.querySelectorAll(`tr[data-row=\"${rowIndex}\"]`).forEach($tr => {\n $tr.classList.add('hover');\n });\n });\n\n // 마우스 이탈\n bodyViewport.addEventListener('mouseout', (e) => {\n const tr = e.target.closest('tr');\n if (!tr) return;\n\n // 현재 영역을 완전히 벗어났을 때만 전체 hover 제거\n const relatedTarget = e.relatedTarget;\n if (tr.contains(relatedTarget)) return;\n\n bodyViewport.querySelectorAll('tr.hover').forEach($tr => {\n $tr.classList.remove('hover');\n });\n activeRowIndex = null;\n });\n }\n\n disconnectedCallback() {\n this.#colResizer?.destroy();\n this.#colMover?.destroy();\n this.innerHTML = '';\n }\n}\n\nif (!customElements.get('nine-table-sheet')) {\n customElements.define('nine-table-sheet', NineTableSheet);\n}","import { trace } from \"@nopeer\";\nimport '@/layout/nine-table-sheets.js';\nimport '@/layout/nine-table-sheets-footer.js';\nimport '@/layout/nine-table-toolbar.js';\nimport { NineTableSheet } from \"@/layout/nine-table-sheet.js\";\n\nexport class LayoutManager {\n #host;\n\n constructor(owner) {\n this.#host = owner;\n this.#init();\n }\n\n #init = () => {\n this.#render();\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }).observe(this.#host);\n }\n\n set loading(val) {\n if (!!val) {\n this.#host.classList.add(\"loading\");\n } else {\n this.#host.classList.remove(\"loading\");\n }\n }\n\n #applyAutoHeight = () => {\n const activeSheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet.active'));\n if (activeSheets.length === 0) return;\n\n const maxDisplayRows = parseInt(this.#host.getAttribute('max-display-row'), 10) || 10;\n const maxRowHeight = Math.max(...activeSheets.map(sheet => sheet.getRowHeight()));\n\n const toolbarEl = this.#host.shadowRoot.querySelector('nine-table-toolbar');\n const footerEl = this.#host.shadowRoot.querySelector('nine-table-sheets-footer');\n\n const toolbarHeight = toolbarEl ? toolbarEl.getBoundingClientRect().height : 0;\n const footerHeight = footerEl ? footerEl.getBoundingClientRect().height : 0;\n const extraPadding = NineTableSheet.SCROLLBAR_SIZE;\n\n const calculatedHeight = (maxDisplayRows * maxRowHeight) + toolbarHeight + footerHeight + extraPadding;\n\n this.#host.style.height = `${calculatedHeight}px`;\n };\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n const sheetCount = rawTables.length;\n\n const sheetsHtml = rawTables.map((tbl, idx) => {\n const className = idx === 0 ? 'active' : '';\n const sheetId = tbl.id || `sheet${idx + 1}`;\n\n const sheetTag = `<nine-table-sheet class=\"${className}\" data-index=\"${idx}\" data-sheet-id=\"${sheetId}\" id=\"${sheetId}\"></nine-table-sheet>`;\n const splitterTag = idx < sheetCount - 1 ? `<nine-splitter class=\"h\" data-split-index=\"${idx}\"></nine-splitter>` : '';\n return sheetTag + splitterTag;\n }).join('');\n\n // 1. 공통 파일명 배열 정의\n\n\n const cssFiles = [\n 'layout', 'nine-table-sheet', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table', 'col-resize', 'sorting', 'fitering', 'col-expand',\n 'host', 'cell-combo', 'cell-selection'\n ];\n\n trace.log(\"Welcome nine-table\", __APP_VERSION__);\n\n const cssImports = [\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/datagrid@${__APP_VERSION__}/dist/css/nine-table.css\";`,\n ];\n\n if (nine[\"nine-table\"] && nine[\"nine-table\"].cssFile) {\n cssImports.push(`@import \"${nine[\"nine-table\"].cssFile}\";`);\n }\n\n this.#host.shadowRoot.innerHTML = `\n <style>\n ${cssImports.join('\\n')}\n </style>\n \n <nine-table-toolbar></nine-table-toolbar>\n\n <nine-table-body>\n <nine-table-summary></nine-table-summary>\n <div class=\"ng-loading-bar\"></div>\n <nine-table-sheets>\n <nine-table-sheets-body>\n ${sheetsHtml}\n </nine-table-sheets-body>\n <nine-table-sheets-footer></nine-table-sheets-footer>\n </nine-table-sheets>\n <nine-table-analysis></nine-table-analysis>\n </nine-table-body>\n <nine-table-footer></nine-table-footer>\n `;\n\n /**\n * <div class=\"nine-tab-bar\">${tabsHtml}</div>\n * <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n */\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($el, idx) => {\n\n if (rawTables[idx]) {\n setTimeout(() => {\n $el.generate(rawTables[idx], idx);\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n });\n }\n });\n };\n}","import { trace } from \"@nopeer\";\n\nexport class ExprEngine {\n #host;\n #fields;\n #exprCache = new Map(); // 💡 통합된 단일 캐시로 모든 컴파일된 함수 관리\n\n constructor(host) {\n this.#host = host;\n this.#fields = host.fields.get();\n }\n\n /**\n * 🎯 표현식 내의 data.fieldName을 원시 배열 인덱스 접근(rowItem.v[idx])으로 변환\n */\n rewriteExpr(expr) {\n\n if (!expr || !this.#fields.length) return expr;\n\n return expr.replace(/data\\.([a-zA-Z_$][\\w$]*)/g, (match, fieldName) => {\n const idx = this.#fields.indexOf(fieldName);\n return idx >= 0 ? `rowItem.v[${idx}]` : match;\n });\n }\n\n /**\n * 🎯 셀 또는 컬럼 정의에 선언된 expr 프리컴파일\n */\n precompile(expr) {\n if (!expr) return expr;\n return this.rewriteExpr(expr);\n }\n\n /**\n * 🎯 표현식 평가 및 실행 (통합 캐싱)\n */\n evaluate(expr, rowItem, row = 0) {\n\n if (expr === undefined || expr === null) return \"\";\n\n try {\n const trimmedExpr = String(expr).trim();\n const compiledExpr = this.rewriteExpr(trimmedExpr);\n\n // 💡 함수 호출, 데이터 참조, 연산식이 포함된 경우 통합 평가 및 캐싱\n if (compiledExpr.includes(\"data.\") || compiledExpr.includes(\"rowItem.v\") || compiledExpr.includes(\"host.\") || compiledExpr.includes(\"(\")) {\n let evalFn = this.#exprCache.get(compiledExpr);\n\n if (!evalFn) {\n evalFn = new Function('rowItem', 'row', 'host', `\n const data = rowItem;\n\n if (!data && !host) return \"\";\n return ${compiledExpr};\n `);\n\n this.#exprCache.set(compiledExpr, evalFn);\n }\n\n return evalFn(rowItem, row, this.#host);\n }\n\n return compiledExpr;\n } catch (e) {\n //console.trace(\"ExprEngine evaluation error:\", e);\n return expr;\n }\n }\n}","import { trace } from \"@nopeer\";\nimport { ngDataManager } from '@/data/ngDataManager.js';\nimport { fields } from \"@/data/Fields.js\";\nimport { LayoutManager } from '@/layout/core/LayoutManager.js';\nimport { ExprEngine } from \"@/core/ExprEngine.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #templateCnt = 0; // 🎯 로딩 상태 플래그\n\n constructor() {\n super();\n\n this.#shadowRoot = this.attachShadow({ mode: 'open' });\n this.#dataManager = new ngDataManager(this);\n }\n\n connectedCallback() {\n setTimeout(() => {\n this.#templateCnt = this.querySelectorAll(\"table\")?.length;\n\n this.fields = new fields(this);\n this.exprEngine = new ExprEngine(this);\n\n this.#bindDynamicSetters();\n\n this.#layoutManager = new LayoutManager(this);\n\n this.#dispatchLoad();\n //this.dispatchEvent(new CustomEvent('load', { bubbles: true, detail: { target: this } }));\n });\n }\n\n disconnectedCallback() {\n trace.log('NineTable disconnected.');\n }\n\n #dispatchLoad = () => {\n // 🎯 2. 변수명 오타 수정 (#sheetCnt -> #templateCnt)\n //trace.log(\"*********************** template count:\", this.#templateCnt);\n\n let checkCount = 0;\n const maxChecks = 50; // 최대 5초 대기 (100ms * 50)\n\n const checkTimer = setInterval(() => {\n checkCount++;\n\n const sheets = this.shadow.querySelectorAll('nine-table-sheet');\n //trace.log(\"Current mounted sheets:\", sheets.length);\n\n if (checkCount >= maxChecks) {\n clearInterval(checkTimer);\n }\n\n if (sheets.length >= this.#templateCnt) {\n let loadSheetCnt = 0;\n sheets.forEach($sheet => {\n if ($sheet.loaded) loadSheetCnt++;\n });\n\n //trace.log('Checking sheet loaded status:', loadSheetCnt, '/', this.#templateCnt);\n\n if (loadSheetCnt >= this.#templateCnt) {\n clearInterval(checkTimer);\n this.loaded = true;\n this.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.LOAD, { bubbles: true, detail: { target: this } }));\n }\n }\n }, 100);\n }\n\n\n // 🎯 공통 데이터 & API 접근자\n get shadow() { return this.#shadowRoot; }\n get dataManager() { return this.#dataManager; }\n get data() { return this.#dataManager.data; }\n get row() { return this.#dataManager.row; }\n\n setData(records) {\n this.#dataManager.data.set(records);\n this.refresh();\n }\n\n refresh() {\n this.activeSheet?.invalidate();\n }\n\n // 🎯 섀도우 돔 내부에서 로딩바 요소를 안전하게 캐싱\n\n\n set loading(val) {\n if (this.#layoutManager) this.#layoutManager.loading = val;\n }\n\n /**\n * 랜더링 이후에 생기는 data-source 처리기능\n */\n rerenderer() {\n\n this.activeSheet?.querySelectorAll(\"tbody.body th,tbody.body td\").forEach(($cell) => {\n const customComp = Array.from($cell.children).find($el => {\n return $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.rerenderer === 'function'\n });\n\n customComp?.rerenderer();\n })\n }\n\n // 시트 제어 API\n sheet = (idOrIndex) => {\n if (idOrIndex === null || idOrIndex < 0) return this.activeSheet;\n const sheets = Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n\n if (typeof idOrIndex === 'number') return sheets[idOrIndex] || null;\n if (typeof idOrIndex === 'string') {\n return this.shadow.querySelector(`nine-table-sheet#${idOrIndex}, nine-table-sheet[data-sheet-id=\"${idOrIndex}\"]`) || null;\n }\n return sheets[0] || null;\n }\n\n get sheets() {\n return Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n }\n\n get activeSheet() {\n return this.shadow.querySelector('nine-table-sheet.active') || null;\n }\n\n #bindDynamicSetters() {\n const extractedMethodNames = new Set();\n\n this.querySelectorAll('[data-source]').forEach(el => {\n const dataSource = el.getAttribute('data-source');\n if (!dataSource) return;\n\n // 💡 [수정] 뒤에 여멀림 괄호 '('가 오는 형태만 매칭하여 'DEPART' 같은 파라미터는 배제!\n const matches = dataSource.matchAll(/(?:host\\.)?([a-zA-Z0-9_$]+)\\s*\\(/g);\n for (const match of matches) {\n const name = match[1];\n if (name && name !== 'host') {\n extractedMethodNames.add(name);\n }\n }\n });\n\n // 추출된 메서드 이름별로 NineTable 인스턴스에 동적 세터 생성\n extractedMethodNames.forEach(methodName => {\n let internalValue = null;\n\n Object.defineProperty(this, methodName, {\n set: (newValue) => {\n internalValue = newValue;\n\n // 값이 대입되는 순간 그리드 자동 갱신\n //this.refresh();\n this.rerenderer();\n },\n get: () => internalValue,\n configurable: true,\n enumerable: true\n });\n });\n }\n\n execute = (fn) => {\n setTimeout(() => {\n this.loading = true;\n setTimeout(() => {\n try {\n fn.call(this);\n } finally {\n this.loading = false;\n }\n });\n });\n }\n}\n\nif (!customElements.get('nine-table')) {\n customElements.define('nine-table', NineTable);\n}\n\nif (!customElements.get('nine-table-simple')) {\n customElements.define('nine-table-simple', class extends NineTable {\n connectedCallback() {\n // simple 태그로 생성되면 자동으로 mode=\"simple\" 속성 부여\n this.setAttribute('theme', 'simple');\n\n super.connectedCallback();\n }\n });\n}","export class BasicCellElement extends HTMLElement {\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tapplyBaseStyle() {\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { BasicCellElement } from './BasicCellElement.js';\r\n\r\nconst exprCache = new Map();\r\n\r\nexport class CellElement extends BasicCellElement {\r\n\t#host;\r\n\t#sheet;\r\n\t#tr;\r\n\t#cell;\r\n\t#attr;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tget host() { return this.#host; }\r\n\tget sheet() { return this.#sheet; }\r\n\tget cell() { return this.#cell; }\r\n\tget tr() { return this.#tr; }\r\n\tget attr() { return this.#attr; }\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\tthis.#cell = this.closest(\"th,td\");\r\n\t\tthis.#tr = this.#cell.closest(\"tr\");\r\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\r\n\r\n\t\tthis.#cell.classList.add(this.tagName);\r\n\r\n\t\tthis.#attr = {};\r\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\r\n\t\t\tconst name = this.#cell.attributes[i].name;\r\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\r\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\r\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#cell) return;\r\n\r\n\r\n\t\tconst root = this.shadowRoot || this;\r\n\r\n\t\t// 🎯 버튼 이벤트 연결\r\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\r\n\t\t\tbutton.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\r\n\r\n\t\t\t\tconst rowData = this.data; // Proxy Lazy 접근\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t/**\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t})); */\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 링크 이벤트 연결\r\n\t\tconst renderer = root.querySelector(\".renderer\");\r\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\r\n\t\t\trenderer.classList.add(\"link\");\r\n\r\n\t\t\trenderer.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\r\n\r\n\t\t\t\tconst rowData = this.data;\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t}));\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tget data() {\r\n\t\tconst rawRecord = this.#tr?.data;\r\n\t\tif (!rawRecord) return null;\r\n\t\tif (!rawRecord.v) return rawRecord;\r\n\r\n\t\tconst host = this.#host;\r\n\r\n\t\treturn new Proxy(rawRecord, {\r\n\t\t\tget(target, prop) {\r\n\t\t\t\tif (prop === '__ng') return target.__ng;\r\n\t\t\t\tif (prop === 'v') return target.v;\r\n\r\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\r\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tget value() {\r\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\r\n\r\n\t\tconst bindKey = this.#cell.dataset?.bind;\r\n\t\tif (!bindKey) return \"\";\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\r\n\t\t\t// 💡 fields.indexOf(bindKey)로 바로 찾기!\r\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\r\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\r\n\t\t}\r\n\r\n\t\treturn rawRecord[bindKey] ?? \"\";\r\n\t}\r\n\r\n\tset value(v) {\r\n\t\tif (!this.#cell || !this.#host?.data) return;\r\n\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tif (isNaN(row) || !bindKey) return;\r\n\r\n\t\tconst updateRowState = this.getAttribute('update-row-state') !== \"false\";\r\n\t\tthis.#host.data.setValue(row, bindKey, v, updateRowState);\r\n\t}\r\n\r\n\tget row() {\r\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\r\n\t}\r\n\tget index() {\r\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\r\n\t}\r\n\r\n\tisValid() {\r\n\t\treturn this.#cell.classList.contains(\"invalid\") ? false : true;\r\n\t}\r\n\r\n\tisInvalid() {\r\n\t\treturn !this.isValid();\r\n\t}\r\n\r\n\tgetDisplayText = (defaultValue = \"\") => {\r\n\r\n\t\tif (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\tif (!rawRecord) return defaultValue;\r\n\r\n\t\tconst expr = this.#cell.dataset.expr;\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\tif (expr) {\r\n\t\t\ttry {\r\n\t\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\r\n\r\n\t\t\t\t\treturn this.getGroupExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row);\r\n\r\n\t\t\t\t\t//return this.getExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\t//console.trace(e);\r\n\t\t\t\t//console.error(\"Expr evaluation error:\", expr, e);\r\n\t\t\t\treturn defaultValue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (bindKey) {\r\n\t\t\tconst val = this.value;\r\n\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\r\n\t\t}\r\n\r\n\t\treturn defaultValue;\r\n\t};\r\n\r\n\r\n\r\n\trefresh() {\r\n\r\n\t\tif (!this.#cell || !this.#tr) return;\r\n\r\n\t\tconst val = this.value;\r\n\r\n\t\tthis.#cell.classList.remove(\"invalid\");\r\n\r\n\t\t[\"color\",\"background\",\"background-color\",\"visible\",\"enable\",\"validator\"].forEach(v => {\r\n\r\n\t\t\tconst expr = this.#attr[v];\r\n\t\t\tif (expr) {\r\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10));\r\n\r\n\t\t\t\tif (v === \"validator\") {\r\n\t\t\t\t\tif (!result) {\r\n\t\t\t\t\t\tthis.#cell.classList.add(\"invalid\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else if (v === \"visible\") {\r\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\r\n\t\t\t\t} else if (v === \"enable\") {\r\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\r\n\t\t\t\t\t\t$el.disabled = !result;\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif (!!result) {\r\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#cell.style[v] = result;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn val;\r\n\t}\r\n\r\n\tgetExprValue(expr, data, row) {\r\n\t\tif (!this.#host || !this.#host.exprEngine || expr === undefined || expr === null || expr === \"\") return expr;\r\n\r\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row);\r\n\t}\r\n\r\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\r\n\t\tif (!expr) return \"\";\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\r\n\r\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\r\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\r\n\t\t\tif (match) {\r\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\r\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\r\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\r\n\r\n\t\t\t\tconst [, funcName, field] = match;\r\n\t\t\t\tconst host = this.#host;\r\n\r\n\t\t\t\tswitch (funcName.toLowerCase()) {\r\n\t\t\t\t\tcase 'count':\r\n\t\t\t\t\t\treturn childRecords.length;\r\n\r\n\t\t\t\t\tcase 'sum': {\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tcase 'avg': {\r\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t\treturn sum / childRecords.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 3. 호스트의 exprFunction 활용\r\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\r\n\t\t\t}\r\n\r\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\r\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\r\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\r\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\r\n \r\n let childRecords = [];\r\n if (Array.isArray(indices)) {\r\n // indices가 숫자 인덱스 배열인지, rowid 문자열 배열인지 판별하여 안전하게 추출\r\n childRecords = indices.map(idx => {\r\n if (typeof idx === 'number') {\r\n return allRecords[idx];\r\n } else {\r\n // rowid 등 문자열 식별자인 경우 전체 배열에서 찾거나 dataManager 활용\r\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\r\n }\r\n }).filter(Boolean);\r\n }\r\n \r\n // 만약 위에서 못 찾았는데 host.grouping을 쓸 수 있다면 매니저 위임 시도\r\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\r\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\r\n }\r\n\r\n const data = childRecords; // data.length 등을 쓸 수 있도록 호환\r\n return ${expr};\r\n `);\r\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\r\n\t\t\t}\r\n\r\n\t\t\treturn expr;\r\n\t\t} catch (e) {\r\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\r\n\t\t\treturn expr;\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class EditableCellElement extends CellElement {\r\n\r\n\tget host() { return super.host; }\r\n\tget sheet() { return super.sheet; }\r\n\tget cell() { return super.cell; }\r\n\tget tr() { return super.tr; }\r\n\tget attr() { return super.attr; }\r\n\r\n\tgetExprValue(expr, data, row, cell) {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\t}\r\n\r\n\trefresh() {\r\n\t\treturn super.refresh();\r\n\t}\r\n\r\n\tgetExprValue = (expr, data, row, cell) => {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tisValid = () => {\r\n\t\treturn super.isValid();\r\n\t}\r\n\r\n\tisInvalid = () => {\r\n\t\treturn super.isInvalid();\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputText extends EditableCellElement\n{\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\t\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#initEvent();\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tthis.#target.value = v;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"input\", e => {\n\t\t\tif (this.#maxbyte) {\n\t\t\t\tconst maxByteNum = Number(this.#maxbyte);\n\t\t\t\tconst currentBytes = nine.getByteLength(e.target.value);\n\n\t\t\t\tif (currentBytes > maxByteNum) {\n\t\t\t\t\te.target.value = nine.cut(e.target.value, maxByteNum);\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<input type=\"text\" ondragstart=\"return false;\">\n\t\t`;\n\t};\n\n\tget #maxbyte() {\n\t\treturn this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\t}\n}\n\nif (!customElements.get('cell-input')) {\n\tcustomElements.define(\"cell-input\", CellInputText);\n}\n","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputNumber extends EditableCellElement\n{\n\t#target;\n\n\tconstructor () {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#initEvent();\n\n\n\t};\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <input type=\"text\" ondragstart=\"return false;\">\n `;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"keydown\", this.#onKeyDown);\n\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tthis.#target.value = v;//v !== undefined && v !== null ? v : \"\";\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate();\n\t\t}\n\t};\n\n\t#validate = () => {\n\n\t\tconst v = this.#target.value;\n\n\t\tif (v !== \"\" && v !== null && v !== undefined) {\n\t\t\tconst num = Number(v);\n\n\t\t\tif (isNaN(num) || (this.#max && num > Number(this.#max)) || (this.#min && num < Number(this.#min))) {\n\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (this.#scale) {\n\t\t\t\tconst str = String(v);\n\t\t\t\tconst idx = str.indexOf('.');\n\t\t\t\tif (idx >= 0 && str.substring(idx + 1).length > Number(this.#scale)) {\n\t\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t#onKeyDown = e => {\n\n\t\tif ([\"Escape\", \"Enter\", \"Tab\", \"Home\", \"End\", \"ArrowLeft\", \"ArrowRight\", \"PageUp\", \"PageDown\", \"Backspace\", \"Delete\"].includes(e.code)) return;\n\n\t\tconst target = e.target;\n\t\tconst value = target.value;\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst key = e.key;\n\n\t\tif (key === \"-\") {\n\t\t\tif (value.includes(\"-\") || selectionStart !== 0) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (key === \".\") {\n\t\t\tconst scale = Number(this.#scale);\n\n\t\t\tif (isNaN(scale) || scale <= 0 || value.includes(\".\")) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tlet validKey = [];\n\t\tif (this.#scale && Number(this.#scale) > 0) validKey.push(\".\");\n\t\tif (this.#min || Number(this.#min) > 0) validKey.push(\"-\");\n\n\t\tconst isNumKey = (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105);\n\n\t\tif (!isNumKey && !validKey.includes(e.key)) {\n\t\t\te.preventDefault();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#scale && isNumKey && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\tconst s = e.target.value;\n\t\t\tconst idx = s.indexOf(\".\");\n\t\t\tif (idx >= 0 && e.target.selectionStart > idx) {\n\t\t\t\tconst decimalPart = s.substr(idx + 1);\n\t\t\t\tif (decimalPart.length >= Number(this.#scale)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.#maxbyte && nine.getByteLength(e.target.value) >= Number(this.#maxbyte) && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\te.preventDefault();\n\t\t}\n\t}\n\n\tget #min() {\n\t\treturn this.cell.getAttribute(\"min\") || \"\";\n\t}\n\n\tget #max() {\n\t\treturn this.cell.getAttribute(\"max\") || \"\";\n\t}\n\n\tget #scale() {\n\t\treturn this.cell.getAttribute(\"scale\") || \"\";\n\t}\n\n\tget #maxbyte() {\n\t\treturn this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\t}\n}\n\nif (!customElements.get('cell-input-number')) {\n\tcustomElements.define(\"cell-input-number\", CellInputNumber);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputColor extends EditableCellElement\n{\n\t#target;\n\t#btn;\n\t#dataSource;\n\n\tconstructor () {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input[type=color]\");\n\t\tthis.#btn = this.querySelector(\"button\");\n\n\t\t//this.#rendererColor();\n\n\t\tthis.#initEvent();\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#btn.addEventListener(\"click\", () => {\n\t\t\tthis.#target.click();\n\t\t});\n\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validate(val);\n\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validate(val);\n\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <input type=\"color\" ondragstart=\"return false;\">\n <button tabindex=\"-1\" type=\"button\"></button>\n `;\n\t};\n\n\trerenderer = () => {\n\t\tthis.refresh();\n\t};\n\n\t#rendererColor = () => {\n\n\t\tconst dataSource = this.cell.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, this.tr.data, this.tr.dataset.row);\n\n\t\tthis.querySelector(\"datalist\")?.remove();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\t\t\tconst datalistId = `color-list-${Math.random().toString(36).substr(2, 9)}`;\n\n\t\t\tconst datalist = document.createElement('datalist');\n\t\t\tdatalist.id = datalistId;\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tif (v.value) {\n\t\t\t\t\tconst option = document.createElement('option');\n\t\t\t\t\toption.value = v.value;\n\t\t\t\t\tfragment.appendChild(option);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdatalist.appendChild(fragment);\n\t\t\tthis.appendChild(datalist);\n\n\t\t\tthis.#target.setAttribute(\"list\", datalistId);\n\t\t}\n\t};\n\n\trefresh = () => {\n\t\tif (!this.tr.data) return;\n\n\t\tconst v = super.refresh();\n\n\t\tthis.#rendererColor();\n\n\t\tthis.#target.value = v !== undefined && v !== null && v !== \"\" ? v : \"#ffffff\";\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate();\n\t\t}\n\t};\n\n\t#validate = () => {\n\n\t\tconst v = this.#target.value;\n\n\t\tif (v !== \"\" && v !== null && v !== undefined) {\n\t\t\tif (!this.#isValidColor(v)) {\n\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (this.#dataSource && Array.isArray(this.#dataSource) && this.#dataSource.length > 0) {\n\t\t\t\tconst exists = this.#dataSource.some(item => {\n\t\t\t\t\tconst itemCode = item.value !== undefined ? item.value : (item.code !== undefined ? item.code : '');\n\t\t\t\t\treturn itemCode.toLowerCase() === v.toLowerCase();\n\t\t\t\t});\n\n\t\t\t\tif (!exists) {\n\t\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidColor = (v) => {\n\t\tif (typeof v !== \"string\" || v.length != 7 || !v.startsWith(\"#\")) return false;\n\n\t\tvar r = parseInt(v.substr(1, 2), 16);\n\t\tvar g = parseInt(v.substr(3, 2), 16);\n\t\tvar b = parseInt(v.substr(5, 2), 16);\n\n\t\tif (isNaN(r) || isNaN(g) || isNaN(b)) return false;\n\t\tif (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) return false;\n\n\t\treturn true;\n\t}\n}\n\nif (!customElements.get('cell-input-color')) {\n\tcustomElements.define(\"cell-input-color\", CellInputColor);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputDate extends EditableCellElement\n{\n\t#target;\n\t#type;\n\n\tconstructor () {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#target.classList.toggle(\"has-value\", !!val); // 💡 실시간 반영\n\t\t\tthis.#validate(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validate(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.#type = this.cell.getAttribute(\"date-type\") || \"date\";\n\t\tif (![\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(this.#type)) {\n\t\t\tthrow `invalid type : ${this.#type}`;\n\t\t}\n\n\t\tlet attr = [];\n\t\tfor (let i = 0; i < this.cell.attributes.length; i++) {\n\t\t\tif ([\"value\", \"max\", \"min\", \"step\"].includes(this.cell.attributes[i].name)) {\n\t\t\t\tattr.push(`${this.cell.attributes[i].name}=\"${this.cell.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <input\n type=\"${this.#type}\"\n data-placeholder=\"${this.cell.getAttribute('placeholder') || 'Select'}\"\n ${attr.join(\" \")}\n required\n />\n `;\n\t};\n\n\trefresh = () => {\n\n\t\tconst v = super.refresh();\n\n\t\tlet formattedVal = v;\n\t\tif (formattedVal) {\n\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"date\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"time\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"00\" + d.getHours()).slice(-2) + \":\" + (\"00\" + d.getMinutes()).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"0000\" + d.getFullYear()).slice(-4) + \"-\" + (\"00\" + (d.getMonth() + 1)).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis.#target.value = formattedVal || \"\";\n\t\tthis.#target.classList.toggle(\"has-value\", !!formattedVal); // 💡 값이 있으면 클래스 추가\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate(formattedVal);\n\t\t}\n\t};\n\n\t#validate = (val) => {\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tlet isValid = this.#isValidDate(val);\n\n\t\t\tif (isValid) {\n\t\t\t\tif (this.#min && val < this.#min) isValid = false;\n\t\t\t\tif (this.#max && val > this.#max) isValid = false;\n\t\t\t}\n\n\t\t\tif (!isValid) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidDate = (v) => {\n\n\t\tif (typeof v !== \"string\") return false;\n\n\t\tlet isValid = true;\n\n\t\tswitch (this.#type) {\n\t\t\tcase \"date\":\n\t\t\tcase \"datetime-local\":\n\t\t\t\tconst year = Number(v.substr(0, 4));\n\t\t\t\tconst month = Number(v.substr(5, 2));\n\t\t\t\tconst day = Number(v.substr(8, 2));\n\n\t\t\t\tif (isNaN(year) || isNaN(month) || isNaN(day)) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month < 1 || month > 12 || day < 1 || day > 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if ([4, 6, 9, 11].includes(month) && day == 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month == 2) {\n\t\t\t\t\tlet isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));\n\t\t\t\t\tif (day > 29 || (day == 29 && !isleap)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (isValid) {\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tvar t = v.substr(10, 1);\n\t\t\t\t\tvar hour = Number(v.substr(11, 2));\n\t\t\t\t\tvar min = Number(v.substr(14, 2));\n\n\t\t\t\t\tif (t != \"T\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(hour) || isNaN(min)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (hour < 0 || hour > 23 || min < 0 || min > 59) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar month = Number(v.substr(5, 2));\n\n\t\t\t\t\tif (isNaN(year) || isNaN(month)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (month < 1 || month > 12) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"week\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar w = v.substr(5, 1);\n\t\t\t\t\tvar week = Number(v.substr(6, 2));\n\n\t\t\t\t\tif (w != \"W\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(year) || isNaN(week)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (week <= 0 || week > 53) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn isValid;\n\t}\n\n\tget #min() {\n\t\treturn this.cell.getAttribute(\"min\");\n\t}\n\n\tget #max() {\n\t\treturn this.cell.getAttribute(\"max\");\n\t}\n\n\tget #step() {\n\t\treturn this.cell.getAttribute(\"step\");\n\t}\n}\n\nif (!customElements.get('cell-input-date')) {\n\tcustomElements.define(\"cell-input-date\", CellInputDate);\n}","import { EditableCellElement } from \"./core/CellElement.js\";\nimport {trace} from \"@nopeer\";\n\nclass CellCheckbox extends EditableCellElement {\n #target;\n #label;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n super.connectedCallback();\n\n this.#renderer();\n\n this.#target = this.querySelector(\"input\");\n this.#label = this.querySelector(\"span\");\n\n this.#initEvent();\n }\n\n get dataSource() {\n return [\n { value: this.trueValue, text: this.#trueText },\n { value: this.falseValue, text: this.#falseText }\n ];\n }\n\n #initEvent = () => {\n if (this.closest(\"thead\")) {\n this.#target.addEventListener(\"change\", (e) => {\n super.sheet.querySelector(`tbody.body [data-col=\"${super.cell.dataset.col}\"] cell-checkbox`)?.selectAll(e.target.checked);\n });\n }\n\n this.#target.addEventListener(\"change\", (event) => {\n if (!this.closest(\"tbody\")) return;\n\n if (this.#isRadio) {\n this.selectAll(false);\n this.value = this.trueValue;\n }\n else {\n this.value = event.target.checked ? this.trueValue : this.falseValue;\n }\n\n this.sheet.rowManager.refresh(true);\n });\n };\n\n #renderer = () => {\n\n const trueValue = this.trueValue;//this.cell.getAttribute(\"true-value\") || false;\n //const selectedBorderColor = this.getAttribute(\"selected-border-color\") || \"dimgray\";\n\n const originalContent = this.cell.getAttribute(\"content\") || \"\";\n const childHtml = this.#isRadio ? `<input type=\"radio\" value=\"${trueValue}\" />` : `<label><input type=\"checkbox\" /><span>${originalContent}</span></label>`;\n\n this.innerHTML = `\n ${childHtml}\n `;\n }\n\n refresh = () => {\n const val = super.refresh();\n\n this.#target.checked = (val === this.trueValue);\n\n if (this.isValid()) {\n this.#validate(val);\n }\n\n const displayText = (val === this.trueValue) ? this.#trueText : ((val === this.falseValue) ? this.#falseText : val);\n\n if (this.#label) {\n this.#label.textContent = displayText;\n }\n };\n\n #validate = (val) => {\n\n this.cell.classList.remove(\"invalid\");\n\n if (val !== \"\" && val !== null && val !== undefined) {\n if (val !== this.trueValue && val !== this.falseValue) {\n this.cell.classList.add(\"invalid\");\n }\n }\n };\n\n selectAll = (v) => {\n if (this.closest(\"thead\")) return; // 헤더 자신은 제외\n\n const data = this.host.data.getArray();\n const colIndex = this.host.fields.indexOf(this.cell.dataset.bind);\n\n if (colIndex < 0) return;\n\n for (let i = 0; i < data.length; i++) {\n if (this.#enable && super.getExprValue(this.#enable, data[i], i, this.cell) === false) continue;\n if (this.#readonly && super.getExprValue(this.#readonly, data[i], i, this.cell) === true) continue;\n if (this.#visible && super.getExprValue(this.#visible, data[i], i, this.cell) === false) continue;\n\n data[i].v[colIndex] = v ? this.trueValue : this.falseValue;\n }\n\n super.sheet.invalidate();\n };\n\n get trueValue() {\n return this.cell.getAttribute(\"true-value\") || \"Y\";\n }\n get falseValue() {\n return this.cell.getAttribute(\"false-value\")|| \"N\";\n }\n get #trueText() {\n return this.cell.getAttribute(\"true-text\") || \"\";\n }\n get #falseText() {\n return this.cell.getAttribute(\"false-text\") || \"\";\n }\n get #isRadio() {\n return this.cell.getAttribute(\"is-radio\") || false;\n }\n get #enable() {\n return this.cell.getAttribute(\"enable\") || false;\n }\n get #readonly() {\n return this.cell.getAttribute(\"readonly\") || false;\n }\n get #visible() {\n return this.cell.getAttribute(\"visible\") || false;\n }\n}\n\nif (!customElements.get('cell-checkbox')) {\n customElements.define(\"cell-checkbox\", CellCheckbox);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellRadio extends EditableCellElement {\n\t#target;\n\t#radioList;\n\t#dataSource = [];\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#rendererRadio();\n\n\t\tthis.#initEvent();\n\t}\n\n\t#initEvent = () => {\n\n\t\tthis.cell.addEventListener(\"keydown\", e => {\n\n\t\t\tif (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n\t\t\tif (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n\t\t\tif (e.code === \"Space\") {\n\t\t\t\te.preventDefault();\n\n\t\t\t\tlet matchIndex = -1;\n\n\t\t\t\tthis.#radioList.forEach(($el,index) => {\n\t\t\t\t\tif (this.value === $el.getAttribute(\"value\")) {\n\t\t\t\t\t\tmatchIndex = index;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tmatchIndex = (matchIndex === this.#radioList.length - 1) ? 0 : (matchIndex >= 0 ? matchIndex + 1 : 0);\n\t\t\t\tthis.value = this.#radioList[matchIndex].getAttribute(\"value\");\n\n\t\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t\t}\n\t\t});\n\t};\n\n\t#rendererRadio = () => {\ntrace.log(\"rendererRadio\");\n\t\t//if (!this.sheet || !this.cell) return;\n\n\t\tconst dataSource = this.cell.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, this.tr.data, this.tr.dataset.row);\n\n\t\tthis.#target.replaceChildren();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tconst codeVal = v[this.#keyName] !== undefined ? v[this.#keyName] : '';\n\t\t\t\tconst nameVal = v[this.#valueName] !== undefined ? v[this.#valueName] : '';\n\n\t\t\t\t// <label> 생성\n\t\t\t\tconst label = document.createElement('label');\n\n\t\t\t\t// <input type=\"radio\" value=\"...\"> 생성\n\t\t\t\tconst input = document.createElement('input');\n\t\t\t\tinput.type = 'radio';\n\t\t\t\tinput.value = codeVal;\n\n\t\t\t\t// <span>텍스트</span> 생성 (textContent를 써야 XSS 방어 및 안전합니다)\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tspan.textContent = nameVal;\n\n\t\t\t\t// 조립\n\t\t\t\tlabel.appendChild(input);\n\t\t\t\tlabel.appendChild(span);\n\t\t\t\tfragment.appendChild(label);\n\t\t\t});\n\n\t\t\tthis.#target.appendChild(fragment);\n\n\t\t\tthis.#radioList = Array.from(this.querySelectorAll(\"input\"));\n\n\t\t\tthis.#radioList.forEach($el => {\n\t\t\t\t$el.addEventListener(\"change\", (e) => {\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<div></div>\n `;\n\n\t\tthis.#target = this.querySelector(\"div\");\n\t};\n\n\trerenderer = () => {\n\t\tthis.#rendererRadio();\n\t\tthis.refresh();\n\t};\n\n\trefresh = () => {\n\n\t\tconst v = super.refresh();\n\n\t\tthis.#radioList.forEach($el => {\n\t\t\t$el.checked = (v === $el.value);\n\t\t});\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate();\n\t\t}\n\t};\n\n\t#validate = () => {\n\t\t//if (!super.cell) return;\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst idx = this.#dataSource.findIndex(m => this.value === m[this.#keyName]);\n\t\tif (idx < 0) {\n\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n\n\tget #keyName() {\n\t\treturn this.cell.getAttribute(\"key-name\") || \"k\";\n\t}\n\n\tget #valueName() {\n\t\treturn this.cell.getAttribute(\"value-name\") || \"v\";\n\t}\n}\n\nif (!customElements.get('cell-radio')) {\n\tcustomElements.define(\"cell-radio\", CellRadio);\n}","import { trace } from \"@nopeer\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#parent;\n\t#keyName;\n\t#valueName;\n\t#isOpen = false;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tthis.#initEvents();\n\t}\n\n\t#initData = (dataSource, keyName, valueName, multi, separator) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource || dataSource.length === 0) return;\n\n\t\tconst itemsAttr = this.#parent.getAttribute(\"items\");\n\t\tlet fieldKeys = [];\n\n\t\tif (itemsAttr) {\n\t\t\tfieldKeys = itemsAttr.split(\",\").map(s => s.trim());\n\t\t} else {\n\t\t\tfieldKeys = [valueName].filter(Boolean);\n\t\t}\n\n\t\tconst activeColumnCount = fieldKeys.length;\n\n\t\tgrd.shadowRoot.querySelector(\".ng-container-left\").style.display = multi ? '' : 'none';\n\n\t\tgrd.shadowRoot.querySelectorAll('table colgroup col, tbody td').forEach(($el, idx) => {\n\n\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\tif (col >= 2) {\n\t\t\t\t$el.style.display = (col - 2 >= activeColumnCount) ? 'none' : '';\n\t\t\t}\n\t\t});\n\n\t\tconst formattedData = dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: keyName && item[keyName] !== undefined ? item[keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\tfieldKeys.forEach((key, idx) => {\n\t\t\t\trow[`tmp${idx + 1}`] = item[key] !== undefined ? item[key] : (item[idx] !== undefined ? item[idx] : \"\");\n\t\t\t});\n\t\t\treturn row;\n\t\t});\n\n\t\tgrd.data.set(formattedData);\n\n\t\tif (multi && this.#parent.value) {\n\t\t\tconst selectedKeys = String(this.#parent.value).split(separator || \",\");\n\t\t\tgrd.data.getValidData().forEach(m => {\n\t\t\t\tif (selectedKeys.includes(String(m.v[1]))) {\n\t\t\t\t\tm.v[0] = \"Y\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tgrd.refreshData();\n\t\t}\n\t};\n\n\topen = (parent, dataSource, keyName, valueName, multi, separator) => {\n\t\tthis.#parent = parent;\n\t\tthis.#keyName = keyName;\n\t\tthis.#valueName = valueName;\n\t\tthis.#isOpen = true;\n\n\t\tthis.classList.add(\"active\");\n\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource) return;\n\n\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\tif (dataSource.length > 10) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tif (multi) {\n\t\t\tthis.classList.add(\"multi\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"multi\");\n\t\t}\n\n\t\tconst sheet = parent.closest(\"nine-table-sheet\");\n\t\tconst btnEl = parent.querySelector(\".btn1\");\n\t\tif (!btnEl || !sheet) return;\n\n\t\tconst btnRect = btnEl.getBoundingClientRect();\n\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\tlet left = btnRect.left - sheetRect.left;\n\t\tlet top = btnRect.bottom - sheetRect.top + 2;\n\n\t\tconst panelWidth = this.offsetWidth || 250;\n\t\tconst panelHeight = this.offsetHeight || 250;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 5);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\tif (top + panelHeight > sheetRect.height) {\n\t\t\tconst upwardTop = (btnRect.top - sheetRect.top) - panelHeight - 2;\n\t\t\tif (upwardTop >= 0) {\n\t\t\t\ttop = upwardTop;\n\t\t\t} else {\n\t\t\t\ttop = Math.max(0, sheetRect.height - panelHeight - 5);\n\t\t\t}\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\tsetTimeout(() => {\n\n\t\t\tthis.#initData(dataSource, keyName, valueName, multi, separator);\n\n\t\t\tconst viewContainer = grd.shadowRoot.querySelector(\".ng-container-body table tbody.body\");\n\n\t\t\tif (!viewContainer.__hasClickEvent) {\n\n\t\t\t\tviewContainer.addEventListener(\"mousedown\", (e) => {\n\n\t\t\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\t\t\tif (!tr) return;\n\n\t\t\t\t\tif (!multi) {\n\t\t\t\t\t\tthis.#onClickRow(e);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tviewContainer.__hasClickEvent = true;\n\t\t\t}\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#isOpen = false;\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus();\n\t\t}\n\t}\n\n\t#onClickRow = (e) => {\n\n\t\tconst sheet = e.target.closest(\"nine-table-sheet\");\n\t\tconst tr = e.target.closest(\"tr\");\n\n\t\tconst rowIndex = parseInt(tr.dataset.row, 10);\n\t\tconst record = sheet.view.get(rowIndex);\n\n\t\tthis.#parent.value = record.k;\n\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onOk = () => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst data = grd.data.getValidData();\n\n\t\tconst selectedKeys = [];\n\t\tdata.forEach(o => {\n\t\t\tif (o.v[0] === \"Y\") {\n\t\t\t\tselectedKeys.push(o.v[1]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = selectedKeys.join(this.#parent.getAttribute(\"multi-separator\") || \",\");\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onSelectAll = (e) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst isChecked = e.target.checked ? \"Y\" : \"N\";\n\t\tgrd.data.getValidData().forEach(m => { m.v[0] = isChecked; });\n\t\tgrd.refreshData();\n\t}\n\n\t#onInput = (e) => {\n\t\tconst keyword = e.target.value.toLowerCase();\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\n\t\tgrd.data.getValidDataNF().forEach(m => {\n\t\t\tconst match = Object.values(m.v).some(val =>\n\t\t\t\tval !== null && val !== undefined && String(val).toLowerCase().includes(keyword)\n\t\t\t);\n\t\t\tm.__ng.filtered = !match;\n\t\t});\n\n\t\tgrd.data.resetRecords();\n\t\tgrd.dataManager.viewRecords.reset();\n\t}\n\n\tget isOpen() {\n\t\treturn this.#isOpen;\n\t}\n\n\tget targetCell() {\n\t\treturn this.#parent;\n\t}\n\n\t#initEvents = () => {\n\t\tthis.querySelector(\".search-input\").addEventListener(\"input\", this.#onInput);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\t\t\tconst path = e.composedPath ? e.composedPath() : [];\n\n\t\t\tif (path.includes(this)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.close();\n\t\t});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <div class=\"head\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\n </div>\n \n <nine-table-simple class=\"combo-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"30\" fixed=\"left\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"0\" />\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"tmp1\" />\n <td data-bind=\"tmp2\" />\n <td data-bind=\"tmp3\" />\n <td data-bind=\"tmp4\" />\n <td data-bind=\"tmp5\" />\n <td data-bind=\"tmp6\" />\n <td data-bind=\"tmp7\" />\n <td data-bind=\"tmp8\" />\n <td data-bind=\"tmp9\" />\n <td data-bind=\"tmp10\" />\n <td data-bind=\"k\" />\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n \n <div class=\"footer\">\n <div>\n <input id=\"chkAll\" type=\"checkbox\" checked>\n <label for=\"chkAll\">Select All</label>\n </div>\n <button id=\"btnOk\">OK</button>\n </div>\n `;\n\t};\n}\n\nif (!customElements.get('cell-combo-panel')) {\n\tcustomElements.define(\"cell-combo-panel\", CellComboPanel);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport \"./cell-combo-panel.js\";\n\nexport class CellCombo extends EditableCellElement {\n\t#targetBtn;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\t#multi;\n\t#multiSeparator;\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tthis.#keyName = super.cell.getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = super.cell.getAttribute(\"value-name\") || \"v\";\n\t\tthis.#multi = super.cell.getAttribute('multi') === \"true\";\n\t\tthis.#multiSeparator = super.cell.getAttribute(\"multi-separator\") || \",\";\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\trerenderer = () => {\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\t#initData = () => {\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t}\n\n\t#initEvent = () => {\n\t\tthis.querySelectorAll(\"button\").forEach(btn => {\n\t\t\tbtn.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\t}\n\n\t#togglePanel = () => {\n\n\t\tif (!this.#panel) {\n\t\t\tthis.#panel = super.sheet.querySelector(\"cell-combo-panel\");\n\t\t\tif (!this.#panel) {\n\t\t\t\tthis.#panel = document.createElement(\"cell-combo-panel\");\n\t\t\t\tsuper.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\tif (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\t\tthis.#panel.close();\n\t\t} else {\n\t\t\tthis.#panel.open(this, this.#dataSource, this.#keyName, this.#valueName, this.#multi, this.#multiSeparator);\n\t\t}\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <button class=\"btn1\" type=\"button\" tabindex=\"-1\">Select</button>\n <button class=\"btn2\" type=\"button\" tabindex=\"-1\"></button>\n `;\n\n\t\tthis.#targetBtn = this.querySelector(\".btn1\");\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tif (!this.#targetBtn) return v;\n\n\t\tthis.#targetBtn.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#getDisplayText = () => {\n\t\tif (!this.value || !Array.isArray(this.#dataSource)) return \"\";\n\n\t\tif (this.#multi) {\n\t\t\tconst keys = String(this.value).split(this.#multiSeparator);\n\t\t\treturn this.#dataSource\n\t\t\t\t.filter(m => keys.includes(String(m[this.#keyName])))\n\t\t\t\t.map(m => m[this.#valueName])\n\t\t\t\t.join(this.#multiSeparator);\n\t\t} else {\n\t\t\tconst found = this.#dataSource.find(m => String(m[this.#keyName]) === String(this.value));\n\t\t\treturn found ? found[this.#valueName] : this.value;\n\t\t}\n\t}\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst list = this.#multi ? String(this.value).split(this.#multiSeparator) : [this.value];\n\t\tfor (const v of list) {\n\t\t\tconst idx = this.#dataSource.findIndex(m => String(v) === String(m[this.#keyName]));\n\t\t\tif (idx < 0) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-combo')) {\n\tcustomElements.define(\"cell-combo\", CellCombo);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRenderer extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"span\");\n\t}\n\n\trefresh = () => {\n\n\t\tsuper.refresh();\n\n\t\tif (this.cell.getAttribute(\"html\") === \"true\") {\n\t\t\tthis.#target.innerHTML = this.getDisplayText();\n\t\t} else {\n\t\t\tthis.#target.textContent = this.getDisplayText();\n\t\t}\n\t};\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <span class=\"wrapper\"></span>\n `;\n\t};\n}\n\nif (!customElements.get(\"cell-renderer\")) {\n\tcustomElements.define(\"cell-renderer\", CellRenderer);\n}","import { CellElement } from \"./core/CellElement.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { trace } from \"@nopeer\";\n\nexport class CellButton extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"button\");\n\n\t\tthis.#target.removeEventListener(\"click\", this.#cellButtonClick);\n\t\tthis.#target.addEventListener(\"click\", this.#cellButtonClick);\n\t}\n\n\t#cellButtonClick = e => {\n\t\te.stopPropagation();\n\n\t\tconst rowid = parseInt(this.cell.dataset.row, 10);\n\n\t\tconst customEvent = new CustomEvent(NINE_TABLE.EVENT.CELL_BUTTON_CLICK, {\n\t\t\tbubbles: true,\n\t\t\tcomposed: true,\n\t\t\tdetail: {\n\t\t\t\toriginalEvent: e,\n\t\t\t\tcell: this.cell,\n\t\t\t\trow: rowid,\n\t\t\t\tcol: parseInt(this.cell.dataset.col, 10),\n\t\t\t\tbind: this.dataset.bind,\n\t\t\t\tdata: this.host.data.get(rowid),\n\t\t\t\tvalue: this.value,\n\t\t\t}\n\t\t});\n\n\t\tthis.dispatchEvent(customEvent);\n\t};\n\n\trefresh = () => {\n\t\tconst rawValue = super.refresh ? super.refresh() : this.value;\n\t\t//let displayValue = this.getDisplayText(rawValue);\n\t\tthis.#target.innerHTML = this.getDisplayText(rawValue);\n\t};\n\n\t#renderer = () => {\n\n\t\tconst buttonText = \"...\";//this.getAttribute(\"text\") || super.attr[\"text\"] || \"\";\n\n\t\tthis.innerHTML = `\n <button class=\"button\">${buttonText}</button>\n `;\n\t};\n}\n\nif (!customElements.get('cell-button')) {\n\tcustomElements.define(\"cell-button\", CellButton);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRowIndicator extends CellElement {\n\t#mainTarget;\n\t#subTarget;\n\t#statusTarget;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tif (this.cell) {\n\t\t\tthis.cell.removeAttribute(\"tabindex\");\n\t\t\tthis.cell.dataset.bind = \"rowState\";\n\n\t\t\tif (!this.cell.dataset.expr) {\n\t\t\t\t//this.cell.dataset.expr = \"data.__ng._[ninegrid.ROW.ORDER]\";\n\t\t\t}\n\n\t\t\tthis.cell.setAttribute(\"text-align\", \"right\");\n\t\t}\n\n\t\tthis.#mainTarget = this.querySelector(\".ng-row-main\");\n\t\tthis.#subTarget = this.querySelector(\".ng-row-sub\");\n\t\tthis.#statusTarget = this.querySelector(\".ng-row-status\");\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n\t\t\t<span class=\"ng-row-main\"></span>\n <span class=\"ng-row-sub\"></span>\n <span class=\"ng-row-status\"></span>\n `;\n\t}\n\n\t/**\n\t * 행 번호 및 상태 갱신\n\t */\n\trefresh = () => {\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tconst row = this.row;\n\t\tif (isNaN(row)) return;\n\n\t\tconst rawRecord = this.tr.data;\n\n\t\tif (rawRecord && rawRecord.__ng) {\n\t\t\tconst rowState = rawRecord.__ng.rowState;\n\n\t\t\t/**\n\t\t\t// 1. 행 상태에 따른 클래스 제어 및 우측 상단 상태 표시\n\t\t\tif (rowState === ninegrid.ROW_STATE.INSERT) {\n\t\t\t\tthis.classList.add('added');\n\t\t\t\tthis.classList.remove('updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"➕\";\n\t\t\t} else if (rowState === ninegrid.ROW_STATE.UPDATE) {\n\t\t\t\tthis.classList.add('updated');\n\t\t\t\tthis.classList.remove('added');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"✏️\";\n\t\t\t} else {\n\t\t\t\tthis.classList.remove('added', 'updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"\";\n\t\t\t} */\n\n\t\t\t/**\n\t\t\t// 2. 필터링 등으로 순번이 밀렸을 때 우측 하단에 원본 번호 표시\n\t\t\tif (rawRecord.__ng.i !== undefined) {\n\t\t\t\tconst currentSeq = row + 1;\n\t\t\t\tconst originalSeq = rawRecord.__ng.i + 1;\n\n\t\t\t\tif (this.#subTarget) {\n\t\t\t\t\tif (currentSeq !== originalSeq) {\n\t\t\t\t\t\tthis.#subTarget.textContent = originalSeq;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#subTarget.textContent = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} */\n\t\t}\n\n\t\tconst displayNum = this.index + 1;\n\n\t\t// 천단위 콤마 포맷팅 (예: 1234567 -> \"1,234,567\")\n\t\tconst formattedNum = displayNum.toLocaleString();\n\n\t\t// 3자리 이상일 경우 마지막 3자리(와 콤마 포함된 덩어리)를 기준으로 앞자리와 분리\n\t\tif (displayNum >= 10000) {\n\t\t\t// 뒤에서 4글자(콤마 + 3자리)를 기준으로 분리합니다. (예: \"1,234\" 와 \"567\")\n\t\t\tconst splitIndex = formattedNum.length - 4;\n\t\t\tconst prefixPart = formattedNum.substring(0, splitIndex + 1); // 천단위 이상 (작은 폰트)\n\t\t\tconst suffixPart = formattedNum.substring(splitIndex + 1); // 마지막 콤마 + 3자리 (기본 폰트)\n\n\t\t\tthis.#mainTarget.innerHTML = `\n <span class=\"ng-row-prefix\">${prefixPart}</span>\n <span class=\"ng-row-suffix\">${suffixPart}</span>\n `;\n\t\t} else {\n\t\t\t// 1000 미만인 경우 콤마만 있거나 일반 숫자로 그대로 표시\n\t\t\tthis.#mainTarget.innerHTML = `${formattedNum}`;\n\t\t}\n\n\t\tconst isSorted = this.sheet.querySelector(\"thead .asc,thead .desc\") ? true : false;\n\t\tconst isFitered = this.sheet.querySelector(\"thead nine-table-filter-button.filtered\") ? true : false;\n\n\t\tthis.#subTarget.innerHTML = row;\n\t\tthis.#subTarget.style.display = (isSorted || isFitered) ? \"\" : \"none\";\n\t};\n}\n\nif (!customElements.get('cell-row-indicator')) {\n\tcustomElements.define(\"cell-row-indicator\", CellRowIndicator);\n}","// ui/col/col-expand.js\nimport { TableCompiler, COLLAPSED_WIDTH } from \"@/layout/core/TableCompiler.js\";\n\nexport class ColExpand extends HTMLElement {\n #sheet;\n #cell;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#cell = this.closest('th, td');\n this.#sheet = this.closest('nine-table-sheet');\n\n if (this.#cell) {\n this.#cell.style.position = 'relative';\n }\n\n const isCollapsed =\n this.getAttribute('collapsed') === 'true' ||\n this.#cell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n requestAnimationFrame(() => {\n this.collapse(true);\n });\n } else {\n this.classList.remove('collapsed');\n this.classList.add('expand');\n }\n\n this.removeEventListener('click', this.#onClick);\n this.addEventListener('click', this.#onClick);\n }\n\n #onClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (this.classList.contains('expand')) {\n this.collapse();\n } else {\n this.expand();\n }\n };\n\n /**\n * 🎯 원래 너비(dataset.expandWidth)로 복구\n */\n expand = () => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n this.classList.remove('collapsed');\n this.classList.add('expand');\n this.#cell.setAttribute('collapsed', 'false');\n this.#cell.style.color = '';\n\n const targetWidth = parseInt(this.#cell.dataset.expandWidth, 10) || 100;\n\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, targetWidth);\n } else {\n const singleWidth = Math.max(30, Math.floor(targetWidth / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, singleWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n collapse = (isInitialInit = false) => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n if (this.classList.contains('expand')) {\n const col = this.#sheet.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n const currentW = col ? parseInt(col.getAttribute('width'), 10) : 0;\n if (currentW > COLLAPSED_WIDTH) {\n this.#cell.dataset.expandWidth = String(currentW * colSpan);\n }\n }\n\n this.classList.remove('expand');\n this.classList.add('collapsed');\n this.#cell.setAttribute('collapsed', 'true');\n this.#cell.style.color = 'transparent';\n\n // 🎯 colSpan이 1이면 16px(COLLAPSED_WIDTH)을 그대로 적용, 2 이상이면 균등 분할\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, COLLAPSED_WIDTH);\n } else {\n const splitWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, splitWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n disconnectedCallback() {\n this.removeEventListener('click', this.#onClick);\n }\n}\n\nif (!customElements.get('nine-table-col-expand')) {\n customElements.define('nine-table-col-expand', ColExpand);\n}","// ui/menu/nine-table-menu.js (수정본)\n\nimport { trace } from \"@nopeer\";\nimport { ColFixManager } from \"@/col/ColFixManager.js\";\n\nexport class ContextMenu extends HTMLElement {\n #tableHost;\n #panel;\n\n connectedCallback() {\n const root = this.getRootNode();\n this.#tableHost = root instanceof ShadowRoot ? root.host : (this.closest('nine-table') || root.host);\n\n if (!this.#tableHost) {\n this.#tableHost = this.parentElement?.closest('nine-table') || this.assignedSlot?.closest('nine-table');\n }\n\n if (!this.#tableHost) return;\n\n //this.#tableHost.addEventListener('contextmenu', this.#onContextMenu);\n }\n\n #onContextMenu = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n const targetCell = path.find(el => el.tagName === 'TH' || el.tagName === 'TD');\n\n if (!targetCell) return;\n\n const targetTable = path.find(el => el.tagName === 'TABLE') || targetCell.closest('table');\n\n e.preventDefault();\n e.stopPropagation();\n\n this.openMenu(e.clientX, e.clientY, targetCell, targetTable);\n };\n\n /**\n * 🎯 우클릭이 발생한 대상 시트(NineTableSheet) 구하기\n */\n #getTargetSheet(targetCell) {\n return targetCell?.closest('nine-table-sheet') || this.#tableHost.activeSheet || this.#tableHost;\n }\n\n #getFixManager(targetCell) {\n const sheet = this.#getTargetSheet(targetCell);\n if (!sheet) return null;\n\n if (!sheet.colFix) {\n sheet.colFix = new ColFixManager(sheet);\n }\n return sheet.colFix;\n }\n\n #parseCustomMenuItems(containerElement, activeTable) {\n const items = [];\n const activeTableId = activeTable?.id;\n const allUls = Array.from(containerElement.querySelectorAll(':scope > ul'));\n\n allUls.forEach(rootUl => {\n const targetTableAttr = rootUl.getAttribute('target-table');\n\n if (!targetTableAttr || (activeTableId && targetTableAttr === activeTableId)) {\n const parsedList = this.#traverseUl(rootUl);\n items.push(...parsedList);\n }\n });\n\n return items;\n }\n\n #traverseUl(ulEl) {\n const list = [];\n Array.from(ulEl.children).forEach(child => {\n const tagName = child.tagName.toLowerCase();\n\n if (tagName === 'hr' || child.classList.contains('separator')) {\n list.push({ type: 'separator' });\n return;\n }\n\n if (tagName === 'li') {\n let name = '';\n const spanEl = child.querySelector(':scope > span');\n if (spanEl) {\n name = spanEl.textContent.trim();\n } else {\n name = Array.from(child.childNodes)\n .filter(n => n.nodeType === Node.TEXT_NODE)\n .map(n => n.textContent.trim())\n .join('');\n }\n\n const subUl = child.querySelector(':scope > ul');\n const item = {\n menuId: child.id || name,\n name: name,\n className: child.className || '',\n disabled: child.hasAttribute('disabled') || child.getAttribute('disabled') === 'true',\n isCustom: true\n };\n\n if (subUl) {\n item.items = this.#traverseUl(subUl);\n }\n\n list.push(item);\n }\n });\n return list;\n }\n\n #buildMenuItems(activeTable, isHeaderCell, targetCell) {\n const useDefault = this.getAttribute('use-default-menu') !== 'false';\n let rawItems = [];\n\n const customItems = this.#parseCustomMenuItems(this, activeTable);\n if (customItems.length > 0) {\n rawItems.push(...customItems);\n }\n\n const fixManager = this.#getFixManager(targetCell);\n const currentFixState = fixManager?.getFixState(targetCell, activeTable) ?? 'none';\n const isFixable = isHeaderCell && (fixManager?.canFixColumn(targetCell, activeTable) ?? false);\n\n let fixMenuItem = null;\n if (currentFixState === 'left' || currentFixState === 'right') {\n fixMenuItem = {\n menuId: 'unfix-column',\n name: 'Unfix Column',\n className: 'ng-menu-unfix-col',\n disabled: !isHeaderCell\n };\n } else {\n fixMenuItem = {\n menuId: 'fix-column',\n name: 'Fix Column',\n className: 'ng-menu-fix-col',\n disabled: !isFixable\n };\n }\n\n if (useDefault) {\n rawItems.push(\n { type: 'separator' },\n {\n menuId: 'sort',\n name: 'Sort',\n className: 'ng-menu-sort',\n disabled: !isHeaderCell\n },\n fixMenuItem,\n { type: 'separator' },\n { menuId: 'filtering', name: 'Filtering', className: 'ng-menu-filtering' },\n { menuId: 'maximize', name: 'Maximize', className: 'maximize' },\n {\n menuId: 'export',\n name: 'Export',\n className: 'export',\n items: [\n { menuId: 'export-excel', name: 'Excel', className: 'export-excel' },\n { menuId: 'export-pdf', name: 'PDF', className: 'export-pdf', disabled: true }\n ]\n },\n {\n menuId: 'properties',\n name: 'Options',\n className: 'options',\n items: [\n { menuId: 'show-title-bar', name: 'Title Bar Show/Hide', className: 'show-title-bar' },\n { menuId: 'show-status-bar', name: 'Status Bar Show/Hide', className: 'show-status-bar' },\n { menuId: 'auto-fit-col', name: 'Auto Fit Columns', className: 'auto-fit-col' }\n ]\n }\n );\n }\n\n const cleanedItems = [];\n rawItems.forEach((item) => {\n if (item.type === 'separator') {\n if (cleanedItems.length === 0 || cleanedItems[cleanedItems.length - 1].type === 'separator') {\n return;\n }\n }\n cleanedItems.push(item);\n });\n\n if (cleanedItems.length > 0 && cleanedItems[cleanedItems.length - 1].type === 'separator') {\n cleanedItems.pop();\n }\n\n return cleanedItems;\n }\n\n openMenu(x, y, targetCell, targetTable) {\n const targetParent = this.#tableHost.shadowRoot || this.#tableHost;\n\n if (!this.#panel) {\n this.#panel = document.createElement('nine-table-menu-panel');\n targetParent.appendChild(this.#panel);\n }\n\n const isHeaderCell = !!targetCell.closest('thead');\n const menuItems = this.#buildMenuItems(targetTable, isHeaderCell, targetCell);\n\n this.#panel.render(menuItems, (e) => this.#handleMenuClick(e, targetCell, targetTable));\n\n const targetSheet = this.#getTargetSheet(targetCell);\n this.#syncMenuStates(targetSheet);\n\n // 🎯 targetCell을 3번째 인자로 전달하여 셀 우측선 정렬\n this.#panel.openAt(x, y);\n }\n\n /**\n * 🎯 메뉴 항목 활성화 체크 표시(✓) 동기화\n */\n #syncMenuStates(targetSheet) {\n if (!this.#panel || !targetSheet) return;\n\n // 🎯 클릭된 개별 시트의 filtering 상태 검사\n const isFiltering = targetSheet.filtering?.isFiltering?.() || false;\n this.#panel.toggleItemState('filtering', 'on', isFiltering);\n\n const autoFit = this.#tableHost.getAttribute('auto-fit-col') === 'true';\n this.#panel.toggleItemState('auto-fit-col', 'on', autoFit);\n\n const showTitle = this.#tableHost.getAttribute('show-title-bar') === 'true';\n this.#panel.toggleItemState('show-title-bar', 'on', showTitle);\n }\n\n #handleMenuClick(e, targetCell, targetTable) {\n const menuId = e.menuId;\n\n const customEvent = new CustomEvent('menu-click', {\n detail: { menuId, targetCell, targetTable, originalEvent: e },\n bubbles: true,\n composed: true\n });\n this.dispatchEvent(customEvent);\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n\n // 🎯 클릭된 셀의 소속 시트 인스턴스 타겟팅\n const targetSheet = this.#getTargetSheet(targetCell);\n\n switch (menuId) {\n case 'fix-column':\n case 'unfix-column':\n const fixManager = this.#getFixManager(targetCell);\n fixManager?.executeFixToggle(menuId, targetCell);\n break;\n\n case 'sort':\n if (!isNaN(baseCol)) {\n targetSheet.sorting?.handleSortFromMenu?.(baseCol, targetCell);\n }\n break;\n\n case 'filtering':\n targetSheet?.filtering?.toggle();\n break;\n\n case 'auto-fit-col':\n this.#tableHost.setAttribute('auto-fit-col', this.#tableHost.getAttribute('auto-fit-col') === 'true' ? 'false' : 'true');\n break;\n\n case 'show-title-bar':\n this.#tableHost.setAttribute('show-title-bar', this.#tableHost.getAttribute('show-title-bar') === 'true' ? 'false' : 'true');\n break;\n }\n\n this.#panel.close();\n }\n\n disconnectedCallback() {\n this.#tableHost?.removeEventListener('contextmenu', this.#onContextMenu);\n }\n}\n\nif (!customElements.get('nine-table-menu')) {\n customElements.define('nine-table-menu', ContextMenu);\n}","// ui/menu/nine-table-menu-panel.js\n\nexport class MenuPanel extends HTMLElement {\n #onCallback;\n #closeHandler = null; // 🎯 이벤트 누수 방지용 리스너 참조\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n // 🎯 [보정 1] 패널 자체의 기본 레이아웃 스타일은 element style로 직접 지정\n this.style.position = 'fixed';\n this.style.display = 'none';\n this.style.zIndex = '99999';\n\n this.innerHTML = `\n <div class=\"menu-wrapper\">\n <ul class=\"menu-container\"></ul>\n </div>\n `;\n }\n\n render(items, callback) {\n this.#onCallback = callback;\n const container = this.querySelector('.menu-container');\n if (!container) return;\n\n container.innerHTML = '';\n\n this.#appendItems(container, items);\n this.#bindClickEvents();\n }\n\n /**\n * 🎯 패널의 우측선과 targetCell의 우측선을 일치시키는 포지셔닝\n */\n openAt(x, y, targetCell = null) {\n this.style.display = 'block';\n\n if (targetCell) {\n const cellRect = targetCell.getBoundingClientRect();\n // 셀의 오른쪽 경계선 좌표\n const cellRightX = cellRect.right;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const panelWidth = wrapper.getBoundingClientRect().width;\n\n // 패널 우측선을 셀 우측선에 맞춤 (Left = cellRight - panelWidth)\n let calculatedLeft = cellRightX - panelWidth;\n\n // 뷰포트 왼쪽 밖으로 벗어나는 예외 처리\n if (calculatedLeft < 0) {\n calculatedLeft = cellRect.left; // 공간이 부족하면 셀 좌측선에 맞춤\n }\n\n // 뷰포트 아래쪽 벗어남 처리\n const panelHeight = wrapper.getBoundingClientRect().height;\n let calculatedTop = y;\n if (y + panelHeight > window.innerHeight) {\n calculatedTop = y - panelHeight;\n }\n\n this.style.left = `${calculatedLeft}px`;\n this.style.top = `${calculatedTop}px`;\n });\n } else {\n // 기본 마우스 클릭 좌표 기반 (Fallback)\n this.style.left = `${x}px`;\n this.style.top = `${y}px`;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n\n if (x + rect.width > window.innerWidth) {\n this.style.left = `${x - rect.width}px`;\n }\n if (y + rect.height > window.innerHeight) {\n this.style.top = `${y - rect.height}px`;\n }\n });\n }\n\n // 바깥 클릭 핸들러 등록\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n }\n\n this.#closeHandler = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n if (!path.includes(this) && !this.contains(e.target)) {\n this.close();\n }\n };\n\n setTimeout(() => {\n window.addEventListener('pointerdown', this.#closeHandler);\n }, 0);\n }\n\n close() {\n this.style.display = 'none';\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n this.#closeHandler = null;\n }\n }\n\n toggleItemState(menuId, className, condition) {\n const li = this.querySelector(`li[menu-id=\"${menuId}\"]`);\n if (li) {\n condition ? li.classList.add(className) : li.classList.remove(className);\n }\n }\n\n #appendItems(parentUl, items) {\n items.forEach(item => {\n if (item.type === 'separator') {\n const sep = document.createElement('li');\n sep.className = 'ng-menu-separator';\n parentUl.appendChild(sep);\n return;\n }\n\n const li = document.createElement('li');\n li.setAttribute('menu-id', item.menuId);\n li.className = `${item.className || ''} ${item.items ? 'submenu' : ''} ${item.disabled ? 'disabled' : ''}`.trim();\n\n const span = document.createElement('span');\n span.textContent = item.name;\n li.appendChild(span);\n\n if (item.items && item.items.length > 0) {\n const subUl = document.createElement('ul');\n subUl.className = 'ng-menu-sublist';\n this.#appendItems(subUl, item.items);\n li.appendChild(subUl);\n }\n\n parentUl.appendChild(li);\n });\n }\n\n #bindClickEvents() {\n this.querySelectorAll('li[menu-id]').forEach(li => {\n li.addEventListener('click', (e) => {\n e.stopPropagation();\n if (li.classList.contains('disabled')) return;\n\n const menuId = li.getAttribute('menu-id');\n this.#onCallback?.({ menuId, target: li });\n this.close();\n });\n });\n }\n\n disconnectedCallback() {\n this.close();\n }\n}\n\nif (!customElements.get('nine-table-menu-panel')) {\n customElements.define('nine-table-menu-panel', MenuPanel);\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nine-table.js","names":["traceOrigin","trace","GROUP_IDX","GROUP_IDX","start","end","mid","target","elementDebounceState","el","state","pointerEvent","pointerFn","debounceTime","dblClickEvent","dblClickFn","_text","stripHtml","tmp","html","canvas","context","_font","w","h","v","cleanText","metrics","ascent","descent","trace$1","trace","NINE_TABLE","ngRow","#parent","parent","#newrow","ngData","#host","host","#initialize","o","validRecords","#getValidRecords","at","targetRecord","colnm","idx","rowData","rowIndex","colIndex","value","#conv","fields","#defaultHeight","templateElements","#getDefaultMeta","loadData","dataSource","#invalidate","#nextId","rowid","jsonArray","arr","json","#json2Array","#defaultInsert","row","updateState","b","a","rowidx","targetId","item","COL_IDX","oldValue","isSingle","targetArr","result","i","ngDataManager","ds","rowIdx","nRow","#init","#fields","f","found","fieldName","fName","#adjust","map","name","type","rawTables","tbl","fieldType","attr","expr","lastIndex","targetField","NineTableSheets","NineTableSheetsFooter","#render","isMultiSelect","tabItem","index","#switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","isActive","clickedTab","activeTabs","targetSheet","tabsHtml","table","SheetTabItem","Toolbar","#bindEvents","#customContainer","#syncStateFromHost","isSimple","showToolbar","showMenu","caption","titleEl","link","currentCaption","menuBtn","element","text","NineTableHScrollBar","#owner","initWhenReady","#elements","#observeResize","#resizeObserver","#dragging","track","thumb","bodyWidth","tableWidth","needsHScroll","trackWidth","thumbWidth","currentLeft","maxScrollLeft","l","maxThumbLeft","trackBound","targetX","x","delayScroll","#interval1","#interval2","thumbLeft","#thumbMoveTo","pos","currentThumbLeft","clearTimer","evt","e","trackRect","onMouseMove","moveEvent","onMouseUp","NineTableVScrollBar","#sheet","viewRecords","totalCount","scrollHolder","rawContentHeight","MAX_BROWSER_HEIGHT","useScaling","scaleFactor","contentHeight","#getScaleInfo","fixedHeight","bodyHeight","viewHeight","needsVScroll","trackHeight","thumbHeight","currentScrollTop","maxScrollTop","thumbTop","maxThumbTop","#startY","#startThumbTop","deltaY","targetThumbTop","ratio","rowHeight","visibleRowCount","targetRow","clickY","scrollInterval","startContinuousScroll","scrollStep","$firstTr","direction","currentRow","stopContinuousScroll","GROUP_IDX$1","GroupingManager","#groupColumns","#groupMap","groupColumns","sourceTable","$cell","$tr","#isApplying","groupId","rowIds","dataManager","Grouping","validRaw","rawRecords","groupMap","nestedTree","#buildNestedMap","flatResult","renderItems","#flattenTree","counter","isLastLevel","depth","groupKey","subMapOrRecords","mapOrArray","parentId","#collectLeafRowIds","groupRecord","resultArr","#collectLeafRecords","record","remainingCols","records","key","subRecords","subVal","r","RowManager","#initResizeObserver","#templateRowHeights","sum","bodyViewport","#cachedTemplateHeight","#measureAndCacheHeight","#renderAllContainers","#handleScroll","force","#isGrouped","#handleGroupedScroll","scrollTop","templateLength","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","renderOffsetTop","firstTr","#element","currentStartIndex","$tbody","dataIndex","#bindRowData","allRenderItems","totalVirtualCount","bodyContent","getItemHeight","dataRowsHeight","groupHeightsTotal","itemHeights","viewportClientHeight","accumulatedHeight","offsetY","visibleRowsCount","dynamicBuffer","targetStart","targetEnd","renderedItems","container","selector","trs","itemIndex","chunkTrs","virtualIndex","isTrGroup","tr","subIdx","#bindGroupRowData","subRowIndex","matrixRow","indices","allRecords","childrenRecords","customComp","$el","#containerTemplates","tableEl","tbody","templateTrs","#sheetHeight","#isProgrammaticScroll","dataRow","targetScrollTop","rawTargetScrollTop","onRendered","trTemplates","fragment","renderedTrs","#updateRowCount","visibleRows","#BUFFER_ROW_COUNT","groupDepth","#cachedRowCount","#renderRows","#syncRowHeights","targetFixedType","clonedTr","targetTbody","tmpl","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","entry","entries","height","TableCompiler","$table","$srcTable","#syncColAttributes","fixed","$col","cols","grid","rowSpan","colSpan","c","CellSelection","#initEvents","sameGroupTrs","t","$td","col","r1","startRow","endRow","r2","c1","startCol","endCol","c2","containers","expanded","loopCount","#getMatrixRow","cell","cellEndRow","cellEndCol","nsR","neR","nsC","neC","#range","mainZone","lastMatrixRow","lastCol","targetCell","allCells","rect","targetTr","CellNavigation","#currentCell","#currentTr","#isCellLeftVisible","#isCellRightVisible","isVisible","#isCellBelowVisible","#isCellAboveVisible","scrollTopIndex","#getVisibleRowCount","currentCell","#findCell","nextCell","#getPreviousCell","#getNextCell","#getUpCell","#getDownCell","#moveCellH","#moveCellV","nextCol","cellCol","cellRect","viewportRect","theadHeight","bodyViewport2","viewportHeight","RESIZE_OFFSET","ColResizer","#panel","#tooltip","#onPointerMove","#onPointerDown","#onDblClick","containerType","firstColgroup","totalWidth","colWidths","colIdx","tables","targetCols","globalColIndex","firstContainer","resolvedContainerType","width","sourceCol","headerPart","offsetX","isLeftEdge","isRightEdge","prevCell","#targetCell","#targetContainerType","#getContainerType","baseColIndex","#targetColIndex","#checkIsAutoFit","#nextColIndex","nextColEl","#nextColStartWidth","targetRect","sheetRect","#startCellWidth","#startLeft","attrW","#startColWidth","#startX","#updatePositions","#onDragMove","#onDragEnd","diff","clientX","isAutoFit","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","finalWidth","newColWidth","newNextWidth","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","val","size","calculatedWidth","ColResizerPanel","#renderer","ColMover","#grip","#indi","root","y","nested","headerCells","hasStrictChildren","isValidGroup","parentGroupRange","subCell","subStart","subSpan","subEnd","isRealGroup","groupRange","#getColGroupRange","origTable","minLeft","maxRight","minTop","maxBottom","targetCells","cCol","cEnd","isGroup","computedStyle","groupWidth","groupHeight","headerContent","clonedCell","style","#checkIsMovable","startX","startY","cancelTimer","#timer","onPointerMovePending","#startDrag","#isDragging","preview","#createGroupHeaderPreview","#sourceCell","#sourceColIndex","#shiftX","bounds","relativeTop","fullHeight","#updateGripPosition","#onPointerUp","#getDeepElementFromPoint","targetColIndex","colMinLeft","colMaxRight","cRect","midX","calculatedTargetCol","indicatorLeft","sourceGroup","movingSpan","sourceRowStart","sourceRowEnd","targetRowStart","targetRowEnd","isRowSpanCompatible","isOutOfBoundsOfParent","pStart","pEnd","isDroppingInsideOtherGroup","spannedCells","sCell","sRowStart","sRowEnd","sStart","sEnd","moveEndCol","isSelfGroup","left","colgroup","targetCol","toColIndex","spanCount","isInRange","fromColIndex","targetViewportCol","fixedType","group","cells","targetRowCell","ColFixManager","baseCol","fixedAttr","targetBoundaryCol","theadTrs","cellBoundaryFound","cEndCol","action","fixType","cIdx","minBaseCol","maxEndCol","rSpan","rIdx","isBroken","isColFixed","NineTableFilterPanel","#closeHandler","#nineTable","#view","#onInput","#onSelectAll","#onOk","#button","filterBtn","panelWidth","top","searchBox","#loadVirtualFilterItems","path","filteredRecords","activeFilters","exprEngine","bindKey","colInfo","exprKey","filterKey","activeSelectedVals","uniqueMap","rawVal","displayVal","uniqueList","valA","valB","numA","numB","selectAllChk","filterRecords","checkedRecords","chk","filterParams","selectedVals","query","data2Idx","matchedValues","isChecked","chkIdx","NineTableFilterButton","#onClick","#columns","seen","uniqueKey","isFiltered","panel","Filtering","#filters","#initFilterPanel","#filterPanel","#isFiltering","#applyFiltering","jsonFilter","oFilter","k","sheetIndex","filterRules","targetKey","allowedValues","isExpr","isPass","recordIdx","allowedSet","Sorting","#handleSort","colName","exprVal","isAsc","isDesc","existingColIndex","m","ruleData","#applySorting","#syncHeaderUI","colRule","asc","SheetView","#cachedVisibleRecords","#viewIndexes","visibleRecords","#convSingle","filterSlot","#sortingColumns","groupResult","columns","rulesWithIdx","rule","idxA","idxB","isEmptyA","isEmptyB","strA","strB","PreCompiler","#ensureColgroup","#ensureThead","#ensureSectionTbodys","#ensureRowIndicator","#normalizeColAttributes","#createColIndicator","#normalizeCollapsibleAttributes","#generateCell","#initColExpanders","#initFilterButtons","#applyInitialCellWidths","thead","firstRow","cnt","td","#numToExcelCol","background","num","headTbody","footTbody","colCount","containerWidth","defaultWidth","widthVal","targetAttributes","autoIdCounter","$tbl","tagName","$datalist","$option","uniqueFuncName","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","rows","section","indicatorCell","startColIdx","targetIdx","NineTableSheet","#rowManager","#index","#colResizer","#filtering","#grouping","#colMover","#colFix","#cellSelection","#cellNavigation","#source","attrTrue","sourceTableTrue","#isSimple","#renderSplitContainers","#updateContainerWidths","#adjustOverlay","$thead","$overlay","#autoFit","enable","totalOriginalWidth","colList","collapsedTotalWidth","availableWidth","allocatedTotal","calculatedCols","exactWidth","baseWidth","remainderPixels","uncollapsedCols","#syncHeaderAndFooterHeights","#initRowHoverEvent","prefix","firstTable","#createSplitTable","offsetHeight","sheetBottom","tbodyBottom","bodyContainer","scrollLeft","#sorting","leftHeaderRows","bodyHeaderRows","rightHeaderRows","#applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","LayoutManager","owner","#applyAutoHeight","maxDisplayRows","maxRowHeight","toolbarEl","footerEl","toolbarHeight","footerHeight","calculatedHeight","isAutoHeight","sheetCount","sheetsHtml","className","sheetId","cssImports","ExprEngine","match","trimmedExpr","compiledExpr","evalFn","#exprCache","rowItem","NineTable","#shadowRoot","#dataManager","#templateCnt","#bindDynamicSetters","#layoutManager","#dispatchLoad","checkCount","checkTimer","loadSheetCnt","$sheet","methods","fn","idOrIndex","extractedMethodNames","matches","internalValue","methodName","newValue","BasicCellElement","exprCache","CellElement","#cell","#tr","#attr","curRow","renderer","rawRecord","prop","updateRowState","defaultValue","\"display\"","data","cleanExpr","childRecords","funcName","field","acc","EditableCellElement","CellInputText","#target","#initEvent","#maxbyte","maxByteNum","event","CellInputNumber","#onKeyDown","#validate","#max","#min","#scale","str","selectionStart","scale","validKey","isNumKey","CellInputColor","#btn","#dataSource","datalistId","datalist","option","#rendererColor","#isValidColor","g","CellInputDate","#type","formattedVal","d","isValid","#isValidDate","year","month","day","isleap","hour","min","week","CellCheckbox","#label","#trueText","#falseText","#isRadio","trueValue","childHtml","displayText","#enable","#readonly","#visible","CellRadio","#rendererRadio","matchIndex","#radioList","codeVal","#keyName","nameVal","#valueName","label","input","span","CellComboPanel","grd","itemsAttr","fieldKeys","valueName","activeColumnCount","multi","formattedData","keyName","selectedKeys","separator","#isOpen","btnEl","btnRect","panelHeight","upwardTop","#initData","viewContainer","#onClickRow","keyword","CellCombo","#multi","#multiSeparator","#togglePanel","#targetBtn","#getDisplayText","#validateInput","keys","list","CellRenderer","CellButton","#cellButtonClick","customEvent","rawValue","CellRowIndicator","#mainTarget","#subTarget","#statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","ColExpand","singleWidth","currentW","splitWidth","ContextMenu","#tableHost","targetTable","#getTargetSheet","items","activeTableId","activeTable","containerElement","targetTableAttr","rootUl","parsedList","#traverseUl","ulEl","child","spanEl","n","subUl","useDefault","rawItems","customItems","#parseCustomMenuItems","fixManager","#getFixManager","currentFixState","isFixable","isHeaderCell","fixMenuItem","cleanedItems","targetParent","menuItems","#buildMenuItems","#handleMenuClick","#syncMenuStates","isFiltering","autoFit","showTitle","menuId","#onContextMenu","MenuPanel","#onCallback","callback","#appendItems","#bindClickEvents","cellRightX","wrapper","calculatedLeft","calculatedTop","li","condition","sep","parentUl"],"sources":["../src/core/protype.js","../src/external/NoPeer.js","../src/core/constants.js","../src/data/ngData.js","../src/data/ngDataManager.js","../src/data/Fields.js","../src/layout/nine-table-sheets.js","../src/layout/nine-table-sheets-footer.js","../src/layout/nine-table-toolbar.js","../src/layout/nine-table-hscrollbar.js","../src/layout/nine-table-vscrollbar.js","../src/data/Grouping.js","../src/layout/core/RowManager.js","../src/layout/core/TableCompiler.js","../src/cell-manager/CellSelection.js","../src/cell-manager/CellNavigation.js","../src/col/ColResizer.js","../src/col/ColMover.js","../src/col/ColFixManager.js","../src/data/Filtering.js","../src/data/Sorting.js","../src/data/SheetView.js","../src/layout/core/PreCompiler.js","../src/layout/nine-table-sheet.js","../src/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/core/nine-table.js","../src/cell/core/BasicCellElement.js","../src/cell/core/CellElement.js","../src/cell/cell-input-text.js","../src/cell/cell-input-number.js","../src/cell/cell-input-color.js","../src/cell/cell-input-date.js","../src/cell/cell-checkbox.js","../src/cell/cell-radio.js","../src/cell/cell-combo-panel.js","../src/cell/cell-combo.js","../src/cell/cell-renderer.js","../src/cell/cell-button.js","../src/cell/cell-row-indicator.js","../src/col/col-expand.js","../src/menu/nine-table-menu.js","../src/menu/nine-table-menu-panel.js"],"sourcesContent":["Array.prototype.nineBinarySearch = function(target) {\n //this.sort((a, b) => { return a > b ? 1 : -1; });\n\n let start = 0;\n let end = this.length - 1;\n let mid;\n\n while (start <= end) {\n mid = parseInt((start + end) / 2);\n\n if (target === this[mid]) {\n return mid;\n } else {\n if (target < this[mid]) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n }\n\n return -1;\n};\n\nconst elementDebounceState = new WeakMap();\n\nHTMLElement.prototype.addDebounseEventListener = function(\n dblClickEvent,\n dblClickFn,\n pointerEvent,\n pointerFn,\n debounceTime = 500\n) {\n const el = this;\n\n if (!elementDebounceState.has(el)) {\n elementDebounceState.set(el, { timer: null, cancelFn: null });\n }\n const state = elementDebounceState.get(el);\n\n el.addEventListener(pointerEvent, (e) => {\n e.actualTarget = e.target;\n\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n\n // 💡 500ms 동안 대기한 뒤에야 실제 pointerFn이 실행됨\n state.timer = setTimeout(() => {\n state.timer = null;\n state.cancelFn = pointerFn.call(el, e);\n }, debounceTime);\n });\n\n el.addEventListener(dblClickEvent, (e) => {\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n\n if (state.cancelFn) {\n state.cancelFn();\n state.cancelFn = null;\n }\n\n dblClickFn.call(el, e);\n });\n};\n\n\nnine.measureTextSize = (_text, _font = '12px sans-serif') => {\n if (typeof _text === 'number') _text = _text + \"\";\n if (!_text) return { width: null, height: null };\n\n const stripHtml = (html) => {\n const tmp = document.createElement(\"DIV\");\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || \"\";\n };\n\n _text = _text.replaceAll(\"\\n\", \"<br>\");\n\n let canvas = document.body.querySelector('canvas#_nine_measure_canvas_');\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.id = '_nine_measure_canvas_';\n canvas.style.cssText = 'position: absolute; visibility: hidden; pointer-events: none; left: -9999px;';\n document.body.appendChild(canvas);\n }\n\n const context = canvas.getContext('2d');\n context.font = _font;\n\n let w = 0;\n let h = 0;\n\n for (let v of _text.split(\"<br>\")) {\n const cleanText = stripHtml(v);\n const metrics = context.measureText(cleanText);\n\n w = Math.max(w, metrics.width);\n\n const ascent = metrics.fontBoundingBoxAscent || 10;\n const descent = metrics.fontBoundingBoxDescent || 3;\n h += ascent + descent;\n }\n\n return {\n width: w,\n height: h\n };\n};","import { trace as traceOrigin } from '@ninebone/util';\n\nexport class Trace extends traceOrigin.constructor {\n constructor() {\n super();\n this.init(\"nine-table\", \"green\");\n }\n}\n\nexport const trace = new Trace();\n","export const NINE_TABLE = {\n META: {\n INDEX: {\n ROWID: 0,\n FILTER: 1,\n GROUP: 2,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 'EMPTY',\n NORMAL: 'NORMAL',\n INSERT: 'INSERT',\n UPDATE: 'UPDATE',\n DELETE: 'DELETE'\n },\n EVENT: {\n LOAD: \"load\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\n\r\nexport class ngRow {\r\n\t#parent;\r\n\t#newrow = -1;\r\n\r\n\tconstructor(parent) {\r\n\t\tthis.#parent = parent;\r\n\t}\r\n\r\n\tget at() {\r\n\t\treturn this.#newrow;\r\n\t}\r\n\tset at(v) {\r\n\t\tthis.#newrow = parseInt(v, 10);\r\n\t}\r\n\r\n\tcount = () => this.#parent.rawRecords.length;\r\n}\r\n\r\nexport class ngData {\r\n\t#host;\r\n\t#parent;\r\n\t#nextId = 0;\r\n\t#defaultHeight = [];\r\n\r\n\tstatic META_INDEX = {\r\n\t\tFILTER: 0,\r\n\t\t// GROUP: 1,\r\n\t\t// SELECT: 2,\r\n\t\t// EXPAND: 3\r\n\t};\r\n\r\n\tstatic ROW_STATE = {\r\n\t\tEMPTY: 'EMPTY',\r\n\t\tNORMAL: 'NORMAL',\r\n\t\tINSERT: 'INSERT',\r\n\t\tUPDATE: 'UPDATE',\r\n\t\tDELETE: 'DELETE'\r\n\t};\r\n\r\n\tconstructor(host, parent) {\r\n\t\tthis.#host = host;\r\n\t\tthis.#parent = parent;\r\n\t\tthis.#initialize();\r\n\t}\r\n\r\n\r\n\t#getValidRecords = () => {\r\n\t\tconst rawRecords = this.#parent.rawRecords || [];\r\n\t\treturn rawRecords.filter(o => !o.__ng?.deleted);\r\n\t};\r\n\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tcount = () => {\r\n\t\treturn this.length;\r\n\t};\r\n\r\n\tgetArray = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn validRecords; // 변환 없이 배열 그대로 반환 (렌더링 최적화)\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord;\r\n\t};\r\n\r\n\tsetArray = (rowIndex, colIndex, value) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\r\n\t\tconst oldValue = rowData.v[colIndex];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[colIndex] = value;\r\n\t};\r\n\r\n\r\n\tget = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn this.#conv(validRecords);\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#conv(targetRecord);\r\n\t};\r\n\r\n\tgetAll = () => {\r\n\t\treturn this.#parent.rawRecords || [];\r\n\t};\r\n\r\n\tgetHostFields = () => {\r\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\r\n\t};\r\n\r\n\t#initialize = () => {\r\n\t\tthis.#defaultHeight = [];\r\n\t\tconst templateElements = this.#host.template || [];\r\n\t\tArray.from(templateElements).forEach(el => {\r\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\r\n\t\t});\r\n\r\n\t\t(this.#parent.rawRecords || []).forEach(v => {\r\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\r\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\r\n\t\t});\r\n\t};\r\n\r\n\tget source() {\r\n\t\treturn this.#conv(this.#parent.rawRecords);\r\n\t}\r\n\tset source(v) {\r\n\t\tthis.set(v);\r\n\t}\r\n\r\n\t#invalidate = () => {\r\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\r\n\t\t\t$el.invalidate();\r\n\t\t});\r\n\r\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\r\n\t};\r\n\r\n\tset = (dataSource) => {\r\n\r\n\t\tconst loadData = () => {\r\n\t\t\tthis.#host.loading = true;\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tthis.clear();\r\n\t\t\t\t\tthis.add(dataSource, false);\r\n\t\t\t\t\tthis.#invalidate();\r\n\t\t\t\t} finally {\r\n\t\t\t\t\tthis.#host.loading = false;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif (this.#host.loaded) {\r\n\t\t\tloadData();\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\r\n\t\t\t\tloadData();\r\n\t\t\t}, { once: true });\r\n\t\t}\r\n\t};\r\n\r\n\tget nextId() {\r\n\t\treturn this.#nextId++;\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.#getValidRecords().length;\r\n\t}\r\n\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tgetRowCount() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\t#getDefaultMeta = (rowid = 0) => {\r\n\t\treturn {\r\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\r\n\t\t\tdeleted: false,\r\n\t\t\tfiltered: false,\r\n\t\t\theight: this.#defaultHeight.slice(),\r\n\t\t\to: {},\r\n\t\t\tc: {},\r\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\r\n\t\t\t_: [rowid, [], ],\r\n\t\t};\r\n\t};\r\n\r\n\treset = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tclear = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tif (this.#parent.viewRecords?.reset) {\r\n\t\t\tthis.#parent.viewRecords.reset();\r\n\t\t}\r\n\r\n\t\tthis.#nextId = 0;\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\t#json2Array = (jsonArray) => {\r\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\r\n\r\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\r\n\t\tconst arr = [];\r\n\r\n\t\tjsonArray.forEach(json => {\r\n\t\t\tconst o = { v: [] };\r\n\t\t\tfields.forEach(colnm => {\r\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\r\n\t\t\t});\r\n\t\t\tarr.push(o);\r\n\t\t});\r\n\r\n\t\treturn arr;\r\n\t};\r\n\r\n\t#defaultInsert = (arr) => {\r\n\t\tif (!Array.isArray(arr)) arr = [arr];\r\n\t\tarr.forEach(o => {\r\n\t\t\tconst rowid = this.nextId;\r\n\r\n\t\t\to.m = this.#getDefaultMeta(rowid);\r\n\t\t\to.__ng = o.m;\r\n\t\t\to.__ng.rowid = rowid;\r\n\t\t\to.__ng.rowState = ngData.ROW_STATE.INSERT;\r\n\t\t\to.__ng._[0] = rowid;\r\n\t\t});\r\n\t\treturn arr;\r\n\t};\r\n\r\n\tadd = (dataSource, updateState = true) => {\r\n\t\tif (dataSource === undefined) dataSource = {};\r\n\t\tconst arr = this.#json2Array(dataSource);\r\n\r\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(this.#defaultInsert(arr));\r\n\r\n\t\tconst row = this.count() - 1;\r\n\t\tif (!updateState) {\r\n\t\t\tarr.forEach((_, idx) => {\r\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\r\n\t\t\t\tif (target) target.__ng.rowState = ngData.ROW_STATE.EMPTY;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#invalidate();\r\n\t\treturn row;\r\n\t};\r\n\r\n\tdelete = (at) => {\r\n\t\tlet arr = [];\r\n\t\tif (Array.isArray(at)) {\r\n\t\t\tarr = at;\r\n\t\t} else if (typeof at === \"undefined\") {\r\n\t\t\tarr = [this.#parent.host.row.at];\r\n\t\t} else {\r\n\t\t\tarr = [parseInt(at, 10)];\r\n\t\t}\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tarr.sort((a, b) => b - a).forEach(rowidx => {\r\n\t\t\tif (validRecords[rowidx]) {\r\n\t\t\t\tconst targetId = validRecords[rowidx].__ng.rowid;\r\n\t\t\t\tif (validRecords[rowidx].__ng.rowState === ngData.ROW_STATE.INSERT) {\r\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.__ng.rowid !== targetId);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\r\n\t\t\t\t\t\tif (item.__ng.rowid === targetId) {\r\n\t\t\t\t\t\t\titem.__ng.deleted = true;\r\n\t\t\t\t\t\t\titem.__ng.rowState = ngData.ROW_STATE.DELETE;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tsetValue = (rowIndex, colnm, value) => {\r\n\r\n\t\trowIndex = parseInt(rowIndex, 10);\r\n\t\tconst fields = this.getHostFields();\r\n\t\tconst COL_IDX = fields.indexOf(colnm);\r\n\t\tif (COL_IDX < 0) return;\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\t\tif (!rowData) return;\r\n\r\n\r\n\r\n\t\tconst oldValue = rowData.v[COL_IDX];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\tif (!rowData.__ng.o.hasOwnProperty(colnm)) rowData.__ng.o[colnm] = oldValue;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[COL_IDX] = value;\r\n\t};\r\n\r\n\t#conv = (arr) => {\r\n\t\tif (!arr) return arr;\r\n\r\n\t\tconst isSingle = !Array.isArray(arr);\r\n\t\tconst targetArr = isSingle ? [arr] : arr;\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\r\n\t\t\tconst t = {};\r\n\t\t\tfields.forEach((colnm, i) => {\r\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t\t});\r\n\t\t\tt.__ng = o.__ng;\r\n\t\t\treturn t;\r\n\t\t});\r\n\r\n\t\treturn isSingle ? result[0] : result;\r\n\t};\r\n}\r\n","import { ngRow, ngData } from \"./ngData.js\";\r\n\r\nexport class ngDataManager {\r\n\t#host;\r\n\r\n\tconstructor(host) {\r\n\t\tthis.#host = host;\r\n\r\n\t\tthis.row = new ngRow(this);\r\n\t\tthis.data = new ngData(this.#host, this);\r\n\r\n\t\tthis.rawRecords = [];\r\n\t\tthis.viewRecords = [];\r\n\t\tthis.delRecords = [];\r\n\t\tthis.pageCnt = 25;\r\n\r\n\t\tthis.viewRecords.reset = () => {\r\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\r\n\t\t};\r\n\r\n\t\tthis.setDataSource = (ds) => {\r\n\t\t\tif (this.data) this.data.reset();\r\n\r\n\t\t\tthis.rawRecords = [];\r\n\t\t\tthis.viewRecords = [];\r\n\t\t\tthis.delRecords = [];\r\n\r\n\t\t\tthis.data.set(ds || []);\r\n\t\t};\r\n\r\n\t\tthis.getRowState = (nRow) => {\r\n\t\t\tconst rowIdx = parseInt(nRow, 10);\r\n\t\t\tif (rowIdx >= this.data.count()) return;\r\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\r\n\t\t};\r\n\r\n\t\tthis.getRowPosition = () => this.row.at;\r\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\r\n\r\n\t\tthis.scrollTo_V1 = (nRow) => {\r\n\t\t\tif (nRow < 0) nRow = 0;\r\n\t\t\tif (nRow >= this.rawRecords.length) nRow = this.rawRecords.length - 1;\r\n\r\n\t\t\tthis.viewRecords.rawIndex = nRow;\r\n\t\t\tif (this.viewRecords.reset) this.viewRecords.reset();\r\n\r\n\t\t\treturn (nRow <= 0 || nRow >= this.rawRecords.length - 1) ? false : true;\r\n\t\t};\r\n\r\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\r\n\r\n\t\tthis.setColumn = (rowidx, colnm, v) => {\r\n\t\t\trowidx = parseInt(rowidx, 10);\r\n\t\t\tthis.data.setValue(rowidx, colnm, v);\r\n\t\t};\r\n\r\n\t\t// 초기 빈 데이터 바인딩\r\n\t\tthis.setDataSource([]);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\n\nexport class fields {\n\t#host;\n\t#fields = [];\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\t\tthis.#init();\n\t};\n\n\tget() {\n\t\treturn this.#fields.map(f => f.name);\n\t};\n\n\tgetFields() {\n\t\treturn this.#fields;\n\t}\n\n\tgetType(fieldName) {\n\t\tconst found = this.#fields.find(f => f.name === fieldName);\n\t\treturn found ? found.type : 'string';\n\t}\n\n\tadd = (arr, type = 'string') => {\n\t\tarr.forEach(fName => {\n\t\t\tif (!this.#fields.some(f => f.name === fName)) {\n\t\t\t\tthis.#fields.push({ name: fName, type: type });\n\t\t\t}\n\t\t});\n\t\tthis.#adjust();\n\t};\n\n\tindexOf(v) {\n\t\treturn this.#fields.findIndex(f => f.name === v);\n\t};\n\n\tincludes(v) {\n\t\treturn this.#fields.some(f => f.name === v);\n\t};\n\n\t#adjust = () => {\n\t\tconst map = new Map();\n\t\tthis.#fields.forEach(f => {\n\t\t\tmap.set(f.name, f.type);\n\t\t});\n\n\t\tthis.#fields = Array.from(map, ([name, type]) => ({ name, type }));\n\n\t\tthis.#fields = this.#fields.filter(f => f.name !== \"\" && f.name !== \"__ng\");\n\n\t\tthis.#fields.sort((a, b) => { return (a.name.length < b.name.length) ? 1 : -1; });\n\t};\n\n\t#init = () => {\n\t\tthis.#fields = [];\n\n\t\tconst rawTables = Array.from(this.#host.querySelectorAll(\"table\"));\n\n\t\tif (!rawTables || rawTables.length === 0) return;\n\n\t\tfor (const tbl of rawTables) {\n\n\t\t\ttbl.querySelectorAll('[data-bind]').forEach((el) => {\n\t\t\t\tconst fieldName = el.dataset.bind;\n\t\t\t\tconst fieldType = el.getAttribute(\"data-type\") || 'string';\n\n\t\t\t\tif (fieldName) {\n\t\t\t\t\tthis.#fields.push({ name: fieldName, type: fieldType });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst exprAttrs = [\n\t\t\t\t\"data-expr\", \"background-color\", \"color\", \"tooltip\",\n\t\t\t\t\"visible\", \"readonly\", \"enable-button\", \"enable-check\",\n\t\t\t\t\"class-expr\", \"icon-color\", \"icon-src\"\n\t\t\t];\n\n\t\t\texprAttrs.forEach(attr => {\n\t\t\t\ttbl.querySelectorAll(`[${attr}]`).forEach((el) => {\n\t\t\t\t\tlet expr = el.getAttribute(attr);\n\t\t\t\t\tif (!expr) return;\n\n\t\t\t\t\tif (expr.indexOf(\"data.\") < 0) {\n\t\t\t\t\t\tconst lastIndex = expr.search(/[(]/g);\n\n\t\t\t\t\t\tif (lastIndex > 0) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\texpr = String(window[expr.substring(0, lastIndex).trim()]);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\texpr = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\texpr.split(\"data.\").forEach(v => {\n\t\t\t\t\t\tif (v.trim() != \"\") {\n\t\t\t\t\t\t\tconst lastIndex = v.search(/[^_A-Za-z0-9]/g);\n\t\t\t\t\t\t\tlet targetField = '';\n\n\t\t\t\t\t\t\tif (lastIndex >= 0) {\n\t\t\t\t\t\t\t\ttargetField = v.substring(0, lastIndex);\n\t\t\t\t\t\t\t} else if (expr.startsWith(\"data.\")) {\n\t\t\t\t\t\t\t\ttargetField = v.replace(\"data.\", \"\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (targetField) {\n\t\t\t\t\t\t\t\tthis.#fields.push({ name: targetField, type: 'string' });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tthis.#adjust();\n\t};\n};","export class NineTableSheets extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n #init = () => {\n\n };\n\n}\n\nif (!customElements.get('nine-table-sheets')) {\n customElements.define('nine-table-sheets', NineTableSheets);\n}","export class NineTableSheetsFooter extends HTMLElement {\n #host;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n refresh = () => {\n this.querySelector(\"#row-count\").innerHTML = this.#host.data.count().toLocaleString();\n };\n\n #init = () => {\n this.#host = this.getRootNode().host;\n\n this.#render();\n\n this.querySelector('.nine-tab-bar')?.addEventListener('click', (e) => {\n const isMultiSelect = e.ctrlKey || e.metaKey || e.shiftKey;\n const tabItem = e.target.closest('nt-sheets-tab-item');\n\n if (!tabItem) return;\n\n const index = parseInt(tabItem.dataset.index, 10);\n this.#switchSheet(index, isMultiSelect);\n });\n\n setTimeout(() => {\n this.#switchSheet(0, false);\n })\n };\n\n #switchSheet = (index, isMultiSelect = false) => {\n\n const updateSplitters = () => {\n const sheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet'));\n const splitters = Array.from(this.#host.shadowRoot.querySelectorAll('nine-splitter'));\n\n splitters.forEach(s => s.style.setProperty('display', 'none'));\n\n const activeSheets = sheets\n .map((sheet, idx) => ({ sheet, idx }))\n .filter(({ sheet }) => sheet.classList.contains('active'));\n\n if (activeSheets.length < 2) return;\n\n for (let i = 0; i < activeSheets.length - 1; i++) {\n const currentIdx = activeSheets[i].idx;\n\n const targetSplitter = this.#host.shadowRoot.querySelector(`nine-splitter[data-split-index=\"${currentIdx}\"]`);\n if (targetSplitter) {\n targetSplitter.style.setProperty('display', '');\n }\n }\n };\n\n const tabBar = this.querySelector('.nine-tab-bar');\n const body = this.#host.shadowRoot.querySelector('nine-table-sheets-body');\n const tabItems = tabBar.querySelectorAll('nt-sheets-tab-item');\n const sheetElements = body.querySelectorAll('nine-table-sheet');\n\n if (!tabItems[index]) return;\n\n if (!isMultiSelect) {\n tabItems.forEach((tab, idx) => {\n tab.setActive(idx === index);\n });\n\n sheetElements.forEach((sheet, idx) => {\n const isActive = idx === index;\n sheet.classList.toggle('active', isActive);\n sheet.style.flex = isActive ? '1 1 100%' : '';\n });\n } else {\n const clickedTab = tabItems[index];\n const activeTabs = tabBar.querySelectorAll('nt-sheets-tab-item.active');\n\n if (clickedTab.classList.contains('active') && activeTabs.length <= 1) {\n return;\n }\n\n clickedTab.classList.toggle('active');\n const targetSheet = body.querySelector(`nine-table-sheet[data-index=\"${index}\"]`);\n if (targetSheet) {\n targetSheet.classList.toggle('active');\n if (!targetSheet.classList.contains('active')) {\n targetSheet.style.flex = '';\n }\n }\n }\n\n const activeSheets = body.querySelectorAll('nine-table-sheet.active');\n\n activeSheets?.forEach(sheet => {\n sheet.style.flex = (activeSheets.length > 1) ? '1 1 0%' : '1 1 100%';\n\n if (typeof sheet.refreshLayout === 'function') {\n sheet.refreshLayout();\n } else {\n sheet.invalidate?.();\n }\n });\n\n updateSplitters();\n };\n\n #render() {\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE'));\n\n const tabsHtml = rawTables.map((table, idx) => {\n const className = idx === 0 ? 'active' : '';\n const tabName = table.getAttribute('caption') || `Sheet ${idx + 1}`;\n\n return `<nt-sheets-tab-item class=\"${className}\" data-index=\"${idx}\">${tabName}</nt-sheets-tab-item>`;\n }).join('');\n\n this.innerHTML = `\n <div class=\"nine-tab-bar\">${tabsHtml}</div>\n <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n `;\n };\n}\n\nexport class SheetTabItem extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n }\n\n setActive(isActive) {\n this.classList.toggle('active', isActive);\n }\n}\n\nif (!customElements.get('nt-sheets-tab-item')) {\n customElements.define('nt-sheets-tab-item', SheetTabItem);\n}\n\nif (!customElements.get('nine-table-sheets-footer')) {\n customElements.define('nine-table-sheets-footer', NineTableSheetsFooter);\n}","import { trace } from \"@nopeer\";\n\nexport class Toolbar extends HTMLElement {\n #host;\n #customContainer;\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#render();\n this.#bindEvents();\n }\n\n #render() {\n this.innerHTML = `\n <div class=\"ng-toolbar-left\">\n <button type=\"button\" class=\"ng-toolbar-menu-btn\" title=\"Menu\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#374151\" stroke-width=\"2\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n </svg>\n </button>\n <span class=\"ng-toolbar-title\"></span>\n </div>\n\n <div class=\"ng-toolbar-custom\" id=\"custom-container\"></div>\n `;\n\n this.#customContainer = this.querySelector('#custom-container');\n this.#syncStateFromHost();\n }\n\n #syncStateFromHost() {\n const isSimple = this.#host.getAttribute('theme') === 'simple' || this.#host.classList.contains('simple');\n const showToolbar = this.#host.getAttribute('show-toolbar') !== 'false';\n const showMenu = this.#host.getAttribute('show-menu') !== 'false';\n const caption = this.#host.getAttribute('caption') || '';\n\n if (isSimple || !showToolbar) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n\n this.setAttribute('show-menu', showMenu ? 'true' : 'false');\n this.updateCaption(caption);\n }\n\n #bindEvents() {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) {\n titleEl.addEventListener('dblclick', () => {\n const link = '<font color=\"green\">https://www.ninegrid.net</font>';\n const currentCaption = this.#host.getAttribute('caption') || '';\n titleEl.innerHTML = titleEl.innerHTML === link ? currentCaption : link;\n });\n }\n\n const menuBtn = this.querySelector('.ng-toolbar-menu-btn');\n if (menuBtn) {\n menuBtn.addEventListener('click', () => {\n this.#host.dispatchEvent(new CustomEvent('toolbar-menu-click', {\n bubbles: true,\n composed: true,\n detail: { targetTable: this.#host }\n }));\n });\n }\n }\n\n addCustomElement(element) {\n if (this.#customContainer) {\n this.#customContainer.append(element);\n }\n }\n\n updateCaption(text) {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) titleEl.textContent = text;\n }\n}\n\nif (!customElements.get('nine-table-toolbar')) {\n customElements.define('nine-table-toolbar', Toolbar);\n}","// ui/nine-table-hscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableHScrollBar extends HTMLElement {\n #owner;\n #dragging = false;\n #elements;\n #interval1;\n #interval2;\n #resizeObserver;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#owner = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n if (!this.#owner) return;\n\n this.innerHTML = `\n <button class='scroll-left' disabled><div class='scroll-icon'></div></button>\n <div class='scroll-track'><div class='scroll-thumb'></div></div>\n <button class='scroll-right' disabled><div class='scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container : body,\n track : this.querySelector(\".scroll-track\"),\n thumb : this.querySelector(\".scroll-thumb\"),\n left : this.querySelector(\".scroll-left\"),\n right : this.querySelector(\".scroll-right\"),\n };\n\n this.#init();\n this.#observeResize();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n disconnectedCallback() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n }\n\n #observeResize = () => {\n if (!this.#owner) return;\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) return;\n\n this.#resizeObserver = new ResizeObserver(() => {\n this.refresh();\n });\n this.#resizeObserver.observe(body);\n };\n\n refresh = () => {\n\n if (!this.#owner || !this.#elements || this.#dragging) return;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return;\n\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n\n const needsHScroll = (bodyWidth !== 0 && tableWidth > bodyWidth);\n this.#owner.classList.toggle('hscroll-visible', needsHScroll);\n\n if (!needsHScroll) {\n return;\n }\n\n const trackWidth = track.clientWidth;\n if (trackWidth <= 0) return;\n\n const thumbWidth = Math.max(Math.min(trackWidth * (bodyWidth / tableWidth), trackWidth), 20);\n thumb.style.width = `${thumbWidth}px`;\n\n const currentLeft = body.scrollLeft;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n let l = 0;\n if (maxScrollLeft > 0) {\n l = parseInt((currentLeft / maxScrollLeft) * (trackWidth - thumbWidth), 10);\n }\n if (l < 0) l = 0;\n\n const maxThumbLeft = trackWidth - thumbWidth;\n if (l > maxThumbLeft) l = maxThumbLeft;\n\n thumb.style.left = `${l}px`;\n\n this.#elements.left.disabled = (l === 0);\n this.#elements.right.disabled = (l >= maxThumbLeft - 1);\n };\n\n #thumbMoveTo = (x) => {\n if (!this.#elements) return false;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return false;\n\n const trackBound = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n\n let targetX = x;\n if (targetX < 0) targetX = 0;\n const maxThumbLeft = trackBound.width - thumbWidth;\n if (targetX > maxThumbLeft) targetX = maxThumbLeft;\n targetX = parseInt(targetX, 10);\n\n this.#elements.thumb.style.left = `${targetX}px`;\n\n this.#elements.left.disabled = (targetX === 0);\n this.#elements.right.disabled = (targetX >= maxThumbLeft - 1);\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n if (maxThumbLeft > 0 && maxScrollLeft > 0) {\n const newScrollLeft = (targetX / maxThumbLeft) * maxScrollLeft;\n body.scrollLeft = newScrollLeft;\n }\n\n return (targetX > 0 && targetX < maxThumbLeft - 1);\n };\n\n #init = () => {\n const delayScroll = (pos) => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n\n const thumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n this.#thumbMoveTo(thumbLeft + pos);\n\n this.#interval1 = setInterval(() => {\n clearInterval(this.#interval1);\n\n this.#interval2 = setInterval(() => {\n const currentThumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n if (!this.#thumbMoveTo(currentThumbLeft + pos)) {\n clearInterval(this.#interval2);\n }\n }, 50);\n }, 500);\n };\n\n const clearTimer = () => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n };\n\n ['mouseup', 'mouseleave', 'touchend'].forEach(evt => {\n this.#elements.left.addEventListener(evt, clearTimer);\n this.#elements.right.addEventListener(evt, clearTimer);\n this.#elements.track.addEventListener(evt, clearTimer);\n });\n\n this.#elements.left.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(-20); });\n this.#elements.right.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(20); });\n this.#elements.left.addEventListener(\"touchstart\", () => delayScroll(-20));\n this.#elements.right.addEventListener(\"touchstart\", () => delayScroll(20));\n\n this.#elements.track.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.preventDefault();\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n this.#thumbMoveTo(e.clientX - trackRect.left - (thumbWidth / 2));\n });\n\n this.#elements.thumb.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n this.shiftX = e.clientX - this.#elements.thumb.getBoundingClientRect().left;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n this.#thumbMoveTo(moveEvent.clientX - trackRect.left - this.shiftX);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n clearTimer();\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n };\n}\n\nif (!customElements.get('nine-table-hscrollbar')) {\n customElements.define(\"nine-table-hscrollbar\", NineTableHScrollBar);\n}","// ui/nine-table-vscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableVScrollBar extends HTMLElement {\n #host;\n #sheet;\n #dragging = false;\n #elements;\n #startY = 0;\n #startScrollTop = 0;\n #startThumbTop = 0;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#sheet = this.closest(\"nine-table-sheet\");\n\n this.innerHTML = `\n <button class='scroll-top' disabled><div class='scroll-icon'></div></button>\n <div class='scroll-track'><div class='scroll-thumb'></div></div>\n <button class='scroll-bottom' disabled><div class='scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#sheet.querySelector(\".ng-sheet-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container: body,\n track: this.querySelector(\".scroll-track\"),\n thumb: this.querySelector(\".scroll-thumb\"),\n top: this.querySelector(\".scroll-top\"),\n bottom: this.querySelector(\".scroll-bottom\"),\n };\n\n this.#init();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n #getScaleInfo = () => {\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords ? viewRecords.length : 0;\n\n const scrollHolder = this.#sheet.elements?.scrollHolder;\n let rawContentHeight = scrollHolder ? parseFloat(scrollHolder.style.height) || 0 : 0;\n\n if (!rawContentHeight || rawContentHeight <= 0) {\n const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n if (isGrouped && this.#sheet.rowManager) {\n rawContentHeight = (body.scrollHeight > body.clientHeight) ? body.scrollHeight : (totalCount * 30);\n } else {\n const rowHeight = this.#sheet.getRowHeight() || 1;\n rawContentHeight = totalCount * rowHeight;\n }\n }\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawContentHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let contentHeight = rawContentHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawContentHeight;\n contentHeight = MAX_BROWSER_HEIGHT;\n }\n\n return { rawContentHeight, contentHeight, scaleFactor, useScaling, totalCount };\n };\n\n\n refresh = () => {\n if (this.#dragging) return;\n\n if (!this.#sheet || !this.#sheet.elements || !this.#elements) return;\n\n const body = this.#elements.container;\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n const { contentHeight } = this.#getScaleInfo();\n\n const fixedHeight = (this.#sheet.querySelector('thead')?.offsetHeight || 0) +\n (this.#sheet.querySelector('tfoot')?.offsetHeight || 0) +\n (this.#sheet.querySelector('tbody.head')?.offsetHeight || 0);\n\n const bodyHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0);\n const viewHeight = bodyHeight - fixedHeight;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n const rawContentHeight = this.#sheet.getRowHeight() * totalCount;\n\n const needsVScroll = (rawContentHeight > viewHeight);\n\n this.#sheet.classList.toggle('vscroll-visible', needsVScroll);\n\n if (!needsVScroll) {\n return;\n }\n\n const trackHeight = track.clientHeight;\n if (trackHeight <= 0) return;\n\n const thumbHeight = Math.max(Math.min(trackHeight * (bodyHeight / rawContentHeight), trackHeight), 20);\n thumb.style.height = `${thumbHeight}px`;\n\n const currentScrollTop = body.scrollTop;\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 1);\n\n let thumbTop = 0;\n if (maxScrollTop > 0) {\n thumbTop = (currentScrollTop / maxScrollTop) * (trackHeight - thumbHeight);\n }\n\n const maxThumbTop = trackHeight - thumbHeight;\n if (thumbTop < 0) thumbTop = 0;\n if (thumbTop > maxThumbTop) thumbTop = maxThumbTop;\n\n thumb.style.top = `${thumbTop}px`;\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n #init = () => {\n\n this.#elements.thumb.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n\n this.#startY = e.clientY;\n this.#startThumbTop = parseFloat(this.#elements.thumb.style.top) || 0;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const trackHeight = trackRect.height;\n const thumbHeight = this.#elements.thumb.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n if (maxThumbTop <= 0) return;\n\n\n const deltaY = moveEvent.clientY - this.#startY;\n let targetThumbTop = this.#startThumbTop + deltaY;\n\n if (targetThumbTop < 0) targetThumbTop = 0;\n if (targetThumbTop > maxThumbTop) targetThumbTop = maxThumbTop;\n\n this.#elements.thumb.style.top = `${targetThumbTop}px`;\n\n const ratio = targetThumbTop / maxThumbTop;\n\n const rowHeight =this.#sheet.getRowHeight();\n const viewHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0) -\n (this.#sheet.elements.body.thead?.offsetHeight || 0) -\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) -\n (this.#sheet.elements.body.tbody.head.offsetHeight || 0);\n\n const visibleRowCount = Math.floor(viewHeight / rowHeight);\n\n const { totalCount } = this.#getScaleInfo();\n const targetRow = Math.floor(ratio * (totalCount - visibleRowCount + 1));\n\n this.#sheet.rowManager.scrollToDataRow(targetRow);\n\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n const currentScrollTop = this.#elements.container.scrollTop;\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 0);\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n\n this.#elements.track.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0 || e.target === this.#elements.thumb) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbHeight = this.#elements.thumb.clientHeight;\n const trackHeight = this.#elements.track.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n if (maxThumbTop > 0) {\n const clickY = e.clientY - trackRect.top - (thumbHeight / 2);\n const ratio = Math.max(0, Math.min(1, clickY / maxThumbTop));\n\n const { totalCount } = this.#getScaleInfo();\n const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n\n\n if (targetRow >= 0 && this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n }\n this.refresh();\n });\n\n let scrollInterval = null;\n\n const startContinuousScroll = (direction) => {\n if (scrollInterval) return;\n\n const scrollStep = () => {\n const $firstTr = this.#sheet.querySelector(\"tbody.body tr\");\n\n if (!$firstTr || $firstTr.dataset.row === undefined) {\n return;\n }\n\n if (direction === 'down' && this.#sheet.isLastRow()) {\n return;\n }\n\n const currentRow = parseInt($firstTr.dataset.row, 10);\n const targetRow = direction === 'down' ? currentRow+1 : Math.max(0, currentRow-1);\n\n this.#sheet.rowManager.scrollToDataRow(targetRow, null, () => {\n this.refresh();\n });\n };\n\n scrollStep();\n scrollInterval = setInterval(scrollStep, 200); // 100ms 간격 반복\n };\n\n const stopContinuousScroll = () => {\n if (scrollInterval) {\n clearInterval(scrollInterval);\n scrollInterval = null;\n }\n };\n\n this.#elements.top.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n startContinuousScroll('up');\n });\n\n this.#elements.bottom.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n startContinuousScroll('down');\n });\n\n document.addEventListener(\"mouseup\", stopContinuousScroll);\n this.#elements.top.addEventListener(\"mouseleave\", stopContinuousScroll);\n this.#elements.bottom.addEventListener(\"mouseleave\", stopContinuousScroll);\n };\n}\n\nif (!customElements.get('nine-table-vscrollbar')) {\n customElements.define(\"nine-table-vscrollbar\", NineTableVScrollBar);\n}\n\n","import { trace } from \"@nopeer\";\r\n\r\nexport const GROUP_IDX = {\r\n\tID: 0,\r\n\tDEPTH: 1,\r\n\tNAME: 2,\r\n\tCHILDREN: 3,\r\n};\r\n\r\nexport class GroupingManager {\r\n\t#sheet;\r\n\t#host;\r\n\t#groupColumns = [];\r\n\t#groupMap = new Map(); // 그룹별 자식 ID 매핑 관리용\r\n\t#isApplying = false;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t}\r\n\r\n\tget columns() {\r\n\t\treturn this.#groupColumns;\r\n\t}\r\n\r\n\tget groupMap() {\r\n\t\treturn this.#groupMap;\r\n\t}\r\n\r\n\tinitialize = () => {\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\t};\r\n\r\n\tapply() {\r\n\r\n\t\tif (this.#isApplying) return;\r\n\t\tthis.#isApplying = true;\r\n\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh();\r\n\t}\r\n\r\n\tclear() {\r\n\t\tthis.#groupColumns = [];\r\n\t\tthis.#groupMap.clear();\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh();\r\n\t}\r\n\r\n\tsetGroupMap(map) {\r\n\t\tthis.#groupMap = map;\r\n\t}\r\n\r\n\tgetChildrenRowIds(groupId) {\r\n\t\treturn this.#groupMap.get(groupId) || [];\r\n\t}\r\n\r\n\tgetChildrenRecords(groupId) {\r\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\r\n\t\tconst dataManager = this.#host.data;\r\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\r\n\t}\r\n}\r\n\r\nexport class Grouping {\r\n\r\n\tstatic apply(rawRecords, groupColumns = [], fields = []) {\r\n\t\tif (!groupColumns || groupColumns.length === 0) {\r\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\r\n\t\t}\r\n\r\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\r\n\t\tconst groupMap = new Map();\r\n\r\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\r\n\t\tconst flatResult = [];\r\n\t\tconst renderItems = [];\r\n\r\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\");\r\n\r\n\t\treturn { headers: flatResult, renderItems, groupMap };\r\n\t}\r\n\r\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId) {\r\n\t\tlet counter = 0;\r\n\t\tconst isLastLevel = (depth === groupColumns.length - 1); // 💡 연산자 수정 반영\r\n\r\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\r\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\r\n\r\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\r\n\t\t\tgroupMap.set(groupId, rowIds);\r\n\r\n\t\t\tconst groupRecord = [];\r\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\r\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\r\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\r\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\r\n\r\n\t\t\tgroupRecord.__isGroupHeader = true;\r\n\t\t\tgroupRecord.__groupId = groupId;\r\n\r\n\t\t\tresultArr.push(groupRecord);\r\n\r\n\t\t\trenderItems.push({\r\n\t\t\t\ttype: 'group',\r\n\t\t\t\trecord: groupRecord,\r\n\t\t\t\tgroupId: groupId\r\n\t\t\t});\r\n\r\n\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\r\n\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId);\r\n\t\t\t} else {\r\n\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\r\n\t\t\t\tleafRecords.forEach(record => {\r\n\t\t\t\t\trecord.__isGroupHeader = false;\r\n\t\t\t\t\trecord.__groupId = groupId;\r\n\t\t\t\t\tresultArr.push(record);\r\n\r\n\t\t\t\t\trenderItems.push({\r\n\t\t\t\t\t\ttype: 'data',\r\n\t\t\t\t\t\trecord: record,\r\n\t\t\t\t\t\tgroupId: groupId\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tstatic #buildNestedMap(records, groupColumns, fields) {\r\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\r\n\t\tconst remainingCols = groupColumns.slice(1);\r\n\t\tconst map = new Map();\r\n\r\n\t\trecords.forEach(record => {\r\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\r\n\t\t\tif (!map.has(key)) map.set(key, []);\r\n\t\t\tmap.get(key).push(record);\r\n\t\t});\r\n\r\n\t\tif (remainingCols.length > 0) {\r\n\t\t\tconst result = new Map();\r\n\t\t\tfor (let [key, subRecords] of map.entries()) {\r\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n\tstatic #collectLeafRowIds(subMapOrRecords) {\r\n\t\tlet rowIds = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\r\n\t\t}\r\n\t\treturn rowIds;\r\n\t}\r\n\r\n\tstatic #collectLeafRecords(subMapOrRecords) {\r\n\t\tlet records = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trecords = records.concat(subMapOrRecords);\r\n\t\t}\r\n\t\treturn records;\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { GROUP_IDX } from \"@/data/Grouping.js\";\n\nexport class RowManager {\n #BUFFER_ROW_COUNT = 3;\n\n #host;\n #sheet;\n #element;\n\n #containerTemplates = new Map();\n\n #templateRowHeights = [];\n #cachedTemplateHeight = null;\n\n #resizeObserver = null;\n #sheetHeight = 0;\n #cachedRowCount;\n\n #isProgrammaticScroll = false;\n #isGrouped = false;\n\n constructor(sheet) {\n this.#host = sheet.getRootNode().host;\n this.#sheet = sheet;\n\n this.#initResizeObserver();\n }\n\n getRowHeight() {\n return this.#templateRowHeights.reduce((sum, h) => sum + h, 0);//this.#cachedTemplateHeight;\n }\n\n refresh = (force = false) => {\n\n if (!this.#sheet.classList.contains('active')) return;\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n const wasInvalidHeight = !this.#cachedTemplateHeight || this.#cachedTemplateHeight <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#cachedTemplateHeight && this.#cachedTemplateHeight > 0) {\n this.#renderAllContainers();\n }\n }\n\n\n this.#handleScroll(bodyViewport.scrollTop, force);\n\n this.#sheet.querySelector('nine-table-vscrollbar')?.refresh();\n };\n\n #handleScroll = (scrollTop, force = false) => {\n\n if (this.#isGrouped) {\n this.#handleGroupedScroll(scrollTop, force);\n return;\n }\n\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) return;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n if (totalCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight - (viewHeight - fixedHeight - rowHeight), 0);\n\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let totalVirtualHeight = rawTotalVirtualHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n totalVirtualHeight = MAX_BROWSER_HEIGHT;\n }\n\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n const actualScrollTop = useScaling ? (scrollTop / scaleFactor) : scrollTop;\n\n const maxStartIndex = Math.max(0, totalCount - 1);\n const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n\n const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n const renderOffsetTop = clampedScrollTop % rowHeight;\n this.#sheet.elements.left.tbody.body.style.top =\n this.#sheet.elements.body.tbody.body.style.top =\n this.#sheet.elements.right.tbody.body.style.top = `-${renderOffsetTop}px`;\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.row !== undefined ? parseInt(firstTr.dataset.row, 10) : -1;\n\n if (!force && currentStartIndex === startIndex) {\n return;\n }\n\n [\n this.#sheet.elements.left.tbody.body,\n this.#sheet.elements.body.tbody.body,\n this.#sheet.elements.right.tbody.body\n ].forEach(($tbody, tbodyIdx) => {\n if (!$tbody) return;\n\n const rows = $tbody.querySelectorAll('tbody.body tr');\n\n rows.forEach(($tr, index) => {\n const dataIndex = startIndex + Math.floor(index / templateLength);\n\n if (dataIndex >= totalCount) {\n $tr.style.display = 'none';\n $tr.dataset.matrixRow = null;\n $tr.dataset.row = null;\n $tr.dataset.index = null;\n return;\n }\n\n const record = viewRecords[dataIndex];//this.#sheet.view.getArray(dataIndex);\n\n if (!record) {\n $tr.style.display = 'none';\n return;\n }\n\n const rowid = record.m._[NINE_TABLE.META.INDEX.ROWID];\n\n $tr.style.display = '';\n\n this.#bindRowData($tr, record, rowid, dataIndex);\n });\n });\n\n this.#sheet.selection.refresh();\n };\n\n\n #handleGroupedScroll = (scrollTop, force = false) => {\n\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.templateLength || 1;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH] || 0;\n const groupHeight = this.#templateRowHeights[depth] || this.#cachedTemplateHeight / templateLength;\n return groupHeight;\n } else {\n let dataRowsHeight = 0;\n const templateLength = this.#sheet.templateLength || 1;\n\n let groupHeightsTotal = 0;\n for(let i = 0; i < templateLength - 1; i++) {\n groupHeightsTotal += this.#templateRowHeights[i] || 0;\n }\n dataRowsHeight = this.#cachedTemplateHeight - groupHeightsTotal;\n\n return dataRowsHeight > 0 ? dataRowsHeight : this.#cachedTemplateHeight;\n }\n };\n\n\n let totalVirtualHeight = 0;\n const itemHeights = new Array(totalVirtualCount);\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = getItemHeight(allRenderItems[i]);\n itemHeights[i] = h;\n totalVirtualHeight += h;\n }\n\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n const viewportClientHeight = this.#sheet.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = 0;\n\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = itemHeights[i];\n if (accumulatedHeight + h > scrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n const offsetY = scrollTop - accumulatedHeight;\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.virtualIndex !== undefined\n ? parseInt(firstTr.dataset.virtualIndex, 10)\n : -1;\n\n if (!force && currentStartIndex === startIndex) {\n return;\n }\n\n const visibleRowsCount = Math.ceil(viewportClientHeight / (this.#cachedTemplateHeight / templateLength));\n const dynamicBuffer = (this.#sheet.grouping.columns?.length || 1) * 15;\n const targetStart = startIndex;\n const targetEnd = Math.min(totalVirtualCount, startIndex + visibleRowsCount + dynamicBuffer);\n const renderedItems = allRenderItems.slice(targetStart, targetEnd);\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const trs = Array.from(container.querySelectorAll('tbody.body tr'));\n\n for (let i = 0; i < trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = trs.slice(i, i + templateLength);\n\n if (!item || itemIndex >= renderedItems.length) {\n chunkTrs.forEach(tr => {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n });\n continue;\n }\n\n const dataIndex = startIndex + itemIndex;\n\n chunkTrs.forEach((tr, subIdx) => {\n const virtualIndex = startIndex + itemIndex;\n tr.dataset.virtualIndex = virtualIndex;\n tr.dataset.row = (item.type === 'data') ? dataIndex : '';\n\n const isTrGroup = tr.getAttribute('grouping') === 'true';\n\n if (item.type === 'group') {\n if (isTrGroup) {\n const depth = item.record[GROUP_IDX.DEPTH];\n if (subIdx === depth) {\n tr.style.display = '';\n this.#bindGroupRowData(tr, allRenderItems, item.record, virtualIndex);\n } else {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n }\n } else {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n }\n } else {\n if (isTrGroup) {\n tr.style.display = 'none';\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.dataset.index = null;\n } else {\n tr.style.display = '';\n\n const rowid = item.record.m?.rowid ?? 0;\n this.#bindRowData(tr, item.record, rowid, virtualIndex);\n }\n }\n });\n }\n });\n\n this.#sheet.selection.refresh();\n };\n\n #bindGroupRowData = ($tr, allRenderItems, groupRecord, virtualIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (virtualIndex * templateLength) + subRowIndex;\n\n const indices = groupRecord[GROUP_IDX.CHILDREN];\n const allRecords = this.#host.data.getArray();\n const childrenRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n\n $tr.dataset.virtualIndex = virtualIndex;\n $tr.dataset.row = '';\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = childrenRecords;//groupRecord;\n $tr.dataset.groupId = groupRecord[GROUP_IDX.ID];\n\n\n Array.from($tr.cells).forEach(($cell) => {\n\n $cell.dataset.row = virtualIndex;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') || typeof $el.refresh === 'function'\n );\n\n\n if (customComp !== undefined && typeof customComp.refresh === 'function') {\n customComp?.refresh();\n }\n });\n };\n\n #bindRowData = ($tr, record, rowid, dataIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (dataIndex * templateLength) + subRowIndex;\n\n $tr.dataset.index = dataIndex;\n $tr.dataset.row = rowid;\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = record;\n\n Array.from($tr.cells).forEach(($cell) => {\n $cell.dataset.index = dataIndex;\n $cell.dataset.row = rowid;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.refresh === 'function'\n );\n\n customComp?.refresh();\n });\n };\n\n initialize = () => {\n\n this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n\n this.#cachedTemplateHeight = null;\n this.#containerTemplates.clear();\n\n this.#element = {\n scrollTables: this.#sheet.querySelectorAll('.ng-sheet-body table'),\n firstTr: this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body tr'),\n };\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const tableEl = container.querySelector('table');\n if (!tableEl) return;\n\n const tbody = tableEl.querySelector('tbody.body');\n if (!tbody) return;\n\n const trs = Array.from(tbody.querySelectorAll('tr'));\n const templateTrs = trs.map(tr => tr.cloneNode(true));\n this.#containerTemplates.set(selector, templateTrs);\n });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n if (bodyViewport) {\n this.#sheetHeight = bodyViewport.clientHeight;\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', (e) => {\n\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#cachedTemplateHeight || 0;\n const totalCount = this.#sheet.view.getArray()?.length || 0;\n const rawTotalVirtualHeight = totalCount * rowHeight;\n\n if (rawTotalVirtualHeight <= bodyViewport.clientHeight) {\n return;\n }\n\n this.#handleScroll(bodyViewport.scrollTop);\n\n this.#sheet.querySelector('nine-table-vscrollbar').refresh();\n\n }, { passive: true });\n }\n };\n\n scrollToDataRow(dataRow, align = 'top', onRendered) {\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords?.length || 0;\n\n const targetRow = Math.max(0, Math.min(dataRow, totalCount - 1));\n let targetScrollTop = 0;\n\n if (this.#isGrouped) {\n const maxScrollTop = Math.max(bodyViewport.scrollHeight - bodyViewport.clientHeight, 1);\n // targetRow가 전체 totalCount에서 차지하는 비율(ratio)만큼 실제 스크롤 최대 높이에 곱해줌\n const ratio = targetRow / Math.max(totalCount - 1, 1);\n targetScrollTop = ratio * maxScrollTop;\n } else {\n\n const rowHeight = this.#cachedTemplateHeight;\n const rawTargetScrollTop = targetRow * rowHeight;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = bodyViewport.offsetHeight || 0;\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + fixedHeight - viewHeight, 0);\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n }\n\n targetScrollTop = rawTargetScrollTop * scaleFactor;\n }\n\n this.#isProgrammaticScroll = true;\n bodyViewport.scrollTop = targetScrollTop;\n this.#handleScroll(targetScrollTop);\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.#isProgrammaticScroll = false;\n if (typeof onRendered === 'function') onRendered();\n });\n });\n }\n\n\n\n destroy = () => {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n };\n\n #measureAndCacheHeight = () => {\n if (!this.#sheet.classList.contains('active')) return;\n\n if (!this.#sheet.sourceTable) return;\n\n const trTemplates = this.#sheet.sourceTable?.querySelectorAll('tbody.body tr');\n\n const $tbody = this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body');\n\n $tbody.querySelectorAll('tr').forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n trTemplates.forEach($tr => fragment.appendChild($tr.cloneNode(true)));\n $tbody.appendChild(fragment);\n\n const renderedTrs = $tbody.querySelectorAll('tr');\n\n this.#templateRowHeights = [];\n renderedTrs.forEach($tr => {\n this.#templateRowHeights.push(Math.max($tr.offsetHeight, 24));\n });\n\n renderedTrs.forEach(tr => tr.remove());\n\n this.#cachedTemplateHeight = this.#templateRowHeights.reduce((sum, h) => sum + h, 0);\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n\n if (this.#sheetHeight > 0 && this.#cachedTemplateHeight > 0) {\n const visibleRows = Math.ceil(this.#sheetHeight / this.#cachedTemplateHeight);\n\n let dynamicBuffer = this.#BUFFER_ROW_COUNT;\n if (this.#isGrouped && this.#sheet.grouping) {\n const groupDepth = this.#sheet.grouping.columns?.length || 1;\n dynamicBuffer += (groupDepth * 15);\n }\n\n this.#cachedRowCount = visibleRows + dynamicBuffer;\n }\n };\n\n #renderAllContainers = () => {\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (container && container.querySelector('tbody')) {\n this.#renderRows(container);\n }\n });\n\n this.#syncRowHeights();\n };\n\n #renderRows = (container) => {\n let targetFixedType = null;\n if (container.classList.contains('ng-container-left')) targetFixedType = 'left';\n else if (container.classList.contains('ng-container-right')) targetFixedType = 'right';\n\n const templateTrs = Array.from(this.#sheet.sourceTable.querySelectorAll('tbody.body tr')).map(tr => {\n const clonedTr = tr.cloneNode(true);\n\n if (targetFixedType === 'left') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'left') $cell.remove();\n });\n } else if (targetFixedType === 'right') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'right') $cell.remove();\n });\n } else {\n clonedTr.querySelectorAll('[fixed=left], [fixed=right]').forEach($cell => {\n $cell.remove();\n });\n }\n\n return clonedTr;\n });\n\n if (templateTrs.length === 0) return;\n\n const targetTbody = container.querySelector('tbody.body');\n if (!targetTbody) return;\n\n targetTbody.querySelectorAll(\"tr\").forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < this.#cachedRowCount; i++) {\n templateTrs.forEach(tmpl => fragment.appendChild(tmpl.cloneNode(true)));\n }\n\n\n targetTbody.appendChild(fragment);\n\n if (container.classList.contains('ng-container-body')) {\n this.#element.firstTr = targetTbody.querySelector('tr');\n }\n };\n\n\n\n #syncRowHeights = () => {\n const leftTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-left table');\n const bodyTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-body table');\n const rightTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-right table');\n\n if (bodyTable) {\n const leftRows = leftTable ? Array.from(leftTable.querySelectorAll('tbody tr')) : [];\n const bodyRows = Array.from(bodyTable.querySelectorAll('tbody tr'));\n const rightRows = rightTable ? Array.from(rightTable.querySelectorAll('tbody tr')) : [];\n\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n }\n };\n\n #initResizeObserver = () => {\n\n if (!this.#sheet || !(this.#sheet instanceof HTMLElement)) return;\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n\n const sheetEl = entry.target;\n if (!sheetEl.classList.contains('active')) continue;\n\n const height = entry.contentRect.height;\n const width = entry.contentRect.width;\n\n if (width > 0 && this.#sheet.isAutoFitCol) {\n this.#sheet.autoFit(true);\n }\n\n if (height > 0 && this.#sheetHeight !== height) {\n this.#sheetHeight = height;\n this.#updateRowCount();\n\n if (this.#cachedTemplateHeight !== null) {\n this.#renderAllContainers();\n this.refresh();\n }\n }\n }\n });\n\n this.#resizeObserver.observe(this.#sheet);\n };\n}","import { trace } from \"@nopeer\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class TableCompiler {\n\n static compile($srcTable) {\n\n const $table = $srcTable.cloneNode(true);\n\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n static recompile($table) {\n\n\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n static #syncColAttributes($table) {\n\n $table.querySelectorAll('colgroup col').forEach(($col, i) => {\n $col.setAttribute('data-col', i);\n const fixed = $col.getAttribute('fixed');\n\n $table.querySelectorAll(`[data-col=\"${i}\"]`).forEach($el => {\n fixed ? $el.setAttribute('fixed', fixed) : $el.removeAttribute('fixed');\n });\n });\n }\n\n static resetColIndex($table, trs) {\n\n const cols = $table.querySelectorAll('colgroup col');\n const grid = Array.from({ length: trs.length }, () => Array(cols.length).fill(null));\n\n trs.forEach(($tr, index) => {\n\n $tr.dataset.subrow = index;\n\n let colIndex = 0;\n\n $tr.querySelectorAll('th, td').forEach($cell => {\n\n while (colIndex < cols.length && grid[index][colIndex] !== null) {\n colIndex++;\n }\n\n $cell.dataset.col = colIndex;\n\n const rowSpan = $cell.rowSpan || 1;\n const colSpan = $cell.colSpan || 1;\n\n for (let r = 0; r < rowSpan; r++) {\n for (let c = 0; c < colSpan; c++) {\n if (index + r < trs.length && colIndex + c < cols.length) {\n grid[index + r][colIndex + c] = $cell;\n }\n }\n }\n\n colIndex += colSpan;\n });\n });\n }\n\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellSelection {\r\n\t#sheet;\r\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#initEvents();\r\n\t}\r\n\r\n\t#getMatrixRow(tr) {\r\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst dataRow = parseInt(tr.dataset.index, 10);\r\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr'));\r\n\r\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.index, 10) === dataRow);\r\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\r\n\t\tconst templateLength = sameGroupTrs.length > 0 ? sameGroupTrs.length : 1;\r\n\r\n\t\tconst matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\r\n\r\n\t\treturn { dataRow, subRowIndex, matrixRow };\r\n\t}\r\n\r\n\tsetFocus(matrixRow, col) {\r\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {\r\n\t\t\t$tr.classList.remove(\"selected-start\");\r\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {\r\n\t\t\t\t$td.classList.remove(\"selected-start\");\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!$td) return;\r\n\r\n\t\t$td.classList.add(\"selected-start\");\r\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\r\n\t}\r\n\r\n\tsetRange(startRow, startCol, endRow, endCol) {\r\n\t\tlet r1 = Math.min(startRow, endRow);\r\n\t\tlet r2 = Math.max(startRow, endRow);\r\n\t\tlet c1 = Math.min(startCol, endCol);\r\n\t\tlet c2 = Math.max(startCol, endCol);\r\n\r\n\t\tconst containers = this.#sheet.querySelectorAll('.ng-container-left, .ng-container-body, .ng-container-right');\r\n\r\n\t\tlet expanded = true;\r\n\t\tlet loopCount = 0;\r\n\r\n\t\twhile (expanded && loopCount < 5) {\r\n\t\t\texpanded = false;\r\n\t\t\tloopCount++;\r\n\r\n\t\t\tcontainers.forEach(container => {\r\n\r\n\t\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\r\n\t\t\t\t\treturn tr.style.display !== 'none'; // 혹은 tr.offsetHeight > 0 체크\r\n\t\t\t\t});\r\n\r\n\t\t\t\tvisibleTrs.forEach(tr => {\r\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\r\n\r\n\t\t\t\t\t\tif (isIntersecting) {\r\n\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\r\n\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\r\n\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\r\n\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\r\n\r\n\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\r\n\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\r\n\t\t\t\t\t\t\t\texpanded = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#range = { startRow: r1, startCol: c1, endRow: r2, endCol: c2 };\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trefresh = () => {\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trender = () => {\r\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\r\n\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-container-left, .ng-container-body, .ng-container-right'\r\n\t\t);\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\r\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\r\n\t\t\t});\r\n\r\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\r\n\t\t\t\ttr.classList.remove('selected-start');\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tif (startRow < 0 || startCol < 0) return;\r\n\r\n\t\tcontainers.forEach((container) => {\r\n\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\r\n\t\t\t\treturn tr.style.display !== 'none';\r\n\t\t\t});\r\n\r\n\t\t\tvisibleTrs.forEach(tr => {\r\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\r\n\t\t\t\t\tif (!isSelected) return;\r\n\r\n\t\t\t\t\tcell.classList.add('selected');\r\n\r\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\r\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\r\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\r\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!mainZone) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmainZone.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\r\n\t\t\tthis.#sheet.style.userSelect = 'none';\r\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\r\n\r\n\t\t\tconst tr = cell.closest('tr');\r\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\r\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\r\n\r\n\t\t\tif (startRow < 0) {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tthis.setFocus(startRow, startCol);\r\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\r\n\r\n\t\t\tlet lastMatrixRow = startRow;\r\n\t\t\tlet lastCol = startCol;\r\n\r\n\t\t\tconst onMouseMove = (moveEvent) => {\r\n\t\t\t\tconst targetEl = document.elementFromPoint(moveEvent.clientX, moveEvent.clientY);\r\n\t\t\t\tlet targetCell = targetEl?.closest('td, th');\r\n\r\n\t\t\t\tif (!targetCell || !this.#sheet.contains(targetCell)) {\r\n\t\t\t\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr td, .ng-sheet-body-content tbody tr:not(.nodata) th');\r\n\t\t\t\t\tfor (const c of allCells) {\r\n\t\t\t\t\t\tconst rect = c.getBoundingClientRect();\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tmoveEvent.clientX >= rect.left &&\r\n\t\t\t\t\t\t\tmoveEvent.clientX <= rect.right &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY >= rect.top &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY <= rect.bottom\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\ttargetCell = c;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!targetCell) return;\r\n\t\t\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\r\n\r\n\t\t\t\tconst targetTr = targetCell.closest('tr');\r\n\t\t\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\r\n\t\t\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\r\n\r\n\t\t\t\tif (endRow < 0) return;\r\n\t\t\t\tif (lastMatrixRow === endRow && lastCol === endCol) return;\r\n\r\n\t\t\t\tlastMatrixRow = endRow;\r\n\t\t\t\tlastCol = endCol;\r\n\r\n\t\t\t\tthis.setRange(startRow, startCol, endRow, endCol);\r\n\t\t\t};\r\n\r\n\t\t\tconst onMouseUp = () => {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\r\n\t\t\t\tdocument.removeEventListener('mousemove', onMouseMove);\r\n\t\t\t\tdocument.removeEventListener('mouseup', onMouseUp);\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener('mousemove', onMouseMove);\r\n\t\t\tdocument.addEventListener('mouseup', onMouseUp);\r\n\t\t});\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellNavigation {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#currentCell = null;\r\n\t#currentTr = null;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.#initEvents();\r\n\t}\r\n\r\n\tget currentCell() {\r\n\t\treturn this.#currentCell;\r\n\t}\r\n\r\n\tset currentCell(cell) {\r\n\t\tif (!cell) return;\r\n\r\n\t\tthis.#currentCell = cell;\r\n\t\tcell.focus({ preventScroll: true });\r\n\r\n\t\tthis.#currentTr = cell.closest(\"tr\");\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\r\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\r\n\t}\r\n\r\n\r\n\t#moveCellH = (e, cell) => {\r\n\r\n\t\tif (!cell) return;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\r\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (!this.#isCellRightVisible(cell)) {\r\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tif (!this.#isCellRightVisible(cell)) {\r\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\r\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tthis.currentCell = cell;\r\n\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\r\n\t};\r\n\r\n\t#moveCellV = (e, cell) => {\r\n\t\tif (cell) {\r\n\t\t\tlet isVisible = false;\r\n\t\t\tswitch (e.code) {\r\n\t\t\t\tcase \"Enter\":\r\n\t\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\r\n\t\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\r\n\t\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"ArrowDown\":\r\n\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\r\n\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"ArrowUp\":\r\n\t\t\t\t\tif (this.#isCellAboveVisible(cell)) {\r\n\t\t\t\t\t\tisVisible = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tif (isVisible) {\r\n\t\t\t\tthis.currentCell = cell;\r\n\t\t\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\r\n\t\tlet scrollTopIndex = -1;\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"Enter\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tconst visibleRowCount = this.#getVisibleRowCount();\r\n\t\t\t\t\tscrollTopIndex = Math.max(dataIndex - visibleRowCount + 0, 0);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tscrollTopIndex = Math.min(dataIndex, this.#sheet.view.count());\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tscrollTopIndex = Math.min(dataIndex, this.#sheet.view.count());\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tconst visibleRowCount = this.#getVisibleRowCount();\r\n\t\t\t\tscrollTopIndex = Math.max(dataIndex - visibleRowCount + 0, 0);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tif (scrollTopIndex < 0) return;\r\n\r\n\t\tlet matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst rowSpan = parseInt(this.#currentCell.rowSpan, 10) || 1;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tmatrixRow += rowSpan;\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tmatrixRow --;\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.rowManager.scrollToDataRow(scrollTopIndex, null, () => {\r\n\t\t\tconst currentCell = this.#findCell(matrixRow, col);\r\n\r\n\t\t\tif (currentCell) {\r\n\t\t\t\tthis.currentCell = currentCell;\r\n\t\t\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, currentCell.dataset.col, this.#currentTr.dataset.matrixRow, currentCell.dataset.col);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tmoveCell = (e) => {\r\n\r\n\t\tif (e.target.tagName === \"INPUT\") {\r\n\t\t\tif ([\"text\"].includes(e.target.type)) {\r\n\t\t\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Home\",\"End\"].includes(e.code)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif ([\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(e.target.type)) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#currentCell || !this.#currentTr) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet nextCell;\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tnextCell = e.shiftKey ? this.#getPreviousCell() : this.#getNextCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tnextCell = this.#getNextCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tnextCell = this.#getPreviousCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Enter\":\r\n\t\t\t\tnextCell = e.shiftKey ? this.#getUpCell() : this.#getDownCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tnextCell = this.#getDownCell();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tnextCell = this.#getUpCell();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\te.preventDefault();\r\n\r\n\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Tab\"].includes(e.code)) {\r\n\t\t\tthis.#moveCellH(e, nextCell);\r\n\t\t}\r\n\t\telse if ([\"Enter\",\"ArrowUp\",\"ArrowDown\"].includes(e.code)) {\r\n\t\t\tthis.#moveCellV(e, nextCell);\r\n\t\t}\r\n\t}\r\n\r\n\t#getNextCell = () => {\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst colSpan = parseInt(this.#currentCell.colSpan, 10) || 1;\r\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\r\n\t\tconst nextCol = col + colSpan;\r\n\r\n\t\tlet nextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${nextCol}\"]`);\r\n\t\tif (!nextCell) {\r\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${nextCol}\"]`);\r\n\t\t}\r\n\r\n\t\treturn nextCell;\r\n\t}\r\n\r\n\t#getPreviousCell = () => {\r\n\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\r\n\t\tlet nextCell;\r\n\t\tfor (let i = col - 1; i >= 0; i--) {\r\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${i}\"]`);\r\n\t\t\tif (!nextCell) {\r\n\t\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${i}\"]`);\r\n\t\t\t}\r\n\r\n\t\t\tif (nextCell) break;\r\n\t\t}\r\n\r\n\t\treturn nextCell;\r\n\t}\r\n\r\n\r\n\r\n\t#findCell = (matrixRow, col) => {\r\n\r\n\t\tconst $tr = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"]`);\r\n\t\tif (!$tr) return;\r\n\r\n\t\tconst dataIndex = parseInt($tr.dataset.index, 10);\r\n\r\n\t\tlet targetCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!targetCell) {\r\n\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-matrix-row=\"${matrixRow}\"] td`).forEach($cell => {\r\n\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\r\n\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\r\n\r\n\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\r\n\t\t\t\t\ttargetCell = $cell;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tif (!targetCell) {\r\n\t\t\t\ttargetCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${col}\"]`);\r\n\r\n\t\t\t\tif (!targetCell) {\r\n\t\t\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-index=\"${dataIndex}\"] td`).forEach($cell => {\r\n\t\t\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\r\n\r\n\t\t\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\r\n\t\t\t\t\t\t\ttargetCell = $cell;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn targetCell;\r\n\t}\r\n\r\n\t#getUpCell = () => {\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\r\n\t\treturn this.#findCell(matrixRow - 1, col);\r\n\t}\r\n\r\n\t#getDownCell = () => {\r\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\r\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\r\n\t\tconst rowSpan = parseInt(this.#currentCell.rowSpan, 10) || 1;\r\n\r\n\t\treturn this.#findCell(matrixRow + rowSpan, col);\r\n\t}\r\n\r\n\t// 1. 위쪽 잘림 체크 (기준: bodyViewport)\r\n\t#isCellAboveVisible = (cell) => {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!bodyViewport || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\t\tconst theadHeight = bodyViewport.querySelector('thead')?.offsetHeight || 0;\r\n\r\n\t\t// 셀의 상단이 헤더 아래쪽보다 위에 있으면 잘린(안 보이는) 상태\r\n\t\treturn cellRect.top >= (viewportRect.top + theadHeight);\r\n\t}\r\n\r\n\t// 2. 아래쪽 잘림 체크 (기준: bodyViewport)\r\n\t#isCellBelowVisible = (cell) => {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!bodyViewport || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\r\n\t\t// 셀의 하단이 뷰포트 하단보다 아래에 있으면 잘린 상태\r\n\t\treturn cellRect.bottom <= viewportRect.bottom;\r\n\t}\r\n\r\n\t// 3. 왼쪽 잘림 체크 (기준: bodyViewport2)\r\n\t#isCellLeftVisible = (cell) => {\r\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body'); // 또는 좌우 스크롤을 담당하는 뷰포트\r\n\t\tif (!bodyViewport2 || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\r\n\r\n\t\t// 셀의 좌측이 뷰포트 좌측보다 왼쪽에 있으면 잘린 상태\r\n\t\treturn cellRect.left >= viewportRect.left;\r\n\t}\r\n\r\n\t// 4. 오른쪽 잘림 체크 (기준: bodyViewport2)\r\n\t#isCellRightVisible = (cell) => {\r\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body');\r\n\t\tif (!bodyViewport2 || !cell) return true;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\r\n\r\n\t\t// 셀의 우측이 뷰포트 우측보다 오른쪽에 있으면 잘린 상태\r\n\t\treturn cellRect.right <= viewportRect.right;\r\n\t}\r\n\r\n\t// 💡 필요하다면 이 4개를 조합해서 전체 가시성을 판단하는 통합 함수도 쉽게 구성할 수 있습니다.\r\n\t#isCellVisible = (cell) => {\r\n\t\treturn this.#isCellAboveVisible(cell) &&\r\n\t\t\tthis.#isCellBelowVisible(cell) &&\r\n\t\t\tthis.#isCellLeftVisible(cell) &&\r\n\t\t\tthis.#isCellRightVisible(cell);\r\n\t}\r\n\r\n\t#getVisibleRowCount = () => {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tconst viewportHeight = bodyViewport.clientHeight - (bodyViewport.querySelector('thead')?.offsetHeight || 0);\r\n\t\tconst rowHeight = this.#sheet.rowManager.getRowHeight();\r\n\r\n\t\t// 뷰포트 높이에 들어오는 행 개수 계산 (소수점 버림)\r\n\t\treturn Math.max(1, Math.floor(viewportHeight / rowHeight));\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.index === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tthis.currentCell = cell;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\r\n\t\t\tif ([\"Enter\", \"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\r\n\t\t\t\tthis.moveCell(e);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}","// ui/col/ColResizer.js\nimport { trace } from \"@nopeer\";\nimport { COLLAPSED_WIDTH } from \"@/layout/core/TableCompiler.js\";\n\nconst RESIZE_OFFSET = 2; // 🎯 리사이즈 감지 영역 오프셋을 상단으로 추출\n\nexport class ColResizer {\n #sheet;\n #host;\n #panel;\n #tooltip;\n\n #targetColIndex = null;\n #nextColIndex = null;\n #targetContainerType = null;\n #targetCell = null;\n #startX = 0;\n #startColWidth = 0;\n #nextColStartWidth = 0;\n #startCellWidth = 0;\n #startLeft = 0;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#host = sheet.getRootNode().host;\n this.#panel = this.#sheet.querySelector('nine-table-col-resizer-panel');\n\n this.#tooltip = this.#panel.querySelector('.resizer-overlay');\n this.bindEvents();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointermove', this.#onPointerMove);\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n this.#sheet.removeEventListener('dblclick', this.#onDblClick);\n }\n\n refreshLayout(containerType = 'body') {\n const containers = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType}`));\n if (containers.length === 0) return;\n\n const isFixedContainer = containerType === 'left' || containerType === 'right';\n const isAutoFit = !isFixedContainer && (\n this.#sheet.isAutoFitCol ||\n containers[0].querySelector('table')?.getAttribute('auto-fit-col') === 'true'\n );\n\n if (!isAutoFit) {\n\n const firstColgroup = containers[0].querySelector('table colgroup');\n if (!firstColgroup) return;\n\n let totalWidth = 0;\n const colWidths = {};\n\n Array.from(firstColgroup.querySelectorAll('col')).forEach(col => {\n const colIdx = col.getAttribute('data-col');\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) {\n colWidths[colIdx] = w;\n totalWidth += w;\n }\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n\n if (containerType === 'body') {\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n //tbl.style.minWidth = `${totalWidth}px`;\n });\n } else {\n container.style.flex = `0 0 ${totalWidth}px`;\n container.style.width = `${totalWidth}px`;\n container.style.minWidth = `${totalWidth}px`;\n container.style.maxWidth = `${totalWidth}px`;\n\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n tbl.style.minWidth = `${totalWidth}px`;\n tbl.style.maxWidth = `${totalWidth}px`;\n\n Object.entries(colWidths).forEach(([colIdx, w]) => {\n tbl.querySelectorAll(`th[data-col=\"${colIdx}\"], td[data-col=\"${colIdx}\"]`).forEach(cell => {\n cell.style.width = `${w}px`;\n cell.style.minWidth = `${w}px`;\n cell.style.maxWidth = `${w}px`;\n });\n });\n });\n }\n });\n } else {\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n tables.forEach(tbl => {\n //tbl.style.width = '100%';\n //tbl.style.minWidth = '100%';\n //tbl.style.maxWidth = '';\n });\n });\n }\n\n this.#sheet.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n setColumnWidth(globalColIndex, width, containerType = null) {\n\n let targetCols = [];\n\n targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n\n if (targetCols.length === 0) return;\n\n const firstContainer = targetCols[0].closest('.ng-container-left, .ng-container-body, .ng-container-right');\n const resolvedContainerType = containerType || (\n firstContainer?.classList.contains('ng-container-left') ? 'left' :\n firstContainer?.classList.contains('ng-container-right') ? 'right' : 'body'\n );\n\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n });\n\n const sourceCol = this.#sheet.sourceTable?.querySelector(`colgroup col[data-col=\"${globalColIndex}\"]`);\n if (sourceCol) {\n sourceCol.setAttribute('width', width);\n sourceCol.style.width = `${width}px`;\n }\n\n this.refreshLayout(resolvedContainerType);\n\n if (resolvedContainerType === 'left' || resolvedContainerType === 'right') {\n this.refreshLayout('body');\n }\n\n this.#sheet.rowManager?.refresh();\n }\n\n #checkIsAutoFit(targetCell) {\n if (this.#sheet.isAutoFitCol) return true;\n const table = targetCell?.closest('table');\n if (table && table.getAttribute('auto-fit-col') === 'true') return true;\n return false;\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointermove', this.#onPointerMove);\n //this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n //this.#sheet.addEventListener('dblclick', this.#onDblClick);\n\n this.#sheet.addDebounseEventListener('dblclick', this.#onDblClick, 'pointerdown', this.#onPointerDown);\n }\n\n #getContainerType(cell) {\n const container = cell.closest('.ng-container-left, .ng-container-body, .ng-container-right');\n if (!container) return null;\n if (container.classList.contains('ng-container-left')) return 'left';\n if (container.classList.contains('ng-container-right')) return 'right';\n return 'body';\n }\n\n #onPointerMove = (e) => {\n\n\n const headerPart = e.target.closest('thead');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n\n headerPart.querySelectorAll('.resizable-edge').forEach(el => {\n if (el !== cell) el.classList.remove('resizable-edge');\n });\n\n if (!cell || cell.dataset.col === undefined) return;\n if (cell.getAttribute('collapsed') === 'true') return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n const isLeftEdge = offsetX <= RESIZE_OFFSET;\n const isRightEdge = (rect.width - offsetX) <= RESIZE_OFFSET;\n\n if (isLeftEdge) {\n const prevCell = cell.previousElementSibling;\n if (!prevCell || prevCell.getAttribute('collapsed') === 'true') {\n cell.classList.remove('resizable-edge');\n return;\n }\n }\n\n if (isLeftEdge || isRightEdge) {\n cell.classList.add('resizable-edge');\n } else {\n cell.classList.remove('resizable-edge');\n }\n };\n\n #onPointerDown = (e) => {\n\n const headerPart = e.actualTarget.closest('thead');\n if (!headerPart) return;\n\n const cell = e.actualTarget.closest('th, td');\n\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n\n\n e.preventDefault();\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n let targetCell = cell;\n\n if (offsetX <= RESIZE_OFFSET) {\n const prevCell = cell.previousElementSibling;\n if (prevCell && prevCell.dataset.col !== undefined && prevCell.getAttribute('collapsed') !== 'true') {\n targetCell = prevCell;\n } else if (!cell.previousElementSibling) {\n return;\n }\n }\n\n this.#targetCell = targetCell;\n this.#targetContainerType = this.#getContainerType(targetCell);\n\n const container = this.#sheet.querySelector(`.ng-container-${this.#targetContainerType}`);\n if (!container) return;\n\n const baseColIndex = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n this.#targetColIndex = baseColIndex + colSpan - 1;\n\n const isAutoFit = this.#checkIsAutoFit(targetCell);\n if (isAutoFit) {\n this.#nextColIndex = this.#targetColIndex + 1;\n const nextColEl = container.querySelector(`col[data-col=\"${this.#nextColIndex}\"]`);\n if (nextColEl) {\n this.#nextColStartWidth = parseInt(nextColEl.getAttribute('width'), 10) || 100;\n } else {\n this.#nextColIndex = null;\n }\n } else {\n this.#nextColIndex = null;\n }\n\n const targetRect = targetCell.getBoundingClientRect();\n const sheetRect = this.#sheet.getBoundingClientRect();\n\n this.#startCellWidth = targetRect.width;\n this.#startLeft = targetRect.left - sheetRect.left;\n\n const targetColEl = container.querySelector(`col[data-col=\"${this.#targetColIndex}\"]`);\n const attrW = targetColEl?.getAttribute('width');\n this.#startColWidth = (attrW && !isNaN(parseInt(attrW, 10))) ? parseInt(attrW, 10) : targetRect.width / colSpan;\n\n this.#startX = e.clientX;\n\n if (this.#panel) {\n this.#panel.classList.add('active');\n this.#updatePositions(e.clientX);\n }\n\n window.addEventListener('pointermove', this.#onDragMove);\n window.addEventListener('pointerup', this.#onDragEnd, { once: true });\n };\n\n #updatePositions(clientX) {\n let diff = clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxDiff = this.#nextColStartWidth - COLLAPSED_WIDTH;\n const minDiff = -(this.#startColWidth - COLLAPSED_WIDTH);\n diff = Math.max(minDiff, Math.min(diff, maxDiff));\n }\n\n const currentColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n\n const targetRect = this.#targetCell.getBoundingClientRect();\n let realCellWidth = clientX - targetRect.left;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxCellWidth = this.#startCellWidth + (this.#nextColStartWidth - COLLAPSED_WIDTH);\n realCellWidth = Math.min(realCellWidth, maxCellWidth);\n }\n\n const currentCellWidth = Math.max(COLLAPSED_WIDTH, realCellWidth);\n\n if (this.#panel) {\n this.#panel.style.setProperty('--col-resizer-tooltip-left', `${this.#startLeft}px`);\n this.#panel.style.setProperty('--col-resizer-tooltip-width', `${currentCellWidth}px`);\n }\n\n const sizeBadge = this.#tooltip?.querySelector('.size-badge');\n if (sizeBadge) {\n sizeBadge.textContent = `${Math.round(currentColWidth)}px`;\n }\n }\n\n #onDragMove = (e) => {\n this.#updatePositions(e.clientX);\n };\n\n #onDragEnd = (e) => {\n window.removeEventListener('pointermove', this.#onDragMove);\n\n const diff = e.clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n let finalWidth = 0;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n let newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n let newNextWidth = this.#startColWidth + this.#nextColStartWidth - newColWidth;\n\n if (newNextWidth < COLLAPSED_WIDTH) {\n newNextWidth = COLLAPSED_WIDTH;\n newColWidth = this.#startColWidth + this.#nextColStartWidth - COLLAPSED_WIDTH;\n }\n\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n this.setColumnWidth(this.#nextColIndex, newNextWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n } else {\n const newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n if (this.#targetColIndex !== null && this.#targetContainerType) {\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n }\n }\n\n if (this.#targetCell) {\n const targetCell = this.#targetCell;\n if (targetCell.getAttribute('collapsed') !== 'true' && finalWidth > 20) {\n targetCell.dataset.expandWidth = String(finalWidth);\n }\n }\n\n if (this.#panel) {\n this.#tooltip?.classList.add('fade-out');\n setTimeout(() => {\n this.#panel.classList.remove('active');\n this.#tooltip?.classList.remove('fade-out');\n }, 150);\n }\n\n this.#targetColIndex = null;\n this.#nextColIndex = null;\n this.#targetContainerType = null;\n this.#targetCell = null;\n };\n\n #onDblClick = (e) => {\n\n const targetEl = e.target;\n let cell = targetEl.closest('th, td');\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n if (offsetX <= RESIZE_OFFSET) {\n cell = cell.previousElementSibling;\n }\n\n const baseColIndex = parseInt(cell.dataset.col, 10);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${baseColIndex}\"]`);\n if (!tbodyCell || !tbodyCell.dataset.bind || tbodyCell.classList.contains(\"CELL-RADIO\")) return;\n\n let extraPadding = 0;\n Array.from(tbodyCell.firstElementChild.children).forEach(($el) => {\n switch ($el.tagName) {\n case 'SPAN': extraPadding += 8; break;\n case 'DIV': extraPadding += 8; break;\n case 'BUTTON': extraPadding += 32; break;\n case 'SELECT': extraPadding += 32; break;\n case 'INPUT':\n switch (($el.type || 'text').toLowerCase()) {\n // 1. 체크박스 / 라디오 (비교적 좁은 영역)\n case 'checkbox':\n case 'radio':\n extraPadding += 12;\n break;\n\n // 2. 버튼 계열 input\n case 'button':\n case 'submit':\n case 'reset':\n case 'image':\n extraPadding += 16;\n break;\n\n // 3. 특수 위젯 (컬러, 파일, 슬라이더)\n case 'color':\n case 'file':\n case 'range':\n extraPadding += 24;\n break;\n\n // 4. 화면에 안 보이는 hidden 필드\n case 'hidden':\n extraPadding += 0;\n break;\n\n // 5. 텍스트 및 숫자, 날짜 등 일반 입력 필드 (기본값)\n case 'text':\n case 'search':\n case 'tel':\n case 'url':\n case 'email':\n case 'password':\n case 'number':\n case 'date':\n case 'time':\n case 'datetime-local':\n case 'month':\n case 'week':\n default:\n extraPadding += 16;\n break;\n }\n break;\n }\n });\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n\n const headerText = cell.innerText || \"\";\n const headerSize = nine.measureTextSize(headerText, font);\n let maxTextWidth = (headerSize.width || 0) + 16;\n\n this.#host.execute(() => {\n\n this.#sheet.view.getArray().forEach((record, idx) => {\n const val = String(tbodyCell.dataset.expr ? this.#host.exprEngine.evaluate(tbodyCell.dataset.expr, record, idx) : record.v[fieldIdx] ?? \"\").trim();\n const size = nine.measureTextSize(val, font);\n if (size.width && size.width > maxTextWidth) {\n maxTextWidth = size.width;\n }\n });\n\n const calculatedWidth = Math.max(32, Math.min(400, Math.ceil(maxTextWidth) + extraPadding));\n\n this.setColumnWidth(tbodyCell.dataset.col, calculatedWidth, this.#getContainerType(cell));\n })\n };\n}\n\n\nexport class ColResizerPanel extends HTMLElement {\n #target;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n this.#renderer();\n }\n\n #renderer = () => {\n this.innerHTML = `\n <div class=\"resizer-overlay\">\n <span class=\"size-badge\">0px</span>\n </div>\n `;\n };\n}\n\nif (!customElements.get('nine-table-col-resizer-panel')) {\n customElements.define(\"nine-table-col-resizer-panel\", ColResizerPanel);\n}\n","// ui/col/ColMover.js\nimport { trace } from \"@nopeer\";\n\nexport class ColMover {\n #sheet;\n #grip;\n #indi;\n\n #isDragging = false;\n #sourceCell = null;\n #sourceColIndex = null;\n #targetColIndex = null;\n #shiftX = 0;\n #timer = null;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#grip = this.#sheet.querySelector('.ng-col-mover-grip');\n this.#indi = this.#sheet.querySelector('.ng-col-mover-indi');\n this.bindEvents();\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n }\n\n #checkIsMovable() {\n const host = this.#sheet.getRootNode()?.host;\n return this.#sheet.getAttribute('col-movable') === 'true' || host?.getAttribute('col-movable') === 'true';\n }\n\n #getDeepElementFromPoint(x, y) {\n const root = this.#sheet.getRootNode();\n let el = root.elementFromPoint ? root.elementFromPoint(x, y) : document.elementFromPoint(x, y);\n\n while (el && el.shadowRoot && el.shadowRoot.elementFromPoint) {\n const nested = el.shadowRoot.elementFromPoint(x, y);\n if (!nested || nested === el) break;\n el = nested;\n }\n\n return el;\n }\n\n #getColGroupRange(cell) {\n if (!cell || cell.dataset.col === undefined) return null;\n\n const startCol = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const endCol = startCol + colSpan - 1;\n const rowIndex = cell.closest('tr')?.sectionRowIndex ?? 0;\n\n const table = cell.closest('table');\n if (!table) return { startCol, colSpan, endCol, rowIndex, isGroup: false, parentGroupRange: null, isValidGroup: true };\n\n const headerCells = table.querySelectorAll('thead th, thead td');\n let hasStrictChildren = false;\n let isValidGroup = true;\n let parentGroupRange = null;\n\n for (const subCell of headerCells) {\n if (subCell === cell || subCell.dataset.col === undefined) continue;\n\n const subStart = parseInt(subCell.dataset.col, 10);\n const subSpan = subCell.colSpan || 1;\n const subEnd = subStart + subSpan - 1;\n const subRowIndex = subCell.closest('tr')?.sectionRowIndex ?? 0;\n\n if (subRowIndex < rowIndex && subStart <= startCol && subEnd >= endCol && subSpan > colSpan) {\n if (!parentGroupRange) {\n parentGroupRange = { startCol: subStart, endCol: subEnd };\n } else {\n parentGroupRange.startCol = Math.max(parentGroupRange.startCol, subStart);\n parentGroupRange.endCol = Math.min(parentGroupRange.endCol, subEnd);\n }\n }\n\n const isOverlap = !(subEnd < startCol || subStart > endCol);\n if (isOverlap) {\n const isFullyContained = (subStart >= startCol && subEnd <= endCol);\n\n if (isFullyContained) {\n if (subSpan < colSpan) {\n hasStrictChildren = true;\n }\n } else if (subStart < startCol || subEnd > endCol) {\n if (!(subStart <= startCol && subEnd >= endCol)) {\n isValidGroup = false;\n }\n }\n }\n }\n\n const isRealGroup = hasStrictChildren && isValidGroup;\n\n return {\n startCol,\n colSpan: isRealGroup ? colSpan : 1,\n endCol: isRealGroup ? endCol : startCol,\n rowIndex,\n isGroup: isRealGroup,\n parentGroupRange,\n isValidGroup\n };\n }\n\n #createGroupHeaderPreview(cell) {\n const groupRange = this.#getColGroupRange(cell);\n if (!groupRange) return null;\n\n const { startCol, endCol, isGroup } = groupRange;\n\n // 핵심: 테이블이 여러 개인 구조이므로 cell이 속한 바로 그 테이블을 직접 가져옵니다.\n const origTable = cell.closest('table');\n if (!origTable) return null;\n\n let minLeft = Infinity, maxRight = -Infinity, minTop = Infinity, maxBottom = -Infinity;\n const targetCells = [];\n\n origTable.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n const isTarget = isGroup\n ? (cCol >= startCol && cEnd <= endCol)\n : (c === cell);\n\n if (isTarget) {\n const rect = c.getBoundingClientRect();\n minLeft = Math.min(minLeft, rect.left);\n maxRight = Math.max(maxRight, rect.right);\n minTop = Math.min(minTop, rect.top);\n maxBottom = Math.max(maxBottom, rect.bottom);\n\n const computedStyle = window.getComputedStyle(c);\n targetCells.push({ el: c, rect, style: computedStyle });\n }\n });\n\n if (targetCells.length === 0) return null;\n\n const groupWidth = maxRight - minLeft;\n const groupHeight = maxBottom - minTop;\n\n const headerContent = document.createElement('div');\n headerContent.className = 'grip-header-content';\n headerContent.style.position = 'relative';\n headerContent.style.width = `${groupWidth}px`;\n headerContent.style.height = `${groupHeight}px`;\n\n targetCells.forEach(({ el, rect, style }) => {\n const clonedCell = el.cloneNode(true);\n\n clonedCell.style.position = 'absolute';\n clonedCell.style.left = `${rect.left - minLeft}px`;\n clonedCell.style.top = `${rect.top - minTop}px`;\n\n clonedCell.style.width = `${rect.width}px`;\n clonedCell.style.minWidth = `${rect.width}px`;\n clonedCell.style.maxWidth = 'none';\n\n clonedCell.style.height = `${rect.height}px`;\n clonedCell.style.boxSizing = 'border-box';\n clonedCell.style.margin = '0';\n\n clonedCell.style.backgroundColor = style.backgroundColor !== 'transparent' && style.backgroundColor !== 'rgba(0, 0, 0, 0)'\n ? style.backgroundColor\n : '#f9fafb';\n clonedCell.style.color = style.color;\n clonedCell.style.font = style.font;\n clonedCell.style.fontWeight = style.fontWeight;\n clonedCell.style.fontSize = style.fontSize;\n clonedCell.style.textAlign = style.textAlign;\n clonedCell.style.padding = style.padding;\n clonedCell.style.border = style.border;\n clonedCell.style.borderRight = style.borderRight;\n clonedCell.style.borderBottom = style.borderBottom;\n clonedCell.style.display = 'flex';\n clonedCell.style.alignItems = 'center';\n clonedCell.style.justifyContent = style.textAlign === 'center' ? 'center' : (style.textAlign === 'right' ? 'flex-end' : 'flex-start');\n\n headerContent.appendChild(clonedCell);\n });\n\n return {\n element: headerContent,\n bounds: {\n left: minLeft,\n right: maxRight,\n top: minTop,\n bottom: maxBottom,\n width: groupWidth,\n height: groupHeight\n }\n };\n }\n\n #onPointerDown = (e) => {\n if (!this.#checkIsMovable()) return;\n\n const headerPart = e.target.closest('.ng-sheet-header');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n if (!cell || cell.classList.contains('resizable-edge') || ['INPUT', 'BUTTON'].includes(e.target.tagName)) return;\n if (cell.dataset.col === undefined) return;\n\n e.preventDefault();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cancelTimer = () => {\n if (this.#timer) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n window.removeEventListener('pointermove', onPointerMovePending);\n window.removeEventListener('pointerup', cancelTimer);\n window.removeEventListener('pointercancel', cancelTimer);\n };\n\n const onPointerMovePending = (moveEvent) => {\n const dist = Math.hypot(moveEvent.clientX - startX, moveEvent.clientY - startY);\n if (dist > 5) {\n cancelTimer();\n }\n };\n\n this.#timer = setTimeout(() => {\n cancelTimer();\n this.#startDrag(e, cell);\n }, 500);\n\n window.addEventListener('pointermove', onPointerMovePending);\n window.addEventListener('pointerup', cancelTimer, { once: true });\n window.addEventListener('pointercancel', cancelTimer, { once: true });\n };\n\n #startDrag(e, cell) {\n if (this.#isDragging) return;\n\n const preview = this.#createGroupHeaderPreview(cell);\n if (!preview) return;\n\n this.#isDragging = true;\n this.#sourceCell = cell;\n this.#sourceColIndex = parseInt(cell.dataset.col, 10);\n\n const sheetRect = this.#sheet.getBoundingClientRect();\n const { bounds, element } = preview;\n\n this.#shiftX = e.clientX - bounds.left;\n\n if (this.#grip) {\n this.#grip.replaceChildren(element);\n\n const relativeTop = bounds.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#grip.style.width = `${bounds.width}px`;\n this.#grip.style.height = `${fullHeight}px`;\n this.#grip.style.top = `${relativeTop}px`;\n this.#grip.style.display = 'block';\n\n this.#updateGripPosition(e.clientX);\n }\n\n document.body.style.cursor = 'move';\n\n window.addEventListener('pointermove', this.#onPointerMove);\n window.addEventListener('pointerup', this.#onPointerUp, { once: true });\n }\n\n #onPointerMove = (e) => {\n if (!this.#isDragging) return;\n\n this.#updateGripPosition(e.clientX);\n\n if (this.#grip) this.#grip.style.pointerEvents = 'none';\n if (this.#indi) this.#indi.style.pointerEvents = 'none';\n\n const targetElement = this.#getDeepElementFromPoint(e.clientX, e.clientY);\n const targetCell = targetElement?.closest('.ng-sheet-header th, .ng-sheet-header td');\n\n if (targetCell && targetCell.dataset.col !== undefined) {\n const targetColIndex = parseInt(targetCell.dataset.col, 10);\n const sheetRect = this.#sheet.getBoundingClientRect();\n const table = targetCell.closest('table');\n\n let colMinLeft = Infinity;\n let colMaxRight = -Infinity;\n\n if (table) {\n table.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n if (cCol <= targetColIndex && cEnd >= targetColIndex) {\n const cRect = c.getBoundingClientRect();\n colMinLeft = Math.min(colMinLeft, cRect.left);\n colMaxRight = Math.max(colMaxRight, cRect.right);\n }\n });\n }\n\n if (colMinLeft === Infinity) {\n const rect = targetCell.getBoundingClientRect();\n colMinLeft = rect.left;\n colMaxRight = rect.right;\n }\n\n const midX = colMinLeft + ((colMaxRight - colMinLeft) / 2);\n let calculatedTargetCol = 0;\n let indicatorLeft = 0;\n\n if (e.clientX < midX) {\n calculatedTargetCol = targetColIndex;\n indicatorLeft = colMinLeft - sheetRect.left;\n } else {\n const colSpan = targetCell.colSpan || 1;\n calculatedTargetCol = targetColIndex + colSpan;\n indicatorLeft = colMaxRight - sheetRect.left;\n }\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n const movingSpan = sourceGroup.colSpan;\n\n const sourceRowStart = sourceGroup.rowIndex;\n const sourceRowSpan = this.#sourceCell.rowSpan || 1;\n const sourceRowEnd = sourceRowStart + sourceRowSpan - 1;\n\n const targetRowStart = targetCell.closest('tr')?.sectionRowIndex ?? 0;\n const targetRowSpan = targetCell.rowSpan || 1;\n const targetRowEnd = targetRowStart + targetRowSpan - 1;\n\n const isRowSpanCompatible = !(sourceRowEnd < targetRowStart || sourceRowStart > targetRowEnd);\n\n let isOutOfBoundsOfParent = false;\n if (sourceGroup.parentGroupRange) {\n const { startCol: pStart, endCol: pEnd } = sourceGroup.parentGroupRange;\n if (calculatedTargetCol < pStart || (calculatedTargetCol + movingSpan - 1) > pEnd) {\n isOutOfBoundsOfParent = true;\n }\n }\n\n let isDroppingInsideOtherGroup = false;\n if (table) {\n const spannedCells = table.querySelectorAll('thead th[colspan], thead td[colspan]');\n\n for (const sCell of spannedCells) {\n if (sCell === this.#sourceCell) continue;\n\n const sRowStart = sCell.closest('tr')?.sectionRowIndex ?? 0;\n const sRowSpan = sCell.rowSpan || 1;\n const sRowEnd = sRowStart + sRowSpan - 1;\n\n const isVerticalOverlap = !(sourceRowEnd < sRowStart || sourceRowStart > sRowEnd);\n if (!isVerticalOverlap) continue;\n\n const sStart = parseInt(sCell.dataset.col, 10);\n const sSpan = sCell.colSpan || 1;\n const sEnd = sStart + sSpan - 1;\n\n if (calculatedTargetCol > sStart && calculatedTargetCol < sEnd + 1) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n\n const moveEndCol = calculatedTargetCol + movingSpan - 1;\n const isCrossIntersecting = (\n (calculatedTargetCol > sStart && calculatedTargetCol <= sEnd && moveEndCol > sEnd) ||\n (calculatedTargetCol < sStart && moveEndCol >= sStart && moveEndCol < sEnd)\n );\n\n if (isCrossIntersecting) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n }\n }\n\n const isSelfGroup = (\n calculatedTargetCol >= sourceGroup.startCol &&\n calculatedTargetCol <= sourceGroup.endCol + 1\n );\n\n const isInvalidMove = !isRowSpanCompatible || isSelfGroup || isOutOfBoundsOfParent || isDroppingInsideOtherGroup || !sourceGroup.isValidGroup;\n\n if (isInvalidMove) {\n this.#targetColIndex = null;\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n } else {\n this.#targetColIndex = calculatedTargetCol;\n if (this.#grip) this.#grip.classList.remove('invalid');\n\n if (this.#indi) {\n const headerPart = targetCell.closest('.ng-sheet-header');\n const headerRect = headerPart.getBoundingClientRect();\n const relativeTop = headerRect.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#indi.style.top = `${relativeTop}px`;\n this.#indi.style.height = `${fullHeight}px`;\n this.#indi.style.left = `${indicatorLeft - 1}px`;\n this.#indi.style.display = 'block';\n }\n }\n } else {\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n this.#targetColIndex = null;\n }\n };\n\n #updateGripPosition(clientX) {\n if (!this.#grip) return;\n const sheetRect = this.#sheet.getBoundingClientRect();\n const left = clientX - sheetRect.left - this.#shiftX;\n this.#grip.style.left = `${left}px`;\n }\n\n #onPointerUp = (e) => {\n if (!this.#isDragging) return;\n\n window.removeEventListener('pointermove', this.#onPointerMove);\n document.body.style.cursor = '';\n\n if (this.#grip) {\n this.#grip.style.display = 'none';\n this.#grip.replaceChildren();\n }\n if (this.#indi) this.#indi.style.display = 'none';\n\n if (\n this.#targetColIndex !== null &&\n this.#sourceColIndex !== null &&\n this.#targetColIndex !== this.#sourceColIndex &&\n this.#targetColIndex !== this.#sourceColIndex + 1\n ) {\n this.moveColumn(this.#sourceColIndex, this.#targetColIndex);\n }\n\n this.#isDragging = false;\n this.#sourceCell = null;\n this.#sourceColIndex = null;\n this.#targetColIndex = null;\n };\n\n moveColumn(fromColIndex, toColIndex) {\n\n const colgroup = this.#sheet.sourceTable.querySelector('colgroup');\n const targetCol = colgroup.querySelector(`col[data-col=\"${toColIndex}\"]`);\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n if (!sourceGroup || !sourceGroup.isValidGroup) return;\n\n const spanCount = sourceGroup.colSpan;\n const isInRange = (idx) => idx >= fromColIndex && idx < fromColIndex + spanCount;\n\n // 1. colgroup 내 <col> 이동 및 fixed 설정\n const targetViewportCol = this.#sheet.querySelector(`.ng-sheet-body-content col[data-col=\"${toColIndex}\"]`);\n const fixedType = targetViewportCol?.closest('.ng-container-left') ? 'left' : targetViewportCol?.closest('.ng-container-right') ? 'right' : null;\n\n colgroup.querySelectorAll('col').forEach(col => {\n if (isInRange(parseInt(col.getAttribute('data-col'), 10))) {\n fixedType ? col.setAttribute('fixed', fixedType) : col.removeAttribute('fixed');\n colgroup.insertBefore(col, targetCol);\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n this.#sheet.sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n const cells = Array.from(tr.children);\n const targetRowCell = cells.find(c => parseInt(c.dataset.col, 10) >= toColIndex);\n\n cells.forEach(cell => {\n if (isInRange(parseInt(cell.dataset.col, 10))) {\n tr.insertBefore(cell, targetRowCell || null);\n }\n });\n });\n });\n\n this.#sheet.recompileAndRefresh();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n }\n}","// ui/col/ColFixManager.js\nimport { trace } from \"@nopeer\";\n\nexport class ColFixManager {\n #sheet;\n\n constructor(sheet) {\n this.#sheet = sheet;\n }\n\n getFixState(targetCell, table) {\n if (!targetCell || !table) return 'none';\n\n const container = targetCell.closest('.ng-container-left, .ng-container-right, .ng-container-body');\n if (container?.classList.contains('ng-container-left')) return 'left';\n if (container?.classList.contains('ng-container-right')) return 'right';\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n if (!isNaN(baseCol)) {\n const colEl = table.querySelector(`colgroup col[data-col=\"${baseCol}\"]`);\n const fixedAttr = colEl?.getAttribute('fixed');\n if (fixedAttr) return fixedAttr;\n }\n\n return 'none';\n }\n\n canFixColumn(targetCell, table) {\n if (!targetCell || targetCell.tagName !== 'TH' || !table) return false;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n if (isNaN(baseCol)) return false;\n\n const targetBoundaryCol = baseCol + colSpan - 1;\n const theadTrs = Array.from(table.querySelectorAll('thead tr'));\n\n if (theadTrs.length <= 1) return true;\n\n for (const tr of theadTrs) {\n const cells = Array.from(tr.querySelectorAll('th, td'));\n let cellBoundaryFound = false;\n\n for (const cell of cells) {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEndCol = cCol + cSpan - 1;\n\n if (cCol <= targetBoundaryCol && targetBoundaryCol < cEndCol) {\n return false;\n }\n\n if (cEndCol === targetBoundaryCol) {\n cellBoundaryFound = true;\n break;\n }\n }\n\n if (!cellBoundaryFound) return false;\n }\n\n return true;\n }\n\n executeFixToggle(action, targetCell, fixType = 'left') {\n if (!this.#sheet || !targetCell) return;\n\n const sourceTable = this.#sheet.sourceTable;\n if (!sourceTable) return;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n const targetColIndex = baseCol + colSpan - 1;\n\n if (isNaN(targetColIndex)) return;\n\n const colgroup = sourceTable.querySelector('colgroup');\n if (!colgroup) return;\n\n const cols = Array.from(colgroup.querySelectorAll('col'));\n\n if (action === 'fix-column') {\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx <= targetColIndex) {\n col.setAttribute('fixed', fixType);\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (!isNaN(cIdx) && cIdx <= targetColIndex) {\n cell.setAttribute('fixed', fixType);\n }\n });\n });\n });\n\n } else if (action === 'unfix-column') {\n let minBaseCol = baseCol;\n let maxEndCol = baseCol + colSpan - 1;\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach((tr, rIdx) => {\n Array.from(tr.children).forEach(cell => {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n const rSpan = cell.rowSpan || 1;\n const trIndex = tr.sectionRowIndex ?? rIdx;\n\n const isVerticalOverlap = !(trIndex + rSpan - 1 < cell.closest('tr').sectionRowIndex || trIndex > (cell.closest('tr').sectionRowIndex + rSpan - 1));\n\n const isHorizontalOverlap = !(cEnd < baseCol || cCol > targetColIndex);\n\n if (isHorizontalOverlap) {\n minBaseCol = Math.min(minBaseCol, cCol);\n maxEndCol = Math.max(maxEndCol, cEnd);\n }\n });\n });\n });\n\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx >= minBaseCol) {\n col.removeAttribute('fixed');\n }\n });\n\n let isBroken = false;\n cols.forEach(col => {\n if (isBroken) {\n col.removeAttribute('fixed');\n } else if (!col.getAttribute('fixed')) {\n isBroken = true;\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (isNaN(cIdx)) return;\n\n const correspondingCol = cols.find(c => parseInt(c.getAttribute('data-col'), 10) === cIdx);\n const isColFixed = correspondingCol?.getAttribute('fixed');\n\n if (isColFixed) {\n cell.setAttribute('fixed', isColFixed);\n } else {\n cell.removeAttribute('fixed');\n }\n });\n });\n });\n }\n\n this.#sheet.recompileAndRefresh?.();\n }\n}","import { NINE_TABLE } from '@/core/constants.js';\r\nimport { trace } from \"@nopeer\";\r\n\r\nexport class NineTableFilterPanel extends HTMLElement {\r\n\t#sheet;\r\n\t#host;\r\n\t#nineTable;\r\n\t#view;\r\n\t#button;\r\n\tcurrentCol = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#init();\r\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\r\n\t}\r\n\r\n\t#init = () => {\r\n\t\t//setTimeout(() => {\r\n\t\t\tthis.#renderer();\r\n\r\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\r\n\t\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\r\n\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\r\n\t\t\t})\r\n\r\n\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t});\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\r\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\r\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\r\n\t\t//});\r\n\t}\r\n\r\n\t#renderer = () => {\r\n\t\tthis.innerHTML = `\r\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\r\n \r\n <nine-table-simple class=\"filter-list\" theme=\"simple\">\r\n <table auto-fit-col=\"true\">\r\n <colgroup>\r\n <col width=\"32\" fixed=\"left\" />\r\n <col width=\"180\" />\r\n <col width=\"0\" fixed=\"right\"/>\r\n </colgroup>\r\n <tbody>\r\n <tr>\r\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\r\n <td data-bind=\"DATA2\" html=\"true\"></td>\r\n <td data-bind=\"DATA\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </nine-table-simple>\r\n\r\n <div class=\"footer-section\">\r\n <div class=\"footer-btns\">\r\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\r\n <div class=\"btn-group\">\r\n <button id=\"btnOk\">Apply</button>\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n\t}\r\n\r\n\topen(filterBtn) {\r\n\t\tthis.#button = filterBtn;\r\n\r\n\t\tconst cell = filterBtn.closest(\"th, td\");\r\n\t\tthis.currentCol = cell?.dataset.col;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\r\n\r\n\t\tconst panelWidth = this.offsetWidth || 240;\r\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\r\n\t\tlet top = cellRect.bottom - sheetRect.top;\r\n\r\n\t\tif (left < 0) {\r\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\r\n\t\t}\r\n\r\n\t\tthis.style.left = `${left}px`;\r\n\t\tthis.style.top = `${top}px`;\r\n\r\n\t\tconst searchBox = this.querySelector(\".search-box\");\r\n\t\tsearchBox.value = \"\";\r\n\r\n\r\n\t\tthis.classList.add(\"active\");\r\n\t\tthis.classList.add(\"loading\");\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tthis.#loadVirtualFilterItems();\r\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\r\n\t\t\t\tsearchBox.focus();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.classList.remove(\"loading\");\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t#closeHandler = (e) => {\r\n\t\tconst path = e.composedPath ? e.composedPath() : [];\r\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.close();\r\n\t};\r\n\r\n\tclose() {\r\n\t\tthis.currentCol = null;\r\n\t\tthis.classList.remove(\"active\");\r\n\t\tthis.#button = null;\r\n\t}\r\n\r\n\t#loadVirtualFilterItems() {\r\n\t\tconst filteredRecords = this.#host.data.getArray();\r\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] 형태 배열\r\n\t\tconst fields = this.#host.fields.get() || [];\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst ds = targetCols.flatMap((colInfo) => {\r\n\t\t\tconst bindKey = colInfo.bind;\r\n\t\t\tconst exprKey = colInfo.expr;\r\n\r\n\t\t\tconst filterKey = bindKey || exprKey; // 실제 필터 파라미터 키로 사용\r\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\r\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\r\n\r\n\t\t\tconst uniqueMap = new Map();\r\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\r\n\t\t\t\tconst record = filteredRecords[i];\r\n\t\t\t\tif (!record) continue;\r\n\r\n\t\t\t\tlet rawVal = undefined;\r\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\trawVal = record.v[fieldIdx];\r\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\r\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\r\n\t\t\t\t} else if (exprKey && exprEngine) {\r\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tlet displayVal = rawVal;\r\n\t\t\t\tif (exprKey && exprEngine) {\r\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\r\n\t\t\t\t\tuniqueMap.set(displayVal, {\r\n\t\t\t\t\t\tv: rawVal, // 💡 필터링 비교 기준 (DATA)\r\n\t\t\t\t\t\tv2: displayVal // 💡 화면 출력 기준 (DATA2)\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst uniqueList = [...uniqueMap.values()];\r\n\r\n\t\t\tuniqueList.sort((a, b) => {\r\n\t\t\t\tconst valA = a.v2;\r\n\t\t\t\tconst valB = b.v2;\r\n\r\n\t\t\t\tif (valA === valB) return 0;\r\n\t\t\t\tif (valA === undefined || valA === null || valA === '') return 1;\r\n\t\t\t\tif (valB === undefined || valB === null || valB === '') return -1;\r\n\r\n\t\t\t\tconst numA = Number(valA);\r\n\t\t\t\tconst numB = Number(valB);\r\n\r\n\t\t\t\tconst isNumA = !isNaN(numA);\r\n\t\t\t\tconst isNumB = !isNaN(numB);\r\n\r\n\t\t\t\tif (isNumA && isNumB) {\r\n\t\t\t\t\treturn numA - numB;\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn String(valA).localeCompare(String(valB));\r\n\t\t\t});\r\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\r\n\r\n\t\t\treturn uniqueList.map(o => ({\r\n\t\t\t\tLVL: 2,\r\n\t\t\t\tDATA: o.v, // 필터링 비교용 값\r\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2,\r\n\t\t\t\tCOLNM: filterKey,\r\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v) >= 0 ? \"Y\" : \"N\"\r\n\t\t\t}));\r\n\t\t});\r\n\r\n\t\tthis.#nineTable.data.set(ds);\r\n\r\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\r\n\t\tif (selectAllChk) {\r\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\r\n\t\t}\r\n\t}\r\n\r\n\t#onOk = () => {\r\n\t\tthis.#host.loading = true;\r\n\r\n\t\tconst filterRecords = this.#view.view.getArray();\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\r\n\t\tconst checkedRecords = filterRecords.filter(record => {\r\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\r\n\t\t\treturn (chk === \"Y\" || chk === true);\r\n\t\t});\r\n\r\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\r\n\r\n\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\r\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\r\n\r\n\t\t\tif (selectedVals.length > 0) {\r\n\t\t\t\tfilterParams[filterKey] = selectedVals;\r\n\t\t\t} else {\r\n\t\t\t\tdelete filterParams[filterKey];\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tconst totalCount = this.#nineTable.data.count();\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tif (totalCount === checkedRecords.length) {\r\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\t\t\tbtn.updateFilteredState();\r\n\t\t\t\t});\r\n\r\n\t\t\t\tthis.#sheet.invalidate();\r\n\t\t\t\tthis.close();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.#host.loading = false;\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t#onInput = (e) => {\r\n\r\n\t\tconst query = e.target.value.toLowerCase().trim();\r\n\r\n\t\tif (!query) {\r\n\t\t\tthis.#view.filtering.clear();\r\n\t\t} else {\r\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\r\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\r\n\r\n\t\t\tconst matchedValues = [];\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\r\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\r\n\r\n\t\t\t\tif (textVal.includes(query)) {\r\n\t\t\t\t\tmatchedValues.push(val);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tthis.#view.filtering.set({\r\n\t\t\t\tDATA2: [...new Set(matchedValues)]\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t#onSelectAll = (e) => {\r\n\t\tconst isChecked = e.target.checked;\r\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\r\n\r\n\t\tif (chkIdx >= 0) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#nineTable.refresh();\r\n\t};\r\n\r\n\t#onCancel = () => {\r\n\t\tthis.close();\r\n\t};\r\n}\r\n\r\nexport class NineTableFilterButton extends HTMLElement {\r\n\t#sheet;\r\n\t#columns = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\r\n\t\tthis.removeEventListener(\"click\", this.#onClick);\r\n\t\tthis.addEventListener(\"click\", this.#onClick);\r\n\t}\r\n\r\n\tget columns() {\r\n\t\tif (this.#columns) return this.#columns;\r\n\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst colIndex = cell?.dataset.col;\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\r\n\t\tconst cols = [];\r\n\t\tconst seen = new Set();\r\n\r\n\t\tif (sourceTable && colIndex !== undefined) {\r\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\t\tconst bindKey = $td.dataset.bind;\r\n\t\t\t\tconst exprKey = $td.dataset.expr;\r\n\r\n\t\t\t\tif (bindKey || exprKey) {\r\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\r\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\r\n\t\t\t\t\t\tseen.add(uniqueKey);\r\n\t\t\t\t\t\tcols.push({\r\n\t\t\t\t\t\t\tbind: bindKey,\r\n\t\t\t\t\t\t\texpr: exprKey,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#columns = cols;\r\n\t\treturn this.#columns;\r\n\t}\r\n\r\n\tupdateFilteredState = () => {\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst isFiltered = this.columns.some(colInfo => {\r\n\t\t\tconst key = colInfo.expr || colInfo.bind;\r\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\r\n\t\t});\r\n\t\tthis.classList.toggle('filtered', isFiltered);\r\n\t};\r\n\r\n\t#onClick = (e) => {\r\n\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst col = cell.dataset.col;\r\n\r\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\r\n\t\t\tpanel.close();\r\n\t\t} else if (panel) {\r\n\t\t\tpanel.open(this);\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class Filtering {\r\n\t#sheet;\r\n\t#host;\r\n\t#isFiltering = false;\r\n\t#filterPanel = null;\r\n\t#filters = {};\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t\tthis.#init();\r\n\t}\r\n\r\n\tget filters() {\r\n\t\treturn this.#filters;\r\n\t};\r\n\r\n\t#init = () => {\r\n\t\tthis.#initFilterPanel();\r\n\t}\r\n\r\n\t#initFilterPanel = () => {\r\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tif (!panel) {\r\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\r\n\t\t\tthis.#sheet.appendChild(panel);\r\n\t\t}\r\n\t\tthis.#filterPanel = panel;\r\n\t}\r\n\r\n\tisFiltering() {\r\n\t\treturn this.#isFiltering;\r\n\t}\r\n\r\n\tclear = (colnm) => {\r\n\t\tif (colnm) {\r\n\t\t\tdelete this.#filters[colnm];\r\n\t\t} else {\r\n\t\t\tthis.#filters = {};\r\n\t\t}\r\n\r\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\r\n\t\tthis.#applyFiltering();\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\tbtn.updateFilteredState();\r\n\t\t});\r\n\t}\r\n\r\n\tset = (oFilter) => {\r\n\r\n\t\tlet jsonFilter = Array.isArray(oFilter)\r\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\r\n\t\t\t: oFilter;\r\n\r\n\t\tthis.#filters = jsonFilter;\r\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\r\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\r\n\r\n\t\tthis.#applyFiltering();\r\n\t}\r\n\r\n\t#applyFiltering() {\r\n\t\tconst hostData = this.#host.data;\r\n\t\tconst rawRecords = hostData.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields();\r\n\t\tconst sheetIndex = this.#sheet.index;\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\r\n\r\n\t\tif (!hasFilters) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\tthis.#sheet.invalidate();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\r\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\r\n\t\t\treturn {\r\n\t\t\t\ttargetKey,\r\n\t\t\t\tisExpr,\r\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\r\n\t\t\t\tallowedSet: new Set(allowedValues)\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\trawRecords.forEach((record, recordIdx) => {\r\n\t\t\tif (!record) return;\r\n\r\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\r\n\t\t\t}\r\n\r\n\t\t\tlet isPass = true;\r\n\r\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\r\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\r\n\t\t\t\tlet val = undefined;\r\n\r\n\t\t\t\tif (isExpr && exprEngine) {\r\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\r\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\tval = record.v[fieldIdx];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!allowedSet.has(val)) {\r\n\t\t\t\t\tisPass = false;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.invalidate();\r\n\t}\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-panel')) {\r\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-button')) {\r\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\r\n}","// ui/data/Sorting.js (또는 정렬 관련 소스)\r\nimport { trace } from \"@nopeer\";\r\n\r\nexport class Sorting {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#columns = [];\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.#initEvents();\r\n\t\t}, 300);\r\n\t}\r\n\r\n\t#initEvents() {\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\r\n\r\n\t\t\t$el.addEventListener('dblclick', (e) => {\r\n\r\n\t\t\t\tconst cell = e.target.closest('th, td');\r\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\r\n\r\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\r\n\r\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\r\n\r\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\r\n\r\n\t\t\t\thost.loading = true;\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tthis.#handleSort(e, cell);\r\n\t\t\t\t\t} finally {\r\n\t\t\t\t\t\thost.loading = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\t#handleSort(e, cell) {\r\n\t\tconst colIndex = cell.dataset.col;\r\n\t\tconst tr = cell.closest('tr');\r\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\r\n\r\n\t\tif (colIndex === undefined) return;\r\n\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (!sourceTable) return;\r\n\r\n\t\tlet colName = null;\r\n\t\tlet exprVal = null;\r\n\r\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\tif ($td.dataset.bind) {\r\n\t\t\t\tcolName = $td.dataset.bind;\r\n\t\t\t}\r\n\r\n\t\t\tif ($td.dataset.expr) {\r\n\t\t\t\texprVal = $td.dataset.expr;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (!colName && !exprVal) return;\r\n\r\n\t\tconst isAsc = cell.classList.contains('asc');\r\n\t\tconst isDesc = cell.classList.contains('desc');\r\n\r\n\t\tif (!e.ctrlKey && !e.shiftKey) {\r\n\t\t\tthis.#columns = [];\r\n\t\t}\r\n\r\n\t\tconst existingColIndex = this.#columns.findIndex(\r\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\r\n\t\t);\r\n\r\n\t\tconst ruleData = {\r\n\t\t\tcolIndex,\r\n\t\t\tsubRowIndex,\r\n\t\t\tcolname: colName || exprVal,\r\n\t\t\tcolName: colName || exprVal,\r\n\t\t\texpr: exprVal, // 💡 expr 규칙 보관\r\n\t\t\tasc: true,\r\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\r\n\t\t};\r\n\r\n\t\tif (!isAsc && !isDesc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\r\n\t\t\t}\r\n\t\t} else if (isAsc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.#columns = this.#columns.filter(\r\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tthis.#applySorting();\r\n\t}\r\n\r\n\t#applySorting() {\r\n\t\tif (!this.#sheet.view) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.view.setSorting(this.#columns);\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.invalidate();\r\n\t}\r\n\r\n\t#syncHeaderUI() {\r\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\r\n\t\t\tel.classList.remove('asc', 'desc');\r\n\t\t});\r\n\r\n\t\tif (this.#columns.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.#columns.forEach(colRule => {\r\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\r\n\r\n\t\t\tif (colIndex !== undefined) {\r\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\r\n\t\t\t\tif (subRowIndex !== undefined) {\r\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\r\n\t\t\t\ttargetHeaderCells.forEach(cell => {\r\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\trestore() {\r\n\t\tthis.#columns = [];\r\n\t\tif (this.#sheet.view) {\r\n\t\t\tthis.#sheet.view.resetSorting();\r\n\t\t}\r\n\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.rowManager?.refresh(true);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\nimport {Grouping} from \"@/data/Grouping.js\";\r\n\r\nexport class SheetView {\r\n\t#sheet;\r\n\t#host;\r\n\t#sortingColumns = [];\r\n\t#filterRules = [];\r\n\t#viewIndexes = [];\r\n\r\n\t#cachedVisibleRecords = null;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.refresh();\r\n\t}\r\n\r\n\tgetArray = (at, colnm) => {\r\n\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords;\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.#host.data.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord;\r\n\t};\r\n\r\n\tcount = () => {\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\treturn this.#cachedVisibleRecords.length;\r\n\t}\r\n\r\n\tget = (at, colnm) => {\r\n\t\tconst visibleRecords = this.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (!targetRecord) return null;\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#convSingle(targetRecord, fields);\r\n\t};\r\n\r\n\t#convSingle = (o, fields) => {\r\n\t\tif (!o) return null;\r\n\t\tconst t = {};\r\n\t\tfields.forEach((colnm, i) => {\r\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t});\r\n\t\tif (o.m) t.m = o.m;\r\n\t\tif (o._) t._ = o._;\r\n\t\treturn t;\r\n\t};\r\n\r\n\trefresh = () => {\r\n\r\n\t\tthis.#cachedVisibleRecords = null;\r\n\r\n\t\tconst rawRecords = this.#host.data.getArray();\r\n\t\tlet indices = [];\r\n\t\trawRecords.forEach((record, i) => {\r\n\t\t\tif (!record) return;\r\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\r\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\r\n\t\t\tindices.push(i);\r\n\t\t});\r\n\r\n\t\tif (this.#sortingColumns.length > 0) {\r\n\t\t\tindices = this.#applySorting(indices, rawRecords);\r\n\t\t}\r\n\r\n\t\tthis.#viewIndexes = indices;\r\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\r\n\r\n\t\tconst groupColumns = this.#sheet.grouping?.columns || [];\r\n\t\tif (groupColumns.length > 0) {\r\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields());\r\n\r\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // 최종 렌더링 아이템\r\n\r\n\t\t\tthis.#sheet.grouping.setGroupMap(groupResult.groupMap); // 자식 매핑 공유\r\n\t\t} else {\r\n\t\t\tthis.#cachedVisibleRecords = validRecords;\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n\tsetSorting = (columns) => {\r\n\t\tthis.#sortingColumns = columns || [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\tgetSorting = () => {\r\n\t\treturn this.#sortingColumns;\r\n\t};\r\n\r\n\tresetSorting = () => {\r\n\t\tthis.#sortingColumns = [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\r\n\t#applySorting = (indices, validRecords) => {\r\n\r\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\r\n\r\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\r\n\t\t\t...rule,\r\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\r\n\t\t}));\r\n\r\n\t\treturn indices.sort((idxA, idxB) => {\r\n\t\t\tconst a = validRecords[idxA];\r\n\t\t\tconst b = validRecords[idxB];\r\n\r\n\t\t\tfor (const rule of rulesWithIdx) {\r\n\t\t\t\tconst isAsc = rule.asc;\r\n\t\t\t\tconst expr = rule.expr; // 💡 등록된 expr 수식\r\n\t\t\t\tlet valA, valB;\r\n\r\n\t\t\t\tif (expr) {\r\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\r\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\r\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\r\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\r\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\r\n\r\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\r\n\t\t\t\tif (isEmptyA) return 1;\r\n\t\t\t\tif (isEmptyB) return -1;\r\n\r\n\t\t\t\tif (valA !== valB) {\r\n\t\t\t\t\tlet diff = 0;\r\n\r\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\r\n\t\t\t\t\t\tdiff = valA - valB;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst strA = String(valA);\r\n\t\t\t\t\t\tconst strB = String(valB);\r\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (diff !== 0) {\r\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn idxA - idxB;\r\n\t\t});\r\n\t};\r\n}","import { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/layout/core/TableCompiler.js\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class PreCompiler {\n\n static initializeTable(host, tbl) {\n\n PreCompiler.#ensureColgroup(tbl);\n PreCompiler.#ensureThead(tbl);\n PreCompiler.#ensureSectionTbodys(tbl);\n\n PreCompiler.#ensureRowIndicator(tbl);\n\n PreCompiler.#normalizeColAttributes(tbl);\n\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tfoot tr'));\n\n PreCompiler.#createColIndicator(tbl);\n\n PreCompiler.#normalizeCollapsibleAttributes(tbl);\n\n PreCompiler.#generateCell(host, tbl);\n\n PreCompiler.#initColExpanders(tbl);\n\n PreCompiler.#initFilterButtons(host, tbl);\n\n PreCompiler.#applyInitialCellWidths(tbl);\n\n return tbl;\n }\n\n static #createColIndicator(tbl) {\n const thead = tbl.querySelector('thead');\n if (!thead || thead.querySelector('.col-indicator-rowgroup')) return;\n\n const tdTmpl = `<th data-col=\"@col\" class=\"col-indicator\" scope=\"col\"></th>`;\n\n const tr = thead.insertRow(0);\n tr.setAttribute('role', 'row');\n tr.classList.add('col-indicator-rowgroup');\n tr.classList.add('collapse');\n\n const firstRow = tbl.querySelector('tbody tr');\n if (!firstRow) return;\n\n let cnt = 0;\n firstRow.querySelectorAll('th, td').forEach(td => {\n if (!td.classList.contains('dummy')) {\n const colSpan = td.colSpan || 1;\n for (let i = 0; i < colSpan; i++) {\n const html = tdTmpl.replace('@col', cnt).replace('@text', PreCompiler.#numToExcelCol(cnt++));\n tr.insertAdjacentHTML('beforeend', html);\n }\n }\n });\n\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n tr.querySelectorAll('.col-indicator').forEach((el, i) => {\n const background = cols[i].getAttribute('background');\n if (background) {\n el.style.background = background;\n }\n });\n }\n\n static #numToExcelCol(num) {\n let text = '';\n for (let n = num; n >= 0; n = Math.floor(n / 26) - 1) {\n text = String.fromCharCode(65 + (n % 26)) + text;\n }\n return text;\n }\n\n static #ensureSectionTbodys(tbl) {\n let tbody = tbl.querySelector('tbody:not(.head):not(.foot)');\n\n if (!tbody) return;\n\n tbody.classList.add('body');\n\n if (!tbl.querySelector('tbody.head')) {\n const headTbody = document.createElement('tbody');\n headTbody.classList.add('head');\n tbody.before(headTbody);\n }\n\n if (!tbl.querySelector('tbody.foot')) {\n const footTbody = document.createElement('tbody');\n footTbody.classList.add('foot');\n tbody.after(footTbody);\n }\n }\n\n static #ensureColgroup(tbl) {\n let colgroup = tbl.querySelector('colgroup');\n if (!colgroup) {\n colgroup = document.createElement('colgroup');\n tbl.prepend(colgroup);\n }\n\n if (colgroup.querySelectorAll('col').length === 0) {\n const firstRow = tbl.querySelector('tbody tr');\n let colCount = 1;\n if (firstRow) {\n colCount = Array.from(firstRow.querySelectorAll('th, td')).reduce((sum, cell) => {\n return sum + (parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1);\n }, 0);\n }\n colCount = Math.max(colCount, 1);\n\n for (let i = 0; i < colCount; i++) {\n const col = document.createElement('col');\n colgroup.appendChild(col);\n }\n }\n }\n\n static #normalizeColAttributes(tbl) {\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n if (cols.length === 0) return;\n\n const containerWidth = tbl.clientWidth || 0;\n const defaultWidth = Math.max(Math.floor(containerWidth / cols.length), 100);\n\n cols.forEach((col, i) => {\n\n if (!col.hasAttribute('data-col')) {\n col.setAttribute('data-col', i);\n }\n\n const width = col.getAttribute('width') || parseInt(col.style.width, 10) || defaultWidth;\n col.setAttribute('width', width);\n\n const widthVal = String(width).includes('px') ? width : `${width}px`;\n col.style.width = widthVal;\n });\n }\n\n static #ensureThead(tbl) {\n if (tbl.querySelector('thead')) return;\n\n const thead = document.createElement('thead');\n const colgroup = tbl.querySelector('colgroup');\n\n if (colgroup) {\n colgroup.after(thead);\n } else {\n tbl.prepend(thead);\n }\n }\n\n static #normalizeCollapsibleAttributes(tbl) {\n const headers = tbl.querySelectorAll('thead th, thead td');\n headers.forEach(cell => {\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n if (isCollapsed && cell.getAttribute('collapsible') !== 'true') {\n cell.setAttribute('collapsible', 'true');\n }\n });\n }\n\n static #generateCell(host, $tbl) {\n\n const targetAttributes = ['data-bind', 'data-expr', 'type'];\n let autoIdCounter = 0;\n\n $tbl.querySelectorAll('tbody th, tbody td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type') || \"renderer\";\n const tagName = `cell-${cellType}`;\n\n const $datalist = $cell.querySelector(\"datalist\");\n\n if ($datalist) {\n let l = [];\n $datalist.querySelectorAll('option').forEach($option => {\n l.push({\n k: $option.getAttribute(\"k\"),\n v: $option.getAttribute(\"v\"),\n value: $option.getAttribute(\"value\"),\n });\n });\n\n const uniqueFuncName = `__ds_${Date.now()}_${++autoIdCounter}`;\n\n if (host) {\n host[uniqueFuncName] = () => l;\n }\n\n $cell.setAttribute(\"data-source\", `host.${uniqueFuncName}()`);\n\n $datalist.remove();\n }\n\n const expr = $cell.dataset.expr;\n if (expr) {\n $cell.setAttribute('data-expr', host.exprEngine.precompile(expr));\n }\n\n Array.from($cell.attributes).forEach(attr => {\n if (['data-bind', 'data-expr', 'cell-type', 'validator'].includes(attr.name)) return;\n if (attr.value.includes(\"data.\") || attr.value.includes(\"host.\")) {\n $cell.setAttribute(attr.name, host.exprEngine.precompile(attr.value));\n }\n });\n\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')}></${tagName}>`;\n $cell.setAttribute('tabindex', '0');\n });\n\n $tbl.querySelectorAll('thead th, thead td, tfoot th, tfoot td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type');\n if (cellType) {\n const originalContent = $cell.innerHTML;\n const tagName = `cell-${cellType}`;\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')} content=\"${originalContent}\"></${tagName}>`;\n }\n });\n }\n\n static #initFilterButtons(host, tbl) {\n const hostFilter = host.getAttribute('filtering') === 'true';\n const tableFilter = tbl.getAttribute('filtering') === 'true';\n\n tbl.querySelectorAll('thead tr:not(.col-indicator-rowgroup) th, thead tr:not(.col-indicator-rowgroup) td').forEach(cell => {\n const finalFiltering = cell.getAttribute('filtering') === 'true' || tableFilter || hostFilter;\n\n cell.setAttribute('filtering', finalFiltering ? 'true' : 'false');\n\n if (finalFiltering) {\n cell.appendChild(document.createElement('nine-table-filter-button'));\n }\n });\n }\n\n static #initColExpanders(tbl) {\n\n tbl.querySelectorAll('thead th, thead td').forEach(cell => {\n const isCollapsible = cell.getAttribute('collapsible') === 'true' || cell.getAttribute('expandable') === 'true';\n if (!isCollapsible) return;\n\n const colIndex = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const col = tbl.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n\n const currentWidth = col ? (parseInt(col.getAttribute('width'), 10) || 100) : 100;\n\n if (!cell.dataset.expandWidth || parseInt(cell.dataset.expandWidth, 10) <= COLLAPSED_WIDTH) {\n cell.dataset.expandWidth = String(currentWidth > COLLAPSED_WIDTH ? currentWidth : 100);\n }\n\n let expandBtn = cell.querySelector('nine-table-col-expand');\n if (!expandBtn) {\n expandBtn = document.createElement('nine-table-col-expand');\n cell.insertBefore(expandBtn, cell.firstChild);\n }\n\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n expandBtn.classList.add('collapsed');\n expandBtn.classList.remove('expand');\n expandBtn.setAttribute('collapsed', 'true');\n cell.style.color = 'transparent';\n\n const targetWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n if (!isNaN(colIndex)) {\n for (let i = 0; i < colSpan; i++) {\n const targetCol = tbl.querySelector(`colgroup col[data-col=\"${colIndex + i}\"]`);\n if (targetCol) {\n targetCol.setAttribute('width', targetWidth);\n targetCol.style.width = `${targetWidth}px`;\n }\n }\n }\n } else {\n expandBtn.classList.remove('collapsed');\n expandBtn.classList.add('expand');\n expandBtn.setAttribute('collapsed', 'false');\n cell.style.color = '';\n }\n });\n }\n\n static #ensureRowIndicator(tbl, host) {\n\n const w = tbl.getAttribute(\"row-indicator\") === 'true' ? 48 : 0;\n\n const colgroup = tbl.querySelector('colgroup');\n\n\n const col = document.createElement('col');\n //col.className = 'row-indicator-col';\n col.setAttribute('fixed', 'left');\n col.setAttribute('width', w);\n col.style.width = `${w}px`;\n colgroup.prepend(col);\n\n\n tbl.querySelectorAll('thead, tbody, tfoot').forEach(section => {\n const rows = Array.from(section.querySelectorAll('tr'));\n if (rows.length === 0) return;\n\n const firstTr = rows[0];\n\n const indicatorCell = document.createElement('th');\n indicatorCell.className = 'row-indicator';\n indicatorCell.setAttribute('cell-type', 'row-indicator');\n\n if (rows.length > 1) {\n indicatorCell.rowSpan = rows.length;\n }\n\n firstTr.insertBefore(indicatorCell, firstTr.firstElementChild);\n });\n }\n\n static #applyInitialCellWidths(tbl) {\n\n tbl.querySelectorAll('th[data-col], td[data-col]').forEach(cell => {\n\n const startColIdx = parseInt(cell.getAttribute('data-col'), 10);\n if (isNaN(startColIdx)) return;\n\n\n const colSpan = parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1;\n let totalWidth = 0;\n\n\n for (let i = 0; i < colSpan; i++) {\n const targetIdx = startColIdx + i;\n const col = tbl.querySelector(`colgroup col[data-col=\"${targetIdx}\"]`);\n if (col) {\n totalWidth += parseInt(col.getAttribute('width'), 10) || 100;\n }\n }\n\n if (totalWidth > 0) {\n const widthVal = `${totalWidth}px`;\n cell.style.width = widthVal;\n cell.style.minWidth = widthVal;\n cell.style.maxWidth = widthVal;\n }\n });\n }\n}\n","import { trace } from \"@nopeer\";\nimport './nine-table-hscrollbar.js';\nimport './nine-table-vscrollbar.js';\nimport { RowManager } from './core/RowManager.js';\nimport { TableCompiler } from \"./core/TableCompiler.js\";\nimport { CellSelection } from \"@/cell-manager/CellSelection.js\";\nimport { CellNavigation } from \"@/cell-manager/CellNavigation.js\";\n\nimport { ColResizer } from \"@/col/ColResizer.js\";\nimport { ColMover } from \"@/col/ColMover.js\";\nimport { ColFixManager } from \"@/col/ColFixManager.js\";\n\nimport { Filtering } from \"@/data/Filtering.js\";\nimport { GroupingManager } from \"@/data/Grouping.js\";\nimport { Sorting } from \"@/data/Sorting.js\";\nimport { SheetView } from \"@/data/SheetView.js\";\n\nimport { PreCompiler } from \"@/layout/core/PreCompiler.js\";\n\nexport class NineTableSheet extends HTMLElement {\n #index;\n #host;\n #rowManager;\n #cellSelection;\n #cellNavigation;\n #colResizer;\n #colMover;\n #colFix;\n #sorting;\n #filtering;\n #grouping;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n static SCROLLBAR_SIZE = 16;\n\n constructor() {\n super();\n\n this.#host = this.getRootNode().host;\n this.#rowManager = new RowManager(this);\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get index() { return this.#index; }\n get colResizer() { return this.#colResizer; }\n get filtering() { return this.#filtering; }\n get grouping() { return this.#grouping; }\n get colMover() { return this.#colMover; }\n get colFix() { return this.#colFix; }\n get rowManager() { return this.#rowManager; }\n get selection() { return this.#cellSelection; }\n get navigation() { return this.#cellNavigation; }\n get templateLength() { return this.#source.tbody.tr.length || 0; }\n\n get elements() { return this.#elements; }\n\n get isAutoFitCol() {\n const attrTrue = this.getAttribute('auto-fit-col') === 'true' || this.#host?.getAttribute('auto-fit-col') === 'true';\n const sourceTableTrue = this.#source.table?.getAttribute('auto-fit-col') === 'true';\n return attrTrue || sourceTableTrue;\n }\n\n get sourceTable() {\n return this.#source.table;\n }\n\n get source() {\n return this.#source;\n }\n\n get #isSimple() {\n return this.#host.hasAttribute('simple') || this.#host.getAttribute('theme') === 'simple';\n }\n\n recompileAndRefresh() {\n if (!this.#source.table) return;\n\n TableCompiler.recompile(this.#source.table);\n\n ['left', 'right', 'body'].forEach(type => {\n ['header', 'body', 'footer'].forEach(section => {\n const container = this.querySelector(`.ng-sheet-${section} .ng-container-${type}`);\n if (!container) return;\n container.querySelectorAll('table').forEach(tbl => tbl.remove());\n });\n });\n\n this.#renderSplitContainers();\n\n this.#updateContainerWidths();\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n requestAnimationFrame(() => {\n this.#updateContainerWidths();\n this.#rowManager?.refresh();\n });\n }\n\n refreshLayout() {\n\n requestAnimationFrame(() => {\n\n if (!this.classList.contains('active') || !this.#source.table) return;\n\n this.#updateContainerWidths();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n this.#adjustOverlay();\n\n this.#colResizer?.refreshLayout();\n\n this.#rowManager?.refresh();\n });\n }\n\n #adjustOverlay = () => {\n const $thead = this.querySelector('.ng-container-body thead');\n const $overlay = this.querySelector('.nodata-overlay');\n $overlay.style.top = `${$thead.offsetHeight}px`;\n }\n\n get view() {\n if (!this.#view && this.#host?.data) {\n this.#view = new SheetView(this);\n }\n return this.#view;\n }\n\n invalidate = () => {\n\n this.view.refresh();\n\n this.#rowManager.refresh(true);\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n }\n };\n\n autoFit = (enable = true) => {\n requestAnimationFrame(() => {\n this.#autoFit?.(enable);\n });\n };\n\n #autoFit = (enable = true) => {\n\n const container = this.querySelector('.ng-sheet-body .ng-container-body');\n if (!container) return;\n\n const firstColgroup = this.querySelector('.ng-container-body table colgroup');\n if (!firstColgroup) return;\n\n if (enable) {\n this.setAttribute('auto-fit-col', 'true');\n const containerWidth = container.clientWidth;\n if (containerWidth <= 0) return;\n\n let totalOriginalWidth = 0;\n const colList = [];\n\n firstColgroup.querySelectorAll('col').forEach(col => {\n const globalColIndex = col.getAttribute('data-col');\n const headerCell = this.querySelector(`thead th[data-col=\"${globalColIndex}\"]`);\n const isCollapsed = headerCell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n colList.unshift({ globalColIndex, width: 16, isCollapsed: true });\n } else {\n const w = parseInt(col.getAttribute('width'), 10) || 100;\n colList.push({ globalColIndex, width: w, isCollapsed: false });\n totalOriginalWidth += w;\n }\n });\n\n const collapsedTotalWidth = colList\n .filter(c => c.isCollapsed)\n .reduce((sum, c) => sum + c.width, 0);\n\n const availableWidth = Math.max(0, containerWidth - collapsedTotalWidth);\n\n if (totalOriginalWidth > 0 && colList.length > 0) {\n let allocatedTotal = 0;\n\n const calculatedCols = colList.map(item => {\n if (item.isCollapsed) {\n return { globalColIndex: item.globalColIndex, remainder: 0, width: 16 };\n }\n\n const exactWidth = (item.width * availableWidth) / totalOriginalWidth;\n const baseWidth = Math.max(30, Math.floor(exactWidth));\n allocatedTotal += baseWidth;\n return {\n globalColIndex: item.globalColIndex,\n remainder: exactWidth - Math.floor(exactWidth),\n width: baseWidth\n };\n });\n\n let remainderPixels = availableWidth - allocatedTotal;\n\n const uncollapsedCols = calculatedCols.filter(c => !colList.find(item => item.globalColIndex === c.globalColIndex)?.isCollapsed);\n\n if (remainderPixels > 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => b.remainder - a.remainder);\n for (let i = 0; i < remainderPixels; i++) {\n uncollapsedCols[i % uncollapsedCols.length].width += 1;\n }\n } else if (remainderPixels < 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => a.remainder - b.remainder);\n for (let i = 0; i < Math.abs(remainderPixels); i++) {\n const target = uncollapsedCols[i % uncollapsedCols.length];\n if (target.width > 30) target.width -= 1;\n }\n }\n\n calculatedCols.forEach(({ globalColIndex, width }) => {\n this.#colResizer?.setColumnWidth(globalColIndex, width, 'body');\n });\n }\n } else {\n this.removeAttribute('auto-fit-col');\n }\n\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n generate = ($table, index) => {\n\n $table.style.display = 'none';\n\n this.#index = index;\n\n PreCompiler.initializeTable(this.#host, $table);\n\n $table.style.display = '';\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n this.#renderSplitContainers();\n\n this.#updateContainerWidths();\n\n this.#syncHeaderAndFooterHeights();\n\n this.#initRowHoverEvent();\n\n ['left', 'body', 'right'].forEach(type => {\n const prefix = `.ng-container-${type}`;\n this.#elements[type] = {\n thead: this.querySelector(`${prefix} thead`),\n tbody: {\n head: this.querySelector(`${prefix} tbody.head`),\n body: this.querySelector(`${prefix} tbody.body`),\n foot: this.querySelector(`${prefix} tbody.foot`),\n },\n tfoot: this.querySelector(`${prefix} tfoot`),\n };\n });\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar').refresh();\n }\n\n this.#grouping.initialize();\n\n this.loaded = true;\n };\n\n\n #updateContainerWidths = () => {\n\n ['left', 'right', 'body'].forEach(type => {\n const containers = this.querySelectorAll(`.ng-container-${type}`);\n if (containers.length === 0) return;\n\n const firstTable = containers[0].querySelector('table');\n if (!firstTable) return;\n\n let width = 0;\n firstTable.querySelectorAll('col').forEach(col => {\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) width += w;\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n if (type === 'body') {\n container.style.flex = `1`;\n } else {\n container.style.flex = `0 0 ${width}px`;\n container.style.width = `${width}px`;\n container.style.minWidth = `${width}px`;\n container.style.maxWidth = `${width}px`;\n }\n });\n });\n };\n\n #renderSplitContainers = () => {\n const colTypes = [\n { selector: '.ng-container-left', type: 'left' },\n { selector: '.ng-container-body', type: null },\n { selector: '.ng-container-right', type: 'right' }\n ];\n\n colTypes.forEach(({ selector, type }) => {\n this.querySelector(`.ng-sheet-body ${selector}`).appendChild(this.#createSplitTable(type));\n });\n };\n\n #createSplitTable = (targetFixedType) => {\n\n const $tbl = this.#source.table.cloneNode(true);\n\n if (targetFixedType === 'left') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"left\") $el.remove();\n });\n } else if (targetFixedType === 'right') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"right\") $el.remove();\n });\n } else {\n $tbl.querySelectorAll(\"[fixed=left], [fixed=right]\").forEach($el => {\n $el.remove();\n });\n }\n\n return $tbl;\n };\n\n getRowHeight = () => {\n return this.#rowManager.getRowHeight();\n };\n\n getViewHeight = () => {\n\n const viewHeight = this.#elements.content.offsetHeight || 0;\n\n const fixedHeight = (this.#elements.body.thead?.offsetHeight || 0) +\n (this.#elements.body.tfoot?.offsetHeight || 0) +\n (this.#elements.body.tbody.head.offsetHeight || 0);\n\n return viewHeight - fixedHeight;\n };\n\n isLastRow = () => {\n\n const sheet = this.querySelector('.ng-sheet-body');\n const tbody = this.querySelector(\".ng-container-body tbody.body\");\n\n const offsetHeight = (this.#elements.body.tfoot?.offsetHeight || 0);\n\n const sheetBottom = sheet.getBoundingClientRect().bottom;\n const tbodyBottom = tbody.getBoundingClientRect().bottom;\n\n return (sheetBottom - offsetHeight) >= tbodyBottom;\n };\n\n scrollToX = (scrollLeft) => {\n const bodyContainer = this.querySelector('.ng-sheet-body .ng-container-body');\n if (bodyContainer) bodyContainer.scrollLeft = scrollLeft;\n };\n\n scrollToY = (scrollTop) => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (bodyViewport) bodyViewport.scrollTop = scrollTop;\n };\n\n #init = () => {\n\n this.#render();\n\n this.#cellSelection = new CellSelection(this);\n this.#cellNavigation = new CellNavigation(this);\n this.#colResizer = new ColResizer(this);\n this.#colMover = new ColMover(this);\n this.#colFix = new ColFixManager(this);\n\n this.#view = new SheetView(this);\n this.#filtering = new Filtering(this);\n this.#grouping = new GroupingManager(this);\n\n if (!this.#isSimple) {\n this.#sorting = new Sorting(this);\n }\n\n this.#elements.mainBody.addEventListener('scroll', () => {\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n\n this.innerHTML = `\n <div class=\"ng-sheet-body\">\n <div class=\"ng-sheet-body-content\">\n <div class=\"ng-container-left\"></div>\n <div class=\"ng-container-body\"></div>\n <div class=\"ng-container-right\"></div>\n </div>\n <div class=\"ng-virtual-height-holder\"></div>\n </div>\n\n <div class=\"nodata-overlay\">Data Not Found</div>\n\n <nine-table-vscrollbar></nine-table-vscrollbar>\n <nine-table-hscrollbar></nine-table-hscrollbar>\n <div class=\"scroll-edge\"></div>\n \n <nine-table-col-resizer-panel></nine-table-col-resizer-panel>\n \n <div class=\"ng-col-mover-grip\"></div>\n <div class=\"ng-col-mover-indi\"></div>\n `;\n\n this.#elements = {\n mainBody: this.querySelector('.ng-sheet-body .ng-container-body'),\n hscrollbar: this.querySelector('nine-table-hscrollbar'),\n vscrollbar: this.querySelector('nine-table-vscrollbar'),\n content: this.querySelector('.ng-sheet-body .ng-sheet-body-content'),\n scrollHolder: this.querySelector('.ng-sheet-body .ng-virtual-height-holder'),\n }\n };\n\n #syncHeaderAndFooterHeights = () => {\n\n const leftTable = this.querySelector('.ng-container-left table');\n const bodyTable = this.querySelector('.ng-container-body table');\n const rightTable = this.querySelector('.ng-container-right table');\n\n const leftHeaderRows = Array.from(leftTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const bodyHeaderRows = Array.from(bodyTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const rightHeaderRows = Array.from(rightTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n\n this.#applyMaxHeights(leftHeaderRows, bodyHeaderRows, rightHeaderRows);\n\n const leftFooterRows = Array.from(leftTable.querySelectorAll('tfoot tr'));\n const bodyFooterRows = Array.from(bodyTable.querySelectorAll('tfoot tr'));\n const rightFooterRows = Array.from(rightTable.querySelectorAll('tfoot tr'));\n\n this.#applyMaxHeights(leftFooterRows, bodyFooterRows, rightFooterRows);\n };\n\n #applyMaxHeights = (leftRows, bodyRows, rightRows) => {\n\n setTimeout(() => {\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n });\n };\n\n #initRowHoverEvent = () => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n let activeRowIndex = null;\n\n bodyViewport.addEventListener('mouseover', (e) => {\n const tr = e.target.closest('tr');\n if (!tr || !tr.dataset.row && tr.dataset.row !== '0') return;\n\n const rowIndex = tr.dataset.row;\n if (activeRowIndex === rowIndex) return;\n activeRowIndex = rowIndex;\n\n bodyViewport.querySelectorAll(`tr[data-row=\"${rowIndex}\"]`).forEach($tr => {\n $tr.classList.add('hover');\n });\n });\n\n bodyViewport.addEventListener('mouseout', (e) => {\n const tr = e.target.closest('tr');\n if (!tr) return;\n\n const relatedTarget = e.relatedTarget;\n if (tr.contains(relatedTarget)) return;\n\n bodyViewport.querySelectorAll('tr.hover').forEach($tr => {\n $tr.classList.remove('hover');\n });\n activeRowIndex = null;\n });\n }\n\n disconnectedCallback() {\n this.#colResizer?.destroy();\n this.#colMover?.destroy();\n this.innerHTML = '';\n }\n}\n\nif (!customElements.get('nine-table-sheet')) {\n customElements.define('nine-table-sheet', NineTableSheet);\n}","import { trace } from \"@nopeer\";\nimport '@/layout/nine-table-sheets.js';\nimport '@/layout/nine-table-sheets-footer.js';\nimport '@/layout/nine-table-toolbar.js';\nimport { NineTableSheet } from \"@/layout/nine-table-sheet.js\";\n\nexport class LayoutManager {\n #host;\n\n constructor(owner) {\n this.#host = owner;\n this.#init();\n }\n\n #init = () => {\n this.#render();\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }).observe(this.#host);\n }\n\n set loading(val) {\n if (!!val) {\n this.#host.classList.add(\"loading\");\n } else {\n this.#host.classList.remove(\"loading\");\n }\n }\n\n #applyAutoHeight = () => {\n const activeSheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet.active'));\n if (activeSheets.length === 0) return;\n\n const maxDisplayRows = parseInt(this.#host.getAttribute('max-display-row'), 10) || 10;\n const maxRowHeight = Math.max(...activeSheets.map(sheet => sheet.getRowHeight()));\n\n const toolbarEl = this.#host.shadowRoot.querySelector('nine-table-toolbar');\n const footerEl = this.#host.shadowRoot.querySelector('nine-table-sheets-footer');\n\n const toolbarHeight = toolbarEl ? toolbarEl.getBoundingClientRect().height : 0;\n const footerHeight = footerEl ? footerEl.getBoundingClientRect().height : 0;\n const extraPadding = NineTableSheet.SCROLLBAR_SIZE;\n\n const calculatedHeight = (maxDisplayRows * maxRowHeight) + toolbarHeight + footerHeight + extraPadding;\n\n this.#host.style.height = `${calculatedHeight}px`;\n };\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n const sheetCount = rawTables.length;\n\n const sheetsHtml = rawTables.map((tbl, idx) => {\n const className = idx === 0 ? 'active' : '';\n const sheetId = tbl.id || `sheet${idx + 1}`;\n\n const sheetTag = `<nine-table-sheet class=\"${className}\" data-index=\"${idx}\" data-sheet-id=\"${sheetId}\" id=\"${sheetId}\"></nine-table-sheet>`;\n const splitterTag = idx < sheetCount - 1 ? `<nine-splitter class=\"h\" data-split-index=\"${idx}\"></nine-splitter>` : '';\n return sheetTag + splitterTag;\n }).join('');\n\n const cssImports = [\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/datagrid@${__APP_VERSION__}/dist/css/nine-table.css\";`,\n ];\n\n if (nine[\"nine-table\"] && nine[\"nine-table\"].cssFile) {\n cssImports.push(`@import \"${nine[\"nine-table\"].cssFile}\";`);\n }\n\n this.#host.shadowRoot.innerHTML = `\n <style>\n ${cssImports.join('\\n')}\n </style>\n \n <nine-table-toolbar></nine-table-toolbar>\n\n <nine-table-body>\n <nine-table-summary></nine-table-summary>\n <div class=\"ng-loading-bar\"></div>\n <nine-table-sheets>\n <nine-table-sheets-body>\n ${sheetsHtml}\n </nine-table-sheets-body>\n <nine-table-sheets-footer></nine-table-sheets-footer>\n </nine-table-sheets>\n <nine-table-analysis></nine-table-analysis>\n </nine-table-body>\n <nine-table-footer></nine-table-footer>\n `;\n\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($el, idx) => {\n\n if (rawTables[idx]) {\n setTimeout(() => {\n $el.generate(rawTables[idx], idx);\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n });\n }\n });\n };\n}","import { trace } from \"@nopeer\";\n\nexport class ExprEngine {\n #host;\n #fields;\n #exprCache = new Map(); // 💡 통합된 단일 캐시로 모든 컴파일된 함수 관리\n\n constructor(host) {\n this.#host = host;\n this.#fields = host.fields.get();\n }\n\n rewriteExpr(expr) {\n\n if (!expr || !this.#fields.length) return expr;\n\n return expr.replace(/data\\.([a-zA-Z_$][\\w$]*)/g, (match, fieldName) => {\n const idx = this.#fields.indexOf(fieldName);\n return idx >= 0 ? `rowItem.v[${idx}]` : match;\n });\n }\n\n precompile(expr) {\n if (!expr) return expr;\n return this.rewriteExpr(expr);\n }\n\n evaluate(expr, rowItem, row = 0) {\n\n if (expr === undefined || expr === null) return \"\";\n\n try {\n const trimmedExpr = String(expr).trim();\n const compiledExpr = this.rewriteExpr(trimmedExpr);\n\n if (compiledExpr.includes(\"provider.\") || compiledExpr.includes(\"host.\") || compiledExpr.includes(\"data.\") || compiledExpr.includes(\"rowItem.v\") || compiledExpr.includes(\"(\")) {\n\n let evalFn = this.#exprCache.get(compiledExpr);\n\n if (!evalFn) {\n evalFn = new Function('rowItem', 'row', 'host', `\n const data = rowItem;\n const provider = host;\n\n if (!data && !host) return \"\";\n return ${compiledExpr};\n `);\n\n this.#exprCache.set(compiledExpr, evalFn);\n }\n\n return evalFn(rowItem, row, this.#host);\n }\n\n return compiledExpr;\n } catch (e) {\n /**\n if (expr.includes(\"getCommonCode\")) {\n console.trace(\"ExprEngine evaluation error:\", e);\n } */\n return expr;\n }\n }\n}","import { trace } from \"@nopeer\";\nimport { ngDataManager } from '@/data/ngDataManager.js';\nimport { fields } from \"@/data/Fields.js\";\nimport { LayoutManager } from '@/layout/core/LayoutManager.js';\nimport { ExprEngine } from \"@/core/ExprEngine.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #templateCnt = 0; // 🎯 로딩 상태 플래그\n\n constructor() {\n super();\n\n if ([\"NINE-TABLE\"].includes(this.tagName)) {\n trace.log(\"Welcome nine-table\", __APP_VERSION__);\n }\n\n this.#shadowRoot = this.attachShadow({ mode: 'open' });\n this.#dataManager = new ngDataManager(this);\n }\n\n connectedCallback() {\n setTimeout(() => {\n this.#templateCnt = this.querySelectorAll(\"table\")?.length;\n\n this.fields = new fields(this);\n this.exprEngine = new ExprEngine(this);\n\n this.#bindDynamicSetters();\n\n this.#layoutManager = new LayoutManager(this);\n\n this.#dispatchLoad();\n });\n }\n\n disconnectedCallback() {\n //trace.log('NineTable disconnected.');\n }\n\n #dispatchLoad = () => {\n\n let checkCount = 0;\n const maxChecks = 50; // 최대 5초 대기 (100ms * 50)\n\n const checkTimer = setInterval(() => {\n checkCount++;\n\n const sheets = this.shadow.querySelectorAll('nine-table-sheet');\n\n if (checkCount >= maxChecks) {\n clearInterval(checkTimer);\n }\n\n if (sheets.length >= this.#templateCnt) {\n let loadSheetCnt = 0;\n sheets.forEach($sheet => {\n if ($sheet.loaded) loadSheetCnt++;\n });\n\n if (loadSheetCnt >= this.#templateCnt) {\n clearInterval(checkTimer);\n this.loaded = true;\n this.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.LOAD, { bubbles: true, detail: { target: this } }));\n }\n }\n }, 100);\n }\n\n // 🎯 공통 데이터 & API 접근자\n get shadow() { return this.#shadowRoot; }\n get dataManager() { return this.#dataManager; }\n get data() { return this.#dataManager.data; }\n get row() { return this.#dataManager.row; }\n\n\n addProvider(methods) {\n if (!methods || typeof methods !== 'object') return;\n\n setTimeout(() => {\n Object.entries(methods).forEach(([name, fn]) => {\n if (typeof fn === 'function') {\n this[name] = fn;\n }\n });\n\n this.rerenderer();\n });\n }\n\n setData(records) {\n this.#dataManager.data.set(records);\n this.refresh();\n }\n\n refresh() {\n this.activeSheet?.invalidate();\n }\n\n\n set loading(val) {\n if (this.#layoutManager) this.#layoutManager.loading = val;\n }\n\n rerenderer() {\n\n this.activeSheet?.querySelectorAll(\"tbody.body th,tbody.body td\").forEach(($cell) => {\n const customComp = Array.from($cell.children).find($el => {\n return $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.rerenderer === 'function'\n });\n\n customComp?.rerenderer();\n })\n }\n\n sheet = (idOrIndex) => {\n if (idOrIndex === null || idOrIndex < 0) return this.activeSheet;\n const sheets = Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n\n if (typeof idOrIndex === 'number') return sheets[idOrIndex] || null;\n if (typeof idOrIndex === 'string') {\n return this.shadow.querySelector(`nine-table-sheet#${idOrIndex}, nine-table-sheet[data-sheet-id=\"${idOrIndex}\"]`) || null;\n }\n return sheets[0] || null;\n }\n\n get sheets() {\n return Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n }\n\n get activeSheet() {\n return this.shadow.querySelector('nine-table-sheet.active') || null;\n }\n\n #bindDynamicSetters() {\n const extractedMethodNames = new Set();\n\n this.querySelectorAll('[data-source]').forEach(el => {\n const dataSource = el.getAttribute('data-source');\n if (!dataSource) return;\n\n const matches = dataSource.matchAll(/(?:host\\.)?([a-zA-Z0-9_$]+)\\s*\\(/g);\n for (const match of matches) {\n const name = match[1];\n if (name && name !== 'host') {\n extractedMethodNames.add(name);\n }\n }\n });\n\n extractedMethodNames.forEach(methodName => {\n let internalValue = null;\n\n Object.defineProperty(this, methodName, {\n set: (newValue) => {\n internalValue = newValue;\n\n this.rerenderer();\n },\n get: () => internalValue,\n configurable: true,\n enumerable: true\n });\n });\n }\n\n execute = (fn) => {\n setTimeout(() => {\n this.loading = true;\n setTimeout(() => {\n try {\n fn.call(this);\n } finally {\n this.loading = false;\n }\n });\n });\n }\n}\n\nif (!customElements.get('nine-table')) {\n customElements.define('nine-table', NineTable);\n}\n\nif (!customElements.get('nine-table-simple')) {\n customElements.define('nine-table-simple', class extends NineTable {\n connectedCallback() {\n this.setAttribute('theme', 'simple');\n\n super.connectedCallback();\n }\n });\n}","export class BasicCellElement extends HTMLElement {\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tapplyBaseStyle() {\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { BasicCellElement } from './BasicCellElement.js';\r\n\r\nconst exprCache = new Map();\r\n\r\nexport class CellElement extends BasicCellElement {\r\n\t#host;\r\n\t#sheet;\r\n\t#tr;\r\n\t#cell;\r\n\t#attr;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tget host() { return this.#host; }\r\n\tget sheet() { return this.#sheet; }\r\n\tget cell() { return this.#cell; }\r\n\tget tr() { return this.#tr; }\r\n\tget attr() { return this.#attr; }\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\tthis.#cell = this.closest(\"th,td\");\r\n\t\tthis.#tr = this.#cell.closest(\"tr\");\r\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\r\n\r\n\t\tthis.#cell.classList.add(this.tagName);\r\n\r\n\t\tthis.#attr = {};\r\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\r\n\t\t\tconst name = this.#cell.attributes[i].name;\r\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\r\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\r\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#cell) return;\r\n\r\n\r\n\t\tconst root = this.shadowRoot || this;\r\n\r\n\t\t// 🎯 버튼 이벤트 연결\r\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\r\n\t\t\tbutton.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\r\n\r\n\t\t\t\tconst rowData = this.data; // Proxy Lazy 접근\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t/**\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t})); */\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 링크 이벤트 연결\r\n\t\tconst renderer = root.querySelector(\".renderer\");\r\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\r\n\t\t\trenderer.classList.add(\"link\");\r\n\r\n\t\t\trenderer.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\r\n\r\n\t\t\t\tconst rowData = this.data;\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t}));\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tget data() {\r\n\t\tconst rawRecord = this.#tr?.data;\r\n\t\tif (!rawRecord) return null;\r\n\t\tif (!rawRecord.v) return rawRecord;\r\n\r\n\t\tconst host = this.#host;\r\n\r\n\t\treturn new Proxy(rawRecord, {\r\n\t\t\tget(target, prop) {\r\n\t\t\t\tif (prop === '__ng') return target.__ng;\r\n\t\t\t\tif (prop === 'v') return target.v;\r\n\r\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\r\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tget value() {\r\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\r\n\r\n\t\tconst bindKey = this.#cell.dataset?.bind;\r\n\t\tif (!bindKey) return \"\";\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\r\n\t\t\t// 💡 fields.indexOf(bindKey)로 바로 찾기!\r\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\r\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\r\n\t\t}\r\n\r\n\t\treturn rawRecord[bindKey] ?? \"\";\r\n\t}\r\n\r\n\tset value(v) {\r\n\t\tif (!this.#cell || !this.#host?.data) return;\r\n\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tif (isNaN(row) || !bindKey) return;\r\n\r\n\t\tconst updateRowState = this.getAttribute('update-row-state') !== \"false\";\r\n\t\tthis.#host.data.setValue(row, bindKey, v, updateRowState);\r\n\t}\r\n\r\n\tget row() {\r\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\r\n\t}\r\n\tget index() {\r\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\r\n\t}\r\n\r\n\tisValid() {\r\n\t\treturn this.#cell.classList.contains(\"invalid\") ? false : true;\r\n\t}\r\n\r\n\tisInvalid() {\r\n\t\treturn !this.isValid();\r\n\t}\r\n\r\n\tgetDisplayText = (defaultValue = \"\") => {\r\n\r\n\t\tif (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\tif (!rawRecord) return defaultValue;\r\n\r\n\t\tconst expr = this.#cell.dataset.expr;\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\tif (expr) {\r\n\t\t\ttry {\r\n\t\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\r\n\r\n\t\t\t\t\treturn this.getGroupExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row);\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\treturn defaultValue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (bindKey) {\r\n\t\t\tconst val = this.value;\r\n\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\r\n\t\t}\r\n\r\n\t\treturn defaultValue;\r\n\t};\r\n\r\n\r\n\r\n\trefresh() {\r\n\r\n\t\tif (!this.#cell || !this.#tr) return;\r\n\r\n\t\tconst val = this.value;\r\n\r\n\t\tthis.#cell.classList.remove(\"invalid\");\r\n\r\n\t\t[\"color\",\"background\",\"background-color\",\"visible\",\"enable\",\"validator\"].forEach(v => {\r\n\r\n\t\t\tconst expr = this.#attr[v];\r\n\t\t\tif (expr) {\r\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10));\r\n\r\n\t\t\t\tif (v === \"validator\") {\r\n\t\t\t\t\tif (!result) {\r\n\t\t\t\t\t\tthis.#cell.classList.add(\"invalid\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else if (v === \"visible\") {\r\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\r\n\t\t\t\t} else if (v === \"enable\") {\r\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\r\n\t\t\t\t\t\t$el.disabled = !result;\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif (!!result) {\r\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#cell.style[v] = result;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn val;\r\n\t}\r\n\r\n\tgetExprValue(expr, data, row) {\r\n\t\tif (!this.#host || !this.#host.exprEngine || expr === undefined || expr === null || expr === \"\") return expr;\r\n\r\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row);\r\n\t}\r\n\r\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\r\n\t\tif (!expr) return \"\";\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\r\n\r\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\r\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\r\n\t\t\tif (match) {\r\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\r\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\r\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\r\n\r\n\t\t\t\tconst [, funcName, field] = match;\r\n\t\t\t\tconst host = this.#host;\r\n\r\n\t\t\t\tswitch (funcName.toLowerCase()) {\r\n\t\t\t\t\tcase 'count':\r\n\t\t\t\t\t\treturn childRecords.length;\r\n\r\n\t\t\t\t\tcase 'sum': {\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tcase 'avg': {\r\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t\treturn sum / childRecords.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 3. 호스트의 exprFunction 활용\r\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\r\n\t\t\t}\r\n\r\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\r\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\r\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\r\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\r\n \r\n let childRecords = [];\r\n if (Array.isArray(indices)) {\r\n // indices가 숫자 인덱스 배열인지, rowid 문자열 배열인지 판별하여 안전하게 추출\r\n childRecords = indices.map(idx => {\r\n if (typeof idx === 'number') {\r\n return allRecords[idx];\r\n } else {\r\n // rowid 등 문자열 식별자인 경우 전체 배열에서 찾거나 dataManager 활용\r\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\r\n }\r\n }).filter(Boolean);\r\n }\r\n \r\n // 만약 위에서 못 찾았는데 host.grouping을 쓸 수 있다면 매니저 위임 시도\r\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\r\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\r\n }\r\n\r\n const data = childRecords; // data.length 등을 쓸 수 있도록 호환\r\n return ${expr};\r\n `);\r\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\r\n\t\t\t}\r\n\r\n\t\t\treturn expr;\r\n\t\t} catch (e) {\r\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\r\n\t\t\treturn expr;\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class EditableCellElement extends CellElement {\r\n\r\n\tget host() { return super.host; }\r\n\tget sheet() { return super.sheet; }\r\n\tget cell() { return super.cell; }\r\n\tget tr() { return super.tr; }\r\n\tget attr() { return super.attr; }\r\n\r\n\tgetExprValue(expr, data, row, cell) {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\t}\r\n\r\n\trefresh() {\r\n\t\treturn super.refresh();\r\n\t}\r\n\r\n\tgetExprValue = (expr, data, row, cell) => {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tisValid = () => {\r\n\t\treturn super.isValid();\r\n\t}\r\n\r\n\tisInvalid = () => {\r\n\t\treturn super.isInvalid();\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputText extends EditableCellElement\n{\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\t\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#initEvent();\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tthis.#target.value = v;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"input\", e => {\n\t\t\tif (this.#maxbyte) {\n\t\t\t\tconst maxByteNum = Number(this.#maxbyte);\n\t\t\t\tconst currentBytes = nine.getByteLength(e.target.value);\n\n\t\t\t\tif (currentBytes > maxByteNum) {\n\t\t\t\t\te.target.value = nine.cut(e.target.value, maxByteNum);\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<input type=\"text\" ondragstart=\"return false;\">\n\t\t`;\n\t};\n\n\tget #maxbyte() {\n\t\treturn this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\t}\n}\n\nif (!customElements.get('cell-input')) {\n\tcustomElements.define(\"cell-input\", CellInputText);\n}\n","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputNumber extends EditableCellElement\n{\n\t#target;\n\n\tconstructor () {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#initEvent();\n\n\n\t};\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <input type=\"text\" ondragstart=\"return false;\">\n `;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"keydown\", this.#onKeyDown);\n\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tthis.#target.value = v;//v !== undefined && v !== null ? v : \"\";\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate();\n\t\t}\n\t};\n\n\t#validate = () => {\n\n\t\tconst v = this.#target.value;\n\n\t\tif (v !== \"\" && v !== null && v !== undefined) {\n\t\t\tconst num = Number(v);\n\n\t\t\tif (isNaN(num) || (this.#max && num > Number(this.#max)) || (this.#min && num < Number(this.#min))) {\n\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (this.#scale) {\n\t\t\t\tconst str = String(v);\n\t\t\t\tconst idx = str.indexOf('.');\n\t\t\t\tif (idx >= 0 && str.substring(idx + 1).length > Number(this.#scale)) {\n\t\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t#onKeyDown = e => {\n\n\t\tif ([\"Escape\", \"Enter\", \"Tab\", \"Home\", \"End\", \"ArrowLeft\", \"ArrowRight\", \"PageUp\", \"PageDown\", \"Backspace\", \"Delete\"].includes(e.code)) return;\n\n\t\tconst target = e.target;\n\t\tconst value = target.value;\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst key = e.key;\n\n\t\tif (key === \"-\") {\n\t\t\tif (value.includes(\"-\") || selectionStart !== 0) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (key === \".\") {\n\t\t\tconst scale = Number(this.#scale);\n\n\t\t\tif (isNaN(scale) || scale <= 0 || value.includes(\".\")) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tlet validKey = [];\n\t\tif (this.#scale && Number(this.#scale) > 0) validKey.push(\".\");\n\t\tif (this.#min || Number(this.#min) > 0) validKey.push(\"-\");\n\n\t\tconst isNumKey = (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105);\n\n\t\tif (!isNumKey && !validKey.includes(e.key)) {\n\t\t\te.preventDefault();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#scale && isNumKey && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\tconst s = e.target.value;\n\t\t\tconst idx = s.indexOf(\".\");\n\t\t\tif (idx >= 0 && e.target.selectionStart > idx) {\n\t\t\t\tconst decimalPart = s.substr(idx + 1);\n\t\t\t\tif (decimalPart.length >= Number(this.#scale)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.#maxbyte && nine.getByteLength(e.target.value) >= Number(this.#maxbyte) && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\te.preventDefault();\n\t\t}\n\t}\n\n\tget #min() {\n\t\treturn this.cell.getAttribute(\"min\") || \"\";\n\t}\n\n\tget #max() {\n\t\treturn this.cell.getAttribute(\"max\") || \"\";\n\t}\n\n\tget #scale() {\n\t\treturn this.cell.getAttribute(\"scale\") || \"\";\n\t}\n\n\tget #maxbyte() {\n\t\treturn this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\t}\n}\n\nif (!customElements.get('cell-input-number')) {\n\tcustomElements.define(\"cell-input-number\", CellInputNumber);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputColor extends EditableCellElement\n{\n\t#target;\n\t#btn;\n\t#dataSource;\n\n\tconstructor () {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input[type=color]\");\n\t\tthis.#btn = this.querySelector(\"button\");\n\n\t\t//this.#rendererColor();\n\n\t\tthis.#initEvent();\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#btn.addEventListener(\"click\", () => {\n\t\t\tthis.#target.click();\n\t\t});\n\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validate(val);\n\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validate(val);\n\n\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <input type=\"color\" ondragstart=\"return false;\">\n <button tabindex=\"-1\" type=\"button\"></button>\n `;\n\t};\n\n\trerenderer = () => {\n\t\tthis.refresh();\n\t};\n\n\t#rendererColor = () => {\n\n\t\tconst dataSource = this.cell.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, this.tr.data, this.tr.dataset.row);\n\n\t\tthis.querySelector(\"datalist\")?.remove();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\t\t\tconst datalistId = `color-list-${Math.random().toString(36).substr(2, 9)}`;\n\n\t\t\tconst datalist = document.createElement('datalist');\n\t\t\tdatalist.id = datalistId;\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tif (v.value) {\n\t\t\t\t\tconst option = document.createElement('option');\n\t\t\t\t\toption.value = v.value;\n\t\t\t\t\tfragment.appendChild(option);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdatalist.appendChild(fragment);\n\t\t\tthis.appendChild(datalist);\n\n\t\t\tthis.#target.setAttribute(\"list\", datalistId);\n\t\t}\n\t};\n\n\trefresh = () => {\n\t\tif (!this.tr.data) return;\n\n\t\tconst v = super.refresh();\n\n\t\tthis.#rendererColor();\n\n\t\tthis.#target.value = v !== undefined && v !== null && v !== \"\" ? v : \"#ffffff\";\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate();\n\t\t}\n\t};\n\n\t#validate = () => {\n\n\t\tconst v = this.#target.value;\n\n\t\tif (v !== \"\" && v !== null && v !== undefined) {\n\t\t\tif (!this.#isValidColor(v)) {\n\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (this.#dataSource && Array.isArray(this.#dataSource) && this.#dataSource.length > 0) {\n\t\t\t\tconst exists = this.#dataSource.some(item => {\n\t\t\t\t\tconst itemCode = item.value !== undefined ? item.value : (item.code !== undefined ? item.code : '');\n\t\t\t\t\treturn itemCode.toLowerCase() === v.toLowerCase();\n\t\t\t\t});\n\n\t\t\t\tif (!exists) {\n\t\t\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidColor = (v) => {\n\t\tif (typeof v !== \"string\" || v.length != 7 || !v.startsWith(\"#\")) return false;\n\n\t\tvar r = parseInt(v.substr(1, 2), 16);\n\t\tvar g = parseInt(v.substr(3, 2), 16);\n\t\tvar b = parseInt(v.substr(5, 2), 16);\n\n\t\tif (isNaN(r) || isNaN(g) || isNaN(b)) return false;\n\t\tif (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) return false;\n\n\t\treturn true;\n\t}\n}\n\nif (!customElements.get('cell-input-color')) {\n\tcustomElements.define(\"cell-input-color\", CellInputColor);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputDate extends EditableCellElement\n{\n\t#target;\n\t#type;\n\n\tconstructor () {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#target.classList.toggle(\"has-value\", !!val); // 💡 실시간 반영\n\t\t\tthis.#validate(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validate(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.#type = this.cell.getAttribute(\"date-type\") || \"date\";\n\t\tif (![\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(this.#type)) {\n\t\t\tthrow `invalid type : ${this.#type}`;\n\t\t}\n\n\t\tlet attr = [];\n\t\tfor (let i = 0; i < this.cell.attributes.length; i++) {\n\t\t\tif ([\"value\", \"max\", \"min\", \"step\"].includes(this.cell.attributes[i].name)) {\n\t\t\t\tattr.push(`${this.cell.attributes[i].name}=\"${this.cell.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <input\n type=\"${this.#type}\"\n data-placeholder=\"${this.cell.getAttribute('placeholder') || 'Select'}\"\n ${attr.join(\" \")}\n required\n />\n `;\n\t};\n\n\trefresh = () => {\n\n\t\tconst v = super.refresh();\n\n\t\tlet formattedVal = v;\n\t\tif (formattedVal) {\n\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"date\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"time\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"00\" + d.getHours()).slice(-2) + \":\" + (\"00\" + d.getMinutes()).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"0000\" + d.getFullYear()).slice(-4) + \"-\" + (\"00\" + (d.getMonth() + 1)).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis.#target.value = formattedVal || \"\";\n\t\tthis.#target.classList.toggle(\"has-value\", !!formattedVal); // 💡 값이 있으면 클래스 추가\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate(formattedVal);\n\t\t}\n\t};\n\n\t#validate = (val) => {\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tlet isValid = this.#isValidDate(val);\n\n\t\t\tif (isValid) {\n\t\t\t\tif (this.#min && val < this.#min) isValid = false;\n\t\t\t\tif (this.#max && val > this.#max) isValid = false;\n\t\t\t}\n\n\t\t\tif (!isValid) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidDate = (v) => {\n\n\t\tif (typeof v !== \"string\") return false;\n\n\t\tlet isValid = true;\n\n\t\tswitch (this.#type) {\n\t\t\tcase \"date\":\n\t\t\tcase \"datetime-local\":\n\t\t\t\tconst year = Number(v.substr(0, 4));\n\t\t\t\tconst month = Number(v.substr(5, 2));\n\t\t\t\tconst day = Number(v.substr(8, 2));\n\n\t\t\t\tif (isNaN(year) || isNaN(month) || isNaN(day)) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month < 1 || month > 12 || day < 1 || day > 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if ([4, 6, 9, 11].includes(month) && day == 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month == 2) {\n\t\t\t\t\tlet isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));\n\t\t\t\t\tif (day > 29 || (day == 29 && !isleap)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (isValid) {\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tvar t = v.substr(10, 1);\n\t\t\t\t\tvar hour = Number(v.substr(11, 2));\n\t\t\t\t\tvar min = Number(v.substr(14, 2));\n\n\t\t\t\t\tif (t != \"T\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(hour) || isNaN(min)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (hour < 0 || hour > 23 || min < 0 || min > 59) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar month = Number(v.substr(5, 2));\n\n\t\t\t\t\tif (isNaN(year) || isNaN(month)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (month < 1 || month > 12) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"week\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar w = v.substr(5, 1);\n\t\t\t\t\tvar week = Number(v.substr(6, 2));\n\n\t\t\t\t\tif (w != \"W\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(year) || isNaN(week)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (week <= 0 || week > 53) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn isValid;\n\t}\n\n\tget #min() {\n\t\treturn this.cell.getAttribute(\"min\");\n\t}\n\n\tget #max() {\n\t\treturn this.cell.getAttribute(\"max\");\n\t}\n\n\tget #step() {\n\t\treturn this.cell.getAttribute(\"step\");\n\t}\n}\n\nif (!customElements.get('cell-input-date')) {\n\tcustomElements.define(\"cell-input-date\", CellInputDate);\n}","import { EditableCellElement } from \"./core/CellElement.js\";\nimport {trace} from \"@nopeer\";\n\nclass CellCheckbox extends EditableCellElement {\n #target;\n #label;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n super.connectedCallback();\n\n this.#renderer();\n\n this.#target = this.querySelector(\"input\");\n this.#label = this.querySelector(\"span\");\n\n this.#initEvent();\n }\n\n get dataSource() {\n return [\n { value: this.trueValue, text: this.#trueText },\n { value: this.falseValue, text: this.#falseText }\n ];\n }\n\n #initEvent = () => {\n if (this.closest(\"thead\")) {\n this.#target.addEventListener(\"change\", (e) => {\n super.sheet.querySelector(`tbody.body [data-col=\"${super.cell.dataset.col}\"] cell-checkbox`)?.selectAll(e.target.checked);\n });\n }\n\n this.#target.addEventListener(\"change\", (event) => {\n if (!this.closest(\"tbody\")) return;\n\n if (this.#isRadio) {\n this.selectAll(false);\n this.value = this.trueValue;\n }\n else {\n this.value = event.target.checked ? this.trueValue : this.falseValue;\n }\n\n this.sheet.rowManager.refresh(true);\n });\n };\n\n #renderer = () => {\n\n const trueValue = this.trueValue;//this.cell.getAttribute(\"true-value\") || false;\n //const selectedBorderColor = this.getAttribute(\"selected-border-color\") || \"dimgray\";\n\n const originalContent = this.cell.getAttribute(\"content\") || \"\";\n const childHtml = this.#isRadio ? `<input type=\"radio\" value=\"${trueValue}\" />` : `<label><input type=\"checkbox\" /><span>${originalContent}</span></label>`;\n\n this.innerHTML = `\n ${childHtml}\n `;\n }\n\n refresh = () => {\n const val = super.refresh();\n\n this.#target.checked = (val === this.trueValue);\n\n if (this.isValid()) {\n this.#validate(val);\n }\n\n const displayText = (val === this.trueValue) ? this.#trueText : ((val === this.falseValue) ? this.#falseText : val);\n\n if (this.#label) {\n this.#label.textContent = displayText;\n }\n };\n\n #validate = (val) => {\n\n this.cell.classList.remove(\"invalid\");\n\n if (val !== \"\" && val !== null && val !== undefined) {\n if (val !== this.trueValue && val !== this.falseValue) {\n this.cell.classList.add(\"invalid\");\n }\n }\n };\n\n selectAll = (v) => {\n if (this.closest(\"thead\")) return; // 헤더 자신은 제외\n\n const data = this.host.data.getArray();\n const colIndex = this.host.fields.indexOf(this.cell.dataset.bind);\n\n if (colIndex < 0) return;\n\n for (let i = 0; i < data.length; i++) {\n if (this.#enable && super.getExprValue(this.#enable, data[i], i, this.cell) === false) continue;\n if (this.#readonly && super.getExprValue(this.#readonly, data[i], i, this.cell) === true) continue;\n if (this.#visible && super.getExprValue(this.#visible, data[i], i, this.cell) === false) continue;\n\n data[i].v[colIndex] = v ? this.trueValue : this.falseValue;\n }\n\n super.sheet.invalidate();\n };\n\n get trueValue() {\n return this.cell.getAttribute(\"true-value\") || \"Y\";\n }\n get falseValue() {\n return this.cell.getAttribute(\"false-value\")|| \"N\";\n }\n get #trueText() {\n return this.cell.getAttribute(\"true-text\") || \"\";\n }\n get #falseText() {\n return this.cell.getAttribute(\"false-text\") || \"\";\n }\n get #isRadio() {\n return this.cell.getAttribute(\"is-radio\") || false;\n }\n get #enable() {\n return this.cell.getAttribute(\"enable\") || false;\n }\n get #readonly() {\n return this.cell.getAttribute(\"readonly\") || false;\n }\n get #visible() {\n return this.cell.getAttribute(\"visible\") || false;\n }\n}\n\nif (!customElements.get('cell-checkbox')) {\n customElements.define(\"cell-checkbox\", CellCheckbox);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellRadio extends EditableCellElement {\n\t#target;\n\t#radioList = [];\n\t#dataSource = [];\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#rendererRadio();\n\n\t\tthis.#initEvent();\n\t}\n\n\t#initEvent = () => {\n\n\t\tthis.cell.addEventListener(\"keydown\", e => {\n\n\t\t\tif (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n\t\t\tif (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n\t\t\tif (e.code === \"Space\") {\n\t\t\t\te.preventDefault();\n\n\t\t\t\tlet matchIndex = -1;\n\n\t\t\t\tthis.#radioList.forEach(($el,index) => {\n\t\t\t\t\tif (this.value === $el.getAttribute(\"value\")) {\n\t\t\t\t\t\tmatchIndex = index;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tmatchIndex = (matchIndex === this.#radioList.length - 1) ? 0 : (matchIndex >= 0 ? matchIndex + 1 : 0);\n\t\t\t\tthis.value = this.#radioList[matchIndex].getAttribute(\"value\");\n\n\t\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t\t}\n\t\t});\n\t};\n\n\t#rendererRadio = () => {\n\n\t\tif (!this.host) return;\n\n\t\tconst dataSource = this.cell.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, this.tr.data, this.tr.dataset.row);\n\n\t\tthis.#target.replaceChildren();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tconst codeVal = v[this.#keyName] !== undefined ? v[this.#keyName] : '';\n\t\t\t\tconst nameVal = v[this.#valueName] !== undefined ? v[this.#valueName] : '';\n\n\t\t\t\tconst label = document.createElement('label');\n\n\t\t\t\tconst input = document.createElement('input');\n\t\t\t\tinput.type = 'radio';\n\t\t\t\tinput.value = codeVal;\n\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tspan.textContent = nameVal;\n\n\t\t\t\tlabel.appendChild(input);\n\t\t\t\tlabel.appendChild(span);\n\t\t\t\tfragment.appendChild(label);\n\t\t\t});\n\n\t\t\tthis.#target.appendChild(fragment);\n\n\n\t\t\tthis.#radioList = Array.from(this.querySelectorAll(\"input\"));\n\n\n\n\t\t\tthis.#radioList.forEach($el => {\n\t\t\t\t$el.addEventListener(\"change\", (e) => {\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t\tthis.sheet.rowManager.refresh(true);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<div></div>\n `;\n\n\t\tthis.#target = this.querySelector(\"div\");\n\t};\n\n\trerenderer = () => {\n\t\tthis.#rendererRadio();\n\t\tthis.refresh();\n\t};\n\n\trefresh = () => {\n\n\t\tconst v = super.refresh();\n\n\t\tthis.#radioList.forEach($el => {\n\t\t\t$el.checked = (v === $el.value);\n\t\t});\n\n\t\tif (this.isValid()) {\n\t\t\tthis.#validate();\n\t\t}\n\t};\n\n\t#validate = () => {\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst idx = this.#dataSource.findIndex(m => this.value === m[this.#keyName]);\n\t\tif (idx < 0) {\n\t\t\tthis.cell.classList.add(\"invalid\");\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n\n\tget #keyName() {\n\t\treturn this.cell.getAttribute(\"key-name\") || \"k\";\n\t}\n\n\tget #valueName() {\n\t\treturn this.cell.getAttribute(\"value-name\") || \"v\";\n\t}\n}\n\nif (!customElements.get('cell-radio')) {\n\tcustomElements.define(\"cell-radio\", CellRadio);\n}","import { trace } from \"@nopeer\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#parent;\n\t#keyName;\n\t#valueName;\n\t#isOpen = false;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tthis.#initEvents();\n\t}\n\n\t#initData = (dataSource, keyName, valueName, multi, separator) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource || dataSource.length === 0) return;\n\n\t\tconst itemsAttr = this.#parent.getAttribute(\"items\");\n\t\tlet fieldKeys = [];\n\n\t\tif (itemsAttr) {\n\t\t\tfieldKeys = itemsAttr.split(\",\").map(s => s.trim());\n\t\t} else {\n\t\t\tfieldKeys = [valueName].filter(Boolean);\n\t\t}\n\n\t\tconst activeColumnCount = fieldKeys.length;\n\n\t\tgrd.shadowRoot.querySelector(\".ng-container-left\").style.display = multi ? '' : 'none';\n\n\t\tgrd.shadowRoot.querySelectorAll('table colgroup col, tbody td').forEach(($el, idx) => {\n\n\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\tif (col >= 2) {\n\t\t\t\t$el.style.display = (col - 2 >= activeColumnCount) ? 'none' : '';\n\t\t\t}\n\t\t});\n\n\t\tconst formattedData = dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: keyName && item[keyName] !== undefined ? item[keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\tfieldKeys.forEach((key, idx) => {\n\t\t\t\trow[`tmp${idx + 1}`] = item[key] !== undefined ? item[key] : (item[idx] !== undefined ? item[idx] : \"\");\n\t\t\t});\n\t\t\treturn row;\n\t\t});\n\n\t\tgrd.data.set(formattedData);\n\n\t\tif (multi && this.#parent.value) {\n\t\t\tconst selectedKeys = String(this.#parent.value).split(separator || \",\");\n\t\t\tgrd.data.getValidData().forEach(m => {\n\t\t\t\tif (selectedKeys.includes(String(m.v[1]))) {\n\t\t\t\t\tm.v[0] = \"Y\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tgrd.refreshData();\n\t\t}\n\t};\n\n\topen = (parent, dataSource, keyName, valueName, multi, separator) => {\n\t\tthis.#parent = parent;\n\t\tthis.#keyName = keyName;\n\t\tthis.#valueName = valueName;\n\t\tthis.#isOpen = true;\n\n\t\tthis.classList.add(\"active\");\n\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource) return;\n\n\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\tif (dataSource.length > 10) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tif (multi) {\n\t\t\tthis.classList.add(\"multi\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"multi\");\n\t\t}\n\n\t\tconst sheet = parent.closest(\"nine-table-sheet\");\n\t\tconst btnEl = parent.querySelector(\".btn1\");\n\t\tif (!btnEl || !sheet) return;\n\n\t\tconst btnRect = btnEl.getBoundingClientRect();\n\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\tlet left = btnRect.left - sheetRect.left;\n\t\tlet top = btnRect.bottom - sheetRect.top + 2;\n\n\t\tconst panelWidth = this.offsetWidth || 250;\n\t\tconst panelHeight = this.offsetHeight || 250;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 5);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\tif (top + panelHeight > sheetRect.height) {\n\t\t\tconst upwardTop = (btnRect.top - sheetRect.top) - panelHeight - 2;\n\t\t\tif (upwardTop >= 0) {\n\t\t\t\ttop = upwardTop;\n\t\t\t} else {\n\t\t\t\ttop = Math.max(0, sheetRect.height - panelHeight - 5);\n\t\t\t}\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\tsetTimeout(() => {\n\n\t\t\tthis.#initData(dataSource, keyName, valueName, multi, separator);\n\n\t\t\tconst viewContainer = grd.shadowRoot.querySelector(\".ng-container-body table tbody.body\");\n\n\t\t\tif (!viewContainer.__hasClickEvent) {\n\n\t\t\t\tviewContainer.addEventListener(\"mousedown\", (e) => {\n\n\t\t\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\t\t\tif (!tr) return;\n\n\t\t\t\t\tif (!multi) {\n\t\t\t\t\t\tthis.#onClickRow(e);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tviewContainer.__hasClickEvent = true;\n\t\t\t}\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#isOpen = false;\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus();\n\t\t}\n\t}\n\n\t#onClickRow = (e) => {\n\n\t\tconst sheet = e.target.closest(\"nine-table-sheet\");\n\t\tconst tr = e.target.closest(\"tr\");\n\n\t\tconst rowIndex = parseInt(tr.dataset.row, 10);\n\t\tconst record = sheet.view.get(rowIndex);\n\n\t\tthis.#parent.value = record.k;\n\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onOk = () => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst data = grd.data.getValidData();\n\n\t\tconst selectedKeys = [];\n\t\tdata.forEach(o => {\n\t\t\tif (o.v[0] === \"Y\") {\n\t\t\t\tselectedKeys.push(o.v[1]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = selectedKeys.join(this.#parent.getAttribute(\"multi-separator\") || \",\");\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onSelectAll = (e) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst isChecked = e.target.checked ? \"Y\" : \"N\";\n\t\tgrd.data.getValidData().forEach(m => { m.v[0] = isChecked; });\n\t\tgrd.refreshData();\n\t}\n\n\t#onInput = (e) => {\n\t\tconst keyword = e.target.value.toLowerCase();\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\n\t\tgrd.data.getValidDataNF().forEach(m => {\n\t\t\tconst match = Object.values(m.v).some(val =>\n\t\t\t\tval !== null && val !== undefined && String(val).toLowerCase().includes(keyword)\n\t\t\t);\n\t\t\tm.__ng.filtered = !match;\n\t\t});\n\n\t\tgrd.data.resetRecords();\n\t\tgrd.dataManager.viewRecords.reset();\n\t}\n\n\tget isOpen() {\n\t\treturn this.#isOpen;\n\t}\n\n\tget targetCell() {\n\t\treturn this.#parent;\n\t}\n\n\t#initEvents = () => {\n\t\tthis.querySelector(\".search-input\").addEventListener(\"input\", this.#onInput);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\t\t\tconst path = e.composedPath ? e.composedPath() : [];\n\n\t\t\tif (path.includes(this)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.close();\n\t\t});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <div class=\"head\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\n </div>\n \n <nine-table-simple class=\"combo-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"30\" fixed=\"left\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"0\" />\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"tmp1\" />\n <td data-bind=\"tmp2\" />\n <td data-bind=\"tmp3\" />\n <td data-bind=\"tmp4\" />\n <td data-bind=\"tmp5\" />\n <td data-bind=\"tmp6\" />\n <td data-bind=\"tmp7\" />\n <td data-bind=\"tmp8\" />\n <td data-bind=\"tmp9\" />\n <td data-bind=\"tmp10\" />\n <td data-bind=\"k\" />\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n \n <div class=\"footer\">\n <div>\n <input id=\"chkAll\" type=\"checkbox\" checked>\n <label for=\"chkAll\">Select All</label>\n </div>\n <button id=\"btnOk\">OK</button>\n </div>\n `;\n\t};\n}\n\nif (!customElements.get('cell-combo-panel')) {\n\tcustomElements.define(\"cell-combo-panel\", CellComboPanel);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport \"./cell-combo-panel.js\";\n\nexport class CellCombo extends EditableCellElement {\n\t#targetBtn;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\t#multi;\n\t#multiSeparator;\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tthis.#keyName = super.cell.getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = super.cell.getAttribute(\"value-name\") || \"v\";\n\t\tthis.#multi = super.cell.getAttribute('multi') === \"true\";\n\t\tthis.#multiSeparator = super.cell.getAttribute(\"multi-separator\") || \",\";\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\trerenderer = () => {\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\t#initData = () => {\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t}\n\n\t#initEvent = () => {\n\t\tthis.querySelectorAll(\"button\").forEach(btn => {\n\t\t\tbtn.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\t}\n\n\t#togglePanel = () => {\n\n\t\tif (!this.#panel) {\n\t\t\tthis.#panel = super.sheet.querySelector(\"cell-combo-panel\");\n\t\t\tif (!this.#panel) {\n\t\t\t\tthis.#panel = document.createElement(\"cell-combo-panel\");\n\t\t\t\tsuper.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\tif (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\t\tthis.#panel.close();\n\t\t} else {\n\t\t\tthis.#panel.open(this, this.#dataSource, this.#keyName, this.#valueName, this.#multi, this.#multiSeparator);\n\t\t}\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <button class=\"btn1\" type=\"button\" tabindex=\"-1\">Select</button>\n <button class=\"btn2\" type=\"button\" tabindex=\"-1\"></button>\n `;\n\n\t\tthis.#targetBtn = this.querySelector(\".btn1\");\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tif (!this.#targetBtn) return v;\n\n\t\tthis.#targetBtn.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#getDisplayText = () => {\n\t\tif (!this.value || !Array.isArray(this.#dataSource)) return \"\";\n\n\t\tif (this.#multi) {\n\t\t\tconst keys = String(this.value).split(this.#multiSeparator);\n\t\t\treturn this.#dataSource\n\t\t\t\t.filter(m => keys.includes(String(m[this.#keyName])))\n\t\t\t\t.map(m => m[this.#valueName])\n\t\t\t\t.join(this.#multiSeparator);\n\t\t} else {\n\t\t\tconst found = this.#dataSource.find(m => String(m[this.#keyName]) === String(this.value));\n\t\t\treturn found ? found[this.#valueName] : this.value;\n\t\t}\n\t}\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst list = this.#multi ? String(this.value).split(this.#multiSeparator) : [this.value];\n\t\tfor (const v of list) {\n\t\t\tconst idx = this.#dataSource.findIndex(m => String(v) === String(m[this.#keyName]));\n\t\t\tif (idx < 0) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-combo')) {\n\tcustomElements.define(\"cell-combo\", CellCombo);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRenderer extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"span\");\n\t}\n\n\trefresh = () => {\n\n\t\tsuper.refresh();\n\n\t\tif (this.cell.getAttribute(\"html\") === \"true\") {\n\t\t\tthis.#target.innerHTML = this.getDisplayText();\n\t\t} else {\n\t\t\tthis.#target.textContent = this.getDisplayText();\n\t\t}\n\t};\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <span class=\"wrapper\"></span>\n `;\n\t};\n}\n\nif (!customElements.get(\"cell-renderer\")) {\n\tcustomElements.define(\"cell-renderer\", CellRenderer);\n}","import { CellElement } from \"./core/CellElement.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { trace } from \"@nopeer\";\n\nexport class CellButton extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"button\");\n\n\t\tthis.#target.removeEventListener(\"click\", this.#cellButtonClick);\n\t\tthis.#target.addEventListener(\"click\", this.#cellButtonClick);\n\t}\n\n\t#cellButtonClick = e => {\n\t\te.stopPropagation();\n\n\t\tconst rowid = parseInt(this.cell.dataset.row, 10);\n\n\t\tconst customEvent = new CustomEvent(NINE_TABLE.EVENT.CELL_BUTTON_CLICK, {\n\t\t\tbubbles: true,\n\t\t\tcomposed: true,\n\t\t\tdetail: {\n\t\t\t\toriginalEvent: e,\n\t\t\t\tcell: this.cell,\n\t\t\t\trow: rowid,\n\t\t\t\tcol: parseInt(this.cell.dataset.col, 10),\n\t\t\t\tbind: this.dataset.bind,\n\t\t\t\tdata: this.host.data.get(rowid),\n\t\t\t\tvalue: this.value,\n\t\t\t}\n\t\t});\n\n\t\tthis.dispatchEvent(customEvent);\n\t};\n\n\trefresh = () => {\n\t\tconst rawValue = super.refresh ? super.refresh() : this.value;\n\t\t//let displayValue = this.getDisplayText(rawValue);\n\t\tthis.#target.innerHTML = this.getDisplayText(rawValue);\n\t};\n\n\t#renderer = () => {\n\n\t\tconst buttonText = \"...\";//this.getAttribute(\"text\") || super.attr[\"text\"] || \"\";\n\n\t\tthis.innerHTML = `\n <button class=\"button\">${buttonText}</button>\n `;\n\t};\n}\n\nif (!customElements.get('cell-button')) {\n\tcustomElements.define(\"cell-button\", CellButton);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRowIndicator extends CellElement {\n\t#mainTarget;\n\t#subTarget;\n\t#statusTarget;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tif (this.cell) {\n\t\t\tthis.cell.removeAttribute(\"tabindex\");\n\t\t\tthis.cell.dataset.bind = \"rowState\";\n\t\t}\n\n\t\tthis.#mainTarget = this.querySelector(\".ng-row-main\");\n\t\tthis.#subTarget = this.querySelector(\".ng-row-sub\");\n\t\tthis.#statusTarget = this.querySelector(\".ng-row-status\");\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n\t\t\t<span class=\"ng-row-main\"></span>\n <span class=\"ng-row-sub\"></span>\n <span class=\"ng-row-status\"></span>\n `;\n\t}\n\n\trefresh = () => {\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tconst row = this.row;\n\t\tif (isNaN(row)) return;\n\n\t\tconst rawRecord = this.tr.data;\n\n\t\tif (rawRecord && rawRecord.__ng) {\n\n\t\t}\n\n\t\tconst displayNum = this.index + 1;\n\t\tconst formattedNum = displayNum.toLocaleString();\n\n\t\tif (displayNum >= 10000) {\n\n\t\t\tconst splitIndex = formattedNum.length - 4;\n\t\t\tconst prefixPart = formattedNum.substring(0, splitIndex + 1);\n\t\t\tconst suffixPart = formattedNum.substring(splitIndex + 1);\n\n\t\t\tthis.#mainTarget.innerHTML = `\n \t<span class=\"ng-row-prefix\">${prefixPart}</span>\n \t<span class=\"ng-row-suffix\">${suffixPart}</span>\n \t`;\n\t\t} else {\n\t\t\tthis.#mainTarget.innerHTML = `${formattedNum}`;\n\t\t}\n\n\t\tconst isSorted = this.sheet.querySelector(\"thead .asc,thead .desc\") ? true : false;\n\t\tconst isFitered = this.sheet.querySelector(\"thead nine-table-filter-button.filtered\") ? true : false;\n\n\t\tthis.#subTarget.innerHTML = row;\n\t\tthis.#subTarget.style.display = (isSorted || isFitered) ? \"\" : \"none\";\n\t};\n}\n\nif (!customElements.get('cell-row-indicator')) {\n\tcustomElements.define(\"cell-row-indicator\", CellRowIndicator);\n}","// ui/col/col-expand.js\nimport { COLLAPSED_WIDTH } from \"@/layout/core/TableCompiler.js\";\n\nexport class ColExpand extends HTMLElement {\n #sheet;\n #cell;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#cell = this.closest('th, td');\n this.#sheet = this.closest('nine-table-sheet');\n\n if (this.#cell) {\n this.#cell.style.position = 'relative';\n }\n\n const isCollapsed =\n this.getAttribute('collapsed') === 'true' ||\n this.#cell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n requestAnimationFrame(() => {\n this.collapse(true);\n });\n } else {\n this.classList.remove('collapsed');\n this.classList.add('expand');\n }\n\n this.removeEventListener('click', this.#onClick);\n this.addEventListener('click', this.#onClick);\n }\n\n #onClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (this.classList.contains('expand')) {\n this.collapse();\n } else {\n this.expand();\n }\n };\n\n expand = () => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n this.classList.remove('collapsed');\n this.classList.add('expand');\n this.#cell.setAttribute('collapsed', 'false');\n this.#cell.style.color = '';\n\n const targetWidth = parseInt(this.#cell.dataset.expandWidth, 10) || 100;\n\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, targetWidth);\n } else {\n const singleWidth = Math.max(30, Math.floor(targetWidth / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, singleWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n collapse = (isInitialInit = false) => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n if (this.classList.contains('expand')) {\n const col = this.#sheet.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n const currentW = col ? parseInt(col.getAttribute('width'), 10) : 0;\n if (currentW > COLLAPSED_WIDTH) {\n this.#cell.dataset.expandWidth = String(currentW * colSpan);\n }\n }\n\n this.classList.remove('expand');\n this.classList.add('collapsed');\n this.#cell.setAttribute('collapsed', 'true');\n this.#cell.style.color = 'transparent';\n\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, COLLAPSED_WIDTH);\n } else {\n const splitWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, splitWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n disconnectedCallback() {\n this.removeEventListener('click', this.#onClick);\n }\n}\n\nif (!customElements.get('nine-table-col-expand')) {\n customElements.define('nine-table-col-expand', ColExpand);\n}","import { trace } from \"@nopeer\";\nimport { ColFixManager } from \"@/col/ColFixManager.js\";\n\nexport class ContextMenu extends HTMLElement {\n #tableHost;\n #panel;\n\n connectedCallback() {\n const root = this.getRootNode();\n this.#tableHost = root instanceof ShadowRoot ? root.host : (this.closest('nine-table') || root.host);\n\n if (!this.#tableHost) {\n this.#tableHost = this.parentElement?.closest('nine-table') || this.assignedSlot?.closest('nine-table');\n }\n\n if (!this.#tableHost) return;\n }\n\n #onContextMenu = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n const targetCell = path.find(el => el.tagName === 'TH' || el.tagName === 'TD');\n\n if (!targetCell) return;\n\n const targetTable = path.find(el => el.tagName === 'TABLE') || targetCell.closest('table');\n\n e.preventDefault();\n e.stopPropagation();\n\n this.openMenu(e.clientX, e.clientY, targetCell, targetTable);\n };\n\n #getTargetSheet(targetCell) {\n return targetCell?.closest('nine-table-sheet') || this.#tableHost.activeSheet || this.#tableHost;\n }\n\n #getFixManager(targetCell) {\n const sheet = this.#getTargetSheet(targetCell);\n if (!sheet) return null;\n\n if (!sheet.colFix) {\n sheet.colFix = new ColFixManager(sheet);\n }\n return sheet.colFix;\n }\n\n #parseCustomMenuItems(containerElement, activeTable) {\n const items = [];\n const activeTableId = activeTable?.id;\n const allUls = Array.from(containerElement.querySelectorAll(':scope > ul'));\n\n allUls.forEach(rootUl => {\n const targetTableAttr = rootUl.getAttribute('target-table');\n\n if (!targetTableAttr || (activeTableId && targetTableAttr === activeTableId)) {\n const parsedList = this.#traverseUl(rootUl);\n items.push(...parsedList);\n }\n });\n\n return items;\n }\n\n #traverseUl(ulEl) {\n const list = [];\n Array.from(ulEl.children).forEach(child => {\n const tagName = child.tagName.toLowerCase();\n\n if (tagName === 'hr' || child.classList.contains('separator')) {\n list.push({ type: 'separator' });\n return;\n }\n\n if (tagName === 'li') {\n let name = '';\n const spanEl = child.querySelector(':scope > span');\n if (spanEl) {\n name = spanEl.textContent.trim();\n } else {\n name = Array.from(child.childNodes)\n .filter(n => n.nodeType === Node.TEXT_NODE)\n .map(n => n.textContent.trim())\n .join('');\n }\n\n const subUl = child.querySelector(':scope > ul');\n const item = {\n menuId: child.id || name,\n name: name,\n className: child.className || '',\n disabled: child.hasAttribute('disabled') || child.getAttribute('disabled') === 'true',\n isCustom: true\n };\n\n if (subUl) {\n item.items = this.#traverseUl(subUl);\n }\n\n list.push(item);\n }\n });\n return list;\n }\n\n #buildMenuItems(activeTable, isHeaderCell, targetCell) {\n const useDefault = this.getAttribute('use-default-menu') !== 'false';\n let rawItems = [];\n\n const customItems = this.#parseCustomMenuItems(this, activeTable);\n if (customItems.length > 0) {\n rawItems.push(...customItems);\n }\n\n const fixManager = this.#getFixManager(targetCell);\n const currentFixState = fixManager?.getFixState(targetCell, activeTable) ?? 'none';\n const isFixable = isHeaderCell && (fixManager?.canFixColumn(targetCell, activeTable) ?? false);\n\n let fixMenuItem = null;\n if (currentFixState === 'left' || currentFixState === 'right') {\n fixMenuItem = {\n menuId: 'unfix-column',\n name: 'Unfix Column',\n className: 'ng-menu-unfix-col',\n disabled: !isHeaderCell\n };\n } else {\n fixMenuItem = {\n menuId: 'fix-column',\n name: 'Fix Column',\n className: 'ng-menu-fix-col',\n disabled: !isFixable\n };\n }\n\n if (useDefault) {\n rawItems.push(\n { type: 'separator' },\n {\n menuId: 'sort',\n name: 'Sort',\n className: 'ng-menu-sort',\n disabled: !isHeaderCell\n },\n fixMenuItem,\n { type: 'separator' },\n { menuId: 'filtering', name: 'Filtering', className: 'ng-menu-filtering' },\n { menuId: 'maximize', name: 'Maximize', className: 'maximize' },\n {\n menuId: 'export',\n name: 'Export',\n className: 'export',\n items: [\n { menuId: 'export-excel', name: 'Excel', className: 'export-excel' },\n { menuId: 'export-pdf', name: 'PDF', className: 'export-pdf', disabled: true }\n ]\n },\n {\n menuId: 'properties',\n name: 'Options',\n className: 'options',\n items: [\n { menuId: 'show-title-bar', name: 'Title Bar Show/Hide', className: 'show-title-bar' },\n { menuId: 'show-status-bar', name: 'Status Bar Show/Hide', className: 'show-status-bar' },\n { menuId: 'auto-fit-col', name: 'Auto Fit Columns', className: 'auto-fit-col' }\n ]\n }\n );\n }\n\n const cleanedItems = [];\n rawItems.forEach((item) => {\n if (item.type === 'separator') {\n if (cleanedItems.length === 0 || cleanedItems[cleanedItems.length - 1].type === 'separator') {\n return;\n }\n }\n cleanedItems.push(item);\n });\n\n if (cleanedItems.length > 0 && cleanedItems[cleanedItems.length - 1].type === 'separator') {\n cleanedItems.pop();\n }\n\n return cleanedItems;\n }\n\n openMenu(x, y, targetCell, targetTable) {\n const targetParent = this.#tableHost.shadowRoot || this.#tableHost;\n\n if (!this.#panel) {\n this.#panel = document.createElement('nine-table-menu-panel');\n targetParent.appendChild(this.#panel);\n }\n\n const isHeaderCell = !!targetCell.closest('thead');\n const menuItems = this.#buildMenuItems(targetTable, isHeaderCell, targetCell);\n\n this.#panel.render(menuItems, (e) => this.#handleMenuClick(e, targetCell, targetTable));\n\n const targetSheet = this.#getTargetSheet(targetCell);\n this.#syncMenuStates(targetSheet);\n\n this.#panel.openAt(x, y);\n }\n\n #syncMenuStates(targetSheet) {\n if (!this.#panel || !targetSheet) return;\n\n const isFiltering = targetSheet.filtering?.isFiltering?.() || false;\n this.#panel.toggleItemState('filtering', 'on', isFiltering);\n\n const autoFit = this.#tableHost.getAttribute('auto-fit-col') === 'true';\n this.#panel.toggleItemState('auto-fit-col', 'on', autoFit);\n\n const showTitle = this.#tableHost.getAttribute('show-title-bar') === 'true';\n this.#panel.toggleItemState('show-title-bar', 'on', showTitle);\n }\n\n #handleMenuClick(e, targetCell, targetTable) {\n const menuId = e.menuId;\n\n const customEvent = new CustomEvent('menu-click', {\n detail: { menuId, targetCell, targetTable, originalEvent: e },\n bubbles: true,\n composed: true\n });\n this.dispatchEvent(customEvent);\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const targetSheet = this.#getTargetSheet(targetCell);\n\n switch (menuId) {\n case 'fix-column':\n case 'unfix-column':\n const fixManager = this.#getFixManager(targetCell);\n fixManager?.executeFixToggle(menuId, targetCell);\n break;\n\n case 'sort':\n if (!isNaN(baseCol)) {\n targetSheet.sorting?.handleSortFromMenu?.(baseCol, targetCell);\n }\n break;\n\n case 'filtering':\n targetSheet?.filtering?.toggle();\n break;\n\n case 'auto-fit-col':\n this.#tableHost.setAttribute('auto-fit-col', this.#tableHost.getAttribute('auto-fit-col') === 'true' ? 'false' : 'true');\n break;\n\n case 'show-title-bar':\n this.#tableHost.setAttribute('show-title-bar', this.#tableHost.getAttribute('show-title-bar') === 'true' ? 'false' : 'true');\n break;\n }\n\n this.#panel.close();\n }\n\n disconnectedCallback() {\n this.#tableHost?.removeEventListener('contextmenu', this.#onContextMenu);\n }\n}\n\nif (!customElements.get('nine-table-menu')) {\n customElements.define('nine-table-menu', ContextMenu);\n}","// ui/menu/nine-table-menu-panel.js\n\nexport class MenuPanel extends HTMLElement {\n #onCallback;\n #closeHandler = null;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n this.style.position = 'fixed';\n this.style.display = 'none';\n this.style.zIndex = '99999';\n\n this.innerHTML = `\n <div class=\"menu-wrapper\">\n <ul class=\"menu-container\"></ul>\n </div>\n `;\n }\n\n render(items, callback) {\n this.#onCallback = callback;\n const container = this.querySelector('.menu-container');\n if (!container) return;\n\n container.innerHTML = '';\n\n this.#appendItems(container, items);\n this.#bindClickEvents();\n }\n\n openAt(x, y, targetCell = null) {\n this.style.display = 'block';\n\n if (targetCell) {\n const cellRect = targetCell.getBoundingClientRect();\n const cellRightX = cellRect.right;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const panelWidth = wrapper.getBoundingClientRect().width;\n\n let calculatedLeft = cellRightX - panelWidth;\n\n if (calculatedLeft < 0) {\n calculatedLeft = cellRect.left;\n }\n\n const panelHeight = wrapper.getBoundingClientRect().height;\n let calculatedTop = y;\n if (y + panelHeight > window.innerHeight) {\n calculatedTop = y - panelHeight;\n }\n\n this.style.left = `${calculatedLeft}px`;\n this.style.top = `${calculatedTop}px`;\n });\n } else {\n this.style.left = `${x}px`;\n this.style.top = `${y}px`;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n\n if (x + rect.width > window.innerWidth) {\n this.style.left = `${x - rect.width}px`;\n }\n if (y + rect.height > window.innerHeight) {\n this.style.top = `${y - rect.height}px`;\n }\n });\n }\n\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n }\n\n this.#closeHandler = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n if (!path.includes(this) && !this.contains(e.target)) {\n this.close();\n }\n };\n\n setTimeout(() => {\n window.addEventListener('pointerdown', this.#closeHandler);\n }, 0);\n }\n\n close() {\n this.style.display = 'none';\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n this.#closeHandler = null;\n }\n }\n\n toggleItemState(menuId, className, condition) {\n const li = this.querySelector(`li[menu-id=\"${menuId}\"]`);\n if (li) {\n condition ? li.classList.add(className) : li.classList.remove(className);\n }\n }\n\n #appendItems(parentUl, items) {\n items.forEach(item => {\n if (item.type === 'separator') {\n const sep = document.createElement('li');\n sep.className = 'ng-menu-separator';\n parentUl.appendChild(sep);\n return;\n }\n\n const li = document.createElement('li');\n li.setAttribute('menu-id', item.menuId);\n li.className = `${item.className || ''} ${item.items ? 'submenu' : ''} ${item.disabled ? 'disabled' : ''}`.trim();\n\n const span = document.createElement('span');\n span.textContent = item.name;\n li.appendChild(span);\n\n if (item.items && item.items.length > 0) {\n const subUl = document.createElement('ul');\n subUl.className = 'ng-menu-sublist';\n this.#appendItems(subUl, item.items);\n li.appendChild(subUl);\n }\n\n parentUl.appendChild(li);\n });\n }\n\n #bindClickEvents() {\n this.querySelectorAll('li[menu-id]').forEach(li => {\n li.addEventListener('click', (e) => {\n e.stopPropagation();\n if (li.classList.contains('disabled')) return;\n\n const menuId = li.getAttribute('menu-id');\n this.#onCallback?.({ menuId, target: li });\n this.close();\n });\n });\n }\n\n disconnectedCallback() {\n this.close();\n }\n}\n\nif (!customElements.get('nine-table-menu-panel')) {\n customElements.define('nine-table-menu-panel', MenuPanel);\n}"],"mappings":";;AAAA,MAAM,UAAU,mBAAmB,SAAS,GAAQ;CAGhD,IAAII,IAAQ,GACRC,IAAM,KAAK,SAAS,GACpBC;CAEJ,OAAOF,KAASC,IAAK;EAGjB,IAFA,IAAM,UAAUD,IAAQC,KAAO,CAAC,GAE5BE,MAAW,KAAKD,IAChB,OAAOA;EAEP,AAAIC,IAAS,KAAKD,KACd,IAAMA,IAAM,IAEZ,IAAQA,IAAM;CAG1B;CAEA,OAAO;AACX;AAEA,IAAME,oBAAuB,IAAI,QAAQ;AAEzC,YAAY,UAAU,2BAA2B,SAC7C,GACA,GACA,GACA,GACA,IAAe,KACjB;CACE,IAAMC,IAAK;CAEX,AAAKD,EAAqB,IAAIC,CAAE,KAC5BD,EAAqB,IAAIC,GAAI;EAAE,OAAO;EAAM,UAAU;CAAK,CAAC;CAEhE,IAAMC,IAAQF,EAAqB,IAAIC,CAAE;CAiBzC,AAfAA,EAAG,iBAAiBE,IAAe,MAAM;EASrC,AARA,EAAE,eAAe,EAAE,QAEnB,AAEID,EAAM,WADN,aAAaA,EAAM,KAAK,GACV,OAIlB,EAAM,QAAQ,iBAAiB;GAE3B,AADA,EAAM,QAAQ,MACd,EAAM,WAAWE,EAAU,KAAKH,GAAI,CAAC;EACzC,GAAGI,CAAY;CACnB,CAAC,GAEDJ,EAAG,iBAAiBK,IAAgB,MAAM;EAWtC,AAVA,AAEIJ,EAAM,WADN,aAAaA,EAAM,KAAK,GACV,OAGlB,AAEIA,EAAM,cADNA,EAAM,SAAS,GACE,OAGrBK,EAAW,KAAKN,GAAI,CAAC;CACzB,CAAC;AACL,GAGA,KAAK,mBAAmB,GAAO,IAAQ,sBAAsB;CAEzD,IADI,OAAOO,KAAU,aAAU,KAAgB,KAC3C,CAACA,GAAO,OAAO;EAAE,OAAO;EAAM,QAAQ;CAAK;CAE/C,IAAMC,KAAa,MAAS;EACxB,IAAMC,IAAM,SAAS,cAAc,KAAK;EAExC,OADA,EAAI,YAAYC,GACTD,EAAI,eAAeA,EAAI,aAAa;CAC/C;CAEA,IAAQF,EAAM,WAAW,MAAM,MAAM;CAErC,IAAII,IAAS,SAAS,KAAK,cAAc,8BAA8B;CACvE,AAAKA,MACD,IAAS,SAAS,cAAc,QAAQ,GACxC,EAAO,KAAK,yBACZ,EAAO,MAAM,UAAU,gFACvB,SAAS,KAAK,YAAYA,CAAM;CAGpC,IAAMC,IAAUD,EAAO,WAAW,IAAI;CACtC,EAAQ,OAAOE;CAEf,IAAIC,IAAI,GACJC,IAAI;CAER,KAAK,IAAIC,KAAKT,EAAM,MAAM,MAAM,GAAG;EAC/B,IAAMU,IAAYT,EAAUQ,CAAC,GACvBE,IAAUN,EAAQ,YAAYK,CAAS;EAE7C,IAAI,KAAK,IAAIH,GAAGI,EAAQ,KAAK;EAE7B,IAAMC,IAASD,EAAQ,yBAAyB,IAC1CE,IAAUF,EAAQ,0BAA0B;EAClD,KAAKC,IAASC;CAClB;CAEA,OAAO;EACH,OAAON;EACP,QAAQC;CACZ;AACJ;ACvGA,IAAavB,IAAQ,IAAI,cAPED,EAAY,YAAY;CAC/C,cAAc;EAEV,AADA,MAAM,GACN,KAAK,KAAK,cAAc,OAAO;CACnC;AACJ,EAE+B,GCTlBgC,IAAa;CACtB,MAAM,EACF,OAAO;EACH,OAAO;EACP,QAAQ;EACR,OAAO;CAGX,EACJ;CACA,WAAW;EACP,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;CACZ;CACA,OAAO;EACH,MAAM;EACN,mBAAoB;CACxB;AACJ,GClBaC,IAAb,MAAmB;CAClB;CACA,KAAU;CAEV,YAAY,GAAQ;EACnB,KAAKC,KAAUC;CAChB;CAEA,IAAI,KAAK;EACR,OAAO,KAAKC;CACb;CACA,IAAI,GAAG,GAAG;EACT,KAAKA,KAAU,SAASX,GAAG,EAAE;CAC9B;CAEA,cAAc,KAAKS,GAAQ,WAAW;AACvC,GAEaG,IAAb,MAAaA,EAAO;CACnB;CACA;CACA,KAAU;CACV,KAAiB,CAAC;CAElB,OAAO,aAAa,EACnB,QAAQ,EAIT;CAEA,OAAO,YAAY;EAClB,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;CACT;CAEA,YAAY,GAAM,GAAQ;EAGzB,AAFA,KAAKC,KAAQC,GACb,KAAKL,KAAUC,GACf,KAAKK,GAAY;CAClB;CAGA,YACoB,KAAKN,GAAQ,cAAc,CAAC,EAAA,CAC7B,QAAO,MAAK,CAACO,EAAE,MAAM,OAAO;CAG/C,IAAI,QAAQ;EACX,OAAO,KAAK;CACb;CAEA,cACQ,KAAK;CAGb,YAAY,GAAI,MAAU;EACzB,IAAMC,IAAe,KAAKC,GAAiB;EAE3C,IAAIC,KAA2B,MAC9B,OAAOF;EAGR,IAAIE,IAAK,KAAKA,KAAMF,EAAa,QAAQ,OAAO;EAEhD,IAAMG,IAAeH,EAAaE;EAElC,IAAIE,KAAS,MAAM;GAElB,IAAMC,IADS,KAAK,cACH,CAAC,CAAC,QAAQD,CAAK;GAChC,OAAQC,KAAO,IAAKF,EAAa,EAAEE,KAAO;EAC3C;EAEA,OAAOF;CACR;CAEA,YAAY,GAAU,GAAU,MAAU;EAEzC,IAAMG,IADe,KAAKL,GACC,CAAC,CAACM;EAO7B,AALiBD,EAAQ,EAAEE,OACVC,KAASH,EAAQ,KAAK,aAAaX,EAAO,UAAU,WACpE,EAAQ,KAAK,WAAWA,EAAO,UAAU,SAG1C,EAAQ,EAAEa,KAAYC;CACvB;CAGA,OAAO,GAAI,MAAU;EACpB,IAAMT,IAAe,KAAKC,GAAiB;EAE3C,IAAIC,KAA2B,MAC9B,OAAO,KAAKQ,GAAMV,CAAY;EAG/B,IAAIE,IAAK,KAAKA,KAAMF,EAAa,QAAQ,OAAO;EAEhD,IAAMG,IAAeH,EAAaE,IAC5BS,IAAS,KAAK,cAAc;EAElC,IAAIP,KAAS,MAAM;GAClB,IAAMC,IAAMM,EAAO,QAAQP,CAAK;GAChC,OAAQC,KAAO,IAAKF,EAAa,EAAEE,KAAO;EAC3C;EAEA,OAAO,KAAKK,GAAMP,CAAY;CAC/B;CAEA,eACQ,KAAKX,GAAQ,cAAc,CAAC;CAGpC,sBACQ,OAAO,KAAKI,GAAM,QAAQ,OAAQ,aAAa,KAAKA,GAAM,OAAO,IAAI,IAAI,CAAC;CAGlF,WAAoB;EACnB,KAAKgB,KAAiB,CAAC;EACvB,IAAMC,IAAmB,KAAKjB,GAAM,YAAY,CAAC;EAKjD,AAJA,MAAM,KAAKiB,CAAgB,CAAC,CAAC,SAAQ,MAAM;GAC1C,KAAKD,GAAe,KAAK7C,EAAG,wBAAwB,CAAC,CAAC,UAAU,EAAE;EACnE,CAAC,IAEA,KAAKyB,GAAQ,cAAc,CAAC,EAAA,CAAG,SAAQ,MAAK;GAE5C,AADA,AAAaT,EAAE,SAAO,KAAK+B,GAAgB,GAC3C,EAAE,KAAK,SAAS,KAAKF,GAAe,MAAM;EAC3C,CAAC;CACF;CAEA,IAAI,SAAS;EACZ,OAAO,KAAKF,GAAM,KAAKlB,GAAQ,UAAU;CAC1C;CACA,IAAI,OAAO,GAAG;EACb,KAAK,IAAIT,CAAC;CACX;CAEA,WAAoB;EAKnB,AAJA,KAAKa,GAAM,WAAW,iBAAiB,kBAAkB,CAAC,CAAC,SAAQ,MAAO;GACzE,EAAI,WAAW;EAChB,CAAC,GAED,KAAKA,GAAM,WAAW,cAAc,0BAA0B,CAAC,EAAE,QAAQ;CAC1E;CAEA,OAAO,MAAe;EAErB,IAAMmB,UAAiB;GAEtB,AADA,KAAKnB,GAAM,UAAU,IACrB,iBAAiB;IAChB,IAAI;KAGH,AAFA,KAAK,MAAM,GACX,KAAK,IAAIoB,GAAY,EAAK,GAC1B,KAAKC,GAAY;IAClB,UAAU;KACT,KAAKrB,GAAM,UAAU;IACtB;GACD,CAAC;EACF;EAEA,AAAI,KAAKA,GAAM,SACdmB,EAAS,IAGT,KAAKnB,GAAM,iBAAiBN,EAAW,MAAM,OAAM,MAAK;GACvD,EAAS;EACV,GAAG,EAAE,MAAM,GAAK,CAAC;CAEnB;CAEA,IAAI,SAAS;EACZ,OAAO,KAAK4B;CACb;CAEA,IAAI,SAAS;EACZ,OAAO,KAAKjB,GAAiB,CAAC,CAAC;CAChC;CAEA,IAAI,QAAQ;EACX,OAAO,KAAK;CACb;CAEA,cAAc;EACb,OAAO,KAAK;CACb;CAEA,MAAmB,IAAQ,OACnB;EACN,UAAUN,EAAO,UAAU;EAC3B,SAAS;EACT,UAAU;EACV,QAAQ,KAAKiB,GAAe,MAAM;EAClC,GAAG,CAAC;EACJ,GAAG,CAAC;EACJ,IAAI;GAAC;GAAG;GAAG;GAAG;GAAGjB,EAAO,UAAU;GAAO;GAAO;GAAO;GAAM;GAAO;GAAM;GAAM;GAAO,KAAKiB,GAAe,MAAM;GAAG;GAAI,CAAC;GAAG,CAAC;EAAC;EAC9H,GAAG,CAACO,GAAO,CAAC,CAAG;CAChB;CAGD,cAAc;EAEb,AADA,KAAK3B,GAAQ,aAAa,CAAC,GAC3B,KAAKyB,GAAY;CAClB;CAEA,cAAc;EAQb,AAPA,KAAKzB,GAAQ,aAAa,CAAC,GACvB,KAAKA,GAAQ,aAAa,SAC7B,KAAKA,GAAQ,YAAY,MAAM,GAGhC,KAAK0B,KAAU,GAEf,KAAKD,GAAY;CAClB;CAEA,MAAe,MAAc;EAC5B,AAAK,MAAM,QAAQG,CAAS,MAAG,IAAY,CAACA,CAAS;EAErD,IAAMT,IAAS,KAAK,cAAc,CAAC,CAAC,SAAS,IAAI,KAAK,cAAc,IAAI,OAAO,KAAKS,EAAU,MAAM,CAAC,CAAC,GAChGC,IAAM,CAAC;EAUb,OARAD,EAAU,SAAQ,MAAQ;GACzB,IAAMrB,IAAI,EAAE,GAAG,CAAC,EAAE;GAIlB,AAHAY,EAAO,SAAQ,MAAS;IACvB,EAAE,EAAE,KAAKW,EAAKlB,OAAW,KAAA,KAAakB,EAAKlB,OAAW,OAAOkB,EAAKlB,KAAS,EAAE;GAC9E,CAAC,GACDiB,EAAI,KAAKtB,CAAC;EACX,CAAC,GAEMsB;CACR;CAEA,MAAkB,OACZ,MAAM,QAAQA,CAAG,MAAG,IAAM,CAACA,CAAG,IACnCA,EAAI,SAAQ,MAAK;EAChB,IAAMF,IAAQ,KAAK;EAMnB,AAJA,EAAE,IAAI,KAAKL,GAAgBK,CAAK,GAChC,EAAE,OAAOpB,EAAE,GACX,EAAE,KAAK,QAAQoB,GACf,EAAE,KAAK,WAAWxB,EAAO,UAAU,QACnC,EAAE,KAAK,EAAE,KAAKwB;CACf,CAAC,GACME;CAGR,OAAO,GAAY,IAAc,OAAS;EACzC,AAAIL,MAAe,KAAA,MAAW,IAAa,CAAC;EAC5C,IAAMK,IAAM,KAAKE,GAAYP,CAAU;EAEvC,KAAKxB,GAAQ,aAAa,KAAKA,GAAQ,WAAW,OAAO,KAAKgC,GAAeH,CAAG,CAAC;EAEjF,IAAMI,IAAM,KAAK,MAAM,IAAI;EAS3B,OARKC,KACJL,EAAI,SAAS,GAAG,MAAQ;GACvB,IAAMxD,IAAS,KAAK2B,GAAQ,WAAW,KAAKA,GAAQ,WAAW,SAAS,IAAIa;GAC5E,AAAIxC,MAAQ,EAAO,KAAK,WAAW8B,EAAO,UAAU;EACrD,CAAC,GAGF,KAAKsB,GAAY,GACVQ;CACR;CAEA,UAAU,MAAO;EAChB,IAAIJ,IAAM,CAAC;EACX,AAKCA,IALG,MAAM,QAAQnB,CAAE,IACbA,IACWA,MAAO,SAClB,CAAC,KAAKV,GAAQ,KAAK,IAAI,EAAE,IAEzB,CAAC,SAASU,GAAI,EAAE,CAAC;EAGxB,IAAMF,IAAe,KAAKC,GAAiB;EAkB3C,AAhBAoB,EAAI,MAAM,GAAG,MAAMM,IAAIC,CAAC,CAAC,CAAC,SAAQ,MAAU;GAC3C,IAAI5B,EAAa6B,IAAS;IACzB,IAAMC,IAAW9B,EAAa6B,EAAO,CAAC,KAAK;IAC3C,AAAI7B,EAAa6B,EAAO,CAAC,KAAK,aAAalC,EAAO,UAAU,SAC3D,KAAKH,GAAQ,aAAa,KAAKA,GAAQ,WAAW,QAAO,MAAQuC,EAAK,KAAK,UAAUD,CAAQ,IAE7F,KAAKtC,GAAQ,WAAW,SAAQ,MAAQ;KACvC,AAAIuC,EAAK,KAAK,UAAUD,MACvB,EAAK,KAAK,UAAU,IACpB,EAAK,KAAK,WAAWnC,EAAO,UAAU;IAExC,CAAC;GAEH;EACD,CAAC,GAED,KAAKsB,GAAY;CAClB;CAEA,YAAY,GAAU,GAAO,MAAU;EAEtC,IAAW,SAASV,GAAU,EAAE;EAEhC,IAAMyB,IADS,KAAK,cACC,CAAC,CAAC,QAAQ5B,CAAK;EACpC,IAAI4B,IAAU,GAAG;EAGjB,IAAM1B,IADe,KAAKL,GACC,CAAC,CAACM;EAC7B,IAAI,CAACD,GAAS;EAId,IAAM2B,IAAW3B,EAAQ,EAAE0B;EAM3B,AALIC,MAAaxB,KAASH,EAAQ,KAAK,aAAaX,EAAO,UAAU,WAC/DW,EAAQ,KAAK,EAAE,eAAeF,CAAK,MAAG,EAAQ,KAAK,EAAEA,KAAS6B,IACnE,EAAQ,KAAK,WAAWtC,EAAO,UAAU,SAG1C,EAAQ,EAAEqC,KAAWvB;CACtB;CAEA,MAAS,MAAQ;EAChB,IAAI,CAACY,GAAK,OAAOA;EAEjB,IAAMa,IAAW,CAAC,MAAM,QAAQb,CAAG,GAC7Bc,IAAYD,IAAW,CAACb,CAAG,IAAIA,GAC/BV,IAAS,KAAK,cAAc,GAE5ByB,IAASD,EAAU,QAAO,MAAK,CAACpC,EAAE,MAAM,OAAO,CAAC,CAAC,KAAI,MAAK;GAC/D,IAAM,IAAI,CAAC;GAKX,OAJAY,EAAO,SAAS,GAAO,MAAM;IAC5B,EAAEP,KAASL,EAAE,IAAIA,EAAE,EAAEsC,KAAKtC,EAAEK;GAC7B,CAAC,GACD,EAAE,OAAOL,EAAE,MACJ;EACR,CAAC;EAED,OAAOmC,IAAWE,EAAO,KAAKA;CAC/B;AACD,GCnVaE,IAAb,MAA2B;CAC1B;CAEA,YAAY,GAAM;EAoDjB,AAnDA,KAAK1C,KAAQC,GAEb,KAAK,MAAM,IAAIN,EAAM,IAAI,GACzB,KAAK,OAAO,IAAII,EAAO,KAAKC,IAAO,IAAI,GAEvC,KAAK,aAAa,CAAC,GACnB,KAAK,cAAc,CAAC,GACpB,KAAK,aAAa,CAAC,GACnB,KAAK,UAAU,IAEf,KAAK,YAAY,cAAc;GAC9B,AAAI,KAAKA,GAAM,MAAM,UAAQ,KAAKA,GAAM,KAAK,OAAO;EACrD,GAEA,KAAK,iBAAiB,MAAO;GAO5B,AANI,KAAK,QAAM,KAAK,KAAK,MAAM,GAE/B,KAAK,aAAa,CAAC,GACnB,KAAK,cAAc,CAAC,GACpB,KAAK,aAAa,CAAC,GAEnB,KAAK,KAAK,IAAI2C,KAAM,CAAC,CAAC;EACvB,GAEA,KAAK,eAAe,MAAS;GAC5B,IAAMC,IAAS,SAASC,GAAM,EAAE;GAChC,IAAI,OAAU,KAAK,KAAK,MAAM,IAC9B,OAAO,KAAK,KAAK,aAAa,CAAC,CAACD,EAAO,EAAE,MAAM;EAChD,GAEA,KAAK,uBAAuB,KAAK,IAAI,IACrC,KAAK,kBAAkB,MAAS;GAAE,KAAK,IAAI,KAAKC;EAAM,GAEtD,KAAK,eAAe,OACfA,IAAO,MAAG,IAAO,IACjBA,KAAQ,KAAK,WAAW,WAAQ,IAAO,KAAK,WAAW,SAAS,IAEpE,KAAK,YAAY,WAAWA,GACxB,KAAK,YAAY,SAAO,KAAK,YAAY,MAAM,GAE3C,OAAQ,KAAKA,KAAQ,KAAK,WAAW,SAAS,KAGvD,KAAK,aAAa,GAAQ,MAAU,KAAK,KAAK,IAAIZ,GAAQzB,CAAK,GAE/D,KAAK,aAAa,GAAQ,GAAO,MAAM;GAEtC,AADA,IAAS,SAASyB,GAAQ,EAAE,GAC5B,KAAK,KAAK,SAASA,GAAQzB,GAAOrB,CAAC;EACpC,GAGA,KAAK,cAAc,CAAC,CAAC;CACtB;AACD,GCzDa4B,IAAb,MAAoB;CACnB;CACA,KAAU,CAAC;CAEX,YAAY,GAAM;EAEjB,AADA,KAAKf,KAAQC,GACb,KAAK6C,GAAM;CACZ;CAEA,MAAM;EACL,OAAO,KAAKC,GAAQ,KAAI,MAAKC,EAAE,IAAI;CACpC;CAEA,YAAY;EACX,OAAO,KAAKD;CACb;CAEA,QAAQ,GAAW;EAClB,IAAME,IAAQ,KAAKF,GAAQ,MAAK,MAAKC,EAAE,SAASE,CAAS;EACzD,OAAOD,IAAQA,EAAM,OAAO;CAC7B;CAEA,OAAO,GAAK,IAAO,aAAa;EAM/B,AALAxB,EAAI,SAAQ,MAAS;GACpB,AAAK,KAAKsB,GAAQ,MAAK,MAAKC,EAAE,SAASG,CAAK,KAC3C,KAAKJ,GAAQ,KAAK;IAAE,MAAMI;IAAa;GAAK,CAAC;EAE/C,CAAC,GACD,KAAKC,GAAQ;CACd;CAEA,QAAQ,GAAG;EACV,OAAO,KAAKL,GAAQ,WAAU,MAAKC,EAAE,SAAS7D,CAAC;CAChD;CAEA,SAAS,GAAG;EACX,OAAO,KAAK4D,GAAQ,MAAK,MAAKC,EAAE,SAAS7D,CAAC;CAC3C;CAEA,WAAgB;EACf,IAAMkE,oBAAM,IAAI,IAAI;EASpB,AARA,KAAKN,GAAQ,SAAQ,MAAK;GACzB,EAAI,IAAIC,EAAE,MAAMA,EAAE,IAAI;EACvB,CAAC,GAED,KAAKD,KAAU,MAAM,KAAKM,IAAM,CAACC,GAAMC,QAAW;GAAE;GAAM;EAAK,EAAE,GAEjE,KAAKR,KAAU,KAAKA,GAAQ,QAAO,MAAKC,EAAE,SAAS,MAAMA,EAAE,SAAS,MAAM,GAE1E,KAAKD,GAAQ,MAAM,GAAG,MAAgBf,EAAE,KAAK,SAASD,EAAE,KAAK,SAAU,IAAI,EAAK;CACjF;CAEA,WAAc;EACb,KAAKgB,KAAU,CAAC;EAEhB,IAAMS,IAAY,MAAM,KAAK,KAAKxD,GAAM,iBAAiB,OAAO,CAAC;EAEjE,IAAKwD,KAAaA,EAAU,WAAW,GAEvC;QAAK,IAAMC,KAAOD,GAiBjB,AAfAC,EAAI,iBAAiB,aAAa,CAAC,CAAC,SAAS,MAAO;IACnD,IAAMP,IAAY/E,EAAG,QAAQ,MACvBuF,IAAYvF,EAAG,aAAa,WAAW,KAAK;IAElD,AAAI+E,KACH,KAAKH,GAAQ,KAAK;KAAE,MAAMG;KAAW,MAAMQ;IAAU,CAAC;GAExD,CAAC,GAQD;IALC;IAAa;IAAoB;IAAS;IAC1C;IAAW;IAAY;IAAiB;IACxC;IAAc;IAAc;GAGrB,CAAC,CAAC,SAAQ,MAAQ;IACzB,EAAI,iBAAiB,IAAIC,EAAK,EAAE,CAAC,CAAC,SAAS,MAAO;KACjD,IAAIC,IAAOzF,EAAG,aAAawF,CAAI;KAC/B,IAAKC,GAEL;UAAIA,EAAK,QAAQ,OAAO,IAAI,GAAG;OAC9B,IAAMC,IAAYD,EAAK,OAAO,MAAM;OAEpC,IAAIC,IAAY,GACf,IAAI;QACH,IAAO,OAAO,OAAOD,EAAK,UAAU,GAAGC,CAAS,CAAC,CAAC,KAAK,EAAE;OAC1D,QAAY;QACX,IAAO;OACR;MAEF;MAEA,EAAK,MAAM,OAAO,CAAC,CAAC,SAAQ,MAAK;OAChC,IAAI1E,EAAE,KAAK,KAAK,IAAI;QACnB,IAAM0E,IAAY1E,EAAE,OAAO,gBAAgB,GACvC2E,IAAc;QAQlB,AANID,KAAa,IAChB,IAAc1E,EAAE,UAAU,GAAG0E,CAAS,IAC5BD,EAAK,WAAW,OAAO,MACjC,IAAczE,EAAE,QAAQ,SAAS,EAAE,IAGhC2E,KACH,KAAKf,GAAQ,KAAK;SAAE,MAAMe;SAAa,MAAM;QAAS,CAAC;OAEzD;MACD,CAAC;KAjBD;IAkBD,CAAC;GACF,CAAC;GAGF,KAAKV,GAAQ;EAFb;CAGD;AACD,GCrHaW,IAAb,cAAqC,YAAY;CAC7C,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAChB,KAAKjB,GAAM;CACf;CAEA,WAAc,CAEd;AAEJ;AAEK,eAAe,IAAI,mBAAmB,KACvC,eAAe,OAAO,qBAAqBiB,CAAe;;AChB9D,IAAaC,IAAb,cAA2C,YAAY;CACnD;CAEA,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAChB,KAAKlB,GAAM;CACf;CAEA,gBAAgB;EACZ,KAAK,cAAc,YAAY,CAAC,CAAC,YAAY,KAAK9C,GAAM,KAAK,MAAM,CAAC,CAAC,eAAe;CACxF;CAEA,WAAc;EAeV,AAdA,KAAKA,KAAQ,KAAK,YAAY,CAAC,CAAC,MAEhC,KAAKiE,GAAQ,GAEb,KAAK,cAAc,eAAe,CAAC,EAAE,iBAAiB,UAAU,MAAM;GAClE,IAAMC,IAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,UAC5CC,IAAU,EAAE,OAAO,QAAQ,oBAAoB;GAErD,IAAI,CAACA,GAAS;GAEd,IAAMC,IAAQ,SAASD,EAAQ,QAAQ,OAAO,EAAE;GAChD,KAAKE,GAAaD,GAAOF,CAAa;EAC1C,CAAC,GAED,iBAAiB;GACb,KAAKG,GAAa,GAAG,EAAK;EAC9B,CAAC;CACL;CAEA,MAAgB,GAAO,IAAgB,OAAU;EAE7C,IAAMC,UAAwB;GAC1B,IAAMC,IAAS,MAAM,KAAK,KAAKvE,GAAM,WAAW,iBAAiB,kBAAkB,CAAC;GAGpF,MAFwB,KAAK,KAAKA,GAAM,WAAW,iBAAiB,eAAe,CAE3E,CAAC,CAAC,SAAQ,MAAKwE,EAAE,MAAM,YAAY,WAAW,MAAM,CAAC;GAE7D,IAAMC,IAAeF,EAChB,KAAK,GAAO,OAAS;IAAE;IAAO;GAAI,EAAE,CAAC,CACrC,QAAQ,EAAE,eAAYG,EAAM,UAAU,SAAS,QAAQ,CAAC;GAE7D,IAAI,IAAa,SAAS,IAE1B,KAAK,IAAIjC,IAAI,GAAGA,IAAIgC,EAAa,SAAS,GAAG,KAAK;IAC9C,IAAME,IAAaF,EAAahC,EAAE,CAAC,KAE7BmC,IAAiB,KAAK5E,GAAM,WAAW,cAAc,mCAAmC2E,EAAW,GAAG;IAC5G,AAAIC,KACAA,EAAe,MAAM,YAAY,WAAW,EAAE;GAEtD;EACJ,GAEMC,IAAS,KAAK,cAAc,eAAe,GAC3CC,IAAO,KAAK9E,GAAM,WAAW,cAAc,wBAAwB,GACnE+E,IAAWF,EAAO,iBAAiB,oBAAoB,GACvDG,IAAgBF,EAAK,iBAAiB,kBAAkB;EAE9D,IAAI,CAACC,EAASX,IAAQ;EAEtB,IAAI,CAACF,GAKD,AAJAa,EAAS,SAAS,GAAK,MAAQ;GAC3B,EAAI,UAAUtE,MAAQ2D,CAAK;EAC/B,CAAC,GAEDY,EAAc,SAAS,GAAO,MAAQ;GAClC,IAAMC,IAAWxE,MAAQ2D;GAEzB,AADAM,EAAM,UAAU,OAAO,UAAUO,CAAQ,GACzC,EAAM,MAAM,OAAOA,IAAW,aAAa;EAC/C,CAAC;OACE;GACH,IAAMC,IAAaH,EAASX,IACtBe,IAAaN,EAAO,iBAAiB,2BAA2B;GAEtE,IAAIK,EAAW,UAAU,SAAS,QAAQ,KAAKC,EAAW,UAAU,GAChE;GAGJ,EAAW,UAAU,OAAO,QAAQ;GACpC,IAAMC,IAAcN,EAAK,cAAc,gCAAgCV,EAAM,GAAG;GAChF,AAAIgB,MACAA,EAAY,UAAU,OAAO,QAAQ,GAChCA,EAAY,UAAU,SAAS,QAAQ,MACxC,EAAY,MAAM,OAAO;EAGrC;EAEA,IAAMX,IAAeK,EAAK,iBAAiB,yBAAyB;EAYpE,AAVAL,GAAc,SAAQ,MAAS;GAG3B,AAFA,EAAM,MAAM,OAAQA,EAAa,SAAS,IAAK,WAAW,YAEtD,OAAOC,EAAM,iBAAkB,aAC/BA,EAAM,cAAc,IAEpBA,EAAM,aAAa;EAE3B,CAAC,GAEDJ,EAAgB;CACpB;CAEA,KAAU;EAIN,IAAMe,IAHc,MAAM,KAAK,KAAKrF,GAAM,QACd,CAAC,CAAC,QAAO,MAAO7B,EAAG,QAAQ,YAAY,MAAM,OAEhD,CAAC,CAAC,KAAK,GAAO,MAI5B,8BAHWsC,MAAQ,IAAI,WAAW,GAGM,gBAAgBA,EAAI,IAFnD6E,EAAM,aAAa,SAAS,KAAK,SAAS7E,IAAM,IAEe,sBAClF,CAAC,CAAC,KAAK,EAAE;EAEV,KAAK,YAAY;wCACe4E,EAAS;;;CAG7C;AACJ,GAEaE,IAAb,cAAkC,YAAY;CAC1C,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB,CAEpB;CAEA,UAAU,GAAU;EAChB,KAAK,UAAU,OAAO,UAAUN,CAAQ;CAC5C;AACJ;AAEK,eAAe,IAAI,oBAAoB,KACxC,eAAe,OAAO,sBAAsBM,CAAY,GAGvD,eAAe,IAAI,0BAA0B,KAC9C,eAAe,OAAO,4BAA4BvB,CAAqB;;AChJ3E,IAAawB,IAAb,cAA6B,YAAY;CACrC;CACA;CAEA,oBAAoB;EAGhB,AAFA,KAAKxF,KAAQ,KAAK,YAAY,CAAC,CAAC,MAChC,KAAKiE,GAAQ,GACb,KAAKwB,GAAY;CACrB;CAEA,KAAU;EAiBN,AAhBA,KAAK,YAAY,8sBAejB,KAAKC,KAAmB,KAAK,cAAc,mBAAmB,GAC9D,KAAKC,GAAmB;CAC5B;CAEA,KAAqB;EACjB,IAAMC,IAAW,KAAK5F,GAAM,aAAa,OAAO,MAAM,YAAY,KAAKA,GAAM,UAAU,SAAS,QAAQ,GAClG6F,IAAc,KAAK7F,GAAM,aAAa,cAAc,MAAM,SAC1D8F,IAAW,KAAK9F,GAAM,aAAa,WAAW,MAAM,SACpD+F,IAAU,KAAK/F,GAAM,aAAa,SAAS,KAAK;EAStD,AAPI4F,KAAY,CAACC,IACb,KAAK,aAAa,UAAU,EAAE,IAE9B,KAAK,gBAAgB,QAAQ,GAGjC,KAAK,aAAa,aAAaC,IAAW,SAAS,OAAO,GAC1D,KAAK,cAAcC,CAAO;CAC9B;CAEA,KAAc;EACV,IAAMC,IAAU,KAAK,cAAc,mBAAmB;EACtD,AAAIA,KACAA,EAAQ,iBAAiB,kBAAkB;GACvC,IAAMC,IAAO,yDACPC,IAAiB,KAAKlG,GAAM,aAAa,SAAS,KAAK;GAC7D,EAAQ,YAAYgG,EAAQ,cAAcC,IAAOC,IAAiBD;EACtE,CAAC;EAGL,IAAME,IAAU,KAAK,cAAc,sBAAsB;EACzD,AAAIA,KACAA,EAAQ,iBAAiB,eAAe;GACpC,KAAKnG,GAAM,cAAc,IAAI,YAAY,sBAAsB;IAC3D,SAAS;IACT,UAAU;IACV,QAAQ,EAAE,aAAa,KAAKA,GAAM;GACtC,CAAC,CAAC;EACN,CAAC;CAET;CAEA,iBAAiB,GAAS;EACtB,AAAI,KAAK0F,MACL,KAAKA,GAAiB,OAAOU,CAAO;CAE5C;CAEA,cAAc,GAAM;EAChB,IAAMJ,IAAU,KAAK,cAAc,mBAAmB;EACtD,AAAIA,MAAS,EAAQ,cAAcK;CACvC;AACJ;AAEK,eAAe,IAAI,oBAAoB,KACxC,eAAe,OAAO,sBAAsBb,CAAO;;AChFvD,IAAac,IAAb,cAAyC,YAAY;CACjD;CACA,KAAY;CACZ;CACA;CACA;CACA;CAEA,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAEhB,IADA,KAAKC,KAAS,KAAK,QAAQ,kBAAkB,KAAK,KAAK,YAAY,CAAC,CAAC,MACjE,CAAC,KAAKA,IAAQ;EAElB,KAAK,YAAY;EAMjB,IAAMC,UAAsB;GACxB,IAAM1B,IAAO,KAAKyB,GAAO,cAAc,mCAAmC;GAC1E,AAAKzB,KAKL,KAAK2B,KAAY;IACb,WAAY3B;IACZ,OAAY,KAAK,cAAc,eAAe;IAC9C,OAAY,KAAK,cAAc,eAAe;IAC9C,MAAY,KAAK,cAAc,cAAc;IAC7C,OAAY,KAAK,cAAc,eAAe;GAClD,GAEA,KAAKhC,GAAM,GACX,KAAK4D,GAAe,GACpB,KAAK,QAAQ,KAdT,WAAWF,GAAe,EAAE;EAepC;EAEA,EAAc;CAClB;CAEA,uBAAuB;EACnB,AAAI,KAAKG,MACL,KAAKA,GAAgB,WAAW;CAExC;CAEA,WAAuB;EACnB,IAAI,CAAC,KAAKJ,IAAQ;EAClB,IAAMzB,IAAO,KAAKyB,GAAO,cAAc,mCAAmC;EAC1E,AAAKzB,MAEL,KAAK6B,KAAkB,IAAI,qBAAqB;GAC5C,KAAK,QAAQ;EACjB,CAAC,GACD,KAAKA,GAAgB,QAAQ7B,CAAI;CACrC;CAEA,gBAAgB;EAEZ,IAAI,CAAC,KAAKyB,MAAU,CAAC,KAAKE,MAAa,KAAKG,IAAW;EAEvD,IAAM9B,IAAO,KAAK2B,GAAU,WACtBnB,IAAQR,EAAK,cAAc,OAAO;EACxC,IAAI,CAACQ,GAAO;EAEZ,IAAMuB,IAAQ,KAAKJ,GAAU,OACvBK,IAAQ,KAAKL,GAAU,OAEvBM,IAAYjC,EAAK,aACjBkC,IAAa1B,EAAM,aAEnB2B,IAAgBF,MAAc,KAAKC,IAAaD;EAGtD,IAFA,KAAKR,GAAO,UAAU,OAAO,mBAAmBU,CAAY,GAExD,CAACA,GACD;EAGJ,IAAMC,IAAaL,EAAM;EACzB,IAAIK,KAAc,GAAG;EAErB,IAAMC,IAAa,KAAK,IAAI,KAAK,IAAkBJ,IAAYC,IAA1BE,GAAuCA,CAAU,GAAG,EAAE;EAC3F,EAAM,MAAM,QAAQ,GAAGC,EAAW;EAElC,IAAMC,IAActC,EAAK,YACnBuC,IAAgBL,IAAaD,GAE/BO,IAAI;EAIR,AAHID,IAAgB,MAChB,IAAI,SAAUD,IAAcC,KAAkBH,IAAaC,IAAa,EAAE,IAE1EG,IAAI,MAAG,IAAI;EAEf,IAAMC,IAAeL,IAAaC;EAMlC,AALIG,IAAIC,MAAc,IAAIA,IAE1B,EAAM,MAAM,OAAO,GAAGD,EAAE,KAExB,KAAKb,GAAU,KAAK,WAAYa,MAAM,GACtC,KAAKb,GAAU,MAAM,WAAYa,KAAKC,IAAe;CACzD;CAEA,MAAgB,MAAM;EAClB,IAAI,CAAC,KAAKd,IAAW,OAAO;EAE5B,IAAM3B,IAAO,KAAK2B,GAAU,WACtBnB,IAAQR,EAAK,cAAc,OAAO;EACxC,IAAI,CAACQ,GAAO,OAAO;EAEnB,IAAMkC,IAAa,KAAKf,GAAU,MAAM,sBAAsB,GACxDU,IAAa,KAAKV,GAAU,MAAM,aAEpCgB,IAAUC;EACd,AAAID,IAAU,MAAG,IAAU;EAC3B,IAAMF,IAAeC,EAAW,QAAQL;EAOxC,AANIM,IAAUF,MAAc,IAAUA,IACtC,IAAU,SAASE,GAAS,EAAE,GAE9B,KAAKhB,GAAU,MAAM,MAAM,OAAO,GAAGgB,EAAQ,KAE7C,KAAKhB,GAAU,KAAK,WAAYgB,MAAY,GAC5C,KAAKhB,GAAU,MAAM,WAAYgB,KAAWF,IAAe;EAE3D,IAAMR,IAAYjC,EAAK,aAEjBuC,IADa/B,EAAM,cACUyB;EAOnC,OALIQ,IAAe,KAAKF,IAAgB,MAEpC,EAAK,aADkBI,IAAUF,IAAgBF,IAI7CI,IAAU,KAAKA,IAAUF,IAAe;CACpD;CAEA,WAAc;EACV,IAAMI,KAAe,MAAQ;GAEzB,AADA,cAAc,KAAKC,EAAU,GAC7B,cAAc,KAAKC,EAAU;GAE7B,IAAMC,IAAY,SAAS,KAAKrB,GAAU,MAAM,MAAM,QAAQ,GAAG,EAAE;GAGnE,AAFA,KAAKsB,GAAaD,IAAYE,CAAG,GAEjC,KAAKJ,KAAa,kBAAkB;IAGhC,AAFA,cAAc,KAAKA,EAAU,GAE7B,KAAKC,KAAa,kBAAkB;KAChC,IAAMI,IAAmB,SAAS,KAAKxB,GAAU,MAAM,MAAM,QAAQ,GAAG,EAAE;KAC1E,AAAK,KAAKsB,GAAaE,IAAmBD,CAAG,KACzC,cAAc,KAAKH,EAAU;IAErC,GAAG,EAAE;GACT,GAAG,GAAG;EACV,GAEMK,UAAmB;GAErB,AADA,cAAc,KAAKN,EAAU,GAC7B,cAAc,KAAKC,EAAU;EACjC;EAqBA,AAnBA;GAAC;GAAW;GAAc;EAAU,CAAC,CAAC,SAAQ,MAAO;GAGjD,AAFA,KAAKpB,GAAU,KAAK,iBAAiB0B,GAAKD,CAAU,GACpD,KAAKzB,GAAU,MAAM,iBAAiB0B,GAAKD,CAAU,GACrD,KAAKzB,GAAU,MAAM,iBAAiB0B,GAAKD,CAAU;EACzD,CAAC,GAED,KAAKzB,GAAU,KAAK,iBAAiB,cAAa,MAAK;GAAE,AAAI2B,EAAE,WAAW,KAAWT,EAAY,GAAG;EAAG,CAAC,GACxG,KAAKlB,GAAU,MAAM,iBAAiB,cAAa,MAAK;GAAE,AAAI2B,EAAE,WAAW,KAAWT,EAAY,EAAE;EAAG,CAAC,GACxG,KAAKlB,GAAU,KAAK,iBAAiB,oBAAoBkB,EAAY,GAAG,CAAC,GACzE,KAAKlB,GAAU,MAAM,iBAAiB,oBAAoBkB,EAAY,EAAE,CAAC,GAEzE,KAAKlB,GAAU,MAAM,iBAAiB,cAAa,MAAK;GACpD,IAAI,EAAE,WAAW,GAAG;GACpB,EAAE,eAAe;GACjB,IAAM4B,IAAY,KAAK5B,GAAU,MAAM,sBAAsB,GACvDU,IAAa,KAAKV,GAAU,MAAM;GACxC,KAAKsB,GAAa,EAAE,UAAUM,EAAU,OAAQlB,IAAa,CAAE;EACnE,CAAC,GAED,KAAKV,GAAU,MAAM,iBAAiB,cAAa,MAAK;GACpD,IAAI,EAAE,WAAW,GAAG;GAIpB,AAHA,EAAE,gBAAgB,GAClB,EAAE,eAAe,GACjB,KAAKG,KAAY,IACjB,KAAK,SAAS,EAAE,UAAU,KAAKH,GAAU,MAAM,sBAAsB,CAAC,CAAC;GAEvE,IAAM6B,KAAe,MAAc;IAC/B,IAAI,CAAC,KAAK1B,IAAW;IACrB,IAAMyB,IAAY,KAAK5B,GAAU,MAAM,sBAAsB;IAC7D,KAAKsB,GAAaQ,EAAU,UAAUF,EAAU,OAAO,KAAK,MAAM;GACtE,GAEMG,UAAkB;IAKpB,AAJA,KAAK5B,KAAY,IACjBsB,EAAW,GACX,SAAS,oBAAoB,aAAaI,CAAW,GACrD,SAAS,oBAAoB,WAAWE,CAAS,GACjD,KAAK,QAAQ;GACjB;GAGA,AADA,SAAS,iBAAiB,aAAaF,CAAW,GAClD,SAAS,iBAAiB,WAAWE,CAAS;EAClD,CAAC;CACL;AACJ;AAEK,eAAe,IAAI,uBAAuB,KAC3C,eAAe,OAAO,yBAAyBlC,CAAmB;;ACpNtE,IAAamC,IAAb,cAAyC,YAAY;CACjD;CACA;CACA,KAAY;CACZ;CACA,KAAU;CAEV,KAAiB;CAEjB,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAIhB,AAHA,KAAKzI,KAAQ,KAAK,YAAY,CAAC,CAAC,MAChC,KAAK0I,KAAS,KAAK,QAAQ,kBAAkB,GAE7C,KAAK,YAAY;EAMjB,IAAMlC,UAAsB;GACxB,IAAM1B,IAAO,KAAK4D,GAAO,cAAc,gBAAgB;GACvD,AAAK5D,KAKL,KAAK2B,KAAY;IACb,WAAW3B;IACX,OAAO,KAAK,cAAc,eAAe;IACzC,OAAO,KAAK,cAAc,eAAe;IACzC,KAAK,KAAK,cAAc,aAAa;IACrC,QAAQ,KAAK,cAAc,gBAAgB;GAC/C,GAEA,KAAKhC,GAAM,GACX,KAAK,QAAQ,KAbT,WAAW0D,GAAe,EAAE;EAcpC;EAEA,EAAc;CAClB;CAEA,WAAsB;EAClB,IAAMmC,IAAc,KAAKD,GAAO,KAAK,SAAS,GACxCE,IAAaD,IAAcA,EAAY,SAAS,GAEhDE,IAAe,KAAKH,GAAO,UAAU,cACvCI,IAAmBD,KAAe,WAAWA,EAAa,MAAM,MAAM,KAAK;EAE/E,CAAI,CAACC,KAAoBA,KAAoB,OAEzC,AAIIA,IALc,KAAKJ,GAAO,aAAa,cAAc,2BAA2B,KACnE,KAAKA,GAAO,aACL,KAAK,eAAe,KAAK,eAAgB,KAAK,eAAgBE,IAAa,KAG5EA,KADD,KAAKF,GAAO,aAAa,KAAK;EAKxD,IAAMK,IAAqB,MACrBC,IAAaF,IAAmBC,GAElCE,IAAc,GACdC,IAAgBJ;EAOpB,OALIE,MACA,IAAcD,IAAqBD,GACnC,IAAgBC,IAGb;GAAE;GAAkB;GAAe;GAAa;GAAY;EAAW;CAClF;CAGA,gBAAgB;EAGZ,IAFI,KAAKnC,MAEL,CAAC,KAAK8B,MAAU,CAAC,KAAKA,GAAO,YAAY,CAAC,KAAKjC,IAAW;EAE9D,IAAM3B,IAAO,KAAK2B,GAAU,WACtBI,IAAQ,KAAKJ,GAAU,OACvBK,IAAQ,KAAKL,GAAU,OACvB,EAAE,qBAAkB,KAAK0C,GAAc,GAEvCC,KAAe,KAAKV,GAAO,cAAc,OAAO,CAAC,EAAE,gBAAgB,MACpE,KAAKA,GAAO,cAAc,OAAO,CAAC,EAAE,gBAAgB,MACpD,KAAKA,GAAO,cAAc,YAAY,CAAC,EAAE,gBAAgB,IAExDW,IAAc,KAAKX,GAAO,cAAc,gBAAgB,CAAC,CAAC,gBAAgB,GAC1EY,IAAaD,IAAaD,GAG1BR,IADc,KAAKF,GAAO,KAAK,SACR,CAAC,CAAC,QAEzBI,IAAmB,KAAKJ,GAAO,aAAa,IAAIE,GAEhDW,IAAgBT,IAAmBQ;EAIzC,IAFA,KAAKZ,GAAO,UAAU,OAAO,mBAAmBa,CAAY,GAExD,CAACA,GACD;EAGJ,IAAMC,IAAc3C,EAAM;EAC1B,IAAI2C,KAAe,GAAG;EAEtB,IAAMC,IAAc,KAAK,IAAI,KAAK,IAAmBJ,IAAaP,IAA5BU,GAA+CA,CAAW,GAAG,EAAE;EACrG,EAAM,MAAM,SAAS,GAAGC,EAAY;EAEpC,IAAMC,IAAmB5E,EAAK,WACxB6E,IAAe,KAAK,IAAIT,IAAgB,KAAKR,GAAO,WAAW,aAAa,GAAG,CAAC,GAElFkB,IAAW;EACf,AAAID,IAAe,MACf,IAAYD,IAAmBC,KAAiBH,IAAcC;EAGlE,IAAMI,IAAcL,IAAcC;EAOlC,AANIG,IAAW,MAAG,IAAW,IACzBA,IAAWC,MAAa,IAAWA,IAEvC,EAAM,MAAM,MAAM,GAAGD,EAAS,KAE9B,KAAKnD,GAAU,IAAI,WAAYiD,KAAoB,GACnD,KAAKjD,GAAU,OAAO,WAAYiD,KAAoBC,IAAe;CACzE;CAEA,WAAc;EA6DV,AA3DA,KAAKlD,GAAU,MAAM,iBAAiB,cAAc,MAAM;GACtD,IAAI,EAAE,WAAW,GAAG;GAMpB,AALA,EAAE,gBAAgB,GAClB,EAAE,eAAe,GACjB,KAAKG,KAAY,IAEjB,KAAKkD,KAAU,EAAE,SACjB,KAAKC,KAAiB,WAAW,KAAKtD,GAAU,MAAM,MAAM,GAAG,KAAK;GAIpE,IAAMoD,IAHY,KAAKpD,GAAU,MAAM,sBACX,CAAC,CAAC,SACV,KAAKA,GAAU,MAAM,cAGnC6B,KAAe,MAAc;IAE/B,IADI,CAAC,KAAK1B,MACNiD,KAAe,GAAG;IAGtB,IAAMG,IAASzB,EAAU,UAAU,KAAKuB,IACpCG,IAAiB,KAAKF,KAAiBC;IAK3C,AAHIC,IAAiB,MAAG,IAAiB,IACrCA,IAAiBJ,MAAa,IAAiBA,IAEnD,KAAKpD,GAAU,MAAM,MAAM,MAAM,GAAGwD,EAAe;IAEnD,IAAMC,IAAQD,IAAiBJ,GAEzBM,IAAW,KAAKzB,GAAO,aAAa,GACpCY,KAAc,KAAKZ,GAAO,cAAc,gBAAgB,CAAC,CAAC,gBAAgB,MAC3E,KAAKA,GAAO,SAAS,KAAK,OAAO,gBAAgB,MACjD,KAAKA,GAAO,SAAS,KAAK,OAAO,gBAAgB,MACjD,KAAKA,GAAO,SAAS,KAAK,MAAM,KAAK,gBAAgB,IAEpD0B,IAAkB,KAAK,MAAMd,IAAaa,CAAS,GAEnD,EAAE,kBAAe,KAAKhB,GAAc,GACpCkB,IAAY,KAAK,MAAMH,KAAStB,IAAawB,IAAkB,EAAE;IAEvE,KAAK1B,GAAO,WAAW,gBAAgB2B,CAAS;IAEhD,IAAM,EAAE,qBAAkB,qBAAkB,KAAKlB,GAAc,GACzDO,IAAmB,KAAKjD,GAAU,UAAU,WAC5CkD,IAAe,KAAK,IAAIT,IAAgB,KAAKR,GAAO,WAAW,aAAa,GAAG,CAAC;IAGtF,AADA,KAAKjC,GAAU,IAAI,WAAYiD,KAAoB,GACnD,KAAKjD,GAAU,OAAO,WAAYiD,KAAoBC,IAAe;GACzE,GAEMnB,UAAkB;IAGpB,AAFA,KAAK5B,KAAY,IACjB,SAAS,oBAAoB,aAAa0B,CAAW,GACrD,SAAS,oBAAoB,WAAWE,CAAS;GACrD;GAGA,AADA,SAAS,iBAAiB,aAAaF,CAAW,GAClD,SAAS,iBAAiB,WAAWE,CAAS;EAClD,CAAC,GAED,KAAK/B,GAAU,MAAM,iBAAiB,cAAc,MAAM;GACtD,IAAI,EAAE,WAAW,KAAK,EAAE,WAAW,KAAKA,GAAU,OAAO;GACzD,IAAM4B,IAAY,KAAK5B,GAAU,MAAM,sBAAsB,GACvDgD,IAAc,KAAKhD,GAAU,MAAM,cAEnCoD,IADc,KAAKpD,GAAU,MAAM,eACPgD;GAElC,IAAII,IAAc,GAAG;IACjB,IAAMS,IAAS,EAAE,UAAUjC,EAAU,MAAOoB,IAAc,GACpDS,IAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGI,IAAST,CAAW,CAAC,GAErD,EAAE,kBAAe,KAAKV,GAAc,GACpCkB,IAAY,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAMH,KAAStB,IAAa,EAAE,GAAGA,IAAa,CAAC,CAAC;IAG5F,AAAIyB,KAAa,KAAK,KAAK3B,GAAO,cAAc,OAAO,KAAKA,GAAO,WAAW,mBAAoB,cAC9F,KAAKA,GAAO,WAAW,gBAAgB2B,GAAW,KAAK;GAE/D;GACA,KAAK,QAAQ;EACjB,CAAC;EAED,IAAIE,IAAiB,MAEfC,KAAyB,MAAc;GACzC,IAAID,GAAgB;GAEpB,IAAME,UAAmB;IACrB,IAAMC,IAAW,KAAKhC,GAAO,cAAc,eAAe;IAM1D,IAJI,CAACgC,KAAYA,EAAS,QAAQ,QAAQ,KAAA,KAItCC,MAAc,UAAU,KAAKjC,GAAO,UAAU,GAC9C;IAGJ,IAAMkC,IAAa,SAASF,EAAS,QAAQ,KAAK,EAAE,GAC9CL,IAAYM,MAAc,SAASC,IAAW,IAAI,KAAK,IAAI,GAAGA,IAAW,CAAC;IAEhF,KAAKlC,GAAO,WAAW,gBAAgB2B,GAAW,YAAY;KAC1D,KAAK,QAAQ;IACjB,CAAC;GACL;GAGA,AADAI,EAAW,GACX,IAAiB,YAAYA,GAAY,GAAG;EAChD,GAEMI,UAA6B;GAC/B,AAEIN,OADA,cAAcA,CAAc,GACX;EAEzB;EAcA,AAZA,KAAK9D,GAAU,IAAI,iBAAiB,cAAc,MAAM;GACpD,AAAI,EAAE,WAAW,KACjB+D,EAAsB,IAAI;EAC9B,CAAC,GAED,KAAK/D,GAAU,OAAO,iBAAiB,cAAc,MAAM;GACvD,AAAI,EAAE,WAAW,KACjB+D,EAAsB,MAAM;EAChC,CAAC,GAED,SAAS,iBAAiB,WAAWK,CAAoB,GACzD,KAAKpE,GAAU,IAAI,iBAAiB,cAAcoE,CAAoB,GACtE,KAAKpE,GAAU,OAAO,iBAAiB,cAAcoE,CAAoB;CAC7E;AACJ;AAEK,eAAe,IAAI,uBAAuB,KAC3C,eAAe,OAAO,yBAAyBpC,CAAmB;;AC3QtE,IAAa7K,IAAY;CACxB,IAAI;CACJ,OAAO;CACP,MAAM;CACN,UAAU;AACX,GAEamN,IAAb,MAA6B;CAC5B;CACA;CACA,KAAgB,CAAC;CACjB,qBAAY,IAAI,IAAI;CACpB,KAAc;CAEd,YAAY,GAAO;EAElB,AADA,KAAKrC,KAAShE,GACd,KAAK1E,KAAQ,KAAK0I,GAAO,YAAY,CAAC,CAAC;CACxC;CAEA,IAAI,UAAU;EACb,OAAO,KAAKsC;CACb;CAEA,IAAI,WAAW;EACd,OAAO,KAAKC;CACb;CAEA,mBAAmB;EAClB,IAAIC,IAAe,CAAC,GACdC,IAAc,KAAKzC,GAAO;EAUhC,AATIyC,KACHA,EAAY,iBAAiB,6BAA2B,CAAC,CAAC,SAAS,MAAQ;GAC1E,IAAMC,IAAOC,EAAI,cAAc,sBAAoB;GACnD,AAAID,KAAQA,EAAM,QAAQ,QACzBF,EAAa,KAAKE,EAAM,QAAQ,IAAI;EAEtC,CAAC,GAGF,KAAKJ,KAAgBE;CACtB;CAEA,QAAQ;EAEP,IAAI,KAAKI,IAAa;EACtB,KAAKA,KAAc;EAEnB,IAAIJ,IAAe,CAAC,GACdC,IAAc,KAAKzC,GAAO;EAchC,AAbIyC,KACHA,EAAY,iBAAiB,6BAA2B,CAAC,CAAC,SAAS,MAAQ;GAC1E,IAAMC,IAAOC,EAAI,cAAc,sBAAoB;GACnD,AAAID,KAAQA,EAAM,QAAQ,QACzBF,EAAa,KAAKE,EAAM,QAAQ,IAAI;EAEtC,CAAC,GAGF,KAAKJ,KAAgBE,GAErB,KAAKI,KAAc,IACnB,KAAK5C,GAAO,UAAU,CAAC,GACvB,KAAKA,GAAO,KAAK,QAAQ;CAC1B;CAEA,QAAQ;EAKP,AAJA,KAAKsC,KAAgB,CAAC,GACtB,KAAKC,GAAU,MAAM,GACrB,KAAKK,KAAc,IACnB,KAAK5C,GAAO,UAAU,CAAC,GACvB,KAAKA,GAAO,KAAK,QAAQ;CAC1B;CAEA,YAAY,GAAK;EAChB,KAAKuC,KAAY5H;CAClB;CAEA,kBAAkB,GAAS;EAC1B,OAAO,KAAK4H,GAAU,IAAIM,CAAO,KAAK,CAAC;CACxC;CAEA,mBAAmB,GAAS;EAC3B,IAAMC,IAAS,KAAK,kBAAkBD,CAAO,GACvCE,IAAc,KAAKzL,GAAM;EAC/B,OAAOwL,EAAO,KAAI,MAASC,EAAY,SAASlK,CAAK,CAAC,CAAC,CAAC,OAAO,OAAO;CACvE;AACD,GAEamK,IAAb,MAAaA,EAAS;CAErB,OAAO,MAAM,GAAY,IAAe,CAAC,GAAG,IAAS,CAAC,GAAG;EACxD,IAAI,CAACR,KAAgBA,EAAa,WAAW,GAC5C,OAAO;GAAE,SAAS,CAAC;GAAG,aAAa,CAAC;GAAG,0BAAU,IAAI,IAAI;EAAE;EAG5D,IAAMS,IAAWC,EAAW,QAAO,MAAK,CAACzL,EAAE,MAAM,OAAO,GAClD0L,oBAAW,IAAI,IAAI,GAEnBC,IAAaJ,EAASK,GAAgBJ,GAAUT,GAAcnK,CAAM,GACpEiL,IAAa,CAAC,GACdC,IAAc,CAAC;EAIrB,OAFAP,EAASQ,GAAaJ,GAAY,GAAGZ,GAAcc,GAAYC,GAAaJ,GAAU,EAAE,GAEjF;GAAE,SAASG;GAAY;GAAa;EAAS;CACrD;CAEA,OAAOE,GAAa,GAAY,GAAO,GAAc,GAAW,GAAa,GAAU,GAAU;EAChG,IAAIC,IAAU,GACRC,IAAeC,MAAUnB,EAAa,SAAS;EAErD,KAAK,IAAI,CAACoB,GAAUC,MAAoBC,EAAW,QAAQ,GAAG;GAC7D,IAAMjB,IAAUkB,IAAW,GAAGA,EAAS,GAAG,QAAc,KAAK,OAEvDjB,IAASE,EAASgB,GAAmBH,CAAe;GAC1D,EAAS,IAAIhB,GAASC,CAAM;GAE5B,IAAMmB,IAAc,CAAC;GAiBrB,AAhBA,EAAY/O,EAAU,MAAM2N,GAC5B,EAAY3N,EAAU,SAASyO,GAC/B,EAAYzO,EAAU,QAAQ0O,GAC9B,EAAY1O,EAAU,YAAY4N,GAElC,EAAY,kBAAkB,IAC9B,EAAY,YAAYD,GAExBqB,EAAU,KAAKD,CAAW,GAE1BV,EAAY,KAAK;IAChB,MAAM;IACN,QAAQU;IACC;GACV,CAAC,GAEG,CAACP,KAAeG,aAA2B,MAC9Cb,EAASQ,GAAaK,GAAiBF,IAAQ,GAAGnB,GAAc0B,GAAWX,GAAaJ,GAAUN,CAAO,IAGzGG,EAD6BmB,GAAoBN,CACvC,CAAC,CAAC,SAAQ,MAAU;IAK7B,AAJA,EAAO,kBAAkB,IACzB,EAAO,YAAYhB,GACnBqB,EAAU,KAAKE,CAAM,GAErBb,EAAY,KAAK;KAChB,MAAM;KACE;KACC;IACV,CAAC;GACF,CAAC;EAEH;CACD;CAEA,OAAOF,GAAgB,GAAS,GAAc,GAAQ;EACrD,IAAMnL,IAAWG,EAAO,QAAQmK,EAAa,EAAE,GACzC6B,IAAgB7B,EAAa,MAAM,CAAC,GACpC7H,oBAAM,IAAI,IAAI;EAQpB,IANA2J,EAAQ,SAAQ,MAAU;GACzB,IAAMC,IAAMrM,KAAY,IAAIkM,EAAO,EAAElM,KAAY;GAEjD,AADKyC,EAAI,IAAI4J,CAAG,KAAG5J,EAAI,IAAI4J,GAAK,CAAC,CAAC,GAClC5J,EAAI,IAAI4J,CAAG,CAAC,CAAC,KAAKH,CAAM;EACzB,CAAC,GAEGC,EAAc,SAAS,GAAG;GAC7B,IAAMvK,oBAAS,IAAI,IAAI;GACvB,KAAK,IAAI,CAACyK,GAAKC,MAAe7J,EAAI,QAAQ,GACzC,EAAO,IAAI4J,GAAKvB,EAASK,GAAgBmB,GAAYH,GAAehM,CAAM,CAAC;GAE5E,OAAOyB;EACR;EACA,OAAOa;CACR;CAEA,OAAOqJ,GAAmB,GAAiB;EAC1C,IAAIlB,IAAS,CAAC;EACd,IAAIe,aAA2B,KAC9B,KAAK,IAAIY,KAAUZ,EAAgB,OAAO,GACzC,IAASf,EAAO,OAAOE,EAASgB,GAAmBS,CAAM,CAAC;OAErD,AAAI,MAAM,QAAQZ,CAAe,MACvC,IAASf,EAAO,OAAOe,EAAgB,KAAI,MAAKa,EAAE,MAAM,SAASA,EAAE,GAAG,IAAI,EAAE,CAAC;EAE9E,OAAO5B;CACR;CAEA,OAAOqB,GAAoB,GAAiB;EAC3C,IAAIG,IAAU,CAAC;EACf,IAAIT,aAA2B,KAC9B,KAAK,IAAIY,KAAUZ,EAAgB,OAAO,GACzC,IAAUS,EAAQ,OAAOtB,EAASmB,GAAoBM,CAAM,CAAC;OAExD,AAAI,MAAM,QAAQZ,CAAe,MACvC,IAAUS,EAAQ,OAAOT,CAAe;EAEzC,OAAOS;CACR;AACD,GCnMaK,IAAb,MAAwB;CACpB,KAAoB;CAEpB;CACA;CACA;CAEA,qBAAsB,IAAI,IAAI;CAE9B,KAAsB,CAAC;CACvB,KAAwB;CAExB,KAAkB;CAClB,KAAe;CACf;CAEA,KAAwB;CACxB,KAAa;CAEb,YAAY,GAAO;EAIf,AAHA,KAAKrN,KAAQ0E,EAAM,YAAY,CAAC,CAAC,MACjC,KAAKgE,KAAShE,GAEd,KAAK4I,GAAoB;CAC7B;CAEA,eAAe;EACX,OAAO,KAAKC,GAAoB,QAAQ,GAAK,MAAMC,IAAMtO,GAAG,CAAC;CACjE;CAEA,WAAW,IAAQ,OAAU;EAEzB,IAAI,CAAC,KAAKwJ,GAAO,UAAU,SAAS,QAAQ,GAAG;EAE/C,IAAM+E,IAAe,KAAK/E,GAAO,cAAc,gBAAgB;EAC/D,AAAK+E,OAEoB,CAAC,KAAKC,MAAyB,KAAKA,MAAyB,OAGlF,KAAKC,GAAuB,GACxB,KAAKD,MAAyB,KAAKA,KAAwB,KAC3D,KAAKE,GAAqB,IAKlC,KAAKC,GAAcJ,EAAa,WAAWK,CAAK,GAEhD,KAAKpF,GAAO,cAAc,uBAAuB,CAAC,EAAE,QAAQ;CAChE;CAEA,MAAiB,GAAW,IAAQ,OAAU;EAE1C,IAAI,KAAKqF,IAAY;GACjB,KAAKC,GAAqBC,GAAWH,CAAK;GAC1C;EACJ;EAEA,IAAM3D,IAAY,KAAKuD;EACvB,IAAI,CAACvD,KAAaA,KAAa,GAAG;EAElC,IAAMxB,IAAc,KAAKD,GAAO,KAAK,SAAS,GACxCE,IAAaD,EAAY;EAE/B,IAAIC,MAAe,GAAG;GAClB,KAAKF,GAAO,SAAS,aAAa,MAAM,SAAS;GACjD;EACJ;EAEA,IAAMwF,IAAiB,KAAKxF,GAAO,gBAE7BU,KAAe,KAAKV,GAAO,SAAS,KAAK,OAAO,gBAAgB,MACjE,KAAKA,GAAO,SAAS,KAAK,OAAO,gBAAgB,KAClD,KAAKA,GAAO,SAAS,KAAK,MAAM,KAAK,cAEnCY,IAAa,KAAKZ,GAAO,cAAc,gBAAgB,CAAC,CAAC,gBAAgB,GACzEyF,IAAwB,KAAK,IAAIvF,IAAauB,KAAab,IAAaF,IAAce,IAAY,CAAC,GAGnGpB,IAAqB,MACrBC,IAAamF,IAAwBpF,GAEvCE,IAAc,GACdmF,IAAqBD;EAOzB,AALInF,MACA,IAAcD,IAAqBoF,GACnC,IAAqBpF,IAGzB,KAAKL,GAAO,SAAS,aAAa,MAAM,SAAS,GAAG0F,EAAmB;EAEvE,IAAMC,IAAkBrF,IAAciF,IAAYhF,IAAegF,GAE3DK,IAAgB,KAAK,IAAI,GAAG1F,IAAa,CAAC,GAC1C2F,IAAmB,KAAK,IAAIF,GAAiBF,CAAqB,GAElEK,IAAa,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAMD,IAAmBpE,CAAS,GAAGmE,CAAa,CAAC,GAE1FG,IAAkBF,IAAmBpE;EAC3C,KAAKzB,GAAO,SAAS,KAAK,MAAM,KAAK,MAAM,MACvC,KAAKA,GAAO,SAAS,KAAK,MAAM,KAAK,MAAM,MACvC,KAAKA,GAAO,SAAS,MAAM,MAAM,KAAK,MAAM,MAAM,IAAI+F,EAAgB;EAE9E,IAAMC,IAAU,KAAKC,GAAS,SACxBC,IAAoBF,KAAWA,EAAQ,QAAQ,QAAQ,KAAA,IAAY,SAASA,EAAQ,QAAQ,KAAK,EAAE,IAAI;EAE7G,CAAKZ,KAASc,MAAsBJ,OAIpC;GACI,KAAK9F,GAAO,SAAS,KAAK,MAAM;GAChC,KAAKA,GAAO,SAAS,KAAK,MAAM;GAChC,KAAKA,GAAO,SAAS,MAAM,MAAM;EACrC,CAAC,CAAC,SAAS,GAAQ,MAAa;GAC5B,AAAKmG,KAILA,EAFoB,iBAAiB,eAElC,CAAC,CAAC,SAAS,GAAK,MAAU;IACzB,IAAMC,IAAYN,IAAa,KAAK,MAAMpK,IAAQ8J,CAAc;IAEhE,IAAIY,KAAalG,GAAY;KAIzB,AAHA,EAAI,MAAM,UAAU,QACpB,EAAI,QAAQ,YAAY,MACxB,EAAI,QAAQ,MAAM,MAClB,EAAI,QAAQ,QAAQ;KACpB;IACJ;IAEA,IAAMkE,IAASnE,EAAYmG;IAE3B,IAAI,CAAChC,GAAQ;KACT,EAAI,MAAM,UAAU;KACpB;IACJ;IAEA,IAAMvL,IAAQuL,EAAO,EAAE,EAAEpN,EAAW,KAAK,MAAM;IAI/C,AAFA,EAAI,MAAM,UAAU,IAEpB,KAAKqP,GAAa1D,GAAKyB,GAAQvL,GAAOuN,CAAS;GACnD,CAAC;EACL,CAAC,GAED,KAAKpG,GAAO,UAAU,QAAQ;CAClC;CAGA,MAAwB,GAAW,IAAQ,OAAU;EAEjD,IAAMsG,IAAiB,KAAKtG,GAAO,KAAK,SAAS,KAAK,CAAC,GACjDuG,IAAoBD,EAAe;EAEzC,IAAIC,MAAsB,GAAG;GACzB,KAAKvG,GAAO,SAAS,aAAa,MAAM,SAAS;GACjD;EACJ;EAGA,IAAMwG,IAAc,KAAKxG,GAAO,cAAc,uCAAuC,GAC/EwF,IAAiB,KAAKxF,GAAO,kBAAkB,GAE/CyG,KAAiB,MAAS;GAC5B,IAAIhN,EAAK,SAAS,SAAS;IACvB,IAAMkK,IAAQlK,EAAK,OAAOtE,EAAU,UAAU;IAE9C,OADoB,KAAK0P,GAAoBlB,MAAU,KAAKqB,KAAwBQ;GAExF;GAAO;IACH,IAAIkB,IAAiB,GACflB,IAAiB,KAAKxF,GAAO,kBAAkB,GAEjD2G,IAAoB;IACxB,KAAI,IAAI5M,IAAI,GAAGA,IAAIyL,IAAiB,GAAG,KACnC,KAAqB,KAAKX,GAAoB9K,MAAM;IAIxD,OAFA,IAAiB,KAAKiL,KAAwB2B,GAEvCD,IAAiB,IAAIA,IAAiB,KAAK1B;GACtD;EACJ,GAGIU,IAAqB,GACnBkB,IAAkB,MAAML,CAAiB;EAC/C,KAAK,IAAIxM,IAAI,GAAGA,IAAIwM,GAAmB,KAAK;GACxC,IAAM/P,IAAIiQ,EAAcH,EAAevM,EAAE;GAEzC,AADA,EAAYA,KAAKvD,GACjB,KAAsBA;EAC1B;EAEA,KAAKwJ,GAAO,SAAS,aAAa,MAAM,SAAS,GAAG0F,EAAmB;EAEvE,IAAMmB,IAAuB,KAAK7G,GAAO,cAErC8G,IAAoB,GACpBhB,IAAa;EAEjB,KAAK,IAAI/L,IAAI,GAAGA,IAAIwM,GAAmB,KAAK;GACxC,IAAM/P,IAAIoQ,EAAY7M;GACtB,IAAI+M,IAAoBtQ,IAAI+O,GAAW;IACnC,IAAaxL;IACb;GACJ;GAEA,AADA,KAAqBvD,GACrB,IAAauD;EACjB;EAEA,IAAMgN,IAAUxB,IAAYuB;EAC5B,AAAIN,KACAA,EAAY,iBAAiB,OAAO,CAAC,CAAC,SAAS,MAAW;GACtD,EAAO,MAAM,MAAM,IAAI,KAAK,IAAI,GAAGO,CAAO,EAAE;EAChD,CAAC;EAGL,IAAMf,IAAU,KAAKC,GAAS,SACxBC,IAAoBF,KAAWA,EAAQ,QAAQ,iBAAiB,KAAA,IAChE,SAASA,EAAQ,QAAQ,cAAc,EAAE,IACzC;EAEN,IAAI,CAACZ,KAASc,MAAsBJ,GAChC;EAGJ,IAAMkB,IAAmB,KAAK,KAAKH,KAAwB,KAAK7B,KAAwBQ,EAAe,GACjGyB,KAAiB,KAAKjH,GAAO,SAAS,SAAS,UAAU,KAAK,IAC9DkH,IAAcpB,GACdqB,IAAY,KAAK,IAAIZ,GAAmBT,IAAakB,IAAmBC,CAAa,GACrFG,IAAgBd,EAAe,MAAMY,GAAaC,CAAS;EAmEjE,AAjEA;GAAC;GAAsB;GAAsB;EAAqB,CAAC,CAAC,SAAQ,MAAY;GACpF,IAAME,IAAY,KAAKrH,GAAO,cAAc,kBAAkBsH,GAAU;GACxE,IAAI,CAACD,GAAW;GAEhB,IAAME,IAAM,MAAM,KAAKF,EAAU,iBAAiB,eAAe,CAAC;GAElE,KAAK,IAAItN,IAAI,GAAGA,IAAIwN,EAAI,QAAQ,KAAK/B,GAAgB;IACjD,IAAMgC,IAAY,KAAK,MAAMzN,IAAIyL,CAAc,GACzC/L,IAAO2N,EAAcI,IACrBC,IAAWF,EAAI,MAAMxN,GAAGA,IAAIyL,CAAc;IAEhD,IAAI,CAAC/L,KAAQ+N,KAAaJ,EAAc,QAAQ;KAC5C,EAAS,SAAQ,MAAM;MAInB,AAHA,EAAG,MAAM,UAAU,QACnB,EAAG,QAAQ,YAAY,MACvB,EAAG,QAAQ,MAAM,MACjB,EAAG,QAAQ,QAAQ;KACvB,CAAC;KACD;IACJ;IAEA,IAAMhB,IAAYN,IAAa0B;IAE/B,EAAS,SAAS,GAAI,MAAW;KAC7B,IAAME,IAAe5B,IAAa0B;KAElC,AADA,EAAG,QAAQ,eAAeE,GAC1B,EAAG,QAAQ,MAAOjO,EAAK,SAAS,SAAU2M,IAAY;KAEtD,IAAMuB,IAAYC,EAAG,aAAa,UAAU,MAAM;KAElD,IAAInO,EAAK,SAAS,SACd,AAAIkO,KAEIE,MADUpO,EAAK,OAAOtE,EAAU,UAEhC,EAAG,MAAM,UAAU,IACnB,KAAK2S,GAAkBF,GAAItB,GAAgB7M,EAAK,QAAQiO,CAAY,MAQxE,EAAG,MAAM,UAAU,QACnB,EAAG,QAAQ,YAAY,MACvB,EAAG,QAAQ,MAAM,MACjB,EAAG,QAAQ,QAAQ;UAGvB,IAAIC,GAIA,AAHA,EAAG,MAAM,UAAU,QACnB,EAAG,QAAQ,YAAY,MACvB,EAAG,QAAQ,MAAM,MACjB,EAAG,QAAQ,QAAQ;UAChB;MACH,EAAG,MAAM,UAAU;MAEnB,IAAM9O,IAAQY,EAAK,OAAO,GAAG,SAAS;MACtC,KAAK4M,GAAauB,GAAInO,EAAK,QAAQZ,GAAO6O,CAAY;KAC1D;IAER,CAAC;GACL;EACJ,CAAC,GAED,KAAK1H,GAAO,UAAU,QAAQ;CAClC;CAEA,MAAqB,GAAK,GAAgB,GAAa,MAAiB;EACpE,IAAMwF,IAAiB,KAAKxF,GAAO,kBAAkB,GAC/C+H,IAAc,SAASpF,EAAI,QAAQ,QAAQ,EAAE,KAAK,GAClDqF,IAAaN,IAAelC,IAAkBuC,GAE9CE,IAAUhE,EAAY9O,EAAU,WAChC+S,IAAa,KAAK5Q,GAAM,KAAK,SAAS,GACtC6Q,IAAkBF,IAAUA,EAAQ,KAAI,MAAOC,EAAWnQ,EAAI,CAAC,CAAC,OAAO,OAAO,IAAI,CAAC;EAUzF,AAPA,EAAI,QAAQ,eAAe2P,GAC3B,EAAI,QAAQ,MAAM,IAClB,EAAI,QAAQ,YAAYM,GACxB,EAAI,OAAOG,GACX,EAAI,QAAQ,UAAUlE,EAAY9O,EAAU,KAG5C,MAAM,KAAKwN,EAAI,KAAK,CAAC,CAAC,SAAS,MAAU;GAErC,EAAM,QAAQ,MAAM+E;GAEpB,IAAMU,IAAa,MAAM,KAAK1F,EAAM,QAAQ,CAAC,CAAC,MAAK,MAC/C2F,EAAI,QAAQ,YAAY,CAAC,CAAC,WAAW,OAAO,KAAK,OAAOA,EAAI,WAAY,UAC5E;GAGA,AAAID,MAAe,KAAA,KAAa,OAAOA,EAAW,WAAY,cAC1DA,GAAY,QAAQ;EAE5B,CAAC;CACL;CAEA,MAAgB,GAAK,GAAQ,GAAO,MAAc;EAC9C,IAAM5C,IAAiB,KAAKxF,GAAO,kBAAkB,GAC/C+H,IAAc,SAASpF,EAAI,QAAQ,QAAQ,EAAE,KAAK,GAClDqF,IAAa5B,IAAYZ,IAAkBuC;EAOjD,AALA,EAAI,QAAQ,QAAQ3B,GACpB,EAAI,QAAQ,MAAMvN,GAClB,EAAI,QAAQ,YAAYmP,GACxB,EAAI,OAAO5D,GAEX,MAAM,KAAKzB,EAAI,KAAK,CAAC,CAAC,SAAS,MAAU;GAQrC,AAPA,EAAM,QAAQ,QAAQyD,GACtB,EAAM,QAAQ,MAAMvN,GAMpB,MAJyB,KAAK6J,EAAM,QAAQ,CAAC,CAAC,MAAK,MAC/C2F,EAAI,QAAQ,YAAY,CAAC,CAAC,WAAW,OAAO,KAAK,OAAOA,EAAI,WAAY,UAGnE,CAAC,EAAE,QAAQ;EACxB,CAAC;CACL;CAEA,mBAAmB;EAYf,AAVA,KAAKhD,KAAa,OAAKrF,GAAO,YAAY,cAAc,2BAA2B,GAEnF,KAAKgF,KAAwB,MAC7B,KAAKsD,GAAoB,MAAM,GAE/B,KAAKrC,KAAW;GACZ,cAAc,KAAKjG,GAAO,iBAAiB,sBAAsB;GACjE,SAAS,KAAKA,GAAO,cAAc,iDAAiD;EACxF,GAEA;GAAC;GAAsB;GAAsB;EAAqB,CAAC,CAAC,SAAQ,MAAY;GACpF,IAAMqH,IAAY,KAAKrH,GAAO,cAAc,kBAAkBsH,GAAU;GACxE,IAAI,CAACD,GAAW;GAEhB,IAAMkB,IAAUlB,EAAU,cAAc,OAAO;GAC/C,IAAI,CAACkB,GAAS;GAEd,IAAMC,IAAQD,EAAQ,cAAc,YAAY;GAChD,IAAI,CAACC,GAAO;GAGZ,IAAMC,IADM,MAAM,KAAKD,EAAM,iBAAiB,IAAI,CAC5B,CAAC,CAAC,KAAI,MAAMZ,EAAG,UAAU,EAAI,CAAC;GACpD,KAAKU,GAAoB,IAAIhB,GAAUmB,CAAW;EACtD,CAAC;EAED,IAAM1D,IAAe,KAAK/E,GAAO,cAAc,gBAAgB;EAE/D,AAAI+E,MACA,KAAK2D,KAAe3D,EAAa,cAEjC,KAAKE,GAAuB,GAC5B,KAAKC,GAAqB,GAC1B,KAAKC,GAAcJ,EAAa,WAAW,EAAI,GAE/CA,EAAa,iBAAiB,WAAW,MAAM;GAE3C,IAAI,KAAK4D,IAAuB;GAEhC,IAAMlH,IAAY,KAAKuD,MAAyB;GAIhD,CAHmB,KAAKhF,GAAO,KAAK,SAAS,CAAC,EAAE,UAAU,KACfyB,KAEdsD,EAAa,iBAI1C,KAAKI,GAAcJ,EAAa,SAAS,GAEzC,KAAK/E,GAAO,cAAc,uBAAuB,CAAC,CAAC,QAAQ;EAE/D,GAAG,EAAE,SAAS,GAAK,CAAC;CAE5B;CAEA,gBAAgB,GAAS,IAAQ,OAAO,GAAY;EAEhD,IAAM+E,IAAe,KAAK/E,GAAO,cAAc,gBAAgB,GAGzDE,IADc,KAAKF,GAAO,KAAK,SACR,CAAC,EAAE,UAAU,GAEpC2B,IAAY,KAAK,IAAI,GAAG,KAAK,IAAIiH,GAAS1I,IAAa,CAAC,CAAC,GAC3D2I,IAAkB;EAEtB,IAAI,KAAKxD,IAAY;GACjB,IAAMpE,IAAe,KAAK,IAAI8D,EAAa,eAAeA,EAAa,cAAc,CAAC;GAGtF,IADcpD,IAAY,KAAK,IAAIzB,IAAa,GAAG,CAAC,IAC1Be;EAC9B,OAAO;GAEH,IAAMQ,IAAY,KAAKuD,IACjB8D,IAAqBnH,IAAYF,GAEjCf,KAAe,KAAKV,GAAO,SAAS,KAAK,OAAO,gBAAgB,MACjE,KAAKA,GAAO,SAAS,KAAK,OAAO,gBAAgB,KAClD,KAAKA,GAAO,SAAS,KAAK,MAAM,KAAK,cAEnCY,IAAamE,EAAa,gBAAgB,GAC1CU,IAAwB,KAAK,IAAIvF,IAAauB,IAAYf,IAAcE,GAAY,CAAC,GAErFP,IAAqB,MACrBC,IAAamF,IAAwBpF,GAEvCE,IAAc;GAKlB,AAJID,MACA,IAAcD,IAAqBoF,IAGvC,IAAkBqD,IAAqBvI;EAC3C;EAMA,AAJA,KAAKoI,KAAwB,IAC7B,EAAa,YAAYE,GACzB,KAAK1D,GAAc0D,CAAe,GAElC,4BAA4B;GACxB,4BAA4B;IAExB,AADA,KAAKF,KAAwB,IACzB,OAAOI,KAAe,cAAYA,EAAW;GACrD,CAAC;EACL,CAAC;CACL;CAIA,gBAAgB;EACZ,AAEI,KAAK9K,QADL,KAAKA,GAAgB,WAAW,GACT;CAE/B;CAEA,WAA+B;EAG3B,IAFI,CAAC,KAAK+B,GAAO,UAAU,SAAS,QAAQ,KAExC,CAAC,KAAKA,GAAO,aAAa;EAE9B,IAAMgJ,IAAc,KAAKhJ,GAAO,aAAa,iBAAiB,eAAe,GAEvEmG,IAAS,KAAKnG,GAAO,cAAc,8CAA8C;EAEvF,EAAO,iBAAiB,IAAI,CAAC,CAAC,SAAQ,MAAM4H,EAAG,OAAO,CAAC;EAEvD,IAAMqB,IAAW,SAAS,uBAAuB;EAEjD,AADAD,EAAY,SAAQ,MAAOC,EAAS,YAAYtG,EAAI,UAAU,EAAI,CAAC,CAAC,GACpEwD,EAAO,YAAY8C,CAAQ;EAE3B,IAAMC,IAAc/C,EAAO,iBAAiB,IAAI;EAWhD,AATA,KAAKtB,KAAsB,CAAC,GAC5BqE,EAAY,SAAQ,MAAO;GACvB,KAAKrE,GAAoB,KAAK,KAAK,IAAIlC,EAAI,cAAc,EAAE,CAAC;EAChE,CAAC,GAEDuG,EAAY,SAAQ,MAAMtB,EAAG,OAAO,CAAC,GAErC,KAAK5C,KAAwB,KAAKH,GAAoB,QAAQ,GAAK,MAAMC,IAAMtO,GAAG,CAAC,GAEnF,KAAK2S,GAAgB;CACzB;CAEA,WAAwB;EAEpB,IAAI,KAAKT,KAAe,KAAK,KAAK1D,KAAwB,GAAG;GACzD,IAAMoE,IAAc,KAAK,KAAK,KAAKV,KAAe,KAAK1D,EAAqB,GAExEiC,IAAgB,KAAKoC;GACzB,IAAI,KAAKhE,MAAc,KAAKrF,GAAO,UAAU;IACzC,IAAMsJ,IAAa,KAAKtJ,GAAO,SAAS,SAAS,UAAU;IAC3D,KAAkBsJ,IAAa;GACnC;GAEA,KAAKC,KAAkBH,IAAcnC;EACzC;CACJ;CAEA,WAA6B;EASzB,AAPA;GAAC;GAAsB;GAAsB;EAAqB,CAAC,CAAC,SAAQ,MAAY;GACpF,IAAMI,IAAY,KAAKrH,GAAO,cAAc,kBAAkBsH,GAAU;GACxE,AAAID,KAAaA,EAAU,cAAc,OAAO,KAC5C,KAAKmC,GAAYnC,CAAS;EAElC,CAAC,GAED,KAAKoC,GAAgB;CACzB;CAEA,MAAe,MAAc;EACzB,IAAIC,IAAkB;EACtB,AAAIrC,EAAU,UAAU,SAAS,mBAAmB,IAAG,IAAkB,SAChEA,EAAU,UAAU,SAAS,oBAAoB,MAAG,IAAkB;EAE/E,IAAMoB,IAAc,MAAM,KAAK,KAAKzI,GAAO,YAAY,iBAAiB,eAAe,CAAC,CAAC,CAAC,KAAI,MAAM;GAChG,IAAM2J,IAAW/B,EAAG,UAAU,EAAI;GAgBlC,OAdI8B,MAAoB,SACpBC,EAAS,iBAAiB,OAAO,CAAC,CAAC,SAAQ,MAAS;IAChD,AAAIjH,EAAM,aAAa,OAAO,MAAM,UAAQA,EAAM,OAAO;GAC7D,CAAC,IACMgH,MAAoB,UAC3BC,EAAS,iBAAiB,OAAO,CAAC,CAAC,SAAQ,MAAS;IAChD,AAAIjH,EAAM,aAAa,OAAO,MAAM,WAASA,EAAM,OAAO;GAC9D,CAAC,IAEDiH,EAAS,iBAAiB,6BAA6B,CAAC,CAAC,SAAQ,MAAS;IACtE,EAAM,OAAO;GACjB,CAAC,GAGEA;EACX,CAAC;EAED,IAAIlB,EAAY,WAAW,GAAG;EAE9B,IAAMmB,IAAcvC,EAAU,cAAc,YAAY;EACxD,IAAI,CAACuC,GAAa;EAElB,EAAY,iBAAiB,IAAI,CAAC,CAAC,SAAQ,MAAMhC,EAAG,OAAO,CAAC;EAE5D,IAAMqB,IAAW,SAAS,uBAAuB;EACjD,KAAK,IAAIlP,IAAI,GAAGA,IAAI,KAAKwP,IAAiB,KACtC,EAAY,SAAQ,MAAQN,EAAS,YAAYY,EAAK,UAAU,EAAI,CAAC,CAAC;EAM1E,AAFAD,EAAY,YAAYX,CAAQ,GAE5B5B,EAAU,UAAU,SAAS,mBAAmB,MAChD,KAAKpB,GAAS,UAAU2D,EAAY,cAAc,IAAI;CAE9D;CAIA,WAAwB;EACpB,IAAME,IAAY,KAAK9J,GAAO,cAAc,yCAAyC,GAC/E+J,IAAY,KAAK/J,GAAO,cAAc,yCAAyC,GAC/EgK,IAAa,KAAKhK,GAAO,cAAc,0CAA0C;EAEvF,IAAI+J,GAAW;GACX,IAAME,IAAWH,IAAY,MAAM,KAAKA,EAAU,iBAAiB,UAAU,CAAC,IAAI,CAAC,GAC7EI,IAAW,MAAM,KAAKH,EAAU,iBAAiB,UAAU,CAAC,GAC5DI,IAAYH,IAAa,MAAM,KAAKA,EAAW,iBAAiB,UAAU,CAAC,IAAI,CAAC,GAEhFI,IAAU,KAAK,IAAIH,EAAS,QAAQC,EAAS,QAAQC,EAAU,MAAM;GAE3E,KAAK,IAAIpQ,IAAI,GAAGA,IAAIqQ,GAAS,KAAK;IAC9B,IAAMC,IAAU;KACZJ,EAASlQ,EAAE,EAAE,sBAAsB,CAAC,CAAC,UAAU;KAC/CmQ,EAASnQ,EAAE,EAAE,sBAAsB,CAAC,CAAC,UAAU;KAC/CoQ,EAAUpQ,EAAE,EAAE,sBAAsB,CAAC,CAAC,UAAU;IACpD,GACMuQ,IAAY,KAAK,IAAI,GAAGD,CAAO;IAErC,AAAIC,IAAY,MACRL,EAASlQ,OAAI,EAASA,EAAE,CAAC,MAAM,SAAS,GAAGuQ,EAAU,MACrDJ,EAASnQ,OAAI,EAASA,EAAE,CAAC,MAAM,SAAS,GAAGuQ,EAAU,MACrDH,EAAUpQ,OAAI,EAAUA,EAAE,CAAC,MAAM,SAAS,GAAGuQ,EAAU;GAEnE;EACJ;CACJ;CAEA,WAA4B;EAExB,AAAK,KAAKtK,MAAY,KAAKA,cAAkB,gBAE7C,KAAK/B,KAAkB,IAAI,gBAAgB,MAAY;GACnD,KAAK,IAAMsM,KAASC,GAAS;IAGzB,IAAI,CADYD,EAAM,OACT,UAAU,SAAS,QAAQ,GAAG;IAE3C,IAAME,IAASF,EAAM,YAAY;IAOjC,AANcA,EAAM,YAAY,QAEpB,KAAK,KAAKvK,GAAO,gBACzB,KAAKA,GAAO,QAAQ,EAAI,GAGxByK,IAAS,KAAK,KAAK/B,OAAiB+B,MACpC,KAAK/B,KAAe+B,GACpB,KAAKtB,GAAgB,GAEjB,KAAKnE,OAA0B,SAC/B,KAAKE,GAAqB,GAC1B,KAAK,QAAQ;GAGzB;EACJ,CAAC,GAED,KAAKjH,GAAgB,QAAQ,KAAK+B,EAAM;CAC5C;AACJ,GCxnBa0K,IAAb,MAAaA,EAAc;CAEvB,OAAO,QAAQ,GAAW;EAEtB,IAAMC,IAASC,EAAU,UAAU,EAAI;EASvC,OAPAF,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,UAAU,CAAC,GACvED,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,kCAAgC,CAAC,GAC7FD,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,wCAAsC,CAAC,GACnGD,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,UAAU,CAAC,GAEvED,EAAcG,GAAmBF,CAAM,GAEhCA;CACX;CAEA,OAAO,UAAU,GAAQ;EAUrB,OAPAD,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,UAAU,CAAC,GACvED,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,kCAAgC,CAAC,GAC7FD,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,wCAAsC,CAAC,GACnGD,EAAc,cAAcC,GAAQA,EAAO,iBAAiB,UAAU,CAAC,GAEvED,EAAcG,GAAmBF,CAAM,GAEhCA;CACX;CAEA,OAAOE,GAAmB,GAAQ;EAE9B,EAAO,iBAAiB,cAAc,CAAC,CAAC,SAAS,GAAM,MAAM;GACzD,EAAK,aAAa,YAAY9Q,CAAC;GAC/B,IAAM+Q,IAAQC,EAAK,aAAa,OAAO;GAEvC,EAAO,iBAAiB,cAAchR,EAAE,GAAG,CAAC,CAAC,SAAQ,MAAO;IACxD,IAAQsO,EAAI,aAAa,SAASyC,CAAK,IAAIzC,EAAI,gBAAgB,OAAO;GAC1E,CAAC;EACL,CAAC;CACL;CAEA,OAAO,cAAc,GAAQ,GAAK;EAE9B,IAAM2C,IAAOL,EAAO,iBAAiB,cAAc,GAC7CM,IAAO,MAAM,KAAK,EAAE,QAAQ1D,EAAI,OAAO,SAAS,MAAMyD,EAAK,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;EAEnF,EAAI,SAAS,GAAK,MAAU;GAExB,EAAI,QAAQ,SAAStP;GAErB,IAAIxD,IAAW;GAEf,EAAI,iBAAiB,QAAQ,CAAC,CAAC,SAAQ,MAAS;IAE5C,OAAOA,IAAW8S,EAAK,UAAUC,EAAKvP,EAAM,CAACxD,OAAc,OACvD;IAGJ,EAAM,QAAQ,MAAMA;IAEpB,IAAMgT,IAAUxI,EAAM,WAAW,GAC3ByI,IAAUzI,EAAM,WAAW;IAEjC,KAAK,IAAIgC,IAAI,GAAGA,IAAIwG,GAAS,KACzB,KAAK,IAAIE,IAAI,GAAGA,IAAID,GAAS,KACzB,AAAIzP,IAAQgJ,IAAI6C,EAAI,UAAUrP,IAAWkT,IAAIJ,EAAK,WAC9C,EAAKtP,IAAQgJ,EAAE,CAACxM,IAAWkT,KAAK1I;IAK5C,KAAYyI;GAChB,CAAC;EACL,CAAC;CACL;AAEJ,GC9EaE,IAAb,MAA2B;CAC1B;CACA,KAAS;EAAE,UAAU;EAAI,UAAU;EAAI,QAAQ;EAAI,QAAQ;CAAG;CAE9D,YAAY,GAAO;EAElB,AADA,KAAKrL,KAAShE,GACd,KAAKsP,GAAY;CAClB;CAEA,GAAc,GAAI;EACjB,IAAI,CAAC1D,GAAI,OAAO;GAAE,SAAS;GAAI,aAAa;GAAI,WAAW;EAAG;EAE9D,IAAMgB,IAAU,SAAShB,EAAG,QAAQ,OAAO,EAAE;EAC7C,IAAI,MAAMgB,CAAO,GAAG,OAAO;GAAE,SAAS;GAAI,aAAa;GAAI,WAAW;EAAG;EAEzE,IAAMJ,IAAQZ,EAAG,QAAQ,OAAO,GAG1B2D,IAFM,MAAM,KAAK/C,EAAM,iBAAiB,IAAI,CAE3B,CAAC,CAAC,QAAO,MAAK,SAASgD,EAAE,QAAQ,OAAO,EAAE,MAAM5C,CAAO,GACxEb,IAAcwD,EAAa,QAAQ3D,CAAE,GACrCpC,IAAiB+F,EAAa,SAAS,IAAIA,EAAa,SAAS;EAIvE,OAAO;GAAE;GAAS;GAAa,WAFZ3C,IAAUpD,KAAmBuC,KAAe,IAAIA,IAAeH,EAAG,kBAAkBpC;EAE9D;CAC1C;CAEA,SAAS,GAAW,GAAK;EACxB,KAAKxF,GAAO,iBAAiB,mBAAmB,CAAC,CAAC,SAAQ,MAAO;GAEhE,AADA2C,EAAI,UAAU,OAAO,gBAAgB,GACrCA,EAAI,iBAAiB,mBAAmB,CAAC,CAAC,SAAQ,MAAO;IACxD,EAAI,UAAU,OAAO,gBAAgB;GACtC,CAAC;EACF,CAAC;EAED,IAAM8I,IAAM,KAAKzL,GAAO,cAAc,8CAA8CgI,EAAU,kBAAkB0D,EAAI,GAAG;EACvH,AAAKD,MAELA,EAAI,UAAU,IAAI,gBAAgB,GAClCA,EAAI,QAAQ,IAAI,CAAC,EAAE,UAAU,IAAI,gBAAgB;CAClD;CAEA,SAAS,GAAU,GAAU,GAAQ,GAAQ;EAC5C,IAAIE,IAAK,KAAK,IAAIC,GAAUC,CAAM,GAC9BC,IAAK,KAAK,IAAIF,GAAUC,CAAM,GAC9BE,IAAK,KAAK,IAAIC,GAAUC,CAAM,GAC9BC,IAAK,KAAK,IAAIF,GAAUC,CAAM,GAE5BE,IAAa,KAAKnM,GAAO,iBAAiB,6DAA6D,GAEzGoM,IAAW,IACXC,IAAY;EAEhB,OAAOD,KAAYC,IAAY,IAI9B,AAHA,IAAW,IACX,KAEAF,EAAW,SAAQ,MAAa;GAM/B,MAJyB,KAAK9E,EAAU,iBAAiB,UAAU,CAAC,CAAC,CAAC,QAAO,MACrEO,EAAG,MAAM,YAAY,MAGpB,CAAC,CAAC,SAAQ,MAAM;IACxB,IAAM,EAAE,iBAAc,KAAK0E,GAAc1E,CAAE;IAC3C,AAAII,IAAY,KAEhBJ,EAAG,iBAAiB,QAAQ,CAAC,CAAC,SAAQ,MAAQ;KAC7C,IAAM8D,IAAM,SAASa,EAAK,QAAQ,KAAK,EAAE;KACzC,IAAI,MAAMb,CAAG,GAAG;KAEhB,IAAMR,IAAU,SAASqB,EAAK,WAAW,GAAG,EAAE,GACxCpB,IAAU,SAASoB,EAAK,WAAW,GAAG,EAAE,GAExCC,IAAaxE,IAAYkD,IAAU,GACnCuB,IAAaf,IAAMP,IAAU;KAInC,IAFuBqB,KAAcb,KAAM3D,KAAa8D,KAAMW,KAAcV,KAAML,KAAOQ,GAErE;MACnB,IAAMQ,IAAM,KAAK,IAAIf,GAAI3D,CAAS,GAC5B2E,IAAM,KAAK,IAAIb,GAAIU,CAAU,GAC7BI,IAAM,KAAK,IAAIb,GAAIL,CAAG,GACtBmB,IAAM,KAAK,IAAIX,GAAIO,CAAU;MAEnC,CAAIC,MAAQf,KAAMgB,MAAQb,KAAMc,MAAQb,KAAMc,MAAQX,OACrD,IAAKQ,GAAK,IAAKC,GAAK,IAAKC,GAAK,IAAKC,GACnC,IAAW;KAEb;IACD,CAAC;GACF,CAAC;EACF,CAAC;EAIF,AADA,KAAKC,KAAS;GAAE,UAAUnB;GAAI,UAAUI;GAAI,QAAQD;GAAI,QAAQI;EAAG,GACnE,KAAK,OAAO;CACb;CAEA,gBAAgB;EACf,KAAK,OAAO;CACb;CAEA,eAAe;EACd,IAAM,EAAE,aAAU,aAAU,WAAQ,cAAW,KAAKY,IAE9CX,IAAa,KAAKnM,GAAO,iBAC9B,6DACD;EAYA,AAVAmM,EAAW,SAAQ,MAAa;GAK/B,AAJA9E,EAAU,iBAAiB,8FAA8F,CAAC,CAAC,SAAQ,MAAM;IACxI,EAAG,UAAU,OAAO,YAAY,gBAAgB,mBAAmB,iBAAiB,kBAAkB,gBAAgB;GACvH,CAAC,GAEDA,EAAU,iBAAiB,mBAAmB,CAAC,CAAC,SAAQ,MAAM;IAC7D,EAAG,UAAU,OAAO,gBAAgB;GACrC,CAAC;EACF,CAAC,GAEGuE,IAAW,KAAKI,IAAW,KAE/BG,EAAW,SAAS,MAAc;GAKjC,MAJyB,KAAK9E,EAAU,iBAAiB,UAAU,CAAC,CAAC,CAAC,QAAO,MACrEO,EAAG,MAAM,YAAY,MAGpB,CAAC,CAAC,SAAQ,MAAM;IACxB,IAAM,EAAE,iBAAc,KAAK0E,GAAc1E,CAAE;IAC3C,AAAII,IAAY,KAEhBJ,EAAG,iBAAiB,QAAQ,CAAC,CAAC,SAAQ,MAAQ;KAC7C,IAAM8D,IAAM,SAASa,EAAK,QAAQ,KAAK,EAAE;KACzC,IAAI,MAAMb,CAAG,GAAG;KAEhB,IAAMR,IAAU,SAASqB,EAAK,WAAW,GAAG,EAAE,GACxCpB,IAAU,SAASoB,EAAK,WAAW,GAAG,EAAE,GAExCC,IAAaxE,IAAYkD,IAAU,GACnCuB,IAAaf,IAAMP,IAAU;KAGnC,AADmBqB,KAAcZ,KAAY5D,KAAa6D,KAAUY,KAAcT,KAAYN,KAAOO,MAGrGM,EAAK,UAAU,IAAI,UAAU,GAEzBvE,KAAa4D,KAAUW,EAAK,UAAU,IAAI,cAAc,GACxDC,KAAcX,KAAQU,EAAK,UAAU,IAAI,iBAAiB,GAC1Db,KAAOM,KAAUO,EAAK,UAAU,IAAI,eAAe,GACnDE,KAAcR,KAAQM,EAAK,UAAU,IAAI,gBAAgB;IAC9D,CAAC;GACF,CAAC;EACF,CAAC;CACF;CAEA,KAAc;EACb,IAAMQ,IAAW,KAAK/M,GAAO,cAAc,gBAAgB;EAC3D,AAAK+M,KAILA,EAAS,iBAAiB,cAAc,MAAM;GAC7C,IAAI,EAAE,WAAW,GAAG;GAEpB,IAAMR,IAAO,EAAE,OAAO,QAAQ,QAAQ;GAEtC,IADI,CAACA,KACDA,EAAK,QAAQ,QAAQ,KAAA,KAAaA,EAAK,QAAQ,QAAQ,KAAA,GAAW;GAGtE,AADA,KAAKvM,GAAO,MAAM,aAAa,QAC/B,KAAKA,GAAO,MAAM,mBAAmB;GAErC,IAAM4H,IAAK2E,EAAK,QAAQ,IAAI,GACtB,EAAE,WAAWX,MAAa,KAAKU,GAAc1E,CAAE,GAC/CoE,IAAW,SAASO,EAAK,QAAQ,KAAK,EAAE;GAE9C,IAAIX,IAAW,GAAG;IAEjB,AADA,KAAK5L,GAAO,MAAM,aAAa,IAC/B,KAAKA,GAAO,MAAM,mBAAmB;IACrC;GACD;GAGA,AADA,KAAK,SAAS4L,GAAUI,CAAQ,GAChC,KAAK,SAASJ,GAAUI,GAAUJ,GAAUI,CAAQ;GAEpD,IAAIgB,IAAgBpB,GAChBqB,IAAUjB,GAERpM,KAAe,MAAc;IAElC,IAAIsN,IADa,SAAS,iBAAiBrN,EAAU,SAASA,EAAU,OAChD,CAAC,EAAE,QAAQ,QAAQ;IAE3C,IAAI,CAACqN,KAAc,CAAC,KAAKlN,GAAO,SAASkN,CAAU,GAAG;KACrD,IAAMC,IAAW,KAAKnN,GAAO,iBAAiB,qFAAqF;KACnI,KAAK,IAAMoL,KAAK+B,GAAU;MACzB,IAAMC,IAAOhC,EAAE,sBAAsB;MACrC,IACCvL,EAAU,WAAWuN,EAAK,QAC1BvN,EAAU,WAAWuN,EAAK,SAC1BvN,EAAU,WAAWuN,EAAK,OAC1BvN,EAAU,WAAWuN,EAAK,QACzB;OACD,IAAahC;OACb;MACD;KACD;IACD;IAGA,IADI,CAAC8B,KACDA,EAAW,QAAQ,QAAQ,KAAA,KAAaA,EAAW,QAAQ,QAAQ,KAAA,GAAW;IAElF,IAAMG,IAAWH,EAAW,QAAQ,IAAI,GAClC,EAAE,WAAWrB,MAAW,KAAKS,GAAce,CAAQ,GACnDpB,IAAS,SAASiB,EAAW,QAAQ,KAAK,EAAE;IAElD,AAAIrB,IAAS,MACTmB,MAAkBnB,KAAUoB,MAAYhB,OAE5C,IAAgBJ,GAChB,IAAUI,GAEV,KAAK,SAASL,GAAUI,GAAUH,GAAQI,CAAM;GACjD,GAEMnM,UAAkB;IAKvB,AAJA,KAAKE,GAAO,MAAM,aAAa,IAC/B,KAAKA,GAAO,MAAM,mBAAmB,IAErC,SAAS,oBAAoB,aAAaJ,CAAW,GACrD,SAAS,oBAAoB,WAAWE,CAAS;GAClD;GAGA,AADA,SAAS,iBAAiB,aAAaF,CAAW,GAClD,SAAS,iBAAiB,WAAWE,CAAS;EAC/C,CAAC;CACF;AACD,GC3OawN,IAAb,MAA4B;CAC3B;CACA;CAEA,KAAe;CACf,KAAa;CAEb,YAAY,GAAO;EAIlB,AAHA,KAAKtN,KAAShE,GACd,KAAK1E,KAAQ0E,EAAM,YAAY,CAAC,CAAC,MAEjC,KAAKsP,GAAY;CAClB;CAEA,IAAI,cAAc;EACjB,OAAO,KAAKiC;CACb;CAEA,IAAI,YAAY,GAAM;EACrB,IAAI,CAAChB,GAAM;EAKX,AAHA,KAAKgB,KAAehB,GACpBA,EAAK,MAAM,EAAE,eAAe,GAAK,CAAC,GAElC,KAAKiB,KAAajB,EAAK,QAAQ,IAAI;EACnC,IAAMvE,IAAY,SAAS,KAAKwF,GAAW,QAAQ,WAAW,EAAE;EAEhE,KAAKxN,GAAO,UAAU,SAASgI,GAAW,KAAKuF,GAAa,QAAQ,GAAG;CACxE;CAGA,MAAc,GAAG,MAAS;EAEzB,IAAKhB,GAEL;WAAQ,EAAE,MAAV;IACC,KAAK;KACJ,AAAI,EAAE,WACA,KAAKkB,GAAmBlB,CAAI,KAChCA,EAAK,eAAe;MAAE,QAAQ;MAAW,OAAO;KAAU,CAAC,IAGvD,KAAKmB,GAAoBnB,CAAI,KACjCA,EAAK,eAAe;MAAE,QAAQ;MAAW,OAAO;KAAU,CAAC;KAG7D;IACD,KAAK;KACJ,AAAK,KAAKmB,GAAoBnB,CAAI,KACjCA,EAAK,eAAe;MAAE,QAAQ;MAAW,OAAO;KAAU,CAAC;KAE5D;IACD,KAAK,aACJ,AAAK,KAAKkB,GAAmBlB,CAAI,KAChCA,EAAK,eAAe;KAAE,QAAQ;KAAW,OAAO;IAAU,CAAC;GAG9D;GAGA,AADA,KAAK,cAAcA,GACnB,KAAKvM,GAAO,UAAU,SAAS,KAAKwN,GAAW,QAAQ,WAAWjB,EAAK,QAAQ,KAAK,KAAKiB,GAAW,QAAQ,WAAWjB,EAAK,QAAQ,GAAG;EAHvI;CAID;CAEA,MAAc,GAAG,MAAS;EACzB,IAAIA,GAAM;GACT,IAAIoB,IAAY;GAChB,QAAQ,EAAE,MAAV;IACC,KAAK;KACJ,AAAI,EAAE,UACD,KAAKC,GAAoBrB,CAAI,MAChC,IAAY;KAOd;IACD,KAAK;KACJ,AAAI,KAAKqB,GAAoBrB,CAAI,MAChC,IAAY;KAEb;IACD,KAAK,WACJ,AAAI,KAAKsB,GAAoBtB,CAAI,MAChC,IAAY;GAGf;GAEA,IAAIoB,GAAW;IAEd,AADA,KAAK,cAAcpB,GACnB,KAAKvM,GAAO,UAAU,SAAS,KAAKwN,GAAW,QAAQ,WAAWjB,EAAK,QAAQ,KAAK,KAAKiB,GAAW,QAAQ,WAAWjB,EAAK,QAAQ,GAAG;IACvI;GACD;EACD;EAEA,IAAMnG,IAAY,SAAS,KAAKoH,GAAW,QAAQ,OAAO,EAAE,GACxDM,IAAiB;EACrB,QAAQ,EAAE,MAAV;GACC,KAAK;IACJ,IAAI,EAAE,UAAU;KACf,IAAMpM,IAAkB,KAAKqM,GAAoB;KACjD,IAAiB,KAAK,IAAI3H,IAAY1E,IAAkB,GAAG,CAAC;IAC7D,OACC,IAAiB,KAAK,IAAI0E,GAAW,KAAKpG,GAAO,KAAK,MAAM,CAAC;IAE9D;GACD,KAAK;IACJ,IAAiB,KAAK,IAAIoG,GAAW,KAAKpG,GAAO,KAAK,MAAM,CAAC;IAC7D;GACD,KAAK;IACJ,IAAM0B,IAAkB,KAAKqM,GAAoB;IACjD,IAAiB,KAAK,IAAI3H,IAAY1E,IAAkB,GAAG,CAAC;EAE9D;EAEA,IAAIoM,IAAiB,GAAG;EAExB,IAAI9F,IAAY,SAAS,KAAKwF,GAAW,QAAQ,WAAW,EAAE,GACxD9B,IAAM,SAAS,KAAK6B,GAAa,QAAQ,KAAK,EAAE,GAChDrC,IAAU,SAAS,KAAKqC,GAAa,SAAS,EAAE,KAAK;EAE3D,QAAQ,EAAE,MAAV;GACC,KAAK;IACJ,KAAarC;IACb;GACD,KAAK,WACJ;EAEF;EAEA,KAAKlL,GAAO,WAAW,gBAAgB8N,GAAgB,YAAY;GAClE,IAAME,IAAc,KAAKC,GAAUjG,GAAW0D,CAAG;GAEjD,AAAIsC,MACH,KAAK,cAAcA,GACnB,KAAKhO,GAAO,UAAU,SAAS,KAAKwN,GAAW,QAAQ,WAAWQ,EAAY,QAAQ,KAAK,KAAKR,GAAW,QAAQ,WAAWQ,EAAY,QAAQ,GAAG;EAEvJ,CAAC;CACF;CAEA,YAAY,MAAM;EAcjB,IAZI,EAAE,OAAO,YAAY,YACpB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,OAAO,IAAI,KAC9B;GAAC;GAAY;GAAa;GAAO;EAAK,CAAC,CAAC,SAAS,EAAE,IAAI,KAKxD;GAAC;GAAO;GAAiB;GAAO;GAAO;EAAO,CAAC,CAAC,SAAS,EAAE,OAAO,IAAI,MAKvE,CAAC,KAAKT,MAAgB,CAAC,KAAKC,IAC/B;EAGD,IAAIU;EACJ,QAAQ,EAAE,MAAV;GACC,KAAK;IACJ,IAAW,EAAE,WAAW,KAAKC,GAAiB,IAAI,KAAKC,GAAa;IACpE;GACD,KAAK;IACJ,IAAW,KAAKA,GAAa;IAC7B;GACD,KAAK;IACJ,IAAW,KAAKD,GAAiB;IACjC;GACD,KAAK;IACJ,IAAW,EAAE,WAAW,KAAKE,GAAW,IAAI,KAAKC,GAAa;IAC9D;GACD,KAAK;IACJ,IAAW,KAAKA,GAAa;IAC7B;GACD,KAAK,WACJ,IAAW,KAAKD,GAAW;EAE7B;EAIA,AAFA,EAAE,eAAe,GAEb;GAAC;GAAY;GAAa;EAAK,CAAC,CAAC,SAAS,EAAE,IAAI,IACnD,KAAKE,GAAW,GAAGL,CAAQ,IAEnB;GAAC;GAAQ;GAAU;EAAW,CAAC,CAAC,SAAS,EAAE,IAAI,KACvD,KAAKM,GAAW,GAAGN,CAAQ;CAE7B;CAEA,WAAqB;EACpB,IAAMxC,IAAM,SAAS,KAAK6B,GAAa,QAAQ,KAAK,EAAE,GAChDpC,IAAU,SAAS,KAAKoC,GAAa,SAAS,EAAE,KAAK,GACrDnH,IAAY,SAAS,KAAKoH,GAAW,QAAQ,OAAO,EAAE,GACtDxF,IAAY,SAAS,KAAKwF,GAAW,QAAQ,WAAW,EAAE,GAE1DiB,IAAU/C,IAAMP,GAElB+C,IAAW,KAAKlO,GAAO,cAAc,6BAA6BgI,EAAU,kBAAkByG,EAAQ,GAAG;EAK7G,OAJA,AACCP,MAAW,KAAKlO,GAAO,cAAc,wBAAwBoG,EAAU,kBAAkBqI,EAAQ,GAAG,GAG9FP;CACR;CAEA,WAAyB;EAExB,IAAMxC,IAAM,SAAS,KAAK6B,GAAa,QAAQ,KAAK,EAAE,GAChDnH,IAAY,SAAS,KAAKoH,GAAW,QAAQ,OAAO,EAAE,GACtDxF,IAAY,SAAS,KAAKwF,GAAW,QAAQ,WAAW,EAAE,GAE5DU;EACJ,KAAK,IAAI,IAAIxC,IAAM,GAAG,KAAK,MAC1B,IAAW,KAAK1L,GAAO,cAAc,6BAA6BgI,EAAU,kBAAkB,EAAE,GAAG,GACnG,AACCkG,MAAW,KAAKlO,GAAO,cAAc,wBAAwBoG,EAAU,kBAAkB,EAAE,GAAG,GAG3F,KANyB;EAS9B,OAAO8H;CACR;CAIA,MAAa,GAAW,MAAQ;EAE/B,IAAMvL,IAAM,KAAK3C,GAAO,cAAc,6BAA6BgI,EAAU,GAAG;EAChF,IAAI,CAACrF,GAAK;EAEV,IAAMyD,IAAY,SAASzD,EAAI,QAAQ,OAAO,EAAE,GAE5CuK,IAAa,KAAKlN,GAAO,cAAc,6BAA6BgI,EAAU,kBAAkB0D,EAAI,GAAG;EA2B3G,OA1BKwB,MACJ,KAAKlN,GAAO,iBAAiB,6BAA6BgI,EAAU,MAAM,CAAC,CAAC,SAAQ,MAAS;GAC5F,IAAM0G,IAAU,SAAShM,EAAM,QAAQ,KAAK,EAAE,GACxCyI,IAAU,SAASzI,EAAM,SAAS,EAAE,KAAK;GAE/C,AAAIgJ,KAAOgD,KAAWhD,IAAMgD,IAAUvD,MACrC,IAAazI;EAEf,CAAC,GAEIwK,MACJ,IAAa,KAAKlN,GAAO,cAAc,wBAAwBoG,EAAU,kBAAkBsF,EAAI,GAAG,GAE7FwB,KACJ,KAAKlN,GAAO,iBAAiB,wBAAwBoG,EAAU,MAAM,CAAC,CAAC,SAAQ,MAAS;GACvF,IAAMsI,IAAU,SAAShM,EAAM,QAAQ,KAAK,EAAE,GACxCyI,IAAU,SAASzI,EAAM,SAAS,EAAE,KAAK;GAE/C,AAAIgJ,KAAOgD,KAAWhD,IAAMgD,IAAUvD,MACrC,IAAazI;EAEf,CAAC,KAKGwK;CACR;CAEA,WAAmB;EAClB,IAAMxB,IAAM,SAAS,KAAK6B,GAAa,QAAQ,KAAK,EAAE,GAChDvF,IAAY,SAAS,KAAKwF,GAAW,QAAQ,WAAW,EAAE;EAEhE,OAAO,KAAKS,GAAUjG,IAAY,GAAG0D,CAAG;CACzC;CAEA,WAAqB;EACpB,IAAMA,IAAM,SAAS,KAAK6B,GAAa,QAAQ,KAAK,EAAE,GAChDvF,IAAY,SAAS,KAAKwF,GAAW,QAAQ,WAAW,EAAE,GAC1DtC,IAAU,SAAS,KAAKqC,GAAa,SAAS,EAAE,KAAK;EAE3D,OAAO,KAAKU,GAAUjG,IAAYkD,GAASQ,CAAG;CAC/C;CAGA,MAAuB,MAAS;EAC/B,IAAM3G,IAAe,KAAK/E,GAAO,cAAc,gBAAgB;EAC/D,IAAI,CAAC+E,KAAgB,CAACwH,GAAM,OAAO;EAEnC,IAAMoC,IAAWpC,EAAK,sBAAsB,GACtCqC,IAAe7J,EAAa,sBAAsB,GAClD8J,IAAc9J,EAAa,cAAc,OAAO,CAAC,EAAE,gBAAgB;EAGzE,OAAO4J,EAAS,OAAQC,EAAa,MAAMC;CAC5C;CAGA,MAAuB,MAAS;EAC/B,IAAM9J,IAAe,KAAK/E,GAAO,cAAc,gBAAgB;EAC/D,IAAI,CAAC+E,KAAgB,CAACwH,GAAM,OAAO;EAEnC,IAAMoC,IAAWpC,EAAK,sBAAsB,GACtCqC,IAAe7J,EAAa,sBAAsB;EAGxD,OAAO4J,EAAS,UAAUC,EAAa;CACxC;CAGA,MAAsB,MAAS;EAC9B,IAAME,IAAgB,KAAK9O,GAAO,cAAc,oBAAoB;EACpE,IAAI,CAAC8O,KAAiB,CAACvC,GAAM,OAAO;EAEpC,IAAMoC,IAAWpC,EAAK,sBAAsB,GACtCqC,IAAeE,EAAc,sBAAsB;EAGzD,OAAOH,EAAS,QAAQC,EAAa;CACtC;CAGA,MAAuB,MAAS;EAC/B,IAAME,IAAgB,KAAK9O,GAAO,cAAc,oBAAoB;EACpE,IAAI,CAAC8O,KAAiB,CAACvC,GAAM,OAAO;EAEpC,IAAMoC,IAAWpC,EAAK,sBAAsB,GACtCqC,IAAeE,EAAc,sBAAsB;EAGzD,OAAOH,EAAS,SAASC,EAAa;CACvC;CAUA,WAA4B;EAC3B,IAAM7J,IAAe,KAAK/E,GAAO,cAAc,gBAAgB,GACzD+O,IAAiBhK,EAAa,gBAAgBA,EAAa,cAAc,OAAO,CAAC,EAAE,gBAAgB,IACnGtD,IAAY,KAAKzB,GAAO,WAAW,aAAa;EAGtD,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM+O,IAAiBtN,CAAS,CAAC;CAC1D;CAEA,KAAc;EASb,AARA,KAAKzB,GAAO,iBAAiB,cAAc,MAAM;GAChD,IAAI,EAAE,WAAW,GAAG;GACpB,IAAMuM,IAAO,EAAE,OAAO,QAAQ,QAAQ;GACtC,AAAKA,KACDA,EAAK,QAAQ,UAAU,KAAA,KAAaA,EAAK,QAAQ,QAAQ,KAAA,MAC7D,KAAK,cAAcA;EACpB,CAAC,GAED,KAAKvM,GAAO,iBAAiB,YAAY,MAAM;GAC9C,AAAI;IAAC;IAAS;IAAO;IAAW;IAAa;IAAa;GAAY,CAAC,CAAC,SAAS,EAAE,IAAI,KACtF,KAAK,SAAS,CAAC;EAEjB,CAAC;CACF;AACD,GCxWMgP,IAAgB,GAETC,IAAb,MAAwB;CACpB;CACA;CACA;CACA;CAEA,KAAkB;CAClB,KAAgB;CAChB,KAAuB;CACvB,KAAc;CACd,KAAU;CACV,KAAiB;CACjB,KAAqB;CACrB,KAAkB;CAClB,KAAa;CAEb,YAAY,GAAO;EAMf,AALA,KAAKjP,KAAShE,GACd,KAAK1E,KAAQ0E,EAAM,YAAY,CAAC,CAAC,MACjC,KAAKkT,KAAS,KAAKlP,GAAO,cAAc,8BAA8B,GAEtE,KAAKmP,KAAW,KAAKD,GAAO,cAAc,kBAAkB,GAC5D,KAAK,WAAW;CACpB;CAEA,UAAU;EAGN,AAFA,KAAKlP,GAAO,oBAAoB,eAAe,KAAKoP,EAAc,GAClE,KAAKpP,GAAO,oBAAoB,eAAe,KAAKqP,EAAc,GAClE,KAAKrP,GAAO,oBAAoB,YAAY,KAAKsP,EAAW;CAChE;CAEA,cAAc,IAAgB,QAAQ;EAClC,IAAMnD,IAAa,MAAM,KAAK,KAAKnM,GAAO,iBAAiB,iBAAiBuP,GAAe,CAAC;EAC5F,IAAIpD,EAAW,WAAW,GAQ1B;OANyBoD,MAAkB,UAAUA,MAAkB,WAEnE,MAAKvP,GAAO,gBACZmM,EAAW,EAAE,CAAC,cAAc,OAAO,CAAC,EAAE,aAAa,cAAc,MAAM,QAG3D;IAEZ,IAAMqD,IAAgBrD,EAAW,EAAE,CAAC,cAAc,gBAAgB;IAClE,IAAI,CAACqD,GAAe;IAEpB,IAAIC,IAAa,GACXC,IAAY,CAAC;IAWnB,AATA,MAAM,KAAKF,EAAc,iBAAiB,KAAK,CAAC,CAAC,CAAC,SAAQ,MAAO;KAC7D,IAAMG,IAASjE,EAAI,aAAa,UAAU,GACpCnV,IAAI,SAASmV,EAAI,aAAa,OAAO,GAAG,EAAE;KAChD,AAAK,MAAMnV,CAAC,MACR,EAAUoZ,KAAUpZ,GACpB,KAAcA;IAEtB,CAAC,GAED4V,EAAW,SAAQ,MAAa;KAC5B,IAAMyD,IAASvI,EAAU,iBAAiB,OAAO;KAEjD,AAAIkI,MAAkB,SAClBK,EAAO,SAAQ,MAAO;MAClB,EAAI,MAAM,QAAQ,GAAGH,EAAW;KAEpC,CAAC,KAED,EAAU,MAAM,OAAO,OAAOA,EAAW,KACzC,EAAU,MAAM,QAAQ,GAAGA,EAAW,KACtC,EAAU,MAAM,WAAW,GAAGA,EAAW,KACzC,EAAU,MAAM,WAAW,GAAGA,EAAW,KAEzCG,EAAO,SAAQ,MAAO;MAKlB,AAJA,EAAI,MAAM,QAAQ,GAAGH,EAAW,KAChC,EAAI,MAAM,WAAW,GAAGA,EAAW,KACnC,EAAI,MAAM,WAAW,GAAGA,EAAW,KAEnC,OAAO,QAAQC,CAAS,CAAC,CAAC,SAAS,CAACC,GAAQpZ,OAAO;OAC/C,EAAI,iBAAiB,gBAAgBoZ,EAAO,mBAAmBA,EAAO,GAAG,CAAC,CAAC,SAAQ,MAAQ;QAGvF,AAFA,EAAK,MAAM,QAAQ,GAAGpZ,EAAE,KACxB,EAAK,MAAM,WAAW,GAAGA,EAAE,KAC3B,EAAK,MAAM,WAAW,GAAGA,EAAE;OAC/B,CAAC;MACL,CAAC;KACL,CAAC;IAET,CAAC;GACL,OACI,EAAW,SAAQ,MAAa;IAE5B,EADyB,iBAAiB,OACrC,CAAC,CAAC,SAAQ,MAAO,CAItB,CAAC;GACL,CAAC;GAGL,KAAKyJ,GAAO,cAAc,uBAAuB,CAAC,EAAE,QAAQ;EAHvD;CAIT;CAEA,eAAe,GAAgB,GAAO,IAAgB,MAAM;EAExD,IAAI6P,IAAa,CAAC;EAIlB,IAFA,IAAa,MAAM,KAAK,KAAK7P,GAAO,iBAAiB,gCAAgC8P,EAAe,GAAG,CAAC,GAEpGD,EAAW,WAAW,GAAG;EAE7B,IAAME,IAAiBF,EAAW,EAAE,CAAC,QAAQ,6DAA6D,GACpGG,IAAwBT,MAC1BQ,GAAgB,UAAU,SAAS,mBAAmB,IAAI,SACtDA,GAAgB,UAAU,SAAS,oBAAoB,IAAI,UAAU;EAG7E,EAAW,SAAQ,MAAO;GAEtB,AADArE,EAAI,aAAa,SAASuE,CAAK,GAC/B,EAAI,MAAM,QAAQ,GAAGA,EAAM;EAC/B,CAAC;EAED,IAAMC,IAAY,KAAKlQ,GAAO,aAAa,cAAc,0BAA0B8P,EAAe,GAAG;EAYrG,AAXII,MACAA,EAAU,aAAa,SAASD,CAAK,GACrC,EAAU,MAAM,QAAQ,GAAGA,EAAM,MAGrC,KAAK,cAAcD,CAAqB,IAEpCA,MAA0B,UAAUA,MAA0B,YAC9D,KAAK,cAAc,MAAM,GAG7B,KAAKhQ,GAAO,YAAY,QAAQ;CACpC;CAEA,GAAgB,GAAY;EACxB,IAAI,KAAKA,GAAO,cAAc,OAAO;EACrC,IAAMpD,IAAQsQ,GAAY,QAAQ,OAAO;EAEzC,OADA,GAAItQ,KAASA,EAAM,aAAa,cAAc,MAAM;CAExD;CAEA,aAAa;EAKT,AAJA,KAAKoD,GAAO,iBAAiB,eAAe,KAAKoP,EAAc,GAI/D,KAAKpP,GAAO,yBAAyB,YAAY,KAAKsP,IAAa,eAAe,KAAKD,EAAc;CACzG;CAEA,GAAkB,GAAM;EACpB,IAAMhI,IAAYkF,EAAK,QAAQ,6DAA6D;EAI5F,OAHKlF,IACDA,EAAU,UAAU,SAAS,mBAAmB,IAAU,SAC1DA,EAAU,UAAU,SAAS,oBAAoB,IAAU,UACxD,SAHgB;CAI3B;CAEA,MAAkB,MAAM;EAGpB,IAAM8I,IAAa,EAAE,OAAO,QAAQ,OAAO;EAC3C,IAAI,CAACA,GAAY;EAEjB,IAAM5D,IAAO,EAAE,OAAO,QAAQ,QAAQ;EAOtC,IALA4D,EAAW,iBAAiB,iBAAiB,CAAC,CAAC,SAAQ,MAAM;GACzD,AAAI1a,MAAO8W,KAAM9W,EAAG,UAAU,OAAO,gBAAgB;EACzD,CAAC,GAEG,CAAC8W,KAAQA,EAAK,QAAQ,QAAQ,KAAA,KAC9BA,EAAK,aAAa,WAAW,MAAM,QAAQ;EAE/C,IAAMa,IAAOb,EAAK,sBAAsB,GAClC6D,IAAU,EAAE,UAAUhD,EAAK,MAC3BiD,IAAaD,KAAWpB,GACxBsB,IAAelD,EAAK,QAAQgD,KAAYpB;EAE9C,IAAIqB,GAAY;GACZ,IAAME,IAAWhE,EAAK;GACtB,IAAI,CAACgE,KAAYA,EAAS,aAAa,WAAW,MAAM,QAAQ;IAC5D,EAAK,UAAU,OAAO,gBAAgB;IACtC;GACJ;EACJ;EAEA,AAAIF,KAAcC,IACd/D,EAAK,UAAU,IAAI,gBAAgB,IAEnCA,EAAK,UAAU,OAAO,gBAAgB;CAE9C;CAEA,MAAkB,MAAM;EAGpB,IAAI,CADe,EAAE,aAAa,QAAQ,OAC5B,GAAG;EAEjB,IAAMA,IAAO,EAAE,aAAa,QAAQ,QAAQ;EAE5C,IAAI,CAACA,KAAQ,CAACA,EAAK,UAAU,SAAS,gBAAgB,GAAG;EAIzD,EAAE,eAAe;EACjB,IAAMa,IAAOb,EAAK,sBAAsB,GAClC6D,IAAU,EAAE,UAAUhD,EAAK,MAE7BF,IAAaX;EAEjB,IAAI6D,KAAWpB,GAAe;GAC1B,IAAMuB,IAAWhE,EAAK;GACtB,IAAIgE,KAAYA,EAAS,QAAQ,QAAQ,KAAA,KAAaA,EAAS,aAAa,WAAW,MAAM,QACzF,IAAaA;QACV,IAAI,CAAChE,EAAK,wBACb;EAER;EAGA,AADA,KAAKiE,KAActD,GACnB,KAAKuD,KAAuB,KAAKC,GAAkBxD,CAAU;EAE7D,IAAM7F,IAAY,KAAKrH,GAAO,cAAc,iBAAiB,KAAKyQ,IAAsB;EACxF,IAAI,CAACpJ,GAAW;EAEhB,IAAMsJ,IAAe,SAASzD,EAAW,QAAQ,KAAK,EAAE,GAClD/B,IAAU+B,EAAW,WAAW;EAItC,IAHA,KAAK0D,KAAkBD,IAAexF,IAAU,GAE9B,KAAK0F,GAAgB3D,CAC3B,GAAG;GACX,KAAK4D,KAAgB,KAAKF,KAAkB;GAC5C,IAAMG,IAAY1J,EAAU,cAAc,iBAAiB,KAAKyJ,GAAc,GAAG;GACjF,AAAIC,IACA,KAAKC,KAAqB,SAASD,EAAU,aAAa,OAAO,GAAG,EAAE,KAAK,MAE3E,KAAKD,KAAgB;EAE7B,OACI,KAAKA,KAAgB;EAGzB,IAAMG,IAAa/D,EAAW,sBAAsB,GAC9CgE,IAAY,KAAKlR,GAAO,sBAAsB;EAGpD,AADA,KAAKmR,KAAkBF,EAAW,OAClC,KAAKG,KAAaH,EAAW,OAAOC,EAAU;EAG9C,IAAMG,IADchK,EAAU,cAAc,iBAAiB,KAAKuJ,GAAgB,GAC1D,CAAC,EAAE,aAAa,OAAO;EAW/C,AAVA,KAAKU,KAAkBD,KAAS,CAAC,MAAM,SAASA,GAAO,EAAE,CAAC,IAAK,SAASA,GAAO,EAAE,IAAIJ,EAAW,QAAQ9F,GAExG,KAAKoG,KAAU,EAAE,SAEb,KAAKrC,OACL,KAAKA,GAAO,UAAU,IAAI,QAAQ,GAClC,KAAKsC,GAAiB,EAAE,OAAO,IAGnC,OAAO,iBAAiB,eAAe,KAAKC,EAAW,GACvD,OAAO,iBAAiB,aAAa,KAAKC,IAAY,EAAE,MAAM,GAAK,CAAC;CACxE;CAEA,GAAiB,GAAS;EACtB,IAAIC,IAAOC,IAAU,KAAKL,IACpBM,IAAY,KAAKhB,GAAgB,KAAKL,EAAW;EAEvD,IAAIqB,KAAa,KAAKf,OAAkB,MAAM;GAC1C,IAAMgB,IAAU,KAAKd,KAAA,IACfe,IAAU,EAAE,KAAKT,KAAA;GACvB,IAAO,KAAK,IAAIS,GAAS,KAAK,IAAIJ,GAAMG,CAAO,CAAC;EACpD;EAEA,IAAME,IAAkB,KAAK,IAAA,IAAqB,KAAKV,KAAiBK,CAAI,GAGxEM,IAAgBL,IADD,KAAKpB,GAAY,sBACG,CAAC,CAAC;EAEzC,IAAIqB,KAAa,KAAKf,OAAkB,MAAM;GAC1C,IAAMoB,IAAe,KAAKf,MAAmB,KAAKH,KAAA;GAClD,IAAgB,KAAK,IAAIiB,GAAeC,CAAY;EACxD;EAEA,IAAMC,IAAmB,KAAK,IAAA,IAAqBF,CAAa;EAEhE,AAAI,KAAK/C,OACL,KAAKA,GAAO,MAAM,YAAY,8BAA8B,GAAG,KAAKkC,GAAW,GAAG,GAClF,KAAKlC,GAAO,MAAM,YAAY,+BAA+B,GAAGiD,EAAiB,GAAG;EAGxF,IAAMC,IAAY,KAAKjD,IAAU,cAAc,aAAa;EAC5D,AAAIiD,MACA,EAAU,cAAc,GAAG,KAAK,MAAMJ,CAAe,EAAE;CAE/D;CAEA,MAAe,MAAM;EACjB,KAAKR,GAAiB,EAAE,OAAO;CACnC;CAEA,MAAc,MAAM;EAChB,OAAO,oBAAoB,eAAe,KAAKC,EAAW;EAE1D,IAAME,IAAO,EAAE,UAAU,KAAKJ,IACxBM,IAAY,KAAKhB,GAAgB,KAAKL,EAAW,GACnD6B,IAAa;EAEjB,IAAIR,KAAa,KAAKf,OAAkB,MAAM;GAC1C,IAAIwB,IAAc,KAAK,IAAA,IAAqB,KAAKhB,KAAiBK,CAAI,GAClEY,IAAe,KAAKjB,KAAiB,KAAKN,KAAqBsB;GASnE,AAPIC,IAAA,OACA,IAAA,IACA,IAAc,KAAKjB,KAAiB,KAAKN,KAAA,KAG7C,KAAK,eAAe,KAAKJ,IAAiB0B,GAAa,KAAK7B,EAAoB,GAChF,KAAK,eAAe,KAAKK,IAAeyB,GAAc,KAAK9B,EAAoB,GAC/E,IAAa6B;EACjB,OAAO;GACH,IAAMA,IAAc,KAAK,IAAA,IAAqB,KAAKhB,KAAiBK,CAAI;GACxE,AAAI,KAAKf,OAAoB,QAAQ,KAAKH,OACtC,KAAK,eAAe,KAAKG,IAAiB0B,GAAa,KAAK7B,EAAoB,GAChF,IAAa6B;EAErB;EAEA,IAAI,KAAK9B,IAAa;GAClB,IAAMtD,IAAa,KAAKsD;GACxB,AAAItD,EAAW,aAAa,WAAW,MAAM,UAAUmF,IAAa,OAChE,EAAW,QAAQ,cAAc,OAAOA,CAAU;EAE1D;EAaA,AAXI,KAAKnD,OACL,KAAKC,IAAU,UAAU,IAAI,UAAU,GACvC,iBAAiB;GAEb,AADA,KAAKD,GAAO,UAAU,OAAO,QAAQ,GACrC,KAAKC,IAAU,UAAU,OAAO,UAAU;EAC9C,GAAG,GAAG,IAGV,KAAKyB,KAAkB,MACvB,KAAKE,KAAgB,MACrB,KAAKL,KAAuB,MAC5B,KAAKD,KAAc;CACvB;CAEA,MAAe,MAAM;EAGjB,IAAIjE,IADa,EAAE,OACC,QAAQ,QAAQ;EACpC,IAAI,CAACA,KAAQ,CAACA,EAAK,UAAU,SAAS,gBAAgB,GAAG;EAEzD,IAAMa,IAAOb,EAAK,sBAAsB;EAGxC,AAFgB,EAAE,UAAUa,EAAK,QAElB4B,MACX,IAAOzC,EAAK;EAGhB,IAAMoE,IAAe,SAASpE,EAAK,QAAQ,KAAK,EAAE,GAC5CiG,IAAY,KAAKxS,GAAO,cAAc,yBAAyB2Q,EAAa,GAAG;EACrF,IAAI,CAAC6B,KAAa,CAACA,EAAU,QAAQ,QAAQA,EAAU,UAAU,SAAS,YAAY,GAAG;EAEzF,IAAIC,IAAe;EACnB,MAAM,KAAKD,EAAU,kBAAkB,QAAQ,CAAC,CAAC,SAAS,MAAQ;GAC9D,QAAQnK,EAAI,SAAZ;IACI,KAAK;KAAQ,KAAgB;KAAG;IAChC,KAAK;KAAO,KAAgB;KAAG;IAC/B,KAAK;KAAU,KAAgB;KAAI;IACnC,KAAK;KAAU,KAAgB;KAAI;IACnC,KAAK,SACD,SAASA,EAAI,QAAQ,OAAA,CAAQ,YAAY,GAAzC;KAEI,KAAK;KACL,KAAK;MACD,KAAgB;MAChB;KAGJ,KAAK;KACL,KAAK;KACL,KAAK;KACL,KAAK;MACD,KAAgB;MAChB;KAGJ,KAAK;KACL,KAAK;KACL,KAAK;MACD,KAAgB;MAChB;KAGJ,KAAK;MACD,KAAgB;MAChB;KAeJ,SACI,KAAgB;IAExB;GAER;EACJ,CAAC;EAED,IAAMqK,IAAW,KAAKpb,GAAM,OAAO,IAAI,CAAC,CAAC,QAAQkb,EAAU,QAAQ,IAAI,GAGjEG,IADgB,OAAO,iBAAiBH,CACrB,CAAC,CAAC,QAAQ,mBAE7BI,IAAarG,EAAK,aAAa,IAEjCsG,KADe,KAAK,gBAAgBD,GAAYD,CACvB,CAAC,CAAC,SAAS,KAAK;EAE7C,KAAKrb,GAAM,cAAc;GAErB,KAAK0I,GAAO,KAAK,SAAS,CAAC,CAAC,SAAS,GAAQ,MAAQ;IACjD,IAAM8S,IAAM,OAAON,EAAU,QAAQ,OAAO,KAAKlb,GAAM,WAAW,SAASkb,EAAU,QAAQ,MAAMpO,GAAQrM,CAAG,IAAIqM,EAAO,EAAEsO,MAAa,EAAE,CAAC,CAAC,KAAK,GAC3IK,IAAO,KAAK,gBAAgBD,GAAKH,CAAI;IAC3C,AAAII,EAAK,SAASA,EAAK,QAAQF,MAC3B,IAAeE,EAAK;GAE5B,CAAC;GAED,IAAMC,IAAkB,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,KAAKH,CAAY,IAAIJ,CAAY,CAAC;GAE1F,KAAK,eAAeD,EAAU,QAAQ,KAAKQ,GAAiB,KAAKtC,GAAkBnE,CAAI,CAAC;EAC5F,CAAC;CACL;AACJ,GAGa0G,IAAb,cAAqC,YAAY;CAG7C,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAEhB,KAAKC,GAAU;CACnB;CAEA,WAAkB;EACd,KAAK,YAAY;CAKrB;AACJ;AAEK,eAAe,IAAI,8BAA8B,KAClD,eAAe,OAAO,gCAAgCD,CAAe;;ACzdzE,IAAaE,IAAb,MAAsB;CAClB;CACA;CACA;CAEA,KAAc;CACd,KAAc;CACd,KAAkB;CAClB,KAAkB;CAClB,KAAU;CACV,KAAS;CAET,YAAY,GAAO;EAIf,AAHA,KAAKnT,KAAShE,GACd,KAAKoX,KAAQ,KAAKpT,GAAO,cAAc,oBAAoB,GAC3D,KAAKqT,KAAQ,KAAKrT,GAAO,cAAc,oBAAoB,GAC3D,KAAK,WAAW;CACpB;CAEA,aAAa;EACT,KAAKA,GAAO,iBAAiB,eAAe,KAAKqP,EAAc;CACnE;CAEA,KAAkB;EACd,IAAM9X,IAAO,KAAKyI,GAAO,YAAY,CAAC,EAAE;EACxC,OAAO,KAAKA,GAAO,aAAa,aAAa,MAAM,UAAUzI,GAAM,aAAa,aAAa,MAAM;CACvG;CAEA,GAAyB,GAAG,GAAG;EAC3B,IAAM+b,IAAO,KAAKtT,GAAO,YAAY,GACjCvK,IAAK6d,EAAK,mBAAmBA,EAAK,iBAAiBtU,GAAGuU,CAAC,IAAI,SAAS,iBAAiBvU,GAAGuU,CAAC;EAE7F,OAAO9d,KAAMA,EAAG,cAAcA,EAAG,WAAW,mBAAkB;GAC1D,IAAM+d,IAAS/d,EAAG,WAAW,iBAAiBuJ,GAAGuU,CAAC;GAClD,IAAI,CAACC,KAAUA,MAAW/d,GAAI;GAC9B,IAAK+d;EACT;EAEA,OAAO/d;CACX;CAEA,GAAkB,GAAM;EACpB,IAAI,CAAC8W,KAAQA,EAAK,QAAQ,QAAQ,KAAA,GAAW,OAAO;EAEpD,IAAMP,IAAW,SAASO,EAAK,QAAQ,KAAK,EAAE,GACxCpB,IAAUoB,EAAK,WAAW,GAC1BN,IAASD,IAAWb,IAAU,GAC9BlT,IAAWsU,EAAK,QAAQ,IAAI,CAAC,EAAE,mBAAmB,GAElD3P,IAAQ2P,EAAK,QAAQ,OAAO;EAClC,IAAI,CAAC3P,GAAO,OAAO;GAAE;GAAU;GAAS;GAAQ;GAAU,SAAS;GAAO,kBAAkB;GAAM,cAAc;EAAK;EAErH,IAAM6W,IAAc7W,EAAM,iBAAiB,oBAAoB,GAC3D8W,IAAoB,IACpBC,IAAe,IACfC,IAAmB;EAEvB,KAAK,IAAMC,KAAWJ,GAAa;GAC/B,IAAII,MAAYtH,KAAQsH,EAAQ,QAAQ,QAAQ,KAAA,GAAW;GAE3D,IAAMC,IAAW,SAASD,EAAQ,QAAQ,KAAK,EAAE,GAC3CE,IAAUF,EAAQ,WAAW,GAC7BG,IAASF,IAAWC,IAAU;GAapC,CAZoBF,EAAQ,QAAQ,IAAI,CAAC,EAAE,mBAAmB,KAE5C5b,KAAY6b,KAAY9H,KAAYgI,KAAU/H,KAAU8H,IAAU5I,MAC3EyI,KAGD,EAAiB,WAAW,KAAK,IAAIA,EAAiB,UAAUE,CAAQ,GACxE,EAAiB,SAAS,KAAK,IAAIF,EAAiB,QAAQI,CAAM,KAHlE,IAAmB;IAAE,UAAUF;IAAU,QAAQE;GAAO,IAO5CA,IAAShI,KAAY8H,IAAW7H,MAEtB6H,KAAY9H,KAAYgI,KAAU/H,IAGpD8H,IAAU5I,MACV,IAAoB,OAEjB2I,IAAW9H,KAAYgI,IAAS/H,OACjC6H,KAAY9H,KAAYgI,KAAU/H,MACpC,IAAe;EAI/B;EAEA,IAAMgI,IAAcP,KAAqBC;EAEzC,OAAO;GACH;GACA,SAASM,IAAc9I,IAAU;GACjC,QAAQ8I,IAAchI,IAASD;GAC/B;GACA,SAASiI;GACT;GACA;EACJ;CACJ;CAEA,GAA0B,GAAM;EAC5B,IAAMC,IAAa,KAAKC,GAAkB5H,CAAI;EAC9C,IAAI,CAAC2H,GAAY,OAAO;EAExB,IAAM,EAAE,aAAU,WAAQ,eAAYA,GAGhCE,IAAY7H,EAAK,QAAQ,OAAO;EACtC,IAAI,CAAC6H,GAAW,OAAO;EAEvB,IAAIC,IAAU,UAAUC,IAAW,WAAWC,IAAS,UAAUC,IAAY,WACvEC,IAAc,CAAC;EAwBrB,IAtBAL,EAAU,iBAAiB,oBAAoB,CAAC,CAAC,SAAQ,MAAK;GAC1D,IAAIhJ,EAAE,QAAQ,QAAQ,KAAA,GAAW;GACjC,IAAMsJ,IAAO,SAAStJ,EAAE,QAAQ,KAAK,EAAE,GAEjCuJ,IAAOD,KADCtJ,EAAE,WAAW,KACC;GAM5B,IAJiBwJ,IACVF,KAAQ1I,KAAY2I,KAAQ1I,IAC5Bb,MAAMmB,GAEC;IACV,IAAMa,IAAOhC,EAAE,sBAAsB;IAIrC,AAHA,IAAU,KAAK,IAAIiJ,GAASjH,EAAK,IAAI,GACrC,IAAW,KAAK,IAAIkH,GAAUlH,EAAK,KAAK,GACxC,IAAS,KAAK,IAAImH,GAAQnH,EAAK,GAAG,GAClC,IAAY,KAAK,IAAIoH,GAAWpH,EAAK,MAAM;IAE3C,IAAMyH,IAAgB,OAAO,iBAAiBzJ,CAAC;IAC/C,EAAY,KAAK;KAAE,IAAIA;KAAG;KAAM,OAAOyJ;IAAc,CAAC;GAC1D;EACJ,CAAC,GAEGJ,EAAY,WAAW,GAAG,OAAO;EAErC,IAAMK,IAAaR,IAAWD,GACxBU,IAAcP,IAAYD,GAE1BS,IAAgB,SAAS,cAAc,KAAK;EAwClD,OAvCA,EAAc,YAAY,uBAC1B,EAAc,MAAM,WAAW,YAC/B,EAAc,MAAM,QAAQ,GAAGF,EAAW,KAC1C,EAAc,MAAM,SAAS,GAAGC,EAAY,KAE5CN,EAAY,SAAS,EAAE,OAAI,SAAM,eAAY;GACzC,IAAMQ,IAAaxf,EAAG,UAAU,EAAI;GA8BpC,AA5BA,EAAW,MAAM,WAAW,YAC5B,EAAW,MAAM,OAAO,GAAG2X,EAAK,OAAOiH,EAAQ,KAC/C,EAAW,MAAM,MAAM,GAAGjH,EAAK,MAAMmH,EAAO,KAE5C,EAAW,MAAM,QAAQ,GAAGnH,EAAK,MAAM,KACvC,EAAW,MAAM,WAAW,GAAGA,EAAK,MAAM,KAC1C,EAAW,MAAM,WAAW,QAE5B,EAAW,MAAM,SAAS,GAAGA,EAAK,OAAO,KACzC,EAAW,MAAM,YAAY,cAC7B,EAAW,MAAM,SAAS,KAE1B,EAAW,MAAM,kBAAkB8H,EAAM,oBAAoB,iBAAiBA,EAAM,oBAAoB,qBAClGA,EAAM,kBACN,WACN,EAAW,MAAM,QAAQA,EAAM,OAC/B,EAAW,MAAM,OAAOA,EAAM,MAC9B,EAAW,MAAM,aAAaA,EAAM,YACpC,EAAW,MAAM,WAAWA,EAAM,UAClC,EAAW,MAAM,YAAYA,EAAM,WACnC,EAAW,MAAM,UAAUA,EAAM,SACjC,EAAW,MAAM,SAASA,EAAM,QAChC,EAAW,MAAM,cAAcA,EAAM,aACrC,EAAW,MAAM,eAAeA,EAAM,cACtC,EAAW,MAAM,UAAU,QAC3B,EAAW,MAAM,aAAa,UAC9B,EAAW,MAAM,iBAAiBA,EAAM,cAAc,WAAW,WAAYA,EAAM,cAAc,UAAU,aAAa,cAExHF,EAAc,YAAYC,CAAU;EACxC,CAAC,GAEM;GACH,SAASD;GACT,QAAQ;IACJ,MAAMX;IACN,OAAOC;IACP,KAAKC;IACL,QAAQC;IACR,OAAOM;IACP,QAAQC;GACZ;EACJ;CACJ;CAEA,MAAkB,MAAM;EAIpB,IAHI,CAAC,KAAKI,GAAgB,KAGtB,CADe,EAAE,OAAO,QAAQ,kBACtB,GAAG;EAEjB,IAAM5I,IAAO,EAAE,OAAO,QAAQ,QAAQ;EAEtC,IADI,CAACA,KAAQA,EAAK,UAAU,SAAS,gBAAgB,KAAK,CAAC,SAAS,QAAQ,CAAC,CAAC,SAAS,EAAE,OAAO,OAAO,KACnGA,EAAK,QAAQ,QAAQ,KAAA,GAAW;EAEpC,EAAE,eAAe;EAEjB,IAAM6I,IAAS,EAAE,SACXC,IAAS,EAAE,SAEXC,UAAoB;GAOtB,AANA,AAEI,KAAKC,QADL,aAAa,KAAKA,EAAM,GACV,OAElB,OAAO,oBAAoB,eAAeC,CAAoB,GAC9D,OAAO,oBAAoB,aAAaF,CAAW,GACnD,OAAO,oBAAoB,iBAAiBA,CAAW;EAC3D,GAEME,KAAwB,MAAc;GAExC,AADa,KAAK,MAAM3V,EAAU,UAAUuV,GAAQvV,EAAU,UAAUwV,CACjE,IAAI,KACPC,EAAY;EAEpB;EASA,AAPA,KAAKC,KAAS,iBAAiB;GAE3B,AADAD,EAAY,GACZ,KAAKG,GAAW,GAAGlJ,CAAI;EAC3B,GAAG,GAAG,GAEN,OAAO,iBAAiB,eAAeiJ,CAAoB,GAC3D,OAAO,iBAAiB,aAAaF,GAAa,EAAE,MAAM,GAAK,CAAC,GAChE,OAAO,iBAAiB,iBAAiBA,GAAa,EAAE,MAAM,GAAK,CAAC;CACxE;CAEA,GAAW,GAAG,GAAM;EAChB,IAAI,KAAKI,IAAa;EAEtB,IAAMC,IAAU,KAAKC,GAA0BrJ,CAAI;EACnD,IAAI,CAACoJ,GAAS;EAId,AAFA,KAAKD,KAAc,IACnB,KAAKG,KAActJ,GACnB,KAAKuJ,KAAkB,SAASvJ,EAAK,QAAQ,KAAK,EAAE;EAEpD,IAAM2E,IAAY,KAAKlR,GAAO,sBAAsB,GAC9C,EAAE,WAAQ,eAAY2V;EAI5B,IAFA,KAAKI,KAAU,EAAE,UAAUC,EAAO,MAE9B,KAAK5C,IAAO;GACZ,KAAKA,GAAM,gBAAgB1V,CAAO;GAElC,IAAMuY,IAAcD,EAAO,MAAM9E,EAAU,KACrCgF,IAAahF,EAAU,SAAS+E;GAOtC,AALA,KAAK7C,GAAM,MAAM,QAAQ,GAAG4C,EAAO,MAAM,KACzC,KAAK5C,GAAM,MAAM,SAAS,GAAG8C,EAAW,KACxC,KAAK9C,GAAM,MAAM,MAAM,GAAG6C,EAAY,KACtC,KAAK7C,GAAM,MAAM,UAAU,SAE3B,KAAK+C,GAAoB,EAAE,OAAO;EACtC;EAKA,AAHA,SAAS,KAAK,MAAM,SAAS,QAE7B,OAAO,iBAAiB,eAAe,KAAK/G,EAAc,GAC1D,OAAO,iBAAiB,aAAa,KAAKgH,IAAc,EAAE,MAAM,GAAK,CAAC;CAC1E;CAEA,MAAkB,MAAM;EACpB,IAAI,CAAC,KAAKV,IAAa;EAKvB,AAHA,KAAKS,GAAoB,EAAE,OAAO,GAE9B,KAAK/C,OAAO,KAAKA,GAAM,MAAM,gBAAgB,SAC7C,KAAKC,OAAO,KAAKA,GAAM,MAAM,gBAAgB;EAGjD,IAAMnG,IADgB,KAAKmJ,GAAyB,EAAE,SAAS,EAAE,OAClC,CAAC,EAAE,QAAQ,0CAA0C;EAEpF,IAAInJ,KAAcA,EAAW,QAAQ,QAAQ,KAAA,GAAW;GACpD,IAAMoJ,IAAiB,SAASpJ,EAAW,QAAQ,KAAK,EAAE,GACpDgE,IAAY,KAAKlR,GAAO,sBAAsB,GAC9CpD,IAAQsQ,EAAW,QAAQ,OAAO,GAEpCqJ,IAAa,UACbC,IAAc;GAiBlB,IAfI5Z,KACAA,EAAM,iBAAiB,oBAAoB,CAAC,CAAC,SAAQ,MAAK;IACtD,IAAIwO,EAAE,QAAQ,QAAQ,KAAA,GAAW;IACjC,IAAMsJ,IAAO,SAAStJ,EAAE,QAAQ,KAAK,EAAE,GAEjCuJ,IAAOD,KADCtJ,EAAE,WAAW,KACC;IAE5B,IAAIsJ,KAAQ4B,KAAkB3B,KAAQ2B,GAAgB;KAClD,IAAMG,IAAQrL,EAAE,sBAAsB;KAEtC,AADA,IAAa,KAAK,IAAImL,GAAYE,EAAM,IAAI,GAC5C,IAAc,KAAK,IAAID,GAAaC,EAAM,KAAK;IACnD;GACJ,CAAC,GAGDF,MAAe,UAAU;IACzB,IAAMnJ,IAAOF,EAAW,sBAAsB;IAE9C,AADA,IAAaE,EAAK,MAClB,IAAcA,EAAK;GACvB;GAEA,IAAMsJ,IAAOH,KAAeC,IAAcD,KAAc,GACpDI,IAAsB,GACtBC,IAAgB;GAEpB,AAAI,EAAE,UAAUF,KACZ,IAAsBJ,GACtB,IAAgBC,IAAarF,EAAU,SAGvC,IAAsBoF,KADNpJ,EAAW,WAAW,IAEtC,IAAgBsJ,IAActF,EAAU;GAG5C,IAAM2F,IAAc,KAAK1C,GAAkB,KAAK0B,EAAW,GACrDiB,IAAaD,EAAY,SAEzBE,IAAiBF,EAAY,UAE7BG,IAAeD,KADC,KAAKlB,GAAY,WAAW,KACI,GAEhDoB,IAAiB/J,EAAW,QAAQ,IAAI,CAAC,EAAE,mBAAmB,GAE9DgK,IAAeD,KADC/J,EAAW,WAAW,KACU,GAEhDiK,IAAsB,EAAEH,IAAeC,KAAkBF,IAAiBG,IAE5EE,IAAwB;GAC5B,IAAIP,EAAY,kBAAkB;IAC9B,IAAM,EAAE,UAAUQ,GAAQ,QAAQC,MAAST,EAAY;IACvD,CAAIF,IAAsBU,KAAWV,IAAsBG,IAAa,IAAKQ,OACzE,IAAwB;GAEhC;GAEA,IAAIC,IAA6B;GACjC,IAAI3a,GAAO;IACP,IAAM4a,IAAe5a,EAAM,iBAAiB,sCAAsC;IAElF,KAAK,IAAM6a,KAASD,GAAc;KAC9B,IAAIC,MAAU,KAAK5B,IAAa;KAEhC,IAAM6B,IAAYD,EAAM,QAAQ,IAAI,CAAC,EAAE,mBAAmB,GAEpDE,IAAUD,KADCD,EAAM,WAAW,KACK;KAGvC,IAD4BT,IAAeU,KAAaX,IAAiBY,GACjD;KAExB,IAAMC,IAAS,SAASH,EAAM,QAAQ,KAAK,EAAE,GAEvCI,IAAOD,KADCH,EAAM,WAAW,KACD;KAE9B,IAAId,IAAsBiB,KAAUjB,IAAsBkB,IAAO,GAAG;MAChE,IAA6B;MAC7B;KACJ;KAEA,IAAMC,IAAanB,IAAsBG,IAAa;KAMtD,IAJKH,IAAsBiB,KAAUjB,KAAuBkB,KAAQC,IAAaD,KAC5ElB,IAAsBiB,KAAUE,KAAcF,KAAUE,IAAaD,GAGjD;MACrB,IAA6B;MAC7B;KACJ;IACJ;GACJ;GAEA,IAAME,IACFpB,KAAuBE,EAAY,YACnCF,KAAuBE,EAAY,SAAS;GAKhD,IAFsB,CAACM,KAAuBY,KAAeX,KAAyBG,KAA8B,CAACV,EAAY,cAK7H,AAFA,KAAKjG,KAAkB,MACnB,KAAKyC,OAAO,KAAKA,GAAM,MAAM,UAAU,SACvC,KAAKD,MAAO,KAAKA,GAAM,UAAU,IAAI,SAAS;QAKlD,IAHA,KAAKxC,KAAkB+F,GACnB,KAAKvD,MAAO,KAAKA,GAAM,UAAU,OAAO,SAAS,GAEjD,KAAKC,IAAO;IAGZ,IAAM4C,IAFa/I,EAAW,QAAQ,kBACV,CAAC,CAAC,sBACD,CAAC,CAAC,MAAMgE,EAAU,KACzCgF,IAAahF,EAAU,SAAS+E;IAKtC,AAHA,KAAK5C,GAAM,MAAM,MAAM,GAAG4C,EAAY,KACtC,KAAK5C,GAAM,MAAM,SAAS,GAAG6C,EAAW,KACxC,KAAK7C,GAAM,MAAM,OAAO,GAAGuD,IAAgB,EAAE,KAC7C,KAAKvD,GAAM,MAAM,UAAU;GAC/B;EAER,OAGI,AAFI,KAAKA,OAAO,KAAKA,GAAM,MAAM,UAAU,SACvC,KAAKD,MAAO,KAAKA,GAAM,UAAU,IAAI,SAAS,GAClD,KAAKxC,KAAkB;CAE/B;CAEA,GAAoB,GAAS;EACzB,IAAI,CAAC,KAAKwC,IAAO;EAEjB,IAAM4E,IAAOpG,IADK,KAAK5R,GAAO,sBACC,CAAC,CAAC,OAAO,KAAK+V;EAC7C,KAAK3C,GAAM,MAAM,OAAO,GAAG4E,EAAK;CACpC;CAEA,MAAgB,MAAM;EAClB,AAAK,KAAKtC,OAEV,OAAO,oBAAoB,eAAe,KAAKtG,EAAc,GAC7D,SAAS,KAAK,MAAM,SAAS,IAEzB,KAAKgE,OACL,KAAKA,GAAM,MAAM,UAAU,QAC3B,KAAKA,GAAM,gBAAgB,IAE3B,KAAKC,OAAO,KAAKA,GAAM,MAAM,UAAU,SAGvC,KAAKzC,OAAoB,QACzB,KAAKkF,OAAoB,QACzB,KAAKlF,OAAoB,KAAKkF,MAC9B,KAAKlF,OAAoB,KAAKkF,KAAkB,KAEhD,KAAK,WAAW,KAAKA,IAAiB,KAAKlF,EAAe,GAG9D,KAAK8E,KAAc,IACnB,KAAKG,KAAc,MACnB,KAAKC,KAAkB,MACvB,KAAKlF,KAAkB;CAC3B;CAEA,WAAW,GAAc,GAAY;EAEjC,IAAMqH,IAAW,KAAKjY,GAAO,YAAY,cAAc,UAAU,GAC3DkY,IAAYD,EAAS,cAAc,iBAAiBE,EAAW,GAAG,GAElEtB,IAAc,KAAK1C,GAAkB,KAAK0B,EAAW;EAC3D,IAAI,CAACgB,KAAe,CAACA,EAAY,cAAc;EAE/C,IAAMuB,IAAYvB,EAAY,SACxBwB,KAAa,MAAQtgB,KAAOugB,KAAgBvgB,IAAMugB,IAAeF,GAGjEG,IAAoB,KAAKvY,GAAO,cAAc,wCAAwCmY,EAAW,GAAG,GACpGK,IAAYD,GAAmB,QAAQ,oBAAoB,IAAI,SAASA,GAAmB,QAAQ,qBAAqB,IAAI,UAAU;EAsB5I,AApBAN,EAAS,iBAAiB,KAAK,CAAC,CAAC,SAAQ,MAAO;GAC5C,AAAII,EAAU,SAAS3M,EAAI,aAAa,UAAU,GAAG,EAAE,CAAC,MACpD8M,IAAY9M,EAAI,aAAa,SAAS8M,CAAS,IAAI9M,EAAI,gBAAgB,OAAO,GAC9EuM,EAAS,aAAavM,GAAKwM,CAAS;EAE5C,CAAC,GAED;GAAC;GAAS;GAAS;EAAO,CAAC,CAAC,SAAQ,MAAS;GACzC,KAAKlY,GAAO,YAAY,iBAAiB,GAAGyY,EAAM,IAAI,CAAC,CAAC,SAAQ,MAAM;IAClE,IAAMC,IAAQ,MAAM,KAAK9Q,EAAG,QAAQ,GAC9B+Q,IAAgBD,EAAM,MAAK,MAAK,SAAStN,EAAE,QAAQ,KAAK,EAAE,KAAK+M,CAAU;IAE/E,EAAM,SAAQ,MAAQ;KAClB,AAAIE,EAAU,SAAS9L,EAAK,QAAQ,KAAK,EAAE,CAAC,KACxC3E,EAAG,aAAa2E,GAAMoM,KAAiB,IAAI;IAEnD,CAAC;GACL,CAAC;EACL,CAAC,GAED,KAAK3Y,GAAO,oBAAoB;CACpC;CAEA,UAAU;EACN,KAAKA,GAAO,oBAAoB,eAAe,KAAKqP,EAAc;CACtE;AACJ,GC5eauJ,IAAb,MAA2B;CACvB;CAEA,YAAY,GAAO;EACf,KAAK5Y,KAAShE;CAClB;CAEA,YAAY,GAAY,GAAO;EAC3B,IAAI,CAACkR,KAAc,CAACtQ,GAAO,OAAO;EAElC,IAAMyK,IAAY6F,EAAW,QAAQ,6DAA6D;EAClG,IAAI7F,GAAW,UAAU,SAAS,mBAAmB,GAAG,OAAO;EAC/D,IAAIA,GAAW,UAAU,SAAS,oBAAoB,GAAG,OAAO;EAEhE,IAAMwR,IAAU,SAAS3L,EAAW,QAAQ,KAAK,EAAE;EACnD,IAAI,CAAC,MAAM2L,CAAO,GAAG;GAEjB,IAAMC,IADQlc,EAAM,cAAc,0BAA0Bic,EAAQ,GAC9C,CAAC,EAAE,aAAa,OAAO;GAC7C,IAAIC,GAAW,OAAOA;EAC1B;EAEA,OAAO;CACX;CAEA,aAAa,GAAY,GAAO;EAC5B,IAAI,CAAC5L,KAAcA,EAAW,YAAY,QAAQ,CAACtQ,GAAO,OAAO;EAEjE,IAAMic,IAAU,SAAS3L,EAAW,QAAQ,KAAK,EAAE,GAC7C/B,IAAU+B,EAAW,WAAW;EACtC,IAAI,MAAM2L,CAAO,GAAG,OAAO;EAE3B,IAAME,IAAoBF,IAAU1N,IAAU,GACxC6N,IAAW,MAAM,KAAKpc,EAAM,iBAAiB,UAAU,CAAC;EAE9D,IAAIoc,EAAS,UAAU,GAAG,OAAO;EAEjC,KAAK,IAAMpR,KAAMoR,GAAU;GACvB,IAAMN,IAAQ,MAAM,KAAK9Q,EAAG,iBAAiB,QAAQ,CAAC,GAClDqR,IAAoB;GAExB,KAAK,IAAM1M,KAAQmM,GAAO;IACtB,IAAMhE,IAAO,SAASnI,EAAK,QAAQ,KAAK,EAAE,GAEpC2M,IAAUxE,KADFnI,EAAK,WAAW,KACC;IAE/B,IAAImI,KAAQqE,KAAqBA,IAAoBG,GACjD,OAAO;IAGX,IAAIA,MAAYH,GAAmB;KAC/B,IAAoB;KACpB;IACJ;GACJ;GAEA,IAAI,CAACE,GAAmB,OAAO;EACnC;EAEA,OAAO;CACX;CAEA,iBAAiB,GAAQ,GAAY,IAAU,QAAQ;EACnD,IAAI,CAAC,KAAKjZ,MAAU,CAACkN,GAAY;EAEjC,IAAMzK,IAAc,KAAKzC,GAAO;EAChC,IAAI,CAACyC,GAAa;EAElB,IAAMoW,IAAU,SAAS3L,EAAW,QAAQ,KAAK,EAAE,GAC7C/B,IAAU+B,EAAW,WAAW,GAChCoJ,IAAiBuC,IAAU1N,IAAU;EAE3C,IAAI,MAAMmL,CAAc,GAAG;EAE3B,IAAM2B,IAAWxV,EAAY,cAAc,UAAU;EACrD,IAAI,CAACwV,GAAU;EAEf,IAAMjN,IAAO,MAAM,KAAKiN,EAAS,iBAAiB,KAAK,CAAC;EAExD,IAAIkB,MAAW,cAQX,AAPAnO,EAAK,SAAQ,MAAO;GAEhB,AADY,SAASU,EAAI,aAAa,UAAU,GAAG,EAC7C,KAAK4K,KACP5K,EAAI,aAAa,SAAS0N,CAAO;EAEzC,CAAC,GAED;GAAC;GAAS;GAAS;EAAO,CAAC,CAAC,SAAQ,MAAS;GACzC,EAAY,iBAAiB,GAAGX,EAAM,IAAI,CAAC,CAAC,SAAQ,MAAM;IACtD,MAAM,KAAK7Q,EAAG,QAAQ,CAAC,CAAC,SAAQ,MAAQ;KACpC,IAAMyR,IAAO,SAAS9M,EAAK,QAAQ,KAAK,EAAE;KAC1C,AAAI,CAAC,MAAM8M,CAAI,KAAKA,KAAQ/C,KACxB/J,EAAK,aAAa,SAAS6M,CAAO;IAE1C,CAAC;GACL,CAAC;EACL,CAAC;OAEE,IAAID,MAAW,gBAAgB;GAClC,IAAIG,IAAaT,GACbU,IAAYV,IAAU1N,IAAU;GAuBpC,AArBA;IAAC;IAAS;IAAS;GAAO,CAAC,CAAC,SAAQ,MAAS;IACzC,EAAY,iBAAiB,GAAGsN,EAAM,IAAI,CAAC,CAAC,SAAS,GAAI,MAAS;KAC9D,MAAM,KAAK7Q,EAAG,QAAQ,CAAC,CAAC,SAAQ,MAAQ;MACpC,IAAM8M,IAAO,SAASnI,EAAK,QAAQ,KAAK,EAAE,GAEpCoI,IAAOD,KADCnI,EAAK,WAAW,KACF,GACtBiN,IAAQjN,EAAK,WAAW;MAO9B,CANgB3E,EAAG,mBAAmB6R,KAEAD,IAAQ,IAAIjN,EAAK,QAAQ,IAAI,CAAC,CAAC,mBAA8BA,EAAK,QAAQ,IAAI,CAAC,CAAC,kBAAkBiN,IAAQ,GAElH7E,IAAOkE,KAAWnE,IAAO4B,MAGnD,IAAa,KAAK,IAAIgD,GAAY5E,CAAI,GACtC,IAAY,KAAK,IAAI6E,GAAW5E,CAAI;KAE5C,CAAC;IACL,CAAC;GACL,CAAC,GAED3J,EAAK,SAAQ,MAAO;IAEhB,AADY,SAASU,EAAI,aAAa,UAAU,GAAG,EAC7C,KAAK4N,KACP5N,EAAI,gBAAgB,OAAO;GAEnC,CAAC;GAED,IAAIgO,IAAW;GASf,AARA1O,EAAK,SAAQ,MAAO;IAChB,AAAI0O,IACAhO,EAAI,gBAAgB,OAAO,IACnBA,EAAI,aAAa,OAAO,MAChC,IAAW;GAEnB,CAAC,GAED;IAAC;IAAS;IAAS;GAAO,CAAC,CAAC,SAAQ,MAAS;IACzC,EAAY,iBAAiB,GAAG+M,EAAM,IAAI,CAAC,CAAC,SAAQ,MAAM;KACtD,MAAM,KAAK7Q,EAAG,QAAQ,CAAC,CAAC,SAAQ,MAAQ;MACpC,IAAMyR,IAAO,SAAS9M,EAAK,QAAQ,KAAK,EAAE;MAC1C,IAAI,MAAM8M,CAAI,GAAG;MAGjB,IAAMM,IADmB3O,EAAK,MAAK,MAAK,SAASI,EAAE,aAAa,UAAU,GAAG,EAAE,MAAMiO,CACnD,CAAC,EAAE,aAAa,OAAO;MAEzD,AAAIM,IACApN,EAAK,aAAa,SAASoN,CAAU,IAErCpN,EAAK,gBAAgB,OAAO;KAEpC,CAAC;IACL,CAAC;GACL,CAAC;EACL;EAEA,KAAKvM,GAAO,sBAAsB;CACtC;AACJ,GC/Ja4Z,IAAb,cAA0C,YAAY;CACrD;CACA;CACA;CACA;CACA;CACA,aAAa;CAEb,oBAAoB;EAEnB,AADA,KAAKxf,GAAM,GACX,SAAS,iBAAiB,aAAa,KAAKyf,EAAa;CAC1D;CAEA,WAAc;EAmBZ,AAjBA,KAAK3G,GAAU,GAEf,KAAKlT,KAAS,KAAK,QAAQ,kBAAkB,GAC7C,KAAK1I,KAAQ,KAAK,YAAY,CAAC,CAAC,MAEhC,KAAKwiB,KAAa,KAAK,cAAc,mBAAmB,GAExD,iBAAiB;GAChB,KAAKC,KAAQ,KAAKD,GAAW,WAAW,cAAc,kBAAkB;EACzE,CAAC,GAGD,KAAK,cAAc,aAAa,CAAC,CAAC,iBAAiB,YAAY,MAAM;GACpE,EAAE,gBAAgB;EACnB,CAAC,GACD,KAAK,cAAc,aAAa,CAAC,CAAC,iBAAiB,SAAS,KAAKE,EAAQ,GACzE,KAAK,cAAc,eAAe,CAAC,CAAC,iBAAiB,UAAU,KAAKC,EAAY,GAChF,KAAK,cAAc,QAAQ,CAAC,CAAC,iBAAiB,SAAS,KAAKC,EAAK;CAEnE;CAEA,WAAkB;EACjB,KAAK,YAAY;CA6BlB;CAEA,KAAK,GAAW;EACf,KAAKC,KAAUC;EAEf,IAAM7N,IAAO6N,EAAU,QAAQ,QAAQ;EACvC,KAAK,aAAa7N,GAAM,QAAQ;EAEhC,IAAMoC,IAAWpC,EAAK,sBAAsB,GACtC2E,IAAY,KAAKlR,GAAO,sBAAsB,GAE9Cqa,IAAa,KAAK,eAAe,KACnCrC,IAAQrJ,EAAS,QAAQuC,EAAU,OAAQmJ,GAC3CC,IAAM3L,EAAS,SAASuC,EAAU;EAOtC,AALI8G,IAAO,MACV,IAAO,KAAK,IAAI,GAAGrJ,EAAS,OAAOuC,EAAU,IAAI,IAGlD,KAAK,MAAM,OAAO,GAAG8G,EAAK,KAC1B,KAAK,MAAM,MAAM,GAAGsC,EAAI;EAExB,IAAMC,IAAY,KAAK,cAAc,aAAa;EAOlD,AANA,EAAU,QAAQ,IAGlB,KAAK,UAAU,IAAI,QAAQ,GAC3B,KAAK,UAAU,IAAI,SAAS,GAE5B,iBAAiB;GAChB,IAAI;IAGH,AAFA,KAAKC,GAAwB,GAC7B,KAAKT,GAAM,WAAW,gBAAgB,CAAC,GACvCQ,EAAU,MAAM;GACjB,UAAU;IACT,KAAK,UAAU,OAAO,SAAS;GAChC;EACD,CAAC;CACF;CAEA,MAAiB,MAAM;EACtB,IAAME,IAAO,EAAE,eAAe,EAAE,aAAa,IAAI,CAAC;EAClD,AAAIA,EAAK,SAAS,IAAI,KAAM,KAAKN,MAAWM,EAAK,SAAS,KAAKN,EAAO,KAGtE,KAAK,MAAM;CACZ;CAEA,QAAQ;EAGP,AAFA,KAAK,aAAa,MAClB,KAAK,UAAU,OAAO,QAAQ,GAC9B,KAAKA,KAAU;CAChB;CAEA,KAA0B;EACzB,IAAMO,IAAkB,KAAKpjB,GAAM,KAAK,SAAS,GAC3CuY,IAAa,KAAKsK,IAAS,WAAW,CAAC,GACvC9hB,IAAS,KAAKf,GAAM,OAAO,IAAI,KAAK,CAAC,GACrCqjB,IAAgB,KAAK3a,GAAO,WAAW,WAAW,CAAC,GACnD4a,IAAa,KAAKtjB,GAAM,YAExB2C,IAAK4V,EAAW,SAAS,MAAY;GAC1C,IAAMgL,IAAUC,EAAQ,MAClBC,IAAUD,EAAQ,MAElBE,IAAYH,KAAWE,GACvBrI,IAAWmI,IAAUxiB,EAAO,QAAQwiB,CAAO,IAAI,IAC/CI,IAAqBN,EAAcK,MAAc,CAAC,GAElDE,oBAAY,IAAI,IAAI;GAC1B,KAAK,IAAInhB,IAAI,GAAGA,IAAI2gB,EAAgB,QAAQ,KAAK;IAChD,IAAMtW,IAASsW,EAAgB3gB;IAC/B,IAAI,CAACqK,GAAQ;IAEb,IAAI+W;IACJ,AAAIzI,KAAY,KAAKtO,EAAO,IAC3B,IAASA,EAAO,EAAEsO,KACRmI,KAAWA,EAAQ,SAAS,OAAO,IAC7C,IAASD,IAAaA,EAAW,SAASC,GAASzW,GAAQrK,CAAC,IAAI,KAAA,IACtDghB,KAAWH,MACrB,IAASA,EAAW,SAASG,GAAS3W,GAAQrK,CAAC;IAGhD,IAAIqhB,IAAaD;IAKjB,AAJIJ,KAAWH,MACd,IAAaA,EAAW,SAASG,GAAS3W,GAAQrK,CAAC,IAGhDqhB,KAA2C,QAAQ,CAACF,EAAU,IAAIE,CAAU,KAC/EF,EAAU,IAAIE,GAAY;KACzB,GAAGD;KACH,IAAIC;IACL,CAAC;GAEH;GAEA,IAAMC,IAAa,CAAC,GAAGH,EAAU,OAAO,CAAC;GAwBzC,OAtBAG,EAAW,MAAM,GAAG,MAAM;IACzB,IAAMC,IAAOhiB,EAAE,IACTiiB,IAAOliB,EAAE;IAEf,IAAIiiB,MAASC,GAAM,OAAO;IAC1B,IAAID,KAA+B,QAAQA,MAAS,IAAI,OAAO;IAC/D,IAAIC,KAA+B,QAAQA,MAAS,IAAI,OAAO;IAE/D,IAAMC,IAAO,OAAOF,CAAI,GAClBG,IAAO,OAAOF,CAAI;IASxB,OAJI,CAHY,MAAMC,CAAI,KAGZ,CAFE,MAAMC,CAAI,IAGlBD,IAAOC,IAGR,OAAOH,CAAI,CAAC,CAAC,cAAc,OAAOC,CAAI,CAAC;GAC/C,CAAC,GACDN,EAAmB,MAAM,GAAG,MAAe3hB,IAAID,IAAI,IAAI,EAAK,GAErDgiB,EAAW,KAAI,OAAM;IAC3B,KAAK;IACL,MAAM5jB,EAAE;IACR,OAAQA,EAAE,OAAO,MAAMA,EAAE,OAAO,QAAQA,EAAE,OAAO,KAAA,IAAa,+CAA6CA,EAAE;IAC7G,OAAOujB;IACP,KAAKC,EAAmB,WAAW,KAAKA,EAAmB,iBAAiBxjB,EAAE,CAAC,KAAK,IAAI,MAAM;GAC/F,EAAE;EACH,CAAC;EAED,KAAKqiB,GAAW,KAAK,IAAI7f,CAAE;EAE3B,IAAMyhB,IAAe,KAAK,cAAc,eAAe;EACvD,AAAIA,MACH,EAAa,UAAUzhB,EAAG,SAAS,KAAKA,EAAG,OAAM,MAAQR,EAAK,QAAQ,GAAG;CAE3E;CAEA,WAAc;EACb,KAAKnC,GAAM,UAAU;EAErB,IAAMqkB,IAAgB,KAAK5B,GAAM,KAAK,SAAS,GACzC1hB,IAAS,KAAKyhB,GAAW,KAAK,cAAc,GAE5C8B,IAAiBD,EAAc,QAAO,MAAU;GACrD,IAAME,IAAMzX,EAAO,EAAE/L,EAAO,QAAQ,KAAK;GACzC,OAAQwjB,MAAQ,OAAOA,MAAQ;EAChC,CAAC,GAEKC,IAAe,EAAE,GAAI,KAAK9b,GAAO,WAAW,WAAW,CAAC,EAAG;EAEjE,KAAKma,GAAQ,QAAQ,SAAQ,MAAW;GACvC,IAAMa,IAAYF,EAAQ,QAAQA,EAAQ,MACpCpI,IAAWoI,EAAQ,OAAOziB,EAAO,QAAQ,OAAO,IAAIA,EAAO,QAAQ,MAAM,GACzE0jB,IAAeH,EAAe,KAAI,MAAKlX,EAAE,EAAEgO,EAAS;GAE1D,AAAIqJ,EAAa,SAAS,IACzB,EAAaf,KAAae,IAE1B,OAAOD,EAAad;EAEtB,CAAC;EAED,IAAM9a,IAAa,KAAK4Z,GAAW,KAAK,MAAM;EAE9C,iBAAiB;GAChB,IAAI;IAeH,AAdI5Z,MAAe0b,EAAe,SACjC,KAAKzB,GAAQ,QAAQ,SAAQ,MAAW;KACvC,IAAMa,IAAYF,EAAQ,QAAQA,EAAQ;KAC1C,AAAIE,KAAW,KAAKhb,GAAO,UAAU,MAAMgb,CAAS;IACrD,CAAC,IAED,KAAKhb,GAAO,UAAU,IAAI8b,CAAY,GAGvC,KAAK9b,GAAO,iBAAiB,0BAA0B,CAAC,CAAC,SAAQ,MAAO;KACvE,EAAI,oBAAoB;IACzB,CAAC,GAED,KAAKA,GAAO,WAAW,GACvB,KAAK,MAAM;GACZ,UAAU;IACT,KAAK1I,GAAM,UAAU;GACtB;EACD,CAAC;CACF;CAEA,MAAY,MAAM;EAEjB,IAAM0kB,IAAQ,EAAE,OAAO,MAAM,YAAY,CAAC,CAAC,KAAK;EAEhD,IAAI,CAACA,GACJ,KAAKjC,GAAM,UAAU,MAAM;OACrB;GACN,IAAM7W,IAAa,KAAK4W,GAAW,KAAK,SAAS,GAE3CmC,IADS,KAAKnC,GAAW,KAAK,cACd,CAAC,CAAC,QAAQ,OAAO,GAEjCoC,IAAgB,CAAC;GAUvB,AATAhZ,EAAW,SAAQ,MAAU;IAC5B,IAAM4P,IAAMmJ,KAAY,KAAK7X,EAAO,IAAIA,EAAO,EAAE6X,KAAY;IAG7D,AAFgB,OAAOnJ,CAAG,CAAC,CAAC,QAAQ,cAAc,EAAE,CAAC,CAAC,YAE5C,CAAC,CAAC,SAASkJ,CAAK,KACzBE,EAAc,KAAKpJ,CAAG;GAExB,CAAC,GAED,KAAKiH,GAAM,UAAU,IAAI,EACxB,OAAO,CAAC,GAAG,IAAI,IAAImC,CAAa,CAAC,EAClC,CAAC;EACF;CACD;CAEA,MAAgB,MAAM;EACrB,IAAMC,IAAY,EAAE,OAAO,SACrBjZ,IAAa,KAAK4W,IAAY,MAAM,SAAS,KAAK,CAAC,GAEnDsC,IADS,KAAKtC,GAAW,KAAK,cAChB,CAAC,CAAC,QAAQ,KAAK;EAQnC,AANIsC,KAAU,KACblZ,EAAW,SAAQ,MAAU;GAC5B,EAAO,EAAEkZ,KAAUD,IAAY,MAAM;EACtC,CAAC,GAGF,KAAKrC,GAAW,QAAQ;CACzB;AAKD,GAEauC,IAAb,cAA2C,YAAY;CACtD;CACA,KAAW;CAEX,oBAAoB;EAGnB,AAFA,KAAKrc,KAAS,KAAK,QAAQ,kBAAkB,KAAK,KAAK,YAAY,CAAC,CAAC,MACrE,KAAK,oBAAoB,SAAS,KAAKsc,EAAQ,GAC/C,KAAK,iBAAiB,SAAS,KAAKA,EAAQ;CAC7C;CAEA,IAAI,UAAU;EACb,IAAI,KAAKC,IAAU,OAAO,KAAKA;EAG/B,IAAMrkB,IADO,KAAK,QAAQ,QACN,CAAC,EAAE,QAAQ,KACzBuK,IAAc,KAAKzC,GAAO,aAE1BgL,IAAO,CAAC,GACRwR,oBAAO,IAAI,IAAI;EAqBrB,OAnBI/Z,KAAevK,MAAa,KAAA,KAC/BuK,EAAY,iBAAiB,oBAAoBvK,EAAS,GAAG,CAAC,CAAC,SAAQ,MAAO;GAC7E,IAAM2iB,IAAUpP,EAAI,QAAQ,MACtBsP,IAAUtP,EAAI,QAAQ;GAE5B,IAAIoP,KAAWE,GAAS;IACvB,IAAM0B,IAAY,GAAG5B,KAAW,GAAG,GAAGE,KAAW;IACjD,AAAKyB,EAAK,IAAIC,CAAS,MACtBD,EAAK,IAAIC,CAAS,GAClBzR,EAAK,KAAK;KACT,MAAM6P;KACN,MAAME;IACP,CAAC;GAEH;EACD,CAAC,GAGF,KAAKwB,KAAWvR,GACT,KAAKuR;CACb;CAEA,4BAA4B;EAC3B,IAAM5B,IAAgB,KAAK3a,GAAO,WAAW,WAAW,CAAC,GACnD0c,IAAa,KAAK,QAAQ,MAAK,MAAW;GAC/C,IAAMnY,IAAMuW,EAAQ,QAAQA,EAAQ;GACpC,OAAOvW,KAAOoW,EAAcpW,MAAQoW,EAAcpW,EAAI,CAAC,SAAS;EACjE,CAAC;EACD,KAAK,UAAU,OAAO,YAAYmY,CAAU;CAC7C;CAEA,MAAY,MAAM;EAGjB,AADA,EAAE,eAAe,GACjB,EAAE,gBAAgB;EAElB,IAAMC,IAAQ,KAAK3c,GAAO,cAAc,yBAAyB,GAE3D0L,IADO,KAAK,QAAQ,QACX,CAAC,CAAC,QAAQ;EAEzB,AAAIiR,KAASA,EAAM,eAAejR,KAAOiR,EAAM,UAAU,SAAS,QAAQ,IACzEA,EAAM,MAAM,IACFA,KACVA,EAAM,KAAK,IAAI;CAEjB;AACD,GAEaC,IAAb,MAAuB;CACtB;CACA;CACA,KAAe;CACf,KAAe;CACf,KAAW,CAAC;CAEZ,YAAY,GAAO;EAGlB,AAFA,KAAK5c,KAAShE,GACd,KAAK1E,KAAQ,KAAK0I,GAAO,YAAY,CAAC,CAAC,MACvC,KAAK5F,GAAM;CACZ;CAEA,IAAI,UAAU;EACb,OAAO,KAAKyiB;CACb;CAEA,WAAc;EACb,KAAKC,GAAiB;CACvB;CAEA,WAAyB;EACxB,IAAI,KAAKxlB,GAAM,QAAQ,YAAY,MAAM,qBACxC;EAGD,IAAIqlB,IAAQ,KAAK3c,GAAO,cAAc,yBAAyB;EAK/D,AAJK2c,MACJ,IAAQ,SAAS,cAAc,yBAAyB,GACxD,KAAK3c,GAAO,YAAY2c,CAAK,IAE9B,KAAKI,KAAeJ;CACrB;CAEA,cAAc;EACb,OAAO,KAAKK;CACb;CAEA,SAAS,MAAU;EAUlB,AATIllB,IACH,OAAO,KAAK+kB,GAAS/kB,KAErB,KAAK+kB,KAAW,CAAC,GAGlB,KAAKG,KAAe,OAAO,KAAK,KAAKH,EAAQ,CAAC,CAAC,SAAS,GACxD,KAAKI,GAAgB,GAErB,KAAKjd,GAAO,iBAAiB,0BAA0B,CAAC,CAAC,SAAQ,MAAO;GACvE,EAAI,oBAAoB;EACzB,CAAC;CACF;CAEA,OAAO,MAAY;EAElB,IAAIkd,IAAa,MAAM,QAAQC,CAAO,IACnC,OAAO,YAAY,OAAO,KAAKA,EAAQ,EAAE,CAAC,CAAC,KAAI,MAAK,CAACC,GAAG,CAAC,GAAG,IAAI,IAAID,EAAQ,KAAI,MAAQ1jB,EAAK2jB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IACpGD;EAMH,AAJA,KAAKN,KAAWK,GAChB,KAAKF,KAAe,OAAO,KAAKE,CAAU,CAAC,CAAC,SAAS,GACrD,KAAKld,GAAO,gBAAgB,aAAa,KAAKgd,EAAY,GAE1D,KAAKC,GAAgB;CACtB;CAEA,KAAkB;EAEjB,IAAM/Z,IADW,KAAK5L,GAAM,KACA,SAAS,GAC/Be,IAAS,KAAKf,GAAM,KAAK,cAAc,GACvC+lB,IAAa,KAAKrd,GAAO,OACzB4a,IAAa,KAAKtjB,GAAM;EAI9B,IAAI,EAFe,OAAO,KAAK,KAAKulB,EAAQ,CAAC,CAAC,SAAS,IAEtC;GAMhB,AALA3Z,EAAW,SAAQ,MAAU;IAC5B,AAAIkB,GAAQ,GAAG,IAAIpN,EAAW,KAAK,MAAM,YACxC,EAAO,EAAE,EAAEA,EAAW,KAAK,MAAM,OAAO,CAACqmB,KAAc;GAEzD,CAAC,GACD,KAAKrd,GAAO,WAAW;GACvB;EACD;EAEA,IAAMsd,IAAc,OAAO,QAAQ,KAAKT,EAAQ,CAAC,CAAC,KAAK,CAACU,GAAWC,OAAmB;GACrF,IAAMC,IAASF,EAAU,SAAS,OAAO,KAAKA,EAAU,SAAS,OAAO,KAAKA,EAAU,SAAS,WAAW;GAC3G,OAAO;IACN;IACA;IACA,UAAWE,IAAqC,KAA5BplB,EAAO,QAAQklB,CAAS;IAC5C,YAAY,IAAI,IAAIC,CAAa;GAClC;EACD,CAAC;EA8BD,AA5BAta,EAAW,SAAS,GAAQ,MAAc;GACzC,IAAI,CAACkB,GAAQ;GAEb,AAAKA,EAAO,EAAE,EAAEpN,EAAW,KAAK,MAAM,YACrC,EAAO,EAAE,EAAEA,EAAW,KAAK,MAAM,UAAU,CAAC;GAG7C,IAAI0mB,IAAS;GAEb,KAAK,IAAI3jB,IAAI,GAAGA,IAAIujB,EAAY,QAAQ,KAAK;IAC5C,IAAM,EAAE,cAAW,WAAQ,aAAU,kBAAeA,EAAYvjB,IAC5D+Y;IAQJ,IANI2K,KAAU7C,IACb,IAAMA,EAAW,SAAS2C,GAAWnZ,GAAQuZ,CAAS,IAC5CjL,KAAY,KAAKtO,EAAO,MAClC,IAAMA,EAAO,EAAEsO,KAGZ,CAACkL,EAAW,IAAI9K,CAAG,GAAG;KACzB,IAAS;KACT;IACD;GACD;GAEA,EAAO,EAAE,EAAE9b,EAAW,KAAK,MAAM,OAAO,CAACqmB,KAAcK;EACxD,CAAC,GAED,KAAK1d,GAAO,WAAW;CACxB;AACD;AAEK,eAAe,IAAI,yBAAyB,KAChD,eAAe,OAAO,2BAA2B4Z,CAAoB,GAGjE,eAAe,IAAI,0BAA0B,KACjD,eAAe,OAAO,4BAA4ByC,CAAqB;;ACpfxE,IAAawB,IAAb,MAAqB;CACpB;CACA;CAEA,KAAW,CAAC;CAEZ,YAAY,GAAO;EAIlB,AAHA,KAAK7d,KAAShE,GACd,KAAK1E,KAAQ0E,EAAM,YAAY,CAAC,CAAC,MAEjC,iBAAiB;GAChB,KAAKsP,GAAY;EAClB,GAAG,GAAG;CACP;CAEA,KAAc;EAEb,KAAKtL,GAAO,iBAAiB,OAAO,CAAC,CAAC,SAAQ,MAAO;GAEpD,EAAI,iBAAiB,aAAa,MAAM;IAEvC,IAAMuM,IAAO,EAAE,OAAO,QAAQ,QAAQ;IAKtC,IAJI,CAACA,KAAQA,EAAK,UAAU,SAAS,gBAAgB,KAEjD,CAAC,SAAQ,eAAe,CAAC,CAAC,SAAS,EAAE,OAAO,OAAO,KAEnD,EAAE,WAAW,KAAK,EAAE,WAAWA,EAAK,cAAc,GAAG;IAEzD,IAAMhV,IAAO,KAAKyI,GAAO,YAAY,CAAC,CAAC;IAGvC,AADA,EAAK,UAAU,IACf,iBAAiB;KAChB,IAAI;MACH,KAAK8d,GAAY,GAAGvR,CAAI;KACzB,UAAU;MACT,EAAK,UAAU;KAChB;IACD,CAAC;GACF,CAAC;EACF,CAAC;CACF;CAEA,GAAY,GAAG,GAAM;EACpB,IAAMrU,IAAWqU,EAAK,QAAQ,KACxB3E,IAAK2E,EAAK,QAAQ,IAAI,GACtBxE,IAAcH,IAAKA,EAAG,QAAQ,UAAU,OAAOA,EAAG,eAAe,IAAI;EAE3E,IAAI1P,MAAa,KAAA,GAAW;EAE5B,IAAMuK,IAAc,KAAKzC,GAAO;EAChC,IAAI,CAACyC,GAAa;EAElB,IAAIsb,IAAU,MACVC,IAAU;EAYd,IAVAvb,EAAY,iBAAiB,oBAAoBvK,EAAS,GAAG,CAAC,CAAC,SAAQ,MAAO;GAK7E,AAJIuT,EAAI,QAAQ,SACf,IAAUA,EAAI,QAAQ,OAGnBA,EAAI,QAAQ,SACf,IAAUA,EAAI,QAAQ;EAExB,CAAC,GAEG,CAACsS,KAAW,CAACC,GAAS;EAE1B,IAAMC,IAAQ1R,EAAK,UAAU,SAAS,KAAK,GACrC2R,IAAS3R,EAAK,UAAU,SAAS,MAAM;EAE7C,AAAI,CAAC,EAAE,WAAW,CAAC,EAAE,aACpB,KAAKgQ,KAAW,CAAC;EAGlB,IAAM4B,IAAmB,KAAK5B,GAAS,WACtC,MAAM6B,EAAE,aAAalmB,KAAYkmB,EAAE,gBAAgBrW,KAAgBqW,EAAE,YAAYL,CAClF,GAEMM,IAAW;GAChB;GACA;GACA,SAASN,KAAWC;GACpB,SAASD,KAAWC;GACpB,MAAMA;GACN,KAAK;GACL,aAAaA,KAAW,GAAQ,MAAQ,KAAK1mB,GAAM,WAAW0mB,GAAS5Z,GAAQrM,CAAG,IAAI;EACvF;EAoBA,AAlBI,CAACkmB,KAAS,CAACC,IACVC,KAAoB,IACvB,KAAK5B,GAAS4B,EAAiB,CAAC,MAAM,KAEtC,KAAK5B,GAAS,KAAK;GAAE,GAAG8B;GAAU,KAAK;EAAK,CAAC,IAEpCJ,IACNE,KAAoB,IACvB,KAAK5B,GAAS4B,EAAiB,CAAC,MAAM,KAEtC,KAAK5B,GAAS,KAAK;GAAE,GAAG8B;GAAU,KAAK;EAAM,CAAC,IAG/C,KAAK9B,KAAW,KAAKA,GAAS,QAC7B,MAAK,EAAG6B,EAAE,aAAalmB,KAAYkmB,EAAE,gBAAgBrW,KAAgBqW,EAAE,YAAYL,EACpF,GAGD,KAAKO,GAAc;CACpB;CAEA,KAAgB;EACf,AAAK,KAAKte,GAAO,SAIjB,KAAKA,GAAO,KAAK,WAAW,KAAKuc,EAAQ,GACzC,KAAKgC,GAAc,GACnB,KAAKve,GAAO,WAAW;CACxB;CAEA,KAAgB;EAKf,AAJA,KAAKA,GAAO,iBAAiB,oBAAoB,CAAC,CAAC,SAAQ,MAAM;GAChE,EAAG,UAAU,OAAO,OAAO,MAAM;EAClC,CAAC,GAEG,KAAKuc,GAAS,WAAW,KAI7B,KAAKA,GAAS,SAAQ,MAAW;GAChC,IAAM,EAAE,aAAU,gBAAa,WAAQiC;GAEvC,IAAItmB,MAAa,KAAA,GAAW;IAC3B,IAAIoP,IAAW,oBAAoBpP,EAAS;IAM5C,AALI6P,MAAgB,KAAA,MACnB,IAAW,yBAAyBA,EAAY,gBAAgB7P,EAAS,MAI1E,KAD+B8H,GAAO,iBAAiBsH,CACvC,CAAC,CAAC,SAAQ,MAAQ;KACjC,EAAK,UAAU,IAAImX,IAAM,QAAQ,MAAM;IACxC,CAAC;GACF;EACD,CAAC;CACF;CAEA,UAAU;EAOT,AANA,KAAKlC,KAAW,CAAC,GACb,KAAKvc,GAAO,QACf,KAAKA,GAAO,KAAK,aAAa,GAG/B,KAAKue,GAAc,GACnB,KAAKve,GAAO,YAAY,QAAQ,EAAI;CACrC;AACD,GCzJa0e,IAAb,MAAuB;CACtB;CACA;CACA,KAAkB,CAAC;CAEnB,KAAe,CAAC;CAEhB,KAAwB;CAExB,YAAY,GAAO;EAIlB,AAHA,KAAK1e,KAAShE,GACd,KAAK1E,KAAQ0E,EAAM,YAAY,CAAC,CAAC,MAEjC,KAAK,QAAQ;CACd;CAEA,YAAY,GAAI,MAAU;EAEzB,IAAI,CAAC,KAAK2iB,IAAuB;GAChC,IAAMra,IAAU,KAAKhN,GAAM,KAAK,SAAS;GACzC,KAAKqnB,KAAwB,KAAKC,GAAa,KAAI,MAAOta,EAAQvM,EAAI;EACvE;EAEA,IAAM8mB,IAAiB,KAAKF;EAE5B,IAAI/mB,KAA2B,MAC9B,OAAOinB;EAGR,IAAIjnB,IAAK,KAAKA,KAAMinB,EAAe,QAAQ,OAAO;EAElD,IAAMhnB,IAAegnB,EAAejnB;EACpC,IAAIE,KAAS,MAAM;GAElB,IAAMC,IADS,KAAKT,GAAM,KAAK,cACd,CAAC,CAAC,QAAQQ,CAAK;GAChC,OAAQC,KAAO,KAAKF,EAAa,IAAKA,EAAa,EAAEE,KAAO;EAC7D;EAEA,OAAOF;CACR;CAEA,cAAc;EACb,IAAI,CAAC,KAAK8mB,IAAuB;GAChC,IAAMra,IAAU,KAAKhN,GAAM,KAAK,SAAS;GACzC,KAAKqnB,KAAwB,KAAKC,GAAa,KAAI,MAAOta,EAAQvM,EAAI;EACvE;EAEA,OAAO,KAAK4mB,GAAsB;CACnC;CAEA,OAAO,GAAI,MAAU;EACpB,IAAME,IAAiB,KAAK,SAAS,GAC/BxmB,IAAS,KAAKf,GAAM,KAAK,gBAAgB,KAAK,CAAC;EAErD,IAAIM,KAA2B,MAC9B,OAAOinB,EAAe,KAAI,MAAU,KAAKC,GAAY1a,GAAQ/L,CAAM,CAAC;EAGrE,IAAIT,IAAK,KAAKA,KAAMinB,EAAe,QAAQ,OAAO;EAElD,IAAMhnB,IAAegnB,EAAejnB;EACpC,IAAI,CAACC,GAAc,OAAO;EAE1B,IAAIC,KAAS,MAAM;GAClB,IAAMC,IAAMM,EAAO,QAAQP,CAAK;GAChC,OAAQC,KAAO,KAAKF,EAAa,IAAKA,EAAa,EAAEE,KAAO;EAC7D;EAEA,OAAO,KAAK+mB,GAAYjnB,GAAcQ,CAAM;CAC7C;CAEA,MAAe,GAAG,MAAW;EAC5B,IAAI,CAACZ,GAAG,OAAO;EACf,IAAM+T,IAAI,CAAC;EAMX,OALAnT,EAAO,SAAS,GAAO,MAAM;GAC5B,EAAEP,KAASL,EAAE,IAAIA,EAAE,EAAEsC,KAAKtC,EAAEK;EAC7B,CAAC,GACGL,EAAE,MAAG,EAAE,IAAIA,EAAE,IACbA,EAAE,MAAG,EAAE,IAAIA,EAAE,IACV+T;CACR;CAEA,gBAAgB;EAEf,KAAKmT,KAAwB;EAE7B,IAAMzb,IAAa,KAAK5L,GAAM,KAAK,SAAS,GACxC2Q,IAAU,CAAC;EAYf,AAXA/E,EAAW,SAAS,GAAQ,MAAM;GACjC,IAAI,CAACkB,GAAQ;GACb,IAAM2a,IAAa3a,EAAO,GAAG,IAAIpN,EAAW,KAAK,MAAM;GACvD,AAAI+nB,KAAcA,EAAW,KAAK/e,GAAO,WAAW,MACpDiI,EAAQ,KAAKlO,CAAC;EACf,CAAC,GAEG,KAAKilB,GAAgB,SAAS,MACjC,IAAU,KAAKV,GAAcrW,GAAS/E,CAAU,IAGjD,KAAK0b,KAAe3W;EACpB,IAAMvQ,IAAeuQ,EAAQ,KAAI,MAAO/E,EAAWnL,EAAI,GAEjDyK,IAAe,KAAKxC,GAAO,UAAU,WAAW,CAAC;EACvD,IAAIwC,EAAa,SAAS,GAAG;GAC5B,IAAMyc,IAAcjc,EAAS,MAAMtL,GAAc8K,GAAc,KAAKlL,GAAM,KAAK,cAAc,CAAC;GAI9F,AAFA,KAAKqnB,KAAwBM,EAAY,aAEzC,KAAKjf,GAAO,SAAS,YAAYif,EAAY,QAAQ;EACtD,OACC,KAAKN,KAAwBjnB;CAK/B;CAEA,cAAc,MAAY;EAEzB,AADA,KAAKsnB,KAAkBE,KAAW,CAAC,GACnC,KAAK,QAAQ;CACd;CAEA,mBACQ,KAAKF;CAGb,qBAAqB;EAEpB,AADA,KAAKA,KAAkB,CAAC,GACxB,KAAK,QAAQ;CACd;CAGA,MAAiB,GAAS,MAAiB;EAE1C,IAAM3mB,IAAS,OAAO,KAAKf,GAAM,KAAK,iBAAkB,aAAa,KAAKA,GAAM,KAAK,cAAc,IAAI,CAAC,GAElG6nB,IAAe,KAAKH,GAAgB,KAAI,OAAS;GACtD,GAAGI;GACH,UAAU/mB,EAAO,QAAQ+mB,EAAK,WAAWA,EAAK,OAAO;EACtD,EAAE;EAEF,OAAOnX,EAAQ,MAAM,GAAM,MAAS;GACnC,IAAM3O,IAAI5B,EAAa2nB,IACjBhmB,IAAI3B,EAAa4nB;GAEvB,KAAK,IAAMF,KAAQD,GAAc;IAChC,IAAMlB,IAAQmB,EAAK,KACblkB,IAAOkkB,EAAK,MACd9D,GAAMC;IAEV,AAAIrgB,KACH,IAAO,KAAK5D,GAAM,WAAW,SAAS4D,GAAM5B,GAAG+lB,CAAI,GACnD,IAAO,KAAK/nB,GAAM,WAAW,SAAS4D,GAAM7B,GAAGimB,CAAI,KAE/CF,EAAK,YAAY,KAAK9lB,EAAE,KAAKD,EAAE,MAClC,IAAOC,EAAE,EAAE8lB,EAAK,WAChB,IAAO/lB,EAAE,EAAE+lB,EAAK;IAIlB,IAAMG,IAAYjE,KAAS,QAA8BA,MAAS,IAC5DkE,IAAYjE,KAAS,QAA8BA,MAAS;IAElE,IAAI,OAAYiE,IAChB;SAAID,GAAU,OAAO;KACrB,IAAIC,GAAU,OAAO;KAErB,IAAIlE,MAASC,GAAM;MAClB,IAAI5J,IAAO;MAEX,IAAI,OAAO2J,KAAS,YAAY,OAAOC,KAAS,UAC/C,IAAOD,IAAOC;WACR;OACN,IAAMkE,IAAO,OAAOnE,CAAI,GAClBoE,IAAO,OAAOnE,CAAI;OACxB,IAAOkE,IAAOC,IAAO,IAAKD,IAAOC,IAAO,KAAK;MAC9C;MAEA,IAAI/N,MAAS,GACZ,OAAOsM,IAAQtM,IAAO,CAACA;KAEzB;IAjBqB;GAkBtB;GAEA,OAAO0N,IAAOC;EACf,CAAC;CACF;AACD,GC1LaK,IAAb,MAAaA,EAAY;CAErB,OAAO,gBAAgB,GAAM,GAAK;EA2B9B,OAzBAA,EAAYC,GAAgB7kB,CAAG,GAC/B4kB,EAAYE,GAAa9kB,CAAG,GAC5B4kB,EAAYG,GAAqB/kB,CAAG,GAEpC4kB,EAAYI,GAAoBhlB,CAAG,GAEnC4kB,EAAYK,GAAwBjlB,CAAG,GAEvC2P,EAAc,cAAc3P,GAAKA,EAAI,iBAAiB,UAAU,CAAC,GACjE2P,EAAc,cAAc3P,GAAKA,EAAI,iBAAiB,kCAAgC,CAAC,GACvF2P,EAAc,cAAc3P,GAAKA,EAAI,iBAAiB,wCAAsC,CAAC,GAC7F2P,EAAc,cAAc3P,GAAKA,EAAI,iBAAiB,UAAU,CAAC,GAEjE4kB,EAAYM,GAAoBllB,CAAG,GAEnC4kB,EAAYO,GAAgCnlB,CAAG,GAE/C4kB,EAAYQ,GAAc5oB,GAAMwD,CAAG,GAEnC4kB,EAAYS,GAAkBrlB,CAAG,GAEjC4kB,EAAYU,GAAmB9oB,GAAMwD,CAAG,GAExC4kB,EAAYW,GAAwBvlB,CAAG,GAEhCA;CACX;CAEA,OAAOklB,GAAoB,GAAK;EAC5B,IAAMM,IAAQxlB,EAAI,cAAc,OAAO;EACvC,IAAI,CAACwlB,KAASA,EAAM,cAAc,yBAAyB,GAAG;EAE9D,IAEM3Y,IAAK2Y,EAAM,UAAU,CAAC;EAG5B,AAFA3Y,EAAG,aAAa,QAAQ,KAAK,GAC7BA,EAAG,UAAU,IAAI,wBAAwB,GACzCA,EAAG,UAAU,IAAI,UAAU;EAE3B,IAAM4Y,IAAWzlB,EAAI,cAAc,UAAU;EAC7C,IAAI,CAACylB,GAAU;EAEf,IAAIC,IAAM;EACV,EAAS,iBAAiB,QAAQ,CAAC,CAAC,SAAQ,MAAM;GAC9C,IAAI,CAACC,EAAG,UAAU,SAAS,OAAO,GAAG;IACjC,IAAMvV,IAAUuV,EAAG,WAAW;IAC9B,KAAK,IAAI3mB,IAAI,GAAGA,IAAIoR,GAAS,KAAK;KAC9B,IAAMhV,IAAO,oEAAO,QAAQ,QAAQsqB,CAAG,CAAC,CAAC,QAAQ,SAASd,EAAYgB,GAAe,GAAK,CAAC;KAC3F,EAAG,mBAAmB,aAAaxqB,CAAI;IAC3C;GACJ;EACJ,CAAC;EAED,IAAM6U,IAAO,MAAM,KAAKjQ,EAAI,iBAAiB,cAAc,CAAC;EAC5D,EAAG,iBAAiB,gBAAgB,CAAC,CAAC,SAAS,GAAI,MAAM;GACrD,IAAM6lB,IAAa5V,EAAKjR,EAAE,CAAC,aAAa,YAAY;GACpD,AAAI6mB,MACA,EAAG,MAAM,aAAaA;EAE9B,CAAC;CACL;CAEA,OAAOD,GAAe,GAAK;EACvB,IAAIhjB,IAAO;EACX,KAAK,IAAI,IAAIkjB,GAAK,KAAK,GAAG,IAAI,KAAK,MAAM,IAAI,EAAE,IAAI,GAC/C,IAAO,OAAO,aAAa,KAAM,IAAI,EAAG,IAAIljB;EAEhD,OAAOA;CACX;CAEA,OAAOmiB,GAAqB,GAAK;EAC7B,IAAItX,IAAQzN,EAAI,cAAc,6BAA6B;EAE3D,IAAKyN,GAEL;GAEA,IAFAA,EAAM,UAAU,IAAI,MAAM,GAEtB,CAACzN,EAAI,cAAc,YAAY,GAAG;IAClC,IAAM+lB,IAAY,SAAS,cAAc,OAAO;IAEhD,AADAA,EAAU,UAAU,IAAI,MAAM,GAC9BtY,EAAM,OAAOsY,CAAS;GAC1B;GAEA,IAAI,CAAC/lB,EAAI,cAAc,YAAY,GAAG;IAClC,IAAMgmB,IAAY,SAAS,cAAc,OAAO;IAEhD,AADAA,EAAU,UAAU,IAAI,MAAM,GAC9BvY,EAAM,MAAMuY,CAAS;GACzB;EAZ0B;CAa9B;CAEA,OAAOnB,GAAgB,GAAK;EACxB,IAAI3H,IAAWld,EAAI,cAAc,UAAU;EAM3C,IALKkd,MACD,IAAW,SAAS,cAAc,UAAU,GAC5Cld,EAAI,QAAQkd,CAAQ,IAGpBA,EAAS,iBAAiB,KAAK,CAAC,CAAC,WAAW,GAAG;GAC/C,IAAMuI,IAAWzlB,EAAI,cAAc,UAAU,GACzCimB,IAAW;GAMf,AALIR,MACA,IAAW,MAAM,KAAKA,EAAS,iBAAiB,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAK,MAC7D1b,KAAO,SAASyH,EAAK,aAAa,SAAS,KAAKA,EAAK,SAAS,EAAE,KAAK,IAC7E,CAAC,IAER,IAAW,KAAK,IAAIyU,GAAU,CAAC;GAE/B,KAAK,IAAIjnB,IAAI,GAAGA,IAAIinB,GAAU,KAAK;IAC/B,IAAMtV,IAAM,SAAS,cAAc,KAAK;IACxC,EAAS,YAAYA,CAAG;GAC5B;EACJ;CACJ;CAEA,OAAOsU,GAAwB,GAAK;EAChC,IAAMhV,IAAO,MAAM,KAAKjQ,EAAI,iBAAiB,cAAc,CAAC;EAC5D,IAAIiQ,EAAK,WAAW,GAAG;EAEvB,IAAMiW,IAAiBlmB,EAAI,eAAe,GACpCmmB,IAAe,KAAK,IAAI,KAAK,MAAMD,IAAiBjW,EAAK,MAAM,GAAG,GAAG;EAE3E,EAAK,SAAS,GAAK,MAAM;GAErB,AAAKU,EAAI,aAAa,UAAU,KAC5BA,EAAI,aAAa,YAAY3R,CAAC;GAGlC,IAAMkW,IAAQvE,EAAI,aAAa,OAAO,KAAK,SAASA,EAAI,MAAM,OAAO,EAAE,KAAKwV;GAC5E,EAAI,aAAa,SAASjR,CAAK;GAE/B,IAAMkR,IAAW,OAAOlR,CAAK,CAAC,CAAC,SAAS,IAAI,IAAIA,IAAQ,GAAGA,EAAM;GACjE,EAAI,MAAM,QAAQkR;EACtB,CAAC;CACL;CAEA,OAAOtB,GAAa,GAAK;EACrB,IAAI9kB,EAAI,cAAc,OAAO,GAAG;EAEhC,IAAMwlB,IAAQ,SAAS,cAAc,OAAO,GACtCtI,IAAWld,EAAI,cAAc,UAAU;EAE7C,AAAIkd,IACAA,EAAS,MAAMsI,CAAK,IAEpBxlB,EAAI,QAAQwlB,CAAK;CAEzB;CAEA,OAAOL,GAAgC,GAAK;EAExC,EADoB,iBAAiB,oBAC/B,CAAC,CAAC,SAAQ,MAAQ;GAEpB,AADoB3T,EAAK,aAAa,WAAW,MAAM,UACpCA,EAAK,aAAa,aAAa,MAAM,UACpDA,EAAK,aAAa,eAAe,MAAM;EAE/C,CAAC;CACL;CAEA,OAAO4T,GAAc,GAAM,GAAM;EAE7B,IAAMiB,IAAmB;GAAC;GAAa;GAAa;EAAM,GACtDC,IAAgB;EAiDpB,AA/CAC,EAAK,iBAAiB,oBAAoB,CAAC,CAAC,SAAQ,MAAS;GAEzD,IAAMC,IAAU,QADC7e,EAAM,aAAa,WAAW,KAAK,cAG9C8e,IAAY9e,EAAM,cAAc,UAAU;GAEhD,IAAI8e,GAAW;IACX,IAAI5iB,IAAI,CAAC;IACT,EAAU,iBAAiB,QAAQ,CAAC,CAAC,SAAQ,MAAW;KACpD,EAAE,KAAK;MACH,GAAG6iB,EAAQ,aAAa,GAAG;MAC3B,GAAGA,EAAQ,aAAa,GAAG;MAC3B,OAAOA,EAAQ,aAAa,OAAO;KACvC,CAAC;IACL,CAAC;IAED,IAAMC,IAAiB,QAAQ,KAAK,IAAI,EAAE,GAAG,EAAEL;IAQ/C,AANI9pB,MACA,EAAKmqB,WAAwB9iB,IAGjC8D,EAAM,aAAa,eAAe,QAAQgf,EAAe,GAAG,GAE5DF,EAAU,OAAO;GACrB;GAEA,IAAMtmB,IAAOwH,EAAM,QAAQ;GAiB3B,AAhBIxH,KACAwH,EAAM,aAAa,aAAanL,EAAK,WAAW,WAAW2D,CAAI,CAAC,GAGpE,MAAM,KAAKwH,EAAM,UAAU,CAAC,CAAC,SAAQ,MAAQ;IACzC,AAAI;KAAC;KAAa;KAAa;KAAa;IAAW,CAAC,CAAC,SAASzH,EAAK,IAAI,MACvEA,EAAK,MAAM,SAAS,OAAO,KAAKA,EAAK,MAAM,SAAS,OAAO,MAC3DyH,EAAM,aAAazH,EAAK,MAAM1D,EAAK,WAAW,WAAW0D,EAAK,KAAK,CAAC;GAE5E,CAAC,GAMD,EAAM,YAAY,IAAIsmB,EAAQ,GAJXH,EACd,QAAO,MAAQ1e,EAAM,aAAazH,CAAI,CAAC,CAAC,CACxC,KAAI,MAAQ,GAAGA,EAAK,IAAIyH,EAAM,aAAazH,CAAI,EAAE,EAEZ,CAAC,CAAC,KAAK,GAAG,EAAE,KAAKsmB,EAAQ,IACnE7e,EAAM,aAAa,YAAY,GAAG;EACtC,CAAC,GAED4e,EAAK,iBAAiB,wCAAwC,CAAC,CAAC,SAAQ,MAAS;GAC7E,IAAMK,IAAWjf,EAAM,aAAa,WAAW;GAC/C,IAAIif,GAAU;IACV,IAAMC,IAAkBlf,EAAM,WACxB6e,IAAU,QAAQI;IAKxB,EAAM,YAAY,IAAIJ,EAAQ,GAJXH,EACd,QAAO,MAAQ1e,EAAM,aAAazH,CAAI,CAAC,CAAC,CACxC,KAAI,MAAQ,GAAGA,EAAK,IAAIyH,EAAM,aAAazH,CAAI,EAAE,EAEZ,CAAC,CAAC,KAAK,GAAG,EAAE,YAAY2mB,EAAgB,MAAML,EAAQ;GACpG;EACJ,CAAC;CACL;CAEA,OAAOlB,GAAmB,GAAM,GAAK;EACjC,IAAMwB,IAAatqB,EAAK,aAAa,WAAW,MAAM,QAChDuqB,IAAc/mB,EAAI,aAAa,WAAW,MAAM;EAEtD,EAAI,iBAAiB,oFAAoF,CAAC,CAAC,SAAQ,MAAQ;GACvH,IAAMgnB,IAAiBxV,EAAK,aAAa,WAAW,MAAM,UAAUuV,KAAeD;GAInF,AAFAtV,EAAK,aAAa,aAAawV,IAAiB,SAAS,OAAO,GAE5DA,KACAxV,EAAK,YAAY,SAAS,cAAc,0BAA0B,CAAC;EAE3E,CAAC;CACL;CAEA,OAAO6T,GAAkB,GAAK;EAE1B,EAAI,iBAAiB,oBAAoB,CAAC,CAAC,SAAQ,MAAQ;GAEvD,IADsB7T,EAAK,aAAa,aAAa,MAAM,UAAUA,EAAK,aAAa,YAAY,MAAM,QACrF;GAEpB,IAAMrU,IAAW,SAASqU,EAAK,QAAQ,KAAK,EAAE,GACxCpB,IAAUoB,EAAK,WAAW,GAC1Bb,IAAM3Q,EAAI,cAAc,0BAA0B7C,EAAS,GAAG,GAE9D8pB,IAAetW,KAAO,SAASA,EAAI,aAAa,OAAO,GAAG,EAAE,KAAK;GAEvE,CAAI,CAACa,EAAK,QAAQ,eAAe,SAASA,EAAK,QAAQ,aAAa,EAAE,KAAA,QAClE,EAAK,QAAQ,cAAc,OAAOyV,IAAA,KAAiCA,IAAe,GAAG;GAGzF,IAAIC,IAAY1V,EAAK,cAAc,uBAAuB;GAQ1D,IAPK0V,MACD,IAAY,SAAS,cAAc,uBAAuB,GAC1D1V,EAAK,aAAa0V,GAAW1V,EAAK,UAAU,IAG5BA,EAAK,aAAa,WAAW,MAAM,QAEtC;IAIb,AAHA0V,EAAU,UAAU,IAAI,WAAW,GACnCA,EAAU,UAAU,OAAO,QAAQ,GACnCA,EAAU,aAAa,aAAa,MAAM,GAC1C,EAAK,MAAM,QAAQ;IAEnB,IAAMC,IAAc,KAAK,IAAI,IAAI,KAAK,MAAA,KAAwB/W,CAAO,CAAC;IACtE,IAAI,CAAC,MAAMjT,CAAQ,GACf,KAAK,IAAI6B,IAAI,GAAGA,IAAIoR,GAAS,KAAK;KAC9B,IAAM+M,IAAYnd,EAAI,cAAc,0BAA0B7C,IAAW6B,EAAE,GAAG;KAC9E,AAAIme,MACAA,EAAU,aAAa,SAASgK,CAAW,GAC3C,EAAU,MAAM,QAAQ,GAAGA,EAAY;IAE/C;GAER,OAII,AAHAD,EAAU,UAAU,OAAO,WAAW,GACtCA,EAAU,UAAU,IAAI,QAAQ,GAChCA,EAAU,aAAa,aAAa,OAAO,GAC3C,EAAK,MAAM,QAAQ;EAE3B,CAAC;CACL;CAEA,OAAOlC,GAAoB,GAAK,GAAM;EAElC,IAAMxpB,IAAIwE,EAAI,aAAa,eAAe,MAAM,SAAS,KAAK,GAExDkd,IAAWld,EAAI,cAAc,UAAU,GAGvC2Q,IAAM,SAAS,cAAc,KAAK;EAQxC,AANAA,EAAI,aAAa,SAAS,MAAM,GAChCA,EAAI,aAAa,SAASnV,CAAC,GAC3B,EAAI,MAAM,QAAQ,GAAGA,EAAE,KACvB0hB,EAAS,QAAQvM,CAAG,GAGpB3Q,EAAI,iBAAiB,qBAAqB,CAAC,CAAC,SAAQ,MAAW;GAC3D,IAAMonB,IAAO,MAAM,KAAKC,EAAQ,iBAAiB,IAAI,CAAC;GACtD,IAAID,EAAK,WAAW,GAAG;GAEvB,IAAMnc,IAAUmc,EAAK,IAEfE,IAAgB,SAAS,cAAc,IAAI;GAQjD,AAPA,EAAc,YAAY,iBAC1BA,EAAc,aAAa,aAAa,eAAe,GAEnDF,EAAK,SAAS,MACd,EAAc,UAAUA,EAAK,SAGjCnc,EAAQ,aAAaqc,GAAerc,EAAQ,iBAAiB;EACjE,CAAC;CACL;CAEA,OAAOsa,GAAwB,GAAK;EAEhC,EAAI,iBAAiB,4BAA4B,CAAC,CAAC,SAAQ,MAAQ;GAE/D,IAAMgC,IAAc,SAAS/V,EAAK,aAAa,UAAU,GAAG,EAAE;GAC9D,IAAI,MAAM+V,CAAW,GAAG;GAGxB,IAAMnX,IAAU,SAASoB,EAAK,aAAa,SAAS,KAAKA,EAAK,SAAS,EAAE,KAAK,GAC1EkD,IAAa;GAGjB,KAAK,IAAI1V,IAAI,GAAGA,IAAIoR,GAAS,KAAK;IAC9B,IAAMoX,IAAYD,IAAcvoB,GAC1B2R,IAAM3Q,EAAI,cAAc,0BAA0BwnB,EAAU,GAAG;IACrE,AAAI7W,MACA,KAAc,SAASA,EAAI,aAAa,OAAO,GAAG,EAAE,KAAK;GAEjE;GAEA,IAAI+D,IAAa,GAAG;IAChB,IAAM0R,IAAW,GAAG1R,EAAW;IAG/B,AAFA,EAAK,MAAM,QAAQ0R,GACnB,EAAK,MAAM,WAAWA,GACtB,EAAK,MAAM,WAAWA;GAC1B;EACJ,CAAC;CACL;AACJ,GCnVaqB,IAAb,cAAoC,YAAY;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CAEA,KAAU,EACN,OAAO,KACX;CAEA;CAEA,OAAO,iBAAiB;CAExB,cAAc;EAIV,AAHA,MAAM,GAEN,KAAKlrB,KAAQ,KAAK,YAAY,CAAC,CAAC,MAChC,KAAKmrB,KAAc,IAAI9d,EAAW,IAAI;CAC1C;CAEA,oBAAoB;EAChB,KAAKvK,GAAM;CACf;CAEA,IAAI,QAAQ;EAAE,OAAO,KAAKsoB;CAAQ;CAClC,IAAI,aAAa;EAAE,OAAO,KAAKC;CAAa;CAC5C,IAAI,YAAY;EAAE,OAAO,KAAKC;CAAY;CAC1C,IAAI,WAAW;EAAE,OAAO,KAAKC;CAAW;CACxC,IAAI,WAAW;EAAE,OAAO,KAAKC;CAAW;CACxC,IAAI,SAAS;EAAE,OAAO,KAAKC;CAAS;CACpC,IAAI,aAAa;EAAE,OAAO,KAAKN;CAAa;CAC5C,IAAI,YAAY;EAAE,OAAO,KAAKO;CAAgB;CAC9C,IAAI,aAAa;EAAE,OAAO,KAAKC;CAAiB;CAChD,IAAI,iBAAiB;EAAE,OAAO,KAAKC,GAAQ,MAAM,GAAG,UAAU;CAAG;CAEjE,IAAI,WAAW;EAAE,OAAO,KAAKnlB;CAAW;CAExC,IAAI,eAAe;EACf,IAAMolB,IAAW,KAAK,aAAa,cAAc,MAAM,UAAU,KAAK7rB,IAAO,aAAa,cAAc,MAAM,QACxG8rB,IAAkB,KAAKF,GAAQ,OAAO,aAAa,cAAc,MAAM;EAC7E,OAAOC,KAAYC;CACvB;CAEA,IAAI,cAAc;EACd,OAAO,KAAKF,GAAQ;CACxB;CAEA,IAAI,SAAS;EACT,OAAO,KAAKA;CAChB;CAEA,IAAIG,KAAY;EACZ,OAAO,KAAK/rB,GAAM,aAAa,QAAQ,KAAK,KAAKA,GAAM,aAAa,OAAO,MAAM;CACrF;CAEA,sBAAsB;EAClB,AAAK,KAAK4rB,GAAQ,UAElBxY,EAAc,UAAU,KAAKwY,GAAQ,KAAK,GAE1C;GAAC;GAAQ;GAAS;EAAM,CAAC,CAAC,SAAQ,MAAQ;GACtC;IAAC;IAAU;IAAQ;GAAQ,CAAC,CAAC,SAAQ,MAAW;IAC5C,IAAM7b,IAAY,KAAK,cAAc,aAAa+a,EAAQ,iBAAiBvnB,GAAM;IACjF,AAAKwM,KACLA,EAAU,iBAAiB,OAAO,CAAC,CAAC,SAAQ,MAAOtM,EAAI,OAAO,CAAC;GACnE,CAAC;EACL,CAAC,GAED,KAAKuoB,GAAuB,GAE5B,KAAKC,GAAuB,GAE5B,KAAKd,GAAY,WAAW,GAExB,KAAK,eACL,KAAK,QAAQ,EAAI,IAEjB,KAAK,cAAc,uBAAuB,CAAC,EAAE,QAAQ,GAGzD,4BAA4B;GAExB,AADA,KAAKc,GAAuB,GAC5B,KAAKd,IAAa,QAAQ;EAC9B,CAAC;CACL;CAEA,gBAAgB;EAEZ,4BAA4B;GAExB,AAAK,KAAK,UAAU,SAAS,QAAQ,KAAM,KAAKS,GAAQ,UAExD,KAAKK,GAAuB,GAExB,KAAK,eACL,KAAK,QAAQ,EAAI,IAEjB,KAAK,cAAc,uBAAuB,CAAC,EAAE,QAAQ,GAGzD,KAAKC,GAAe,GAEpB,KAAKb,IAAa,cAAc,GAEhC,KAAKF,IAAa,QAAQ;EAC9B,CAAC;CACL;CAEA,WAAuB;EACnB,IAAMgB,IAAS,KAAK,cAAc,0BAA0B,GACtDC,IAAW,KAAK,cAAc,iBAAiB;EACrD,EAAS,MAAM,MAAM,GAAGD,EAAO,aAAa;CAChD;CAEA,IAAI,OAAO;EAIP,OAHI,CAAC,KAAK1J,MAAS,KAAKziB,IAAO,SAC3B,KAAKyiB,KAAQ,IAAI2E,EAAU,IAAI,IAE5B,KAAK3E;CAChB;CAEA,mBAAmB;EAMf,AAJA,KAAK,KAAK,QAAQ,GAElB,KAAK0I,GAAY,QAAQ,EAAI,GAEzB,KAAK,gBACL,KAAK,QAAQ,EAAI;CAEzB;CAEA,WAAW,IAAS,OAAS;EACzB,4BAA4B;GACxB,KAAKkB,KAAWC,CAAM;EAC1B,CAAC;CACL;CAEA,MAAY,IAAS,OAAS;EAE1B,IAAMvc,IAAY,KAAK,cAAc,mCAAmC;EACxE,IAAI,CAACA,GAAW;EAEhB,IAAMmI,IAAgB,KAAK,cAAc,mCAAmC;EAC5E,IAAKA,GAEL;OAAIoU,GAAQ;IACR,KAAK,aAAa,gBAAgB,MAAM;IACxC,IAAM3C,IAAiB5Z,EAAU;IACjC,IAAI4Z,KAAkB,GAAG;IAEzB,IAAI4C,IAAqB,GACnBC,IAAU,CAAC;IAEjB,EAAc,iBAAiB,KAAK,CAAC,CAAC,SAAQ,MAAO;KACjD,IAAMhU,IAAiBpE,EAAI,aAAa,UAAU;KAIlD,IAHmB,KAAK,cAAc,sBAAsBoE,EAAe,GAC9C,CAAC,EAAE,aAAa,WAAW,MAAM,QAG1D,EAAQ,QAAQ;MAAE;MAAgB,OAAO;MAAI,aAAa;KAAK,CAAC;UAC7D;MACH,IAAMvZ,IAAI,SAASmV,EAAI,aAAa,OAAO,GAAG,EAAE,KAAK;MAErD,AADAoY,EAAQ,KAAK;OAAE;OAAgB,OAAOvtB;OAAG,aAAa;MAAM,CAAC,GAC7D,KAAsBA;KAC1B;IACJ,CAAC;IAED,IAAMwtB,IAAsBD,EACvB,QAAO,MAAK1Y,EAAE,WAAW,CAAC,CAC1B,QAAQ,GAAK,MAAMtG,IAAMsG,EAAE,OAAO,CAAC,GAElC4Y,IAAiB,KAAK,IAAI,GAAG/C,IAAiB8C,CAAmB;IAEvE,IAAIF,IAAqB,KAAKC,EAAQ,SAAS,GAAG;KAC9C,IAAIG,IAAiB,GAEfC,IAAiBJ,EAAQ,KAAI,MAAQ;MACvC,IAAIrqB,EAAK,aACL,OAAO;OAAE,gBAAgBA,EAAK;OAAgB,WAAW;OAAG,OAAO;MAAG;MAG1E,IAAM0qB,IAAc1qB,EAAK,QAAQuqB,IAAkBH,GAC7CO,IAAY,KAAK,IAAI,IAAI,KAAK,MAAMD,CAAU,CAAC;MAErD,OADA,KAAkBC,GACX;OACH,gBAAgB3qB,EAAK;OACrB,WAAW0qB,IAAa,KAAK,MAAMA,CAAU;OAC7C,OAAOC;MACX;KACJ,CAAC,GAEGC,IAAkBL,IAAiBC,GAEjCK,IAAkBJ,EAAe,QAAO,MAAK,CAACJ,EAAQ,MAAK,MAAQrqB,EAAK,mBAAmB2R,EAAE,cAAc,CAAC,EAAE,WAAW;KAE/H,IAAIiZ,IAAkB,KAAKC,EAAgB,SAAS,GAAG;MACnD,EAAgB,MAAM,GAAG,MAAMjrB,EAAE,YAAYC,EAAE,SAAS;MACxD,KAAK,IAAIS,IAAI,GAAGA,IAAIsqB,GAAiB,KACjC,EAAgBtqB,IAAIuqB,EAAgB,OAAO,CAAC,SAAS;KAE7D,OAAO,IAAID,IAAkB,KAAKC,EAAgB,SAAS,GAAG;MAC1D,EAAgB,MAAM,GAAG,MAAMhrB,EAAE,YAAYD,EAAE,SAAS;MACxD,KAAK,IAAIU,IAAI,GAAGA,IAAI,KAAK,IAAIsqB,CAAe,GAAG,KAAK;OAChD,IAAM9uB,IAAS+uB,EAAgBvqB,IAAIuqB,EAAgB;OACnD,AAAI/uB,EAAO,QAAQ,MAAI,IAAO;MAClC;KACJ;KAEA,EAAe,SAAS,EAAE,mBAAgB,eAAY;MAClD,KAAKotB,IAAa,eAAe7S,GAAgBG,GAAO,MAAM;KAClE,CAAC;IACL;GACJ,OACI,KAAK,gBAAgB,cAAc;GAGvC,KAAK,cAAc,uBAAuB,CAAC,EAAE,QAAQ;EAHd;CAI3C;CAEA,YAAY,GAAQ,MAAU;EAgD1B,AA9CA,EAAO,MAAM,UAAU,QAEvB,KAAKyS,KAAShnB,GAEdikB,EAAY,gBAAgB,KAAKroB,IAAOqT,CAAM,GAE9C,EAAO,MAAM,UAAU,IAEvB,KAAKuY,KAAU;GACX,OAAOxY,EAAc,QAAQC,CAAM;GACnC,OAAO,EACH,IAAIA,EAAO,iBAAiB,UAAU,EAC1C;EACJ,GAEA,KAAK2Y,GAAuB,GAE5B,KAAKC,GAAuB,GAE5B,KAAKgB,GAA4B,GAEjC,KAAKC,GAAmB,GAExB;GAAC;GAAQ;GAAQ;EAAO,CAAC,CAAC,SAAQ,MAAQ;GACtC,IAAMC,IAAS,iBAAiB5pB;GAChC,KAAKkD,GAAUlD,KAAQ;IACnB,OAAO,KAAK,cAAc,GAAG4pB,EAAO,OAAO;IAC3C,OAAO;KACH,MAAM,KAAK,cAAc,GAAGA,EAAO,YAAY;KAC/C,MAAM,KAAK,cAAc,GAAGA,EAAO,YAAY;KAC/C,MAAM,KAAK,cAAc,GAAGA,EAAO,YAAY;IACnD;IACA,OAAO,KAAK,cAAc,GAAGA,EAAO,OAAO;GAC/C;EACJ,CAAC,GAED,KAAKhC,GAAY,WAAW,GAExB,KAAK,eACL,KAAK,QAAQ,EAAI,IAEjB,KAAK,cAAc,uBAAuB,CAAC,CAAC,QAAQ,GAGxD,KAAKI,GAAU,WAAW,GAE1B,KAAK,SAAS;CAClB;CAGA,WAA+B;EAE3B;GAAC;GAAQ;GAAS;EAAM,CAAC,CAAC,SAAQ,MAAQ;GACtC,IAAM1W,IAAa,KAAK,iBAAiB,iBAAiBtR,GAAM;GAChE,IAAIsR,EAAW,WAAW,GAAG;GAE7B,IAAMuY,IAAavY,EAAW,EAAE,CAAC,cAAc,OAAO;GACtD,IAAI,CAACuY,GAAY;GAEjB,IAAIzU,IAAQ;GAMZ,AALAyU,EAAW,iBAAiB,KAAK,CAAC,CAAC,SAAQ,MAAO;IAC9C,IAAMnuB,IAAI,SAASmV,EAAI,aAAa,OAAO,GAAG,EAAE;IAChD,AAAK,MAAMnV,CAAC,MAAG,KAASA;GAC5B,CAAC,GAED4V,EAAW,SAAQ,MAAa;IAE5B,AADe9E,EAAU,iBAAiB,OAAO,GAC7CxM,MAAS,SACT,EAAU,MAAM,OAAO,OAEvB,EAAU,MAAM,OAAO,OAAOoV,EAAM,KACpC,EAAU,MAAM,QAAQ,GAAGA,EAAM,KACjC,EAAU,MAAM,WAAW,GAAGA,EAAM,KACpC,EAAU,MAAM,WAAW,GAAGA,EAAM;GAE5C,CAAC;EACL,CAAC;CACL;CAEA,WAA+B;EAO3B;GALI;IAAE,UAAU;IAAsB,MAAM;GAAO;GAC/C;IAAE,UAAU;IAAsB,MAAM;GAAK;GAC7C;IAAE,UAAU;IAAuB,MAAM;GAAQ;EAG9C,CAAC,CAAC,SAAS,EAAE,aAAU,cAAW;GACrC,KAAK,cAAc,kBAAkB3I,GAAU,CAAC,CAAC,YAAY,KAAKqd,GAAkB9pB,CAAI,CAAC;EAC7F,CAAC;CACL;CAEA,MAAqB,MAAoB;EAErC,IAAMymB,IAAO,KAAK4B,GAAQ,MAAM,UAAU,EAAI;EAgB9C,OAdIxZ,MAAoB,SACpB4X,EAAK,iBAAiB,aAAa,CAAC,CAAC,SAAQ,MAAO;GAChD,AAAIjZ,EAAI,aAAa,OAAO,MAAM,UAAQA,EAAI,OAAO;EACzD,CAAC,IACMqB,MAAoB,UAC3B4X,EAAK,iBAAiB,aAAa,CAAC,CAAC,SAAQ,MAAO;GAChD,AAAIjZ,EAAI,aAAa,OAAO,MAAM,WAASA,EAAI,OAAO;EAC1D,CAAC,IAEDiZ,EAAK,iBAAiB,6BAA6B,CAAC,CAAC,SAAQ,MAAO;GAChE,EAAI,OAAO;EACf,CAAC,GAGEA;CACX;CAEA,qBACW,KAAKmB,GAAY,aAAa;CAGzC,uBAEuB,KAAK1kB,GAAU,QAAQ,gBAAgB,OAErC,KAAKA,GAAU,KAAK,OAAO,gBAAgB,MAC3D,KAAKA,GAAU,KAAK,OAAO,gBAAgB,MAC3C,KAAKA,GAAU,KAAK,MAAM,KAAK,gBAAgB;CAKxD,kBAAkB;EAEd,IAAM/B,IAAQ,KAAK,cAAc,gBAAgB,GAC3CwM,IAAQ,KAAK,cAAc,+BAA+B,GAE1Doc,IAAgB,KAAK7mB,GAAU,KAAK,OAAO,gBAAgB,GAE3D8mB,IAAc7oB,EAAM,sBAAsB,CAAC,CAAC,QAC5C8oB,IAActc,EAAM,sBAAsB,CAAC,CAAC;EAElD,OAAQqc,IAAcD,KAAiBE;CAC3C;CAEA,aAAa,MAAe;EACxB,IAAMC,IAAgB,KAAK,cAAc,mCAAmC;EAC5E,AAAIA,MAAe,EAAc,aAAaC;CAClD;CAEA,aAAa,MAAc;EACvB,IAAMjgB,IAAe,KAAK,cAAc,gBAAgB;EACxD,AAAIA,MAAc,EAAa,YAAYQ;CAC/C;CAEA,WAAc;EAkBV,AAhBA,KAAKhK,GAAQ,GAEb,KAAKynB,KAAiB,IAAI3X,EAAc,IAAI,GAC5C,KAAK4X,KAAkB,IAAI3V,EAAe,IAAI,GAC9C,KAAKqV,KAAc,IAAI1T,EAAW,IAAI,GACtC,KAAK6T,KAAY,IAAI3P,EAAS,IAAI,GAClC,KAAK4P,KAAU,IAAInK,EAAc,IAAI,GAErC,KAAKmB,KAAQ,IAAI2E,EAAU,IAAI,GAC/B,KAAKkE,KAAa,IAAIhG,EAAU,IAAI,GACpC,KAAKiG,KAAY,IAAIxgB,EAAgB,IAAI,GAEpC,KAAKghB,OACN,KAAK4B,KAAW,IAAIpH,EAAQ,IAAI,IAGpC,KAAK9f,GAAU,SAAS,iBAAiB,gBAAgB;GACrD,KAAK,cAAc,uBAAuB,CAAC,CAAC,QAAQ;EACxD,CAAC;CACL;CAIA,WAAgB;EAwBZ,AAtBA,KAAK,YAAY,k1BAsBjB,KAAKA,KAAY;GACb,UAAU,KAAK,cAAc,mCAAmC;GAChE,YAAY,KAAK,cAAc,uBAAuB;GACtD,YAAY,KAAK,cAAc,uBAAuB;GACtD,SAAS,KAAK,cAAc,uCAAuC;GACnE,cAAc,KAAK,cAAc,0CAA0C;EAC/E;CACJ;CAEA,WAAoC;EAEhC,IAAM+L,IAAY,KAAK,cAAc,0BAA0B,GACzDC,IAAY,KAAK,cAAc,0BAA0B,GACzDC,IAAa,KAAK,cAAc,2BAA2B,GAE3Dkb,IAAiB,MAAM,KAAKpb,EAAU,iBAAiB,uCAAuC,CAAC,GAC/Fqb,IAAiB,MAAM,KAAKpb,EAAU,iBAAiB,uCAAuC,CAAC,GAC/Fqb,IAAkB,MAAM,KAAKpb,EAAW,iBAAiB,uCAAuC,CAAC;EAEvG,KAAKqb,GAAiBH,GAAgBC,GAAgBC,CAAe;EAErE,IAAME,IAAiB,MAAM,KAAKxb,EAAU,iBAAiB,UAAU,CAAC,GAClEyb,IAAiB,MAAM,KAAKxb,EAAU,iBAAiB,UAAU,CAAC,GAClEyb,IAAkB,MAAM,KAAKxb,EAAW,iBAAiB,UAAU,CAAC;EAE1E,KAAKqb,GAAiBC,GAAgBC,GAAgBC,CAAe;CACzE;CAEA,MAAoB,GAAU,GAAU,MAAc;EAElD,iBAAiB;GACb,IAAMpb,IAAU,KAAK,IAAIH,EAAS,QAAQC,EAAS,QAAQC,EAAU,MAAM;GAE3E,KAAK,IAAI,IAAI,GAAG,IAAIC,GAAS,KAAK;IAE9B,IAAMC,IAAU;KACZJ,EAAS,EAAE,EAAE,sBAAsB,CAAC,CAAC,UAAU;KAC/CC,EAAS,EAAE,EAAE,sBAAsB,CAAC,CAAC,UAAU;KAC/CC,EAAU,EAAE,EAAE,sBAAsB,CAAC,CAAC,UAAU;IACpD,GACMG,IAAY,KAAK,IAAI,GAAGD,CAAO;IAErC,AAAIC,IAAY,MACRL,EAAS,OAAI,EAAS,EAAE,CAAC,MAAM,SAAS,GAAGK,EAAU,MACrDJ,EAAS,OAAI,EAAS,EAAE,CAAC,MAAM,SAAS,GAAGI,EAAU,MACrDH,EAAU,OAAI,EAAU,EAAE,CAAC,MAAM,SAAS,GAAGG,EAAU;GAEnE;EACJ,CAAC;CACL;CAEA,WAA2B;EACvB,IAAMvF,IAAe,KAAK,cAAc,gBAAgB;EACxD,IAAI,CAACA,GAAc;EAEnB,IAAI0gB,IAAiB;EAerB,AAbA1gB,EAAa,iBAAiB,cAAc,MAAM;GAC9C,IAAM6C,IAAKlI,EAAE,OAAO,QAAQ,IAAI;GAChC,IAAI,CAACkI,KAAM,CAACA,EAAG,QAAQ,OAAOA,EAAG,QAAQ,QAAQ,KAAK;GAEtD,IAAM3P,IAAW2P,EAAG,QAAQ;GAC5B,AAAI6d,MAAmBxtB,MACvB,IAAiBA,GAEjB8M,EAAa,iBAAiB,gBAAgB9M,EAAS,GAAG,CAAC,CAAC,SAAQ,MAAO;IACvE,EAAI,UAAU,IAAI,OAAO;GAC7B,CAAC;EACL,CAAC,GAED8M,EAAa,iBAAiB,aAAa,MAAM;GAC7C,IAAM6C,IAAKlI,EAAE,OAAO,QAAQ,IAAI;GAChC,IAAI,CAACkI,GAAI;GAET,IAAM8d,IAAgBhmB,EAAE;GACxB,AAAIkI,EAAG,SAAS8d,CAAa,MAE7B3gB,EAAa,iBAAiB,UAAU,CAAC,CAAC,SAAQ,MAAO;IACrD,EAAI,UAAU,OAAO,OAAO;GAChC,CAAC,GACD,IAAiB;EACrB,CAAC;CACL;CAEA,uBAAuB;EAGnB,AAFA,KAAK4d,IAAa,QAAQ,GAC1B,KAAKG,IAAW,QAAQ,GACxB,KAAK,YAAY;CACrB;AACJ;AAEK,eAAe,IAAI,kBAAkB,KACtC,eAAe,OAAO,oBAAoBN,CAAc;;ACxhB5D,IAAamD,IAAb,MAA2B;CACvB;CAEA,YAAY,GAAO;EAEf,AADA,KAAKruB,KAAQsuB,GACb,KAAKxrB,GAAM;CACf;CAEA,WAAc;EAGV,AAFA,KAAKmB,GAAQ,GAEb,IAAI,gBAAgB,MAAY;GAC5B,KAAK,IAAIgP,KAASC,GAEd,AADqB,KAAKlT,GAAM,aAAa,aAAa,MAAM,UAE5D,KAAKuuB,GAAiB;EAGlC,CAAC,CAAC,CAAC,QAAQ,KAAKvuB,EAAK;CACzB;CAEA,IAAI,QAAQ,GAAK;EACb,AAAMwb,IACF,KAAKxb,GAAM,UAAU,IAAI,SAAS,IAElC,KAAKA,GAAM,UAAU,OAAO,SAAS;CAE7C;CAEA,WAAyB;EACrB,IAAMyE,IAAe,MAAM,KAAK,KAAKzE,GAAM,WAAW,iBAAiB,yBAAyB,CAAC;EACjG,IAAIyE,EAAa,WAAW,GAAG;EAE/B,IAAM+pB,IAAiB,SAAS,KAAKxuB,GAAM,aAAa,iBAAiB,GAAG,EAAE,KAAK,IAC7EyuB,IAAe,KAAK,IAAI,GAAGhqB,EAAa,KAAI,MAASC,EAAM,aAAa,CAAC,CAAC,GAE1EgqB,IAAY,KAAK1uB,GAAM,WAAW,cAAc,oBAAoB,GACpE2uB,IAAW,KAAK3uB,GAAM,WAAW,cAAc,0BAA0B,GAEzE4uB,IAAgBF,IAAYA,EAAU,sBAAsB,CAAC,CAAC,SAAS,GACvEG,IAAeF,IAAWA,EAAS,sBAAsB,CAAC,CAAC,SAAS,GACpExT,IAAe+P,EAAe,gBAE9B4D,IAAoBN,IAAiBC,IAAgBG,IAAgBC,IAAe1T;EAE1F,KAAKnb,GAAM,MAAM,SAAS,GAAG8uB,EAAiB;CAClD;CAEA,WAAgB;EAGZ,IAAMtrB,IADc,MAAM,KAAK,KAAKxD,GAAM,QACd,CAAC,CAAC,QAAO,MAAO7B,EAAG,QAAQ,YAAY,MAAM,OAAS,GAC5E4wB,IAAe,KAAK/uB,GAAM,aAAa,aAAa,MAAM,QAC1DgvB,IAAaxrB,EAAU,QAEvByrB,IAAazrB,EAAU,KAAK,GAAK,MAAQ;GAC3C,IAAM0rB,IAAYzuB,MAAQ,IAAI,WAAW,IACnC0uB,IAAU1rB,EAAI,MAAM,QAAQhD,IAAM;GAIxC,OAAO,4BAFsCyuB,EAAU,gBAAgBzuB,EAAI,mBAAmB0uB,EAAQ,QAAQA,EAAQ,0BAClG1uB,IAAMuuB,IAAa,IAAI,8CAA8CvuB,EAAI,sBAAsB;EAEvH,CAAC,CAAC,CAAC,KAAK,EAAE,GAEJ2uB,IAAa,CACf,4FACJ;EA2BA,AAzBI,KAAK,iBAAiB,KAAK,aAAa,CAAC,WACzCA,EAAW,KAAK,YAAY,KAAK,aAAa,CAAC,QAAQ,GAAG,GAG9D,KAAKpvB,GAAM,WAAW,YAAY;;kBAExBovB,EAAW,KAAK,IAAI,EAAE;;;;;;;;;;0BAUdH,EAAW;;;;;;;WAS7B,KAAKjvB,GAAM,WAAW,iBAAiB,kBAAkB,CAAC,CAAC,SAAS,GAAK,MAAQ;GAE7E,AAAIwD,EAAU/C,MACV,iBAAiB;IAEb,AADAsQ,EAAI,SAASvN,EAAU/C,IAAMA,CAAG,GAC5BsuB,KACA,KAAKR,GAAiB;GAE9B,CAAC;EAET,CAAC;CACL;AACJ,GC7Gac,IAAb,MAAwB;CACpB;CACA;CACA,qBAAa,IAAI,IAAI;CAErB,YAAY,GAAM;EAEd,AADA,KAAKrvB,KAAQC,GACb,KAAK8C,KAAU9C,EAAK,OAAO,IAAI;CACnC;CAEA,YAAY,GAAM;EAId,OAFI,CAAC2D,KAAQ,CAAC,KAAKb,GAAQ,SAAea,IAEnCA,EAAK,QAAQ,8BAA8B,GAAO,MAAc;GACnE,IAAMnD,IAAM,KAAKsC,GAAQ,QAAQG,CAAS;GAC1C,OAAOzC,KAAO,IAAI,aAAaA,EAAI,KAAK6uB;EAC5C,CAAC;CACL;CAEA,WAAW,GAAM;EAEb,OADK1rB,KACE,KAAK,YAAYA,CAAI;CAChC;CAEA,SAAS,GAAM,GAAS,IAAM,GAAG;EAE7B,IAAIA,KAA+B,MAAM,OAAO;EAEhD,IAAI;GACA,IAAM2rB,IAAc,OAAO3rB,CAAI,CAAC,CAAC,KAAK,GAChC4rB,IAAe,KAAK,YAAYD,CAAW;GAEjD,IAAIC,EAAa,SAAS,WAAW,KAAKA,EAAa,SAAS,OAAO,KAAKA,EAAa,SAAS,OAAO,KAAKA,EAAa,SAAS,WAAW,KAAKA,EAAa,SAAS,GAAG,GAAG;IAE5K,IAAIC,IAAS,KAAKC,GAAW,IAAIF,CAAY;IAc7C,OAZKC,MACD,IAAa,SAAS,WAAW,OAAO,QAAQ;;;;;iCAKnCD,EAAa;qBACzB,GAED,KAAKE,GAAW,IAAIF,GAAcC,CAAM,IAGrCA,EAAOE,GAAS9tB,GAAK,KAAK7B,EAAK;GAC1C;GAEA,OAAOwvB;EACX,QAAY;GAKR,OAAO5rB;EACX;CACJ;AACJ,GCxDqBgsB,IAArB,cAAuC,YAAY;CAC/C;CACA;CACA;CACA,KAAe;CAEf,cAAc;EAQV,AAPA,MAAM,GAEF,CAAC,YAAY,CAAC,CAAC,SAAS,KAAK,OAAO,KACpCpwB,EAAM,IAAI,sBAAA,OAAqC,GAGnD,KAAKqwB,KAAc,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC,GACrD,KAAKC,KAAe,IAAIptB,EAAc,IAAI;CAC9C;CAEA,oBAAoB;EAChB,iBAAiB;GAUb,AATA,KAAKqtB,KAAe,KAAK,iBAAiB,OAAO,CAAC,EAAE,QAEpD,KAAK,SAAS,IAAIhvB,EAAO,IAAI,GAC7B,KAAK,aAAa,IAAIsuB,EAAW,IAAI,GAErC,KAAKW,GAAoB,GAEzB,KAAKC,KAAiB,IAAI5B,EAAc,IAAI,GAE5C,KAAK6B,GAAc;EACvB,CAAC;CACL;CAEA,uBAAuB,CAEvB;CAEA,WAAsB;EAElB,IAAIC,IAAa,GAGXC,IAAa,kBAAkB;GACjC;GAEA,IAAM7rB,IAAS,KAAK,OAAO,iBAAiB,kBAAkB;GAM9D,IAJI4rB,KAAc,MACd,cAAcC,CAAU,GAGxB7rB,EAAO,UAAU,KAAKwrB,IAAc;IACpC,IAAIM,IAAe;IAKnB,AAJA9rB,EAAO,SAAQ,MAAU;KACrB,AAAI+rB,EAAO,UAAQ;IACvB,CAAC,GAEGD,KAAgB,KAAKN,OACrB,cAAcK,CAAU,GACxB,KAAK,SAAS,IACd,KAAK,cAAc,IAAI,YAAY1wB,EAAW,MAAM,MAAM;KAAE,SAAS;KAAM,QAAQ,EAAE,QAAQ,KAAK;IAAE,CAAC,CAAC;GAE9G;EACJ,GAAG,GAAG;CACV;CAGA,IAAI,SAAS;EAAE,OAAO,KAAKmwB;CAAa;CACxC,IAAI,cAAc;EAAE,OAAO,KAAKC;CAAc;CAC9C,IAAI,OAAO;EAAE,OAAO,KAAKA,GAAa;CAAM;CAC5C,IAAI,MAAM;EAAE,OAAO,KAAKA,GAAa;CAAK;CAG1C,YAAY,GAAS;EACjB,AAAKS,KAAW,OAAOA,KAAY,YAEnC,iBAAiB;GAOb,AANA,OAAO,QAAQA,CAAO,CAAC,CAAC,SAAS,CAACjtB,GAAMktB,OAAQ;IAC5C,AAAI,OAAOA,KAAO,eACd,KAAKltB,KAAQktB;GAErB,CAAC,GAED,KAAK,WAAW;EACpB,CAAC;CACL;CAEA,QAAQ,GAAS;EAEb,AADA,KAAKV,GAAa,KAAK,IAAI9iB,CAAO,GAClC,KAAK,QAAQ;CACjB;CAEA,UAAU;EACN,KAAK,aAAa,WAAW;CACjC;CAGA,IAAI,QAAQ,GAAK;EACb,AAAI,KAAKijB,OAAgB,KAAKA,GAAe,UAAUzU;CAC3D;CAEA,aAAa;EAET,KAAK,aAAa,iBAAiB,6BAA6B,CAAC,CAAC,SAAS,MAAU;GAKjF,MAJyB,KAAKpQ,EAAM,QAAQ,CAAC,CAAC,MAAK,MACxC2F,EAAI,QAAQ,YAAY,CAAC,CAAC,WAAW,OAAO,KAAK,OAAOA,EAAI,cAAe,UAG7E,CAAC,EAAE,WAAW;EAC3B,CAAC;CACL;CAEA,SAAS,MAAc;EACnB,IAAI0f,MAAc,QAAQA,IAAY,GAAG,OAAO,KAAK;EACrD,IAAMlsB,IAAS,MAAM,KAAK,KAAK,OAAO,iBAAiB,kBAAkB,CAAC;EAM1E,OAJI,OAAOksB,KAAc,WAAiBlsB,EAAOksB,MAAc,OAC3D,OAAOA,KAAc,WACd,KAAK,OAAO,cAAc,oBAAoBA,EAAU,oCAAoCA,EAAU,GAAG,KAAK,OAElHlsB,EAAO,MAAM;CACxB;CAEA,IAAI,SAAS;EACT,OAAO,MAAM,KAAK,KAAK,OAAO,iBAAiB,kBAAkB,CAAC;CACtE;CAEA,IAAI,cAAc;EACd,OAAO,KAAK,OAAO,cAAc,yBAAyB,KAAK;CACnE;CAEA,KAAsB;EAClB,IAAMmsB,oBAAuB,IAAI,IAAI;EAerC,AAbA,KAAK,iBAAiB,eAAe,CAAC,CAAC,SAAQ,MAAM;GACjD,IAAMtvB,IAAajD,EAAG,aAAa,aAAa;GAChD,IAAI,CAACiD,GAAY;GAEjB,IAAMuvB,IAAUvvB,EAAW,SAAS,mCAAmC;GACvE,KAAK,IAAMkuB,KAASqB,GAAS;IACzB,IAAMrtB,IAAOgsB,EAAM;IACnB,AAAIhsB,KAAQA,MAAS,UACjBotB,EAAqB,IAAIptB,CAAI;GAErC;EACJ,CAAC,GAEDotB,EAAqB,SAAQ,MAAc;GACvC,IAAIE,IAAgB;GAEpB,OAAO,eAAe,MAAMC,GAAY;IACpC,MAAM,MAAa;KAGf,AAFA,IAAgBC,GAEhB,KAAK,WAAW;IACpB;IACA,WAAWF;IACX,cAAc;IACd,YAAY;GAChB,CAAC;EACL,CAAC;CACL;CAEA,WAAW,MAAO;EACd,iBAAiB;GAEb,AADA,KAAK,UAAU,IACf,iBAAiB;IACb,IAAI;KACA,EAAG,KAAK,IAAI;IAChB,UAAU;KACN,KAAK,UAAU;IACnB;GACJ,CAAC;EACL,CAAC;CACL;AACJ;AAEK,eAAe,IAAI,YAAY,KAChC,eAAe,OAAO,cAAchB,CAAS,GAG5C,eAAe,IAAI,mBAAmB,KACvC,eAAe,OAAO,qBAAqB,cAAcA,EAAU;CAC/D,oBAAoB;EAGhB,AAFA,KAAK,aAAa,SAAS,QAAQ,GAEnC,MAAM,kBAAkB;CAC5B;AACJ,CAAC;;AClML,IAAamB,IAAb,cAAsC,YAAY;CAEjD,cAAc;EACb,MAAM;CACP;CAEA,iBAAiB,CACjB;CAEA,oBAAoB,CACpB;AACD,GCRMC,oBAAY,IAAI,IAAI,GAEbC,IAAb,cAAiCF,EAAiB;CACjD;CACA;CACA;CACA;CACA;CAEA,cAAc;EACb,MAAM;CACP;CAEA,IAAI,OAAO;EAAE,OAAO,KAAK/wB;CAAO;CAChC,IAAI,QAAQ;EAAE,OAAO,KAAK0I;CAAQ;CAClC,IAAI,OAAO;EAAE,OAAO,KAAKwoB;CAAO;CAChC,IAAI,KAAK;EAAE,OAAO,KAAKC;CAAK;CAC5B,IAAI,OAAO;EAAE,OAAO,KAAKC;CAAO;CAEhC,oBAAoB;EAWnB,AAVA,MAAM,kBAAkB,GAExB,KAAKpxB,KAAQ,KAAK,YAAY,CAAC,CAAC,MAEhC,KAAKkxB,KAAQ,KAAK,QAAQ,OAAO,GACjC,KAAKC,KAAM,KAAKD,GAAM,QAAQ,IAAI,GAClC,KAAKxoB,KAAS,KAAKyoB,GAAI,QAAQ,kBAAkB,GAEjD,KAAKD,GAAM,UAAU,IAAI,KAAK,OAAO,GAErC,KAAKE,KAAQ,CAAC;EACd,KAAK,IAAI3uB,IAAI,GAAGA,IAAI,KAAKyuB,GAAM,WAAW,QAAQ,KAAK;GACtD,IAAM5tB,IAAO,KAAK4tB,GAAM,WAAWzuB,EAAE,CAAC;GACtC,AAAK;IAAC;IAAa;IAAQ;IAAY;IAAY;IAAY;IAAW;GAAU,CAAC,CAAC,SAASa,CAAI,MAClG,KAAK8tB,GAAM9tB,KAAQ,KAAK4tB,GAAM,WAAWzuB,EAAE,CAAC;EAG9C;EAEA,IAAI,CAAC,KAAKyuB,IAAO;EAGjB,IAAMlV,IAAO,KAAK,cAAc;EAGhC,EAAK,iBAAiB,0BAA0B,CAAC,CAAC,SAAQ,MAAU;GACnE,EAAO,iBAAiB,eAAe;IACtC,IAAIwU,IAAK,KAAK,aAAa,eAAe,KAAK,KAAK,aAAa,eAAe,KAAK,KAAKU,IAAO,aAAa,eAAe,KAAK,KAAKA,IAAO,aAAa,eAAe,GAEpKxwB,IAAU,KAAK,MACf2wB,IAAS,SAAS,KAAKH,GAAM,QAAQ,KAAK,EAAE;IAElD,IAAIV,KAAM,KAAKxwB,IAAO;KACrB,IAAKwwB,EAAG,QAAQ,MAAM,EAAE;KAExB,IAAMK,IADQL,EAAG,MAAM,aACA,CAAC,GAAG,MAAMA;KAEjC,AAAI,OAAO,KAAKxwB,GAAM6wB,MAAgB,aACrC,KAAK7wB,GAAM6wB,EAAW,CAAC,KAAK,KAAK7wB,IAAOU,GAAS2wB,GAAQ,KAAKH,EAAK,IACzD,OAAO,KAAKlxB,GAAM,gBAAiB,cAC7C,KAAKA,GAAM,aAAawwB,CAAE,CAAC,CAAC,KAAK,MAAM9vB,GAAS2wB,CAAM;IAExD;GAOD,CAAC;EACF,CAAC;EAGD,IAAMC,IAAWtV,EAAK,cAAc,WAAW;EAC/C,AAAIsV,KAAY,KAAK,aAAa,MAAM,MAAM,WAC7CA,EAAS,UAAU,IAAI,MAAM,GAE7BA,EAAS,iBAAiB,eAAe;GACxC,IAAId,IAAK,KAAK,aAAa,aAAa,KAAK,KAAK,aAAa,aAAa,GAEtE9vB,IAAU,KAAK,MACf2wB,IAAS,SAAS,KAAKH,GAAM,QAAQ,KAAK,EAAE;GAElD,IAAIV,KAAM,KAAKxwB,IAAO;IACrB,IAAKwwB,EAAG,QAAQ,MAAM,EAAE;IAExB,IAAMK,IADQL,EAAG,MAAM,aACA,CAAC,GAAG,MAAMA;IAEjC,AAAI,OAAO,KAAKxwB,GAAM6wB,MAAgB,aACrC,KAAK7wB,GAAM6wB,EAAW,CAAC,KAAK,KAAK7wB,IAAOU,GAAS2wB,GAAQ,KAAKH,EAAK,IACzD,OAAO,KAAKlxB,GAAM,gBAAiB,cAC7C,KAAKA,GAAM,aAAawwB,CAAE,CAAC,CAAC,KAAK,MAAM9vB,GAAS2wB,CAAM;GAExD;GAEA,KAAKrxB,IAAO,cAAc,IAAI,YAAY,SAAS,MAAM,YAAY;IACpE,QAAQ;KAAE,QAAQ,KAAKkxB;KAAO,MAAMxwB;KAAS,QAAQ2wB;IAAO;IAC5D,SAAS;IACT,UAAU;GACX,CAAC,CAAC;EACH,CAAC;CAEH;CAEA,IAAI,OAAO;EACV,IAAME,IAAY,KAAKJ,IAAK;EAC5B,IAAI,CAACI,GAAW,OAAO;EACvB,IAAI,CAACA,EAAU,GAAG,OAAOA;EAEzB,IAAMtxB,IAAO,KAAKD;EAElB,OAAO,IAAI,MAAMuxB,GAAW,EAC3B,IAAI,GAAQ,GAAM;GACjB,IAAIC,MAAS,QAAQ,OAAOvzB,EAAO;GACnC,IAAIuzB,MAAS,KAAK,OAAOvzB,EAAO;GAEhC,IAAMwC,IAAMR,GAAM,QAAQ,UAAUuxB,CAAI,KAAK;GAC7C,OAAO/wB,KAAO,IAAIxC,EAAO,EAAEwC,KAAOxC,EAAOuzB;EAC1C,EACD,CAAC;CACF;CAEA,IAAI,QAAQ;EACX,IAAI,CAAC,KAAKN,MAAS,CAAC,KAAKC,IAAK,MAAM,OAAO;EAE3C,IAAM5N,IAAU,KAAK2N,GAAM,SAAS;EACpC,IAAI,CAAC3N,GAAS,OAAO;EAErB,IAAMgO,IAAY,KAAKJ,GAAI;EAE3B,IAAII,EAAU,KAAK,MAAM,QAAQA,EAAU,CAAC,GAAG;GAE9C,IAAMlZ,IAAS,KAAKrY,GAAM,OAAO,IAAI,CAAC,CAAC,QAAQujB,CAAO,KAAK;GAC3D,OAAOlL,KAAU,IAAKkZ,EAAU,EAAElZ,MAAW,KAAM;EACpD;EAEA,OAAOkZ,EAAUhO,MAAY;CAC9B;CAEA,IAAI,MAAM,GAAG;EACZ,IAAI,CAAC,KAAK2N,MAAS,CAAC,KAAKlxB,IAAO,MAAM;EAEtC,IAAM6B,IAAM,SAAS,KAAKqvB,GAAM,QAAQ,KAAK,EAAE,GACzC3N,IAAU,KAAK2N,GAAM,QAAQ;EACnC,IAAI,MAAMrvB,CAAG,KAAK,CAAC0hB,GAAS;EAE5B,IAAMkO,IAAiB,KAAK,aAAa,kBAAkB,MAAM;EACjE,KAAKzxB,GAAM,KAAK,SAAS6B,GAAK0hB,GAASpkB,GAAGsyB,CAAc;CACzD;CAEA,IAAI,MAAM;EACT,OAAO,SAAS,KAAKP,IAAO,SAAS,KAAK,EAAE;CAC7C;CACA,IAAI,QAAQ;EACX,OAAO,SAAS,KAAKA,IAAO,SAAS,OAAO,EAAE;CAC/C;CAEA,UAAU;EACT,OAAO,MAAKA,GAAM,UAAU,SAAS,SAAS;CAC/C;CAEA,YAAY;EACX,OAAO,CAAC,KAAK,QAAQ;CACtB;CAEA,kBAAkB,IAAe,OAAO;EAMvC,IAJI,CAAC,KAAKA,MAAS,CAAC,KAAKA,GAAM,QAAQ,OAAO,KAI1C,CAFc,KAAKC,GAAI,MAEX,OAAOO;EAEvB,IAAM9tB,IAAO,KAAKstB,GAAM,QAAQ,MAC1B3N,IAAU,KAAK2N,GAAM,QAAQ,MAC7BrvB,IAAM,SAAS,KAAKqvB,GAAM,QAAQ,KAAK,EAAE;EAE/C,IAAIttB,GACH,IAAI;GAKF,OAJG,KAAKutB,GAAI,aAAa,UAAU,MAAM,SAElC,KAAK,kBAAkBvtB,GAAM,KAAKutB,GAAI,MAAMtvB,GAAK,KAAKqvB,EAAK,IAE3D,KAAKlxB,GAAM,WAAW,SAAS4D,GAAM,KAAKutB,GAAI,MAAMtvB,CAAG;EAEhE,QAAY;GACX,OAAO6vB;EACR;EAQD,OALInO,IACS,KAAK,SACgCmO,IAG3CA;CACR;CAIA,UAAU;EAET,IAAI,CAAC,KAAKR,MAAS,CAAC,KAAKC,IAAK;EAE9B,IAAM3V,IAAM,KAAK;EAgCjB,OA9BA,KAAK0V,GAAM,UAAU,OAAO,SAAS,GAErC;GAAC;GAAQ;GAAa;GAAmB;GAAU;GAAS;EAAW,CAAC,CAAC,SAAQ,MAAK;GAErF,IAAMttB,IAAO,KAAKwtB,GAAMjyB;GACxB,IAAIyE,GAAM;IACT,IAAMpB,IAAS,KAAKxC,GAAM,WAAW,SAAS4D,GAAM,KAAKutB,GAAI,MAAM,SAAS,KAAKD,GAAM,QAAQ,KAAK,EAAE,CAAC;IAEvG,AAAI/xB,MAAM,cACJqD,KACJ,KAAK0uB,GAAM,UAAU,IAAI,SAAS,IAEzB/xB,MAAM,YAChB,KAAK,MAAMwyB,UAAanvB,IAAS,KAAK,SAC5BrD,MAAM,YAChB,KAAK,iBAAiB,iCAAiC,CAAC,CAAC,SAAQ,MAAO;KACvE,EAAI,WAAW,CAACqD;IACjB,CAAC,GAEKA,IACL,KAAK0uB,GAAM,gBAAgB,UAAU,IAErC,KAAKA,GAAM,aAAa,YAAY,MAAM,KAG3C,KAAKA,GAAM,MAAM/xB,KAAKqD;GAExB;EACD,CAAC,GAEMgZ;CACR;CAEA,aAAa,GAAM,GAAM,GAAK;EAG7B,OAFI,CAAC,KAAKxb,MAAS,CAAC,KAAKA,GAAM,cAAc4D,KAA+B,QAAQA,MAAS,KAAWA,IAEjG,KAAK5D,GAAM,WAAW,SAAS4D,GAAMguB,GAAM/vB,CAAG;CACtD;CAEA,qBAAqB,GAAM,GAAa,GAAK,MAAS;EACrD,IAAI,CAAC+B,GAAM,OAAO;EAElB,IAAI;GACH,IAAM,SAAS/B,GAAK,EAAE;GACtB,IAAMgwB,IAAYjuB,EAAK,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK;GAE9C,IAAI,KAAK5D,MAAS,OAAO,KAAKA,GAAM6xB,MAAe,YAClD,OAAO,KAAK7xB,GAAM6xB,EAAU,CAAC,KAAK,MAAMllB,GAAa9K,GAAKoT,CAAI;GAG/D,IAAMqa,IAAQuC,EAAU,MAAM,8BAA8B;GAC5D,IAAIvC,GAAO;IACV,IAAM3e,IAAUhE,EAAY,UAAU,WAChCiE,IAAa,KAAK5Q,IAAO,MAAM,WAAW,KAAKA,GAAM,KAAK,SAAS,IAAI,CAAC,GACxE8xB,IAAenhB,IAAUA,EAAQ,KAAI,MAAOC,EAAWnQ,EAAI,CAAC,CAAC,OAAO,OAAO,IAAI,CAAC,GAEhF,GAAGsxB,GAAUC,KAAS1C,GACtBrvB,IAAO,KAAKD;IAElB,QAAQ+xB,EAAS,YAAY,GAA7B;KACC,KAAK,SACJ,OAAOD,EAAa;KAErB,KAAK,OAAO;MACX,IAAMzZ,IAASpY,GAAM,QAAQ,UAAU+xB,CAAK,KAAK;MACjD,OAAOF,EAAa,QAAQ,GAAK,MAAW;OAC3C,IAAMtW,IAAMnD,KAAU,IAAIvL,EAAO,IAAIuL,KAAUvL,EAAOklB;OACtD,OAAOC,KAAO,OAAOzW,CAAG,KAAK;MAC9B,GAAG,CAAC;KACL;KAEA,KAAK,OAAO;MACX,IAAIsW,EAAa,WAAW,GAAG,OAAO;MACtC,IAAMzZ,IAASpY,GAAM,QAAQ,UAAU+xB,CAAK,KAAK;MAKjD,OAJYF,EAAa,QAAQ,GAAK,MAAW;OAChD,IAAMtW,IAAMnD,KAAU,IAAIvL,EAAO,IAAIuL,KAAUvL,EAAOklB;OACtD,OAAOC,KAAO,OAAOzW,CAAG,KAAK;MAC9B,GAAG,CACM,IAAIsW,EAAa;KAC3B;IACD;GACD;GAGA,IAAI,KAAK9xB,MAAS,OAAO,KAAKA,GAAM,gBAAiB,YACpD,OAAO,KAAKA,GAAM,aAAa4D,CAAI,CAAC,CAAC,KAAK,MAAM+I,GAAa9K,GAAK,KAAK7B,GAAM,IAAI;GAGlF,IAAI4D,EAAK,SAAS,OAAO,KAAKA,EAAK,SAAS,cAAc,KAAKA,EAAK,SAAS,aAAa,GAAG;IAC5F,IAAI6rB,IAASuB,EAAU,IAAI,SAASptB,CAAI;IA6BxC,OA5BK6rB,MACJ,IAAa,SAAS,eAAe,OAAO,QAAQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;4BAuBrC7rB,EAAK;iBAChB,GACZotB,EAAU,IAAI,SAASptB,GAAM6rB,CAAM,IAE7BA,EAAO9iB,GAAa9K,GAAKoT,GAAM,KAAKjV,EAAK;GACjD;GAEA,OAAO4D;EACR,SAASwE,GAAG;GAEX,OADA,QAAQ,MAAM,gCAAgCxE,GAAMwE,CAAC,GAC9CxE;EACR;CACD;AACD,GAEasuB,IAAb,cAAyCjB,EAAY;CAEpD,IAAI,OAAO;EAAE,OAAO,MAAM;CAAM;CAChC,IAAI,QAAQ;EAAE,OAAO,MAAM;CAAO;CAClC,IAAI,OAAO;EAAE,OAAO,MAAM;CAAM;CAChC,IAAI,KAAK;EAAE,OAAO,MAAM;CAAI;CAC5B,IAAI,OAAO;EAAE,OAAO,MAAM;CAAM;CAEhC,aAAa,GAAM,GAAM,GAAK,GAAM;EACnC,OAAO,MAAM,aAAartB,GAAMguB,GAAM/vB,GAAKoT,CAAI;CAChD;CAEA,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EACnB,MAAM,kBAAkB;CACzB;CAEA,UAAU;EACT,OAAO,MAAM,QAAQ;CACtB;CAEA,gBAAgB,GAAM,GAAM,GAAK,MACzB,MAAM,aAAarR,GAAMguB,GAAM/vB,GAAKoT,CAAI;CAGhD,gBACQ,MAAM,QAAQ;CAGtB,kBACQ,MAAM,UAAU;AAEzB,GClXMkd,IAAN,cAA4BD,EAC5B;CACC;CAEA,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EAQnB,AANA,MAAM,kBAAkB,GAExB,KAAKtW,GAAU,GAEf,KAAKwW,KAAU,KAAK,cAAc,OAAO,GAEzC,KAAKC,GAAW;CACjB;CAEA,gBAAgB;EACf,IAAMlzB,IAAI,MAAM,QAAQ;EACxB,KAAKizB,GAAQ,QAAQjzB;CACtB;CAEA,WAAmB;EAalB,AAZA,KAAKizB,GAAQ,iBAAiB,UAAS,MAAK;GAC3C,IAAI,KAAKE,IAAU;IAClB,IAAMC,IAAa,OAAO,KAAKD,EAAQ;IAGvC,AAFqB,KAAK,cAAc,EAAE,OAAO,KAElC,IAAIC,MAClB,EAAE,OAAO,QAAQ,KAAK,IAAI,EAAE,OAAO,OAAOA,CAAU,GACpD,KAAK,QAAQ,EAAE,OAAO;GAExB;EACD,CAAC,GAED,KAAKH,GAAQ,iBAAiB,WAAW,MAAU;GAElD,AADA,KAAK,QAAQI,EAAM,OAAO,OAC1B,KAAK,MAAM,WAAW,QAAQ,EAAI;EACnC,CAAC;CACF;CAEA,WAAkB;EAEjB,KAAK,YAAY;CAGlB;CAEA,IAAIF,KAAW;EACd,OAAO,KAAK,KAAK,aAAa,SAAS,KAAK,KAAK,KAAK,aAAa,UAAU;CAC9E;AACD;AAEK,eAAe,IAAI,YAAY,KACnC,eAAe,OAAO,cAAcH,CAAa;;ACxDlD,IAAMM,IAAN,cAA8BP,EAC9B;CACC;CAEA,cAAe;EACd,MAAM;CACP;CAEA,oBAAoB;EAQnB,AANA,MAAM,kBAAkB,GAExB,KAAKtW,GAAU,GAEf,KAAKwW,KAAU,KAAK,cAAc,OAAO,GAEzC,KAAKC,GAAW;CAGjB;CAEA,WAAkB;EACjB,KAAK,YAAY;CAGlB;CAEA,WAAmB;EAQlB,AAPA,KAAKD,GAAQ,iBAAiB,WAAW,KAAKM,EAAU,GAExD,KAAKN,GAAQ,iBAAiB,UAAU,MAAU;GAEjD,AADA,KAAK,QAAQI,EAAM,OAAO,OAC1B,KAAK,MAAM,WAAW,QAAQ,EAAI;EACnC,CAAC,GAED,KAAKJ,GAAQ,iBAAiB,WAAW,MAAU;GAElD,AADA,KAAK,QAAQI,EAAM,OAAO,OAC1B,KAAK,MAAM,WAAW,QAAQ,EAAI;EACnC,CAAC;CACF;CAEA,gBAAgB;EACf,IAAMrzB,IAAI,MAAM,QAAQ;EAIxB,AAFA,KAAKizB,GAAQ,QAAQjzB,GAEjB,KAAK,QAAQ,KAChB,KAAKwzB,GAAU;CAEjB;CAEA,WAAkB;EAEjB,IAAMxzB,IAAI,KAAKizB,GAAQ;EAEvB,IAAIjzB,MAAM,MAAMA,KAAM,MAAyB;GAC9C,IAAMoqB,IAAM,OAAOpqB,CAAC;GAEpB,IAAI,MAAMoqB,CAAG,KAAM,KAAKqJ,MAAQrJ,IAAM,OAAO,KAAKqJ,EAAI,KAAO,KAAKC,MAAQtJ,IAAM,OAAO,KAAKsJ,EAAI,GAC/F,KAAK,KAAK,UAAU,IAAI,SAAS;QAE7B,IAAI,KAAKC,IAAQ;IACrB,IAAMC,IAAM,OAAO5zB,CAAC,GACdsB,IAAMsyB,EAAI,QAAQ,GAAG;IAC3B,AAAItyB,KAAO,KAAKsyB,EAAI,UAAUtyB,IAAM,CAAC,CAAC,CAAC,SAAS,OAAO,KAAKqyB,EAAM,KACjE,KAAK,KAAK,UAAU,IAAI,SAAS;GAEnC;EACD;CACD;CAEA,MAAa,MAAK;EAEjB,IAAI;GAAC;GAAU;GAAS;GAAO;GAAQ;GAAO;GAAa;GAAc;GAAU;GAAY;GAAa;EAAQ,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG;EAExI,IAAM70B,IAAS,EAAE,QACX4C,IAAQ5C,EAAO,OACf+0B,IAAiB/0B,EAAO,gBACxBgP,IAAM,EAAE;EAEd,IAAIA,MAAQ,QACPpM,EAAM,SAAS,GAAG,KAAKmyB,MAAmB,IAAG;GAChD,EAAE,eAAe;GACjB;EACD;EAGD,IAAI/lB,MAAQ,KAAK;GAChB,IAAMgmB,IAAQ,OAAO,KAAKH,EAAM;GAEhC,IAAI,MAAMG,CAAK,KAAKA,KAAS,KAAKpyB,EAAM,SAAS,GAAG,GAAG;IACtD,EAAE,eAAe;IACjB;GACD;EACD;EAEA,IAAIqyB,IAAW,CAAC;EAEhB,AADI,KAAKJ,MAAU,OAAO,KAAKA,EAAM,IAAI,KAAGI,EAAS,KAAK,GAAG,IACzD,KAAKL,MAAQ,OAAO,KAAKA,EAAI,IAAI,MAAGK,EAAS,KAAK,GAAG;EAEzD,IAAMC,IAAY,EAAE,WAAW,MAAM,EAAE,WAAW,MAAQ,EAAE,WAAW,MAAM,EAAE,WAAW;EAE1F,IAAI,CAACA,KAAY,CAACD,EAAS,SAAS,EAAE,GAAG,GACxC,EAAE,eAAe;OAIlB;OAAI,KAAKJ,MAAUK,KAAY,EAAE,OAAO,kBAAkB,EAAE,OAAO,cAAc;IAChF,IAAM3uB,IAAI,EAAE,OAAO,OACb/D,IAAM+D,EAAE,QAAQ,GAAG;IACzB,AAAI/D,KAAO,KAAK,EAAE,OAAO,iBAAiBA,KACrB+D,EAAE,OAAO/D,IAAM,CACrB,CAAC,CAAC,UAAU,OAAO,KAAKqyB,EAAM,KAC3C,EAAE,eAAe;GAGpB;GAEA,AAAI,KAAKR,MAAY,KAAK,cAAc,EAAE,OAAO,KAAK,KAAK,OAAO,KAAKA,EAAQ,KAAK,EAAE,OAAO,kBAAkB,EAAE,OAAO,gBACvH,EAAE,eAAe;EAHlB;CAKD;CAEA,IAAIO,KAAO;EACV,OAAO,KAAK,KAAK,aAAa,KAAK,KAAK;CACzC;CAEA,IAAID,KAAO;EACV,OAAO,KAAK,KAAK,aAAa,KAAK,KAAK;CACzC;CAEA,IAAIE,KAAS;EACZ,OAAO,KAAK,KAAK,aAAa,OAAO,KAAK;CAC3C;CAEA,IAAIR,KAAW;EACd,OAAO,KAAK,KAAK,aAAa,SAAS,KAAK,KAAK,KAAK,aAAa,UAAU;CAC9E;AACD;AAEK,eAAe,IAAI,mBAAmB,KAC1C,eAAe,OAAO,qBAAqBG,CAAe;;AC7I3D,IAAMW,IAAN,cAA6BlB,EAC7B;CACC;CACA;CACA;CAEA,cAAe;EACd,MAAM;CACP;CAEA,oBAAoB;EAWnB,AATA,MAAM,kBAAkB,GAExB,KAAKtW,GAAU,GAEf,KAAKwW,KAAU,KAAK,cAAc,mBAAmB,GACrD,KAAKiB,KAAO,KAAK,cAAc,QAAQ,GAIvC,KAAKhB,GAAW;CACjB;CAEA,WAAmB;EAalB,AAZA,KAAKgB,GAAK,iBAAiB,eAAe;GACzC,KAAKjB,GAAQ,MAAM;EACpB,CAAC,GAED,KAAKA,GAAQ,iBAAiB,UAAU,MAAU;GACjD,IAAM5W,IAAMgX,EAAM,OAAO;GAIzB,AAHA,KAAK,QAAQhX,GACb,KAAKmX,GAAUnX,CAAG,GAElB,KAAK,MAAM,WAAW,QAAQ,EAAI;EACnC,CAAC,GAED,KAAK4W,GAAQ,iBAAiB,WAAW,MAAU;GAClD,IAAM5W,IAAMgX,EAAM,OAAO;GAIzB,AAHA,KAAK,QAAQhX,GACb,KAAKmX,GAAUnX,CAAG,GAElB,KAAK,MAAM,WAAW,QAAQ,EAAI;EACnC,CAAC;CACF;CAEA,WAAkB;EACjB,KAAK,YAAY;CAIlB;CAEA,mBAAmB;EAClB,KAAK,QAAQ;CACd;CAEA,WAAuB;EAEtB,IAAMpa,IAAa,KAAK,KAAK,aAAa,aAAa;EACvD,IAAKA,MAEL,KAAKkyB,KAAc,MAAM,aAAalyB,GAAY,KAAK,GAAG,MAAM,KAAK,GAAG,QAAQ,GAAG,GAEnF,KAAK,cAAc,UAAU,CAAC,EAAE,OAAO,GAEnC,KAAKkyB,MAAe,MAAM,QAAQ,KAAKA,EAAW,IAAG;GACxD,IAAMC,IAAa,cAAc,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,KAEjEC,IAAW,SAAS,cAAc,UAAU;GAClD,EAAS,KAAKD;GAEd,IAAM5hB,IAAW,SAAS,uBAAuB;GAajD,AAXA,KAAK2hB,GAAY,SAAQ,MAAK;IAC7B,IAAIn0B,EAAE,OAAO;KACZ,IAAMs0B,IAAS,SAAS,cAAc,QAAQ;KAE9C,AADA,EAAO,QAAQt0B,EAAE,OACjBwS,EAAS,YAAY8hB,CAAM;IAC5B;GACD,CAAC,GAEDD,EAAS,YAAY7hB,CAAQ,GAC7B,KAAK,YAAY6hB,CAAQ,GAEzB,KAAKpB,GAAQ,aAAa,QAAQmB,CAAU;EAC7C;CACD;CAEA,gBAAgB;EACf,IAAI,CAAC,KAAK,GAAG,MAAM;EAEnB,IAAMp0B,IAAI,MAAM,QAAQ;EAMxB,AAJA,KAAKu0B,GAAe,GAEpB,KAAKtB,GAAQ,QAAQjzB,KAAyB,QAAQA,MAAM,KAAKA,IAAI,WAEjE,KAAK,QAAQ,KAChB,KAAKwzB,GAAU;CAEjB;CAEA,WAAkB;EAEjB,IAAMxzB,IAAI,KAAKizB,GAAQ;EAEvB,AAAIjzB,MAAM,MAAMA,KAAM,SAChB,KAAKw0B,GAAcx0B,CAAC,IAGhB,KAAKm0B,MAAe,MAAM,QAAQ,KAAKA,EAAW,KAAK,KAAKA,GAAY,SAAS,MAC1E,KAAKA,GAAY,MAAK,OACnBnxB,EAAK,UAAU,KAAA,IAA0BA,EAAK,SAAS,KAAA,IAAwB,KAAZA,EAAK,OAA7CA,EAAK,MAA+C,CAChF,YAAY,MAAMhD,EAAE,YAAY,CAGvC,KACT,KAAK,KAAK,UAAU,IAAI,SAAS,KATlC,KAAK,KAAK,UAAU,IAAI,SAAS;CAapC;CAEA,MAAiB,MAAM;EACtB,IAAI,OAAOA,KAAM,YAAYA,EAAE,UAAU,KAAK,CAACA,EAAE,WAAW,GAAG,GAAG,OAAO;EAEzE,IAAIiO,IAAI,SAASjO,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE,GAC/By0B,IAAI,SAASz0B,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE,GAC/B4C,IAAI,SAAS5C,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE;EAKnC,OAFA,EADI,MAAMiO,CAAC,KAAK,MAAMwmB,CAAC,KAAK,MAAM7xB,CAAC,KAC/BqL,IAAI,KAAKA,IAAI,OAAOwmB,IAAI,KAAKA,IAAI,OAAO7xB,IAAI,KAAKA,IAAI;CAG1D;AACD;AAEK,eAAe,IAAI,kBAAkB,KACzC,eAAe,OAAO,oBAAoBqxB,CAAc;;AC3IzD,IAAMS,IAAN,cAA4B3B,EAC5B;CACC;CACA;CAEA,cAAe;EACd,MAAM;CACP;CAEA,oBAAoB;EAgBnB,AAfA,MAAM,kBAAkB,GAExB,KAAKtW,GAAU,GAEf,KAAKwW,KAAU,KAAK,cAAc,OAAO,GAEzC,KAAKA,GAAQ,iBAAiB,UAAU,MAAU;GACjD,IAAM5W,IAAMgX,EAAM,OAAO;GAKzB,AAJA,KAAK,QAAQhX,GACb,KAAK4W,GAAQ,UAAU,OAAO,aAAa,CAAC,CAAC5W,CAAG,GAChD,KAAKmX,GAAUnX,CAAG,GAElB,MAAM,MAAM,WAAW,QAAQ,EAAI;EACpC,CAAC,GAED,KAAK4W,GAAQ,iBAAiB,WAAW,MAAU;GAClD,IAAM5W,IAAMgX,EAAM,OAAO;GAIzB,AAHA,KAAK,QAAQhX,GACb,KAAKmX,GAAUnX,CAAG,GAElB,MAAM,MAAM,WAAW,QAAQ,EAAI;EACpC,CAAC;CACF;CAEA,WAAkB;EAGjB,IADA,KAAKsY,KAAQ,KAAK,KAAK,aAAa,WAAW,KAAK,QAChD,CAAC;GAAC;GAAO;GAAiB;GAAO;GAAO;EAAO,CAAC,CAAC,SAAS,KAAKA,EAAK,GACvE,MAAM,kBAAkB,KAAKA;EAG9B,IAAInwB,IAAO,CAAC;EACZ,KAAK,IAAIlB,IAAI,GAAGA,IAAI,KAAK,KAAK,WAAW,QAAQ,KAChD,AAAI;GAAC;GAAS;GAAO;GAAO;EAAM,CAAC,CAAC,SAAS,KAAK,KAAK,WAAWA,EAAE,CAAC,IAAI,KACxEkB,EAAK,KAAK,GAAG,KAAK,KAAK,WAAWlB,EAAE,CAAC,KAAK,IAAI,KAAK,KAAK,WAAWA,EAAE,CAAC,MAAM,EAAE;EAIhF,KAAK,YAAY;;qBAEE,KAAKqxB,GAAM;iCACC,KAAK,KAAK,aAAa,aAAa,KAAK,SAAS;eACpEnwB,EAAK,KAAK,GAAG,EAAE;;;;CAI7B;CAEA,gBAAgB;EAEf,IAAMxE,IAAI,MAAM,QAAQ,GAEpB40B,IAAe50B;EACnB,IAAI40B,GAEH,QAAQ,KAAKD,IAAb;GACC,KAAK;IACJ,IAAeC,EAAa,OAAO,GAAG,EAAE;IACxC;GACD,KAAK;IACJ,IAAeA,EAAa,OAAO,GAAG,EAAE;IACxC;GACD,KAAK;IACJ,IAAIC,IAAI,IAAI,KAAK70B,CAAC;IAClB,AAAI60B,KAAK,kBAAkB,CAAC,MAAMA,CAAC,MAClC,KAAgB,OAAOA,EAAE,SAAS,EAAA,CAAG,MAAM,EAAE,IAAI,OAAO,OAAOA,EAAE,WAAW,EAAA,CAAG,MAAM,EAAE;IAExF;GACD,KAAK;IACJ,IAAIA,IAAI,IAAI,KAAK70B,CAAC;IAClB,AAAI60B,KAAK,kBAAkB,CAAC,MAAMA,CAAC,MAClC,KAAgB,SAASA,EAAE,YAAY,EAAA,CAAG,MAAM,EAAE,IAAI,OAAO,QAAQA,EAAE,SAAS,IAAI,GAAA,CAAI,MAAM,EAAE;EAGnG;EAMD,AAHA,KAAK5B,GAAQ,QAAQ2B,KAAgB,IACrC,KAAK3B,GAAQ,UAAU,OAAO,aAAa,CAAC,CAAC2B,CAAY,GAErD,KAAK,QAAQ,KAChB,KAAKpB,GAAUoB,CAAY;CAE7B;CAEA,MAAa,MAAQ;EAEpB,IAAIvY,MAAQ,MAAMA,KAAQ,MAA2B;GACpD,IAAIyY,IAAU,KAAKC,GAAa1Y,CAAG;GAOnC,AALIyY,MACC,KAAKpB,MAAQrX,IAAM,KAAKqX,OAAM,IAAU,KACxC,KAAKD,MAAQpX,IAAM,KAAKoX,OAAM,IAAU,MAGxCqB,KACJ,MAAM,KAAK,UAAU,IAAI,SAAS;EAEpC;CACD;CAEA,MAAgB,MAAM;EAErB,IAAI,OAAO90B,KAAM,UAAU,OAAO;EAElC,IAAI80B,IAAU;EAEd,QAAQ,KAAKH,IAAb;GACC,KAAK;GACL,KAAK;IACJ,IAAMK,IAAQ,OAAOh1B,EAAE,OAAO,GAAG,CAAC,CAAC,GAC7Bi1B,IAAQ,OAAOj1B,EAAE,OAAO,GAAG,CAAC,CAAC,GAC7Bk1B,IAAQ,OAAOl1B,EAAE,OAAO,GAAG,CAAC,CAAC;IAEnC,IAAI,MAAMg1B,CAAI,KAAK,MAAMC,CAAK,KAAK,MAAMC,CAAG,GAC3C,IAAU;SACJ,IAAID,IAAQ,KAAKA,IAAQ,MAAMC,IAAM,KAAKA,IAAM,IACtD,IAAU;SACJ,IAAI;KAAC;KAAG;KAAG;KAAG;IAAE,CAAC,CAAC,SAASD,CAAK,KAAKC,KAAO,IAClD,IAAU;SACJ,IAAID,KAAS,GAAG;KACtB,IAAIE,IAAUH,IAAO,KAAK,MAAMA,IAAO,OAAO,KAAKA,IAAO,OAAO;KACjE,CAAIE,IAAM,MAAOA,KAAO,MAAM,CAACC,OAC9B,IAAU;IAEZ;EAEF;EAEA,IAAIL,GACH,QAAQ,KAAKH,IAAb;GACC,KAAK;IACJ,IAAI5f,IAAO/U,EAAE,OAAO,IAAI,CAAC,GACrBo1B,IAAO,OAAOp1B,EAAE,OAAO,IAAI,CAAC,CAAC,GAC7Bq1B,IAAO,OAAOr1B,EAAE,OAAO,IAAI,CAAC,CAAC;IAEjC,AAAI+U,KAAK,OAEE,MAAMqgB,CAAI,KAAK,MAAMC,CAAG,KAExBD,IAAO,KAAKA,IAAO,MAAMC,IAAM,KAAKA,IAAM,QACpD,IAAU,MAJV,IAAU;IAMX;GAED,KAAK;IACJ,IAAIL,IAAQ,OAAOh1B,EAAE,OAAO,GAAG,CAAC,CAAC,GAC7Bi1B,IAAQ,OAAOj1B,EAAE,OAAO,GAAG,CAAC,CAAC;IAEjC,CAAI,MAAMg1B,CAAI,KAAK,MAAMC,CAAK,KAEnBA,IAAQ,KAAKA,IAAQ,QAC/B,IAAU;IAEX;GAED,KAAK;IACJ,IAAID,IAAO,OAAOh1B,EAAE,OAAO,GAAG,CAAC,CAAC,GAC5BF,IAAOE,EAAE,OAAO,GAAG,CAAC,GACpBs1B,IAAO,OAAOt1B,EAAE,OAAO,GAAG,CAAC,CAAC;IAEhC,AAAIF,KAAK,OAEE,MAAMk1B,CAAI,KAAK,MAAMM,CAAI,KAEzBA,KAAQ,KAAKA,IAAO,QAC9B,IAAU,MAJV,IAAU;EAOb;EAGD,OAAOR;CACR;CAEA,IAAIpB,KAAO;EACV,OAAO,KAAK,KAAK,aAAa,KAAK;CACpC;CAEA,IAAID,KAAO;EACV,OAAO,KAAK,KAAK,aAAa,KAAK;CACpC;AAKD;AAEK,eAAe,IAAI,iBAAiB,KACxC,eAAe,OAAO,mBAAmBiB,CAAa;;ACvMvD,IAAMa,IAAN,cAA2BxC,EAAoB;CAC3C;CACA;CAEA,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAQhB,AAPA,MAAM,kBAAkB,GAExB,KAAKtW,GAAU,GAEf,KAAKwW,KAAU,KAAK,cAAc,OAAO,GACzC,KAAKuC,KAAS,KAAK,cAAc,MAAM,GAEvC,KAAKtC,GAAW;CACpB;CAEA,IAAI,aAAa;EACb,OAAO,CACH;GAAE,OAAO,KAAK;GAAW,MAAM,KAAKuC;EAAU,GAC9C;GAAE,OAAO,KAAK;GAAY,MAAM,KAAKC;EAAW,CACpD;CACJ;CAEA,WAAmB;EAOf,AANI,KAAK,QAAQ,OAAO,KACpB,KAAKzC,GAAQ,iBAAiB,WAAW,MAAM;GAC3C,MAAM,MAAM,cAAc,yBAAyB,MAAM,KAAK,QAAQ,IAAI,iBAAiB,CAAC,EAAE,UAAU,EAAE,OAAO,OAAO;EAC5H,CAAC,GAGL,KAAKA,GAAQ,iBAAiB,WAAW,MAAU;GAC/C,AAAK,KAAK,QAAQ,OAAO,MAErB,KAAK0C,MACL,KAAK,UAAU,EAAK,GACpB,KAAK,QAAQ,KAAK,aAGlB,KAAK,QAAQtC,EAAM,OAAO,UAAU,KAAK,YAAY,KAAK,YAG9D,KAAK,MAAM,WAAW,QAAQ,EAAI;EACtC,CAAC;CACL;CAEA,WAAkB;EAEd,IAAMuC,IAAY,KAAK,WAGjBzK,IAAkB,KAAK,KAAK,aAAa,SAAS,KAAK,IACvD0K,IAAY,KAAKF,KAAW,8BAA8BC,EAAU,QAAQ,yCAAyCzK,EAAgB;EAE3I,KAAK,YAAY;cACX0K,EAAU;;CAEpB;CAEA,gBAAgB;EACZ,IAAMxZ,IAAM,MAAM,QAAQ;EAI1B,AAFA,KAAK4W,GAAQ,UAAW5W,MAAQ,KAAK,WAEjC,KAAK,QAAQ,KACb,KAAKmX,GAAUnX,CAAG;EAGtB,IAAMyZ,IAAezZ,MAAQ,KAAK,YAAa,KAAKoZ,KAAcpZ,MAAQ,KAAK,aAAc,KAAKqZ,KAAarZ;EAE/G,AAAI,KAAKmZ,OACL,KAAKA,GAAO,cAAcM;CAElC;CAEA,MAAa,MAAQ;EAIjB,AAFA,KAAK,KAAK,UAAU,OAAO,SAAS,GAEhCzZ,MAAQ,MAAMA,KAAQ,QAClBA,MAAQ,KAAK,aAAaA,MAAQ,KAAK,cACvC,KAAK,KAAK,UAAU,IAAI,SAAS;CAG7C;CAEA,aAAa,MAAM;EACf,IAAI,KAAK,QAAQ,OAAO,GAAG;EAE3B,IAAMoW,IAAO,KAAK,KAAK,KAAK,SAAS,GAC/BhxB,IAAW,KAAK,KAAK,OAAO,QAAQ,KAAK,KAAK,QAAQ,IAAI;EAEhE,IAAI,MAAW,IAEf;QAAK,IAAI6B,IAAI,GAAGA,IAAImvB,EAAK,QAAQ,KAC7B,AAAI,KAAKsD,MAAW,MAAM,aAAa,KAAKA,IAAStD,EAAKnvB,IAAIA,GAAG,KAAK,IAAI,MAAM,MAC5E,KAAK0yB,MAAa,MAAM,aAAa,KAAKA,IAAWvD,EAAKnvB,IAAIA,GAAG,KAAK,IAAI,MAAM,MAChF,KAAK2yB,MAAY,MAAM,aAAa,KAAKA,IAAUxD,EAAKnvB,IAAIA,GAAG,KAAK,IAAI,MAAM,OAElF,EAAKA,EAAE,CAAC,EAAE7B,KAAYzB,IAAI,KAAK,YAAY,KAAK;GAGpD,MAAM,MAAM,WAAW;EAFvB;CAGJ;CAEA,IAAI,YAAY;EACZ,OAAO,KAAK,KAAK,aAAa,YAAY,KAAK;CACnD;CACA,IAAI,aAAa;EACb,OAAO,KAAK,KAAK,aAAa,aAAa,KAAI;CACnD;CACA,IAAIy1B,KAAY;EACZ,OAAO,KAAK,KAAK,aAAa,WAAW,KAAK;CAClD;CACA,IAAIC,KAAa;EACb,OAAO,KAAK,KAAK,aAAa,YAAY,KAAK;CACnD;CACA,IAAIC,KAAW;EACX,OAAO,KAAK,KAAK,aAAa,UAAU,KAAK;CACjD;CACA,IAAII,KAAU;EACV,OAAO,KAAK,KAAK,aAAa,QAAQ,KAAK;CAC/C;CACA,IAAIC,KAAY;EACZ,OAAO,KAAK,KAAK,aAAa,UAAU,KAAK;CACjD;CACA,IAAIC,KAAW;EACX,OAAO,KAAK,KAAK,aAAa,SAAS,KAAK;CAChD;AACJ;AAEK,eAAe,IAAI,eAAe,KACnC,eAAe,OAAO,iBAAiBV,CAAY;;ACtIvD,IAAMW,IAAN,cAAwBnD,EAAoB;CAC3C;CACA,KAAa,CAAC;CACd,KAAc,CAAC;CAEf,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EAOnB,AANA,MAAM,kBAAkB,GAExB,KAAKtW,GAAU,GAEf,KAAK0Z,GAAe,GAEpB,KAAKjD,GAAW;CACjB;CAEA,WAAmB;EAElB,KAAK,KAAK,iBAAiB,YAAW,MAAK;GAE1C,IAAI,OAAK,KAAK,aAAa,UAAU,KAAK,KAAK,KAAK,UAAU,SAAS,UAAU,MAC7E,KAAK,KAAK,aAAa,UAAU,MAAM,UAEvC,EAAE,SAAS,SAAS;IACvB,EAAE,eAAe;IAEjB,IAAIkD,IAAa;IAYjB,AAVA,KAAKC,GAAW,SAAS,GAAI,MAAU;KACtC,IAAI,KAAK,UAAUzkB,EAAI,aAAa,OAAO,GAE1C,OADA,IAAa3M,GACN;IAET,CAAC,GAED,IAAcmxB,MAAe,KAAKC,GAAW,SAAS,IAAK,IAAKD,KAAc,IAAIA,IAAa,IAAI,GACnG,KAAK,QAAQ,KAAKC,GAAWD,EAAW,CAAC,aAAa,OAAO,GAE7D,KAAK,MAAM,WAAW,QAAQ,EAAI;GACnC;EACD,CAAC;CACF;CAEA,WAAuB;EAEtB,IAAI,CAAC,KAAK,MAAM;EAEhB,IAAMn0B,IAAa,KAAK,KAAK,aAAa,aAAa;EACvD,IAAKA,MAEL,KAAKkyB,KAAc,MAAM,aAAalyB,GAAY,KAAK,GAAG,MAAM,KAAK,GAAG,QAAQ,GAAG,GAEnF,KAAKgxB,GAAQ,gBAAgB,GAEzB,KAAKkB,MAAe,MAAM,QAAQ,KAAKA,EAAW,IAAG;GAExD,IAAM3hB,IAAW,SAAS,uBAAuB;GA2BjD,AAzBA,KAAK2hB,GAAY,SAAQ,MAAK;IAC7B,IAAMmC,IAAUt2B,EAAE,KAAKu2B,QAAc,KAAA,IAA+B,KAAnBv2B,EAAE,KAAKu2B,KAClDC,IAAUx2B,EAAE,KAAKy2B,QAAgB,KAAA,IAAiC,KAArBz2B,EAAE,KAAKy2B,KAEpDC,IAAQ,SAAS,cAAc,OAAO,GAEtCC,IAAQ,SAAS,cAAc,OAAO;IAE5C,AADA,EAAM,OAAO,SACb,EAAM,QAAQL;IAEd,IAAMM,IAAO,SAAS,cAAc,MAAM;IAK1C,AAJA,EAAK,cAAcJ,GAEnBE,EAAM,YAAYC,CAAK,GACvBD,EAAM,YAAYE,CAAI,GACtBpkB,EAAS,YAAYkkB,CAAK;GAC3B,CAAC,GAED,KAAKzD,GAAQ,YAAYzgB,CAAQ,GAGjC,KAAK6jB,KAAa,MAAM,KAAK,KAAK,iBAAiB,OAAO,CAAC,GAI3D,KAAKA,GAAW,SAAQ,MAAO;IAC9B,EAAI,iBAAiB,WAAW,MAAM;KAErC,AADA,KAAK,QAAQ,EAAE,OAAO,OACtB,KAAK,MAAM,WAAW,QAAQ,EAAI;IACnC,CAAC;GACF,CAAC;EACF;CACD;CAEA,WAAkB;EAMjB,AAJA,KAAK,YAAY,8BAIjB,KAAKpD,KAAU,KAAK,cAAc,KAAK;CACxC;CAEA,mBAAmB;EAElB,AADA,KAAKkD,GAAe,GACpB,KAAK,QAAQ;CACd;CAEA,gBAAgB;EAEf,IAAMn2B,IAAI,MAAM,QAAQ;EAMxB,AAJA,KAAKq2B,GAAW,SAAQ,MAAO;GAC9B,EAAI,UAAWr2B,MAAM4R,EAAI;EAC1B,CAAC,GAEG,KAAK,QAAQ,KAChB,KAAK4hB,GAAU;CAEjB;CAEA,WAAkB;EAEjB,AAAI,KAAK,UAAU,QAAQ,KAAK,UAAU,KAAA,KAAa,KAAK,UAAU,MAAO,MAAM,QAAQ,KAAKW,EAAW,KAI/F,KAAKA,GAAY,WAAU,MAAK,KAAK,UAAUxM,EAAE,KAAK4O,GAC5D,IAAI,KACT,KAAK,KAAK,UAAU,IAAI,SAAS;CAEnC;CAEA,IAAI,aAAa;EAChB,OAAO,KAAKpC;CACb;CAEA,IAAIoC,KAAW;EACd,OAAO,KAAK,KAAK,aAAa,UAAU,KAAK;CAC9C;CAEA,IAAIE,KAAa;EAChB,OAAO,KAAK,KAAK,aAAa,YAAY,KAAK;CAChD;AACD;AAEK,eAAe,IAAI,YAAY,KACnC,eAAe,OAAO,cAAcP,CAAS;;ACrJ9C,IAAaW,IAAb,cAAoC,YAAY;CAC/C;CACA;CACA;CACA,KAAU;CAEV,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EAEnB,AADA,KAAKpa,GAAU,GACf,KAAK5H,GAAY;CAClB;CAEA,MAAa,GAAY,GAAS,GAAW,GAAO,MAAc;EACjE,IAAMiiB,IAAM,KAAK,cAAc,mBAAmB;EAClD,IAAI,CAACA,KAAO,CAAC70B,KAAcA,EAAW,WAAW,GAAG;EAEpD,IAAM80B,IAAY,KAAKt2B,GAAQ,aAAa,OAAO,GAC/Cu2B,IAAY,CAAC;EAEjB,AAGCA,IAHGD,IACSA,EAAU,MAAM,GAAG,CAAC,CAAC,KAAI,MAAK1xB,EAAE,KAAK,CAAC,IAEtC,CAAC4xB,CAAS,CAAC,CAAC,OAAO,OAAO;EAGvC,IAAMC,IAAoBF,EAAU;EAIpC,AAFA,EAAI,WAAW,cAAc,oBAAoB,CAAC,CAAC,MAAM,UAAUG,IAAQ,KAAK,QAEhFL,EAAI,WAAW,iBAAiB,8BAA8B,CAAC,CAAC,SAAS,GAAK,MAAQ;GAErF,IAAM7hB,IAAM,SAASrD,EAAI,QAAQ,KAAK,EAAE;GACxC,AAAIqD,KAAO,MACV,EAAI,MAAM,UAAWA,IAAM,KAAKiiB,IAAqB,SAAS;EAEhE,CAAC;EAED,IAAME,IAAgBn1B,EAAW,KAAI,MAAQ;GAC5C,IAAMS,IAAM;IACX,KAAK;IACL,GAAG20B,KAAWr0B,EAAKq0B,OAAa,KAAA,IAAYr0B,EAAKq0B,KAAYr0B,EAAK,OAAO,KAAA,IAAsB,KAAVA,EAAK;GAC3F;GAKA,OAHAg0B,EAAU,SAAS,GAAK,MAAQ;IAC/B,EAAI,MAAM11B,IAAM,OAAO0B,EAAK8K,OAAS,KAAA,IAAyB9K,EAAK1B,OAAS,KAAA,IAAwB,KAAZ0B,EAAK1B,KAA5C0B,EAAK8K;GACvD,CAAC,GACMpL;EACR,CAAC;EAID,IAFAo0B,EAAI,KAAK,IAAIM,CAAa,GAEtBD,KAAS,KAAK12B,GAAQ,OAAO;GAChC,IAAM62B,IAAe,OAAO,KAAK72B,GAAQ,KAAK,CAAC,CAAC,MAAM82B,KAAa,GAAG;GAMtE,AALAT,EAAI,KAAK,aAAa,CAAC,CAAC,SAAQ,MAAK;IACpC,AAAIQ,EAAa,SAAS,OAAO3P,EAAE,EAAE,EAAE,CAAC,MACvC,EAAE,EAAE,KAAK;GAEX,CAAC,GACDmP,EAAI,YAAY;EACjB;CACD;CAEA,QAAQ,GAAQ,GAAY,GAAS,GAAW,GAAO,MAAc;EAMpE,AALA,KAAKr2B,KAAUC,GACf,KAAK61B,KAAWc,GAChB,KAAKZ,KAAaQ,GAClB,KAAKO,KAAU,IAEf,KAAK,UAAU,IAAI,QAAQ;EAE3B,IAAMV,IAAM,KAAK,cAAc,mBAAmB;EAClD,IAAI,CAACA,KAAO,CAAC70B,GAAY;EAWzB,AATA,KAAK,cAAc,eAAe,CAAC,CAAC,QAAQ,IAC5C,KAAK,cAAc,SAAS,CAAC,CAAC,UAAU,IAEpCA,EAAW,SAAS,KACvB,KAAK,UAAU,IAAI,QAAQ,IAE3B,KAAK,UAAU,OAAO,QAAQ,GAG3Bk1B,IACH,KAAK,UAAU,IAAI,OAAO,IAE1B,KAAK,UAAU,OAAO,OAAO;EAG9B,IAAM5xB,IAAQ7E,EAAO,QAAQ,kBAAkB,GACzC+2B,IAAQ/2B,EAAO,cAAc,OAAO;EAC1C,IAAI,CAAC+2B,KAAS,CAAClyB,GAAO;EAEtB,IAAMmyB,IAAUD,EAAM,sBAAsB,GACtChd,IAAYlV,EAAM,sBAAsB,GAE1Cgc,IAAOmW,EAAQ,OAAOjd,EAAU,MAChCoJ,IAAM6T,EAAQ,SAASjd,EAAU,MAAM,GAErCmJ,IAAa,KAAK,eAAe,KACjC+T,IAAc,KAAK,gBAAgB;EASzC,IARIpW,IAAOqC,IAAanJ,EAAU,UACjC,IAAO,KAAK,IAAI,GAAGA,EAAU,QAAQmJ,IAAa,CAAC,IAGhDrC,IAAO,MACV,IAAO,IAGJsC,IAAM8T,IAAcld,EAAU,QAAQ;GACzC,IAAMmd,IAAaF,EAAQ,MAAMjd,EAAU,MAAOkd,IAAc;GAChE,AAGC9T,IAHG+T,KAAa,IACVA,IAEA,KAAK,IAAI,GAAGnd,EAAU,SAASkd,IAAc,CAAC;EAEtD;EAKA,AAHA,KAAK,MAAM,OAAO,GAAGpW,EAAK,KAC1B,KAAK,MAAM,MAAM,GAAGsC,EAAI,KAExB,iBAAiB;GAEhB,KAAKgU,GAAU51B,GAAYo1B,GAASJ,GAAWE,GAAOI,CAAS;GAE/D,IAAMO,IAAgBhB,EAAI,WAAW,cAAc,qCAAqC;GAExF,AAWCgB,EAAc,qBATdA,EAAc,iBAAiB,cAAc,MAAM;IAGlD,AADW,EAAE,OAAO,QAAQ,IACtB,MAEDX,KACJ,KAAKY,GAAY,CAAC;GAEpB,CAAC,GAC+B;EAElC,GAAG,GAAG;CACP;CAEA,cAAc;EAGb,AAFA,KAAK,UAAU,OAAO,QAAQ,GAC9B,KAAKP,KAAU,IACX,KAAK/2B,MAAW,KAAKA,GAAQ,QAChC,KAAKA,GAAQ,KAAK,MAAM;CAE1B;CAEA,MAAe,MAAM;EAEpB,IAAM8E,IAAQ,EAAE,OAAO,QAAQ,kBAAkB,GAC3C4L,IAAK,EAAE,OAAO,QAAQ,IAAI,GAE1B3P,IAAW,SAAS2P,EAAG,QAAQ,KAAK,EAAE,GACtCxD,IAASpI,EAAM,KAAK,IAAI/D,CAAQ;EAMtC,AAJA,KAAKf,GAAQ,QAAQkN,EAAO,GAE5B,KAAKlN,GAAQ,MAAM,WAAW,QAAQ,EAAI,GAE1C,KAAK,MAAM;CACZ;CAEA,WAAc;EAEb,IAAMgyB,IADM,KAAK,cAAc,mBAChB,CAAC,CAAC,KAAK,aAAa,GAE7B6E,IAAe,CAAC;EAUtB,AATA7E,EAAK,SAAQ,MAAK;GACjB,AAAIzxB,EAAE,EAAE,OAAO,OACds2B,EAAa,KAAKt2B,EAAE,EAAE,EAAE;EAE1B,CAAC,GAED,KAAKP,GAAQ,QAAQ62B,EAAa,KAAK,KAAK72B,GAAQ,aAAa,iBAAiB,KAAK,GAAG,GAC1F,KAAKA,GAAQ,MAAM,WAAW,QAAQ,EAAI,GAE1C,KAAK,MAAM;CACZ;CAEA,MAAgB,MAAM;EACrB,IAAMq2B,IAAM,KAAK,cAAc,mBAAmB,GAC5CpR,IAAY,EAAE,OAAO,UAAU,MAAM;EAE3C,AADAoR,EAAI,KAAK,aAAa,CAAC,CAAC,SAAQ,MAAK;GAAE,EAAE,EAAE,KAAKpR;EAAW,CAAC,GAC5DoR,EAAI,YAAY;CACjB;CAEA,MAAY,MAAM;EACjB,IAAMkB,IAAU,EAAE,OAAO,MAAM,YAAY,GACrClB,IAAM,KAAK,cAAc,mBAAmB;EAUlD,AARAA,EAAI,KAAK,eAAe,CAAC,CAAC,SAAQ,MAAK;GACtC,IAAM3G,IAAQ,OAAO,OAAOxI,EAAE,CAAC,CAAC,CAAC,MAAK,MACrCtL,KAAQ,QAA6B,OAAOA,CAAG,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS2b,CAAO,CAChF;GACA,EAAE,KAAK,WAAW,CAAC7H;EACpB,CAAC,GAED2G,EAAI,KAAK,aAAa,GACtBA,EAAI,YAAY,YAAY,MAAM;CACnC;CAEA,IAAI,SAAS;EACZ,OAAO,KAAKU;CACb;CAEA,IAAI,aAAa;EAChB,OAAO,KAAK/2B;CACb;CAEA,WAAoB;EAKnB,AAJA,KAAK,cAAc,eAAe,CAAC,CAAC,iBAAiB,SAAS,KAAK8iB,EAAQ,GAC3E,KAAK,cAAc,QAAQ,CAAC,CAAC,iBAAiB,SAAS,KAAKE,EAAK,GACjE,KAAK,cAAc,SAAS,CAAC,CAAC,iBAAiB,UAAU,KAAKD,EAAY,GAE1E,SAAS,iBAAiB,cAAc,MAAM;GAG7C,CAFa,EAAE,eAAe,EAAE,aAAa,IAAI,CAAC,EAAA,CAEzC,SAAS,IAAI,KAGtB,KAAK,MAAM;EACZ,CAAC;CACF;CAEA,WAAkB;EACjB,KAAK,YAAY;CAgDlB;AACD;AAEK,eAAe,IAAI,kBAAkB,KACzC,eAAe,OAAO,oBAAoBqT,CAAc;;ACzRzD,IAAaoB,IAAb,cAA+BlF,EAAoB;CAClD;CACA,KAAc,CAAC;CACf;CACA;CACA;CACA;CACA;CAEA,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EAWnB,AATA,KAAKtW,GAAU,GACf,MAAM,kBAAkB,GAExB,KAAK8Z,KAAW,MAAM,KAAK,aAAa,UAAU,KAAK,KACvD,KAAKE,KAAa,MAAM,KAAK,aAAa,YAAY,KAAK,KAC3D,KAAKyB,KAAS,MAAM,KAAK,aAAa,OAAO,MAAM,QACnD,KAAKC,KAAkB,MAAM,KAAK,aAAa,iBAAiB,KAAK,KAErE,KAAKN,GAAU,GACf,KAAK3E,GAAW;CACjB;CAEA,mBAAmB;EAElB,AADA,KAAK2E,GAAU,GACf,KAAK,QAAQ;CACd;CAEA,WAAkB;EACjB,IAAI,CAAC,MAAM,SAAS,CAAC,MAAM,MAAM;EAEjC,IAAM51B,IAAa,MAAM,MAAM,aAAa,aAAa;EACzD,AAAKA,MAEL,KAAKkyB,KAAc,MAAM,aAAalyB,GAAY,MAAM,GAAG,MAAM,MAAM,GAAG,QAAQ,GAAG;CACtF;CAEA,WAAmB;EAClB,KAAK,iBAAiB,QAAQ,CAAC,CAAC,SAAQ,MAAO;GAC9C,EAAI,iBAAiB,UAAU,MAAM;IAEpC,AADA,EAAE,gBAAgB,GAClB,KAAKm2B,GAAa;GACnB,CAAC;EACF,CAAC;CACF;CAEA,WAAqB;EAUpB,AARK,KAAK3f,OACT,KAAKA,KAAS,MAAM,MAAM,cAAc,kBAAkB,GACrD,KAAKA,OACT,KAAKA,KAAS,SAAS,cAAc,kBAAkB,GACvD,MAAM,MAAM,YAAY,KAAKA,EAAM,KAIjC,KAAKA,GAAO,UAAU,KAAKA,GAAO,eAAe,OACpD,KAAKA,GAAO,MAAM,IAElB,KAAKA,GAAO,KAAK,MAAM,KAAK0b,IAAa,KAAKoC,IAAU,KAAKE,IAAY,KAAKyB,IAAQ,KAAKC,EAAe;CAE5G;CAEA,WAAkB;EAMjB,AALA,KAAK,YAAY,gLAKjB,KAAKE,KAAa,KAAK,cAAc,OAAO;CAC7C;CAEA,gBAAgB;EACf,IAAMr4B,IAAI,MAAM,QAAQ;EAMxB,OALK,KAAKq4B,OAEV,KAAKA,GAAW,cAAc,KAAKC,GAAgB,KAAK,UACxD,KAAKC,GAAe,IAEbv4B;CACR;CAEA,WAAwB;EACvB,IAAI,CAAC,KAAK,SAAS,CAAC,MAAM,QAAQ,KAAKm0B,EAAW,GAAG,OAAO;EAE5D,IAAI,KAAK+D,IAAQ;GAChB,IAAMM,IAAO,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,KAAKL,EAAe;GAC1D,OAAO,KAAKhE,GACV,QAAO,MAAKqE,EAAK,SAAS,OAAO7Q,EAAE,KAAK4O,GAAS,CAAC,CAAC,CAAC,CACpD,KAAI,MAAK5O,EAAE,KAAK8O,GAAW,CAAC,CAC5B,KAAK,KAAK0B,EAAe;EAC5B;EAAO;GACN,IAAMr0B,IAAQ,KAAKqwB,GAAY,MAAK,MAAK,OAAOxM,EAAE,KAAK4O,GAAS,MAAM,OAAO,KAAK,KAAK,CAAC;GACxF,OAAOzyB,IAAQA,EAAM,KAAK2yB,MAAc,KAAK;EAC9C;CACD;CAEA,WAAuB;EAItB,IAHI,CAAC,MAAM,SACX,MAAM,KAAK,UAAU,OAAO,SAAS,GAEjC,KAAK,UAAU,QAAQ,KAAK,UAAU,KAAA,KAAa,KAAK,UAAU,MAAM,CAAC,MAAM,QAAQ,KAAKtC,EAAW,IAC1G;EAGD,IAAMsE,IAAO,KAAKP,KAAS,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,KAAKC,EAAe,IAAI,CAAC,KAAK,KAAK;EACvF,KAAK,IAAMn4B,KAAKy4B,GAEf,IADY,KAAKtE,GAAY,WAAU,MAAK,OAAOn0B,CAAC,MAAM,OAAO2nB,EAAE,KAAK4O,GAAS,CAC3E,IAAI,GAAG;GACZ,MAAM,KAAK,UAAU,IAAI,SAAS;GAClC;EACD;CAEF;CAEA,IAAI,aAAa;EAChB,OAAO,KAAKpC;CACb;AACD;AAEK,eAAe,IAAI,YAAY,KACnC,eAAe,OAAO,cAAc8D,CAAS;;AC9H9C,IAAMS,IAAN,cAA2B5G,EAAY;CACtC;CAEA,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EAKnB,AAJA,MAAM,kBAAkB,GAExB,KAAKrV,GAAU,GAEf,KAAKwW,KAAU,KAAK,cAAc,MAAM;CACzC;CAEA,gBAAgB;EAIf,AAFA,MAAM,QAAQ,GAEV,KAAK,KAAK,aAAa,MAAM,MAAM,SACtC,KAAKA,GAAQ,YAAY,KAAK,eAAe,IAE7C,KAAKA,GAAQ,cAAc,KAAK,eAAe;CAEjD;CAEA,WAAkB;EACjB,KAAK,YAAY;CAGlB;AACD;AAEK,eAAe,IAAI,eAAe,KACtC,eAAe,OAAO,iBAAiByF,CAAY;;ACjCpD,IAAaC,IAAb,cAAgC7G,EAAY;CAC3C;CAEA,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EASnB,AAPA,KAAKrV,GAAU,GAEf,MAAM,kBAAkB,GAExB,KAAKwW,KAAU,KAAK,cAAc,QAAQ,GAE1C,KAAKA,GAAQ,oBAAoB,SAAS,KAAK2F,EAAgB,GAC/D,KAAK3F,GAAQ,iBAAiB,SAAS,KAAK2F,EAAgB;CAC7D;CAEA,MAAmB,MAAK;EACvB,EAAE,gBAAgB;EAElB,IAAMx2B,IAAQ,SAAS,KAAK,KAAK,QAAQ,KAAK,EAAE,GAE1Cy2B,IAAc,IAAI,YAAYt4B,EAAW,MAAM,mBAAmB;GACvE,SAAS;GACT,UAAU;GACV,QAAQ;IACP,eAAe;IACf,MAAM,KAAK;IACX,KAAK6B;IACL,KAAK,SAAS,KAAK,KAAK,QAAQ,KAAK,EAAE;IACvC,MAAM,KAAK,QAAQ;IACnB,MAAM,KAAK,KAAK,KAAK,IAAIA,CAAK;IAC9B,OAAO,KAAK;GACb;EACD,CAAC;EAED,KAAK,cAAcy2B,CAAW;CAC/B;CAEA,gBAAgB;EACf,IAAMC,IAAW,MAAM,UAAU,MAAM,QAAQ,IAAI,KAAK;EAExD,KAAK7F,GAAQ,YAAY,KAAK,eAAe6F,CAAQ;CACtD;CAEA,WAAkB;EAIjB,KAAK,YAAY;CAGlB;AACD;AAEK,eAAe,IAAI,aAAa,KACpC,eAAe,OAAO,eAAeH,CAAU;;AC3DhD,IAAMI,IAAN,cAA+BjH,EAAY;CAC1C;CACA;CACA;CAEA,cAAc;EACb,MAAM;CACP;CAEA,oBAAoB;EAWnB,AAVA,KAAKrV,GAAU,GACf,MAAM,kBAAkB,GAEpB,KAAK,SACR,KAAK,KAAK,gBAAgB,UAAU,GACpC,KAAK,KAAK,QAAQ,OAAO,aAG1B,KAAKuc,KAAc,KAAK,cAAc,cAAc,GACpD,KAAKC,KAAa,KAAK,cAAc,aAAa,GAClD,KAAKC,KAAgB,KAAK,cAAc,gBAAgB;CACzD;CAEA,WAAkB;EACjB,KAAK,YAAY;CAKlB;CAEA,gBAAgB;EACf,IAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,IAAI;EAE5B,IAAMx2B,IAAM,KAAK;EACjB,IAAI,MAAMA,CAAG,GAAG;EAEhB,IAAM0vB,IAAY,KAAK,GAAG;EAE1B,AAAIA,KAAaA,EAAU;EAI3B,IAAM+G,IAAa,KAAK,QAAQ,GAC1BC,IAAeD,EAAW,eAAe;EAE/C,IAAIA,KAAc,KAAO;GAExB,IAAME,IAAaD,EAAa,SAAS,GACnCE,IAAaF,EAAa,UAAU,GAAGC,IAAa,CAAC,GACrDE,IAAaH,EAAa,UAAUC,IAAa,CAAC;GAExD,KAAKL,GAAY,YAAY;2CACWM,EAAW;2CACXC,EAAW;;EAEpD,OACC,KAAKP,GAAY,YAAY,GAAGI;EAGjC,IAAMI,IAAW,OAAK,MAAM,cAAc,wBAAwB,GAC5DC,IAAY,OAAK,MAAM,cAAc,yCAAyC;EAGpF,AADA,KAAKR,GAAW,YAAYv2B,GAC5B,KAAKu2B,GAAW,MAAM,UAAWO,KAAYC,IAAa,KAAK;CAChE;AACD;AAEK,eAAe,IAAI,oBAAoB,KAC3C,eAAe,OAAO,sBAAsBV,CAAgB;;ACrE7D,IAAaW,IAAb,cAA+B,YAAY;CACvC;CACA;CAEA,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAsBhB,AArBA,KAAK3H,KAAQ,KAAK,QAAQ,QAAQ,GAClC,KAAKxoB,KAAS,KAAK,QAAQ,kBAAkB,GAEzC,KAAKwoB,OACL,KAAKA,GAAM,MAAM,WAAW,aAI5B,KAAK,aAAa,WAAW,MAAM,UACnC,KAAKA,IAAO,aAAa,WAAW,MAAM,SAG1C,4BAA4B;GACxB,KAAK,SAAS,EAAI;EACtB,CAAC,KAED,KAAK,UAAU,OAAO,WAAW,GACjC,KAAK,UAAU,IAAI,QAAQ,IAG/B,KAAK,oBAAoB,SAAS,KAAKlM,EAAQ,GAC/C,KAAK,iBAAiB,SAAS,KAAKA,EAAQ;CAChD;CAEA,MAAY,MAAM;EAId,AAHA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAEd,KAAK,UAAU,SAAS,QAAQ,IAChC,KAAK,SAAS,IAEd,KAAK,OAAO;CAEpB;CAEA,eAAe;EACX,IAAI,CAAC,KAAKtc,IAAQ,cAAc,CAAC,KAAKwoB,IAAO;EAC7C,IAAMtwB,IAAW,SAAS,KAAKswB,GAAM,QAAQ,KAAK,EAAE,GAC9Crd,IAAU,KAAKqd,GAAM,WAAW;EAKtC,AAHA,KAAK,UAAU,OAAO,WAAW,GACjC,KAAK,UAAU,IAAI,QAAQ,GAC3B,KAAKA,GAAM,aAAa,aAAa,OAAO,GAC5C,KAAKA,GAAM,MAAM,QAAQ;EAEzB,IAAMtG,IAAc,SAAS,KAAKsG,GAAM,QAAQ,aAAa,EAAE,KAAK;EAEpE,IAAIrd,MAAY,GACZ,KAAKnL,GAAO,WAAW,eAAe9H,GAAUgqB,CAAW;OACxD;GACH,IAAMkO,IAAc,KAAK,IAAI,IAAI,KAAK,MAAMlO,IAAc/W,CAAO,CAAC;GAClE,KAAK,IAAIpR,IAAI,GAAGA,IAAIoR,GAAS,KACzB,KAAKnL,GAAO,WAAW,eAAe9H,IAAW6B,GAAGq2B,CAAW;EAEvE;EAEA,4BAA4B;GACxB,AAAI,OAAO,KAAKpwB,GAAO,iBAAkB,cACrC,KAAKA,GAAO,cAAc;EAElC,CAAC;CACL;CAEA,YAAY,IAAgB,OAAU;EAClC,IAAI,CAAC,KAAKA,IAAQ,cAAc,CAAC,KAAKwoB,IAAO;EAC7C,IAAMtwB,IAAW,SAAS,KAAKswB,GAAM,QAAQ,KAAK,EAAE,GAC9Crd,IAAU,KAAKqd,GAAM,WAAW;EAEtC,IAAI,KAAK,UAAU,SAAS,QAAQ,GAAG;GACnC,IAAM9c,IAAM,KAAK1L,GAAO,cAAc,0BAA0B9H,EAAS,GAAG,GACtEm4B,IAAW3kB,IAAM,SAASA,EAAI,aAAa,OAAO,GAAG,EAAE,IAAI;GACjE,AAAI2kB,IAAA,OACA,KAAK7H,GAAM,QAAQ,cAAc,OAAO6H,IAAWllB,CAAO;EAElE;EAOA,IALA,KAAK,UAAU,OAAO,QAAQ,GAC9B,KAAK,UAAU,IAAI,WAAW,GAC9B,KAAKqd,GAAM,aAAa,aAAa,MAAM,GAC3C,KAAKA,GAAM,MAAM,QAAQ,eAErBrd,MAAY,GACZ,KAAKnL,GAAO,WAAW,eAAe9H,GAAA,EAAyB;OAC5D;GACH,IAAMo4B,IAAa,KAAK,IAAI,IAAI,KAAK,MAAA,KAAwBnlB,CAAO,CAAC;GACrE,KAAK,IAAIpR,IAAI,GAAGA,IAAIoR,GAAS,KACzB,KAAKnL,GAAO,WAAW,eAAe9H,IAAW6B,GAAGu2B,CAAU;EAEtE;EAEA,4BAA4B;GACxB,AAAI,OAAO,KAAKtwB,GAAO,iBAAkB,cACrC,KAAKA,GAAO,cAAc;EAElC,CAAC;CACL;CAEA,uBAAuB;EACnB,KAAK,oBAAoB,SAAS,KAAKsc,EAAQ;CACnD;AACJ;AAEK,eAAe,IAAI,uBAAuB,KAC3C,eAAe,OAAO,yBAAyB6T,CAAS;;AChH5D,IAAaI,IAAb,cAAiC,YAAY;CACzC;CACA;CAEA,oBAAoB;EAChB,IAAMjd,IAAO,KAAK,YAAY;EAO9B,AANA,KAAKkd,KAAald,aAAgB,aAAaA,EAAK,OAAQ,KAAK,QAAQ,YAAY,KAAKA,EAAK,MAE/F,AACI,KAAKkd,OAAa,KAAK,eAAe,QAAQ,YAAY,KAAK,KAAK,cAAc,QAAQ,YAAY,GAGrG,KAAKA;CACd;CAEA,MAAkB,MAAM;EACpB,IAAM/V,IAAO,EAAE,eAAe,EAAE,aAAa,IAAI,CAAC,GAC5CvN,IAAauN,EAAK,MAAK,MAAMhlB,EAAG,YAAY,QAAQA,EAAG,YAAY,IAAI;EAE7E,IAAI,CAACyX,GAAY;EAEjB,IAAMujB,IAAchW,EAAK,MAAK,MAAMhlB,EAAG,YAAY,OAAO,KAAKyX,EAAW,QAAQ,OAAO;EAKzF,AAHA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAElB,KAAK,SAAS,EAAE,SAAS,EAAE,SAASA,GAAYujB,CAAW;CAC/D;CAEA,GAAgB,GAAY;EACxB,OAAOvjB,GAAY,QAAQ,kBAAkB,KAAK,KAAKsjB,GAAW,eAAe,KAAKA;CAC1F;CAEA,GAAe,GAAY;EACvB,IAAMx0B,IAAQ,KAAK00B,GAAgBxjB,CAAU;EAM7C,OALKlR,KAEL,AACIA,EAAM,WAAS,IAAI4c,EAAc5c,CAAK,GAEnCA,EAAM,UALM;CAMvB;CAEA,GAAsB,GAAkB,GAAa;EACjD,IAAM20B,IAAQ,CAAC,GACTC,IAAgBC,GAAa;EAYnC,OATA,MAFqB,KAAKC,EAAiB,iBAAiB,aAAa,CAEpE,CAAC,CAAC,SAAQ,MAAU;GACrB,IAAMC,IAAkBC,EAAO,aAAa,cAAc;GAE1D,IAAI,CAACD,KAAoBH,KAAiBG,MAAoBH,GAAgB;IAC1E,IAAMK,IAAa,KAAKC,GAAYF,CAAM;IAC1C,EAAM,KAAK,GAAGC,CAAU;GAC5B;EACJ,CAAC,GAEMN;CACX;CAEA,GAAY,GAAM;EACd,IAAMzB,IAAO,CAAC;EAqCd,OApCA,MAAM,KAAKiC,EAAK,QAAQ,CAAC,CAAC,SAAQ,MAAS;GACvC,IAAM5P,IAAU6P,EAAM,QAAQ,YAAY;GAE1C,IAAI7P,MAAY,QAAQ6P,EAAM,UAAU,SAAS,WAAW,GACxD,EAAK,KAAK,EAAE,MAAM,YAAY,CAAC;QAInC,IAAI7P,MAAY,MAAM;IAClB,IAAI3mB,IAAO,IACLy2B,IAASD,EAAM,cAAc,eAAe;IAClD,AAGIx2B,IAHAy2B,IACOA,EAAO,YAAY,KAAK,IAExB,MAAM,KAAKD,EAAM,UAAU,CAAC,CAC9B,QAAO,MAAKE,EAAE,aAAa,KAAK,SAAS,CAAC,CAC1C,KAAI,MAAKA,EAAE,YAAY,KAAK,CAAC,CAAC,CAC9B,KAAK,EAAE;IAGhB,IAAMC,IAAQH,EAAM,cAAc,aAAa,GACzC33B,IAAO;KACT,QAAQ23B,EAAM,MAAMx2B;KACd;KACN,WAAWw2B,EAAM,aAAa;KAC9B,UAAUA,EAAM,aAAa,UAAU,KAAKA,EAAM,aAAa,UAAU,MAAM;KAC/E,UAAU;IACd;IAMA,AAJIG,MACA,EAAK,QAAQ,KAAKL,GAAYK,CAAK,IAGvCrC,EAAK,KAAKz1B,CAAI;GAClB;EACJ,CAAC,GACMy1B;CACX;CAEA,GAAgB,GAAa,GAAc,GAAY;EACnD,IAAMsC,IAAa,KAAK,aAAa,kBAAkB,MAAM,SACzDC,IAAW,CAAC,GAEVC,IAAc,KAAKC,GAAsB,MAAMd,CAAW;EAChE,AAAIa,EAAY,SAAS,KACrBD,EAAS,KAAK,GAAGC,CAAW;EAGhC,IAAME,IAAa,KAAKC,GAAe3kB,CAAU,GAC3C4kB,IAAkBF,GAAY,YAAY1kB,GAAY2jB,CAAW,KAAK,QACtEkB,IAAYC,MAAiBJ,GAAY,aAAa1kB,GAAY2jB,CAAW,KAAK,KAEpFoB,IAAc;EAiBlB,AAhBA,AAQIA,IARAH,MAAoB,UAAUA,MAAoB,UACpC;GACV,QAAQ;GACR,MAAM;GACN,WAAW;GACX,UAAU,CAACE;EACf,IAEc;GACV,QAAQ;GACR,MAAM;GACN,WAAW;GACX,UAAU,CAACD;EACf,GAGAP,KACAC,EAAS,KACL,EAAE,MAAM,YAAY,GACpB;GACI,QAAQ;GACR,MAAM;GACN,WAAW;GACX,UAAU,CAACO;EACf,GACAC,GACA,EAAE,MAAM,YAAY,GACpB;GAAE,QAAQ;GAAa,MAAM;GAAa,WAAW;EAAoB,GACzE;GAAE,QAAQ;GAAY,MAAM;GAAY,WAAW;EAAW,GAC9D;GACI,QAAQ;GACR,MAAM;GACN,WAAW;GACX,OAAO,CACH;IAAE,QAAQ;IAAgB,MAAM;IAAS,WAAW;GAAe,GACnE;IAAE,QAAQ;IAAc,MAAM;IAAO,WAAW;IAAc,UAAU;GAAK,CACjF;EACJ,GACA;GACI,QAAQ;GACR,MAAM;GACN,WAAW;GACX,OAAO;IACH;KAAE,QAAQ;KAAkB,MAAM;KAAuB,WAAW;IAAiB;IACrF;KAAE,QAAQ;KAAmB,MAAM;KAAwB,WAAW;IAAkB;IACxF;KAAE,QAAQ;KAAgB,MAAM;KAAoB,WAAW;IAAe;GAClF;EACJ,CACJ;EAGJ,IAAMC,IAAe,CAAC;EActB,OAbAT,EAAS,SAAS,MAAS;GACvB,CAAIh4B,EAAK,SAAS,eACVy4B,EAAa,WAAW,KAAKA,EAAaA,EAAa,SAAS,EAAE,CAAC,SAAS,gBAIpFA,EAAa,KAAKz4B,CAAI;EAC1B,CAAC,GAEGy4B,EAAa,SAAS,KAAKA,EAAaA,EAAa,SAAS,EAAE,CAAC,SAAS,eAC1EA,EAAa,IAAI,GAGdA;CACX;CAEA,SAAS,GAAG,GAAG,GAAY,GAAa;EACpC,IAAMC,IAAe,KAAK3B,GAAW,cAAc,KAAKA;EAExD,AAAK,KAAKthB,OACN,KAAKA,KAAS,SAAS,cAAc,uBAAuB,GAC5DijB,EAAa,YAAY,KAAKjjB,EAAM;EAGxC,IAAM8iB,IAAe,CAAC,CAAC9kB,EAAW,QAAQ,OAAO,GAC3CklB,IAAY,KAAKC,GAAgB5B,GAAauB,GAAc9kB,CAAU;EAE5E,KAAKgC,GAAO,OAAOkjB,IAAY,MAAM,KAAKE,GAAiB,GAAGplB,GAAYujB,CAAW,CAAC;EAEtF,IAAM/zB,IAAc,KAAKg0B,GAAgBxjB,CAAU;EAGnD,AAFA,KAAKqlB,GAAgB71B,CAAW,GAEhC,KAAKwS,GAAO,OAAOlQ,GAAGuU,CAAC;CAC3B;CAEA,GAAgB,GAAa;EACzB,IAAI,CAAC,KAAKrE,MAAU,CAACxS,GAAa;EAElC,IAAM81B,IAAc91B,EAAY,WAAW,cAAc,KAAK;EAC9D,KAAKwS,GAAO,gBAAgB,aAAa,MAAMsjB,CAAW;EAE1D,IAAMC,IAAU,KAAKjC,GAAW,aAAa,cAAc,MAAM;EACjE,KAAKthB,GAAO,gBAAgB,gBAAgB,MAAMujB,CAAO;EAEzD,IAAMC,IAAY,KAAKlC,GAAW,aAAa,gBAAgB,MAAM;EACrE,KAAKthB,GAAO,gBAAgB,kBAAkB,MAAMwjB,CAAS;CACjE;CAEA,GAAiB,GAAG,GAAY,GAAa;EACzC,IAAMC,IAAS,EAAE,QAEXrD,IAAc,IAAI,YAAY,cAAc;GAC9C,QAAQ;IAAE;IAAQ;IAAY;IAAa,eAAe;GAAE;GAC5D,SAAS;GACT,UAAU;EACd,CAAC;EACD,KAAK,cAAcA,CAAW;EAE9B,IAAMzW,IAAU,SAAS3L,EAAW,QAAQ,KAAK,EAAE,GAC7CxQ,IAAc,KAAKg0B,GAAgBxjB,CAAU;EAEnD,QAAQylB,GAAR;GACI,KAAK;GACL,KAAK;IAED,KADwBd,GAAe3kB,CAC9B,CAAC,EAAE,iBAAiBylB,GAAQzlB,CAAU;IAC/C;GAEJ,KAAK;IACD,AAAK,MAAM2L,CAAO,KACdnc,EAAY,SAAS,qBAAqBmc,GAAS3L,CAAU;IAEjE;GAEJ,KAAK;IACD,GAAa,WAAW,OAAO;IAC/B;GAEJ,KAAK;IACD,KAAKsjB,GAAW,aAAa,gBAAgB,KAAKA,GAAW,aAAa,cAAc,MAAM,SAAS,UAAU,MAAM;IACvH;GAEJ,KAAK,kBACD,KAAKA,GAAW,aAAa,kBAAkB,KAAKA,GAAW,aAAa,gBAAgB,MAAM,SAAS,UAAU,MAAM;EAEnI;EAEA,KAAKthB,GAAO,MAAM;CACtB;CAEA,uBAAuB;EACnB,KAAKshB,IAAY,oBAAoB,eAAe,KAAKoC,EAAc;CAC3E;AACJ;AAEK,eAAe,IAAI,iBAAiB,KACrC,eAAe,OAAO,mBAAmBrC,CAAW;;ACxQxD,IAAasC,IAAb,cAA+B,YAAY;CACvC;CACA,KAAgB;CAEhB,cAAc;EACV,MAAM;CACV;CAEA,oBAAoB;EAMhB,AAJA,KAAK,MAAM,WAAW,SACtB,KAAK,MAAM,UAAU,QACrB,KAAK,MAAM,SAAS,SAEpB,KAAK,YAAY;CAKrB;CAEA,OAAO,GAAO,GAAU;EACpB,KAAKC,KAAcC;EACnB,IAAM1rB,IAAY,KAAK,cAAc,iBAAiB;EACtD,AAAKA,MAEL,EAAU,YAAY,IAEtB,KAAK2rB,GAAa3rB,GAAWspB,CAAK,GAClC,KAAKsC,GAAiB;CAC1B;CAEA,OAAO,GAAG,GAAG,IAAa,MAAM;EAG5B,IAFA,KAAK,MAAM,UAAU,SAEjB/lB,GAAY;GACZ,IAAMyB,IAAWzB,EAAW,sBAAsB,GAC5CgmB,IAAavkB,EAAS;GAE5B,4BAA4B;IACxB,IAAMwkB,IAAU,KAAK,cAAc,eAAe;IAClD,IAAI,CAACA,GAAS;IACd,IAAM9Y,IAAa8Y,EAAQ,sBAAsB,CAAC,CAAC,OAE/CC,IAAiBF,IAAa7Y;IAElC,AAAI+Y,IAAiB,MACjB,IAAiBzkB,EAAS;IAG9B,IAAMyf,IAAc+E,EAAQ,sBAAsB,CAAC,CAAC,QAChDE,IAAgB9f;IAMpB,AALIA,IAAI6a,IAAc,OAAO,gBACzB,IAAgB7a,IAAI6a,IAGxB,KAAK,MAAM,OAAO,GAAGgF,EAAe,KACpC,KAAK,MAAM,MAAM,GAAGC,EAAc;GACtC,CAAC;EACL,OAII,AAHA,KAAK,MAAM,OAAO,GAAGr0B,EAAE,KACvB,KAAK,MAAM,MAAM,GAAGuU,EAAE,KAEtB,4BAA4B;GACxB,IAAM4f,IAAU,KAAK,cAAc,eAAe;GAClD,IAAI,CAACA,GAAS;GACd,IAAM/lB,IAAO+lB,EAAQ,sBAAsB;GAK3C,AAHIn0B,IAAIoO,EAAK,QAAQ,OAAO,eACxB,KAAK,MAAM,OAAO,GAAGpO,IAAIoO,EAAK,MAAM,MAEpCmG,IAAInG,EAAK,SAAS,OAAO,gBACzB,KAAK,MAAM,MAAM,GAAGmG,IAAInG,EAAK,OAAO;EAE5C,CAAC;EAcL,AAXI,KAAKyM,MACL,OAAO,oBAAoB,eAAe,KAAKA,EAAa,GAGhE,KAAKA,MAAiB,MAAM;GAExB,AAAI,EADS,EAAE,eAAe,EAAE,aAAa,IAAI,CAAC,EAAA,CACxC,SAAS,IAAI,KAAK,CAAC,KAAK,SAAS,EAAE,MAAM,KAC/C,KAAK,MAAM;EAEnB,GAEA,iBAAiB;GACb,OAAO,iBAAiB,eAAe,KAAKA,EAAa;EAC7D,GAAG,CAAC;CACR;CAEA,QAAQ;EAEJ,AADA,KAAK,MAAM,UAAU,QACrB,AAEI,KAAKA,QADL,OAAO,oBAAoB,eAAe,KAAKA,EAAa,GACvC;CAE7B;CAEA,gBAAgB,GAAQ,GAAW,GAAW;EAC1C,IAAMyZ,IAAK,KAAK,cAAc,eAAeX,EAAO,GAAG;EACvD,AAAIW,MACAC,IAAYD,EAAG,UAAU,IAAI9M,CAAS,IAAI8M,EAAG,UAAU,OAAO9M,CAAS;CAE/E;CAEA,GAAa,GAAU,GAAO;EAC1B,EAAM,SAAQ,MAAQ;GAClB,IAAI/sB,EAAK,SAAS,aAAa;IAC3B,IAAM+5B,IAAM,SAAS,cAAc,IAAI;IAEvC,AADA,EAAI,YAAY,qBAChBC,EAAS,YAAYD,CAAG;IACxB;GACJ;GAEA,IAAMF,IAAK,SAAS,cAAc,IAAI;GAEtC,AADAA,EAAG,aAAa,WAAW75B,EAAK,MAAM,GACtC,EAAG,YAAY,GAAGA,EAAK,aAAa,GAAG,GAAGA,EAAK,QAAQ,YAAY,GAAG,GAAGA,EAAK,WAAW,aAAa,KAAK,KAAK;GAEhH,IAAM4zB,IAAO,SAAS,cAAc,MAAM;GAI1C,IAHA,EAAK,cAAc5zB,EAAK,MACxB65B,EAAG,YAAYjG,CAAI,GAEf5zB,EAAK,SAASA,EAAK,MAAM,SAAS,GAAG;IACrC,IAAM83B,IAAQ,SAAS,cAAc,IAAI;IAGzC,AAFA,EAAM,YAAY,mBAClB,KAAKyB,GAAazB,GAAO93B,EAAK,KAAK,GACnC65B,EAAG,YAAY/B,CAAK;GACxB;GAEA,EAAS,YAAY+B,CAAE;EAC3B,CAAC;CACL;CAEA,KAAmB;EACf,KAAK,iBAAiB,aAAa,CAAC,CAAC,SAAQ,MAAM;GAC/C,EAAG,iBAAiB,UAAU,MAAM;IAEhC,IADA5zB,EAAE,gBAAgB,GACd4zB,EAAG,UAAU,SAAS,UAAU,GAAG;IAEvC,IAAMX,IAASW,EAAG,aAAa,SAAS;IAExC,AADA,KAAKR,KAAc;KAAE;KAAQ,QAAQQ;IAAG,CAAC,GACzC,KAAK,MAAM;GACf,CAAC;EACL,CAAC;CACL;CAEA,uBAAuB;EACnB,KAAK,MAAM;CACf;AACJ;AAEK,eAAe,IAAI,uBAAuB,KAC3C,eAAe,OAAO,yBAAyBT,CAAS"}
|