@ninebone/datagrid 0.1.6 โ 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/nine-table.css +76 -5
- package/dist/nine-table.js +580 -337
- package/dist/nine-table.js.map +1 -1
- package/dist/nine-table.umd.js +56 -19
- package/dist/nine-table.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nine-table.umd.js","names":["traceOrigin","GROUP_IDX","GROUP_IDX","factory","global","exports","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","_ninebone_util","NINE_TABLE","ngRow","#parent","parent","#newrow","ngData","#host","host","#initialize","item","validRecords","#getValidRecords","at","targetRecord","colnm","idx","rowData","rowIndex","colIndex","value","#conv","fields","#defaultHeight","templateElements","#getDefaultMeta","$el","loadData","dataSource","#invalidate","#nextId","rowid","jsonArray","arr","o","json","record","#json2Array","processedArr","#defaultInsert","row","updateState","targetIndex","#getIndexFromRow","arrIndex","records","b","a","targetId","index","COL_IDX","rowState","isSingle","targetArr","result","i","ngDataManager","ds","rowIdx","nRow","rowidx","#init","#fields","f","found","fieldName","fName","#adjust","map","name","type","rawTables","tbl","fieldType","attr","expr","lastIndex","targetField","NineTableSheets","NineTableSheetsFooter","#render","isMultiSelect","tabItem","#switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","tab","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","remainingCols","key","subRecords","subVal","r","RowManager","#initResizeObserver","bodyViewport","#measureAndCacheHeight","#renderAllContainers","#handleScroll","force","#isGrouped","#handleGroupedScroll","scrollTop","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","firstTr","#element","currentStartIndex","$tbody","dataIndex","#bindRowData","allRenderItems","totalVirtualCount","bodyContent","templateLength","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","#containerTemplates","tableEl","tbody","templateTrs","#sheetHeight","#isProgrammaticScroll","dataRow","targetScrollTop","rawTargetScrollTop","onRendered","#updateRowCount","visibleRows","#BUFFER_ROW_COUNT","groupDepth","#cachedRowCount","#renderRows","#syncRowHeights","targetFixedType","clonedTr","targetTbody","fragment","tmpl","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","entry","entries","height","TableCompiler","$table","$srcTable","#syncColAttributes","$col","fixed","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","sanitize","val","#range","root","elements","clientX","clientY","allCells","rect","targetCell","#getCellFromPoint","targetTr","#lastMatrixRow","#lastCol","#startRow","#startCol","#onMouseMove","mainZone","#onMouseUp","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","isAutoFit","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","finalWidth","newColWidth","newNextWidth","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","size","calculatedWidth","ColResizerPanel","#renderer","ColMover","#grip","#indi","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","btn","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","sum","containerWidth","defaultWidth","widthVal","targetAttributes","autoIdCounter","$tbl","tagName","$datalist","$option","uniqueFuncName","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","rows","section","indicatorCell","startColIdx","targetIdx","SheetAPI","colEl","resolve","$trs","matrixRows","n","callback","$sheetBody","tfootHeight","viewportTop","viewportBottom","trRect","isAbove","isBelow","toRowid","NineTableSheet","#rowManager","#api","#bindApiMethods","#template","#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","activeParent","$parent","minRows","#syncHeaderAndFooterHeights","#initRowHoverEvent","prefix","firstTable","#createSplitTable","offsetHeight","sheetBottom","tbodyBottom","bodyContainer","scrollLeft","#sorting","leftHeaderRows","bodyHeaderRows","rightHeaderRows","#applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","api","args","LayoutManager","owner","#initEvent","sheetCount","sheetsHtml","className","sheetId","cssImports","$sheet","#isAutoHeight","#applyAutoHeight","lastHeight","currentHeight","basicHeight","ExprEngine","match","trimmedExpr","compiledExpr","evalFn","#exprCache","rowItem","DataAPI","providerObj","methods","fn","NineTableAPI","ns","#getActiveSheet","targetMethod","prop","NineTable","#shadowRoot","#dataManager","#dataApi","#sheetApi","#templateCnt","#bindDynamicSetters","#layoutManager","#dispatchLoad","checkCount","checkTimer","loadSheetCnt","idOrIndex","extractedMethodNames","matches","internalValue","methodName","newValue","BasicCellElement","exprCache","CellElement","#updateRowState","#cell","#tr","#attr","button","curRow","renderer","rawRecord","defaultValue","\"display\"","data","cleanExpr","childRecords","funcName","field","acc","EditableCellElement","CellInputText","#target","#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","activeColumnCount","selectedKeys","kIndex","chkIndex","#selectRow","currentValue","formattedData","#EXPAND_ROW_COUNT","$btn","btnRect","h1","isDropDown","h2","items","#isPanelBelow","#calculatePanelHeight","#calculatePanelLeft","#initData","#checkRow","#returnRow","#onKeydown_input","#onKeydown","CellCombo","#getDisplayText","#validateInput","keys","list","#togglePanel","CellRenderer","CellButton","#cellButtonClick","customEvent","rawValue","CellRowIndicator","#mainTarget","#subTarget","#statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","ColExpand","singleWidth","currentW","splitWidth","ContextMenu","#tableHost","targetTable","#getTargetSheet","activeTableId","activeTable","containerElement","targetTableAttr","rootUl","parsedList","#traverseUl","ulEl","child","spanEl","subUl","useDefault","rawItems","customItems","#parseCustomMenuItems","fixManager","#getFixManager","currentFixState","isFixable","isHeaderCell","fixMenuItem","cleanedItems","targetParent","menuItems","#buildMenuItems","#handleMenuClick","#syncMenuStates","isFiltering","autoFit","showTitle","menuId","#onContextMenu","MenuPanel","#onCallback","#appendItems","#bindClickEvents","cellRightX","wrapper","calculatedLeft","panelHeight","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/api/SheetAPI.js","../src/layout/nine-table-sheet.js","../src/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/api/DataAPI.js","../src/api/NineTableAPI.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 ROW_STATE: 1,\n FILTER: 2,\n GROUP: 3,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 0,\n NORMAL: 1,\n INSERT: 2,\n UPDATE: 3,\n DELETE: 9\n },\n EVENT: {\n LOAD: \"load\",\n ROW_ADDED: \"row-added\",\n ROW_REMOVED: \"row-removed\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport class ngRow {\n\t#parent;\n\t#newrow = -1;\n\n\tconstructor(parent) {\n\t\tthis.#parent = parent;\n\t}\n\n\tget at() {\n\t\treturn this.#newrow;\n\t}\n\tset at(v) {\n\t\tthis.#newrow = parseInt(v, 10);\n\t}\n\n\tcount = () => this.#parent.rawRecords.length;\n}\n\nexport class ngData {\n\t#host;\n\t#parent;\n\t#nextId = 0;\n\t#defaultHeight = [];\n\n\tstatic META_INDEX = {\n\t\tFILTER: 0,\n\t\t// GROUP: 1,\n\t\t// SELECT: 2,\n\t\t// EXPAND: 3\n\t};\n\n\tstatic ROW_STATE = {\n\t\tEMPTY: 'EMPTY',\n\t\tNORMAL: 'NORMAL',\n\t\tINSERT: 'INSERT',\n\t\tUPDATE: 'UPDATE',\n\t\tDELETE: 'DELETE'\n\t};\n\n\tconstructor(host, parent) {\n\t\tthis.#host = host;\n\t\tthis.#parent = parent;\n\t\tthis.#initialize();\n\t}\n\n\n\t#getValidRecords = () => {\n\t\tconst rawRecords = this.#parent.rawRecords || [];\n\t\treturn rawRecords.filter(item => item.m._[NINE_TABLE.META.INDEX.ROW_STATE] !== NINE_TABLE.ROW_STATE.DELETE);\n\t};\n\n\tget count() {\n\t\treturn this.length;\n\t}\n\n\tcount = () => {\n\t\treturn this.length;\n\t};\n\n\tgetArray = (at, colnm) => {\n\t\tconst validRecords = this.#getValidRecords();\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn validRecords; // ๋ณํ ์์ด ๋ฐฐ์ด ๊ทธ๋๋ก ๋ฐํ (๋ ๋๋ง ์ต์ ํ)\n\t\t}\n\n\t\tif (at < 0 || at >= validRecords.length) return null;\n\n\t\tconst targetRecord = validRecords[at];\n\n\t\tif (colnm != null) {\n\t\t\tconst fields = this.getHostFields();\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn targetRecord;\n\t};\n\n\tsetArray = (rowIndex, colIndex, value) => {\n\t\tconst validRecords = this.#getValidRecords();\n\t\tconst rowData = validRecords[rowIndex];\n\n\t\tconst oldValue = rowData.v[colIndex];\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\n\t\t}\n\n\t\trowData.v[colIndex] = value;\n\t};\n\n\n\tget = (at, colnm) => {\n\t\tconst validRecords = this.#getValidRecords();\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn this.#conv(validRecords);\n\t\t}\n\n\t\tif (at < 0 || at >= validRecords.length) return null;\n\n\t\tconst targetRecord = validRecords[at];\n\t\tconst fields = this.getHostFields();\n\n\t\tif (colnm != null) {\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn this.#conv(targetRecord);\n\t};\n\n\tgetAll = () => {\n\t\treturn this.#parent.rawRecords || [];\n\t};\n\n\tgetHostFields = () => {\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\n\t};\n\n\t#initialize = () => {\n\t\tthis.#defaultHeight = [];\n\t\tconst templateElements = this.#host.template || [];\n\t\tArray.from(templateElements).forEach(el => {\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\n\t\t});\n\n\t\t(this.#parent.rawRecords || []).forEach(v => {\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\n\t\t});\n\t};\n\n\tget source() {\n\t\treturn this.#conv(this.#parent.rawRecords);\n\t}\n\tset source(v) {\n\t\tthis.set(v);\n\t}\n\n\t#invalidate = () => {\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\n\t\t\t$el.invalidate();\n\t\t});\n\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\n\t};\n\n\tset = (dataSource) => {\n\n\t\tconst loadData = () => {\n\t\t\tthis.#host.loading = true;\n\t\t\tsetTimeout(() => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.clear();\n\t\t\t\t\tthis.add(dataSource, false);\n\t\t\t\t\tthis.#invalidate();\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#host.loading = false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (this.#host.loaded) {\n\t\t\tloadData();\n\t\t}\n\t\telse {\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\n\t\t\t\tloadData();\n\t\t\t}, { once: true });\n\t\t}\n\t};\n\n\tget nextId() {\n\t\treturn this.#nextId++;\n\t}\n\n\tget length() {\n\t\treturn this.#getValidRecords().length;\n\t}\n\n\tget count() {\n\t\treturn this.length;\n\t}\n\n\tgetRowCount() {\n\t\treturn this.length;\n\t}\n\n\t#getDefaultMeta = (rowid = 0) => {\n\t\treturn {\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\n\t\t\tdeleted: false,\n\t\t\tfiltered: false,\n\t\t\theight: this.#defaultHeight.slice(),\n\t\t\to: {},\n\t\t\tc: {},\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\n\t\t\t_: [rowid, NINE_TABLE.ROW_STATE.EMPTY, [], []],\n\t\t};\n\t};\n\n\treset = () => {\n\t\tthis.#parent.rawRecords = [];\n\t\tthis.#invalidate();\n\t};\n\n\tclear = () => {\n\t\tthis.#parent.rawRecords = [];\n\t\tif (this.#parent.viewRecords?.reset) {\n\t\t\tthis.#parent.viewRecords.reset();\n\t\t}\n\n\t\tthis.#nextId = 0;\n\n\t\tthis.#invalidate();\n\t};\n\n\t#json2Array = (jsonArray) => {\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\n\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\n\t\tconst arr = [];\n\n\t\tjsonArray.forEach(json => {\n\t\t\tconst o = { v: [] };\n\t\t\tfields.forEach(colnm => {\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\n\t\t\t});\n\t\t\tarr.push(o);\n\t\t});\n\n\t\treturn arr;\n\t};\n\n\t#defaultInsert = (arr) => {\n\t\tif (!Array.isArray(arr)) arr = [arr];\n\t\tarr.forEach(o => {\n\t\t\tconst rowid = this.nextId;\n\n\t\t\to.m = this.#getDefaultMeta(rowid);\n\t\t\to.__ng = o.m;\n\t\t\to.__ng.rowid = rowid;\n\t\t\t//o.__ng.rowState = ngData.ROW_STATE.INSERT;\n\n\t\t\to.m._[NINE_TABLE.META.INDEX.ROWID] = rowid;\n\t\t\to.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.EMPTY;\n\t\t});\n\t\treturn arr;\n\t};\n\n\t#getIndexFromRow = (rowid) => {\n\t\tconst index = this.#parent.rawRecords.findIndex(record => {\n\t\t\tif (!record || !record.m || !record.m._) return false;\n\t\t\treturn record.m._[NINE_TABLE.META.INDEX.ROWID] === rowid;\n\t\t});\n\n\t\treturn index;\n\t}\n\n\tadd = (dataSource, updateState = true) => {\n\t\tif (dataSource === undefined) dataSource = {};\n\t\tconst arr = this.#json2Array(dataSource);\n\n\t\tconst processedArr = this.#defaultInsert(arr);\n\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(processedArr);\n\n\t\tconst row = this.count() - 1;\n\t\tif (updateState) {\n\t\t\tarr.forEach((_, idx) => {\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\n\t\t\t\tif (target) target.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.INSERT;\n\t\t\t});\n\t\t}\n\n\t\tthis.#invalidate();\n\n\t\tthis.#host.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.ROW_ADDED, {\n\t\t\tbubbles: true,\n\t\t\tdetail: { target: this.#host, rowid: processedArr.length > 0 ? processedArr[0].m._[NINE_TABLE.META.INDEX.ROWID] : null }\n\t\t}));\n\n\t\treturn row;\n\t};\n\n\n\tinsert = (rowid, dataSource, updateState = true) => {\n\t\t//trace.log(\"์ฐพ์ rowid:\", rowid);\n\n\t\tif (dataSource === undefined) dataSource = {};\n\t\tconst arr = this.#json2Array(dataSource);\n\t\tif (arr.length === 0) return -1;\n\n\t\tlet targetIndex = this.#getIndexFromRow(rowid);\n\t\t/**\n\t\tif (rowid !== undefined && rowid !== null) {\n\t\t\ttargetIndex = this.#parent.rawRecords.findIndex(record => {\n\t\t\t\tif (!record || !record.m || !record.m._) return false;\n\t\t\t\treturn record.m._[NINE_TABLE.META.INDEX.ROWID] === rowid;\n\t\t\t});\n\t\t} */\n\n\t\tconst processedArr = this.#defaultInsert(arr);\n\n\t\t//if (targetIndex === -1) {\n\t\t//\ttargetIndex = this.#parent.rawRecords.length;\n\t\t//}\n\n\t\tthis.#parent.rawRecords.splice(targetIndex, 0, ...processedArr);\n\n\t\tif (updateState) {\n\t\t\tprocessedArr.forEach((_, idx) => {\n\t\t\t\tconst target = this.#parent.rawRecords[targetIndex + idx];\n\n\t\t\t\tif (target && target.m && target.m._) {\n\t\t\t\t\ttarget.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.INSERT;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.#invalidate();\n\n\t\tthis.#host.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.ROW_ADDED, {\n\t\t\tbubbles: true,\n\t\t\tdetail: { target: this.#host, rowid: processedArr.length > 0 ? processedArr[0].m._[NINE_TABLE.META.INDEX.ROWID] : null }\n\t\t}));\n\n\t\treturn processedArr[0].m._[NINE_TABLE.META.INDEX.ROWID]; // ์ฝ์
๋ ์ค์ ๋ฐฐ์ด ์ธ๋ฑ์ค ๋ฐํ\n\t};\n\n\tremove = (v) => {\n\t\tlet arr = [];\n\t\tif (Array.isArray(v)) {\n\t\t\tarr = at;\n\t\t//} else if (typeof at === \"undefined\") {\n\t\t//\tarr = [this.#parent.host.row.at];\n\t\t} else {\n\t\t\tarr = [parseInt(v, 10)];\n\t\t}\n\n\t\tlet arrIndex = [];\n\t\tarr.forEach(rowid => {\n\t\t\tarrIndex.push(this.#getIndexFromRow(rowid));\n\t\t});\n\n\t\tconst records = this.#parent.rawRecords;//this.#getValidRecords();\n\n\t\tarrIndex.sort((a, b) => b - a).forEach(index => {\n\t\t\t//if (validRecords[index]) {\n\t\t\t\tconst targetId = records[index].m._[NINE_TABLE.META.INDEX.ROWID];\n\n\t\t\t\tif (records[index].m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.INSERT) {\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.m._[NINE_TABLE.META.INDEX.ROWID] !== targetId);\n\t\t\t\t} else {\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\n\t\t\t\t\t\tif (item.m._[NINE_TABLE.META.INDEX.ROWID] === targetId) {\n\t\t\t\t\t\t\titem.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.DELETE;\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.#invalidate();\n\n\t\tthis.#host.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.ROW_REMOVED, {\n\t\t\tbubbles: true,\n\t\t\tdetail: { target: this.#host, rowid: arr.length > 0 ? arr[0] : null }\n\t\t}));\n\t};\n\n\tsetValue = (rowid, colnm, value, updateState = true) => {\n\n\t\trowid = parseInt(rowid, 10);\n\t\tconst fields = this.getHostFields();\n\t\tconst COL_IDX = fields.indexOf(colnm);\n\t\tif (COL_IDX < 0) return;\n\n\t\tconst index = this.#getIndexFromRow(rowid);\n\n\t\tconst records = this.#parent.rawRecords;\n\t\tconst rowData = records[index];\n\t\tif (!rowData) return;\n\n\t\tconst oldValue = rowData.v[COL_IDX];\n\t\tif (oldValue !== value && updateState && rowData.m._[NINE_TABLE.META.INDEX.ROW_STATE] !== NINE_TABLE.ROW_STATE.INSERT) {\n\t\t\trowData.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.UPDATE;\n\t\t}\n\n\t\trowData.v[COL_IDX] = value;\n\t};\n\n\tgetChangedData = (rowState) => {\n\n\t\tconst records = this.#parent.rawRecords;\n\n\t\tif (rowState) {\n\t\t\treturn this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === rowState; } ) );\n\t\t}\n\t\telse {\n\t\t\treturn {\n\t\t\t\tC: this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.INSERT; } ) ),\n\t\t\t\tU: this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.UPDATE; } ) ),\n\t\t\t\tD: this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.DELETE; } ) ),\n\t\t\t};\n\t\t}\n\t};\n\n\t#conv = (arr) => {\n\t\tif (!arr) return arr;\n\n\t\tconst isSingle = !Array.isArray(arr);\n\t\tconst targetArr = isSingle ? [arr] : arr;\n\t\tconst fields = this.getHostFields();\n\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\n\t\t\tconst t = {};\n\t\t\tfields.forEach((colnm, i) => {\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\n\t\t\t});\n\t\t\tt.__ng = o.__ng;\n\t\t\treturn t;\n\t\t});\n\n\t\treturn isSingle ? result[0] : result;\n\t};\n}\n","import { ngRow, ngData } from \"./ngData.js\";\n\nexport class ngDataManager {\n\t#host;\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\n\t\tthis.row = new ngRow(this);\n\t\tthis.data = new ngData(this.#host, this);\n\n\t\tthis.rawRecords = [];\n\t\tthis.viewRecords = [];\n\t\tthis.delRecords = [];\n\t\tthis.pageCnt = 25;\n\n\t\tthis.viewRecords.reset = () => {\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\n\t\t};\n\n\t\tthis.setDataSource = (ds) => {\n\t\t\tif (this.data) this.data.reset();\n\n\t\t\tthis.rawRecords = [];\n\t\t\tthis.viewRecords = [];\n\t\t\tthis.delRecords = [];\n\n\t\t\tthis.data.set(ds || []);\n\t\t};\n\n\t\tthis.getRowState = (nRow) => {\n\t\t\tconst rowIdx = parseInt(nRow, 10);\n\t\t\tif (rowIdx >= this.data.count()) return;\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\n\t\t};\n\n\t\tthis.getRowPosition = () => this.row.at;\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\n\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\n\n\t\tthis.setColumn = (rowidx, colnm, v) => {\n\t\t\trowidx = parseInt(rowidx, 10);\n\t\t\tthis.data.setValue(rowidx, colnm, v);\n\t\t};\n\n\t\t// ์ด๊ธฐ ๋น ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ\n\t\tthis.setDataSource([]);\n\t}\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 ['mouseup', 'mouseleave'].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\";\n\nexport const GROUP_IDX = {\n\tID: 0,\n\tDEPTH: 1,\n\tNAME: 2,\n\tCHILDREN: 3,\n};\n\nexport class GroupingManager {\n\t#sheet;\n\t#host;\n\t#groupColumns = [];\n\t#groupMap = new Map(); // ๊ทธ๋ฃน๋ณ ์์ ID ๋งคํ ๊ด๋ฆฌ์ฉ\n\t#isApplying = false;\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = this.#sheet.getRootNode().host;\n\t}\n\n\tget columns() {\n\t\treturn this.#groupColumns;\n\t}\n\n\tget groupMap() {\n\t\treturn this.#groupMap;\n\t}\n\n\tinitialize = () => {\n\t\tlet groupColumns = [];\n\t\tconst sourceTable = this.#sheet.sourceTable;\n\t\tif (sourceTable) {\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.#groupColumns = groupColumns;\n\t};\n\n\tapply() {\n\n\t\tif (this.#isApplying) return;\n\t\tthis.#isApplying = true;\n\n\t\tlet groupColumns = [];\n\t\tconst sourceTable = this.#sheet.sourceTable;\n\t\tif (sourceTable) {\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.#groupColumns = groupColumns;\n\n\t\tthis.#isApplying = false;\n\t\tthis.#sheet.scrollToY(0);\n\t\tthis.#sheet.view.refresh();\n\t}\n\n\tclear() {\n\t\tthis.#groupColumns = [];\n\t\tthis.#groupMap.clear();\n\t\tthis.#isApplying = false;\n\t\tthis.#sheet.scrollToY(0);\n\t\tthis.#sheet.view.refresh();\n\t}\n\n\tsetGroupMap(map) {\n\t\tthis.#groupMap = map;\n\t}\n\n\tgetChildrenRowIds(groupId) {\n\t\treturn this.#groupMap.get(groupId) || [];\n\t}\n\n\tgetChildrenRecords(groupId) {\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\n\t\tconst dataManager = this.#host.data;\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\n\t}\n}\n\nexport class Grouping {\n\n\tstatic apply(rawRecords, groupColumns = [], fields = []) {\n\t\tif (!groupColumns || groupColumns.length === 0) {\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\n\t\t}\n\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\n\t\tconst groupMap = new Map();\n\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\n\t\tconst flatResult = [];\n\t\tconst renderItems = [];\n\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\");\n\n\t\treturn { headers: flatResult, renderItems, groupMap };\n\t}\n\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId) {\n\t\tlet counter = 0;\n\t\tconst isLastLevel = (depth === groupColumns.length - 1); // ๐ก ์ฐ์ฐ์ ์์ ๋ฐ์\n\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\n\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\n\t\t\tgroupMap.set(groupId, rowIds);\n\n\t\t\tconst groupRecord = [];\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\n\n\t\t\tgroupRecord.__isGroupHeader = true;\n\t\t\tgroupRecord.__groupId = groupId;\n\n\t\t\tresultArr.push(groupRecord);\n\n\t\t\trenderItems.push({\n\t\t\t\ttype: 'group',\n\t\t\t\trecord: groupRecord,\n\t\t\t\tgroupId: groupId\n\t\t\t});\n\n\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\n\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId);\n\t\t\t} else {\n\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\n\t\t\t\tleafRecords.forEach(record => {\n\t\t\t\t\trecord.__isGroupHeader = false;\n\t\t\t\t\trecord.__groupId = groupId;\n\t\t\t\t\tresultArr.push(record);\n\n\t\t\t\t\trenderItems.push({\n\t\t\t\t\t\ttype: 'data',\n\t\t\t\t\t\trecord: record,\n\t\t\t\t\t\tgroupId: groupId\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic #buildNestedMap(records, groupColumns, fields) {\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\n\t\tconst remainingCols = groupColumns.slice(1);\n\t\tconst map = new Map();\n\n\t\trecords.forEach(record => {\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\n\t\t\tif (!map.has(key)) map.set(key, []);\n\t\t\tmap.get(key).push(record);\n\t\t});\n\n\t\tif (remainingCols.length > 0) {\n\t\t\tconst result = new Map();\n\t\t\tfor (let [key, subRecords] of map.entries()) {\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\treturn map;\n\t}\n\n\tstatic #collectLeafRowIds(subMapOrRecords) {\n\t\tlet rowIds = [];\n\t\tif (subMapOrRecords instanceof Map) {\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\n\t\t\t}\n\t\t} else if (Array.isArray(subMapOrRecords)) {\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\n\t\t}\n\t\treturn rowIds;\n\t}\n\n\tstatic #collectLeafRecords(subMapOrRecords) {\n\t\tlet records = [];\n\t\tif (subMapOrRecords instanceof Map) {\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\n\t\t\t}\n\t\t} else if (Array.isArray(subMapOrRecords)) {\n\t\t\trecords = records.concat(subMapOrRecords);\n\t\t}\n\t\treturn records;\n\t}\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 #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.#sheet.template.height;\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.#sheet.template.height || this.#sheet.template.height <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#sheet.template.height && this.#sheet.template.height > 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.#sheet.template.height;\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 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) - rowHeight, 0);\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\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 const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n //trace.log(clampedScrollTop % rowHeight, rowHeight);\n\n /*\n * FIX: Use GPU-accelerated transform3d instead of 'top' positioning.\n * On mobile devices (iOS Safari), direct 'top' updates trigger expensive\n * layout reflows and cause severe scrolling lag during inertia touch scrolls.\n * translate3d forces hardware compositing for buttery-smooth performance.\n */\n this.#sheet.elements.left.tbody.body.style.transform =\n this.#sheet.elements.body.tbody.body.style.transform =\n this.#sheet.elements.right.tbody.body.style.transform = `translate3d(0px, -${clampedScrollTop % rowHeight}px, 0px)`;\n\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 / this.#sheet.template.length);\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.#sheet.template.height[depth] || this.#sheet.template.height / 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.#sheet.template.heights[i] || 0;\n }\n dataRowsHeight = this.#sheet.template.height - groupHeightsTotal;\n\n return dataRowsHeight > 0 ? dataRowsHeight : this.#sheet.template.height;\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.#sheet.template.height / 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 //trace.log(\"this.#sheetHeight\", this.#sheetHeight, this.#sheet);\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', (e) => {\n\n this.#sheet.querySelectorAll(\"cell-combo-panel\").forEach($el => {\n $el.classList.remove('active');\n });\n\n\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#sheet.template.height || 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.#sheet.template.height;\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 this.#updateRowCount();\n return;\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-container-body tbody.body');\n if (!$tbody) return;\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 renderedTrs.forEach(tr => tr.remove());\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n\n if (this.#sheetHeight > 0 && this.#sheet.template.height > 0) {\n const visibleRows = Math.ceil(this.#sheetHeight / this.#sheet.template.height);\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\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\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\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 //trace.log(\"this.#sheetHeight\", this.#sheetHeight);\n this.#updateRowCount();\n\n if (this.#sheet.template.height !== 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\";\n\nexport class CellSelection {\n\t#sheet;\n\t#host;\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tthis.#initEvents();\n\t}\n\n\t#getMatrixRow(tr) {\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\n\n\t\tconst dataRow = parseInt(tr.dataset.index, 10);\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\n\n\t\tconst tbody = tr.closest('tbody');\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr'));\n\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.index, 10) === dataRow);\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\n\t\tconst templateLength = sameGroupTrs.length > 0 ? sameGroupTrs.length : 1;\n\n\t\tconst matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\n\n\t\treturn { dataRow, subRowIndex, matrixRow };\n\t}\n\n\tsetFocus(matrixRow, col) {\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {\n\t\t\t$tr.classList.remove(\"selected-start\");\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {\n\t\t\t\t$td.classList.remove(\"selected-start\");\n\t\t\t});\n\t\t});\n\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\n\t\tif (!$td) return;\n\n\t\t$td.classList.add(\"selected-start\");\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\n\t}\n\n\tsetRange(startRow, startCol, endRow, endCol) {\n\t\tlet r1 = Math.min(startRow, endRow);\n\t\tlet r2 = Math.max(startRow, endRow);\n\t\tlet c1 = Math.min(startCol, endCol);\n\t\tlet c2 = Math.max(startCol, endCol);\n\n\n\t\tif (this.#host.tagName === \"NINE-TABLE-SIMPLE\") {\n\t\t\tc1 = 1;\n\t\t\tc2 = 10;\n\t\t}\n\n\t\tconst containers = this.#sheet.querySelectorAll('.ng-container-left, .ng-container-body, .ng-container-right');\n\n\t\tlet expanded = true;\n\t\tlet loopCount = 0;\n\n\t\twhile (expanded && loopCount < 5) {\n\t\t\texpanded = false;\n\t\t\tloopCount++;\n\n\t\t\tcontainers.forEach(container => {\n\n\t\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\n\t\t\t\t\treturn tr.style.display !== 'none'; // ํน์ tr.offsetHeight > 0 ์ฒดํฌ\n\t\t\t\t});\n\n\t\t\t\tvisibleTrs.forEach(tr => {\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\n\t\t\t\t\tif (matrixRow < 0) return;\n\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\n\t\t\t\t\t\tif (isNaN(col)) return;\n\n\t\t\t\t\t\tconst colEl = this.#sheet.querySelector(`col[data-col=\"${col}\"]`);\n\t\t\t\t\t\tif (colEl.style.display !== 'none') {\n\t\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\n\t\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\n\n\t\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\n\t\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\n\n\t\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\n\n\t\t\t\t\t\t\tif (isIntersecting) {\n\t\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\n\t\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\n\t\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\n\t\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\n\n\t\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\n\t\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\n\t\t\t\t\t\t\t\t\texpanded = true;\n\t\t\t\t\t\t\t\t}\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\tconst sanitize = (val) => (!Number.isFinite(val) ? -1 : val);\n\n\t\tthis.#range = {\n\t\t\tstartRow: sanitize(r1),\n\t\t\tstartCol: sanitize(c1),\n\t\t\tendRow: sanitize(r2),\n\t\t\tendCol: sanitize(c2)\n\t\t};\n\n\t\t//trace.log(this.#range);\n\n\t\tthis.render();\n\t}\n\n\tclear = () => {\n\t\tthis.#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\n\t};\n\n\tget minRow() {\n\t\treturn this.#range.startRow;\n\t};\n\tget maxRow() {\n\t\treturn this.#range.endRow;\n\t};\n\tget minCol() {\n\t\treturn this.#range.startCol;\n\t};\n\tget maxCol() {\n\t\treturn this.#range.endCol;\n\t};\n\n\trefresh = () => {\n\t\tthis.render();\n\t}\n\n\trender = () => {\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\n\n\t\tconst containers = this.#sheet.querySelectorAll(\n\t\t\t'.ng-container-left, .ng-container-body, .ng-container-right'\n\t\t);\n\n\t\tcontainers.forEach(container => {\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\n\t\t\t});\n\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\n\t\t\t\ttr.classList.remove('selected-start');\n\t\t\t});\n\t\t});\n\n\t\tif (startRow < 0 || startCol < 0) return;\n\n\t\tcontainers.forEach((container) => {\n\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\n\t\t\t\treturn tr.style.display !== 'none';\n\t\t\t});\n\n\t\t\tvisibleTrs.forEach(tr => {\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\n\t\t\t\tif (matrixRow < 0) return;\n\n\n\t\t\t\tif (matrixRow >= startRow && matrixRow <= endRow) {\n\t\t\t\t\tcontainer.querySelectorAll(`tbody tr[data-index=\"${tr.dataset.index}\"]`).forEach(tr => {\n\t\t\t\t\t\ttr.classList.add('selected');\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t//trace.log(this.#sheet.view);\n\n\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\n\t\t\t\t\tif (isNaN(col)) return;\n\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\n\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\n\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\n\t\t\t\t\tif (!isSelected) return;\n\n\t\t\t\t\tcell.classList.add('selected');\n\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t}\n\n\t#lastMatrixRow;\n\t#lastCol;\n\t#startRow;\n\t#startCol;\n\t//#dragStart;\n\n\t#getCellFromPoint = (clientX, clientY) => {\n\t\tconst root = this.#sheet.getRootNode();\n\t\tif (root && typeof root.elementsFromPoint === 'function') {\n\t\t\tconst elements = root.elementsFromPoint(clientX, clientY);\n\t\t\tfor (const el of elements) {\n\t\t\t\tconst c = el.closest('td, th');\n\t\t\t\tif (c && this.#sheet.contains(c) && c.dataset.row !== undefined) {\n\t\t\t\t\treturn c;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr td, .ng-sheet-body-content tbody tr:not(.nodata) th');\n\t\tfor (const c of allCells) {\n\t\t\tconst rect = c.getBoundingClientRect();\n\t\t\tif (\n\t\t\t\tclientX >= rect.left &&\n\t\t\t\tclientX <= rect.right &&\n\t\t\t\tclientY >= rect.top &&\n\t\t\t\tclientY <= rect.bottom\n\t\t\t) {\n\t\t\t\treturn c;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t};\n\n\t#onMouseMove = (moveEvent) => {\n\n\t\t//if (!this.#dragStart) return;\n\n\t\tconst targetCell = this.#getCellFromPoint(moveEvent.clientX, moveEvent.clientY);\n\t\tif (!targetCell) return;\n\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\n\n\t\tconst targetTr = targetCell.closest('tr');\n\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\n\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\n\n\t\tif (endRow < 0) return;\n\t\tif (this.#lastMatrixRow === endRow && this.#lastCol === endCol) return;\n\n\t\t//trace.log(moveEvent);\n\n\t\tthis.#lastMatrixRow = endRow;\n\t\tthis.#lastCol = endCol;\n\n\t\tthis.setRange(this.#startRow, this.#startCol, endRow, endCol);\n\t};\n\n\t#onMouseUp = () => {\n\t\t//this.#dragStart = false;\n\n\t\tdocument.removeEventListener('mousemove', this.#onMouseMove);\n\n\t\t//this.#sheet.style.userSelect = '';\n\t\t//this.#sheet.style.webkitUserSelect = '';\n\n\n\t\t//document.removeEventListener('mouseup', this.#onMouseUp);\n\t};\n\n\t#initEvents() {\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\n\t\tif (!mainZone) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocument.addEventListener('mouseup', this.#onMouseUp);\n\n\t\tmainZone.addEventListener('mousedown', (e) => {\n\n\t\t\tif (e.button !== 0) return;\n\n\t\t\t/**\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#dragStart = true;\n\t\t\t}, 100);\n\t\t\t*/\n\n\t\t\tconst cell = e.target.closest('td, th');\n\t\t\tif (!cell) return;\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\n\n\t\t\tthis.#sheet.style.userSelect = 'none';\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\n\n\t\t\tconst tr = cell.closest('tr');\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\n\n\t\t\tthis.#startRow = startRow;\n\t\t\tthis.#startCol = startCol;\n\n\t\t\tif (startRow < 0) {\n\t\t\t\tthis.#sheet.style.userSelect = '';\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.setFocus(startRow, startCol);\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\n\n\t\t\tthis.#lastMatrixRow = startRow;\n\t\t\tthis.#lastCol = startCol;\n\n\t\t\t// ๋๋๊ทธ๊ฐ ์์๋ ๋๋ง document์ move/up ๋ฆฌ์ค๋๋ฅผ ๋ถ์ฌ ๋ญ๋น๋ฅผ ์ค์ด๊ณ ํ์คํ๊ฒ ์ถ์ \n\t\t\tdocument.addEventListener('mousemove', this.#onMouseMove);\n\t\t});\n\t}\n}","import { trace } from \"@nopeer\";\n\nexport class CellNavigation {\n\t#sheet;\n\t#host;\n\n\t#currentCell = null;\n\t#currentTr = null;\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tthis.#initEvents();\n\t}\n\n\tget currentCell() {\n\t\treturn this.#currentCell;\n\t}\n\n\tset currentCell(cell) {\n\t\tif (!cell) return;\n\n\t\tthis.#currentCell = cell;\n\t\tcell.focus({ preventScroll: true });\n\n\t\tthis.#currentTr = cell.closest(\"tr\");\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\n\t}\n\n\n\t#moveCellH = (e, cell) => {\n\n\t\tif (!cell) return;\n\n\t\tswitch (e.code) {\n\t\t\tcase \"Tab\":\n\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!this.#isCellRightVisible(cell)) {\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowRight\":\n\t\t\t\tif (!this.#isCellRightVisible(cell) || !this.#isCellLeftVisible(cell)) {\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowLeft\":\n\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tthis.currentCell = cell;\n\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\n\t};\n\n\t#moveCellV = (e, cell) => {\n\t\tif (cell) {\n\t\t\tlet isVisible = false;\n\t\t\tswitch (e.code) {\n\t\t\t\tcase \"Enter\":\n\t\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\n\t\t\t\t\t\t\tisVisible = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\n\t\t\t\t\t\t\tisVisible = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ArrowDown\":\n\t\t\t\t\tif (this.#isCellBelowVisible(cell)) {\n\t\t\t\t\t\tisVisible = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ArrowUp\":\n\t\t\t\t\tif (this.#isCellAboveVisible(cell)) {\n\t\t\t\t\t\tisVisible = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (isVisible) {\n\t\t\t\tthis.currentCell = cell;\n\t\t\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\n\t\tlet scrollTopIndex = -1;\n\t\tswitch (e.code) {\n\t\t\tcase \"Enter\":\n\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\tconst visibleRowCount = this.#getVisibleRowCount();\n\t\t\t\t\tscrollTopIndex = Math.max(dataIndex - visibleRowCount + 0, 0);\n\t\t\t\t} else {\n\t\t\t\t\tscrollTopIndex = Math.min(dataIndex, this.#sheet.view.count());\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tscrollTopIndex = Math.min(dataIndex, this.#sheet.view.count());\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowUp\":\n\t\t\t\tconst visibleRowCount = this.#getVisibleRowCount();\n\t\t\t\tscrollTopIndex = Math.max(dataIndex - visibleRowCount + 0, 0);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (scrollTopIndex < 0) return;\n\n\t\tlet matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst rowSpan = parseInt(this.#currentCell.rowSpan, 10) || 1;\n\n\t\tswitch (e.code) {\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tmatrixRow += rowSpan;\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowUp\":\n\t\t\t\tmatrixRow --;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tthis.#sheet.rowManager.scrollToDataRow(scrollTopIndex, null, () => {\n\t\t\tconst currentCell = this.#findCell(matrixRow, col);\n\n\t\t\tif (currentCell) {\n\t\t\t\tthis.currentCell = currentCell;\n\t\t\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, currentCell.dataset.col, this.#currentTr.dataset.matrixRow, currentCell.dataset.col);\n\t\t\t}\n\t\t});\n\t}\n\n\tmoveCell = (e) => {\n\n\t\tif (e.target.tagName === \"INPUT\") {\n\t\t\tif ([\"text\"].includes(e.target.type)) {\n\t\t\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Home\",\"End\"].includes(e.code)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ([\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(e.target.type)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (!this.#currentCell || !this.#currentTr) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet nextCell;\n\t\tswitch (e.code) {\n\t\t\tcase \"Tab\":\n\t\t\t\tnextCell = e.shiftKey ? this.#getPreviousCell() : this.#getNextCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowRight\":\n\t\t\t\tnextCell = this.#getNextCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowLeft\":\n\t\t\t\tnextCell = this.#getPreviousCell();\n\t\t\t\tbreak;\n\t\t\tcase \"Enter\":\n\t\t\t\tnextCell = e.shiftKey ? this.#getUpCell() : this.#getDownCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tnextCell = this.#getDownCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowUp\":\n\t\t\t\tnextCell = this.#getUpCell();\n\t\t\t\tbreak;\n\t\t}\n\n\t\te.preventDefault();\n\n\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Tab\"].includes(e.code)) {\n\t\t\tthis.#moveCellH(e, nextCell);\n\t\t}\n\t\telse if ([\"Enter\",\"ArrowUp\",\"ArrowDown\"].includes(e.code)) {\n\t\t\tthis.#moveCellV(e, nextCell);\n\t\t}\n\t}\n\n\t#getNextCell = () => {\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst colSpan = parseInt(this.#currentCell.colSpan, 10) || 1;\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\tconst nextCol = col + colSpan;\n\n\t\tlet nextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${nextCol}\"]`);\n\t\tif (!nextCell) {\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${nextCol}\"]`);\n\t\t}\n\n\t\treturn nextCell;\n\t}\n\n\t#getPreviousCell = () => {\n\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\tlet nextCell;\n\t\tfor (let i = col - 1; i >= 0; i--) {\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${i}\"]`);\n\t\t\tif (!nextCell) {\n\t\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${i}\"]`);\n\t\t\t}\n\n\t\t\tif (nextCell) break;\n\t\t}\n\n\t\treturn nextCell;\n\t}\n\n\n\n\t#findCell = (matrixRow, col) => {\n\n\t\tconst $tr = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"]`);\n\t\tif (!$tr) return;\n\n\t\tconst dataIndex = parseInt($tr.dataset.index, 10);\n\n\t\tlet targetCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\n\t\tif (!targetCell) {\n\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-matrix-row=\"${matrixRow}\"] td`).forEach($cell => {\n\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\n\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\n\n\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\n\t\t\t\t\ttargetCell = $cell;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!targetCell) {\n\t\t\t\ttargetCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${col}\"]`);\n\n\t\t\t\tif (!targetCell) {\n\t\t\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-index=\"${dataIndex}\"] td`).forEach($cell => {\n\t\t\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\n\t\t\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\n\n\t\t\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\n\t\t\t\t\t\t\ttargetCell = $cell;\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\treturn targetCell;\n\t}\n\n\t#getUpCell = () => {\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\treturn this.#findCell(matrixRow - 1, col);\n\t}\n\n\t#getDownCell = () => {\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\t\tconst rowSpan = parseInt(this.#currentCell.rowSpan, 10) || 1;\n\n\t\treturn this.#findCell(matrixRow + rowSpan, col);\n\t}\n\n\t// 1. ์์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport)\n\t#isCellAboveVisible = (cell) => {\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\t\tif (!bodyViewport || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\n\t\tconst theadHeight = bodyViewport.querySelector('thead')?.offsetHeight || 0;\n\n\t\t// ์
์ ์๋จ์ด ํค๋ ์๋์ชฝ๋ณด๋ค ์์ ์์ผ๋ฉด ์๋ฆฐ(์ ๋ณด์ด๋) ์ํ\n\t\treturn cellRect.top >= (viewportRect.top + theadHeight);\n\t}\n\n\t// 2. ์๋์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport)\n\t#isCellBelowVisible = (cell) => {\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\t\tif (!bodyViewport || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\n\n\t\t// ์
์ ํ๋จ์ด ๋ทฐํฌํธ ํ๋จ๋ณด๋ค ์๋์ ์์ผ๋ฉด ์๋ฆฐ ์ํ\n\t\treturn cellRect.bottom <= viewportRect.bottom;\n\t}\n\n\t// 3. ์ผ์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport2)\n\t#isCellLeftVisible = (cell) => {\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body'); // ๋๋ ์ข์ฐ ์คํฌ๋กค์ ๋ด๋นํ๋ ๋ทฐํฌํธ\n\t\tif (!bodyViewport2 || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\n\n\t\t// ์
์ ์ข์ธก์ด ๋ทฐํฌํธ ์ข์ธก๋ณด๋ค ์ผ์ชฝ์ ์์ผ๋ฉด ์๋ฆฐ ์ํ\n\t\treturn cellRect.left >= viewportRect.left;\n\t}\n\n\t// 4. ์ค๋ฅธ์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport2)\n\t#isCellRightVisible = (cell) => {\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body');\n\t\tif (!bodyViewport2 || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\n\n\t\t// ์
์ ์ฐ์ธก์ด ๋ทฐํฌํธ ์ฐ์ธก๋ณด๋ค ์ค๋ฅธ์ชฝ์ ์์ผ๋ฉด ์๋ฆฐ ์ํ\n\t\treturn cellRect.right <= viewportRect.right;\n\t}\n\n\t// ๐ก ํ์ํ๋ค๋ฉด ์ด 4๊ฐ๋ฅผ ์กฐํฉํด์ ์ ์ฒด ๊ฐ์์ฑ์ ํ๋จํ๋ ํตํฉ ํจ์๋ ์ฝ๊ฒ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.\n\t#isCellVisible = (cell) => {\n\t\treturn this.#isCellAboveVisible(cell) &&\n\t\t\tthis.#isCellBelowVisible(cell) &&\n\t\t\tthis.#isCellLeftVisible(cell) &&\n\t\t\tthis.#isCellRightVisible(cell);\n\t}\n\n\t#getVisibleRowCount = () => {\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\t\tconst viewportHeight = bodyViewport.clientHeight - (bodyViewport.querySelector('thead')?.offsetHeight || 0);\n\t\tconst rowHeight = this.#sheet.rowManager.getRowHeight();\n\n\t\t// ๋ทฐํฌํธ ๋์ด์ ๋ค์ด์ค๋ ํ ๊ฐ์ ๊ณ์ฐ (์์์ ๋ฒ๋ฆผ)\n\t\treturn Math.max(1, Math.floor(viewportHeight / rowHeight));\n\t}\n\n\t#initEvents() {\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\n\t\t\tif (e.button !== 0) return;\n\t\t\tconst cell = e.target.closest('td, th');\n\t\t\tif (!cell) return;\n\t\t\tif (cell.dataset.index === undefined || cell.dataset.col === undefined) return;\n\n\t\t\tif (cell.querySelector(\"cell-row-indicator\")) {\n\t\t\t\tthis.#sheet.row.focus(cell.dataset.index);\n\t\t\t} else {\n\t\t\t\tthis.currentCell = cell;\n\t\t\t}\n\t\t});\n\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\n\n\t\t\tconst cell = e.target.closest('td,th');\n\t\t\tif (!cell || !this.#sheet.contains(cell)) return;\n\n\t\t\tif (this.#host.tagName === 'NINE-TABLE-SIMPLE') {\n\t\t\t\tif ([\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\t\tthis.moveCell(e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ([\"Enter\", \"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\t\tthis.moveCell(e);\n\t\t\t\t} else if ([\"Space\"].includes(e.code)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\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';\nimport { trace } from \"@nopeer\";\n\nexport class NineTableFilterPanel extends HTMLElement {\n\t#sheet;\n\t#host;\n\t#nineTable;\n\t#view;\n\t#button;\n\tcurrentCol = null;\n\n\tconnectedCallback() {\n\t\tthis.#init();\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\n\t}\n\n\t#init = () => {\n\t\t//setTimeout(() => {\n\t\t\tthis.#renderer();\n\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\n\t\t\tthis.#host = this.getRootNode().host;\n\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\n\t\t\t})\n\n\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t});\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\t//});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\n \n <nine-table-simple class=\"filter-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"32\" fixed=\"left\" />\n <col width=\"180\" />\n <col width=\"0\" fixed=\"right\"/>\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"DATA2\" html=\"true\"></td>\n <td data-bind=\"DATA\"></td>\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n\n <div class=\"footer-section\">\n <div class=\"footer-btns\">\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\n <div class=\"btn-group\">\n <button id=\"btnOk\">Apply</button>\n </div>\n </div>\n </div>\n `;\n\t}\n\n\topen(filterBtn) {\n\t\tthis.#button = filterBtn;\n\n\t\tconst cell = filterBtn.closest(\"th, td\");\n\t\tthis.currentCol = cell?.dataset.col;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\n\n\t\tconst panelWidth = this.offsetWidth || 240;\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\n\t\tlet top = cellRect.bottom - sheetRect.top;\n\n\t\tif (left < 0) {\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\tconst searchBox = this.querySelector(\".search-box\");\n\t\tsearchBox.value = \"\";\n\n\n\t\tthis.classList.add(\"active\");\n\t\tthis.classList.add(\"loading\");\n\n\t\tsetTimeout(() => {\n\t\t\ttry {\n\t\t\t\tthis.#loadVirtualFilterItems();\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\n\t\t\t\tsearchBox.focus({ preventScroll: true });\n\t\t\t} finally {\n\t\t\t\tthis.classList.remove(\"loading\");\n\t\t\t}\n\t\t});\n\t}\n\n\t#closeHandler = (e) => {\n\n\t\tconst path = e.composedPath ? e.composedPath() : [];\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\n\t\t\treturn;\n\t\t}\n\t\tthis.close();\n\t};\n\n\tclose() {\n\t\tthis.currentCol = null;\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#button = null;\n\t}\n\n\t#loadVirtualFilterItems() {\n\t\tconst filteredRecords = this.#host.data.getArray();\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] ํํ ๋ฐฐ์ด\n\t\tconst fields = this.#host.fields.get() || [];\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\n\t\tconst exprEngine = this.#host.exprEngine;\n\n\t\tconst ds = targetCols.flatMap((colInfo) => {\n\t\t\tconst bindKey = colInfo.bind;\n\t\t\tconst exprKey = colInfo.expr;\n\n\t\t\tconst filterKey = bindKey || exprKey; // ์ค์ ํํฐ ํ๋ผ๋ฏธํฐ ํค๋ก ์ฌ์ฉ\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\n\n\t\t\tconst uniqueMap = new Map();\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\n\t\t\t\tconst record = filteredRecords[i];\n\t\t\t\tif (!record) continue;\n\n\t\t\t\tlet rawVal = undefined;\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\n\t\t\t\t\trawVal = record.v[fieldIdx];\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\n\t\t\t\t} else if (exprKey && exprEngine) {\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\n\t\t\t\t}\n\n\t\t\t\tlet displayVal = rawVal;\n\t\t\t\tif (exprKey && exprEngine) {\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\n\t\t\t\t}\n\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\n\t\t\t\t\tuniqueMap.set(displayVal, {\n\t\t\t\t\t\tv: rawVal, // ๐ก ํํฐ๋ง ๋น๊ต ๊ธฐ์ค (DATA)\n\t\t\t\t\t\tv2: displayVal // ๐ก ํ๋ฉด ์ถ๋ ฅ ๊ธฐ์ค (DATA2)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst uniqueList = [...uniqueMap.values()];\n\n\t\t\tuniqueList.sort((a, b) => {\n\t\t\t\tconst valA = a.v2;\n\t\t\t\tconst valB = b.v2;\n\n\t\t\t\tif (valA === valB) return 0;\n\t\t\t\tif (valA === undefined || valA === null || valA === '') return 1;\n\t\t\t\tif (valB === undefined || valB === null || valB === '') return -1;\n\n\t\t\t\tconst numA = Number(valA);\n\t\t\t\tconst numB = Number(valB);\n\n\t\t\t\tconst isNumA = !isNaN(numA);\n\t\t\t\tconst isNumB = !isNaN(numB);\n\n\t\t\t\tif (isNumA && isNumB) {\n\t\t\t\t\treturn numA - numB;\n\t\t\t\t}\n\n\t\t\t\treturn String(valA).localeCompare(String(valB));\n\t\t\t});\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\n\n\t\t\treturn uniqueList.map(o => ({\n\t\t\t\tLVL: 2,\n\t\t\t\tDATA: o.v, // ํํฐ๋ง ๋น๊ต์ฉ ๊ฐ\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2,\n\t\t\t\tCOLNM: filterKey,\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v) >= 0 ? \"Y\" : \"N\"\n\t\t\t}));\n\t\t});\n\n\t\tthis.#nineTable.data.set(ds);\n\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\n\t\tif (selectAllChk) {\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\n\t\t}\n\t}\n\n\t#onOk = () => {\n\t\tthis.#host.loading = true;\n\n\t\tconst filterRecords = this.#view.view.getArray();\n\t\tconst fields = this.#nineTable.data.getHostFields();\n\n\t\tconst checkedRecords = filterRecords.filter(record => {\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\n\t\t\treturn (chk === \"Y\" || chk === true);\n\t\t});\n\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\n\n\t\tthis.#button.columns.forEach(colInfo => {\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\n\n\t\t\tif (selectedVals.length > 0) {\n\t\t\t\tfilterParams[filterKey] = selectedVals;\n\t\t\t} else {\n\t\t\t\tdelete filterParams[filterKey];\n\t\t\t}\n\t\t});\n\n\t\tconst totalCount = this.#nineTable.data.count();\n\n\t\tsetTimeout(() => {\n\t\t\ttry {\n\t\t\t\tif (totalCount === checkedRecords.length) {\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\n\t\t\t\t}\n\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\n\t\t\t\t\tbtn.updateFilteredState();\n\t\t\t\t});\n\n\t\t\t\tthis.#sheet.invalidate();\n\t\t\t\tthis.close();\n\t\t\t} finally {\n\t\t\t\tthis.#host.loading = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t#onInput = (e) => {\n\n\t\tconst query = e.target.value.toLowerCase().trim();\n\n\t\tif (!query) {\n\t\t\tthis.#view.filtering.clear();\n\t\t} else {\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\n\n\t\t\tconst matchedValues = [];\n\t\t\trawRecords.forEach(record => {\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\n\n\t\t\t\tif (textVal.includes(query)) {\n\t\t\t\t\tmatchedValues.push(val);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.#view.filtering.set({\n\t\t\t\tDATA2: [...new Set(matchedValues)]\n\t\t\t});\n\t\t}\n\t};\n\n\t#onSelectAll = (e) => {\n\t\tconst isChecked = e.target.checked;\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\n\t\tconst fields = this.#nineTable.data.getHostFields();\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\n\n\t\tif (chkIdx >= 0) {\n\t\t\trawRecords.forEach(record => {\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\n\t\t\t});\n\t\t}\n\n\t\tthis.#nineTable.refresh();\n\t};\n\n\t#onCancel = () => {\n\t\tthis.close();\n\t};\n}\n\nexport class NineTableFilterButton extends HTMLElement {\n\t#sheet;\n\t#columns = null;\n\n\tconnectedCallback() {\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n\t\tthis.removeEventListener(\"click\", this.#onClick);\n\t\tthis.addEventListener(\"click\", this.#onClick);\n\t}\n\n\tget columns() {\n\t\tif (this.#columns) return this.#columns;\n\n\t\tconst cell = this.closest(\"th, td\");\n\t\tconst colIndex = cell?.dataset.col;\n\t\tconst sourceTable = this.#sheet.sourceTable;\n\n\t\tconst cols = [];\n\t\tconst seen = new Set();\n\n\t\tif (sourceTable && colIndex !== undefined) {\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\n\t\t\t\tconst bindKey = $td.dataset.bind;\n\t\t\t\tconst exprKey = $td.dataset.expr;\n\n\t\t\t\tif (bindKey || exprKey) {\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\n\t\t\t\t\t\tseen.add(uniqueKey);\n\t\t\t\t\t\tcols.push({\n\t\t\t\t\t\t\tbind: bindKey,\n\t\t\t\t\t\t\texpr: exprKey,\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.#columns = cols;\n\t\treturn this.#columns;\n\t}\n\n\tupdateFilteredState = () => {\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\n\t\tconst isFiltered = this.columns.some(colInfo => {\n\t\t\tconst key = colInfo.expr || colInfo.bind;\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\n\t\t});\n\t\tthis.classList.toggle('filtered', isFiltered);\n\t};\n\n\t#onClick = (e) => {\n\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\n\t\tconst cell = this.closest(\"th, td\");\n\t\tconst col = cell.dataset.col;\n\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\n\t\t\tpanel.close();\n\t\t} else if (panel) {\n\t\t\tpanel.open(this);\n\t\t}\n\t};\n}\n\nexport class Filtering {\n\t#sheet;\n\t#host;\n\t#isFiltering = false;\n\t#filterPanel = null;\n\t#filters = {};\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = this.#sheet.getRootNode().host;\n\t\tthis.#init();\n\t}\n\n\tget filters() {\n\t\treturn this.#filters;\n\t};\n\n\t#init = () => {\n\t\tthis.#initFilterPanel();\n\t}\n\n\t#initFilterPanel = () => {\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\n\t\t\treturn;\n\t\t}\n\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\n\t\tif (!panel) {\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\n\t\t\tthis.#sheet.appendChild(panel);\n\t\t}\n\t\tthis.#filterPanel = panel;\n\t}\n\n\tisFiltering() {\n\t\treturn this.#isFiltering;\n\t}\n\n\tclear = (colnm) => {\n\t\tif (colnm) {\n\t\t\tdelete this.#filters[colnm];\n\t\t} else {\n\t\t\tthis.#filters = {};\n\t\t}\n\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\n\t\tthis.#applyFiltering();\n\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\n\t\t\tbtn.updateFilteredState();\n\t\t});\n\t}\n\n\tset = (oFilter) => {\n\n\t\tlet jsonFilter = Array.isArray(oFilter)\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\n\t\t\t: oFilter;\n\n\t\tthis.#filters = jsonFilter;\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\n\n\t\tthis.#applyFiltering();\n\t}\n\n\t#applyFiltering() {\n\t\tconst hostData = this.#host.data;\n\t\tconst rawRecords = hostData.getArray();\n\t\tconst fields = this.#host.data.getHostFields();\n\t\tconst sheetIndex = this.#sheet.index;\n\t\tconst exprEngine = this.#host.exprEngine;\n\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\n\n\t\tif (!hasFilters) {\n\t\t\trawRecords.forEach(record => {\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.#sheet.invalidate();\n\t\t\treturn;\n\t\t}\n\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\n\t\t\treturn {\n\t\t\t\ttargetKey,\n\t\t\t\tisExpr,\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\n\t\t\t\tallowedSet: new Set(allowedValues)\n\t\t\t};\n\t\t});\n\n\t\trawRecords.forEach((record, recordIdx) => {\n\t\t\tif (!record) return;\n\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\n\t\t\t}\n\n\t\t\tlet isPass = true;\n\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\n\t\t\t\tlet val = undefined;\n\n\t\t\t\tif (isExpr && exprEngine) {\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\n\t\t\t\t\tval = record.v[fieldIdx];\n\t\t\t\t}\n\n\t\t\t\tif (!allowedSet.has(val)) {\n\t\t\t\t\tisPass = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\n\t\t});\n\n\t\tthis.#sheet.selection.clear();\n\n\t\tthis.#sheet.invalidate();\n\t}\n}\n\nif (!customElements.get('nine-table-filter-panel')) {\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\n}\n\nif (!customElements.get('nine-table-filter-button')) {\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\n}","// ui/data/Sorting.js (๋๋ ์ ๋ ฌ ๊ด๋ จ ์์ค)\nimport { trace } from \"@nopeer\";\n\nexport class Sorting {\n\t#sheet;\n\t#host;\n\n\t#columns = [];\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.#initEvents();\n\t\t}, 300);\n\t}\n\n\t#initEvents() {\n\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\n\n\t\t\t$el.addEventListener('dblclick', (e) => {\n\n\t\t\t\tconst cell = e.target.closest('th, td');\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\n\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\n\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\n\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\n\n\t\t\t\thost.loading = true;\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.#handleSort(e, cell);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\thost.loading = false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t}\n\n\t#handleSort(e, cell) {\n\t\tconst colIndex = cell.dataset.col;\n\t\tconst tr = cell.closest('tr');\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\n\n\t\tif (colIndex === undefined) return;\n\n\t\tconst sourceTable = this.#sheet.sourceTable;\n\t\tif (!sourceTable) return;\n\n\t\tlet colName = null;\n\t\tlet exprVal = null;\n\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\n\t\t\tif ($td.dataset.bind) {\n\t\t\t\tcolName = $td.dataset.bind;\n\t\t\t}\n\n\t\t\tif ($td.dataset.expr) {\n\t\t\t\texprVal = $td.dataset.expr;\n\t\t\t}\n\t\t});\n\n\t\tif (!colName && !exprVal) return;\n\n\t\tconst isAsc = cell.classList.contains('asc');\n\t\tconst isDesc = cell.classList.contains('desc');\n\n\t\tif (!e.ctrlKey && !e.shiftKey) {\n\t\t\tthis.#columns = [];\n\t\t}\n\n\t\tconst existingColIndex = this.#columns.findIndex(\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\n\t\t);\n\n\t\tconst ruleData = {\n\t\t\tcolIndex,\n\t\t\tsubRowIndex,\n\t\t\tcolname: colName || exprVal,\n\t\t\tcolName: colName || exprVal,\n\t\t\texpr: exprVal, // ๐ก expr ๊ท์น ๋ณด๊ด\n\t\t\tasc: true,\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\n\t\t};\n\n\t\tif (!isAsc && !isDesc) {\n\t\t\tif (existingColIndex >= 0) {\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\n\t\t\t} else {\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\n\t\t\t}\n\t\t} else if (isAsc) {\n\t\t\tif (existingColIndex >= 0) {\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\n\t\t\t} else {\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#columns = this.#columns.filter(\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\n\t\t\t);\n\t\t}\n\n\t\tthis.#applySorting(cell);\n\t}\n\n\t#applySorting(cell) {\n\n\t\tthis.#sheet.view.setSorting(this.#columns);\n\t\tthis.#syncHeaderUI();\n\t\tthis.#sheet.invalidate();\n\t\trequestAnimationFrame(() => {\n\t\tconst cells = this.#sheet.querySelectorAll('tbody.body th, tbody.body td');\n\n\t\tcells.forEach($td => {\n\t\t\t$td.classList.remove('sorting-anim-asc', 'sorting-anim-desc', 'sorting-anim-none');\n\n\t\t\tif (cell.classList.contains('asc')) {\n\t\t\t\t$td.classList.add('sorting-anim-asc');\n\t\t\t} else if (cell.classList.contains('desc')) {\n\t\t\t\t$td.classList.add('sorting-anim-desc');\n\t\t\t} else {\n\t\t\t\t$td.classList.add('sorting-anim-none');\n\t\t\t}\n\t\t});\n\n\t\trequestAnimationFrame(() => {\n\t\t\tcells.forEach($td => {\n\t\t\t\t$td.classList.remove('sorting-anim-asc', 'sorting-anim-desc', 'sorting-anim-none');\n\t\t\t});\n\t\t});\n\t\t});\n\t}\n\n\t#syncHeaderUI() {\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\n\t\t\tel.classList.remove('asc', 'desc');\n\t\t});\n\n\t\tif (this.#columns.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#columns.forEach(colRule => {\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\n\n\t\t\tif (colIndex !== undefined) {\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\n\t\t\t\tif (subRowIndex !== undefined) {\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\n\t\t\t\t}\n\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\n\t\t\t\ttargetHeaderCells.forEach(cell => {\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\trestore() {\n\t\tthis.#columns = [];\n\t\tif (this.#sheet.view) {\n\t\t\tthis.#sheet.view.resetSorting();\n\t\t}\n\n\t\tthis.#syncHeaderUI();\n\t\tthis.#sheet.rowManager?.refresh(true);\n\t}\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport {Grouping} from \"@/data/Grouping.js\";\n\nexport class SheetView {\n\t#sheet;\n\t#host;\n\t#sortingColumns = [];\n\t#filterRules = [];\n\t#viewIndexes = [];\n\n\t#cachedVisibleRecords = null;\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tthis.refresh();\n\t}\n\n\tgetArray = (at, colnm) => {\n\n\t\tif (!this.#cachedVisibleRecords) {\n\t\t\tconst records = this.#host.data.getArray();\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\n\t\t}\n\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn visibleRecords;\n\t\t}\n\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\n\n\t\tconst targetRecord = visibleRecords[at];\n\t\tif (colnm != null) {\n\t\t\tconst fields = this.#host.data.getHostFields();\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn targetRecord;\n\t};\n\n\tcount = () => {\n\t\tif (!this.#cachedVisibleRecords) {\n\t\t\tconst records = this.#host.data.getArray();\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\n\t\t}\n\n\t\treturn this.#cachedVisibleRecords.length;\n\t}\n\n\tget = (at, colnm) => {\n\t\tconst visibleRecords = this.getArray();\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\n\t\t}\n\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\n\n\t\tconst targetRecord = visibleRecords[at];\n\t\tif (!targetRecord) return null;\n\n\t\tif (colnm != null) {\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn this.#convSingle(targetRecord, fields);\n\t};\n\n\t#convSingle = (o, fields) => {\n\t\tif (!o) return null;\n\t\tconst t = {};\n\t\tfields.forEach((colnm, i) => {\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\n\t\t});\n\t\tif (o.m) t.m = o.m;\n\t\tif (o._) t._ = o._;\n\t\treturn t;\n\t};\n\n\trefresh = () => {\n\n\t\tthis.#cachedVisibleRecords = null;\n\n\t\tconst rawRecords = this.#host.data.getArray();\n\t\tlet indices = [];\n\t\trawRecords.forEach((record, i) => {\n\t\t\tif (!record) return;\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\n\t\t\tindices.push(i);\n\t\t});\n\n\t\tif (this.#sortingColumns.length > 0) {\n\t\t\tindices = this.#applySorting(indices, rawRecords);\n\t\t}\n\n\t\tthis.#viewIndexes = indices;\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\n\n\t\tconst groupColumns = this.#sheet.grouping?.columns || [];\n\t\tif (groupColumns.length > 0) {\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields());\n\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // ์ต์ข
๋ ๋๋ง ์์ดํ
\n\n\t\t\tthis.#sheet.grouping.setGroupMap(groupResult.groupMap); // ์์ ๋งคํ ๊ณต์ \n\t\t} else {\n\t\t\tthis.#cachedVisibleRecords = validRecords;\n\t\t}\n\n\n\n\t}\n\n\tsetSorting = (columns) => {\n\t\tthis.#sortingColumns = columns || [];\n\t\tthis.refresh();\n\t};\n\n\tgetSorting = () => {\n\t\treturn this.#sortingColumns;\n\t};\n\n\tresetSorting = () => {\n\t\tthis.#sortingColumns = [];\n\t\tthis.refresh();\n\t};\n\n\n\t#applySorting = (indices, validRecords) => {\n\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\n\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\n\t\t\t...rule,\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\n\t\t}));\n\n\t\treturn indices.sort((idxA, idxB) => {\n\t\t\tconst a = validRecords[idxA];\n\t\t\tconst b = validRecords[idxB];\n\n\t\t\tfor (const rule of rulesWithIdx) {\n\t\t\t\tconst isAsc = rule.asc;\n\t\t\t\tconst expr = rule.expr; // ๐ก ๋ฑ๋ก๋ expr ์์\n\t\t\t\tlet valA, valB;\n\n\t\t\t\tif (expr) {\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\n\t\t\t\t} else {\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\n\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\n\t\t\t\tif (isEmptyA) return 1;\n\t\t\t\tif (isEmptyB) return -1;\n\n\t\t\t\tif (valA !== valB) {\n\t\t\t\t\tlet diff = 0;\n\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\n\t\t\t\t\t\tdiff = valA - valB;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst strA = String(valA);\n\t\t\t\t\t\tconst strB = String(valB);\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (diff !== 0) {\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn idxA - idxB;\n\t\t});\n\t};\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 : 4;\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 } from \"@/core/constants.js\";\n\nexport class SheetAPI {\n #sheet;\n #host;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#host = sheet.getRootNode().host;\n }\n\n /**\n currentRow = () => {\n let rows = this.currentRows();\n return (rows.length === 0) ? -1 : rows[0];\n }\n currentRows = () => {\n\n let rows = [];\n this.#shadowRoot.querySelectorAll('nine-table-sheet.active').forEach($sheet => {\n\n const arr = $sheet.view.getArray($sheet.selection.minRow);\n const rowid = arr.m._[NINE_TABLE.META.INDEX.ROWID];\n\n //trace.log(this.data.getArray($sheet.selection.minRow));\n\n rows.push(rowid);\n });\n\n return rows;\n } */\n\n col = {\n // 1. ํน์ ์ปฌ๋ผ์ ๋๋น ์ค์ (ColResizer ํ์ฉ)\n setWidth: (colIndex, width, containerType = null) => {\n const targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${colIndex}\"]`));\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n });\n\n },\n\n // 2. ํน์ ์ปฌ๋ผ์ ํ์ฌ ๋๋น ๊ฐ์ ธ์ค๊ธฐ\n getWidth: (colIndex) => {\n const colEl = this.#sheet.querySelector(`table colgroup col[data-col=\"${colIndex}\"]`);\n if (!colEl) return 0;\n return parseInt(colEl.getAttribute('width') || colEl.style.width, 10) || 0;\n },\n measureAutoFitColumnWidth: (cell, tbodyCell) => {\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n let maxTextWidth = 32;\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 return maxTextWidth;\n },\n // 3. ํน์ ์ปฌ๋ผ ์๋ ๋ง์ถค (์๊น ๋ถ๋ฆฌํ measureAutoFitColumnWidth ์ฐ๋)\n autoFit: (colIndex) => {\n const cell = this.#sheet.querySelector(`thead th[data-col=\"${colIndex}\"]`);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${colIndex}\"]`);\n\n if (!cell || !tbodyCell) return;\n\n this.#host.execute(() => {\n const calculatedWidth = this.col.measureAutoFitColumnWidth(cell, tbodyCell);\n if (calculatedWidth !== null) {\n this.col.setWidth(colIndex, calculatedWidth);\n }\n });\n },\n\n // 4. ์ปฌ๋ผ ํ์/์จ๊น ์ฒ๋ฆฌ\n setVisible: (colIndex, isVisible) => {\n const targets = this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${colIndex}\"], th[data-col=\"${colIndex}\"], td[data-col=\"${colIndex}\"]`);\n targets.forEach(el => {\n el.style.display = isVisible ? '' : 'none';\n });\n this.#sheet.rowManager?.refresh();\n }\n };\n\n row = {\n at: () => {\n if (this.#sheet.selection.minRow < 0) return -1;\n return Math.floor(this.#sheet.selection.minRow / this.#sheet.template.length);\n },\n focus: async (index, callback) => {\n // 1. ํ๋ฉด์ ์ ๋ณด์ด๋ฉด moveTo ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆผ\n if (!this.#sheet.row.isVisible(index)) {\n await new Promise((resolve) => {\n this.#sheet.row.moveTo(index, () => {\n resolve();\n });\n });\n } else {\n // 2. ์ด๋ฏธ ๋ณด์ด๋๋ผ๋ ๋ธ๋ผ์ฐ์ ๋ ๋๋ง ํ์ ํ ํ
ํฌ ์๋ณด (requestAnimationFrame)\n await new Promise((resolve) => requestAnimationFrame(resolve));\n }\n\n // 3. ๋ ๋๋ง์ด ์์ ํ ์์ ํ๋ ์์ ์ DOM ์กฐํ ๋ฐ ์ ํ ์ฒ๋ฆฌ\n const $trs = this.#sheet.querySelectorAll(`tbody.body tr[data-index=\"${index}\"]`);\n const matrixRows = Array.from($trs, $tr => parseInt($tr.dataset.matrixRow, 10)).filter(n => !isNaN(n));\n\n const cols = [];\n $trs.forEach($tr => {\n $tr.querySelectorAll('td, th').forEach($cell => {\n const col = parseInt($cell.dataset.col, 10);\n if (col != 0) cols.push(parseInt($cell.dataset.col, 10));\n });\n });\n\n if (matrixRows.length === 0 || cols.length === 0) return;\n\n const result = this.#sheet.selection.setRange(Math.min(...matrixRows), Math.min(...cols), Math.max(...matrixRows), Math.max(...cols));\n\n if (typeof callback === 'function') {\n callback();\n }\n\n return result;\n },\n isVisible: (index) => {\n\n const $sheetBody = this.#sheet.querySelector('.ng-sheet-body');\n\n const $trs = $sheetBody.querySelectorAll(`.ng-container-body tbody.body tr[data-index=\"${index}\"]`);\n if (!$trs || $trs.length === 0) return false;\n\n const viewportRect = $sheetBody.getBoundingClientRect();\n const theadHeight = $sheetBody.querySelector('thead')?.offsetHeight || 0;\n const tfootHeight = $sheetBody.querySelector('tfoot')?.offsetHeight || 0;\n\n const viewportTop = viewportRect.top + theadHeight;\n const viewportBottom = viewportRect.bottom - tfootHeight;\n\n let isVisible = true;\n\n for (const $tr of $trs) {\n const trRect = $tr.getBoundingClientRect();\n\n const isAbove = trRect.top < viewportTop;\n const isBelow = trRect.bottom > viewportBottom;\n\n if (isAbove || isBelow) {\n isVisible = false;\n break;\n }\n }\n\n return isVisible;\n },\n add: (dataSource, updateState) => {\n return this.#host.data.add(dataSource, updateState);\n },\n moveTo: (index, callback) => {\n if (this.#sheet.row.isVisible(index)) {\n if (typeof callback === 'function') callback();\n } else {\n this.#sheet.scrollTo(index, () => {\n if (typeof callback === 'function') callback();\n });\n }\n },\n insert: (index, dataSource, updateState = true) => {\n\n const currentJson = this.#sheet.view.get(index);\n const rowid = currentJson.m._[NINE_TABLE.META.INDEX.ROWID];\n\n const toRowid = this.#host.data.insert(rowid, dataSource, updateState);\n const records = this.#sheet.view.getArray();\n\n const targetIndex = records.findIndex(record => {\n if (!record || !record.m || !record.m._) return false;\n return record.m._[NINE_TABLE.META.INDEX.ROWID] === toRowid; // ํ์
์ฐจ์ด ๋ฐฉ์ง๋ฅผ ์ํด == ์ฌ์ฉ\n });\n\n return targetIndex;\n },\n remove: (index) => {\n\n const currentJson = this.#sheet.view.get(index);\n const rowid = currentJson.m._[NINE_TABLE.META.INDEX.ROWID];\n\n this.#host.data.remove(rowid);\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\";\nimport { SheetAPI } from \"@/api/SheetAPI.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 #api;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n #template = {\n length: 0,\n height: 0,\n heights: [],\n };\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 this.#api = new SheetAPI(this);\n\n this.#bindApiMethods();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get template() { return this.#template; }\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 /**\n get template() {\n return {\n length: this.#source?.tbody?.tr?.length || 0,\n trs: this.#source?.tbody?.tr || []\n };\n } */\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 scrollTo = (dataRow, callback) => {\n this.rowManager.scrollToDataRow(dataRow, 'top', callback);\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 generateTemplate = ($table, index) => {\n\n const activeParent = (v) => {\n\n if (['NINE-TABLE-SIMPLE'].includes(this.#host.tagName)) {\n const $parent = this.#host.closest(\"nine-table-filter-panel, cell-combo-panel\");\n if ($parent) {\n v ? $parent.classList.add('active') : $parent.classList.remove('active');\n }\n }\n };\n\n activeParent(true);\n\n this.#index = index;\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n this.querySelector(`.ng-container-body`).appendChild(this.#source.table);\n\n this.#template.height = this.#template.length = 0;\n this.#template.heights = [];\n this.querySelectorAll(`.ng-container-body tbody.body tr`).forEach(($tr) => {\n this.#template.height += Math.max($tr.offsetHeight || 0, 28);\n this.#template.heights.push($tr.offsetHeight || 0);\n //if (['NINE-TABLE-SIMPLE'].includes(this.#host.tagName)) {\n // trace.log(this.#host, $tr.offsetHeight, $tr.clientHeight);\n //}\n });\n this.#template.length = this.#template.heights.length;\n\n if (this.#index === 0) {\n const minRows = parseInt(this.#host.getAttribute('display-min-rows'), 10);\n const maxRows = parseInt(this.#host.getAttribute('display-max-rows'), 10);\n\n const h = (this.querySelector(\"nine-table-toolbar\")?.offsetHeight || 0) +\n (this.querySelector(\"nine-table-footer\")?.offsetHeight || 0) +\n (this.querySelector(\"thead\")?.offsetHeight || 0) +\n (this.querySelector(\"tfoot\")?.offsetHeight || 0) +\n (this.querySelector(\"tbody.head\")?.offsetHeight || 0);\n\n if (this.#host.getAttribute('auto-height') === \"true\" || !isNaN(minRows) || !isNaN(maxRows)) {\n this.#host.setAttribute('scroll-bar', \"none\");\n }\n\n if (!isNaN(minRows)) {\n this.#host.style.minHeight = h + (this.#template.height * minRows) + \"px\";\n }\n\n if (!isNaN(maxRows)) {\n this.#host.style.maxHeight = h + (this.#template.height * maxRows) + \"px\";\n }\n }\n\n this.querySelectorAll((\"tbody.body tr\")).forEach(($tr) => {\n $tr.style.display = \"none\";\n });\n\n this.querySelector(`.ng-container-body table`).remove();\n\n activeParent(false);\n };\n\n generate = () => {\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 if (this.#host.classList.contains(\"combo-list\")) return;\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', (e) => {\n this.querySelectorAll(\"nine-table-filter-panel,cell-combo-panel\").forEach($el => {\n $el.classList.remove('active');\n });\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n\n this.setAttribute(\"tabindex\", \"0\");\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\">\n \n </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 \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 #bindApiMethods = () => {\n //const apis = [this.#sheetAPI, this.#dataAPI];\n const apis = [this.#api];\n\n apis.forEach(api => {\n // api ์ธ์คํด์ค(this)์ ์ง์ ์ ์ธ๋ ์์ฑ๋ค๊ณผ ํ๋กํ ํ์
์์ฑ์ ๋ชจ๋ ๊ฐ์ ธ์ด\n // Reflect.ownKeys๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ณผ์ด๋ ์จ๊ฒจ์ง ํ๋กํผํฐ๊น์ง ์์ ํ๊ฒ ํ์ ๊ฐ๋ฅํฉ๋๋ค.\n const keys = new Set([\n ...Reflect.ownKeys(api),\n ...Reflect.ownKeys(Object.getPrototypeOf(api))\n ]);\n\n keys.forEach(key => {\n // constructor๋ ๋ด๋ถ ํ๋ผ์ด๋น ๋ฉค๋ฒ(#)๋ ์ ์ธ\n if (key === 'constructor' || String(key).startsWith('#')) return;\n\n const target = api[key];\n\n if (typeof target === 'function') {\n if (!this[key]) {\n //trace.log(`[Binding Function] ${key}`);\n this[key] = (...args) => target.apply(api, args);\n }\n } else if (target !== null && typeof target === 'object') {\n\n if (!this[key]) {\n //trace.log(`[Binding Object Namespace] ${key}`);\n this[key] = target; // ๊ฐ์ฒด ๋ค์์คํ์ด์ค(์: row) ํต์งธ๋ก ์ฐ๊ฒฐ\n }\n }\n });\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\";\nimport {PreCompiler} from \"@/layout/core/PreCompiler.js\";\nimport {NINE_TABLE} from \"@\";\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 this.#initEvent();\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\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\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 ${this.#host.provider.style.value}\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 rawTables.forEach($el => {\n PreCompiler.initializeTable(this.#host, $el);\n })\n\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($sheet, idx) => {\n $sheet.classList.add('active');\n $sheet.generateTemplate(rawTables[idx], idx);\n });\n\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($sheet) => {\n\n setTimeout(() => {\n $sheet.generate();\n if (this.#isAutoHeight) this.#applyAutoHeight();\n });\n });\n\n\n setTimeout(() => {\n this.#host.data.clear();\n });\n };\n\n #initEvent = () => {\n\n this.#host.addEventListener(NINE_TABLE.EVENT.ROW_ADDED, () => {\n if (this.#isAutoHeight) this.#applyAutoHeight();\n });\n\n this.#host.addEventListener(NINE_TABLE.EVENT.ROW_REMOVED, () => {\n if (this.#isAutoHeight) this.#applyAutoHeight();\n });\n\n let lastHeight = 0; // ์ง์ ๋์ด๋ฅผ ๊ธฐ์ตํ ๋ณ์\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n if (entry.target.tagName === \"NINE-TABLE\") {\n const currentHeight = entry.contentRect.height;\n\n if (currentHeight !== lastHeight) {\n lastHeight = currentHeight;\n if (this.#isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }\n }\n }).observe(this.#host);\n };\n\n #applyAutoHeight = () => {\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($sheet) => {\n if ($sheet.index === 0) {\n const fixedHeight = ($sheet.querySelector(\"thead\")?.offsetHeight || 0) +\n ($sheet.querySelector(\"tfoot\")?.offsetHeight || 0) +\n ($sheet.querySelector(\"tbody.head\")?.offsetHeight || 0);\n const basicHeight = this.#host.offsetHeight - $sheet.offsetHeight + fixedHeight;\n\n const h = Math.min($sheet.template.height * $sheet.view.count(), window.innerHeight * 0.8);\n\n this.#host.style.height = basicHeight + (h) + \"px\";\n }\n });\n };\n\n get #isAutoHeight() {\n return this.#host.getAttribute('auto-height') === 'true';\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 { NINE_TABLE } from \"@/core/constants.js\";\n\nexport class DataAPI {\n\n #host;\n\n constructor(host) {\n this.#host = host;\n }\n\n provider = {\n // ์คํ์ผ ๋ฐ์ดํฐ๋ฅผ provider ๊ฐ์ฒด ๋ด๋ถ์์ ์ง์ ๊ด๋ฆฌ (์ผ๋ฐ ๋ฉ์๋ ์ถ์ฝํ ์ฌ์ฉ)\n style: {\n value: '',\n },\n add: (providerObj) => {\n if (!providerObj || typeof providerObj !== 'object') return;\n\n const { style, ...methods } = providerObj;\n\n if (style && typeof style === 'string') {\n this.provider.style.value = style;\n }\n\n if (Object.keys(methods).length > 0) {\n setTimeout(() => {\n Object.entries(methods).forEach(([name, fn]) => {\n if (typeof fn === 'function') {\n this.#host[name] = fn;\n }\n });\n\n this.#host.rerenderer();\n });\n }\n },\n }\n\n}","export class NineTableAPI {\n #host;\n\n constructor(host) {\n this.#host = host;\n\n // ๊ด๋ฆฌํ ๋ค์์คํ์ด์ค๋ค์ ๋ฐฐ์ด๋ก ์ ์\n const namespaces = [\"col\", \"row\"]; // ๋์ค์ \"col\", \"cell\" ๋ฑ๋ง ์ถ๊ฐํ๋ฉด ๋!\n\n namespaces.forEach(ns => {\n this[ns] = new Proxy({}, {\n get: (target, prop) => {\n const $sheet = this.#getActiveSheet();\n if (!$sheet || !$sheet[ns]) return undefined;\n\n const targetMethod = $sheet[ns][prop];\n\n if (typeof targetMethod === 'function') {\n return (...args) => targetMethod.apply($sheet[ns], args);\n }\n return targetMethod;\n }\n });\n });\n }\n\n getActiveSheets() {\n return this.#host.shadow.querySelectorAll('nine-table-sheet.active');\n }\n\n #getActiveSheet() {\n const arr = this.getActiveSheets();\n return arr.length > 0 ? arr[0] : null;\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\";\nimport { DataAPI } from '../api/DataAPI.js';\nimport { NineTableAPI } from '../api/NineTableAPI.js';\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #dataApi;\n #sheetApi;\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 this.#dataApi = new DataAPI(this);\n this.#sheetApi = new NineTableAPI(this);\n\n this.#bindApiMethods();\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\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 #bindApiMethods() {\n\n const apis = [this.#dataApi, this.#sheetApi];\n\n apis.forEach(api => {\n // api ์ธ์คํด์ค(this)์ ์ง์ ์ ์ธ๋ ์์ฑ๋ค๊ณผ ํ๋กํ ํ์
์์ฑ์ ๋ชจ๋ ๊ฐ์ ธ์ด\n // Reflect.ownKeys๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ณผ์ด๋ ์จ๊ฒจ์ง ํ๋กํผํฐ๊น์ง ์์ ํ๊ฒ ํ์ ๊ฐ๋ฅํฉ๋๋ค.\n const keys = new Set([\n ...Reflect.ownKeys(api),\n ...Reflect.ownKeys(Object.getPrototypeOf(api))\n ]);\n\n keys.forEach(key => {\n // constructor๋ ๋ด๋ถ ํ๋ผ์ด๋น ๋ฉค๋ฒ(#)๋ ์ ์ธ\n if (key === 'constructor' || String(key).startsWith('#')) return;\n\n const target = api[key];\n\n if (typeof target === 'function') {\n if (!this[key]) {\n //trace.log(`[Binding Function] ${key}`);\n this[key] = (...args) => target.apply(api, args);\n }\n } else if (target !== null && typeof target === 'object') {\n if (!this[key]) {\n //trace.log(`[Binding Object Namespace] ${key}`, target);\n this[key] = target; // ๊ฐ์ฒด ๋ค์์คํ์ด์ค(์: row) ํต์งธ๋ก ์ฐ๊ฒฐ\n }\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 {\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tapplyBaseStyle() {\n\t}\n\n\tconnectedCallback() {\n\t}\n}","import { trace } from \"@nopeer\";\nimport { BasicCellElement } from './BasicCellElement.js';\n\nconst exprCache = new Map();\n\nexport class CellElement extends BasicCellElement {\n\t#host;\n\t#sheet;\n\t#tr;\n\t#cell;\n\t#attr;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tget #updateRowState() {\n\t\treturn this.#cell.getAttribute(\"update-row-state\") === \"false\";\n\t}\n\n\tget host() { return this.#host; }\n\tget sheet() { return this.#sheet; }\n\tget cell() { return this.#cell; }\n\tget tr() { return this.#tr; }\n\tget attr() { return this.#attr; }\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#host = this.getRootNode().host;\n\n\t\tthis.#cell = this.closest(\"th,td\");\n\t\tthis.#tr = this.#cell.closest(\"tr\");\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\n\n\t\tthis.#cell.classList.add(this.tagName);\n\n\t\tthis.#attr = {};\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\n\t\t\tconst name = this.#cell.attributes[i].name;\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\n\t\t\t}\n\t\t}\n\n\t\tif (!this.#cell) return;\n\n\n\t\tconst root = this.shadowRoot || this;\n\n\t\t// ๐ฏ ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\n\t\t\tbutton.addEventListener(\"click\", () => {\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\n\n\t\t\t\tconst rowData = this.data; // Proxy Lazy ์ ๊ทผ\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\n\n\t\t\t\tif (fn && this.#host) {\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\n\t\t\t\t\tconst methodName = match?.[1] || fn;\n\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true\n\t\t\t\t})); */\n\t\t\t});\n\t\t});\n\n\t\t// ๐ฏ ๋งํฌ ์ด๋ฒคํธ ์ฐ๊ฒฐ\n\t\tconst renderer = root.querySelector(\".renderer\");\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\n\t\t\trenderer.classList.add(\"link\");\n\n\t\t\trenderer.addEventListener(\"click\", () => {\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\n\n\t\t\t\tconst rowData = this.data;\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\n\n\t\t\t\tif (fn && this.#host) {\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\n\t\t\t\t\tconst methodName = match?.[1] || fn;\n\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true\n\t\t\t\t}));\n\t\t\t});\n\t\t}\n\t}\n\n\tget data() {\n\t\tconst rawRecord = this.#tr?.data;\n\t\tif (!rawRecord) return null;\n\t\tif (!rawRecord.v) return rawRecord;\n\n\t\tconst host = this.#host;\n\n\t\treturn new Proxy(rawRecord, {\n\t\t\tget(target, prop) {\n\t\t\t\tif (prop === '__ng') return target.__ng;\n\t\t\t\tif (prop === 'v') return target.v;\n\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\n\t\t\t}\n\t\t});\n\t}\n\n\tget value() {\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\n\n\t\tconst bindKey = this.#cell.dataset?.bind;\n\t\tif (!bindKey) return \"\";\n\n\t\tconst rawRecord = this.#tr.data;\n\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\n\t\t}\n\n\t\treturn rawRecord[bindKey] ?? \"\";\n\t}\n\n\tset value(v) {\n\t\tif (!this.#cell || !this.#host?.data) return;\n\n\t\tconst row = parseInt(this.#tr.dataset.row, 10);\n\t\tconst bindKey = this.#cell.dataset.bind;\n\t\tif (isNaN(row) || !bindKey) return;\n\n\t\t//update-row-state\n\t\tthis.#host.data.setValue(row, bindKey, v, this.#updateRowState);\n\t}\n\n\tget row() {\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\n\t}\n\tget index() {\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\n\t}\n\n\tisValid() {\n\t\treturn this.#cell.classList.contains(\"invalid\") ? false : true;\n\t}\n\n\tisInvalid() {\n\t\treturn !this.isValid();\n\t}\n\n\tgetDisplayText = (defaultValue = \"\") => {\n\n\t\tif (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\n\n\t\tconst rawRecord = this.#tr.data;\n\n\t\tif (!rawRecord) return defaultValue;\n\n\t\tconst expr = this.#cell.dataset.expr;\n\t\tconst bindKey = this.#cell.dataset.bind;\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\n\n\t\tif (expr) {\n\t\t\ttry {\n\t\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\n\n\t\t\t\t\treturn this.getGroupExprValue(expr, this.#tr.data, row, this.#cell);\n\t\t\t\t} else {\n\t\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\n\t\tif (bindKey) {\n\t\t\tconst val = this.value;\n\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\n\n\trefresh() {\n\n\t\tif (!this.#cell || !this.#tr) return;\n\n\t\tconst val = this.value;\n\n\t\tthis.#cell.classList.remove(\"invalid\");\n\n\t\t[\"color\",\"background\",\"background-color\",\"visible\",\"enable\",\"validator\"].forEach(v => {\n\n\t\t\tconst expr = this.#attr[v];\n\t\t\tif (expr) {\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10));\n\n\t\t\t\tif (v === \"validator\") {\n\t\t\t\t\tif (!result) {\n\t\t\t\t\t\tthis.#cell.classList.add(\"invalid\");\n\t\t\t\t\t}\n\t\t\t\t} else if (v === \"visible\") {\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\n\t\t\t\t} else if (v === \"enable\") {\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\n\t\t\t\t\t\t$el.disabled = !result;\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!!result) {\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.#cell.style[v] = result;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn val;\n\t}\n\n\tgetExprValue(expr, data, row) {\n\t\tif (!this.#host || !this.#host.exprEngine || expr === undefined || expr === null || expr === \"\") return expr;\n\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row);\n\t}\n\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\n\t\tif (!expr) return \"\";\n\n\t\ttry {\n\t\t\trow = parseInt(row, 10);\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\n\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\n\t\t\t}\n\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\n\t\t\tif (match) {\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n\t\t\t\tconst [, funcName, field] = match;\n\t\t\t\tconst host = this.#host;\n\n\t\t\t\tswitch (funcName.toLowerCase()) {\n\t\t\t\t\tcase 'count':\n\t\t\t\t\t\treturn childRecords.length;\n\n\t\t\t\t\tcase 'sum': {\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\n\t\t\t\t\t\t}, 0);\n\t\t\t\t\t}\n\n\t\t\t\t\tcase 'avg': {\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\n\t\t\t\t\t\t}, 0);\n\t\t\t\t\t\treturn sum / childRecords.length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 3. ํธ์คํธ์ exprFunction ํ์ฉ\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\n\t\t\t}\n\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\n\t\t\t\tif (!evalFn) {\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\n \n let childRecords = [];\n if (Array.isArray(indices)) {\n // indices๊ฐ ์ซ์ ์ธ๋ฑ์ค ๋ฐฐ์ด์ธ์ง, rowid ๋ฌธ์์ด ๋ฐฐ์ด์ธ์ง ํ๋ณํ์ฌ ์์ ํ๊ฒ ์ถ์ถ\n childRecords = indices.map(idx => {\n if (typeof idx === 'number') {\n return allRecords[idx];\n } else {\n // rowid ๋ฑ ๋ฌธ์์ด ์๋ณ์์ธ ๊ฒฝ์ฐ ์ ์ฒด ๋ฐฐ์ด์์ ์ฐพ๊ฑฐ๋ dataManager ํ์ฉ\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\n }\n }).filter(Boolean);\n }\n \n // ๋ง์ฝ ์์์ ๋ชป ์ฐพ์๋๋ฐ host.grouping์ ์ธ ์ ์๋ค๋ฉด ๋งค๋์ ์์ ์๋\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\n }\n\n const data = childRecords; // data.length ๋ฑ์ ์ธ ์ ์๋๋ก ํธํ\n return ${expr};\n `);\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\n\t\t\t\t}\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\n\t\t\t}\n\n\t\t\treturn expr;\n\t\t} catch (e) {\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\n\t\t\treturn expr;\n\t\t}\n\t};\n}\n\nexport class EditableCellElement extends CellElement {\n\n\tget host() { return super.host; }\n\tget sheet() { return super.sheet; }\n\tget cell() { return super.cell; }\n\tget tr() { return super.tr; }\n\tget attr() { return super.attr; }\n\n\tgetExprValue(expr, data, row) {\n\t\treturn super.getExprValue(expr, data, row);\n\t}\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\t}\n\n\trefresh() {\n\t\treturn super.refresh();\n\t}\n\n\tgetExprValue = (expr, data, row, cell) => {\n\t\treturn super.getExprValue(expr, data, row, cell);\n\t}\n\n\tisValid = () => {\n\t\treturn super.isValid();\n\t}\n\n\tisInvalid = () => {\n\t\treturn super.isInvalid();\n\t}\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\";\nimport { NINE_TABLE } from \"@\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#EXPAND_ROW_COUNT = 10;\n\n\t#parent;\n\t#grd;\n\t#sheet;\n\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\n\t\tthis.#grd = this.querySelector(\"nine-table-simple\");\n\t\tsetTimeout(() => {\n\t\t\tthis.#sheet = this.#grd.shadowRoot.querySelector(\"nine-table-sheet\");\n\t\t\tthis.#initEvents();\n\t\t})\n\t}\n\n\t#initData = (formattedData) => {\n\n\t\tif (!this.#grd || !this.#parent.dataSource || this.#parent.dataSource.length === 0) return;\n\n\t\tconst activeColumnCount = this.#parent.items.length || 1;\n\n\t\tthis.#sheet.source.table.querySelectorAll('colgroup col, tbody td').forEach(($el, idx) => {\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\tthis.#sheet.querySelectorAll('table colgroup col').forEach(($el, idx) => {\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\n\t\tthis.#grd.addEventListener(NINE_TABLE.EVENT.ROW_ADDED, () => {\n\t\t\tsetTimeout(() => {\n\n\t\t\t\tthis.style.opacity = \"\";\n\t\t\t\tthis.classList.add(\"active\");\n\n\t\t\t\tthis.#sheet.querySelectorAll('colgroup col').forEach(($el, idx) => {\n\t\t\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\t\t\tif (col >= 2 && $el.style.display !== \"none\") {\n\t\t\t\t\t\tthis.#sheet.col.autoFit(col);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst fields = this.#grd.fields.get();\n\n\t\t\t\tif (this.#parent.multi) {\n\t\t\t\t\tconst selectedKeys = this.#parent.value ? String(this.#parent.value).split(this.#parent.separator).map(s => s.trim()) : [];\n\t\t\t\t\tconst kIndex = fields.indexOf(\"k\");\n\t\t\t\t\tconst chkIndex = fields.indexOf(\"CHK\");\n\n\t\t\t\t\tthis.#grd.data.getArray().forEach(record => {\n\t\t\t\t\t\trecord.v[chkIndex] = (selectedKeys.includes(String(record.v[kIndex]))) ? \"Y\" : \"N\";\n\t\t\t\t\t});\n\n\t\t\t\t\tconst index = this.#sheet.view.getArray().findIndex((record, idx) => {\n\t\t\t\t\t\treturn record.v[kIndex] === selectedKeys[0];\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.#selectRow(index);\n\t\t\t\t} else {\n\t\t\t\t\tconst currentValue = this.#parent.value;\n\t\t\t\t\tconst kIndex = fields.indexOf(\"k\");\n\t\t\t\t\tconst index = this.#sheet.view.getArray().findIndex((record, idx) => {\n\t\t\t\t\t\treturn record.v[kIndex] === currentValue;\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.#selectRow(index);\n\t\t\t\t}\n\t\t\t})\n\t\t}, {once: true});\n\n\t\tif (formattedData.length > this.#EXPAND_ROW_COUNT) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tthis.#grd.data.set(formattedData);\n\t};\n\n\t#isPanelBelow = ($btn) => {\n\t\tconst $sheet = $btn.closest(\".ng-sheet-body\");\n\n\t\tconst btnRect = $btn.getBoundingClientRect();\n\t\tconst sheetRect = $sheet.getBoundingClientRect();\n\t\tconst spaceBelow = sheetRect.bottom - btnRect.bottom;\n\t\tconst spaceAbove = btnRect.top - sheetRect.top;\n\n\t\treturn spaceBelow >= spaceAbove;\n\t};\n\n\t#calculatePanelHeight = ($btn, isDropDown, rows) => {\n\t\tconst $sheet = $btn.closest(\".ng-sheet-body\");\n\n\t\tconst btnRect = $btn.getBoundingClientRect();\n\t\tconst sheetRect = $sheet.getBoundingClientRect();\n\n\t\tconst searchInputHeight = 32;\n\t\tconst h1 = (isDropDown ? (sheetRect.bottom - btnRect.bottom) : (btnRect.top - sheetRect.top)) - 5;\n\t\tconst h2 = (rows * this.#sheet.template.height) + (rows > this.#EXPAND_ROW_COUNT ? searchInputHeight : 0) + 2;\n\n\t\treturn Math.min(h1, h2);\n\t}\n\n\t#calculatePanelLeft = ($btn) => {\n\n\t\tconst $cell = $btn.closest(\"th,td\");\n\t\tconst $sheet = $cell.closest(\".ng-sheet-body\");\n\n\n\t\tconst cellRect = $cell.getBoundingClientRect();\n\t\tconst sheetRect = $sheet.getBoundingClientRect();\n\n\t\tlet left = cellRect.left - sheetRect.left;\n\n\t\tconst panelWidth = this.offsetWidth;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 2);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\treturn left;\n\t};\n\n\topen = (parent) => {\n\t\tthis.#parent = parent;\n\n\t\tthis.classList.add(\"active\");\n\t\tthis.style.opacity = \"0\";\n\n\t\tlet items = this.#parent.items;\n\t\tif (items.length === 0) {\n\t\t\titems.push(this.#parent.valueName);\n\t\t}\n\n\t\tconst formattedData = this.#parent.dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: this.#parent.keyName && item[this.#parent.keyName] !== undefined ? item[this.#parent.keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\titems.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\tsetTimeout(() => {\n\n\t\t\tif (!this.#grd || !this.#parent.dataSource) return;\n\n\t\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\t\tconst sheet = parent.closest(\".ng-sheet-body\");\n\t\t\tconst btnRect = parent.getBoundingClientRect();\n\t\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\t\tconst isDropDown = this.#isPanelBelow(parent);\n\t\t\tconst h = this.#calculatePanelHeight(parent, isDropDown, formattedData.length);\n\t\t\tconst l = this.#calculatePanelLeft(parent);\n\t\t\tconst t = isDropDown ? (btnRect.bottom - sheetRect.top) : (btnRect.top - sheetRect.top - h);\n\n\t\t\tthis.style.height = `${h}px`;\n\t\t\tthis.style.left = `${l}px`;\n\t\t\tthis.style.top = `${t}px`;\n\t\t\t//this.style.opacity = \"\";\n\n\t\t\tif (this.#parent.multi) {\n\t\t\t\tthis.classList.add(\"multi\");\n\t\t\t\tthis.#grd.classList.add(\"multi\");\n\t\t\t} else {\n\t\t\t\tthis.classList.remove(\"multi\");\n\t\t\t\tthis.#grd.classList.remove(\"multi\");\n\t\t\t}\n\n\t\t\tthis.#initData(formattedData);\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus({ preventScroll: true });\n\t\t}\n\t}\n\n\n\t#onClick = (e) => {\n\t\tconst $cell = e.target.closest(\"th,td\");\n\t\tif (this.#grd.classList.contains(\"multi\")) {\n\t\t\tconst index = parseInt($cell?.dataset.index, 10);\n\t\t\tthis.#checkRow(index);\n\t\t}\n\t\telse {\n\t\t\tconst col = parseInt($cell?.dataset.col, 10);\n\n\t\t\tif (col >= 2) {\n\t\t\t\tthis.#returnRow();\n\t\t\t}\n\t\t}\n\t}\n\n\t#onKeydown_input = (e) => {\n\t\tswitch (e.code) {\n\t\t\tcase \"Enter\":\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tconst index = this.#grd.row.at();\n\t\t\t\tif (index < 0) {\n\t\t\t\t\tthis.#selectRow(0)\n\t\t\t\t} else {\n\t\t\t\t\tthis.#selectRow(index)\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"Tab\":\n\t\t\t\tthis.#selectRow(this.#grd.row.at());\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\t#onKeydown = (e) => {\n\t\tlet index;\n\t\tswitch (e.code) {\n\t\t\tcase \"Escape\":\n\t\t\t\tthis.close();\n\t\t\t\tbreak;\n\t\t\tcase \"Enter\":\n\t\t\t\tif (this.classList.contains(\"multi\")) {\n\t\t\t\t\tthis.#onOk();\n\t\t\t\t} else {\n\t\t\t\t\tthis.#returnRow();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"Tab\":\n\t\t\t\tif (this.classList.contains(\"expand\")) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tthis.querySelector(\"input[type='text']\").focus({ preventScroll: true });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tindex = this.#grd.row.at();\n\t\t\t\tif (index < 0) {\n\t\t\t\t\tthis.#selectRow(0)\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"Space\":\n\t\t\t\te.preventDefault();\n\t\t\t\tif ([\"TH\",\"TD\"].includes(e.target.tagName)) {\n\t\t\t\t\tthis.#checkRow(this.#grd.row.at());\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t#onOk = () => {\n\n\t\tconst fields = this.#grd.fields.get();\n\t\tconst kIndex = fields.indexOf(\"k\");\n\t\tconst chkIndex = fields.indexOf(\"CHK\");\n\n\t\tconst arr = [];\n\t\tthis.#sheet.view.getArray().forEach(o => {\n\t\t\tif (o.v[chkIndex] === \"Y\") {\n\t\t\t\tarr.push(o.v[kIndex]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = arr.join(this.#parent.separator);\n\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\t\tthis.close();\n\t}\n\n\t#returnRow = () => {\n\t\tconst index = this.#grd.row.at();\n\n\t\tif (index >= 0) {\n\t\t\tconst record = this.#sheet.view.get(index);\n\n\t\t\tthis.#parent.value = record.k;\n\t\t\tthis.#parent.sheet.rowManager.refresh(true);\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t#checkRow = (index) => {\n\n\t\tif (this.#grd.classList.contains(\"multi\") && index >= 0) {\n\t\t\tconst record = this.#sheet.view.get(index);\n\n\t\t\tthis.#grd.data.setValue(record.m._[NINE_TABLE.META.INDEX.ROWID], \"CHK\", record.CHK === \"Y\" ? \"N\" : \"Y\");\n\n\t\t\tthis.#grd.refresh();\n\t\t}\n\t};\n\n\t#selectRow = (index) => {\n\t\tif (index !== -1) {\n\t\t\tthis.#sheet.row.focus(index, () => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tconst cell = this.#sheet.querySelector(`tr[data-index=\"${index}\"] td[data-col=\"2\"]`);\n\t\t\t\t\tthis.#sheet.navigation.currentCell = cell;\n\t\t\t\t\tcell.focus({ preventScroll: true });\n\t\t\t\t\tthis.#sheet.invalidate();\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tthis.#sheet.row.focus(-1, () => {\n\t\t\t});\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#sheet.selection.clear();\n\n\t\t\t\tthis.#sheet.navigation.currentCell = this.#sheet.querySelector(`tr[data-index=\"0\"] td[data-col=\"2\"]`);\n\t\t\t\tthis.#sheet.focus({ preventScroll: true });\n\t\t\t\tthis.#sheet.invalidate();\n\t\t\t});\n\t\t}\n\t}\n\n\t#onSelectAll = (e) => {\n\n\t\tconst chkIdx = this.#grd.fields.get().indexOf(\"CHK\");\n\n\t\tthis.#grd.data.getArray().forEach(record => {\n\t\t\trecord.v[chkIdx] = e.target.checked ? \"Y\" : \"N\";\n\t\t});\n\n\t\tthis.#sheet.invalidate();\n\t};\n\n\n\t#onInput = (e) => {\n\t\tconst query = e.target.value.toLowerCase().trim();\n\n\t\tif (!query) {\n\t\t\tthis.#sheet.filtering.clear();\n\t\t} else {\n\t\t\tconst rawRecords = this.#grd.data.getArray();\n\t\t\tconst fields = this.#grd.fields.get();\n\n\t\t\tconst colnm = \"tmp1\";\n\t\t\tconst data2Idx = fields.indexOf(colnm);\n\n\t\t\tlet matchedValues = [];\n\t\t\trawRecords.forEach(record => {\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\n\n\t\t\t\tif (textVal.includes(query)) {\n\t\t\t\t\tmatchedValues.push(val);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.#sheet.filtering.set({\n\t\t\t\t[colnm]: [...new Set(matchedValues)]\n\t\t\t});\n\t\t}\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(\".search-input\").addEventListener(\"keydown\", this.#onKeydown_input);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\t\tthis.#sheet.addEventListener(\"keydown\", this.#onKeydown);\n\t\tthis.#sheet.addEventListener(\"click\", this.#onClick);\n\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\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 <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\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 <label for=\"chkAll\"><input id=\"chkAll\" type=\"checkbox\" checked><span>Select All</span></label>\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#target;\n\t#dataSource = [];\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#init();\n\t}\n\n\trerenderer = () => {\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\n\trefresh = () => {\n\t\tsuper.refresh();\n\n\t\tthis.#target.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\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\t#init = () => {\n\n\t\tthis.#renderer();\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\t#initData = () => {\n\t\t//if (!this.sheet || !this.cell) return;\n\n\t\tconst dataSource = this.cell.getAttribute(\"data-source\");\n\t\tif (dataSource) {\n\t\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\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.#target = this.querySelector(\".btn1\");\n\t};\n\n\t#initEvent = () => {\n\t\tthis.querySelectorAll(\"button\").forEach($el => {\n\t\t\t$el.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\n\n\t\tthis.cell.addEventListener('keydown', (e) => {\n\t\t\tif ([\"Space\"].includes(e.code)) {\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 = this.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\tthis.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\t//if (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\tif (this.#panel.classList.contains(\"active\") && 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\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n\tget keyName() {\n\t\treturn this.cell.getAttribute(\"key-name\") || \"k\";\n\t}\n\tget valueName() {\n\t\treturn this.cell.getAttribute(\"value-name\") || \"v\";\n\t}\n\tget multi() {\n\t\treturn this.cell.getAttribute('multi') === \"true\";\n\t}\n\tget multiSeparator() {\n\t\treturn this.cell.getAttribute(\"multi-separator\") || \",\";\n\t}\n\tget items() {\n\t\treturn this.cell.getAttribute(\"items\")?.split(\",\").map(s => s.trim()) || [];\n\t}\n\tget separator() {\n\t\treturn this.multiSeparator;\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\";\nimport {NINE_TABLE} from \"@\";\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(\".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=\"row-status\"></span>\n `;\n\t}\n\n\trefresh = () => {\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tthis.classList.remove(\"is-insert\", \"is-update\", \"is-delete\");\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) {\n\t\t\tswitch (rawRecord.m._[NINE_TABLE.META.INDEX.ROW_STATE]) {\n\t\t\t\tcase NINE_TABLE.ROW_STATE.INSERT:\n\t\t\t\t\tthis.classList.add(\"is-insert\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase NINE_TABLE.ROW_STATE.UPDATE:\n\t\t\t\t\tthis.classList.add(\"is-update\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase NINE_TABLE.ROW_STATE.DELETE:\n\t\t\t\t\tthis.classList.add(\"is-delete\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\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<div class=\"row-status\"></div>\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":"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"}
|
|
1
|
+
{"version":3,"file":"nine-table.umd.js","names":["traceOrigin","GROUP_IDX","GROUP_IDX","GROUP_IDX","factory","global","exports","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","_ninebone_util","NINE_TABLE","ngRow","#parent","parent","#newrow","ngData","#host","host","#initialize","item","validRecords","#getValidRecords","at","targetRecord","colnm","idx","rowData","rowIndex","colIndex","value","#conv","fields","#defaultHeight","templateElements","#getDefaultMeta","$el","loadData","dataSource","#invalidate","#nextId","rowid","jsonArray","arr","o","json","record","#json2Array","processedArr","#defaultInsert","row","updateState","targetIndex","#getIndexFromRow","arrIndex","records","b","a","targetId","index","COL_IDX","rowState","isSingle","targetArr","result","i","ngDataManager","ds","rowIdx","nRow","rowidx","#init","#fields","f","found","fieldName","fName","#adjust","map","name","type","rawTables","tbl","fieldType","attr","expr","lastIndex","targetField","NineTableSheets","NineTableSheetsFooter","#render","isMultiSelect","tabItem","#switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","tab","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","GROUP_IDX$1","GroupingManager","#sheet","#groupColumns","#groupMap","currentState","#collapsedMap","groupId","groupColumns","sourceTable","$cell","$tr","#isApplying","rowIds","dataManager","Grouping","validRaw","rawRecords","groupMap","nestedTree","#buildNestedMap","flatResult","renderItems","#flattenTree","collapsedMap","counter","isLastLevel","depth","groupKey","subMapOrRecords","mapOrArray","parentId","isCollapsed","#collectLeafRowIds","groupRecord","resultArr","#collectLeafRecords","remainingCols","key","subRecords","subVal","r","NineTableVScrollBar","viewRecords","totalCount","scrollHolder","rawContentHeight","getItemHeight","dataRowsHeight","sumHeight","MAX_BROWSER_HEIGHT","useScaling","scaleFactor","contentHeight","#getScaleInfo","fixedHeight","viewHeight","needsVScroll","trackHeight","thumbHeight","currentScrollTop","maxScrollTop","thumbTop","maxThumbTop","#startY","#startThumbTop","deltaY","targetThumbTop","ratio","#onMouseUp","#onMouseMove","#onMouseDown","clickY","scrollTimeout","startContinuousScroll","currentDelay","scrollStep","bodyView","scrollTop","effectiveTop","trs","firstTr","tr","rects","groupTop","isGroupRow","targetScrollTop","targetStepSize","direction","totalGroupHeight","stopContinuousScroll","RowManager","#initResizeObserver","bodyViewport","#measureAndCacheHeight","#renderAllContainers","#chchedAllRecords","#handleScroll","force","rowHeight","#isGrouped","#handleGroupedScroll","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","#element","currentStartIndex","$tbody","dataIndex","#bindRowData","allRenderItems","totalVirtualCount","bodyContent","templateLength","itemHeights","accumulatedHeight","offsetY","targetEnd","renderedItems","headerGroupIds","vIndex","itemIndex","chunkTrs","isTrGroup","subIdx","#bindGroupRowData","subRowIndex","matrixRow","virtualIndex","indices","childrenRecords","#containerTemplates","container","selector","tableEl","tbody","templateTrs","#sheetHeight","#isProgrammaticScroll","targetRow","dataRow","currentDataCount","totalGroupVirtualHeight","targetAccumulatedHeight","itemTotalHeight","tmplTr","isVisible","rawTargetScrollTop","onRendered","#updateRowCount","visibleRows","dynamicBuffer","#BUFFER_ROW_COUNT","groupRows","#cachedRowCount","#renderRows","#syncRowHeights","targetFixedType","clonedTr","targetTbody","fragment","tmpl","fragment2","trIndex","totalGroupingCount","$clonedTr","thead","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","entry","entries","height","TableCompiler","$table","$srcTable","#syncColAttributes","$col","fixed","cols","grid","rowSpan","colSpan","c","CellSelection","#initEvents","t","$td","col","r1","startRow","endRow","r2","c1","startCol","endCol","c2","containers","expanded","loopCount","#getMatrixRow","cell","cellEndRow","cellEndCol","nsR","neR","nsC","neC","sanitize","val","#range","root","elements","clientX","clientY","allCells","rect","targetCell","#getCellFromPoint","targetTr","#lastMatrixRow","#lastCol","#startRow","#startCol","mainZone","CellNavigation","#currentCell","#currentTr","#isCellLeftVisible","#isCellRightVisible","#isCellBelowVisible","#isCellAboveVisible","viewportRect","cellRect","theadHeight","delta","targetMatrixRow","targetCol","foundCell","#findCell","nextCell","#getPreviousCell","#getNextCell","#getUpCell","#getDownCell","#moveCellH","#moveCellV","nextCol","cellCol","$nextCell","bodyViewport2","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","isAutoFit","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","finalWidth","newColWidth","newNextWidth","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","size","calculatedWidth","ColResizerPanel","#renderer","ColMover","#grip","#indi","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","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","btn","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","groupingManager","groupResult","columns","rulesWithIdx","rule","idxA","idxB","isEmptyA","isEmptyB","strA","strB","PreCompiler","#ensureColgroup","#ensureThead","#ensureSectionTbodys","#ensureRowIndicator","#normalizeColAttributes","#createColIndicator","#normalizeCollapsibleAttributes","#generateCell","#initColExpanders","#initFilterButtons","#applyInitialCellWidths","firstRow","cnt","td","#numToExcelCol","background","num","headTbody","footTbody","colCount","sum","containerWidth","defaultWidth","widthVal","theadFoot","targetAttributes","autoIdCounter","$tbl","tagName","$datalist","$option","uniqueFuncName","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","rows","section","groups","currentGroup","indicatorCell","startColIdx","targetIdx","SheetAPI","self","getHeight","#resetElements","colEl","resolve","$trs","matrixRows","n","callback","$sheetBody","tfootHeight","viewportTop","viewportBottom","trRect","isAbove","isBelow","toRowid","NineTableSheet","#rowManager","#api","#bindApiMethods","#template","#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","activeParent","$parent","minRows","#syncHeaderAndFooterHeights","#initRowHoverEvent","prefix","firstTable","#createSplitTable","offsetHeight","sheetBottom","tbodyBottom","bodyContainer","scrollLeft","#sorting","leftHeaderRows","bodyHeaderRows","rightHeaderRows","#applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","api","args","LayoutManager","owner","#initEvent","sheetCount","sheetsHtml","className","sheetId","cssImports","$sheet","#isAutoHeight","#applyAutoHeight","lastHeight","currentHeight","basicHeight","ExprEngine","match","trimmedExpr","compiledExpr","evalFn","#exprCache","rowItem","DataAPI","providerObj","methods","fn","NineTableAPI","ns","#getActiveSheet","targetMethod","prop","NineTable","#shadowRoot","#dataManager","#dataApi","#sheetApi","#templateCnt","#bindDynamicSetters","#layoutManager","#dispatchLoad","checkCount","checkTimer","loadSheetCnt","idOrIndex","extractedMethodNames","matches","internalValue","methodName","newValue","BasicCellElement","exprCache","CellElement","#updateRowState","#cell","#tr","#attr","button","curRow","renderer","rawRecord","defaultValue","\"display\"","data","cleanExpr","allRecords","childRecords","funcName","field","acc","EditableCellElement","CellInputText","#target","#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","activeColumnCount","selectedKeys","kIndex","chkIndex","#selectRow","currentValue","formattedData","#EXPAND_ROW_COUNT","$btn","btnRect","h1","isDropDown","h2","items","#isPanelBelow","#calculatePanelHeight","#calculatePanelLeft","#initData","#checkRow","#returnRow","#onKeydown_input","#onKeydown","CellCombo","#getDisplayText","#validateInput","keys","list","#togglePanel","CellRenderer","CellButton","#cellButtonClick","customEvent","rawValue","CellTree","level","#textElement","#updateTreeState","hasChildren","#checkHasChildren","#iconElement","CellRowIndicator","#mainTarget","#subTarget","#statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","ColExpand","singleWidth","currentW","splitWidth","ContextMenu","#tableHost","targetTable","#getTargetSheet","activeTableId","activeTable","containerElement","targetTableAttr","rootUl","parsedList","#traverseUl","ulEl","child","spanEl","subUl","useDefault","rawItems","customItems","#parseCustomMenuItems","fixManager","#getFixManager","currentFixState","isFixable","isHeaderCell","fixMenuItem","cleanedItems","targetParent","menuItems","#buildMenuItems","#handleMenuClick","#syncMenuStates","isFiltering","autoFit","showTitle","menuId","#onContextMenu","MenuPanel","#onCallback","#appendItems","#bindClickEvents","cellRightX","wrapper","calculatedLeft","panelHeight","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/data/Grouping.js","../src/layout/nine-table-vscrollbar.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/api/SheetAPI.js","../src/layout/nine-table-sheet.js","../src/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/api/DataAPI.js","../src/api/NineTableAPI.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-tree.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 ROW_STATE: 1,\n FILTER: 2,\n GROUP: 3,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 0,\n NORMAL: 1,\n INSERT: 2,\n UPDATE: 3,\n DELETE: 9\n },\n EVENT: {\n LOAD: \"load\",\n ROW_ADDED: \"row-added\",\n ROW_REMOVED: \"row-removed\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport class ngRow {\n\t#parent;\n\t#newrow = -1;\n\n\tconstructor(parent) {\n\t\tthis.#parent = parent;\n\t}\n\n\tget at() {\n\t\treturn this.#newrow;\n\t}\n\tset at(v) {\n\t\tthis.#newrow = parseInt(v, 10);\n\t}\n\n\tcount = () => this.#parent.rawRecords.length;\n}\n\nexport class ngData {\n\t#host;\n\t#parent;\n\t#nextId = 0;\n\t#defaultHeight = [];\n\n\tstatic META_INDEX = {\n\t\tFILTER: 0,\n\t\t// GROUP: 1,\n\t\t// SELECT: 2,\n\t\t// EXPAND: 3\n\t};\n\n\tstatic ROW_STATE = {\n\t\tEMPTY: 'EMPTY',\n\t\tNORMAL: 'NORMAL',\n\t\tINSERT: 'INSERT',\n\t\tUPDATE: 'UPDATE',\n\t\tDELETE: 'DELETE'\n\t};\n\n\tconstructor(host, parent) {\n\t\tthis.#host = host;\n\t\tthis.#parent = parent;\n\t\tthis.#initialize();\n\t}\n\n\n\t#getValidRecords = () => {\n\t\tconst rawRecords = this.#parent.rawRecords || [];\n\t\treturn rawRecords.filter(item => item.m._[NINE_TABLE.META.INDEX.ROW_STATE] !== NINE_TABLE.ROW_STATE.DELETE);\n\t};\n\n\tgetRawRecords = () => {\n\t\treturn this.#parent.rawRecords || [];\n\t};\n\n\tget count() {\n\t\treturn this.length;\n\t}\n\n\tcount = () => {\n\t\treturn this.length;\n\t};\n\n\tgetArray = (at, colnm) => {\n\t\tconst validRecords = this.#getValidRecords();\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn validRecords; // ๋ณํ ์์ด ๋ฐฐ์ด ๊ทธ๋๋ก ๋ฐํ (๋ ๋๋ง ์ต์ ํ)\n\t\t}\n\n\t\tif (at < 0 || at >= validRecords.length) return null;\n\n\t\tconst targetRecord = validRecords[at];\n\n\t\tif (colnm != null) {\n\t\t\tconst fields = this.getHostFields();\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn targetRecord;\n\t};\n\n\tsetArray = (rowIndex, colIndex, value) => {\n\t\tconst validRecords = this.#getValidRecords();\n\t\tconst rowData = validRecords[rowIndex];\n\n\t\tconst oldValue = rowData.v[colIndex];\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\n\t\t}\n\n\t\trowData.v[colIndex] = value;\n\t};\n\n\n\tget = (at, colnm) => {\n\t\tconst validRecords = this.#getValidRecords();\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn this.#conv(validRecords);\n\t\t}\n\n\t\tif (at < 0 || at >= validRecords.length) return null;\n\n\t\tconst targetRecord = validRecords[at];\n\t\tconst fields = this.getHostFields();\n\n\t\tif (colnm != null) {\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn this.#conv(targetRecord);\n\t};\n\n\tgetAll = () => {\n\t\treturn this.#parent.rawRecords || [];\n\t};\n\n\tgetHostFields = () => {\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\n\t};\n\n\t#initialize = () => {\n\t\tthis.#defaultHeight = [];\n\t\tconst templateElements = this.#host.template || [];\n\t\tArray.from(templateElements).forEach(el => {\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\n\t\t});\n\n\t\t(this.#parent.rawRecords || []).forEach(v => {\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\n\t\t});\n\t};\n\n\tget source() {\n\t\treturn this.#conv(this.#parent.rawRecords);\n\t}\n\tset source(v) {\n\t\tthis.set(v);\n\t}\n\n\t#invalidate = () => {\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\n\t\t\t$el.invalidate();\n\t\t});\n\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\n\t};\n\n\tset = (dataSource) => {\n\n\t\tconst loadData = () => {\n\t\t\tthis.#host.loading = true;\n\t\t\tsetTimeout(() => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.clear();\n\t\t\t\t\tthis.add(dataSource, false);\n\t\t\t\t\tthis.#invalidate();\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#host.loading = false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (this.#host.loaded) {\n\t\t\tloadData();\n\t\t}\n\t\telse {\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\n\t\t\t\tloadData();\n\t\t\t}, { once: true });\n\t\t}\n\t};\n\n\tget nextId() {\n\t\treturn this.#nextId++;\n\t}\n\n\tget length() {\n\t\treturn this.#getValidRecords().length;\n\t}\n\n\tget count() {\n\t\treturn this.length;\n\t}\n\n\tgetRowCount() {\n\t\treturn this.length;\n\t}\n\n\t#getDefaultMeta = (rowid = 0) => {\n\t\treturn {\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\n\t\t\tdeleted: false,\n\t\t\tfiltered: false,\n\t\t\theight: this.#defaultHeight.slice(),\n\t\t\to: {},\n\t\t\tc: {},\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\n\t\t\t_: [rowid, NINE_TABLE.ROW_STATE.EMPTY, [], []],\n\t\t};\n\t};\n\n\treset = () => {\n\t\tthis.#parent.rawRecords = [];\n\t\tthis.#invalidate();\n\t};\n\n\tclear = () => {\n\t\tthis.#parent.rawRecords = [];\n\t\tif (this.#parent.viewRecords?.reset) {\n\t\t\tthis.#parent.viewRecords.reset();\n\t\t}\n\n\t\tthis.#nextId = 0;\n\n\t\tthis.#invalidate();\n\t};\n\n\t#json2Array = (jsonArray) => {\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\n\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\n\t\tconst arr = [];\n\n\t\tjsonArray.forEach(json => {\n\t\t\tconst o = { v: [] };\n\t\t\tfields.forEach(colnm => {\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\n\t\t\t});\n\t\t\tarr.push(o);\n\t\t});\n\n\t\treturn arr;\n\t};\n\n\t#defaultInsert = (arr) => {\n\t\tif (!Array.isArray(arr)) arr = [arr];\n\t\tarr.forEach(o => {\n\t\t\tconst rowid = this.nextId;\n\n\t\t\to.m = this.#getDefaultMeta(rowid);\n\t\t\to.__ng = o.m;\n\t\t\to.__ng.rowid = rowid;\n\t\t\t//o.__ng.rowState = ngData.ROW_STATE.INSERT;\n\n\t\t\to.m._[NINE_TABLE.META.INDEX.ROWID] = rowid;\n\t\t\to.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.EMPTY;\n\t\t});\n\t\treturn arr;\n\t};\n\n\t#getIndexFromRow = (rowid) => {\n\t\tconst index = this.#parent.rawRecords.findIndex(record => {\n\t\t\tif (!record || !record.m || !record.m._) return false;\n\t\t\treturn record.m._[NINE_TABLE.META.INDEX.ROWID] === rowid;\n\t\t});\n\n\t\treturn index;\n\t}\n\n\tadd = (dataSource, updateState = true) => {\n\t\tif (dataSource === undefined) dataSource = {};\n\t\tconst arr = this.#json2Array(dataSource);\n\n\t\tconst processedArr = this.#defaultInsert(arr);\n\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(processedArr);\n\n\t\tconst row = this.count() - 1;\n\t\tif (updateState) {\n\t\t\tarr.forEach((_, idx) => {\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\n\t\t\t\tif (target) target.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.INSERT;\n\t\t\t});\n\t\t}\n\n\t\tthis.#invalidate();\n\n\t\tthis.#host.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.ROW_ADDED, {\n\t\t\tbubbles: true,\n\t\t\tdetail: { target: this.#host, rowid: processedArr.length > 0 ? processedArr[0].m._[NINE_TABLE.META.INDEX.ROWID] : null }\n\t\t}));\n\n\t\treturn row;\n\t};\n\n\n\tinsert = (rowid, dataSource, updateState = true) => {\n\t\t//trace.log(\"์ฐพ์ rowid:\", rowid);\n\n\t\tif (dataSource === undefined) dataSource = {};\n\t\tconst arr = this.#json2Array(dataSource);\n\t\tif (arr.length === 0) return -1;\n\n\t\tlet targetIndex = this.#getIndexFromRow(rowid);\n\t\t/**\n\t\tif (rowid !== undefined && rowid !== null) {\n\t\t\ttargetIndex = this.#parent.rawRecords.findIndex(record => {\n\t\t\t\tif (!record || !record.m || !record.m._) return false;\n\t\t\t\treturn record.m._[NINE_TABLE.META.INDEX.ROWID] === rowid;\n\t\t\t});\n\t\t} */\n\n\t\tconst processedArr = this.#defaultInsert(arr);\n\n\t\t//if (targetIndex === -1) {\n\t\t//\ttargetIndex = this.#parent.rawRecords.length;\n\t\t//}\n\n\t\tthis.#parent.rawRecords.splice(targetIndex, 0, ...processedArr);\n\n\t\tif (updateState) {\n\t\t\tprocessedArr.forEach((_, idx) => {\n\t\t\t\tconst target = this.#parent.rawRecords[targetIndex + idx];\n\n\t\t\t\tif (target && target.m && target.m._) {\n\t\t\t\t\ttarget.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.INSERT;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.#invalidate();\n\n\t\tthis.#host.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.ROW_ADDED, {\n\t\t\tbubbles: true,\n\t\t\tdetail: { target: this.#host, rowid: processedArr.length > 0 ? processedArr[0].m._[NINE_TABLE.META.INDEX.ROWID] : null }\n\t\t}));\n\n\t\treturn processedArr[0].m._[NINE_TABLE.META.INDEX.ROWID]; // ์ฝ์
๋ ์ค์ ๋ฐฐ์ด ์ธ๋ฑ์ค ๋ฐํ\n\t};\n\n\tremove = (v) => {\n\t\tlet arr = [];\n\t\tif (Array.isArray(v)) {\n\t\t\tarr = at;\n\t\t//} else if (typeof at === \"undefined\") {\n\t\t//\tarr = [this.#parent.host.row.at];\n\t\t} else {\n\t\t\tarr = [parseInt(v, 10)];\n\t\t}\n\n\t\tlet arrIndex = [];\n\t\tarr.forEach(rowid => {\n\t\t\tarrIndex.push(this.#getIndexFromRow(rowid));\n\t\t});\n\n\t\tconst records = this.#parent.rawRecords;//this.#getValidRecords();\n\n\t\tarrIndex.sort((a, b) => b - a).forEach(index => {\n\t\t\t//if (validRecords[index]) {\n\t\t\t\tconst targetId = records[index].m._[NINE_TABLE.META.INDEX.ROWID];\n\n\t\t\t\tif (records[index].m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.INSERT) {\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.m._[NINE_TABLE.META.INDEX.ROWID] !== targetId);\n\t\t\t\t} else {\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\n\t\t\t\t\t\tif (item.m._[NINE_TABLE.META.INDEX.ROWID] === targetId) {\n\t\t\t\t\t\t\titem.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.DELETE;\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.#invalidate();\n\n\t\tthis.#host.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.ROW_REMOVED, {\n\t\t\tbubbles: true,\n\t\t\tdetail: { target: this.#host, rowid: arr.length > 0 ? arr[0] : null }\n\t\t}));\n\t};\n\n\tsetValue = (rowid, colnm, value, updateState = true) => {\n\n\t\trowid = parseInt(rowid, 10);\n\t\tconst fields = this.getHostFields();\n\t\tconst COL_IDX = fields.indexOf(colnm);\n\t\tif (COL_IDX < 0) return;\n\n\t\tconst index = this.#getIndexFromRow(rowid);\n\n\t\tconst records = this.#parent.rawRecords;\n\t\tconst rowData = records[index];\n\t\tif (!rowData) return;\n\n\t\tconst oldValue = rowData.v[COL_IDX];\n\t\tif (oldValue !== value && updateState && rowData.m._[NINE_TABLE.META.INDEX.ROW_STATE] !== NINE_TABLE.ROW_STATE.INSERT) {\n\t\t\trowData.m._[NINE_TABLE.META.INDEX.ROW_STATE] = NINE_TABLE.ROW_STATE.UPDATE;\n\t\t}\n\n\t\trowData.v[COL_IDX] = value;\n\t};\n\n\tgetChangedData = (rowState) => {\n\n\t\tconst records = this.#parent.rawRecords;\n\n\t\tif (rowState) {\n\t\t\treturn this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === rowState; } ) );\n\t\t}\n\t\telse {\n\t\t\treturn {\n\t\t\t\tC: this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.INSERT; } ) ),\n\t\t\t\tU: this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.UPDATE; } ) ),\n\t\t\t\tD: this.#conv( records.filter(item => { return item.m._[NINE_TABLE.META.INDEX.ROW_STATE] === NINE_TABLE.ROW_STATE.DELETE; } ) ),\n\t\t\t};\n\t\t}\n\t};\n\n\t#conv = (arr) => {\n\t\tif (!arr) return arr;\n\n\t\tconst isSingle = !Array.isArray(arr);\n\t\tconst targetArr = isSingle ? [arr] : arr;\n\t\tconst fields = this.getHostFields();\n\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\n\t\t\tconst t = {};\n\t\t\tfields.forEach((colnm, i) => {\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\n\t\t\t});\n\t\t\tt.__ng = o.__ng;\n\t\t\treturn t;\n\t\t});\n\n\t\treturn isSingle ? result[0] : result;\n\t};\n}\n","import { ngRow, ngData } from \"./ngData.js\";\n\nexport class ngDataManager {\n\t#host;\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\n\t\tthis.row = new ngRow(this);\n\t\tthis.data = new ngData(this.#host, this);\n\n\t\tthis.rawRecords = [];\n\t\tthis.viewRecords = [];\n\t\tthis.delRecords = [];\n\t\tthis.pageCnt = 25;\n\n\t\tthis.viewRecords.reset = () => {\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\n\t\t};\n\n\t\tthis.setDataSource = (ds) => {\n\t\t\tif (this.data) this.data.reset();\n\n\t\t\tthis.rawRecords = [];\n\t\t\tthis.viewRecords = [];\n\t\t\tthis.delRecords = [];\n\n\t\t\tthis.data.set(ds || []);\n\t\t};\n\n\t\tthis.getRowState = (nRow) => {\n\t\t\tconst rowIdx = parseInt(nRow, 10);\n\t\t\tif (rowIdx >= this.data.count()) return;\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\n\t\t};\n\n\t\tthis.getRowPosition = () => this.row.at;\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\n\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\n\n\t\tthis.setColumn = (rowidx, colnm, v) => {\n\t\t\trowidx = parseInt(rowidx, 10);\n\t\t\tthis.data.setValue(rowidx, colnm, v);\n\t\t};\n\n\t\t// ์ด๊ธฐ ๋น ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ\n\t\tthis.setDataSource([]);\n\t}\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 ['mouseup', 'mouseleave'].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}","import { trace } from \"@nopeer\";\n\nexport const GROUP_IDX = {\n\tID: 0,\n\tDEPTH: 1,\n\tNAME: 2,\n\tCHILDREN: 3,\n};\n\nexport class GroupingManager {\n\t#sheet;\n\t#host;\n\t#groupColumns = [];\n\t#groupMap = new Map();\n\t#collapsedMap = new Map(); // ๊ทธ๋ฃน๋ณ ์ ํ ์ํ ๊ด๋ฆฌ\n\t#isApplying = false;\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = this.#sheet.getRootNode().host;\n\t}\n\n\tget columns() {\n\t\treturn this.#groupColumns;\n\t}\n\n\tget groupMap() {\n\t\treturn this.#groupMap;\n\t}\n\n\t// ๐ก ๋๋ฝ๋์๋ setGroupMap ๋ฉ์๋ ์ถ๊ฐ\n\tsetGroupMap(map) {\n\t\tthis.#groupMap = map;\n\t}\n\n\t// ํน์ ๊ทธ๋ฃน์ ์ ๊ธฐ/ํด๊ธฐ ์ํ ํ ๊ธ\n\ttoggleGroup(groupId) {\n\t\tconst currentState = this.#collapsedMap.get(groupId) || false;\n\t\tthis.#collapsedMap.set(groupId, !currentState);\n\t\tthis.#sheet.invalidate();\n\t}\n\n\tisCollapsed(groupId) {\n\t\treturn this.#collapsedMap.get(groupId) || false;\n\t}\n\n\tget collapsedMap() {\n\t\treturn this.#collapsedMap;\n\t}\n\n\tinitialize = () => {\n\t\tlet groupColumns = [];\n\t\tconst sourceTable = this.#sheet.sourceTable;\n\t\tif (sourceTable) {\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\n\t\t\t\tconst $cell = $tr.querySelector(`[cell-type=\"tree\"]`);\n\t\t\t\tif ($cell && $cell.dataset.bind) {\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.#groupColumns = groupColumns;\n\t};\n\n\tapply() {\n\t\tif (this.#isApplying) return;\n\t\tthis.#isApplying = true;\n\t\tthis.initialize();\n\t\tthis.#isApplying = false;\n\t\tthis.#sheet.scrollToY(0);\n\t\tthis.#sheet.view.refresh();\n\t}\n\n\tclear() {\n\t\tthis.#groupColumns = [];\n\t\tthis.#groupMap.clear();\n\t\tthis.#collapsedMap.clear();\n\t\tthis.#isApplying = false;\n\t\tthis.#sheet.scrollToY(0);\n\t\tthis.#sheet.view.refresh();\n\t}\n\n\tgetChildrenRowIds(groupId) {\n\t\treturn this.#groupMap.get(groupId) || [];\n\t}\n\n\tgetChildrenRecords(groupId) {\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\n\t\tconst dataManager = this.#host.data;\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\n\t}\n}\n\nexport class Grouping {\n\n\tstatic apply(rawRecords, groupColumns = [], fields = [], collapsedMap = new Map()) {\n\t\tif (!groupColumns || groupColumns.length === 0) {\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\n\t\t}\n\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\n\t\tconst groupMap = new Map();\n\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\n\t\tconst flatResult = [];\n\t\tconst renderItems = [];\n\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\", collapsedMap);\n\n\t\treturn { headers: flatResult, renderItems, groupMap };\n\t}\n\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId, collapsedMap) {\n\t\tlet counter = 0;\n\t\tconst isLastLevel = (depth === groupColumns.length - 1);\n\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\n\t\t\tconst isCollapsed = collapsedMap.get(groupId) || false;\n\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\n\t\t\tgroupMap.set(groupId, rowIds);\n\n\t\t\tconst groupRecord = [];\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\n\n\t\t\tgroupRecord.__isGroupHeader = true;\n\t\t\tgroupRecord.__groupId = groupId;\n\t\t\tgroupRecord.__collapsed = isCollapsed;\n\n\t\t\tresultArr.push(groupRecord);\n\n\t\t\trenderItems.push({\n\t\t\t\ttype: 'group',\n\t\t\t\trecord: groupRecord,\n\t\t\t\tgroupId: groupId,\n\t\t\t\tcollapsed: isCollapsed,\n\t\t\t});\n\n\t\t\t// ๐ก ๊ทธ๋ฃน์ด ์ ํ์์ง ์์ ๊ฒฝ์ฐ์๋ง ํ์ ํธ๋ฆฌ ๋ฐ ์์ ๋ ์ฝ๋ ์ถ๊ฐ\n\t\t\tif (!isCollapsed) {\n\t\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\n\t\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId, collapsedMap);\n\t\t\t\t} else {\n\t\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\n\t\t\t\t\tleafRecords.forEach(record => {\n\t\t\t\t\t\trecord.__isGroupHeader = false;\n\t\t\t\t\t\trecord.__groupId = groupId;\n\t\t\t\t\t\tresultArr.push(record);\n\n\t\t\t\t\t\trenderItems.push({\n\t\t\t\t\t\t\ttype: 'data',\n\t\t\t\t\t\t\trecord: record,\n\t\t\t\t\t\t\tgroupId: groupId\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\t}\n\n\n\n\tstatic #buildNestedMap(records, groupColumns, fields) {\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\n\t\tconst remainingCols = groupColumns.slice(1);\n\t\tconst map = new Map();\n\n\t\trecords.forEach(record => {\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\n\t\t\tif (!map.has(key)) map.set(key, []);\n\t\t\tmap.get(key).push(record);\n\t\t});\n\n\t\tif (remainingCols.length > 0) {\n\t\t\tconst result = new Map();\n\t\t\tfor (let [key, subRecords] of map.entries()) {\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\treturn map;\n\t}\n\n\tstatic #collectLeafRowIds(subMapOrRecords) {\n\t\tlet rowIds = [];\n\t\tif (subMapOrRecords instanceof Map) {\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\n\t\t\t}\n\t\t} else if (Array.isArray(subMapOrRecords)) {\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\n\t\t}\n\t\treturn rowIds;\n\t}\n\n\tstatic #collectLeafRecords(subMapOrRecords) {\n\t\tlet records = [];\n\t\tif (subMapOrRecords instanceof Map) {\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\n\t\t\t}\n\t\t} else if (Array.isArray(subMapOrRecords)) {\n\t\t\trecords = records.concat(subMapOrRecords);\n\t\t}\n\t\treturn records;\n\t}\n}","// ui/nine-table-vscrollbar.js\nimport { trace } from \"@nopeer\";\nimport { GROUP_IDX } from \"@/data/Grouping.js\";\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) {\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH];\n return this.#sheet.template.heights[depth];\n } else {\n // ์ ์์ ์ธ ๋ง์ด๋์ค ์ฐ์ฐ์(-)๊ฐ ํฌํจ๋ ๋ฐ์ดํฐ ํ ๋์ด ์ฐ์ถ\n const dataRowsHeight = this.#sheet.template.height - this.#sheet.template.group.height;\n return dataRowsHeight > 0 ? dataRowsHeight : this.#sheet.template.height;\n }\n };\n\n let sumHeight = 0;\n for (let i = 0; i < viewRecords.length; i++) {\n sumHeight += getItemHeight(viewRecords[i]);\n }\n\n rawContentHeight = sumHeight;\n } else {\n const rowHeight = this.#sheet.template.height;\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 { 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 // ๐ก hardcoded ๋ฐฉ์ ๋์ #getScaleInfo()๊ฐ ์ฐ์ถํ contentHeight๋ฅผ ๊ธฐ์ค(rawContentHeight ๋์ฒด)์ผ๋ก ํ์ฉ\n const rawContentHeight = contentHeight;\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 // ๐ก ๋๋ฝ๋ ๊ณฑํ๊ธฐ(*) ์ฐ์ฐ์ ๋ณต๊ตฌ\n const thumbHeight = Math.max(Math.min(trackHeight * (viewHeight / rawContentHeight), trackHeight), 20);\n thumb.style.height = `${thumbHeight}px`;\n\n const currentScrollTop = body.scrollTop;\n\n // ๐ก ๋๋ฝ๋ ๋ง์ด๋์ค(-) ์ฐ์ฐ์ ๋ณต๊ตฌ ๋ฐ viewHeight ๊ธฐ์ค ๋ฐ์\n const maxScrollTop = Math.max(rawContentHeight - viewHeight, 1);\n\n let thumbTop = 0;\n if (maxScrollTop > 0) {\n // ๐ก ๋๋ฝ๋ ๋ง์ด๋์ค(-) ์ฐ์ฐ์ ๋ณต๊ตฌ\n thumbTop = (currentScrollTop / maxScrollTop) * (trackHeight - thumbHeight);\n }\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 // ๐ก ๋๋ฝ๋ ๋ง์ด๋์ค(-) ์ฐ์ฐ์ ๋ณต๊ตฌ\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n #onMouseUp = () => {\n this.#dragging = false;\n };\n\n #onMouseDown = (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\n };\n\n #onMouseMove = (e) => {\n if (!this.#dragging) return;\n\n /** will be move down */\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 if (maxThumbTop <= 0) return;\n\n //trace.log(new Date().toISOString());\n\n const deltaY = e.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 // ์ด๋ ๋น์จ(0 ~ 1) ์ฐ์ถ\n const ratio = maxThumbTop > 0 ? (targetThumbTop / maxThumbTop) : 0;\n\n // RowManager ๋ฐ RowManager #handleScroll๊ณผ ์๋ฒฝํ ๋๊ธฐํ๋๋ ํฝ์
๋จ์ scrollTop ์ฐ์ถ\n const body = this.#elements.container;\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 || 0);\n const viewHeight = body.clientHeight - fixedHeight;\n\n const { contentHeight } = this.#getScaleInfo();\n const maxScrollTop = Math.max(contentHeight - viewHeight, 0);\n\n const targetScrollTop = ratio * maxScrollTop;\n\n // ๋ทฐํฌํธ ์คํฌ๋กค ์ง์ ์ง์ ๋ฐ RowManager ๊ฐฑ์ ์ ๋\n body.scrollTop = targetScrollTop;\n //this.#sheet.rowManager?.refresh(true);\n\n const currentScrollTop = body.scrollTop;\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n\n #init = () => {\n\n document.addEventListener('mouseup', this.#onMouseUp);\n document.addEventListener('mousemove', this.#onMouseMove);\n this.#elements.thumb.addEventListener(\"mousedown\", this.#onMouseDown);\n\n // 2. ํธ๋(Track) ๋น ๊ณต๊ฐ ํด๋ฆญ ์ ์ด\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 body = this.#elements.container;\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 || 0);\n const viewHeight = body.clientHeight - fixedHeight;\n\n const { contentHeight } = this.#getScaleInfo();\n const maxScrollTop = Math.max(contentHeight - viewHeight, 0);\n\n const targetScrollTop = ratio * maxScrollTop;\n\n body.scrollTop = targetScrollTop;\n this.#sheet.rowManager?.refresh(true);\n }\n this.refresh();\n });\n\n let scrollTimeout = null;\n\n const startContinuousScroll = (direction) => {\n if (scrollTimeout) return;\n\n const viewRecords = this.#sheet.view.getArray();\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 let currentDelay = 400;\n const minDelay = 1;\n\n const scrollStep = () => {\n const bodyView = this.#elements.container; // ๐ก ๋ทฐํฌํธ DOM ์ปจํ
์ด๋ (bodyView)\n const scrollTop = bodyView.scrollTop;\n const bodyRect = bodyView.getBoundingClientRect(); // ๐ก DOM ์์น ์ ๋ณด\n const effectiveTop = bodyRect.top + fixedHeight;\n\n // 1. ํ์ฌ ๋ทฐํฌํธ์ ๋ ๋๋ง๋ tr๋ค์ ๊ฐ์ ธ์ด\n const trs = Array.from(this.#sheet.querySelectorAll('.ng-container-body tbody.body tr'));\n if (trs.length === 0) return;\n\n // 2. ์ฒซ ๋ฒ์งธ ์ ํจํ(๋ณด์ด๋) tr ์ฐพ๊ธฐ\n const firstTr = trs.find(tr => tr.style.display !== 'none');\n if (!firstTr) return;\n\n const index = parseInt(firstTr.dataset.index, 10);\n const sameIndexTrs = trs.filter(tr => {\n if (tr.style.display === 'none') return false;\n return tr.dataset.index === firstTr.dataset.index;\n });\n\n const rects = sameIndexTrs.map(tr => tr.getBoundingClientRect());\n const groupTop = Math.min(...rects.map(r => r.top));\n\n // 3. ์ฒซ ๋ฒ์งธ tr์ด ๊ทธ๋ฃน ํ์ธ์ง ํ๋จ\n const isGroupRow = firstTr.getAttribute('grouping') === 'true';\n\n let targetScrollTop = scrollTop;\n let targetStepSize = 0;\n\n if (direction === 'down') {\n\n if (isGroupRow) {\n\n const groupBottom = Math.max(...rects.map(r => r.bottom));\n const totalGroupHeight = groupBottom - groupTop;\n\n if (effectiveTop > groupTop) {\n targetStepSize = totalGroupHeight - (effectiveTop - groupTop);\n } else {\n targetStepSize = totalGroupHeight;\n }\n } else {\n if (effectiveTop > groupTop) {\n targetStepSize = this.#sheet.template.height - this.#sheet.template.group.height - (effectiveTop - groupTop);\n } else {\n targetStepSize = this.#sheet.template.height - this.#sheet.template.group.height;\n }\n }\n\n targetScrollTop = scrollTop + targetStepSize;\n } else {\n if (groupTop >= effectiveTop) {\n if (index > 0) {\n if (viewRecords[index-1].type === \"group\") {\n const depth = viewRecords[index-1].groupId.split(\"_\").length - 2;\n targetStepSize = this.#sheet.template.group.heights[depth];\n } else {\n targetStepSize = this.#sheet.template.height - this.#sheet.template.group.height;\n }\n }\n } else {\n targetStepSize = effectiveTop - groupTop;\n }\n\n targetScrollTop = Math.max(0, scrollTop - targetStepSize);\n }\n\n bodyView.scrollTop = targetScrollTop;\n this.#sheet.rowManager?.refresh(true);\n this.refresh();\n\n currentDelay = Math.max(minDelay, Math.floor(currentDelay * 0.7));\n scrollTimeout = setTimeout(scrollStep, currentDelay);\n };\n\n scrollStep();\n };\n\n const stopContinuousScroll = () => {\n if (scrollTimeout) {\n clearTimeout(scrollTimeout); // ๐ก setTimeout์ด๋ฏ๋ก clearTimeout ์ฌ์ฉ\n scrollTimeout = 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 #init1 = () => {\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 records = this.#sheet.getArray();\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n if (maxThumbTop <= 0) return;\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.template.height;\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 trace.log(totalCount, targetRow);\n\n this.#sheet.rowManager.scrollToDataRow(targetRow);\n\n const { 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 //trace.log(new Date().toISOString());\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\";\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 #chchedAllRecords;\n #containerTemplates = new Map();\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.#sheet.template.height;\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.#sheet.template.height || this.#sheet.template.height <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#sheet.template.height && this.#sheet.template.height > 0) {\n this.#renderAllContainers();\n }\n }\n\n this.#chchedAllRecords = this.#host.data.getArray();\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 const rowHeight = this.#sheet.template.height;\n if (!rowHeight || rowHeight <= 0) return;\n\n if (this.#isGrouped) {\n this.#handleGroupedScroll(scrollTop, force);\n return;\n }\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 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) - rowHeight, 0);\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 const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n //trace.log(clampedScrollTop % rowHeight, rowHeight);\n\n /*\n * FIX: Use GPU-accelerated transform3d instead of 'top' positioning.\n * On mobile devices (iOS Safari), direct 'top' updates trigger expensive\n * layout reflows and cause severe scrolling lag during inertia touch scrolls.\n * translate3d forces hardware compositing for buttery-smooth performance.\n */\n this.#sheet.elements.left.tbody.body.style.transform =\n this.#sheet.elements.body.tbody.body.style.transform =\n this.#sheet.elements.right.tbody.body.style.transform = `translate3d(0px, -${clampedScrollTop % rowHeight}px, 0px)`;\n\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 $tbody.trs.forEach(($tr, index) => {\n const dataIndex = startIndex + Math.floor(index / this.#sheet.template.length);\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 #getPreviousSiblingGroupId = (groupId) => {\n if (!groupId) return null;\n\n const parts = groupId.split('_'); // ์: ['g', '0', '1', '2']\n const lastIdx = parts.length - 1;\n const lastVal = parseInt(parts[lastIdx], 10);\n\n // ๋ง์ง๋ง ์๋ฒ์ด 0๋ณด๋ค ์ปค์ผ ๋ฐ๋ก ์ํ์ ๊ฐ ์กด์ฌํจ\n if (lastVal > 0) {\n let siblingParts = [...parts];\n siblingParts[lastIdx] = lastVal - 1;\n return siblingParts.join('_');\n }\n\n return null; // ๋ฐ๋ก ์ํ์ ๊ฐ ์๋ ๊ฒฝ์ฐ (์: 'g_0', 'g_0_0' ๋ฑ)\n };\n\n #getRootAncestorGroupId = (groupId) => {\n if (!groupId) return null;\n\n const parts = groupId.split('_'); // ์: ['g', '0', '1', '2']\n\n // ์ต์ํ 'g'์ ์ต์์ ๋ฒํธ(์: ['g', '0'])๊ฐ ์์ด์ผ ํจ\n if (parts.length > 2) {\n return parts.slice(0, 2).join('_'); // ํญ์ ['g', '0'] ํํ์ธ ์ต์์ ์กฐ์ ๋ฐํ\n }\n\n return groupId; // ์ด๋ฏธ ์ต์์์ด๊ฑฐ๋ ํ์์ด ๋ค๋ฅธ ๊ฒฝ์ฐ\n };\n\n #getAllAncestorGroupIds = (groupId) => {\n if (!groupId) return [];\n\n const parts = groupId.split('_'); // ์: ['g', '0', '1', '2']\n let ancestors = [];\n\n // 'g'๋ฅผ ์ ์ธํ๊ณ ์ต์์๋ถํฐ ๋ฐ๋ก ์ง์ ๋ถ๋ชจ๊น์ง ์กฐ์ ID๋ค์ ์์๋๋ก ์์ง\n // ์: 'g_0_1_2' -> ['g_0', 'g_0_1']\n for (let i = 2; i < parts.length; i++) {\n ancestors.push(parts.slice(0, i).join('_'));\n }\n\n return ancestors;\n };\n\n #getLastDescendantGroupIds = (groupId, allRenderItems) => {\n if (!groupId || !allRenderItems) return [];\n\n let descendantIds = [];\n let currentId = groupId;\n\n while (true) {\n const prefix = currentId + '_';\n const currentDepth = currentId.split('_').length;\n\n // 1. ํ์ฌ ๋์ค๋ณด๋ค ๋ฑ 1๋จ๊ณ ๊น์ ์ง์ ์์๋ค๋ง ์์ถ\n const children = allRenderItems.filter(item => {\n if (!item.groupId || item.type !== 'group') return false;\n if (!item.groupId.startsWith(prefix)) return false;\n return item.groupId.split('_').length === currentDepth + 1;\n });\n\n // 2. ๋ ์ด์ ์์์ด ์์ผ๋ฉด ํ์ ์ข
๋ฃ\n if (children.length === 0) {\n break;\n }\n\n // 3. ์์๋ค ์ค ๋ฒํธ๊ฐ ๊ฐ์ฅ ํฐ ๋
์(๋ง๋ด) ์ ํ\n children.sort((a, b) => {\n const partsA = a.groupId.split('_');\n const partsB = b.groupId.split('_');\n const valA = parseInt(partsA[partsA.length - 1], 10);\n const valB = parseInt(partsB[partsB.length - 1], 10);\n return valB - valA;\n });\n\n const youngestChildId = children[0].groupId;\n\n // 4. ์ฐพ์ ๋ง๋ด๋ฅผ ๋ฐฐ์ด์ ์ถ๊ฐ\n descendantIds.push(youngestChildId);\n\n // 5. ๊ทธ ๋ง๋ด๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ค์ ๋จ๊ณ(์์์ ์์) ํ์ ์งํ\n currentId = youngestChildId;\n }\n\n return descendantIds; // ๋ง๋ด๋ค์ ์ฒด์ธ ๋ฐฐ์ด ๋ฆฌํด\n };\n\n\n #getParentGroupIds = (renderedItems, allRenderItems) => {\n let headerGroupIds = [];\n\n const firstItem = renderedItems[0];\n if (!firstItem || !firstItem.groupId) return headerGroupIds;\n\n const parts = firstItem.groupId.split('_'); // ์: [\"g\", \"1\"] ๋๋ [\"g\", \"0\", \"1\"]\n\n if (firstItem.type === 'data') {\n // 1. ๋ฐ์ดํฐ ํ์ธ ๊ฒฝ์ฐ: ์กฐ์ ๊ทธ๋ฃน ID๋ค๋ง ์์๋๋ก ๋ชจ๋ ์์ง\n for (let i = 1; i < parts.length; i++) {\n headerGroupIds.push(parts.slice(0, i + 1).join('_'));\n }\n } else {\n // 2. ๊ทธ๋ฃน์ธ ๊ฒฝ์ฐ:\n // A. ๋์ ์ง์ ๋ถ๋ชจ/์กฐ์๋ค ์์ง (๋ง๋จ ๋ณธ์ธ ์ ์ธ)\n if (parts.length > 2) {\n for (let i = 1; i < parts.length - 1; i++) {\n //headerGroupIds.push(parts.slice(0, i + 1).join('_'));\n }\n }\n\n const rootGroupId = this.#getRootAncestorGroupId(firstItem.groupId);\n //const siblingGroupId = this.#getPreviousSiblingGroupId(rootGroupId);\n const siblingGroupId = this.#getPreviousSiblingGroupId(firstItem.groupId);\ntrace.log(firstItem.groupId, siblingGroupId);\n if (siblingGroupId) {\n // 1. ์กฐ์ ๋ฐฐ์ด๋ค์ 1์ฐจ์์ผ๋ก ํผ์ณ์ ์ถ๊ฐ\n headerGroupIds.push(...this.#getAllAncestorGroupIds(siblingGroupId));\n\n //trace.log(siblingGroupId, this.#getLastDescendantGroupIds(siblingGroupId, allRenderItems));\n // 2. ๋ฐ๋ก ์ํ์ ๋ณธ์ธ ์ถ๊ฐ\n headerGroupIds.push(siblingGroupId);\n // 3. ์ํ์ ์ ๋ง๋ด ํ์ ์ถ๊ฐ (allRenderItems ์ธ์ ์ ๋ฌ ํ์ ์ฌ๋ถ ํ์ธ)\n //const lastDescendant = this.#getLastDescendantGroupIds(siblingGroupId, allRenderItems);\n //trace.log(siblingGroupId, lastDescendant);\n headerGroupIds.push(...this.#getLastDescendantGroupIds(siblingGroupId, allRenderItems));\n\n }\n else {\n headerGroupIds.push(...this.#getAllAncestorGroupIds(firstItem.groupId));\n }\n\n }\n\n // โ [๋ฒ์ธ ์์ถ ์๋ฃ] renderedItems(๋ณธ๋ฌธ ํญ๋ชฉ๋ค)๋ฅผ ํค๋๋ก ๊ธ์ด๋ชจ์ผ๋ 3๋ฒ ๋ฃจํ๋ ์์ ํ ์ญ์ ํ์ต๋๋ค!\n // ํค๋๋ ์ค์ง ์์์ ๊ณ์ฐ๋ ์กฐ์๊ณผ ์ํ์ ์ฒด์ธ๋ง ๊ฐ์ง๋ฉด ์ถฉ๋ถํฉ๋๋ค.\n\n // 3. ์งง์ ์กฐ์๋ถํฐ ๊น์ ์์ ์์ผ๋ก ์ ๋ ฌ\n headerGroupIds.sort((a, b) => a.length - b.length || a.localeCompare(b));\n\n return headerGroupIds;\n };\n\n #isShouldHoldHeader = (renderedItems) => {\n\n return false;\n\n const $activeFooterTrs = Array.from(this.#sheet.querySelectorAll('thead.foot tr'))\n .filter(tr => tr.style.display !== 'none' && tr.dataset.groupId);\n\n const lastFooterTr = $activeFooterTrs[$activeFooterTrs.length - 1];\n const lastHeaderGroupId = lastFooterTr?.dataset.groupId;\n const lastHeaderDepth = lastHeaderGroupId ? lastHeaderGroupId.split(\"_\").length - 2 : -1;\n\n const firstItem = renderedItems[0];\n const isFirstItemGroup = firstItem.type === 'group';\n const firstItemDepth = isFirstItemGroup && firstItem.groupId\n ? firstItem.groupId.split(\"_\").length - 2\n : -1;\n\n // ์ ์ง ์กฐ๊ฑด: ๋ฐ์ดํฐ ํ์ด๊ฑฐ๋, ํค๋ ๋ง์ง๋ง ๋์ค๊ฐ ์ฒซ ํ ๋์ค๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ๋ ํ๋\n const shouldHoldHeader = !isFirstItemGroup || (lastHeaderDepth >= firstItemDepth);\n\n return shouldHoldHeader;\n };\n\n #findScrollTargetTrs = (renderedItems, allRenderItems) => {\n // 1. ํค๋์ ํ์ฌ ์ด์์๋(display: none์ด ์๋) ๋ชจ๋ footer tr ์ถ์ถ\n const $activeFooterTrs = Array.from(this.#sheet.querySelectorAll('.ng-container-body thead.foot tr'))\n .filter(tr => tr.style.display !== 'none' && tr.dataset.groupId);\n\n if ($activeFooterTrs.length === 0) return [];\n\n // 2. ๋ฐ๋์์ ํ์ฌ ํ๋ฉด์ ๋ณด์ด๋ ์ฒซ ๋ฒ์งธ ์ค๋ฌผ tr ์ฐพ๊ธฐ\n const $visibleTrs = Array.from(this.#sheet.querySelectorAll('.ng-container-body tbody.body tr'));\n const $firstRealTr = $visibleTrs.find(tr => tr.style.display !== 'none');\n\n if (!$firstRealTr) return [];\n\n // 3. ์คํฌ๋กค ์์น ๋ฐ ๋ฐ๋ ์ฒซ ํ๊ณผ์ ์ถฉ๋ ๊ฑฐ๋ฆฌ ๊ณ์ฐ\n const $theadFoot = this.#sheet.querySelector('.ng-container-body thead.foot');\n const footRect = $theadFoot.getBoundingClientRect();\n const trRect = $firstRealTr.getBoundingClientRect();\n const distance = Math.max(0, footRect.bottom - trRect.top);\n\n if (distance === 0) return []; // ์ถฉ๋ํ์ง ์์ผ๋ฉด ์์ง์ผ ํ์ ์์\n\n // 4. ์ด๋ค tr๋ค์ ๋ฐ์ด ์ฌ๋ ค์ผ ํ ์ง ํ๊ฒํ
\n // (์: ํ์ฌ ํค๋์ ์์ฌ ์๋ tr๋ค ์ค ๋ฐ๋ ์ฒซ ํ์ ๋์ค์ ๋ง๋ฌผ๋ฆฌ๊ฑฐ๋ ๋ฐ์ด๋ด์ผ ํ๋ ๋์ ํํฐ๋ง)\n const targets = [];\n\n for (const $tr of $activeFooterTrs) {\n const groupId = $tr.dataset.groupId;\n const headerItem = allRenderItems.find(item => item.groupId === groupId);\n if (!headerItem) continue;\n\n const headerDepth = headerItem.record[GROUP_IDX.DEPTH];\n const firstItem = renderedItems[0];\n const firstItemDepth = firstItem.type === 'group'\n ? firstItem.record[GROUP_IDX.DEPTH]\n : headerDepth;\n\n // ๋ฐ์ด ์ฌ๋ ค์ผ ํ๋ ์กฐ๊ฑด์ ํ๋ณ\n if (headerDepth >= firstItemDepth) {\n targets.push({\n tr: $tr,\n depth: headerDepth,\n distance: distance\n });\n\n //trace.log($tr);\n }\n }\n\n return targets;\n };\n\n #adjustHeaderGroup = (renderedItems, allRenderItems) => {\n const firstItem = renderedItems[0];\n\n const trs = this.#findScrollTargetTrs(renderedItems, allRenderItems);\n\n const $activeFooterTrs = Array.from(this.#sheet.querySelectorAll('.ng-container-body thead.foot tr'))\n .filter(tr => tr.style.display !== 'none' && tr.dataset.groupId);\n\n const lastFooterTr = $activeFooterTrs[$activeFooterTrs.length - 1];\n const lastHeaderGroupId = lastFooterTr?.dataset.groupId;\n const lastHeaderItem = lastHeaderGroupId ? allRenderItems.find(item => item.groupId === lastHeaderGroupId) : null;\n\n // ์ด๊ธฐํ: ๋ชจ๋ ํค๋์ transform ์ ๊ฑฐ\n this.#sheet.querySelectorAll('thead.foot tr').forEach(($tr) => {\n $tr.style.transform = ``;\n });\n\n if (lastHeaderItem && firstItem) {\n const lastHeaderDepth = lastHeaderItem.record[GROUP_IDX.DEPTH];\n const firstItemDepth = firstItem.type === 'group'\n ? firstItem.record[GROUP_IDX.DEPTH]\n : lastHeaderDepth;\n\n const $visibleTrs = Array.from(this.#sheet.querySelectorAll('.ng-container-body tbody.body tr'));\n const $firstRealTr = $visibleTrs.find(tr => tr.style.display !== 'none');\n\n if ($firstRealTr) {\n const targetSectionRowIndex = lastHeaderDepth;\n\n // ํค๋ ๋์ค๊ฐ ๋ฐ๋ ์ฒซ ๋ฒ์งธ ๋์ค๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ๊ณ ๊ฐ๋ฌธ์ด ๋ค๋ฅผ ๋ ๋ฐ์ด ์ฌ๋ฆผ\n if (lastHeaderDepth >= firstItemDepth) {\n const trRect = $firstRealTr.getBoundingClientRect();\n const $theadFoot = this.#sheet.querySelector('.ng-container-body thead.foot');\n const distance = Math.max(0, $theadFoot.getBoundingClientRect().bottom - trRect.top);\n //trace.log(distance)\n this.#sheet.querySelectorAll('thead.foot tr').forEach(($tr) => {\n if ($tr.sectionRowIndex === targetSectionRowIndex) {\n $tr.style.transform = `translateY(-${distance}px)`;\n }\n });\n }\n }\n }\n };\n\n #handleGroupedScroll = (scrollTop, force = false) => {\n\n //trace.log(scrollTop);\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const findItemByGroupId = (allRenderItems, targetGroupId) => {\n return allRenderItems.find(item => item.groupId === targetGroupId && item.type === 'group');\n };\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.template.length;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH];\n return this.#sheet.template.heights[depth];\n } else {\n const dataRowsHeight = this.#sheet.template.height - this.#sheet.template.group.height;\n return dataRowsHeight > 0 ? dataRowsHeight : this.#sheet.template.height;\n }\n };\n\n let sumHeight = 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 sumHeight += h;\n }\n\n const rawTotalVirtualHeight = Math.max(sumHeight - this.#sheet.viewport.height + this.#sheet.viewport.fixedHeight, 0);\n\n //trace.log(allRenderItems.length);\n //const rawTotalVirtualHeight = Math.max(sumHeight, 0);\n\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 const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n //const clampedScrollTop = Math.min(rawTotalVirtualHeight, rawTotalVirtualHeight);\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 > clampedScrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n const offsetY = clampedScrollTop - accumulatedHeight;\n //trace.log(offsetY, scrollTop, actualScrollTop, rawTotalVirtualHeight, clampedScrollTop, accumulatedHeight);\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody.body\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const targetEnd = Math.min(totalVirtualCount, startIndex + this.#sheet.viewport.tr.length);\n const renderedItems = allRenderItems.slice(startIndex, targetEnd);\n\n\n //trace.log(allRenderItems.length, renderedItems.length, rawTotalVirtualHeight, sumHeight, this.#sheet.viewport.height, this.#sheet.viewport.fixedHeight);\n //trace.log(renderedItems.length, allRenderItems.length, this.#cachedRowCount, totalVirtualCount, startIndex, this.#sheet.viewport.tr.length);\n\n\n if (renderedItems.length === 0) return;\n\n\n const headerGroupIds = [];//this.#getParentGroupIds(renderedItems, allRenderItems);\n\n const shouldHoldHeader = true;//this.#isShouldHoldHeader(renderedItems);\n\n //trace.log(renderedItems[0].groupId, headerGroupIds);\n\n if (!shouldHoldHeader) {\n ['.ng-container-left', '.ng-container-body', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n container.querySelectorAll('thead.foot tr').forEach(($tr, rowIndex) => {\n const targetGroupId = headerGroupIds[rowIndex];\n\n if (targetGroupId) {\n $tr.style.display = '';\n const targetGroup = allRenderItems.find(item => item.groupId === targetGroupId && item.type === 'group');\n if (targetGroup) {\n const actualIndex = allRenderItems.indexOf(targetGroup);\n this.#bindGroupRowData($tr, allRenderItems, targetGroup.record, actualIndex);\n }\n } else {\n $tr.style.display = 'none';\n }\n });\n });\n }\n\n\n const trueFirstItem = renderedItems.find(item => {\n // ๋ง์ฝ group ํ์
์ด๊ณ headerGroupIds์ ํฌํจ๋์ด ์๋ค๋ฉด ๋ณธ๋ฌธ์์ ์จ๊ฒจ์ง๋ฏ๋ก ์ ์ธ\n if (item.type === 'group' && headerGroupIds.includes(item.groupId)) {\n return false;\n }\n return true;\n });\n\n // ==========================================\n // ๐ก 2๋จ๊ณ: ๋ณธ๋ฌธ(tbody.body) ๋ ๋๋ง (๋ชจ๋ ์์ดํ
๋น ์ง์์ด ์ถ๋ ฅ)\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 let vIndex = startIndex;\n\n for (let i = 0; i < $tbody.trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = $tbody.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 tr.dataset.virtualIndex = vIndex;\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\n this.#bindGroupRowData(tr, allRenderItems, item.record, startIndex + itemIndex);\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 const rowid = item.record.m._[NINE_TABLE.META.INDEX.ROWID];\n this.#bindRowData(tr, item.record, rowid, startIndex + itemIndex);\n //if (subIdx === templateLength - 1) vIndex++;\n }\n }\n });\n }\n });\n\n //this.#adjustHeaderGroup(renderedItems, allRenderItems);\n /**\n const firstItem = trueFirstItem || renderedItems[0];\n const lastHeaderGroupId = headerGroupIds[headerGroupIds.length - 1];\n const lastHeaderItem = allRenderItems.find(item => item.groupId === lastHeaderGroupId);\n\n if (lastHeaderItem && firstItem) {\n const lastHeaderDepth = lastHeaderItem.record[GROUP_IDX.DEPTH];\n\n const firstItemDepth = firstItem.type === 'group'\n ? firstItem.record[GROUP_IDX.DEPTH]\n : lastHeaderDepth;\n\n const $visibleTrs = Array.from(this.#sheet.querySelectorAll('.ng-container-body tbody.body tr'));\n const $firstRealTr = $visibleTrs.find(tr => tr.style.display !== 'none');\n const sectionRowIndex = $firstRealTr.dataset.groupId?.split(\"_\").length - 2;\n\n if (lastHeaderDepth === firstItemDepth && lastHeaderItem.groupId !== firstItem.groupId) {\n const trRect = $firstRealTr.getBoundingClientRect();\n const $theadFoot = this.#sheet.querySelector('.ng-container-body thead.foot');\n const distance = $theadFoot.getBoundingClientRect().bottom - trRect.top;\n\n this.#sheet.querySelectorAll('thead.foot tr').forEach(($tr) => {\n if ($tr.sectionRowIndex === sectionRowIndex) {\n $tr.style.transform = `translateY(-${distance}px)`;\n }\n });\n } else {\n this.#sheet.querySelectorAll('thead.foot tr').forEach(($tr) => {\n $tr.style.transform = ``;\n });\n }\n }\n */\n this.#sheet.selection.refresh();\n };\n\n\n\n #handleGroupedScroll_BAK = (scrollTop, force = false) => {\n\n trace.log(scrollTop);\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const findItemByGroupId = (allRenderItems, targetGroupId) => {\n return allRenderItems.find(item => item.groupId === targetGroupId && item.type === 'group');\n };\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.template.length;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH];\n return this.#sheet.template.heights[depth];\n } else {\n const dataRowsHeight = this.#sheet.template.height - this.#sheet.template.group.height;\n return dataRowsHeight > 0 ? dataRowsHeight : this.#sheet.template.height;\n }\n };\n\n let sumHeight = 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 sumHeight += h;\n }\n\n //const rawTotalVirtualHeight = Math.max(sumHeight - this.#sheet.viewport.height + this.#sheet.viewport.fixedHeight, 0);\n\n const rawTotalVirtualHeight = Math.max(sumHeight, 0);\n\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 const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n //const clampedScrollTop = Math.min(rawTotalVirtualHeight, rawTotalVirtualHeight);\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 > clampedScrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n const offsetY = clampedScrollTop - accumulatedHeight;\n //trace.log(offsetY, scrollTop, actualScrollTop, rawTotalVirtualHeight, clampedScrollTop, accumulatedHeight);\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody.body\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const targetEnd = Math.min(totalVirtualCount, startIndex + this.#sheet.viewport.tr.length);\n const renderedItems = allRenderItems.slice(startIndex, targetEnd);\n\n\n //trace.log(allRenderItems.length, renderedItems.length, rawTotalVirtualHeight, sumHeight, this.#sheet.viewport.height, this.#sheet.viewport.fixedHeight);\n //trace.log(renderedItems.length, allRenderItems.length, this.#cachedRowCount, totalVirtualCount, startIndex, this.#sheet.viewport.tr.length);\n\n\n if (renderedItems.length === 0) return;\n\n // ==========================================\n // ๐ก 1๋จ๊ณ: thead.foot๋ก ์ฌ๋ฆด ์์ ๊ทธ๋ฃน ์์ดํ
์ ๋ณ (๋ชจ๋ ์์ ๋ถ๋ชจ ์์ ๋์ )\n // ==========================================\n let headerGroupIds = [];\n //const firstItem = renderedItems[0];\n const firstItemGroupId = renderedItems[0].groupId;\n const firstItemdepth = firstItemGroupId.split(\"_\").length - 2;\n\n trace.log(firstItemGroupId, firstItemdepth);\n\n if (firstItemGroupId) {\n const parts = firstItemGroupId.split('_'); // ์: [\"g\", \"1\", \"0\"]\n let ids = [];\n\n if (renderedItems[0].type === 'group') {\n // 2. ๊ทธ๋ฃน ํ์ธ ๊ฒฝ์ฐ: ๋ถ๋ชจ ์กฐ์๋ค + (์ํ์ ๊ฐ ์กด์ฌํ ๋๋ง ๋ฐ๋ก ์ํ์ ์ถ๊ฐ)\n\n // A. ๋ถ๋ชจ ์กฐ์๋ค ์์ง (๋ง์ง๋ง ๋ง๋จ ๊ทธ๋ฃน ์ ์ธ)\n if (parts.length > 2) {\n for (let i = 1; i < parts.length - 1; i++) {\n ids.push(parts.slice(0, i + 1).join('_'));\n }\n }\n\n // B. ๋ง๋จ ๊ทธ๋ฃน์ ์ํ์ ์ฒ๋ฆฌ\n const lastIdx = parts.length - 1;\n const lastVal = parseInt(parts[lastIdx], 10);\n\n // ๐ก ํต์ฌ: lastVal์ด 0๋ณด๋ค ํด ๋๋ง ์ํ์ (lastVal - 1) ์กด์ฌํจ!\n // 0์ธ ๊ฒฝ์ฐ(์ฒซ ๋ฒ์งธ ๊ทธ๋ฃน ๋๋ ์ฒซ์งธ ์์)๋ ์ํ์ ๊ฐ ์์ผ๋ฏ๋ก ์๋ฌด๊ฒ๋ ์ถ๊ฐํ์ง ์์ (g_0 ์ฌ๋จ ๋ฐฉ์ง)\n if (lastVal > 0) {\n let siblingParts = [...parts];\n siblingParts[lastIdx] = lastVal - 1;\n ids.push(siblingParts.join('_'));\n }\n } else {\n // type์ด data์ธ ๊ฒฝ์ฐ: groupId ์์ฒด๊ฐ ์กฐ์๋ค ์ฒด์ธ\n ids = parts.map((_, index) => parts.slice(0, index + 1).join('_')).slice(1);\n }\n\n headerGroupIds = ids;\n }\n\n //trace.log(headerGroupIds);\n\n for (const item of renderedItems) {\n\n const itemDepth = item.groupId.split(\"_\").length - 2;\n //firstItemGroupId\n trace.log(firstItemdepth, itemDepth);\n if (firstItemdepth >= itemDepth) break;\n\n if (item.type === 'group') {\n if (item.groupId && !headerGroupIds.includes(item.groupId)) {\n headerGroupIds.push(item.groupId);\n }\n } else {\n break; // ๋ฐ์ดํฐ ํ์ ๋ง๋๋ฉด ์ค๋จ\n }\n }\n\n\n if (headerGroupIds.length === 0) {\n for (const item of renderedItems) {\n const itemDepth = item.groupId.split(\"_\") - 1;\n\n if (item.type === 'group') {\n if (item.groupId && !headerGroupIds.includes(item.groupId)) {\n headerGroupIds.push(item.groupId);\n }\n } else {\n break; // ๋ฐ์ดํฐ ํ์ ๋ง๋๋ฉด ์ค๋จ\n }\n }\n }\n\n trace.log(headerGroupIds);\n\n // ๐ก thead.foot์ ์ฌ๋ผ๊ฐ์ ๋ณธ๋ฌธ์์ ์จ๊ฒจ์ง(excluded) ์์ดํ
๋ค์ ์ ์ธํ๊ณ ,\n // ์ฌ์ฉ์ ๋์ ์ค์ ๋ก ๋งจ ์ฒ์์ ๋ณด์ด๋ '์ง์ง ์ฒซ ๋ฒ์งธ ์์ดํ
'์ ์ฐพ์ต๋๋ค.\n const trueFirstItem = renderedItems.find(item => {\n // ๋ง์ฝ group ํ์
์ด๊ณ headerGroupIds์ ํฌํจ๋์ด ์๋ค๋ฉด ๋ณธ๋ฌธ์์ ์จ๊ฒจ์ง๋ฏ๋ก ์ ์ธ\n if (item.type === 'group' && headerGroupIds.includes(item.groupId)) {\n return false;\n }\n return true;\n });\n\n\n ['.ng-container-left', '.ng-container-body', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n container.querySelectorAll('thead.foot tr').forEach(($tr, rowIndex) => {\n const targetGroupId = headerGroupIds[rowIndex];\n\n if (targetGroupId) {\n $tr.style.display = '';\n const targetGroup = allRenderItems.find(item => item.groupId === targetGroupId && item.type === 'group');\n if (targetGroup) {\n const actualIndex = allRenderItems.indexOf(targetGroup);\n this.#bindGroupRowData($tr, allRenderItems, targetGroup.record, actualIndex);\n }\n } else {\n $tr.style.display = 'none';\n }\n });\n });\n\n // ==========================================\n // ๐ก 2๋จ๊ณ: ๋ณธ๋ฌธ(tbody.body) ๋ ๋๋ง (๋ชจ๋ ์์ดํ
๋น ์ง์์ด ์ถ๋ ฅ)\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 let vIndex = startIndex;\n\n for (let i = 0; i < $tbody.trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = $tbody.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 tr.dataset.virtualIndex = vIndex;\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\n this.#bindGroupRowData(tr, allRenderItems, item.record, startIndex + itemIndex);\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 const rowid = item.record.m._[NINE_TABLE.META.INDEX.ROWID];\n this.#bindRowData(tr, item.record, rowid, startIndex + itemIndex);\n //if (subIdx === templateLength - 1) vIndex++;\n }\n }\n });\n }\n });\n\n const firstItem = trueFirstItem || renderedItems[0];\n const lastHeaderGroupId = headerGroupIds[headerGroupIds.length - 1];\n const lastHeaderItem = allRenderItems.find(item => item.groupId === lastHeaderGroupId);\n\n if (lastHeaderItem && firstItem) {\n const lastHeaderDepth = lastHeaderItem.record[GROUP_IDX.DEPTH];\n\n const firstItemDepth = firstItem.type === 'group'\n ? firstItem.record[GROUP_IDX.DEPTH]\n : lastHeaderDepth;\n\n const $visibleTrs = Array.from(this.#sheet.querySelectorAll('.ng-container-body tbody.body tr'));\n const $firstRealTr = $visibleTrs.find(tr => tr.style.display !== 'none');\n const sectionRowIndex = $firstRealTr.dataset.groupId?.split(\"_\").length - 2;\n\n if (lastHeaderDepth === firstItemDepth && lastHeaderItem.groupId !== firstItem.groupId) {\n const trRect = $firstRealTr.getBoundingClientRect();\n const $theadFoot = this.#sheet.querySelector('.ng-container-body thead.foot');\n const distance = $theadFoot.getBoundingClientRect().bottom - trRect.top;\n\n this.#sheet.querySelectorAll('thead.foot tr').forEach(($tr) => {\n if ($tr.sectionRowIndex === sectionRowIndex) {\n $tr.style.transform = `translateY(-${distance}px)`;\n }\n });\n } else {\n this.#sheet.querySelectorAll('thead.foot tr').forEach(($tr) => {\n $tr.style.transform = ``;\n });\n }\n }\n\n this.#sheet.selection.refresh();\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 #bindGroupRowData = ($tr, allRenderItems, groupRecord, virtualIndex) => {\n\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (virtualIndex * templateLength) + subRowIndex;\n\n //trace.log(matrixRow);\n\n const indices = groupRecord[GROUP_IDX.CHILDREN];\n //const allRecords = this.#host.data.getArray();\n //trace.log(this.#chchedAllRecords, indices);\n const childrenRecords = indices ? indices.map(idx => this.#chchedAllRecords[idx]).filter(Boolean) : [];\n\n $tr.dataset.virtualIndex = virtualIndex;\n $tr.dataset.index = 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 Array.from($tr.cells).forEach(($cell) => {\n $cell.dataset.index = virtualIndex;\n $cell.dataset.row = virtualIndex;\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 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 //trace.log(\"this.#sheetHeight\", this.#sheetHeight, this.#sheet);\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', (e) => {\n\n this.#sheet.querySelectorAll(\"cell-combo-panel\").forEach($el => {\n $el.classList.remove('active');\n });\n\n\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#sheet.template.height || 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 const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\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 const MAX_BROWSER_HEIGHT = 15000000;\n\n if (this.#isGrouped) {\n const allRenderItems = this.#sheet.view.getArray() || [];\n const templateTrs = Array.from(this.#sheet.sourceTable?.querySelectorAll('tbody.body tr') || []);\n const templateLength = templateTrs.length || 1;\n\n let accumulatedHeight = 0;\n let currentDataCount = 0;\n\n // 1. ์ ์ฒด ๊ฐ์ ๋์ด(rawTotalVirtualHeight)๋ฅผ ๊ตฌํ๊ธฐ ์ํ ์ ์ฒด ๋์ด ์ธก์ ๋๋ targetRow๊น์ง์ ๋์ ๋์ด\n // ๐ก ์ฃผ์: scaleFactor๋ฅผ ์ ํํ ๊ตฌํ๋ ค๋ฉด \"์ ์ฒด ์ฝํ
์ธ ์ ์ด ๋์ด\"๊ฐ ํ์ํ๋ฏ๋ก\n // ์ ์ฒด ๋ทฐ ์์ดํ
๋ค์ ์ด ๋์ด๋ฅผ ๋จผ์ ๊ตฌํ๊ฑฐ๋ ๋์ ํด์ผ ํฉ๋๋ค.\n let totalGroupVirtualHeight = 0;\n let targetAccumulatedHeight = 0;\n\n for (let i = 0; i < targetRow; i++) {\n const item = allRenderItems[i];\n\n let itemTotalHeight = 0;\n for (let subIdx = 0; subIdx < templateLength; subIdx++) {\n const tmplTr = templateTrs[subIdx];\n if (!tmplTr) continue;\n\n const isTrGroup = tmplTr.getAttribute('grouping') === 'true';\n let isVisible = false;\n\n if (item.type === 'group') {\n if (isTrGroup) {\n const depth = item.record[GROUP_IDX.DEPTH];\n if (subIdx === depth) isVisible = true;\n }\n } else {\n if (!isTrGroup) isVisible = true;\n }\n\n if (isVisible) {\n if (isTrGroup) {\n const depth = item.record[GROUP_IDX.DEPTH];\n itemTotalHeight += this.#sheet.template.group.heights[depth];\n } else {\n const dataRowsHeight = this.#sheet.template.height - this.#sheet.template.group.height;\n itemTotalHeight += (this.#sheet.template.height - this.#sheet.template.group.height) / (this.#sheet.template.length - this.#sheet.template.group.length);\n }\n }\n }\n\n if (item.type === 'data') {\n if (currentDataCount === targetRow) {\n targetAccumulatedHeight = totalGroupVirtualHeight;\n }\n currentDataCount++;\n }\n\n totalGroupVirtualHeight += itemTotalHeight;\n }\n\n // ๋ง์ฝ targetRow๊ฐ ๋ง์ง๋ง ์ธ๋ฑ์ค์ด๊ฑฐ๋ ํ๋ค๋ฉด ๋ณด์ \n if (currentDataCount <= targetRow) {\n targetAccumulatedHeight = totalGroupVirtualHeight;\n }\n\n // 2. ์ค์ผ์ผ๋ง ์ ์ฉ (MAX_BROWSER_HEIGHT ์ด๊ณผ ์ ์์ถ)\n const useScaling = totalGroupVirtualHeight > MAX_BROWSER_HEIGHT;\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / totalGroupVirtualHeight;\n }\n\n targetScrollTop = Math.max(0, targetAccumulatedHeight * scaleFactor);\n\n } else {\n const rowHeight = this.#sheet.template.height;\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 - rowHeight + fixedHeight - viewHeight - rowHeight, 0);\n\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 this.#updateRowCount();\n return;\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-container-body tbody.body');\n if (!$tbody) return;\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 renderedTrs.forEach(tr => tr.remove());\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n\n if (this.#sheet.viewport.innerHeight > 0 && this.#sheet.template.height > 0) {\n const visibleRows = Math.ceil(this.#sheet.viewport.innerHeight / (this.#sheet.template.height - this.#sheet.template.group.height));\n\n let dynamicBuffer = this.#BUFFER_ROW_COUNT;\n if (this.#isGrouped) {\n const groupRows = Math.ceil(this.#sheet.viewport.innerHeight / this.#sheet.template.group.height) + this.#BUFFER_ROW_COUNT;\n dynamicBuffer += (this.#sheet.viewport.group.length * groupRows);\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\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\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 targetTbody.appendChild(fragment);\n\n /****\n */\n const fragment2 = document.createDocumentFragment();\n let trIndex = 0;\n\n// ์ ์ฒด grouping tr ๊ฐ์ ๋ฏธ๋ฆฌ ํ์
(์ญ์ z-index ๋ถ์ฌ๋ฅผ ์ํด)\n const groupingTrs = templateTrs.filter(tmpl => tmpl.getAttribute(\"grouping\") === \"true\");\n const totalGroupingCount = groupingTrs.length;\n\n templateTrs.forEach(tmpl => {\n if (tmpl.getAttribute(\"grouping\") === \"true\") {\n const $clonedTr = tmpl.cloneNode(true);\n\n $clonedTr.style.position = 'relative';\n // ๐ก ํต์ฌ: ์๋๋ก ๋ด๋ ค์ฌ์๋ก z-index๊ฐ ์์์ง๋๋ก ์ค์ (๋๋ถ๋ฅ๊ฐ ๊ฐ์ฅ ์!)\n // ์: 3๋จ ๊ตฌ์กฐ๋ฉด ์ฒซ ๋ฒ์งธ ํ z-index: 30, ๋ ๋ฒ์งธ ํ: 20, ์ธ ๋ฒ์งธ ํ: 10\n $clonedTr.style.zIndex = (totalGroupingCount - trIndex) * 10;\n\n fragment2.appendChild($clonedTr);\n trIndex++;\n }\n });\n\n const thead = container.querySelector('thead.foot');\n if (thead) {\n thead.querySelectorAll(\"tr\").forEach(tr => tr.remove());\n thead.appendChild(fragment2);\n }\n\n\n if (container.classList.contains('ng-container-body')) {\n this.#element.firstTr = targetTbody.querySelector('tr');\n }\n\n targetTbody.trs = Array.from(container.querySelectorAll('tbody.body tr'));\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 //trace.log(\"this.#sheetHeight\", this.#sheetHeight);\n this.#updateRowCount();\n\n if (this.#sheet.template.height !== 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\";\n\nexport class CellSelection {\n\t#sheet;\n\t#host;\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tthis.#initEvents();\n\t}\n\n\t#getMatrixRow(tr) {\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\n\n\t\tconst dataRow = parseInt(tr.dataset.index, 10);\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\n\n\t\tconst tbody = tr.closest('tbody');\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr'));\n\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.index, 10) === dataRow);\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\n\n\t\t//const matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\n\t\t//const matrixRow = (dataRow * this.#sheet.template.length) + subRowIndex;//(subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % this.#sheet.template.length));\n\t\tconst matrixRow = parseInt(tr.dataset.matrixRow, 10);\n\n\t\treturn { dataRow, subRowIndex, matrixRow };\n\t}\n\n\tsetFocus(matrixRow, col) {\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {\n\t\t\t$tr.classList.remove(\"selected-start\");\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {\n\t\t\t\t$td.classList.remove(\"selected-start\");\n\t\t\t});\n\t\t});\n\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\n\t\tif (!$td) return;\n\n\t\t$td.classList.add(\"selected-start\");\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\n\t}\n\n\tsetRange(startRow, startCol, endRow, endCol) {\n\t\tlet r1 = Math.min(startRow, endRow);\n\t\tlet r2 = Math.max(startRow, endRow);\n\t\tlet c1 = Math.min(startCol, endCol);\n\t\tlet c2 = Math.max(startCol, endCol);\n\n\n\n\t\tif (this.#host.tagName === \"NINE-TABLE-SIMPLE\") {\n\t\t\tc1 = 1;\n\t\t\tc2 = 10;\n\t\t}\n\n\n\n\t\tconst containers = this.#sheet.querySelectorAll('.ng-container-left, .ng-container-body, .ng-container-right');\n\n\t\tlet expanded = true;\n\t\tlet loopCount = 0;\n\n\t\twhile (expanded && loopCount < 5) {\n\t\t\texpanded = false;\n\t\t\tloopCount++;\n\n\t\t\tcontainers.forEach(container => {\n\n\t\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\n\t\t\t\t\treturn tr.style.display !== 'none'; // ํน์ tr.offsetHeight > 0 ์ฒดํฌ\n\t\t\t\t});\n\n\t\t\t\tvisibleTrs.forEach(tr => {\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\n\t\t\t\t\tif (matrixRow < 0) return;\n\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\n\t\t\t\t\t\tif (isNaN(col)) return;\n\n\t\t\t\t\t\tconst colEl = this.#sheet.querySelector(`col[data-col=\"${col}\"]`);\n\t\t\t\t\t\tif (colEl.style.display !== 'none') {\n\t\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\n\t\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\n\n\t\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\n\t\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\n\n\t\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\n\n\t\t\t\t\t\t\tif (isIntersecting) {\n\t\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\n\t\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\n\t\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\n\t\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\n\n\t\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\n\t\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\n\t\t\t\t\t\t\t\t\texpanded = true;\n\t\t\t\t\t\t\t\t}\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\tconst sanitize = (val) => (!Number.isFinite(val) ? -1 : val);\n\n\t\tthis.#range = {\n\t\t\tstartRow: sanitize(r1),\n\t\t\tstartCol: sanitize(c1),\n\t\t\tendRow: sanitize(r2),\n\t\t\tendCol: sanitize(c2)\n\t\t};\n\n\n\n\t\t//trace.log(this.#range);\n\n\t\tthis.render();\n\t}\n\n\tclear = () => {\n\t\tthis.#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\n\t};\n\n\tget minRow() {\n\t\treturn this.#range.startRow;\n\t};\n\tget maxRow() {\n\t\treturn this.#range.endRow;\n\t};\n\tget minCol() {\n\t\treturn this.#range.startCol;\n\t};\n\tget maxCol() {\n\t\treturn this.#range.endCol;\n\t};\n\n\trefresh = () => {\n\t\tthis.render();\n\t}\n\n\trender = () => {\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\n\n\t\tconst containers = this.#sheet.querySelectorAll(\n\t\t\t'.ng-container-left, .ng-container-body, .ng-container-right'\n\t\t);\n\n\t\tcontainers.forEach(container => {\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\n\t\t\t});\n\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\n\t\t\t\ttr.classList.remove('selected-start');\n\t\t\t});\n\t\t});\n\n\n\t\tif (startRow < 0 || startCol < 0) return;\n\n\t\tcontainers.forEach((container) => {\n\t\t\tconst visibleTrs = Array.from(container.querySelectorAll('tbody tr')).filter(tr => {\n\t\t\t\treturn tr.style.display !== 'none';\n\t\t\t});\n\n\t\t\tvisibleTrs.forEach(tr => {\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\n\n\t\t\t\t//trace.log(tr.dataset.matrixRow);\n\n\t\t\t\tif (matrixRow < 0) return;\n\n\t\t\t\t//trace.log(matrixRow, this.#range, startRow, endRow);\n\n\t\t\t\tif (matrixRow >= startRow && matrixRow <= endRow) {\n\n\n\t\t\t\t\tcontainer.querySelectorAll(`tbody tr[data-index=\"${tr.dataset.index}\"]`).forEach(tr => {\n\t\t\t\t\t\ttr.classList.add('selected');\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t//trace.log(this.#sheet.view);\n\n\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\n\t\t\t\t\tif (isNaN(col)) return;\n\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\n\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\n\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\n\t\t\t\t\tif (!isSelected) return;\n\n\t\t\t\t\tcell.classList.add('selected');\n\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t}\n\n\t#lastMatrixRow;\n\t#lastCol;\n\t#startRow;\n\t#startCol;\n\t//#dragStart;\n\n\t#getCellFromPoint = (clientX, clientY) => {\n\t\tconst root = this.#sheet.getRootNode();\n\t\tif (root && typeof root.elementsFromPoint === 'function') {\n\t\t\tconst elements = root.elementsFromPoint(clientX, clientY);\n\t\t\tfor (const el of elements) {\n\t\t\t\tconst c = el.closest('td, th');\n\t\t\t\tif (c && this.#sheet.contains(c) && c.dataset.row !== undefined) {\n\t\t\t\t\treturn c;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr td, .ng-sheet-body-content tbody tr:not(.nodata) th');\n\t\tfor (const c of allCells) {\n\t\t\tconst rect = c.getBoundingClientRect();\n\t\t\tif (\n\t\t\t\tclientX >= rect.left &&\n\t\t\t\tclientX <= rect.right &&\n\t\t\t\tclientY >= rect.top &&\n\t\t\t\tclientY <= rect.bottom\n\t\t\t) {\n\t\t\t\treturn c;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t};\n\n\t#onMouseMove = (moveEvent) => {\n\n\t\t//if (!this.#dragStart) return;\n\n\t\tconst targetCell = this.#getCellFromPoint(moveEvent.clientX, moveEvent.clientY);\n\t\tif (!targetCell) return;\n\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\n\n\t\tconst targetTr = targetCell.closest('tr');\n\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\n\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\n\n\t\tif (endRow < 0) return;\n\t\tif (this.#lastMatrixRow === endRow && this.#lastCol === endCol) return;\n\n\t\t//trace.log(moveEvent);\n\n\t\tthis.#lastMatrixRow = endRow;\n\t\tthis.#lastCol = endCol;\n\n\t\t//trace.log(this.#startRow, this.#startCol, endRow, endCol);\n\n\t\tthis.setRange(this.#startRow, this.#startCol, endRow, endCol);\n\t};\n\n\t#onMouseUp = () => {\n\t\t//this.#dragStart = false;\n\n\t\tdocument.removeEventListener('mousemove', this.#onMouseMove);\n\n\t\t//this.#sheet.style.userSelect = '';\n\t\t//this.#sheet.style.webkitUserSelect = '';\n\n\n\t\t//document.removeEventListener('mouseup', this.#onMouseUp);\n\t};\n\n\t#initEvents() {\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\n\t\tif (!mainZone) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocument.addEventListener('mouseup', this.#onMouseUp);\n\n\t\tmainZone.addEventListener('mousedown', (e) => {\n\n\t\t\tif (e.button !== 0) return;\n\n\t\t\t/**\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#dragStart = true;\n\t\t\t}, 100);\n\t\t\t*/\n\n\t\t\tconst cell = e.target.closest('td, th');\n\t\t\tif (!cell) return;\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\n\n\t\t\tthis.#sheet.style.userSelect = 'none';\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\n\n\t\t\tconst tr = cell.closest('tr');\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\n\n\t\t\tthis.#startRow = startRow;\n\t\t\tthis.#startCol = startCol;\n\n\t\t\tif (startRow < 0) {\n\t\t\t\tthis.#sheet.style.userSelect = '';\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.setFocus(startRow, startCol);\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\n\n\t\t\tthis.#lastMatrixRow = startRow;\n\t\t\tthis.#lastCol = startCol;\n\n\t\t\t// ๋๋๊ทธ๊ฐ ์์๋ ๋๋ง document์ move/up ๋ฆฌ์ค๋๋ฅผ ๋ถ์ฌ ๋ญ๋น๋ฅผ ์ค์ด๊ณ ํ์คํ๊ฒ ์ถ์ \n\t\t\tdocument.addEventListener('mousemove', this.#onMouseMove);\n\t\t});\n\t}\n}","import { trace } from \"@nopeer\";\n\nexport class CellNavigation {\n\t#sheet;\n\t#host;\n\n\t#currentCell = null;\n\t#currentTr = null;\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tthis.#initEvents();\n\t}\n\n\tget currentCell() {\n\t\treturn this.#currentCell;\n\t}\n\n\tset currentCell(cell) {\n\t\tif (!cell) return;\n\n\t\tthis.#currentCell = cell;\n\t\tcell.focus({ preventScroll: true });\n\n\t\tthis.#currentTr = cell.closest(\"tr\");\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\n\t}\n\n\n\t#moveCellH = (e, cell) => {\n\n\t\tif (!cell) return;\n\n\t\tswitch (e.code) {\n\t\t\tcase \"Tab\":\n\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!this.#isCellRightVisible(cell)) {\n\t\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowRight\":\n\t\t\t\tif (!this.#isCellRightVisible(cell) || !this.#isCellLeftVisible(cell)) {\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowLeft\":\n\t\t\t\tif (!this.#isCellLeftVisible(cell)) {\n\t\t\t\t\tcell.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tthis.currentCell = cell;\n\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\n\t};\n\n\t#moveCellV = (e, cell) => {\n\t\t// 1. ๋ง์ฝ ๋ค์ ์ด๋ํ ์
์ด ์ด๋ฏธ DOM์ ์กด์ฌํ๋ค๋ฉด\n\t\tif (cell) {\n\t\t\tlet isVisible = false;\n\t\t\tswitch (e.code) {\n\t\t\t\tcase \"Enter\":\n\t\t\t\tcase \"ArrowDown\":\n\t\t\t\t\tif (this.#isCellBelowVisible(cell)) isVisible = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ArrowUp\":\n\t\t\t\t\tif (this.#isCellAboveVisible(cell)) isVisible = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// ํ๋ฉด ์ ์์ญ์ ์๋ค๋ฉด ๊ฐ๋ณ๊ฒ ํฌ์ปค์ค ๋ฐ ์ ํ ๋ฒ์ ์ง์ ํ ๋ฆฌํด\n\t\t\tif (isVisible) {\n\t\t\t\tthis.currentCell = cell;\n\t\t\t\tthis.#sheet.selection.setRange(this.#currentTr.dataset.matrixRow, cell.dataset.col, this.#currentTr.dataset.matrixRow, cell.dataset.col);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// 2. ์
์ด ํ๋ฉด์ ์๊ฑฐ๋ ์๋ ค ์๋ค๋ฉด(๋ทฐํฌํธ ๋ฐ),\n\t\t// ํ์ฌ ์
(๋๋ ๋์ ์
)๊ณผ .ng-sheet-body์ ์๋์ ์์น(top) ์ฐจ์ด๋ฅผ ์ด์ฉํด scrollTop์ ์ง์ ์กฐ์ \n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\t\tif (!bodyViewport) return;\n\n\t\t// ๋ง์ฝ nextCell์ด ์กด์ฌํ๋ฉด ๊ทธ ์
์ ๊ธฐ์ค์ผ๋ก, ์๋๋ฉด ํ์ฌ ์
๊ธฐ์ค์ผ๋ก ๊ณ์ฐ\n\t\tconst targetCell = cell || this.#currentCell;\n\t\tif (!targetCell) return;\n\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\n\t\tconst cellRect = targetCell.getBoundingClientRect();\n\t\tconst theadHeight = bodyViewport.querySelector('thead')?.offsetHeight || 0;\n\n\t\tlet delta = 0;\n\n\t\tswitch (e.code) {\n\t\t\tcase \"Enter\":\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tdelta = (cellRect.top - cellRect.height) - (viewportRect.top + theadHeight);\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowUp\":\n\t\t\t\tdelta = (cellRect.bottom + cellRect.height) - (viewportRect.bottom);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst targetMatrixRow = cell ? parseInt(cell.closest(\"tr\")?.dataset.matrixRow, 10) : parseInt(this.#currentTr.dataset.matrixRow, 10);\n\t\tconst targetCol = cell ? parseInt(cell.dataset.col, 10) : parseInt(this.#currentCell.dataset.col, 10);\n\n\t\tif (delta !== 0) {\n\t\t\tbodyViewport.scrollTop += delta;\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tconst foundCell = this.#findCell(targetMatrixRow, targetCol);\n\t\t\tif (foundCell) {\n\t\t\t\tthis.currentCell = foundCell;\n\t\t\t\tconst targetTr = foundCell.closest(\"tr\");\n\t\t\t\tif (targetTr) {\n\t\t\t\t\tthis.#sheet.selection.setRange(targetTr.dataset.matrixRow, foundCell.dataset.col, targetTr.dataset.matrixRow, foundCell.dataset.col);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tmoveCell = (e) => {\n\n\t\tif (e.target.tagName === \"INPUT\") {\n\t\t\tif ([\"text\"].includes(e.target.type)) {\n\t\t\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Home\",\"End\"].includes(e.code)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ([\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(e.target.type)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (!this.#currentCell || !this.#currentTr) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet nextCell;\n\t\tswitch (e.code) {\n\t\t\tcase \"Tab\":\n\t\t\t\tnextCell = e.shiftKey ? this.#getPreviousCell() : this.#getNextCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowRight\":\n\t\t\t\tnextCell = this.#getNextCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowLeft\":\n\t\t\t\tnextCell = this.#getPreviousCell();\n\t\t\t\tbreak;\n\t\t\tcase \"Enter\":\n\t\t\t\tnextCell = e.shiftKey ? this.#getUpCell() : this.#getDownCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tnextCell = this.#getDownCell();\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowUp\":\n\t\t\t\tnextCell = this.#getUpCell();\n\t\t\t\tbreak;\n\t\t}\n\n\t\te.preventDefault();\n\n\t\tif ([\"ArrowLeft\",\"ArrowRight\",\"Tab\"].includes(e.code)) {\n\t\t\tthis.#moveCellH(e, nextCell);\n\t\t}\n\t\telse if ([\"Enter\",\"ArrowUp\",\"ArrowDown\"].includes(e.code)) {\n\t\t\tthis.#moveCellV(e, nextCell);\n\t\t}\n\t}\n\n\t#getNextCell = () => {\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst colSpan = parseInt(this.#currentCell.colSpan, 10) || 1;\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\tconst nextCol = col + colSpan;\n\n\t\tlet nextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${nextCol}\"]`);\n\t\tif (!nextCell) {\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${nextCol}\"]`);\n\t\t}\n\n\t\treturn nextCell;\n\t}\n\n\t#getPreviousCell = () => {\n\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst dataIndex = parseInt(this.#currentTr.dataset.index, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\tlet nextCell;\n\t\tfor (let i = col - 1; i >= 0; i--) {\n\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${i}\"]`);\n\t\t\tif (!nextCell) {\n\t\t\t\tnextCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${i}\"]`);\n\t\t\t}\n\n\t\t\tif (nextCell) break;\n\t\t}\n\n\t\treturn nextCell;\n\t}\n\n\n\n\t#findCell = (matrixRow, col) => {\n\n\t\tconst $tr = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"]`);\n\n\t\tif (!$tr) return;\n\n\n\n\t\tconst dataIndex = parseInt($tr.dataset.index, 10);\n\n\n\n\t\tlet targetCell = this.#sheet.querySelector(`tbody tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\n\t\tif (!targetCell) {\n\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-matrix-row=\"${matrixRow}\"] td`).forEach($cell => {\n\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\n\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\n\n\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\n\t\t\t\t\ttargetCell = $cell;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!targetCell) {\n\t\t\t\ttargetCell = this.#sheet.querySelector(`tbody tr[data-index=\"${dataIndex}\"] td[data-col=\"${col}\"]`);\n\n\t\t\t\tif (!targetCell) {\n\t\t\t\t\tthis.#sheet.querySelectorAll(`tbody tr[data-index=\"${dataIndex}\"] td`).forEach($cell => {\n\t\t\t\t\t\tconst cellCol = parseInt($cell.dataset.col, 10);\n\t\t\t\t\t\tconst colSpan = parseInt($cell.colSpan, 10) || 1;\n\n\t\t\t\t\t\tif (col >= cellCol && col < cellCol + colSpan) {\n\t\t\t\t\t\t\ttargetCell = $cell;\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\treturn targetCell;\n\t}\n\n\t#getUpCell = () => {\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\n\t\tlet $nextCell = null\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\t$nextCell = this.#findCell(matrixRow - 1 - i, col);\n\t\t\tif ($nextCell) break;\n\t\t}\n\n\t\treturn $nextCell;// this.#findCell(matrixRow + rowSpan, col);\n\n\t\t//return this.#findCell(matrixRow - 1, col);\n\t}\n\n\t#getDownCell = () => {\n\t\tconst col = parseInt(this.#currentCell.dataset.col, 10);\n\t\tconst matrixRow = parseInt(this.#currentTr.dataset.matrixRow, 10);\n\t\tconst rowSpan = parseInt(this.#currentCell.rowSpan, 10) || 1;\n\n\t\tlet $nextCell = null\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\t$nextCell = this.#findCell(matrixRow + rowSpan + i, col);\n\t\t\tif ($nextCell) break;\n\t\t}\n\n\t\treturn $nextCell;// this.#findCell(matrixRow + rowSpan, col);\n\t}\n\n\t// 1. ์์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport)\n\t#isCellAboveVisible = (cell) => {\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\t\tif (!bodyViewport || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\n\t\tconst theadHeight = bodyViewport.querySelector('thead')?.offsetHeight || 0;\n\n\t\t// ์
์ ์๋จ์ด ํค๋ ์๋์ชฝ๋ณด๋ค ์์ ์์ผ๋ฉด ์๋ฆฐ(์ ๋ณด์ด๋) ์ํ\n\t\treturn cellRect.top >= (viewportRect.top + theadHeight);\n\t}\n\n\t// 2. ์๋์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport)\n\t#isCellBelowVisible = (cell) => {\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\t\tif (!bodyViewport || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\n\n\t\t// ์
์ ํ๋จ์ด ๋ทฐํฌํธ ํ๋จ๋ณด๋ค ์๋์ ์์ผ๋ฉด ์๋ฆฐ ์ํ\n\t\treturn cellRect.bottom <= viewportRect.bottom;\n\t}\n\n\t// 3. ์ผ์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport2)\n\t#isCellLeftVisible = (cell) => {\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body'); // ๋๋ ์ข์ฐ ์คํฌ๋กค์ ๋ด๋นํ๋ ๋ทฐํฌํธ\n\t\tif (!bodyViewport2 || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\n\n\t\t// ์
์ ์ข์ธก์ด ๋ทฐํฌํธ ์ข์ธก๋ณด๋ค ์ผ์ชฝ์ ์์ผ๋ฉด ์๋ฆฐ ์ํ\n\t\treturn cellRect.left >= viewportRect.left;\n\t}\n\n\t// 4. ์ค๋ฅธ์ชฝ ์๋ฆผ ์ฒดํฌ (๊ธฐ์ค: bodyViewport2)\n\t#isCellRightVisible = (cell) => {\n\t\tconst bodyViewport2 = this.#sheet.querySelector('.ng-container-body');\n\t\tif (!bodyViewport2 || !cell) return true;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst viewportRect = bodyViewport2.getBoundingClientRect();\n\n\t\t// ์
์ ์ฐ์ธก์ด ๋ทฐํฌํธ ์ฐ์ธก๋ณด๋ค ์ค๋ฅธ์ชฝ์ ์์ผ๋ฉด ์๋ฆฐ ์ํ\n\t\treturn cellRect.right <= viewportRect.right;\n\t}\n\n\t// ๐ก ํ์ํ๋ค๋ฉด ์ด 4๊ฐ๋ฅผ ์กฐํฉํด์ ์ ์ฒด ๊ฐ์์ฑ์ ํ๋จํ๋ ํตํฉ ํจ์๋ ์ฝ๊ฒ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.\n\t#isCellVisible = (cell) => {\n\t\treturn this.#isCellAboveVisible(cell) &&\n\t\t\tthis.#isCellBelowVisible(cell) &&\n\t\t\tthis.#isCellLeftVisible(cell) &&\n\t\t\tthis.#isCellRightVisible(cell);\n\t}\n\n\t#getVisibleRowCount = () => {\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\t\tconst viewportHeight = bodyViewport.clientHeight - (bodyViewport.querySelector('thead')?.offsetHeight || 0);\n\t\tconst rowHeight = this.#sheet.rowManager.getRowHeight();\n\n\t\t// ๋ทฐํฌํธ ๋์ด์ ๋ค์ด์ค๋ ํ ๊ฐ์ ๊ณ์ฐ (์์์ ๋ฒ๋ฆผ)\n\t\treturn Math.max(1, Math.floor(viewportHeight / rowHeight));\n\t}\n\n\t#initEvents() {\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\n\t\t\tif (e.button !== 0) return;\n\t\t\tconst cell = e.target.closest('td, th');\n\t\t\tif (!cell) return;\n\t\t\tif (cell.dataset.index === undefined || cell.dataset.col === undefined) return;\n\n\t\t\tif (cell.querySelector(\"cell-row-indicator\")) {\n\t\t\t\tthis.#sheet.row.focus(cell.dataset.index);\n\t\t\t} else {\n\t\t\t\tthis.currentCell = cell;\n\t\t\t}\n\t\t});\n\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\n\n\t\t\tconst cell = e.target.closest('td,th');\n\t\t\tif (!cell || !this.#sheet.contains(cell)) return;\n\n\t\t\tif (this.#host.tagName === 'NINE-TABLE-SIMPLE') {\n\t\t\t\tif ([\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\t\tthis.moveCell(e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ([\"Enter\", \"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\t\tthis.moveCell(e);\n\t\t\t\t} else if ([\"Space\"].includes(e.code)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\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 = col.style.minWidth = col.style.maxWidth = `${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 = sourceCol.style.minWidth = sourceCol.style.maxWidth = `${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';\nimport { trace } from \"@nopeer\";\n\nexport class NineTableFilterPanel extends HTMLElement {\n\t#sheet;\n\t#host;\n\t#nineTable;\n\t#view;\n\t#button;\n\tcurrentCol = null;\n\n\tconnectedCallback() {\n\t\tthis.#init();\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\n\t}\n\n\t#init = () => {\n\t\t//setTimeout(() => {\n\t\t\tthis.#renderer();\n\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\n\t\t\tthis.#host = this.getRootNode().host;\n\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\n\t\t\t})\n\n\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t});\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\t//});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\n \n <nine-table-simple class=\"filter-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"32\" fixed=\"left\" />\n <col width=\"180\" />\n <col width=\"0\" fixed=\"right\"/>\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"DATA2\" html=\"true\"></td>\n <td data-bind=\"DATA\"></td>\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n\n <div class=\"footer-section\">\n <div class=\"footer-btns\">\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\n <div class=\"btn-group\">\n <button id=\"btnOk\">Apply</button>\n </div>\n </div>\n </div>\n `;\n\t}\n\n\topen(filterBtn) {\n\t\tthis.#button = filterBtn;\n\n\t\tconst cell = filterBtn.closest(\"th, td\");\n\t\tthis.currentCol = cell?.dataset.col;\n\n\t\tconst cellRect = cell.getBoundingClientRect();\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\n\n\t\tconst panelWidth = this.offsetWidth || 240;\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\n\t\tlet top = cellRect.bottom - sheetRect.top;\n\n\t\tif (left < 0) {\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\tconst searchBox = this.querySelector(\".search-box\");\n\t\tsearchBox.value = \"\";\n\n\n\t\tthis.classList.add(\"active\");\n\t\tthis.classList.add(\"loading\");\n\n\t\tsetTimeout(() => {\n\t\t\ttry {\n\t\t\t\tthis.#loadVirtualFilterItems();\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\n\t\t\t\tsearchBox.focus({ preventScroll: true });\n\t\t\t} finally {\n\t\t\t\tthis.classList.remove(\"loading\");\n\t\t\t}\n\t\t});\n\t}\n\n\t#closeHandler = (e) => {\n\n\t\tconst path = e.composedPath ? e.composedPath() : [];\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\n\t\t\treturn;\n\t\t}\n\t\tthis.close();\n\t};\n\n\tclose() {\n\t\tthis.currentCol = null;\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#button = null;\n\t}\n\n\t#loadVirtualFilterItems() {\n\t\tconst filteredRecords = this.#host.data.getArray();\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] ํํ ๋ฐฐ์ด\n\t\tconst fields = this.#host.fields.get() || [];\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\n\t\tconst exprEngine = this.#host.exprEngine;\n\n\t\tconst ds = targetCols.flatMap((colInfo) => {\n\t\t\tconst bindKey = colInfo.bind;\n\t\t\tconst exprKey = colInfo.expr;\n\n\t\t\tconst filterKey = bindKey || exprKey; // ์ค์ ํํฐ ํ๋ผ๋ฏธํฐ ํค๋ก ์ฌ์ฉ\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\n\n\t\t\tconst uniqueMap = new Map();\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\n\t\t\t\tconst record = filteredRecords[i];\n\t\t\t\tif (!record) continue;\n\n\t\t\t\tlet rawVal = undefined;\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\n\t\t\t\t\trawVal = record.v[fieldIdx];\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\n\t\t\t\t} else if (exprKey && exprEngine) {\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\n\t\t\t\t}\n\n\t\t\t\tlet displayVal = rawVal;\n\t\t\t\tif (exprKey && exprEngine) {\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\n\t\t\t\t}\n\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\n\t\t\t\t\tuniqueMap.set(displayVal, {\n\t\t\t\t\t\tv: rawVal, // ๐ก ํํฐ๋ง ๋น๊ต ๊ธฐ์ค (DATA)\n\t\t\t\t\t\tv2: displayVal // ๐ก ํ๋ฉด ์ถ๋ ฅ ๊ธฐ์ค (DATA2)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst uniqueList = [...uniqueMap.values()];\n\n\t\t\tuniqueList.sort((a, b) => {\n\t\t\t\tconst valA = a.v2;\n\t\t\t\tconst valB = b.v2;\n\n\t\t\t\tif (valA === valB) return 0;\n\t\t\t\tif (valA === undefined || valA === null || valA === '') return 1;\n\t\t\t\tif (valB === undefined || valB === null || valB === '') return -1;\n\n\t\t\t\tconst numA = Number(valA);\n\t\t\t\tconst numB = Number(valB);\n\n\t\t\t\tconst isNumA = !isNaN(numA);\n\t\t\t\tconst isNumB = !isNaN(numB);\n\n\t\t\t\tif (isNumA && isNumB) {\n\t\t\t\t\treturn numA - numB;\n\t\t\t\t}\n\n\t\t\t\treturn String(valA).localeCompare(String(valB));\n\t\t\t});\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\n\n\t\t\treturn uniqueList.map(o => ({\n\t\t\t\tLVL: 2,\n\t\t\t\tDATA: o.v, // ํํฐ๋ง ๋น๊ต์ฉ ๊ฐ\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2,\n\t\t\t\tCOLNM: filterKey,\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v) >= 0 ? \"Y\" : \"N\"\n\t\t\t}));\n\t\t});\n\n\t\tthis.#nineTable.data.set(ds);\n\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\n\t\tif (selectAllChk) {\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\n\t\t}\n\t}\n\n\t#onOk = () => {\n\t\tthis.#host.loading = true;\n\n\t\tconst filterRecords = this.#view.view.getArray();\n\t\tconst fields = this.#nineTable.data.getHostFields();\n\n\t\tconst checkedRecords = filterRecords.filter(record => {\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\n\t\t\treturn (chk === \"Y\" || chk === true);\n\t\t});\n\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\n\n\t\tthis.#button.columns.forEach(colInfo => {\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\n\n\t\t\tif (selectedVals.length > 0) {\n\t\t\t\tfilterParams[filterKey] = selectedVals;\n\t\t\t} else {\n\t\t\t\tdelete filterParams[filterKey];\n\t\t\t}\n\t\t});\n\n\t\tconst totalCount = this.#nineTable.data.count();\n\n\t\tsetTimeout(() => {\n\t\t\ttry {\n\t\t\t\tif (totalCount === checkedRecords.length) {\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\n\t\t\t\t}\n\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\n\t\t\t\t\tbtn.updateFilteredState();\n\t\t\t\t});\n\n\t\t\t\tthis.#sheet.invalidate();\n\t\t\t\tthis.close();\n\t\t\t} finally {\n\t\t\t\tthis.#host.loading = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t#onInput = (e) => {\n\n\t\tconst query = e.target.value.toLowerCase().trim();\n\n\t\tif (!query) {\n\t\t\tthis.#view.filtering.clear();\n\t\t} else {\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\n\n\t\t\tconst matchedValues = [];\n\t\t\trawRecords.forEach(record => {\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\n\n\t\t\t\tif (textVal.includes(query)) {\n\t\t\t\t\tmatchedValues.push(val);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.#view.filtering.set({\n\t\t\t\tDATA2: [...new Set(matchedValues)]\n\t\t\t});\n\t\t}\n\t};\n\n\t#onSelectAll = (e) => {\n\t\tconst isChecked = e.target.checked;\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\n\t\tconst fields = this.#nineTable.data.getHostFields();\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\n\n\t\tif (chkIdx >= 0) {\n\t\t\trawRecords.forEach(record => {\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\n\t\t\t});\n\t\t}\n\n\t\tthis.#nineTable.refresh();\n\t};\n\n\t#onCancel = () => {\n\t\tthis.close();\n\t};\n}\n\nexport class NineTableFilterButton extends HTMLElement {\n\t#sheet;\n\t#columns = null;\n\n\tconnectedCallback() {\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n\t\tthis.removeEventListener(\"click\", this.#onClick);\n\t\tthis.addEventListener(\"click\", this.#onClick);\n\t}\n\n\tget columns() {\n\t\tif (this.#columns) return this.#columns;\n\n\t\tconst cell = this.closest(\"th, td\");\n\t\tconst colIndex = cell?.dataset.col;\n\t\tconst sourceTable = this.#sheet.sourceTable;\n\n\t\tconst cols = [];\n\t\tconst seen = new Set();\n\n\t\tif (sourceTable && colIndex !== undefined) {\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\n\t\t\t\tconst bindKey = $td.dataset.bind;\n\t\t\t\tconst exprKey = $td.dataset.expr;\n\n\t\t\t\tif (bindKey || exprKey) {\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\n\t\t\t\t\t\tseen.add(uniqueKey);\n\t\t\t\t\t\tcols.push({\n\t\t\t\t\t\t\tbind: bindKey,\n\t\t\t\t\t\t\texpr: exprKey,\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.#columns = cols;\n\t\treturn this.#columns;\n\t}\n\n\tupdateFilteredState = () => {\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\n\t\tconst isFiltered = this.columns.some(colInfo => {\n\t\t\tconst key = colInfo.expr || colInfo.bind;\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\n\t\t});\n\t\tthis.classList.toggle('filtered', isFiltered);\n\t};\n\n\t#onClick = (e) => {\n\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\n\t\tconst cell = this.closest(\"th, td\");\n\t\tconst col = cell.dataset.col;\n\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\n\t\t\tpanel.close();\n\t\t} else if (panel) {\n\t\t\tpanel.open(this);\n\t\t}\n\t};\n}\n\nexport class Filtering {\n\t#sheet;\n\t#host;\n\t#isFiltering = false;\n\t#filterPanel = null;\n\t#filters = {};\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = this.#sheet.getRootNode().host;\n\t\tthis.#init();\n\t}\n\n\tget filters() {\n\t\treturn this.#filters;\n\t};\n\n\t#init = () => {\n\t\tthis.#initFilterPanel();\n\t}\n\n\t#initFilterPanel = () => {\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\n\t\t\treturn;\n\t\t}\n\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\n\t\tif (!panel) {\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\n\t\t\tthis.#sheet.appendChild(panel);\n\t\t}\n\t\tthis.#filterPanel = panel;\n\t}\n\n\tisFiltering() {\n\t\treturn this.#isFiltering;\n\t}\n\n\tclear = (colnm) => {\n\t\tif (colnm) {\n\t\t\tdelete this.#filters[colnm];\n\t\t} else {\n\t\t\tthis.#filters = {};\n\t\t}\n\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\n\t\tthis.#applyFiltering();\n\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\n\t\t\tbtn.updateFilteredState();\n\t\t});\n\t}\n\n\tset = (oFilter) => {\n\n\t\tlet jsonFilter = Array.isArray(oFilter)\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\n\t\t\t: oFilter;\n\n\t\tthis.#filters = jsonFilter;\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\n\n\t\tthis.#applyFiltering();\n\t}\n\n\t#applyFiltering() {\n\t\tconst hostData = this.#host.data;\n\t\tconst rawRecords = hostData.getArray();\n\t\tconst fields = this.#host.data.getHostFields();\n\t\tconst sheetIndex = this.#sheet.index;\n\t\tconst exprEngine = this.#host.exprEngine;\n\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\n\n\t\tif (!hasFilters) {\n\t\t\trawRecords.forEach(record => {\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.#sheet.invalidate();\n\t\t\treturn;\n\t\t}\n\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\n\t\t\treturn {\n\t\t\t\ttargetKey,\n\t\t\t\tisExpr,\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\n\t\t\t\tallowedSet: new Set(allowedValues)\n\t\t\t};\n\t\t});\n\n\t\trawRecords.forEach((record, recordIdx) => {\n\t\t\tif (!record) return;\n\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\n\t\t\t}\n\n\t\t\tlet isPass = true;\n\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\n\t\t\t\tlet val = undefined;\n\n\t\t\t\tif (isExpr && exprEngine) {\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\n\t\t\t\t\tval = record.v[fieldIdx];\n\t\t\t\t}\n\n\t\t\t\tif (!allowedSet.has(val)) {\n\t\t\t\t\tisPass = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\n\t\t});\n\n\t\tthis.#sheet.selection.clear();\n\n\t\tthis.#sheet.invalidate();\n\t}\n}\n\nif (!customElements.get('nine-table-filter-panel')) {\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\n}\n\nif (!customElements.get('nine-table-filter-button')) {\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\n}","// ui/data/Sorting.js (๋๋ ์ ๋ ฌ ๊ด๋ จ ์์ค)\nimport { trace } from \"@nopeer\";\n\nexport class Sorting {\n\t#sheet;\n\t#host;\n\n\t#columns = [];\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.#initEvents();\n\t\t}, 300);\n\t}\n\n\t#initEvents() {\n\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\n\n\t\t\t$el.addEventListener('dblclick', (e) => {\n\n\t\t\t\tconst cell = e.target.closest('th, td');\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\n\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\n\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\n\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\n\n\t\t\t\thost.loading = true;\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.#handleSort(e, cell);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\thost.loading = false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t}\n\n\t#handleSort(e, cell) {\n\t\tconst colIndex = cell.dataset.col;\n\t\tconst tr = cell.closest('tr');\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\n\n\t\tif (colIndex === undefined) return;\n\n\t\tconst sourceTable = this.#sheet.sourceTable;\n\t\tif (!sourceTable) return;\n\n\t\tlet colName = null;\n\t\tlet exprVal = null;\n\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\n\t\t\tif ($td.dataset.bind) {\n\t\t\t\tcolName = $td.dataset.bind;\n\t\t\t}\n\n\t\t\tif ($td.dataset.expr) {\n\t\t\t\texprVal = $td.dataset.expr;\n\t\t\t}\n\t\t});\n\n\t\tif (!colName && !exprVal) return;\n\n\t\tconst isAsc = cell.classList.contains('asc');\n\t\tconst isDesc = cell.classList.contains('desc');\n\n\t\tif (!e.ctrlKey && !e.shiftKey) {\n\t\t\tthis.#columns = [];\n\t\t}\n\n\t\tconst existingColIndex = this.#columns.findIndex(\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\n\t\t);\n\n\t\tconst ruleData = {\n\t\t\tcolIndex,\n\t\t\tsubRowIndex,\n\t\t\tcolname: colName || exprVal,\n\t\t\tcolName: colName || exprVal,\n\t\t\texpr: exprVal, // ๐ก expr ๊ท์น ๋ณด๊ด\n\t\t\tasc: true,\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\n\t\t};\n\n\t\tif (!isAsc && !isDesc) {\n\t\t\tif (existingColIndex >= 0) {\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\n\t\t\t} else {\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\n\t\t\t}\n\t\t} else if (isAsc) {\n\t\t\tif (existingColIndex >= 0) {\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\n\t\t\t} else {\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#columns = this.#columns.filter(\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\n\t\t\t);\n\t\t}\n\n\t\tthis.#applySorting(cell);\n\t}\n\n\t#applySorting(cell) {\n\n\t\tthis.#sheet.view.setSorting(this.#columns);\n\t\tthis.#syncHeaderUI();\n\t\tthis.#sheet.invalidate();\n\t\trequestAnimationFrame(() => {\n\t\tconst cells = this.#sheet.querySelectorAll('tbody.body th, tbody.body td');\n\n\t\tcells.forEach($td => {\n\t\t\t$td.classList.remove('sorting-anim-asc', 'sorting-anim-desc', 'sorting-anim-none');\n\n\t\t\tif (cell.classList.contains('asc')) {\n\t\t\t\t$td.classList.add('sorting-anim-asc');\n\t\t\t} else if (cell.classList.contains('desc')) {\n\t\t\t\t$td.classList.add('sorting-anim-desc');\n\t\t\t} else {\n\t\t\t\t$td.classList.add('sorting-anim-none');\n\t\t\t}\n\t\t});\n\n\t\trequestAnimationFrame(() => {\n\t\t\tcells.forEach($td => {\n\t\t\t\t$td.classList.remove('sorting-anim-asc', 'sorting-anim-desc', 'sorting-anim-none');\n\t\t\t});\n\t\t});\n\t\t});\n\t}\n\n\t#syncHeaderUI() {\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\n\t\t\tel.classList.remove('asc', 'desc');\n\t\t});\n\n\t\tif (this.#columns.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#columns.forEach(colRule => {\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\n\n\t\t\tif (colIndex !== undefined) {\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\n\t\t\t\tif (subRowIndex !== undefined) {\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\n\t\t\t\t}\n\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\n\t\t\t\ttargetHeaderCells.forEach(cell => {\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\trestore() {\n\t\tthis.#columns = [];\n\t\tif (this.#sheet.view) {\n\t\t\tthis.#sheet.view.resetSorting();\n\t\t}\n\n\t\tthis.#syncHeaderUI();\n\t\tthis.#sheet.rowManager?.refresh(true);\n\t}\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport {Grouping} from \"@/data/Grouping.js\";\n\nexport class SheetView {\n\t#sheet;\n\t#host;\n\t#sortingColumns = [];\n\t#filterRules = [];\n\t#viewIndexes = [];\n\n\t#cachedVisibleRecords = null;\n\n\tconstructor(sheet) {\n\t\tthis.#sheet = sheet;\n\t\tthis.#host = sheet.getRootNode().host;\n\n\t\tthis.refresh();\n\t}\n\n\tgetArray = (at, colnm) => {\n\n\t\tif (!this.#cachedVisibleRecords) {\n\t\t\tconst records = this.#host.data.getArray();\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\n\t\t}\n\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn visibleRecords;\n\t\t}\n\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\n\n\t\tconst targetRecord = visibleRecords[at];\n\t\tif (colnm != null) {\n\t\t\tconst fields = this.#host.fields.get();\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn targetRecord;\n\t};\n\n\tcount = () => {\n\t\tif (!this.#cachedVisibleRecords) {\n\t\t\tconst records = this.#host.data.getArray();\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\n\t\t}\n\n\t\treturn this.#cachedVisibleRecords.length;\n\t}\n\n\tget = (at, colnm) => {\n\t\tconst visibleRecords = this.getArray();\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\n\n\t\tif (at === undefined || at === null) {\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\n\t\t}\n\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\n\n\t\tconst targetRecord = visibleRecords[at];\n\t\tif (!targetRecord) return null;\n\n\t\tif (colnm != null) {\n\t\t\tconst idx = fields.indexOf(colnm);\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\n\t\t}\n\n\t\treturn this.#convSingle(targetRecord, fields);\n\t};\n\n\t#convSingle = (o, fields) => {\n\t\tif (!o) return null;\n\t\tconst t = {};\n\t\tfields.forEach((colnm, i) => {\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\n\t\t});\n\t\tif (o.m) t.m = o.m;\n\t\tif (o._) t._ = o._;\n\t\treturn t;\n\t};\n\n\trefresh = () => {\n\n\t\tthis.#cachedVisibleRecords = null;\n\n\t\tconst rawRecords = this.#host.data.getArray();\n\t\tlet indices = [];\n\t\trawRecords.forEach((record, i) => {\n\t\t\tif (!record) return;\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\n\t\t\tindices.push(i);\n\t\t});\n\n\t\tif (this.#sortingColumns.length > 0) {\n\t\t\tindices = this.#applySorting(indices, rawRecords);\n\t\t}\n\n\t\tthis.#viewIndexes = indices;\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\n\n\t\t// ๐ก ์ํธ๋ณ ๊ทธ๋ฃนํ ์ค์ ๋ฐ ์ ํ ์ํ(collapsedMap) ๊ฐ์ ธ์ค๊ธฐ\n\t\tconst groupingManager = this.#sheet.grouping;\n\t\tconst groupColumns = groupingManager?.columns || [];\n\n\t\tif (groupColumns.length > 0) {\n\t\t\t// ๊ฐ ์ํธ๋ณ ๊ทธ๋ฃนํ ๋งค๋์ ์ ๊ด๋ฆฌ๋๋ collapsedMap์ ์ ๋ฌํ์ฌ ์ ํ ์ํ ์ ์ง\n\t\t\tconst collapsedMap = groupingManager.collapsedMap || new Map();\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields(), collapsedMap);\n\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // ์ต์ข
๋ ๋๋ง ์์ดํ
(์ ํ ํญ๋ชฉ ์๋ ์ ์ธ๋จ)\n\n\t\t\tgroupingManager.setGroupMap(groupResult.groupMap); // ์์ ๋งคํ ๊ณต์ \n\t\t} else {\n\t\t\tthis.#cachedVisibleRecords = validRecords;\n\t\t}\n\t}\n\n\tsetSorting = (columns) => {\n\t\tthis.#sortingColumns = columns || [];\n\t\tthis.refresh();\n\t};\n\n\tgetSorting = () => {\n\t\treturn this.#sortingColumns;\n\t};\n\n\tresetSorting = () => {\n\t\tthis.#sortingColumns = [];\n\t\tthis.refresh();\n\t};\n\n\n\t#applySorting = (indices, validRecords) => {\n\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\n\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\n\t\t\t...rule,\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\n\t\t}));\n\n\t\treturn indices.sort((idxA, idxB) => {\n\t\t\tconst a = validRecords[idxA];\n\t\t\tconst b = validRecords[idxB];\n\n\t\t\tfor (const rule of rulesWithIdx) {\n\t\t\t\tconst isAsc = rule.asc;\n\t\t\t\tconst expr = rule.expr; // ๐ก ๋ฑ๋ก๋ expr ์์\n\t\t\t\tlet valA, valB;\n\n\t\t\t\tif (expr) {\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\n\t\t\t\t} else {\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\n\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\n\t\t\t\tif (isEmptyA) return 1;\n\t\t\t\tif (isEmptyB) return -1;\n\n\t\t\t\tif (valA !== valB) {\n\t\t\t\t\tlet diff = 0;\n\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\n\t\t\t\t\t\tdiff = valA - valB;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst strA = String(valA);\n\t\t\t\t\t\tconst strB = String(valB);\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (diff !== 0) {\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn idxA - idxB;\n\t\t});\n\t};\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 = col.style.minWidth = col.style.maxWidth = widthVal;\n });\n }\n\n static #ensureThead(tbl) {\n // 1. ๊ธฐ๋ณธ ๋ฉ์ธ thead (not .foot) ๋ณด์ฅ\n let thead = tbl.querySelector('thead:not(.foot)');\n if (!thead) {\n thead = document.createElement('thead');\n }\n\n const colgroup = tbl.querySelector('colgroup');\n if (colgroup) {\n colgroup.after(thead);\n } else {\n tbl.prepend(thead);\n }\n\n let theadFoot = tbl.querySelector('thead.foot');\n if (!theadFoot) {\n theadFoot = document.createElement('thead');\n theadFoot.classList.add('foot');\n thead.after(theadFoot); // ๋ฉ์ธ thead ๋ฐ๋ก ๋ค์ ์์นํ๋๋ก ๋ฐฐ์น\n }\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 $tr = $cell.closest('tr');\n const expr = $cell.dataset.expr;\n if (expr) {\n $cell.setAttribute('data-expr', host.exprEngine.precompile(expr, $tr.getAttribute(\"grouping\") === \"true\"));\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 = targetCol.style.minWidth = targetCol.style.maxWidth`${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 const w = tbl.getAttribute(\"row-indicator\") === 'true' ? 48 : 4;\n const colgroup = tbl.querySelector('colgroup');\n\n // row-indicator์ฉ col์ด ์ด๋ฏธ ์๋ค๋ฉด ์ถ๊ฐ\n if (colgroup && !colgroup.querySelector('.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 = col.style.minWidth = col.style.maxWidth = `${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 // 1. ํ๋ค์ ๊ท์น์ ๋ง๊ฒ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ๊ธฐ\n const groups = [];\n let currentGroup = null;\n\n rows.forEach(tr => {\n // col-indicator ์ ์ฉ ํ ๋ฑ์ ์ ์ธ ์ฒ๋ฆฌ\n if (tr.classList.contains('col-indicator-rowgroup')) return;\n\n const isGrouping = tr.getAttribute('grouping') === 'true';\n\n if (isGrouping) {\n // grouping=\"true\"์ธ ํ์ ์ฐ์ ์ฌ๋ถ์ ์๊ด์์ด '๊ฐ๊ฐ ๋
๋ฆฝ๋ ๋จ๋
๊ทธ๋ฃน'์ผ๋ก ๋ถ๋ฆฌ\n groups.push({ isGrouping: true, rows: [tr] });\n currentGroup = null; // ์ผ๋ฐ ๊ทธ๋ฃน ์ฒด์ด๋ ๋๊ธฐ\n } else {\n // ์ผ๋ฐ ํ๋ค์ ์ฐ์๋๋ ๊ฒฝ์ฐ ํ๋์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์\n if (!currentGroup || currentGroup.isGrouping !== false) {\n currentGroup = { isGrouping: false, rows: [tr] };\n groups.push(currentGroup);\n } else {\n currentGroup.rows.push(tr);\n }\n }\n });\n\n // 2. ๊ฐ ๊ทธ๋ฃน๋ณ๋ก ์ฒซ ๋ฒ์งธ tr์ row-indicator ์ฝ์
\n groups.forEach(group => {\n const groupRows = group.rows;\n if (groupRows.length === 0) return;\n\n const firstTr = groupRows[0];\n\n // ์ด๋ฏธ ํด๋น ํ์ row-indicator๊ฐ ์กด์ฌํ๋ฉด ์ค๋ณต ์์ฑ ๋ฐฉ์ง\n if (firstTr.querySelector(':scope > th.row-indicator')) return;\n\n const indicatorCell = document.createElement('th');\n indicatorCell.className = 'row-indicator';\n indicatorCell.setAttribute('cell-type', 'row-indicator');\n\n // grouping ๊ทธ๋ฃน์ ํญ์ rowSpan=1, ์ผ๋ฐ ๊ทธ๋ฃน์ ์ฐ์๋ ํ ๊ฐ์(groupRows.length)๋งํผ ์ง์ \n if (!group.isGrouping && groupRows.length > 1) {\n indicatorCell.rowSpan = groupRows.length;\n }\n\n firstTr.insertBefore(indicatorCell, firstTr.firstElementChild);\n });\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 }\n}\n","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport class SheetAPI {\n #sheet;\n #host;\n #elements;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#host = sheet.getRootNode().host;\n\n //this.#resetElements();\n }\n\n #resetElements = () => {\n this.#elements = {\n viewport: this.#sheet.querySelector('.ng-sheet-body'),\n thead: this.#sheet.querySelector('thead'),\n tbody: this.#sheet.querySelector('tbody.body'),\n tfoot: this.#sheet.querySelector('tfoot'),\n thead_foot: this.#sheet.querySelector('thead.foot'),\n tbody_head: this.#sheet.querySelector('tbody.head'),\n tbody_foot: this.#sheet.querySelector('tbody.foot'),\n }\n };\n\n get elem() {\n\n if (this.#elements?.tbody_foot) return this.#elements;\n\n this.#elements = {\n viewport: this.#sheet.querySelector('.ng-sheet-body'),\n thead: this.#sheet.querySelector('thead'),\n tbody: this.#sheet.querySelector('tbody.body'),\n tfoot: this.#sheet.querySelector('tfoot'),\n thead_foot: this.#sheet.querySelector('thead.foot'),\n tbody_head: this.#sheet.querySelector('tbody.head'),\n tbody_foot: this.#sheet.querySelector('tbody.foot'),\n }\n\n return this.#elements;\n }\n\n get viewport() {\n const self = this;\n\n return {\n get tr() {\n return {\n get length() {\n return Math.ceil(self.#sheet.querySelector('.ng-container-body tbody.body tr:last-child').sectionRowIndex / self.#sheet.template.length);\n },\n count() {\n return this.length;\n }\n };\n },\n get group() {\n return {\n get length() {\n return self.#sheet.source.table.querySelectorAll(\"tbody tr[grouping='true']\").length;\n },\n count() {\n return this.length;\n }\n };\n },\n get fixedHeight() {\n const getHeight = () => {\n return (self.elem.thead?.offsetHeight || 0) +\n (self.elem.thead_foot?.offsetHeight || 0) +\n (self.elem.tfoot?.offsetHeight || 0) +\n (self.elem.tbody_head?.offsetHeight || 0);\n }\n\n let h = getHeight();\n\n if (h === 0) {\n self.#resetElements();\n h = getHeight();\n }\n\n return h;\n },\n get height() {\n return self.elem.viewport.offsetHeight;\n },\n get innerHeight() {\n const viewPortHeight = self.elem.viewport.clientHeight;\n return viewPortHeight - this.fixedHeight; // ๐ก ๋์ผ ๊ฐ์ฒด ๋ด๋ถ์ด๋ฏ๋ก this.fixedHeight ์ฌ์ฉ\n },\n get outerHeight() {\n return self.elem.viewport.offsetHeight;\n }\n };\n };\n\n\n\n\n\n col = {\n // 1. ํน์ ์ปฌ๋ผ์ ๋๋น ์ค์ (ColResizer ํ์ฉ)\n setWidth: (colIndex, width, containerType = null) => {\n const targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${colIndex}\"]`));\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n });\n\n },\n\n // 2. ํน์ ์ปฌ๋ผ์ ํ์ฌ ๋๋น ๊ฐ์ ธ์ค๊ธฐ\n getWidth: (colIndex) => {\n const colEl = this.#sheet.querySelector(`table colgroup col[data-col=\"${colIndex}\"]`);\n if (!colEl) return 0;\n return parseInt(colEl.getAttribute('width') || colEl.style.width, 10) || 0;\n },\n measureAutoFitColumnWidth: (cell, tbodyCell) => {\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n let maxTextWidth = 32;\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 return maxTextWidth;\n },\n // 3. ํน์ ์ปฌ๋ผ ์๋ ๋ง์ถค (์๊น ๋ถ๋ฆฌํ measureAutoFitColumnWidth ์ฐ๋)\n autoFit: (colIndex) => {\n const cell = this.#sheet.querySelector(`thead th[data-col=\"${colIndex}\"]`);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${colIndex}\"]`);\n\n if (!cell || !tbodyCell) return;\n\n this.#host.execute(() => {\n const calculatedWidth = this.col.measureAutoFitColumnWidth(cell, tbodyCell);\n if (calculatedWidth !== null) {\n this.col.setWidth(colIndex, calculatedWidth);\n }\n });\n },\n\n // 4. ์ปฌ๋ผ ํ์/์จ๊น ์ฒ๋ฆฌ\n setVisible: (colIndex, isVisible) => {\n const targets = this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${colIndex}\"], th[data-col=\"${colIndex}\"], td[data-col=\"${colIndex}\"]`);\n targets.forEach(el => {\n el.style.display = isVisible ? '' : 'none';\n });\n this.#sheet.rowManager?.refresh();\n }\n };\n\n row = {\n at: () => {\n if (this.#sheet.selection.minRow < 0) return -1;\n return Math.floor(this.#sheet.selection.minRow / this.#sheet.template.length);\n },\n focus: async (index, callback) => {\n // 1. ํ๋ฉด์ ์ ๋ณด์ด๋ฉด moveTo ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆผ\n if (!this.#sheet.row.isVisible(index)) {\n await new Promise((resolve) => {\n this.#sheet.row.moveTo(index, () => {\n resolve();\n });\n });\n } else {\n // 2. ์ด๋ฏธ ๋ณด์ด๋๋ผ๋ ๋ธ๋ผ์ฐ์ ๋ ๋๋ง ํ์ ํ ํ
ํฌ ์๋ณด (requestAnimationFrame)\n await new Promise((resolve) => requestAnimationFrame(resolve));\n }\n\n // 3. ๋ ๋๋ง์ด ์์ ํ ์์ ํ๋ ์์ ์ DOM ์กฐํ ๋ฐ ์ ํ ์ฒ๋ฆฌ\n const $trs = this.#sheet.querySelectorAll(`tbody.body tr[data-index=\"${index}\"]`);\n const matrixRows = Array.from($trs, $tr => parseInt($tr.dataset.matrixRow, 10)).filter(n => !isNaN(n));\n\n const cols = [];\n $trs.forEach($tr => {\n $tr.querySelectorAll('td, th').forEach($cell => {\n const col = parseInt($cell.dataset.col, 10);\n if (col != 0) cols.push(parseInt($cell.dataset.col, 10));\n });\n });\n\n if (matrixRows.length === 0 || cols.length === 0) return;\n\n const result = this.#sheet.selection.setRange(Math.min(...matrixRows), Math.min(...cols), Math.max(...matrixRows), Math.max(...cols));\n\n if (typeof callback === 'function') {\n callback();\n }\n\n return result;\n },\n isVisible: (index) => {\n\n const $sheetBody = this.#sheet.querySelector('.ng-sheet-body');\n\n const $trs = $sheetBody.querySelectorAll(`.ng-container-body tbody.body tr[data-index=\"${index}\"]`);\n if (!$trs || $trs.length === 0) return false;\n\n const viewportRect = $sheetBody.getBoundingClientRect();\n const theadHeight = $sheetBody.querySelector('thead')?.offsetHeight || 0;\n const tfootHeight = $sheetBody.querySelector('tfoot')?.offsetHeight || 0;\n\n const viewportTop = viewportRect.top + theadHeight;\n const viewportBottom = viewportRect.bottom - tfootHeight;\n\n let isVisible = true;\n\n for (const $tr of $trs) {\n const trRect = $tr.getBoundingClientRect();\n\n const isAbove = trRect.top < viewportTop;\n const isBelow = trRect.bottom > viewportBottom;\n\n if (isAbove || isBelow) {\n isVisible = false;\n break;\n }\n }\n\n return isVisible;\n },\n add: (dataSource, updateState) => {\n return this.#host.data.add(dataSource, updateState);\n },\n moveTo: (index, callback) => {\n if (this.#sheet.row.isVisible(index)) {\n if (typeof callback === 'function') callback();\n } else {\n this.#sheet.scrollTo(index, () => {\n if (typeof callback === 'function') callback();\n });\n }\n },\n insert: (index, dataSource, updateState = true) => {\n\n const currentJson = this.#sheet.view.get(index);\n const rowid = currentJson.m._[NINE_TABLE.META.INDEX.ROWID];\n\n const toRowid = this.#host.data.insert(rowid, dataSource, updateState);\n const records = this.#sheet.view.getArray();\n\n const targetIndex = records.findIndex(record => {\n if (!record || !record.m || !record.m._) return false;\n return record.m._[NINE_TABLE.META.INDEX.ROWID] === toRowid; // ํ์
์ฐจ์ด ๋ฐฉ์ง๋ฅผ ์ํด == ์ฌ์ฉ\n });\n\n return targetIndex;\n },\n remove: (index) => {\n\n const currentJson = this.#sheet.view.get(index);\n const rowid = currentJson.m._[NINE_TABLE.META.INDEX.ROWID];\n\n this.#host.data.remove(rowid);\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\";\nimport { SheetAPI } from \"@/api/SheetAPI.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 #api;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n #template = {\n length: 0,\n height: 0,\n heights: [],\n group: {\n length: 0,\n height: 0,\n heights: [],\n },\n };\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 this.#api = new SheetAPI(this);\n\n this.#bindApiMethods();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get template() { return this.#template; }\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 /**\n get template() {\n return {\n length: this.#source?.tbody?.tr?.length || 0,\n trs: this.#source?.tbody?.tr || []\n };\n } */\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 scrollTo = (dataRow, callback) => {\n this.rowManager.scrollToDataRow(dataRow, 'top', callback);\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 if ($overlay) {\n $overlay.style.top = `${$thead?.offsetHeight}px`;\n }\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 generateTemplate = ($table, index) => {\n\n const activeParent = (v) => {\n\n if (['NINE-TABLE-SIMPLE'].includes(this.#host.tagName)) {\n const $parent = this.#host.closest(\"nine-table-filter-panel, cell-combo-panel\");\n if ($parent) {\n v ? $parent.classList.add('active') : $parent.classList.remove('active');\n }\n }\n };\n\n activeParent(true);\n\n this.#index = index;\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n this.querySelector(`.ng-container-body`).appendChild(this.#source.table);\n\n this.#template = {\n height: 0,\n heights: [],\n length: 0,\n group: {\n height: 0,\n heights: [],\n length: 0,\n }\n }\n\n this.querySelectorAll(`.ng-container-body tbody.body tr`).forEach(($tr) => {\n const h = Math.max($tr.offsetHeight || 0, 28);\n this.#template.height += h;\n this.#template.heights.push(h);\n });\n\n this.querySelectorAll(`.ng-container-body tbody.body tr[grouping=\"true\"]`).forEach(($tr) => {\n const h = Math.max($tr.offsetHeight || 0, 28);\n this.#template.group.height += h;\n this.#template.group.heights.push(h);\n });\n\n this.#template.length = this.#template.heights.length;\n this.#template.group.length = this.#template.group.heights.length;\n\n if (this.#index === 0) {\n const minRows = parseInt(this.#host.getAttribute('display-min-rows'), 10);\n const maxRows = parseInt(this.#host.getAttribute('display-max-rows'), 10);\n\n const h = (this.querySelector(\"nine-table-toolbar\")?.offsetHeight || 0) +\n (this.querySelector(\"nine-table-footer\")?.offsetHeight || 0) +\n (this.querySelector(\"thead\")?.offsetHeight || 0) +\n (this.querySelector(\"tfoot\")?.offsetHeight || 0) +\n (this.querySelector(\"tbody.head\")?.offsetHeight || 0);\n\n if (this.#host.getAttribute('auto-height') === \"true\" || !isNaN(minRows) || !isNaN(maxRows)) {\n this.#host.setAttribute('scroll-bar', \"none\");\n }\n\n if (!isNaN(minRows)) {\n this.#host.style.minHeight = h + (this.#template.height * minRows) + \"px\";\n }\n\n if (!isNaN(maxRows)) {\n this.#host.style.maxHeight = h + (this.#template.height * maxRows) + \"px\";\n }\n }\n\n this.querySelectorAll((\"tbody.body tr\")).forEach(($tr) => {\n $tr.style.display = \"none\";\n });\n\n this.querySelector(`.ng-container-body table`).remove();\n\n activeParent(false);\n };\n\n generate = () => {\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 if (this.#host.classList.contains(\"combo-list\")) return;\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\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', (e) => {\n this.querySelectorAll(\"nine-table-filter-panel,cell-combo-panel\").forEach($el => {\n $el.classList.remove('active');\n });\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n\n this.setAttribute(\"tabindex\", \"0\");\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\">\n \n </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 \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 #bindApiMethods = () => {\n //const apis = [this.#sheetAPI, this.#dataAPI];\n const apis = [this.#api];\n\n apis.forEach(api => {\n // api ์ธ์คํด์ค(this)์ ์ง์ ์ ์ธ๋ ์์ฑ๋ค๊ณผ ํ๋กํ ํ์
์์ฑ์ ๋ชจ๋ ๊ฐ์ ธ์ด\n // Reflect.ownKeys๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ณผ์ด๋ ์จ๊ฒจ์ง ํ๋กํผํฐ๊น์ง ์์ ํ๊ฒ ํ์ ๊ฐ๋ฅํฉ๋๋ค.\n const keys = new Set([\n ...Reflect.ownKeys(api),\n ...Reflect.ownKeys(Object.getPrototypeOf(api))\n ]);\n\n keys.forEach(key => {\n // constructor๋ ๋ด๋ถ ํ๋ผ์ด๋น ๋ฉค๋ฒ(#)๋ ์ ์ธ\n if (key === 'constructor' || String(key).startsWith('#')) return;\n\n const target = api[key];\n\n if (typeof target === 'function') {\n if (!this[key]) {\n //trace.log(`[Binding Function] ${key}`);\n this[key] = (...args) => target.apply(api, args);\n }\n } else if (target !== null && typeof target === 'object') {\n\n if (!this[key]) {\n //trace.log(`[Binding Object Namespace] ${key}`);\n this[key] = target; // ๊ฐ์ฒด ๋ค์์คํ์ด์ค(์: row) ํต์งธ๋ก ์ฐ๊ฒฐ\n }\n }\n });\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\";\nimport {PreCompiler} from \"@/layout/core/PreCompiler.js\";\nimport {NINE_TABLE} from \"@\";\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 this.#initEvent();\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\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\n const sheetCount = rawTables.length;\n\n rawTables.forEach($el => {\n PreCompiler.initializeTable(this.#host, $el);\n });\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 ${this.#host.provider.style.value}\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\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($sheet, idx) => {\n $sheet.classList.add('active');\n $sheet.generateTemplate(rawTables[idx], idx);\n });\n\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($sheet) => {\n\n setTimeout(() => {\n $sheet.generate();\n if (this.#isAutoHeight) this.#applyAutoHeight();\n });\n });\n\n\n setTimeout(() => {\n this.#host.data.clear();\n });\n };\n\n #initEvent = () => {\n\n this.#host.addEventListener(NINE_TABLE.EVENT.ROW_ADDED, () => {\n if (this.#isAutoHeight) this.#applyAutoHeight();\n });\n\n this.#host.addEventListener(NINE_TABLE.EVENT.ROW_REMOVED, () => {\n if (this.#isAutoHeight) this.#applyAutoHeight();\n });\n\n let lastHeight = 0; // ์ง์ ๋์ด๋ฅผ ๊ธฐ์ตํ ๋ณ์\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n if (entry.target.tagName === \"NINE-TABLE\") {\n const currentHeight = entry.contentRect.height;\n\n if (currentHeight !== lastHeight) {\n lastHeight = currentHeight;\n if (this.#isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }\n }\n }).observe(this.#host);\n };\n\n #applyAutoHeight = () => {\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($sheet) => {\n if ($sheet.index === 0) {\n const fixedHeight = ($sheet.querySelector(\"thead\")?.offsetHeight || 0) +\n ($sheet.querySelector(\"tfoot\")?.offsetHeight || 0) +\n ($sheet.querySelector(\"tbody.head\")?.offsetHeight || 0);\n const basicHeight = this.#host.offsetHeight - $sheet.offsetHeight + fixedHeight;\n\n const h = Math.min($sheet.template.height * $sheet.view.count(), window.innerHeight * 0.8);\n\n this.#host.style.height = basicHeight + (h) + \"px\";\n }\n });\n };\n\n get #isAutoHeight() {\n return this.#host.getAttribute('auto-height') === 'true';\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 rewriteExprGroup(expr) {\nreturn expr;\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 ? `childrenItems` : match;\n });\n }\n\n precompile(expr, isGroup) {\n if (!expr) return expr;\n return isGroup ? this.rewriteExprGroup(expr) : this.rewriteExpr(expr);\n }\n\n evaluate(expr, rowItem, row = 0, isGroup = false) {\n\n if (expr === undefined || expr === null) return \"\";\n\n try {\n\n const trimmedExpr = String(expr).trim();\n const compiledExpr = isGroup ? this.rewriteExprGroup(trimmedExpr) : 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 (isGroup) {\n if (!evalFn) {\n evalFn = new Function('childrenItems', 'row', 'host', `\n const children = childrenItems || [];\n const fields = ${JSON.stringify(this.#fields)};\n \n const data = new Proxy(children, {\n get(target, prop) {\n if (prop in target || typeof prop === 'symbol') return target[prop];\n \n const idx = fields.indexOf(prop);\n if (idx >= 0) {\n return target.map(r => r.v ? r.v[idx] : r[prop]);\n }\n \n return target[prop];\n }\n });\n \n const provider = host;\n \n // ๐ก 1. ์์ ์์์ ๋ฐ๋ก ์ธ ์ ์๋ ์ง๊ณ ํจ์๋ค ์ ์ธ\n \n const sum = (arr) => Array.isArray(arr) ? arr.reduce((a, b) => a + (Number(b) || 0), 0) : 0;\n const avg = (arr) => Array.isArray(arr) && arr.length > 0 ? sum(arr) / arr.length : 0;\n const max = (arr) => Array.isArray(arr) && arr.length > 0 ? Math.max(...arr.map(Number)) : 0;\n const min = (arr) => Array.isArray(arr) && arr.length > 0 ? Math.min(...arr.map(Number)) : 0;\n \n // ๋ง์ฝ ๊ผญ 'Math.sum' ํํ๋ก ์ฐ๊ณ ์ถ๋ค๋ฉด ์๋์ฒ๋ผ Math ๊ฐ์ฒด์ ์ ์ ๋ถ์ฌ์ค ์๋ ์์ต๋๋ค.\n if (!Math.sum) Math.sum = sum;\n if (!Math.avg) Math.avg = avg;\n \n if (!data && !host) return \"\";\n return ${compiledExpr};\n `);\n\n this.#exprCache.set(compiledExpr, evalFn);\n }\n } else {\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\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 { NINE_TABLE } from \"@/core/constants.js\";\n\nexport class DataAPI {\n\n #host;\n\n constructor(host) {\n this.#host = host;\n }\n\n provider = {\n // ์คํ์ผ ๋ฐ์ดํฐ๋ฅผ provider ๊ฐ์ฒด ๋ด๋ถ์์ ์ง์ ๊ด๋ฆฌ (์ผ๋ฐ ๋ฉ์๋ ์ถ์ฝํ ์ฌ์ฉ)\n style: {\n value: '',\n },\n add: (providerObj) => {\n if (!providerObj || typeof providerObj !== 'object') return;\n\n const { style, ...methods } = providerObj;\n\n if (style && typeof style === 'string') {\n this.provider.style.value = style;\n }\n\n if (Object.keys(methods).length > 0) {\n setTimeout(() => {\n Object.entries(methods).forEach(([name, fn]) => {\n if (typeof fn === 'function') {\n this.#host[name] = fn;\n }\n });\n\n this.#host.rerenderer();\n });\n }\n },\n }\n\n}","export class NineTableAPI {\n #host;\n\n constructor(host) {\n this.#host = host;\n\n // ๊ด๋ฆฌํ ๋ค์์คํ์ด์ค๋ค์ ๋ฐฐ์ด๋ก ์ ์\n const namespaces = [\"col\", \"row\", \"viewport\"]; // ๋์ค์ \"col\", \"cell\" ๋ฑ๋ง ์ถ๊ฐํ๋ฉด ๋!\n\n namespaces.forEach(ns => {\n this[ns] = new Proxy({}, {\n get: (target, prop) => {\n const $sheet = this.#getActiveSheet();\n if (!$sheet || !$sheet[ns]) return undefined;\n\n const targetMethod = $sheet[ns][prop];\n\n if (typeof targetMethod === 'function') {\n return (...args) => targetMethod.apply($sheet[ns], args);\n }\n return targetMethod;\n }\n });\n });\n }\n\n getActiveSheets() {\n return this.#host.shadow.querySelectorAll('nine-table-sheet.active');\n }\n\n #getActiveSheet() {\n const arr = this.getActiveSheets();\n return arr.length > 0 ? arr[0] : null;\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\";\nimport { DataAPI } from '../api/DataAPI.js';\nimport { NineTableAPI } from '../api/NineTableAPI.js';\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #dataApi;\n #sheetApi;\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 this.#dataApi = new DataAPI(this);\n this.#sheetApi = new NineTableAPI(this);\n\n this.#bindApiMethods();\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\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 #bindApiMethods() {\n\n const apis = [this.#dataApi, this.#sheetApi];\n\n apis.forEach(api => {\n // api ์ธ์คํด์ค(this)์ ์ง์ ์ ์ธ๋ ์์ฑ๋ค๊ณผ ํ๋กํ ํ์
์์ฑ์ ๋ชจ๋ ๊ฐ์ ธ์ด\n // Reflect.ownKeys๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ณผ์ด๋ ์จ๊ฒจ์ง ํ๋กํผํฐ๊น์ง ์์ ํ๊ฒ ํ์ ๊ฐ๋ฅํฉ๋๋ค.\n const keys = new Set([\n ...Reflect.ownKeys(api),\n ...Reflect.ownKeys(Object.getPrototypeOf(api))\n ]);\n\n keys.forEach(key => {\n // constructor๋ ๋ด๋ถ ํ๋ผ์ด๋น ๋ฉค๋ฒ(#)๋ ์ ์ธ\n if (key === 'constructor' || String(key).startsWith('#')) return;\n\n const target = api[key];\n\n if (typeof target === 'function') {\n if (!this[key]) {\n //trace.log(`[Binding Function] ${key}`);\n this[key] = (...args) => target.apply(api, args);\n }\n } else if (target !== null && typeof target === 'object') {\n if (!this[key]) {\n //trace.log(`[Binding Object Namespace] ${key}`, target);\n this[key] = target; // ๊ฐ์ฒด ๋ค์์คํ์ด์ค(์: row) ํต์งธ๋ก ์ฐ๊ฒฐ\n }\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 {\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tapplyBaseStyle() {\n\t}\n\n\tconnectedCallback() {\n\t}\n}","import { trace } from \"@nopeer\";\nimport { BasicCellElement } from './BasicCellElement.js';\n\nconst exprCache = new Map();\n\nexport class CellElement extends BasicCellElement {\n\t#host;\n\t#sheet;\n\t#tr;\n\t#cell;\n\t#attr;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tget #updateRowState() {\n\t\treturn !(this.#cell.getAttribute(\"update-row-state\") === \"false\");\n\t}\n\n\tget host() { return this.#host; }\n\tget sheet() { return this.#sheet; }\n\tget cell() { return this.#cell; }\n\tget tr() { return this.#tr; }\n\tget attr() { return this.#attr; }\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#host = this.getRootNode().host;\n\n\t\tthis.#cell = this.closest(\"th,td\");\n\t\tthis.#tr = this.#cell.closest(\"tr\");\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\n\n\t\tthis.#cell.classList.add(this.tagName);\n\n\t\tthis.#attr = {};\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\n\t\t\tconst name = this.#cell.attributes[i].name;\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\n\t\t\t}\n\t\t}\n\n\t\tif (!this.#cell) return;\n\n\n\t\tconst root = this.shadowRoot || this;\n\n\t\t// ๐ฏ ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\n\t\t\tbutton.addEventListener(\"click\", () => {\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\n\n\t\t\t\tconst rowData = this.data; // Proxy Lazy ์ ๊ทผ\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\n\n\t\t\t\tif (fn && this.#host) {\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\n\t\t\t\t\tconst methodName = match?.[1] || fn;\n\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true\n\t\t\t\t})); */\n\t\t\t});\n\t\t});\n\n\t\t// ๐ฏ ๋งํฌ ์ด๋ฒคํธ ์ฐ๊ฒฐ\n\t\tconst renderer = root.querySelector(\".renderer\");\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\n\t\t\trenderer.classList.add(\"link\");\n\n\t\t\trenderer.addEventListener(\"click\", () => {\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\n\n\t\t\t\tconst rowData = this.data;\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\n\n\t\t\t\tif (fn && this.#host) {\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\n\t\t\t\t\tconst methodName = match?.[1] || fn;\n\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true\n\t\t\t\t}));\n\t\t\t});\n\t\t}\n\t}\n\n\tget data() {\n\t\tconst rawRecord = this.#tr?.data;\n\t\tif (!rawRecord) return null;\n\t\tif (!rawRecord.v) return rawRecord;\n\n\t\tconst host = this.#host;\n\n\t\treturn new Proxy(rawRecord, {\n\t\t\tget(target, prop) {\n\t\t\t\tif (prop === '__ng') return target.__ng;\n\t\t\t\tif (prop === 'v') return target.v;\n\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\n\t\t\t}\n\t\t});\n\t}\n\n\tget value() {\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\n\n\t\tconst bindKey = this.#cell.dataset?.bind;\n\t\tif (!bindKey) return \"\";\n\n\t\tconst rawRecord = this.#tr.data;\n\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\n\t\t}\n\n\t\treturn rawRecord[bindKey] ?? \"\";\n\t}\n\n\tset value(v) {\n\t\tif (!this.#cell || !this.#host?.data) return;\n\n\t\tconst row = parseInt(this.#tr.dataset.row, 10);\n\t\tconst bindKey = this.#cell.dataset.bind;\n\t\tif (isNaN(row) || !bindKey) return;\n\n\t\t//update-row-state\n\t\tthis.#host.data.setValue(row, bindKey, v, this.#updateRowState);\n\t}\n\n\tget row() {\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\n\t}\n\tget index() {\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\n\t}\n\n\tisValid() {\n\t\treturn this.#cell.classList.contains(\"invalid\") ? false : true;\n\t}\n\n\tisInvalid() {\n\t\treturn !this.isValid();\n\t}\n\n\tgetDisplayText = (defaultValue = \"\") => {\n\n\t\t//if (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\n\t\tif (!this.#cell || (!this.#cell.closest(\"tbody\") && !this.#cell.closest(\"thead.foot\") && !this.#cell.closest(\"tfoot\"))) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tconst rawRecord = this.#tr.data;\n\n\t\tif (!rawRecord) return defaultValue;\n\n\t\tconst expr = this.#cell.dataset.expr;\n\t\tconst bindKey = this.#cell.dataset.bind;\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\n\n\t\tif (expr) {\n\t\t\ttry {\n\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row, this.#tr.getAttribute(\"grouping\") === \"true\");\n\t\t\t} catch (e) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\n\t\tif (bindKey) {\n\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\n\t\t\t\tconst idx = this.#host.fields.get().indexOf(bindKey);\n\t\t\t\treturn this.#tr.data[0].v[idx];\n\t\t\t} else {\n\t\t\t\tconst val = this.value;\n\t\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\n\t\t\t}\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\n\n\trefresh() {\n\n\t\tif (!this.#cell || !this.#tr) return;\n\n\t\tconst val = this.value;\n\n\t\tthis.#cell.classList.remove(\"invalid\");\n\n\t\t[\"color\",\"background\",\"background-color\",\"visible\",\"enable\",\"validator\"].forEach(v => {\n\n\t\t\tconst expr = this.#attr[v];\n\t\t\tif (expr) {\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10), this.#tr.getAttribute(\"grouping\") === \"true\");\n\n\t\t\t\tif (v === \"validator\") {\n\t\t\t\t\tif (!result) {\n\t\t\t\t\t\tthis.#cell.classList.add(\"invalid\");\n\t\t\t\t\t}\n\t\t\t\t} else if (v === \"visible\") {\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\n\t\t\t\t} else if (v === \"enable\") {\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\n\t\t\t\t\t\t$el.disabled = !result;\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!!result) {\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.#cell.style[v] = result;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn val;\n\t}\n\n\tgetExprValue(expr, data, row) {\n\t\tif (!this.#host || !this.#host.exprEngine || expr === undefined || expr === null || expr === \"\") return expr;\n\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row, this.#tr.getAttribute(\"grouping\") === \"true\");\n\t}\n\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\n\t\tif (!expr) return \"\";\n\n\t\ttry {\n\t\t\trow = parseInt(row, 10);\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\n\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\n\t\t\t}\n\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\n\t\t\tif (match) {\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n\t\t\t\tconst [, funcName, field] = match;\n\t\t\t\tconst host = this.#host;\n\n\t\t\t\tswitch (funcName.toLowerCase()) {\n\t\t\t\t\tcase 'count':\n\t\t\t\t\t\treturn childRecords.length;\n\n\t\t\t\t\tcase 'sum': {\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\n\t\t\t\t\t\t}, 0);\n\t\t\t\t\t}\n\n\t\t\t\t\tcase 'avg': {\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\n\t\t\t\t\t\t}, 0);\n\t\t\t\t\t\treturn sum / childRecords.length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 3. ํธ์คํธ์ exprFunction ํ์ฉ\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\n\t\t\t}\n\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\n\t\t\t\tif (!evalFn) {\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\n \n let childRecords = [];\n if (Array.isArray(indices)) {\n // indices๊ฐ ์ซ์ ์ธ๋ฑ์ค ๋ฐฐ์ด์ธ์ง, rowid ๋ฌธ์์ด ๋ฐฐ์ด์ธ์ง ํ๋ณํ์ฌ ์์ ํ๊ฒ ์ถ์ถ\n childRecords = indices.map(idx => {\n if (typeof idx === 'number') {\n return allRecords[idx];\n } else {\n // rowid ๋ฑ ๋ฌธ์์ด ์๋ณ์์ธ ๊ฒฝ์ฐ ์ ์ฒด ๋ฐฐ์ด์์ ์ฐพ๊ฑฐ๋ dataManager ํ์ฉ\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\n }\n }).filter(Boolean);\n }\n \n // ๋ง์ฝ ์์์ ๋ชป ์ฐพ์๋๋ฐ host.grouping์ ์ธ ์ ์๋ค๋ฉด ๋งค๋์ ์์ ์๋\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\n }\n\n const data = childRecords; // data.length ๋ฑ์ ์ธ ์ ์๋๋ก ํธํ\n return ${expr};\n `);\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\n\t\t\t\t}\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\n\t\t\t}\n\n\t\t\treturn expr;\n\t\t} catch (e) {\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\n\t\t\treturn expr;\n\t\t}\n\t};\n}\n\nexport class EditableCellElement extends CellElement {\n\n\tget host() { return super.host; }\n\tget sheet() { return super.sheet; }\n\tget cell() { return super.cell; }\n\tget tr() { return super.tr; }\n\tget attr() { return super.attr; }\n\n\tgetExprValue(expr, data, row) {\n\t\treturn super.getExprValue(expr, data, row);\n\t}\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\t}\n\n\trefresh() {\n\t\treturn super.refresh();\n\t}\n\n\tgetExprValue = (expr, data, row, cell) => {\n\t\treturn super.getExprValue(expr, data, row, cell);\n\t}\n\n\tisValid = () => {\n\t\treturn super.isValid();\n\t}\n\n\tisInvalid = () => {\n\t\treturn super.isInvalid();\n\t}\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 this.cell.addEventListener(\"keydown\", e => {\n\n if (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n if (this.cell.getAttribute(\"disabled\") === \"true\") return;\n if (this.style.display === \"none\") return;\n\n if (e.code === \"Space\") {\n e.preventDefault();\n\n this.value = this.#target.checked ? this.falseValue : this.trueValue;\n\n this.sheet.rowManager.refresh(true);\n }\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\t\t\tif (this.style.display === \"none\") 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\";\nimport { NINE_TABLE } from \"@\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#EXPAND_ROW_COUNT = 10;\n\n\t#parent;\n\t#grd;\n\t#sheet;\n\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\n\t\tthis.#grd = this.querySelector(\"nine-table-simple\");\n\t\tsetTimeout(() => {\n\t\t\tthis.#sheet = this.#grd.shadowRoot.querySelector(\"nine-table-sheet\");\n\t\t\tthis.#initEvents();\n\t\t})\n\t}\n\n\t#initData = (formattedData) => {\n\n\t\tif (!this.#grd || !this.#parent.dataSource || this.#parent.dataSource.length === 0) return;\n\n\t\tconst activeColumnCount = this.#parent.items.length || 1;\n\n\t\tthis.#sheet.source.table.querySelectorAll('colgroup col, tbody td').forEach(($el, idx) => {\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\tthis.#sheet.querySelectorAll('table colgroup col').forEach(($el, idx) => {\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\n\t\tthis.#grd.addEventListener(NINE_TABLE.EVENT.ROW_ADDED, () => {\n\t\t\tsetTimeout(() => {\n\n\t\t\t\tthis.style.opacity = \"\";\n\t\t\t\tthis.classList.add(\"active\");\n\n\t\t\t\tthis.#sheet.querySelectorAll('colgroup col').forEach(($el, idx) => {\n\t\t\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\t\t\tif (col >= 2 && $el.style.display !== \"none\") {\n\t\t\t\t\t\tthis.#sheet.col.autoFit(col);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst fields = this.#grd.fields.get();\n\n\t\t\t\tif (this.#parent.multi) {\n\t\t\t\t\tconst selectedKeys = this.#parent.value ? String(this.#parent.value).split(this.#parent.separator).map(s => s.trim()) : [];\n\t\t\t\t\tconst kIndex = fields.indexOf(\"k\");\n\t\t\t\t\tconst chkIndex = fields.indexOf(\"CHK\");\n\n\t\t\t\t\tthis.#grd.data.getArray().forEach(record => {\n\t\t\t\t\t\trecord.v[chkIndex] = (selectedKeys.includes(String(record.v[kIndex]))) ? \"Y\" : \"N\";\n\t\t\t\t\t});\n\n\t\t\t\t\tconst index = this.#sheet.view.getArray().findIndex((record, idx) => {\n\t\t\t\t\t\treturn record.v[kIndex] === selectedKeys[0];\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.#selectRow(index);\n\t\t\t\t} else {\n\t\t\t\t\tconst currentValue = this.#parent.value;\n\t\t\t\t\tconst kIndex = fields.indexOf(\"k\");\n\t\t\t\t\tconst index = this.#sheet.view.getArray().findIndex((record, idx) => {\n\t\t\t\t\t\treturn record.v[kIndex] === currentValue;\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.#selectRow(index);\n\t\t\t\t}\n\t\t\t})\n\t\t}, {once: true});\n\n\t\tif (formattedData.length > this.#EXPAND_ROW_COUNT) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tthis.#grd.data.set(formattedData);\n\t};\n\n\t#isPanelBelow = ($btn) => {\n\t\tconst $sheet = $btn.closest(\".ng-sheet-body\");\n\n\t\tconst btnRect = $btn.getBoundingClientRect();\n\t\tconst sheetRect = $sheet.getBoundingClientRect();\n\t\tconst spaceBelow = sheetRect.bottom - btnRect.bottom;\n\t\tconst spaceAbove = btnRect.top - sheetRect.top;\n\n\t\treturn spaceBelow >= spaceAbove;\n\t};\n\n\t#calculatePanelHeight = ($btn, isDropDown, rows) => {\n\t\tconst $sheet = $btn.closest(\".ng-sheet-body\");\n\n\t\tconst btnRect = $btn.getBoundingClientRect();\n\t\tconst sheetRect = $sheet.getBoundingClientRect();\n\n\t\tconst searchInputHeight = 32;\n\t\tconst h1 = (isDropDown ? (sheetRect.bottom - btnRect.bottom) : (btnRect.top - sheetRect.top)) - 5;\n\t\tconst h2 = (rows * this.#sheet.template.height) + (rows > this.#EXPAND_ROW_COUNT ? searchInputHeight : 0) + 2;\n\n\t\treturn Math.min(h1, h2);\n\t}\n\n\t#calculatePanelLeft = ($btn) => {\n\n\t\tconst $cell = $btn.closest(\"th,td\");\n\t\tconst $sheet = $cell.closest(\".ng-sheet-body\");\n\n\n\t\tconst cellRect = $cell.getBoundingClientRect();\n\t\tconst sheetRect = $sheet.getBoundingClientRect();\n\n\t\tlet left = cellRect.left - sheetRect.left;\n\n\t\tconst panelWidth = this.offsetWidth;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 2);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\treturn left;\n\t};\n\n\topen = (parent) => {\n\t\tthis.#parent = parent;\n\n\t\tthis.classList.add(\"active\");\n\t\tthis.style.opacity = \"0\";\n\n\t\tlet items = this.#parent.items;\n\t\tif (items.length === 0) {\n\t\t\titems.push(this.#parent.valueName);\n\t\t}\n\n\t\tconst formattedData = this.#parent.dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: this.#parent.keyName && item[this.#parent.keyName] !== undefined ? item[this.#parent.keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\titems.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\tsetTimeout(() => {\n\n\t\t\tif (!this.#grd || !this.#parent.dataSource) return;\n\n\t\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\t\tconst sheet = parent.closest(\".ng-sheet-body\");\n\t\t\tconst btnRect = parent.getBoundingClientRect();\n\t\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\t\tconst isDropDown = this.#isPanelBelow(parent);\n\t\t\tconst h = this.#calculatePanelHeight(parent, isDropDown, formattedData.length);\n\t\t\tconst l = this.#calculatePanelLeft(parent);\n\t\t\tconst t = isDropDown ? (btnRect.bottom - sheetRect.top) : (btnRect.top - sheetRect.top - h);\n\n\t\t\tthis.style.height = `${h}px`;\n\t\t\tthis.style.left = `${l}px`;\n\t\t\tthis.style.top = `${t}px`;\n\t\t\t//this.style.opacity = \"\";\n\n\t\t\tif (this.#parent.multi) {\n\t\t\t\tthis.classList.add(\"multi\");\n\t\t\t\tthis.#grd.classList.add(\"multi\");\n\t\t\t} else {\n\t\t\t\tthis.classList.remove(\"multi\");\n\t\t\t\tthis.#grd.classList.remove(\"multi\");\n\t\t\t}\n\n\t\t\tthis.#initData(formattedData);\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus({ preventScroll: true });\n\t\t}\n\t}\n\n\n\t#onClick = (e) => {\n\t\tconst $cell = e.target.closest(\"th,td\");\n\t\tif (this.#grd.classList.contains(\"multi\")) {\n\t\t\tconst index = parseInt($cell?.dataset.index, 10);\n\t\t\tthis.#checkRow(index);\n\t\t}\n\t\telse {\n\t\t\tconst col = parseInt($cell?.dataset.col, 10);\n\n\t\t\tif (col >= 2) {\n\t\t\t\tthis.#returnRow();\n\t\t\t}\n\t\t}\n\t}\n\n\t#onKeydown_input = (e) => {\n\t\tswitch (e.code) {\n\t\t\tcase \"Enter\":\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tconst index = this.#grd.row.at();\n\t\t\t\tif (index < 0) {\n\t\t\t\t\tthis.#selectRow(0)\n\t\t\t\t} else {\n\t\t\t\t\tthis.#selectRow(index)\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"Tab\":\n\t\t\t\tthis.#selectRow(this.#grd.row.at());\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\t#onKeydown = (e) => {\n\t\tlet index;\n\t\tswitch (e.code) {\n\t\t\tcase \"Escape\":\n\t\t\t\tthis.close();\n\t\t\t\tbreak;\n\t\t\tcase \"Enter\":\n\t\t\t\tif (this.classList.contains(\"multi\")) {\n\t\t\t\t\tthis.#onOk();\n\t\t\t\t} else {\n\t\t\t\t\tthis.#returnRow();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"Tab\":\n\t\t\t\tif (this.classList.contains(\"expand\")) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tthis.querySelector(\"input[type='text']\").focus({ preventScroll: true });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tindex = this.#grd.row.at();\n\t\t\t\tif (index < 0) {\n\t\t\t\t\tthis.#selectRow(0)\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"Space\":\n\t\t\t\te.preventDefault();\n\t\t\t\tif ([\"TH\",\"TD\"].includes(e.target.tagName)) {\n\t\t\t\t\tthis.#checkRow(this.#grd.row.at());\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t#onOk = () => {\n\n\t\tconst fields = this.#grd.fields.get();\n\t\tconst kIndex = fields.indexOf(\"k\");\n\t\tconst chkIndex = fields.indexOf(\"CHK\");\n\n\t\tconst arr = [];\n\t\tthis.#sheet.view.getArray().forEach(o => {\n\t\t\tif (o.v[chkIndex] === \"Y\") {\n\t\t\t\tarr.push(o.v[kIndex]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = arr.join(this.#parent.separator);\n\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\t\tthis.close();\n\t}\n\n\t#returnRow = () => {\n\t\tconst index = this.#grd.row.at();\n\n\t\tif (index >= 0) {\n\t\t\tconst record = this.#sheet.view.get(index);\n\n\t\t\tthis.#parent.value = record.k;\n\t\t\tthis.#parent.sheet.rowManager.refresh(true);\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t#checkRow = (index) => {\n\n\t\tif (this.#grd.classList.contains(\"multi\") && index >= 0) {\n\t\t\tconst record = this.#sheet.view.get(index);\n\n\t\t\tthis.#grd.data.setValue(record.m._[NINE_TABLE.META.INDEX.ROWID], \"CHK\", record.CHK === \"Y\" ? \"N\" : \"Y\");\n\n\t\t\tthis.#grd.refresh();\n\t\t}\n\t};\n\n\t#selectRow = (index) => {\n\t\tif (index !== -1) {\n\t\t\tthis.#sheet.row.focus(index, () => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tconst cell = this.#sheet.querySelector(`tr[data-index=\"${index}\"] td[data-col=\"2\"]`);\n\t\t\t\t\tthis.#sheet.navigation.currentCell = cell;\n\t\t\t\t\tcell.focus({ preventScroll: true });\n\t\t\t\t\tthis.#sheet.invalidate();\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tthis.#sheet.row.focus(-1, () => {\n\t\t\t});\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#sheet.selection.clear();\n\n\t\t\t\tthis.#sheet.navigation.currentCell = this.#sheet.querySelector(`tr[data-index=\"0\"] td[data-col=\"2\"]`);\n\t\t\t\tthis.#sheet.focus({ preventScroll: true });\n\t\t\t\tthis.#sheet.invalidate();\n\t\t\t});\n\t\t}\n\t}\n\n\t#onSelectAll = (e) => {\n\n\t\tconst chkIdx = this.#grd.fields.get().indexOf(\"CHK\");\n\n\t\tthis.#grd.data.getArray().forEach(record => {\n\t\t\trecord.v[chkIdx] = e.target.checked ? \"Y\" : \"N\";\n\t\t});\n\n\t\tthis.#sheet.invalidate();\n\t};\n\n\n\t#onInput = (e) => {\n\t\tconst query = e.target.value.toLowerCase().trim();\n\n\t\tif (!query) {\n\t\t\tthis.#sheet.filtering.clear();\n\t\t} else {\n\t\t\tconst rawRecords = this.#grd.data.getArray();\n\t\t\tconst fields = this.#grd.fields.get();\n\n\t\t\tconst colnm = \"tmp1\";\n\t\t\tconst data2Idx = fields.indexOf(colnm);\n\n\t\t\tlet matchedValues = [];\n\t\t\trawRecords.forEach(record => {\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\n\n\t\t\t\tif (textVal.includes(query)) {\n\t\t\t\t\tmatchedValues.push(val);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.#sheet.filtering.set({\n\t\t\t\t[colnm]: [...new Set(matchedValues)]\n\t\t\t});\n\t\t}\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(\".search-input\").addEventListener(\"keydown\", this.#onKeydown_input);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\t\tthis.#sheet.addEventListener(\"keydown\", this.#onKeydown);\n\t\tthis.#sheet.addEventListener(\"click\", this.#onClick);\n\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\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 <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\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 <label for=\"chkAll\"><input id=\"chkAll\" type=\"checkbox\" checked><span>Select All</span></label>\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#target;\n\t#dataSource = [];\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#init();\n\t}\n\n\trerenderer = () => {\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\n\trefresh = () => {\n\t\tsuper.refresh();\n\n\t\tthis.#target.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\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\t#init = () => {\n\n\t\tthis.#renderer();\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\t#initData = () => {\n\t\t//if (!this.sheet || !this.cell) return;\n\n\t\tconst dataSource = this.cell.getAttribute(\"data-source\");\n\t\tif (dataSource) {\n\t\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\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.#target = this.querySelector(\".btn1\");\n\t};\n\n\t#initEvent = () => {\n\t\tthis.querySelectorAll(\"button\").forEach($el => {\n\t\t\t$el.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\n\n\t\tthis.cell.addEventListener('keydown', (e) => {\n\t\t\tif ([\"Space\"].includes(e.code)) {\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 = this.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\tthis.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\t//if (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\tif (this.#panel.classList.contains(\"active\") && 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\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n\tget keyName() {\n\t\treturn this.cell.getAttribute(\"key-name\") || \"k\";\n\t}\n\tget valueName() {\n\t\treturn this.cell.getAttribute(\"value-name\") || \"v\";\n\t}\n\tget multi() {\n\t\treturn this.cell.getAttribute('multi') === \"true\";\n\t}\n\tget multiSeparator() {\n\t\treturn this.cell.getAttribute(\"multi-separator\") || \",\";\n\t}\n\tget items() {\n\t\treturn this.cell.getAttribute(\"items\")?.split(\",\").map(s => s.trim()) || [];\n\t}\n\tget separator() {\n\t\treturn this.multiSeparator;\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 { CellElement } from \"./core/CellElement.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { trace } from \"@nopeer\";\n\nexport class CellTree extends CellElement {\n\n\t#iconElement;\n\t#textElement;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\tthis.#init();\n\t}\n\n\t#groupExprValue = () => {\n\t\tconst records = this.data;\n\n\t\treturn \"...\";\n\t}\n\t/**\n\t * ๋ฐ์ดํฐ๊ทธ๋ฆฌ๋ ์
ํ์ค refresh ์ฌ์ดํด์ ๋ง์ถฐ ํธ์ถ\n\t */\n\trefresh() {\n\n\t\tif (this.tr.style.display === \"none\") return;\n\n\t\tconst groupId = this.tr.dataset.groupId;\n\n\t\tconst record = this.data; // ํ ๋ฐ์ดํฐ ๋ ์ฝ๋\n\t\tif (!record) return;\n\n\t\tconst level = groupId ? groupId?.split(\"_\").length - 2 : this.sheet.grouping.columns.length;\n\n\t\tthis.style.setProperty('--tree-level', level);\n\n\t\t// 2. ํ
์คํธ ํ์ (data-bind ๋๋ data-expr ๊ฒฐ๊ณผ ๋ฑ)\n\t\tthis.#textElement.textContent = this.getDisplayText();//this.textContent || record[this.getAttribute(\"data-bind\")] || '';\n\n\t\t// 3. ํธ๋ฆฌ ์์ด์ฝ ๋ฐ ์ํ ๋ฐ์\n\t\tthis.#updateTreeState(record);\n\t}\n\n\t#updateTreeState(record) {\n\t\tconst hasChildren = this.#checkHasChildren(record);\n\n\t\tconst isCollapsed = this.sheet.grouping.isCollapsed(this.tr.dataset.groupId);\n\n\t\tthis.#iconElement.className = \"icon\";\n\n\t\tthis.#iconElement.classList.remove(\"expand-on,expand-off\");\n\n\t\tif (hasChildren) {\n\t\t\tthis.#iconElement.classList.add(isCollapsed ? \"expand-off\" : \"expand-on\");\n\t\t} else {\n\t\t\tthis.#iconElement.classList.add(\"node\");\n\t\t}\n\t}\n\n\t#checkHasChildren(record) {\n\t\t// ์์ ์กด์ฌ ์ฌ๋ถ ํ๋จ ๋ก์ง\n\t\treturn this.tr.data.length > 0;\n\t}\n\n\t#init = () => {\n\t\tthis.#renderer();\n\t\tthis.#initEvent();\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n\t <div class=\"item\">\n <div class=\"icon\"></div>\n <span class=\"tree-text\"></span>\n </div>\n `;\n\n\t\tthis.#iconElement = this.querySelector(\".icon\");\n\t\tthis.#textElement = this.querySelector(\".tree-text\");\n\t}\n\n\t#initEvent = () => {\n\t\tthis.#iconElement.addEventListener(\"click\", (e) => {\n\t\t\te.stopPropagation();\n\t\t\tthis.sheet.grouping.toggleGroup(this.tr.dataset.groupId);\n\t\t});\n\t}\n}\n\nif (!customElements.get('cell-tree')) {\n\tcustomElements.define('cell-tree', CellTree);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\nimport {NINE_TABLE} from \"@\";\nimport {CellTree} from \"@/cell/cell-tree.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(\".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=\"row-status\"></span>\n `;\n\t}\n\n\trefresh = () => {\n\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tthis.classList.remove(\"is-insert\", \"is-update\", \"is-delete\");\n\n\t\tconst rawRecord = this.tr.data;\n\n\t\tif (rawRecord) {\n\n\t\t\tif (rawRecord.m === undefined) {\n\n\t\t\t} else {\n\t\t\t\tswitch (rawRecord.m._[NINE_TABLE.META.INDEX.ROW_STATE]) {\n\t\t\t\t\tcase NINE_TABLE.ROW_STATE.INSERT:\n\t\t\t\t\t\tthis.classList.add(\"is-insert\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase NINE_TABLE.ROW_STATE.UPDATE:\n\t\t\t\t\t\tthis.classList.add(\"is-update\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase NINE_TABLE.ROW_STATE.DELETE:\n\t\t\t\t\t\tthis.classList.add(\"is-delete\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\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<div class=\"row-status\"></div>\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 = this.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}\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":"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"}
|