@ninebone/table 0.1.39 → 0.1.41

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.
@@ -1 +1 @@
1
- {"version":3,"file":"nine-table.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 const headerBody = this.#owner.querySelector(\".ng-sheet-header .ng-container-body\");\n const footerBody = this.#owner.querySelector(\".ng-sheet-footer .ng-container-body\");\n if (headerBody) headerBody.scrollLeft = newScrollLeft;\n if (footerBody) footerBody.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\tconst 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\tconst 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- headerBody (scrollLeft: ${headerBody?.scrollLeft}, width: ${headerRect?.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\ttrace.log(\"11111111111\");\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 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-sheet-header .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(`.ng-sheet-header 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 = ['layout.css', 'nine-table-sheet.css', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table'];\n // 2. npm 패키지 CSS 배열 생성\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}\";`\n );\n\n // 3. 커스텀 CSS 배열 생성\n const customCssImports = [];\n if (nine.cssPath) {\n cssFiles.forEach(file => {\n customCssImports.push(`@import \"${nine.cssPath}/${file}\";`);\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","headerBody","footerBody","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","headerRect","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","file","customCssImports","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.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 const headerBody = this.#owner.querySelector(\".ng-sheet-header .ng-container-body\");\n const footerBody = this.#owner.querySelector(\".ng-sheet-footer .ng-container-body\");\n if (headerBody) headerBody.scrollLeft = newScrollLeft;\n if (footerBody) footerBody.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\tconst 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\tconst 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- headerBody (scrollLeft: ${headerBody?.scrollLeft}, width: ${headerRect?.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\ttrace.log(\"11111111111\");\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 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-sheet-header .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(`.ng-sheet-header 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 = ['layout', 'nine-table-sheet', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table'];\n // 2. npm 패키지 CSS 배열 생성\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}.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","headerBody","footerBody","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","headerRect","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","file","customCssImports","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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"}