@ninebone/table 0.1.45 → 0.1.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nine-table.js +2 -12
- package/dist/nine-table.js.map +1 -1
- package/dist/nine-table.umd.js +1 -1
- package/dist/nine-table.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nine-table.umd.js","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/ui/layout/nine-table-sheets.js","../src/ui/layout/nine-table-sheets-footer.js","../src/ui/layout/nine-table-toolbar.js","../src/ui/layout/nine-table-hscrollbar.js","../src/ui/layout/nine-table-vscrollbar.js","../src/data/Grouping.js","../src/ui/layout/core/RowManager.js","../src/ui/layout/core/TableCompiler.js","../src/ui/cell-manager/CellSelection.js","../src/ui/cell-manager/CellNavigation.js","../src/ui/col/ColResizer.js","../src/ui/col/ColMover.js","../src/ui/col/ColFixManager.js","../src/data/Filtering.js","../src/data/Sorting.js","../src/data/SheetView.js","../src/ui/layout/core/PreCompiler.js","../src/ui/layout/nine-table-sheet.js","../src/ui/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/core/nine-table.js","../src/ui/cell/core/BasicCellElement.js","../src/ui/cell/core/CellElement.js","../src/ui/cell/cell-input-text.js","../src/ui/cell/cell-input-number.js","../src/ui/cell/cell-input-color.js","../src/ui/cell/cell-input-date.js","../src/ui/cell/cell-checkbox.js","../src/ui/cell/cell-radio.js","../src/ui/cell/cell-combo-panel.js","../src/ui/cell/cell-combo.js","../src/ui/cell/cell-renderer.js","../src/ui/cell/cell-button.js","../src/ui/cell/cell-row-indicator.js","../src/ui/col/col-expand.js","../src/ui/menu/nine-table-menu.js","../src/ui/menu/nine-table-menu-panel.js"],"sourcesContent":["Array.prototype.nineBinarySearch = function(target) {\n //this.sort((a, b) => { return a > b ? 1 : -1; });\n\n let start = 0;\n let end = this.length - 1;\n let mid;\n\n while (start <= end) {\n mid = parseInt((start + end) / 2);\n\n if (target === this[mid]) {\n return mid;\n } else {\n if (target < this[mid]) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n }\n\n return -1;\n};\n\n// 엘리먼트별 디바운스/취소 상태를 격리하기 위한 WeakMap\nconst elementDebounceState = new WeakMap();\n\nHTMLElement.prototype.addDebounseEventListener = function(\n dblClickEvent,\n dblClickFn,\n pointerEvent,\n pointerFn,\n debounceTime = 500\n) {\n const el = this;\n\n if (!elementDebounceState.has(el)) {\n elementDebounceState.set(el, { timer: null, cancelFn: null });\n }\n const state = elementDebounceState.get(el);\n\n // 1. 포인터(다운) 이벤트: 즉시 실행하지 않고 debounceTime 동안 지연시킴\n el.addEventListener(pointerEvent, (e) => {\n e.actualTarget = e.target;\n\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n\n // 💡 500ms 동안 대기한 뒤에야 실제 pointerFn이 실행됨\n state.timer = setTimeout(() => {\n state.timer = null;\n state.cancelFn = pointerFn.call(el, e);\n }, debounceTime);\n });\n\n // 2. 더블클릭 이벤트: 대기 시간 내에 들어오면 예약되어 있던 pointerdown 자체를 원천 차단\n el.addEventListener(dblClickEvent, (e) => {\n //trace.log(e);\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null; // 💡 pointerdown 실행 예약이 아예 취소됨!\n }\n\n // 혹시 이미 실행되어 버린 경우의 안전장치 롤백\n if (state.cancelFn) {\n state.cancelFn();\n state.cancelFn = null;\n }\n\n dblClickFn.call(el, e);\n });\n};\n\n\nnine.measureTextSize = (_text, _font = '12px sans-serif') => {\n if (typeof _text === 'number') _text = _text + \"\";\n if (!_text) return { width: null, height: null };\n\n // 🎯 브라우저 DOM 파싱을 이용한 완벽한 HTML 태그 제거 함수\n const stripHtml = (html) => {\n const tmp = document.createElement(\"DIV\");\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || \"\";\n };\n\n // 줄바꿈 처리 전 HTML 정제 또는 줄바꿈 단위별 정제\n _text = _text.replaceAll(\"\\n\", \"<br>\");\n\n // 🎯 공용 숨김 캔버스를 querySelector로 찾거나 없으면 생성\n let canvas = document.body.querySelector('canvas#_nine_measure_canvas_');\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.id = '_nine_measure_canvas_';\n canvas.style.cssText = 'position: absolute; visibility: hidden; pointer-events: none; left: -9999px;';\n document.body.appendChild(canvas);\n }\n\n const context = canvas.getContext('2d');\n context.font = _font;\n\n let w = 0;\n let h = 0;\n\n for (let v of _text.split(\"<br>\")) {\n // 브라우저 파서로 HTML 태그를 완전히 제거한 순수 텍스트 획득\n const cleanText = stripHtml(v);\n const metrics = context.measureText(cleanText);\n\n //trace.log(cleanText);\n\n w = Math.max(w, metrics.width);\n\n const ascent = metrics.fontBoundingBoxAscent || 10;\n const descent = metrics.fontBoundingBoxDescent || 3;\n h += ascent + descent;\n }\n\n return {\n width: w,\n height: h\n };\n};","import { trace as traceOrigin } from '@ninebone/util';\n\n/**\n// 1. 내부 프라이빗 필드 문제를 피하기 위해 래퍼 객체 생성\nexport const trace = {\n init(prefix, color) {\n // 필요하다면 여기서 초기화 로직 수행 가능\n if (traceOrigin.init) {\n try { traceOrigin.init(prefix, color); } catch (e) {}\n }\n },\n log(...args) {\n return traceOrigin.log(...args);\n },\n warn(...args) {\n return traceOrigin.warn(...args);\n },\n error(...args) {\n return traceOrigin.error(...args);\n }\n};\n\n// 2. 모듈 로드 시점에 네임스페이스 초기화 시도\ntry {\n traceOrigin.init(\"nine-table\", \"green\");\n} catch (e) {}\n*/\n\n\nexport class Trace extends traceOrigin.constructor {\n constructor() {\n super();\n this.init(\"nine-table\", \"green\");\n }\n}\n\nexport const trace = new Trace();\n\n\n//trace.init(\"nine-table\", \"green\");","export const NINE_TABLE = {\n META: {\n INDEX: {\n ROWID: 0,\n FILTER: 1, // 멀티뷰 필터 통과 여부 (true/false)\n GROUP: 2,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 'EMPTY',\n NORMAL: 'NORMAL',\n INSERT: 'INSERT',\n UPDATE: 'UPDATE',\n DELETE: 'DELETE'\n },\n EVENT: {\n LOAD: \"load\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\n\r\nexport class ngRow {\r\n\t#parent;\r\n\t#newrow = -1;\r\n\r\n\tconstructor(parent) {\r\n\t\tthis.#parent = parent;\r\n\t}\r\n\r\n\tget at() {\r\n\t\treturn this.#newrow;\r\n\t}\r\n\tset at(v) {\r\n\t\tthis.#newrow = parseInt(v, 10);\r\n\t}\r\n\r\n\tcount = () => this.#parent.rawRecords.length;\r\n}\r\n\r\nexport class ngData {\r\n\t#host;\r\n\t#parent;\r\n\t#nextId = 0;\r\n\t#defaultHeight = [];\r\n\r\n\tstatic META_INDEX = {\r\n\t\tFILTER: 0, // 멀티뷰 필터 통과 여부 (true/false)\r\n\t\t// ── 추후 확장 예시 ──\r\n\t\t// GROUP: 1,\r\n\t\t// SELECT: 2,\r\n\t\t// EXPAND: 3\r\n\t};\r\n\r\n\t// 🎯 행 상태 정의 상수 내재화\r\n\tstatic ROW_STATE = {\r\n\t\tEMPTY: 'EMPTY',\r\n\t\tNORMAL: 'NORMAL',\r\n\t\tINSERT: 'INSERT',\r\n\t\tUPDATE: 'UPDATE',\r\n\t\tDELETE: 'DELETE'\r\n\t};\r\n\r\n\tconstructor(host, parent) {\r\n\t\tthis.#host = host;\r\n\t\tthis.#parent = parent;\r\n\t\tthis.#initialize();\r\n\t}\r\n\r\n\r\n\r\n\t/**\r\n\t * 🎯 [내부 공통] 삭제되지 않은 유효 레코드 목록 반환 (중복 제거 및 캡슐화)\r\n\t */\r\n\t#getValidRecords = () => {\r\n\t\tconst rawRecords = this.#parent.rawRecords || [];\r\n\t\treturn rawRecords.filter(o => !o.__ng?.deleted);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 행 개수 반환 (속성 및 메서드 형태 모두 지원)\r\n\t */\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tcount = () => {\r\n\t\treturn this.length;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [내부 엔진/고성능용] 변환 오버헤드 없이 순수 데이터(v 배열 등) 그대로 반환\r\n\t * - data.getArray() : 유효한 전체 내부 레코드 배열 반환\r\n\t * - data.getArray(at) : 특정 행의 내부 레코드 객체({ v: [...] }) 반환\r\n\t * - data.getArray(at, colnm) : 특정 행의 특정 컬럼 원시 값 반환\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn validRecords; // 변환 없이 배열 그대로 반환 (렌더링 최적화)\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord; // { v: [...], __ng: {...} } 원본 형태 반환\r\n\t};\r\n\r\n\tsetArray = (rowIndex, colIndex, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\r\n\t\tconst oldValue = rowData.v[colIndex];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\t// 변경 전 값 보존 우선 주석처리\r\n\t\t\t//rowData.o[colIndex] = value;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[colIndex] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\r\n\t/**\r\n\t * 🎯 [외부 개발자/비즈니스 로직용] 개발자가 활용하기 편한 JSON 객체 형태로 변환하여 반환\r\n\t * - data.get() : 전체 유효 데이터를 JSON 객체 배열로 변환\r\n\t * - data.get(at) : 특정 행을 JSON 객체로 변환\r\n\t * - data.get(at, colnm) : 특정 컬럼 값 반환\r\n\t */\r\n\tget = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn this.#conv(validRecords);\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#conv(targetRecord);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [저장/서버 전송용] 삭제된 행을 포함한 전체 원본 배열 반환\r\n\t */\r\n\tgetAll = () => {\r\n\t\treturn this.#parent.rawRecords || [];\r\n\t};\r\n\r\n\tgetHostFields = () => {\r\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\r\n\t};\r\n\r\n\t#initialize = () => {\r\n\t\tthis.#defaultHeight = [];\r\n\t\tconst templateElements = this.#host.template || [];\r\n\t\tArray.from(templateElements).forEach(el => {\r\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\r\n\t\t});\r\n\r\n\t\t(this.#parent.rawRecords || []).forEach(v => {\r\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\r\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\r\n\t\t});\r\n\t};\r\n\r\n\tget source() {\r\n\t\treturn this.#conv(this.#parent.rawRecords);\r\n\t}\r\n\tset source(v) {\r\n\t\tthis.set(v);\r\n\t\t//this.clear();\r\n\t\t//this.add(v, false);\r\n\t}\r\n\r\n\t#invalidate = () => {\r\n\t\tconst $sheets = this.#host.shadowRoot.querySelector(\"nine-table-sheets\");\r\n\t\t$sheets?.classList.toggle(\"nodata\", this.length === 0);\r\n\r\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\r\n\t\t\t$el.invalidate();\r\n\t\t});\r\n\r\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\r\n\t};\r\n\r\n\tset = (dataSource) => {\r\n\r\n\t\tconst loadData = () => {\r\n\t\t\tthis.clear();\r\n\t\t\tthis.add(dataSource, false);\r\n\t\t\tthis.#invalidate();\r\n\t\t}\r\n\r\n\t\tif (this.#host.loaded) {\r\n\t\t\tloadData();\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\r\n\t\t\t\tloadData();\r\n\t\t\t}, { once: true });\r\n\t\t}\r\n\t};\r\n\r\n\tget nextId() {\r\n\t\treturn this.#nextId++;\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.#getValidRecords().length;\r\n\t}\r\n\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tgetRowCount() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\t#getDefaultMeta = (rowid = 0) => {\r\n\t\treturn {\r\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\r\n\t\t\tdeleted: false,\r\n\t\t\tfiltered: false,\r\n\t\t\theight: this.#defaultHeight.slice(),\r\n\t\t\to: {},\r\n\t\t\tc: {},\r\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\r\n\t\t\t_: [rowid, [], ],\r\n\t\t};\r\n\t};\r\n\r\n\treset = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tclear = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tif (this.#parent.viewRecords?.reset) {\r\n\t\t\tthis.#parent.viewRecords.reset();\r\n\t\t}\r\n\r\n\t\tthis.#nextId = 0;\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\t#json2Array = (jsonArray) => {\r\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\r\n\r\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\r\n\t\tconst arr = [];\r\n\r\n\t\tjsonArray.forEach(json => {\r\n\t\t\tconst o = { v: [] };\r\n\t\t\tfields.forEach(colnm => {\r\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\r\n\t\t\t});\r\n\t\t\tarr.push(o);\r\n\t\t});\r\n\r\n\t\treturn arr;\r\n\t};\r\n\r\n\t#defaultInsert = (arr) => {\r\n\t\tif (!Array.isArray(arr)) arr = [arr];\r\n\t\tarr.forEach(o => {\r\n\t\t\tconst rowid = this.nextId;\r\n\r\n\t\t\to.m = this.#getDefaultMeta(rowid);\r\n\t\t\to.__ng = o.m;\r\n\t\t\to.__ng.rowid = rowid;\r\n\t\t\to.__ng.rowState = ngData.ROW_STATE.INSERT;\r\n\t\t\to.__ng._[0] = rowid;\r\n\t\t});\r\n\t\treturn arr;\r\n\t};\r\n\r\n\tadd = (dataSource, updateState = true) => {\r\n\t\tif (dataSource === undefined) dataSource = {};\r\n\t\tconst arr = this.#json2Array(dataSource);\r\n\r\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(this.#defaultInsert(arr));\r\n\r\n\t\tconst row = this.count() - 1;\r\n\t\tif (!updateState) {\r\n\t\t\tarr.forEach((_, idx) => {\r\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\r\n\t\t\t\tif (target) target.__ng.rowState = ngData.ROW_STATE.EMPTY;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#invalidate();\r\n\t\treturn row;\r\n\t};\r\n\r\n\tdelete = (at) => {\r\n\t\tlet arr = [];\r\n\t\tif (Array.isArray(at)) {\r\n\t\t\tarr = at;\r\n\t\t} else if (typeof at === \"undefined\") {\r\n\t\t\tarr = [this.#parent.host.row.at];\r\n\t\t} else {\r\n\t\t\tarr = [parseInt(at, 10)];\r\n\t\t}\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tarr.sort((a, b) => b - a).forEach(rowidx => {\r\n\t\t\tif (validRecords[rowidx]) {\r\n\t\t\t\tconst targetId = validRecords[rowidx].__ng.rowid;\r\n\t\t\t\tif (validRecords[rowidx].__ng.rowState === ngData.ROW_STATE.INSERT) {\r\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.__ng.rowid !== targetId);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\r\n\t\t\t\t\t\tif (item.__ng.rowid === targetId) {\r\n\t\t\t\t\t\t\titem.__ng.deleted = true;\r\n\t\t\t\t\t\t\titem.__ng.rowState = ngData.ROW_STATE.DELETE;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tsetValue = (rowIndex, colnm, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\trowIndex = parseInt(rowIndex, 10);\r\n\t\tconst fields = this.getHostFields();\r\n\t\tconst COL_IDX = fields.indexOf(colnm);\r\n\t\tif (COL_IDX < 0) return;\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\t\tif (!rowData) return;\r\n\r\n\r\n\r\n\t\tconst oldValue = rowData.v[COL_IDX];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\tif (!rowData.__ng.o.hasOwnProperty(colnm)) rowData.__ng.o[colnm] = oldValue;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[COL_IDX] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\t#conv = (arr) => {\r\n\t\tif (!arr) return arr;\r\n\r\n\t\tconst isSingle = !Array.isArray(arr);\r\n\t\tconst targetArr = isSingle ? [arr] : arr;\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\r\n\t\t\tconst t = {};\r\n\t\t\tfields.forEach((colnm, i) => {\r\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t\t});\r\n\t\t\tt.__ng = o.__ng;\r\n\t\t\treturn t;\r\n\t\t});\r\n\r\n\t\treturn isSingle ? result[0] : result;\r\n\t};\r\n}\r\n","import { ngRow, ngData } from \"./ngData.js\";\r\n\r\nexport class ngDataManager {\r\n\t#host;\r\n\r\n\tconstructor(host) {\r\n\t\tthis.#host = host;\r\n\r\n\t\tthis.row = new ngRow(this);\r\n\t\tthis.data = new ngData(this.#host, this);\r\n\r\n\t\tthis.rawRecords = [];\r\n\t\tthis.viewRecords = [];\r\n\t\tthis.delRecords = [];\r\n\t\tthis.pageCnt = 25;\r\n\r\n\t\tthis.viewRecords.reset = () => {\r\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\r\n\t\t};\r\n\r\n\t\tthis.setDataSource = (ds) => {\r\n\t\t\tif (this.data) this.data.reset();\r\n\r\n\t\t\tthis.rawRecords = [];\r\n\t\t\tthis.viewRecords = [];\r\n\t\t\tthis.delRecords = [];\r\n\r\n\t\t\tthis.data.set(ds || []);\r\n\t\t};\r\n\r\n\t\tthis.getRowState = (nRow) => {\r\n\t\t\tconst rowIdx = parseInt(nRow, 10);\r\n\t\t\tif (rowIdx >= this.data.count()) return;\r\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\r\n\t\t};\r\n\r\n\t\tthis.getRowPosition = () => this.row.at;\r\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\r\n\r\n\t\tthis.scrollTo_V1 = (nRow) => {\r\n\t\t\tif (nRow < 0) nRow = 0;\r\n\t\t\tif (nRow >= this.rawRecords.length) nRow = this.rawRecords.length - 1;\r\n\r\n\t\t\tthis.viewRecords.rawIndex = nRow;\r\n\t\t\tif (this.viewRecords.reset) this.viewRecords.reset();\r\n\r\n\t\t\treturn (nRow <= 0 || nRow >= this.rawRecords.length - 1) ? false : true;\r\n\t\t};\r\n\r\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\r\n\r\n\t\tthis.setColumn = (rowidx, colnm, v) => {\r\n\t\t\trowidx = parseInt(rowidx, 10);\r\n\t\t\tthis.data.setValue(rowidx, colnm, v);\r\n\t\t};\r\n\r\n\t\t// 초기 빈 데이터 바인딩\r\n\t\tthis.setDataSource([]);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\n\nexport class fields {\n\t#host;\n\t#fields = []; // 🎯 이제 { name: string, type: string } 객체들의 배열로 관리합니다.\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\t\tthis.#init();\n\t};\n\n\t// 🎯 기존에 필드 이름만 쓰던 곳들과의 호환을 위해 이름 배열만 리턴하는 메서드 유지\n\tget() {\n\t\treturn this.#fields.map(f => f.name);\n\t};\n\n\t// 🎯 내부 객체 통째로 얻기\n\tgetFields() {\n\t\treturn this.#fields;\n\t}\n\n\t// 🎯 특정 필드의 데이터 타입 조회\n\tgetType(fieldName) {\n\t\tconst found = this.#fields.find(f => f.name === fieldName);\n\t\treturn found ? found.type : 'string';\n\t}\n\n\tadd = (arr, type = 'string') => {\n\t\tarr.forEach(fName => {\n\t\t\tif (!this.#fields.some(f => f.name === fName)) {\n\t\t\t\tthis.#fields.push({ name: fName, type: type });\n\t\t\t}\n\t\t});\n\t\tthis.#adjust();\n\t};\n\n\tindexOf(v) {\n\t\treturn this.#fields.findIndex(f => f.name === v);\n\t};\n\n\tincludes(v) {\n\t\treturn this.#fields.some(f => f.name === v);\n\t};\n\n\t#adjust = () => {\n\t\t// 🎯 이름 기준으로 중복 제거 (Map을 활용하여 마지막에 들어온 타입 유지)\n\t\tconst map = new Map();\n\t\tthis.#fields.forEach(f => {\n\t\t\tmap.set(f.name, f.type);\n\t\t});\n\n\t\tthis.#fields = Array.from(map, ([name, type]) => ({ name, type }));\n\n\t\t// 🎯 빈 문자열이나 __ng 필터링\n\t\tthis.#fields = this.#fields.filter(f => f.name !== \"\" && f.name !== \"__ng\");\n\n\t\t// 🎯 긴 이름순 정렬\n\t\tthis.#fields.sort((a, b) => { return (a.name.length < b.name.length) ? 1 : -1; });\n\t};\n\n\t#init = () => {\n\t\tthis.#fields = [];\n\n\t\ttrace.log(this.#host.querySelectorAll(\"table\"));\n\n\t\tconst rawTables = Array.from(this.#host.querySelectorAll(\"table\"));\n\n\t\tif (!rawTables || rawTables.length === 0) return;\n\n\t\tfor (const tbl of rawTables) {\n\t\t\ttrace.log(tbl);\n\n\t\t\t// 1. [data-bind] 속성 탐색 및 타입 수집\n\t\t\ttbl.querySelectorAll('[data-bind]').forEach((el) => {\n\t\t\t\tconst fieldName = el.dataset.bind;\n\t\t\t\tconst fieldType = el.getAttribute(\"data-type\") || 'string';\n\n\t\t\t\tif (fieldName) {\n\t\t\t\t\tthis.#fields.push({ name: fieldName, type: fieldType });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// 2. 표현식 속성들 탐색 (순수 자바스크립트로 변환)\n\t\t\tconst exprAttrs = [\n\t\t\t\t\"data-expr\", \"background-color\", \"color\", \"tooltip\",\n\t\t\t\t\"visible\", \"readonly\", \"enable-button\", \"enable-check\",\n\t\t\t\t\"class-expr\", \"icon-color\", \"icon-src\"\n\t\t\t];\n\n\t\t\texprAttrs.forEach(attr => {\n\t\t\t\t// 💡 jQuery의 $([attr], tbl).each(...)를 순수 querySelectorAll로 대체\n\t\t\t\ttbl.querySelectorAll(`[${attr}]`).forEach((el) => {\n\t\t\t\t\tlet expr = el.getAttribute(attr);\n\t\t\t\t\tif (!expr) return;\n\n\t\t\t\t\tif (expr.indexOf(\"data.\") < 0) {\n\t\t\t\t\t\tconst lastIndex = expr.search(/[(]/g);\n\n\t\t\t\t\t\tif (lastIndex > 0) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\texpr = String(window[expr.substring(0, lastIndex).trim()]);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\texpr = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\texpr.split(\"data.\").forEach(v => {\n\t\t\t\t\t\tif (v.trim() != \"\") {\n\t\t\t\t\t\t\tconst lastIndex = v.search(/[^_A-Za-z0-9]/g);\n\t\t\t\t\t\t\tlet targetField = '';\n\n\t\t\t\t\t\t\tif (lastIndex >= 0) {\n\t\t\t\t\t\t\t\ttargetField = v.substring(0, lastIndex);\n\t\t\t\t\t\t\t} else if (expr.startsWith(\"data.\")) {\n\t\t\t\t\t\t\t\ttargetField = v.replace(\"data.\", \"\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (targetField) {\n\t\t\t\t\t\t\t\tthis.#fields.push({ name: targetField, type: 'string' });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tthis.#adjust();\n\t};\n};","export class NineTableSheets extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n #init = () => {\n\n };\n\n}\n\nif (!customElements.get('nine-table-sheets')) {\n customElements.define('nine-table-sheets', NineTableSheets);\n}","export class NineTableSheetsFooter extends HTMLElement {\n #host;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n refresh = () => {\n this.querySelector(\"#row-count\").innerHTML = this.#host.data.count().toLocaleString();\n };\n\n #init = () => {\n this.#host = this.getRootNode().host;\n\n this.#render();\n\n this.querySelector('.nine-tab-bar')?.addEventListener('click', (e) => {\n const isMultiSelect = e.ctrlKey || e.metaKey || e.shiftKey;\n const tabItem = e.target.closest('nt-sheets-tab-item');\n\n if (!tabItem) return;\n\n const index = parseInt(tabItem.dataset.index, 10);\n this.#switchSheet(index, isMultiSelect);\n });\n\n this.#switchSheet(0, false);\n };\n\n #switchSheet = (index, isMultiSelect = false) => {\n\n const updateSplitters = () => {\n const sheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet'));\n const splitters = Array.from(this.#host.shadowRoot.querySelectorAll('nine-splitter'));\n\n // 1. 모든 스플리터 일단 숨김 처리\n splitters.forEach(s => s.style.setProperty('display', 'none'));\n\n // 2. 현재 active 상태인 시트들을 인덱스 오름차순으로 정렬\n const activeSheets = sheets\n .map((sheet, idx) => ({ sheet, idx }))\n .filter(({ sheet }) => sheet.classList.contains('active'));\n\n if (activeSheets.length < 2) return;\n\n // 3. 인접한 활성화 시트 쌍 사이에 정확히 하나의 스플리터만 노출\n for (let i = 0; i < activeSheets.length - 1; i++) {\n const currentIdx = activeSheets[i].idx;\n\n const targetSplitter = this.#host.shadowRoot.querySelector(`nine-splitter[data-split-index=\"${currentIdx}\"]`);\n if (targetSplitter) {\n targetSplitter.style.setProperty('display', '');\n }\n }\n };\n\n const tabBar = this.querySelector('.nine-tab-bar');\n const body = this.#host.shadowRoot.querySelector('nine-table-sheets-body');\n const tabItems = tabBar.querySelectorAll('nt-sheets-tab-item');\n const sheetElements = body.querySelectorAll('nine-table-sheet');\n\n if (!tabItems[index]) return;\n\n if (!isMultiSelect) {\n tabItems.forEach((tab, idx) => {\n tab.setActive(idx === index);\n });\n\n sheetElements.forEach((sheet, idx) => {\n const isActive = idx === index;\n sheet.classList.toggle('active', isActive);\n sheet.style.flex = isActive ? '1 1 100%' : '';\n });\n } else {\n const clickedTab = tabItems[index];\n const activeTabs = tabBar.querySelectorAll('nt-sheets-tab-item.active');\n\n if (clickedTab.classList.contains('active') && activeTabs.length <= 1) {\n return;\n }\n\n clickedTab.classList.toggle('active');\n const targetSheet = body.querySelector(`nine-table-sheet[data-index=\"${index}\"]`);\n if (targetSheet) {\n targetSheet.classList.toggle('active');\n if (!targetSheet.classList.contains('active')) {\n targetSheet.style.flex = '';\n }\n }\n }\n\n const activeSheets = body.querySelectorAll('nine-table-sheet.active');\n\n activeSheets?.forEach(sheet => {\n sheet.style.flex = (activeSheets.length > 1) ? '1 1 0%' : '1 1 100%';\n\n if (typeof sheet.refreshLayout === 'function') {\n sheet.refreshLayout();\n } else {\n sheet.invalidate?.();\n }\n });\n\n updateSplitters();\n };\n\n #render() {\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE'));\n\n const tabsHtml = rawTables.map((table, idx) => {\n const className = idx === 0 ? 'active' : '';\n const tabName = table.getAttribute('caption') || `Sheet ${idx + 1}`;\n\n return `<nt-sheets-tab-item class=\"${className}\" data-index=\"${idx}\">${tabName}</nt-sheets-tab-item>`;\n }).join('');\n\n this.innerHTML = `\n <div class=\"nine-tab-bar\">${tabsHtml}</div>\n <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n `;\n };\n}\n\nexport class SheetTabItem extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n }\n\n setActive(isActive) {\n this.classList.toggle('active', isActive);\n }\n}\n\nif (!customElements.get('nt-sheets-tab-item')) {\n customElements.define('nt-sheets-tab-item', SheetTabItem);\n}\n\nif (!customElements.get('nine-table-sheets-footer')) {\n customElements.define('nine-table-sheets-footer', NineTableSheetsFooter);\n}","import { trace } from \"@nopeer\";\n\nexport class Toolbar extends HTMLElement {\n #host;\n #customContainer;\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#render();\n this.#bindEvents();\n }\n\n #render() {\n this.innerHTML = `\n <div class=\"ng-toolbar-left\">\n <button type=\"button\" class=\"ng-toolbar-menu-btn\" title=\"Menu\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#374151\" stroke-width=\"2\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n </svg>\n </button>\n <span class=\"ng-toolbar-title\"></span>\n </div>\n\n <div class=\"ng-toolbar-custom\" id=\"custom-container\"></div>\n `;\n\n this.#customContainer = this.querySelector('#custom-container');\n this.#syncStateFromHost();\n }\n\n #syncStateFromHost() {\n const isSimple = this.#host.getAttribute('theme') === 'simple' || this.#host.classList.contains('simple');\n const showToolbar = this.#host.getAttribute('show-toolbar') !== 'false';\n const showMenu = this.#host.getAttribute('show-menu') !== 'false';\n const caption = this.#host.getAttribute('caption') || '';\n\n if (isSimple || !showToolbar) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n\n this.setAttribute('show-menu', showMenu ? 'true' : 'false');\n this.updateCaption(caption);\n }\n\n #bindEvents() {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) {\n titleEl.addEventListener('dblclick', () => {\n const link = '<font color=\"green\">https://www.ninegrid.net</font>';\n const currentCaption = this.#host.getAttribute('caption') || '';\n titleEl.innerHTML = titleEl.innerHTML === link ? currentCaption : link;\n });\n }\n\n const menuBtn = this.querySelector('.ng-toolbar-menu-btn');\n if (menuBtn) {\n menuBtn.addEventListener('click', () => {\n this.#host.dispatchEvent(new CustomEvent('toolbar-menu-click', {\n bubbles: true,\n composed: true,\n detail: { targetTable: this.#host }\n }));\n });\n }\n }\n\n addCustomElement(element) {\n if (this.#customContainer) {\n this.#customContainer.append(element);\n }\n }\n\n updateCaption(text) {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) titleEl.textContent = text;\n }\n}\n\nif (!customElements.get('nine-table-toolbar')) {\n customElements.define('nine-table-toolbar', Toolbar);\n}","// ui/nine-table-hscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableHScrollBar extends HTMLElement {\n #owner;\n #dragging = false;\n #elements;\n #interval1;\n #interval2;\n #resizeObserver;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#owner = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n if (!this.#owner) return;\n\n this.innerHTML = `\n <style>\n nine-table-hscrollbar {\n display: flex;\n flex-direction: row;\n width: 100%;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-hscrollbar button {\n width: 16px;\n height: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-hscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-hscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-hscrollbar .ng-scroll-left .ng-scroll-icon { transform: rotate(-135deg); }\n nine-table-hscrollbar .ng-scroll-right .ng-scroll-icon { transform: rotate(45deg); }\n nine-table-hscrollbar .ng-scroll-track {\n flex: 1;\n height: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-hscrollbar .ng-scroll-thumb {\n position: absolute;\n top: 2px;\n bottom: 2px;\n left: 0px;\n width: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-hscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-left' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-right' disabled><div class='ng-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(\".ng-scroll-track\"),\n thumb : this.querySelector(\".ng-scroll-thumb\"),\n left : this.querySelector(\".ng-scroll-left\"),\n right : this.querySelector(\".ng-scroll-right\"),\n };\n\n this.#init();\n this.#observeResize();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n disconnectedCallback() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n }\n\n #observeResize = () => {\n if (!this.#owner) return;\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) return;\n\n this.#resizeObserver = new ResizeObserver(() => {\n this.refresh();\n });\n this.#resizeObserver.observe(body);\n };\n\n refresh = () => {\n\n if (!this.#owner || !this.#elements || this.#dragging) return;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return;\n\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n\n //trace.log(bodyWidth, tableWidth, bodyWidth);\n\n // 🎯 [순수 클래스 연동] 인라인 스타일 조작 없이 오직 클래스 토글만 수행\n const needsHScroll = (bodyWidth !== 0 && tableWidth > bodyWidth);\n this.#owner.classList.toggle('hscroll-visible', needsHScroll);\n\n if (!needsHScroll) {\n return;\n }\n\n const trackWidth = track.clientWidth;\n if (trackWidth <= 0) return;\n\n const thumbWidth = Math.max(Math.min(trackWidth * (bodyWidth / tableWidth), trackWidth), 20);\n thumb.style.width = `${thumbWidth}px`;\n\n const currentLeft = body.scrollLeft;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n let l = 0;\n if (maxScrollLeft > 0) {\n l = parseInt((currentLeft / maxScrollLeft) * (trackWidth - thumbWidth), 10);\n }\n if (l < 0) l = 0;\n\n const maxThumbLeft = trackWidth - thumbWidth;\n if (l > maxThumbLeft) l = maxThumbLeft;\n\n thumb.style.left = `${l}px`;\n\n this.#elements.left.disabled = (l === 0);\n this.#elements.right.disabled = (l >= maxThumbLeft - 1);\n };\n\n #thumbMoveTo = (x) => {\n if (!this.#elements) return false;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return false;\n\n const trackBound = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n\n let targetX = x;\n if (targetX < 0) targetX = 0;\n const maxThumbLeft = trackBound.width - thumbWidth;\n if (targetX > maxThumbLeft) targetX = maxThumbLeft;\n targetX = parseInt(targetX, 10);\n\n this.#elements.thumb.style.left = `${targetX}px`;\n\n this.#elements.left.disabled = (targetX === 0);\n this.#elements.right.disabled = (targetX >= maxThumbLeft - 1);\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n if (maxThumbLeft > 0 && maxScrollLeft > 0) {\n const newScrollLeft = (targetX / maxThumbLeft) * maxScrollLeft;\n body.scrollLeft = newScrollLeft;\n }\n\n return (targetX > 0 && targetX < maxThumbLeft - 1);\n };\n\n #init = () => {\n const delayScroll = (pos) => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n\n const thumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n this.#thumbMoveTo(thumbLeft + pos);\n\n this.#interval1 = setInterval(() => {\n clearInterval(this.#interval1);\n\n this.#interval2 = setInterval(() => {\n const currentThumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n if (!this.#thumbMoveTo(currentThumbLeft + pos)) {\n clearInterval(this.#interval2);\n }\n }, 50);\n }, 500);\n };\n\n const clearTimer = () => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n };\n\n ['mouseup', 'mouseleave', 'touchend'].forEach(evt => {\n this.#elements.left.addEventListener(evt, clearTimer);\n this.#elements.right.addEventListener(evt, clearTimer);\n this.#elements.track.addEventListener(evt, clearTimer);\n });\n\n this.#elements.left.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(-20); });\n this.#elements.right.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(20); });\n this.#elements.left.addEventListener(\"touchstart\", () => delayScroll(-20));\n this.#elements.right.addEventListener(\"touchstart\", () => delayScroll(20));\n\n this.#elements.track.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.preventDefault();\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n this.#thumbMoveTo(e.clientX - trackRect.left - (thumbWidth / 2));\n });\n\n this.#elements.thumb.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n this.shiftX = e.clientX - this.#elements.thumb.getBoundingClientRect().left;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n this.#thumbMoveTo(moveEvent.clientX - trackRect.left - this.shiftX);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n clearTimer();\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n };\n}\n\nif (!customElements.get('nine-table-hscrollbar')) {\n customElements.define(\"nine-table-hscrollbar\", NineTableHScrollBar);\n}","// ui/nine-table-vscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableVScrollBar extends HTMLElement {\n #host;\n #sheet;\n #dragging = false;\n #elements;\n #startY = 0;\n #startScrollTop = 0;\n #startThumbTop = 0;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#sheet = this.closest(\"nine-table-sheet\");\n\n this.innerHTML = `\n <style>\n nine-table-vscrollbar {\n display: flex;\n flex-direction: column;\n width: 16px;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-vscrollbar button {\n height: 16px;\n width: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-vscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-vscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-vscrollbar .ng-scroll-top .ng-scroll-icon { transform: rotate(-45deg); margin-top: 2px; }\n nine-table-vscrollbar .ng-scroll-bottom .ng-scroll-icon { transform: rotate(135deg); margin-bottom: 2px; }\n \n nine-table-vscrollbar .ng-scroll-track {\n flex: 1;\n width: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-vscrollbar .ng-scroll-thumb {\n position: absolute;\n left: 2px;\n right: 2px;\n top: 0px;\n height: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-vscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-top' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-bottom' disabled><div class='ng-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(\".ng-scroll-track\"),\n thumb: this.querySelector(\".ng-scroll-thumb\"),\n top: this.querySelector(\".ng-scroll-top\"),\n bottom: this.querySelector(\".ng-scroll-bottom\"),\n };\n\n this.#init();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n #getScaleInfo = () => {\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords ? viewRecords.length : 0;\n\n // 🎯 [핵심] 그룹핑이든 일반이든 스크롤홀더(scrollHolder)가 가진 실제 가상 총 높이를 최우선으로 반영\n const scrollHolder = this.#sheet.elements?.scrollHolder;\n let rawContentHeight = scrollHolder ? parseFloat(scrollHolder.style.height) || 0 : 0;\n\n if (!rawContentHeight || rawContentHeight <= 0) {\n const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n if (isGrouped && this.#sheet.rowManager) {\n // RowManager가 관리하는 누적 높이 활용 또는 fallback\n rawContentHeight = (body.scrollHeight > body.clientHeight) ? body.scrollHeight : (totalCount * 30);\n } else {\n const rowHeight = this.#sheet.getRowHeight() || 1;\n rawContentHeight = totalCount * rowHeight;\n }\n }\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawContentHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let contentHeight = rawContentHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawContentHeight;\n contentHeight = MAX_BROWSER_HEIGHT;\n }\n\n return { rawContentHeight, contentHeight, scaleFactor, useScaling, totalCount };\n };\n\n #getViewHeight = () => {\n const body = this.#elements.container;\n if (!body) return 0;\n\n const thead = this.#sheet.elements?.body?.thead?.offsetHeight || 0;\n const tfoot = this.#sheet.elements?.body?.tfoot?.offsetHeight || 0;\n const tbodyHead = this.#sheet.elements?.body?.tbody?.head?.offsetHeight || 0;\n const fixedHeight = thead + tfoot + tbodyHead;\n\n return body.clientHeight - fixedHeight;\n };\n\n refresh = () => {\n trace.log(\"=================\", \"vscrollbar.refresh\");\n // 💡 드래그 중에는 refresh에 의한 썸 위치 덮어쓰기 차단\n if (this.#dragging) return;\n\n if (!this.#sheet || !this.#sheet.elements || !this.#elements) return;\n\n const body = this.#elements.container;\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n /**\n * const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n * (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n * this.#sheet.elements.body.tbody.head.offsetHeight;\n *\n * const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n * // 1. 전체 실제 데이터의 높이 계산\n * const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + rowHeight + fixedHeight - viewHeight, 0);\n * @type {number|*}\n */\n\n const bodyHeight = this.#getViewHeight();\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n\n const needsVScroll = (rawContentHeight > bodyHeight && rawContentHeight > 0 && bodyHeight > 0);\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 / contentHeight), trackHeight), 20);\n thumb.style.height = `${thumbHeight}px`;\n\n const currentScrollTop = body.scrollTop;\n //const maxScrollTop = Math.max(contentHeight - bodyHeight, 1);\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 1);\n\n let thumbTop = 0;\n if (maxScrollTop > 0) {\n thumbTop = (currentScrollTop / maxScrollTop) * (trackHeight - thumbHeight);\n }\n\n const maxThumbTop = trackHeight - thumbHeight;\n if (thumbTop < 0) thumbTop = 0;\n if (thumbTop > maxThumbTop) thumbTop = maxThumbTop;\n\n thumb.style.top = `${thumbTop}px`;\n\n /**\n // 🎯 [디버깅 로그] 스크롤바가 리프레시될 때 현재 상태 로깅\n trace.log(\"🔍 [VScroll Refresh]\", {\n isGrouped: this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false,\n totalCount,\n bodyScrollTop: currentScrollTop,\n maxScrollTop,\n thumbTop,\n maxThumbTop\n }); */\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n #init = () => {\n trace.log(\"nine-table-vscrollbar.#init\");\n\n const body = this.#elements.container;\n\n this.#elements.thumb.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n\n this.#startY = e.clientY;\n this.#startThumbTop = parseFloat(this.#elements.thumb.style.top) || 0;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const trackHeight = trackRect.height;\n const thumbHeight = this.#elements.thumb.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n if (maxThumbTop <= 0) return;\n\n //this.#elements.container.scrollTop = 0;\n\n const deltaY = moveEvent.clientY - this.#startY;\n let targetThumbTop = this.#startThumbTop + deltaY;\n\n if (targetThumbTop < 0) targetThumbTop = 0;\n if (targetThumbTop > maxThumbTop) targetThumbTop = maxThumbTop;\n\n // 썸 위치 즉시 고정\n this.#elements.thumb.style.top = `${targetThumbTop}px`;\n\n const ratio = targetThumbTop / maxThumbTop;\n\n const rowHeight =this.#sheet.getRowHeight();\n const viewHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0) -\n (this.#sheet.elements.body.thead?.offsetHeight || 0) -\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) -\n (this.#sheet.elements.body.tbody.head.offsetHeight || 0);\n\n const visibleRowCount = Math.floor(viewHeight / rowHeight);\n\n const { totalCount } = this.#getScaleInfo();\n //const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n const targetRow = Math.floor(ratio * (totalCount - visibleRowCount + 1));\n // 1000010 - 6\n this.#sheet.rowManager.scrollToDataRow(targetRow);\n\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n const currentScrollTop = this.#elements.container.scrollTop;\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 0);\n\n //trace.log(\"*****************\", visibleRowCount, ratio, totalCount, targetRow);\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n //this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n\n this.#elements.track.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0 || e.target === this.#elements.thumb) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbHeight = this.#elements.thumb.clientHeight;\n const trackHeight = this.#elements.track.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n if (maxThumbTop > 0) {\n const clickY = e.clientY - trackRect.top - (thumbHeight / 2);\n const ratio = Math.max(0, Math.min(1, clickY / maxThumbTop));\n\n const { totalCount } = this.#getScaleInfo();\n const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n\n trace.log(\"🎯 [VScroll Track Click]\", { ratio, clickY, totalCount, targetRow });\n\n if (targetRow >= 0 && this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n }\n this.refresh();\n });\n\n this.#elements.top.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = Math.max(0, currentTopRow - 1);\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n\n this.#elements.bottom.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = currentTopRow + 1;\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n };\n}\n\nif (!customElements.get('nine-table-vscrollbar')) {\n customElements.define(\"nine-table-vscrollbar\", NineTableVScrollBar);\n}","import { trace } from \"@nopeer\";\r\n\r\n// 💡 배열 인덱스 상수 정의\r\nexport const GROUP_IDX = {\r\n\tID: 0,\r\n\tDEPTH: 1,\r\n\tNAME: 2,\r\n\tCHILDREN: 3,\r\n};\r\n\r\nexport class GroupingManager {\r\n\t#sheet;\r\n\t#host;\r\n\t#groupColumns = [];\r\n\t#groupMap = new Map(); // 그룹별 자식 ID 매핑 관리용\r\n\t#isApplying = false;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t}\r\n\r\n\tget columns() {\r\n\t\treturn this.#groupColumns;\r\n\t}\r\n\r\n\tget groupMap() {\r\n\t\treturn this.#groupMap;\r\n\t}\r\n\r\n\tinitialize = () => {\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\t};\r\n\r\n\tapply() {\r\n\r\n\t\ttrace.log(\"==================\", \"Grouping.Apply\");\r\n\r\n\t\tif (this.#isApplying) return;\r\n\t\tthis.#isApplying = true;\r\n\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\r\n\t\t// 💡 데이터 캐시와 렌더링 아이템은 이제 SheetView 단일 파이프라인에서 관리하므로\r\n\t\t// 그룹핑 설정이 바뀌면 SheetView.refresh()를 호출해 전체 흐름을 일괄 재계산합니다.\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh(); // 🎯 SheetView에서 필터/정렬/그룹핑 일괄 처리\r\n\t}\r\n\r\n\tclear() {\r\n\t\tthis.#groupColumns = [];\r\n\t\tthis.#groupMap.clear();\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh();\r\n\t}\r\n\r\n\t// SheetView가 그룹핑 연산 후 groupMap을 공유할 수 있도록 설정 메서드 제공\r\n\tsetGroupMap(map) {\r\n\t\tthis.#groupMap = map;\r\n\t}\r\n\r\n\tgetChildrenRowIds(groupId) {\r\n\t\treturn this.#groupMap.get(groupId) || [];\r\n\t}\r\n\r\n\tgetChildrenRecords(groupId) {\r\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\r\n\t\tconst dataManager = this.#host.data;\r\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\r\n\t}\r\n}\r\n\r\nexport class Grouping {\r\n\r\n\tstatic apply(rawRecords, groupColumns = [], fields = []) {\r\n\t\tif (!groupColumns || groupColumns.length === 0) {\r\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\r\n\t\t}\r\n\r\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\r\n\t\tconst groupMap = new Map();\r\n\r\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\r\n\t\tconst flatResult = [];\r\n\t\tconst renderItems = [];\r\n\r\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\");\r\n\r\n\t\treturn { headers: flatResult, renderItems, groupMap };\r\n\t}\r\n\r\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId) {\r\n\t\tlet counter = 0;\r\n\t\tconst isLastLevel = (depth === groupColumns.length - 1); // 💡 연산자 수정 반영\r\n\r\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\r\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\r\n\r\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\r\n\t\t\tgroupMap.set(groupId, rowIds);\r\n\r\n\t\t\tconst groupRecord = [];\r\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\r\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\r\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\r\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\r\n\r\n\t\t\tgroupRecord.__isGroupHeader = true;\r\n\t\t\tgroupRecord.__groupId = groupId;\r\n\r\n\t\t\tresultArr.push(groupRecord);\r\n\r\n\t\t\trenderItems.push({\r\n\t\t\t\ttype: 'group',\r\n\t\t\t\trecord: groupRecord,\r\n\t\t\t\tgroupId: groupId\r\n\t\t\t});\r\n\r\n\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\r\n\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId);\r\n\t\t\t} else {\r\n\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\r\n\t\t\t\tleafRecords.forEach(record => {\r\n\t\t\t\t\trecord.__isGroupHeader = false;\r\n\t\t\t\t\trecord.__groupId = groupId;\r\n\t\t\t\t\tresultArr.push(record);\r\n\r\n\t\t\t\t\trenderItems.push({\r\n\t\t\t\t\t\ttype: 'data',\r\n\t\t\t\t\t\trecord: record,\r\n\t\t\t\t\t\tgroupId: groupId\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tstatic #buildNestedMap(records, groupColumns, fields) {\r\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\r\n\t\tconst remainingCols = groupColumns.slice(1);\r\n\t\tconst map = new Map();\r\n\r\n\t\trecords.forEach(record => {\r\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\r\n\t\t\tif (!map.has(key)) map.set(key, []);\r\n\t\t\tmap.get(key).push(record);\r\n\t\t});\r\n\r\n\t\tif (remainingCols.length > 0) {\r\n\t\t\tconst result = new Map();\r\n\t\t\tfor (let [key, subRecords] of map.entries()) {\r\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n\tstatic #collectLeafRowIds(subMapOrRecords) {\r\n\t\tlet rowIds = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\r\n\t\t}\r\n\t\treturn rowIds;\r\n\t}\r\n\r\n\tstatic #collectLeafRecords(subMapOrRecords) {\r\n\t\tlet records = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trecords = records.concat(subMapOrRecords);\r\n\t\t}\r\n\t\treturn records;\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { GROUP_IDX } from \"@/data/Grouping.js\";\n\nexport class RowManager {\n #BUFFER_ROW_COUNT = 3;\n\n #host;\n #sheet;\n #element;\n\n #containerTemplates = new Map();\n\n #templateRowHeights = []; // 💡 [추가] 템플릿 행별 개별 높이 보관 ([그룹1, 그룹2, 데이터])\n #cachedTemplateHeight = null;\n\n #resizeObserver = null;\n #sheetHeight = 0;\n #cachedRowCount;\n\n #isProgrammaticScroll = false;\n #isGrouped = false;\n\n constructor(sheet) {\n this.#host = sheet.getRootNode().host;\n this.#sheet = sheet;\n\n this.#initResizeObserver();\n }\n\n // ==========================================\n // 🎯 Public APIs & Getters\n // ==========================================\n\n getRowHeight() {\n return this.#templateRowHeights.reduce((sum, h) => sum + h, 0);//this.#cachedTemplateHeight;\n }\n\n\n refresh = (force = false) => {\n //trace.log(\"rowManager.refresh\", { force });\n\n //this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[group='true']\") ? true : false;\n\n if (!this.#sheet.classList.contains('active')) return;\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n const wasInvalidHeight = !this.#cachedTemplateHeight || this.#cachedTemplateHeight <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#cachedTemplateHeight && this.#cachedTemplateHeight > 0) {\n this.#renderAllContainers();\n }\n }\n\n\n //this.#updateFooterSpacing();\n\n this.#handleScroll(bodyViewport.scrollTop, force);\n\n this.#sheet.querySelector('nine-table-vscrollbar')?.refresh();\n };\n\n #handleScroll = (scrollTop, force = false) => {\n\n //this.#sheet.querySelector('.ng-sheet-body').scrollTop = 0;\n\n\n if (this.#isGrouped) {\n this.#handleGroupedScroll(scrollTop, force);\n return;\n }\n\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) return;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n if (totalCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n // 🎯 [핵심] 브라우저 DOM 최대 높이 제한 대응 (약 1,500만 픽셀 상한선)\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let totalVirtualHeight = rawTotalVirtualHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n totalVirtualHeight = MAX_BROWSER_HEIGHT;\n }\n //trace.log(totalCount, rowHeight, rawTotalVirtualHeight, MAX_BROWSER_HEIGHT);\n // 스크롤홀더에는 브라우저가 소화할 수 있는 최대 높이만 부여\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n //trace.log(\"*************\",this.#sheet.querySelector('.ng-sheet-body').clientHeight, this.#sheet.querySelector('.ng-sheet-body').offsetHeight, viewHeight, fixedHeight, rawTotalVirtualHeight, totalVirtualHeight);\n\n //trace.log(totalVirtualHeight);\n // 🎯 스크롤바 위치(scrollTop)를 실제 데이터 좌표계로 역환산\n const actualScrollTop = useScaling ? (scrollTop / scaleFactor) : scrollTop;\n\n const maxStartIndex = Math.max(0, totalCount - 1);\n const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n\n // 실제 데이터 좌표 기준으로 시작 인덱스 산출 (원하시는 -1 보정 유지)\n const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight) - 1, maxStartIndex));\n // 🎯 -1 보정을 제거하여 최하단까지 정확히 매핑되도록 수정\n //const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n //trace.log(startIndex, clampedScrollTop, totalVirtualHeight, fixedHeight, rowHeight);\n\n // 🎯 화면 렌더링 오프셋도 '실제 데이터 좌표(clampedScrollTop)' 기준의 모듈러 연산 적용\n const renderOffsetTop = clampedScrollTop % rowHeight;\n this.#sheet.elements.left.tbody.body.style.top =\n this.#sheet.elements.body.tbody.body.style.top =\n this.#sheet.elements.right.tbody.body.style.top = `-${renderOffsetTop}px`;\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.row !== undefined ? parseInt(firstTr.dataset.row, 10) : -1;\n\n if (!force && currentStartIndex === startIndex) {\n //trace.log(`[Perf ${getTimestamp()}] ⏭️ 인덱스 동일로 스킵! 총 소요: ${(performance.now() - startTime).toFixed(2)}ms`);\n return;\n }\n\n //trace.log(`${getTimestamp()}`);\n\n\n // [범인 구간 추적]\n [\n this.#sheet.elements.left.tbody.body,\n this.#sheet.elements.body.tbody.body,\n this.#sheet.elements.right.tbody.body\n ].forEach(($tbody, tbodyIdx) => {\n if (!$tbody) return;\n\n const rows = $tbody.querySelectorAll('tbody.body tr');\n\n //trace.log(`${getTimestamp()}`);\n\n rows.forEach(($tr, index) => {\n const dataIndex = startIndex + Math.floor(index / templateLength);\n\n if (dataIndex >= totalCount) {\n $tr.style.display = 'none';\n $tr.dataset.matrixRow = null;\n $tr.dataset.row = null;\n return;\n }\n\n // trace.log(`${getTimestamp()}`);\n const record = viewRecords[dataIndex];//this.#sheet.view.getArray(dataIndex);\n //trace.log(`${getTimestamp()}`);\n\n if (!record) {\n $tr.style.display = 'none';\n return;\n }\n\n const rowid = record.m._[NINE_TABLE.META.INDEX.ROWID];\n\n $tr.style.display = '';\n\n // 💡 만약 개별 바인딩 안에서 느린지 확인하려면 여기서 측정 가능\n this.#bindRowData($tr, record, rowid, dataIndex);\n });\n });\n\n // 셀렉션 갱신\n this.#sheet.selection.refresh();\n };\n\n\n #handleGroupedScroll = (scrollTop, force = false) => {\n\n trace.log(\"handleGroupdScroll() start\")\n\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n //trace.log(allRenderItems);\n\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.templateLength || 1;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH] || 0;\n // 💡 해당 뎁스 그룹 행의 높이가 정확히 잡히는지 확인 (없으면 첫 번째 템플릿 높이)\n const groupHeight = this.#templateRowHeights[depth] || this.#cachedTemplateHeight / templateLength;\n return groupHeight;\n } else {\n // 💡 데이터 행은 전체 템플릿 높이에서 그룹 TR들을 제외한 순수 데이터 TR들의 높이 합산이어야 합니다.\n // 만약 templateLength가 1이고 일반 행이라면 아래와 같이 처리\n let dataRowsHeight = 0;\n // templateRowHeights 전체 중에서 그룹이 아닌 데이터 행들의 높이만 합산하거나,\n // 단일 데이터 템플릿 높이를 정확히 반환해야 합니다.\n const templateLength = this.#sheet.templateLength || 1;\n\n // 간단하게 전체 캐시된 템플릿 높이에서 그룹 높이들을 뺀 나머지를 데이터 높이로 산정\n let groupHeightsTotal = 0;\n for(let i = 0; i < templateLength - 1; i++) {\n groupHeightsTotal += this.#templateRowHeights[i] || 0;\n }\n dataRowsHeight = this.#cachedTemplateHeight - groupHeightsTotal;\n\n return dataRowsHeight > 0 ? dataRowsHeight : this.#cachedTemplateHeight;\n }\n };\n\n\n let totalVirtualHeight = 0;\n const itemHeights = new Array(totalVirtualCount);\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = getItemHeight(allRenderItems[i]);\n itemHeights[i] = h;\n totalVirtualHeight += h;\n }\n\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n trace.log(\"*************\", totalVirtualHeight);\n\n const viewportClientHeight = this.#sheet.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = 0;\n\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = itemHeights[i];\n if (accumulatedHeight + h > scrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n //trace.log(startIndex);\n\n const offsetY = scrollTop - accumulatedHeight;\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.virtualIndex !== undefined\n ? parseInt(firstTr.dataset.virtualIndex, 10)\n : -1;\n\n if (!force && currentStartIndex === startIndex) {\n return;\n }\n\n const visibleRowsCount = Math.ceil(viewportClientHeight / (this.#cachedTemplateHeight / templateLength));\n const dynamicBuffer = (this.#sheet.grouping.columns?.length || 1) * 15;\n const targetStart = startIndex;\n const targetEnd = Math.min(totalVirtualCount, startIndex + visibleRowsCount + dynamicBuffer);\n\n\n\n\n const renderedItems = allRenderItems.slice(targetStart, targetEnd);\n\n //trace.log(\"handleGroupdScroll() 22\", renderedItems);\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const trs = Array.from(container.querySelectorAll('tbody.body tr'));\n\n for (let i = 0; i < trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = trs.slice(i, i + templateLength);\n\n if (!item || itemIndex >= renderedItems.length) {\n chunkTrs.forEach(tr => {\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.style.display = 'none';\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 }\n } else {\n tr.style.display = 'none';\n }\n } else {\n if (isTrGroup) {\n tr.style.display = 'none';\n } else {\n tr.style.display = '';\n\n //trace.log(item.record)\n const rowid = item.record.m?.rowid ?? 0;\n this.#bindRowData(tr, item.record, rowid, virtualIndex);\n }\n }\n });\n }\n });\n\n this.#sheet.selection.refresh();\n\n trace.log(\"handleGroupdScroll() end\")\n };\n\n #bindGroupRowData = ($tr, allRenderItems, groupRecord, virtualIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (virtualIndex * templateLength) + subRowIndex;\n\n const indices = groupRecord[GROUP_IDX.CHILDREN]; // 인덱스 배열이 들어있는 위치 (정확한 인덱스는 구조에 맞게 조절)\n const allRecords = this.#host.data.getArray();\n const childrenRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n // 필요하다면 groupRecord나 tr에 자식 레코드들을 캐싱해 둘 수도 있습니다.\n //groupRecord.childrenRecords = childrenRecords;\n\n //trace.log(allRecords, childrenRecords);\n\n\n $tr.dataset.virtualIndex = virtualIndex;\n $tr.dataset.row = '';\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = childrenRecords;//groupRecord;\n $tr.dataset.groupId = groupRecord[GROUP_IDX.ID];\n\n //trace.log(tr, groupRecord)\n\n Array.from($tr.cells).forEach(($cell) => {\n\n $cell.dataset.row = virtualIndex;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') || typeof $el.refresh === 'function'\n );\n\n //trace.log(customComp)\n\n if (customComp !== undefined && typeof customComp.refresh === 'function') {\n customComp?.refresh();\n }\n });\n };\n\n #bindRowData = ($tr, record, rowid, dataIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (dataIndex * templateLength) + subRowIndex;\n\n $tr.dataset.index = dataIndex;\n $tr.dataset.row = rowid;\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = record;\n\n Array.from($tr.cells).forEach(($cell) => {\n $cell.dataset.index = dataIndex;\n $cell.dataset.row = rowid;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.refresh === 'function'\n );\n\n customComp?.refresh();\n });\n };\n\n initialize = () => {\n //trace.log(\"rowManager.initialize\");\n\n this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n\n this.#cachedTemplateHeight = null;\n this.#containerTemplates.clear();\n\n this.#element = {\n scrollTables: this.#sheet.querySelectorAll('.ng-sheet-body table'),\n firstTr: this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body tr'),\n };\n\n // 컨테이너 템플릿 수집 부분도 tbody.body 기준으로 변경\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const tableEl = container.querySelector('table');\n if (!tableEl) return;\n\n const tbody = tableEl.querySelector('tbody.body'); // 👈 .bindable-tbody 대신 tbody.body\n if (!tbody) return;\n\n const trs = Array.from(tbody.querySelectorAll('tr'));\n const templateTrs = trs.map(tr => tr.cloneNode(true));\n this.#containerTemplates.set(selector, templateTrs);\n });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n if (bodyViewport) {\n this.#sheetHeight = bodyViewport.clientHeight;\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', () => {\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#cachedTemplateHeight || 0;\n const totalCount = this.#sheet.view.getArray()?.length || 0;\n const rawTotalVirtualHeight = totalCount * rowHeight;\n\n if (rawTotalVirtualHeight <= bodyViewport.clientHeight) {\n return;\n }\n\n this.#handleScroll(bodyViewport.scrollTop);\n\n this.#sheet.querySelector('nine-table-vscrollbar').refresh();\n //this.#sheet.querySelector('nine-table-hscrollbar').refresh();\n }, { passive: true });\n }\n };\n\n scrollToDataRow(dataRow, align = 'top', onRendered) {\n //trace.log(\"🔍 [scrollToDataRow ENTER]\", { dataRow, isGrouped: this.#isGrouped });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords?.length || 0;\n if (totalCount === 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const targetRow = Math.max(0, Math.min(dataRow, totalCount - 1));\n let targetScrollTop = 0;\n\n // 🎯 [핵심] 그룹핑 모드일 때는 실제 scrollHeight(또는 렌더링된 총 높이)를 기준으로 비율 계산\n if (this.#isGrouped) {\n const maxScrollTop = Math.max(bodyViewport.scrollHeight - bodyViewport.clientHeight, 1);\n // targetRow가 전체 totalCount에서 차지하는 비율(ratio)만큼 실제 스크롤 최대 높이에 곱해줌\n const ratio = targetRow / Math.max(totalCount - 1, 1);\n targetScrollTop = ratio * maxScrollTop;\n } else {\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n let rawTargetScrollTop = targetRow * rowHeight;\n\n /**\n if (align === 'bottom') {\n const viewportHeight = bodyViewport.clientHeight;\n const visibleRowsCount = Math.floor(viewportHeight / rowHeight);\n const adjustedRow = Math.max(0, targetRow - visibleRowsCount + 1);\n rawTargetScrollTop = adjustedRow * rowHeight;\n } */\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n //const rawTotalVirtualHeight = totalCount * rowHeight;\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n }\n\n targetScrollTop = rawTargetScrollTop * scaleFactor;\n }\n\n //trace.log(\"🔍 [scrollToDataRow CALC FIXED]\", { targetRow, totalCount, targetScrollTop });\n\n this.#isProgrammaticScroll = true;\n bodyViewport.scrollTop = targetScrollTop;\n this.#handleScroll(targetScrollTop);\n //trace.log(targetScrollTop);\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.#isProgrammaticScroll = false;\n if (typeof onRendered === 'function') onRendered();\n });\n });\n }\n\n\n\n destroy = () => {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n };\n\n #measureAndCacheHeight = () => {\n if (!this.#sheet.classList.contains('active')) return;\n\n if (!this.#sheet.sourceTable) return;\n\n const trTemplates = this.#sheet.sourceTable?.querySelectorAll('tbody.body tr');\n //trace.log(\"[DEBUG #measureAndCacheHeight] bodyTemplates count:\", trTemplates?.length);\n //if (!trTemplates || trTemplates.length === 0) return;\n\n const $tbody = this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body');\n //if (!tbody) return -1;\n\n $tbody.querySelectorAll('tr').forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n trTemplates.forEach($tr => fragment.appendChild($tr.cloneNode(true)));\n $tbody.appendChild(fragment);\n\n //let totalHeight = 0;\n const renderedTrs = $tbody.querySelectorAll('tr');\n\n this.#templateRowHeights = [];\n renderedTrs.forEach($tr => {\n //const h = $tr.offsetHeight;\n //trace.log(`[DEBUG #measureAndCacheHeight] tr[${idx}] height:`, h);\n //totalHeight += h;\n\n this.#templateRowHeights.push($tr.offsetHeight);\n });\n\n renderedTrs.forEach(tr => tr.remove());\n\n this.#cachedTemplateHeight = this.#templateRowHeights.reduce((sum, h) => sum + h, 0);\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n trace.log(\"[DEBUG #updateRowCount] sheetHeight:\", this.#sheetHeight, \"cachedTemplateHeight:\", this.#cachedTemplateHeight);\n if (this.#sheetHeight > 0 && this.#cachedTemplateHeight > 0) {\n const visibleRows = Math.ceil(this.#sheetHeight / this.#cachedTemplateHeight);\n\n // 💡 [유연한 개선] 그룹화가 켜져 있다면 그룹 컬럼 깊이(다단 레벨)에 따라 버퍼를 동적으로 확장\n let dynamicBuffer = this.#BUFFER_ROW_COUNT;\n if (this.#isGrouped && this.#sheet.grouping) {\n const groupDepth = this.#sheet.grouping.columns?.length || 1;\n // 그룹 단계가 깊을수록 헤더 행이 많이 차지하므로 여유분을 비례해서 늘림 (예: 기본 버퍼 + (뎁스당 추가 여유))\n dynamicBuffer += (groupDepth * 15);\n }\n\n this.#cachedRowCount = visibleRows + dynamicBuffer;\n trace.log(\"[DEBUG #updateRowCount] calculated cachedRowCount:\", this.#cachedRowCount);\n }\n };\n\n #renderAllContainers = () => {\n trace.log(\"rowManager.#renderAllContainers\");\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (container && container.querySelector('tbody')) {\n this.#renderRows(container); // selector 인자 제거!\n }\n });\n\n this.#syncRowHeights();\n };\n\n #renderRows = (container) => {\n let targetFixedType = null;\n if (container.classList.contains('ng-container-left')) targetFixedType = 'left';\n else if (container.classList.contains('ng-container-right')) targetFixedType = 'right';\n\n // 🎯 [수정] 원본 테이블에서 tbody.body에 해당하는 tr들만 복제\n const templateTrs = Array.from(this.#sheet.sourceTable.querySelectorAll('tbody.body tr')).map(tr => {\n const clonedTr = tr.cloneNode(true);\n\n if (targetFixedType === 'left') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'left') $cell.remove();\n });\n } else if (targetFixedType === 'right') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'right') $cell.remove();\n });\n } else {\n clonedTr.querySelectorAll('[fixed=left], [fixed=right]').forEach($cell => {\n $cell.remove();\n });\n }\n\n return clonedTr;\n });\n\n if (templateTrs.length === 0) return;\n\n // 🎯 [수정] targetTbody도 일반 tbody가 아니라 tbody.body를 정확히 타겟팅\n const targetTbody = container.querySelector('tbody.body');\n if (!targetTbody) return;\n\n targetTbody.querySelectorAll(\"tr\").forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < this.#cachedRowCount; i++) {\n templateTrs.forEach(tmpl => fragment.appendChild(tmpl.cloneNode(true)));\n }\n\n\n targetTbody.appendChild(fragment);\n\n if (container.classList.contains('ng-container-body')) {\n this.#element.firstTr = targetTbody.querySelector('tr');\n }\n };\n\n\n\n #syncRowHeights = () => {\n const leftTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-left table');\n const bodyTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-body table');\n const rightTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-right table');\n\n if (bodyTable) {\n const leftRows = leftTable ? Array.from(leftTable.querySelectorAll('tbody tr')) : [];\n const bodyRows = Array.from(bodyTable.querySelectorAll('tbody tr'));\n const rightRows = rightTable ? Array.from(rightTable.querySelectorAll('tbody tr')) : [];\n\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n }\n };\n\n #initResizeObserver = () => {\n\n if (!this.#sheet || !(this.#sheet instanceof HTMLElement)) return;\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const sheetEl = entry.target;\n if (!sheetEl.classList.contains('active')) continue;\n\n const height = entry.contentRect.height;\n const width = entry.contentRect.width;\n\n if (width > 0 && this.#sheet.isAutoFitCol) {\n this.#sheet.autoFit(true);\n }\n\n if (height > 0 && this.#sheetHeight !== height) {\n this.#sheetHeight = height;\n this.#updateRowCount();\n\n if (this.#cachedTemplateHeight !== null) {\n this.#renderAllContainers();\n this.refresh();\n }\n }\n }\n });\n\n this.#resizeObserver.observe(this.#sheet);\n };\n}","import { trace } from \"@nopeer\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class TableCompiler {\n\n static compile($srcTable) {\n\n const $table = $srcTable.cloneNode(true);\n\n // 1. 헤더 컴파일\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n // 4. colgroup과 인덱스/fixed 속성 동기화\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n static recompile($table) {\n\n /** 너비조정은 필요없을듯 */\n /**\n const cols = Array.from($table.querySelectorAll('colgroup col'));\n cols.forEach((col, idx) => {\n //trace.log(col.cloneNode(true));\n\n col.setAttribute('data-col', idx);\n\n let w = col.getAttribute('width');\n if (!w || isNaN(parseFloat(w))) {\n w = parseFloat(col.style.width);\n }\n if (w && !isNaN(parseFloat(w))) {\n const numericWidth = Math.round(parseFloat(w));\n //trace.log(w, numericWidth);\n\n col.setAttribute('width', numericWidth);\n col.style.width = `${numericWidth}px`;\n }\n }); */\n\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n\n\n static #syncColAttributes($table) {\n\n $table.querySelectorAll('colgroup col').forEach(($col, i) => {\n $col.setAttribute('data-col', i);\n const fixed = $col.getAttribute('fixed');\n\n $table.querySelectorAll(`[data-col=\"${i}\"]`).forEach($el => {\n fixed ? $el.setAttribute('fixed', fixed) : $el.removeAttribute('fixed');\n });\n });\n }\n\n static resetColIndex($table, trs) {\n\n const cols = $table.querySelectorAll('colgroup col');\n const grid = Array.from({ length: trs.length }, () => Array(cols.length).fill(null));\n\n trs.forEach(($tr, index) => {\n\n $tr.dataset.subrow = index;\n\n let colIndex = 0;\n\n $tr.querySelectorAll('th, td').forEach($cell => {\n\n while (colIndex < cols.length && grid[index][colIndex] !== null) {\n colIndex++;\n }\n\n $cell.dataset.col = colIndex;\n\n const rowSpan = $cell.rowSpan || 1;\n const colSpan = $cell.colSpan || 1;\n\n for (let r = 0; r < rowSpan; r++) {\n for (let c = 0; c < colSpan; c++) {\n if (index + r < trs.length && colIndex + c < cols.length) {\n grid[index + r][colIndex + c] = $cell;\n }\n }\n }\n\n colIndex += colSpan;\n });\n });\n }\n\n\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellSelection {\r\n\t#sheet;\r\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#initEvents();\r\n\r\n\t\t/**\r\n\t\t// 🎯 [신규 구조 대응] .ng-sheet-body 및 내부 컨테이너 스크롤 감지\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (bodyViewport) {\r\n\t\t\tbodyViewport.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t} */\r\n\r\n\t\t/**\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}); */\r\n\r\n\t\ttrace.log(\"🎯 [CellSelection] Initialized (New Structure Compatible)\");\r\n\t}\r\n\r\n\t#getMatrixRow(tr) {\r\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10);\r\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr:not(.nodata)'));\r\n\r\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.row, 10) === dataRow);\r\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\r\n\t\tconst templateLength = sameGroupTrs.length > 0 ? sameGroupTrs.length : 1;\r\n\r\n\t\tconst matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\r\n\r\n\t\treturn { dataRow, subRowIndex, matrixRow };\r\n\t}\r\n\r\n\tsetFocus(matrixRow, col) {\r\n\t\t// 1. 기존 포커스 클래스 제거\r\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {$tr.classList.remove(\"selected-start\");\r\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {$td.classList.remove(\"selected-start\");\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 [신규 구조 대응] data-matrix-row 탐색 경로 수정 (.ng-sheet-body-content 기준)\r\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!$td) return;\r\n\r\n\t\t$td.classList.add(\"selected-start\");\r\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\r\n\t}\r\n\r\n\tsetRange(startRow, startCol, endRow, endCol) {\r\n\t\tlet r1 = Math.min(startRow, endRow);\r\n\t\tlet r2 = Math.max(startRow, endRow);\r\n\t\tlet c1 = Math.min(startCol, endCol);\r\n\t\tlet c2 = Math.max(startCol, endCol);\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tlet expanded = true;\r\n\t\tlet loopCount = 0;\r\n\r\n\t\twhile (expanded && loopCount < 5) {\r\n\t\t\texpanded = false;\r\n\t\t\tloopCount++;\r\n\r\n\t\t\tcontainers.forEach(container => {\r\n\t\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\t\tif (tr.classList.contains('nodata')) return;\r\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\r\n\t\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\r\n\r\n\t\t\t\t\t\tif (isIntersecting) {\r\n\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\r\n\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\r\n\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\r\n\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\r\n\r\n\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\r\n\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\r\n\t\t\t\t\t\t\t\texpanded = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#range = { startRow: r1, startCol: c1, endRow: r2, endCol: c2 };\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trefresh = () => {\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trender = () => {\r\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\t// 1. 기존 선택 클래스 초기화\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\r\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\r\n\t\t\t});\r\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\r\n\t\t\t\ttr.classList.remove('selected-start');\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tif (startRow < 0 || startCol < 0) return;\r\n\r\n\t\t// 2. 범위 렌더링\r\n\t\tcontainers.forEach((container) => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\r\n\t\t\t\t\tif (!isSelected) return;\r\n\r\n\t\t\t\t\tcell.classList.add('selected');\r\n\r\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\r\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\r\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\r\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 3. 포커스 셀 복구\r\n\t\tconst $focusTd = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${startRow}\"] td[data-col=\"${startCol}\"]`);\r\n\t\tif ($focusTd) {$focusTd.classList.add(\"selected-start\");\r\n\t\t\t$focusTd.closest('tr')?.classList.add(\"selected-start\");\r\n\t\t}\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!mainZone) {\r\n\t\t\ttrace.log(\"❌ [CellSelection] .ng-sheet-body not found!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmainZone.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tif (cell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\tthis.#sheet.style.userSelect = 'none';\r\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\r\n\r\n\t\t\tconst tr = cell.closest('tr');\r\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\r\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\r\n\r\n\t\t\tif (startRow < 0) {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tthis.setFocus(startRow, startCol);\r\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\r\n\r\n\t\t\tlet lastMatrixRow = startRow;\r\n\t\t\tlet lastCol = startCol;\r\n\r\n\t\t\tconst onMouseMove = (moveEvent) => {\r\n\t\t\t\tconst targetEl = document.elementFromPoint(moveEvent.clientX, moveEvent.clientY);\r\n\t\t\t\tlet targetCell = targetEl?.closest('td, th');\r\n\r\n\t\t\t\tif (!targetCell || !this.#sheet.contains(targetCell)) {\r\n\t\t\t\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr:not(.nodata) td, .ng-sheet-body-content tbody tr:not(.nodata) th');\r\n\t\t\t\t\tfor (const c of allCells) {\r\n\t\t\t\t\t\tconst rect = c.getBoundingClientRect();\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tmoveEvent.clientX >= rect.left &&\r\n\t\t\t\t\t\t\tmoveEvent.clientX <= rect.right &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY >= rect.top &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY <= rect.bottom\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\ttargetCell = c;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!targetCell) return;\r\n\t\t\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\r\n\t\t\t\tif (targetCell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\t\tconst targetTr = targetCell.closest('tr');\r\n\t\t\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\r\n\t\t\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\r\n\r\n\t\t\t\tif (endRow < 0) return;\r\n\t\t\t\tif (lastMatrixRow === endRow && lastCol === endCol) return;\r\n\r\n\t\t\t\tlastMatrixRow = endRow;\r\n\t\t\t\tlastCol = endCol;\r\n\r\n\t\t\t\tthis.setRange(startRow, startCol, endRow, endCol);\r\n\t\t\t};\r\n\r\n\t\t\tconst onMouseUp = () => {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\r\n\t\t\t\tdocument.removeEventListener('mousemove', onMouseMove);\r\n\t\t\t\tdocument.removeEventListener('mouseup', onMouseUp);\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener('mousemove', onMouseMove);\r\n\t\t\tdocument.addEventListener('mouseup', onMouseUp);\r\n\t\t});\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellNavigation {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#currentCell = null;\r\n\t#currentTr = null;\r\n\t#currentRow = -1;\r\n\t#currentCol = -1;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.#initEvents();\r\n\t\ttrace.log(\"🎯 [CellNavigation] Initialized (Diagnostic Logging Restored)\");\r\n\t}\r\n\r\n\tget currentCell() {\r\n\t\treturn this.#currentCell;\r\n\t}\r\n\r\n\tset currentCell(cell) {\r\n\t\tif (!cell) return;\r\n\r\n\t\tthis.#currentCell = cell;\r\n\t\tcell.focus({ preventScroll: true });\r\n\r\n\t\tthis.#currentTr = cell.closest(\"tr\");\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\ttrace.log(`📌 [setCurCell] Active set -> dataRow: ${cell.dataset.row}, subrow: ${cell.closest('tr')?.dataset.subrow}, matrixRow: ${matrixRow}, col: ${cell.dataset.col}`);\r\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\r\n\t}\r\n\r\n\t#getMatrixRowFromTr(tr) {\r\n\t\tif (!tr) return 0;\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10) || 0;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\t// 1. tr에 data-matrix-row가 박혀있다면 최우선 사용\r\n\t\tconst mRowAttr = parseInt(tr.dataset.matrixRow, 10);\r\n\t\tif (!isNaN(mRowAttr)) return mRowAttr;\r\n\r\n\t\t// 2. tbody 내에서 동일 data-row를 가진 그룹 중 몇 번째 서브 행인지 정확히 산출\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tif (tbody) {\r\n\t\t\tconst groupTrs = Array.from(tbody.querySelectorAll(`tr[data-row=\"${dataRow}\"]`));\r\n\t\t\tconst subIdx = groupTrs.indexOf(tr);\r\n\t\t\tif (subIdx >= 0) {\r\n\t\t\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\t\t\treturn (dataRow * templateLength) + subIdx;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst subRowIndex = parseInt(tr.dataset.subrow, 10) || 0;\r\n\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\treturn (dataRow * templateLength) + subRowIndex;\r\n\t}\r\n\r\n\tmoveCell(e) {\r\n\r\n\t\t//trace.log(e.target.tagName);\r\n\t\tif (![\"TH\",\"TD\"].includes(e.target.tagName)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!this.#currentCell || !this.#currentTr) {\r\n\t\t\ttrace.log(\"⚠️ [moveCell] currentCell or currentTr is missing!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst cell = this.#currentCell;\r\n\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\tlet nextMatrixRow = matrixRow;\r\n\t\tlet nextCol = col;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tnextMatrixRow = matrixRow + (cell.rowSpan || 1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\t\tnextMatrixRow = Math.max(0, matrixRow - (cell.rowSpan || 1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\t\tif (nextCol < 0 && matrixRow > 0) {\r\n\t\t\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow - 1;\r\n\t\t\t\t\t\tconst prevTrs = this.#findTargetTrsByMatrix(nextMatrixRow);\r\n\t\t\t\t\t\tconst maxColCell = this.#getMaxColCell(prevTrs);\r\n\t\t\t\t\t\tnextCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) : 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\t\t\tconst maxColCell = this.#getMaxColCell(targetTrs);\r\n\t\t\t\t\tconst maxCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) + parseInt(maxColCell.colSpan || 1, 10) : 0;\r\n\r\n\t\t\t\t\tif (nextCol >= maxCol) {\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow + 1;\r\n\t\t\t\t\t\tnextCol = 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tconst maxDataRow = this.#host.data.length;\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst maxMatrixRowLimit = (maxDataRow * templateLength) - 1;\r\n\t\t\t\tif (matrixRow + (cell.rowSpan || 1) > maxMatrixRowLimit) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tif (matrixRow <= 0) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\ttrace.log(\"========\")\r\n\r\n\t\t// 🎯 전체 데이터 갯수 한계 체크 (오버플로우 방지)\r\n\t\tconst totalCount = this.#sheet.view.getArray()?.length || 0;\r\n\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\tconst maxMatrixRow = (totalCount * templateLength) - 1;\r\n\t\tnextMatrixRow = Math.max(0, Math.min(nextMatrixRow, maxMatrixRow));\r\n\r\n\t\ttrace.log(`⌨️ [Key: ${e.code}] Current matrixRow: ${matrixRow} -> Target nextMatrixRow: ${nextMatrixRow}, nextCol: ${nextCol}`);\r\n\r\n\t\tconst nextDataRow = Math.floor(nextMatrixRow / templateLength);\r\n\t\tconst nextSubRowIndex = nextMatrixRow % templateLength;\r\n\r\n\t\tconst attemptFindAndMove = (retries = 0) => {\r\n\t\t\tlet targetCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\r\n\t\t\tif (targetCell) {\r\n\t\t\t\ttrace.log(`✅ [Found Cell] Attempt ${retries} -> dataRow: ${targetCell.dataset.row}, col: ${targetCell.dataset.col}`);\r\n\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, targetCell.dataset.col, actualMatrixRow, targetCell.dataset.col);\r\n\r\n\t\t\t\tthis.#ensureCellVisible(targetCell);\r\n\t\t\t} else {\r\n\t\t\t\ttrace.log(`📜 [Scroll Trigger] Cell not found in DOM, invoking rowManager.scrollToDataRow(${nextDataRow})`);\r\n\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(nextDataRow, \"bottom\", () => {\r\n\t\t\t\t\ttrace.log(\"nextDataRow\", nextDataRow);\r\n\r\n\t\t\t\t\tconst retryLoop = () => {\r\n\t\t\t\t\t\tlet retryCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\t\t\t\t\t\tif (retryCell) {\r\n\t\t\t\t\t\t\ttrace.log(`✅ [Found After Scroll] RetryLoop success -> dataRow: ${retryCell.dataset.row}`);\r\n\t\t\t\t\t\t\tthis.currentCell = retryCell;\r\n\t\t\t\t\t\t\tconst tr = retryCell.closest(\"tr\");\r\n\t\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, retryCell.dataset.col, actualMatrixRow, retryCell.dataset.col);\r\n\t\t\t\t\t\t\tthis.#ensureCellVisible(retryCell);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t};\r\n\t\t\t\t\tretryLoop();\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tattemptFindAndMove();\r\n\t}\r\n\r\n\t#ensureCellVisible(cell) {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tconst bodyContainer = this.#sheet.querySelector('.ng-sheet-body .ng-container-body');\r\n\t\t//const headerBody = this.#sheet.querySelector('.ng-sheet-header .ng-container-body');\r\n\r\n\t\tif (!bodyViewport || !bodyContainer) return;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\t\tconst containerRect = bodyContainer.getBoundingClientRect();\r\n\t\t//const headerRect = headerBody ? headerBody.getBoundingClientRect() : null;\r\n\r\n\t\ttrace.log(`📐 [DIAGNOSTIC VISIBILITY] \r\n- cell.dataset.col: ${cell.dataset.col}\r\n- cellRect (left: ${cellRect.left}, right: ${cellRect.right})\r\n- containerRect (left: ${containerRect.left}, right: ${containerRect.right}, width: ${containerRect.width}, scrollLeft: ${bodyContainer.scrollLeft}, scrollWidth: ${bodyContainer.scrollWidth}, clientWidth: ${bodyContainer.clientWidth})\r\n- viewportRect (width: ${viewportRect.width})\r\n `);\r\n\r\n\t\tconst isAbove = cellRect.top < viewportRect.top;\r\n\t\tconst isBelow = cellRect.bottom > viewportRect.bottom;\r\n\r\n\t\tif (isAbove || isBelow) {\r\n\t\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\t\tconst col = cell.dataset.col;\r\n\t\t\tconst $tr = cell.closest(\"tr\");\r\n\t\t\tconst subrow = $tr?.dataset.subrow || 0;\r\n\r\n\t\t\tif (!isNaN(dataRow) && this.#sheet.rowManager) {\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(dataRow, \"top\", () => {\r\n\t\t\t\t\tconst targetCell = this.#sheet.querySelector(`.ng-sheet-body tr[data-row=\"${dataRow}\"][data-subrow=\"${subrow}\"] td[data-col=\"${col}\"]`);\r\n\t\t\t\t\tif (targetCell) {\r\n\t\t\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\t\t\tconst tr = targetCell.closest(\"tr\");\r\n\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, col, actualMatrixRow, col);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (cellRect.left < containerRect.left) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Left] cell out of left bound`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft -= (containerRect.left - cellRect.left + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t} else if (cellRect.right > containerRect.right) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Right] cell out of right bound. cellRect.right: ${cellRect.right} > containerRect.right: ${containerRect.right}`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft += (cellRect.right - containerRect.right + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t}\r\n\t}\r\n\r\n\t#getMinCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet minCol = Infinity;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tminCol = Math.min(minCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn minCol === Infinity ? 0 : minCol;\r\n\t};\r\n\r\n\t#getMaxCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet maxCol = 0;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tmaxCol = Math.max(maxCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn maxCol;\r\n\t};\r\n\r\n\t#getMaxColCell = (targetTrs) => {\r\n\t\tconst allCells = [];\r\n\t\ttargetTrs.forEach(tr => allCells.push(...Array.from(tr.querySelectorAll('td'))));\r\n\t\tif (allCells.length === 0) return null;\r\n\t\tallCells.sort((a, b) => parseInt(a.dataset.col, 10) - parseInt(b.dataset.col, 10));\r\n\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\treturn allCells[allCells.length - 1];\r\n\t};\r\n\r\n\t#getNextCol = (matrixRow, col) => {\r\n\t\tconst td = this.#sheet.querySelector(`.ng-sheet-body tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`) ||\r\n\t\t\tthis.#sheet.querySelector(`.ng-sheet-body td[data-col=\"${col}\"]`);\r\n\r\n\t\tconst colSpan = td?.colSpan || 1;\r\n\t\tconst next = col + colSpan;\r\n\t\ttrace.log(`🔍 [#getNextCol] current col: ${col}, found td colSpan: ${colSpan}, calculated next col: ${next}`);\r\n\t\treturn next;\r\n\t}\r\n\r\n\t#getPreviousCol = (matrixRow, currentCol) => {\r\n\t\tif (currentCol <= 0) return 0;\r\n\t\tconst currentTrCells = this.#currentTr ? Array.from(this.#currentTr.querySelectorAll('td, th')) : [];\r\n\t\tconst cols = new Set();\r\n\r\n\t\tcurrentTrCells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tcols.add(c);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (cols.size === 0) {\r\n\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\ttargetTrs.forEach(tr => {\r\n\t\t\t\tArray.from(tr.querySelectorAll('td, th')).forEach(cell => {\r\n\t\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\t\t\tcols.add(c);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst smallerCols = Array.from(cols).filter(c => c < currentCol);\r\n\t\treturn smallerCols.length === 0 ? Math.max(0, currentCol - 1) : Math.max(...smallerCols);\r\n\t};\r\n\r\n\t#findTargetTrsByMatrix = (matrixRow) => {\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body .ng-container-left, .ng-sheet-body .ng-container-body, .ng-sheet-body .ng-container-right'\r\n\t\t);\r\n\t\tconst matchedTrs = [];\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tconst trs = Array.from(container.querySelectorAll('tbody tr'));\r\n\t\t\tfor (const tr of trs) {\r\n\t\t\t\tconst mRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\tif (mRow === matrixRow) {\r\n\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst cells = Array.from(tr.querySelectorAll('td'));\r\n\t\t\t\tlet foundInSpan = false;\r\n\t\t\t\tfor (const cell of cells) {\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tif (rowSpan > 1 && matrixRow >= mRow && matrixRow < mRow + rowSpan) {\r\n\t\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\t\tfoundInSpan = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (foundInSpan) break;\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn matchedTrs;\r\n\t};\r\n\r\n\t#getNearElement = (dataRow, subRowIndex, col, matrixRow) => {\r\n\t\tconst targetMatrixRow = matrixRow !== undefined ? matrixRow : (dataRow * (this.#sheet.templateLength || 1)) + subRowIndex;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\tconst targetDataRow = Math.floor(targetMatrixRow / templateLength);\r\n\t\tconst targetSubRow = targetMatrixRow % templateLength;\r\n\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body, .ng-container-left, .ng-container-body, .ng-container-right, .ng-part-body'\r\n\t\t);\r\n\r\n\t\tconst searchedTrs = new Set();\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => searchedTrs.add(tr));\r\n\t\t});\r\n\r\n\t\tfor (const tr of Array.from(searchedTrs)) {\r\n\t\t\tconst trDataRow = parseInt(tr.dataset.row, 10);\r\n\t\t\tif (isNaN(trDataRow)) continue;\r\n\r\n\t\t\tconst tbody = tr.closest('tbody');\r\n\t\t\tconst groupTrs = tbody ? Array.from(tbody.querySelectorAll(`tr[data-row=\"${trDataRow}\"]`)) : [tr];\r\n\t\t\tconst trSubIdx = groupTrs.indexOf(tr);\r\n\r\n\t\t\tfor (const cell of Array.from(tr.querySelectorAll('td'))) {\r\n\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\tconst span = parseInt(cell.colSpan || 1, 10);\r\n\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\r\n\t\t\t\tif (isNaN(c) || window.getComputedStyle(cell).display === 'none') continue;\r\n\r\n\t\t\t\tconst cellDataRowStart = trDataRow;\r\n\t\t\t\tconst cellSubRowStart = trSubIdx;\r\n\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst cellStartMatrix = (cellDataRowStart * templateLength) + cellSubRowStart;\r\n\t\t\t\tconst cellEndMatrix = cellStartMatrix + rowSpan - 1;\r\n\r\n\t\t\t\tif (targetMatrixRow >= cellStartMatrix && targetMatrixRow <= cellEndMatrix) {\r\n\t\t\t\t\tif (col >= c && col < c + span) {\r\n\t\t\t\t\t\treturn cell;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn null;\r\n\t};\r\n\r\n\t#initEvents() {\r\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tthis.currentCell = cell;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\r\n\t\t\tif ([\"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\r\n\t\t\t\tthis.moveCell(e);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}","// ui/col/ColResizer.js\nimport { trace } from \"@nopeer\";\nimport { COLLAPSED_WIDTH, TableCompiler } from \"@/ui/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('.ng-col-resizer-panel');\n\n this.#tooltip = this.#panel?.querySelector('.resizer-overlay');\n this.bindEvents();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointermove', this.#onPointerMove);\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n this.#sheet.removeEventListener('dblclick', this.#onDblClick);\n }\n\n refreshLayout(containerType = 'body') {\n const containers = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType}`));\n if (containers.length === 0) return;\n\n const isFixedContainer = containerType === 'left' || containerType === 'right';\n const isAutoFit = !isFixedContainer && (\n this.#sheet.isAutoFitCol ||\n containers[0].querySelector('table')?.getAttribute('auto-fit-col') === 'true'\n );\n\n if (!isAutoFit) {\n\n const firstColgroup = containers[0].querySelector('table colgroup');\n if (!firstColgroup) return;\n\n let totalWidth = 0;\n const colWidths = {};\n\n Array.from(firstColgroup.querySelectorAll('col')).forEach(col => {\n const colIdx = col.getAttribute('data-col');\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) {\n colWidths[colIdx] = w;\n totalWidth += w;\n }\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n\n trace.log(\"====================\", containers, containerType);\n\n if (containerType === 'body') {\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n //tbl.style.minWidth = `${totalWidth}px`;\n });\n } else {\n container.style.flex = `0 0 ${totalWidth}px`;\n container.style.width = `${totalWidth}px`;\n container.style.minWidth = `${totalWidth}px`;\n container.style.maxWidth = `${totalWidth}px`;\n\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n tbl.style.minWidth = `${totalWidth}px`;\n tbl.style.maxWidth = `${totalWidth}px`;\n\n Object.entries(colWidths).forEach(([colIdx, w]) => {\n tbl.querySelectorAll(`th[data-col=\"${colIdx}\"], td[data-col=\"${colIdx}\"]`).forEach(cell => {\n cell.style.width = `${w}px`;\n cell.style.minWidth = `${w}px`;\n cell.style.maxWidth = `${w}px`;\n });\n });\n });\n }\n });\n } else {\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n tables.forEach(tbl => {\n //tbl.style.width = '100%';\n //tbl.style.minWidth = '100%';\n //tbl.style.maxWidth = '';\n });\n });\n }\n\n this.#sheet.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n setColumnWidth(globalColIndex, width, containerType = null) {\n\n trace.log(\"setColumnWidth\");\n\n\n let targetCols = [];\n\n //if (containerType) {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType} table colgroup col[data-col=\"${globalColIndex}\"]`));\n //} else {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n //}\n targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n\n if (targetCols.length === 0) return;\n\n const firstContainer = targetCols[0].closest('.ng-container-left, .ng-container-body, .ng-container-right');\n const resolvedContainerType = containerType || (\n firstContainer?.classList.contains('ng-container-left') ? 'left' :\n firstContainer?.classList.contains('ng-container-right') ? 'right' : 'body'\n );\n\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n\n trace.log(col, width);\n });\n\n const sourceCol = this.#sheet.sourceTable?.querySelector(`colgroup col[data-col=\"${globalColIndex}\"]`);\n if (sourceCol) {\n sourceCol.setAttribute('width', width);\n sourceCol.style.width = `${width}px`;\n }\n\n\n\n this.refreshLayout(resolvedContainerType);\n\n // 🎯 [핵심] autoFit을 여기서 또 호출하면 루프가 돌거나 레이아웃 계산이 꼬입니다.\n // 바디 영역 리사이즈 시에는 body만 refreshLayout 해주면 됩니다!\n if (resolvedContainerType === 'left' || resolvedContainerType === 'right') {\n this.refreshLayout('body');\n }\n\n this.#sheet.rowManager?.refresh();\n }\n\n #checkIsAutoFit(targetCell) {\n if (this.#sheet.isAutoFitCol) return true;\n const table = targetCell?.closest('table');\n if (table && table.getAttribute('auto-fit-col') === 'true') return true;\n return false;\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointermove', this.#onPointerMove);\n //this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n //this.#sheet.addEventListener('dblclick', this.#onDblClick);\n\n this.#sheet.addDebounseEventListener('dblclick', this.#onDblClick, 'pointerdown', this.#onPointerDown);\n }\n\n #getContainerType(cell) {\n const container = cell.closest('.ng-container-left, .ng-container-body, .ng-container-right');\n if (!container) return null;\n if (container.classList.contains('ng-container-left')) return 'left';\n if (container.classList.contains('ng-container-right')) return 'right';\n return 'body';\n }\n\n #onPointerMove = (e) => {\n\n\n const headerPart = e.target.closest('thead');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n\n headerPart.querySelectorAll('.resizable-edge').forEach(el => {\n if (el !== cell) el.classList.remove('resizable-edge');\n });\n\n if (!cell || cell.dataset.col === undefined) return;\n if (cell.getAttribute('collapsed') === 'true') return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n const isLeftEdge = offsetX <= RESIZE_OFFSET;\n const isRightEdge = (rect.width - offsetX) <= RESIZE_OFFSET;\n\n if (isLeftEdge) {\n const prevCell = cell.previousElementSibling;\n if (!prevCell || prevCell.getAttribute('collapsed') === 'true') {\n cell.classList.remove('resizable-edge');\n return;\n }\n }\n\n if (isLeftEdge || isRightEdge) {\n cell.classList.add('resizable-edge');\n } else {\n cell.classList.remove('resizable-edge');\n }\n };\n\n #onPointerDown = (e) => {\n\n //const path = e.composedPath();\n //const cell1 = path.find(el => el?.nodeType === Node.ELEMENT_NODE && (el.tagName === 'TH' || el.tagName === 'TD'));\n\n //trace.log(e);\n //trace.log( path, cell1);\n\n //const actualTarget = document.elementFromPoint(e.clientX, e.clientY);\n //if (!actualTarget) return;\n\n trace.log(e.actualTarget, e.target);\n\n const headerPart = e.actualTarget.closest('thead');\n if (!headerPart) return;\n\n const cell = e.actualTarget.closest('th, td');\n trace.log(cell, e.actualTarget);\n\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n\n\n e.preventDefault();\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n let targetCell = cell;\n\n if (offsetX <= RESIZE_OFFSET) {\n const prevCell = cell.previousElementSibling;\n if (prevCell && prevCell.dataset.col !== undefined && prevCell.getAttribute('collapsed') !== 'true') {\n targetCell = prevCell;\n } else if (!cell.previousElementSibling) {\n return;\n }\n }\n\n this.#targetCell = targetCell;\n this.#targetContainerType = this.#getContainerType(targetCell);\n\n const container = this.#sheet.querySelector(`.ng-container-${this.#targetContainerType}`);\n if (!container) return;\n\n const baseColIndex = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n this.#targetColIndex = baseColIndex + colSpan - 1;\n\n const isAutoFit = this.#checkIsAutoFit(targetCell);\n if (isAutoFit) {\n this.#nextColIndex = this.#targetColIndex + 1;\n const nextColEl = container.querySelector(`col[data-col=\"${this.#nextColIndex}\"]`);\n if (nextColEl) {\n this.#nextColStartWidth = parseInt(nextColEl.getAttribute('width'), 10) || 100;\n } else {\n this.#nextColIndex = null;\n }\n } else {\n this.#nextColIndex = null;\n }\n\n const targetRect = targetCell.getBoundingClientRect();\n const sheetRect = this.#sheet.getBoundingClientRect();\n\n this.#startCellWidth = targetRect.width;\n this.#startLeft = targetRect.left - sheetRect.left;\n\n const targetColEl = container.querySelector(`col[data-col=\"${this.#targetColIndex}\"]`);\n const attrW = targetColEl?.getAttribute('width');\n this.#startColWidth = (attrW && !isNaN(parseInt(attrW, 10))) ? parseInt(attrW, 10) : targetRect.width / colSpan;\n\n this.#startX = e.clientX;\n\n if (this.#panel) {\n this.#panel.classList.add('active');\n this.#updatePositions(e.clientX);\n }\n\n window.addEventListener('pointermove', this.#onDragMove);\n window.addEventListener('pointerup', this.#onDragEnd, { once: true });\n };\n\n #updatePositions(clientX) {\n let diff = clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxDiff = this.#nextColStartWidth - COLLAPSED_WIDTH;\n const minDiff = -(this.#startColWidth - COLLAPSED_WIDTH);\n diff = Math.max(minDiff, Math.min(diff, maxDiff));\n }\n\n const currentColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n\n const targetRect = this.#targetCell.getBoundingClientRect();\n let realCellWidth = clientX - targetRect.left;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxCellWidth = this.#startCellWidth + (this.#nextColStartWidth - COLLAPSED_WIDTH);\n realCellWidth = Math.min(realCellWidth, maxCellWidth);\n }\n\n const currentCellWidth = Math.max(COLLAPSED_WIDTH, realCellWidth);\n\n if (this.#panel) {\n this.#panel.style.setProperty('--tooltip-left', `${this.#startLeft}px`);\n this.#panel.style.setProperty('--tooltip-width', `${currentCellWidth}px`);\n }\n\n const sizeBadge = this.#tooltip?.querySelector('.size-badge');\n if (sizeBadge) {\n sizeBadge.textContent = `${Math.round(currentColWidth)}px`;\n }\n }\n\n #onDragMove = (e) => {\n trace.log(e);\n this.#updatePositions(e.clientX);\n };\n\n #onDragEnd = (e) => {\n window.removeEventListener('pointermove', this.#onDragMove);\n\n const diff = e.clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n let finalWidth = 0;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n let newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n let newNextWidth = this.#startColWidth + this.#nextColStartWidth - newColWidth;\n\n if (newNextWidth < COLLAPSED_WIDTH) {\n newNextWidth = COLLAPSED_WIDTH;\n newColWidth = this.#startColWidth + this.#nextColStartWidth - COLLAPSED_WIDTH;\n }\n\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n this.setColumnWidth(this.#nextColIndex, newNextWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n } else {\n const newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n if (this.#targetColIndex !== null && this.#targetContainerType) {\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n }\n }\n\n if (this.#targetCell) {\n const targetCell = this.#targetCell;\n if (targetCell.getAttribute('collapsed') !== 'true' && finalWidth > 20) {\n targetCell.dataset.expandWidth = String(finalWidth);\n }\n }\n\n if (this.#panel) {\n this.#tooltip?.classList.add('fade-out');\n setTimeout(() => {\n this.#panel.classList.remove('active');\n this.#tooltip?.classList.remove('fade-out');\n }, 150);\n }\n\n this.#targetColIndex = null;\n this.#nextColIndex = null;\n this.#targetContainerType = null;\n this.#targetCell = null;\n };\n\n #onDblClick = (e) => {\n\n const targetEl = e.target;\n let cell = targetEl.closest('th, td');\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n if (offsetX <= RESIZE_OFFSET) {\n cell = cell.previousElementSibling;\n }\n\n const baseColIndex = parseInt(cell.dataset.col, 10);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${baseColIndex}\"]`);\n if (!tbodyCell || !tbodyCell.dataset.bind || tbodyCell.classList.contains(\"CELL-RADIO\")) return;\n\n let extraPadding = 0;\n Array.from(tbodyCell.firstElementChild.children).forEach(($el) => {\n switch ($el.tagName) {\n case 'SPAN': extraPadding += 8; break;\n case 'DIV': extraPadding += 8; break;\n case 'BUTTON': extraPadding += 32; break;\n case 'SELECT': extraPadding += 32; break;\n case 'INPUT':\n switch (($el.type || 'text').toLowerCase()) {\n // 1. 체크박스 / 라디오 (비교적 좁은 영역)\n case 'checkbox':\n case 'radio':\n extraPadding += 12;\n break;\n\n // 2. 버튼 계열 input\n case 'button':\n case 'submit':\n case 'reset':\n case 'image':\n extraPadding += 16;\n break;\n\n // 3. 특수 위젯 (컬러, 파일, 슬라이더)\n case 'color':\n case 'file':\n case 'range':\n extraPadding += 24;\n break;\n\n // 4. 화면에 안 보이는 hidden 필드\n case 'hidden':\n extraPadding += 0;\n break;\n\n // 5. 텍스트 및 숫자, 날짜 등 일반 입력 필드 (기본값)\n case 'text':\n case 'search':\n case 'tel':\n case 'url':\n case 'email':\n case 'password':\n case 'number':\n case 'date':\n case 'time':\n case 'datetime-local':\n case 'month':\n case 'week':\n default:\n extraPadding += 16;\n break;\n }\n break;\n }\n });\n\n trace.log(extraPadding);\n\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n\n // 헤더 텍스트 길이 측정\n const headerText = cell.innerText || \"\";\n const headerSize = nine.measureTextSize(headerText, font);\n let maxTextWidth = (headerSize.width || 0) + 16;\n\n this.#host.execute(() => {\n\n this.#sheet.view.getArray().forEach((record, idx) => {\n const val = String(tbodyCell.dataset.expr ? this.#host.exprEngine.evaluate(tbodyCell.dataset.expr, record, idx) : record.v[fieldIdx] ?? \"\").trim();\n const size = nine.measureTextSize(val, font);\n if (size.width && size.width > maxTextWidth) {\n maxTextWidth = size.width;\n }\n });\n\n // 글자 수 당 대략적인 픽셀 계산 (기본 패딩 여백 포함, 최소 32px ~ 최대 400px 제한)\n const calculatedWidth = Math.max(32, Math.min(400, Math.ceil(maxTextWidth) + extraPadding));\n\n // 자동 계산된 너비 적용\n this.setColumnWidth(tbodyCell.dataset.col, calculatedWidth, this.#getContainerType(cell));\n })\n };\n}\n\n","// ui/col/ColMover.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColMover {\n #sheet;\n #grip;\n #indi;\n\n #isDragging = false;\n #sourceCell = null;\n #sourceColIndex = null;\n #targetColIndex = null;\n #shiftX = 0;\n #timer = null;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#grip = this.#sheet.querySelector('.ng-col-mover-grip');\n this.#indi = this.#sheet.querySelector('.ng-col-mover-indi');\n this.bindEvents();\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n }\n\n #checkIsMovable() {\n const host = this.#sheet.getRootNode()?.host;\n return this.#sheet.getAttribute('col-movable') === 'true' || host?.getAttribute('col-movable') === 'true';\n }\n\n #getDeepElementFromPoint(x, y) {\n const root = this.#sheet.getRootNode();\n let el = root.elementFromPoint ? root.elementFromPoint(x, y) : document.elementFromPoint(x, y);\n\n while (el && el.shadowRoot && el.shadowRoot.elementFromPoint) {\n const nested = el.shadowRoot.elementFromPoint(x, y);\n if (!nested || nested === el) break;\n el = nested;\n }\n\n return el;\n }\n\n #getColGroupRange(cell) {\n if (!cell || cell.dataset.col === undefined) return null;\n\n const startCol = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const endCol = startCol + colSpan - 1;\n const rowIndex = cell.closest('tr')?.sectionRowIndex ?? 0;\n\n const table = cell.closest('table');\n if (!table) return { startCol, colSpan, endCol, rowIndex, isGroup: false, parentGroupRange: null, isValidGroup: true };\n\n const headerCells = table.querySelectorAll('thead th, thead td');\n let hasStrictChildren = false;\n let isValidGroup = true;\n let parentGroupRange = null;\n\n for (const subCell of headerCells) {\n if (subCell === cell || subCell.dataset.col === undefined) continue;\n\n const subStart = parseInt(subCell.dataset.col, 10);\n const subSpan = subCell.colSpan || 1;\n const subEnd = subStart + subSpan - 1;\n const subRowIndex = subCell.closest('tr')?.sectionRowIndex ?? 0;\n\n if (subRowIndex < rowIndex && subStart <= startCol && subEnd >= endCol && subSpan > colSpan) {\n if (!parentGroupRange) {\n parentGroupRange = { startCol: subStart, endCol: subEnd };\n } else {\n parentGroupRange.startCol = Math.max(parentGroupRange.startCol, subStart);\n parentGroupRange.endCol = Math.min(parentGroupRange.endCol, subEnd);\n }\n }\n\n const isOverlap = !(subEnd < startCol || subStart > endCol);\n if (isOverlap) {\n const isFullyContained = (subStart >= startCol && subEnd <= endCol);\n\n if (isFullyContained) {\n if (subSpan < colSpan) {\n hasStrictChildren = true;\n }\n } else if (subStart < startCol || subEnd > endCol) {\n if (!(subStart <= startCol && subEnd >= endCol)) {\n isValidGroup = false;\n }\n }\n }\n }\n\n const isRealGroup = hasStrictChildren && isValidGroup;\n\n return {\n startCol,\n colSpan: isRealGroup ? colSpan : 1,\n endCol: isRealGroup ? endCol : startCol,\n rowIndex,\n isGroup: isRealGroup,\n parentGroupRange,\n isValidGroup\n };\n }\n\n #createGroupHeaderPreview(cell) {\n const groupRange = this.#getColGroupRange(cell);\n if (!groupRange) return null;\n\n const { startCol, endCol, isGroup } = groupRange;\n\n // 핵심: 테이블이 여러 개인 구조이므로 cell이 속한 바로 그 테이블을 직접 가져옵니다.\n const origTable = cell.closest('table');\n if (!origTable) return null;\n\n let minLeft = Infinity, maxRight = -Infinity, minTop = Infinity, maxBottom = -Infinity;\n const targetCells = [];\n\n origTable.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n const isTarget = isGroup\n ? (cCol >= startCol && cEnd <= endCol)\n : (c === cell);\n\n if (isTarget) {\n const rect = c.getBoundingClientRect();\n minLeft = Math.min(minLeft, rect.left);\n maxRight = Math.max(maxRight, rect.right);\n minTop = Math.min(minTop, rect.top);\n maxBottom = Math.max(maxBottom, rect.bottom);\n\n const computedStyle = window.getComputedStyle(c);\n targetCells.push({ el: c, rect, style: computedStyle });\n }\n });\n\n if (targetCells.length === 0) return null;\n\n const groupWidth = maxRight - minLeft;\n const groupHeight = maxBottom - minTop;\n\n const headerContent = document.createElement('div');\n headerContent.className = 'grip-header-content';\n headerContent.style.position = 'relative';\n headerContent.style.width = `${groupWidth}px`;\n headerContent.style.height = `${groupHeight}px`;\n\n targetCells.forEach(({ el, rect, style }) => {\n const clonedCell = el.cloneNode(true);\n\n clonedCell.style.position = 'absolute';\n clonedCell.style.left = `${rect.left - minLeft}px`;\n clonedCell.style.top = `${rect.top - minTop}px`;\n\n clonedCell.style.width = `${rect.width}px`;\n clonedCell.style.minWidth = `${rect.width}px`;\n clonedCell.style.maxWidth = 'none';\n\n clonedCell.style.height = `${rect.height}px`;\n clonedCell.style.boxSizing = 'border-box';\n clonedCell.style.margin = '0';\n\n clonedCell.style.backgroundColor = style.backgroundColor !== 'transparent' && style.backgroundColor !== 'rgba(0, 0, 0, 0)'\n ? style.backgroundColor\n : '#f9fafb';\n clonedCell.style.color = style.color;\n clonedCell.style.font = style.font;\n clonedCell.style.fontWeight = style.fontWeight;\n clonedCell.style.fontSize = style.fontSize;\n clonedCell.style.textAlign = style.textAlign;\n clonedCell.style.padding = style.padding;\n clonedCell.style.border = style.border;\n clonedCell.style.borderRight = style.borderRight;\n clonedCell.style.borderBottom = style.borderBottom;\n clonedCell.style.display = 'flex';\n clonedCell.style.alignItems = 'center';\n clonedCell.style.justifyContent = style.textAlign === 'center' ? 'center' : (style.textAlign === 'right' ? 'flex-end' : 'flex-start');\n\n headerContent.appendChild(clonedCell);\n });\n\n return {\n element: headerContent,\n bounds: {\n left: minLeft,\n right: maxRight,\n top: minTop,\n bottom: maxBottom,\n width: groupWidth,\n height: groupHeight\n }\n };\n }\n\n #onPointerDown = (e) => {\n if (!this.#checkIsMovable()) return;\n\n const headerPart = e.target.closest('.ng-sheet-header');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n if (!cell || cell.classList.contains('resizable-edge') || ['INPUT', 'BUTTON'].includes(e.target.tagName)) return;\n if (cell.dataset.col === undefined) return;\n\n e.preventDefault();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cancelTimer = () => {\n if (this.#timer) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n window.removeEventListener('pointermove', onPointerMovePending);\n window.removeEventListener('pointerup', cancelTimer);\n window.removeEventListener('pointercancel', cancelTimer);\n };\n\n const onPointerMovePending = (moveEvent) => {\n const dist = Math.hypot(moveEvent.clientX - startX, moveEvent.clientY - startY);\n if (dist > 5) {\n cancelTimer();\n }\n };\n\n this.#timer = setTimeout(() => {\n cancelTimer();\n this.#startDrag(e, cell);\n }, 500);\n\n window.addEventListener('pointermove', onPointerMovePending);\n window.addEventListener('pointerup', cancelTimer, { once: true });\n window.addEventListener('pointercancel', cancelTimer, { once: true });\n };\n\n #startDrag(e, cell) {\n if (this.#isDragging) return;\n\n const preview = this.#createGroupHeaderPreview(cell);\n if (!preview) return;\n\n this.#isDragging = true;\n this.#sourceCell = cell;\n this.#sourceColIndex = parseInt(cell.dataset.col, 10);\n\n const sheetRect = this.#sheet.getBoundingClientRect();\n const { bounds, element } = preview;\n\n this.#shiftX = e.clientX - bounds.left;\n\n if (this.#grip) {\n this.#grip.replaceChildren(element);\n\n const relativeTop = bounds.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#grip.style.width = `${bounds.width}px`;\n this.#grip.style.height = `${fullHeight}px`;\n this.#grip.style.top = `${relativeTop}px`;\n this.#grip.style.display = 'block';\n\n this.#updateGripPosition(e.clientX);\n }\n\n document.body.style.cursor = 'move';\n\n window.addEventListener('pointermove', this.#onPointerMove);\n window.addEventListener('pointerup', this.#onPointerUp, { once: true });\n }\n\n #onPointerMove = (e) => {\n if (!this.#isDragging) return;\n\n this.#updateGripPosition(e.clientX);\n\n if (this.#grip) this.#grip.style.pointerEvents = 'none';\n if (this.#indi) this.#indi.style.pointerEvents = 'none';\n\n const targetElement = this.#getDeepElementFromPoint(e.clientX, e.clientY);\n const targetCell = targetElement?.closest('.ng-sheet-header th, .ng-sheet-header td');\n\n if (targetCell && targetCell.dataset.col !== undefined) {\n const targetColIndex = parseInt(targetCell.dataset.col, 10);\n const sheetRect = this.#sheet.getBoundingClientRect();\n const table = targetCell.closest('table');\n\n let colMinLeft = Infinity;\n let colMaxRight = -Infinity;\n\n if (table) {\n table.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n if (cCol <= targetColIndex && cEnd >= targetColIndex) {\n const cRect = c.getBoundingClientRect();\n colMinLeft = Math.min(colMinLeft, cRect.left);\n colMaxRight = Math.max(colMaxRight, cRect.right);\n }\n });\n }\n\n if (colMinLeft === Infinity) {\n const rect = targetCell.getBoundingClientRect();\n colMinLeft = rect.left;\n colMaxRight = rect.right;\n }\n\n const midX = colMinLeft + ((colMaxRight - colMinLeft) / 2);\n let calculatedTargetCol = 0;\n let indicatorLeft = 0;\n\n if (e.clientX < midX) {\n calculatedTargetCol = targetColIndex;\n indicatorLeft = colMinLeft - sheetRect.left;\n } else {\n const colSpan = targetCell.colSpan || 1;\n calculatedTargetCol = targetColIndex + colSpan;\n indicatorLeft = colMaxRight - sheetRect.left;\n }\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n const movingSpan = sourceGroup.colSpan;\n\n const sourceRowStart = sourceGroup.rowIndex;\n const sourceRowSpan = this.#sourceCell.rowSpan || 1;\n const sourceRowEnd = sourceRowStart + sourceRowSpan - 1;\n\n const targetRowStart = targetCell.closest('tr')?.sectionRowIndex ?? 0;\n const targetRowSpan = targetCell.rowSpan || 1;\n const targetRowEnd = targetRowStart + targetRowSpan - 1;\n\n const isRowSpanCompatible = !(sourceRowEnd < targetRowStart || sourceRowStart > targetRowEnd);\n\n let isOutOfBoundsOfParent = false;\n if (sourceGroup.parentGroupRange) {\n const { startCol: pStart, endCol: pEnd } = sourceGroup.parentGroupRange;\n if (calculatedTargetCol < pStart || (calculatedTargetCol + movingSpan - 1) > pEnd) {\n isOutOfBoundsOfParent = true;\n }\n }\n\n let isDroppingInsideOtherGroup = false;\n if (table) {\n const spannedCells = table.querySelectorAll('thead th[colspan], thead td[colspan]');\n\n for (const sCell of spannedCells) {\n if (sCell === this.#sourceCell) continue;\n\n const sRowStart = sCell.closest('tr')?.sectionRowIndex ?? 0;\n const sRowSpan = sCell.rowSpan || 1;\n const sRowEnd = sRowStart + sRowSpan - 1;\n\n const isVerticalOverlap = !(sourceRowEnd < sRowStart || sourceRowStart > sRowEnd);\n if (!isVerticalOverlap) continue;\n\n const sStart = parseInt(sCell.dataset.col, 10);\n const sSpan = sCell.colSpan || 1;\n const sEnd = sStart + sSpan - 1;\n\n if (calculatedTargetCol > sStart && calculatedTargetCol < sEnd + 1) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n\n const moveEndCol = calculatedTargetCol + movingSpan - 1;\n const isCrossIntersecting = (\n (calculatedTargetCol > sStart && calculatedTargetCol <= sEnd && moveEndCol > sEnd) ||\n (calculatedTargetCol < sStart && moveEndCol >= sStart && moveEndCol < sEnd)\n );\n\n if (isCrossIntersecting) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n }\n }\n\n const isSelfGroup = (\n calculatedTargetCol >= sourceGroup.startCol &&\n calculatedTargetCol <= sourceGroup.endCol + 1\n );\n\n const isInvalidMove = !isRowSpanCompatible || isSelfGroup || isOutOfBoundsOfParent || isDroppingInsideOtherGroup || !sourceGroup.isValidGroup;\n\n if (isInvalidMove) {\n this.#targetColIndex = null;\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n } else {\n this.#targetColIndex = calculatedTargetCol;\n if (this.#grip) this.#grip.classList.remove('invalid');\n\n if (this.#indi) {\n const headerPart = targetCell.closest('.ng-sheet-header');\n const headerRect = headerPart.getBoundingClientRect();\n const relativeTop = headerRect.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#indi.style.top = `${relativeTop}px`;\n this.#indi.style.height = `${fullHeight}px`;\n this.#indi.style.left = `${indicatorLeft - 1}px`;\n this.#indi.style.display = 'block';\n }\n }\n } else {\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n this.#targetColIndex = null;\n }\n };\n\n #updateGripPosition(clientX) {\n if (!this.#grip) return;\n const sheetRect = this.#sheet.getBoundingClientRect();\n const left = clientX - sheetRect.left - this.#shiftX;\n this.#grip.style.left = `${left}px`;\n }\n\n #onPointerUp = (e) => {\n if (!this.#isDragging) return;\n\n window.removeEventListener('pointermove', this.#onPointerMove);\n document.body.style.cursor = '';\n\n if (this.#grip) {\n this.#grip.style.display = 'none';\n this.#grip.replaceChildren();\n }\n if (this.#indi) this.#indi.style.display = 'none';\n\n if (\n this.#targetColIndex !== null &&\n this.#sourceColIndex !== null &&\n this.#targetColIndex !== this.#sourceColIndex &&\n this.#targetColIndex !== this.#sourceColIndex + 1\n ) {\n this.moveColumn(this.#sourceColIndex, this.#targetColIndex);\n }\n\n this.#isDragging = false;\n this.#sourceCell = null;\n this.#sourceColIndex = null;\n this.#targetColIndex = null;\n };\n\n moveColumn(fromColIndex, toColIndex) {\n\n trace.log(this.#sheet.sourceTable.cloneNode(true));\n\n const colgroup = this.#sheet.sourceTable.querySelector('colgroup');\n const targetCol = colgroup.querySelector(`col[data-col=\"${toColIndex}\"]`);\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n if (!sourceGroup || !sourceGroup.isValidGroup) return;\n\n const spanCount = sourceGroup.colSpan;\n const isInRange = (idx) => idx >= fromColIndex && idx < fromColIndex + spanCount;\n\n // 1. colgroup 내 <col> 이동 및 fixed 설정\n const targetViewportCol = this.#sheet.querySelector(`.ng-sheet-body-content col[data-col=\"${toColIndex}\"]`);\n const fixedType = targetViewportCol?.closest('.ng-container-left') ? 'left' : targetViewportCol?.closest('.ng-container-right') ? 'right' : null;\n\n colgroup.querySelectorAll('col').forEach(col => {\n if (isInRange(parseInt(col.getAttribute('data-col'), 10))) {\n fixedType ? col.setAttribute('fixed', fixedType) : col.removeAttribute('fixed');\n colgroup.insertBefore(col, targetCol);\n }\n });\n\n // 2. 테이블 행(tr) 내부의 셀(th, td) 순서 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n this.#sheet.sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n const cells = Array.from(tr.children);\n const targetRowCell = cells.find(c => parseInt(c.dataset.col, 10) >= toColIndex);\n\n cells.forEach(cell => {\n if (isInRange(parseInt(cell.dataset.col, 10))) {\n tr.insertBefore(cell, targetRowCell || null);\n }\n });\n });\n });\n\n this.#sheet.recompileAndRefresh();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n }\n}","// ui/col/ColFixManager.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColFixManager {\n #sheet;\n\n constructor(sheet) {\n this.#sheet = sheet;\n }\n\n /**\n * 🎯 현재 클릭된 셀의 고정 구역('left', 'right', 'none') 탐색\n */\n getFixState(targetCell, table) {\n if (!targetCell || !table) return 'none';\n\n // 🎯 [보정] 3분할 레이어 구조 내부의 컨테이너를 안전하게 탐색\n const container = targetCell.closest('.ng-container-left, .ng-container-right, .ng-container-body');\n if (container?.classList.contains('ng-container-left')) return 'left';\n if (container?.classList.contains('ng-container-right')) return 'right';\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n if (!isNaN(baseCol)) {\n const colEl = table.querySelector(`colgroup col[data-col=\"${baseCol}\"]`);\n const fixedAttr = colEl?.getAttribute('fixed');\n if (fixedAttr) return fixedAttr;\n }\n\n return 'none';\n }\n\n /**\n * 🎯 상하 멀티 헤더 경계선 일치 여부 검사 (Fix Column 가부 판별)\n */\n canFixColumn(targetCell, table) {\n if (!targetCell || targetCell.tagName !== 'TH' || !table) return false;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n if (isNaN(baseCol)) return false;\n\n const targetBoundaryCol = baseCol + colSpan - 1;\n const theadTrs = Array.from(table.querySelectorAll('thead tr'));\n\n if (theadTrs.length <= 1) return true;\n\n for (const tr of theadTrs) {\n const cells = Array.from(tr.querySelectorAll('th, td'));\n let cellBoundaryFound = false;\n\n for (const cell of cells) {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEndCol = cCol + cSpan - 1;\n\n // 목표 경계선이 특정 셀의 중간을 관통하는 경우 (Fix 불가능)\n if (cCol <= targetBoundaryCol && targetBoundaryCol < cEndCol) {\n return false;\n }\n\n if (cEndCol === targetBoundaryCol) {\n cellBoundaryFound = true;\n break;\n }\n }\n\n if (!cellBoundaryFound) return false;\n }\n\n return true;\n }\n\n /**\n * 🎯 [인스턴스 메서드] 배치 범위 고정 및 해제 처리\n * - 원본(`sourceTable`)의 구조(fixed 속성)를 직접 조작하므로 decompile은 절대 호출하지 않음!\n */\n executeFixToggle(action, targetCell, fixType = 'left') {\n if (!this.#sheet || !targetCell) return;\n\n const sourceTable = this.#sheet.sourceTable;\n if (!sourceTable) return;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n const targetColIndex = baseCol + colSpan - 1;\n\n if (isNaN(targetColIndex)) return;\n\n const colgroup = sourceTable.querySelector('colgroup');\n if (!colgroup) return;\n\n const cols = Array.from(colgroup.querySelectorAll('col'));\n\n if (action === 'fix-column') {\n // 🎯 Batch Fix: 0번부터 targetColIndex까지의 모든 <col>과 셀에 fixed 속성 일괄 부여\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx <= targetColIndex) {\n col.setAttribute('fixed', fixType);\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (!isNaN(cIdx) && cIdx <= targetColIndex) {\n cell.setAttribute('fixed', fixType);\n }\n });\n });\n });\n\n } else if (action === 'unfix-column') {\n let minBaseCol = baseCol;\n let maxEndCol = baseCol + colSpan - 1;\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach((tr, rIdx) => {\n Array.from(tr.children).forEach(cell => {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n const rSpan = cell.rowSpan || 1;\n const trIndex = tr.sectionRowIndex ?? rIdx;\n\n // 현재 클릭된 셀의 수직 범위와 겹치는 머지 셀이 있는지 검사\n const isVerticalOverlap = !(trIndex + rSpan - 1 < cell.closest('tr').sectionRowIndex || trIndex > (cell.closest('tr').sectionRowIndex + rSpan - 1));\n\n // 만약 기존에 고정(fixed)되어 있으면서 현재 클릭한 타겟 라인과 걸쳐있는 머지 셀이라면 범위를 확장합니다.\n const isHorizontalOverlap = !(cEnd < baseCol || cCol > targetColIndex);\n\n if (isHorizontalOverlap) {\n minBaseCol = Math.min(minBaseCol, cCol);\n maxEndCol = Math.max(maxEndCol, cEnd);\n }\n });\n });\n });\n\n // 🎯 2단계: 계산된 실제 머지 블록의 시작점(minBaseCol) 이상인 모든 <col> 속성 해제\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx >= minBaseCol) {\n col.removeAttribute('fixed');\n }\n });\n\n // 🎯 3단계: left 구역의 고정 연속성(체인) 검증\n let isBroken = false;\n cols.forEach(col => {\n if (isBroken) {\n col.removeAttribute('fixed');\n } else if (!col.getAttribute('fixed')) {\n isBroken = true;\n }\n });\n\n // 🎯 4단계: <col>들의 최종 fixed 상태를 기준으로 모든 thead, tbody, tfoot 셀(th, td)의 fixed 속성 완벽 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (isNaN(cIdx)) return;\n\n const correspondingCol = cols.find(c => parseInt(c.getAttribute('data-col'), 10) === cIdx);\n const isColFixed = correspondingCol?.getAttribute('fixed');\n\n if (isColFixed) {\n cell.setAttribute('fixed', isColFixed);\n } else {\n cell.removeAttribute('fixed');\n }\n });\n });\n });\n }\n\n trace.log(this.#sheet.sourceTable);\n\n // 🎯 recompileAndRefresh 단 1회 호출로 원본 정렬 및 뷰포트 재생성 완결\n this.#sheet.recompileAndRefresh?.();\n }\n}","import { NINE_TABLE } from '@/core/constants.js';\r\nimport { trace } from \"@nopeer\";\r\n\r\n/**\r\n * 🎯 [필터 패널 커스텀 엘리먼트 Light DOM 버전]\r\n */\r\nexport class NineTableFilterPanel extends HTMLElement {\r\n\t#sheet;\r\n\t#host;\r\n\t#nineTable;\r\n\t#view;\r\n\t#button;\r\n\tcurrentCol = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#init();\r\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\r\n\t}\r\n\r\n\t#init = () => {\r\n\t\t//setTimeout(() => {\r\n\t\t\tthis.#renderer();\r\n\r\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\r\n\t\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\r\n\t\t\ttrace.log(\"1***********************\", this.#nineTable);\r\n\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\r\n\t\t\t\ttrace.log(\"2***********************\", this.#view);\r\n\t\t\t})\r\n\r\n\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t});\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\r\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\r\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\r\n\t\t//});\r\n\t}\r\n\r\n\t#renderer = () => {\r\n\t\tthis.innerHTML = `\r\n <style>\r\n nine-table-filter-panel nine-table-simple {\r\n width: 100%;\r\n flex: 1;\r\n border: none;\r\n }\r\n nine-table-filter-panel.active {\r\n display: flex;\r\n }\r\n nine-table-filter-panel .search-box {\r\n width: 100%;\r\n height: 28px;\r\n box-sizing: border-box;\r\n padding: 0px 8px;\r\n border: none;\r\n border-bottom: 1px solid #e5e7eb;\r\n border-radius: 0px;\r\n outline: none;\r\n font-size: 12px;\r\n background: #fafafa;\r\n color: #333;\r\n }\r\n nine-table-filter-panel .search-box:focus {\r\n background: #ffffff;\r\n }\r\n nine-table-filter-panel .footer-section {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 4px 6px;\r\n gap: 8px;\r\n border-top: 1px solid #e5e7eb;\r\n background: #f9fafb;\r\n flex-shrink: 0;\r\n }\r\n nine-table-filter-panel .footer-btns {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 6px;\r\n }\r\n nine-table-filter-panel .footer-btns label {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n cursor: pointer;\r\n user-select: none;\r\n }\r\n nine-table-filter-panel .btn-group {\r\n display: flex;\r\n gap: 4px;\r\n }\r\n nine-table-filter-panel button {\r\n padding: 4px 14px;\r\n border-radius: 4px;\r\n border: 1px solid #d1d5db;\r\n background: #ffffff;\r\n cursor: pointer;\r\n font-size: 11px;\r\n }\r\n nine-table-filter-panel button:hover {\r\n background: #f3f4f6;\r\n }\r\n nine-table-filter-panel button#btnOk {\r\n background: #2563eb;\r\n color: white;\r\n border: none;\r\n }\r\n </style>\r\n\r\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\r\n \r\n <nine-table-simple class=\"filter-list\" theme=\"simple\">\r\n <table auto-fit-col=\"true\">\r\n <colgroup>\r\n <col width=\"32\" fixed=\"left\" />\r\n <col width=\"180\" />\r\n <col width=\"0\" fixed=\"right\"/>\r\n </colgroup>\r\n <tbody>\r\n <tr>\r\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\r\n <td data-bind=\"DATA2\" html=\"true\"></td>\r\n <td data-bind=\"DATA\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </nine-table-simple>\r\n\r\n <div class=\"footer-section\">\r\n <div class=\"footer-btns\">\r\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\r\n <div class=\"btn-group\">\r\n <button id=\"btnOk\">Apply</button>\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n\t}\r\n\r\n\topen(filterBtn) {\r\n\t\tthis.#button = filterBtn;\r\n\r\n\t\tconst cell = filterBtn.closest(\"th, td\");\r\n\t\tthis.currentCol = cell?.dataset.col;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\r\n\r\n\t\tconst panelWidth = this.offsetWidth || 240;\r\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\r\n\t\tlet top = cellRect.bottom - sheetRect.top;\r\n\r\n\t\tif (left < 0) {\r\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\r\n\t\t}\r\n\r\n\t\tthis.style.left = `${left}px`;\r\n\t\tthis.style.top = `${top}px`;\r\n\r\n\t\tconst searchBox = this.querySelector(\".search-box\");\r\n\t\tsearchBox.value = \"\";\r\n\r\n\t\tthis.classList.add(\"active\");\r\n\t\tthis.classList.add(\"loading\");\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tthis.#loadVirtualFilterItems();\r\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\r\n\t\t\t} finally {\r\n\t\t\t\tthis.classList.remove(\"loading\");\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t#closeHandler = (e) => {\r\n\t\tconst path = e.composedPath ? e.composedPath() : [];\r\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.close();\r\n\t};\r\n\r\n\tclose() {\r\n\t\tthis.currentCol = null;\r\n\t\tthis.classList.remove(\"active\");\r\n\t\tthis.#button = null;\r\n\t}\r\n\r\n\t#loadVirtualFilterItems() {\r\n\t\tconst filteredRecords = this.#host.data.getArray();\r\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] 형태 배열\r\n\t\tconst fields = this.#host.fields.get() || [];\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst ds = targetCols.flatMap((colInfo) => {\r\n\t\t\tconst bindKey = colInfo.bind;\r\n\t\t\tconst exprKey = colInfo.expr;\r\n\r\n\t\t\tconst filterKey = bindKey || exprKey; // 실제 필터 파라미터 키로 사용\r\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\r\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\r\n\r\n\t\t\t// 1. Map을 이용한 O(N) 고속 유니크 추출 (DATA는 bind/원시값, DATA2는 expr 연산 결과)\r\n\t\t\tconst uniqueMap = new Map();\r\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\r\n\t\t\t\tconst record = filteredRecords[i];\r\n\t\t\t\tif (!record) continue;\r\n\r\n\t\t\t\t// DATA 기준이 될 원시 값 (bind가 있으면 필드 인덱스에서, 없으면 expr 결과)\r\n\t\t\t\tlet rawVal = undefined;\r\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\trawVal = record.v[fieldIdx];\r\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\r\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\r\n\t\t\t\t} else if (exprKey && exprEngine) {\r\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// DATA2에 출력될 화면 표시 값 (expr 수식 연산 결과, 없으면 rawVal)\r\n\t\t\t\tlet displayVal = rawVal;\r\n\t\t\t\tif (exprKey && exprEngine) {\r\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\r\n\t\t\t\t\tuniqueMap.set(displayVal, {\r\n\t\t\t\t\t\tv: rawVal, // 💡 필터링 비교 기준 (DATA)\r\n\t\t\t\t\t\tv2: displayVal // 💡 화면 출력 기준 (DATA2)\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst uniqueList = [...uniqueMap.values()];\r\n\r\n\t\t\t// 2. 출력값(v2) 기준 정렬\r\n\t\t\tuniqueList.sort((a, b) => String(a.v2 || \"\").localeCompare(String(b.v2 || \"\")));\r\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\r\n\r\n\t\t\treturn uniqueList.map(o => ({\r\n\t\t\t\tLVL: 2,\r\n\t\t\t\tDATA: o.v, // 필터링 비교용 값\r\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2, // 화면 출력용 값\r\n\t\t\t\tCOLNM: filterKey,\r\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v || \"\") >= 0 ? \"Y\" : \"N\"\r\n\t\t\t}));\r\n\t\t});\r\n\r\n\t\tthis.#nineTable.data.set(ds);\r\n\r\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\r\n\t\tif (selectAllChk) {\r\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\r\n\t\t}\r\n\t}\r\n\r\n\t#onOk = () => {\r\n\t\tthis.#host.loading = true;\r\n\r\n\t\tconst filterRecords = this.#view.view.getArray();\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\r\n\t\tconst checkedRecords = filterRecords.filter(record => {\r\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\r\n\t\t\treturn (chk === \"Y\" || chk === true);\r\n\t\t});\r\n\r\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\r\n\r\n\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\r\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\r\n\r\n\t\t\tif (selectedVals.length > 0) {\r\n\t\t\t\tfilterParams[filterKey] = selectedVals;\r\n\t\t\t} else {\r\n\t\t\t\tdelete filterParams[filterKey];\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tconst totalCount = this.#nineTable.data.count();\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tif (totalCount === checkedRecords.length) {\r\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\t\t\tbtn.updateFilteredState();\r\n\t\t\t\t});\r\n\r\n\t\t\t\tthis.#sheet.invalidate();\r\n\t\t\t\tthis.close();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.#host.loading = false;\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t#onInput = (e) => {\r\n\r\n\t\tconst query = e.target.value.toLowerCase().trim();\r\n\r\n\t\tif (!query) {\r\n\t\t\tthis.#view.filtering.clear();\r\n\t\t} else {\r\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\r\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\r\n\r\n\t\t\tconst matchedValues = [];\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\r\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\r\n\r\n\t\t\t\t// 💡 expr 연산 결과가 담긴 DATA2 텍스트와 검색어 비교\r\n\t\t\t\tif (textVal.includes(query)) {\r\n\t\t\t\t\tmatchedValues.push(val);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\ttrace.log(matchedValues);\r\n\r\n\t\t\tthis.#view.filtering.set({\r\n\t\t\t\tDATA2: [...new Set(matchedValues)]\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t#onSelectAll = (e) => {\r\n\t\tconst isChecked = e.target.checked;\r\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\r\n\r\n\t\tif (chkIdx >= 0) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#nineTable.refresh();\r\n\t};\r\n\r\n\t#onCancel = () => {\r\n\t\tthis.close();\r\n\t};\r\n}\r\n\r\nexport class NineTableFilterButton extends HTMLElement {\r\n\t#sheet;\r\n\t#columns = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\r\n\t\tthis.removeEventListener(\"click\", this.#onClick);\r\n\t\tthis.addEventListener(\"click\", this.#onClick);\r\n\t}\r\n\r\n\tget columns() {\r\n\t\tif (this.#columns) return this.#columns;\r\n\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst colIndex = cell?.dataset.col;\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\r\n\t\tconst cols = [];\r\n\t\tconst seen = new Set();\r\n\r\n\t\tif (sourceTable && colIndex !== undefined) {\r\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\t\tconst bindKey = $td.dataset.bind;\r\n\t\t\t\tconst exprKey = $td.dataset.expr;\r\n\r\n\t\t\t\tif (bindKey || exprKey) {\r\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\r\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\r\n\t\t\t\t\t\tseen.add(uniqueKey);\r\n\t\t\t\t\t\tcols.push({\r\n\t\t\t\t\t\t\tbind: bindKey,\r\n\t\t\t\t\t\t\texpr: exprKey,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#columns = cols;\r\n\t\treturn this.#columns;\r\n\t}\r\n\r\n\tupdateFilteredState = () => {\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst isFiltered = this.columns.some(colInfo => {\r\n\t\t\tconst key = colInfo.expr || colInfo.bind;\r\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\r\n\t\t});\r\n\t\tthis.classList.toggle('filtered', isFiltered);\r\n\t};\r\n\r\n\t#onClick = (e) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst col = cell?.dataset.col;\r\n\r\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\r\n\t\t\tpanel.close();\r\n\t\t} else if (panel) {\r\n\t\t\tpanel.open(this);\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class Filtering {\r\n\t#sheet;\r\n\t#host;\r\n\t#isFiltering = false;\r\n\t#filterPanel = null;\r\n\t#filters = {};\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t\tthis.#init();\r\n\t}\r\n\r\n\tget filters() {\r\n\t\treturn this.#filters;\r\n\t};\r\n\r\n\t#init = () => {\r\n\t\tthis.#initFilterPanel();\r\n\t}\r\n\r\n\t#initFilterPanel = () => {\r\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tif (!panel) {\r\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\r\n\t\t\tthis.#sheet.appendChild(panel);\r\n\t\t}\r\n\t\tthis.#filterPanel = panel;\r\n\t}\r\n\r\n\tisFiltering() {\r\n\t\treturn this.#isFiltering;\r\n\t}\r\n\r\n\tclear = (colnm) => {\r\n\t\tif (colnm) {\r\n\t\t\tdelete this.#filters[colnm];\r\n\t\t} else {\r\n\t\t\tthis.#filters = {};\r\n\t\t}\r\n\r\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\r\n\t\tthis.#applyFiltering();\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\tbtn.updateFilteredState();\r\n\t\t});\r\n\r\n\t\ttrace.log(`🔄 [NineTableFiltering] Filter cleared for ${colnm || 'all'}`);\r\n\t}\r\n\r\n\tset = (oFilter) => {\r\n\r\n\t\ttrace.log(oFilter);\r\n\r\n\t\tlet jsonFilter = Array.isArray(oFilter)\r\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\r\n\t\t\t: oFilter;\r\n\r\n\t\tthis.#filters = jsonFilter;\r\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\r\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\r\n\r\n\t\tthis.#applyFiltering();\r\n\t}\r\n\r\n\t#applyFiltering() {\r\n\t\tconst hostData = this.#host.data;\r\n\t\tconst rawRecords = hostData.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields();\r\n\t\tconst sheetIndex = this.#sheet.index;\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\r\n\r\n\t\tif (!hasFilters) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\tthis.#sheet.invalidate();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 💡 필터 규칙 빌드 (targetKey가 bind인지 expr 수식인지 판별)\r\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\r\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\r\n\t\t\treturn {\r\n\t\t\t\ttargetKey,\r\n\t\t\t\tisExpr,\r\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\r\n\t\t\t\tallowedSet: new Set(allowedValues)\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\trawRecords.forEach((record, recordIdx) => {\r\n\t\t\tif (!record) return;\r\n\r\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\r\n\t\t\t}\r\n\r\n\t\t\tlet isPass = true;\r\n\r\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\r\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\r\n\t\t\t\tlet val = undefined;\r\n\r\n\t\t\t\tif (isExpr && exprEngine) {\r\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\r\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\tval = record.v[fieldIdx];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!allowedSet.has(val)) {\r\n\t\t\t\t\tisPass = false;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.invalidate();\r\n\t}\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-panel')) {\r\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-button')) {\r\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\r\n}","// ui/data/Sorting.js (또는 정렬 관련 소스)\r\nimport { trace } from \"@nopeer\";\r\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\r\n\r\nexport class Sorting {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#columns = [];\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.#initEvents();\r\n\t\t}, 300);\r\n\t}\r\n\r\n\t#initEvents() {\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\r\n\r\n\t\t\t$el.addEventListener('dblclick', (e) => {\r\n\r\n\t\t\t\tconst cell = e.target.closest('th, td');\r\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\r\n\r\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\r\n\r\n\t\t\t\t// 🎯 [수정] 줄바꿈으로 깨져있던 마이너스 연산자를 한 줄로 정상 복구\r\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\r\n\r\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\r\n\r\n\t\t\t\thost.loading = true;\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tthis.#handleSort(e, cell);\r\n\t\t\t\t\t} finally {\r\n\t\t\t\t\t\t// 🎯 3. 작업이 끝나면 무조건 로딩바 끄기\r\n\t\t\t\t\t\thost.loading = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}); // 또는 requestAnimationF\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\ttrace.log(\"🎯 [NineTableSorting] Initialized\");\r\n\t}\r\n\r\n\t#handleSort(e, cell) {\r\n\t\tconst colIndex = cell.dataset.col;\r\n\t\tconst tr = cell.closest('tr');\r\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\r\n\r\n\t\tif (colIndex === undefined) return;\r\n\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (!sourceTable) return;\r\n\r\n\t\tlet colName = null;\r\n\t\tlet exprVal = null; // 💡 expr 속성 수집용 변수\r\n\r\n\t\t// 1. 🎯 데이터 바인딩 키(colName) 및 expr 탐지\r\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\tif ($td.dataset.bind) {\r\n\t\t\t\tcolName = $td.dataset.bind;\r\n\t\t\t}\r\n\t\t\t// 💡 셀에 선언된 expr 식 추출\r\n\t\t\tif ($td.dataset.expr) {\r\n\t\t\t\texprVal = $td.dataset.expr;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (!colName && !exprVal) return;\r\n\r\n\t\tconst isAsc = cell.classList.contains('asc');\r\n\t\tconst isDesc = cell.classList.contains('desc');\r\n\r\n\t\tif (!e.ctrlKey && !e.shiftKey) {\r\n\t\t\tthis.#columns = [];\r\n\t\t}\r\n\r\n\t\tconst existingColIndex = this.#columns.findIndex(\r\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\r\n\t\t);\r\n\r\n\t\t// 정렬 규칙 추가 시 expr 속성(`expr`) 함께 저장\r\n\t\tconst ruleData = {\r\n\t\t\tcolIndex,\r\n\t\t\tsubRowIndex,\r\n\t\t\tcolname: colName || exprVal,\r\n\t\t\tcolName: colName || exprVal,\r\n\t\t\texpr: exprVal, // 💡 expr 규칙 보관\r\n\t\t\tasc: true,\r\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\r\n\t\t};\r\n\r\n\t\tif (!isAsc && !isDesc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\r\n\t\t\t}\r\n\t\t} else if (isAsc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.#columns = this.#columns.filter(\r\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tthis.#applySorting();\r\n\t}\r\n\r\n\t#applySorting() {\r\n\t\tif (!this.#sheet.view) {\r\n\t\t\tconsole.warn(\"⚠️ [NineTableSorting] Sheet view (SheetView) is not initialized.\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.view.setSorting(this.#columns);\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.invalidate();\r\n\t\t//this.#sheet.rowManager?.refresh(true);\r\n\r\n\t\ttrace.log(\"🔄 [NineTableSorting] Sorting applied via RowManager.refresh(true)\");\r\n\t}\r\n\r\n\t#syncHeaderUI() {\r\n\t\t// 기존 UI 클래스 초기화\r\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\r\n\t\t\tel.classList.remove('asc', 'desc');\r\n\t\t});\r\n\r\n\t\tif (this.#columns.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 🎯 [핵심] tr[data-subrow] + [data-col] 조합으로 정밀 타겟팅\r\n\t\tthis.#columns.forEach(colRule => {\r\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\r\n\r\n\t\t\tif (colIndex !== undefined) {\r\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\r\n\t\t\t\tif (subRowIndex !== undefined) {\r\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\r\n\t\t\t\ttargetHeaderCells.forEach(cell => {\r\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t//TableCompiler.decompile(this.#sheet);\r\n\t}\r\n\r\n\trestore() {\r\n\t\tthis.#columns = [];\r\n\t\tif (this.#sheet.view) {\r\n\t\t\tthis.#sheet.view.resetSorting();\r\n\t\t}\r\n\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.rowManager?.refresh(true);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\nimport {Grouping} from \"@/data/Grouping.js\";\r\n\r\nexport class SheetView {\r\n\t#sheet;\r\n\t#host;\r\n\t#sortingColumns = []; // 정렬 규칙 [{ colname, asc, expr-func }]\r\n\t#filterRules = []; // 필터 규칙\r\n\t#viewIndexes = []; // 필터링 및 소팅이 반영된 유효 데이터 인덱스 버퍼\r\n\r\n\t#cachedVisibleRecords = null; // 💡 [추가] 캐싱된 유효 레코드 배열\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.refresh();\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [시트 뷰 전용 배열 조회] - 캐시 적용으로 성능 대폭 개선\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\t// 💡 캐시가 없거나 비어있을 때만 가져옴 (보통 refresh에서 갱신됨)\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords;\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.#host.data.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord;\r\n\t};\r\n\r\n\tget = (at, colnm) => {\r\n\t\tconst visibleRecords = this.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (!targetRecord) return null;\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#convSingle(targetRecord, fields);\r\n\t};\r\n\r\n\t#convSingle = (o, fields) => {\r\n\t\tif (!o) return null;\r\n\t\tconst t = {};\r\n\t\tfields.forEach((colnm, i) => {\r\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t});\r\n\t\tif (o.m) t.m = o.m;\r\n\t\tif (o._) t._ = o._;\r\n\t\treturn t;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 또는 정렬/필터 변경 시에만 실행되는 뷰 버퍼 재계산\r\n\t */\r\n\t\t// SheetView.refresh() 내부 예시\r\n\trefresh = () => {\r\n\r\n\t\tthis.#cachedVisibleRecords = null;\r\n\r\n\t\t// 1. 필터 적용\r\n\t\tconst rawRecords = this.#host.data.getArray();\r\n\t\tlet indices = [];\r\n\t\trawRecords.forEach((record, i) => {\r\n\t\t\tif (!record) return;\r\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\r\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\r\n\t\t\tindices.push(i);\r\n\t\t});\r\n\r\n\t\ttrace.log(indices);\r\n\r\n\t\t// 2. 정렬 적용\r\n\t\tif (this.#sortingColumns.length > 0) {\r\n\t\t\tindices = this.#applySorting(indices, rawRecords);\r\n\t\t}\r\n\r\n\t\tthis.#viewIndexes = indices;\r\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\r\n\r\n\t\t//trace.log(this.#sheet.sourceTable);\r\n\t\t//const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\r\n\t\t//trace.log(\"#######\", isGrouped, this.#sheet.grouping?.columns);\r\n\t\tconst groupColumns = this.#sheet.grouping?.columns || [];\r\n\t\tif (groupColumns.length > 0) {\r\n\t\t\t//this.#sheet.grouping.apply();\r\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields());\r\n\t\t\t//const groupResult = Grouping.apply(validRecords);\r\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // 최종 렌더링 아이템\r\n\r\n\t\t\t//trace.log(\"2.============================\", groupColumns, this.#cachedVisibleRecords);\r\n\r\n\t\t\tthis.#sheet.grouping.setGroupMap(groupResult.groupMap); // 자식 매핑 공유\r\n\t\t} else {\r\n\t\t\tthis.#cachedVisibleRecords = validRecords;\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n\tsetSorting = (columns) => {\r\n\t\tthis.#sortingColumns = columns || [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\tgetSorting = () => {\r\n\t\treturn this.#sortingColumns;\r\n\t};\r\n\r\n\tresetSorting = () => {\r\n\t\tthis.#sortingColumns = [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\r\n\t#applySorting = (indices, validRecords) => {\r\n\t\ttrace.log(new Date());\r\n\r\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\r\n\r\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\r\n\t\t\t...rule,\r\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\r\n\t\t}));\r\n\r\n\t\treturn indices.sort((idxA, idxB) => {\r\n\t\t\tconst a = validRecords[idxA];\r\n\t\t\tconst b = validRecords[idxB];\r\n\r\n\t\t\tfor (const rule of rulesWithIdx) {\r\n\t\t\t\tconst isAsc = rule.asc;\r\n\t\t\t\tconst expr = rule.expr; // 💡 등록된 expr 수식\r\n\t\t\t\tlet valA, valB;\r\n\r\n\t\t\t\t// 💡 1. expr 수식이 존재하면 ExprEngine으로 연산된 결과값을 가져옴\r\n\t\t\t\tif (expr) {\r\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\r\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 2. 일반 바인딩 필드인 경우 원시 배열에서 추출\r\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\r\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\r\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\r\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\r\n\r\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\r\n\t\t\t\tif (isEmptyA) return 1;\r\n\t\t\t\tif (isEmptyB) return -1;\r\n\r\n\t\t\t\tif (valA !== valB) {\r\n\t\t\t\t\tlet diff = 0;\r\n\r\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\r\n\t\t\t\t\t\tdiff = valA - valB;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst strA = String(valA);\r\n\t\t\t\t\t\tconst strB = String(valB);\r\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (diff !== 0) {\r\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn idxA - idxB;\r\n\t\t});\r\n\r\n\t\ttrace.log(new Date());\r\n\t};\r\n}","import { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class PreCompiler {\n\n static initializeTable(host, tbl) {\n if (!host || !tbl) return null;\n\n // 1. 기본 구조 보장 (colgroup, thead)\n PreCompiler.#ensureColgroup(tbl);\n PreCompiler.#ensureThead(tbl);\n PreCompiler.#ensureSectionTbodys(tbl);\n\n PreCompiler.#ensureRowIndicator(tbl);\n\n PreCompiler.#normalizeColAttributes(tbl);\n\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tfoot tr'));\n\n PreCompiler.#createColIndicator(tbl);\n\n // 2. 속성 정규화 (collapsed=\"true\" -> collapsible=\"true\" 보정)\n PreCompiler.#normalizeCollapsibleAttributes(tbl);\n\n // 3. 셀 커스텀 엘리먼트 생성\n PreCompiler.#generateCell(host, tbl);\n\n // 5. 초기 접힘/펼치기(expand) 버튼 및 너비 세팅\n PreCompiler.#initColExpanders(tbl);\n\n // 6. 필터 버튼 생성\n PreCompiler.#initFilterButtons(host, tbl);\n\n PreCompiler.#applyInitialCellWidths(tbl);\n //tbl.classList.add('nine-table-element');\n\n //trace.log(\"**************\", tbl.cloneNode(true));\n return tbl;\n }\n\n static #createColIndicator(tbl) {\n const thead = tbl.querySelector('thead');\n if (!thead || thead.querySelector('.col-indicator-rowgroup')) return;\n\n const tdTmpl = `<th data-col=\"@col\" class=\"col-indicator\" scope=\"col\"></th>`;\n\n // 맨 위에 인덱스용 row(tr) 삽입\n const tr = thead.insertRow(0);\n tr.setAttribute('role', 'row');\n tr.classList.add('col-indicator-rowgroup');\n tr.classList.add('collapse');\n\n const firstRow = tbl.querySelector('tbody tr');\n if (!firstRow) return;\n\n let cnt = 0;\n firstRow.querySelectorAll('th, td').forEach(td => {\n if (!td.classList.contains('dummy')) {\n const colSpan = td.colSpan || 1;\n for (let i = 0; i < colSpan; i++) {\n const html = tdTmpl.replace('@col', cnt).replace('@text', PreCompiler.#numToExcelCol(cnt++));\n tr.insertAdjacentHTML('beforeend', html);\n }\n }\n });\n\n // 🎯 colgroup의 모든 스타일 및 속성 동기화\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n tr.querySelectorAll('.col-indicator').forEach((el, i) => {\n const background = cols[i].getAttribute('background');\n if (background) {\n el.style.background = background;\n }\n });\n }\n\n // 엑셀 스타일 알파벳 변환 유틸 (A, B, C ... Z, AA, AB ...)\n static #numToExcelCol(num) {\n let text = '';\n for (let n = num; n >= 0; n = Math.floor(n / 26) - 1) {\n text = String.fromCharCode(65 + (n % 26)) + text;\n }\n return text;\n }\n\n static #ensureSectionTbodys(tbl) {\n let tbody = tbl.querySelector('tbody:not(.head):not(.foot)');\n\n if (!tbody) return;\n\n tbody.classList.add('body');\n\n // 🎯 이미 존재하지 않을 때만 생성\n if (!tbl.querySelector('tbody.head')) {\n const headTbody = document.createElement('tbody');\n headTbody.classList.add('head');\n tbody.before(headTbody);\n }\n\n if (!tbl.querySelector('tbody.foot')) {\n const footTbody = document.createElement('tbody');\n footTbody.classList.add('foot');\n tbody.after(footTbody);\n }\n }\n\n static #ensureColgroup(tbl) {\n let colgroup = tbl.querySelector('colgroup');\n if (!colgroup) {\n colgroup = document.createElement('colgroup');\n tbl.prepend(colgroup);\n }\n\n // 🎯 <col> 엘리먼트 자체가 없다면 행 기준으로 생성\n if (colgroup.querySelectorAll('col').length === 0) {\n const firstRow = tbl.querySelector('tbody tr');\n let colCount = 1;\n if (firstRow) {\n colCount = Array.from(firstRow.querySelectorAll('th, td')).reduce((sum, cell) => {\n return sum + (parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1);\n }, 0);\n }\n colCount = Math.max(colCount, 1);\n\n for (let i = 0; i < colCount; i++) {\n const col = document.createElement('col');\n colgroup.appendChild(col);\n }\n }\n\n // 🎯 col 속성 및 너비 정리는 별도 함수로 분리\n //PreCompiler.#normalizeColAttributes(tbl);\n }\n\n // 🎯 <col>들의 data-col, width, style.width 속성 정리를 전담하는 메서드\n static #normalizeColAttributes(tbl) {\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n if (cols.length === 0) return;\n\n const containerWidth = tbl.clientWidth || 0;\n const defaultWidth = Math.max(Math.floor(containerWidth / cols.length), 100);\n\n cols.forEach((col, i) => {\n // 1. data-col 인덱스 보장\n if (!col.hasAttribute('data-col')) {\n col.setAttribute('data-col', i);\n }\n\n // 2. width 속성 및 style.width 정규화\n const width = col.getAttribute('width') || parseInt(col.style.width, 10) || defaultWidth;\n col.setAttribute('width', width);\n\n const widthVal = String(width).includes('px') ? width : `${width}px`;\n col.style.width = widthVal;\n });\n }\n\n static #ensureThead(tbl) {\n if (tbl.querySelector('thead')) return;\n\n const thead = document.createElement('thead');\n const colgroup = tbl.querySelector('colgroup');\n\n if (colgroup) {\n colgroup.after(thead);\n } else {\n tbl.prepend(thead);\n }\n }\n\n static #normalizeCollapsibleAttributes(tbl) {\n const headers = tbl.querySelectorAll('thead th, thead td');\n headers.forEach(cell => {\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n if (isCollapsed && cell.getAttribute('collapsible') !== 'true') {\n cell.setAttribute('collapsible', 'true');\n }\n });\n }\n\n static #generateCell(host, $tbl) {\n\n const targetAttributes = ['data-bind', 'data-expr', 'type'];\n let autoIdCounter = 0;\n\n $tbl.querySelectorAll('tbody th, tbody td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type') || \"renderer\";\n const tagName = `cell-${cellType}`;\n\n const $datalist = $cell.querySelector(\"datalist\");\n\n if ($datalist) {\n let l = [];\n $datalist.querySelectorAll('option').forEach($option => {\n l.push({\n k: $option.getAttribute(\"k\"),\n v: $option.getAttribute(\"v\"),\n });\n });\n\n // 🎯 1. 절대 겹치지 않는 유니크한 가상 함수 이름 생성\n const uniqueFuncName = `__ds_${Date.now()}_${++autoIdCounter}`;\n\n // 🎯 2. 호스트(NineTable)에 해당 데이터를 반환하는 클로저 함수 등록\n if (host) {\n host[uniqueFuncName] = () => l;\n }\n\n // 🎯 3. 셀에 data-source 자동 장착 (정규식/세터 스캔기가 알아서 캐치함)\n $cell.setAttribute(\"data-source\", `host.${uniqueFuncName}()`);\n\n // 🎯 4. 사용이 끝난 정적 datalist 엘리먼트는 DOM에서 제거\n $datalist.remove();\n }\n\n const expr = $cell.dataset.expr;\n if (expr) {\n $cell.setAttribute('data-expr', host.exprEngine.precompile(expr));\n }\n\n // 💡 2. 기타 속성들 중 표현식이 포함된 경우 프리컴파일\n Array.from($cell.attributes).forEach(attr => {\n if (['data-bind', 'data-expr', 'cell-type'].includes(attr.name)) return;\n if (attr.value.includes(\"data.\") || attr.value.includes(\"host.\")) {\n $cell.setAttribute(attr.name, host.exprEngine.precompile(attr.value));\n }\n });\n\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')}></${tagName}>`;\n $cell.setAttribute('tabindex', '0');\n });\n\n $tbl.querySelectorAll('thead th, thead td, tfoot th, tfoot td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type');\n if (cellType) {\n const originalContent = $cell.innerHTML;\n const tagName = `cell-${cellType}`;\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')} content=\"${originalContent}\"></${tagName}>`;\n }\n });\n }\n\n static #initFilterButtons(host, tbl) {\n const hostFilter = host.getAttribute('filtering') === 'true';\n const tableFilter = tbl.getAttribute('filtering') === 'true';\n\n // 🎯 인덱스 행을 제외한 실제 헤더 셀들만 타겟팅\n tbl.querySelectorAll('thead tr:not(.col-indicator-rowgroup) th, thead tr:not(.col-indicator-rowgroup) td').forEach(cell => {\n const finalFiltering = cell.getAttribute('filtering') === 'true' || tableFilter || hostFilter;\n\n cell.setAttribute('filtering', finalFiltering ? 'true' : 'false');\n\n if (finalFiltering) {\n cell.appendChild(document.createElement('nine-table-filter-button'));\n }\n });\n }\n\n static #initColExpanders(tbl) {\n /** 작동하나? */\n tbl.querySelectorAll('thead th, thead td').forEach(cell => {\n const isCollapsible = cell.getAttribute('collapsible') === 'true' || cell.getAttribute('expandable') === 'true';\n if (!isCollapsible) return;\n\n trace.log(\"11.*******************************\", cell.dataset.col);\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 trace.log(\"11.*******************************\", col);\n\n const currentWidth = col ? (parseInt(col.getAttribute('width'), 10) || 100) : 100;\n\n if (!cell.dataset.expandWidth || parseInt(cell.dataset.expandWidth, 10) <= COLLAPSED_WIDTH) {\n cell.dataset.expandWidth = String(currentWidth > COLLAPSED_WIDTH ? currentWidth : 100);\n }\n\n let expandBtn = cell.querySelector('nine-table-col-expand');\n if (!expandBtn) {\n expandBtn = document.createElement('nine-table-col-expand');\n cell.insertBefore(expandBtn, cell.firstChild);\n }\n\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n expandBtn.classList.add('collapsed');\n expandBtn.classList.remove('expand');\n expandBtn.setAttribute('collapsed', 'true');\n cell.style.color = 'transparent';\n\n const targetWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n if (!isNaN(colIndex)) {\n for (let i = 0; i < colSpan; i++) {\n const targetCol = tbl.querySelector(`colgroup col[data-col=\"${colIndex + i}\"]`);\n if (targetCol) {\n targetCol.setAttribute('width', targetWidth);\n targetCol.style.width = `${targetWidth}px`;\n }\n }\n }\n } else {\n expandBtn.classList.remove('collapsed');\n expandBtn.classList.add('expand');\n expandBtn.setAttribute('collapsed', 'false');\n cell.style.color = '';\n }\n });\n }\n\n static #ensureRowIndicator(tbl, host) {\n // 1. colgroup에 인디케이터용 <col> 추가\n const w = tbl.getAttribute(\"row-indicator\") === 'true' ? 48 : 0;\n\n const colgroup = tbl.querySelector('colgroup');\n\n //if (colgroup && !colgroup.querySelector('col.row-indicator-col')) {\n const col = document.createElement('col');\n //col.className = 'row-indicator-col';\n col.setAttribute('fixed', 'left');\n col.setAttribute('width', w);\n col.style.width = `${w}px`;\n colgroup.prepend(col);\n //}\n\n // 2. thead, tbody, tfoot 각 섹션별로 첫 번째 tr에 인디케이터 생성 및 rowSpan 부여\n //const sections = tbl.querySelectorAll('thead, tbody, tfoot');\n\n tbl.querySelectorAll('thead, tbody, tfoot').forEach(section => {\n const rows = Array.from(section.querySelectorAll('tr'));\n if (rows.length === 0) return;\n\n const firstTr = rows[0];\n\n const indicatorCell = document.createElement('th');\n indicatorCell.className = 'row-indicator';\n indicatorCell.setAttribute('cell-type', 'row-indicator');\n //indicatorCell.setAttribute('filtering', 'false');\n\n // 💡 섹션 내 행이 여러 개면(멀티 라인 템플릿 등) 전체를 아우르도록 rowSpan 설정\n if (rows.length > 1) {\n indicatorCell.rowSpan = rows.length;\n }\n\n firstTr.insertBefore(indicatorCell, firstTr.firstElementChild);\n });\n }\n\n static #applyInitialCellWidths(tbl) {\n // 🎯 컬럼 기준이 아닌 셀(th, td) 기준으로 순회하여 colspan 반영\n tbl.querySelectorAll('th[data-col], td[data-col]').forEach(cell => {\n\n trace.log(cell);\n\n const startColIdx = parseInt(cell.getAttribute('data-col'), 10);\n if (isNaN(startColIdx)) return;\n\n // 셀의 실제 colspan 값 추출 (기본값 1)\n const colSpan = parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1;\n let totalWidth = 0;\n\n // colspan 만큼 다음 컬럼들의 너비를 누적 합산\n for (let i = 0; i < colSpan; i++) {\n const targetIdx = startColIdx + i;\n const col = tbl.querySelector(`colgroup col[data-col=\"${targetIdx}\"]`);\n if (col) {\n totalWidth += parseInt(col.getAttribute('width'), 10) || 100;\n }\n }\n\n if (totalWidth > 0) {\n const widthVal = `${totalWidth}px`;\n cell.style.width = widthVal;\n cell.style.minWidth = widthVal;\n cell.style.maxWidth = widthVal;\n }\n });\n }\n}","// NineTableSheet.js (필터 버튼 레이아웃 및 패딩 스타일 완벽 통합본)\n\nimport { trace } from \"@nopeer\";\nimport './nine-table-hscrollbar.js';\nimport './nine-table-vscrollbar.js';\nimport { RowManager } from './core/RowManager.js';\nimport { TableCompiler } from \"./core/TableCompiler.js\";\nimport { CellSelection } from \"@/ui/cell-manager/CellSelection.js\";\nimport { CellNavigation } from \"@/ui/cell-manager/CellNavigation.js\";\n\nimport { ColResizer } from \"@/ui/col/ColResizer.js\";\nimport { ColMover } from \"@/ui/col/ColMover.js\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nimport { Filtering } from \"@/data/Filtering.js\";\nimport {Grouping, GroupingManager} from \"@/data/Grouping.js\";\nimport { Sorting } from \"@/data/Sorting.js\";\nimport { SheetView } from \"@/data/SheetView.js\";\n\nimport { PreCompiler } from \"@/ui/layout/core/PreCompiler.js\";\n\nexport class NineTableSheet extends HTMLElement {\n #index;\n #host;\n #rowManager;\n #cellSelection;\n #cellNavigation;\n #colResizer;\n #colMover;\n #colFix;\n #sorting;\n #filtering;\n #grouping;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n static SCROLLBAR_SIZE = 16;\n\n constructor() {\n super();\n trace.log(\"11111\")\n this.#rowManager = new RowManager(this);\n trace.log(\"222\")\n this.#host = this.getRootNode().host;\n trace.log(\"333\")\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get index() { return this.#index; }\n get colResizer() { return this.#colResizer; }\n get filtering() { return this.#filtering; }\n get grouping() { return this.#grouping; }\n get colMover() { return this.#colMover; }\n get colFix() { return this.#colFix; }\n get rowManager() { return this.#rowManager; }\n get selection() { return this.#cellSelection; }\n get navigation() { return this.#cellNavigation; }\n get templateLength() { return this.#source.tbody.tr.length || 0; }\n\n get elements() { return this.#elements; }\n\n get isAutoFitCol() {\n const attrTrue = this.getAttribute('auto-fit-col') === 'true' || this.#host?.getAttribute('auto-fit-col') === 'true';\n const sourceTableTrue = this.#source.table?.getAttribute('auto-fit-col') === 'true';\n return attrTrue || sourceTableTrue;\n }\n\n get sourceTable() {\n return this.#source.table;\n }\n\n get source() {\n return this.#source;\n }\n\n get #isSimple() {\n return this.#host.hasAttribute('simple') || this.#host.getAttribute('theme') === 'simple';\n }\n\n recompileAndRefresh() {\n if (!this.#source.table) return;\n\n TableCompiler.recompile(this.#source.table);\n\n ['left', 'right', 'body'].forEach(type => {\n ['header', 'body', 'footer'].forEach(section => {\n const container = this.querySelector(`.ng-sheet-${section} .ng-container-${type}`);\n if (!container) return;\n container.querySelectorAll('table').forEach(tbl => tbl.remove());\n });\n });\n\n this.#renderSplitContainers();\n\n this.#updateContainerWidths();\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n requestAnimationFrame(() => {\n this.#updateContainerWidths();\n this.#rowManager?.refresh();\n });\n }\n\n refreshLayout() {\n if (!this.classList.contains('active') || !this.#source.table) return;\n\n requestAnimationFrame(() => {\n\n this.#updateContainerWidths();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n this.#adjustOverlay();\n\n this.#colResizer?.refreshLayout();\n\n this.#rowManager?.refresh();\n });\n }\n\n #adjustOverlay = () => {\n // 3분할된 영역 중 중앙(body) 또는 좌측 영역의 thead를 타겟팅하여 높이 측정\n const $thead = this.querySelector('.ng-container-body thead');\n const $overlay = this.querySelector('.ng-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 trace.log(\"***************** autoFit\", this);\n\n const container = this.querySelector('.ng-sheet-body .ng-container-body');\n if (!container) return;\n\n //const tables = container.querySelectorAll('table');\n const firstColgroup = this.querySelector('.ng-container-body table colgroup');\n if (!firstColgroup) return;\n\n if (enable) {\n this.setAttribute('auto-fit-col', 'true');\n const containerWidth = container.clientWidth;\n if (containerWidth <= 0) return;\n\n let totalOriginalWidth = 0;\n const colList = [];\n\n // 1단계: 접힌 컬럼(16px 고정)과 일반 컬럼을 분리해서 수집\n firstColgroup.querySelectorAll('col').forEach(col => {\n const globalColIndex = col.getAttribute('data-col');\n const headerCell = this.querySelector(`thead th[data-col=\"${globalColIndex}\"]`);\n const isCollapsed = headerCell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n colList.unshift({ globalColIndex, width: 16, isCollapsed: true });\n trace.log(`[AutoFit Col] Index ${globalColIndex}: COLLAPSED (forced 16px)`);\n } else {\n const w = parseInt(col.getAttribute('width'), 10) || 100;\n colList.push({ globalColIndex, width: w, isCollapsed: false });\n totalOriginalWidth += w;\n trace.log(`[AutoFit Col] Index ${globalColIndex}: NORMAL (original width: ${w}px)`);\n }\n });\n\n trace.log(`[AutoFit] Total Original Width of Normal Cols: ${totalOriginalWidth}px`);\n\n // 접힌 컬럼들이 차지하는 총 너비 계산\n const collapsedTotalWidth = colList\n .filter(c => c.isCollapsed)\n .reduce((sum, c) => sum + c.width, 0);\n\n // 남은 컨테이너 너비를 펼쳐진 컬럼들에게만 배분 (오류 수정)\n const availableWidth = Math.max(0, containerWidth - collapsedTotalWidth);\n trace.log(`[AutoFit] Collapsed Total Width: ${collapsedTotalWidth}px | Available Width for Normal Cols: ${availableWidth}px`);\n\n if (totalOriginalWidth > 0 && colList.length > 0) {\n let allocatedTotal = 0;\n\n const calculatedCols = colList.map(item => {\n if (item.isCollapsed) {\n return { globalColIndex: item.globalColIndex, remainder: 0, width: 16 };\n }\n\n // 연산자 오류 수정 (* 와 - 추가)\n const exactWidth = (item.width * availableWidth) / totalOriginalWidth;\n const baseWidth = Math.max(30, Math.floor(exactWidth));\n allocatedTotal += baseWidth;\n return {\n globalColIndex: item.globalColIndex,\n remainder: exactWidth - Math.floor(exactWidth),\n width: baseWidth\n };\n });\n\n // 잔여 픽셀 보정 (오류 수정)\n let remainderPixels = availableWidth - allocatedTotal;\n trace.log(`[AutoFit] Initial Allocated Total: ${allocatedTotal}px | Remainder Pixels to distribute: ${remainderPixels}`);\n\n const uncollapsedCols = calculatedCols.filter(c => !colList.find(item => item.globalColIndex === c.globalColIndex)?.isCollapsed);\n\n if (remainderPixels > 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => b.remainder - a.remainder);\n for (let i = 0; i < remainderPixels; i++) {\n uncollapsedCols[i % uncollapsedCols.length].width += 1;\n }\n } else if (remainderPixels < 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => a.remainder - b.remainder);\n for (let i = 0; i < Math.abs(remainderPixels); i++) {\n const target = uncollapsedCols[i % uncollapsedCols.length];\n if (target.width > 30) target.width -= 1;\n }\n }\n\n const finalSumWidth = calculatedCols.reduce((sum, c) => sum + c.width, 0);\n trace.log(`[AutoFit Verification] Target Container Width: ${containerWidth}px | Sum of All Calculated Cols: ${finalSumWidth}px`);\n\n if (containerWidth !== finalSumWidth) {\n trace.log(`⚠️ [AutoFit Mismatch Warning!] 오차 발생: ${containerWidth - finalSumWidth}px 차이가 납니다.`);\n } else {\n trace.log(`✅ [AutoFit Success] 완벽하게 일치합니다!`);\n }\n\n // 최종 적용\n calculatedCols.forEach(({ globalColIndex, width }) => {\n trace.log(`[AutoFit Apply] Col Index ${globalColIndex} -> ${width}px`);\n this.#colResizer?.setColumnWidth(globalColIndex, width, 'body');\n });\n }\n } else {\n this.removeAttribute('auto-fit-col');\n }\n\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n generate = ($table, index) => {\n\n this.#index = index;\n\n PreCompiler.initializeTable(this.#host, $table);\n\n trace.log(\"=======\", $table);\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n this.#renderSplitContainers();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#updateContainerWidths();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#syncHeaderAndFooterHeights();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //\n this.#initRowHoverEvent();\n\n ['left', 'body', 'right'].forEach(type => {\n const prefix = `.ng-container-${type}`;\n this.#elements[type] = {\n thead: this.querySelector(`${prefix} thead`),\n tbody: {\n head: this.querySelector(`${prefix} tbody.head`),\n body: this.querySelector(`${prefix} tbody.body`),\n foot: this.querySelector(`${prefix} tbody.foot`),\n },\n tfoot: this.querySelector(`${prefix} tfoot`),\n };\n });\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //trace.log(\"********1\", this.#source.table)\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar').refresh();\n }\n\n //this.#grouping = new GroupingManager(this);\n this.#grouping.initialize();\n\n this.loaded = true;\n };\n\n\n #updateContainerWidths = () => {\n const isAutoFit = this.isAutoFitCol;\n\n ['left', 'right', 'body'].forEach(type => {\n const containers = this.querySelectorAll(`.ng-container-${type}`);\n if (containers.length === 0) return;\n\n const firstTable = containers[0].querySelector('table');\n if (!firstTable) return;\n\n let width = 0;\n firstTable.querySelectorAll('col').forEach(col => {\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) width += w;\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n if (type === 'body') {\n container.style.flex = `1`;\n tables.forEach(tbl => {\n //tbl.style.width = isAutoFit ? `100%` : `${width}px`;\n //tbl.style.minWidth = isAutoFit ? `100%` : `${width}px`;\n });\n } else {\n container.style.flex = `0 0 ${width}px`;\n container.style.width = `${width}px`;\n container.style.minWidth = `${width}px`;\n container.style.maxWidth = `${width}px`;\n tables.forEach(tbl => {\n //tbl.style.width = `${width}px`;\n //tbl.style.minWidth = `${width}px`;\n });\n }\n });\n });\n };\n\n #renderSplitContainers = () => {\n const colTypes = [\n { selector: '.ng-container-left', type: 'left' },\n { selector: '.ng-container-body', type: null },\n { selector: '.ng-container-right', type: 'right' }\n ];\n\n colTypes.forEach(({ selector, type }) => {\n this.querySelector(`.ng-sheet-body ${selector}`).appendChild(this.#createSplitTable(type));\n });\n };\n\n #createSplitTable = (targetFixedType) => {\n\n const $tbl = this.#source.table.cloneNode(true);\n\n if (targetFixedType === 'left') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"left\") $el.remove();\n });\n } else if (targetFixedType === 'right') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"right\") $el.remove();\n });\n } else {\n $tbl.querySelectorAll(\"[fixed=left], [fixed=right]\").forEach($el => {\n $el.remove();\n });\n }\n\n return $tbl;\n };\n\n getRowHeight = () => {\n return this.#rowManager.getRowHeight();\n };\n\n 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 trace.log(\"11111*****************\");\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 //trace.log(\"----------------------\")\n //trace.log(\"Is GroupingManager instance?\", this.#grouping instanceof GroupingManager); // true가 나와야 정상\n //trace.log(\"Grouping keys:\", Object.keys(this.#grouping)); // 또는 내부 속성 확인\n\n if (!this.#isSimple) {\n this.#sorting = new Sorting(this);\n }\n\n this.#elements.mainBody.addEventListener('scroll', () => {\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n trace.log(\"11111*****************\");\n const sbSize = NineTableSheet.SCROLLBAR_SIZE;\n trace.log(\"2222*****************\");\n this.innerHTML = `\n <div class=\"ng-sheet-body\">\n <div class=\"ng-sheet-body-content\">\n <div class=\"ng-container-left\"></div>\n <div class=\"ng-container-body\"></div>\n <div class=\"ng-container-right\"></div>\n </div>\n <div class=\"ng-virtual-height-holder\"></div>\n </div>\n\n <div class=\"ng-nodata-overlay\">Data Not Found</div>\n\n <!-- [Grid Row 1, Col 2] 세로 스크롤바 -->\n <nine-table-vscrollbar></nine-table-vscrollbar>\n\n <!-- [Grid Row 2, Col 1] 가로 스크롤바 -->\n <nine-table-hscrollbar></nine-table-hscrollbar>\n\n <!-- [Grid Row 2, Col 2] 우하단 엣지 -->\n <div class=\"ng-scroll-edge\"></div>\n \n <!-- 리사이저 및 드래그 패널들 -->\n <div class=\"ng-col-resizer-panel\">\n <div class=\"resizer-overlay\">\n <span class=\"size-badge\">0px</span>\n </div>\n </div>\n \n <div class=\"ng-col-mover-grip\"></div>\n <div class=\"ng-col-mover-indi\"></div>\n `;\n\n //let fixedHeight = this.#sheet.querySelector('.ng-container-body thead').offsetHeight + this.#sheet.querySelector('.ng-container-body tfoot').offsetHeight;\n trace.log(\"3333*****************\");\n this.#elements = {\n mainBody: this.querySelector('.ng-sheet-body .ng-container-body'),\n hscrollbar: this.querySelector('nine-table-hscrollbar'),\n vscrollbar: this.querySelector('nine-table-vscrollbar'),\n content: this.querySelector('.ng-sheet-body .ng-sheet-body-content'),\n scrollHolder: this.querySelector('.ng-sheet-body .ng-virtual-height-holder'),\n }\n trace.log(\"444*****************\");\n };\n\n #syncHeaderAndFooterHeights = () => {\n trace.log(\"**********************\", \"#syncHeaderAndFooterHeights\");\n\n const leftTable = this.querySelector('.ng-container-left table');\n const bodyTable = this.querySelector('.ng-container-body table');\n const rightTable = this.querySelector('.ng-container-right table');\n\n // 1. 헤더(thead) 행 높이 싱크 (인덱스 행 제외)\n const leftHeaderRows = Array.from(leftTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const bodyHeaderRows = Array.from(bodyTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const rightHeaderRows = Array.from(rightTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n\n this.#applyMaxHeights(leftHeaderRows, bodyHeaderRows, rightHeaderRows);\n\n // 2. 푸터(tfoot) 행 높이 싱크\n const leftFooterRows = Array.from(leftTable.querySelectorAll('tfoot tr'));\n const bodyFooterRows = Array.from(bodyTable.querySelectorAll('tfoot tr'));\n const rightFooterRows = Array.from(rightTable.querySelectorAll('tfoot tr'));\n\n this.#applyMaxHeights(leftFooterRows, bodyFooterRows, rightFooterRows);\n };\n\n// 공통 최대 높이 적용 헬퍼 메서드\n #applyMaxHeights = (leftRows, bodyRows, rightRows) => {\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 #initRowHoverEvent = () => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n let activeRowIndex = null;\n\n // 마우스 진입 (모든 컨테이너 탐색)\n bodyViewport.addEventListener('mouseover', (e) => {\n const tr = e.target.closest('tr');\n if (!tr || !tr.dataset.row && tr.dataset.row !== '0') return;\n\n const rowIndex = tr.dataset.row;\n if (activeRowIndex === rowIndex) return;\n activeRowIndex = rowIndex;\n\n // 좌측, 본문, 우측 컨테이너에서 동일한 data-row를 가진 tr들을 모두 찾아 .hover 부여\n bodyViewport.querySelectorAll(`tr[data-row=\"${rowIndex}\"]`).forEach($tr => {\n $tr.classList.add('hover');\n });\n });\n\n // 마우스 이탈\n bodyViewport.addEventListener('mouseout', (e) => {\n const tr = e.target.closest('tr');\n if (!tr) return;\n\n // 현재 영역을 완전히 벗어났을 때만 전체 hover 제거\n const relatedTarget = e.relatedTarget;\n if (tr.contains(relatedTarget)) return;\n\n bodyViewport.querySelectorAll('tr.hover').forEach($tr => {\n $tr.classList.remove('hover');\n });\n activeRowIndex = null;\n });\n }\n\n disconnectedCallback() {\n this.#colResizer?.destroy();\n this.#colMover?.destroy();\n this.innerHTML = '';\n }\n}\n\nif (!customElements.get('nine-table-sheet')) {\n customElements.define('nine-table-sheet', NineTableSheet);\n}","import { trace } from \"@nopeer\";\nimport '@/ui/layout/nine-table-sheets.js';\nimport '@/ui/layout/nine-table-sheets-footer.js';\nimport '@/ui/layout/nine-table-toolbar.js';\nimport { NineTableSheet } from \"@/ui/layout/nine-table-sheet.js\";\n\nexport class LayoutManager {\n #host;\n\n constructor(owner) {\n this.#host = owner;\n this.#init();\n }\n\n #init = () => {\n this.#render();\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }).observe(this.#host);\n }\n\n set loading(val) {\n if (!!val) {\n this.#host.classList.add(\"loading\");\n } else {\n this.#host.classList.remove(\"loading\");\n }\n }\n\n #applyAutoHeight = () => {\n const activeSheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet.active'));\n if (activeSheets.length === 0) return;\n\n const maxDisplayRows = parseInt(this.#host.getAttribute('max-display-row'), 10) || 10;\n const maxRowHeight = Math.max(...activeSheets.map(sheet => sheet.getRowHeight()));\n\n const toolbarEl = this.#host.shadowRoot.querySelector('nine-table-toolbar');\n const footerEl = this.#host.shadowRoot.querySelector('nine-table-sheets-footer');\n\n const toolbarHeight = toolbarEl ? toolbarEl.getBoundingClientRect().height : 0;\n const footerHeight = footerEl ? footerEl.getBoundingClientRect().height : 0;\n const extraPadding = NineTableSheet.SCROLLBAR_SIZE;\n\n const calculatedHeight = (maxDisplayRows * maxRowHeight) + toolbarHeight + footerHeight + extraPadding;\n\n this.#host.style.height = `${calculatedHeight}px`;\n };\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n const sheetCount = rawTables.length;\n\n const sheetsHtml = rawTables.map((tbl, idx) => {\n const className = idx === 0 ? 'active' : '';\n const sheetId = tbl.id || `sheet${idx + 1}`;\n\n const sheetTag = `<nine-table-sheet class=\"${className}\" data-index=\"${idx}\" data-sheet-id=\"${sheetId}\" id=\"${sheetId}\"></nine-table-sheet>`;\n const splitterTag = idx < sheetCount - 1 ? `<nine-splitter class=\"h\" data-split-index=\"${idx}\"></nine-splitter>` : '';\n return sheetTag + splitterTag;\n }).join('');\n\n // 1. 공통 파일명 배열 정의\n const cssFiles = [\n 'layout', 'nine-table-sheet', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table', 'col-resize', 'sorting', 'fitering', 'cell-select', 'col-expand',\n 'cell-combo',\n ];\n // 2. npm 패키지 CSS 배열 생성\n /**\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}.css\";`\n ); */\n const npmCssImports = [\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/nine-table.css\";`,\n ];\n\n // 3. 커스텀 CSS 배열 생성\n const customCssImports = [];\n if (nine.cssPath) {\n cssFiles.forEach(file => {\n customCssImports.push(`@import \"${nine.cssPath}/${file}.css\";`);\n });\n }\n\n this.#host.shadowRoot.innerHTML = `\n <style>\n ${[...npmCssImports, ...customCssImports].join('\\n')}\n </style>\n \n <nine-table-toolbar></nine-table-toolbar>\n\n <nine-table-body>\n <nine-table-summary></nine-table-summary>\n <div class=\"ng-loading-bar\"></div>\n <nine-table-sheets>\n <nine-table-sheets-body>\n ${sheetsHtml}\n </nine-table-sheets-body>\n <nine-table-sheets-footer></nine-table-sheets-footer>\n </nine-table-sheets>\n <nine-table-analysis></nine-table-analysis>\n </nine-table-body>\n <nine-table-footer></nine-table-footer>\n `;\n\n /**\n * <div class=\"nine-tab-bar\">${tabsHtml}</div>\n * <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n */\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($el, idx) => {\n\n if (rawTables[idx]) {\n setTimeout(() => {\n $el.generate(rawTables[idx], idx);\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n });\n }\n });\n };\n}","import { trace } from \"@nopeer\";\n\nexport class ExprEngine {\n #host;\n #fields;\n #exprCache = new Map(); // 💡 통합된 단일 캐시로 모든 컴파일된 함수 관리\n\n constructor(host) {\n this.#host = host;\n this.#fields = host.fields.get();\n }\n\n /**\n * 🎯 표현식 내의 data.fieldName을 원시 배열 인덱스 접근(rowItem.v[idx])으로 변환\n */\n rewriteExpr(expr) {\n\n if (!expr || !this.#fields.length) return expr;\n\n return expr.replace(/data\\.([a-zA-Z_$][\\w$]*)/g, (match, fieldName) => {\n const idx = this.#fields.indexOf(fieldName);\n return idx >= 0 ? `rowItem.v[${idx}]` : match;\n });\n }\n\n /**\n * 🎯 셀 또는 컬럼 정의에 선언된 expr 프리컴파일\n */\n precompile(expr) {\n if (!expr) return expr;\n return this.rewriteExpr(expr);\n }\n\n /**\n * 🎯 표현식 평가 및 실행 (통합 캐싱)\n */\n evaluate(expr, rowItem, row = 0) {\n if (expr === undefined || expr === null) return \"\";\n\n //trace.log(expr, rowItem, this.#exprCache);\n\n try {\n const trimmedExpr = String(expr).trim();\n const compiledExpr = this.rewriteExpr(trimmedExpr);\n\n // 💡 함수 호출, 데이터 참조, 연산식이 포함된 경우 통합 평가 및 캐싱\n if (compiledExpr.includes(\"data.\") || compiledExpr.includes(\"rowItem.v\") || compiledExpr.includes(\"host.\") || compiledExpr.includes(\"(\")) {\n let evalFn = this.#exprCache.get(compiledExpr);\n\n if (!evalFn) {\n evalFn = new Function('rowItem', 'row', 'host', `\n const data = rowItem;\n if (!data && !host) return \"\";\n return ${compiledExpr};\n `);\n this.#exprCache.set(compiledExpr, evalFn);\n }\n\n return evalFn(rowItem, row, this.#host);\n }\n\n // 단순 리터럴 문자열인 경우\n return compiledExpr;\n } catch (e) {\n //console.error(\"ExprEngine evaluation error:\", expr, e);\n return expr;\n }\n }\n}","import { trace } from \"@nopeer\";\nimport { ngDataManager } from '@/data/ngDataManager.js';\nimport { fields } from \"@/data/Fields.js\";\nimport { LayoutManager } from '@/ui/layout/core/LayoutManager.js';\nimport { ExprEngine } from \"@/core/ExprEngine.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #templateCnt = 0; // 🎯 로딩 상태 플래그\n\n constructor() {\n super();\n\n this.#shadowRoot = this.attachShadow({ mode: 'open' });\n this.#dataManager = new ngDataManager(this);\n }\n\n connectedCallback() {\n setTimeout(() => {\n this.#templateCnt = this.querySelectorAll(\"table\")?.length;\n\n this.fields = new fields(this);\n this.exprEngine = new ExprEngine(this);\n\n this.#bindDynamicSetters();\n\n this.#layoutManager = new LayoutManager(this);\n\n this.#dispatchLoad();\n //this.dispatchEvent(new CustomEvent('load', { bubbles: true, detail: { target: this } }));\n });\n }\n\n disconnectedCallback() {\n trace.log('NineTable disconnected.');\n }\n\n #dispatchLoad = () => {\n // 🎯 2. 변수명 오타 수정 (#sheetCnt -> #templateCnt)\n //trace.log(\"*********************** template count:\", this.#templateCnt);\n\n let checkCount = 0;\n const maxChecks = 50; // 최대 5초 대기 (100ms * 50)\n\n const checkTimer = setInterval(() => {\n checkCount++;\n\n const sheets = this.shadow.querySelectorAll('nine-table-sheet');\n //trace.log(\"Current mounted sheets:\", sheets.length);\n\n if (checkCount >= maxChecks) {\n clearInterval(checkTimer);\n }\n\n if (sheets.length >= this.#templateCnt) {\n let loadSheetCnt = 0;\n sheets.forEach($sheet => {\n if ($sheet.loaded) loadSheetCnt++;\n });\n\n //trace.log('Checking sheet loaded status:', loadSheetCnt, '/', this.#templateCnt);\n\n if (loadSheetCnt >= this.#templateCnt) {\n clearInterval(checkTimer);\n this.loaded = true;\n this.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.LOAD, { bubbles: true, detail: { target: this } }));\n }\n }\n }, 100);\n }\n\n\n // 🎯 공통 데이터 & API 접근자\n get shadow() { return this.#shadowRoot; }\n get dataManager() { return this.#dataManager; }\n get data() { return this.#dataManager.data; }\n get row() { return this.#dataManager.row; }\n\n setData(records) {\n this.#dataManager.data.set(records);\n this.refresh();\n }\n\n refresh() {\n this.activeSheet?.invalidate();\n }\n\n // 🎯 섀도우 돔 내부에서 로딩바 요소를 안전하게 캐싱\n\n\n set loading(val) {\n this.#layoutManager.loading = val;\n }\n\n /**\n * 랜더링 이후에 생기는 data-source 처리기능\n */\n rerenderer() {\n\n this.activeSheet?.querySelectorAll(\"tbody.body th,tbody.body td\").forEach(($cell) => {\n const customComp = Array.from($cell.children).find($el => {\n return $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.rerenderer === 'function'\n });\n\n customComp?.rerenderer();\n })\n }\n\n // 시트 제어 API\n sheet = (idOrIndex) => {\n if (idOrIndex === null || idOrIndex < 0) return this.activeSheet;\n const sheets = Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n\n if (typeof idOrIndex === 'number') return sheets[idOrIndex] || null;\n if (typeof idOrIndex === 'string') {\n return this.shadow.querySelector(`nine-table-sheet#${idOrIndex}, nine-table-sheet[data-sheet-id=\"${idOrIndex}\"]`) || null;\n }\n return sheets[0] || null;\n }\n\n get sheets() {\n return Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n }\n\n get activeSheet() {\n return this.shadow.querySelector('nine-table-sheet.active') || null;\n }\n\n #bindDynamicSetters() {\n const extractedMethodNames = new Set();\n\n this.querySelectorAll('[data-source]').forEach(el => {\n const dataSource = el.getAttribute('data-source');\n if (!dataSource) return;\n\n // 💡 [수정] 뒤에 여멀림 괄호 '('가 오는 형태만 매칭하여 'DEPART' 같은 파라미터는 배제!\n const matches = dataSource.matchAll(/(?:host\\.)?([a-zA-Z0-9_$]+)\\s*\\(/g);\n for (const match of matches) {\n const name = match[1];\n if (name && name !== 'host') {\n extractedMethodNames.add(name);\n }\n }\n });\n\n // 추출된 메서드 이름별로 NineTable 인스턴스에 동적 세터 생성\n extractedMethodNames.forEach(methodName => {\n let internalValue = null;\n\n Object.defineProperty(this, methodName, {\n set: (newValue) => {\n internalValue = newValue;\n\n // 값이 대입되는 순간 그리드 자동 갱신\n //this.refresh();\n this.rerenderer();\n },\n get: () => internalValue,\n configurable: true,\n enumerable: true\n });\n });\n }\n\n execute = (fn) => {\n this.loading = true;\n setTimeout(() => {\n try {\n fn.call(this);\n } finally {\n this.loading = false;\n }\n })\n }\n}\n\nif (!customElements.get('nine-table')) {\n customElements.define('nine-table', NineTable);\n}\n\nif (!customElements.get('nine-table-simple')) {\n customElements.define('nine-table-simple', class extends NineTable {\n connectedCallback() {\n // simple 태그로 생성되면 자동으로 mode=\"simple\" 속성 부여\n this.setAttribute('theme', 'simple');\n\n super.connectedCallback();\n }\n });\n}","export class BasicCellElement extends HTMLElement {\r\n\r\n\tstatic _styleCache = new Map();\r\n\tstatic _customStyleCache = new Map(); // 👈 커스텀 스타일용 캐시 추가\r\n\r\n\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tapplyBaseStyle() {\r\n\t\tconst className = this.constructor.name;\r\n\r\n\t\treturn;\r\n\t\t// 1. 기본 스타일 시트 처리 (캐싱 O)\r\n\t\tif (!ngElement._styleCache.has(className)) {\r\n\t\t\tconst baseSheet = new CSSStyleSheet();\r\n\t\t\tngElement._styleCache.set(className, baseSheet);\r\n\r\n\t\t\tconst baseUrl = `https://cdn.jsdelivr.net/npm/@ninebone/grid@${__APP_VERSION__}/dist/css/${className}.css`;\r\n\t\t\tfetch(baseUrl)\r\n\t\t\t\t.then(res => res.text())\r\n\t\t\t\t.then(cssText => baseSheet.replaceSync(cssText))\r\n\t\t\t\t.catch(err => console.error(`Base CSS Load Error:`, err));\r\n\t\t}\r\n\r\n\t\tconst sheets = [ngElement._styleCache.get(className)];\r\n\r\n\t\t// 2. 커스텀 스타일 시트 처리 (자바스크립트 단 캐싱 O)\r\n\t\tif (nine.cssPath) {\r\n\t\t\tif (!ngElement._customStyleCache.has(className)) {\r\n\t\t\t\tconst customSheet = new CSSStyleSheet();\r\n\t\t\t\tngElement._customStyleCache.set(className, customSheet);\r\n\r\n\t\t\t\t// 💡 오타 수정 및 캐시 파라미터 제거\r\n\t\t\t\tconst customUrl = `${nine.cssPath}/ninegrid/${className}.css`;\r\n\r\n\t\t\t\tfetch(customUrl)\r\n\t\t\t\t\t.then(res => res.text())\r\n\t\t\t\t\t.then(cssText => customSheet.replaceSync(cssText))\r\n\t\t\t\t\t.catch(err => console.error(`Custom CSS Load Error:`, err));\r\n\t\t\t}\r\n\r\n\t\t\t// 캐시된 커스텀 시트가 있으면 기본 시트 배열 뒤에 추가\r\n\t\t\tsheets.push(ngElement._customStyleCache.get(className));\r\n\t\t}\r\n\r\n\t\t// 한 번에 섀도우 돔에 적용\r\n\t\tthis.shadowRoot.adoptedStyleSheets = sheets;\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\t// ngElement 레벨에서는 비워두셔도 됩니다.\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { BasicCellElement } from './BasicCellElement.js';\r\n\r\nconst exprCache = new Map();\r\nconst hostFuncCache = new Map();\r\n\r\nexport class CellElement extends BasicCellElement {\r\n\t#host;\r\n\t#sheet;\r\n\t#tr;\r\n\t#cell;\r\n\r\n\t#attr;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tget host() { return this.#host; }\r\n\tget sheet() { return this.#sheet; }\r\n\tget cell() { return this.#cell; }\r\n\tget tr() { return this.#tr; }\r\n\tget attr() { return this.#attr; }\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\tthis.#cell = this.closest(\"th,td\");\r\n\t\tthis.#tr = this.#cell.closest(\"tr\");\r\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\r\n\r\n\t\tthis.#cell.classList.add(this.tagName);\r\n\r\n\t\tthis.#attr = {};\r\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\r\n\t\t\tconst name = this.#cell.attributes[i].name;\r\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\r\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\r\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#cell) return;\r\n\r\n\r\n\t\tconst root = this.shadowRoot || this;\r\n\r\n\t\t// 🎯 버튼 이벤트 연결\r\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\r\n\t\t\tbutton.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\r\n\r\n\t\t\t\tconst rowData = this.data; // Proxy Lazy 접근\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t/**\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t})); */\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 링크 이벤트 연결\r\n\t\tconst renderer = root.querySelector(\".renderer\");\r\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\r\n\t\t\trenderer.classList.add(\"link\");\r\n\r\n\t\t\trenderer.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\r\n\r\n\t\t\t\tconst rowData = this.data;\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t}));\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [Proxy 최적화] 속성 읽기 시에도 fields.indexOf() 사용\r\n\t */\r\n\tget data() {\r\n\t\tconst rawRecord = this.#tr?.data;\r\n\t\tif (!rawRecord) return null;\r\n\t\tif (!rawRecord.v) return rawRecord;\r\n\r\n\t\tconst host = this.#host;\r\n\r\n\t\treturn new Proxy(rawRecord, {\r\n\t\t\tget(target, prop) {\r\n\t\t\t\tif (prop === '__ng') return target.__ng;\r\n\t\t\t\tif (prop === 'v') return target.v;\r\n\r\n\t\t\t\t// 💡 host.fields.indexOf(prop) 사용\r\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\r\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [핵심] 변환 없이 원시 v 배열에서 direct 인덱스 검색 (GC zero)\r\n\t */\r\n\tget value() {\r\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\r\n\r\n\t\tconst bindKey = this.#cell.dataset?.bind;\r\n\t\tif (!bindKey) return \"\";\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\t// 1. 원시 데이터 배열({ v: [...] }) 구조인 경우\r\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\r\n\t\t\t// 💡 fields.indexOf(bindKey)로 바로 찾기!\r\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\r\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\r\n\t\t}\r\n\r\n\t\t// 2. 일반 JSON 객체인 경우 (하위 호환)\r\n\t\treturn rawRecord[bindKey] ?? \"\";\r\n\t}\r\n\r\n\tset value(v) {\r\n\t\tif (!this.#cell || !this.#host?.data) return;\r\n\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tif (isNaN(row) || !bindKey) return;\r\n\r\n\t\tconst updateRowState = this.getAttribute('update-row-state') !== \"false\";\r\n\t\tthis.#host.data.setValue(row, bindKey, v, updateRowState);\r\n\t}\r\n\r\n\tget row() {\r\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\r\n\t}\r\n\tget index() {\r\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\r\n\t}\r\n\r\n\tgetDisplayText = (defaultValue = \"\") => {\r\n\r\n\t\ttrace.log(\"=================================\");\r\n\t\tif (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\ttrace.log(\"==============================\", rawRecord);\r\n\r\n\t\tif (!rawRecord) return defaultValue;\r\n\r\n\t\tconst expr = this.#cell.dataset.expr;\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\tif (expr) {\r\n\t\t\ttry {\r\n\t\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\r\n\t\t\t\t\t// 💡 상수가 정의되어 있다면 GROUP_IDX.ID 로 고유 ID 추출 (아니면 배열 인덱스 직접 참조)\r\n\t\t\t\t\t// 배열 구조체인 경우: rawRecord[0]이 groupId임\r\n\t\t\t\t\t//const groupId = Array.isArray(rawRecord) ? rawRecord[0] : (rawRecord.__ng?.id || rawRecord.m?.id);\r\n\r\n\t\t\t\t\t// 💡 매니저를 통해 해당 그룹의 자식 레코드 목록을 O(1)로 획득\r\n\t\t\t\t\t//const childRecords = this.#sheet.grouping.getChildrenRecords(\"g_0\");\r\n\t\t\t\t\t//trace.log(\"--========\", childRecords);\r\n\t\t\t\t\t// 그룹 전용 표현식 계산 메서드 호출\r\n\t\t\t\t\t//return \"\";//this.getGroupExprValue(expr, childRecords, row, this.#cell);\r\n\r\n\t\t\t\t\t//trace.log(this, this.#cell.dataset.bind);\r\n\t\t\t\t\t//return \"x\";//this.data.length;\r\n\t\t\t\t\treturn this.getGroupExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row);\r\n\r\n\t\t\t\t\t//return this.getExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\tconsole.trace(e);\r\n\t\t\t\t//console.error(\"Expr evaluation error:\", expr, e);\r\n\t\t\t\treturn defaultValue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\ttrace.log(\"==============================\", bindKey, this.value);\r\n\r\n\t\tif (bindKey) {\r\n\t\t\tconst val = this.value; // 직통 읽기\r\n\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\r\n\t\t}\r\n\r\n\t\treturn defaultValue;\r\n\t};\r\n\r\n\r\n\r\n\trefresh() {\r\n\r\n\t\tif (!this.#cell || !this.#tr) return;\r\n\r\n\t\tconst val = this.value; // 원시 배열 직통 조회\r\n\r\n\t\t[\"color\",\"background\",\"background-color\",\"class\",\"visible\",\"enable\"].forEach(v => {\r\n\t\t\tconst expr = this.#attr[v];\r\n\t\t\tif (expr) {\r\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10));\r\n\r\n\t\t\t\tif (v === \"visible\") {\r\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\r\n\t\t\t\t} else if (v === \"enable\") {\r\n\t\t\t\t\t// 💡 enable이 false면 비활성화(disabled = true), true면 활성화(disabled = false)\r\n\t\t\t\t\t//const isEnabled = !!result;\r\n\r\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\r\n\t\t\t\t\t\t$el.disabled = !result;\r\n\t\t\t\t\t});\r\n\r\n\r\n\t\t\t\t\tif (!!result) {\r\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#cell.style[v] = result;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn val;\r\n\t}\r\n\r\n\tgetExprValue(expr, data, row) {\r\n\t\t//trace.log(\"********************************************\", expr, data, row);\r\n\r\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row);\r\n\r\n\r\n\t\tif (expr === undefined) return expr;\r\n\t\tconsole.trace(\"********************************************\");\r\ntrace.log(\"********************************************\", expr);\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst trimmedExpr = expr.trim();\r\n\t\t\t//const fields = this.#host?.fields;\r\n\r\n\t\t\t// 🎯 1. 데이터가 원시 배열 구조인 경우 표현식 내부의 필드명을 인덱스로 자동 치환\r\n\t\t\t//const isRawArray = data && typeof data === 'object' && Array.isArray(data.v);\r\n\t\t\t//const compiledExpr = isRawArray ? this.#rewriteExpr(trimmedExpr, fields) : trimmedExpr;\r\n\t\t\t//trace.log(compiledExpr);\r\n\t\t\t// 2. 함수 호출식인 경우 (예: oppositeColor(...))\r\n\t\t\t//const match = trimmedExpr.match(/^([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\tconst match = trimmedExpr.match(/(?:[a-zA-Z_$][\\w$]*\\.)*([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\t//trace.log(trimmedExpr, match);\r\n\t\t\tif (match) {\r\n\t\t\t\tconst fnName = match[1].replace(\"host.\", \"\");\r\n\t\t\t\t//trace.log(fnName);\r\n\t\t\t\tif (this.#host && typeof this.#host[fnName] === 'function') {\r\n\r\n\t\t\t\t\tlet evalFn = hostFuncCache.get(trimmedExpr);\r\n\r\n\t\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\t\tconst openIdx = trimmedExpr.indexOf('(');\r\n\t\t\t\t\t\tconst closeIdx = trimmedExpr.lastIndexOf(')');\r\n\t\t\t\t\t\tconst argsString = (openIdx !== -1 && closeIdx !== -1) ? trimmedExpr.substring(openIdx + 1, closeIdx) : \"\";\r\n\r\n\t\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', 'host', `\r\n\t\t\t\t\t\t try {\r\n\t\t\t\t\t\t const data = rowItem;\r\n\t\t\t\t\t\t //console.log(data);\r\n\t\t\t\t\t\t \r\n\t\t\t\t\t\t //if (!data) return \"\";\r\n\t\t\t\t\t\t return host.${fnName}.call(host, ${argsString});\r\n\t\t\t\t\t\t } catch (err) {\r\n\t\t\t\t\t\t console.error(\"Expr eval error:\", err);\r\n\t\t\t\t\t\t return \"\";\r\n\t\t\t\t\t\t }\r\n\t\t\t\t\t `);\r\n\r\n\t\t\t\t\t\thostFuncCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn evalFn(data, row, cell, this.#host);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//trace.log(trimmedExpr);\r\n\t\t\t// 3. 일반 연산식인 경우 (예: data.v[0] + ' vs ' + data.v[1])\r\n\t\t\tif (trimmedExpr.includes(\"data.\") || trimmedExpr.includes(\"rowItem.v\") || trimmedExpr.includes(\"(\")) {\r\n\t\t\t\t//trace.log(\"=========================\")\r\n\t\t\t\tlet evalFn = exprCache.get(trimmedExpr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', `\r\n const data = rowItem;\r\n\r\n if (!data) return \"\";\r\n return ${trimmedExpr};\r\n `);\r\n\t\t\t\t\texprCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(data, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\treturn trimmedExpr;\r\n\t\t} catch (e) {\r\n\t\t\treturn [\"NG-COMBO\"].includes(this.tagName) ? \"\" : expr;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [신규] 그룹 행의 자식 데이터 목록(childRecords)을 기반으로 합계/평균/개수 등을 처리하는 메서드\r\n\t */\r\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\r\n\t\tif (!expr) return \"\";\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\r\n\r\n\t\t\t// 1. 호스트(컴포넌트)에 정의된 그룹 전용 커스텀 메서드가 있는 경우 우선 위임\r\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\r\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\t// 2. 기본 내장 집계 함수 파싱 처리 (예: sum(price), count(), avg(score) 등)\r\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\r\n\t\t\tif (match) {\r\n\t\t\t\t// 💡 groupRecord에서 자식 레코드 목록 안전하게 추출 (indices 배열 -> 실제 레코드 매핑)\r\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\r\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\r\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\r\n\r\n\t\t\t\tconst [, funcName, field] = match;\r\n\t\t\t\tconst host = this.#host;\r\n\r\n\t\t\t\tswitch (funcName.toLowerCase()) {\r\n\t\t\t\t\tcase 'count':\r\n\t\t\t\t\t\treturn childRecords.length;\r\n\r\n\t\t\t\t\tcase 'sum': {\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tcase 'avg': {\r\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t\treturn sum / childRecords.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 3. 호스트의 exprFunction 활용\r\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\r\n\t\t\t}\r\n\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (예: \"childRecords.reduce(...)\")\r\n\t\t\t// groupRecord 자체나 내부 자식들을 활용하는 표현식 문자열 처리\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (안전성 강화 버전)\r\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\r\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\r\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\r\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\r\n \r\n let childRecords = [];\r\n if (Array.isArray(indices)) {\r\n // indices가 숫자 인덱스 배열인지, rowid 문자열 배열인지 판별하여 안전하게 추출\r\n childRecords = indices.map(idx => {\r\n if (typeof idx === 'number') {\r\n return allRecords[idx];\r\n } else {\r\n // rowid 등 문자열 식별자인 경우 전체 배열에서 찾거나 dataManager 활용\r\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\r\n }\r\n }).filter(Boolean);\r\n }\r\n \r\n // 만약 위에서 못 찾았는데 host.grouping을 쓸 수 있다면 매니저 위임 시도\r\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\r\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\r\n }\r\n\r\n const data = childRecords; // data.length 등을 쓸 수 있도록 호환\r\n return ${expr};\r\n `);\r\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\r\n\t\t\t}\r\n\r\n\t\t\treturn expr;\r\n\t\t} catch (e) {\r\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\r\n\t\t\treturn expr;\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class EditableCellElement extends CellElement {\r\n\r\n\tget host() { return super.host; }\r\n\tget sheet() { return super.sheet; }\r\n\tget cell() { return super.cell; }\r\n\tget tr() { return super.tr; }\r\n\tget attr() { return super.attr; }\r\n\r\n\tgetExprValue(expr, data, row, cell) {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\t/**\r\n\t\tthis.querySelectorAll(\"input, textarea\").forEach($el => {\r\n\t\t\t$el.addEventListener(\"change\", (event) => {\r\n\t\t\t\tif (!this.closest(\"tbody\")) return;\r\n\r\n\t\t\t\tconst target = event.target;\r\n\t\t\t\tconst inputType = target.getAttribute('type');\r\n\r\n\t\t\t\tif (inputType === \"checkbox\") {\r\n\t\t\t\t\tconst trueVal = super.attr[\"true-value\"] || \"Y\";\r\n\t\t\t\t\tconst falseVal = super.attr[\"false-value\"] || \"N\";\r\n\t\t\t\t\tthis.value = target.checked ? trueVal : falseVal;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlet v = target.value;\r\n\t\t\t\t\tconst maxbyte = super.attr[\"maxbyte\"];\r\n\r\n\t\t\t\t\ttrace.log(maxbyte);\r\n\r\n\t\t\t\t\tif (maxbyte) {\r\n\t\t\t\t\t\tconst byteLen = nine.getByteLength(v);\r\n\t\t\t\t\t\tif (byteLen >= parseInt(maxbyte, 10)) {\r\n\t\t\t\t\t\t\tv = nine.cut(v, parseInt(maxbyte, 10));\r\n\t\t\t\t\t\t\ttarget.value = v;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tthis.value = this.getAttribute(\"type\") === \"number\" ? (isNaN(v) ? \"\" : Number(v)) : v;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsuper.sheet.invalidate();\r\n\t\t\t});\r\n\t\t}); */\r\n\t}\r\n\r\n\trefresh() {\r\n\t\treturn super.refresh();\r\n\t}\r\n\r\n\tgetExprValue = (expr, data, row, cell) => {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n}","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\n\t\tsuper.refresh();\n\n\t\tthis.#target.value = this.value;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"input\", e => {\n\t\t\tconst maxbyte = this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\n\t\t\tif (maxbyte) {\n\t\t\t\tconst maxByteNum = Number(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\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<style>\n\t\t\t\tcell-input {\n\t\t\t\t\tinput {\n\t\t\t\t\t\tposition: relative;\n\t\t\t\t\t\t-moz-user-select: auto;\n\t\t\t\t\t\t-webkit-user-select: auto;\n\t\t\t\t\t\t-ms-user-select: auto;\n\t\t\t\t\t\tuser-select: auto;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 26px;\n\t\t\t\t\t\tborder: 1px solid #eee;\n\t\t\t\t\t\tborder-radius: 3px;\n\t\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t\t\toutline: 0;\n\t\t\t\t\t\tfont: inherit;\n\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\tbackground-color: white;\n\t\t\t\t\t\tcolor: #333;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tinput:read-only {\n\t\t\t\t\t\tborder-color: #fdfdfd;\n\t\t\t\t\t\tfilter: brightness(97%);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n\t\t\t<input type=\"text\" ondragstart=\"return false;\">\n\t\t`;\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\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\tthis.#target.addEventListener(\"keydown\", this.#onKeyDown);\n\n\t\t// change 대신 input 이벤트를 사용하면 색상을 고르는 즉시 바로 적용됩니다.\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tthis.value = event.target.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 만약 색상 선택 창을 닫을 때(확정할 때) 추가로 처리할 로직이 필요하다면 change에 남겨둘 수 있습니다.\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\t//this.#target.style.backgroundColor = this.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\t/**\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t}); */\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n \t\tcell-input-number {\n\t\t\t\t\tinput[type=text].border-left-none {\n\t\t\t\t\t\t border-left: 0;\n\t\t\t\t\t\t border-top-left-radius: 0;\n\t\t\t\t\t\t border-bottom-left-radius: 0;\n\t\t\t\t\t }\n\t\t\t\t\t input[type=text].border-right-none {\n\t\t\t\t\t\t border-right: 0;\n\t\t\t\t\t\t border-top-right-radius: 0;\n\t\t\t\t\t\t border-bottom-right-radius: 0;\n\t\t\t\t\t }\n\t\t\n\t\t\t\t\t input[type=text] {\n\t\t\t\t\t\t position: relative;\n\t\t\t\t\t\t -moz-user-select: auto;\n\t\t\t\t\t\t -webkit-user-select: auto;\n\t\t\t\t\t\t -ms-user-select: auto;\n\t\t\t\t\t\t user-select: auto;\n\t\t\t\t\t\t width: 100%;\n\t\t\t\t\t\t height: 26px;\n\t\t\t\t\t\t border: 1px solid #eee;\n\t\t\t\t\t\t border-radius: 3px;\n\t\t\t\t\t\t padding-left: 4px;\n\t\t\t\t\t\t outline: 0;\n\t\t\t\t\t\t font: inherit;\n\t\t\t\t\t\t box-sizing: border-box;\n\t\t\t\t\t\t background-color: white;\n\t\t\t\t\t\t color: #333;\n\t\t\t\t\t\t text-align: right; /* 숫자는 기본적으로 우측 정렬이 어울림 */\n\t\t\t\t\t }\n\t\n\t\t\t\t\t input[type=text]:read-only {\n\t\t\t\t\t\t border-color: #fdfdfd;\n\t\t\t\t\t\t filter: brightness(97%);\n\t\t\t\t\t }\n \t\t}\n </style>\n\n <input type=\"text\" ${attr.join(\" \")} ondragstart=\"return false;\">\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tthis.#target.value = v !== undefined && v !== null ? v : \"\";\n\t\t\tthis.#validateInput(this.#target.value);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\n\t\tif (!this.#target) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tconst num = Number(val);\n\t\t\tif (isNaN(num) ||\n\t\t\t\t(super.attr.max !== null && super.attr.max !== undefined && num > Number(super.attr.max)) ||\n\t\t\t\t(super.attr.min !== null && super.attr.min !== undefined && num < Number(super.attr.min))\n\t\t\t) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (super.attr.scale !== null && super.attr.scale !== undefined) {\n\t\t\t\tconst strVal = String(val);\n\t\t\t\tconst dotIdx = strVal.indexOf('.');\n\t\t\t\tif (dotIdx >= 0 && strVal.substring(dotIdx + 1).length > Number(super.attr.scale)) {\n\t\t\t\t\tsuper.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 selectionEnd = target.selectionEnd;\n\t\tconst key = e.key;\n\n\t\tif (key === \"-\") {\n\t\t\t// 이미 마이너스가 존재하거나, 커서가 맨 앞(0)이 아니면 차단 (중간이나 끝에 입력 방지)\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(super.attr.scale);\n\t\t\t// scale이 설정되지 않았거나(0 이하), 이미 소수점이 존재하면 차단\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\t// 마이너스만 있는 상태(\"-\")에서 바로 소수점이 찍히는 것(-.)을 막으려면 아래 조건 추가 가능\n\t\t\t// if (value === \"-\" && selectionStart === 1) { e.preventDefault(); return; }\n\t\t}\n\n\t\tlet validKey = [];\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && Number(super.attr.scale) > 0) validKey.push(\".\");\n\t\tif (super.attr.min === null || super.attr.min === undefined || Number(super.attr.min) > 0) validKey.push(\"-\");\n\n\t\t// 숫자 키패드 및 상단 숫자 키 허용 + 소수점/마이너스 허용\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\t// 소수점 자리수(scale) 제한 체크\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && 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(super.attr.scale)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (super.attr.maxbyte && nine.getByteLength(e.target.value) >= Number(super.attr.maxbyte) && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\te.preventDefault();\n\t\t}\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\n\tconstructor () {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input[type=color]\");\n\t\tthis.#btn = this.querySelector(\"button\");\n\t\tif (!this.#target) return;\n\n\t\t// 버튼 클릭 시 컬러 input을 프로그래밍 방식으로 클릭하여 팝업 오픈\n\t\tif (this.#btn) {\n\t\t\tthis.#btn.addEventListener(\"click\", () => {\n\t\t\t\tthis.#target.click();\n\t\t\t});\n\t\t}\n\n\t\t// 색상 변경 즉시 반영\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.#validateInput(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.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\tthis.#target.click();\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-color {\n --position: relative;\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-color.invalid button {\n padding: 2px;\n }\n cell-input-color.invalid button:after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-input-color input[type=color] {\n width: 100%;\n height: 26px;\n padding: 0px;\n margin-left: unset;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-color: transparent;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color input[type=color]::-webkit-color-swatch {\n border: 0;\n border-top-left-radius: 2px;\n border-bottom-left-radius: 2px;\n }\n cell-input-color input[type=color]::-webkit-color-swatch-wrapper {\n padding: 1px;\n }\n\n cell-input-color button {\n display: inline-flex;\n width: 24px;\n height: 26px;\n margin-right: unset;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color button:after {\n content: \"\";\n border-top: 0.3em solid #333;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n cell-input-color input[type=color]:hover {\n filter: brightness(90%);\n }\n cell-input-color button:hover {\n filter: brightness(95%);\n }\n \n .CELL-INPUT-COLOR {\n \n }\n </style>\n\n <input type=\"color\" ${attr.join(\" \")} ondragstart=\"return false;\">\n <button tabindex=\"-1\" type=\"button\"></button>\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tconst val = v !== undefined && v !== null && v !== \"\" ? v : \"#ffffff\";\n\t\t\tthis.#target.value = val;\n\t\t\tthis.#validateInput(val);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\t\tthis.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tif (!this.#isValidColor(val)) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tthis.classList.add(\"invalid\");\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\tthis.applyBaseStyle();\n\n\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#type = super.attr[\"date-type\"] || \"date\";//this.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\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\t// 값 변경 시 즉시 반영 및 검증\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.#validateInput(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.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\t// 필요 시 추가 동작\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst height = parseInt(this.closest(\"tr\")?.style.height || \"26\", 10) - 1;\n\n\t\tlet attr = [];\n\t\tfor (var i = 0; i < cell.attributes.length; i++) {\n\t\t\tif ([\"value\", \"max\", \"min\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t//if ([\"value\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t\tattr.push(`${cell.attributes[i].name}=\"${cell.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-date {\n height: 100%;\n --width: calc(100% - 8px);\n width: 100%;\n display: flex;\n align-items: center;\n --margin-left: 4px;\n --margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-date input {\n position: relative;\n height: 26px;\n padding: 0;\n margin: 0;\n font: inherit;\n width: 100%;\n padding-left: 4px;\n border: 1px solid #f0f0f0;\n border-radius: 3px;\n outline: 0;\n background-color: transparent;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"black\" viewBox=\"0 0 16 16\"><path d=\"M11 7.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z\"/><path d=\"M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M2 2a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/><path d=\"M2.5 4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5z\"/></svg>');\n background-repeat: no-repeat;\n background-position: right 2px center;\n background-size: 14px auto;\n color: #333;\n box-sizing: border-box;\n }\n\n cell-input-date input:hover {\n filter: brightness(95%);\n }\n \n cell-input-date input::-webkit-calendar-picker-indicator {\n position: absolute;\n right: 0;\n top: 0;\n width: 16px;\n height: 100%;\n background: transparent;\n --color: transparent;\n cursor: pointer;\n \t--opacity: 0.3;\n \t--filter: brightness(80%);\n }\n \n\t\t\t\n\t\t\t\n cell-input-date input::before {\n content: attr(data-placeholder);\n position: absolute;\n display: flex;\n align-items: center;\n width: calc(100% - 22px);\n height: 100%;\n background-color: white;\n left: 1px;\n top: 1px;\n pointer-events: none;\n }\n\n cell-input-date input.has-value::before,\n cell-input-date input:focus::before {\n display: none;\n }\n\n cell-input-date input:focus {\n border: 1px solid #28a745;\n border-radius: 3px;\n }\n \n \n </style>\n\n <input\n type=\"${cell.getAttribute('date-type') || 'date'}\"\n data-placeholder=\"${cell.getAttribute('placeholder') || 'Select'}\"\n ${attr.join(\" \")}\n required\n />\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (!this.#target) return v;\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\t//trace.log(this.#type, formattedVal);\n\n\t\tthis.#target.value = formattedVal || \"\";\n\t\tthis.#target.classList.toggle(\"has-value\", !!formattedVal); // 💡 값이 있으면 클래스 추가\n\t\tthis.#validateInput(formattedVal);\n\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst min = cell?.getAttribute(\"min\");\n\t\tconst max = cell?.getAttribute(\"max\");\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tlet isValid = this.#isValidDate(val);\n\n\t\t\t// 💡 형식 검증을 통과했더라도 min/max 범위를 벗어났다면 invalid 처리\n\t\t\tif (isValid) {\n\t\t\t\tif (min && val < min) isValid = false;\n\t\t\t\tif (max && val > 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\t\t//if (ninegrid.isNull(v)) return true;\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\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 #isRadio;\n #trueText;\n #falseText;\n\n constructor() {\n super();\n\n\n }\n\n connectedCallback() {\n this.#renderer();\n\n super.connectedCallback();\n\n this.#init();\n }\n\n get trueValue() {\n return super.attr[\"true-value\"] || \"Y\";\n }\n get falseValue() {\n return super.attr[\"false-value\"] || \"N\";\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 #init = () => {\n this.#target = this.querySelector(\"input\");\n this.#label = this.querySelector(\"span\");\n\n this.#trueText = super.attr[\"true-text\"] || \"\";\n this.#falseText = super.attr[\"false-text\"] || \"\";\n //this.#isRadio = super.attr[\"is-radio\"] || false;\n\n // 헤더에 있는 체크박스인 경우 (전체 선택/해제 기능)\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 // 스페이스바 입력 시 값 토글 처리\n this.cell?.addEventListener(\"keydown\", (e) => {\n\n e.preventDefault();\n\n if (e.code === \"Space\") return;\n if (this.closest(\"thead\")) return; // 헤더는 제외\n if (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n if (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\n //this.value = newVal;\n if (this.#isRadio) {\n this.selectAll(false);\n }\n\n this.value = newVal;\n\n super.sheet.invalidate();\n });\n\n\n this.#target.addEventListener(\"change\", (event) => {\n if (!this.closest(\"tbody\")) return;\n\n //const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\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 super.sheet.rowManager.refresh(true);\n //super.sheet.invalidate();\n });\n }\n\n #renderer = () => {\n\n const $cell = this.closest(\"th,td\");\n\n this.#isRadio = $cell?.getAttribute(\"is-radio\") || false;\n\n const trueValue = $cell?.getAttribute(\"true-value\") || false;\n //const selectedBorderColor = this.getAttribute(\"selected-border-color\") || \"dimgray\";\n\n const originalContent = $cell?.getAttribute(\"content\") || \"\";\n const childHtml = this.#isRadio ? `<input type=\"radio\" value=\"${trueValue}\" />` : `<label><input type=\"checkbox\" /><span>${originalContent}</span></label>`;\n\n // 🎯 div.ng-wrap 없이 cell-checkbox(Host) 자체를 플렉스 컨테이너로 활용하여 중앙정렬 보장\n this.innerHTML = `\n <style>\n .CELL-CHECKBOX {\n cell-checkbox {\n justify-content: center;\n }\n label {\n display: flex;\n }\n input {\n background-color: #ffffff;\n }\n \n \n /* 라디오 버튼 스타일 */\n input[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n .CELL-CHECKBOX[text-align='left'] {\n cell-checkbox {\n justify-content: flex-start;\n }\n }\n .CELL-CHECKBOX[text-align='center'] {\n cell-checkbox {\n justify-content: center;\n }\n }\n .CELL-CHECKBOX[text-align='right'] {\n cell-checkbox {\n justify-content: flex-end;\n }\n label {\n flex-direction: row-reverse;\n }\n }\n \n \n \n cell-checkbox {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n }\n cell-checkbox label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n cursor: pointer;\n user-select: none;\n }\n cell-checkbox input {\n outline: none;\n }\n \n </style>\n ${childHtml}\n `;\n }\n\n refresh = () => {\n const val = super.refresh(); // CellElement의 원시값 직통 조회 활용\n\n if (!this.closest(\"tbody\") && !this.closest(\"thead\")) return val;\n\n // 체크박스 상태 동기화\n if (this.#target) {\n this.#target.checked = (val === this.trueValue);\n this.#validateInput(val);\n }\n\n // 라벨 텍스트 동기화\n if (this.#label) {\n const displayText = (val === this.trueValue) ? this.#trueText : ((val === this.falseValue) ? this.#falseText : val);\n this.#label.textContent = displayText;\n }\n\n return val;\n };\n\n #validateInput = (val) => {\n\n if (!this.#target) return;\n\n super.cell.classList.remove(\"invalid\");\n\n if (val !== \"\" && val !== null && val !== undefined) {\n if (val !== this.trueValue && val !== this.falseValue) {\n super.cell.classList.add(\"invalid\");\n }\n }\n };\n\n selectAll = (v) => {\n if (this.closest(\"thead\")) return; // 헤더 자신은 제외\n\n const data = super.host.data.getArray();\n const colIndex = super.host.fields.indexOf(super.cell.dataset.bind);\n\n if (colIndex < 0) return;\n\n for (let i = 0; i < data.length; i++) {\n if (super.attr.enable && super.getExprValue(super.attr.enable, data[i], i, super.cell) === false) continue;\n if (super.attr.readonly && super.getExprValue(super.attr.readonly, data[i], i, super.cell) === true) continue;\n if (super.attr.visible && super.getExprValue(super.attr.visible, data[i], i, super.cell) === false) continue;\n\n data[i].v[colIndex] = v ? this.trueValue : this.falseValue;\n }\n\n super.sheet.invalidate();\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\";\nimport {NINE_TABLE} from \"@\";\n\nclass CellRadio extends EditableCellElement {\n\t#target;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\n\t#host;\n\t#sheet;\n\t#cell;\n\t#tr;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#keyName = this.closest(\"th,td\").getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = this.closest(\"th,td\").getAttribute(\"value-name\") || \"v\";\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\n\n\t\tthis.#rendererRadio();\n\n\t\tthis.#initEvent();\n\n\t\t// 3. 사용자 인터랙션 (스페이스바로 라디오 순회 변경)\n\n\t}\n\n\t#initEvent = () => {\n\t\tsuper.cell.addEventListener(\"keydown\", e => {\n\n\t\t\te.preventDefault();\n\n\t\t\tif (e.code !== \"Space\") return;\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\tlet matchIndex = -1;\n\n\t\t\tconst targets = Array.from(this.querySelectorAll(\"input\"));\n\t\t\ttargets.forEach(($el,index) => {\n\t\t\t\tif (this.value === $el.getAttribute(\"value\")) {\n\t\t\t\t\tmatchIndex = index;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmatchIndex = (matchIndex === targets.length - 1) ? 0 : (matchIndex >= 0 ? matchIndex + 1 : 0);\n\t\t\tthis.value = targets[matchIndex].getAttribute(\"value\");\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#rendererRadio = () => {\n\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\ttrace.log(\"==============================================\");\n\t\ttrace.log(this.sheet, this.#dataSource);\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(\"1111\");\n\t\t}, 300)\n\n\t\tthis.#target.replaceChildren();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tconst codeVal = v[this.#keyName] !== undefined ? v[this.#keyName] : '';\n\t\t\t\tconst nameVal = v[this.#valueName] !== undefined ? v[this.#valueName] : '';\n\n\t\t\t\t// <label> 생성\n\t\t\t\tconst label = document.createElement('label');\n\n\t\t\t\t// <input type=\"radio\" value=\"...\"> 생성\n\t\t\t\tconst input = document.createElement('input');\n\t\t\t\tinput.type = 'radio';\n\t\t\t\tinput.value = codeVal;\n\n\t\t\t\t// <span>텍스트</span> 생성 (textContent를 써야 XSS 방어 및 안전합니다)\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tspan.textContent = nameVal;\n\n\t\t\t\t// 조립\n\t\t\t\tlabel.appendChild(input);\n\t\t\t\tlabel.appendChild(span);\n\t\t\t\tfragment.appendChild(label);\n\t\t\t});\n\n\t\t\tthis.#target.appendChild(fragment);\n\n\t\t\tthis.querySelectorAll(\"input\").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\tsuper.sheet.rowManager.refresh(true);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\n\t\t// 4. 마우스 클릭 시 값 변경 및 즉시 반영\n\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n <style>\n \t.CELL-RADIO {\n \t\t\tinput[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n \n \t.CELL-RADIO[text-align='left'] {\n cell-radio {\n justify-content: flex-start;\n }\n }\n .CELL-RADIO[text-align='center'] {\n cell-radio {\n justify-content: center;\n }\n }\n .CELL-RADIO[text-align='right'] {\n cell-radio {\n justify-content: flex-end;\n }\n }\n \n cell-radio {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n \n div {\n \tdisplay: flex;\n \t\t\t\t\tflex-direction: row;\n }\n }\n\n cell-radio.invalid::after {\n content: '';\n margin-left: 4px;\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-radio input {\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n padding: 0;\n margin: 0;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border: 1px solid dimgray;\n border-radius: 50%;\n outline: 0;\n cursor: pointer;\n }\n\n cell-radio input:checked {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3\" cx=\"50%\" cy=\"50%\" fill=\"dimgray\" /></svg>');\n }\n\n cell-radio label {\n display: flex;\n align-items: center;\n margin-right: 8px;\n cursor: pointer;\n user-select: none;\n }\n\n cell-radio label.disabled {\n pointer-events: none;\n opacity: 0.5;\n }\n\n cell-radio span {\n margin-left: 4px;\n font-size: 12px;\n }\n </style>\n \n <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\tif (!this.#target) return v;\n\n\t\tthis.querySelectorAll(\"input\").forEach($el => {\n\t\t\t$el.checked = (this.value == $el.getAttribute(\"value\")) ? true : false;\n\t\t});\n\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\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 idx = this.#dataSource.findIndex(m => this.value === m[this.#keyName]);\n\t\tif (idx < 0) {\n\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-radio')) {\n\tcustomElements.define(\"cell-radio\", CellRadio);\n}","import { trace } from \"@nopeer\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#parent;\n\t#keyName;\n\t#valueName;\n\t#isOpen = false;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tthis.#initEvents();\n\t}\n\n\t#initData = (dataSource, keyName, valueName, multi, separator) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource || dataSource.length === 0) return;\n\n\t\t// 1. 부모(parent)의 items 속성 확인 (예: \"CODE,NAME,DESC\" 형태)\n\t\tconst itemsAttr = this.#parent.getAttribute(\"items\");\n\t\tlet fieldKeys = [];\n\n\t\tif (itemsAttr) {\n\t\t\tfieldKeys = itemsAttr.split(\",\").map(s => s.trim());\n\t\t} else {\n\t\t\tfieldKeys = [valueName].filter(Boolean);\n\t\t}\n\n\t\tconst activeColumnCount = fieldKeys.length;\n\n\t\t// 2. 🎯 [수정] multi 모드 여부에 따라 0번 컬럼(체크박스) 가시성 제어\n\t\t//trace.log(grd.shadowRoot, grd.shadowRoot.querySelectorAll('nine-table-body table'));\n\t\tgrd.shadowRoot.querySelector(\".ng-container-left\").style.display = multi ? '' : 'none';\n\n\t\tgrd.shadowRoot.querySelectorAll('table colgroup col, tbody td').forEach(($el, idx) => {\n\t\t\ttrace.log($el);\n\n\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\tif (col >= 2) {\t// row-indicator, checkbox 제외\n\t\t\t\t$el.style.display = (col - 2 >= activeColumnCount) ? 'none' : '';\n\t\t\t}\n\t\t});\n\n\t\t// 3. 동적 데이터 매핑 (dataSource 원본 객체에서 fieldKeys 순서대로 tmp1 ~ tmpN에 매핑)\n\t\tconst formattedData = dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: keyName && item[keyName] !== undefined ? item[keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\tfieldKeys.forEach((key, idx) => {\n\t\t\t\trow[`tmp${idx + 1}`] = item[key] !== undefined ? item[key] : (item[idx] !== undefined ? item[idx] : \"\");\n\t\t\t});\n\t\t\treturn row;\n\t\t});\n\n\t\tgrd.data.set(formattedData);\n\n\t\t// 4. 멀티 모드일 때 기존 선택값 반영\n\t\tif (multi && this.#parent.value) {\n\t\t\tconst selectedKeys = String(this.#parent.value).split(separator || \",\");\n\t\t\tgrd.data.getValidData().forEach(m => {\n\t\t\t\tif (selectedKeys.includes(String(m.v[1]))) {\n\t\t\t\t\tm.v[0] = \"Y\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tgrd.refreshData();\n\t\t}\n\t};\n\n\topen = (parent, dataSource, keyName, valueName, multi, separator) => {\n\t\tthis.#parent = parent;\n\t\tthis.#keyName = keyName;\n\t\tthis.#valueName = valueName;\n\t\tthis.#isOpen = true;\n\n\t\ttrace.log(new Date());\n\n\t\tthis.classList.add(\"active\");\n\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource) return;\n\n\t\t// 🎯 패널을 열자마자 active를 주어 레이아웃(offsetHeight) 확보 및 초기화 수행\n\n\n\t\t// 검색어 초기화 및 체크박스 기본값 설정\n\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\t// 데이터 개수 및 모드에 따른 클래스 제어\n\t\tif (dataSource.length > 10) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tif (multi) {\n\t\t\tthis.classList.add(\"multi\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"multi\");\n\t\t}\n\n\t\t// 데이터 및 멀티컬럼 구조 초기화 실행\n\n\t\t// 🎯 [필터 패널 방식 위치 정렬 적용] 시트(sheet) 기준 상대 좌표계산\n\t\tconst sheet = parent.closest(\"nine-table-sheet\");\n\t\tconst btnEl = parent.querySelector(\".btn1\");\n\t\tif (!btnEl || !sheet) return;\n\n\t\tconst btnRect = btnEl.getBoundingClientRect();\n\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\tlet left = btnRect.left - sheetRect.left;\n\t\tlet top = btnRect.bottom - sheetRect.top + 2;\n\n\t\t// 화면 오른쪽 밖으로 넘칠 경우 보정\n\t\tconst panelWidth = this.offsetWidth || 250;\n\t\tconst panelHeight = this.offsetHeight || 250;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 5);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\tif (top + panelHeight > sheetRect.height) {\n\t\t\tconst upwardTop = (btnRect.top - sheetRect.top) - panelHeight - 2;\n\t\t\tif (upwardTop >= 0) {\n\t\t\t\ttop = upwardTop; // 위쪽 공간이 있으면 위로 팝업\n\t\t\t} else {\n\t\t\t\ttop = Math.max(0, sheetRect.height - panelHeight - 5); // 위아래 다 부족하면 시트 하단에 밀착\n\t\t\t}\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\t// 내부 그리드 행 클릭 이벤트 바인딩 (싱글 모드용)\n\t\ttrace.log(new Date());\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(new Date());\n\t\t\tthis.#initData(dataSource, keyName, valueName, multi, separator);\n\t\t\ttrace.log(new Date());\n\t\t\tconst viewContainer = grd.shadowRoot.querySelector(\".ng-container-body table tbody.body\");\n\n\t\t\t// 중복 바인딩 방지를 위한 플래그 체크 또는 기존 리스너 관리\n\t\t\tif (!viewContainer.__hasClickEvent) {\n\n\t\t\t\tviewContainer.addEventListener(\"mousedown\", (e) => {\n\t\t\t\t\ttrace.log(\"==========================================\", e.target);\n\n\t\t\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\t\t\tif (!tr) return;\n\n\t\t\t\t\ttrace.log(\"==========================================\", multi);\n\n\t\t\t\t\tif (!multi) {\n\t\t\t\t\t\tthis.#onClickRow(e);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tviewContainer.__hasClickEvent = true;\n\t\t\t}\n\n\t\t\ttrace.log(new Date());\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#isOpen = false;\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus();\n\t\t}\n\t}\n\n\t#onClickRow = (e) => {\n\n\t\tconst sheet = e.target.closest(\"nine-table-sheet\");\n\t\tconst tr = e.target.closest(\"tr\");\n\n\t\tconst rowIndex = parseInt(tr.dataset.row, 10);\n\t\tconst record = sheet.view.get(rowIndex);\n\n\t\tthis.#parent.value = record.k;\n\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onOk = () => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst data = grd.data.getValidData();\n\n\t\tconst selectedKeys = [];\n\t\tdata.forEach(o => {\n\t\t\tif (o.v[0] === \"Y\") {\n\t\t\t\tselectedKeys.push(o.v[1]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = selectedKeys.join(this.#parent.getAttribute(\"multi-separator\") || \",\");\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onSelectAll = (e) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst isChecked = e.target.checked ? \"Y\" : \"N\";\n\t\tgrd.data.getValidData().forEach(m => { m.v[0] = isChecked; });\n\t\tgrd.refreshData();\n\t}\n\n\t#onInput = (e) => {\n\t\tconst keyword = e.target.value.toLowerCase();\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\n\t\t// 동적 컬럼(모든 밸류) 대상 검색 대응\n\t\tgrd.data.getValidDataNF().forEach(m => {\n\t\t\tconst match = Object.values(m.v).some(val =>\n\t\t\t\tval !== null && val !== undefined && String(val).toLowerCase().includes(keyword)\n\t\t\t);\n\t\t\tm.__ng.filtered = !match;\n\t\t});\n\n\t\tgrd.data.resetRecords();\n\t\tgrd.dataManager.viewRecords.reset();\n\t}\n\n\tget isOpen() {\n\t\treturn this.#isOpen;\n\t}\n\n\tget targetCell() {\n\t\treturn this.#parent;\n\t}\n\n\t#initEvents = () => {\n\t\tthis.querySelector(\".search-input\").addEventListener(\"input\", this.#onInput);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\n\n\t\t// 🎯 [개선] open() 할 때마다 붙일 필요 없이, 내부 그리드 영역에 이벤트 위임 처리\n\n\t\t/**\n\t\t// shadowRoot 내부 또는 컴포넌트 전체 영역을 감싸는 리스너 등록\n\t\tthis.querySelector(\"nine-table-simple\").addEventListener(\"click\", (e) => {\n\t\t\ttrace.log(e);\n\n\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\tif (!tr) return;\n\n\t\t\t// 멀티 모드가 아닐 때만 행 클릭 동작 수행\n\t\t\tconst isMulti = this.classList.contains(\"multi\");\n\t\t\tif (!isMulti) {\n\t\t\t\tthis.#onClickRow(e, false, grd);\n\t\t\t}\n\t\t}); */\n\n\t\t// 패널 외부 클릭 시 닫기\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\t\t\tconst path = e.composedPath ? e.composedPath() : [];\n\n\t\t\t// 패널 자신이나 현재 열려 있는 필터 버튼이 경로에 포함되어 있다면 닫지 않음\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 <style>\n \n cell-combo-panel.active {\n display: flex;\n }\n cell-combo-panel .head {\n display: none;\n padding: 6px;\n background: #f8f9fa;\n border-bottom: 1px solid #e5e7eb;\n }\n cell-combo-panel .head input[type=\"text\"] {\n width: 100%;\n height: 26px;\n padding: 0 6px;\n box-sizing: border-box;\n border: 1px solid #d1d5db;\n border-radius: 3px;\n outline: none;\n font-size: 12px;\n }\n cell-combo-panel.expand .head {\n display: flex;\n }\n cell-combo-panel nine-table-simple {\n width: 100%;\n flex: 1;\n border: none;\n }\n cell-combo-panel .footer {\n display: none;\n height: 32px;\n background: #f3f4f6;\n border-top: 1px solid #e5e7eb;\n align-items: center;\n padding: 0 8px;\n box-sizing: border-box;\n }\n cell-combo-panel.multi .footer {\n display: flex;\n justify-content: space-between;\n }\n cell-combo-panel .footer label {\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n }\n cell-combo-panel .footer button {\n height: 22px;\n padding: 0 12px;\n font-size: 11px;\n cursor: pointer;\n background: #2563eb;\n color: white;\n border: none;\n border-radius: 3px;\n }\n cell-combo-panel .footer button:hover {\n background: #1d4ed8;\n }\n </style>\n \n <div class=\"head\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\n </div>\n \n <nine-table-simple class=\"combo-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"30\" fixed=\"left\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"0\" />\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"tmp1\" />\n <td data-bind=\"tmp2\" />\n <td data-bind=\"tmp3\" />\n <td data-bind=\"tmp4\" />\n <td data-bind=\"tmp5\" />\n <td data-bind=\"tmp6\" />\n <td data-bind=\"tmp7\" />\n <td data-bind=\"tmp8\" />\n <td data-bind=\"tmp9\" />\n <td data-bind=\"tmp10\" />\n <td data-bind=\"k\" />\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n \n <div class=\"footer\">\n <div>\n <input id=\"chkAll\" type=\"checkbox\" checked>\n <label for=\"chkAll\">Select All</label>\n </div>\n <button id=\"btnOk\">OK</button>\n </div>\n `;\n\t};\n}\n\nif (!customElements.get('cell-combo-panel')) {\n\tcustomElements.define(\"cell-combo-panel\", CellComboPanel);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport \"./cell-combo-panel.js\";\n\nexport class CellCombo extends EditableCellElement {\n\t#targetBtn;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\t#multi;\n\t#multiSeparator;\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tthis.#keyName = super.cell.getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = super.cell.getAttribute(\"value-name\") || \"v\";\n\t\tthis.#multi = super.cell.getAttribute('multi') === \"true\";\n\t\tthis.#multiSeparator = super.cell.getAttribute(\"multi-separator\") || \",\";\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\trerenderer = () => {\n\t\ttrace.log(\"rerenderer\");\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\t#initData = () => {\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\t// 🎯 공통 표현식 평가기를 통해 데이터 소스(배열 또는 함수 결과) 획득\n\t\t//this.#host.exprEngine.evaluate(dataSource, data, row);\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\t//trace.log(\"*******************************\", this.#dataSource);\n\t}\n\n\t#initEvent = () => {\n\t\t// 엔터 키 입력 시 드롭다운 토글\n\t\tthis.addEventListener(\"keydown\", e => {\n\t\t\tif (e.code === \"Enter\") {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.#togglePanel();\n\t\t\t}\n\t\t});\n\n\t\t// Light DOM 기준이므로 this 안에서 버튼 탐색\n\t\tthis.querySelectorAll(\"button\").forEach(btn => {\n\t\t\tbtn.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\t}\n\n\t#togglePanel = () => {\n\t\ttrace.log(new Date());\n\t\tif (!this.#panel) {\n\t\t\t// 🎯 필터링 패널 방식과 동일하게 현재 셀이 속한 sheet(또는 그리드) 탐색\n\t\t\tthis.#panel = super.sheet.querySelector(\"cell-combo-panel\");\n\t\t\tif (!this.#panel) {\n\t\t\t\tthis.#panel = document.createElement(\"cell-combo-panel\");\n\t\t\t\tsuper.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\ttrace.log(new Date());\n\n\t\tif (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\t\tthis.#panel.close();\n\t\t} else {\n\t\t\tthis.#panel.open(this, this.#dataSource, this.#keyName, this.#valueName, this.#multi, this.#multiSeparator);\n\t\t}\n\n\t\ttrace.log(new Date());\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-combo {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n cell-combo.invalid .btn2::after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n cell-combo button {\n outline: none;\n cursor: pointer;\n font: inherit;\n }\n cell-combo button.btn1 {\n width: calc(100% - 24px);\n height: 26px;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n text-align: left;\n background-color: white;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 4px;\n color: #000;\n }\n cell-combo button.btn2 {\n padding: 3px;\n width: 24px;\n height: 26px;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #333;\n }\n cell-combo button.btn2:after {\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n </style>\n <button class=\"btn1\" type=\"button\" tabindex=\"-1\">Select</button>\n <button class=\"btn2\" type=\"button\" tabindex=\"-1\"></button>\n `;\n\n\t\t// Light DOM 구조이므로 this에서 직접 쿼리\n\t\tthis.#targetBtn = this.querySelector(\".btn1\");\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tif (!this.#targetBtn) return v;\n\n\t\t// 현재 값에 매칭되는 텍스트(표시명) 계산\n\t\tthis.#targetBtn.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#getDisplayText = () => {\n\t\tif (!this.value || !Array.isArray(this.#dataSource)) return \"\";\n\n\t\tif (this.#multi) {\n\t\t\tconst keys = String(this.value).split(this.#multiSeparator);\n\t\t\treturn this.#dataSource\n\t\t\t\t.filter(m => keys.includes(String(m[this.#keyName])))\n\t\t\t\t.map(m => m[this.#valueName])\n\t\t\t\t.join(this.#multiSeparator);\n\t\t} else {\n\t\t\tconst found = this.#dataSource.find(m => String(m[this.#keyName]) === String(this.value));\n\t\t\treturn found ? found[this.#valueName] : this.value;\n\t\t}\n\t}\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst list = this.#multi ? String(this.value).split(this.#multiSeparator) : [this.value];\n\t\tfor (const v of list) {\n\t\t\tconst idx = this.#dataSource.findIndex(m => String(v) === String(m[this.#keyName]));\n\t\t\tif (idx < 0) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-combo')) {\n\tcustomElements.define(\"cell-combo\", CellCombo);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\"; // Inherits from CellElement instead of EditableCellElement\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\t// Debug trace for inspecting component context and parent elements\n\t\t// trace.log(\"******************\", this, this.host, this.sheet, this.tr, this.cell);\n\n\t\tthis.#renderer();\n\n\t\t// Cache the internal text span target element\n\t\tthis.#target = this.querySelector(\"span\");\n\t}\n\n\t/**\n\t * Refreshes the cell display value based on binding and expression evaluations.\n\t */\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/**\n\t * Renders the internal markup and CSS layout rules for the cell renderer.\n\t */\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <span></span>\n `;\n\t};\n}\n\n// Register the custom element if not already defined\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\t// 부모 클래스의 connectedCallback 호출 (필수)\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\t/**\n\t * 레거시 dataRefresh 패턴 반영 (표현식 동적 평가 및 스타일링)\n\t */\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\n\t\t/**\n\t\t// 행 데이터 및 인덱스 확보\n\t\tconst rowIdx = parseInt(super.cell.dataset.row, 10);\n\t\tconst rowData = super.host?.data?.get ? super.host.data.get(rowIdx) : (this.closest(\"tr\")?.data);\n\n\t\tif (rowData && !isNaN(rowIdx)) {\n\t\t\t[\"color\", \"background\", \"border\"].forEach(attrName => {\n\t\t\t\tconst expr = this.getAttribute(attrName);\n\t\t\t\tif (expr && this.#target) {\n\t\t\t\t\tconst evaluatedVal = super.getExprValue ? super.getExprValue(expr, rowData, rowIdx, super.cell) : expr;\n\t\t\t\t\tthis.#target.style[attrName] = evaluatedVal;\n\t\t\t\t}\n\t\t\t});\n\t\t} */\n\t};\n\n\t#renderer = () => {\n\t\t/**\n\t\tconst allowedAttrs = [\"color\", \"background\", \"border\", \"class\", \"style\"];\n\t\tconst attrList = [];\n\n\t\tfor (let i = 0; i < this.attributes.length; i++) {\n\t\t\tconst attr = this.attributes[i];\n\t\t\tif (allowedAttrs.includes(attr.name)) {\n\t\t\t\tattrList.push(`${attr.name}=\"${attr.value}\"`);\n\t\t\t}\n\t\t} */\n\n\t\tconst cell = this.closest(\"th,td\");\n\n\t\tconst buttonText = \"...\";//this.getAttribute(\"text\") || super.attr[\"text\"] || \"\";\n\t\tconst height = (parseInt(cell.offsetHeight, 10) || 32) - 8;\n\n\t\tthis.innerHTML = `\n <style>\n /* 셀(td, th) 내부 패딩 제거 및 꽉 채우기 설정 */\n cell-button {\n display: flex;\n align-items: stretch;\n justify-content: stretch;\n width: 100%;\n height: ${height}px;\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n cell-button .button {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n border-radius: 0; /* 셀에 꽉 차게 보이려면 0이 깔끔할 수 있음 */\n border: 1px solid #d1d5db;\n background-color: #f3f4f6;\n color: #1f2937;\n outline: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n cell-button .button:hover {\n background-color: #e5e7eb;\n }\n cell-button .button:active {\n background-color: #d1d5db;\n }\n </style>\n <button class=\"button\">${buttonText}</button>\n `;\n\t};\n}\n\nif (!customElements.get('cell-button')) {\n\tcustomElements.define(\"cell-button\", CellButton);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRowIndicator extends CellElement {\n\t#mainTarget;\n\t#subTarget;\n\t#statusTarget;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback?.();\n\n\t\tif (this.cell) {\n\t\t\tthis.cell.removeAttribute(\"tabindex\");\n\t\t\tthis.cell.dataset.bind = \"rowState\";\n\n\t\t\tif (!this.cell.dataset.expr) {\n\t\t\t\tthis.cell.dataset.expr = \"data.__ng._[ninegrid.ROW.ORDER]\";\n\t\t\t}\n\n\t\t\tthis.cell.setAttribute(\"text-align\", \"center\");\n\t\t}\n\n\t\tthis.#mainTarget = this.querySelector(\".ng-row-main\");\n\t\tthis.#subTarget = this.querySelector(\".ng-row-sub\");\n\t\tthis.#statusTarget = this.querySelector(\".ng-row-status\");\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-row-indicator {\n display: block;\n position: absolute; /* 💡 셀 전체를 강제로 꽉 채움 */\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n box-sizing: border-box;\n user-select: none;\n }\n /* 메인 행 번호 (중앙 정렬을 위해 플렉스 적용) */\n .ng-row-main {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n text-align: center;\n overflow: hidden;\n }\n \n /* 🎯 천단위 콤마 및 분할 스타일링 */\n .ng-row-prefix {\n \tfont-weight: normal;\n font-size: 0.40rem; /* 앞자리(천단위 이상)는 아주 작게 */\n }\n .ng-row-suffix {\n font-size: 0.55rem; /* 마지막 3자리 및 콤마는 현재 셀 기본 폰트 크기 유지 */\n }\n \n /* 우측 하단: 원본/이빨빠진 번호 */\n .ng-row-sub {\n position: absolute;\n right: 2px;\n bottom: 1px;\n font-size: 0.40rem;\n line-height: 1;\n opacity: 0.2;\n pointer-events: none;\n }\n /* 우측 상단: 상태 표시 */\n .ng-row-status {\n position: absolute;\n right: 2px;\n top: 1px;\n font-size: 0.55rem;\n line-height: 1;\n pointer-events: none;\n }\n </style>\n \n <span class=\"ng-row-main\"></span>\n <span class=\"ng-row-sub\"></span>\n <span class=\"ng-row-status\"></span>\n `;\n\t}\n\n\t/**\n\t * 행 번호 및 상태 갱신\n\t */\n\trefresh = () => {\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tconst row = this.row;\n\t\tif (isNaN(row)) return;\n\n\t\tconst rawRecord = this.tr.data;\n\n\t\tif (rawRecord && rawRecord.__ng) {\n\t\t\tconst rowState = rawRecord.__ng.rowState;\n\n\t\t\t/**\n\t\t\t// 1. 행 상태에 따른 클래스 제어 및 우측 상단 상태 표시\n\t\t\tif (rowState === ninegrid.ROW_STATE.INSERT) {\n\t\t\t\tthis.classList.add('added');\n\t\t\t\tthis.classList.remove('updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"➕\";\n\t\t\t} else if (rowState === ninegrid.ROW_STATE.UPDATE) {\n\t\t\t\tthis.classList.add('updated');\n\t\t\t\tthis.classList.remove('added');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"✏️\";\n\t\t\t} else {\n\t\t\t\tthis.classList.remove('added', 'updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"\";\n\t\t\t} */\n\n\t\t\t/**\n\t\t\t// 2. 필터링 등으로 순번이 밀렸을 때 우측 하단에 원본 번호 표시\n\t\t\tif (rawRecord.__ng.i !== undefined) {\n\t\t\t\tconst currentSeq = row + 1;\n\t\t\t\tconst originalSeq = rawRecord.__ng.i + 1;\n\n\t\t\t\tif (this.#subTarget) {\n\t\t\t\t\tif (currentSeq !== originalSeq) {\n\t\t\t\t\t\tthis.#subTarget.textContent = originalSeq;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#subTarget.textContent = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} */\n\t\t}\n\n\t\tconst displayNum = this.index + 1;\n\n\t\t// 천단위 콤마 포맷팅 (예: 1234567 -> \"1,234,567\")\n\t\tconst formattedNum = displayNum.toLocaleString();\n\n\t\t// 3자리 이상일 경우 마지막 3자리(와 콤마 포함된 덩어리)를 기준으로 앞자리와 분리\n\t\tif (displayNum >= 10000) {\n\t\t\t// 뒤에서 4글자(콤마 + 3자리)를 기준으로 분리합니다. (예: \"1,234\" 와 \"567\")\n\t\t\tconst splitIndex = formattedNum.length - 4;\n\t\t\tconst prefixPart = formattedNum.substring(0, splitIndex + 1); // 천단위 이상 (작은 폰트)\n\t\t\tconst suffixPart = formattedNum.substring(splitIndex + 1); // 마지막 콤마 + 3자리 (기본 폰트)\n\n\t\t\tthis.#mainTarget.innerHTML = `\n <span class=\"ng-row-prefix\">${prefixPart}</span>\n <span class=\"ng-row-suffix\">${suffixPart}</span>\n `;\n\t\t} else {\n\t\t\t// 1000 미만인 경우 콤마만 있거나 일반 숫자로 그대로 표시\n\t\t\tthis.#mainTarget.innerHTML = `${formattedNum}`;\n\t\t}\n\n\t\tconst isSorted = this.sheet.querySelector(\"thead .asc,thead .desc\") ? true : false;\n\t\tconst isFitered = this.sheet.querySelector(\"thead nine-table-filter-button.filtered\") ? true : false;\n\n\t\tthis.#subTarget.innerHTML = row;\n\t\tthis.#subTarget.style.display = (isSorted || isFitered) ? \"\" : \"none\";\n\t};\n}\n\nif (!customElements.get('cell-row-indicator')) {\n\tcustomElements.define(\"cell-row-indicator\", CellRowIndicator);\n}","// ui/col/col-expand.js\nimport { TableCompiler, COLLAPSED_WIDTH } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColExpand extends HTMLElement {\n #sheet;\n #cell;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#cell = this.closest('th, td');\n this.#sheet = this.closest('nine-table-sheet');\n\n if (this.#cell) {\n this.#cell.style.position = 'relative';\n }\n\n const isCollapsed =\n this.getAttribute('collapsed') === 'true' ||\n this.#cell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n requestAnimationFrame(() => {\n this.collapse(true);\n });\n } else {\n this.classList.remove('collapsed');\n this.classList.add('expand');\n }\n\n this.removeEventListener('click', this.#onClick);\n this.addEventListener('click', this.#onClick);\n }\n\n #onClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (this.classList.contains('expand')) {\n this.collapse();\n } else {\n this.expand();\n }\n };\n\n /**\n * 🎯 원래 너비(dataset.expandWidth)로 복구\n */\n expand = () => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n this.classList.remove('collapsed');\n this.classList.add('expand');\n this.#cell.setAttribute('collapsed', 'false');\n this.#cell.style.color = '';\n\n const targetWidth = parseInt(this.#cell.dataset.expandWidth, 10) || 100;\n\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, targetWidth);\n } else {\n const singleWidth = Math.max(30, Math.floor(targetWidth / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, singleWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n collapse = (isInitialInit = false) => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n if (this.classList.contains('expand')) {\n const col = this.#sheet.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n const currentW = col ? parseInt(col.getAttribute('width'), 10) : 0;\n if (currentW > COLLAPSED_WIDTH) {\n this.#cell.dataset.expandWidth = String(currentW * colSpan);\n }\n }\n\n this.classList.remove('expand');\n this.classList.add('collapsed');\n this.#cell.setAttribute('collapsed', 'true');\n this.#cell.style.color = 'transparent';\n\n // 🎯 colSpan이 1이면 16px(COLLAPSED_WIDTH)을 그대로 적용, 2 이상이면 균등 분할\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, COLLAPSED_WIDTH);\n } else {\n const splitWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, splitWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n disconnectedCallback() {\n this.removeEventListener('click', this.#onClick);\n }\n}\n\nif (!customElements.get('nine-table-col-expand')) {\n customElements.define('nine-table-col-expand', ColExpand);\n}","// ui/menu/nine-table-menu.js (수정본)\n\nimport { trace } from \"@nopeer\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nexport class ContextMenu extends HTMLElement {\n #tableHost;\n #panel;\n\n connectedCallback() {\n const root = this.getRootNode();\n this.#tableHost = root instanceof ShadowRoot ? root.host : (this.closest('nine-table') || root.host);\n\n if (!this.#tableHost) {\n this.#tableHost = this.parentElement?.closest('nine-table') || this.assignedSlot?.closest('nine-table');\n }\n\n if (!this.#tableHost) return;\n\n //this.#tableHost.addEventListener('contextmenu', this.#onContextMenu);\n }\n\n #onContextMenu = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n const targetCell = path.find(el => el.tagName === 'TH' || el.tagName === 'TD');\n\n if (!targetCell) return;\n\n const targetTable = path.find(el => el.tagName === 'TABLE') || targetCell.closest('table');\n\n e.preventDefault();\n e.stopPropagation();\n\n this.openMenu(e.clientX, e.clientY, targetCell, targetTable);\n };\n\n /**\n * 🎯 우클릭이 발생한 대상 시트(NineTableSheet) 구하기\n */\n #getTargetSheet(targetCell) {\n return targetCell?.closest('nine-table-sheet') || this.#tableHost.activeSheet || this.#tableHost;\n }\n\n #getFixManager(targetCell) {\n const sheet = this.#getTargetSheet(targetCell);\n if (!sheet) return null;\n\n if (!sheet.colFix) {\n sheet.colFix = new ColFixManager(sheet);\n }\n return sheet.colFix;\n }\n\n #parseCustomMenuItems(containerElement, activeTable) {\n const items = [];\n const activeTableId = activeTable?.id;\n const allUls = Array.from(containerElement.querySelectorAll(':scope > ul'));\n\n allUls.forEach(rootUl => {\n const targetTableAttr = rootUl.getAttribute('target-table');\n\n if (!targetTableAttr || (activeTableId && targetTableAttr === activeTableId)) {\n const parsedList = this.#traverseUl(rootUl);\n items.push(...parsedList);\n }\n });\n\n return items;\n }\n\n #traverseUl(ulEl) {\n const list = [];\n Array.from(ulEl.children).forEach(child => {\n const tagName = child.tagName.toLowerCase();\n\n if (tagName === 'hr' || child.classList.contains('separator')) {\n list.push({ type: 'separator' });\n return;\n }\n\n if (tagName === 'li') {\n let name = '';\n const spanEl = child.querySelector(':scope > span');\n if (spanEl) {\n name = spanEl.textContent.trim();\n } else {\n name = Array.from(child.childNodes)\n .filter(n => n.nodeType === Node.TEXT_NODE)\n .map(n => n.textContent.trim())\n .join('');\n }\n\n const subUl = child.querySelector(':scope > ul');\n const item = {\n menuId: child.id || name,\n name: name,\n className: child.className || '',\n disabled: child.hasAttribute('disabled') || child.getAttribute('disabled') === 'true',\n isCustom: true\n };\n\n if (subUl) {\n item.items = this.#traverseUl(subUl);\n }\n\n list.push(item);\n }\n });\n return list;\n }\n\n #buildMenuItems(activeTable, isHeaderCell, targetCell) {\n const useDefault = this.getAttribute('use-default-menu') !== 'false';\n let rawItems = [];\n\n const customItems = this.#parseCustomMenuItems(this, activeTable);\n if (customItems.length > 0) {\n rawItems.push(...customItems);\n }\n\n const fixManager = this.#getFixManager(targetCell);\n const currentFixState = fixManager?.getFixState(targetCell, activeTable) ?? 'none';\n const isFixable = isHeaderCell && (fixManager?.canFixColumn(targetCell, activeTable) ?? false);\n\n let fixMenuItem = null;\n if (currentFixState === 'left' || currentFixState === 'right') {\n fixMenuItem = {\n menuId: 'unfix-column',\n name: 'Unfix Column',\n className: 'ng-menu-unfix-col',\n disabled: !isHeaderCell\n };\n } else {\n fixMenuItem = {\n menuId: 'fix-column',\n name: 'Fix Column',\n className: 'ng-menu-fix-col',\n disabled: !isFixable\n };\n }\n\n if (useDefault) {\n rawItems.push(\n { type: 'separator' },\n {\n menuId: 'sort',\n name: 'Sort',\n className: 'ng-menu-sort',\n disabled: !isHeaderCell\n },\n fixMenuItem,\n { type: 'separator' },\n { menuId: 'filtering', name: 'Filtering', className: 'ng-menu-filtering' },\n { menuId: 'maximize', name: 'Maximize', className: 'maximize' },\n {\n menuId: 'export',\n name: 'Export',\n className: 'export',\n items: [\n { menuId: 'export-excel', name: 'Excel', className: 'export-excel' },\n { menuId: 'export-pdf', name: 'PDF', className: 'export-pdf', disabled: true }\n ]\n },\n {\n menuId: 'properties',\n name: 'Options',\n className: 'options',\n items: [\n { menuId: 'show-title-bar', name: 'Title Bar Show/Hide', className: 'show-title-bar' },\n { menuId: 'show-status-bar', name: 'Status Bar Show/Hide', className: 'show-status-bar' },\n { menuId: 'auto-fit-col', name: 'Auto Fit Columns', className: 'auto-fit-col' }\n ]\n }\n );\n }\n\n const cleanedItems = [];\n rawItems.forEach((item) => {\n if (item.type === 'separator') {\n if (cleanedItems.length === 0 || cleanedItems[cleanedItems.length - 1].type === 'separator') {\n return;\n }\n }\n cleanedItems.push(item);\n });\n\n if (cleanedItems.length > 0 && cleanedItems[cleanedItems.length - 1].type === 'separator') {\n cleanedItems.pop();\n }\n\n return cleanedItems;\n }\n\n openMenu(x, y, targetCell, targetTable) {\n const targetParent = this.#tableHost.shadowRoot || this.#tableHost;\n\n if (!this.#panel) {\n this.#panel = document.createElement('nine-table-menu-panel');\n targetParent.appendChild(this.#panel);\n }\n\n const isHeaderCell = !!targetCell.closest('thead');\n const menuItems = this.#buildMenuItems(targetTable, isHeaderCell, targetCell);\n\n this.#panel.render(menuItems, (e) => this.#handleMenuClick(e, targetCell, targetTable));\n\n const targetSheet = this.#getTargetSheet(targetCell);\n this.#syncMenuStates(targetSheet);\n\n // 🎯 targetCell을 3번째 인자로 전달하여 셀 우측선 정렬\n this.#panel.openAt(x, y);\n }\n\n /**\n * 🎯 메뉴 항목 활성화 체크 표시(✓) 동기화\n */\n #syncMenuStates(targetSheet) {\n if (!this.#panel || !targetSheet) return;\n\n // 🎯 클릭된 개별 시트의 filtering 상태 검사\n const isFiltering = targetSheet.filtering?.isFiltering?.() || false;\n this.#panel.toggleItemState('filtering', 'on', isFiltering);\n\n const autoFit = this.#tableHost.getAttribute('auto-fit-col') === 'true';\n this.#panel.toggleItemState('auto-fit-col', 'on', autoFit);\n\n const showTitle = this.#tableHost.getAttribute('show-title-bar') === 'true';\n this.#panel.toggleItemState('show-title-bar', 'on', showTitle);\n }\n\n #handleMenuClick(e, targetCell, targetTable) {\n const menuId = e.menuId;\n\n const customEvent = new CustomEvent('menu-click', {\n detail: { menuId, targetCell, targetTable, originalEvent: e },\n bubbles: true,\n composed: true\n });\n this.dispatchEvent(customEvent);\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n\n // 🎯 클릭된 셀의 소속 시트 인스턴스 타겟팅\n const targetSheet = this.#getTargetSheet(targetCell);\n\n switch (menuId) {\n case 'fix-column':\n case 'unfix-column':\n const fixManager = this.#getFixManager(targetCell);\n fixManager?.executeFixToggle(menuId, targetCell);\n break;\n\n case 'sort':\n if (!isNaN(baseCol)) {\n targetSheet.sorting?.handleSortFromMenu?.(baseCol, targetCell);\n }\n break;\n\n case 'filtering':\n targetSheet?.filtering?.toggle();\n break;\n\n case 'auto-fit-col':\n this.#tableHost.setAttribute('auto-fit-col', this.#tableHost.getAttribute('auto-fit-col') === 'true' ? 'false' : 'true');\n break;\n\n case 'show-title-bar':\n this.#tableHost.setAttribute('show-title-bar', this.#tableHost.getAttribute('show-title-bar') === 'true' ? 'false' : 'true');\n break;\n }\n\n this.#panel.close();\n }\n\n disconnectedCallback() {\n this.#tableHost?.removeEventListener('contextmenu', this.#onContextMenu);\n }\n}\n\nif (!customElements.get('nine-table-menu')) {\n customElements.define('nine-table-menu', ContextMenu);\n}","// ui/menu/nine-table-menu-panel.js\n\nexport class MenuPanel extends HTMLElement {\n #onCallback;\n #closeHandler = null; // 🎯 이벤트 누수 방지용 리스너 참조\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n // 🎯 [보정 1] 패널 자체의 기본 레이아웃 스타일은 element style로 직접 지정\n this.style.position = 'fixed';\n this.style.display = 'none';\n this.style.zIndex = '99999';\n\n this.innerHTML = `\n <style>\n \n nine-table-menu-panel .menu-wrapper {\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 150px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 12px;\n }\n nine-table-menu-panel ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n nine-table-menu-panel li {\n position: relative;\n padding: 6px 16px;\n cursor: pointer;\n color: #374151;\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n }\n nine-table-menu-panel li:hover {\n background-color: #f3f4f6;\n color: #111827;\n }\n nine-table-menu-panel li.on::before {\n content: '✓';\n position: absolute;\n left: 4px;\n font-weight: bold;\n }\n nine-table-menu-panel li.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background: transparent !important;\n }\n nine-table-menu-panel li.ng-menu-separator {\n height: 1px;\n background: #e5e7eb;\n margin: 4px 0;\n padding: 0;\n cursor: default;\n }\n nine-table-menu-panel li.submenu::after {\n content: '▶';\n font-size: 9px;\n margin-left: 8px;\n color: #9ca3af;\n }\n nine-table-menu-panel .ng-menu-sublist {\n display: none;\n position: absolute;\n top: -4px;\n left: 100%;\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 140px;\n }\n nine-table-menu-panel li.submenu:hover > .ng-menu-sublist {\n display: block;\n }\n </style>\n <div class=\"menu-wrapper\">\n <ul class=\"menu-container\"></ul>\n </div>\n `;\n }\n\n render(items, callback) {\n this.#onCallback = callback;\n const container = this.querySelector('.menu-container');\n if (!container) return;\n\n container.innerHTML = '';\n\n this.#appendItems(container, items);\n this.#bindClickEvents();\n }\n\n /**\n * 🎯 패널의 우측선과 targetCell의 우측선을 일치시키는 포지셔닝\n */\n openAt(x, y, targetCell = null) {\n this.style.display = 'block';\n\n if (targetCell) {\n const cellRect = targetCell.getBoundingClientRect();\n // 셀의 오른쪽 경계선 좌표\n const cellRightX = cellRect.right;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const panelWidth = wrapper.getBoundingClientRect().width;\n\n // 패널 우측선을 셀 우측선에 맞춤 (Left = cellRight - panelWidth)\n let calculatedLeft = cellRightX - panelWidth;\n\n // 뷰포트 왼쪽 밖으로 벗어나는 예외 처리\n if (calculatedLeft < 0) {\n calculatedLeft = cellRect.left; // 공간이 부족하면 셀 좌측선에 맞춤\n }\n\n // 뷰포트 아래쪽 벗어남 처리\n const panelHeight = wrapper.getBoundingClientRect().height;\n let calculatedTop = y;\n if (y + panelHeight > window.innerHeight) {\n calculatedTop = y - panelHeight;\n }\n\n this.style.left = `${calculatedLeft}px`;\n this.style.top = `${calculatedTop}px`;\n });\n } else {\n // 기본 마우스 클릭 좌표 기반 (Fallback)\n this.style.left = `${x}px`;\n this.style.top = `${y}px`;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n\n if (x + rect.width > window.innerWidth) {\n this.style.left = `${x - rect.width}px`;\n }\n if (y + rect.height > window.innerHeight) {\n this.style.top = `${y - rect.height}px`;\n }\n });\n }\n\n // 바깥 클릭 핸들러 등록\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n }\n\n this.#closeHandler = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n if (!path.includes(this) && !this.contains(e.target)) {\n this.close();\n }\n };\n\n setTimeout(() => {\n window.addEventListener('pointerdown', this.#closeHandler);\n }, 0);\n }\n\n close() {\n this.style.display = 'none';\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n this.#closeHandler = null;\n }\n }\n\n toggleItemState(menuId, className, condition) {\n const li = this.querySelector(`li[menu-id=\"${menuId}\"]`);\n if (li) {\n condition ? li.classList.add(className) : li.classList.remove(className);\n }\n }\n\n #appendItems(parentUl, items) {\n items.forEach(item => {\n if (item.type === 'separator') {\n const sep = document.createElement('li');\n sep.className = 'ng-menu-separator';\n parentUl.appendChild(sep);\n return;\n }\n\n const li = document.createElement('li');\n li.setAttribute('menu-id', item.menuId);\n li.className = `${item.className || ''} ${item.items ? 'submenu' : ''} ${item.disabled ? 'disabled' : ''}`.trim();\n\n const span = document.createElement('span');\n span.textContent = item.name;\n li.appendChild(span);\n\n if (item.items && item.items.length > 0) {\n const subUl = document.createElement('ul');\n subUl.className = 'ng-menu-sublist';\n this.#appendItems(subUl, item.items);\n li.appendChild(subUl);\n }\n\n parentUl.appendChild(li);\n });\n }\n\n #bindClickEvents() {\n this.querySelectorAll('li[menu-id]').forEach(li => {\n li.addEventListener('click', (e) => {\n e.stopPropagation();\n if (li.classList.contains('disabled')) return;\n\n const menuId = li.getAttribute('menu-id');\n this.#onCallback?.({ menuId, target: li });\n this.close();\n });\n });\n }\n\n disconnectedCallback() {\n this.close();\n }\n}\n\nif (!customElements.get('nine-table-menu-panel')) {\n customElements.define('nine-table-menu-panel', MenuPanel);\n}"],"names":["target","start","end","mid","elementDebounceState","dblClickEvent","dblClickFn","pointerEvent","pointerFn","debounceTime","el","state","e","_text","_font","stripHtml","__name","html","tmp","canvas","context","w","h","v","cleanText","metrics","ascent","descent","_Trace","traceOrigin","Trace","trace","NINE_TABLE","_ngRow","parent","__privateAdd","_parent","_newrow","__publicField","__privateGet","__privateSet","ngRow","_ngData","host","_host","_nextId","_defaultHeight","_getValidRecords","o","_a","at","colnm","validRecords","targetRecord","idx","rowIndex","colIndex","value","rowData","_conv","fields","_initialize","templateElements","_getDefaultMeta","_invalidate","$sheets","$el","dataSource","loadData","rowid","_json2Array","jsonArray","arr","json","_defaultInsert","updateState","row","_","a","b","rowidx","targetId","item","COL_IDX","oldValue","isSingle","targetArr","result","t","i","__privateWrapper","ngData","_ngDataManager","ds","nRow","rowIdx","_b","ngDataManager","_fields","type","fName","f","_adjust","map","name","_init","rawTables","tbl","fieldName","fieldType","attr","expr","lastIndex","targetField","found","_NineTableSheets","NineTableSheets","_NineTableSheetsFooter","_NineTableSheetsFooter_instances","__privateMethod","render_fn","isMultiSelect","tabItem","index","_switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","tab","isActive","clickedTab","activeTabs","targetSheet","tabsHtml","table","className","tabName","NineTableSheetsFooter","_SheetTabItem","SheetTabItem","_Toolbar","_Toolbar_instances","_customContainer","bindEvents_fn","element","text","titleEl","syncStateFromHost_fn","isSimple","showToolbar","showMenu","caption","link","currentCaption","menuBtn","Toolbar","_NineTableHScrollBar","_owner","_dragging","_elements","_interval1","_interval2","_resizeObserver","_observeResize","track","thumb","bodyWidth","tableWidth","needsHScroll","trackWidth","thumbWidth","currentLeft","maxScrollLeft","l","maxThumbLeft","_thumbMoveTo","x","trackBound","targetX","newScrollLeft","delayScroll","pos","thumbLeft","currentThumbLeft","clearTimer","evt","trackRect","onMouseMove","moveEvent","onMouseUp","initWhenReady","NineTableHScrollBar","_NineTableVScrollBar","_sheet","_startY","_startScrollTop","_startThumbTop","_getScaleInfo","viewRecords","totalCount","scrollHolder","rawContentHeight","rowHeight","MAX_BROWSER_HEIGHT","useScaling","scaleFactor","contentHeight","_getViewHeight","thead","_c","tfoot","_f","_e","_d","tbodyHead","_j","_i","_h","_g","fixedHeight","bodyHeight","needsVScroll","trackHeight","thumbHeight","currentScrollTop","maxScrollTop","thumbTop","maxThumbTop","deltaY","targetThumbTop","ratio","viewHeight","visibleRowCount","targetRow","clickY","currentTopRow","NineTableVScrollBar","GROUP_IDX","_GroupingManager","_groupColumns","_groupMap","_isApplying","groupColumns","sourceTable","$tr","$cell","groupId","rowIds","dataManager","GroupingManager","_Grouping","rawRecords","validRaw","groupMap","nestedTree","_Grouping_static","buildNestedMap_fn","flatResult","renderItems","flattenTree_fn","mapOrArray","depth","resultArr","parentId","counter","isLastLevel","groupKey","subMapOrRecords","collectLeafRowIds_fn","groupRecord","collectLeafRecords_fn","record","records","remainingCols","key","subRecords","subVal","r","Grouping","_RowManager","_BUFFER_ROW_COUNT","_element","_containerTemplates","_templateRowHeights","_cachedTemplateHeight","_sheetHeight","_cachedRowCount","_isProgrammaticScroll","_isGrouped","force","bodyViewport","_measureAndCacheHeight","_renderAllContainers","_handleScroll","scrollTop","_handleGroupedScroll","templateLength","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","renderOffsetTop","firstTr","currentStartIndex","$tbody","tbodyIdx","dataIndex","_bindRowData","allRenderItems","totalVirtualCount","bodyContent","getItemHeight","dataRowsHeight","groupHeightsTotal","itemHeights","viewportClientHeight","accumulatedHeight","offsetY","visibleRowsCount","dynamicBuffer","targetStart","targetEnd","renderedItems","selector","container","trs","itemIndex","chunkTrs","tr","subIdx","virtualIndex","isTrGroup","_bindGroupRowData","subRowIndex","matrixRow","indices","allRecords","childrenRecords","customComp","tableEl","tbody","templateTrs","trTemplates","fragment","renderedTrs","sum","_updateRowCount","visibleRows","groupDepth","_renderRows","_syncRowHeights","targetFixedType","clonedTr","targetTbody","tmpl","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","_initResizeObserver","entries","entry","height","dataRow","align","onRendered","targetScrollTop","rawTargetScrollTop","RowManager","COLLAPSED_WIDTH","_TableCompiler","$srcTable","$table","_TableCompiler_static","syncColAttributes_fn","cols","grid","rowSpan","colSpan","c","$col","fixed","TableCompiler","_CellSelection","_CellSelection_instances","_range","startRow","startCol","endRow","endCol","containers","getMatrixRow_fn","cell","col","cellEndRow","cellEndCol","$focusTd","initEvents_fn","$td","r1","r2","c1","c2","expanded","loopCount","nsR","neR","nsC","neC","sameGroupTrs","mainZone","lastMatrixRow","lastCol","targetEl","targetCell","allCells","rect","targetTr","CellSelection","_CellNavigation","_CellNavigation_instances","_currentCell","_currentTr","_currentRow","_currentCol","_getMinCol","cells","minCol","_getMaxCol","maxCol","_getMaxColCell","targetTrs","_getNextCol","td","next","_getPreviousCol","currentCol","currentTrCells","_findTargetTrsByMatrix","smallerCols","matchedTrs","mRow","getMatrixRowFromTr_fn","foundInSpan","_getNearElement","targetMatrixRow","searchedTrs","trDataRow","trSubIdx","span","cellDataRowStart","cellSubRowStart","cellStartMatrix","cellEndMatrix","nextMatrixRow","nextCol","prevTrs","maxColCell","maxMatrixRowLimit","maxMatrixRow","nextDataRow","nextSubRowIndex","retries","actualMatrixRow","ensureCellVisible_fn","retryCell","mRowAttr","bodyContainer","cellRect","viewportRect","containerRect","isAbove","isBelow","subrow","CellNavigation","RESIZE_OFFSET","_ColResizer","_ColResizer_instances","_panel","_tooltip","_targetColIndex","_nextColIndex","_targetContainerType","_targetCell","_startX","_startColWidth","_nextColStartWidth","_startCellWidth","_startLeft","_onPointerMove","headerPart","offsetX","isLeftEdge","isRightEdge","prevCell","_onPointerDown","getContainerType_fn","baseColIndex","checkIsAutoFit_fn","nextColEl","targetRect","sheetRect","targetColEl","attrW","updatePositions_fn","_onDragMove","_onDragEnd","diff","isAutoFit","finalWidth","newColWidth","newNextWidth","_onDblClick","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","val","size","calculatedWidth","containerType","firstColgroup","totalWidth","colWidths","colIdx","tables","globalColIndex","width","targetCols","firstContainer","resolvedContainerType","sourceCol","clientX","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","ColResizer","_ColMover","_ColMover_instances","_grip","_indi","_isDragging","_sourceCell","_sourceColIndex","_shiftX","_timer","checkIsMovable_fn","startX","startY","cancelTimer","onPointerMovePending","startDrag_fn","updateGripPosition_fn","targetElement","getDeepElementFromPoint_fn","targetColIndex","colMinLeft","colMaxRight","cCol","cSpan","cEnd","cRect","midX","calculatedTargetCol","indicatorLeft","sourceGroup","getColGroupRange_fn","movingSpan","sourceRowStart","sourceRowSpan","sourceRowEnd","targetRowStart","targetRowSpan","targetRowEnd","isRowSpanCompatible","isOutOfBoundsOfParent","pStart","pEnd","isDroppingInsideOtherGroup","spannedCells","sCell","sRowStart","sRowSpan","sRowEnd","sStart","sSpan","sEnd","moveEndCol","isSelfGroup","relativeTop","fullHeight","_onPointerUp","fromColIndex","toColIndex","colgroup","targetCol","spanCount","isInRange","targetViewportCol","fixedType","group","targetRowCell","y","root","nested","headerCells","hasStrictChildren","isValidGroup","parentGroupRange","subCell","subStart","subSpan","subEnd","isRealGroup","createGroupHeaderPreview_fn","groupRange","isGroup","origTable","minLeft","maxRight","minTop","maxBottom","targetCells","computedStyle","groupWidth","groupHeight","headerContent","style","clonedCell","preview","bounds","left","ColMover","_ColFixManager","baseCol","colEl","fixedAttr","targetBoundaryCol","theadTrs","cellBoundaryFound","cEndCol","action","fixType","cIdx","minBaseCol","rIdx","rSpan","trIndex","isBroken","correspondingCol","isColFixed","ColFixManager","_NineTableFilterPanel","_NineTableFilterPanel_instances","_nineTable","_view","_button","_renderer","_onInput","_onSelectAll","_onOk","_closeHandler","path","filterRecords","checkedRecords","chk","filterParams","colInfo","filterKey","selectedVals","btn","query","data2Idx","matchedValues","isChecked","chkIdx","_onCancel","filterBtn","panelWidth","top","searchBox","loadVirtualFilterItems_fn","filteredRecords","activeFilters","exprEngine","bindKey","exprKey","activeSelectedVals","uniqueMap","rawVal","displayVal","uniqueList","selectAllChk","NineTableFilterPanel","_NineTableFilterButton","_columns","isFiltered","_onClick","panel","seen","uniqueKey","NineTableFilterButton","_Filtering","_Filtering_instances","_isFiltering","_filterPanel","_filters","_initFilterPanel","applyFiltering_fn","oFilter","jsonFilter","k","sheetIndex","filterRules","targetKey","allowedValues","isExpr","recordIdx","isPass","allowedSet","Filtering","_Sorting","_Sorting_instances","syncHeaderUI_fn","handleSort_fn","colName","exprVal","isAsc","isDesc","existingColIndex","m","ruleData","applySorting_fn","colRule","asc","Sorting","_SheetView","_sortingColumns","_filterRules","_viewIndexes","_cachedVisibleRecords","visibleRecords","_convSingle","filterSlot","_applySorting","groupResult","columns","rulesWithIdx","rule","idxA","idxB","valA","valB","isEmptyA","isEmptyB","strA","strB","SheetView","_PreCompiler","_PreCompiler_static","ensureColgroup_fn","ensureThead_fn","ensureSectionTbodys_fn","ensureRowIndicator_fn","normalizeColAttributes_fn","createColIndicator_fn","normalizeCollapsibleAttributes_fn","generateCell_fn","initColExpanders_fn","initFilterButtons_fn","_k","applyInitialCellWidths_fn","tdTmpl","firstRow","cnt","numToExcelCol_fn","background","num","n","headTbody","footTbody","colCount","containerWidth","defaultWidth","widthVal","$tbl","targetAttributes","autoIdCounter","tagName","$datalist","$option","uniqueFuncName","innerAttrs","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","section","rows","indicatorCell","startColIdx","targetIdx","PreCompiler","_NineTableSheet","_NineTableSheet_instances","_index","_rowManager","_cellSelection","_cellNavigation","_colResizer","_colMover","_colFix","_sorting","_filtering","_grouping","_source","_adjustOverlay","$thead","$overlay","enable","_autoFit","totalOriginalWidth","colList","headerCell","collapsedTotalWidth","availableWidth","allocatedTotal","calculatedCols","exactWidth","baseWidth","remainderPixels","uncollapsedCols","finalSumWidth","_renderSplitContainers","_updateContainerWidths","_syncHeaderAndFooterHeights","_initRowHoverEvent","prefix","firstTable","_createSplitTable","scrollLeft","_render","isSimple_get","leftHeaderRows","bodyHeaderRows","rightHeaderRows","_applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","attrTrue","sourceTableTrue","NineTableSheet","_LayoutManager","owner","_applyAutoHeight","maxDisplayRows","maxRowHeight","toolbarEl","footerEl","toolbarHeight","footerHeight","calculatedHeight","isAutoHeight","sheetCount","sheetsHtml","sheetId","sheetTag","splitterTag","cssFiles","npmCssImports","customCssImports","file","LayoutManager","_ExprEngine","_exprCache","match","rowItem","trimmedExpr","compiledExpr","evalFn","ExprEngine","_NineTable","_NineTable_instances","_shadowRoot","_dataManager","_layoutManager","_templateCnt","_dispatchLoad","checkCount","maxChecks","checkTimer","loadSheetCnt","$sheet","idOrIndex","fn","bindDynamicSetters_fn","extractedMethodNames","matches","methodName","internalValue","newValue","NineTable","_BasicCellElement","BasicCellElement","exprCache","_CellElement","_tr","_cell","_attr","defaultValue","rawRecord","cleanExpr","childRecords","funcName","field","acc","button","curRow","renderer","prop","updateRowState","data","CellElement","_EditableCellElement","EditableCellElement","_CellInputText","_target","_initEvent","maxbyte","maxByteNum","event","CellInputText","_CellInputNumber","_validateInput","strVal","dotIdx","_onKeyDown","selectionStart","scale","validKey","isNumKey","CellInputNumber","_CellInputColor","_btn","_isValidColor","g","CellInputColor","_CellInputDate","_type","formattedVal","d","min","max","isValid","_isValidDate","year","month","day","isleap","hour","week","CellInputDate","_CellCheckbox","_label","_isRadio","_trueText","_falseText","newVal","trueValue","childHtml","displayText","CellCheckbox","_CellRadio","_dataSource","_keyName","_valueName","matchIndex","targets","_rendererRadio","codeVal","nameVal","label","input","CellRadio","_CellComboPanel","_isOpen","_initData","keyName","valueName","multi","separator","grd","itemsAttr","fieldKeys","activeColumnCount","formattedData","selectedKeys","btnEl","btnRect","panelHeight","upwardTop","viewContainer","_onClickRow","keyword","_initEvents","CellComboPanel","_CellCombo","_targetBtn","_multi","_multiSeparator","_togglePanel","_getDisplayText","keys","list","CellCombo","_CellRenderer","CellRenderer","_CellButton","_cellButtonClick","customEvent","rawValue","buttonText","CellButton","_CellRowIndicator","_mainTarget","_subTarget","_statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","CellRowIndicator","_ColExpand","singleWidth","isInitialInit","currentW","splitWidth","ColExpand","_ContextMenu","_ContextMenu_instances","_tableHost","_onContextMenu","targetTable","targetParent","isHeaderCell","menuItems","buildMenuItems_fn","handleMenuClick_fn","getTargetSheet_fn","syncMenuStates_fn","getFixManager_fn","parseCustomMenuItems_fn","containerElement","activeTable","items","activeTableId","rootUl","targetTableAttr","parsedList","traverseUl_fn","ulEl","child","spanEl","subUl","useDefault","rawItems","customItems","fixManager","currentFixState","isFixable","fixMenuItem","cleanedItems","isFiltering","autoFit","showTitle","menuId","ContextMenu","_MenuPanel","_MenuPanel_instances","_onCallback","callback","appendItems_fn","bindClickEvents_fn","cellRightX","wrapper","calculatedLeft","calculatedTop","condition","li","parentUl","sep","MenuPanel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nine-table.umd.js","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/ui/layout/nine-table-sheets.js","../src/ui/layout/nine-table-sheets-footer.js","../src/ui/layout/nine-table-toolbar.js","../src/ui/layout/nine-table-hscrollbar.js","../src/ui/layout/nine-table-vscrollbar.js","../src/data/Grouping.js","../src/ui/layout/core/RowManager.js","../src/ui/layout/core/TableCompiler.js","../src/ui/cell-manager/CellSelection.js","../src/ui/cell-manager/CellNavigation.js","../src/ui/col/ColResizer.js","../src/ui/col/ColMover.js","../src/ui/col/ColFixManager.js","../src/data/Filtering.js","../src/data/Sorting.js","../src/data/SheetView.js","../src/ui/layout/core/PreCompiler.js","../src/ui/layout/nine-table-sheet.js","../src/ui/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/core/nine-table.js","../src/ui/cell/core/BasicCellElement.js","../src/ui/cell/core/CellElement.js","../src/ui/cell/cell-input-text.js","../src/ui/cell/cell-input-number.js","../src/ui/cell/cell-input-color.js","../src/ui/cell/cell-input-date.js","../src/ui/cell/cell-checkbox.js","../src/ui/cell/cell-radio.js","../src/ui/cell/cell-combo-panel.js","../src/ui/cell/cell-combo.js","../src/ui/cell/cell-renderer.js","../src/ui/cell/cell-button.js","../src/ui/cell/cell-row-indicator.js","../src/ui/col/col-expand.js","../src/ui/menu/nine-table-menu.js","../src/ui/menu/nine-table-menu-panel.js"],"sourcesContent":["Array.prototype.nineBinarySearch = function(target) {\n //this.sort((a, b) => { return a > b ? 1 : -1; });\n\n let start = 0;\n let end = this.length - 1;\n let mid;\n\n while (start <= end) {\n mid = parseInt((start + end) / 2);\n\n if (target === this[mid]) {\n return mid;\n } else {\n if (target < this[mid]) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n }\n\n return -1;\n};\n\n// 엘리먼트별 디바운스/취소 상태를 격리하기 위한 WeakMap\nconst elementDebounceState = new WeakMap();\n\nHTMLElement.prototype.addDebounseEventListener = function(\n dblClickEvent,\n dblClickFn,\n pointerEvent,\n pointerFn,\n debounceTime = 500\n) {\n const el = this;\n\n if (!elementDebounceState.has(el)) {\n elementDebounceState.set(el, { timer: null, cancelFn: null });\n }\n const state = elementDebounceState.get(el);\n\n // 1. 포인터(다운) 이벤트: 즉시 실행하지 않고 debounceTime 동안 지연시킴\n el.addEventListener(pointerEvent, (e) => {\n e.actualTarget = e.target;\n\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n\n // 💡 500ms 동안 대기한 뒤에야 실제 pointerFn이 실행됨\n state.timer = setTimeout(() => {\n state.timer = null;\n state.cancelFn = pointerFn.call(el, e);\n }, debounceTime);\n });\n\n // 2. 더블클릭 이벤트: 대기 시간 내에 들어오면 예약되어 있던 pointerdown 자체를 원천 차단\n el.addEventListener(dblClickEvent, (e) => {\n //trace.log(e);\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null; // 💡 pointerdown 실행 예약이 아예 취소됨!\n }\n\n // 혹시 이미 실행되어 버린 경우의 안전장치 롤백\n if (state.cancelFn) {\n state.cancelFn();\n state.cancelFn = null;\n }\n\n dblClickFn.call(el, e);\n });\n};\n\n\nnine.measureTextSize = (_text, _font = '12px sans-serif') => {\n if (typeof _text === 'number') _text = _text + \"\";\n if (!_text) return { width: null, height: null };\n\n // 🎯 브라우저 DOM 파싱을 이용한 완벽한 HTML 태그 제거 함수\n const stripHtml = (html) => {\n const tmp = document.createElement(\"DIV\");\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || \"\";\n };\n\n // 줄바꿈 처리 전 HTML 정제 또는 줄바꿈 단위별 정제\n _text = _text.replaceAll(\"\\n\", \"<br>\");\n\n // 🎯 공용 숨김 캔버스를 querySelector로 찾거나 없으면 생성\n let canvas = document.body.querySelector('canvas#_nine_measure_canvas_');\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.id = '_nine_measure_canvas_';\n canvas.style.cssText = 'position: absolute; visibility: hidden; pointer-events: none; left: -9999px;';\n document.body.appendChild(canvas);\n }\n\n const context = canvas.getContext('2d');\n context.font = _font;\n\n let w = 0;\n let h = 0;\n\n for (let v of _text.split(\"<br>\")) {\n // 브라우저 파서로 HTML 태그를 완전히 제거한 순수 텍스트 획득\n const cleanText = stripHtml(v);\n const metrics = context.measureText(cleanText);\n\n //trace.log(cleanText);\n\n w = Math.max(w, metrics.width);\n\n const ascent = metrics.fontBoundingBoxAscent || 10;\n const descent = metrics.fontBoundingBoxDescent || 3;\n h += ascent + descent;\n }\n\n return {\n width: w,\n height: h\n };\n};","import { trace as traceOrigin } from '@ninebone/util';\n\n/**\n// 1. 내부 프라이빗 필드 문제를 피하기 위해 래퍼 객체 생성\nexport const trace = {\n init(prefix, color) {\n // 필요하다면 여기서 초기화 로직 수행 가능\n if (traceOrigin.init) {\n try { traceOrigin.init(prefix, color); } catch (e) {}\n }\n },\n log(...args) {\n return traceOrigin.log(...args);\n },\n warn(...args) {\n return traceOrigin.warn(...args);\n },\n error(...args) {\n return traceOrigin.error(...args);\n }\n};\n\n// 2. 모듈 로드 시점에 네임스페이스 초기화 시도\ntry {\n traceOrigin.init(\"nine-table\", \"green\");\n} catch (e) {}\n*/\n\n\nexport class Trace extends traceOrigin.constructor {\n constructor() {\n super();\n this.init(\"nine-table\", \"green\");\n }\n}\n\nexport const trace = new Trace();\n\n\n//trace.init(\"nine-table\", \"green\");","export const NINE_TABLE = {\n META: {\n INDEX: {\n ROWID: 0,\n FILTER: 1, // 멀티뷰 필터 통과 여부 (true/false)\n GROUP: 2,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 'EMPTY',\n NORMAL: 'NORMAL',\n INSERT: 'INSERT',\n UPDATE: 'UPDATE',\n DELETE: 'DELETE'\n },\n EVENT: {\n LOAD: \"load\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\n\r\nexport class ngRow {\r\n\t#parent;\r\n\t#newrow = -1;\r\n\r\n\tconstructor(parent) {\r\n\t\tthis.#parent = parent;\r\n\t}\r\n\r\n\tget at() {\r\n\t\treturn this.#newrow;\r\n\t}\r\n\tset at(v) {\r\n\t\tthis.#newrow = parseInt(v, 10);\r\n\t}\r\n\r\n\tcount = () => this.#parent.rawRecords.length;\r\n}\r\n\r\nexport class ngData {\r\n\t#host;\r\n\t#parent;\r\n\t#nextId = 0;\r\n\t#defaultHeight = [];\r\n\r\n\tstatic META_INDEX = {\r\n\t\tFILTER: 0, // 멀티뷰 필터 통과 여부 (true/false)\r\n\t\t// ── 추후 확장 예시 ──\r\n\t\t// GROUP: 1,\r\n\t\t// SELECT: 2,\r\n\t\t// EXPAND: 3\r\n\t};\r\n\r\n\t// 🎯 행 상태 정의 상수 내재화\r\n\tstatic ROW_STATE = {\r\n\t\tEMPTY: 'EMPTY',\r\n\t\tNORMAL: 'NORMAL',\r\n\t\tINSERT: 'INSERT',\r\n\t\tUPDATE: 'UPDATE',\r\n\t\tDELETE: 'DELETE'\r\n\t};\r\n\r\n\tconstructor(host, parent) {\r\n\t\tthis.#host = host;\r\n\t\tthis.#parent = parent;\r\n\t\tthis.#initialize();\r\n\t}\r\n\r\n\r\n\r\n\t/**\r\n\t * 🎯 [내부 공통] 삭제되지 않은 유효 레코드 목록 반환 (중복 제거 및 캡슐화)\r\n\t */\r\n\t#getValidRecords = () => {\r\n\t\tconst rawRecords = this.#parent.rawRecords || [];\r\n\t\treturn rawRecords.filter(o => !o.__ng?.deleted);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 행 개수 반환 (속성 및 메서드 형태 모두 지원)\r\n\t */\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tcount = () => {\r\n\t\treturn this.length;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [내부 엔진/고성능용] 변환 오버헤드 없이 순수 데이터(v 배열 등) 그대로 반환\r\n\t * - data.getArray() : 유효한 전체 내부 레코드 배열 반환\r\n\t * - data.getArray(at) : 특정 행의 내부 레코드 객체({ v: [...] }) 반환\r\n\t * - data.getArray(at, colnm) : 특정 행의 특정 컬럼 원시 값 반환\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn validRecords; // 변환 없이 배열 그대로 반환 (렌더링 최적화)\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord; // { v: [...], __ng: {...} } 원본 형태 반환\r\n\t};\r\n\r\n\tsetArray = (rowIndex, colIndex, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\r\n\t\tconst oldValue = rowData.v[colIndex];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\t// 변경 전 값 보존 우선 주석처리\r\n\t\t\t//rowData.o[colIndex] = value;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[colIndex] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\r\n\t/**\r\n\t * 🎯 [외부 개발자/비즈니스 로직용] 개발자가 활용하기 편한 JSON 객체 형태로 변환하여 반환\r\n\t * - data.get() : 전체 유효 데이터를 JSON 객체 배열로 변환\r\n\t * - data.get(at) : 특정 행을 JSON 객체로 변환\r\n\t * - data.get(at, colnm) : 특정 컬럼 값 반환\r\n\t */\r\n\tget = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn this.#conv(validRecords);\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#conv(targetRecord);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [저장/서버 전송용] 삭제된 행을 포함한 전체 원본 배열 반환\r\n\t */\r\n\tgetAll = () => {\r\n\t\treturn this.#parent.rawRecords || [];\r\n\t};\r\n\r\n\tgetHostFields = () => {\r\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\r\n\t};\r\n\r\n\t#initialize = () => {\r\n\t\tthis.#defaultHeight = [];\r\n\t\tconst templateElements = this.#host.template || [];\r\n\t\tArray.from(templateElements).forEach(el => {\r\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\r\n\t\t});\r\n\r\n\t\t(this.#parent.rawRecords || []).forEach(v => {\r\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\r\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\r\n\t\t});\r\n\t};\r\n\r\n\tget source() {\r\n\t\treturn this.#conv(this.#parent.rawRecords);\r\n\t}\r\n\tset source(v) {\r\n\t\tthis.set(v);\r\n\t\t//this.clear();\r\n\t\t//this.add(v, false);\r\n\t}\r\n\r\n\t#invalidate = () => {\r\n\t\tconst $sheets = this.#host.shadowRoot.querySelector(\"nine-table-sheets\");\r\n\t\t$sheets?.classList.toggle(\"nodata\", this.length === 0);\r\n\r\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\r\n\t\t\t$el.invalidate();\r\n\t\t});\r\n\r\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\r\n\t};\r\n\r\n\tset = (dataSource) => {\r\n\r\n\t\tconst loadData = () => {\r\n\t\t\tthis.clear();\r\n\t\t\tthis.add(dataSource, false);\r\n\t\t\tthis.#invalidate();\r\n\t\t}\r\n\r\n\t\tif (this.#host.loaded) {\r\n\t\t\tloadData();\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\r\n\t\t\t\tloadData();\r\n\t\t\t}, { once: true });\r\n\t\t}\r\n\t};\r\n\r\n\tget nextId() {\r\n\t\treturn this.#nextId++;\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.#getValidRecords().length;\r\n\t}\r\n\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tgetRowCount() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\t#getDefaultMeta = (rowid = 0) => {\r\n\t\treturn {\r\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\r\n\t\t\tdeleted: false,\r\n\t\t\tfiltered: false,\r\n\t\t\theight: this.#defaultHeight.slice(),\r\n\t\t\to: {},\r\n\t\t\tc: {},\r\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\r\n\t\t\t_: [rowid, [], ],\r\n\t\t};\r\n\t};\r\n\r\n\treset = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tclear = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tif (this.#parent.viewRecords?.reset) {\r\n\t\t\tthis.#parent.viewRecords.reset();\r\n\t\t}\r\n\r\n\t\tthis.#nextId = 0;\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\t#json2Array = (jsonArray) => {\r\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\r\n\r\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\r\n\t\tconst arr = [];\r\n\r\n\t\tjsonArray.forEach(json => {\r\n\t\t\tconst o = { v: [] };\r\n\t\t\tfields.forEach(colnm => {\r\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\r\n\t\t\t});\r\n\t\t\tarr.push(o);\r\n\t\t});\r\n\r\n\t\treturn arr;\r\n\t};\r\n\r\n\t#defaultInsert = (arr) => {\r\n\t\tif (!Array.isArray(arr)) arr = [arr];\r\n\t\tarr.forEach(o => {\r\n\t\t\tconst rowid = this.nextId;\r\n\r\n\t\t\to.m = this.#getDefaultMeta(rowid);\r\n\t\t\to.__ng = o.m;\r\n\t\t\to.__ng.rowid = rowid;\r\n\t\t\to.__ng.rowState = ngData.ROW_STATE.INSERT;\r\n\t\t\to.__ng._[0] = rowid;\r\n\t\t});\r\n\t\treturn arr;\r\n\t};\r\n\r\n\tadd = (dataSource, updateState = true) => {\r\n\t\tif (dataSource === undefined) dataSource = {};\r\n\t\tconst arr = this.#json2Array(dataSource);\r\n\r\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(this.#defaultInsert(arr));\r\n\r\n\t\tconst row = this.count() - 1;\r\n\t\tif (!updateState) {\r\n\t\t\tarr.forEach((_, idx) => {\r\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\r\n\t\t\t\tif (target) target.__ng.rowState = ngData.ROW_STATE.EMPTY;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#invalidate();\r\n\t\treturn row;\r\n\t};\r\n\r\n\tdelete = (at) => {\r\n\t\tlet arr = [];\r\n\t\tif (Array.isArray(at)) {\r\n\t\t\tarr = at;\r\n\t\t} else if (typeof at === \"undefined\") {\r\n\t\t\tarr = [this.#parent.host.row.at];\r\n\t\t} else {\r\n\t\t\tarr = [parseInt(at, 10)];\r\n\t\t}\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tarr.sort((a, b) => b - a).forEach(rowidx => {\r\n\t\t\tif (validRecords[rowidx]) {\r\n\t\t\t\tconst targetId = validRecords[rowidx].__ng.rowid;\r\n\t\t\t\tif (validRecords[rowidx].__ng.rowState === ngData.ROW_STATE.INSERT) {\r\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.__ng.rowid !== targetId);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\r\n\t\t\t\t\t\tif (item.__ng.rowid === targetId) {\r\n\t\t\t\t\t\t\titem.__ng.deleted = true;\r\n\t\t\t\t\t\t\titem.__ng.rowState = ngData.ROW_STATE.DELETE;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tsetValue = (rowIndex, colnm, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\trowIndex = parseInt(rowIndex, 10);\r\n\t\tconst fields = this.getHostFields();\r\n\t\tconst COL_IDX = fields.indexOf(colnm);\r\n\t\tif (COL_IDX < 0) return;\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\t\tif (!rowData) return;\r\n\r\n\r\n\r\n\t\tconst oldValue = rowData.v[COL_IDX];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\tif (!rowData.__ng.o.hasOwnProperty(colnm)) rowData.__ng.o[colnm] = oldValue;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[COL_IDX] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\t#conv = (arr) => {\r\n\t\tif (!arr) return arr;\r\n\r\n\t\tconst isSingle = !Array.isArray(arr);\r\n\t\tconst targetArr = isSingle ? [arr] : arr;\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\r\n\t\t\tconst t = {};\r\n\t\t\tfields.forEach((colnm, i) => {\r\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t\t});\r\n\t\t\tt.__ng = o.__ng;\r\n\t\t\treturn t;\r\n\t\t});\r\n\r\n\t\treturn isSingle ? result[0] : result;\r\n\t};\r\n}\r\n","import { ngRow, ngData } from \"./ngData.js\";\r\n\r\nexport class ngDataManager {\r\n\t#host;\r\n\r\n\tconstructor(host) {\r\n\t\tthis.#host = host;\r\n\r\n\t\tthis.row = new ngRow(this);\r\n\t\tthis.data = new ngData(this.#host, this);\r\n\r\n\t\tthis.rawRecords = [];\r\n\t\tthis.viewRecords = [];\r\n\t\tthis.delRecords = [];\r\n\t\tthis.pageCnt = 25;\r\n\r\n\t\tthis.viewRecords.reset = () => {\r\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\r\n\t\t};\r\n\r\n\t\tthis.setDataSource = (ds) => {\r\n\t\t\tif (this.data) this.data.reset();\r\n\r\n\t\t\tthis.rawRecords = [];\r\n\t\t\tthis.viewRecords = [];\r\n\t\t\tthis.delRecords = [];\r\n\r\n\t\t\tthis.data.set(ds || []);\r\n\t\t};\r\n\r\n\t\tthis.getRowState = (nRow) => {\r\n\t\t\tconst rowIdx = parseInt(nRow, 10);\r\n\t\t\tif (rowIdx >= this.data.count()) return;\r\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\r\n\t\t};\r\n\r\n\t\tthis.getRowPosition = () => this.row.at;\r\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\r\n\r\n\t\tthis.scrollTo_V1 = (nRow) => {\r\n\t\t\tif (nRow < 0) nRow = 0;\r\n\t\t\tif (nRow >= this.rawRecords.length) nRow = this.rawRecords.length - 1;\r\n\r\n\t\t\tthis.viewRecords.rawIndex = nRow;\r\n\t\t\tif (this.viewRecords.reset) this.viewRecords.reset();\r\n\r\n\t\t\treturn (nRow <= 0 || nRow >= this.rawRecords.length - 1) ? false : true;\r\n\t\t};\r\n\r\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\r\n\r\n\t\tthis.setColumn = (rowidx, colnm, v) => {\r\n\t\t\trowidx = parseInt(rowidx, 10);\r\n\t\t\tthis.data.setValue(rowidx, colnm, v);\r\n\t\t};\r\n\r\n\t\t// 초기 빈 데이터 바인딩\r\n\t\tthis.setDataSource([]);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\n\nexport class fields {\n\t#host;\n\t#fields = []; // 🎯 이제 { name: string, type: string } 객체들의 배열로 관리합니다.\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\t\tthis.#init();\n\t};\n\n\t// 🎯 기존에 필드 이름만 쓰던 곳들과의 호환을 위해 이름 배열만 리턴하는 메서드 유지\n\tget() {\n\t\treturn this.#fields.map(f => f.name);\n\t};\n\n\t// 🎯 내부 객체 통째로 얻기\n\tgetFields() {\n\t\treturn this.#fields;\n\t}\n\n\t// 🎯 특정 필드의 데이터 타입 조회\n\tgetType(fieldName) {\n\t\tconst found = this.#fields.find(f => f.name === fieldName);\n\t\treturn found ? found.type : 'string';\n\t}\n\n\tadd = (arr, type = 'string') => {\n\t\tarr.forEach(fName => {\n\t\t\tif (!this.#fields.some(f => f.name === fName)) {\n\t\t\t\tthis.#fields.push({ name: fName, type: type });\n\t\t\t}\n\t\t});\n\t\tthis.#adjust();\n\t};\n\n\tindexOf(v) {\n\t\treturn this.#fields.findIndex(f => f.name === v);\n\t};\n\n\tincludes(v) {\n\t\treturn this.#fields.some(f => f.name === v);\n\t};\n\n\t#adjust = () => {\n\t\t// 🎯 이름 기준으로 중복 제거 (Map을 활용하여 마지막에 들어온 타입 유지)\n\t\tconst map = new Map();\n\t\tthis.#fields.forEach(f => {\n\t\t\tmap.set(f.name, f.type);\n\t\t});\n\n\t\tthis.#fields = Array.from(map, ([name, type]) => ({ name, type }));\n\n\t\t// 🎯 빈 문자열이나 __ng 필터링\n\t\tthis.#fields = this.#fields.filter(f => f.name !== \"\" && f.name !== \"__ng\");\n\n\t\t// 🎯 긴 이름순 정렬\n\t\tthis.#fields.sort((a, b) => { return (a.name.length < b.name.length) ? 1 : -1; });\n\t};\n\n\t#init = () => {\n\t\tthis.#fields = [];\n\n\t\ttrace.log(this.#host.querySelectorAll(\"table\"));\n\n\t\tconst rawTables = Array.from(this.#host.querySelectorAll(\"table\"));\n\n\t\tif (!rawTables || rawTables.length === 0) return;\n\n\t\tfor (const tbl of rawTables) {\n\t\t\ttrace.log(tbl);\n\n\t\t\t// 1. [data-bind] 속성 탐색 및 타입 수집\n\t\t\ttbl.querySelectorAll('[data-bind]').forEach((el) => {\n\t\t\t\tconst fieldName = el.dataset.bind;\n\t\t\t\tconst fieldType = el.getAttribute(\"data-type\") || 'string';\n\n\t\t\t\tif (fieldName) {\n\t\t\t\t\tthis.#fields.push({ name: fieldName, type: fieldType });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// 2. 표현식 속성들 탐색 (순수 자바스크립트로 변환)\n\t\t\tconst exprAttrs = [\n\t\t\t\t\"data-expr\", \"background-color\", \"color\", \"tooltip\",\n\t\t\t\t\"visible\", \"readonly\", \"enable-button\", \"enable-check\",\n\t\t\t\t\"class-expr\", \"icon-color\", \"icon-src\"\n\t\t\t];\n\n\t\t\texprAttrs.forEach(attr => {\n\t\t\t\t// 💡 jQuery의 $([attr], tbl).each(...)를 순수 querySelectorAll로 대체\n\t\t\t\ttbl.querySelectorAll(`[${attr}]`).forEach((el) => {\n\t\t\t\t\tlet expr = el.getAttribute(attr);\n\t\t\t\t\tif (!expr) return;\n\n\t\t\t\t\tif (expr.indexOf(\"data.\") < 0) {\n\t\t\t\t\t\tconst lastIndex = expr.search(/[(]/g);\n\n\t\t\t\t\t\tif (lastIndex > 0) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\texpr = String(window[expr.substring(0, lastIndex).trim()]);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\texpr = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\texpr.split(\"data.\").forEach(v => {\n\t\t\t\t\t\tif (v.trim() != \"\") {\n\t\t\t\t\t\t\tconst lastIndex = v.search(/[^_A-Za-z0-9]/g);\n\t\t\t\t\t\t\tlet targetField = '';\n\n\t\t\t\t\t\t\tif (lastIndex >= 0) {\n\t\t\t\t\t\t\t\ttargetField = v.substring(0, lastIndex);\n\t\t\t\t\t\t\t} else if (expr.startsWith(\"data.\")) {\n\t\t\t\t\t\t\t\ttargetField = v.replace(\"data.\", \"\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (targetField) {\n\t\t\t\t\t\t\t\tthis.#fields.push({ name: targetField, type: 'string' });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tthis.#adjust();\n\t};\n};","export class NineTableSheets extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n #init = () => {\n\n };\n\n}\n\nif (!customElements.get('nine-table-sheets')) {\n customElements.define('nine-table-sheets', NineTableSheets);\n}","export class NineTableSheetsFooter extends HTMLElement {\n #host;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n refresh = () => {\n this.querySelector(\"#row-count\").innerHTML = this.#host.data.count().toLocaleString();\n };\n\n #init = () => {\n this.#host = this.getRootNode().host;\n\n this.#render();\n\n this.querySelector('.nine-tab-bar')?.addEventListener('click', (e) => {\n const isMultiSelect = e.ctrlKey || e.metaKey || e.shiftKey;\n const tabItem = e.target.closest('nt-sheets-tab-item');\n\n if (!tabItem) return;\n\n const index = parseInt(tabItem.dataset.index, 10);\n this.#switchSheet(index, isMultiSelect);\n });\n\n this.#switchSheet(0, false);\n };\n\n #switchSheet = (index, isMultiSelect = false) => {\n\n const updateSplitters = () => {\n const sheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet'));\n const splitters = Array.from(this.#host.shadowRoot.querySelectorAll('nine-splitter'));\n\n // 1. 모든 스플리터 일단 숨김 처리\n splitters.forEach(s => s.style.setProperty('display', 'none'));\n\n // 2. 현재 active 상태인 시트들을 인덱스 오름차순으로 정렬\n const activeSheets = sheets\n .map((sheet, idx) => ({ sheet, idx }))\n .filter(({ sheet }) => sheet.classList.contains('active'));\n\n if (activeSheets.length < 2) return;\n\n // 3. 인접한 활성화 시트 쌍 사이에 정확히 하나의 스플리터만 노출\n for (let i = 0; i < activeSheets.length - 1; i++) {\n const currentIdx = activeSheets[i].idx;\n\n const targetSplitter = this.#host.shadowRoot.querySelector(`nine-splitter[data-split-index=\"${currentIdx}\"]`);\n if (targetSplitter) {\n targetSplitter.style.setProperty('display', '');\n }\n }\n };\n\n const tabBar = this.querySelector('.nine-tab-bar');\n const body = this.#host.shadowRoot.querySelector('nine-table-sheets-body');\n const tabItems = tabBar.querySelectorAll('nt-sheets-tab-item');\n const sheetElements = body.querySelectorAll('nine-table-sheet');\n\n if (!tabItems[index]) return;\n\n if (!isMultiSelect) {\n tabItems.forEach((tab, idx) => {\n tab.setActive(idx === index);\n });\n\n sheetElements.forEach((sheet, idx) => {\n const isActive = idx === index;\n sheet.classList.toggle('active', isActive);\n sheet.style.flex = isActive ? '1 1 100%' : '';\n });\n } else {\n const clickedTab = tabItems[index];\n const activeTabs = tabBar.querySelectorAll('nt-sheets-tab-item.active');\n\n if (clickedTab.classList.contains('active') && activeTabs.length <= 1) {\n return;\n }\n\n clickedTab.classList.toggle('active');\n const targetSheet = body.querySelector(`nine-table-sheet[data-index=\"${index}\"]`);\n if (targetSheet) {\n targetSheet.classList.toggle('active');\n if (!targetSheet.classList.contains('active')) {\n targetSheet.style.flex = '';\n }\n }\n }\n\n const activeSheets = body.querySelectorAll('nine-table-sheet.active');\n\n activeSheets?.forEach(sheet => {\n sheet.style.flex = (activeSheets.length > 1) ? '1 1 0%' : '1 1 100%';\n\n if (typeof sheet.refreshLayout === 'function') {\n sheet.refreshLayout();\n } else {\n sheet.invalidate?.();\n }\n });\n\n updateSplitters();\n };\n\n #render() {\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE'));\n\n const tabsHtml = rawTables.map((table, idx) => {\n const className = idx === 0 ? 'active' : '';\n const tabName = table.getAttribute('caption') || `Sheet ${idx + 1}`;\n\n return `<nt-sheets-tab-item class=\"${className}\" data-index=\"${idx}\">${tabName}</nt-sheets-tab-item>`;\n }).join('');\n\n this.innerHTML = `\n <div class=\"nine-tab-bar\">${tabsHtml}</div>\n <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n `;\n };\n}\n\nexport class SheetTabItem extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n }\n\n setActive(isActive) {\n this.classList.toggle('active', isActive);\n }\n}\n\nif (!customElements.get('nt-sheets-tab-item')) {\n customElements.define('nt-sheets-tab-item', SheetTabItem);\n}\n\nif (!customElements.get('nine-table-sheets-footer')) {\n customElements.define('nine-table-sheets-footer', NineTableSheetsFooter);\n}","import { trace } from \"@nopeer\";\n\nexport class Toolbar extends HTMLElement {\n #host;\n #customContainer;\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#render();\n this.#bindEvents();\n }\n\n #render() {\n this.innerHTML = `\n <div class=\"ng-toolbar-left\">\n <button type=\"button\" class=\"ng-toolbar-menu-btn\" title=\"Menu\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#374151\" stroke-width=\"2\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n </svg>\n </button>\n <span class=\"ng-toolbar-title\"></span>\n </div>\n\n <div class=\"ng-toolbar-custom\" id=\"custom-container\"></div>\n `;\n\n this.#customContainer = this.querySelector('#custom-container');\n this.#syncStateFromHost();\n }\n\n #syncStateFromHost() {\n const isSimple = this.#host.getAttribute('theme') === 'simple' || this.#host.classList.contains('simple');\n const showToolbar = this.#host.getAttribute('show-toolbar') !== 'false';\n const showMenu = this.#host.getAttribute('show-menu') !== 'false';\n const caption = this.#host.getAttribute('caption') || '';\n\n if (isSimple || !showToolbar) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n\n this.setAttribute('show-menu', showMenu ? 'true' : 'false');\n this.updateCaption(caption);\n }\n\n #bindEvents() {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) {\n titleEl.addEventListener('dblclick', () => {\n const link = '<font color=\"green\">https://www.ninegrid.net</font>';\n const currentCaption = this.#host.getAttribute('caption') || '';\n titleEl.innerHTML = titleEl.innerHTML === link ? currentCaption : link;\n });\n }\n\n const menuBtn = this.querySelector('.ng-toolbar-menu-btn');\n if (menuBtn) {\n menuBtn.addEventListener('click', () => {\n this.#host.dispatchEvent(new CustomEvent('toolbar-menu-click', {\n bubbles: true,\n composed: true,\n detail: { targetTable: this.#host }\n }));\n });\n }\n }\n\n addCustomElement(element) {\n if (this.#customContainer) {\n this.#customContainer.append(element);\n }\n }\n\n updateCaption(text) {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) titleEl.textContent = text;\n }\n}\n\nif (!customElements.get('nine-table-toolbar')) {\n customElements.define('nine-table-toolbar', Toolbar);\n}","// ui/nine-table-hscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableHScrollBar extends HTMLElement {\n #owner;\n #dragging = false;\n #elements;\n #interval1;\n #interval2;\n #resizeObserver;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#owner = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n if (!this.#owner) return;\n\n this.innerHTML = `\n <style>\n nine-table-hscrollbar {\n display: flex;\n flex-direction: row;\n width: 100%;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-hscrollbar button {\n width: 16px;\n height: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-hscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-hscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-hscrollbar .ng-scroll-left .ng-scroll-icon { transform: rotate(-135deg); }\n nine-table-hscrollbar .ng-scroll-right .ng-scroll-icon { transform: rotate(45deg); }\n nine-table-hscrollbar .ng-scroll-track {\n flex: 1;\n height: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-hscrollbar .ng-scroll-thumb {\n position: absolute;\n top: 2px;\n bottom: 2px;\n left: 0px;\n width: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-hscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-left' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-right' disabled><div class='ng-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(\".ng-scroll-track\"),\n thumb : this.querySelector(\".ng-scroll-thumb\"),\n left : this.querySelector(\".ng-scroll-left\"),\n right : this.querySelector(\".ng-scroll-right\"),\n };\n\n this.#init();\n this.#observeResize();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n disconnectedCallback() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n }\n\n #observeResize = () => {\n if (!this.#owner) return;\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) return;\n\n this.#resizeObserver = new ResizeObserver(() => {\n this.refresh();\n });\n this.#resizeObserver.observe(body);\n };\n\n refresh = () => {\n\n if (!this.#owner || !this.#elements || this.#dragging) return;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return;\n\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n\n //trace.log(bodyWidth, tableWidth, bodyWidth);\n\n // 🎯 [순수 클래스 연동] 인라인 스타일 조작 없이 오직 클래스 토글만 수행\n const needsHScroll = (bodyWidth !== 0 && tableWidth > bodyWidth);\n this.#owner.classList.toggle('hscroll-visible', needsHScroll);\n\n if (!needsHScroll) {\n return;\n }\n\n const trackWidth = track.clientWidth;\n if (trackWidth <= 0) return;\n\n const thumbWidth = Math.max(Math.min(trackWidth * (bodyWidth / tableWidth), trackWidth), 20);\n thumb.style.width = `${thumbWidth}px`;\n\n const currentLeft = body.scrollLeft;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n let l = 0;\n if (maxScrollLeft > 0) {\n l = parseInt((currentLeft / maxScrollLeft) * (trackWidth - thumbWidth), 10);\n }\n if (l < 0) l = 0;\n\n const maxThumbLeft = trackWidth - thumbWidth;\n if (l > maxThumbLeft) l = maxThumbLeft;\n\n thumb.style.left = `${l}px`;\n\n this.#elements.left.disabled = (l === 0);\n this.#elements.right.disabled = (l >= maxThumbLeft - 1);\n };\n\n #thumbMoveTo = (x) => {\n if (!this.#elements) return false;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return false;\n\n const trackBound = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n\n let targetX = x;\n if (targetX < 0) targetX = 0;\n const maxThumbLeft = trackBound.width - thumbWidth;\n if (targetX > maxThumbLeft) targetX = maxThumbLeft;\n targetX = parseInt(targetX, 10);\n\n this.#elements.thumb.style.left = `${targetX}px`;\n\n this.#elements.left.disabled = (targetX === 0);\n this.#elements.right.disabled = (targetX >= maxThumbLeft - 1);\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n if (maxThumbLeft > 0 && maxScrollLeft > 0) {\n const newScrollLeft = (targetX / maxThumbLeft) * maxScrollLeft;\n body.scrollLeft = newScrollLeft;\n }\n\n return (targetX > 0 && targetX < maxThumbLeft - 1);\n };\n\n #init = () => {\n const delayScroll = (pos) => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n\n const thumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n this.#thumbMoveTo(thumbLeft + pos);\n\n this.#interval1 = setInterval(() => {\n clearInterval(this.#interval1);\n\n this.#interval2 = setInterval(() => {\n const currentThumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n if (!this.#thumbMoveTo(currentThumbLeft + pos)) {\n clearInterval(this.#interval2);\n }\n }, 50);\n }, 500);\n };\n\n const clearTimer = () => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n };\n\n ['mouseup', 'mouseleave', 'touchend'].forEach(evt => {\n this.#elements.left.addEventListener(evt, clearTimer);\n this.#elements.right.addEventListener(evt, clearTimer);\n this.#elements.track.addEventListener(evt, clearTimer);\n });\n\n this.#elements.left.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(-20); });\n this.#elements.right.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(20); });\n this.#elements.left.addEventListener(\"touchstart\", () => delayScroll(-20));\n this.#elements.right.addEventListener(\"touchstart\", () => delayScroll(20));\n\n this.#elements.track.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.preventDefault();\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n this.#thumbMoveTo(e.clientX - trackRect.left - (thumbWidth / 2));\n });\n\n this.#elements.thumb.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n this.shiftX = e.clientX - this.#elements.thumb.getBoundingClientRect().left;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n this.#thumbMoveTo(moveEvent.clientX - trackRect.left - this.shiftX);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n clearTimer();\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n };\n}\n\nif (!customElements.get('nine-table-hscrollbar')) {\n customElements.define(\"nine-table-hscrollbar\", NineTableHScrollBar);\n}","// ui/nine-table-vscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableVScrollBar extends HTMLElement {\n #host;\n #sheet;\n #dragging = false;\n #elements;\n #startY = 0;\n #startScrollTop = 0;\n #startThumbTop = 0;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#sheet = this.closest(\"nine-table-sheet\");\n\n this.innerHTML = `\n <style>\n nine-table-vscrollbar {\n display: flex;\n flex-direction: column;\n width: 16px;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-vscrollbar button {\n height: 16px;\n width: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-vscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-vscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-vscrollbar .ng-scroll-top .ng-scroll-icon { transform: rotate(-45deg); margin-top: 2px; }\n nine-table-vscrollbar .ng-scroll-bottom .ng-scroll-icon { transform: rotate(135deg); margin-bottom: 2px; }\n \n nine-table-vscrollbar .ng-scroll-track {\n flex: 1;\n width: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-vscrollbar .ng-scroll-thumb {\n position: absolute;\n left: 2px;\n right: 2px;\n top: 0px;\n height: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-vscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-top' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-bottom' disabled><div class='ng-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(\".ng-scroll-track\"),\n thumb: this.querySelector(\".ng-scroll-thumb\"),\n top: this.querySelector(\".ng-scroll-top\"),\n bottom: this.querySelector(\".ng-scroll-bottom\"),\n };\n\n this.#init();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n #getScaleInfo = () => {\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords ? viewRecords.length : 0;\n\n // 🎯 [핵심] 그룹핑이든 일반이든 스크롤홀더(scrollHolder)가 가진 실제 가상 총 높이를 최우선으로 반영\n const scrollHolder = this.#sheet.elements?.scrollHolder;\n let rawContentHeight = scrollHolder ? parseFloat(scrollHolder.style.height) || 0 : 0;\n\n if (!rawContentHeight || rawContentHeight <= 0) {\n const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n if (isGrouped && this.#sheet.rowManager) {\n // RowManager가 관리하는 누적 높이 활용 또는 fallback\n rawContentHeight = (body.scrollHeight > body.clientHeight) ? body.scrollHeight : (totalCount * 30);\n } else {\n const rowHeight = this.#sheet.getRowHeight() || 1;\n rawContentHeight = totalCount * rowHeight;\n }\n }\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawContentHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let contentHeight = rawContentHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawContentHeight;\n contentHeight = MAX_BROWSER_HEIGHT;\n }\n\n return { rawContentHeight, contentHeight, scaleFactor, useScaling, totalCount };\n };\n\n #getViewHeight = () => {\n const body = this.#elements.container;\n if (!body) return 0;\n\n const thead = this.#sheet.elements?.body?.thead?.offsetHeight || 0;\n const tfoot = this.#sheet.elements?.body?.tfoot?.offsetHeight || 0;\n const tbodyHead = this.#sheet.elements?.body?.tbody?.head?.offsetHeight || 0;\n const fixedHeight = thead + tfoot + tbodyHead;\n\n return body.clientHeight - fixedHeight;\n };\n\n refresh = () => {\n trace.log(\"=================\", \"vscrollbar.refresh\");\n // 💡 드래그 중에는 refresh에 의한 썸 위치 덮어쓰기 차단\n if (this.#dragging) return;\n\n if (!this.#sheet || !this.#sheet.elements || !this.#elements) return;\n\n const body = this.#elements.container;\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n /**\n * const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n * (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n * this.#sheet.elements.body.tbody.head.offsetHeight;\n *\n * const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n * // 1. 전체 실제 데이터의 높이 계산\n * const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + rowHeight + fixedHeight - viewHeight, 0);\n * @type {number|*}\n */\n\n const bodyHeight = this.#getViewHeight();\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n\n const needsVScroll = (rawContentHeight > bodyHeight && rawContentHeight > 0 && bodyHeight > 0);\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 / contentHeight), trackHeight), 20);\n thumb.style.height = `${thumbHeight}px`;\n\n const currentScrollTop = body.scrollTop;\n //const maxScrollTop = Math.max(contentHeight - bodyHeight, 1);\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 1);\n\n let thumbTop = 0;\n if (maxScrollTop > 0) {\n thumbTop = (currentScrollTop / maxScrollTop) * (trackHeight - thumbHeight);\n }\n\n const maxThumbTop = trackHeight - thumbHeight;\n if (thumbTop < 0) thumbTop = 0;\n if (thumbTop > maxThumbTop) thumbTop = maxThumbTop;\n\n thumb.style.top = `${thumbTop}px`;\n\n /**\n // 🎯 [디버깅 로그] 스크롤바가 리프레시될 때 현재 상태 로깅\n trace.log(\"🔍 [VScroll Refresh]\", {\n isGrouped: this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false,\n totalCount,\n bodyScrollTop: currentScrollTop,\n maxScrollTop,\n thumbTop,\n maxThumbTop\n }); */\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n #init = () => {\n trace.log(\"nine-table-vscrollbar.#init\");\n\n const body = this.#elements.container;\n\n this.#elements.thumb.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n\n this.#startY = e.clientY;\n this.#startThumbTop = parseFloat(this.#elements.thumb.style.top) || 0;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const trackHeight = trackRect.height;\n const thumbHeight = this.#elements.thumb.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n if (maxThumbTop <= 0) return;\n\n //this.#elements.container.scrollTop = 0;\n\n const deltaY = moveEvent.clientY - this.#startY;\n let targetThumbTop = this.#startThumbTop + deltaY;\n\n if (targetThumbTop < 0) targetThumbTop = 0;\n if (targetThumbTop > maxThumbTop) targetThumbTop = maxThumbTop;\n\n // 썸 위치 즉시 고정\n this.#elements.thumb.style.top = `${targetThumbTop}px`;\n\n const ratio = targetThumbTop / maxThumbTop;\n\n const rowHeight =this.#sheet.getRowHeight();\n const viewHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0) -\n (this.#sheet.elements.body.thead?.offsetHeight || 0) -\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) -\n (this.#sheet.elements.body.tbody.head.offsetHeight || 0);\n\n const visibleRowCount = Math.floor(viewHeight / rowHeight);\n\n const { totalCount } = this.#getScaleInfo();\n //const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n const targetRow = Math.floor(ratio * (totalCount - visibleRowCount + 1));\n // 1000010 - 6\n this.#sheet.rowManager.scrollToDataRow(targetRow);\n\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n const currentScrollTop = this.#elements.container.scrollTop;\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 0);\n\n //trace.log(\"*****************\", visibleRowCount, ratio, totalCount, targetRow);\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n //this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n\n this.#elements.track.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0 || e.target === this.#elements.thumb) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbHeight = this.#elements.thumb.clientHeight;\n const trackHeight = this.#elements.track.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n if (maxThumbTop > 0) {\n const clickY = e.clientY - trackRect.top - (thumbHeight / 2);\n const ratio = Math.max(0, Math.min(1, clickY / maxThumbTop));\n\n const { totalCount } = this.#getScaleInfo();\n const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n\n trace.log(\"🎯 [VScroll Track Click]\", { ratio, clickY, totalCount, targetRow });\n\n if (targetRow >= 0 && this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n }\n this.refresh();\n });\n\n this.#elements.top.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = Math.max(0, currentTopRow - 1);\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n\n this.#elements.bottom.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = currentTopRow + 1;\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n };\n}\n\nif (!customElements.get('nine-table-vscrollbar')) {\n customElements.define(\"nine-table-vscrollbar\", NineTableVScrollBar);\n}","import { trace } from \"@nopeer\";\r\n\r\n// 💡 배열 인덱스 상수 정의\r\nexport const GROUP_IDX = {\r\n\tID: 0,\r\n\tDEPTH: 1,\r\n\tNAME: 2,\r\n\tCHILDREN: 3,\r\n};\r\n\r\nexport class GroupingManager {\r\n\t#sheet;\r\n\t#host;\r\n\t#groupColumns = [];\r\n\t#groupMap = new Map(); // 그룹별 자식 ID 매핑 관리용\r\n\t#isApplying = false;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t}\r\n\r\n\tget columns() {\r\n\t\treturn this.#groupColumns;\r\n\t}\r\n\r\n\tget groupMap() {\r\n\t\treturn this.#groupMap;\r\n\t}\r\n\r\n\tinitialize = () => {\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\t};\r\n\r\n\tapply() {\r\n\r\n\t\ttrace.log(\"==================\", \"Grouping.Apply\");\r\n\r\n\t\tif (this.#isApplying) return;\r\n\t\tthis.#isApplying = true;\r\n\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\r\n\t\t// 💡 데이터 캐시와 렌더링 아이템은 이제 SheetView 단일 파이프라인에서 관리하므로\r\n\t\t// 그룹핑 설정이 바뀌면 SheetView.refresh()를 호출해 전체 흐름을 일괄 재계산합니다.\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh(); // 🎯 SheetView에서 필터/정렬/그룹핑 일괄 처리\r\n\t}\r\n\r\n\tclear() {\r\n\t\tthis.#groupColumns = [];\r\n\t\tthis.#groupMap.clear();\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh();\r\n\t}\r\n\r\n\t// SheetView가 그룹핑 연산 후 groupMap을 공유할 수 있도록 설정 메서드 제공\r\n\tsetGroupMap(map) {\r\n\t\tthis.#groupMap = map;\r\n\t}\r\n\r\n\tgetChildrenRowIds(groupId) {\r\n\t\treturn this.#groupMap.get(groupId) || [];\r\n\t}\r\n\r\n\tgetChildrenRecords(groupId) {\r\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\r\n\t\tconst dataManager = this.#host.data;\r\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\r\n\t}\r\n}\r\n\r\nexport class Grouping {\r\n\r\n\tstatic apply(rawRecords, groupColumns = [], fields = []) {\r\n\t\tif (!groupColumns || groupColumns.length === 0) {\r\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\r\n\t\t}\r\n\r\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\r\n\t\tconst groupMap = new Map();\r\n\r\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\r\n\t\tconst flatResult = [];\r\n\t\tconst renderItems = [];\r\n\r\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\");\r\n\r\n\t\treturn { headers: flatResult, renderItems, groupMap };\r\n\t}\r\n\r\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId) {\r\n\t\tlet counter = 0;\r\n\t\tconst isLastLevel = (depth === groupColumns.length - 1); // 💡 연산자 수정 반영\r\n\r\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\r\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\r\n\r\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\r\n\t\t\tgroupMap.set(groupId, rowIds);\r\n\r\n\t\t\tconst groupRecord = [];\r\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\r\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\r\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\r\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\r\n\r\n\t\t\tgroupRecord.__isGroupHeader = true;\r\n\t\t\tgroupRecord.__groupId = groupId;\r\n\r\n\t\t\tresultArr.push(groupRecord);\r\n\r\n\t\t\trenderItems.push({\r\n\t\t\t\ttype: 'group',\r\n\t\t\t\trecord: groupRecord,\r\n\t\t\t\tgroupId: groupId\r\n\t\t\t});\r\n\r\n\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\r\n\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId);\r\n\t\t\t} else {\r\n\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\r\n\t\t\t\tleafRecords.forEach(record => {\r\n\t\t\t\t\trecord.__isGroupHeader = false;\r\n\t\t\t\t\trecord.__groupId = groupId;\r\n\t\t\t\t\tresultArr.push(record);\r\n\r\n\t\t\t\t\trenderItems.push({\r\n\t\t\t\t\t\ttype: 'data',\r\n\t\t\t\t\t\trecord: record,\r\n\t\t\t\t\t\tgroupId: groupId\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tstatic #buildNestedMap(records, groupColumns, fields) {\r\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\r\n\t\tconst remainingCols = groupColumns.slice(1);\r\n\t\tconst map = new Map();\r\n\r\n\t\trecords.forEach(record => {\r\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\r\n\t\t\tif (!map.has(key)) map.set(key, []);\r\n\t\t\tmap.get(key).push(record);\r\n\t\t});\r\n\r\n\t\tif (remainingCols.length > 0) {\r\n\t\t\tconst result = new Map();\r\n\t\t\tfor (let [key, subRecords] of map.entries()) {\r\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n\tstatic #collectLeafRowIds(subMapOrRecords) {\r\n\t\tlet rowIds = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\r\n\t\t}\r\n\t\treturn rowIds;\r\n\t}\r\n\r\n\tstatic #collectLeafRecords(subMapOrRecords) {\r\n\t\tlet records = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trecords = records.concat(subMapOrRecords);\r\n\t\t}\r\n\t\treturn records;\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { GROUP_IDX } from \"@/data/Grouping.js\";\n\nexport class RowManager {\n #BUFFER_ROW_COUNT = 3;\n\n #host;\n #sheet;\n #element;\n\n #containerTemplates = new Map();\n\n #templateRowHeights = []; // 💡 [추가] 템플릿 행별 개별 높이 보관 ([그룹1, 그룹2, 데이터])\n #cachedTemplateHeight = null;\n\n #resizeObserver = null;\n #sheetHeight = 0;\n #cachedRowCount;\n\n #isProgrammaticScroll = false;\n #isGrouped = false;\n\n constructor(sheet) {\n this.#host = sheet.getRootNode().host;\n this.#sheet = sheet;\n\n this.#initResizeObserver();\n }\n\n // ==========================================\n // 🎯 Public APIs & Getters\n // ==========================================\n\n getRowHeight() {\n return this.#templateRowHeights.reduce((sum, h) => sum + h, 0);//this.#cachedTemplateHeight;\n }\n\n\n refresh = (force = false) => {\n //trace.log(\"rowManager.refresh\", { force });\n\n //this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[group='true']\") ? true : false;\n\n if (!this.#sheet.classList.contains('active')) return;\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n const wasInvalidHeight = !this.#cachedTemplateHeight || this.#cachedTemplateHeight <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#cachedTemplateHeight && this.#cachedTemplateHeight > 0) {\n this.#renderAllContainers();\n }\n }\n\n\n //this.#updateFooterSpacing();\n\n this.#handleScroll(bodyViewport.scrollTop, force);\n\n this.#sheet.querySelector('nine-table-vscrollbar')?.refresh();\n };\n\n #handleScroll = (scrollTop, force = false) => {\n\n //this.#sheet.querySelector('.ng-sheet-body').scrollTop = 0;\n\n\n if (this.#isGrouped) {\n this.#handleGroupedScroll(scrollTop, force);\n return;\n }\n\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) return;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n if (totalCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n // 🎯 [핵심] 브라우저 DOM 최대 높이 제한 대응 (약 1,500만 픽셀 상한선)\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let totalVirtualHeight = rawTotalVirtualHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n totalVirtualHeight = MAX_BROWSER_HEIGHT;\n }\n //trace.log(totalCount, rowHeight, rawTotalVirtualHeight, MAX_BROWSER_HEIGHT);\n // 스크롤홀더에는 브라우저가 소화할 수 있는 최대 높이만 부여\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n //trace.log(\"*************\",this.#sheet.querySelector('.ng-sheet-body').clientHeight, this.#sheet.querySelector('.ng-sheet-body').offsetHeight, viewHeight, fixedHeight, rawTotalVirtualHeight, totalVirtualHeight);\n\n //trace.log(totalVirtualHeight);\n // 🎯 스크롤바 위치(scrollTop)를 실제 데이터 좌표계로 역환산\n const actualScrollTop = useScaling ? (scrollTop / scaleFactor) : scrollTop;\n\n const maxStartIndex = Math.max(0, totalCount - 1);\n const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n\n // 실제 데이터 좌표 기준으로 시작 인덱스 산출 (원하시는 -1 보정 유지)\n const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight) - 1, maxStartIndex));\n // 🎯 -1 보정을 제거하여 최하단까지 정확히 매핑되도록 수정\n //const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n //trace.log(startIndex, clampedScrollTop, totalVirtualHeight, fixedHeight, rowHeight);\n\n // 🎯 화면 렌더링 오프셋도 '실제 데이터 좌표(clampedScrollTop)' 기준의 모듈러 연산 적용\n const renderOffsetTop = clampedScrollTop % rowHeight;\n this.#sheet.elements.left.tbody.body.style.top =\n this.#sheet.elements.body.tbody.body.style.top =\n this.#sheet.elements.right.tbody.body.style.top = `-${renderOffsetTop}px`;\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.row !== undefined ? parseInt(firstTr.dataset.row, 10) : -1;\n\n if (!force && currentStartIndex === startIndex) {\n //trace.log(`[Perf ${getTimestamp()}] ⏭️ 인덱스 동일로 스킵! 총 소요: ${(performance.now() - startTime).toFixed(2)}ms`);\n return;\n }\n\n //trace.log(`${getTimestamp()}`);\n\n\n // [범인 구간 추적]\n [\n this.#sheet.elements.left.tbody.body,\n this.#sheet.elements.body.tbody.body,\n this.#sheet.elements.right.tbody.body\n ].forEach(($tbody, tbodyIdx) => {\n if (!$tbody) return;\n\n const rows = $tbody.querySelectorAll('tbody.body tr');\n\n //trace.log(`${getTimestamp()}`);\n\n rows.forEach(($tr, index) => {\n const dataIndex = startIndex + Math.floor(index / templateLength);\n\n if (dataIndex >= totalCount) {\n $tr.style.display = 'none';\n $tr.dataset.matrixRow = null;\n $tr.dataset.row = null;\n return;\n }\n\n // trace.log(`${getTimestamp()}`);\n const record = viewRecords[dataIndex];//this.#sheet.view.getArray(dataIndex);\n //trace.log(`${getTimestamp()}`);\n\n if (!record) {\n $tr.style.display = 'none';\n return;\n }\n\n const rowid = record.m._[NINE_TABLE.META.INDEX.ROWID];\n\n $tr.style.display = '';\n\n // 💡 만약 개별 바인딩 안에서 느린지 확인하려면 여기서 측정 가능\n this.#bindRowData($tr, record, rowid, dataIndex);\n });\n });\n\n // 셀렉션 갱신\n this.#sheet.selection.refresh();\n };\n\n\n #handleGroupedScroll = (scrollTop, force = false) => {\n\n trace.log(\"handleGroupdScroll() start\")\n\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n //trace.log(allRenderItems);\n\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.templateLength || 1;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH] || 0;\n // 💡 해당 뎁스 그룹 행의 높이가 정확히 잡히는지 확인 (없으면 첫 번째 템플릿 높이)\n const groupHeight = this.#templateRowHeights[depth] || this.#cachedTemplateHeight / templateLength;\n return groupHeight;\n } else {\n // 💡 데이터 행은 전체 템플릿 높이에서 그룹 TR들을 제외한 순수 데이터 TR들의 높이 합산이어야 합니다.\n // 만약 templateLength가 1이고 일반 행이라면 아래와 같이 처리\n let dataRowsHeight = 0;\n // templateRowHeights 전체 중에서 그룹이 아닌 데이터 행들의 높이만 합산하거나,\n // 단일 데이터 템플릿 높이를 정확히 반환해야 합니다.\n const templateLength = this.#sheet.templateLength || 1;\n\n // 간단하게 전체 캐시된 템플릿 높이에서 그룹 높이들을 뺀 나머지를 데이터 높이로 산정\n let groupHeightsTotal = 0;\n for(let i = 0; i < templateLength - 1; i++) {\n groupHeightsTotal += this.#templateRowHeights[i] || 0;\n }\n dataRowsHeight = this.#cachedTemplateHeight - groupHeightsTotal;\n\n return dataRowsHeight > 0 ? dataRowsHeight : this.#cachedTemplateHeight;\n }\n };\n\n\n let totalVirtualHeight = 0;\n const itemHeights = new Array(totalVirtualCount);\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = getItemHeight(allRenderItems[i]);\n itemHeights[i] = h;\n totalVirtualHeight += h;\n }\n\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n trace.log(\"*************\", totalVirtualHeight);\n\n const viewportClientHeight = this.#sheet.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = 0;\n\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = itemHeights[i];\n if (accumulatedHeight + h > scrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n //trace.log(startIndex);\n\n const offsetY = scrollTop - accumulatedHeight;\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.virtualIndex !== undefined\n ? parseInt(firstTr.dataset.virtualIndex, 10)\n : -1;\n\n if (!force && currentStartIndex === startIndex) {\n return;\n }\n\n const visibleRowsCount = Math.ceil(viewportClientHeight / (this.#cachedTemplateHeight / templateLength));\n const dynamicBuffer = (this.#sheet.grouping.columns?.length || 1) * 15;\n const targetStart = startIndex;\n const targetEnd = Math.min(totalVirtualCount, startIndex + visibleRowsCount + dynamicBuffer);\n\n\n\n\n const renderedItems = allRenderItems.slice(targetStart, targetEnd);\n\n //trace.log(\"handleGroupdScroll() 22\", renderedItems);\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const trs = Array.from(container.querySelectorAll('tbody.body tr'));\n\n for (let i = 0; i < trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = trs.slice(i, i + templateLength);\n\n if (!item || itemIndex >= renderedItems.length) {\n chunkTrs.forEach(tr => {\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.style.display = 'none';\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 }\n } else {\n tr.style.display = 'none';\n }\n } else {\n if (isTrGroup) {\n tr.style.display = 'none';\n } else {\n tr.style.display = '';\n\n //trace.log(item.record)\n const rowid = item.record.m?.rowid ?? 0;\n this.#bindRowData(tr, item.record, rowid, virtualIndex);\n }\n }\n });\n }\n });\n\n this.#sheet.selection.refresh();\n\n trace.log(\"handleGroupdScroll() end\")\n };\n\n #bindGroupRowData = ($tr, allRenderItems, groupRecord, virtualIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (virtualIndex * templateLength) + subRowIndex;\n\n const indices = groupRecord[GROUP_IDX.CHILDREN]; // 인덱스 배열이 들어있는 위치 (정확한 인덱스는 구조에 맞게 조절)\n const allRecords = this.#host.data.getArray();\n const childrenRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n // 필요하다면 groupRecord나 tr에 자식 레코드들을 캐싱해 둘 수도 있습니다.\n //groupRecord.childrenRecords = childrenRecords;\n\n //trace.log(allRecords, childrenRecords);\n\n\n $tr.dataset.virtualIndex = virtualIndex;\n $tr.dataset.row = '';\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = childrenRecords;//groupRecord;\n $tr.dataset.groupId = groupRecord[GROUP_IDX.ID];\n\n //trace.log(tr, groupRecord)\n\n Array.from($tr.cells).forEach(($cell) => {\n\n $cell.dataset.row = virtualIndex;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') || typeof $el.refresh === 'function'\n );\n\n //trace.log(customComp)\n\n if (customComp !== undefined && typeof customComp.refresh === 'function') {\n customComp?.refresh();\n }\n });\n };\n\n #bindRowData = ($tr, record, rowid, dataIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (dataIndex * templateLength) + subRowIndex;\n\n $tr.dataset.index = dataIndex;\n $tr.dataset.row = rowid;\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = record;\n\n Array.from($tr.cells).forEach(($cell) => {\n $cell.dataset.index = dataIndex;\n $cell.dataset.row = rowid;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.refresh === 'function'\n );\n\n customComp?.refresh();\n });\n };\n\n initialize = () => {\n //trace.log(\"rowManager.initialize\");\n\n this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n\n this.#cachedTemplateHeight = null;\n this.#containerTemplates.clear();\n\n this.#element = {\n scrollTables: this.#sheet.querySelectorAll('.ng-sheet-body table'),\n firstTr: this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body tr'),\n };\n\n // 컨테이너 템플릿 수집 부분도 tbody.body 기준으로 변경\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const tableEl = container.querySelector('table');\n if (!tableEl) return;\n\n const tbody = tableEl.querySelector('tbody.body'); // 👈 .bindable-tbody 대신 tbody.body\n if (!tbody) return;\n\n const trs = Array.from(tbody.querySelectorAll('tr'));\n const templateTrs = trs.map(tr => tr.cloneNode(true));\n this.#containerTemplates.set(selector, templateTrs);\n });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n if (bodyViewport) {\n this.#sheetHeight = bodyViewport.clientHeight;\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', () => {\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#cachedTemplateHeight || 0;\n const totalCount = this.#sheet.view.getArray()?.length || 0;\n const rawTotalVirtualHeight = totalCount * rowHeight;\n\n if (rawTotalVirtualHeight <= bodyViewport.clientHeight) {\n return;\n }\n\n this.#handleScroll(bodyViewport.scrollTop);\n\n this.#sheet.querySelector('nine-table-vscrollbar').refresh();\n //this.#sheet.querySelector('nine-table-hscrollbar').refresh();\n }, { passive: true });\n }\n };\n\n scrollToDataRow(dataRow, align = 'top', onRendered) {\n //trace.log(\"🔍 [scrollToDataRow ENTER]\", { dataRow, isGrouped: this.#isGrouped });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords?.length || 0;\n if (totalCount === 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const targetRow = Math.max(0, Math.min(dataRow, totalCount - 1));\n let targetScrollTop = 0;\n\n // 🎯 [핵심] 그룹핑 모드일 때는 실제 scrollHeight(또는 렌더링된 총 높이)를 기준으로 비율 계산\n if (this.#isGrouped) {\n const maxScrollTop = Math.max(bodyViewport.scrollHeight - bodyViewport.clientHeight, 1);\n // targetRow가 전체 totalCount에서 차지하는 비율(ratio)만큼 실제 스크롤 최대 높이에 곱해줌\n const ratio = targetRow / Math.max(totalCount - 1, 1);\n targetScrollTop = ratio * maxScrollTop;\n } else {\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n let rawTargetScrollTop = targetRow * rowHeight;\n\n /**\n if (align === 'bottom') {\n const viewportHeight = bodyViewport.clientHeight;\n const visibleRowsCount = Math.floor(viewportHeight / rowHeight);\n const adjustedRow = Math.max(0, targetRow - visibleRowsCount + 1);\n rawTargetScrollTop = adjustedRow * rowHeight;\n } */\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n //const rawTotalVirtualHeight = totalCount * rowHeight;\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n }\n\n targetScrollTop = rawTargetScrollTop * scaleFactor;\n }\n\n //trace.log(\"🔍 [scrollToDataRow CALC FIXED]\", { targetRow, totalCount, targetScrollTop });\n\n this.#isProgrammaticScroll = true;\n bodyViewport.scrollTop = targetScrollTop;\n this.#handleScroll(targetScrollTop);\n //trace.log(targetScrollTop);\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.#isProgrammaticScroll = false;\n if (typeof onRendered === 'function') onRendered();\n });\n });\n }\n\n\n\n destroy = () => {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n };\n\n #measureAndCacheHeight = () => {\n if (!this.#sheet.classList.contains('active')) return;\n\n if (!this.#sheet.sourceTable) return;\n\n const trTemplates = this.#sheet.sourceTable?.querySelectorAll('tbody.body tr');\n //trace.log(\"[DEBUG #measureAndCacheHeight] bodyTemplates count:\", trTemplates?.length);\n //if (!trTemplates || trTemplates.length === 0) return;\n\n const $tbody = this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body');\n //if (!tbody) return -1;\n\n $tbody.querySelectorAll('tr').forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n trTemplates.forEach($tr => fragment.appendChild($tr.cloneNode(true)));\n $tbody.appendChild(fragment);\n\n //let totalHeight = 0;\n const renderedTrs = $tbody.querySelectorAll('tr');\n\n this.#templateRowHeights = [];\n renderedTrs.forEach($tr => {\n //const h = $tr.offsetHeight;\n //trace.log(`[DEBUG #measureAndCacheHeight] tr[${idx}] height:`, h);\n //totalHeight += h;\n\n this.#templateRowHeights.push($tr.offsetHeight);\n });\n\n renderedTrs.forEach(tr => tr.remove());\n\n this.#cachedTemplateHeight = this.#templateRowHeights.reduce((sum, h) => sum + h, 0);\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n trace.log(\"[DEBUG #updateRowCount] sheetHeight:\", this.#sheetHeight, \"cachedTemplateHeight:\", this.#cachedTemplateHeight);\n if (this.#sheetHeight > 0 && this.#cachedTemplateHeight > 0) {\n const visibleRows = Math.ceil(this.#sheetHeight / this.#cachedTemplateHeight);\n\n // 💡 [유연한 개선] 그룹화가 켜져 있다면 그룹 컬럼 깊이(다단 레벨)에 따라 버퍼를 동적으로 확장\n let dynamicBuffer = this.#BUFFER_ROW_COUNT;\n if (this.#isGrouped && this.#sheet.grouping) {\n const groupDepth = this.#sheet.grouping.columns?.length || 1;\n // 그룹 단계가 깊을수록 헤더 행이 많이 차지하므로 여유분을 비례해서 늘림 (예: 기본 버퍼 + (뎁스당 추가 여유))\n dynamicBuffer += (groupDepth * 15);\n }\n\n this.#cachedRowCount = visibleRows + dynamicBuffer;\n trace.log(\"[DEBUG #updateRowCount] calculated cachedRowCount:\", this.#cachedRowCount);\n }\n };\n\n #renderAllContainers = () => {\n trace.log(\"rowManager.#renderAllContainers\");\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (container && container.querySelector('tbody')) {\n this.#renderRows(container); // selector 인자 제거!\n }\n });\n\n this.#syncRowHeights();\n };\n\n #renderRows = (container) => {\n let targetFixedType = null;\n if (container.classList.contains('ng-container-left')) targetFixedType = 'left';\n else if (container.classList.contains('ng-container-right')) targetFixedType = 'right';\n\n // 🎯 [수정] 원본 테이블에서 tbody.body에 해당하는 tr들만 복제\n const templateTrs = Array.from(this.#sheet.sourceTable.querySelectorAll('tbody.body tr')).map(tr => {\n const clonedTr = tr.cloneNode(true);\n\n if (targetFixedType === 'left') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'left') $cell.remove();\n });\n } else if (targetFixedType === 'right') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'right') $cell.remove();\n });\n } else {\n clonedTr.querySelectorAll('[fixed=left], [fixed=right]').forEach($cell => {\n $cell.remove();\n });\n }\n\n return clonedTr;\n });\n\n if (templateTrs.length === 0) return;\n\n // 🎯 [수정] targetTbody도 일반 tbody가 아니라 tbody.body를 정확히 타겟팅\n const targetTbody = container.querySelector('tbody.body');\n if (!targetTbody) return;\n\n targetTbody.querySelectorAll(\"tr\").forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < this.#cachedRowCount; i++) {\n templateTrs.forEach(tmpl => fragment.appendChild(tmpl.cloneNode(true)));\n }\n\n\n targetTbody.appendChild(fragment);\n\n if (container.classList.contains('ng-container-body')) {\n this.#element.firstTr = targetTbody.querySelector('tr');\n }\n };\n\n\n\n #syncRowHeights = () => {\n const leftTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-left table');\n const bodyTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-body table');\n const rightTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-right table');\n\n if (bodyTable) {\n const leftRows = leftTable ? Array.from(leftTable.querySelectorAll('tbody tr')) : [];\n const bodyRows = Array.from(bodyTable.querySelectorAll('tbody tr'));\n const rightRows = rightTable ? Array.from(rightTable.querySelectorAll('tbody tr')) : [];\n\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n }\n };\n\n #initResizeObserver = () => {\n\n if (!this.#sheet || !(this.#sheet instanceof HTMLElement)) return;\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const sheetEl = entry.target;\n if (!sheetEl.classList.contains('active')) continue;\n\n const height = entry.contentRect.height;\n const width = entry.contentRect.width;\n\n if (width > 0 && this.#sheet.isAutoFitCol) {\n this.#sheet.autoFit(true);\n }\n\n if (height > 0 && this.#sheetHeight !== height) {\n this.#sheetHeight = height;\n this.#updateRowCount();\n\n if (this.#cachedTemplateHeight !== null) {\n this.#renderAllContainers();\n this.refresh();\n }\n }\n }\n });\n\n this.#resizeObserver.observe(this.#sheet);\n };\n}","import { trace } from \"@nopeer\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class TableCompiler {\n\n static compile($srcTable) {\n\n const $table = $srcTable.cloneNode(true);\n\n // 1. 헤더 컴파일\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n // 4. colgroup과 인덱스/fixed 속성 동기화\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n static recompile($table) {\n\n /** 너비조정은 필요없을듯 */\n /**\n const cols = Array.from($table.querySelectorAll('colgroup col'));\n cols.forEach((col, idx) => {\n //trace.log(col.cloneNode(true));\n\n col.setAttribute('data-col', idx);\n\n let w = col.getAttribute('width');\n if (!w || isNaN(parseFloat(w))) {\n w = parseFloat(col.style.width);\n }\n if (w && !isNaN(parseFloat(w))) {\n const numericWidth = Math.round(parseFloat(w));\n //trace.log(w, numericWidth);\n\n col.setAttribute('width', numericWidth);\n col.style.width = `${numericWidth}px`;\n }\n }); */\n\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n\n\n static #syncColAttributes($table) {\n\n $table.querySelectorAll('colgroup col').forEach(($col, i) => {\n $col.setAttribute('data-col', i);\n const fixed = $col.getAttribute('fixed');\n\n $table.querySelectorAll(`[data-col=\"${i}\"]`).forEach($el => {\n fixed ? $el.setAttribute('fixed', fixed) : $el.removeAttribute('fixed');\n });\n });\n }\n\n static resetColIndex($table, trs) {\n\n const cols = $table.querySelectorAll('colgroup col');\n const grid = Array.from({ length: trs.length }, () => Array(cols.length).fill(null));\n\n trs.forEach(($tr, index) => {\n\n $tr.dataset.subrow = index;\n\n let colIndex = 0;\n\n $tr.querySelectorAll('th, td').forEach($cell => {\n\n while (colIndex < cols.length && grid[index][colIndex] !== null) {\n colIndex++;\n }\n\n $cell.dataset.col = colIndex;\n\n const rowSpan = $cell.rowSpan || 1;\n const colSpan = $cell.colSpan || 1;\n\n for (let r = 0; r < rowSpan; r++) {\n for (let c = 0; c < colSpan; c++) {\n if (index + r < trs.length && colIndex + c < cols.length) {\n grid[index + r][colIndex + c] = $cell;\n }\n }\n }\n\n colIndex += colSpan;\n });\n });\n }\n\n\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellSelection {\r\n\t#sheet;\r\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#initEvents();\r\n\r\n\t\t/**\r\n\t\t// 🎯 [신규 구조 대응] .ng-sheet-body 및 내부 컨테이너 스크롤 감지\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (bodyViewport) {\r\n\t\t\tbodyViewport.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t} */\r\n\r\n\t\t/**\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}); */\r\n\r\n\t\ttrace.log(\"🎯 [CellSelection] Initialized (New Structure Compatible)\");\r\n\t}\r\n\r\n\t#getMatrixRow(tr) {\r\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10);\r\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr:not(.nodata)'));\r\n\r\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.row, 10) === dataRow);\r\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\r\n\t\tconst templateLength = sameGroupTrs.length > 0 ? sameGroupTrs.length : 1;\r\n\r\n\t\tconst matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\r\n\r\n\t\treturn { dataRow, subRowIndex, matrixRow };\r\n\t}\r\n\r\n\tsetFocus(matrixRow, col) {\r\n\t\t// 1. 기존 포커스 클래스 제거\r\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {$tr.classList.remove(\"selected-start\");\r\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {$td.classList.remove(\"selected-start\");\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 [신규 구조 대응] data-matrix-row 탐색 경로 수정 (.ng-sheet-body-content 기준)\r\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!$td) return;\r\n\r\n\t\t$td.classList.add(\"selected-start\");\r\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\r\n\t}\r\n\r\n\tsetRange(startRow, startCol, endRow, endCol) {\r\n\t\tlet r1 = Math.min(startRow, endRow);\r\n\t\tlet r2 = Math.max(startRow, endRow);\r\n\t\tlet c1 = Math.min(startCol, endCol);\r\n\t\tlet c2 = Math.max(startCol, endCol);\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tlet expanded = true;\r\n\t\tlet loopCount = 0;\r\n\r\n\t\twhile (expanded && loopCount < 5) {\r\n\t\t\texpanded = false;\r\n\t\t\tloopCount++;\r\n\r\n\t\t\tcontainers.forEach(container => {\r\n\t\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\t\tif (tr.classList.contains('nodata')) return;\r\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\r\n\t\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\r\n\r\n\t\t\t\t\t\tif (isIntersecting) {\r\n\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\r\n\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\r\n\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\r\n\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\r\n\r\n\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\r\n\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\r\n\t\t\t\t\t\t\t\texpanded = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#range = { startRow: r1, startCol: c1, endRow: r2, endCol: c2 };\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trefresh = () => {\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trender = () => {\r\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\t// 1. 기존 선택 클래스 초기화\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\r\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\r\n\t\t\t});\r\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\r\n\t\t\t\ttr.classList.remove('selected-start');\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tif (startRow < 0 || startCol < 0) return;\r\n\r\n\t\t// 2. 범위 렌더링\r\n\t\tcontainers.forEach((container) => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\r\n\t\t\t\t\tif (!isSelected) return;\r\n\r\n\t\t\t\t\tcell.classList.add('selected');\r\n\r\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\r\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\r\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\r\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 3. 포커스 셀 복구\r\n\t\tconst $focusTd = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${startRow}\"] td[data-col=\"${startCol}\"]`);\r\n\t\tif ($focusTd) {$focusTd.classList.add(\"selected-start\");\r\n\t\t\t$focusTd.closest('tr')?.classList.add(\"selected-start\");\r\n\t\t}\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!mainZone) {\r\n\t\t\ttrace.log(\"❌ [CellSelection] .ng-sheet-body not found!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmainZone.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tif (cell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\tthis.#sheet.style.userSelect = 'none';\r\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\r\n\r\n\t\t\tconst tr = cell.closest('tr');\r\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\r\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\r\n\r\n\t\t\tif (startRow < 0) {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tthis.setFocus(startRow, startCol);\r\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\r\n\r\n\t\t\tlet lastMatrixRow = startRow;\r\n\t\t\tlet lastCol = startCol;\r\n\r\n\t\t\tconst onMouseMove = (moveEvent) => {\r\n\t\t\t\tconst targetEl = document.elementFromPoint(moveEvent.clientX, moveEvent.clientY);\r\n\t\t\t\tlet targetCell = targetEl?.closest('td, th');\r\n\r\n\t\t\t\tif (!targetCell || !this.#sheet.contains(targetCell)) {\r\n\t\t\t\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr:not(.nodata) td, .ng-sheet-body-content tbody tr:not(.nodata) th');\r\n\t\t\t\t\tfor (const c of allCells) {\r\n\t\t\t\t\t\tconst rect = c.getBoundingClientRect();\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tmoveEvent.clientX >= rect.left &&\r\n\t\t\t\t\t\t\tmoveEvent.clientX <= rect.right &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY >= rect.top &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY <= rect.bottom\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\ttargetCell = c;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!targetCell) return;\r\n\t\t\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\r\n\t\t\t\tif (targetCell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\t\tconst targetTr = targetCell.closest('tr');\r\n\t\t\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\r\n\t\t\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\r\n\r\n\t\t\t\tif (endRow < 0) return;\r\n\t\t\t\tif (lastMatrixRow === endRow && lastCol === endCol) return;\r\n\r\n\t\t\t\tlastMatrixRow = endRow;\r\n\t\t\t\tlastCol = endCol;\r\n\r\n\t\t\t\tthis.setRange(startRow, startCol, endRow, endCol);\r\n\t\t\t};\r\n\r\n\t\t\tconst onMouseUp = () => {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\r\n\t\t\t\tdocument.removeEventListener('mousemove', onMouseMove);\r\n\t\t\t\tdocument.removeEventListener('mouseup', onMouseUp);\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener('mousemove', onMouseMove);\r\n\t\t\tdocument.addEventListener('mouseup', onMouseUp);\r\n\t\t});\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellNavigation {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#currentCell = null;\r\n\t#currentTr = null;\r\n\t#currentRow = -1;\r\n\t#currentCol = -1;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.#initEvents();\r\n\t\ttrace.log(\"🎯 [CellNavigation] Initialized (Diagnostic Logging Restored)\");\r\n\t}\r\n\r\n\tget currentCell() {\r\n\t\treturn this.#currentCell;\r\n\t}\r\n\r\n\tset currentCell(cell) {\r\n\t\tif (!cell) return;\r\n\r\n\t\tthis.#currentCell = cell;\r\n\t\tcell.focus({ preventScroll: true });\r\n\r\n\t\tthis.#currentTr = cell.closest(\"tr\");\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\ttrace.log(`📌 [setCurCell] Active set -> dataRow: ${cell.dataset.row}, subrow: ${cell.closest('tr')?.dataset.subrow}, matrixRow: ${matrixRow}, col: ${cell.dataset.col}`);\r\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\r\n\t}\r\n\r\n\t#getMatrixRowFromTr(tr) {\r\n\t\tif (!tr) return 0;\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10) || 0;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\t// 1. tr에 data-matrix-row가 박혀있다면 최우선 사용\r\n\t\tconst mRowAttr = parseInt(tr.dataset.matrixRow, 10);\r\n\t\tif (!isNaN(mRowAttr)) return mRowAttr;\r\n\r\n\t\t// 2. tbody 내에서 동일 data-row를 가진 그룹 중 몇 번째 서브 행인지 정확히 산출\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tif (tbody) {\r\n\t\t\tconst groupTrs = Array.from(tbody.querySelectorAll(`tr[data-row=\"${dataRow}\"]`));\r\n\t\t\tconst subIdx = groupTrs.indexOf(tr);\r\n\t\t\tif (subIdx >= 0) {\r\n\t\t\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\t\t\treturn (dataRow * templateLength) + subIdx;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst subRowIndex = parseInt(tr.dataset.subrow, 10) || 0;\r\n\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\treturn (dataRow * templateLength) + subRowIndex;\r\n\t}\r\n\r\n\tmoveCell(e) {\r\n\r\n\t\t//trace.log(e.target.tagName);\r\n\t\tif (![\"TH\",\"TD\"].includes(e.target.tagName)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!this.#currentCell || !this.#currentTr) {\r\n\t\t\ttrace.log(\"⚠️ [moveCell] currentCell or currentTr is missing!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst cell = this.#currentCell;\r\n\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\tlet nextMatrixRow = matrixRow;\r\n\t\tlet nextCol = col;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tnextMatrixRow = matrixRow + (cell.rowSpan || 1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\t\tnextMatrixRow = Math.max(0, matrixRow - (cell.rowSpan || 1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\t\tif (nextCol < 0 && matrixRow > 0) {\r\n\t\t\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow - 1;\r\n\t\t\t\t\t\tconst prevTrs = this.#findTargetTrsByMatrix(nextMatrixRow);\r\n\t\t\t\t\t\tconst maxColCell = this.#getMaxColCell(prevTrs);\r\n\t\t\t\t\t\tnextCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) : 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\t\t\tconst maxColCell = this.#getMaxColCell(targetTrs);\r\n\t\t\t\t\tconst maxCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) + parseInt(maxColCell.colSpan || 1, 10) : 0;\r\n\r\n\t\t\t\t\tif (nextCol >= maxCol) {\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow + 1;\r\n\t\t\t\t\t\tnextCol = 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tconst maxDataRow = this.#host.data.length;\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst maxMatrixRowLimit = (maxDataRow * templateLength) - 1;\r\n\t\t\t\tif (matrixRow + (cell.rowSpan || 1) > maxMatrixRowLimit) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tif (matrixRow <= 0) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\ttrace.log(\"========\")\r\n\r\n\t\t// 🎯 전체 데이터 갯수 한계 체크 (오버플로우 방지)\r\n\t\tconst totalCount = this.#sheet.view.getArray()?.length || 0;\r\n\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\tconst maxMatrixRow = (totalCount * templateLength) - 1;\r\n\t\tnextMatrixRow = Math.max(0, Math.min(nextMatrixRow, maxMatrixRow));\r\n\r\n\t\ttrace.log(`⌨️ [Key: ${e.code}] Current matrixRow: ${matrixRow} -> Target nextMatrixRow: ${nextMatrixRow}, nextCol: ${nextCol}`);\r\n\r\n\t\tconst nextDataRow = Math.floor(nextMatrixRow / templateLength);\r\n\t\tconst nextSubRowIndex = nextMatrixRow % templateLength;\r\n\r\n\t\tconst attemptFindAndMove = (retries = 0) => {\r\n\t\t\tlet targetCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\r\n\t\t\tif (targetCell) {\r\n\t\t\t\ttrace.log(`✅ [Found Cell] Attempt ${retries} -> dataRow: ${targetCell.dataset.row}, col: ${targetCell.dataset.col}`);\r\n\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, targetCell.dataset.col, actualMatrixRow, targetCell.dataset.col);\r\n\r\n\t\t\t\tthis.#ensureCellVisible(targetCell);\r\n\t\t\t} else {\r\n\t\t\t\ttrace.log(`📜 [Scroll Trigger] Cell not found in DOM, invoking rowManager.scrollToDataRow(${nextDataRow})`);\r\n\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(nextDataRow, \"bottom\", () => {\r\n\t\t\t\t\ttrace.log(\"nextDataRow\", nextDataRow);\r\n\r\n\t\t\t\t\tconst retryLoop = () => {\r\n\t\t\t\t\t\tlet retryCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\t\t\t\t\t\tif (retryCell) {\r\n\t\t\t\t\t\t\ttrace.log(`✅ [Found After Scroll] RetryLoop success -> dataRow: ${retryCell.dataset.row}`);\r\n\t\t\t\t\t\t\tthis.currentCell = retryCell;\r\n\t\t\t\t\t\t\tconst tr = retryCell.closest(\"tr\");\r\n\t\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, retryCell.dataset.col, actualMatrixRow, retryCell.dataset.col);\r\n\t\t\t\t\t\t\tthis.#ensureCellVisible(retryCell);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t};\r\n\t\t\t\t\tretryLoop();\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tattemptFindAndMove();\r\n\t}\r\n\r\n\t#ensureCellVisible(cell) {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tconst bodyContainer = this.#sheet.querySelector('.ng-sheet-body .ng-container-body');\r\n\t\t//const headerBody = this.#sheet.querySelector('.ng-sheet-header .ng-container-body');\r\n\r\n\t\tif (!bodyViewport || !bodyContainer) return;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\t\tconst containerRect = bodyContainer.getBoundingClientRect();\r\n\t\t//const headerRect = headerBody ? headerBody.getBoundingClientRect() : null;\r\n\r\n\t\ttrace.log(`📐 [DIAGNOSTIC VISIBILITY] \r\n- cell.dataset.col: ${cell.dataset.col}\r\n- cellRect (left: ${cellRect.left}, right: ${cellRect.right})\r\n- containerRect (left: ${containerRect.left}, right: ${containerRect.right}, width: ${containerRect.width}, scrollLeft: ${bodyContainer.scrollLeft}, scrollWidth: ${bodyContainer.scrollWidth}, clientWidth: ${bodyContainer.clientWidth})\r\n- viewportRect (width: ${viewportRect.width})\r\n `);\r\n\r\n\t\tconst isAbove = cellRect.top < viewportRect.top;\r\n\t\tconst isBelow = cellRect.bottom > viewportRect.bottom;\r\n\r\n\t\tif (isAbove || isBelow) {\r\n\t\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\t\tconst col = cell.dataset.col;\r\n\t\t\tconst $tr = cell.closest(\"tr\");\r\n\t\t\tconst subrow = $tr?.dataset.subrow || 0;\r\n\r\n\t\t\tif (!isNaN(dataRow) && this.#sheet.rowManager) {\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(dataRow, \"top\", () => {\r\n\t\t\t\t\tconst targetCell = this.#sheet.querySelector(`.ng-sheet-body tr[data-row=\"${dataRow}\"][data-subrow=\"${subrow}\"] td[data-col=\"${col}\"]`);\r\n\t\t\t\t\tif (targetCell) {\r\n\t\t\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\t\t\tconst tr = targetCell.closest(\"tr\");\r\n\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, col, actualMatrixRow, col);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (cellRect.left < containerRect.left) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Left] cell out of left bound`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft -= (containerRect.left - cellRect.left + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t} else if (cellRect.right > containerRect.right) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Right] cell out of right bound. cellRect.right: ${cellRect.right} > containerRect.right: ${containerRect.right}`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft += (cellRect.right - containerRect.right + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t}\r\n\t}\r\n\r\n\t#getMinCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet minCol = Infinity;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tminCol = Math.min(minCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn minCol === Infinity ? 0 : minCol;\r\n\t};\r\n\r\n\t#getMaxCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet maxCol = 0;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tmaxCol = Math.max(maxCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn maxCol;\r\n\t};\r\n\r\n\t#getMaxColCell = (targetTrs) => {\r\n\t\tconst allCells = [];\r\n\t\ttargetTrs.forEach(tr => allCells.push(...Array.from(tr.querySelectorAll('td'))));\r\n\t\tif (allCells.length === 0) return null;\r\n\t\tallCells.sort((a, b) => parseInt(a.dataset.col, 10) - parseInt(b.dataset.col, 10));\r\n\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\treturn allCells[allCells.length - 1];\r\n\t};\r\n\r\n\t#getNextCol = (matrixRow, col) => {\r\n\t\tconst td = this.#sheet.querySelector(`.ng-sheet-body tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`) ||\r\n\t\t\tthis.#sheet.querySelector(`.ng-sheet-body td[data-col=\"${col}\"]`);\r\n\r\n\t\tconst colSpan = td?.colSpan || 1;\r\n\t\tconst next = col + colSpan;\r\n\t\ttrace.log(`🔍 [#getNextCol] current col: ${col}, found td colSpan: ${colSpan}, calculated next col: ${next}`);\r\n\t\treturn next;\r\n\t}\r\n\r\n\t#getPreviousCol = (matrixRow, currentCol) => {\r\n\t\tif (currentCol <= 0) return 0;\r\n\t\tconst currentTrCells = this.#currentTr ? Array.from(this.#currentTr.querySelectorAll('td, th')) : [];\r\n\t\tconst cols = new Set();\r\n\r\n\t\tcurrentTrCells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tcols.add(c);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (cols.size === 0) {\r\n\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\ttargetTrs.forEach(tr => {\r\n\t\t\t\tArray.from(tr.querySelectorAll('td, th')).forEach(cell => {\r\n\t\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\t\t\tcols.add(c);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst smallerCols = Array.from(cols).filter(c => c < currentCol);\r\n\t\treturn smallerCols.length === 0 ? Math.max(0, currentCol - 1) : Math.max(...smallerCols);\r\n\t};\r\n\r\n\t#findTargetTrsByMatrix = (matrixRow) => {\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body .ng-container-left, .ng-sheet-body .ng-container-body, .ng-sheet-body .ng-container-right'\r\n\t\t);\r\n\t\tconst matchedTrs = [];\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tconst trs = Array.from(container.querySelectorAll('tbody tr'));\r\n\t\t\tfor (const tr of trs) {\r\n\t\t\t\tconst mRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\tif (mRow === matrixRow) {\r\n\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst cells = Array.from(tr.querySelectorAll('td'));\r\n\t\t\t\tlet foundInSpan = false;\r\n\t\t\t\tfor (const cell of cells) {\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tif (rowSpan > 1 && matrixRow >= mRow && matrixRow < mRow + rowSpan) {\r\n\t\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\t\tfoundInSpan = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (foundInSpan) break;\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn matchedTrs;\r\n\t};\r\n\r\n\t#getNearElement = (dataRow, subRowIndex, col, matrixRow) => {\r\n\t\tconst targetMatrixRow = matrixRow !== undefined ? matrixRow : (dataRow * (this.#sheet.templateLength || 1)) + subRowIndex;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\tconst targetDataRow = Math.floor(targetMatrixRow / templateLength);\r\n\t\tconst targetSubRow = targetMatrixRow % templateLength;\r\n\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body, .ng-container-left, .ng-container-body, .ng-container-right, .ng-part-body'\r\n\t\t);\r\n\r\n\t\tconst searchedTrs = new Set();\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => searchedTrs.add(tr));\r\n\t\t});\r\n\r\n\t\tfor (const tr of Array.from(searchedTrs)) {\r\n\t\t\tconst trDataRow = parseInt(tr.dataset.row, 10);\r\n\t\t\tif (isNaN(trDataRow)) continue;\r\n\r\n\t\t\tconst tbody = tr.closest('tbody');\r\n\t\t\tconst groupTrs = tbody ? Array.from(tbody.querySelectorAll(`tr[data-row=\"${trDataRow}\"]`)) : [tr];\r\n\t\t\tconst trSubIdx = groupTrs.indexOf(tr);\r\n\r\n\t\t\tfor (const cell of Array.from(tr.querySelectorAll('td'))) {\r\n\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\tconst span = parseInt(cell.colSpan || 1, 10);\r\n\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\r\n\t\t\t\tif (isNaN(c) || window.getComputedStyle(cell).display === 'none') continue;\r\n\r\n\t\t\t\tconst cellDataRowStart = trDataRow;\r\n\t\t\t\tconst cellSubRowStart = trSubIdx;\r\n\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst cellStartMatrix = (cellDataRowStart * templateLength) + cellSubRowStart;\r\n\t\t\t\tconst cellEndMatrix = cellStartMatrix + rowSpan - 1;\r\n\r\n\t\t\t\tif (targetMatrixRow >= cellStartMatrix && targetMatrixRow <= cellEndMatrix) {\r\n\t\t\t\t\tif (col >= c && col < c + span) {\r\n\t\t\t\t\t\treturn cell;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn null;\r\n\t};\r\n\r\n\t#initEvents() {\r\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tthis.currentCell = cell;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\r\n\t\t\tif ([\"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\r\n\t\t\t\tthis.moveCell(e);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}","// ui/col/ColResizer.js\nimport { trace } from \"@nopeer\";\nimport { COLLAPSED_WIDTH, TableCompiler } from \"@/ui/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('.ng-col-resizer-panel');\n\n this.#tooltip = this.#panel?.querySelector('.resizer-overlay');\n this.bindEvents();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointermove', this.#onPointerMove);\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n this.#sheet.removeEventListener('dblclick', this.#onDblClick);\n }\n\n refreshLayout(containerType = 'body') {\n const containers = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType}`));\n if (containers.length === 0) return;\n\n const isFixedContainer = containerType === 'left' || containerType === 'right';\n const isAutoFit = !isFixedContainer && (\n this.#sheet.isAutoFitCol ||\n containers[0].querySelector('table')?.getAttribute('auto-fit-col') === 'true'\n );\n\n if (!isAutoFit) {\n\n const firstColgroup = containers[0].querySelector('table colgroup');\n if (!firstColgroup) return;\n\n let totalWidth = 0;\n const colWidths = {};\n\n Array.from(firstColgroup.querySelectorAll('col')).forEach(col => {\n const colIdx = col.getAttribute('data-col');\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) {\n colWidths[colIdx] = w;\n totalWidth += w;\n }\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n\n trace.log(\"====================\", containers, containerType);\n\n if (containerType === 'body') {\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n //tbl.style.minWidth = `${totalWidth}px`;\n });\n } else {\n container.style.flex = `0 0 ${totalWidth}px`;\n container.style.width = `${totalWidth}px`;\n container.style.minWidth = `${totalWidth}px`;\n container.style.maxWidth = `${totalWidth}px`;\n\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n tbl.style.minWidth = `${totalWidth}px`;\n tbl.style.maxWidth = `${totalWidth}px`;\n\n Object.entries(colWidths).forEach(([colIdx, w]) => {\n tbl.querySelectorAll(`th[data-col=\"${colIdx}\"], td[data-col=\"${colIdx}\"]`).forEach(cell => {\n cell.style.width = `${w}px`;\n cell.style.minWidth = `${w}px`;\n cell.style.maxWidth = `${w}px`;\n });\n });\n });\n }\n });\n } else {\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n tables.forEach(tbl => {\n //tbl.style.width = '100%';\n //tbl.style.minWidth = '100%';\n //tbl.style.maxWidth = '';\n });\n });\n }\n\n this.#sheet.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n setColumnWidth(globalColIndex, width, containerType = null) {\n\n trace.log(\"setColumnWidth\");\n\n\n let targetCols = [];\n\n //if (containerType) {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType} table colgroup col[data-col=\"${globalColIndex}\"]`));\n //} else {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n //}\n targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n\n if (targetCols.length === 0) return;\n\n const firstContainer = targetCols[0].closest('.ng-container-left, .ng-container-body, .ng-container-right');\n const resolvedContainerType = containerType || (\n firstContainer?.classList.contains('ng-container-left') ? 'left' :\n firstContainer?.classList.contains('ng-container-right') ? 'right' : 'body'\n );\n\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n\n trace.log(col, width);\n });\n\n const sourceCol = this.#sheet.sourceTable?.querySelector(`colgroup col[data-col=\"${globalColIndex}\"]`);\n if (sourceCol) {\n sourceCol.setAttribute('width', width);\n sourceCol.style.width = `${width}px`;\n }\n\n\n\n this.refreshLayout(resolvedContainerType);\n\n // 🎯 [핵심] autoFit을 여기서 또 호출하면 루프가 돌거나 레이아웃 계산이 꼬입니다.\n // 바디 영역 리사이즈 시에는 body만 refreshLayout 해주면 됩니다!\n if (resolvedContainerType === 'left' || resolvedContainerType === 'right') {\n this.refreshLayout('body');\n }\n\n this.#sheet.rowManager?.refresh();\n }\n\n #checkIsAutoFit(targetCell) {\n if (this.#sheet.isAutoFitCol) return true;\n const table = targetCell?.closest('table');\n if (table && table.getAttribute('auto-fit-col') === 'true') return true;\n return false;\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointermove', this.#onPointerMove);\n //this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n //this.#sheet.addEventListener('dblclick', this.#onDblClick);\n\n this.#sheet.addDebounseEventListener('dblclick', this.#onDblClick, 'pointerdown', this.#onPointerDown);\n }\n\n #getContainerType(cell) {\n const container = cell.closest('.ng-container-left, .ng-container-body, .ng-container-right');\n if (!container) return null;\n if (container.classList.contains('ng-container-left')) return 'left';\n if (container.classList.contains('ng-container-right')) return 'right';\n return 'body';\n }\n\n #onPointerMove = (e) => {\n\n\n const headerPart = e.target.closest('thead');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n\n headerPart.querySelectorAll('.resizable-edge').forEach(el => {\n if (el !== cell) el.classList.remove('resizable-edge');\n });\n\n if (!cell || cell.dataset.col === undefined) return;\n if (cell.getAttribute('collapsed') === 'true') return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n const isLeftEdge = offsetX <= RESIZE_OFFSET;\n const isRightEdge = (rect.width - offsetX) <= RESIZE_OFFSET;\n\n if (isLeftEdge) {\n const prevCell = cell.previousElementSibling;\n if (!prevCell || prevCell.getAttribute('collapsed') === 'true') {\n cell.classList.remove('resizable-edge');\n return;\n }\n }\n\n if (isLeftEdge || isRightEdge) {\n cell.classList.add('resizable-edge');\n } else {\n cell.classList.remove('resizable-edge');\n }\n };\n\n #onPointerDown = (e) => {\n\n //const path = e.composedPath();\n //const cell1 = path.find(el => el?.nodeType === Node.ELEMENT_NODE && (el.tagName === 'TH' || el.tagName === 'TD'));\n\n //trace.log(e);\n //trace.log( path, cell1);\n\n //const actualTarget = document.elementFromPoint(e.clientX, e.clientY);\n //if (!actualTarget) return;\n\n trace.log(e.actualTarget, e.target);\n\n const headerPart = e.actualTarget.closest('thead');\n if (!headerPart) return;\n\n const cell = e.actualTarget.closest('th, td');\n trace.log(cell, e.actualTarget);\n\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n\n\n e.preventDefault();\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n let targetCell = cell;\n\n if (offsetX <= RESIZE_OFFSET) {\n const prevCell = cell.previousElementSibling;\n if (prevCell && prevCell.dataset.col !== undefined && prevCell.getAttribute('collapsed') !== 'true') {\n targetCell = prevCell;\n } else if (!cell.previousElementSibling) {\n return;\n }\n }\n\n this.#targetCell = targetCell;\n this.#targetContainerType = this.#getContainerType(targetCell);\n\n const container = this.#sheet.querySelector(`.ng-container-${this.#targetContainerType}`);\n if (!container) return;\n\n const baseColIndex = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n this.#targetColIndex = baseColIndex + colSpan - 1;\n\n const isAutoFit = this.#checkIsAutoFit(targetCell);\n if (isAutoFit) {\n this.#nextColIndex = this.#targetColIndex + 1;\n const nextColEl = container.querySelector(`col[data-col=\"${this.#nextColIndex}\"]`);\n if (nextColEl) {\n this.#nextColStartWidth = parseInt(nextColEl.getAttribute('width'), 10) || 100;\n } else {\n this.#nextColIndex = null;\n }\n } else {\n this.#nextColIndex = null;\n }\n\n const targetRect = targetCell.getBoundingClientRect();\n const sheetRect = this.#sheet.getBoundingClientRect();\n\n this.#startCellWidth = targetRect.width;\n this.#startLeft = targetRect.left - sheetRect.left;\n\n const targetColEl = container.querySelector(`col[data-col=\"${this.#targetColIndex}\"]`);\n const attrW = targetColEl?.getAttribute('width');\n this.#startColWidth = (attrW && !isNaN(parseInt(attrW, 10))) ? parseInt(attrW, 10) : targetRect.width / colSpan;\n\n this.#startX = e.clientX;\n\n if (this.#panel) {\n this.#panel.classList.add('active');\n this.#updatePositions(e.clientX);\n }\n\n window.addEventListener('pointermove', this.#onDragMove);\n window.addEventListener('pointerup', this.#onDragEnd, { once: true });\n };\n\n #updatePositions(clientX) {\n let diff = clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxDiff = this.#nextColStartWidth - COLLAPSED_WIDTH;\n const minDiff = -(this.#startColWidth - COLLAPSED_WIDTH);\n diff = Math.max(minDiff, Math.min(diff, maxDiff));\n }\n\n const currentColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n\n const targetRect = this.#targetCell.getBoundingClientRect();\n let realCellWidth = clientX - targetRect.left;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxCellWidth = this.#startCellWidth + (this.#nextColStartWidth - COLLAPSED_WIDTH);\n realCellWidth = Math.min(realCellWidth, maxCellWidth);\n }\n\n const currentCellWidth = Math.max(COLLAPSED_WIDTH, realCellWidth);\n\n if (this.#panel) {\n this.#panel.style.setProperty('--tooltip-left', `${this.#startLeft}px`);\n this.#panel.style.setProperty('--tooltip-width', `${currentCellWidth}px`);\n }\n\n const sizeBadge = this.#tooltip?.querySelector('.size-badge');\n if (sizeBadge) {\n sizeBadge.textContent = `${Math.round(currentColWidth)}px`;\n }\n }\n\n #onDragMove = (e) => {\n trace.log(e);\n this.#updatePositions(e.clientX);\n };\n\n #onDragEnd = (e) => {\n window.removeEventListener('pointermove', this.#onDragMove);\n\n const diff = e.clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n let finalWidth = 0;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n let newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n let newNextWidth = this.#startColWidth + this.#nextColStartWidth - newColWidth;\n\n if (newNextWidth < COLLAPSED_WIDTH) {\n newNextWidth = COLLAPSED_WIDTH;\n newColWidth = this.#startColWidth + this.#nextColStartWidth - COLLAPSED_WIDTH;\n }\n\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n this.setColumnWidth(this.#nextColIndex, newNextWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n } else {\n const newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n if (this.#targetColIndex !== null && this.#targetContainerType) {\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n }\n }\n\n if (this.#targetCell) {\n const targetCell = this.#targetCell;\n if (targetCell.getAttribute('collapsed') !== 'true' && finalWidth > 20) {\n targetCell.dataset.expandWidth = String(finalWidth);\n }\n }\n\n if (this.#panel) {\n this.#tooltip?.classList.add('fade-out');\n setTimeout(() => {\n this.#panel.classList.remove('active');\n this.#tooltip?.classList.remove('fade-out');\n }, 150);\n }\n\n this.#targetColIndex = null;\n this.#nextColIndex = null;\n this.#targetContainerType = null;\n this.#targetCell = null;\n };\n\n #onDblClick = (e) => {\n\n const targetEl = e.target;\n let cell = targetEl.closest('th, td');\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n if (offsetX <= RESIZE_OFFSET) {\n cell = cell.previousElementSibling;\n }\n\n const baseColIndex = parseInt(cell.dataset.col, 10);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${baseColIndex}\"]`);\n if (!tbodyCell || !tbodyCell.dataset.bind || tbodyCell.classList.contains(\"CELL-RADIO\")) return;\n\n let extraPadding = 0;\n Array.from(tbodyCell.firstElementChild.children).forEach(($el) => {\n switch ($el.tagName) {\n case 'SPAN': extraPadding += 8; break;\n case 'DIV': extraPadding += 8; break;\n case 'BUTTON': extraPadding += 32; break;\n case 'SELECT': extraPadding += 32; break;\n case 'INPUT':\n switch (($el.type || 'text').toLowerCase()) {\n // 1. 체크박스 / 라디오 (비교적 좁은 영역)\n case 'checkbox':\n case 'radio':\n extraPadding += 12;\n break;\n\n // 2. 버튼 계열 input\n case 'button':\n case 'submit':\n case 'reset':\n case 'image':\n extraPadding += 16;\n break;\n\n // 3. 특수 위젯 (컬러, 파일, 슬라이더)\n case 'color':\n case 'file':\n case 'range':\n extraPadding += 24;\n break;\n\n // 4. 화면에 안 보이는 hidden 필드\n case 'hidden':\n extraPadding += 0;\n break;\n\n // 5. 텍스트 및 숫자, 날짜 등 일반 입력 필드 (기본값)\n case 'text':\n case 'search':\n case 'tel':\n case 'url':\n case 'email':\n case 'password':\n case 'number':\n case 'date':\n case 'time':\n case 'datetime-local':\n case 'month':\n case 'week':\n default:\n extraPadding += 16;\n break;\n }\n break;\n }\n });\n\n trace.log(extraPadding);\n\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n\n // 헤더 텍스트 길이 측정\n const headerText = cell.innerText || \"\";\n const headerSize = nine.measureTextSize(headerText, font);\n let maxTextWidth = (headerSize.width || 0) + 16;\n\n this.#host.execute(() => {\n\n this.#sheet.view.getArray().forEach((record, idx) => {\n const val = String(tbodyCell.dataset.expr ? this.#host.exprEngine.evaluate(tbodyCell.dataset.expr, record, idx) : record.v[fieldIdx] ?? \"\").trim();\n const size = nine.measureTextSize(val, font);\n if (size.width && size.width > maxTextWidth) {\n maxTextWidth = size.width;\n }\n });\n\n // 글자 수 당 대략적인 픽셀 계산 (기본 패딩 여백 포함, 최소 32px ~ 최대 400px 제한)\n const calculatedWidth = Math.max(32, Math.min(400, Math.ceil(maxTextWidth) + extraPadding));\n\n // 자동 계산된 너비 적용\n this.setColumnWidth(tbodyCell.dataset.col, calculatedWidth, this.#getContainerType(cell));\n })\n };\n}\n\n","// ui/col/ColMover.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColMover {\n #sheet;\n #grip;\n #indi;\n\n #isDragging = false;\n #sourceCell = null;\n #sourceColIndex = null;\n #targetColIndex = null;\n #shiftX = 0;\n #timer = null;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#grip = this.#sheet.querySelector('.ng-col-mover-grip');\n this.#indi = this.#sheet.querySelector('.ng-col-mover-indi');\n this.bindEvents();\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n }\n\n #checkIsMovable() {\n const host = this.#sheet.getRootNode()?.host;\n return this.#sheet.getAttribute('col-movable') === 'true' || host?.getAttribute('col-movable') === 'true';\n }\n\n #getDeepElementFromPoint(x, y) {\n const root = this.#sheet.getRootNode();\n let el = root.elementFromPoint ? root.elementFromPoint(x, y) : document.elementFromPoint(x, y);\n\n while (el && el.shadowRoot && el.shadowRoot.elementFromPoint) {\n const nested = el.shadowRoot.elementFromPoint(x, y);\n if (!nested || nested === el) break;\n el = nested;\n }\n\n return el;\n }\n\n #getColGroupRange(cell) {\n if (!cell || cell.dataset.col === undefined) return null;\n\n const startCol = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const endCol = startCol + colSpan - 1;\n const rowIndex = cell.closest('tr')?.sectionRowIndex ?? 0;\n\n const table = cell.closest('table');\n if (!table) return { startCol, colSpan, endCol, rowIndex, isGroup: false, parentGroupRange: null, isValidGroup: true };\n\n const headerCells = table.querySelectorAll('thead th, thead td');\n let hasStrictChildren = false;\n let isValidGroup = true;\n let parentGroupRange = null;\n\n for (const subCell of headerCells) {\n if (subCell === cell || subCell.dataset.col === undefined) continue;\n\n const subStart = parseInt(subCell.dataset.col, 10);\n const subSpan = subCell.colSpan || 1;\n const subEnd = subStart + subSpan - 1;\n const subRowIndex = subCell.closest('tr')?.sectionRowIndex ?? 0;\n\n if (subRowIndex < rowIndex && subStart <= startCol && subEnd >= endCol && subSpan > colSpan) {\n if (!parentGroupRange) {\n parentGroupRange = { startCol: subStart, endCol: subEnd };\n } else {\n parentGroupRange.startCol = Math.max(parentGroupRange.startCol, subStart);\n parentGroupRange.endCol = Math.min(parentGroupRange.endCol, subEnd);\n }\n }\n\n const isOverlap = !(subEnd < startCol || subStart > endCol);\n if (isOverlap) {\n const isFullyContained = (subStart >= startCol && subEnd <= endCol);\n\n if (isFullyContained) {\n if (subSpan < colSpan) {\n hasStrictChildren = true;\n }\n } else if (subStart < startCol || subEnd > endCol) {\n if (!(subStart <= startCol && subEnd >= endCol)) {\n isValidGroup = false;\n }\n }\n }\n }\n\n const isRealGroup = hasStrictChildren && isValidGroup;\n\n return {\n startCol,\n colSpan: isRealGroup ? colSpan : 1,\n endCol: isRealGroup ? endCol : startCol,\n rowIndex,\n isGroup: isRealGroup,\n parentGroupRange,\n isValidGroup\n };\n }\n\n #createGroupHeaderPreview(cell) {\n const groupRange = this.#getColGroupRange(cell);\n if (!groupRange) return null;\n\n const { startCol, endCol, isGroup } = groupRange;\n\n // 핵심: 테이블이 여러 개인 구조이므로 cell이 속한 바로 그 테이블을 직접 가져옵니다.\n const origTable = cell.closest('table');\n if (!origTable) return null;\n\n let minLeft = Infinity, maxRight = -Infinity, minTop = Infinity, maxBottom = -Infinity;\n const targetCells = [];\n\n origTable.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n const isTarget = isGroup\n ? (cCol >= startCol && cEnd <= endCol)\n : (c === cell);\n\n if (isTarget) {\n const rect = c.getBoundingClientRect();\n minLeft = Math.min(minLeft, rect.left);\n maxRight = Math.max(maxRight, rect.right);\n minTop = Math.min(minTop, rect.top);\n maxBottom = Math.max(maxBottom, rect.bottom);\n\n const computedStyle = window.getComputedStyle(c);\n targetCells.push({ el: c, rect, style: computedStyle });\n }\n });\n\n if (targetCells.length === 0) return null;\n\n const groupWidth = maxRight - minLeft;\n const groupHeight = maxBottom - minTop;\n\n const headerContent = document.createElement('div');\n headerContent.className = 'grip-header-content';\n headerContent.style.position = 'relative';\n headerContent.style.width = `${groupWidth}px`;\n headerContent.style.height = `${groupHeight}px`;\n\n targetCells.forEach(({ el, rect, style }) => {\n const clonedCell = el.cloneNode(true);\n\n clonedCell.style.position = 'absolute';\n clonedCell.style.left = `${rect.left - minLeft}px`;\n clonedCell.style.top = `${rect.top - minTop}px`;\n\n clonedCell.style.width = `${rect.width}px`;\n clonedCell.style.minWidth = `${rect.width}px`;\n clonedCell.style.maxWidth = 'none';\n\n clonedCell.style.height = `${rect.height}px`;\n clonedCell.style.boxSizing = 'border-box';\n clonedCell.style.margin = '0';\n\n clonedCell.style.backgroundColor = style.backgroundColor !== 'transparent' && style.backgroundColor !== 'rgba(0, 0, 0, 0)'\n ? style.backgroundColor\n : '#f9fafb';\n clonedCell.style.color = style.color;\n clonedCell.style.font = style.font;\n clonedCell.style.fontWeight = style.fontWeight;\n clonedCell.style.fontSize = style.fontSize;\n clonedCell.style.textAlign = style.textAlign;\n clonedCell.style.padding = style.padding;\n clonedCell.style.border = style.border;\n clonedCell.style.borderRight = style.borderRight;\n clonedCell.style.borderBottom = style.borderBottom;\n clonedCell.style.display = 'flex';\n clonedCell.style.alignItems = 'center';\n clonedCell.style.justifyContent = style.textAlign === 'center' ? 'center' : (style.textAlign === 'right' ? 'flex-end' : 'flex-start');\n\n headerContent.appendChild(clonedCell);\n });\n\n return {\n element: headerContent,\n bounds: {\n left: minLeft,\n right: maxRight,\n top: minTop,\n bottom: maxBottom,\n width: groupWidth,\n height: groupHeight\n }\n };\n }\n\n #onPointerDown = (e) => {\n if (!this.#checkIsMovable()) return;\n\n const headerPart = e.target.closest('.ng-sheet-header');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n if (!cell || cell.classList.contains('resizable-edge') || ['INPUT', 'BUTTON'].includes(e.target.tagName)) return;\n if (cell.dataset.col === undefined) return;\n\n e.preventDefault();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cancelTimer = () => {\n if (this.#timer) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n window.removeEventListener('pointermove', onPointerMovePending);\n window.removeEventListener('pointerup', cancelTimer);\n window.removeEventListener('pointercancel', cancelTimer);\n };\n\n const onPointerMovePending = (moveEvent) => {\n const dist = Math.hypot(moveEvent.clientX - startX, moveEvent.clientY - startY);\n if (dist > 5) {\n cancelTimer();\n }\n };\n\n this.#timer = setTimeout(() => {\n cancelTimer();\n this.#startDrag(e, cell);\n }, 500);\n\n window.addEventListener('pointermove', onPointerMovePending);\n window.addEventListener('pointerup', cancelTimer, { once: true });\n window.addEventListener('pointercancel', cancelTimer, { once: true });\n };\n\n #startDrag(e, cell) {\n if (this.#isDragging) return;\n\n const preview = this.#createGroupHeaderPreview(cell);\n if (!preview) return;\n\n this.#isDragging = true;\n this.#sourceCell = cell;\n this.#sourceColIndex = parseInt(cell.dataset.col, 10);\n\n const sheetRect = this.#sheet.getBoundingClientRect();\n const { bounds, element } = preview;\n\n this.#shiftX = e.clientX - bounds.left;\n\n if (this.#grip) {\n this.#grip.replaceChildren(element);\n\n const relativeTop = bounds.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#grip.style.width = `${bounds.width}px`;\n this.#grip.style.height = `${fullHeight}px`;\n this.#grip.style.top = `${relativeTop}px`;\n this.#grip.style.display = 'block';\n\n this.#updateGripPosition(e.clientX);\n }\n\n document.body.style.cursor = 'move';\n\n window.addEventListener('pointermove', this.#onPointerMove);\n window.addEventListener('pointerup', this.#onPointerUp, { once: true });\n }\n\n #onPointerMove = (e) => {\n if (!this.#isDragging) return;\n\n this.#updateGripPosition(e.clientX);\n\n if (this.#grip) this.#grip.style.pointerEvents = 'none';\n if (this.#indi) this.#indi.style.pointerEvents = 'none';\n\n const targetElement = this.#getDeepElementFromPoint(e.clientX, e.clientY);\n const targetCell = targetElement?.closest('.ng-sheet-header th, .ng-sheet-header td');\n\n if (targetCell && targetCell.dataset.col !== undefined) {\n const targetColIndex = parseInt(targetCell.dataset.col, 10);\n const sheetRect = this.#sheet.getBoundingClientRect();\n const table = targetCell.closest('table');\n\n let colMinLeft = Infinity;\n let colMaxRight = -Infinity;\n\n if (table) {\n table.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n if (cCol <= targetColIndex && cEnd >= targetColIndex) {\n const cRect = c.getBoundingClientRect();\n colMinLeft = Math.min(colMinLeft, cRect.left);\n colMaxRight = Math.max(colMaxRight, cRect.right);\n }\n });\n }\n\n if (colMinLeft === Infinity) {\n const rect = targetCell.getBoundingClientRect();\n colMinLeft = rect.left;\n colMaxRight = rect.right;\n }\n\n const midX = colMinLeft + ((colMaxRight - colMinLeft) / 2);\n let calculatedTargetCol = 0;\n let indicatorLeft = 0;\n\n if (e.clientX < midX) {\n calculatedTargetCol = targetColIndex;\n indicatorLeft = colMinLeft - sheetRect.left;\n } else {\n const colSpan = targetCell.colSpan || 1;\n calculatedTargetCol = targetColIndex + colSpan;\n indicatorLeft = colMaxRight - sheetRect.left;\n }\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n const movingSpan = sourceGroup.colSpan;\n\n const sourceRowStart = sourceGroup.rowIndex;\n const sourceRowSpan = this.#sourceCell.rowSpan || 1;\n const sourceRowEnd = sourceRowStart + sourceRowSpan - 1;\n\n const targetRowStart = targetCell.closest('tr')?.sectionRowIndex ?? 0;\n const targetRowSpan = targetCell.rowSpan || 1;\n const targetRowEnd = targetRowStart + targetRowSpan - 1;\n\n const isRowSpanCompatible = !(sourceRowEnd < targetRowStart || sourceRowStart > targetRowEnd);\n\n let isOutOfBoundsOfParent = false;\n if (sourceGroup.parentGroupRange) {\n const { startCol: pStart, endCol: pEnd } = sourceGroup.parentGroupRange;\n if (calculatedTargetCol < pStart || (calculatedTargetCol + movingSpan - 1) > pEnd) {\n isOutOfBoundsOfParent = true;\n }\n }\n\n let isDroppingInsideOtherGroup = false;\n if (table) {\n const spannedCells = table.querySelectorAll('thead th[colspan], thead td[colspan]');\n\n for (const sCell of spannedCells) {\n if (sCell === this.#sourceCell) continue;\n\n const sRowStart = sCell.closest('tr')?.sectionRowIndex ?? 0;\n const sRowSpan = sCell.rowSpan || 1;\n const sRowEnd = sRowStart + sRowSpan - 1;\n\n const isVerticalOverlap = !(sourceRowEnd < sRowStart || sourceRowStart > sRowEnd);\n if (!isVerticalOverlap) continue;\n\n const sStart = parseInt(sCell.dataset.col, 10);\n const sSpan = sCell.colSpan || 1;\n const sEnd = sStart + sSpan - 1;\n\n if (calculatedTargetCol > sStart && calculatedTargetCol < sEnd + 1) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n\n const moveEndCol = calculatedTargetCol + movingSpan - 1;\n const isCrossIntersecting = (\n (calculatedTargetCol > sStart && calculatedTargetCol <= sEnd && moveEndCol > sEnd) ||\n (calculatedTargetCol < sStart && moveEndCol >= sStart && moveEndCol < sEnd)\n );\n\n if (isCrossIntersecting) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n }\n }\n\n const isSelfGroup = (\n calculatedTargetCol >= sourceGroup.startCol &&\n calculatedTargetCol <= sourceGroup.endCol + 1\n );\n\n const isInvalidMove = !isRowSpanCompatible || isSelfGroup || isOutOfBoundsOfParent || isDroppingInsideOtherGroup || !sourceGroup.isValidGroup;\n\n if (isInvalidMove) {\n this.#targetColIndex = null;\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n } else {\n this.#targetColIndex = calculatedTargetCol;\n if (this.#grip) this.#grip.classList.remove('invalid');\n\n if (this.#indi) {\n const headerPart = targetCell.closest('.ng-sheet-header');\n const headerRect = headerPart.getBoundingClientRect();\n const relativeTop = headerRect.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#indi.style.top = `${relativeTop}px`;\n this.#indi.style.height = `${fullHeight}px`;\n this.#indi.style.left = `${indicatorLeft - 1}px`;\n this.#indi.style.display = 'block';\n }\n }\n } else {\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n this.#targetColIndex = null;\n }\n };\n\n #updateGripPosition(clientX) {\n if (!this.#grip) return;\n const sheetRect = this.#sheet.getBoundingClientRect();\n const left = clientX - sheetRect.left - this.#shiftX;\n this.#grip.style.left = `${left}px`;\n }\n\n #onPointerUp = (e) => {\n if (!this.#isDragging) return;\n\n window.removeEventListener('pointermove', this.#onPointerMove);\n document.body.style.cursor = '';\n\n if (this.#grip) {\n this.#grip.style.display = 'none';\n this.#grip.replaceChildren();\n }\n if (this.#indi) this.#indi.style.display = 'none';\n\n if (\n this.#targetColIndex !== null &&\n this.#sourceColIndex !== null &&\n this.#targetColIndex !== this.#sourceColIndex &&\n this.#targetColIndex !== this.#sourceColIndex + 1\n ) {\n this.moveColumn(this.#sourceColIndex, this.#targetColIndex);\n }\n\n this.#isDragging = false;\n this.#sourceCell = null;\n this.#sourceColIndex = null;\n this.#targetColIndex = null;\n };\n\n moveColumn(fromColIndex, toColIndex) {\n\n trace.log(this.#sheet.sourceTable.cloneNode(true));\n\n const colgroup = this.#sheet.sourceTable.querySelector('colgroup');\n const targetCol = colgroup.querySelector(`col[data-col=\"${toColIndex}\"]`);\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n if (!sourceGroup || !sourceGroup.isValidGroup) return;\n\n const spanCount = sourceGroup.colSpan;\n const isInRange = (idx) => idx >= fromColIndex && idx < fromColIndex + spanCount;\n\n // 1. colgroup 내 <col> 이동 및 fixed 설정\n const targetViewportCol = this.#sheet.querySelector(`.ng-sheet-body-content col[data-col=\"${toColIndex}\"]`);\n const fixedType = targetViewportCol?.closest('.ng-container-left') ? 'left' : targetViewportCol?.closest('.ng-container-right') ? 'right' : null;\n\n colgroup.querySelectorAll('col').forEach(col => {\n if (isInRange(parseInt(col.getAttribute('data-col'), 10))) {\n fixedType ? col.setAttribute('fixed', fixedType) : col.removeAttribute('fixed');\n colgroup.insertBefore(col, targetCol);\n }\n });\n\n // 2. 테이블 행(tr) 내부의 셀(th, td) 순서 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n this.#sheet.sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n const cells = Array.from(tr.children);\n const targetRowCell = cells.find(c => parseInt(c.dataset.col, 10) >= toColIndex);\n\n cells.forEach(cell => {\n if (isInRange(parseInt(cell.dataset.col, 10))) {\n tr.insertBefore(cell, targetRowCell || null);\n }\n });\n });\n });\n\n this.#sheet.recompileAndRefresh();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n }\n}","// ui/col/ColFixManager.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColFixManager {\n #sheet;\n\n constructor(sheet) {\n this.#sheet = sheet;\n }\n\n /**\n * 🎯 현재 클릭된 셀의 고정 구역('left', 'right', 'none') 탐색\n */\n getFixState(targetCell, table) {\n if (!targetCell || !table) return 'none';\n\n // 🎯 [보정] 3분할 레이어 구조 내부의 컨테이너를 안전하게 탐색\n const container = targetCell.closest('.ng-container-left, .ng-container-right, .ng-container-body');\n if (container?.classList.contains('ng-container-left')) return 'left';\n if (container?.classList.contains('ng-container-right')) return 'right';\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n if (!isNaN(baseCol)) {\n const colEl = table.querySelector(`colgroup col[data-col=\"${baseCol}\"]`);\n const fixedAttr = colEl?.getAttribute('fixed');\n if (fixedAttr) return fixedAttr;\n }\n\n return 'none';\n }\n\n /**\n * 🎯 상하 멀티 헤더 경계선 일치 여부 검사 (Fix Column 가부 판별)\n */\n canFixColumn(targetCell, table) {\n if (!targetCell || targetCell.tagName !== 'TH' || !table) return false;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n if (isNaN(baseCol)) return false;\n\n const targetBoundaryCol = baseCol + colSpan - 1;\n const theadTrs = Array.from(table.querySelectorAll('thead tr'));\n\n if (theadTrs.length <= 1) return true;\n\n for (const tr of theadTrs) {\n const cells = Array.from(tr.querySelectorAll('th, td'));\n let cellBoundaryFound = false;\n\n for (const cell of cells) {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEndCol = cCol + cSpan - 1;\n\n // 목표 경계선이 특정 셀의 중간을 관통하는 경우 (Fix 불가능)\n if (cCol <= targetBoundaryCol && targetBoundaryCol < cEndCol) {\n return false;\n }\n\n if (cEndCol === targetBoundaryCol) {\n cellBoundaryFound = true;\n break;\n }\n }\n\n if (!cellBoundaryFound) return false;\n }\n\n return true;\n }\n\n /**\n * 🎯 [인스턴스 메서드] 배치 범위 고정 및 해제 처리\n * - 원본(`sourceTable`)의 구조(fixed 속성)를 직접 조작하므로 decompile은 절대 호출하지 않음!\n */\n executeFixToggle(action, targetCell, fixType = 'left') {\n if (!this.#sheet || !targetCell) return;\n\n const sourceTable = this.#sheet.sourceTable;\n if (!sourceTable) return;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n const targetColIndex = baseCol + colSpan - 1;\n\n if (isNaN(targetColIndex)) return;\n\n const colgroup = sourceTable.querySelector('colgroup');\n if (!colgroup) return;\n\n const cols = Array.from(colgroup.querySelectorAll('col'));\n\n if (action === 'fix-column') {\n // 🎯 Batch Fix: 0번부터 targetColIndex까지의 모든 <col>과 셀에 fixed 속성 일괄 부여\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx <= targetColIndex) {\n col.setAttribute('fixed', fixType);\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (!isNaN(cIdx) && cIdx <= targetColIndex) {\n cell.setAttribute('fixed', fixType);\n }\n });\n });\n });\n\n } else if (action === 'unfix-column') {\n let minBaseCol = baseCol;\n let maxEndCol = baseCol + colSpan - 1;\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach((tr, rIdx) => {\n Array.from(tr.children).forEach(cell => {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n const rSpan = cell.rowSpan || 1;\n const trIndex = tr.sectionRowIndex ?? rIdx;\n\n // 현재 클릭된 셀의 수직 범위와 겹치는 머지 셀이 있는지 검사\n const isVerticalOverlap = !(trIndex + rSpan - 1 < cell.closest('tr').sectionRowIndex || trIndex > (cell.closest('tr').sectionRowIndex + rSpan - 1));\n\n // 만약 기존에 고정(fixed)되어 있으면서 현재 클릭한 타겟 라인과 걸쳐있는 머지 셀이라면 범위를 확장합니다.\n const isHorizontalOverlap = !(cEnd < baseCol || cCol > targetColIndex);\n\n if (isHorizontalOverlap) {\n minBaseCol = Math.min(minBaseCol, cCol);\n maxEndCol = Math.max(maxEndCol, cEnd);\n }\n });\n });\n });\n\n // 🎯 2단계: 계산된 실제 머지 블록의 시작점(minBaseCol) 이상인 모든 <col> 속성 해제\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx >= minBaseCol) {\n col.removeAttribute('fixed');\n }\n });\n\n // 🎯 3단계: left 구역의 고정 연속성(체인) 검증\n let isBroken = false;\n cols.forEach(col => {\n if (isBroken) {\n col.removeAttribute('fixed');\n } else if (!col.getAttribute('fixed')) {\n isBroken = true;\n }\n });\n\n // 🎯 4단계: <col>들의 최종 fixed 상태를 기준으로 모든 thead, tbody, tfoot 셀(th, td)의 fixed 속성 완벽 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (isNaN(cIdx)) return;\n\n const correspondingCol = cols.find(c => parseInt(c.getAttribute('data-col'), 10) === cIdx);\n const isColFixed = correspondingCol?.getAttribute('fixed');\n\n if (isColFixed) {\n cell.setAttribute('fixed', isColFixed);\n } else {\n cell.removeAttribute('fixed');\n }\n });\n });\n });\n }\n\n trace.log(this.#sheet.sourceTable);\n\n // 🎯 recompileAndRefresh 단 1회 호출로 원본 정렬 및 뷰포트 재생성 완결\n this.#sheet.recompileAndRefresh?.();\n }\n}","import { NINE_TABLE } from '@/core/constants.js';\r\nimport { trace } from \"@nopeer\";\r\n\r\n/**\r\n * 🎯 [필터 패널 커스텀 엘리먼트 Light DOM 버전]\r\n */\r\nexport class NineTableFilterPanel extends HTMLElement {\r\n\t#sheet;\r\n\t#host;\r\n\t#nineTable;\r\n\t#view;\r\n\t#button;\r\n\tcurrentCol = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#init();\r\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\r\n\t}\r\n\r\n\t#init = () => {\r\n\t\t//setTimeout(() => {\r\n\t\t\tthis.#renderer();\r\n\r\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\r\n\t\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\r\n\t\t\ttrace.log(\"1***********************\", this.#nineTable);\r\n\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\r\n\t\t\t\ttrace.log(\"2***********************\", this.#view);\r\n\t\t\t})\r\n\r\n\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t});\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\r\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\r\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\r\n\t\t//});\r\n\t}\r\n\r\n\t#renderer = () => {\r\n\t\tthis.innerHTML = `\r\n <style>\r\n nine-table-filter-panel nine-table-simple {\r\n width: 100%;\r\n flex: 1;\r\n border: none;\r\n }\r\n nine-table-filter-panel.active {\r\n display: flex;\r\n }\r\n nine-table-filter-panel .search-box {\r\n width: 100%;\r\n height: 28px;\r\n box-sizing: border-box;\r\n padding: 0px 8px;\r\n border: none;\r\n border-bottom: 1px solid #e5e7eb;\r\n border-radius: 0px;\r\n outline: none;\r\n font-size: 12px;\r\n background: #fafafa;\r\n color: #333;\r\n }\r\n nine-table-filter-panel .search-box:focus {\r\n background: #ffffff;\r\n }\r\n nine-table-filter-panel .footer-section {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 4px 6px;\r\n gap: 8px;\r\n border-top: 1px solid #e5e7eb;\r\n background: #f9fafb;\r\n flex-shrink: 0;\r\n }\r\n nine-table-filter-panel .footer-btns {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 6px;\r\n }\r\n nine-table-filter-panel .footer-btns label {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n cursor: pointer;\r\n user-select: none;\r\n }\r\n nine-table-filter-panel .btn-group {\r\n display: flex;\r\n gap: 4px;\r\n }\r\n nine-table-filter-panel button {\r\n padding: 4px 14px;\r\n border-radius: 4px;\r\n border: 1px solid #d1d5db;\r\n background: #ffffff;\r\n cursor: pointer;\r\n font-size: 11px;\r\n }\r\n nine-table-filter-panel button:hover {\r\n background: #f3f4f6;\r\n }\r\n nine-table-filter-panel button#btnOk {\r\n background: #2563eb;\r\n color: white;\r\n border: none;\r\n }\r\n </style>\r\n\r\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\r\n \r\n <nine-table-simple class=\"filter-list\" theme=\"simple\">\r\n <table auto-fit-col=\"true\">\r\n <colgroup>\r\n <col width=\"32\" fixed=\"left\" />\r\n <col width=\"180\" />\r\n <col width=\"0\" fixed=\"right\"/>\r\n </colgroup>\r\n <tbody>\r\n <tr>\r\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\r\n <td data-bind=\"DATA2\" html=\"true\"></td>\r\n <td data-bind=\"DATA\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </nine-table-simple>\r\n\r\n <div class=\"footer-section\">\r\n <div class=\"footer-btns\">\r\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\r\n <div class=\"btn-group\">\r\n <button id=\"btnOk\">Apply</button>\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n\t}\r\n\r\n\topen(filterBtn) {\r\n\t\tthis.#button = filterBtn;\r\n\r\n\t\tconst cell = filterBtn.closest(\"th, td\");\r\n\t\tthis.currentCol = cell?.dataset.col;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\r\n\r\n\t\tconst panelWidth = this.offsetWidth || 240;\r\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\r\n\t\tlet top = cellRect.bottom - sheetRect.top;\r\n\r\n\t\tif (left < 0) {\r\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\r\n\t\t}\r\n\r\n\t\tthis.style.left = `${left}px`;\r\n\t\tthis.style.top = `${top}px`;\r\n\r\n\t\tconst searchBox = this.querySelector(\".search-box\");\r\n\t\tsearchBox.value = \"\";\r\n\r\n\t\tthis.classList.add(\"active\");\r\n\t\tthis.classList.add(\"loading\");\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tthis.#loadVirtualFilterItems();\r\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\r\n\t\t\t} finally {\r\n\t\t\t\tthis.classList.remove(\"loading\");\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t#closeHandler = (e) => {\r\n\t\tconst path = e.composedPath ? e.composedPath() : [];\r\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.close();\r\n\t};\r\n\r\n\tclose() {\r\n\t\tthis.currentCol = null;\r\n\t\tthis.classList.remove(\"active\");\r\n\t\tthis.#button = null;\r\n\t}\r\n\r\n\t#loadVirtualFilterItems() {\r\n\t\tconst filteredRecords = this.#host.data.getArray();\r\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] 형태 배열\r\n\t\tconst fields = this.#host.fields.get() || [];\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst ds = targetCols.flatMap((colInfo) => {\r\n\t\t\tconst bindKey = colInfo.bind;\r\n\t\t\tconst exprKey = colInfo.expr;\r\n\r\n\t\t\tconst filterKey = bindKey || exprKey; // 실제 필터 파라미터 키로 사용\r\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\r\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\r\n\r\n\t\t\t// 1. Map을 이용한 O(N) 고속 유니크 추출 (DATA는 bind/원시값, DATA2는 expr 연산 결과)\r\n\t\t\tconst uniqueMap = new Map();\r\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\r\n\t\t\t\tconst record = filteredRecords[i];\r\n\t\t\t\tif (!record) continue;\r\n\r\n\t\t\t\t// DATA 기준이 될 원시 값 (bind가 있으면 필드 인덱스에서, 없으면 expr 결과)\r\n\t\t\t\tlet rawVal = undefined;\r\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\trawVal = record.v[fieldIdx];\r\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\r\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\r\n\t\t\t\t} else if (exprKey && exprEngine) {\r\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// DATA2에 출력될 화면 표시 값 (expr 수식 연산 결과, 없으면 rawVal)\r\n\t\t\t\tlet displayVal = rawVal;\r\n\t\t\t\tif (exprKey && exprEngine) {\r\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\r\n\t\t\t\t\tuniqueMap.set(displayVal, {\r\n\t\t\t\t\t\tv: rawVal, // 💡 필터링 비교 기준 (DATA)\r\n\t\t\t\t\t\tv2: displayVal // 💡 화면 출력 기준 (DATA2)\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst uniqueList = [...uniqueMap.values()];\r\n\r\n\t\t\t// 2. 출력값(v2) 기준 정렬\r\n\t\t\tuniqueList.sort((a, b) => String(a.v2 || \"\").localeCompare(String(b.v2 || \"\")));\r\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\r\n\r\n\t\t\treturn uniqueList.map(o => ({\r\n\t\t\t\tLVL: 2,\r\n\t\t\t\tDATA: o.v, // 필터링 비교용 값\r\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2, // 화면 출력용 값\r\n\t\t\t\tCOLNM: filterKey,\r\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v || \"\") >= 0 ? \"Y\" : \"N\"\r\n\t\t\t}));\r\n\t\t});\r\n\r\n\t\tthis.#nineTable.data.set(ds);\r\n\r\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\r\n\t\tif (selectAllChk) {\r\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\r\n\t\t}\r\n\t}\r\n\r\n\t#onOk = () => {\r\n\t\tthis.#host.loading = true;\r\n\r\n\t\tconst filterRecords = this.#view.view.getArray();\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\r\n\t\tconst checkedRecords = filterRecords.filter(record => {\r\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\r\n\t\t\treturn (chk === \"Y\" || chk === true);\r\n\t\t});\r\n\r\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\r\n\r\n\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\r\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\r\n\r\n\t\t\tif (selectedVals.length > 0) {\r\n\t\t\t\tfilterParams[filterKey] = selectedVals;\r\n\t\t\t} else {\r\n\t\t\t\tdelete filterParams[filterKey];\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tconst totalCount = this.#nineTable.data.count();\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tif (totalCount === checkedRecords.length) {\r\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\t\t\tbtn.updateFilteredState();\r\n\t\t\t\t});\r\n\r\n\t\t\t\tthis.#sheet.invalidate();\r\n\t\t\t\tthis.close();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.#host.loading = false;\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t#onInput = (e) => {\r\n\r\n\t\tconst query = e.target.value.toLowerCase().trim();\r\n\r\n\t\tif (!query) {\r\n\t\t\tthis.#view.filtering.clear();\r\n\t\t} else {\r\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\r\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\r\n\r\n\t\t\tconst matchedValues = [];\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\r\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\r\n\r\n\t\t\t\t// 💡 expr 연산 결과가 담긴 DATA2 텍스트와 검색어 비교\r\n\t\t\t\tif (textVal.includes(query)) {\r\n\t\t\t\t\tmatchedValues.push(val);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\ttrace.log(matchedValues);\r\n\r\n\t\t\tthis.#view.filtering.set({\r\n\t\t\t\tDATA2: [...new Set(matchedValues)]\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t#onSelectAll = (e) => {\r\n\t\tconst isChecked = e.target.checked;\r\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\r\n\r\n\t\tif (chkIdx >= 0) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#nineTable.refresh();\r\n\t};\r\n\r\n\t#onCancel = () => {\r\n\t\tthis.close();\r\n\t};\r\n}\r\n\r\nexport class NineTableFilterButton extends HTMLElement {\r\n\t#sheet;\r\n\t#columns = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\r\n\t\tthis.removeEventListener(\"click\", this.#onClick);\r\n\t\tthis.addEventListener(\"click\", this.#onClick);\r\n\t}\r\n\r\n\tget columns() {\r\n\t\tif (this.#columns) return this.#columns;\r\n\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst colIndex = cell?.dataset.col;\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\r\n\t\tconst cols = [];\r\n\t\tconst seen = new Set();\r\n\r\n\t\tif (sourceTable && colIndex !== undefined) {\r\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\t\tconst bindKey = $td.dataset.bind;\r\n\t\t\t\tconst exprKey = $td.dataset.expr;\r\n\r\n\t\t\t\tif (bindKey || exprKey) {\r\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\r\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\r\n\t\t\t\t\t\tseen.add(uniqueKey);\r\n\t\t\t\t\t\tcols.push({\r\n\t\t\t\t\t\t\tbind: bindKey,\r\n\t\t\t\t\t\t\texpr: exprKey,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#columns = cols;\r\n\t\treturn this.#columns;\r\n\t}\r\n\r\n\tupdateFilteredState = () => {\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst isFiltered = this.columns.some(colInfo => {\r\n\t\t\tconst key = colInfo.expr || colInfo.bind;\r\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\r\n\t\t});\r\n\t\tthis.classList.toggle('filtered', isFiltered);\r\n\t};\r\n\r\n\t#onClick = (e) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst col = cell?.dataset.col;\r\n\r\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\r\n\t\t\tpanel.close();\r\n\t\t} else if (panel) {\r\n\t\t\tpanel.open(this);\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class Filtering {\r\n\t#sheet;\r\n\t#host;\r\n\t#isFiltering = false;\r\n\t#filterPanel = null;\r\n\t#filters = {};\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t\tthis.#init();\r\n\t}\r\n\r\n\tget filters() {\r\n\t\treturn this.#filters;\r\n\t};\r\n\r\n\t#init = () => {\r\n\t\tthis.#initFilterPanel();\r\n\t}\r\n\r\n\t#initFilterPanel = () => {\r\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tif (!panel) {\r\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\r\n\t\t\tthis.#sheet.appendChild(panel);\r\n\t\t}\r\n\t\tthis.#filterPanel = panel;\r\n\t}\r\n\r\n\tisFiltering() {\r\n\t\treturn this.#isFiltering;\r\n\t}\r\n\r\n\tclear = (colnm) => {\r\n\t\tif (colnm) {\r\n\t\t\tdelete this.#filters[colnm];\r\n\t\t} else {\r\n\t\t\tthis.#filters = {};\r\n\t\t}\r\n\r\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\r\n\t\tthis.#applyFiltering();\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\tbtn.updateFilteredState();\r\n\t\t});\r\n\r\n\t\ttrace.log(`🔄 [NineTableFiltering] Filter cleared for ${colnm || 'all'}`);\r\n\t}\r\n\r\n\tset = (oFilter) => {\r\n\r\n\t\ttrace.log(oFilter);\r\n\r\n\t\tlet jsonFilter = Array.isArray(oFilter)\r\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\r\n\t\t\t: oFilter;\r\n\r\n\t\tthis.#filters = jsonFilter;\r\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\r\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\r\n\r\n\t\tthis.#applyFiltering();\r\n\t}\r\n\r\n\t#applyFiltering() {\r\n\t\tconst hostData = this.#host.data;\r\n\t\tconst rawRecords = hostData.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields();\r\n\t\tconst sheetIndex = this.#sheet.index;\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\r\n\r\n\t\tif (!hasFilters) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\tthis.#sheet.invalidate();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 💡 필터 규칙 빌드 (targetKey가 bind인지 expr 수식인지 판별)\r\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\r\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\r\n\t\t\treturn {\r\n\t\t\t\ttargetKey,\r\n\t\t\t\tisExpr,\r\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\r\n\t\t\t\tallowedSet: new Set(allowedValues)\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\trawRecords.forEach((record, recordIdx) => {\r\n\t\t\tif (!record) return;\r\n\r\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\r\n\t\t\t}\r\n\r\n\t\t\tlet isPass = true;\r\n\r\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\r\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\r\n\t\t\t\tlet val = undefined;\r\n\r\n\t\t\t\tif (isExpr && exprEngine) {\r\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\r\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\tval = record.v[fieldIdx];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!allowedSet.has(val)) {\r\n\t\t\t\t\tisPass = false;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.invalidate();\r\n\t}\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-panel')) {\r\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-button')) {\r\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\r\n}","// ui/data/Sorting.js (또는 정렬 관련 소스)\r\nimport { trace } from \"@nopeer\";\r\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\r\n\r\nexport class Sorting {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#columns = [];\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.#initEvents();\r\n\t\t}, 300);\r\n\t}\r\n\r\n\t#initEvents() {\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\r\n\r\n\t\t\t$el.addEventListener('dblclick', (e) => {\r\n\r\n\t\t\t\tconst cell = e.target.closest('th, td');\r\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\r\n\r\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\r\n\r\n\t\t\t\t// 🎯 [수정] 줄바꿈으로 깨져있던 마이너스 연산자를 한 줄로 정상 복구\r\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\r\n\r\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\r\n\r\n\t\t\t\thost.loading = true;\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tthis.#handleSort(e, cell);\r\n\t\t\t\t\t} finally {\r\n\t\t\t\t\t\t// 🎯 3. 작업이 끝나면 무조건 로딩바 끄기\r\n\t\t\t\t\t\thost.loading = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}); // 또는 requestAnimationF\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\ttrace.log(\"🎯 [NineTableSorting] Initialized\");\r\n\t}\r\n\r\n\t#handleSort(e, cell) {\r\n\t\tconst colIndex = cell.dataset.col;\r\n\t\tconst tr = cell.closest('tr');\r\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\r\n\r\n\t\tif (colIndex === undefined) return;\r\n\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (!sourceTable) return;\r\n\r\n\t\tlet colName = null;\r\n\t\tlet exprVal = null; // 💡 expr 속성 수집용 변수\r\n\r\n\t\t// 1. 🎯 데이터 바인딩 키(colName) 및 expr 탐지\r\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\tif ($td.dataset.bind) {\r\n\t\t\t\tcolName = $td.dataset.bind;\r\n\t\t\t}\r\n\t\t\t// 💡 셀에 선언된 expr 식 추출\r\n\t\t\tif ($td.dataset.expr) {\r\n\t\t\t\texprVal = $td.dataset.expr;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (!colName && !exprVal) return;\r\n\r\n\t\tconst isAsc = cell.classList.contains('asc');\r\n\t\tconst isDesc = cell.classList.contains('desc');\r\n\r\n\t\tif (!e.ctrlKey && !e.shiftKey) {\r\n\t\t\tthis.#columns = [];\r\n\t\t}\r\n\r\n\t\tconst existingColIndex = this.#columns.findIndex(\r\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\r\n\t\t);\r\n\r\n\t\t// 정렬 규칙 추가 시 expr 속성(`expr`) 함께 저장\r\n\t\tconst ruleData = {\r\n\t\t\tcolIndex,\r\n\t\t\tsubRowIndex,\r\n\t\t\tcolname: colName || exprVal,\r\n\t\t\tcolName: colName || exprVal,\r\n\t\t\texpr: exprVal, // 💡 expr 규칙 보관\r\n\t\t\tasc: true,\r\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\r\n\t\t};\r\n\r\n\t\tif (!isAsc && !isDesc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\r\n\t\t\t}\r\n\t\t} else if (isAsc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.#columns = this.#columns.filter(\r\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tthis.#applySorting();\r\n\t}\r\n\r\n\t#applySorting() {\r\n\t\tif (!this.#sheet.view) {\r\n\t\t\tconsole.warn(\"⚠️ [NineTableSorting] Sheet view (SheetView) is not initialized.\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.view.setSorting(this.#columns);\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.invalidate();\r\n\t\t//this.#sheet.rowManager?.refresh(true);\r\n\r\n\t\ttrace.log(\"🔄 [NineTableSorting] Sorting applied via RowManager.refresh(true)\");\r\n\t}\r\n\r\n\t#syncHeaderUI() {\r\n\t\t// 기존 UI 클래스 초기화\r\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\r\n\t\t\tel.classList.remove('asc', 'desc');\r\n\t\t});\r\n\r\n\t\tif (this.#columns.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 🎯 [핵심] tr[data-subrow] + [data-col] 조합으로 정밀 타겟팅\r\n\t\tthis.#columns.forEach(colRule => {\r\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\r\n\r\n\t\t\tif (colIndex !== undefined) {\r\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\r\n\t\t\t\tif (subRowIndex !== undefined) {\r\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\r\n\t\t\t\ttargetHeaderCells.forEach(cell => {\r\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t//TableCompiler.decompile(this.#sheet);\r\n\t}\r\n\r\n\trestore() {\r\n\t\tthis.#columns = [];\r\n\t\tif (this.#sheet.view) {\r\n\t\t\tthis.#sheet.view.resetSorting();\r\n\t\t}\r\n\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.rowManager?.refresh(true);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\nimport {Grouping} from \"@/data/Grouping.js\";\r\n\r\nexport class SheetView {\r\n\t#sheet;\r\n\t#host;\r\n\t#sortingColumns = []; // 정렬 규칙 [{ colname, asc, expr-func }]\r\n\t#filterRules = []; // 필터 규칙\r\n\t#viewIndexes = []; // 필터링 및 소팅이 반영된 유효 데이터 인덱스 버퍼\r\n\r\n\t#cachedVisibleRecords = null; // 💡 [추가] 캐싱된 유효 레코드 배열\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.refresh();\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [시트 뷰 전용 배열 조회] - 캐시 적용으로 성능 대폭 개선\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\t// 💡 캐시가 없거나 비어있을 때만 가져옴 (보통 refresh에서 갱신됨)\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords;\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.#host.data.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord;\r\n\t};\r\n\r\n\tget = (at, colnm) => {\r\n\t\tconst visibleRecords = this.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (!targetRecord) return null;\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#convSingle(targetRecord, fields);\r\n\t};\r\n\r\n\t#convSingle = (o, fields) => {\r\n\t\tif (!o) return null;\r\n\t\tconst t = {};\r\n\t\tfields.forEach((colnm, i) => {\r\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t});\r\n\t\tif (o.m) t.m = o.m;\r\n\t\tif (o._) t._ = o._;\r\n\t\treturn t;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 또는 정렬/필터 변경 시에만 실행되는 뷰 버퍼 재계산\r\n\t */\r\n\t\t// SheetView.refresh() 내부 예시\r\n\trefresh = () => {\r\n\r\n\t\tthis.#cachedVisibleRecords = null;\r\n\r\n\t\t// 1. 필터 적용\r\n\t\tconst rawRecords = this.#host.data.getArray();\r\n\t\tlet indices = [];\r\n\t\trawRecords.forEach((record, i) => {\r\n\t\t\tif (!record) return;\r\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\r\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\r\n\t\t\tindices.push(i);\r\n\t\t});\r\n\r\n\t\ttrace.log(indices);\r\n\r\n\t\t// 2. 정렬 적용\r\n\t\tif (this.#sortingColumns.length > 0) {\r\n\t\t\tindices = this.#applySorting(indices, rawRecords);\r\n\t\t}\r\n\r\n\t\tthis.#viewIndexes = indices;\r\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\r\n\r\n\t\t//trace.log(this.#sheet.sourceTable);\r\n\t\t//const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\r\n\t\t//trace.log(\"#######\", isGrouped, this.#sheet.grouping?.columns);\r\n\t\tconst groupColumns = this.#sheet.grouping?.columns || [];\r\n\t\tif (groupColumns.length > 0) {\r\n\t\t\t//this.#sheet.grouping.apply();\r\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields());\r\n\t\t\t//const groupResult = Grouping.apply(validRecords);\r\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // 최종 렌더링 아이템\r\n\r\n\t\t\t//trace.log(\"2.============================\", groupColumns, this.#cachedVisibleRecords);\r\n\r\n\t\t\tthis.#sheet.grouping.setGroupMap(groupResult.groupMap); // 자식 매핑 공유\r\n\t\t} else {\r\n\t\t\tthis.#cachedVisibleRecords = validRecords;\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n\tsetSorting = (columns) => {\r\n\t\tthis.#sortingColumns = columns || [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\tgetSorting = () => {\r\n\t\treturn this.#sortingColumns;\r\n\t};\r\n\r\n\tresetSorting = () => {\r\n\t\tthis.#sortingColumns = [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\r\n\t#applySorting = (indices, validRecords) => {\r\n\t\ttrace.log(new Date());\r\n\r\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\r\n\r\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\r\n\t\t\t...rule,\r\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\r\n\t\t}));\r\n\r\n\t\treturn indices.sort((idxA, idxB) => {\r\n\t\t\tconst a = validRecords[idxA];\r\n\t\t\tconst b = validRecords[idxB];\r\n\r\n\t\t\tfor (const rule of rulesWithIdx) {\r\n\t\t\t\tconst isAsc = rule.asc;\r\n\t\t\t\tconst expr = rule.expr; // 💡 등록된 expr 수식\r\n\t\t\t\tlet valA, valB;\r\n\r\n\t\t\t\t// 💡 1. expr 수식이 존재하면 ExprEngine으로 연산된 결과값을 가져옴\r\n\t\t\t\tif (expr) {\r\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\r\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 2. 일반 바인딩 필드인 경우 원시 배열에서 추출\r\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\r\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\r\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\r\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\r\n\r\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\r\n\t\t\t\tif (isEmptyA) return 1;\r\n\t\t\t\tif (isEmptyB) return -1;\r\n\r\n\t\t\t\tif (valA !== valB) {\r\n\t\t\t\t\tlet diff = 0;\r\n\r\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\r\n\t\t\t\t\t\tdiff = valA - valB;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst strA = String(valA);\r\n\t\t\t\t\t\tconst strB = String(valB);\r\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (diff !== 0) {\r\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn idxA - idxB;\r\n\t\t});\r\n\r\n\t\ttrace.log(new Date());\r\n\t};\r\n}","import { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class PreCompiler {\n\n static initializeTable(host, tbl) {\n if (!host || !tbl) return null;\n\n // 1. 기본 구조 보장 (colgroup, thead)\n PreCompiler.#ensureColgroup(tbl);\n PreCompiler.#ensureThead(tbl);\n PreCompiler.#ensureSectionTbodys(tbl);\n\n PreCompiler.#ensureRowIndicator(tbl);\n\n PreCompiler.#normalizeColAttributes(tbl);\n\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tfoot tr'));\n\n PreCompiler.#createColIndicator(tbl);\n\n // 2. 속성 정규화 (collapsed=\"true\" -> collapsible=\"true\" 보정)\n PreCompiler.#normalizeCollapsibleAttributes(tbl);\n\n // 3. 셀 커스텀 엘리먼트 생성\n PreCompiler.#generateCell(host, tbl);\n\n // 5. 초기 접힘/펼치기(expand) 버튼 및 너비 세팅\n PreCompiler.#initColExpanders(tbl);\n\n // 6. 필터 버튼 생성\n PreCompiler.#initFilterButtons(host, tbl);\n\n PreCompiler.#applyInitialCellWidths(tbl);\n //tbl.classList.add('nine-table-element');\n\n //trace.log(\"**************\", tbl.cloneNode(true));\n return tbl;\n }\n\n static #createColIndicator(tbl) {\n const thead = tbl.querySelector('thead');\n if (!thead || thead.querySelector('.col-indicator-rowgroup')) return;\n\n const tdTmpl = `<th data-col=\"@col\" class=\"col-indicator\" scope=\"col\"></th>`;\n\n // 맨 위에 인덱스용 row(tr) 삽입\n const tr = thead.insertRow(0);\n tr.setAttribute('role', 'row');\n tr.classList.add('col-indicator-rowgroup');\n tr.classList.add('collapse');\n\n const firstRow = tbl.querySelector('tbody tr');\n if (!firstRow) return;\n\n let cnt = 0;\n firstRow.querySelectorAll('th, td').forEach(td => {\n if (!td.classList.contains('dummy')) {\n const colSpan = td.colSpan || 1;\n for (let i = 0; i < colSpan; i++) {\n const html = tdTmpl.replace('@col', cnt).replace('@text', PreCompiler.#numToExcelCol(cnt++));\n tr.insertAdjacentHTML('beforeend', html);\n }\n }\n });\n\n // 🎯 colgroup의 모든 스타일 및 속성 동기화\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n tr.querySelectorAll('.col-indicator').forEach((el, i) => {\n const background = cols[i].getAttribute('background');\n if (background) {\n el.style.background = background;\n }\n });\n }\n\n // 엑셀 스타일 알파벳 변환 유틸 (A, B, C ... Z, AA, AB ...)\n static #numToExcelCol(num) {\n let text = '';\n for (let n = num; n >= 0; n = Math.floor(n / 26) - 1) {\n text = String.fromCharCode(65 + (n % 26)) + text;\n }\n return text;\n }\n\n static #ensureSectionTbodys(tbl) {\n let tbody = tbl.querySelector('tbody:not(.head):not(.foot)');\n\n if (!tbody) return;\n\n tbody.classList.add('body');\n\n // 🎯 이미 존재하지 않을 때만 생성\n if (!tbl.querySelector('tbody.head')) {\n const headTbody = document.createElement('tbody');\n headTbody.classList.add('head');\n tbody.before(headTbody);\n }\n\n if (!tbl.querySelector('tbody.foot')) {\n const footTbody = document.createElement('tbody');\n footTbody.classList.add('foot');\n tbody.after(footTbody);\n }\n }\n\n static #ensureColgroup(tbl) {\n let colgroup = tbl.querySelector('colgroup');\n if (!colgroup) {\n colgroup = document.createElement('colgroup');\n tbl.prepend(colgroup);\n }\n\n // 🎯 <col> 엘리먼트 자체가 없다면 행 기준으로 생성\n if (colgroup.querySelectorAll('col').length === 0) {\n const firstRow = tbl.querySelector('tbody tr');\n let colCount = 1;\n if (firstRow) {\n colCount = Array.from(firstRow.querySelectorAll('th, td')).reduce((sum, cell) => {\n return sum + (parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1);\n }, 0);\n }\n colCount = Math.max(colCount, 1);\n\n for (let i = 0; i < colCount; i++) {\n const col = document.createElement('col');\n colgroup.appendChild(col);\n }\n }\n\n // 🎯 col 속성 및 너비 정리는 별도 함수로 분리\n //PreCompiler.#normalizeColAttributes(tbl);\n }\n\n // 🎯 <col>들의 data-col, width, style.width 속성 정리를 전담하는 메서드\n static #normalizeColAttributes(tbl) {\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n if (cols.length === 0) return;\n\n const containerWidth = tbl.clientWidth || 0;\n const defaultWidth = Math.max(Math.floor(containerWidth / cols.length), 100);\n\n cols.forEach((col, i) => {\n // 1. data-col 인덱스 보장\n if (!col.hasAttribute('data-col')) {\n col.setAttribute('data-col', i);\n }\n\n // 2. width 속성 및 style.width 정규화\n const width = col.getAttribute('width') || parseInt(col.style.width, 10) || defaultWidth;\n col.setAttribute('width', width);\n\n const widthVal = String(width).includes('px') ? width : `${width}px`;\n col.style.width = widthVal;\n });\n }\n\n static #ensureThead(tbl) {\n if (tbl.querySelector('thead')) return;\n\n const thead = document.createElement('thead');\n const colgroup = tbl.querySelector('colgroup');\n\n if (colgroup) {\n colgroup.after(thead);\n } else {\n tbl.prepend(thead);\n }\n }\n\n static #normalizeCollapsibleAttributes(tbl) {\n const headers = tbl.querySelectorAll('thead th, thead td');\n headers.forEach(cell => {\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n if (isCollapsed && cell.getAttribute('collapsible') !== 'true') {\n cell.setAttribute('collapsible', 'true');\n }\n });\n }\n\n static #generateCell(host, $tbl) {\n\n const targetAttributes = ['data-bind', 'data-expr', 'type'];\n let autoIdCounter = 0;\n\n $tbl.querySelectorAll('tbody th, tbody td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type') || \"renderer\";\n const tagName = `cell-${cellType}`;\n\n const $datalist = $cell.querySelector(\"datalist\");\n\n if ($datalist) {\n let l = [];\n $datalist.querySelectorAll('option').forEach($option => {\n l.push({\n k: $option.getAttribute(\"k\"),\n v: $option.getAttribute(\"v\"),\n });\n });\n\n // 🎯 1. 절대 겹치지 않는 유니크한 가상 함수 이름 생성\n const uniqueFuncName = `__ds_${Date.now()}_${++autoIdCounter}`;\n\n // 🎯 2. 호스트(NineTable)에 해당 데이터를 반환하는 클로저 함수 등록\n if (host) {\n host[uniqueFuncName] = () => l;\n }\n\n // 🎯 3. 셀에 data-source 자동 장착 (정규식/세터 스캔기가 알아서 캐치함)\n $cell.setAttribute(\"data-source\", `host.${uniqueFuncName}()`);\n\n // 🎯 4. 사용이 끝난 정적 datalist 엘리먼트는 DOM에서 제거\n $datalist.remove();\n }\n\n const expr = $cell.dataset.expr;\n if (expr) {\n $cell.setAttribute('data-expr', host.exprEngine.precompile(expr));\n }\n\n // 💡 2. 기타 속성들 중 표현식이 포함된 경우 프리컴파일\n Array.from($cell.attributes).forEach(attr => {\n if (['data-bind', 'data-expr', 'cell-type'].includes(attr.name)) return;\n if (attr.value.includes(\"data.\") || attr.value.includes(\"host.\")) {\n $cell.setAttribute(attr.name, host.exprEngine.precompile(attr.value));\n }\n });\n\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')}></${tagName}>`;\n $cell.setAttribute('tabindex', '0');\n });\n\n $tbl.querySelectorAll('thead th, thead td, tfoot th, tfoot td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type');\n if (cellType) {\n const originalContent = $cell.innerHTML;\n const tagName = `cell-${cellType}`;\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')} content=\"${originalContent}\"></${tagName}>`;\n }\n });\n }\n\n static #initFilterButtons(host, tbl) {\n const hostFilter = host.getAttribute('filtering') === 'true';\n const tableFilter = tbl.getAttribute('filtering') === 'true';\n\n // 🎯 인덱스 행을 제외한 실제 헤더 셀들만 타겟팅\n tbl.querySelectorAll('thead tr:not(.col-indicator-rowgroup) th, thead tr:not(.col-indicator-rowgroup) td').forEach(cell => {\n const finalFiltering = cell.getAttribute('filtering') === 'true' || tableFilter || hostFilter;\n\n cell.setAttribute('filtering', finalFiltering ? 'true' : 'false');\n\n if (finalFiltering) {\n cell.appendChild(document.createElement('nine-table-filter-button'));\n }\n });\n }\n\n static #initColExpanders(tbl) {\n /** 작동하나? */\n tbl.querySelectorAll('thead th, thead td').forEach(cell => {\n const isCollapsible = cell.getAttribute('collapsible') === 'true' || cell.getAttribute('expandable') === 'true';\n if (!isCollapsible) return;\n\n trace.log(\"11.*******************************\", cell.dataset.col);\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 trace.log(\"11.*******************************\", col);\n\n const currentWidth = col ? (parseInt(col.getAttribute('width'), 10) || 100) : 100;\n\n if (!cell.dataset.expandWidth || parseInt(cell.dataset.expandWidth, 10) <= COLLAPSED_WIDTH) {\n cell.dataset.expandWidth = String(currentWidth > COLLAPSED_WIDTH ? currentWidth : 100);\n }\n\n let expandBtn = cell.querySelector('nine-table-col-expand');\n if (!expandBtn) {\n expandBtn = document.createElement('nine-table-col-expand');\n cell.insertBefore(expandBtn, cell.firstChild);\n }\n\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n expandBtn.classList.add('collapsed');\n expandBtn.classList.remove('expand');\n expandBtn.setAttribute('collapsed', 'true');\n cell.style.color = 'transparent';\n\n const targetWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n if (!isNaN(colIndex)) {\n for (let i = 0; i < colSpan; i++) {\n const targetCol = tbl.querySelector(`colgroup col[data-col=\"${colIndex + i}\"]`);\n if (targetCol) {\n targetCol.setAttribute('width', targetWidth);\n targetCol.style.width = `${targetWidth}px`;\n }\n }\n }\n } else {\n expandBtn.classList.remove('collapsed');\n expandBtn.classList.add('expand');\n expandBtn.setAttribute('collapsed', 'false');\n cell.style.color = '';\n }\n });\n }\n\n static #ensureRowIndicator(tbl, host) {\n // 1. colgroup에 인디케이터용 <col> 추가\n const w = tbl.getAttribute(\"row-indicator\") === 'true' ? 48 : 0;\n\n const colgroup = tbl.querySelector('colgroup');\n\n //if (colgroup && !colgroup.querySelector('col.row-indicator-col')) {\n const col = document.createElement('col');\n //col.className = 'row-indicator-col';\n col.setAttribute('fixed', 'left');\n col.setAttribute('width', w);\n col.style.width = `${w}px`;\n colgroup.prepend(col);\n //}\n\n // 2. thead, tbody, tfoot 각 섹션별로 첫 번째 tr에 인디케이터 생성 및 rowSpan 부여\n //const sections = tbl.querySelectorAll('thead, tbody, tfoot');\n\n tbl.querySelectorAll('thead, tbody, tfoot').forEach(section => {\n const rows = Array.from(section.querySelectorAll('tr'));\n if (rows.length === 0) return;\n\n const firstTr = rows[0];\n\n const indicatorCell = document.createElement('th');\n indicatorCell.className = 'row-indicator';\n indicatorCell.setAttribute('cell-type', 'row-indicator');\n //indicatorCell.setAttribute('filtering', 'false');\n\n // 💡 섹션 내 행이 여러 개면(멀티 라인 템플릿 등) 전체를 아우르도록 rowSpan 설정\n if (rows.length > 1) {\n indicatorCell.rowSpan = rows.length;\n }\n\n firstTr.insertBefore(indicatorCell, firstTr.firstElementChild);\n });\n }\n\n static #applyInitialCellWidths(tbl) {\n // 🎯 컬럼 기준이 아닌 셀(th, td) 기준으로 순회하여 colspan 반영\n tbl.querySelectorAll('th[data-col], td[data-col]').forEach(cell => {\n\n trace.log(cell);\n\n const startColIdx = parseInt(cell.getAttribute('data-col'), 10);\n if (isNaN(startColIdx)) return;\n\n // 셀의 실제 colspan 값 추출 (기본값 1)\n const colSpan = parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1;\n let totalWidth = 0;\n\n // colspan 만큼 다음 컬럼들의 너비를 누적 합산\n for (let i = 0; i < colSpan; i++) {\n const targetIdx = startColIdx + i;\n const col = tbl.querySelector(`colgroup col[data-col=\"${targetIdx}\"]`);\n if (col) {\n totalWidth += parseInt(col.getAttribute('width'), 10) || 100;\n }\n }\n\n if (totalWidth > 0) {\n const widthVal = `${totalWidth}px`;\n cell.style.width = widthVal;\n cell.style.minWidth = widthVal;\n cell.style.maxWidth = widthVal;\n }\n });\n }\n}","// NineTableSheet.js (필터 버튼 레이아웃 및 패딩 스타일 완벽 통합본)\n\nimport { trace } from \"@nopeer\";\nimport './nine-table-hscrollbar.js';\nimport './nine-table-vscrollbar.js';\nimport { RowManager } from './core/RowManager.js';\nimport { TableCompiler } from \"./core/TableCompiler.js\";\nimport { CellSelection } from \"@/ui/cell-manager/CellSelection.js\";\nimport { CellNavigation } from \"@/ui/cell-manager/CellNavigation.js\";\n\nimport { ColResizer } from \"@/ui/col/ColResizer.js\";\nimport { ColMover } from \"@/ui/col/ColMover.js\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nimport { Filtering } from \"@/data/Filtering.js\";\nimport {Grouping, GroupingManager} from \"@/data/Grouping.js\";\nimport { Sorting } from \"@/data/Sorting.js\";\nimport { SheetView } from \"@/data/SheetView.js\";\n\nimport { PreCompiler } from \"@/ui/layout/core/PreCompiler.js\";\n\nexport class NineTableSheet extends HTMLElement {\n #index;\n #host;\n #rowManager;\n #cellSelection;\n #cellNavigation;\n #colResizer;\n #colMover;\n #colFix;\n #sorting;\n #filtering;\n #grouping;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n static SCROLLBAR_SIZE = 16;\n\n constructor() {\n super();\n trace.log(\"11111\")\n this.#rowManager = new RowManager(this);\n trace.log(\"222\")\n this.#host = this.getRootNode().host;\n trace.log(\"333\")\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get index() { return this.#index; }\n get colResizer() { return this.#colResizer; }\n get filtering() { return this.#filtering; }\n get grouping() { return this.#grouping; }\n get colMover() { return this.#colMover; }\n get colFix() { return this.#colFix; }\n get rowManager() { return this.#rowManager; }\n get selection() { return this.#cellSelection; }\n get navigation() { return this.#cellNavigation; }\n get templateLength() { return this.#source.tbody.tr.length || 0; }\n\n get elements() { return this.#elements; }\n\n get isAutoFitCol() {\n const attrTrue = this.getAttribute('auto-fit-col') === 'true' || this.#host?.getAttribute('auto-fit-col') === 'true';\n const sourceTableTrue = this.#source.table?.getAttribute('auto-fit-col') === 'true';\n return attrTrue || sourceTableTrue;\n }\n\n get sourceTable() {\n return this.#source.table;\n }\n\n get source() {\n return this.#source;\n }\n\n get #isSimple() {\n return this.#host.hasAttribute('simple') || this.#host.getAttribute('theme') === 'simple';\n }\n\n recompileAndRefresh() {\n if (!this.#source.table) return;\n\n TableCompiler.recompile(this.#source.table);\n\n ['left', 'right', 'body'].forEach(type => {\n ['header', 'body', 'footer'].forEach(section => {\n const container = this.querySelector(`.ng-sheet-${section} .ng-container-${type}`);\n if (!container) return;\n container.querySelectorAll('table').forEach(tbl => tbl.remove());\n });\n });\n\n this.#renderSplitContainers();\n\n this.#updateContainerWidths();\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n requestAnimationFrame(() => {\n this.#updateContainerWidths();\n this.#rowManager?.refresh();\n });\n }\n\n refreshLayout() {\n if (!this.classList.contains('active') || !this.#source.table) return;\n\n requestAnimationFrame(() => {\n\n this.#updateContainerWidths();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n this.#adjustOverlay();\n\n this.#colResizer?.refreshLayout();\n\n this.#rowManager?.refresh();\n });\n }\n\n #adjustOverlay = () => {\n // 3분할된 영역 중 중앙(body) 또는 좌측 영역의 thead를 타겟팅하여 높이 측정\n const $thead = this.querySelector('.ng-container-body thead');\n const $overlay = this.querySelector('.ng-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 trace.log(\"***************** autoFit\", this);\n\n const container = this.querySelector('.ng-sheet-body .ng-container-body');\n if (!container) return;\n\n //const tables = container.querySelectorAll('table');\n const firstColgroup = this.querySelector('.ng-container-body table colgroup');\n if (!firstColgroup) return;\n\n if (enable) {\n this.setAttribute('auto-fit-col', 'true');\n const containerWidth = container.clientWidth;\n if (containerWidth <= 0) return;\n\n let totalOriginalWidth = 0;\n const colList = [];\n\n // 1단계: 접힌 컬럼(16px 고정)과 일반 컬럼을 분리해서 수집\n firstColgroup.querySelectorAll('col').forEach(col => {\n const globalColIndex = col.getAttribute('data-col');\n const headerCell = this.querySelector(`thead th[data-col=\"${globalColIndex}\"]`);\n const isCollapsed = headerCell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n colList.unshift({ globalColIndex, width: 16, isCollapsed: true });\n trace.log(`[AutoFit Col] Index ${globalColIndex}: COLLAPSED (forced 16px)`);\n } else {\n const w = parseInt(col.getAttribute('width'), 10) || 100;\n colList.push({ globalColIndex, width: w, isCollapsed: false });\n totalOriginalWidth += w;\n trace.log(`[AutoFit Col] Index ${globalColIndex}: NORMAL (original width: ${w}px)`);\n }\n });\n\n trace.log(`[AutoFit] Total Original Width of Normal Cols: ${totalOriginalWidth}px`);\n\n // 접힌 컬럼들이 차지하는 총 너비 계산\n const collapsedTotalWidth = colList\n .filter(c => c.isCollapsed)\n .reduce((sum, c) => sum + c.width, 0);\n\n // 남은 컨테이너 너비를 펼쳐진 컬럼들에게만 배분 (오류 수정)\n const availableWidth = Math.max(0, containerWidth - collapsedTotalWidth);\n trace.log(`[AutoFit] Collapsed Total Width: ${collapsedTotalWidth}px | Available Width for Normal Cols: ${availableWidth}px`);\n\n if (totalOriginalWidth > 0 && colList.length > 0) {\n let allocatedTotal = 0;\n\n const calculatedCols = colList.map(item => {\n if (item.isCollapsed) {\n return { globalColIndex: item.globalColIndex, remainder: 0, width: 16 };\n }\n\n // 연산자 오류 수정 (* 와 - 추가)\n const exactWidth = (item.width * availableWidth) / totalOriginalWidth;\n const baseWidth = Math.max(30, Math.floor(exactWidth));\n allocatedTotal += baseWidth;\n return {\n globalColIndex: item.globalColIndex,\n remainder: exactWidth - Math.floor(exactWidth),\n width: baseWidth\n };\n });\n\n // 잔여 픽셀 보정 (오류 수정)\n let remainderPixels = availableWidth - allocatedTotal;\n trace.log(`[AutoFit] Initial Allocated Total: ${allocatedTotal}px | Remainder Pixels to distribute: ${remainderPixels}`);\n\n const uncollapsedCols = calculatedCols.filter(c => !colList.find(item => item.globalColIndex === c.globalColIndex)?.isCollapsed);\n\n if (remainderPixels > 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => b.remainder - a.remainder);\n for (let i = 0; i < remainderPixels; i++) {\n uncollapsedCols[i % uncollapsedCols.length].width += 1;\n }\n } else if (remainderPixels < 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => a.remainder - b.remainder);\n for (let i = 0; i < Math.abs(remainderPixels); i++) {\n const target = uncollapsedCols[i % uncollapsedCols.length];\n if (target.width > 30) target.width -= 1;\n }\n }\n\n const finalSumWidth = calculatedCols.reduce((sum, c) => sum + c.width, 0);\n trace.log(`[AutoFit Verification] Target Container Width: ${containerWidth}px | Sum of All Calculated Cols: ${finalSumWidth}px`);\n\n if (containerWidth !== finalSumWidth) {\n trace.log(`⚠️ [AutoFit Mismatch Warning!] 오차 발생: ${containerWidth - finalSumWidth}px 차이가 납니다.`);\n } else {\n trace.log(`✅ [AutoFit Success] 완벽하게 일치합니다!`);\n }\n\n // 최종 적용\n calculatedCols.forEach(({ globalColIndex, width }) => {\n trace.log(`[AutoFit Apply] Col Index ${globalColIndex} -> ${width}px`);\n this.#colResizer?.setColumnWidth(globalColIndex, width, 'body');\n });\n }\n } else {\n this.removeAttribute('auto-fit-col');\n }\n\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n generate = ($table, index) => {\n\n this.#index = index;\n\n PreCompiler.initializeTable(this.#host, $table);\n\n trace.log(\"=======\", $table);\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n this.#renderSplitContainers();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#updateContainerWidths();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#syncHeaderAndFooterHeights();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //\n this.#initRowHoverEvent();\n\n ['left', 'body', 'right'].forEach(type => {\n const prefix = `.ng-container-${type}`;\n this.#elements[type] = {\n thead: this.querySelector(`${prefix} thead`),\n tbody: {\n head: this.querySelector(`${prefix} tbody.head`),\n body: this.querySelector(`${prefix} tbody.body`),\n foot: this.querySelector(`${prefix} tbody.foot`),\n },\n tfoot: this.querySelector(`${prefix} tfoot`),\n };\n });\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //trace.log(\"********1\", this.#source.table)\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar').refresh();\n }\n\n //this.#grouping = new GroupingManager(this);\n this.#grouping.initialize();\n\n this.loaded = true;\n };\n\n\n #updateContainerWidths = () => {\n const isAutoFit = this.isAutoFitCol;\n\n ['left', 'right', 'body'].forEach(type => {\n const containers = this.querySelectorAll(`.ng-container-${type}`);\n if (containers.length === 0) return;\n\n const firstTable = containers[0].querySelector('table');\n if (!firstTable) return;\n\n let width = 0;\n firstTable.querySelectorAll('col').forEach(col => {\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) width += w;\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n if (type === 'body') {\n container.style.flex = `1`;\n tables.forEach(tbl => {\n //tbl.style.width = isAutoFit ? `100%` : `${width}px`;\n //tbl.style.minWidth = isAutoFit ? `100%` : `${width}px`;\n });\n } else {\n container.style.flex = `0 0 ${width}px`;\n container.style.width = `${width}px`;\n container.style.minWidth = `${width}px`;\n container.style.maxWidth = `${width}px`;\n tables.forEach(tbl => {\n //tbl.style.width = `${width}px`;\n //tbl.style.minWidth = `${width}px`;\n });\n }\n });\n });\n };\n\n #renderSplitContainers = () => {\n const colTypes = [\n { selector: '.ng-container-left', type: 'left' },\n { selector: '.ng-container-body', type: null },\n { selector: '.ng-container-right', type: 'right' }\n ];\n\n colTypes.forEach(({ selector, type }) => {\n this.querySelector(`.ng-sheet-body ${selector}`).appendChild(this.#createSplitTable(type));\n });\n };\n\n #createSplitTable = (targetFixedType) => {\n\n const $tbl = this.#source.table.cloneNode(true);\n\n if (targetFixedType === 'left') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"left\") $el.remove();\n });\n } else if (targetFixedType === 'right') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"right\") $el.remove();\n });\n } else {\n $tbl.querySelectorAll(\"[fixed=left], [fixed=right]\").forEach($el => {\n $el.remove();\n });\n }\n\n return $tbl;\n };\n\n getRowHeight = () => {\n return this.#rowManager.getRowHeight();\n };\n\n 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 trace.log(\"11111*****************\");\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 //trace.log(\"----------------------\")\n //trace.log(\"Is GroupingManager instance?\", this.#grouping instanceof GroupingManager); // true가 나와야 정상\n //trace.log(\"Grouping keys:\", Object.keys(this.#grouping)); // 또는 내부 속성 확인\n\n if (!this.#isSimple) {\n this.#sorting = new Sorting(this);\n }\n\n this.#elements.mainBody.addEventListener('scroll', () => {\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n trace.log(\"11111*****************\");\n const sbSize = NineTableSheet.SCROLLBAR_SIZE;\n trace.log(\"2222*****************\");\n this.innerHTML = `\n <div class=\"ng-sheet-body\">\n <div class=\"ng-sheet-body-content\">\n <div class=\"ng-container-left\"></div>\n <div class=\"ng-container-body\"></div>\n <div class=\"ng-container-right\"></div>\n </div>\n <div class=\"ng-virtual-height-holder\"></div>\n </div>\n\n <div class=\"ng-nodata-overlay\">Data Not Found</div>\n\n <!-- [Grid Row 1, Col 2] 세로 스크롤바 -->\n <nine-table-vscrollbar></nine-table-vscrollbar>\n\n <!-- [Grid Row 2, Col 1] 가로 스크롤바 -->\n <nine-table-hscrollbar></nine-table-hscrollbar>\n\n <!-- [Grid Row 2, Col 2] 우하단 엣지 -->\n <div class=\"ng-scroll-edge\"></div>\n \n <!-- 리사이저 및 드래그 패널들 -->\n <div class=\"ng-col-resizer-panel\">\n <div class=\"resizer-overlay\">\n <span class=\"size-badge\">0px</span>\n </div>\n </div>\n \n <div class=\"ng-col-mover-grip\"></div>\n <div class=\"ng-col-mover-indi\"></div>\n `;\n\n //let fixedHeight = this.#sheet.querySelector('.ng-container-body thead').offsetHeight + this.#sheet.querySelector('.ng-container-body tfoot').offsetHeight;\n trace.log(\"3333*****************\");\n this.#elements = {\n mainBody: this.querySelector('.ng-sheet-body .ng-container-body'),\n hscrollbar: this.querySelector('nine-table-hscrollbar'),\n vscrollbar: this.querySelector('nine-table-vscrollbar'),\n content: this.querySelector('.ng-sheet-body .ng-sheet-body-content'),\n scrollHolder: this.querySelector('.ng-sheet-body .ng-virtual-height-holder'),\n }\n trace.log(\"444*****************\");\n };\n\n #syncHeaderAndFooterHeights = () => {\n trace.log(\"**********************\", \"#syncHeaderAndFooterHeights\");\n\n const leftTable = this.querySelector('.ng-container-left table');\n const bodyTable = this.querySelector('.ng-container-body table');\n const rightTable = this.querySelector('.ng-container-right table');\n\n // 1. 헤더(thead) 행 높이 싱크 (인덱스 행 제외)\n const leftHeaderRows = Array.from(leftTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const bodyHeaderRows = Array.from(bodyTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const rightHeaderRows = Array.from(rightTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n\n this.#applyMaxHeights(leftHeaderRows, bodyHeaderRows, rightHeaderRows);\n\n // 2. 푸터(tfoot) 행 높이 싱크\n const leftFooterRows = Array.from(leftTable.querySelectorAll('tfoot tr'));\n const bodyFooterRows = Array.from(bodyTable.querySelectorAll('tfoot tr'));\n const rightFooterRows = Array.from(rightTable.querySelectorAll('tfoot tr'));\n\n this.#applyMaxHeights(leftFooterRows, bodyFooterRows, rightFooterRows);\n };\n\n// 공통 최대 높이 적용 헬퍼 메서드\n #applyMaxHeights = (leftRows, bodyRows, rightRows) => {\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 #initRowHoverEvent = () => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n let activeRowIndex = null;\n\n // 마우스 진입 (모든 컨테이너 탐색)\n bodyViewport.addEventListener('mouseover', (e) => {\n const tr = e.target.closest('tr');\n if (!tr || !tr.dataset.row && tr.dataset.row !== '0') return;\n\n const rowIndex = tr.dataset.row;\n if (activeRowIndex === rowIndex) return;\n activeRowIndex = rowIndex;\n\n // 좌측, 본문, 우측 컨테이너에서 동일한 data-row를 가진 tr들을 모두 찾아 .hover 부여\n bodyViewport.querySelectorAll(`tr[data-row=\"${rowIndex}\"]`).forEach($tr => {\n $tr.classList.add('hover');\n });\n });\n\n // 마우스 이탈\n bodyViewport.addEventListener('mouseout', (e) => {\n const tr = e.target.closest('tr');\n if (!tr) return;\n\n // 현재 영역을 완전히 벗어났을 때만 전체 hover 제거\n const relatedTarget = e.relatedTarget;\n if (tr.contains(relatedTarget)) return;\n\n bodyViewport.querySelectorAll('tr.hover').forEach($tr => {\n $tr.classList.remove('hover');\n });\n activeRowIndex = null;\n });\n }\n\n disconnectedCallback() {\n this.#colResizer?.destroy();\n this.#colMover?.destroy();\n this.innerHTML = '';\n }\n}\n\nif (!customElements.get('nine-table-sheet')) {\n customElements.define('nine-table-sheet', NineTableSheet);\n}","import { trace } from \"@nopeer\";\nimport '@/ui/layout/nine-table-sheets.js';\nimport '@/ui/layout/nine-table-sheets-footer.js';\nimport '@/ui/layout/nine-table-toolbar.js';\nimport { NineTableSheet } from \"@/ui/layout/nine-table-sheet.js\";\n\nexport class LayoutManager {\n #host;\n\n constructor(owner) {\n this.#host = owner;\n this.#init();\n }\n\n #init = () => {\n this.#render();\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }).observe(this.#host);\n }\n\n set loading(val) {\n if (!!val) {\n this.#host.classList.add(\"loading\");\n } else {\n this.#host.classList.remove(\"loading\");\n }\n }\n\n #applyAutoHeight = () => {\n const activeSheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet.active'));\n if (activeSheets.length === 0) return;\n\n const maxDisplayRows = parseInt(this.#host.getAttribute('max-display-row'), 10) || 10;\n const maxRowHeight = Math.max(...activeSheets.map(sheet => sheet.getRowHeight()));\n\n const toolbarEl = this.#host.shadowRoot.querySelector('nine-table-toolbar');\n const footerEl = this.#host.shadowRoot.querySelector('nine-table-sheets-footer');\n\n const toolbarHeight = toolbarEl ? toolbarEl.getBoundingClientRect().height : 0;\n const footerHeight = footerEl ? footerEl.getBoundingClientRect().height : 0;\n const extraPadding = NineTableSheet.SCROLLBAR_SIZE;\n\n const calculatedHeight = (maxDisplayRows * maxRowHeight) + toolbarHeight + footerHeight + extraPadding;\n\n this.#host.style.height = `${calculatedHeight}px`;\n };\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n const sheetCount = rawTables.length;\n\n const sheetsHtml = rawTables.map((tbl, idx) => {\n const className = idx === 0 ? 'active' : '';\n const sheetId = tbl.id || `sheet${idx + 1}`;\n\n const sheetTag = `<nine-table-sheet class=\"${className}\" data-index=\"${idx}\" data-sheet-id=\"${sheetId}\" id=\"${sheetId}\"></nine-table-sheet>`;\n const splitterTag = idx < sheetCount - 1 ? `<nine-splitter class=\"h\" data-split-index=\"${idx}\"></nine-splitter>` : '';\n return sheetTag + splitterTag;\n }).join('');\n\n // 1. 공통 파일명 배열 정의\n\n /**\n const cssFiles = [\n 'layout', 'nine-table-sheet', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table', 'col-resize', 'sorting', 'fitering', 'cell-select', 'col-expand',\n 'cell-combo',\n ]; */\n\n\n const cssFiles = [\n '_nine-table',\n ];\n // 2. npm 패키지 CSS 배열 생성\n /**\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}.css\";`\n ); */\n const npmCssImports = [\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/nine-table.css\";`,\n ];\n\n // 3. 커스텀 CSS 배열 생성\n const customCssImports = [];\n if (nine.cssPath) {\n cssFiles.forEach(file => {\n customCssImports.push(`@import \"${nine.cssPath}/${file}.css\";`);\n });\n }\n\n this.#host.shadowRoot.innerHTML = `\n <style>\n ${[...npmCssImports, ...customCssImports].join('\\n')}\n </style>\n \n <nine-table-toolbar></nine-table-toolbar>\n\n <nine-table-body>\n <nine-table-summary></nine-table-summary>\n <div class=\"ng-loading-bar\"></div>\n <nine-table-sheets>\n <nine-table-sheets-body>\n ${sheetsHtml}\n </nine-table-sheets-body>\n <nine-table-sheets-footer></nine-table-sheets-footer>\n </nine-table-sheets>\n <nine-table-analysis></nine-table-analysis>\n </nine-table-body>\n <nine-table-footer></nine-table-footer>\n `;\n\n /**\n * <div class=\"nine-tab-bar\">${tabsHtml}</div>\n * <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n */\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($el, idx) => {\n\n if (rawTables[idx]) {\n setTimeout(() => {\n $el.generate(rawTables[idx], idx);\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n });\n }\n });\n };\n}","import { trace } from \"@nopeer\";\n\nexport class ExprEngine {\n #host;\n #fields;\n #exprCache = new Map(); // 💡 통합된 단일 캐시로 모든 컴파일된 함수 관리\n\n constructor(host) {\n this.#host = host;\n this.#fields = host.fields.get();\n }\n\n /**\n * 🎯 표현식 내의 data.fieldName을 원시 배열 인덱스 접근(rowItem.v[idx])으로 변환\n */\n rewriteExpr(expr) {\n\n if (!expr || !this.#fields.length) return expr;\n\n return expr.replace(/data\\.([a-zA-Z_$][\\w$]*)/g, (match, fieldName) => {\n const idx = this.#fields.indexOf(fieldName);\n return idx >= 0 ? `rowItem.v[${idx}]` : match;\n });\n }\n\n /**\n * 🎯 셀 또는 컬럼 정의에 선언된 expr 프리컴파일\n */\n precompile(expr) {\n if (!expr) return expr;\n return this.rewriteExpr(expr);\n }\n\n /**\n * 🎯 표현식 평가 및 실행 (통합 캐싱)\n */\n evaluate(expr, rowItem, row = 0) {\n if (expr === undefined || expr === null) return \"\";\n\n //trace.log(expr, rowItem, this.#exprCache);\n\n try {\n const trimmedExpr = String(expr).trim();\n const compiledExpr = this.rewriteExpr(trimmedExpr);\n\n // 💡 함수 호출, 데이터 참조, 연산식이 포함된 경우 통합 평가 및 캐싱\n if (compiledExpr.includes(\"data.\") || compiledExpr.includes(\"rowItem.v\") || compiledExpr.includes(\"host.\") || compiledExpr.includes(\"(\")) {\n let evalFn = this.#exprCache.get(compiledExpr);\n\n if (!evalFn) {\n evalFn = new Function('rowItem', 'row', 'host', `\n const data = rowItem;\n if (!data && !host) return \"\";\n return ${compiledExpr};\n `);\n this.#exprCache.set(compiledExpr, evalFn);\n }\n\n return evalFn(rowItem, row, this.#host);\n }\n\n // 단순 리터럴 문자열인 경우\n return compiledExpr;\n } catch (e) {\n //console.error(\"ExprEngine evaluation error:\", expr, e);\n return expr;\n }\n }\n}","import { trace } from \"@nopeer\";\nimport { ngDataManager } from '@/data/ngDataManager.js';\nimport { fields } from \"@/data/Fields.js\";\nimport { LayoutManager } from '@/ui/layout/core/LayoutManager.js';\nimport { ExprEngine } from \"@/core/ExprEngine.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #templateCnt = 0; // 🎯 로딩 상태 플래그\n\n constructor() {\n super();\n\n this.#shadowRoot = this.attachShadow({ mode: 'open' });\n this.#dataManager = new ngDataManager(this);\n }\n\n connectedCallback() {\n setTimeout(() => {\n this.#templateCnt = this.querySelectorAll(\"table\")?.length;\n\n this.fields = new fields(this);\n this.exprEngine = new ExprEngine(this);\n\n this.#bindDynamicSetters();\n\n this.#layoutManager = new LayoutManager(this);\n\n this.#dispatchLoad();\n //this.dispatchEvent(new CustomEvent('load', { bubbles: true, detail: { target: this } }));\n });\n }\n\n disconnectedCallback() {\n trace.log('NineTable disconnected.');\n }\n\n #dispatchLoad = () => {\n // 🎯 2. 변수명 오타 수정 (#sheetCnt -> #templateCnt)\n //trace.log(\"*********************** template count:\", this.#templateCnt);\n\n let checkCount = 0;\n const maxChecks = 50; // 최대 5초 대기 (100ms * 50)\n\n const checkTimer = setInterval(() => {\n checkCount++;\n\n const sheets = this.shadow.querySelectorAll('nine-table-sheet');\n //trace.log(\"Current mounted sheets:\", sheets.length);\n\n if (checkCount >= maxChecks) {\n clearInterval(checkTimer);\n }\n\n if (sheets.length >= this.#templateCnt) {\n let loadSheetCnt = 0;\n sheets.forEach($sheet => {\n if ($sheet.loaded) loadSheetCnt++;\n });\n\n //trace.log('Checking sheet loaded status:', loadSheetCnt, '/', this.#templateCnt);\n\n if (loadSheetCnt >= this.#templateCnt) {\n clearInterval(checkTimer);\n this.loaded = true;\n this.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.LOAD, { bubbles: true, detail: { target: this } }));\n }\n }\n }, 100);\n }\n\n\n // 🎯 공통 데이터 & API 접근자\n get shadow() { return this.#shadowRoot; }\n get dataManager() { return this.#dataManager; }\n get data() { return this.#dataManager.data; }\n get row() { return this.#dataManager.row; }\n\n setData(records) {\n this.#dataManager.data.set(records);\n this.refresh();\n }\n\n refresh() {\n this.activeSheet?.invalidate();\n }\n\n // 🎯 섀도우 돔 내부에서 로딩바 요소를 안전하게 캐싱\n\n\n set loading(val) {\n this.#layoutManager.loading = val;\n }\n\n /**\n * 랜더링 이후에 생기는 data-source 처리기능\n */\n rerenderer() {\n\n this.activeSheet?.querySelectorAll(\"tbody.body th,tbody.body td\").forEach(($cell) => {\n const customComp = Array.from($cell.children).find($el => {\n return $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.rerenderer === 'function'\n });\n\n customComp?.rerenderer();\n })\n }\n\n // 시트 제어 API\n sheet = (idOrIndex) => {\n if (idOrIndex === null || idOrIndex < 0) return this.activeSheet;\n const sheets = Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n\n if (typeof idOrIndex === 'number') return sheets[idOrIndex] || null;\n if (typeof idOrIndex === 'string') {\n return this.shadow.querySelector(`nine-table-sheet#${idOrIndex}, nine-table-sheet[data-sheet-id=\"${idOrIndex}\"]`) || null;\n }\n return sheets[0] || null;\n }\n\n get sheets() {\n return Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n }\n\n get activeSheet() {\n return this.shadow.querySelector('nine-table-sheet.active') || null;\n }\n\n #bindDynamicSetters() {\n const extractedMethodNames = new Set();\n\n this.querySelectorAll('[data-source]').forEach(el => {\n const dataSource = el.getAttribute('data-source');\n if (!dataSource) return;\n\n // 💡 [수정] 뒤에 여멀림 괄호 '('가 오는 형태만 매칭하여 'DEPART' 같은 파라미터는 배제!\n const matches = dataSource.matchAll(/(?:host\\.)?([a-zA-Z0-9_$]+)\\s*\\(/g);\n for (const match of matches) {\n const name = match[1];\n if (name && name !== 'host') {\n extractedMethodNames.add(name);\n }\n }\n });\n\n // 추출된 메서드 이름별로 NineTable 인스턴스에 동적 세터 생성\n extractedMethodNames.forEach(methodName => {\n let internalValue = null;\n\n Object.defineProperty(this, methodName, {\n set: (newValue) => {\n internalValue = newValue;\n\n // 값이 대입되는 순간 그리드 자동 갱신\n //this.refresh();\n this.rerenderer();\n },\n get: () => internalValue,\n configurable: true,\n enumerable: true\n });\n });\n }\n\n execute = (fn) => {\n this.loading = true;\n setTimeout(() => {\n try {\n fn.call(this);\n } finally {\n this.loading = false;\n }\n })\n }\n}\n\nif (!customElements.get('nine-table')) {\n customElements.define('nine-table', NineTable);\n}\n\nif (!customElements.get('nine-table-simple')) {\n customElements.define('nine-table-simple', class extends NineTable {\n connectedCallback() {\n // simple 태그로 생성되면 자동으로 mode=\"simple\" 속성 부여\n this.setAttribute('theme', 'simple');\n\n super.connectedCallback();\n }\n });\n}","export class BasicCellElement extends HTMLElement {\r\n\r\n\tstatic _styleCache = new Map();\r\n\tstatic _customStyleCache = new Map(); // 👈 커스텀 스타일용 캐시 추가\r\n\r\n\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tapplyBaseStyle() {\r\n\t\tconst className = this.constructor.name;\r\n\r\n\t\treturn;\r\n\t\t// 1. 기본 스타일 시트 처리 (캐싱 O)\r\n\t\tif (!ngElement._styleCache.has(className)) {\r\n\t\t\tconst baseSheet = new CSSStyleSheet();\r\n\t\t\tngElement._styleCache.set(className, baseSheet);\r\n\r\n\t\t\tconst baseUrl = `https://cdn.jsdelivr.net/npm/@ninebone/grid@${__APP_VERSION__}/dist/css/${className}.css`;\r\n\t\t\tfetch(baseUrl)\r\n\t\t\t\t.then(res => res.text())\r\n\t\t\t\t.then(cssText => baseSheet.replaceSync(cssText))\r\n\t\t\t\t.catch(err => console.error(`Base CSS Load Error:`, err));\r\n\t\t}\r\n\r\n\t\tconst sheets = [ngElement._styleCache.get(className)];\r\n\r\n\t\t// 2. 커스텀 스타일 시트 처리 (자바스크립트 단 캐싱 O)\r\n\t\tif (nine.cssPath) {\r\n\t\t\tif (!ngElement._customStyleCache.has(className)) {\r\n\t\t\t\tconst customSheet = new CSSStyleSheet();\r\n\t\t\t\tngElement._customStyleCache.set(className, customSheet);\r\n\r\n\t\t\t\t// 💡 오타 수정 및 캐시 파라미터 제거\r\n\t\t\t\tconst customUrl = `${nine.cssPath}/ninegrid/${className}.css`;\r\n\r\n\t\t\t\tfetch(customUrl)\r\n\t\t\t\t\t.then(res => res.text())\r\n\t\t\t\t\t.then(cssText => customSheet.replaceSync(cssText))\r\n\t\t\t\t\t.catch(err => console.error(`Custom CSS Load Error:`, err));\r\n\t\t\t}\r\n\r\n\t\t\t// 캐시된 커스텀 시트가 있으면 기본 시트 배열 뒤에 추가\r\n\t\t\tsheets.push(ngElement._customStyleCache.get(className));\r\n\t\t}\r\n\r\n\t\t// 한 번에 섀도우 돔에 적용\r\n\t\tthis.shadowRoot.adoptedStyleSheets = sheets;\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\t// ngElement 레벨에서는 비워두셔도 됩니다.\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { BasicCellElement } from './BasicCellElement.js';\r\n\r\nconst exprCache = new Map();\r\nconst hostFuncCache = new Map();\r\n\r\nexport class CellElement extends BasicCellElement {\r\n\t#host;\r\n\t#sheet;\r\n\t#tr;\r\n\t#cell;\r\n\r\n\t#attr;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tget host() { return this.#host; }\r\n\tget sheet() { return this.#sheet; }\r\n\tget cell() { return this.#cell; }\r\n\tget tr() { return this.#tr; }\r\n\tget attr() { return this.#attr; }\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\tthis.#cell = this.closest(\"th,td\");\r\n\t\tthis.#tr = this.#cell.closest(\"tr\");\r\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\r\n\r\n\t\tthis.#cell.classList.add(this.tagName);\r\n\r\n\t\tthis.#attr = {};\r\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\r\n\t\t\tconst name = this.#cell.attributes[i].name;\r\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\r\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\r\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#cell) return;\r\n\r\n\r\n\t\tconst root = this.shadowRoot || this;\r\n\r\n\t\t// 🎯 버튼 이벤트 연결\r\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\r\n\t\t\tbutton.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\r\n\r\n\t\t\t\tconst rowData = this.data; // Proxy Lazy 접근\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t/**\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t})); */\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 링크 이벤트 연결\r\n\t\tconst renderer = root.querySelector(\".renderer\");\r\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\r\n\t\t\trenderer.classList.add(\"link\");\r\n\r\n\t\t\trenderer.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\r\n\r\n\t\t\t\tconst rowData = this.data;\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t}));\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [Proxy 최적화] 속성 읽기 시에도 fields.indexOf() 사용\r\n\t */\r\n\tget data() {\r\n\t\tconst rawRecord = this.#tr?.data;\r\n\t\tif (!rawRecord) return null;\r\n\t\tif (!rawRecord.v) return rawRecord;\r\n\r\n\t\tconst host = this.#host;\r\n\r\n\t\treturn new Proxy(rawRecord, {\r\n\t\t\tget(target, prop) {\r\n\t\t\t\tif (prop === '__ng') return target.__ng;\r\n\t\t\t\tif (prop === 'v') return target.v;\r\n\r\n\t\t\t\t// 💡 host.fields.indexOf(prop) 사용\r\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\r\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [핵심] 변환 없이 원시 v 배열에서 direct 인덱스 검색 (GC zero)\r\n\t */\r\n\tget value() {\r\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\r\n\r\n\t\tconst bindKey = this.#cell.dataset?.bind;\r\n\t\tif (!bindKey) return \"\";\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\t// 1. 원시 데이터 배열({ v: [...] }) 구조인 경우\r\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\r\n\t\t\t// 💡 fields.indexOf(bindKey)로 바로 찾기!\r\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\r\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\r\n\t\t}\r\n\r\n\t\t// 2. 일반 JSON 객체인 경우 (하위 호환)\r\n\t\treturn rawRecord[bindKey] ?? \"\";\r\n\t}\r\n\r\n\tset value(v) {\r\n\t\tif (!this.#cell || !this.#host?.data) return;\r\n\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tif (isNaN(row) || !bindKey) return;\r\n\r\n\t\tconst updateRowState = this.getAttribute('update-row-state') !== \"false\";\r\n\t\tthis.#host.data.setValue(row, bindKey, v, updateRowState);\r\n\t}\r\n\r\n\tget row() {\r\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\r\n\t}\r\n\tget index() {\r\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\r\n\t}\r\n\r\n\tgetDisplayText = (defaultValue = \"\") => {\r\n\r\n\t\ttrace.log(\"=================================\");\r\n\t\tif (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\ttrace.log(\"==============================\", rawRecord);\r\n\r\n\t\tif (!rawRecord) return defaultValue;\r\n\r\n\t\tconst expr = this.#cell.dataset.expr;\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\tif (expr) {\r\n\t\t\ttry {\r\n\t\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\r\n\t\t\t\t\t// 💡 상수가 정의되어 있다면 GROUP_IDX.ID 로 고유 ID 추출 (아니면 배열 인덱스 직접 참조)\r\n\t\t\t\t\t// 배열 구조체인 경우: rawRecord[0]이 groupId임\r\n\t\t\t\t\t//const groupId = Array.isArray(rawRecord) ? rawRecord[0] : (rawRecord.__ng?.id || rawRecord.m?.id);\r\n\r\n\t\t\t\t\t// 💡 매니저를 통해 해당 그룹의 자식 레코드 목록을 O(1)로 획득\r\n\t\t\t\t\t//const childRecords = this.#sheet.grouping.getChildrenRecords(\"g_0\");\r\n\t\t\t\t\t//trace.log(\"--========\", childRecords);\r\n\t\t\t\t\t// 그룹 전용 표현식 계산 메서드 호출\r\n\t\t\t\t\t//return \"\";//this.getGroupExprValue(expr, childRecords, row, this.#cell);\r\n\r\n\t\t\t\t\t//trace.log(this, this.#cell.dataset.bind);\r\n\t\t\t\t\t//return \"x\";//this.data.length;\r\n\t\t\t\t\treturn this.getGroupExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row);\r\n\r\n\t\t\t\t\t//return this.getExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\tconsole.trace(e);\r\n\t\t\t\t//console.error(\"Expr evaluation error:\", expr, e);\r\n\t\t\t\treturn defaultValue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\ttrace.log(\"==============================\", bindKey, this.value);\r\n\r\n\t\tif (bindKey) {\r\n\t\t\tconst val = this.value; // 직통 읽기\r\n\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\r\n\t\t}\r\n\r\n\t\treturn defaultValue;\r\n\t};\r\n\r\n\r\n\r\n\trefresh() {\r\n\r\n\t\tif (!this.#cell || !this.#tr) return;\r\n\r\n\t\tconst val = this.value; // 원시 배열 직통 조회\r\n\r\n\t\t[\"color\",\"background\",\"background-color\",\"class\",\"visible\",\"enable\"].forEach(v => {\r\n\t\t\tconst expr = this.#attr[v];\r\n\t\t\tif (expr) {\r\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10));\r\n\r\n\t\t\t\tif (v === \"visible\") {\r\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\r\n\t\t\t\t} else if (v === \"enable\") {\r\n\t\t\t\t\t// 💡 enable이 false면 비활성화(disabled = true), true면 활성화(disabled = false)\r\n\t\t\t\t\t//const isEnabled = !!result;\r\n\r\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\r\n\t\t\t\t\t\t$el.disabled = !result;\r\n\t\t\t\t\t});\r\n\r\n\r\n\t\t\t\t\tif (!!result) {\r\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#cell.style[v] = result;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn val;\r\n\t}\r\n\r\n\tgetExprValue(expr, data, row) {\r\n\t\t//trace.log(\"********************************************\", expr, data, row);\r\n\r\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row);\r\n\r\n\r\n\t\tif (expr === undefined) return expr;\r\n\t\tconsole.trace(\"********************************************\");\r\ntrace.log(\"********************************************\", expr);\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst trimmedExpr = expr.trim();\r\n\t\t\t//const fields = this.#host?.fields;\r\n\r\n\t\t\t// 🎯 1. 데이터가 원시 배열 구조인 경우 표현식 내부의 필드명을 인덱스로 자동 치환\r\n\t\t\t//const isRawArray = data && typeof data === 'object' && Array.isArray(data.v);\r\n\t\t\t//const compiledExpr = isRawArray ? this.#rewriteExpr(trimmedExpr, fields) : trimmedExpr;\r\n\t\t\t//trace.log(compiledExpr);\r\n\t\t\t// 2. 함수 호출식인 경우 (예: oppositeColor(...))\r\n\t\t\t//const match = trimmedExpr.match(/^([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\tconst match = trimmedExpr.match(/(?:[a-zA-Z_$][\\w$]*\\.)*([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\t//trace.log(trimmedExpr, match);\r\n\t\t\tif (match) {\r\n\t\t\t\tconst fnName = match[1].replace(\"host.\", \"\");\r\n\t\t\t\t//trace.log(fnName);\r\n\t\t\t\tif (this.#host && typeof this.#host[fnName] === 'function') {\r\n\r\n\t\t\t\t\tlet evalFn = hostFuncCache.get(trimmedExpr);\r\n\r\n\t\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\t\tconst openIdx = trimmedExpr.indexOf('(');\r\n\t\t\t\t\t\tconst closeIdx = trimmedExpr.lastIndexOf(')');\r\n\t\t\t\t\t\tconst argsString = (openIdx !== -1 && closeIdx !== -1) ? trimmedExpr.substring(openIdx + 1, closeIdx) : \"\";\r\n\r\n\t\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', 'host', `\r\n\t\t\t\t\t\t try {\r\n\t\t\t\t\t\t const data = rowItem;\r\n\t\t\t\t\t\t //console.log(data);\r\n\t\t\t\t\t\t \r\n\t\t\t\t\t\t //if (!data) return \"\";\r\n\t\t\t\t\t\t return host.${fnName}.call(host, ${argsString});\r\n\t\t\t\t\t\t } catch (err) {\r\n\t\t\t\t\t\t console.error(\"Expr eval error:\", err);\r\n\t\t\t\t\t\t return \"\";\r\n\t\t\t\t\t\t }\r\n\t\t\t\t\t `);\r\n\r\n\t\t\t\t\t\thostFuncCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn evalFn(data, row, cell, this.#host);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//trace.log(trimmedExpr);\r\n\t\t\t// 3. 일반 연산식인 경우 (예: data.v[0] + ' vs ' + data.v[1])\r\n\t\t\tif (trimmedExpr.includes(\"data.\") || trimmedExpr.includes(\"rowItem.v\") || trimmedExpr.includes(\"(\")) {\r\n\t\t\t\t//trace.log(\"=========================\")\r\n\t\t\t\tlet evalFn = exprCache.get(trimmedExpr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', `\r\n const data = rowItem;\r\n\r\n if (!data) return \"\";\r\n return ${trimmedExpr};\r\n `);\r\n\t\t\t\t\texprCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(data, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\treturn trimmedExpr;\r\n\t\t} catch (e) {\r\n\t\t\treturn [\"NG-COMBO\"].includes(this.tagName) ? \"\" : expr;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [신규] 그룹 행의 자식 데이터 목록(childRecords)을 기반으로 합계/평균/개수 등을 처리하는 메서드\r\n\t */\r\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\r\n\t\tif (!expr) return \"\";\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\r\n\r\n\t\t\t// 1. 호스트(컴포넌트)에 정의된 그룹 전용 커스텀 메서드가 있는 경우 우선 위임\r\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\r\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\t// 2. 기본 내장 집계 함수 파싱 처리 (예: sum(price), count(), avg(score) 등)\r\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\r\n\t\t\tif (match) {\r\n\t\t\t\t// 💡 groupRecord에서 자식 레코드 목록 안전하게 추출 (indices 배열 -> 실제 레코드 매핑)\r\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\r\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\r\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\r\n\r\n\t\t\t\tconst [, funcName, field] = match;\r\n\t\t\t\tconst host = this.#host;\r\n\r\n\t\t\t\tswitch (funcName.toLowerCase()) {\r\n\t\t\t\t\tcase 'count':\r\n\t\t\t\t\t\treturn childRecords.length;\r\n\r\n\t\t\t\t\tcase 'sum': {\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tcase 'avg': {\r\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t\treturn sum / childRecords.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 3. 호스트의 exprFunction 활용\r\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\r\n\t\t\t}\r\n\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (예: \"childRecords.reduce(...)\")\r\n\t\t\t// groupRecord 자체나 내부 자식들을 활용하는 표현식 문자열 처리\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (안전성 강화 버전)\r\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\r\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\r\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\r\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\r\n \r\n let childRecords = [];\r\n if (Array.isArray(indices)) {\r\n // indices가 숫자 인덱스 배열인지, rowid 문자열 배열인지 판별하여 안전하게 추출\r\n childRecords = indices.map(idx => {\r\n if (typeof idx === 'number') {\r\n return allRecords[idx];\r\n } else {\r\n // rowid 등 문자열 식별자인 경우 전체 배열에서 찾거나 dataManager 활용\r\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\r\n }\r\n }).filter(Boolean);\r\n }\r\n \r\n // 만약 위에서 못 찾았는데 host.grouping을 쓸 수 있다면 매니저 위임 시도\r\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\r\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\r\n }\r\n\r\n const data = childRecords; // data.length 등을 쓸 수 있도록 호환\r\n return ${expr};\r\n `);\r\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\r\n\t\t\t}\r\n\r\n\t\t\treturn expr;\r\n\t\t} catch (e) {\r\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\r\n\t\t\treturn expr;\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class EditableCellElement extends CellElement {\r\n\r\n\tget host() { return super.host; }\r\n\tget sheet() { return super.sheet; }\r\n\tget cell() { return super.cell; }\r\n\tget tr() { return super.tr; }\r\n\tget attr() { return super.attr; }\r\n\r\n\tgetExprValue(expr, data, row, cell) {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\t/**\r\n\t\tthis.querySelectorAll(\"input, textarea\").forEach($el => {\r\n\t\t\t$el.addEventListener(\"change\", (event) => {\r\n\t\t\t\tif (!this.closest(\"tbody\")) return;\r\n\r\n\t\t\t\tconst target = event.target;\r\n\t\t\t\tconst inputType = target.getAttribute('type');\r\n\r\n\t\t\t\tif (inputType === \"checkbox\") {\r\n\t\t\t\t\tconst trueVal = super.attr[\"true-value\"] || \"Y\";\r\n\t\t\t\t\tconst falseVal = super.attr[\"false-value\"] || \"N\";\r\n\t\t\t\t\tthis.value = target.checked ? trueVal : falseVal;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlet v = target.value;\r\n\t\t\t\t\tconst maxbyte = super.attr[\"maxbyte\"];\r\n\r\n\t\t\t\t\ttrace.log(maxbyte);\r\n\r\n\t\t\t\t\tif (maxbyte) {\r\n\t\t\t\t\t\tconst byteLen = nine.getByteLength(v);\r\n\t\t\t\t\t\tif (byteLen >= parseInt(maxbyte, 10)) {\r\n\t\t\t\t\t\t\tv = nine.cut(v, parseInt(maxbyte, 10));\r\n\t\t\t\t\t\t\ttarget.value = v;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tthis.value = this.getAttribute(\"type\") === \"number\" ? (isNaN(v) ? \"\" : Number(v)) : v;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsuper.sheet.invalidate();\r\n\t\t\t});\r\n\t\t}); */\r\n\t}\r\n\r\n\trefresh() {\r\n\t\treturn super.refresh();\r\n\t}\r\n\r\n\tgetExprValue = (expr, data, row, cell) => {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n}","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\n\t\tsuper.refresh();\n\n\t\tthis.#target.value = this.value;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"input\", e => {\n\t\t\tconst maxbyte = this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\n\t\t\tif (maxbyte) {\n\t\t\t\tconst maxByteNum = Number(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\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<style>\n\t\t\t\tcell-input {\n\t\t\t\t\tinput {\n\t\t\t\t\t\tposition: relative;\n\t\t\t\t\t\t-moz-user-select: auto;\n\t\t\t\t\t\t-webkit-user-select: auto;\n\t\t\t\t\t\t-ms-user-select: auto;\n\t\t\t\t\t\tuser-select: auto;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 26px;\n\t\t\t\t\t\tborder: 1px solid #eee;\n\t\t\t\t\t\tborder-radius: 3px;\n\t\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t\t\toutline: 0;\n\t\t\t\t\t\tfont: inherit;\n\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\tbackground-color: white;\n\t\t\t\t\t\tcolor: #333;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tinput:read-only {\n\t\t\t\t\t\tborder-color: #fdfdfd;\n\t\t\t\t\t\tfilter: brightness(97%);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n\t\t\t<input type=\"text\" ondragstart=\"return false;\">\n\t\t`;\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\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\tthis.#target.addEventListener(\"keydown\", this.#onKeyDown);\n\n\t\t// change 대신 input 이벤트를 사용하면 색상을 고르는 즉시 바로 적용됩니다.\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tthis.value = event.target.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 만약 색상 선택 창을 닫을 때(확정할 때) 추가로 처리할 로직이 필요하다면 change에 남겨둘 수 있습니다.\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\t//this.#target.style.backgroundColor = this.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\t/**\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t}); */\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n \t\tcell-input-number {\n\t\t\t\t\tinput[type=text].border-left-none {\n\t\t\t\t\t\t border-left: 0;\n\t\t\t\t\t\t border-top-left-radius: 0;\n\t\t\t\t\t\t border-bottom-left-radius: 0;\n\t\t\t\t\t }\n\t\t\t\t\t input[type=text].border-right-none {\n\t\t\t\t\t\t border-right: 0;\n\t\t\t\t\t\t border-top-right-radius: 0;\n\t\t\t\t\t\t border-bottom-right-radius: 0;\n\t\t\t\t\t }\n\t\t\n\t\t\t\t\t input[type=text] {\n\t\t\t\t\t\t position: relative;\n\t\t\t\t\t\t -moz-user-select: auto;\n\t\t\t\t\t\t -webkit-user-select: auto;\n\t\t\t\t\t\t -ms-user-select: auto;\n\t\t\t\t\t\t user-select: auto;\n\t\t\t\t\t\t width: 100%;\n\t\t\t\t\t\t height: 26px;\n\t\t\t\t\t\t border: 1px solid #eee;\n\t\t\t\t\t\t border-radius: 3px;\n\t\t\t\t\t\t padding-left: 4px;\n\t\t\t\t\t\t outline: 0;\n\t\t\t\t\t\t font: inherit;\n\t\t\t\t\t\t box-sizing: border-box;\n\t\t\t\t\t\t background-color: white;\n\t\t\t\t\t\t color: #333;\n\t\t\t\t\t\t text-align: right; /* 숫자는 기본적으로 우측 정렬이 어울림 */\n\t\t\t\t\t }\n\t\n\t\t\t\t\t input[type=text]:read-only {\n\t\t\t\t\t\t border-color: #fdfdfd;\n\t\t\t\t\t\t filter: brightness(97%);\n\t\t\t\t\t }\n \t\t}\n </style>\n\n <input type=\"text\" ${attr.join(\" \")} ondragstart=\"return false;\">\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tthis.#target.value = v !== undefined && v !== null ? v : \"\";\n\t\t\tthis.#validateInput(this.#target.value);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\n\t\tif (!this.#target) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tconst num = Number(val);\n\t\t\tif (isNaN(num) ||\n\t\t\t\t(super.attr.max !== null && super.attr.max !== undefined && num > Number(super.attr.max)) ||\n\t\t\t\t(super.attr.min !== null && super.attr.min !== undefined && num < Number(super.attr.min))\n\t\t\t) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (super.attr.scale !== null && super.attr.scale !== undefined) {\n\t\t\t\tconst strVal = String(val);\n\t\t\t\tconst dotIdx = strVal.indexOf('.');\n\t\t\t\tif (dotIdx >= 0 && strVal.substring(dotIdx + 1).length > Number(super.attr.scale)) {\n\t\t\t\t\tsuper.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 selectionEnd = target.selectionEnd;\n\t\tconst key = e.key;\n\n\t\tif (key === \"-\") {\n\t\t\t// 이미 마이너스가 존재하거나, 커서가 맨 앞(0)이 아니면 차단 (중간이나 끝에 입력 방지)\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(super.attr.scale);\n\t\t\t// scale이 설정되지 않았거나(0 이하), 이미 소수점이 존재하면 차단\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\t// 마이너스만 있는 상태(\"-\")에서 바로 소수점이 찍히는 것(-.)을 막으려면 아래 조건 추가 가능\n\t\t\t// if (value === \"-\" && selectionStart === 1) { e.preventDefault(); return; }\n\t\t}\n\n\t\tlet validKey = [];\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && Number(super.attr.scale) > 0) validKey.push(\".\");\n\t\tif (super.attr.min === null || super.attr.min === undefined || Number(super.attr.min) > 0) validKey.push(\"-\");\n\n\t\t// 숫자 키패드 및 상단 숫자 키 허용 + 소수점/마이너스 허용\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\t// 소수점 자리수(scale) 제한 체크\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && 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(super.attr.scale)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (super.attr.maxbyte && nine.getByteLength(e.target.value) >= Number(super.attr.maxbyte) && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\te.preventDefault();\n\t\t}\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\n\tconstructor () {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input[type=color]\");\n\t\tthis.#btn = this.querySelector(\"button\");\n\t\tif (!this.#target) return;\n\n\t\t// 버튼 클릭 시 컬러 input을 프로그래밍 방식으로 클릭하여 팝업 오픈\n\t\tif (this.#btn) {\n\t\t\tthis.#btn.addEventListener(\"click\", () => {\n\t\t\t\tthis.#target.click();\n\t\t\t});\n\t\t}\n\n\t\t// 색상 변경 즉시 반영\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.#validateInput(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.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\tthis.#target.click();\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-color {\n --position: relative;\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-color.invalid button {\n padding: 2px;\n }\n cell-input-color.invalid button:after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-input-color input[type=color] {\n width: 100%;\n height: 26px;\n padding: 0px;\n margin-left: unset;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-color: transparent;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color input[type=color]::-webkit-color-swatch {\n border: 0;\n border-top-left-radius: 2px;\n border-bottom-left-radius: 2px;\n }\n cell-input-color input[type=color]::-webkit-color-swatch-wrapper {\n padding: 1px;\n }\n\n cell-input-color button {\n display: inline-flex;\n width: 24px;\n height: 26px;\n margin-right: unset;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color button:after {\n content: \"\";\n border-top: 0.3em solid #333;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n cell-input-color input[type=color]:hover {\n filter: brightness(90%);\n }\n cell-input-color button:hover {\n filter: brightness(95%);\n }\n \n .CELL-INPUT-COLOR {\n \n }\n </style>\n\n <input type=\"color\" ${attr.join(\" \")} ondragstart=\"return false;\">\n <button tabindex=\"-1\" type=\"button\"></button>\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tconst val = v !== undefined && v !== null && v !== \"\" ? v : \"#ffffff\";\n\t\t\tthis.#target.value = val;\n\t\t\tthis.#validateInput(val);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\t\tthis.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tif (!this.#isValidColor(val)) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tthis.classList.add(\"invalid\");\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\tthis.applyBaseStyle();\n\n\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#type = super.attr[\"date-type\"] || \"date\";//this.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\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\t// 값 변경 시 즉시 반영 및 검증\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.#validateInput(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.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\t// 필요 시 추가 동작\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst height = parseInt(this.closest(\"tr\")?.style.height || \"26\", 10) - 1;\n\n\t\tlet attr = [];\n\t\tfor (var i = 0; i < cell.attributes.length; i++) {\n\t\t\tif ([\"value\", \"max\", \"min\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t//if ([\"value\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t\tattr.push(`${cell.attributes[i].name}=\"${cell.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-date {\n height: 100%;\n --width: calc(100% - 8px);\n width: 100%;\n display: flex;\n align-items: center;\n --margin-left: 4px;\n --margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-date input {\n position: relative;\n height: 26px;\n padding: 0;\n margin: 0;\n font: inherit;\n width: 100%;\n padding-left: 4px;\n border: 1px solid #f0f0f0;\n border-radius: 3px;\n outline: 0;\n background-color: transparent;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"black\" viewBox=\"0 0 16 16\"><path d=\"M11 7.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z\"/><path d=\"M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M2 2a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/><path d=\"M2.5 4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5z\"/></svg>');\n background-repeat: no-repeat;\n background-position: right 2px center;\n background-size: 14px auto;\n color: #333;\n box-sizing: border-box;\n }\n\n cell-input-date input:hover {\n filter: brightness(95%);\n }\n \n cell-input-date input::-webkit-calendar-picker-indicator {\n position: absolute;\n right: 0;\n top: 0;\n width: 16px;\n height: 100%;\n background: transparent;\n --color: transparent;\n cursor: pointer;\n \t--opacity: 0.3;\n \t--filter: brightness(80%);\n }\n \n\t\t\t\n\t\t\t\n cell-input-date input::before {\n content: attr(data-placeholder);\n position: absolute;\n display: flex;\n align-items: center;\n width: calc(100% - 22px);\n height: 100%;\n background-color: white;\n left: 1px;\n top: 1px;\n pointer-events: none;\n }\n\n cell-input-date input.has-value::before,\n cell-input-date input:focus::before {\n display: none;\n }\n\n cell-input-date input:focus {\n border: 1px solid #28a745;\n border-radius: 3px;\n }\n \n \n </style>\n\n <input\n type=\"${cell.getAttribute('date-type') || 'date'}\"\n data-placeholder=\"${cell.getAttribute('placeholder') || 'Select'}\"\n ${attr.join(\" \")}\n required\n />\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (!this.#target) return v;\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\t//trace.log(this.#type, formattedVal);\n\n\t\tthis.#target.value = formattedVal || \"\";\n\t\tthis.#target.classList.toggle(\"has-value\", !!formattedVal); // 💡 값이 있으면 클래스 추가\n\t\tthis.#validateInput(formattedVal);\n\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst min = cell?.getAttribute(\"min\");\n\t\tconst max = cell?.getAttribute(\"max\");\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tlet isValid = this.#isValidDate(val);\n\n\t\t\t// 💡 형식 검증을 통과했더라도 min/max 범위를 벗어났다면 invalid 처리\n\t\t\tif (isValid) {\n\t\t\t\tif (min && val < min) isValid = false;\n\t\t\t\tif (max && val > 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\t\t//if (ninegrid.isNull(v)) return true;\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\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 #isRadio;\n #trueText;\n #falseText;\n\n constructor() {\n super();\n\n\n }\n\n connectedCallback() {\n this.#renderer();\n\n super.connectedCallback();\n\n this.#init();\n }\n\n get trueValue() {\n return super.attr[\"true-value\"] || \"Y\";\n }\n get falseValue() {\n return super.attr[\"false-value\"] || \"N\";\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 #init = () => {\n this.#target = this.querySelector(\"input\");\n this.#label = this.querySelector(\"span\");\n\n this.#trueText = super.attr[\"true-text\"] || \"\";\n this.#falseText = super.attr[\"false-text\"] || \"\";\n //this.#isRadio = super.attr[\"is-radio\"] || false;\n\n // 헤더에 있는 체크박스인 경우 (전체 선택/해제 기능)\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 // 스페이스바 입력 시 값 토글 처리\n this.cell?.addEventListener(\"keydown\", (e) => {\n\n e.preventDefault();\n\n if (e.code === \"Space\") return;\n if (this.closest(\"thead\")) return; // 헤더는 제외\n if (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n if (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\n //this.value = newVal;\n if (this.#isRadio) {\n this.selectAll(false);\n }\n\n this.value = newVal;\n\n super.sheet.invalidate();\n });\n\n\n this.#target.addEventListener(\"change\", (event) => {\n if (!this.closest(\"tbody\")) return;\n\n //const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\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 super.sheet.rowManager.refresh(true);\n //super.sheet.invalidate();\n });\n }\n\n #renderer = () => {\n\n const $cell = this.closest(\"th,td\");\n\n this.#isRadio = $cell?.getAttribute(\"is-radio\") || false;\n\n const trueValue = $cell?.getAttribute(\"true-value\") || false;\n //const selectedBorderColor = this.getAttribute(\"selected-border-color\") || \"dimgray\";\n\n const originalContent = $cell?.getAttribute(\"content\") || \"\";\n const childHtml = this.#isRadio ? `<input type=\"radio\" value=\"${trueValue}\" />` : `<label><input type=\"checkbox\" /><span>${originalContent}</span></label>`;\n\n // 🎯 div.ng-wrap 없이 cell-checkbox(Host) 자체를 플렉스 컨테이너로 활용하여 중앙정렬 보장\n this.innerHTML = `\n <style>\n .CELL-CHECKBOX {\n cell-checkbox {\n justify-content: center;\n }\n label {\n display: flex;\n }\n input {\n background-color: #ffffff;\n }\n \n \n /* 라디오 버튼 스타일 */\n input[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n .CELL-CHECKBOX[text-align='left'] {\n cell-checkbox {\n justify-content: flex-start;\n }\n }\n .CELL-CHECKBOX[text-align='center'] {\n cell-checkbox {\n justify-content: center;\n }\n }\n .CELL-CHECKBOX[text-align='right'] {\n cell-checkbox {\n justify-content: flex-end;\n }\n label {\n flex-direction: row-reverse;\n }\n }\n \n \n \n cell-checkbox {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n }\n cell-checkbox label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n cursor: pointer;\n user-select: none;\n }\n cell-checkbox input {\n outline: none;\n }\n \n </style>\n ${childHtml}\n `;\n }\n\n refresh = () => {\n const val = super.refresh(); // CellElement의 원시값 직통 조회 활용\n\n if (!this.closest(\"tbody\") && !this.closest(\"thead\")) return val;\n\n // 체크박스 상태 동기화\n if (this.#target) {\n this.#target.checked = (val === this.trueValue);\n this.#validateInput(val);\n }\n\n // 라벨 텍스트 동기화\n if (this.#label) {\n const displayText = (val === this.trueValue) ? this.#trueText : ((val === this.falseValue) ? this.#falseText : val);\n this.#label.textContent = displayText;\n }\n\n return val;\n };\n\n #validateInput = (val) => {\n\n if (!this.#target) return;\n\n super.cell.classList.remove(\"invalid\");\n\n if (val !== \"\" && val !== null && val !== undefined) {\n if (val !== this.trueValue && val !== this.falseValue) {\n super.cell.classList.add(\"invalid\");\n }\n }\n };\n\n selectAll = (v) => {\n if (this.closest(\"thead\")) return; // 헤더 자신은 제외\n\n const data = super.host.data.getArray();\n const colIndex = super.host.fields.indexOf(super.cell.dataset.bind);\n\n if (colIndex < 0) return;\n\n for (let i = 0; i < data.length; i++) {\n if (super.attr.enable && super.getExprValue(super.attr.enable, data[i], i, super.cell) === false) continue;\n if (super.attr.readonly && super.getExprValue(super.attr.readonly, data[i], i, super.cell) === true) continue;\n if (super.attr.visible && super.getExprValue(super.attr.visible, data[i], i, super.cell) === false) continue;\n\n data[i].v[colIndex] = v ? this.trueValue : this.falseValue;\n }\n\n super.sheet.invalidate();\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\";\nimport {NINE_TABLE} from \"@\";\n\nclass CellRadio extends EditableCellElement {\n\t#target;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\n\t#host;\n\t#sheet;\n\t#cell;\n\t#tr;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#keyName = this.closest(\"th,td\").getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = this.closest(\"th,td\").getAttribute(\"value-name\") || \"v\";\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\n\n\t\tthis.#rendererRadio();\n\n\t\tthis.#initEvent();\n\n\t\t// 3. 사용자 인터랙션 (스페이스바로 라디오 순회 변경)\n\n\t}\n\n\t#initEvent = () => {\n\t\tsuper.cell.addEventListener(\"keydown\", e => {\n\n\t\t\te.preventDefault();\n\n\t\t\tif (e.code !== \"Space\") return;\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\tlet matchIndex = -1;\n\n\t\t\tconst targets = Array.from(this.querySelectorAll(\"input\"));\n\t\t\ttargets.forEach(($el,index) => {\n\t\t\t\tif (this.value === $el.getAttribute(\"value\")) {\n\t\t\t\t\tmatchIndex = index;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmatchIndex = (matchIndex === targets.length - 1) ? 0 : (matchIndex >= 0 ? matchIndex + 1 : 0);\n\t\t\tthis.value = targets[matchIndex].getAttribute(\"value\");\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#rendererRadio = () => {\n\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\ttrace.log(\"==============================================\");\n\t\ttrace.log(this.sheet, this.#dataSource);\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(\"1111\");\n\t\t}, 300)\n\n\t\tthis.#target.replaceChildren();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tconst codeVal = v[this.#keyName] !== undefined ? v[this.#keyName] : '';\n\t\t\t\tconst nameVal = v[this.#valueName] !== undefined ? v[this.#valueName] : '';\n\n\t\t\t\t// <label> 생성\n\t\t\t\tconst label = document.createElement('label');\n\n\t\t\t\t// <input type=\"radio\" value=\"...\"> 생성\n\t\t\t\tconst input = document.createElement('input');\n\t\t\t\tinput.type = 'radio';\n\t\t\t\tinput.value = codeVal;\n\n\t\t\t\t// <span>텍스트</span> 생성 (textContent를 써야 XSS 방어 및 안전합니다)\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tspan.textContent = nameVal;\n\n\t\t\t\t// 조립\n\t\t\t\tlabel.appendChild(input);\n\t\t\t\tlabel.appendChild(span);\n\t\t\t\tfragment.appendChild(label);\n\t\t\t});\n\n\t\t\tthis.#target.appendChild(fragment);\n\n\t\t\tthis.querySelectorAll(\"input\").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\tsuper.sheet.rowManager.refresh(true);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\n\t\t// 4. 마우스 클릭 시 값 변경 및 즉시 반영\n\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n <style>\n \t.CELL-RADIO {\n \t\t\tinput[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n \n \t.CELL-RADIO[text-align='left'] {\n cell-radio {\n justify-content: flex-start;\n }\n }\n .CELL-RADIO[text-align='center'] {\n cell-radio {\n justify-content: center;\n }\n }\n .CELL-RADIO[text-align='right'] {\n cell-radio {\n justify-content: flex-end;\n }\n }\n \n cell-radio {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n \n div {\n \tdisplay: flex;\n \t\t\t\t\tflex-direction: row;\n }\n }\n\n cell-radio.invalid::after {\n content: '';\n margin-left: 4px;\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-radio input {\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n padding: 0;\n margin: 0;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border: 1px solid dimgray;\n border-radius: 50%;\n outline: 0;\n cursor: pointer;\n }\n\n cell-radio input:checked {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3\" cx=\"50%\" cy=\"50%\" fill=\"dimgray\" /></svg>');\n }\n\n cell-radio label {\n display: flex;\n align-items: center;\n margin-right: 8px;\n cursor: pointer;\n user-select: none;\n }\n\n cell-radio label.disabled {\n pointer-events: none;\n opacity: 0.5;\n }\n\n cell-radio span {\n margin-left: 4px;\n font-size: 12px;\n }\n </style>\n \n <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\tif (!this.#target) return v;\n\n\t\tthis.querySelectorAll(\"input\").forEach($el => {\n\t\t\t$el.checked = (this.value == $el.getAttribute(\"value\")) ? true : false;\n\t\t});\n\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\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 idx = this.#dataSource.findIndex(m => this.value === m[this.#keyName]);\n\t\tif (idx < 0) {\n\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-radio')) {\n\tcustomElements.define(\"cell-radio\", CellRadio);\n}","import { trace } from \"@nopeer\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#parent;\n\t#keyName;\n\t#valueName;\n\t#isOpen = false;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tthis.#initEvents();\n\t}\n\n\t#initData = (dataSource, keyName, valueName, multi, separator) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource || dataSource.length === 0) return;\n\n\t\t// 1. 부모(parent)의 items 속성 확인 (예: \"CODE,NAME,DESC\" 형태)\n\t\tconst itemsAttr = this.#parent.getAttribute(\"items\");\n\t\tlet fieldKeys = [];\n\n\t\tif (itemsAttr) {\n\t\t\tfieldKeys = itemsAttr.split(\",\").map(s => s.trim());\n\t\t} else {\n\t\t\tfieldKeys = [valueName].filter(Boolean);\n\t\t}\n\n\t\tconst activeColumnCount = fieldKeys.length;\n\n\t\t// 2. 🎯 [수정] multi 모드 여부에 따라 0번 컬럼(체크박스) 가시성 제어\n\t\t//trace.log(grd.shadowRoot, grd.shadowRoot.querySelectorAll('nine-table-body table'));\n\t\tgrd.shadowRoot.querySelector(\".ng-container-left\").style.display = multi ? '' : 'none';\n\n\t\tgrd.shadowRoot.querySelectorAll('table colgroup col, tbody td').forEach(($el, idx) => {\n\t\t\ttrace.log($el);\n\n\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\tif (col >= 2) {\t// row-indicator, checkbox 제외\n\t\t\t\t$el.style.display = (col - 2 >= activeColumnCount) ? 'none' : '';\n\t\t\t}\n\t\t});\n\n\t\t// 3. 동적 데이터 매핑 (dataSource 원본 객체에서 fieldKeys 순서대로 tmp1 ~ tmpN에 매핑)\n\t\tconst formattedData = dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: keyName && item[keyName] !== undefined ? item[keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\tfieldKeys.forEach((key, idx) => {\n\t\t\t\trow[`tmp${idx + 1}`] = item[key] !== undefined ? item[key] : (item[idx] !== undefined ? item[idx] : \"\");\n\t\t\t});\n\t\t\treturn row;\n\t\t});\n\n\t\tgrd.data.set(formattedData);\n\n\t\t// 4. 멀티 모드일 때 기존 선택값 반영\n\t\tif (multi && this.#parent.value) {\n\t\t\tconst selectedKeys = String(this.#parent.value).split(separator || \",\");\n\t\t\tgrd.data.getValidData().forEach(m => {\n\t\t\t\tif (selectedKeys.includes(String(m.v[1]))) {\n\t\t\t\t\tm.v[0] = \"Y\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tgrd.refreshData();\n\t\t}\n\t};\n\n\topen = (parent, dataSource, keyName, valueName, multi, separator) => {\n\t\tthis.#parent = parent;\n\t\tthis.#keyName = keyName;\n\t\tthis.#valueName = valueName;\n\t\tthis.#isOpen = true;\n\n\t\ttrace.log(new Date());\n\n\t\tthis.classList.add(\"active\");\n\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource) return;\n\n\t\t// 🎯 패널을 열자마자 active를 주어 레이아웃(offsetHeight) 확보 및 초기화 수행\n\n\n\t\t// 검색어 초기화 및 체크박스 기본값 설정\n\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\t// 데이터 개수 및 모드에 따른 클래스 제어\n\t\tif (dataSource.length > 10) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tif (multi) {\n\t\t\tthis.classList.add(\"multi\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"multi\");\n\t\t}\n\n\t\t// 데이터 및 멀티컬럼 구조 초기화 실행\n\n\t\t// 🎯 [필터 패널 방식 위치 정렬 적용] 시트(sheet) 기준 상대 좌표계산\n\t\tconst sheet = parent.closest(\"nine-table-sheet\");\n\t\tconst btnEl = parent.querySelector(\".btn1\");\n\t\tif (!btnEl || !sheet) return;\n\n\t\tconst btnRect = btnEl.getBoundingClientRect();\n\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\tlet left = btnRect.left - sheetRect.left;\n\t\tlet top = btnRect.bottom - sheetRect.top + 2;\n\n\t\t// 화면 오른쪽 밖으로 넘칠 경우 보정\n\t\tconst panelWidth = this.offsetWidth || 250;\n\t\tconst panelHeight = this.offsetHeight || 250;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 5);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\tif (top + panelHeight > sheetRect.height) {\n\t\t\tconst upwardTop = (btnRect.top - sheetRect.top) - panelHeight - 2;\n\t\t\tif (upwardTop >= 0) {\n\t\t\t\ttop = upwardTop; // 위쪽 공간이 있으면 위로 팝업\n\t\t\t} else {\n\t\t\t\ttop = Math.max(0, sheetRect.height - panelHeight - 5); // 위아래 다 부족하면 시트 하단에 밀착\n\t\t\t}\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\t// 내부 그리드 행 클릭 이벤트 바인딩 (싱글 모드용)\n\t\ttrace.log(new Date());\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(new Date());\n\t\t\tthis.#initData(dataSource, keyName, valueName, multi, separator);\n\t\t\ttrace.log(new Date());\n\t\t\tconst viewContainer = grd.shadowRoot.querySelector(\".ng-container-body table tbody.body\");\n\n\t\t\t// 중복 바인딩 방지를 위한 플래그 체크 또는 기존 리스너 관리\n\t\t\tif (!viewContainer.__hasClickEvent) {\n\n\t\t\t\tviewContainer.addEventListener(\"mousedown\", (e) => {\n\t\t\t\t\ttrace.log(\"==========================================\", e.target);\n\n\t\t\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\t\t\tif (!tr) return;\n\n\t\t\t\t\ttrace.log(\"==========================================\", multi);\n\n\t\t\t\t\tif (!multi) {\n\t\t\t\t\t\tthis.#onClickRow(e);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tviewContainer.__hasClickEvent = true;\n\t\t\t}\n\n\t\t\ttrace.log(new Date());\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#isOpen = false;\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus();\n\t\t}\n\t}\n\n\t#onClickRow = (e) => {\n\n\t\tconst sheet = e.target.closest(\"nine-table-sheet\");\n\t\tconst tr = e.target.closest(\"tr\");\n\n\t\tconst rowIndex = parseInt(tr.dataset.row, 10);\n\t\tconst record = sheet.view.get(rowIndex);\n\n\t\tthis.#parent.value = record.k;\n\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onOk = () => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst data = grd.data.getValidData();\n\n\t\tconst selectedKeys = [];\n\t\tdata.forEach(o => {\n\t\t\tif (o.v[0] === \"Y\") {\n\t\t\t\tselectedKeys.push(o.v[1]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = selectedKeys.join(this.#parent.getAttribute(\"multi-separator\") || \",\");\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onSelectAll = (e) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst isChecked = e.target.checked ? \"Y\" : \"N\";\n\t\tgrd.data.getValidData().forEach(m => { m.v[0] = isChecked; });\n\t\tgrd.refreshData();\n\t}\n\n\t#onInput = (e) => {\n\t\tconst keyword = e.target.value.toLowerCase();\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\n\t\t// 동적 컬럼(모든 밸류) 대상 검색 대응\n\t\tgrd.data.getValidDataNF().forEach(m => {\n\t\t\tconst match = Object.values(m.v).some(val =>\n\t\t\t\tval !== null && val !== undefined && String(val).toLowerCase().includes(keyword)\n\t\t\t);\n\t\t\tm.__ng.filtered = !match;\n\t\t});\n\n\t\tgrd.data.resetRecords();\n\t\tgrd.dataManager.viewRecords.reset();\n\t}\n\n\tget isOpen() {\n\t\treturn this.#isOpen;\n\t}\n\n\tget targetCell() {\n\t\treturn this.#parent;\n\t}\n\n\t#initEvents = () => {\n\t\tthis.querySelector(\".search-input\").addEventListener(\"input\", this.#onInput);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\n\n\t\t// 🎯 [개선] open() 할 때마다 붙일 필요 없이, 내부 그리드 영역에 이벤트 위임 처리\n\n\t\t/**\n\t\t// shadowRoot 내부 또는 컴포넌트 전체 영역을 감싸는 리스너 등록\n\t\tthis.querySelector(\"nine-table-simple\").addEventListener(\"click\", (e) => {\n\t\t\ttrace.log(e);\n\n\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\tif (!tr) return;\n\n\t\t\t// 멀티 모드가 아닐 때만 행 클릭 동작 수행\n\t\t\tconst isMulti = this.classList.contains(\"multi\");\n\t\t\tif (!isMulti) {\n\t\t\t\tthis.#onClickRow(e, false, grd);\n\t\t\t}\n\t\t}); */\n\n\t\t// 패널 외부 클릭 시 닫기\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\t\t\tconst path = e.composedPath ? e.composedPath() : [];\n\n\t\t\t// 패널 자신이나 현재 열려 있는 필터 버튼이 경로에 포함되어 있다면 닫지 않음\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 <style>\n \n cell-combo-panel.active {\n display: flex;\n }\n cell-combo-panel .head {\n display: none;\n padding: 6px;\n background: #f8f9fa;\n border-bottom: 1px solid #e5e7eb;\n }\n cell-combo-panel .head input[type=\"text\"] {\n width: 100%;\n height: 26px;\n padding: 0 6px;\n box-sizing: border-box;\n border: 1px solid #d1d5db;\n border-radius: 3px;\n outline: none;\n font-size: 12px;\n }\n cell-combo-panel.expand .head {\n display: flex;\n }\n cell-combo-panel nine-table-simple {\n width: 100%;\n flex: 1;\n border: none;\n }\n cell-combo-panel .footer {\n display: none;\n height: 32px;\n background: #f3f4f6;\n border-top: 1px solid #e5e7eb;\n align-items: center;\n padding: 0 8px;\n box-sizing: border-box;\n }\n cell-combo-panel.multi .footer {\n display: flex;\n justify-content: space-between;\n }\n cell-combo-panel .footer label {\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n }\n cell-combo-panel .footer button {\n height: 22px;\n padding: 0 12px;\n font-size: 11px;\n cursor: pointer;\n background: #2563eb;\n color: white;\n border: none;\n border-radius: 3px;\n }\n cell-combo-panel .footer button:hover {\n background: #1d4ed8;\n }\n </style>\n \n <div class=\"head\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\n </div>\n \n <nine-table-simple class=\"combo-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"30\" fixed=\"left\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"0\" />\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"tmp1\" />\n <td data-bind=\"tmp2\" />\n <td data-bind=\"tmp3\" />\n <td data-bind=\"tmp4\" />\n <td data-bind=\"tmp5\" />\n <td data-bind=\"tmp6\" />\n <td data-bind=\"tmp7\" />\n <td data-bind=\"tmp8\" />\n <td data-bind=\"tmp9\" />\n <td data-bind=\"tmp10\" />\n <td data-bind=\"k\" />\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n \n <div class=\"footer\">\n <div>\n <input id=\"chkAll\" type=\"checkbox\" checked>\n <label for=\"chkAll\">Select All</label>\n </div>\n <button id=\"btnOk\">OK</button>\n </div>\n `;\n\t};\n}\n\nif (!customElements.get('cell-combo-panel')) {\n\tcustomElements.define(\"cell-combo-panel\", CellComboPanel);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport \"./cell-combo-panel.js\";\n\nexport class CellCombo extends EditableCellElement {\n\t#targetBtn;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\t#multi;\n\t#multiSeparator;\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tthis.#keyName = super.cell.getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = super.cell.getAttribute(\"value-name\") || \"v\";\n\t\tthis.#multi = super.cell.getAttribute('multi') === \"true\";\n\t\tthis.#multiSeparator = super.cell.getAttribute(\"multi-separator\") || \",\";\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\trerenderer = () => {\n\t\ttrace.log(\"rerenderer\");\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\t#initData = () => {\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\t// 🎯 공통 표현식 평가기를 통해 데이터 소스(배열 또는 함수 결과) 획득\n\t\t//this.#host.exprEngine.evaluate(dataSource, data, row);\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\t//trace.log(\"*******************************\", this.#dataSource);\n\t}\n\n\t#initEvent = () => {\n\t\t// 엔터 키 입력 시 드롭다운 토글\n\t\tthis.addEventListener(\"keydown\", e => {\n\t\t\tif (e.code === \"Enter\") {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.#togglePanel();\n\t\t\t}\n\t\t});\n\n\t\t// Light DOM 기준이므로 this 안에서 버튼 탐색\n\t\tthis.querySelectorAll(\"button\").forEach(btn => {\n\t\t\tbtn.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\t}\n\n\t#togglePanel = () => {\n\t\ttrace.log(new Date());\n\t\tif (!this.#panel) {\n\t\t\t// 🎯 필터링 패널 방식과 동일하게 현재 셀이 속한 sheet(또는 그리드) 탐색\n\t\t\tthis.#panel = super.sheet.querySelector(\"cell-combo-panel\");\n\t\t\tif (!this.#panel) {\n\t\t\t\tthis.#panel = document.createElement(\"cell-combo-panel\");\n\t\t\t\tsuper.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\ttrace.log(new Date());\n\n\t\tif (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\t\tthis.#panel.close();\n\t\t} else {\n\t\t\tthis.#panel.open(this, this.#dataSource, this.#keyName, this.#valueName, this.#multi, this.#multiSeparator);\n\t\t}\n\n\t\ttrace.log(new Date());\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-combo {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n cell-combo.invalid .btn2::after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n cell-combo button {\n outline: none;\n cursor: pointer;\n font: inherit;\n }\n cell-combo button.btn1 {\n width: calc(100% - 24px);\n height: 26px;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n text-align: left;\n background-color: white;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 4px;\n color: #000;\n }\n cell-combo button.btn2 {\n padding: 3px;\n width: 24px;\n height: 26px;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #333;\n }\n cell-combo button.btn2:after {\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n </style>\n <button class=\"btn1\" type=\"button\" tabindex=\"-1\">Select</button>\n <button class=\"btn2\" type=\"button\" tabindex=\"-1\"></button>\n `;\n\n\t\t// Light DOM 구조이므로 this에서 직접 쿼리\n\t\tthis.#targetBtn = this.querySelector(\".btn1\");\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tif (!this.#targetBtn) return v;\n\n\t\t// 현재 값에 매칭되는 텍스트(표시명) 계산\n\t\tthis.#targetBtn.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#getDisplayText = () => {\n\t\tif (!this.value || !Array.isArray(this.#dataSource)) return \"\";\n\n\t\tif (this.#multi) {\n\t\t\tconst keys = String(this.value).split(this.#multiSeparator);\n\t\t\treturn this.#dataSource\n\t\t\t\t.filter(m => keys.includes(String(m[this.#keyName])))\n\t\t\t\t.map(m => m[this.#valueName])\n\t\t\t\t.join(this.#multiSeparator);\n\t\t} else {\n\t\t\tconst found = this.#dataSource.find(m => String(m[this.#keyName]) === String(this.value));\n\t\t\treturn found ? found[this.#valueName] : this.value;\n\t\t}\n\t}\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst list = this.#multi ? String(this.value).split(this.#multiSeparator) : [this.value];\n\t\tfor (const v of list) {\n\t\t\tconst idx = this.#dataSource.findIndex(m => String(v) === String(m[this.#keyName]));\n\t\t\tif (idx < 0) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-combo')) {\n\tcustomElements.define(\"cell-combo\", CellCombo);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\"; // Inherits from CellElement instead of EditableCellElement\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\t// Debug trace for inspecting component context and parent elements\n\t\t// trace.log(\"******************\", this, this.host, this.sheet, this.tr, this.cell);\n\n\t\tthis.#renderer();\n\n\t\t// Cache the internal text span target element\n\t\tthis.#target = this.querySelector(\"span\");\n\t}\n\n\t/**\n\t * Refreshes the cell display value based on binding and expression evaluations.\n\t */\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/**\n\t * Renders the internal markup and CSS layout rules for the cell renderer.\n\t */\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <span></span>\n `;\n\t};\n}\n\n// Register the custom element if not already defined\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\t// 부모 클래스의 connectedCallback 호출 (필수)\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\t/**\n\t * 레거시 dataRefresh 패턴 반영 (표현식 동적 평가 및 스타일링)\n\t */\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\n\t\t/**\n\t\t// 행 데이터 및 인덱스 확보\n\t\tconst rowIdx = parseInt(super.cell.dataset.row, 10);\n\t\tconst rowData = super.host?.data?.get ? super.host.data.get(rowIdx) : (this.closest(\"tr\")?.data);\n\n\t\tif (rowData && !isNaN(rowIdx)) {\n\t\t\t[\"color\", \"background\", \"border\"].forEach(attrName => {\n\t\t\t\tconst expr = this.getAttribute(attrName);\n\t\t\t\tif (expr && this.#target) {\n\t\t\t\t\tconst evaluatedVal = super.getExprValue ? super.getExprValue(expr, rowData, rowIdx, super.cell) : expr;\n\t\t\t\t\tthis.#target.style[attrName] = evaluatedVal;\n\t\t\t\t}\n\t\t\t});\n\t\t} */\n\t};\n\n\t#renderer = () => {\n\t\t/**\n\t\tconst allowedAttrs = [\"color\", \"background\", \"border\", \"class\", \"style\"];\n\t\tconst attrList = [];\n\n\t\tfor (let i = 0; i < this.attributes.length; i++) {\n\t\t\tconst attr = this.attributes[i];\n\t\t\tif (allowedAttrs.includes(attr.name)) {\n\t\t\t\tattrList.push(`${attr.name}=\"${attr.value}\"`);\n\t\t\t}\n\t\t} */\n\n\t\tconst cell = this.closest(\"th,td\");\n\n\t\tconst buttonText = \"...\";//this.getAttribute(\"text\") || super.attr[\"text\"] || \"\";\n\t\tconst height = (parseInt(cell.offsetHeight, 10) || 32) - 8;\n\n\t\tthis.innerHTML = `\n <style>\n /* 셀(td, th) 내부 패딩 제거 및 꽉 채우기 설정 */\n cell-button {\n display: flex;\n align-items: stretch;\n justify-content: stretch;\n width: 100%;\n height: ${height}px;\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n cell-button .button {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n border-radius: 0; /* 셀에 꽉 차게 보이려면 0이 깔끔할 수 있음 */\n border: 1px solid #d1d5db;\n background-color: #f3f4f6;\n color: #1f2937;\n outline: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n cell-button .button:hover {\n background-color: #e5e7eb;\n }\n cell-button .button:active {\n background-color: #d1d5db;\n }\n </style>\n <button class=\"button\">${buttonText}</button>\n `;\n\t};\n}\n\nif (!customElements.get('cell-button')) {\n\tcustomElements.define(\"cell-button\", CellButton);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRowIndicator extends CellElement {\n\t#mainTarget;\n\t#subTarget;\n\t#statusTarget;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback?.();\n\n\t\tif (this.cell) {\n\t\t\tthis.cell.removeAttribute(\"tabindex\");\n\t\t\tthis.cell.dataset.bind = \"rowState\";\n\n\t\t\tif (!this.cell.dataset.expr) {\n\t\t\t\tthis.cell.dataset.expr = \"data.__ng._[ninegrid.ROW.ORDER]\";\n\t\t\t}\n\n\t\t\tthis.cell.setAttribute(\"text-align\", \"center\");\n\t\t}\n\n\t\tthis.#mainTarget = this.querySelector(\".ng-row-main\");\n\t\tthis.#subTarget = this.querySelector(\".ng-row-sub\");\n\t\tthis.#statusTarget = this.querySelector(\".ng-row-status\");\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-row-indicator {\n display: block;\n position: absolute; /* 💡 셀 전체를 강제로 꽉 채움 */\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n box-sizing: border-box;\n user-select: none;\n }\n /* 메인 행 번호 (중앙 정렬을 위해 플렉스 적용) */\n .ng-row-main {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n text-align: center;\n overflow: hidden;\n }\n \n /* 🎯 천단위 콤마 및 분할 스타일링 */\n .ng-row-prefix {\n \tfont-weight: normal;\n font-size: 0.40rem; /* 앞자리(천단위 이상)는 아주 작게 */\n }\n .ng-row-suffix {\n font-size: 0.55rem; /* 마지막 3자리 및 콤마는 현재 셀 기본 폰트 크기 유지 */\n }\n \n /* 우측 하단: 원본/이빨빠진 번호 */\n .ng-row-sub {\n position: absolute;\n right: 2px;\n bottom: 1px;\n font-size: 0.40rem;\n line-height: 1;\n opacity: 0.2;\n pointer-events: none;\n }\n /* 우측 상단: 상태 표시 */\n .ng-row-status {\n position: absolute;\n right: 2px;\n top: 1px;\n font-size: 0.55rem;\n line-height: 1;\n pointer-events: none;\n }\n </style>\n \n <span class=\"ng-row-main\"></span>\n <span class=\"ng-row-sub\"></span>\n <span class=\"ng-row-status\"></span>\n `;\n\t}\n\n\t/**\n\t * 행 번호 및 상태 갱신\n\t */\n\trefresh = () => {\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tconst row = this.row;\n\t\tif (isNaN(row)) return;\n\n\t\tconst rawRecord = this.tr.data;\n\n\t\tif (rawRecord && rawRecord.__ng) {\n\t\t\tconst rowState = rawRecord.__ng.rowState;\n\n\t\t\t/**\n\t\t\t// 1. 행 상태에 따른 클래스 제어 및 우측 상단 상태 표시\n\t\t\tif (rowState === ninegrid.ROW_STATE.INSERT) {\n\t\t\t\tthis.classList.add('added');\n\t\t\t\tthis.classList.remove('updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"➕\";\n\t\t\t} else if (rowState === ninegrid.ROW_STATE.UPDATE) {\n\t\t\t\tthis.classList.add('updated');\n\t\t\t\tthis.classList.remove('added');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"✏️\";\n\t\t\t} else {\n\t\t\t\tthis.classList.remove('added', 'updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"\";\n\t\t\t} */\n\n\t\t\t/**\n\t\t\t// 2. 필터링 등으로 순번이 밀렸을 때 우측 하단에 원본 번호 표시\n\t\t\tif (rawRecord.__ng.i !== undefined) {\n\t\t\t\tconst currentSeq = row + 1;\n\t\t\t\tconst originalSeq = rawRecord.__ng.i + 1;\n\n\t\t\t\tif (this.#subTarget) {\n\t\t\t\t\tif (currentSeq !== originalSeq) {\n\t\t\t\t\t\tthis.#subTarget.textContent = originalSeq;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#subTarget.textContent = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} */\n\t\t}\n\n\t\tconst displayNum = this.index + 1;\n\n\t\t// 천단위 콤마 포맷팅 (예: 1234567 -> \"1,234,567\")\n\t\tconst formattedNum = displayNum.toLocaleString();\n\n\t\t// 3자리 이상일 경우 마지막 3자리(와 콤마 포함된 덩어리)를 기준으로 앞자리와 분리\n\t\tif (displayNum >= 10000) {\n\t\t\t// 뒤에서 4글자(콤마 + 3자리)를 기준으로 분리합니다. (예: \"1,234\" 와 \"567\")\n\t\t\tconst splitIndex = formattedNum.length - 4;\n\t\t\tconst prefixPart = formattedNum.substring(0, splitIndex + 1); // 천단위 이상 (작은 폰트)\n\t\t\tconst suffixPart = formattedNum.substring(splitIndex + 1); // 마지막 콤마 + 3자리 (기본 폰트)\n\n\t\t\tthis.#mainTarget.innerHTML = `\n <span class=\"ng-row-prefix\">${prefixPart}</span>\n <span class=\"ng-row-suffix\">${suffixPart}</span>\n `;\n\t\t} else {\n\t\t\t// 1000 미만인 경우 콤마만 있거나 일반 숫자로 그대로 표시\n\t\t\tthis.#mainTarget.innerHTML = `${formattedNum}`;\n\t\t}\n\n\t\tconst isSorted = this.sheet.querySelector(\"thead .asc,thead .desc\") ? true : false;\n\t\tconst isFitered = this.sheet.querySelector(\"thead nine-table-filter-button.filtered\") ? true : false;\n\n\t\tthis.#subTarget.innerHTML = row;\n\t\tthis.#subTarget.style.display = (isSorted || isFitered) ? \"\" : \"none\";\n\t};\n}\n\nif (!customElements.get('cell-row-indicator')) {\n\tcustomElements.define(\"cell-row-indicator\", CellRowIndicator);\n}","// ui/col/col-expand.js\nimport { TableCompiler, COLLAPSED_WIDTH } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColExpand extends HTMLElement {\n #sheet;\n #cell;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#cell = this.closest('th, td');\n this.#sheet = this.closest('nine-table-sheet');\n\n if (this.#cell) {\n this.#cell.style.position = 'relative';\n }\n\n const isCollapsed =\n this.getAttribute('collapsed') === 'true' ||\n this.#cell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n requestAnimationFrame(() => {\n this.collapse(true);\n });\n } else {\n this.classList.remove('collapsed');\n this.classList.add('expand');\n }\n\n this.removeEventListener('click', this.#onClick);\n this.addEventListener('click', this.#onClick);\n }\n\n #onClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (this.classList.contains('expand')) {\n this.collapse();\n } else {\n this.expand();\n }\n };\n\n /**\n * 🎯 원래 너비(dataset.expandWidth)로 복구\n */\n expand = () => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n this.classList.remove('collapsed');\n this.classList.add('expand');\n this.#cell.setAttribute('collapsed', 'false');\n this.#cell.style.color = '';\n\n const targetWidth = parseInt(this.#cell.dataset.expandWidth, 10) || 100;\n\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, targetWidth);\n } else {\n const singleWidth = Math.max(30, Math.floor(targetWidth / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, singleWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n collapse = (isInitialInit = false) => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n if (this.classList.contains('expand')) {\n const col = this.#sheet.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n const currentW = col ? parseInt(col.getAttribute('width'), 10) : 0;\n if (currentW > COLLAPSED_WIDTH) {\n this.#cell.dataset.expandWidth = String(currentW * colSpan);\n }\n }\n\n this.classList.remove('expand');\n this.classList.add('collapsed');\n this.#cell.setAttribute('collapsed', 'true');\n this.#cell.style.color = 'transparent';\n\n // 🎯 colSpan이 1이면 16px(COLLAPSED_WIDTH)을 그대로 적용, 2 이상이면 균등 분할\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, COLLAPSED_WIDTH);\n } else {\n const splitWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, splitWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n disconnectedCallback() {\n this.removeEventListener('click', this.#onClick);\n }\n}\n\nif (!customElements.get('nine-table-col-expand')) {\n customElements.define('nine-table-col-expand', ColExpand);\n}","// ui/menu/nine-table-menu.js (수정본)\n\nimport { trace } from \"@nopeer\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nexport class ContextMenu extends HTMLElement {\n #tableHost;\n #panel;\n\n connectedCallback() {\n const root = this.getRootNode();\n this.#tableHost = root instanceof ShadowRoot ? root.host : (this.closest('nine-table') || root.host);\n\n if (!this.#tableHost) {\n this.#tableHost = this.parentElement?.closest('nine-table') || this.assignedSlot?.closest('nine-table');\n }\n\n if (!this.#tableHost) return;\n\n //this.#tableHost.addEventListener('contextmenu', this.#onContextMenu);\n }\n\n #onContextMenu = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n const targetCell = path.find(el => el.tagName === 'TH' || el.tagName === 'TD');\n\n if (!targetCell) return;\n\n const targetTable = path.find(el => el.tagName === 'TABLE') || targetCell.closest('table');\n\n e.preventDefault();\n e.stopPropagation();\n\n this.openMenu(e.clientX, e.clientY, targetCell, targetTable);\n };\n\n /**\n * 🎯 우클릭이 발생한 대상 시트(NineTableSheet) 구하기\n */\n #getTargetSheet(targetCell) {\n return targetCell?.closest('nine-table-sheet') || this.#tableHost.activeSheet || this.#tableHost;\n }\n\n #getFixManager(targetCell) {\n const sheet = this.#getTargetSheet(targetCell);\n if (!sheet) return null;\n\n if (!sheet.colFix) {\n sheet.colFix = new ColFixManager(sheet);\n }\n return sheet.colFix;\n }\n\n #parseCustomMenuItems(containerElement, activeTable) {\n const items = [];\n const activeTableId = activeTable?.id;\n const allUls = Array.from(containerElement.querySelectorAll(':scope > ul'));\n\n allUls.forEach(rootUl => {\n const targetTableAttr = rootUl.getAttribute('target-table');\n\n if (!targetTableAttr || (activeTableId && targetTableAttr === activeTableId)) {\n const parsedList = this.#traverseUl(rootUl);\n items.push(...parsedList);\n }\n });\n\n return items;\n }\n\n #traverseUl(ulEl) {\n const list = [];\n Array.from(ulEl.children).forEach(child => {\n const tagName = child.tagName.toLowerCase();\n\n if (tagName === 'hr' || child.classList.contains('separator')) {\n list.push({ type: 'separator' });\n return;\n }\n\n if (tagName === 'li') {\n let name = '';\n const spanEl = child.querySelector(':scope > span');\n if (spanEl) {\n name = spanEl.textContent.trim();\n } else {\n name = Array.from(child.childNodes)\n .filter(n => n.nodeType === Node.TEXT_NODE)\n .map(n => n.textContent.trim())\n .join('');\n }\n\n const subUl = child.querySelector(':scope > ul');\n const item = {\n menuId: child.id || name,\n name: name,\n className: child.className || '',\n disabled: child.hasAttribute('disabled') || child.getAttribute('disabled') === 'true',\n isCustom: true\n };\n\n if (subUl) {\n item.items = this.#traverseUl(subUl);\n }\n\n list.push(item);\n }\n });\n return list;\n }\n\n #buildMenuItems(activeTable, isHeaderCell, targetCell) {\n const useDefault = this.getAttribute('use-default-menu') !== 'false';\n let rawItems = [];\n\n const customItems = this.#parseCustomMenuItems(this, activeTable);\n if (customItems.length > 0) {\n rawItems.push(...customItems);\n }\n\n const fixManager = this.#getFixManager(targetCell);\n const currentFixState = fixManager?.getFixState(targetCell, activeTable) ?? 'none';\n const isFixable = isHeaderCell && (fixManager?.canFixColumn(targetCell, activeTable) ?? false);\n\n let fixMenuItem = null;\n if (currentFixState === 'left' || currentFixState === 'right') {\n fixMenuItem = {\n menuId: 'unfix-column',\n name: 'Unfix Column',\n className: 'ng-menu-unfix-col',\n disabled: !isHeaderCell\n };\n } else {\n fixMenuItem = {\n menuId: 'fix-column',\n name: 'Fix Column',\n className: 'ng-menu-fix-col',\n disabled: !isFixable\n };\n }\n\n if (useDefault) {\n rawItems.push(\n { type: 'separator' },\n {\n menuId: 'sort',\n name: 'Sort',\n className: 'ng-menu-sort',\n disabled: !isHeaderCell\n },\n fixMenuItem,\n { type: 'separator' },\n { menuId: 'filtering', name: 'Filtering', className: 'ng-menu-filtering' },\n { menuId: 'maximize', name: 'Maximize', className: 'maximize' },\n {\n menuId: 'export',\n name: 'Export',\n className: 'export',\n items: [\n { menuId: 'export-excel', name: 'Excel', className: 'export-excel' },\n { menuId: 'export-pdf', name: 'PDF', className: 'export-pdf', disabled: true }\n ]\n },\n {\n menuId: 'properties',\n name: 'Options',\n className: 'options',\n items: [\n { menuId: 'show-title-bar', name: 'Title Bar Show/Hide', className: 'show-title-bar' },\n { menuId: 'show-status-bar', name: 'Status Bar Show/Hide', className: 'show-status-bar' },\n { menuId: 'auto-fit-col', name: 'Auto Fit Columns', className: 'auto-fit-col' }\n ]\n }\n );\n }\n\n const cleanedItems = [];\n rawItems.forEach((item) => {\n if (item.type === 'separator') {\n if (cleanedItems.length === 0 || cleanedItems[cleanedItems.length - 1].type === 'separator') {\n return;\n }\n }\n cleanedItems.push(item);\n });\n\n if (cleanedItems.length > 0 && cleanedItems[cleanedItems.length - 1].type === 'separator') {\n cleanedItems.pop();\n }\n\n return cleanedItems;\n }\n\n openMenu(x, y, targetCell, targetTable) {\n const targetParent = this.#tableHost.shadowRoot || this.#tableHost;\n\n if (!this.#panel) {\n this.#panel = document.createElement('nine-table-menu-panel');\n targetParent.appendChild(this.#panel);\n }\n\n const isHeaderCell = !!targetCell.closest('thead');\n const menuItems = this.#buildMenuItems(targetTable, isHeaderCell, targetCell);\n\n this.#panel.render(menuItems, (e) => this.#handleMenuClick(e, targetCell, targetTable));\n\n const targetSheet = this.#getTargetSheet(targetCell);\n this.#syncMenuStates(targetSheet);\n\n // 🎯 targetCell을 3번째 인자로 전달하여 셀 우측선 정렬\n this.#panel.openAt(x, y);\n }\n\n /**\n * 🎯 메뉴 항목 활성화 체크 표시(✓) 동기화\n */\n #syncMenuStates(targetSheet) {\n if (!this.#panel || !targetSheet) return;\n\n // 🎯 클릭된 개별 시트의 filtering 상태 검사\n const isFiltering = targetSheet.filtering?.isFiltering?.() || false;\n this.#panel.toggleItemState('filtering', 'on', isFiltering);\n\n const autoFit = this.#tableHost.getAttribute('auto-fit-col') === 'true';\n this.#panel.toggleItemState('auto-fit-col', 'on', autoFit);\n\n const showTitle = this.#tableHost.getAttribute('show-title-bar') === 'true';\n this.#panel.toggleItemState('show-title-bar', 'on', showTitle);\n }\n\n #handleMenuClick(e, targetCell, targetTable) {\n const menuId = e.menuId;\n\n const customEvent = new CustomEvent('menu-click', {\n detail: { menuId, targetCell, targetTable, originalEvent: e },\n bubbles: true,\n composed: true\n });\n this.dispatchEvent(customEvent);\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n\n // 🎯 클릭된 셀의 소속 시트 인스턴스 타겟팅\n const targetSheet = this.#getTargetSheet(targetCell);\n\n switch (menuId) {\n case 'fix-column':\n case 'unfix-column':\n const fixManager = this.#getFixManager(targetCell);\n fixManager?.executeFixToggle(menuId, targetCell);\n break;\n\n case 'sort':\n if (!isNaN(baseCol)) {\n targetSheet.sorting?.handleSortFromMenu?.(baseCol, targetCell);\n }\n break;\n\n case 'filtering':\n targetSheet?.filtering?.toggle();\n break;\n\n case 'auto-fit-col':\n this.#tableHost.setAttribute('auto-fit-col', this.#tableHost.getAttribute('auto-fit-col') === 'true' ? 'false' : 'true');\n break;\n\n case 'show-title-bar':\n this.#tableHost.setAttribute('show-title-bar', this.#tableHost.getAttribute('show-title-bar') === 'true' ? 'false' : 'true');\n break;\n }\n\n this.#panel.close();\n }\n\n disconnectedCallback() {\n this.#tableHost?.removeEventListener('contextmenu', this.#onContextMenu);\n }\n}\n\nif (!customElements.get('nine-table-menu')) {\n customElements.define('nine-table-menu', ContextMenu);\n}","// ui/menu/nine-table-menu-panel.js\n\nexport class MenuPanel extends HTMLElement {\n #onCallback;\n #closeHandler = null; // 🎯 이벤트 누수 방지용 리스너 참조\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n // 🎯 [보정 1] 패널 자체의 기본 레이아웃 스타일은 element style로 직접 지정\n this.style.position = 'fixed';\n this.style.display = 'none';\n this.style.zIndex = '99999';\n\n this.innerHTML = `\n <style>\n \n nine-table-menu-panel .menu-wrapper {\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 150px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 12px;\n }\n nine-table-menu-panel ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n nine-table-menu-panel li {\n position: relative;\n padding: 6px 16px;\n cursor: pointer;\n color: #374151;\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n }\n nine-table-menu-panel li:hover {\n background-color: #f3f4f6;\n color: #111827;\n }\n nine-table-menu-panel li.on::before {\n content: '✓';\n position: absolute;\n left: 4px;\n font-weight: bold;\n }\n nine-table-menu-panel li.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background: transparent !important;\n }\n nine-table-menu-panel li.ng-menu-separator {\n height: 1px;\n background: #e5e7eb;\n margin: 4px 0;\n padding: 0;\n cursor: default;\n }\n nine-table-menu-panel li.submenu::after {\n content: '▶';\n font-size: 9px;\n margin-left: 8px;\n color: #9ca3af;\n }\n nine-table-menu-panel .ng-menu-sublist {\n display: none;\n position: absolute;\n top: -4px;\n left: 100%;\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 140px;\n }\n nine-table-menu-panel li.submenu:hover > .ng-menu-sublist {\n display: block;\n }\n </style>\n <div class=\"menu-wrapper\">\n <ul class=\"menu-container\"></ul>\n </div>\n `;\n }\n\n render(items, callback) {\n this.#onCallback = callback;\n const container = this.querySelector('.menu-container');\n if (!container) return;\n\n container.innerHTML = '';\n\n this.#appendItems(container, items);\n this.#bindClickEvents();\n }\n\n /**\n * 🎯 패널의 우측선과 targetCell의 우측선을 일치시키는 포지셔닝\n */\n openAt(x, y, targetCell = null) {\n this.style.display = 'block';\n\n if (targetCell) {\n const cellRect = targetCell.getBoundingClientRect();\n // 셀의 오른쪽 경계선 좌표\n const cellRightX = cellRect.right;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const panelWidth = wrapper.getBoundingClientRect().width;\n\n // 패널 우측선을 셀 우측선에 맞춤 (Left = cellRight - panelWidth)\n let calculatedLeft = cellRightX - panelWidth;\n\n // 뷰포트 왼쪽 밖으로 벗어나는 예외 처리\n if (calculatedLeft < 0) {\n calculatedLeft = cellRect.left; // 공간이 부족하면 셀 좌측선에 맞춤\n }\n\n // 뷰포트 아래쪽 벗어남 처리\n const panelHeight = wrapper.getBoundingClientRect().height;\n let calculatedTop = y;\n if (y + panelHeight > window.innerHeight) {\n calculatedTop = y - panelHeight;\n }\n\n this.style.left = `${calculatedLeft}px`;\n this.style.top = `${calculatedTop}px`;\n });\n } else {\n // 기본 마우스 클릭 좌표 기반 (Fallback)\n this.style.left = `${x}px`;\n this.style.top = `${y}px`;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n\n if (x + rect.width > window.innerWidth) {\n this.style.left = `${x - rect.width}px`;\n }\n if (y + rect.height > window.innerHeight) {\n this.style.top = `${y - rect.height}px`;\n }\n });\n }\n\n // 바깥 클릭 핸들러 등록\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n }\n\n this.#closeHandler = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n if (!path.includes(this) && !this.contains(e.target)) {\n this.close();\n }\n };\n\n setTimeout(() => {\n window.addEventListener('pointerdown', this.#closeHandler);\n }, 0);\n }\n\n close() {\n this.style.display = 'none';\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n this.#closeHandler = null;\n }\n }\n\n toggleItemState(menuId, className, condition) {\n const li = this.querySelector(`li[menu-id=\"${menuId}\"]`);\n if (li) {\n condition ? li.classList.add(className) : li.classList.remove(className);\n }\n }\n\n #appendItems(parentUl, items) {\n items.forEach(item => {\n if (item.type === 'separator') {\n const sep = document.createElement('li');\n sep.className = 'ng-menu-separator';\n parentUl.appendChild(sep);\n return;\n }\n\n const li = document.createElement('li');\n li.setAttribute('menu-id', item.menuId);\n li.className = `${item.className || ''} ${item.items ? 'submenu' : ''} ${item.disabled ? 'disabled' : ''}`.trim();\n\n const span = document.createElement('span');\n span.textContent = item.name;\n li.appendChild(span);\n\n if (item.items && item.items.length > 0) {\n const subUl = document.createElement('ul');\n subUl.className = 'ng-menu-sublist';\n this.#appendItems(subUl, item.items);\n li.appendChild(subUl);\n }\n\n parentUl.appendChild(li);\n });\n }\n\n #bindClickEvents() {\n this.querySelectorAll('li[menu-id]').forEach(li => {\n li.addEventListener('click', (e) => {\n e.stopPropagation();\n if (li.classList.contains('disabled')) return;\n\n const menuId = li.getAttribute('menu-id');\n this.#onCallback?.({ menuId, target: li });\n this.close();\n });\n });\n }\n\n disconnectedCallback() {\n this.close();\n }\n}\n\nif (!customElements.get('nine-table-menu-panel')) {\n customElements.define('nine-table-menu-panel', MenuPanel);\n}"],"names":["target","start","end","mid","elementDebounceState","dblClickEvent","dblClickFn","pointerEvent","pointerFn","debounceTime","el","state","e","_text","_font","stripHtml","__name","html","tmp","canvas","context","w","h","v","cleanText","metrics","ascent","descent","_Trace","traceOrigin","Trace","trace","NINE_TABLE","_ngRow","parent","__privateAdd","_parent","_newrow","__publicField","__privateGet","__privateSet","ngRow","_ngData","host","_host","_nextId","_defaultHeight","_getValidRecords","o","_a","at","colnm","validRecords","targetRecord","idx","rowIndex","colIndex","value","rowData","_conv","fields","_initialize","templateElements","_getDefaultMeta","_invalidate","$sheets","$el","dataSource","loadData","rowid","_json2Array","jsonArray","arr","json","_defaultInsert","updateState","row","_","a","b","rowidx","targetId","item","COL_IDX","oldValue","isSingle","targetArr","result","t","i","__privateWrapper","ngData","_ngDataManager","ds","nRow","rowIdx","_b","ngDataManager","_fields","type","fName","f","_adjust","map","name","_init","rawTables","tbl","fieldName","fieldType","attr","expr","lastIndex","targetField","found","_NineTableSheets","NineTableSheets","_NineTableSheetsFooter","_NineTableSheetsFooter_instances","__privateMethod","render_fn","isMultiSelect","tabItem","index","_switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","tab","isActive","clickedTab","activeTabs","targetSheet","tabsHtml","table","className","tabName","NineTableSheetsFooter","_SheetTabItem","SheetTabItem","_Toolbar","_Toolbar_instances","_customContainer","bindEvents_fn","element","text","titleEl","syncStateFromHost_fn","isSimple","showToolbar","showMenu","caption","link","currentCaption","menuBtn","Toolbar","_NineTableHScrollBar","_owner","_dragging","_elements","_interval1","_interval2","_resizeObserver","_observeResize","track","thumb","bodyWidth","tableWidth","needsHScroll","trackWidth","thumbWidth","currentLeft","maxScrollLeft","l","maxThumbLeft","_thumbMoveTo","x","trackBound","targetX","newScrollLeft","delayScroll","pos","thumbLeft","currentThumbLeft","clearTimer","evt","trackRect","onMouseMove","moveEvent","onMouseUp","initWhenReady","NineTableHScrollBar","_NineTableVScrollBar","_sheet","_startY","_startScrollTop","_startThumbTop","_getScaleInfo","viewRecords","totalCount","scrollHolder","rawContentHeight","rowHeight","MAX_BROWSER_HEIGHT","useScaling","scaleFactor","contentHeight","_getViewHeight","thead","_c","tfoot","_f","_e","_d","tbodyHead","_j","_i","_h","_g","fixedHeight","bodyHeight","needsVScroll","trackHeight","thumbHeight","currentScrollTop","maxScrollTop","thumbTop","maxThumbTop","deltaY","targetThumbTop","ratio","viewHeight","visibleRowCount","targetRow","clickY","currentTopRow","NineTableVScrollBar","GROUP_IDX","_GroupingManager","_groupColumns","_groupMap","_isApplying","groupColumns","sourceTable","$tr","$cell","groupId","rowIds","dataManager","GroupingManager","_Grouping","rawRecords","validRaw","groupMap","nestedTree","_Grouping_static","buildNestedMap_fn","flatResult","renderItems","flattenTree_fn","mapOrArray","depth","resultArr","parentId","counter","isLastLevel","groupKey","subMapOrRecords","collectLeafRowIds_fn","groupRecord","collectLeafRecords_fn","record","records","remainingCols","key","subRecords","subVal","r","Grouping","_RowManager","_BUFFER_ROW_COUNT","_element","_containerTemplates","_templateRowHeights","_cachedTemplateHeight","_sheetHeight","_cachedRowCount","_isProgrammaticScroll","_isGrouped","force","bodyViewport","_measureAndCacheHeight","_renderAllContainers","_handleScroll","scrollTop","_handleGroupedScroll","templateLength","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","renderOffsetTop","firstTr","currentStartIndex","$tbody","tbodyIdx","dataIndex","_bindRowData","allRenderItems","totalVirtualCount","bodyContent","getItemHeight","dataRowsHeight","groupHeightsTotal","itemHeights","viewportClientHeight","accumulatedHeight","offsetY","visibleRowsCount","dynamicBuffer","targetStart","targetEnd","renderedItems","selector","container","trs","itemIndex","chunkTrs","tr","subIdx","virtualIndex","isTrGroup","_bindGroupRowData","subRowIndex","matrixRow","indices","allRecords","childrenRecords","customComp","tableEl","tbody","templateTrs","trTemplates","fragment","renderedTrs","sum","_updateRowCount","visibleRows","groupDepth","_renderRows","_syncRowHeights","targetFixedType","clonedTr","targetTbody","tmpl","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","_initResizeObserver","entries","entry","height","dataRow","align","onRendered","targetScrollTop","rawTargetScrollTop","RowManager","COLLAPSED_WIDTH","_TableCompiler","$srcTable","$table","_TableCompiler_static","syncColAttributes_fn","cols","grid","rowSpan","colSpan","c","$col","fixed","TableCompiler","_CellSelection","_CellSelection_instances","_range","startRow","startCol","endRow","endCol","containers","getMatrixRow_fn","cell","col","cellEndRow","cellEndCol","$focusTd","initEvents_fn","$td","r1","r2","c1","c2","expanded","loopCount","nsR","neR","nsC","neC","sameGroupTrs","mainZone","lastMatrixRow","lastCol","targetEl","targetCell","allCells","rect","targetTr","CellSelection","_CellNavigation","_CellNavigation_instances","_currentCell","_currentTr","_currentRow","_currentCol","_getMinCol","cells","minCol","_getMaxCol","maxCol","_getMaxColCell","targetTrs","_getNextCol","td","next","_getPreviousCol","currentCol","currentTrCells","_findTargetTrsByMatrix","smallerCols","matchedTrs","mRow","getMatrixRowFromTr_fn","foundInSpan","_getNearElement","targetMatrixRow","searchedTrs","trDataRow","trSubIdx","span","cellDataRowStart","cellSubRowStart","cellStartMatrix","cellEndMatrix","nextMatrixRow","nextCol","prevTrs","maxColCell","maxMatrixRowLimit","maxMatrixRow","nextDataRow","nextSubRowIndex","retries","actualMatrixRow","ensureCellVisible_fn","retryCell","mRowAttr","bodyContainer","cellRect","viewportRect","containerRect","isAbove","isBelow","subrow","CellNavigation","RESIZE_OFFSET","_ColResizer","_ColResizer_instances","_panel","_tooltip","_targetColIndex","_nextColIndex","_targetContainerType","_targetCell","_startX","_startColWidth","_nextColStartWidth","_startCellWidth","_startLeft","_onPointerMove","headerPart","offsetX","isLeftEdge","isRightEdge","prevCell","_onPointerDown","getContainerType_fn","baseColIndex","checkIsAutoFit_fn","nextColEl","targetRect","sheetRect","targetColEl","attrW","updatePositions_fn","_onDragMove","_onDragEnd","diff","isAutoFit","finalWidth","newColWidth","newNextWidth","_onDblClick","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","val","size","calculatedWidth","containerType","firstColgroup","totalWidth","colWidths","colIdx","tables","globalColIndex","width","targetCols","firstContainer","resolvedContainerType","sourceCol","clientX","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","ColResizer","_ColMover","_ColMover_instances","_grip","_indi","_isDragging","_sourceCell","_sourceColIndex","_shiftX","_timer","checkIsMovable_fn","startX","startY","cancelTimer","onPointerMovePending","startDrag_fn","updateGripPosition_fn","targetElement","getDeepElementFromPoint_fn","targetColIndex","colMinLeft","colMaxRight","cCol","cSpan","cEnd","cRect","midX","calculatedTargetCol","indicatorLeft","sourceGroup","getColGroupRange_fn","movingSpan","sourceRowStart","sourceRowSpan","sourceRowEnd","targetRowStart","targetRowSpan","targetRowEnd","isRowSpanCompatible","isOutOfBoundsOfParent","pStart","pEnd","isDroppingInsideOtherGroup","spannedCells","sCell","sRowStart","sRowSpan","sRowEnd","sStart","sSpan","sEnd","moveEndCol","isSelfGroup","relativeTop","fullHeight","_onPointerUp","fromColIndex","toColIndex","colgroup","targetCol","spanCount","isInRange","targetViewportCol","fixedType","group","targetRowCell","y","root","nested","headerCells","hasStrictChildren","isValidGroup","parentGroupRange","subCell","subStart","subSpan","subEnd","isRealGroup","createGroupHeaderPreview_fn","groupRange","isGroup","origTable","minLeft","maxRight","minTop","maxBottom","targetCells","computedStyle","groupWidth","groupHeight","headerContent","style","clonedCell","preview","bounds","left","ColMover","_ColFixManager","baseCol","colEl","fixedAttr","targetBoundaryCol","theadTrs","cellBoundaryFound","cEndCol","action","fixType","cIdx","minBaseCol","rIdx","rSpan","trIndex","isBroken","correspondingCol","isColFixed","ColFixManager","_NineTableFilterPanel","_NineTableFilterPanel_instances","_nineTable","_view","_button","_renderer","_onInput","_onSelectAll","_onOk","_closeHandler","path","filterRecords","checkedRecords","chk","filterParams","colInfo","filterKey","selectedVals","btn","query","data2Idx","matchedValues","isChecked","chkIdx","_onCancel","filterBtn","panelWidth","top","searchBox","loadVirtualFilterItems_fn","filteredRecords","activeFilters","exprEngine","bindKey","exprKey","activeSelectedVals","uniqueMap","rawVal","displayVal","uniqueList","selectAllChk","NineTableFilterPanel","_NineTableFilterButton","_columns","isFiltered","_onClick","panel","seen","uniqueKey","NineTableFilterButton","_Filtering","_Filtering_instances","_isFiltering","_filterPanel","_filters","_initFilterPanel","applyFiltering_fn","oFilter","jsonFilter","k","sheetIndex","filterRules","targetKey","allowedValues","isExpr","recordIdx","isPass","allowedSet","Filtering","_Sorting","_Sorting_instances","syncHeaderUI_fn","handleSort_fn","colName","exprVal","isAsc","isDesc","existingColIndex","m","ruleData","applySorting_fn","colRule","asc","Sorting","_SheetView","_sortingColumns","_filterRules","_viewIndexes","_cachedVisibleRecords","visibleRecords","_convSingle","filterSlot","_applySorting","groupResult","columns","rulesWithIdx","rule","idxA","idxB","valA","valB","isEmptyA","isEmptyB","strA","strB","SheetView","_PreCompiler","_PreCompiler_static","ensureColgroup_fn","ensureThead_fn","ensureSectionTbodys_fn","ensureRowIndicator_fn","normalizeColAttributes_fn","createColIndicator_fn","normalizeCollapsibleAttributes_fn","generateCell_fn","initColExpanders_fn","initFilterButtons_fn","_k","applyInitialCellWidths_fn","tdTmpl","firstRow","cnt","numToExcelCol_fn","background","num","n","headTbody","footTbody","colCount","containerWidth","defaultWidth","widthVal","$tbl","targetAttributes","autoIdCounter","tagName","$datalist","$option","uniqueFuncName","innerAttrs","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","section","rows","indicatorCell","startColIdx","targetIdx","PreCompiler","_NineTableSheet","_NineTableSheet_instances","_index","_rowManager","_cellSelection","_cellNavigation","_colResizer","_colMover","_colFix","_sorting","_filtering","_grouping","_source","_adjustOverlay","$thead","$overlay","enable","_autoFit","totalOriginalWidth","colList","headerCell","collapsedTotalWidth","availableWidth","allocatedTotal","calculatedCols","exactWidth","baseWidth","remainderPixels","uncollapsedCols","finalSumWidth","_renderSplitContainers","_updateContainerWidths","_syncHeaderAndFooterHeights","_initRowHoverEvent","prefix","firstTable","_createSplitTable","scrollLeft","_render","isSimple_get","leftHeaderRows","bodyHeaderRows","rightHeaderRows","_applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","attrTrue","sourceTableTrue","NineTableSheet","_LayoutManager","owner","_applyAutoHeight","maxDisplayRows","maxRowHeight","toolbarEl","footerEl","toolbarHeight","footerHeight","calculatedHeight","isAutoHeight","sheetCount","sheetsHtml","sheetId","sheetTag","splitterTag","cssFiles","npmCssImports","customCssImports","file","LayoutManager","_ExprEngine","_exprCache","match","rowItem","trimmedExpr","compiledExpr","evalFn","ExprEngine","_NineTable","_NineTable_instances","_shadowRoot","_dataManager","_layoutManager","_templateCnt","_dispatchLoad","checkCount","maxChecks","checkTimer","loadSheetCnt","$sheet","idOrIndex","fn","bindDynamicSetters_fn","extractedMethodNames","matches","methodName","internalValue","newValue","NineTable","_BasicCellElement","BasicCellElement","exprCache","_CellElement","_tr","_cell","_attr","defaultValue","rawRecord","cleanExpr","childRecords","funcName","field","acc","button","curRow","renderer","prop","updateRowState","data","CellElement","_EditableCellElement","EditableCellElement","_CellInputText","_target","_initEvent","maxbyte","maxByteNum","event","CellInputText","_CellInputNumber","_validateInput","strVal","dotIdx","_onKeyDown","selectionStart","scale","validKey","isNumKey","CellInputNumber","_CellInputColor","_btn","_isValidColor","g","CellInputColor","_CellInputDate","_type","formattedVal","d","min","max","isValid","_isValidDate","year","month","day","isleap","hour","week","CellInputDate","_CellCheckbox","_label","_isRadio","_trueText","_falseText","newVal","trueValue","childHtml","displayText","CellCheckbox","_CellRadio","_dataSource","_keyName","_valueName","matchIndex","targets","_rendererRadio","codeVal","nameVal","label","input","CellRadio","_CellComboPanel","_isOpen","_initData","keyName","valueName","multi","separator","grd","itemsAttr","fieldKeys","activeColumnCount","formattedData","selectedKeys","btnEl","btnRect","panelHeight","upwardTop","viewContainer","_onClickRow","keyword","_initEvents","CellComboPanel","_CellCombo","_targetBtn","_multi","_multiSeparator","_togglePanel","_getDisplayText","keys","list","CellCombo","_CellRenderer","CellRenderer","_CellButton","_cellButtonClick","customEvent","rawValue","buttonText","CellButton","_CellRowIndicator","_mainTarget","_subTarget","_statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","CellRowIndicator","_ColExpand","singleWidth","isInitialInit","currentW","splitWidth","ColExpand","_ContextMenu","_ContextMenu_instances","_tableHost","_onContextMenu","targetTable","targetParent","isHeaderCell","menuItems","buildMenuItems_fn","handleMenuClick_fn","getTargetSheet_fn","syncMenuStates_fn","getFixManager_fn","parseCustomMenuItems_fn","containerElement","activeTable","items","activeTableId","rootUl","targetTableAttr","parsedList","traverseUl_fn","ulEl","child","spanEl","subUl","useDefault","rawItems","customItems","fixManager","currentFixState","isFixable","fixMenuItem","cleanedItems","isFiltering","autoFit","showTitle","menuId","ContextMenu","_MenuPanel","_MenuPanel_instances","_onCallback","callback","appendItems_fn","bindClickEvents_fn","cellRightX","wrapper","calculatedLeft","calculatedTop","condition","li","parentUl","sep","MenuPanel"],"mappings":"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"}
|