open-grid 0.3.2 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +3 -2
  2. package/dist/OpenGrid-C6SK6VeK.cjs +90 -0
  3. package/dist/OpenGrid-C6SK6VeK.cjs.map +1 -0
  4. package/dist/OpenGrid-D7EJOVi1.js +4864 -0
  5. package/dist/OpenGrid-D7EJOVi1.js.map +1 -0
  6. package/dist/open-grid-base.css +14 -0
  7. package/dist/open-grid-react.cjs +1 -1
  8. package/dist/open-grid-react.js +1 -1
  9. package/dist/open-grid-vue.cjs +1 -1
  10. package/dist/open-grid-vue.js +1 -1
  11. package/dist/open-grid.cjs +6 -6
  12. package/dist/open-grid.cjs.map +1 -1
  13. package/dist/open-grid.js +224 -172
  14. package/dist/open-grid.js.map +1 -1
  15. package/dist/types/core/CellEditManager.d.ts +2 -3
  16. package/dist/types/core/CellEventHandler.d.ts +4 -5
  17. package/dist/types/core/CellTypeRegistry.d.ts +1 -2
  18. package/dist/types/core/ColumnLayout.d.ts +1 -2
  19. package/dist/types/core/ContextMenu.d.ts +1 -2
  20. package/dist/types/core/CrossGridMapper.d.ts +21 -0
  21. package/dist/types/core/CrossGridRegistry.d.ts +12 -0
  22. package/dist/types/core/DataLayer.d.ts +4 -2
  23. package/dist/types/core/DragVisuals.d.ts +23 -0
  24. package/dist/types/core/ExportManager.d.ts +4 -3
  25. package/dist/types/core/FilterPanel.d.ts +1 -2
  26. package/dist/types/core/FilterSelect.d.ts +1 -2
  27. package/dist/types/core/FindBarManager.d.ts +4 -5
  28. package/dist/types/core/FooterManager.d.ts +2 -1
  29. package/dist/types/core/FormulaEngine.d.ts +1 -2
  30. package/dist/types/core/GridRenderer.d.ts +3 -2
  31. package/dist/types/core/GridShuttle.d.ts +24 -0
  32. package/dist/types/core/GroupEngine.d.ts +7 -4
  33. package/dist/types/core/GroupTreeManager.d.ts +6 -3
  34. package/dist/types/core/KeyboardManager.d.ts +4 -5
  35. package/dist/types/core/OpenGrid.d.ts +55 -4
  36. package/dist/types/core/OverrideKernel.d.ts +70 -0
  37. package/dist/types/core/PivotEngine.d.ts +1 -2
  38. package/dist/types/core/RowDragDrop.d.ts +25 -5
  39. package/dist/types/core/RowManager.d.ts +0 -1
  40. package/dist/types/core/SortFilterManager.d.ts +5 -6
  41. package/dist/types/core/TriggerManager.d.ts +1 -2
  42. package/dist/types/core/WorksheetManager.d.ts +1 -2
  43. package/dist/types/core/editors/CellEditor.d.ts +2 -3
  44. package/dist/types/core/editors/DateEditor.d.ts +2 -3
  45. package/dist/types/core/editors/SelectEditor.d.ts +2 -3
  46. package/dist/types/core/renderers/CellRenderer.d.ts +15 -4
  47. package/dist/types/core/types.d.ts +115 -0
  48. package/dist/types/index.d.ts +3 -1
  49. package/dist/types/react/OpenGrid.d.ts +3 -3
  50. package/dist/types/vue/types.d.ts +1 -2
  51. package/package.json +99 -102
  52. package/dist/OpenGrid-CzP1mcZW.cjs +0 -90
  53. package/dist/OpenGrid-CzP1mcZW.cjs.map +0 -1
  54. package/dist/OpenGrid-Dult64jp.js +0 -4401
  55. package/dist/OpenGrid-Dult64jp.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"OpenGrid-Dult64jp.js","sources":["../src/core/EventEmitter.ts","../src/core/DataLayer.ts","../src/core/VirtualScroll.ts","../src/core/ColumnLayout.ts","../src/core/FilterPanel.ts","../src/core/MathUtils.ts","../src/core/OGDecimal.ts","../src/core/FormulaEngine.ts","../src/core/MaskingEngine.ts","../src/core/renderers/CellRenderer.ts","../src/core/GridRenderer.ts","../src/core/RowManager.ts","../src/core/editors/DateEditor.ts","../src/core/editors/SelectEditor.ts","../src/core/editors/CellEditor.ts","../src/core/CellTypeRegistry.ts","../src/core/CellEditManager.ts","../src/core/FilterSelect.ts","../src/core/Pagination.ts","../src/core/RowDragDrop.ts","../src/core/MergeEngine.ts","../src/core/ContextMenu.ts","../src/core/WorksheetManager.ts","../src/core/ExportManager.ts","../src/core/FooterManager.ts","../src/core/KeyboardManager.ts","../src/core/FindBarManager.ts","../src/core/GroupEngine.ts","../src/core/TreeEngine.ts","../src/core/GroupTreeManager.ts","../src/core/SortFilterManager.ts","../src/core/CellEventHandler.ts","../src/core/TriggerManager.ts","../src/core/OpenGrid.ts"],"sourcesContent":["type Handler = (...args: any[]) => any;\n\ninterface ListenerEntry {\n handler: Handler;\n once: boolean;\n}\n\nexport class EventEmitter {\n private listeners: Map<string, ListenerEntry[]> = new Map();\n\n on(event: string, handler: Handler): this {\n const list = this.listeners.get(event) ?? [];\n list.push({ handler, once: false });\n this.listeners.set(event, list);\n return this;\n }\n\n once(event: string, handler: Handler): this {\n const list = this.listeners.get(event) ?? [];\n list.push({ handler, once: true });\n this.listeners.set(event, list);\n return this;\n }\n\n off(event: string, handler?: Handler): this {\n if (!handler) {\n this.listeners.delete(event);\n return this;\n }\n const list = this.listeners.get(event);\n if (list) {\n const filtered = list.filter(e => e.handler !== handler);\n if (filtered.length === 0) this.listeners.delete(event);\n else this.listeners.set(event, filtered);\n }\n return this;\n }\n\n emit(event: string, ...args: any[]): boolean {\n const list = this.listeners.get(event);\n if (!list || list.length === 0) return false;\n\n const remaining: ListenerEntry[] = [];\n for (const entry of list) {\n entry.handler(...args);\n if (!entry.once) remaining.push(entry);\n }\n\n if (remaining.length !== list.length) {\n if (remaining.length === 0) this.listeners.delete(event);\n else this.listeners.set(event, remaining);\n }\n return true;\n }\n\n removeAllListeners(event?: string): this {\n if (event) this.listeners.delete(event);\n else this.listeners.clear();\n return this;\n }\n\n listenerCount(event: string): number {\n return this.listeners.get(event)?.length ?? 0;\n }\n}\n","import type { SortItem, FilterItem } from './types.js';\n\ntype RowState = 'added' | 'edited' | 'removed' | 'none';\n\ninterface RowMeta {\n state: RowState;\n original?: any;\n rowId: string;\n}\n\nlet _rowIdSeq = 0;\nfunction nextRowId(): string {\n return `og-r-${++_rowIdSeq}`;\n}\n\nexport class DataLayer<T extends Record<string, any> = any> {\n private _data: T[] = [];\n private _original: T[] = [];\n private _meta: Map<string, RowMeta> = new Map();\n private _idField: string;\n\n // 정렬/필터 적용 후 표시되는 인덱스 목록\n private _displayIndexes: number[] = [];\n\n // rowId → _data 인덱스 역매핑\n private _idMap: Map<string, number> = new Map();\n\n // F3: 찾기 바 전용 크로스-필드 OR 필터\n private _findQuery: string = '';\n private _findFields: string[] = [];\n\n constructor(idField: string = '_ogRowId') {\n this._idField = idField;\n }\n\n // ─── 데이터 설정 ──────────────────────────────────────\n setData(data: T[]): void {\n this._data = data.map(row => {\n const id = nextRowId();\n const item = { ...row, [this._idField]: id };\n this._meta.set(id, { state: 'none', rowId: id });\n return item as T;\n });\n this._original = this._data.map(r => ({ ...r }));\n this._rebuildIdMap();\n this._displayIndexes = this._data.map((_, i) => i);\n }\n\n getData(): T[] {\n return this._displayIndexes.map(i => this._data[i]!);\n }\n\n getOriginalData(): T[] {\n return [...this._original];\n }\n\n getAllData(): T[] {\n return [...this._data];\n }\n\n clearData(): void {\n this._data = [];\n this._original = [];\n this._meta.clear();\n this._idMap.clear();\n this._displayIndexes = [];\n }\n\n get rowCount(): number {\n return this._displayIndexes.length;\n }\n\n get totalRowCount(): number {\n return this._data.length;\n }\n\n // ─── 행 CRUD ──────────────────────────────────────────\n addRow(item: Partial<T>, position: 'first' | 'last' | number = 'last'): void {\n const id = nextRowId();\n const row = { ...item, [this._idField]: id } as T;\n this._meta.set(id, { state: 'added', rowId: id });\n\n if (position === 'last') {\n const idx = this._data.push(row) - 1;\n this._idMap.set(id, idx);\n this._displayIndexes.push(idx);\n } else if (position === 'first') {\n this._data.unshift(row);\n this._rebuildIdMap();\n this._displayIndexes.unshift(0);\n } else {\n const dispPos = Math.min(position, this._displayIndexes.length);\n const dataIdx = dispPos < this._displayIndexes.length\n ? this._displayIndexes[dispPos]!\n : this._data.length;\n this._data.splice(dataIdx, 0, row);\n this._rebuildIdMap();\n this._displayIndexes = this._data.map((_, i) => i);\n }\n }\n\n removeRow(rowIndex: number): T | undefined {\n const dataIdx = this._displayIndexes[rowIndex];\n if (dataIdx === undefined) return undefined;\n\n const row = this._data[dataIdx]!;\n const id = row[this._idField] as string;\n const meta = this._meta.get(id);\n\n if (meta?.state === 'added') {\n // 새로 추가된 행은 완전 삭제\n this._data.splice(dataIdx, 1);\n this._meta.delete(id);\n } else {\n // 기존 행은 soft delete\n this._meta.set(id, { ...meta!, state: 'removed' });\n }\n\n this._rebuildIdMap();\n this._displayIndexes = this._data\n .map((r, i) => ({ r, i }))\n .filter(({ r }) => this._meta.get(r[this._idField] as string)?.state !== 'removed')\n .map(({ i }) => i);\n\n return row;\n }\n\n moveRow(fromDisplayIdx: number, toDisplayIdx: number): void {\n const fromDataIdx = this._displayIndexes[fromDisplayIdx];\n const toDataIdx = this._displayIndexes[toDisplayIdx];\n if (fromDataIdx === undefined || toDataIdx === undefined) return;\n\n // _data 배열에서 실제 이동\n const [row] = this._data.splice(fromDataIdx, 1);\n const insertAt = fromDataIdx < toDataIdx ? toDataIdx - 1 : toDataIdx;\n this._data.splice(insertAt, 0, row!);\n\n this._rebuildIdMap();\n this._displayIndexes = this._data\n .map((r, i) => ({ r, i }))\n .filter(({ r }) => this._meta.get(r[this._idField] as string)?.state !== 'removed')\n .map(({ i }) => i);\n }\n\n updateCell(rowIndex: number, field: string, value: any): boolean {\n const dataIdx = this._displayIndexes[rowIndex];\n if (dataIdx === undefined) return false;\n\n const row = this._data[dataIdx]!;\n const id = row[this._idField] as string;\n const meta = this._meta.get(id);\n\n // original 백업\n if (meta?.state === 'none') {\n this._meta.set(id, {\n ...meta,\n state: 'edited',\n original: { ...this._original[dataIdx] }\n });\n }\n\n (this._data[dataIdx] as any)[field] = value;\n return true;\n }\n\n getRowByIndex(rowIndex: number): T | undefined {\n const dataIdx = this._displayIndexes[rowIndex];\n return dataIdx !== undefined ? this._data[dataIdx] : undefined;\n }\n\n getCellValue(rowIndex: number, field: string): any {\n return this.getRowByIndex(rowIndex)?.[field];\n }\n\n // ─── 변경 추적 ────────────────────────────────────────\n /** 수정된 행만 반환 (추가/삭제 제외) */\n getEditedRows(): T[] {\n return this._data.filter(r =>\n this._meta.get(r[this._idField] as string)?.state === 'edited'\n );\n }\n\n /** 수정된 행만 반환 (하위 호환용 — 신규 코드는 getEditedRows() 사용) */\n getChangedRows(): T[] { return this.getEditedRows(); }\n\n getAddedRows(): T[] {\n return this._data.filter(r =>\n this._meta.get(r[this._idField] as string)?.state === 'added'\n );\n }\n\n getRemovedRows(): T[] {\n return this._data.filter(r =>\n this._meta.get(r[this._idField] as string)?.state === 'removed'\n );\n }\n\n /**\n * 추가/수정/삭제 모든 변경사항을 한 번에 반환.\n * edited 행에는 _changedFields 배열도 포함.\n */\n getChanges(): { added: T[]; edited: T[]; removed: T[] } {\n const added: T[] = [];\n const edited: T[] = [];\n const removed: T[] = [];\n\n for (const row of this._data) {\n const id = row[this._idField] as string;\n const meta = this._meta.get(id);\n const state = meta?.state ?? 'none';\n if (state === 'added') { added.push({ ...row }); }\n else if (state === 'removed') { removed.push({ ...row }); }\n else if (state === 'edited') {\n const orig = meta!.original ?? {};\n const changedFields = Object.keys(row).filter(\n k => k !== this._idField && row[k] !== orig[k]\n );\n edited.push({ ...row, _changedFields: changedFields } as any);\n }\n }\n return { added, edited, removed };\n }\n\n /**\n * 수정된 컬럼 정보 반환 — 각 edited 행에 대해 { row, fields, diff } 반환.\n * diff: { field, oldValue, newValue }[]\n */\n getChangedColumns(): Array<{ row: T; fields: string[]; diff: Array<{ field: string; oldValue: any; newValue: any }> }> {\n return this._data\n .filter(r => this._meta.get(r[this._idField] as string)?.state === 'edited')\n .map(row => {\n const orig = this._meta.get(row[this._idField] as string)?.original ?? {};\n const diff: Array<{ field: string; oldValue: any; newValue: any }> = [];\n for (const key of Object.keys(row)) {\n if (key === this._idField) continue;\n if (row[key] !== orig[key]) {\n diff.push({ field: key, oldValue: orig[key], newValue: row[key] });\n }\n }\n return { row: { ...row }, fields: diff.map(d => d.field), diff };\n });\n }\n\n /** rowIndex 행의 원본(수정 전) 데이터 반환. 추가된 행은 undefined. */\n getOriginalRow(rowIndex: number): T | undefined {\n const dataIdx = this._displayIndexes[rowIndex];\n if (dataIdx === undefined) return undefined;\n const row = this._data[dataIdx]!;\n const meta = this._meta.get(row[this._idField] as string);\n if (!meta || meta.state === 'added') return undefined;\n if (meta.state === 'edited' && meta.original) return { ...meta.original } as T;\n return { ...this._original[dataIdx] } as T;\n }\n\n getRowsWithState(stateField: string): T[] {\n return this._data.map(r => {\n const state = this._meta.get(r[this._idField] as string)?.state ?? 'none';\n return { ...r, [stateField]: state };\n });\n }\n\n getRowState(rowIndex: number): RowState {\n const row = this.getRowByIndex(rowIndex);\n if (!row) return 'none';\n return this._meta.get(row[this._idField] as string)?.state ?? 'none';\n }\n\n // ─── 정렬 ─────────────────────────────────────────────\n applySort(sortList: SortItem[]): void {\n const notRemoved = (i: number) =>\n this._meta.get((this._data[i] as any)?.[this._idField])?.state !== 'removed';\n\n if (sortList.length === 0) {\n this._displayIndexes = this._data.map((_, i) => i).filter(notRemoved);\n return;\n }\n\n // Schwartzian transform: 키를 미리 추출하여 sort comparator 비용 절감\n const keyed = this._displayIndexes\n .filter(notRemoved)\n .map(idx => {\n const row = this._data[idx]!;\n return {\n idx,\n keys: sortList.map(s => row[s.field]),\n };\n });\n\n keyed.sort((a, b) => {\n for (let si = 0; si < sortList.length; si++) {\n const dir = sortList[si]!.dir;\n const av = a.keys[si];\n const bv = b.keys[si];\n let cmp = 0;\n if (av == null && bv == null) cmp = 0;\n else if (av == null) cmp = -1;\n else if (bv == null) cmp = 1;\n else if (typeof av === 'number' && typeof bv === 'number') cmp = av - bv;\n else {\n const sa = String(av), sb = String(bv);\n cmp = sa < sb ? -1 : sa > sb ? 1 : 0;\n }\n if (cmp !== 0) return dir === 'asc' ? cmp : -cmp;\n }\n return 0;\n });\n\n this._displayIndexes = keyed.map(k => k.idx);\n }\n\n // ─── 필터 ─────────────────────────────────────────────\n applyFilter(filters: Record<string, FilterItem[]>): void {\n const fields = Object.keys(filters);\n\n this._displayIndexes = this._data\n .map((r, i) => ({ r, i }))\n .filter(({ r }) => {\n if (this._meta.get(r[this._idField] as string)?.state === 'removed') return false;\n // 컬럼별 AND 필터\n if (fields.length > 0) {\n if (!fields.every(field => {\n const val = r[field];\n return filters[field]!.every(fi => matchFilter(val, fi));\n })) return false;\n }\n // F3 찾기 바: 전체 컬럼 OR 검색\n if (this._findQuery && this._findFields.length > 0) {\n const q = this._findQuery;\n const matched = this._findFields.some(f => {\n const v = r[f];\n return v != null && String(v).toLowerCase().includes(q);\n });\n if (!matched) return false;\n }\n return true;\n })\n .map(({ i }) => i);\n }\n\n /** F3: 찾기 바 전체 컬럼 OR 검색 설정 */\n setFindFilter(query: string, fields: string[]): void {\n this._findQuery = query.toLowerCase();\n this._findFields = fields;\n }\n\n // ─── 내부 유틸 ────────────────────────────────────────\n private _rebuildIdMap(): void {\n this._idMap.clear();\n this._data.forEach((r, i) => {\n this._idMap.set(r[this._idField] as string, i);\n });\n }\n}\n\nfunction matchFilter(value: any, fi: FilterItem): boolean {\n const v = value;\n const fv = fi.value;\n switch (fi.operator) {\n case '=': return v == fv;\n case '!=': return v != fv;\n case '>': return v > fv;\n case '>=': return v >= fv;\n case '<': return v < fv;\n case '<=': return v <= fv;\n case 'contains': return String(v).includes(String(fv));\n case 'startsWith': return String(v).startsWith(String(fv));\n case 'endsWith': return String(v).endsWith(String(fv));\n default: return true;\n }\n}\n","export interface VirtualScrollOptions {\n rowHeight: number;\n overscan?: number;\n onRender: (startIndex: number, endIndex: number) => void;\n}\n\nexport interface VirtualScrollRange {\n startIndex: number;\n endIndex: number;\n offsetY: number;\n}\n\nexport class VirtualScroll {\n private container: HTMLElement;\n private rowHeight: number;\n private overscan: number;\n private _totalRows: number = 0;\n private _scrollTop: number = 0;\n private _viewportHeight: number = 0;\n private _rafId: number | null = null;\n private onRender: (startIndex: number, endIndex: number) => void;\n\n constructor(container: HTMLElement, options: VirtualScrollOptions) {\n this.container = container;\n this.rowHeight = options.rowHeight;\n this.overscan = options.overscan ?? 5;\n this.onRender = options.onRender;\n\n this.container.addEventListener('scroll', this._onScroll, { passive: true });\n }\n\n private _onScroll = (): void => {\n this._scrollTop = this.container.scrollTop;\n this._scheduleRender();\n };\n\n private _scheduleRender(): void {\n if (this._rafId !== null) return;\n this._rafId = requestAnimationFrame(() => {\n this._rafId = null;\n const range = this.getVisibleRange();\n this.onRender(range.startIndex, range.endIndex);\n });\n }\n\n getVisibleRange(): VirtualScrollRange {\n const visibleCount = Math.ceil(this._viewportHeight / this.rowHeight);\n const startIndex = Math.max(0, Math.floor(this._scrollTop / this.rowHeight) - this.overscan);\n const endIndex = Math.min(\n this._totalRows - 1,\n startIndex + visibleCount + this.overscan * 2\n );\n const offsetY = startIndex * this.rowHeight;\n return { startIndex, endIndex, offsetY };\n }\n\n setTotalRows(count: number): void {\n this._totalRows = count;\n this._updateSpacerHeight();\n this._scheduleRender();\n }\n\n setViewportHeight(height: number): void {\n this._viewportHeight = height;\n this._scheduleRender();\n }\n\n setRowHeight(height: number): void {\n this.rowHeight = height;\n this._updateSpacerHeight();\n this._scheduleRender();\n }\n\n scrollToRow(rowIndex: number): void {\n const targetTop = rowIndex * this.rowHeight;\n const targetBottom = targetTop + this.rowHeight;\n const viewBottom = this._scrollTop + this._viewportHeight;\n\n if (targetTop < this._scrollTop) {\n this._scrollTop = targetTop;\n this.container.scrollTop = targetTop;\n } else if (targetBottom > viewBottom) {\n const newTop = targetBottom - this._viewportHeight;\n this._scrollTop = newTop;\n this.container.scrollTop = newTop;\n }\n }\n\n getTotalHeight(): number {\n return this._totalRows * this.rowHeight;\n }\n\n private _updateSpacerHeight(): void {\n // spacer 엘리먼트가 있다면 높이 업데이트\n const spacer = this.container.querySelector<HTMLElement>('.og-spacer');\n if (spacer) spacer.style.height = `${this.getTotalHeight()}px`;\n }\n\n destroy(): void {\n this.container.removeEventListener('scroll', this._onScroll);\n if (this._rafId !== null) cancelAnimationFrame(this._rafId);\n }\n}\n","import type { ColumnDef } from './types.js';\n\nexport interface FlatColumn<T = any> extends ColumnDef<T> {\n _colIndex: number;\n _depth: number;\n _leaf: boolean;\n _colSpanCount?: number;\n _rowSpanCount?: number;\n}\n\nexport interface HeaderCell {\n column: FlatColumn;\n colIndex: number;\n depth: number;\n colSpan: number;\n rowSpan: number;\n}\n\nexport class ColumnLayout<T = any> {\n private _columns: ColumnDef<T>[];\n private _flatLeaves: FlatColumn<T>[] = [];\n private _maxDepth: number = 1;\n private _frozenCount: number = 0;\n\n constructor(columns: ColumnDef<T>[], frozenCount: number = 0) {\n this._columns = columns;\n this._frozenCount = frozenCount;\n this._process();\n }\n\n private _process(): void {\n const leaves: FlatColumn<T>[] = [];\n let colIndex = 0;\n\n const walk = (cols: ColumnDef<T>[], depth: number): void => {\n for (const col of cols) {\n if (col.children && col.children.length > 0) {\n walk(col.children, depth + 1);\n this._maxDepth = Math.max(this._maxDepth, depth + 1);\n } else {\n leaves.push({ ...col, _colIndex: colIndex++, _depth: depth, _leaf: true });\n }\n }\n };\n\n this._maxDepth = 1;\n walk(this._columns, 1);\n this._flatLeaves = leaves;\n }\n\n get leaves(): FlatColumn<T>[] {\n return this._flatLeaves;\n }\n\n get visibleLeaves(): FlatColumn<T>[] {\n return this._flatLeaves.filter(c => !c.hidden);\n }\n\n get headerDepth(): number {\n return this._maxDepth;\n }\n\n get frozenCount(): number {\n return this._frozenCount;\n }\n\n setFrozen(count: number): void {\n this._frozenCount = count;\n }\n\n setColumns(columns: ColumnDef<T>[]): void {\n this._columns = columns;\n this._process();\n }\n\n hideColumn(field: string | string[]): void {\n const fields = Array.isArray(field) ? field : [field];\n this._flatLeaves.forEach(c => {\n if (fields.includes(c.field)) c.hidden = true;\n });\n }\n\n showColumn(field: string | string[]): void {\n const fields = Array.isArray(field) ? field : [field];\n this._flatLeaves.forEach(c => {\n if (fields.includes(c.field)) c.hidden = false;\n });\n }\n\n addColumn(colDef: ColumnDef<T>, position: 'first' | 'last' | number = 'last'): void {\n if (position === 'last') {\n this._columns.push(colDef);\n } else if (position === 'first') {\n this._columns.unshift(colDef);\n } else {\n this._columns.splice(position, 0, colDef);\n }\n this._process();\n }\n\n removeColumn(field: string): void {\n const removeFromList = (cols: ColumnDef<T>[]): ColumnDef<T>[] => {\n return cols.filter(c => {\n if (c.field === field) return false;\n if (c.children) c.children = removeFromList(c.children);\n return true;\n });\n };\n this._columns = removeFromList(this._columns);\n this._process();\n }\n\n getColumnByField(field: string): FlatColumn<T> | undefined {\n return this._flatLeaves.find(c => c.field === field);\n }\n\n getColumnByIndex(index: number): FlatColumn<T> | undefined {\n return this._flatLeaves[index];\n }\n\n getColumnIndex(field: string): number {\n return this._flatLeaves.findIndex(c => c.field === field);\n }\n\n /** 헤더 렌더링용 셀 계산 */\n buildHeaderCells(): HeaderCell[][] {\n const rows: HeaderCell[][] = Array.from({ length: this._maxDepth }, () => []);\n let colIndex = 0;\n\n const walk = (cols: ColumnDef<T>[], depth: number): number => {\n let span = 0;\n for (const col of cols) {\n if (col.hidden) continue;\n if (col.children && col.children.length > 0) {\n const childSpan = walk(col.children, depth + 1);\n if (childSpan > 0) {\n rows[depth - 1]!.push({\n column: col as FlatColumn<T>,\n colIndex: colIndex,\n depth,\n colSpan: childSpan,\n rowSpan: 1\n });\n span += childSpan;\n }\n } else {\n rows[depth - 1]!.push({\n column: col as FlatColumn<T>,\n colIndex: colIndex++,\n depth,\n colSpan: 1,\n rowSpan: this._maxDepth - depth + 1\n });\n span++;\n }\n }\n return span;\n };\n\n walk(this._columns, 1);\n return rows;\n }\n\n /** 각 리프 컬럼의 계산된 너비 배열 반환 */\n computeWidths(totalWidth: number, defaultWidth: number = 100): number[] {\n const visible = this.visibleLeaves;\n const flexCols = visible.filter(c => c.flex);\n const fixedTotal = visible\n .filter(c => !c.flex && c.width)\n .reduce((sum, c) => sum + c.width!, 0);\n\n const flexTotal = flexCols.reduce((sum, c) => sum + (c.flex ?? 1), 0);\n const remaining = Math.max(0, totalWidth - fixedTotal);\n\n return visible.map(c => {\n if (c.flex) return Math.round((c.flex / flexTotal) * remaining);\n return c.width ?? defaultWidth;\n });\n }\n}\n","import type { FilterItem } from './types.js';\n\nexport type FilterApplyFn = (field: string, items: FilterItem[]) => void;\nexport type FilterClearFn = (field: string) => void;\n\n/**\n * 컬럼 헤더 필터 드롭다운 패널.\n * 단일 인스턴스를 재사용(열릴 때 위치 재계산).\n */\nexport class FilterPanel {\n private _el: HTMLElement;\n private _field = '';\n private _onApply: FilterApplyFn;\n private _onClear: FilterClearFn;\n private _outsideHandler: ((e: MouseEvent) => void) | null = null;\n\n constructor(container: HTMLElement, onApply: FilterApplyFn, onClear: FilterClearFn) {\n this._onApply = onApply;\n this._onClear = onClear;\n\n this._el = document.createElement('div');\n this._el.className = 'og-filter-panel';\n this._el.style.cssText = `\n position:absolute;z-index:1000;min-width:200px;max-width:280px;\n background:var(--og-row-bg,#fff);border:1px solid var(--og-border-color,#e0e0e0);\n border-radius:4px;box-shadow:0 4px 16px rgba(0,0,0,0.15);\n padding:10px;box-sizing:border-box;display:none;font-size:13px;\n `;\n container.appendChild(this._el);\n }\n\n open(field: string, anchorEl: HTMLElement, currentFilters: FilterItem[]): void {\n this._field = field;\n this._el.innerHTML = '';\n\n // 제목\n const title = document.createElement('div');\n title.textContent = '필터';\n title.style.cssText = `font-weight:600;margin-bottom:8px;color:var(--og-text-color,#333);`;\n this._el.appendChild(title);\n\n // 조건 선택\n const condRow = document.createElement('div');\n condRow.style.cssText = 'display:flex;gap:4px;margin-bottom:6px;';\n\n const condSel = document.createElement('select');\n condSel.style.cssText = `flex:1;padding:3px 4px;border:1px solid var(--og-border-color,#e0e0e0);border-radius:3px;font-size:12px;`;\n const conditions: Array<{ label: string; value: FilterItem['operator'] }> = [\n { label: '포함', value: 'contains' },\n { label: '같음', value: '=' },\n { label: '같지 않음', value: '!=' },\n { label: '시작', value: 'startsWith' },\n { label: '끝남', value: 'endsWith' },\n { label: '보다 큼', value: '>' },\n { label: '보다 작음', value: '<' },\n { label: '이상', value: '>=' },\n { label: '이하', value: '<=' },\n ];\n for (const c of conditions) {\n const opt = document.createElement('option');\n opt.value = c.value;\n opt.textContent = c.label;\n condSel.appendChild(opt);\n }\n if (currentFilters[0]) condSel.value = currentFilters[0].operator;\n condRow.appendChild(condSel);\n this._el.appendChild(condRow);\n\n // 값 입력\n const valueInput = document.createElement('input');\n valueInput.type = 'text';\n valueInput.placeholder = '필터 값 입력...';\n valueInput.value = currentFilters[0]?.value ?? '';\n valueInput.style.cssText = `\n width:100%;padding:4px 6px;border:1px solid var(--og-border-color,#e0e0e0);\n border-radius:3px;font-size:12px;box-sizing:border-box;margin-bottom:8px;\n outline:none;\n `;\n valueInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') applyBtn.click();\n else if (e.key === 'Escape') this.close();\n });\n this._el.appendChild(valueInput);\n\n // 버튼 행\n const btnRow = document.createElement('div');\n btnRow.style.cssText = 'display:flex;gap:6px;justify-content:flex-end;';\n\n const clearBtn = document.createElement('button');\n clearBtn.textContent = '초기화';\n clearBtn.style.cssText = `\n padding:3px 10px;border:1px solid var(--og-border-color,#e0e0e0);\n border-radius:3px;background:#fff;cursor:pointer;font-size:12px;color:#666;\n `;\n clearBtn.addEventListener('click', () => {\n this._onClear(this._field);\n this.close();\n });\n\n const applyBtn = document.createElement('button');\n applyBtn.textContent = '적용';\n applyBtn.style.cssText = `\n padding:3px 10px;border:1px solid var(--og-primary,#1976d2);\n border-radius:3px;background:var(--og-primary,#1976d2);\n color:#fff;cursor:pointer;font-size:12px;\n `;\n applyBtn.addEventListener('click', () => {\n const val = valueInput.value.trim();\n if (!val) {\n this._onClear(this._field);\n } else {\n this._onApply(this._field, [{ operator: condSel.value as FilterItem['operator'], value: val }]);\n }\n this.close();\n });\n\n btnRow.appendChild(clearBtn);\n btnRow.appendChild(applyBtn);\n this._el.appendChild(btnRow);\n\n // 위치 계산 (앵커 기준)\n const rect = anchorEl.getBoundingClientRect();\n const containerRect = this._el.parentElement!.getBoundingClientRect();\n this._el.style.top = `${rect.bottom - containerRect.top + 2}px`;\n this._el.style.left = `${Math.min(rect.left - containerRect.left, containerRect.width - 220)}px`;\n this._el.style.display = 'block';\n\n requestAnimationFrame(() => valueInput.focus());\n\n // 외부 클릭 시 닫기\n if (this._outsideHandler) document.removeEventListener('mousedown', this._outsideHandler);\n this._outsideHandler = (e: MouseEvent) => {\n if (!this._el.contains(e.target as Node) && e.target !== anchorEl) {\n this.close();\n }\n };\n setTimeout(() => document.addEventListener('mousedown', this._outsideHandler!), 0);\n }\n\n close(): void {\n this._el.style.display = 'none';\n if (this._outsideHandler) {\n document.removeEventListener('mousedown', this._outsideHandler);\n this._outsideHandler = null;\n }\n }\n\n get isOpen(): boolean {\n return this._el.style.display !== 'none';\n }\n\n destroy(): void {\n this.close();\n this._el.remove();\n }\n}\n","// ============================================================\n// MathUtils — 부동소수점 안전 연산 유틸리티\n// 레이어: Algorithm\n// 설계 근거(Why): JS IEEE 754 오차(0.1+0.2=0.30000000000000004) 방지.\n// epsilon_round(곱셈 스케일링)와 Kahan compensated summation 두 전략을 조합.\n// ============================================================\n\nconst DEFAULT_PREC = 10;\n\n/**\n * 소수점 precision 자리로 반올림 (epsilon round).\n * 0.1+0.2+... 누적 오차를 최종 표시 단계에서 제거한다.\n */\nexport function round(val: number, precision: number = DEFAULT_PREC): number {\n const factor = Math.pow(10, precision);\n return Math.round(val * factor) / factor;\n}\n\n/**\n * Kahan compensated summation — 대량 합산 시 부동소수점 오차 최소화.\n * 시간복잡도 O(n), 공간 O(1). 빈 배열 → 0 반환.\n */\nexport function kahanSum(arr: number[]): number {\n let sum = 0, c = 0;\n for (const y of arr) {\n const corrected = y - c;\n const t = sum + corrected;\n c = (t - sum) - corrected;\n sum = t;\n }\n return sum;\n}\n\n/**\n * 안전 사칙연산 — 두 수의 곱셈 스케일링으로 소수점 오차 방지.\n */\nexport function safeAdd(a: number, b: number, precision: number = DEFAULT_PREC): number {\n return round(a + b, precision);\n}\n\nexport function safeSub(a: number, b: number, precision: number = DEFAULT_PREC): number {\n return round(a - b, precision);\n}\n\nexport function safeMul(a: number, b: number, precision: number = DEFAULT_PREC): number {\n return round(a * b, precision);\n}\n\nexport function safeDiv(a: number, b: number, precision: number = DEFAULT_PREC): number {\n if (b === 0) throw new Error('safeDiv: division by zero');\n return round(a / b, precision);\n}\n\n/**\n * Kahan 합산 후 precision 반올림.\n * SUM/AVG footer 계산에 사용.\n */\nexport function kahanSumRounded(arr: number[], precision: number = DEFAULT_PREC): number {\n return round(kahanSum(arr), precision);\n}\n\n/**\n * Kahan AVG — 합산 후 count로 나누기.\n */\nexport function kahanAvg(arr: number[], precision: number = DEFAULT_PREC): number {\n if (arr.length === 0) return 0;\n return round(kahanSum(arr) / arr.length, precision);\n}\n","// ============================================================\n// OGDecimal — BigInt 기반 임의정밀도 소수 클래스\n// 레이어: Algorithm\n// 설계 근거(Why): JS IEEE 754는 소수점 17자리가 한계.\n// 음원 수익 배분 등 수백 자리 정밀도가 필요한 경우 BigInt를\n// coefficient + scale 구조로 표현해 오차 없는 연산을 보장한다.\n// 외부 라이브러리 없음 (ES2020+ BigInt 내장 사용).\n// 표현: value = coefficient / 10^scale\n// 예) 3.14 → {c: 314n, s: 2} / 0.001 → {c: 1n, s: 3}\n// ============================================================\n\nexport type OGDecimalLike = string | number | bigint | OGDecimal;\n\nexport class OGDecimal {\n private readonly _c: bigint; // coefficient (부호 포함 정수)\n private readonly _s: number; // scale = 소수점 아래 자릿수\n\n constructor(coefficient: bigint, scale: number) {\n this._c = coefficient;\n this._s = scale < 0 ? 0 : scale;\n }\n\n // ── 생성 ─────────────────────────────────────────────────\n\n static from(value: OGDecimalLike): OGDecimal {\n if (value instanceof OGDecimal) return value;\n if (typeof value === 'bigint') return new OGDecimal(value, 0);\n\n const str = String(value).trim();\n if (!str || str === 'null' || str === 'undefined' || str === 'NaN') {\n return new OGDecimal(0n, 0);\n }\n\n const isNeg = str.startsWith('-');\n const abs = isNeg ? str.slice(1) : str;\n const dot = abs.indexOf('.');\n\n let coeff: bigint;\n let scale: number;\n\n if (dot === -1) {\n coeff = BigInt(abs);\n scale = 0;\n } else {\n const frac = abs.slice(dot + 1);\n coeff = BigInt(abs.slice(0, dot) + frac);\n scale = frac.length;\n }\n\n return new OGDecimal(isNeg ? -coeff : coeff, scale);\n }\n\n static zero(): OGDecimal { return new OGDecimal(0n, 0); }\n static one(): OGDecimal { return new OGDecimal(1n, 0); }\n\n // ── 내부: 두 값의 스케일 정렬 ────────────────────────────\n\n private static _align(a: OGDecimal, b: OGDecimal): [bigint, bigint, number] {\n if (a._s === b._s) return [a._c, b._c, a._s];\n if (a._s > b._s) {\n return [a._c, b._c * (10n ** BigInt(a._s - b._s)), a._s];\n }\n return [a._c * (10n ** BigInt(b._s - a._s)), b._c, b._s];\n }\n\n // ── 사칙연산 ─────────────────────────────────────────────\n\n add(other: OGDecimalLike): OGDecimal {\n const [ac, bc, s] = OGDecimal._align(this, OGDecimal.from(other));\n return new OGDecimal(ac + bc, s);\n }\n\n sub(other: OGDecimalLike): OGDecimal {\n const [ac, bc, s] = OGDecimal._align(this, OGDecimal.from(other));\n return new OGDecimal(ac - bc, s);\n }\n\n mul(other: OGDecimalLike): OGDecimal {\n const o = OGDecimal.from(other);\n return new OGDecimal(this._c * o._c, this._s + o._s);\n }\n\n /**\n * 나눗셈. precision = 결과 소수점 자리수 (기본 20).\n * 수익 배분처럼 소수 수백 자리가 필요하면 precision을 높인다.\n */\n div(other: OGDecimalLike, precision = 20): OGDecimal {\n const o = OGDecimal.from(other);\n if (o._c === 0n) throw new Error('OGDecimal: division by zero');\n // 분자를 키워서 정수 나눗셈으로 정밀도 확보\n const scaledNumerator = this._c * (10n ** BigInt(precision + o._s));\n const result = scaledNumerator / o._c;\n return new OGDecimal(result, precision + this._s);\n }\n\n /** 나머지 (정수 나머지와 동일한 개념을 소수에 적용) */\n mod(other: OGDecimalLike): OGDecimal {\n const o = OGDecimal.from(other);\n const [ac, bc, s] = OGDecimal._align(this, o);\n return new OGDecimal(ac % bc, s);\n }\n\n /** 부호 반전 */\n neg(): OGDecimal { return new OGDecimal(-this._c, this._s); }\n\n /** 절댓값 */\n abs(): OGDecimal {\n return new OGDecimal(this._c < 0n ? -this._c : this._c, this._s);\n }\n\n // ── 비교 ─────────────────────────────────────────────────\n\n eq(other: OGDecimalLike): boolean {\n const [ac, bc] = OGDecimal._align(this, OGDecimal.from(other));\n return ac === bc;\n }\n gt(other: OGDecimalLike): boolean {\n const [ac, bc] = OGDecimal._align(this, OGDecimal.from(other));\n return ac > bc;\n }\n lt(other: OGDecimalLike): boolean {\n const [ac, bc] = OGDecimal._align(this, OGDecimal.from(other));\n return ac < bc;\n }\n gte(other: OGDecimalLike): boolean { return !this.lt(other); }\n lte(other: OGDecimalLike): boolean { return !this.gt(other); }\n isZero(): boolean { return this._c === 0n; }\n isNeg(): boolean { return this._c < 0n; }\n isPos(): boolean { return this._c > 0n; }\n\n // ── 출력 ─────────────────────────────────────────────────\n\n /**\n * 지정 소수점 자리수로 반올림(Half-up) 후 문자열 반환.\n * 음원 배분 등 정확한 자리수 표시에 사용.\n */\n toFixed(dp: number): string {\n let c = this._c;\n let s = this._s;\n\n if (s < dp) {\n c = c * (10n ** BigInt(dp - s));\n } else if (s > dp) {\n const diff = BigInt(s - dp);\n const divisor = 10n ** diff;\n const half = divisor / 2n;\n const isNeg = c < 0n;\n const abs_c = isNeg ? -c : c;\n const rem = abs_c % divisor;\n let rounded = abs_c / divisor;\n if (rem >= half) rounded += 1n;\n c = isNeg ? -rounded : rounded;\n }\n s = dp;\n\n const isNeg = c < 0n;\n const abs_c = isNeg ? -c : c;\n const digits = abs_c.toString().padStart(dp + 1, '0');\n const intPart = digits.slice(0, digits.length - dp) || '0';\n const fracPart = dp > 0 ? '.' + digits.slice(digits.length - dp) : '';\n return (isNeg ? '-' : '') + intPart + fracPart;\n }\n\n /** 정규화(후행 0 제거) 후 최소 표현 문자열 반환 */\n toString(): string {\n if (this._s === 0) return this._c.toString();\n // 후행 0 제거\n let c = this._c, s = this._s;\n while (s > 0 && c !== 0n && c % 10n === 0n) { c /= 10n; s--; }\n return new OGDecimal(c, s).toFixed(s);\n }\n\n /** number로 변환 (정밀도 손실 주의 — 표시 전용) */\n toNumber(): number { return parseFloat(this.toFixed(20)); }\n\n // ── 집계 정적 메서드 ─────────────────────────────────────\n\n /** 정확한 합산 (내부적으로 BigInt 정수 연산) */\n static sum(arr: OGDecimalLike[]): OGDecimal {\n return arr.reduce<OGDecimal>((acc, v) => acc.add(v), OGDecimal.zero());\n }\n\n /** 정확한 평균. precision = 나눗셈 소수점 자리수 */\n static avg(arr: OGDecimalLike[], precision = 20): OGDecimal {\n if (!arr.length) return OGDecimal.zero();\n return OGDecimal.sum(arr).div(arr.length, precision);\n }\n\n /** 배열 최솟값 */\n static min(arr: OGDecimalLike[]): OGDecimal {\n if (!arr.length) throw new Error('OGDecimal.min: empty array');\n return arr.map(OGDecimal.from).reduce((a, b) => a.lt(b) ? a : b);\n }\n\n /** 배열 최댓값 */\n static max(arr: OGDecimalLike[]): OGDecimal {\n if (!arr.length) throw new Error('OGDecimal.max: empty array');\n return arr.map(OGDecimal.from).reduce((a, b) => a.gt(b) ? a : b);\n }\n}\n","// ============================================================\n// FormulaEngine — 그리드 컬럼 수식 파서/실행기\n// 레이어: Algorithm (순수 파싱·연산 로직)\n// 설계 근거(Why): Excel처럼 컬럼에 문자열 수식을 지정하면\n// 행 데이터를 컨텍스트로 OGDecimal 정밀 연산을 수행한다.\n// 재귀 하강 파서(Recursive Descent) 사용 — 연산자 우선순위 자동 처리.\n// 문법:\n// expression = additive\n// additive = multiplicative (('+' | '-') multiplicative)*\n// multiplicative = unary (('*' | '/' | '%') unary)*\n// unary = '-' unary | primary\n// primary = '(' expression ')' | '[' field ']' | number\n// 예시:\n// \"[revenue] * 0.035\"\n// \"([price] - [cost]) / [price] * 100\"\n// \"[qty] * [unit_price] * (1 - [discount_rate] / 100)\"\n// ============================================================\n\nimport { OGDecimal, type OGDecimalLike } from './OGDecimal.js';\n\nexport type FormulaContext = Record<string, OGDecimalLike>;\n\n/**\n * 문자열 수식을 평가해 OGDecimal 결과를 반환한다.\n * @param expr - 수식 문자열 (예: \"[price] * [qty] * 0.035\")\n * @param ctx - 필드값 컨텍스트 (행 데이터)\n * @param divisionPrecision - 나눗셈 소수점 자리수 (기본 30)\n */\nexport function evaluateFormula(\n expr: string,\n ctx: FormulaContext,\n divisionPrecision = 30,\n): OGDecimal {\n return new _FormulaParser(expr, ctx, divisionPrecision).parse();\n}\n\n// ─── 내부: 재귀 하강 파서 ────────────────────────────────\n\nclass _FormulaParser {\n private _pos = 0;\n private readonly _src: string;\n\n constructor(\n src: string,\n private readonly _ctx: FormulaContext,\n private readonly _prec: number,\n ) {\n this._src = src.trim();\n }\n\n parse(): OGDecimal {\n const result = this._additive();\n this._skip();\n if (this._pos < this._src.length) {\n throw new SyntaxError(\n `FormulaEngine: 예상치 못한 토큰 '${this._src[this._pos]}' (위치 ${this._pos})`\n );\n }\n return result;\n }\n\n // ── expression layers ──────────────────────────────────\n\n private _additive(): OGDecimal {\n let left = this._multiplicative();\n this._skip();\n while (this._pos < this._src.length) {\n const ch = this._src[this._pos];\n if (ch !== '+' && ch !== '-') break;\n this._pos++;\n this._skip();\n const right = this._multiplicative();\n left = ch === '+' ? left.add(right) : left.sub(right);\n this._skip();\n }\n return left;\n }\n\n private _multiplicative(): OGDecimal {\n let left = this._unary();\n this._skip();\n while (this._pos < this._src.length) {\n const ch = this._src[this._pos];\n if (ch !== '*' && ch !== '/' && ch !== '%') break;\n this._pos++;\n this._skip();\n const right = this._unary();\n if (ch === '*') left = left.mul(right);\n else if (ch === '/') left = left.div(right, this._prec);\n else left = left.mod(right);\n this._skip();\n }\n return left;\n }\n\n private _unary(): OGDecimal {\n this._skip();\n if (this._src[this._pos] === '-') {\n this._pos++;\n return this._unary().neg();\n }\n return this._primary();\n }\n\n private _primary(): OGDecimal {\n this._skip();\n const ch = this._src[this._pos];\n\n if (ch === '(') {\n this._pos++;\n const val = this._additive();\n this._skip();\n if (this._src[this._pos] !== ')') {\n throw new SyntaxError('FormulaEngine: 닫는 괄호 ) 누락');\n }\n this._pos++;\n return val;\n }\n\n if (ch === '[') return this._fieldRef();\n\n return this._literal();\n }\n\n // ── 토큰 파싱 ─────────────────────────────────────────\n\n /** [fieldName] → 행 데이터에서 값 추출 */\n private _fieldRef(): OGDecimal {\n this._pos++; // skip '['\n const start = this._pos;\n while (this._pos < this._src.length && this._src[this._pos] !== ']') {\n this._pos++;\n }\n if (this._pos >= this._src.length) {\n throw new SyntaxError('FormulaEngine: 닫는 ] 누락');\n }\n const field = this._src.slice(start, this._pos);\n this._pos++; // skip ']'\n\n const val = this._ctx[field];\n if (val == null) {\n throw new ReferenceError(`FormulaEngine: 필드 '[${field}]'가 행 데이터에 없습니다`);\n }\n return OGDecimal.from(val);\n }\n\n /** 숫자 리터럴 파싱 (정수 / 소수 모두) */\n private _literal(): OGDecimal {\n const start = this._pos;\n while (this._pos < this._src.length && /[0-9.]/.test(this._src[this._pos])) {\n this._pos++;\n }\n const numStr = this._src.slice(start, this._pos);\n if (!numStr) {\n throw new SyntaxError(\n `FormulaEngine: 숫자 또는 [필드]를 기대했지만 '${this._src[this._pos] ?? 'EOF'}' 발견 (위치 ${start})`\n );\n }\n return OGDecimal.from(numStr);\n }\n\n /** 공백 스킵 */\n private _skip(): void {\n while (this._pos < this._src.length && /\\s/.test(this._src[this._pos])) {\n this._pos++;\n }\n }\n}\n","// ============================================================\n// F5: MaskingEngine — 컬럼 데이터 마스킹 처리\n// ============================================================\n//\n// 지원 타입 (MaskType):\n// ssn — 주민등록번호 930101-1******\n// phone — 전화번호 010-****-5678 / 02-****-5678\n// mobile — 휴대폰 (phone과 동일)\n// email — 이메일 ho***@example.com\n// credit — 신용카드 1234-****-****-5678\n// account — 계좌번호 123-*****-1234 (앞3 뒤4 노출)\n// password — 비밀번호 ******* (전체 마스킹)\n// name — 이름 홍*동 / 홍**\n// ip — IP 주소 192.168.***.***\n// partial — 부분 마스킹 visiblePrefix/visibleSuffix 자유 지정\n//\n// 사용법:\n// applyMask('01012345678', 'phone')\n// → '010-****-5678'\n//\n// applyMask('hong@example.com', { type: 'email', char: '#' })\n// → 'ho###@example.com'\n//\n// applyMask('1234567890', { type: 'partial', visiblePrefix: 2, visibleSuffix: 2 })\n// → '12******90'\n// ============================================================\n\n/** 지원 마스킹 타입 */\nexport type MaskType =\n | 'ssn' // 주민등록번호: 930101-1******\n | 'phone' // 전화번호: 010-****-5678\n | 'mobile' // 휴대폰 (phone과 동일)\n | 'email' // 이메일: ho***@example.com\n | 'credit' // 신용카드: 1234-****-****-5678\n | 'account' // 계좌번호: 123-*****-1234\n | 'password' // 비밀번호: ******* (전체)\n | 'name' // 이름: 홍*동\n | 'ip' // IP 주소: 192.168.***.***\n | 'partial'; // 부분 마스킹 (visiblePrefix/visibleSuffix 지정)\n\n/** 마스킹 상세 옵션 */\nexport interface MaskDef {\n type: MaskType;\n /** 마스킹 치환 문자 (기본: '*') */\n char?: string;\n /** partial/account: 앞 N자리 표시 */\n visiblePrefix?: number;\n /** partial/account: 뒤 N자리 표시 */\n visibleSuffix?: number;\n}\n\n/**\n * 원본 값에 마스킹을 적용해 표시용 문자열을 반환.\n *\n * @param value 원본 값 (null/undefined → 빈 문자열 그대로 반환)\n * @param maskDef 마스킹 타입 또는 상세 옵션\n * @returns 마스킹된 문자열\n *\n * @example\n * applyMask('930101-1234567', 'ssn') // '930101-1******'\n * applyMask('01012345678', 'phone') // '010-****-5678'\n * applyMask('hong@test.com', 'email') // 'ho***@test.com'\n */\nexport function applyMask(value: string, maskDef: MaskType | MaskDef): string {\n if (value == null || value === '') return value ?? '';\n const def: MaskDef = typeof maskDef === 'string' ? { type: maskDef } : maskDef;\n const char = def.char ?? '*';\n\n switch (def.type) {\n case 'ssn': return _maskSSN(value, char);\n case 'phone':\n case 'mobile': return _maskPhone(value, char);\n case 'email': return _maskEmail(value, char);\n case 'credit': return _maskCredit(value, char);\n case 'account': return _maskAccount(value, char, def.visiblePrefix ?? 3, def.visibleSuffix ?? 4);\n case 'password': return char.repeat(Math.max(value.length, 6));\n case 'name': return _maskName(value, char);\n case 'ip': return _maskIP(value, char);\n case 'partial': return _maskPartial(value, char, def.visiblePrefix ?? 0, def.visibleSuffix ?? 4);\n default: return value;\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// 개별 마스킹 함수\n// ─────────────────────────────────────────────────────────────\n\n/**\n * 주민등록번호 마스킹\n * 입력: '9301011234567' 또는 '930101-1234567'\n * 출력: '930101-1******' (앞 6자리 + 뒷 1자리 노출, 나머지 마스킹)\n */\nfunction _maskSSN(v: string, c: string): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length < 7) {\n // 7자리 미만이면 구분자 유지하며 뒷자리 마스킹\n const sep = v.includes('-') ? '-' : '';\n const frontEnd = v.indexOf('-') >= 0 ? v.indexOf('-') : 6;\n return v.slice(0, frontEnd) + sep + c.repeat(Math.max(1, v.length - frontEnd - sep.length));\n }\n const front = clean.slice(0, 6);\n const backFirst = clean[6]!;\n const maskLen = clean.length - 7;\n return `${front}-${backFirst}${c.repeat(maskLen)}`;\n}\n\n/**\n * 전화번호/휴대폰 마스킹\n * 입력: '01012345678' → '010-****-5678'\n * 입력: '0215551234' → '02-****-1234'\n * 입력: '0319991234' → '031-***-1234'\n */\nfunction _maskPhone(v: string, c: string): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length === 11) {\n // 010-xxxx-xxxx (11자리 휴대폰)\n return `${clean.slice(0, 3)}-${c.repeat(4)}-${clean.slice(7)}`;\n } else if (clean.length === 10) {\n if (clean.startsWith('02')) {\n // 서울 02-xxxx-xxxx\n return `${clean.slice(0, 2)}-${c.repeat(4)}-${clean.slice(6)}`;\n }\n // 지역번호 3자리 031-xxx-xxxx\n return `${clean.slice(0, 3)}-${c.repeat(3)}-${clean.slice(6)}`;\n } else if (clean.length === 9) {\n // 02-xxx-xxxx (구형 서울)\n return `${clean.slice(0, 2)}-${c.repeat(3)}-${clean.slice(5)}`;\n }\n // fallback: 앞 3자리 + 뒤 4자리 노출\n return _maskPartial(v, c, 3, 4);\n}\n\n/**\n * 이메일 마스킹\n * 입력: 'hong@example.com' → 'ho***@example.com'\n * 입력: 'a@b.com' → 'a***@b.com' (1자리도 앞 1자리 노출)\n */\nfunction _maskEmail(v: string, c: string): string {\n const atIdx = v.indexOf('@');\n if (atIdx < 0) return _maskPartial(v, c, 2, 0);\n const local = v.slice(0, atIdx);\n const domain = v.slice(atIdx); // '@' 포함\n const visLen = Math.min(2, local.length);\n const visible = local.slice(0, visLen);\n // 마스킹 최소 3자리 이상으로 표시 (원본 길이 무관)\n const maskLen = Math.max(local.length - visLen, 3);\n return `${visible}${c.repeat(maskLen)}${domain}`;\n}\n\n/**\n * 신용카드 마스킹\n * 입력: '4123456789012345' → '4123-****-****-2345'\n * 앞 4자리 + 뒤 4자리 노출, 중간 마스킹 (4자리씩 구분)\n */\nfunction _maskCredit(v: string, c: string): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length < 8) return v;\n const first4 = clean.slice(0, 4);\n const last4 = clean.slice(-4);\n const midLen = clean.length - 8;\n // 중간부가 없으면 8자리(****-****)로 패딩\n const mid = c.repeat(Math.max(midLen, 8));\n const parts: string[] = [first4];\n for (let i = 0; i < mid.length; i += 4) {\n const chunk = mid.slice(i, i + 4);\n if (chunk) parts.push(chunk);\n }\n parts.push(last4);\n return parts.join('-');\n}\n\n/**\n * 계좌번호 마스킹\n * 입력: '1234567890123' → '123-*******-0123' (기본 앞3 뒤4)\n * visiblePrefix/visibleSuffix로 조절 가능\n */\nfunction _maskAccount(v: string, c: string, prefixLen: number, suffixLen: number): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length <= prefixLen + suffixLen) {\n return _maskPartial(clean, c, prefixLen, suffixLen);\n }\n const prefix = clean.slice(0, prefixLen);\n const suffix = clean.slice(-suffixLen);\n const midLen = clean.length - prefixLen - suffixLen;\n return `${prefix}-${c.repeat(midLen)}-${suffix}`;\n}\n\n/**\n * 이름 마스킹\n * 2자: 홍* (첫 글자만 노출)\n * 3자: 홍*동 (첫글자+끝글자, 중간 마스킹)\n * 4자+: 홍**동\n */\nfunction _maskName(v: string, c: string): string {\n const t = v.trim();\n if (t.length === 0) return v;\n if (t.length === 1) return c;\n if (t.length === 2) return `${t[0]}${c}`;\n // 3자 이상: 첫글자 + 중간 마스킹 + 끝글자\n return `${t[0]}${c.repeat(t.length - 2)}${t[t.length - 1]}`;\n}\n\n/**\n * IP 주소 마스킹\n * 입력: '192.168.1.100' → '192.168.***.***'\n * 앞 2옥텟 노출, 3·4 옥텟 마스킹\n */\nfunction _maskIP(v: string, c: string): string {\n const parts = v.split('.');\n if (parts.length !== 4) return _maskPartial(v, c, 3, 0);\n const maskOctet = (octet: string) => c.repeat(Math.max(octet.length, 3));\n return `${parts[0]}.${parts[1]}.${maskOctet(parts[2]!)}.${maskOctet(parts[3]!)}`;\n}\n\n/**\n * 부분 마스킹\n * 앞 visiblePrefix자리 + 중간 마스킹 + 뒤 visibleSuffix자리 노출\n * 예) applyMask('1234567890', { type:'partial', visiblePrefix:2, visibleSuffix:2 })\n * → '12******90'\n */\nfunction _maskPartial(v: string, c: string, prefixLen: number, suffixLen: number): string {\n if (v.length <= prefixLen + suffixLen) return v;\n const prefix = v.slice(0, prefixLen);\n const suffix = suffixLen > 0 ? v.slice(-suffixLen) : '';\n const midLen = v.length - prefixLen - suffixLen;\n return `${prefix}${c.repeat(midLen)}${suffix}`;\n}\n","import type { ColumnDef } from '../types.js';\nimport { round } from '../MathUtils.js';\nimport { OGDecimal } from '../OGDecimal.js';\nimport { evaluateFormula } from '../FormulaEngine.js';\nimport { applyMask } from '../MaskingEngine.js';\n\nexport interface RenderContext<T = any> {\n value: any;\n row: T;\n rowIndex: number;\n column: ColumnDef<T>;\n colIndex: number;\n isSelected: boolean;\n rowState: 'none' | 'added' | 'edited' | 'removed';\n}\n\nexport interface CellRenderer {\n render(ctx: RenderContext): HTMLElement;\n}\n\n// ─── 수식 평가 헬퍼 ───────────────────────────────────────\n/**\n * 컬럼에 formula가 있으면 OGDecimal로 평가해 표시값(string)을 반환.\n * formula가 없으면 null 반환 → 기존 ctx.value 사용.\n */\nexport function resolveFormula(ctx: RenderContext): string | null {\n const col = ctx.column;\n if (!col.formula) return null;\n const prec = col.formulaPrecision ?? 30;\n try {\n let result: any;\n if (typeof col.formula === 'function') {\n result = col.formula(ctx.row, OGDecimal);\n } else {\n result = evaluateFormula(col.formula, ctx.row as Record<string, any>, prec);\n }\n // OGDecimal → toFixed(precision) or toString\n if (result instanceof OGDecimal) {\n return col.precision != null ? result.toFixed(col.precision) : result.toString();\n }\n // string 반환된 경우 그대로 사용\n if (typeof result === 'string') return result;\n // number 등 → precision 적용\n return col.precision != null\n ? OGDecimal.from(result).toFixed(col.precision)\n : String(result);\n } catch (e) {\n console.warn('[OpenGrid] Formula error:', e);\n return '#ERR';\n }\n}\n\n// ─── 숫자 포맷 유틸 ───────────────────────────────────────\nexport function formatNumber(value: any, format?: string, precision?: number): string {\n if (value == null || value === '') return '';\n let num = Number(value);\n if (isNaN(num)) return String(value);\n\n // F4: precision 지정 시 epsilon round 적용\n if (precision != null) num = round(num, precision);\n\n if (!format) {\n // precision 지정 시 소수점 자리 고정 표시\n return precision != null ? num.toFixed(precision) : String(num);\n }\n\n // #,##0 → 천단위 구분자\n if (format.includes(',')) {\n const decimals = format.includes('.') ? format.split('.')[1]!.length : (precision ?? 0);\n return num.toLocaleString('ko-KR', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n }\n return String(num);\n}\n\n// ─── 날짜 포맷 유틸 ───────────────────────────────────────\nexport function formatDate(value: any, format = 'yyyy-MM-dd'): string {\n if (!value) return '';\n const d = value instanceof Date ? value : new Date(value);\n if (isNaN(d.getTime())) return String(value);\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return format\n .replace('yyyy', String(y))\n .replace('MM', m)\n .replace('dd', day);\n}\n\n// ─── F5: 마스킹 셀 렌더링 헬퍼 ──────────────────────────\n/**\n * 마스킹된 셀을 렌더링한다.\n * - 좌측: 마스킹 문자열 (monospace)\n * - 우측: 눈 아이콘 버튼 — 클릭 시 해당 셀만 원문 표시 (DOM 직접 교체)\n *\n * 재렌더 시 col._maskRevealedRows에 rowIndex가 있으면 원문이 유지된다.\n */\nfunction _renderMasked(original: string, col: ColumnDef, rowIndex: number): HTMLElement {\n const masked = applyMask(original, col.mask!);\n\n const wrap = document.createElement('span');\n wrap.style.cssText =\n 'display:flex;align-items:center;gap:3px;overflow:hidden;width:100%;box-sizing:border-box;';\n\n const text = document.createElement('span');\n text.style.cssText =\n 'flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;' +\n 'font-family:monospace;letter-spacing:0.4px;color:var(--og-mask-text,#888);';\n text.textContent = masked;\n\n // 눈 아이콘 — SVG (Bootstrap Icons eye)\n const eye = document.createElement('button');\n eye.title = '클릭하면 원문 표시';\n eye.setAttribute('aria-label', '마스킹 해제');\n eye.innerHTML =\n '<svg width=\"13\" height=\"13\" viewBox=\"0 0 16 16\" fill=\"currentColor\">' +\n '<path d=\"M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8z\"/>' +\n '<path d=\"M8 5.5A2.5 2.5 0 1 0 8 10.5 2.5 2.5 0 0 0 8 5.5zm0 4A1.5 1.5 0 1 1 8 6.5a1.5 1.5 0 0 1 0 3z\" fill=\"#fff\"/>' +\n '</svg>';\n eye.style.cssText =\n 'flex-shrink:0;background:none;border:none;cursor:pointer;' +\n 'color:#c0c0c0;padding:1px 2px;line-height:0;border-radius:3px;' +\n 'display:flex;align-items:center;';\n\n eye.addEventListener('mouseover', () => {\n eye.style.color = 'var(--og-primary,#1976d2)';\n eye.style.background = 'rgba(25,118,210,0.08)';\n });\n eye.addEventListener('mouseout', () => {\n eye.style.color = '#c0c0c0';\n eye.style.background = 'none';\n });\n\n eye.addEventListener('click', (e: MouseEvent) => {\n e.stopPropagation();\n // DOM 즉시 교체 — 재렌더 없이 원문 표시\n text.textContent = original;\n text.style.fontFamily = '';\n text.style.letterSpacing = '';\n text.style.color = '';\n eye.remove();\n // 재렌더 시에도 해제 유지: 컬럼 내부 상태에 기록\n ((col as any)._maskRevealedRows as Set<number> | undefined ??\n (((col as any)._maskRevealedRows = new Set<number>()) as Set<number>)).add(rowIndex);\n });\n\n wrap.appendChild(text);\n wrap.appendChild(eye);\n return wrap;\n}\n\n// ─── TextRenderer ────────────────────────────────────────\nexport class TextRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-text';\n // formula 우선 평가\n const formulaResult = resolveFormula(ctx);\n if (formulaResult !== null) {\n span.textContent = formulaResult;\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n return span;\n }\n const { value, column, rowIndex } = ctx;\n\n let displayText: string;\n if (column.valueMap && value != null && column.valueMap[value]) {\n displayText = column.valueMap[value]!;\n } else {\n displayText = value == null ? '' : String(value);\n }\n\n // F5: 마스킹 처리\n // 컬럼 전체 해제(_maskRevealed) 또는 해당 행 해제(_maskRevealedRows) 시 원문 표시\n if (column.mask) {\n const colRevealed = (column as any)._maskRevealed === true;\n const rowRevealed = ((column as any)._maskRevealedRows as Set<number> | undefined)?.has(rowIndex) === true;\n if (!colRevealed && !rowRevealed) {\n return _renderMasked(displayText, column, rowIndex);\n }\n }\n\n span.textContent = displayText;\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n return span;\n }\n}\n\n// ─── SelectRenderer ───────────────────────────────────────\nexport class SelectRenderer implements CellRenderer {\n private _opts: Array<{ label: string; value: any }>;\n private _fn: ((row: any, ri: number) => Array<{ label?: string; text?: string; value: any }>) | null;\n\n constructor(\n opts: Array<{ label?: string; text?: string; value: any }> = [],\n fn?: (row: any, ri: number) => Array<{ label?: string; text?: string; value: any }>\n ) {\n this._opts = opts.map(o =>\n typeof o === 'string' ? { label: o, value: o }\n : { label: (o as any).label ?? (o as any).text ?? String((o as any).value ?? ''), value: (o as any).value }\n );\n this._fn = fn ?? null;\n }\n\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-text';\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n const rawVal = ctx.value;\n if (rawVal == null || rawVal === '') return span;\n const vs = String(rawVal);\n const list = this._fn\n ? this._fn(ctx.row, ctx.rowIndex).map((o: any) =>\n typeof o === 'string' ? { label: o, value: o }\n : { label: o.label ?? o.text ?? String(o.value ?? ''), value: o.value })\n : this._opts;\n const found = list.find(o => String(o.value) === vs);\n span.textContent = found ? found.label : vs;\n return span;\n }\n}\n\n// ─── NumberRenderer ───────────────────────────────────────\nexport class NumberRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-number';\n // formula 우선 평가 (OGDecimal 고정밀도)\n const formulaResult = resolveFormula(ctx);\n if (formulaResult !== null) {\n span.textContent = formulaResult;\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;width:100%;text-align:right;';\n return span;\n }\n // format 미지정 시 기본 천단위 콤마 (#,##0). precision 있으면 F4 epsilon round 적용\n span.textContent = formatNumber(ctx.value, ctx.column.format ?? '#,##0', ctx.column.precision);\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;width:100%;text-align:right;';\n return span;\n }\n}\n\n// ─── DateRenderer ─────────────────────────────────────────\nexport class DateRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-date';\n span.textContent = formatDate(ctx.value, ctx.column.format);\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n return span;\n }\n}\n\n// ─── CheckboxRenderer ─────────────────────────────────────\nexport class CheckboxRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'og-cell-checkbox';\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const chk = document.createElement('input');\n chk.type = 'checkbox';\n chk.checked = !!ctx.value;\n chk.disabled = true; // 클릭은 셀 이벤트로 처리 (_handleCellClick → writeCell)\n chk.style.cssText += 'cursor:pointer;pointer-events:none;';\n wrap.appendChild(chk);\n return wrap;\n }\n}\n\n// ─── ButtonRenderer ───────────────────────────────────────\nexport interface ButtonRendererDef {\n type: 'button';\n label?: string | ((value: any, row: any) => string);\n buttonClass?: string;\n style?: string;\n}\n\nexport class ButtonRenderer implements CellRenderer {\n constructor(private def?: ButtonRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const btn = document.createElement('button');\n btn.className = `og-cell-btn${this.def?.buttonClass ? ' ' + this.def.buttonClass : ''}`;\n const label = this.def?.label;\n if (typeof label === 'function') btn.textContent = label(ctx.value, ctx.row);\n else btn.textContent = label ?? String(ctx.value ?? 'btn');\n btn.style.cssText = `\n padding:2px 10px;border:1px solid var(--og-primary,#1976d2);\n border-radius:4px;background:var(--og-row-bg,#fff);color:var(--og-primary,#1976d2);\n cursor:pointer;font-size:12px;white-space:nowrap;transition:background 0.12s;\n ${this.def?.style ?? ''}\n `;\n btn.addEventListener('mouseover', () => btn.style.background = 'var(--og-primary-light,#e3f2fd)');\n btn.addEventListener('mouseout', () => btn.style.background = 'var(--og-row-bg,#fff)');\n wrap.appendChild(btn);\n return wrap;\n }\n}\n\n// ─── BadgeRenderer (상태/태그 표시용) ─────────────────────\nexport class BadgeRenderer implements CellRenderer {\n constructor(\n private colorMap?: Record<string, string>,\n private labelMap?: Record<string, string>,\n ) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;height:100%;';\n const badge = document.createElement('span');\n const val = ctx.value == null ? '' : String(ctx.value);\n // labelMap이 있으면 표시 텍스트 변환, 없으면 column.valueMap → 원값 순으로 사용\n const label = this.labelMap?.[val] ?? ctx.column.valueMap?.[val] ?? val;\n badge.textContent = label;\n const color = this.colorMap?.[val] ?? '#666';\n badge.style.cssText = `\n display:inline-block;padding:2px 8px;border-radius:12px;font-size:11px;\n background:${color}22;color:${color};border:1px solid ${color}66;\n white-space:nowrap;\n `;\n wrap.appendChild(badge);\n return wrap;\n }\n}\n\n// ─── LinkRenderer ─────────────────────────────────────────\nexport class LinkRenderer implements CellRenderer {\n constructor(\n private hrefFn?: (value: any, row: any) => string,\n private target?: string,\n ) {}\n\n render(ctx: RenderContext): HTMLElement {\n const a = document.createElement('a');\n a.className = 'og-cell-link';\n a.textContent = ctx.value == null ? '' : String(ctx.value);\n a.href = this.hrefFn ? this.hrefFn(ctx.value, ctx.row) : '#';\n if (this.target) a.target = this.target;\n a.style.cssText = 'color:var(--og-primary,#1976d2);text-decoration:underline;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n if (!this.hrefFn) a.addEventListener('click', e => e.preventDefault());\n return a;\n }\n}\n\n// ─── TemplateRenderer (사용자 정의 HTML) ──────────────────\nexport class TemplateRenderer implements CellRenderer {\n constructor(private templateFn: (value: any, row: any, rowIndex: number) => string) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'og-cell-template';\n wrap.style.cssText = 'display:flex;align-items:center;height:100%;overflow:hidden;';\n wrap.innerHTML = this.templateFn(ctx.value, ctx.row, ctx.rowIndex);\n return wrap;\n }\n}\n\n// ─── ImageRenderer ────────────────────────────────────────\nexport interface ImageRendererDef {\n type: 'image';\n width?: number;\n height?: number;\n radius?: number;\n srcFn?: (value: any, row: any) => string;\n alt?: string | ((value: any, row: any) => string);\n}\n\nexport class ImageRenderer implements CellRenderer {\n constructor(private def?: ImageRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const img = document.createElement('img');\n const src = this.def?.srcFn ? this.def.srcFn(ctx.value, ctx.row) : String(ctx.value ?? '');\n img.src = src;\n const w = this.def?.width ?? 28;\n const h = this.def?.height ?? 28;\n const r = this.def?.radius ?? 4;\n img.style.cssText = `width:${w}px;height:${h}px;object-fit:cover;border-radius:${r}px;display:block;`;\n const alt = this.def?.alt;\n img.alt = typeof alt === 'function' ? alt(ctx.value, ctx.row) : (alt ?? '');\n img.onerror = () => { img.style.display = 'none'; };\n wrap.appendChild(img);\n return wrap;\n }\n}\n\n// ─── ProgressRenderer ─────────────────────────────────────\nexport interface ProgressRendererDef {\n type: 'progress';\n max?: number;\n color?: string;\n showLabel?: boolean;\n colorFn?: (value: number) => string;\n}\n\nexport class ProgressRenderer implements CellRenderer {\n constructor(private def?: ProgressRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;gap:5px;width:100%;padding:0 4px;box-sizing:border-box;';\n const max = this.def?.max ?? 100;\n const raw = Number(ctx.value) || 0;\n const pct = Math.min(100, Math.max(0, (raw / max) * 100));\n const color = this.def?.colorFn\n ? this.def.colorFn(raw)\n : (this.def?.color ?? 'var(--og-primary,#1976d2)');\n\n const track = document.createElement('div');\n track.className = 'og-progress-track';\n track.style.cssText = 'flex:1;height:10px;background:#e0e0e0;border-radius:5px;overflow:hidden;';\n const fill = document.createElement('div');\n fill.className = 'og-progress-fill';\n fill.style.cssText = `width:${pct}%;height:100%;background:${color};border-radius:5px;`;\n track.appendChild(fill);\n wrap.appendChild(track);\n\n if (this.def?.showLabel !== false) {\n const lbl = document.createElement('span');\n lbl.style.cssText = 'font-size:11px;color:#666;white-space:nowrap;min-width:28px;text-align:right;';\n lbl.textContent = `${Math.round(pct)}%`;\n wrap.appendChild(lbl);\n }\n return wrap;\n }\n}\n\n// ─── SparklineRenderer (인라인 미니 차트) ─────────────────\nexport interface SparklineRendererDef {\n type: 'sparkline';\n width?: number;\n height?: number;\n color?: string;\n chartType?: 'bar' | 'line' | 'area';\n}\n\nexport class SparklineRenderer implements CellRenderer {\n constructor(private def?: SparklineRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n\n const values: number[] = Array.isArray(ctx.value) ? ctx.value.map(Number) : [];\n if (!values.length) {\n wrap.textContent = '-';\n return wrap;\n }\n\n const W = this.def?.width ?? 80;\n const H = this.def?.height ?? 22;\n const color = this.def?.color ?? '#1976d2';\n const chartType = this.def?.chartType ?? 'bar';\n\n const canvas = document.createElement('canvas');\n canvas.width = W;\n canvas.height = H;\n canvas.style.cssText = 'display:block;';\n\n const c = canvas.getContext('2d');\n if (c) {\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = max - min || 1;\n const n = values.length;\n\n if (chartType === 'bar') {\n const bw = W / n;\n values.forEach((v, i) => {\n const bh = ((v - min) / range) * (H - 2);\n c.fillStyle = color;\n c.fillRect(i * bw + 1, H - bh - 1, bw - 2, bh);\n });\n } else {\n const pts = values.map((v, i) => ({\n x: (i / (n - 1 || 1)) * W,\n y: H - ((v - min) / range) * (H - 4) - 2,\n }));\n if (chartType === 'area') {\n c.fillStyle = color + '33';\n c.beginPath();\n c.moveTo(pts[0]!.x, H);\n pts.forEach(p => c.lineTo(p.x, p.y));\n c.lineTo(pts[pts.length - 1]!.x, H);\n c.closePath();\n c.fill();\n }\n c.strokeStyle = color;\n c.lineWidth = 1.5;\n c.beginPath();\n pts.forEach((p, i) => (i === 0 ? c.moveTo(p.x, p.y) : c.lineTo(p.x, p.y)));\n c.stroke();\n }\n }\n\n wrap.appendChild(canvas);\n return wrap;\n }\n}\n\n// ─── SwitchRenderer (토글 스위치 표시) ───────────────────\nexport class SwitchRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const on = !!ctx.value;\n const sw = document.createElement('span');\n sw.className = 'og-switch' + (on ? ' og-switch--on' : '');\n sw.style.cssText = `display:inline-block;width:34px;height:18px;border-radius:9px;\n background:${on ? 'var(--og-primary,#1976d2)' : '#bdbdbd'};\n position:relative;transition:background 0.2s;cursor:pointer;flex-shrink:0;pointer-events:none;`;\n const knob = document.createElement('span');\n knob.style.cssText = `position:absolute;top:2px;left:${on ? '16px' : '2px'};\n width:14px;height:14px;border-radius:50%;background:#fff;\n transition:left 0.2s;box-shadow:0 1px 3px rgba(0,0,0,0.3);`;\n sw.appendChild(knob);\n wrap.appendChild(sw);\n return wrap;\n }\n}\n\n// ─── RatingRenderer (별점 표시) ───────────────────────────\nexport interface RatingRendererDef {\n type: 'rating';\n max?: number;\n color?: string;\n}\n\nexport class RatingRenderer implements CellRenderer {\n constructor(private def?: RatingRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;gap:1px;height:100%;';\n const max = this.def?.max ?? 5;\n const val = Math.round(Number(ctx.value) || 0);\n const color = this.def?.color ?? '#ffa000';\n for (let i = 1; i <= max; i++) {\n const star = document.createElement('span');\n star.textContent = '★';\n star.style.cssText = `font-size:14px;color:${i <= val ? color : '#e0e0e0'};line-height:1;`;\n wrap.appendChild(star);\n }\n return wrap;\n }\n}\n\n// ─── RadioRenderer ────────────────────────────────────────\nexport class RadioRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;pointer-events:none;';\n const radio = document.createElement('input');\n radio.type = 'radio';\n radio.checked = !!ctx.value;\n radio.setAttribute('aria-checked', ctx.value ? 'true' : 'false');\n radio.setAttribute('aria-label', ctx.column.header ?? '선택');\n if (ctx.column.group) radio.name = `og-radio-${ctx.rowIndex}-${ctx.column.group}`;\n radio.style.cssText = 'width:14px;height:14px;cursor:pointer;accent-color:var(--og-primary,#1976d2);';\n wrap.appendChild(radio);\n return wrap;\n }\n}\n\n// ─── ImgRenderer ──────────────────────────────────────────\nexport class ImgRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;overflow:hidden;';\n if (!ctx.value) return wrap;\n const img = document.createElement('img');\n img.src = String(ctx.value);\n img.alt = (ctx.column as any).alt ?? ctx.column.field;\n img.style.cssText = 'max-width:100%;max-height:100%;object-fit:contain;display:block;';\n img.setAttribute('role', 'img');\n wrap.appendChild(img);\n return wrap;\n }\n}\n\n// ─── HtmlRenderer ─────────────────────────────────────────\nfunction _sanitizeHtml(html: string): string {\n const div = document.createElement('div');\n div.innerHTML = html;\n div.querySelectorAll('script,iframe,object,embed').forEach(el => el.remove());\n div.querySelectorAll('*').forEach(el => {\n for (const attr of [...el.attributes]) {\n if (attr.name.startsWith('on')) el.removeAttribute(attr.name);\n }\n if (el.tagName === 'A') {\n const href = el.getAttribute('href') ?? '';\n if (/^javascript:/i.test(href)) el.removeAttribute('href');\n }\n });\n return div.innerHTML;\n}\n\nexport class HtmlRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:block;overflow:hidden;width:100%;';\n const doSanitize = (ctx.column as any).sanitize !== false;\n const html = String(ctx.value ?? '');\n wrap.innerHTML = doSanitize ? _sanitizeHtml(html) : html;\n return wrap;\n }\n}\n\n// ─── BarcodeRenderer (Code128B) ───────────────────────────\nconst _C128W: string[] = [\n '212222','222122','222221','121223','121322','131222','122213','122312', // 0-7\n '132212','221213','221312','231212','112232','122132','122231','113222', // 8-15\n '123122','123221','223211','221132','221231','213212','223112','312131', // 16-23\n '311222','321122','321221','312212','322112','322211','212123','212321', // 24-31\n '232121','111323','131123','131321','112313','132113','132311','211313', // 32-39\n '231113','231311','112133','112331','132131','113123','113321','133121', // 40-47\n '313121','211331','231131','213113','213311','213131','311123','311321', // 48-55\n '331121','312113','312311','332111','314111','221411','431111','111224', // 56-63\n '111422','121124','121421','141122','141221','112214','112412','122114', // 64-71\n '122411','142112','142211','241211','221114','413111','241112','134111', // 72-79\n '111242','121142','121241','114212','124112','124211','411212','421112', // 80-87\n '421211','212141','214121','412121','111143','111341','131141','114113', // 88-95\n '114311','411113','411311','113141','114131','311141','411131','211412', // 96-103\n '211214','211232', // 104 (Start B), 105 (Start C)\n];\nconst _C128_STOP = '2331112';\n\nfunction _c128Bits(w: string): string {\n let out = '', bar = true;\n for (const ch of w) { out += (bar ? '1' : '0').repeat(+ch); bar = !bar; }\n return out;\n}\n\nfunction _encodeC128B(text: string): string {\n const codes: number[] = [104]; // Start B\n for (const ch of text) {\n const c = ch.charCodeAt(0) - 32;\n if (c >= 0 && c <= 94) codes.push(c);\n }\n let sum = 104;\n for (let i = 1; i < codes.length; i++) sum += codes[i]! * i;\n codes.push(sum % 103);\n return codes.map(c => _c128Bits(_C128W[c]!)).join('') + _c128Bits(_C128_STOP) + '11';\n}\n\nexport class BarcodeRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const val = String(ctx.value ?? '');\n const h = (ctx.column as any).barcodeHeight ?? 28;\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;overflow:hidden;gap:1px;';\n wrap.setAttribute('role', 'img');\n wrap.setAttribute('aria-label', `바코드: ${val}`);\n wrap.innerHTML = _barcodeSvg(val, h);\n const label = document.createElement('span');\n label.textContent = val;\n label.style.cssText = 'font-size:9px;font-family:monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;';\n wrap.appendChild(label);\n return wrap;\n }\n}\n\nfunction _barcodeSvg(text: string, H: number): string {\n if (!text) return '';\n const bits = _encodeC128B(text);\n const MW = 1.4, QZ = 6;\n const TW = bits.length * MW + QZ * 2;\n const rects: string[] = [];\n let i = 0, x = QZ;\n while (i < bits.length) {\n if (bits[i] === '1') {\n let n = 0;\n while (i + n < bits.length && bits[i + n] === '1') n++;\n rects.push(`<rect x=\"${x.toFixed(2)}\" y=\"0\" width=\"${(n * MW).toFixed(2)}\" height=\"${H}\"/>`);\n x += n * MW; i += n;\n } else { x += MW; i++; }\n }\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${TW.toFixed(2)} ${H}\" width=\"${TW.toFixed(2)}\" height=\"${H}\" style=\"display:block\" aria-hidden=\"true\"><g fill=\"currentColor\">${rects.join('')}</g></svg>`;\n}\n\n// ─── Renderer 팩토리 ──────────────────────────────────────\nexport function createRenderer(col: ColumnDef): CellRenderer {\n const renderer = col.renderer;\n if (!renderer) {\n switch (col.type as string) {\n case 'number': return new NumberRenderer();\n case 'date': return new DateRenderer();\n case 'boolean': return new CheckboxRenderer();\n case 'radio': return new RadioRenderer();\n case 'img': return new ImgRenderer();\n case 'html': return new HtmlRenderer();\n case 'barcode': return new BarcodeRenderer();\n case 'select': return new SelectRenderer(col.options as any ?? [], col.optionsFn as any);\n default: return new TextRenderer();\n }\n }\n if (typeof renderer === 'string') {\n switch (renderer) {\n case 'number': return new NumberRenderer();\n case 'date': return new DateRenderer();\n case 'checkbox': return new CheckboxRenderer();\n case 'button': return new ButtonRenderer();\n case 'link': return new LinkRenderer();\n case 'badge': return new BadgeRenderer();\n case 'switch': return new SwitchRenderer();\n case 'radio': return new RadioRenderer();\n case 'img': return new ImgRenderer();\n case 'html': return new HtmlRenderer();\n case 'barcode': return new BarcodeRenderer();\n default: return new TextRenderer();\n }\n }\n // RendererDef 객체\n switch (renderer.type) {\n case 'button': return new ButtonRenderer(renderer as ButtonRendererDef);\n case 'checkbox': return new CheckboxRenderer();\n case 'link': return new LinkRenderer(renderer.hrefFn, renderer.target);\n case 'template': return new TemplateRenderer(renderer.templateFn);\n case 'badge': return new BadgeRenderer(renderer.colorMap, renderer.labelMap ?? renderer.valueMap);\n case 'image': return new ImageRenderer(renderer as ImageRendererDef);\n case 'progress': return new ProgressRenderer(renderer as ProgressRendererDef);\n case 'sparkline': return new SparklineRenderer(renderer as SparklineRendererDef);\n case 'switch': return new SwitchRenderer();\n case 'rating': return new RatingRenderer(renderer as RatingRendererDef);\n case 'number': return new NumberRenderer();\n case 'date': return new DateRenderer();\n case 'radio': return new RadioRenderer();\n case 'img': return new ImgRenderer();\n case 'html': return new HtmlRenderer();\n case 'barcode': return new BarcodeRenderer();\n default: return new TextRenderer();\n }\n}\n","import { DataLayer } from './DataLayer.js';\nimport { RowDragDrop } from './RowDragDrop.js';\nimport { MergeEngine } from './MergeEngine.js';\nimport { createRenderer } from './renderers/CellRenderer.js';\nimport type { ColumnDef, SortItem, TreeNodeIconDef } from './types.js';\n\n// ─── RendererCallbacks ────────────────────────────────────\nexport interface RendererCallbacks {\n onHeaderClick: (field: string, shiftKey: boolean) => void;\n onCellClick: (ri: number, ci: number, e: MouseEvent) => void;\n onCellDblClick: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseOver: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseOut: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseDown: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseUp: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseMove: (ri: number, ci: number, e: MouseEvent) => void;\n onRowCheck: (ri: number, checked: boolean) => void;\n onAllCheck: (checked: boolean) => void;\n onColResize: (colIndex: number, newWidth: number) => void;\n onFilterIconClick: (field: string, anchorEl: HTMLElement) => void;\n getDndManager: () => RowDragDrop | null;\n onColDragStart: (colIndex: number) => void;\n onColDrop: (toIndex: number) => void;\n getColDragIdx: () => number | null;\n}\n\n// ─── GridRenderer ─────────────────────────────────────────\nexport class GridRenderer {\n private _root: HTMLElement;\n private _header: HTMLElement;\n private _bodyWrap: HTMLElement;\n private _body: HTMLElement;\n private _opts: any;\n private _cbs: RendererCallbacks;\n // rowIndex → {colIndex → cellEl} 맵\n private _cellMap: Map<number, Map<number, HTMLElement>> = new Map();\n\n get bodyWrapper() { return this._bodyWrap; }\n\n constructor(root: HTMLElement, opts: any, cbs: RendererCallbacks) {\n this._root = root;\n this._opts = opts;\n this._cbs = cbs;\n\n this._header = _el('div', 'og-header');\n // host isolation: border:0 로 4변 폭을 먼저 0 으로 못박는다. WordPress 전역 스타일\n // `:where([style*=\"border-color\"]){border-style:solid}` 이 인라인의 var(--og-border-color)\n // 문자열에 매칭되어, 폭 미지정 변에 medium(3px) 기본 보더를 강제하는 것을 차단(헤더 좌/우/상 굵은선 방지).\n this._header.style.cssText = `flex-shrink:0;overflow-x:auto;overflow-y:hidden;border:0;border-bottom:1px solid var(--og-border-color,#e0e0e0);scrollbar-width:none;`;\n\n this._bodyWrap = _el('div', 'og-body-wrapper');\n this._bodyWrap.style.cssText = `flex:1;overflow:auto;position:relative;`;\n this._bodyWrap.style.setProperty('--scrollbar-size', '8px');\n\n this._body = _el('div', 'og-body');\n this._body.style.cssText = `position:relative;`;\n this._bodyWrap.appendChild(this._body);\n\n root.appendChild(this._header);\n root.appendChild(this._bodyWrap);\n\n // 헤더 가로 스크롤 동기화\n this._bodyWrap.addEventListener('scroll', () => {\n this._header.scrollLeft = this._bodyWrap.scrollLeft;\n }, { passive: true });\n }\n\n updateSize(totalHeight: number, headerHeight: number): void {\n this._bodyWrap.style.height = `${totalHeight - headerHeight}px`;\n }\n\n renderHeader(\n headerRows: any[][],\n leaves: ColumnDef[],\n widths: number[],\n sortList: SortItem[],\n opts: any\n ): void {\n this._header.innerHTML = '';\n const frozenCount: number = opts._frozenCount ?? 0;\n\n // 헤더·바디 정렬을 위해 총 컬럼 너비를 계산 — 헤더 table은 이 너비로 고정\n let _extraW = 0;\n if (opts.stateColumn) _extraW += 24;\n if (opts.draggable) _extraW += 18;\n if (opts.rowNumber) _extraW += 44;\n if (opts.checkColumn) _extraW += 36;\n const totalColWidth = _extraW + leaves.reduce((s: number, _: any, i: number) => s + (widths[i] ?? opts.defaultColumnWidth), 0);\n\n // 헤더 div 배경 — 테이블이 totalColWidth보다 짧아도 헤더 영역 전체에 배경 유지\n this._header.style.background = 'var(--og-header-bg,#f5f5f5)';\n\n const table = _el('table', 'og-header-table') as HTMLTableElement;\n table.setAttribute('role', 'presentation');\n // host isolation: margin/border-spacing 을 인라인으로도 0 고정 → 호스트 table{} 차단.\n // (og-header-table 클래스로 base.css 규칙도 적용되나, 인라인으로 이중 방어)\n table.style.cssText = `table-layout:fixed;border-collapse:collapse;border-spacing:0;margin:0;width:${totalColWidth}px;background:var(--og-header-bg,#f5f5f5);`;\n\n // 엑스트라 컬럼 헤더\n const extraRows = headerRows.length;\n let extraHeaderLeft = 0;\n const addExtraCol = (tr: HTMLElement, w: number, label: string, extraClass = '') => {\n const th = _el('th', `og-header-cell og-extra-col ${extraClass}`);\n th.setAttribute('rowspan', String(extraRows));\n th.textContent = label;\n _style(th, {\n width: `${w}px`, minWidth: `${w}px`, textAlign: 'center',\n borderRight: '1px solid var(--og-border-color,#e0e0e0)',\n borderBottom: '1px solid var(--og-border-color,#e0e0e0)',\n // host isolation: extra 컬럼 th 도 호스트 th{} 침범 차단 (border/line-height)\n borderTop: '0', borderLeft: '0', lineHeight: 'normal', verticalAlign: 'middle',\n padding: '0', fontSize: '11px', color: '#999',\n userSelect: 'none', boxSizing: 'border-box',\n background: 'var(--og-header-bg,#f5f5f5)',\n });\n if (frozenCount > 0) {\n th.style.position = 'sticky';\n th.style.left = `${extraHeaderLeft}px`;\n th.style.zIndex = '4';\n }\n extraHeaderLeft += w;\n tr.appendChild(th);\n };\n\n for (let ri = 0; ri < headerRows.length; ri++) {\n const tr = _el('tr', 'og-header-row') as HTMLTableRowElement;\n tr.style.height = `${opts.headerHeight}px`;\n\n if (ri === 0) {\n // 컬럼 순서: stateColumn → draggable → rowNumber → checkColumn\n if (opts.stateColumn) addExtraCol(tr, 24, '');\n if (opts.draggable) addExtraCol(tr, 18, '');\n if (opts.rowNumber) addExtraCol(tr, 44, 'No');\n if (opts.checkColumn) {\n const th = _el('th', 'og-header-cell og-extra-col');\n th.setAttribute('rowspan', String(extraRows));\n th.style.cssText = `width:36px;min-width:36px;text-align:center;border-right:1px solid var(--og-border-color,#e0e0e0);border-bottom:1px solid var(--og-border-color,#e0e0e0);border-top:0;border-left:0;line-height:normal;vertical-align:middle;background:var(--og-header-bg,#f5f5f5);box-sizing:border-box;`;\n if (frozenCount > 0) {\n th.style.position = 'sticky';\n th.style.left = `${extraHeaderLeft}px`;\n th.style.zIndex = '4';\n }\n extraHeaderLeft += 36;\n const allChk = document.createElement('input');\n allChk.type = 'checkbox';\n allChk.setAttribute('aria-label', '전체 행 선택');\n allChk.style.cssText = 'width:16px;height:16px;';\n allChk.addEventListener('change', () => this._cbs.onAllCheck(allChk.checked));\n th.appendChild(allChk);\n tr.appendChild(th);\n }\n }\n\n for (const cell of (headerRows[ri] ?? [])) {\n const th = _el('th', 'og-header-cell') as HTMLTableHeaderCellElement;\n const col: ColumnDef = cell.column;\n if (cell.colSpan > 1) th.colSpan = cell.colSpan;\n if (cell.rowSpan > 1) th.rowSpan = cell.rowSpan;\n\n // 너비: leaf 컬럼만\n const leafIdx = cell.colSpan === 1 ? leaves.findIndex(l => l.field === col.field) : -1;\n if (cell.colSpan === 1) {\n const w = leafIdx >= 0 ? (widths[leafIdx] ?? opts.defaultColumnWidth) : (col.width ?? opts.defaultColumnWidth);\n th.style.width = `${w}px`;\n th.style.minWidth = `${w}px`;\n }\n\n const sortInfo = sortList.find(s => s.field === col.field);\n const sortable = col.sortable !== false && opts.sortable && cell.colSpan === 1;\n\n // ARIA + 키보드 접근성\n th.setAttribute('role', 'columnheader');\n th.setAttribute('scope', 'col');\n if (sortable) {\n th.setAttribute('aria-sort', sortInfo ? (sortInfo.dir === 'asc' ? 'ascending' : 'descending') : 'none');\n // 정렬 가능한 헤더는 키보드로 접근 가능 (roving tabindex: 첫 번째만 0)\n th.tabIndex = leafIdx === 0 ? 0 : -1;\n th.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this._cbs.onHeaderClick(col.field, e.shiftKey);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n const next = th.nextElementSibling as HTMLElement;\n if (next?.tagName === 'TH') next.focus();\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n const prev = th.previousElementSibling as HTMLElement;\n if (prev?.tagName === 'TH') prev.focus();\n }\n });\n }\n\n // 고정 컬럼 sticky\n if (leafIdx >= 0 && leafIdx < frozenCount) {\n let leftOff = 0;\n // extra 컬럼 순서와 동일하게: stateColumn → draggable → rowNumber → checkColumn\n if (opts.stateColumn) leftOff += 24;\n if (opts.draggable) leftOff += 18;\n if (opts.rowNumber) leftOff += 44;\n if (opts.checkColumn) leftOff += 36;\n for (let i = 0; i < leafIdx; i++) leftOff += widths[i] ?? opts.defaultColumnWidth;\n th.classList.add('og-frozen');\n if (leafIdx === frozenCount - 1) th.classList.add('og-frozen-last');\n th.style.left = `${leftOff}px`;\n }\n\n _style(th, {\n padding: '4px 8px', boxSizing: 'border-box',\n // host isolation: 헤더 <th> 의 모든 시각 속성을 인라인으로 고정한다.\n // 임베드 호스트(WordPress 등)가 `.entry-content th`/`.fn-post-content th`(특이도 0,2,1)로\n // 배경·글자·라인높이·보더·폰트크기를 덮어써도 인라인(최고 우선순위)이 이긴다.\n // (var 참조라 setTheme 시 자동 반영. text-align/padding 은 그리드 의도값 유지)\n background: 'var(--og-header-bg)', color: 'var(--og-header-color)',\n lineHeight: 'normal', verticalAlign: 'middle',\n fontSize: 'var(--og-font-size)',\n textAlign: col.headerAlign ?? 'center',\n borderTop: '0', borderLeft: '0',\n borderRight: '1px solid var(--og-border-color,#e0e0e0)',\n borderBottom: '1px solid var(--og-border-color,#e0e0e0)',\n userSelect: 'none', cursor: sortable ? 'pointer' : 'default',\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',\n position: 'relative',\n });\n\n // 헤더 툴팁: col.tooltip(문자열) 우선, 없으면 헤더 텍스트 — 잘린 헤더 가독성 보조\n th.title = (typeof col.tooltip === 'string' ? col.tooltip : (col.header ?? col.field)) ?? '';\n\n const label = _el('span');\n label.textContent = col.header ?? col.field;\n label.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';\n th.appendChild(label);\n\n // 정렬 아이콘\n if (sortInfo) {\n th.classList.add('og-sorted');\n const icon = _el('span', 'og-sort-icon');\n icon.textContent = sortInfo.dir === 'asc' ? ' ↑' : ' ↓';\n th.appendChild(icon);\n }\n\n // 필터 아이콘 (leaf 컬럼 + filterable)\n const filterable = col.filterable !== false && opts.filterable && cell.colSpan === 1;\n if (filterable) {\n const filterIcon = _el('span', 'og-filter-icon');\n const hasFilter = opts._activeFilters?.[col.field]?.length > 0;\n filterIcon.textContent = hasFilter ? '⊿' : '▿';\n filterIcon.title = '필터';\n filterIcon.style.cssText = 'margin-left:3px;cursor:pointer;font-size:10px;opacity:0.6;';\n if (hasFilter) filterIcon.classList.add('og-filter-icon--active');\n filterIcon.addEventListener('click', (e) => {\n e.stopPropagation();\n this._cbs.onFilterIconClick(col.field, filterIcon);\n });\n th.appendChild(filterIcon);\n }\n\n // 컬럼 리사이즈 핸들\n if (col.resizable !== false) {\n const resizer = _el('div', 'og-resize-handle');\n resizer.style.cssText = `position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;z-index:1;`;\n th.appendChild(resizer);\n const capturedLeafIdx = leafIdx;\n _addResizer(resizer, th, (w) => {\n if (capturedLeafIdx >= 0) this._cbs.onColResize(capturedLeafIdx, w);\n });\n }\n\n // 컬럼 드래그 리오더\n if (opts.columnReorder && leafIdx >= 0 && cell.colSpan === 1) {\n th.draggable = true;\n th.addEventListener('dragstart', (e) => {\n this._cbs.onColDragStart(leafIdx);\n th.classList.add('og-col-dragging');\n e.dataTransfer?.setData('text/plain', String(leafIdx));\n });\n th.addEventListener('dragend', () => {\n th.classList.remove('og-col-dragging');\n this._header.querySelectorAll('.og-col-drop-over').forEach(el => el.classList.remove('og-col-drop-over'));\n });\n th.addEventListener('dragover', (e) => {\n e.preventDefault();\n const fromIdx = this._cbs.getColDragIdx();\n if (fromIdx !== null && fromIdx !== leafIdx) {\n this._header.querySelectorAll('.og-col-drop-over').forEach(el => el.classList.remove('og-col-drop-over'));\n th.classList.add('og-col-drop-over');\n }\n });\n th.addEventListener('dragleave', () => {\n th.classList.remove('og-col-drop-over');\n });\n th.addEventListener('drop', (e) => {\n e.preventDefault();\n th.classList.remove('og-col-drop-over');\n this._cbs.onColDrop(leafIdx);\n });\n }\n\n if (sortable) {\n th.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('og-resize-handle')) return;\n this._cbs.onHeaderClick(col.field, e.shiftKey);\n });\n }\n\n tr.appendChild(th);\n }\n table.appendChild(tr);\n }\n this._header.appendChild(table);\n }\n\n renderBody(\n startIndex: number, endIndex: number,\n data: DataLayer<any>,\n leaves: ColumnDef[],\n widths: number[],\n opts: any,\n offsetY: number,\n totalHeight: number,\n selectedRows: Set<number>,\n checkedRows: Set<number>,\n groupFlatRows: Array<any> | null = null,\n onGroupToggle?: (key: string) => void,\n onTreeToggle?: (nodeId: any) => void,\n extraOpts: Record<string, any> = {},\n mergeEngine?: MergeEngine\n ): void {\n // opts에 extraOpts 병합 (DnD _totalRows 등)\n if (Object.keys(extraOpts).length) opts = { ...opts, ...extraOpts };\n this._body.innerHTML = '';\n this._cellMap.clear();\n this._body.style.height = `${totalHeight}px`;\n const frozenCount: number = opts._frozenCount ?? 0;\n\n // 바디 최소 너비를 totalColWidth로 설정 — 헤더 table과 너비 동기화 (수평 스크롤 영역 확보)\n {\n let _ew = 0;\n if (opts.stateColumn) _ew += 24;\n if (opts.draggable) _ew += 18;\n if (opts.rowNumber) _ew += 44;\n if (opts.checkColumn) _ew += 36;\n const _totalCW = _ew + leaves.reduce((s: number, _: any, i: number) => s + (widths[i] ?? opts.defaultColumnWidth), 0);\n this._body.style.minWidth = `${_totalCW}px`;\n }\n\n if (endIndex < startIndex) return;\n\n const frag = document.createDocumentFragment();\n for (let ri = startIndex; ri <= endIndex; ri++) {\n // 그룹/트리 모드: flatRow 배열 사용\n const flatItem = groupFlatRows ? groupFlatRows[ri] : null;\n const isGroupRow = flatItem && (flatItem as any)._isGroup === true;\n const isTreeRow = flatItem && (flatItem as any)._isTree === true;\n\n if (isGroupRow) {\n const g = flatItem as any;\n const groupKey = `__${g._groupField}:${g._groupValue}`;\n const rowEl = _el('div', 'og-group-row');\n const top = offsetY + (ri - startIndex) * opts.rowHeight;\n rowEl.style.cssText = [\n `top:${top}px;height:${opts.rowHeight}px;`,\n 'display:flex;align-items:stretch;cursor:pointer;',\n `padding-left:${4 + g._depth * 12}px;`,\n 'background:var(--og-header-bg,#f5f5f5);',\n // host isolation: border:0 선행 (WP :where([style*=border-color]) 의 3px 강제 차단)\n 'border:0;border-bottom:1px solid var(--og-border-color,#e0e0e0);',\n ].join('');\n rowEl.setAttribute('role', 'row');\n rowEl.setAttribute('aria-expanded', g._expanded ? 'true' : 'false');\n rowEl.setAttribute('aria-rowindex', String(ri + 1));\n rowEl.setAttribute('aria-level', String(g._depth + 1));\n\n // ── extra 컬럼 영역 (stateColumn/draggable/rowNumber/checkColumn) ──────\n let extraW = 0;\n if (opts.stateColumn) extraW += 24;\n if (opts.draggable) extraW += 18;\n if (opts.rowNumber) extraW += 44;\n if (opts.checkColumn) extraW += 36;\n\n // stateColumn 자리: 편집 상태 배지 표시\n if (extraW > 0) {\n const stCell = _el('div', 'og-group-state-cell');\n stCell.style.cssText = [\n `width:${extraW}px;min-width:${extraW}px;flex-shrink:0;`,\n 'display:flex;align-items:center;justify-content:center;',\n 'font-size:10px;font-weight:700;gap:2px;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n ].join('');\n const st = g._states ?? { added: 0, edited: 0, removed: 0 };\n if (st.added > 0) { const b = _el('span'); b.textContent=`+${st.added}`; b.style.cssText='color:var(--og-row-added-bg,#2e7d32);background:#e8f5e9;padding:1px 3px;border-radius:3px;'; stCell.appendChild(b); }\n if (st.edited > 0) { const b = _el('span'); b.textContent=`M${st.edited}`; b.style.cssText='color:#e65100;background:#fff8e1;padding:1px 3px;border-radius:3px;'; stCell.appendChild(b); }\n if (st.removed > 0) { const b = _el('span'); b.textContent=`D${st.removed}`; b.style.cssText='color:var(--og-row-removed-bg,#c62828);background:#ffebee;padding:1px 3px;border-radius:3px;'; stCell.appendChild(b); }\n rowEl.appendChild(stCell);\n }\n\n // ── 컬럼별 셀 ─────────────────────────────────────────────────────────\n let labelPlaced = false;\n for (let ci = 0; ci < leaves.length; ci++) {\n const col = leaves[ci]!;\n const w = widths[ci] ?? opts.defaultColumnWidth;\n const hasSummary = g._summaryFmt !== undefined && col.field in (g._summaryFmt ?? {});\n\n const cell = _el('div', 'og-group-cell');\n cell.style.cssText = [\n `width:${w}px;min-width:${w}px;flex-shrink:0;`,\n 'padding:2px 8px;box-sizing:border-box;overflow:hidden;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n 'display:flex;align-items:center;',\n 'white-space:nowrap;text-overflow:ellipsis;',\n ].join('');\n\n if (hasSummary) {\n // 소계 값 — 숫자 컬럼은 우측 정렬\n const fmt = g._summaryFmt[col.field];\n cell.textContent = fmt !== '' ? fmt : '-';\n cell.style.justifyContent = 'flex-end';\n cell.style.color = 'var(--og-primary,#1976d2)';\n cell.style.fontWeight = '600';\n } else if (!labelPlaced) {\n // 맨 첫 번째 비-소계 컬럼에 그룹 레이블 배치\n labelPlaced = true;\n const arrow = _el('span', 'og-group-arrow');\n arrow.textContent = g._expanded ? '▾ ' : '▸ ';\n arrow.style.cssText = 'color:var(--og-primary,#1976d2);margin-right:4px;flex-shrink:0;';\n cell.appendChild(arrow);\n\n const lbl = _el('span', 'og-group-label');\n lbl.textContent = `${g._groupLabel} (${g._childCount}건)`;\n lbl.style.cssText = 'overflow:hidden;text-overflow:ellipsis;font-weight:600;';\n cell.appendChild(lbl);\n cell.style.gap = '0';\n }\n // 소계도 없고 첫 번째도 아닌 열: 빈 셀 (간격 유지)\n\n rowEl.appendChild(cell);\n }\n\n rowEl.addEventListener('click', () => onGroupToggle?.(groupKey));\n frag.appendChild(rowEl);\n continue;\n }\n\n // 일반 데이터 행 (트리 노드 포함)\n const treeNode: any | null = isTreeRow ? (flatItem as any) : null;\n const rowData = treeNode ? treeNode.data : (groupFlatRows ? flatItem : data.getRowByIndex(ri));\n if (!rowData) continue;\n const rowState = (isTreeRow || isGroupRow) ? 'none' : data.getRowState(ri);\n\n const rowEl = _el('div', 'og-row');\n rowEl.setAttribute('role', 'row');\n rowEl.setAttribute('aria-rowindex', String(ri + 1));\n const top = offsetY + (ri - startIndex) * opts.rowHeight;\n rowEl.style.top = `${top}px`;\n rowEl.style.height = `${opts.rowHeight}px`;\n\n // 교차 행 배경 — 가상스크롤에서 :nth-child는 DOM 위치 기반이라 ri 기준으로 인라인 설정\n let bg = ri % 2 === 0 ? 'var(--og-row-bg,#fff)' : 'var(--og-row-alt-bg,#fafafa)';\n rowEl.style.background = bg;\n\n // 상태/선택 CSS 클래스 부착 — !important 로 인라인 background 오버라이드\n if (rowState === 'added') rowEl.classList.add('og-state-added');\n if (rowState === 'edited') rowEl.classList.add('og-state-edited');\n if (rowState === 'removed') rowEl.classList.add('og-state-removed');\n if (selectedRows.has(ri)) rowEl.classList.add('og-selected');\n rowEl.setAttribute('aria-selected', selectedRows.has(ri) ? 'true' : 'false');\n\n // frozen 셀 배경용 bg — 상태행은 상태 색으로 덮어쓰기\n if (rowState === 'added') bg = 'var(--og-row-added-bg,#e8f5e9)';\n if (rowState === 'edited') bg = 'var(--og-row-edited-bg,#fff8e1)';\n if (rowState === 'removed') bg = 'var(--og-row-removed-bg,#ffebee)';\n if (selectedRows.has(ri)) bg = 'var(--og-row-selected-bg,#bbdefb)';\n\n // 행 레벨 클릭 (rowNumber·stateColumn 등 extra 컬럼 포함) → 선택 처리\n const localRowRi = ri;\n rowEl.addEventListener('click', (e) => { this._cbs.onCellClick(localRowRi, -1, e); });\n\n const colMap = new Map<number, HTMLElement>();\n\n // extra 컬럼 순서: stateColumn → draggable → rowNumber → checkColumn\n let extraBodyLeft = 0;\n\n // 상태 컬럼 (맨 앞)\n if (opts.stateColumn) {\n const stCell = _el('div', 'og-cell og-col-state');\n const icons: Record<string, string> = { added: '✚', edited: '✎', removed: '✖', none: '' };\n const colors: Record<string, string> = { added: '#2e7d32', edited: '#bf360c', removed: '#c62828', none: '' };\n stCell.textContent = icons[rowState] ?? '';\n stCell.style.color = colors[rowState] ?? '';\n stCell.title = rowState;\n if (frozenCount > 0) {\n stCell.style.position = 'sticky';\n stCell.style.left = `${extraBodyLeft}px`;\n stCell.style.zIndex = '2';\n stCell.style.background = bg;\n }\n extraBodyLeft += 24;\n rowEl.appendChild(stCell);\n }\n\n // 드래그 핸들\n const dnd = this._cbs.getDndManager();\n if (opts.draggable && dnd) {\n const handle = dnd.attachHandle(rowEl, ri, opts._totalRows ?? endIndex + 1);\n if (frozenCount > 0) {\n handle.style.position = 'sticky';\n handle.style.left = `${extraBodyLeft}px`;\n handle.style.zIndex = '2';\n handle.style.background = bg;\n }\n extraBodyLeft += 18;\n rowEl.appendChild(handle);\n }\n\n // 행 번호 컬럼\n if (opts.rowNumber) {\n const numCell = _el('div', 'og-cell og-col-rownum');\n numCell.textContent = String(ri + 1);\n if (frozenCount > 0) {\n numCell.style.position = 'sticky';\n numCell.style.left = `${extraBodyLeft}px`;\n numCell.style.zIndex = '2';\n numCell.style.background = bg;\n }\n extraBodyLeft += 44;\n rowEl.appendChild(numCell);\n }\n\n // 체크박스 컬럼\n if (opts.checkColumn) {\n const chkCell = _el('div', 'og-cell og-col-check');\n const chk = document.createElement('input');\n chk.type = 'checkbox';\n chk.checked = checkedRows.has(ri);\n chk.setAttribute('aria-label', `${ri + 1}행 선택`);\n chk.addEventListener('click', (e) => e.stopPropagation());\n chk.addEventListener('change', (e) => {\n e.stopPropagation();\n this._cbs.onRowCheck(ri, chk.checked);\n });\n chkCell.appendChild(chk);\n if (frozenCount > 0) {\n chkCell.style.position = 'sticky';\n chkCell.style.left = `${extraBodyLeft}px`;\n chkCell.style.zIndex = '2';\n chkCell.style.background = bg;\n }\n extraBodyLeft += 36;\n rowEl.appendChild(chkCell);\n }\n\n // 데이터 컬럼\n for (let ci = 0; ci < leaves.length; ci++) {\n const col = leaves[ci]!;\n const w = widths[ci] ?? opts.defaultColumnWidth;\n const isEditable = opts.editable && col.editable !== false;\n const isFirstCol = ci === 0;\n\n // 셀 병합 처리\n const mergeInfo = mergeEngine && !mergeEngine.isEmpty\n ? mergeEngine.getInfo(ri, ci)\n : null;\n if (mergeInfo?.hidden) {\n // 병합 하위 셀: flex 공간만 차지하는 투명 placeholder (컬럼 정렬 보존)\n const ph = _el('div', 'og-cell og-cell--merge-ph');\n ph.style.cssText = `width:${w}px;min-width:${w}px;flex-shrink:0;visibility:hidden;box-sizing:border-box;`;\n rowEl.appendChild(ph);\n continue;\n }\n\n const cellEl = _el('div', 'og-cell');\n cellEl.setAttribute('role', 'gridcell');\n cellEl.setAttribute('aria-colindex', String(ci + 1));\n\n // rowSpan 적용: 여러 행 높이만큼 절대 위치로 늘림\n const rs = mergeInfo?.rowSpan ?? 1;\n const cs = mergeInfo?.colSpan ?? 1;\n const mergedHeight = rs > 1 ? rs * opts.rowHeight : opts.rowHeight;\n // colSpan 시 width 합산\n let mergedWidth = w;\n if (cs > 1) {\n for (let dc = 1; dc < cs; dc++) {\n mergedWidth += widths[ci + dc] ?? opts.defaultColumnWidth;\n }\n }\n\n const hPad = treeNode && isFirstCol ? 0 : 8;\n\n // 고정 컬럼 sticky\n const isFrozenCell = ci < frozenCount;\n let frozenLeftOff = 0;\n if (isFrozenCell) {\n // extra 컬럼 순서: stateColumn → draggable → rowNumber → checkColumn\n if (opts.stateColumn) frozenLeftOff += 24;\n if (opts.draggable) frozenLeftOff += 18;\n if (opts.rowNumber) frozenLeftOff += 44;\n if (opts.checkColumn) frozenLeftOff += 36;\n for (let i = 0; i < ci; i++) frozenLeftOff += widths[i] ?? opts.defaultColumnWidth;\n cellEl.classList.add('og-frozen-cell');\n if (ci === frozenCount - 1) cellEl.classList.add('og-frozen-last');\n }\n\n // frozen 셀: sticky 특성상 배경 필요 → bg 적용. 일반 셀: 행에서 상속\n const cellBg = isFrozenCell ? bg : 'inherit';\n cellEl.style.width = `${mergedWidth}px`;\n cellEl.style.minWidth = `${mergedWidth}px`;\n cellEl.style.maxWidth = `${mergedWidth}px`;\n if (rs > 1) cellEl.style.height = `${mergedHeight}px`;\n if (isFrozenCell) cellEl.style.background = bg;\n if (treeNode && isFirstCol) cellEl.style.padding = '0';\n cellEl.style.overflow = 'hidden';\n if (rs > 1) {\n // rowSpan 마스터셀: body 기준 absolute 위치 (flex flow 밖)\n cellEl.style.height = `${mergedHeight}px`;\n cellEl.style.position = 'absolute';\n cellEl.style.zIndex = '3';\n // 마스터셀에 명시적 배경색 필요(하단 행 덮기)\n cellEl.style.background = (bg && bg !== 'inherit') ? bg : 'var(--og-row-bg, #fff)';\n // host isolation: 미지정 변 폭 0 명시 (WP :where([style*=border-color]) 의 3px 강제 차단)\n cellEl.style.borderTop = '0';\n cellEl.style.borderLeft = '0';\n cellEl.style.borderBottom = `1px solid var(--og-border-color, #e0e0e0)`;\n } else if (isFrozenCell) {\n cellEl.style.position = 'sticky';\n cellEl.style.left = `${frozenLeftOff}px`;\n cellEl.style.zIndex = '1';\n }\n if (col.type === 'number' || col.align === 'right') cellEl.classList.add('og-cell--right');\n else if (col.align === 'center') cellEl.classList.add('og-cell--center');\n if (isEditable) cellEl.classList.add('og-cell--editable');\n // 줄바꿈(wrap): nowrap+ellipsis 대신 여러 줄 표시 (rowHeight를 키워 함께 사용)\n if (col.wrap) cellEl.classList.add('og-cell--wrap');\n\n // ── ARIA + 포커스 셀 ───────────────────────\n if (!isEditable) cellEl.setAttribute('aria-readonly', 'true');\n if (cs > 1) cellEl.setAttribute('aria-colspan', String(cs));\n if (rs > 1) cellEl.setAttribute('aria-rowspan', String(rs));\n // 포커스 셀 표시 (og-cell-focused 클래스 + tabIndex for programmatic focus)\n const isFocused = opts._focusCell?.ri === ri && opts._focusCell?.ci === ci;\n if (isFocused) {\n cellEl.classList.add('og-cell-focused');\n cellEl.tabIndex = -1;\n }\n // 셀 접근성 레이블 (헤더명: 값)\n const _rawVal = rowData ? rowData[col.field] : null;\n cellEl.setAttribute('aria-label', `${col.header}: ${_rawVal == null ? '' : String(_rawVal)}`);\n\n // 툴팁(native title): col.tooltip(문자열|함수) 우선, 없고 opts.tooltips 면 셀 값 자동 노출\n if (col.tooltip != null) {\n cellEl.title = typeof col.tooltip === 'function'\n ? String(col.tooltip(_rawVal, rowData as any) ?? '')\n : String(col.tooltip);\n } else if (opts.tooltips && _rawVal != null && _rawVal !== '') {\n cellEl.title = String(_rawVal);\n }\n\n // ── 트리 첫 컬럼: 탐색기 스타일 렌더링 ──────────────\n let _treeRenderTarget: HTMLElement = cellEl;\n\n if (treeNode && isFirstCol) {\n const treeCell = _el('div', 'og-tree-cell');\n\n // ① 조상 가이드 라인 (│ or 空白) — 깊이만큼 반복\n const hasMoreChain: boolean[] = treeNode._ancestorHasMore ?? [];\n for (let d = 0; d < treeNode._depth; d++) {\n const guide = _el('span', 'og-tree-guide');\n if (hasMoreChain[d]) guide.classList.add('og-tree-guide--line');\n treeCell.appendChild(guide);\n }\n\n // ② 연결선 (depth > 0 만) : ├─ 또는 └─\n if (treeNode._depth > 0) {\n const conn = _el('span', 'og-tree-connector');\n conn.classList.add(\n treeNode._isLastChild ? 'og-tree-connector--last' : 'og-tree-connector--mid'\n );\n treeCell.appendChild(conn);\n }\n\n // ③ 토글 래퍼 — branch: 정렬 스페이서(빈 칸), leaf: 원형 점\n const toggleWrap = _el('span', 'og-tree-toggle-wrap');\n if (!treeNode._hasChildren) {\n const dot = _el('span', 'og-tree-leaf-dot');\n toggleWrap.appendChild(dot);\n }\n treeCell.appendChild(toggleWrap);\n\n // ④ 노드 아이콘 — branch: 폴더(클릭 토글), leaf: 파일\n const nodeIcon = document.createElement('i');\n if (treeNode._hasChildren) {\n const iconCls = _resolveTreeIcon(col.treeNodeIcon, rowData, true, treeNode._expanded);\n nodeIcon.className = treeNode._expanded\n ? `${iconCls} og-tree-node-icon og-tree-node-icon--branch og-tree-node-icon--open og-tree-node-icon--toggle`\n : `${iconCls} og-tree-node-icon og-tree-node-icon--branch og-tree-node-icon--toggle`;\n nodeIcon.setAttribute('role', 'button');\n nodeIcon.setAttribute('tabindex', '0');\n nodeIcon.setAttribute('aria-expanded', treeNode._expanded ? 'true' : 'false');\n nodeIcon.setAttribute('aria-label', treeNode._expanded ? '접기' : '펼치기');\n nodeIcon.addEventListener('click', (e: MouseEvent) => {\n e.stopPropagation();\n onTreeToggle?.(treeNode._treeId);\n });\n nodeIcon.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n onTreeToggle?.(treeNode._treeId);\n }\n });\n } else {\n const iconCls = _resolveTreeIcon(col.treeNodeIcon, rowData, false, false);\n nodeIcon.setAttribute('aria-hidden', 'true');\n nodeIcon.className = `${iconCls} og-tree-node-icon og-tree-node-icon--leaf`;\n }\n treeCell.appendChild(nodeIcon);\n\n cellEl.appendChild(treeCell);\n _treeRenderTarget = treeCell;\n }\n\n // 사용자 정의 cellStyle\n if (col.cellStyle) {\n const val = rowData[col.field];\n const s = typeof col.cellStyle === 'function' ? col.cellStyle(val, rowData as any, ri) : col.cellStyle;\n Object.assign(cellEl.style, s);\n }\n\n // 렌더러 사용 — 트리 첫 컬럼은 treeCell 안에 추가, 그 외는 cellEl에 추가\n const renderer = createRenderer(col);\n const rendered = renderer.render({\n value: rowData[col.field], row: rowData, rowIndex: ri,\n column: col as any, colIndex: ci,\n isSelected: selectedRows.has(ri), rowState\n });\n _treeRenderTarget.appendChild(rendered);\n\n // 이벤트\n const localRi = ri, localCi = ci;\n cellEl.addEventListener('click', (e) => { e.stopPropagation(); this._cbs.onCellClick(localRi, localCi, e); });\n cellEl.addEventListener('dblclick', (e) => { e.stopPropagation(); this._cbs.onCellDblClick(localRi, localCi, e); });\n cellEl.addEventListener('mouseover', (e) => { e.stopPropagation(); this._cbs.onCellMouseOver(localRi, localCi, e); });\n cellEl.addEventListener('mouseout', (e) => { e.stopPropagation(); this._cbs.onCellMouseOut(localRi, localCi, e); });\n cellEl.addEventListener('mousedown', (e) => { e.stopPropagation(); this._cbs.onCellMouseDown(localRi, localCi, e); });\n cellEl.addEventListener('mouseup', (e) => { e.stopPropagation(); this._cbs.onCellMouseUp(localRi, localCi, e); });\n cellEl.addEventListener('mousemove', (e) => { e.stopPropagation(); this._cbs.onCellMouseMove(localRi, localCi, e); });\n\n colMap.set(ci, cellEl);\n\n if (rs > 1) {\n // ① 마스터 행의 flex에 투명 placeholder 삽입 → 컬럼 너비 보존\n const ph = document.createElement('div');\n ph.style.cssText = [\n `width:${w}px;min-width:${w}px;height:${opts.rowHeight}px;`,\n 'flex-shrink:0;box-sizing:border-box;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n ].join('');\n rowEl.appendChild(ph);\n\n // ② 마스터셀은 body 기준 absolute — top/left 정밀 계산\n let leftOff = 0;\n if (opts.stateColumn) leftOff += 24;\n if (opts.draggable) leftOff += 18;\n if (opts.rowNumber) leftOff += 44;\n if (opts.checkColumn) leftOff += 36;\n for (let pc = 0; pc < ci; pc++) leftOff += widths[pc] ?? opts.defaultColumnWidth;\n const rowTop = offsetY + (ri - startIndex) * opts.rowHeight;\n cellEl.style.left = `${leftOff}px`;\n cellEl.style.top = `${rowTop}px`;\n frag.appendChild(cellEl); // rowEl이 아닌 body 레벨에 직접 부착\n } else {\n rowEl.appendChild(cellEl);\n }\n }\n\n this._cellMap.set(ri, colMap);\n frag.appendChild(rowEl);\n }\n\n // 빈 데이터 메시지\n if (data.rowCount === 0) {\n const empty = _el('div', 'og-empty-message');\n empty.textContent = '데이터가 없습니다.';\n empty.style.cssText = `width:100%;`;\n frag.appendChild(empty);\n }\n\n this._body.appendChild(frag);\n }\n\n getCellEl(rowIndex: number, colIndex: number): HTMLElement | undefined {\n return this._cellMap.get(rowIndex)?.get(colIndex);\n }\n\n destroy(): void {\n this._root.innerHTML = '';\n }\n}\n\n// ─── 트리 노드 아이콘 해석 ────────────────────────────────\nfunction _resolveTreeIcon(\n def: TreeNodeIconDef | ((row: Record<string, any>, hasChildren: boolean, expanded: boolean) => string) | undefined,\n row: Record<string, any>,\n hasChildren: boolean,\n expanded: boolean\n): string {\n let icon: string;\n if (!def) {\n icon = hasChildren ? (expanded ? 'bi-folder2-open' : 'bi-folder2') : 'bi-file-earmark';\n } else if (typeof def === 'function') {\n icon = def(row, hasChildren, expanded);\n } else {\n if (hasChildren) {\n icon = expanded ? (def.branchOpen ?? 'bi-folder2-open') : (def.branch ?? 'bi-folder2');\n } else {\n icon = def.leaf ?? 'bi-file-earmark';\n }\n }\n return icon.startsWith('bi ') ? icon : `bi ${icon}`;\n}\n\n// ─── DOM 유틸 ─────────────────────────────────────────────\nexport function _el(tag: string, className?: string): HTMLElement {\n const e = document.createElement(tag);\n if (className) e.className = className;\n return e;\n}\n\nexport function _style(el: HTMLElement, styles: Partial<CSSStyleDeclaration>): void {\n Object.assign(el.style, styles);\n}\n\nexport function _downloadText(content: string, filename: string, mime = 'text/plain;charset=utf-8'): void {\n const blob = new Blob([content], { type: mime });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url; a.download = filename; a.click();\n URL.revokeObjectURL(url);\n}\n\n// ─── 컬럼 리사이즈 헬퍼 ──────────────────────────────────\nfunction _addResizer(handle: HTMLElement, th: HTMLElement, onChange: (w: number) => void): void {\n let startX = 0, startW = 0;\n\n handle.addEventListener('mousedown', (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n startX = e.clientX;\n startW = th.offsetWidth;\n\n const onMove = (ev: MouseEvent) => {\n const w = Math.max(40, startW + ev.clientX - startX);\n th.style.width = `${w}px`;\n th.style.minWidth = `${w}px`;\n };\n const onUp = (ev: MouseEvent) => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n onChange(Math.max(40, startW + ev.clientX - startX));\n };\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n });\n}\n","import { DataLayer } from './DataLayer.js';\n\nexport class RowManager<T extends Record<string, any> = any> {\n private _selectedRows: Set<number> = new Set();\n private _checkedRows: Set<number> = new Set();\n private _data: DataLayer<T>;\n\n constructor(data: DataLayer<T>) {\n this._data = data;\n }\n\n // ─── Read-only 접근 ───────────────────────────────────────\n get selectedRows(): Set<number> { return this._selectedRows; }\n get checkedRows(): Set<number> { return this._checkedRows; }\n\n // ─── 선택 변경 ───────────────────────────────────────────\n selectSingle(ri: number): void {\n this._selectedRows.clear();\n this._selectedRows.add(ri);\n }\n\n selectToggle(ri: number): void {\n if (this._selectedRows.has(ri)) this._selectedRows.delete(ri);\n else this._selectedRows.add(ri);\n }\n\n clearSelection(): void { this._selectedRows.clear(); }\n\n // ─── 체크 변경 ───────────────────────────────────────────\n check(ri: number, checked: boolean): void {\n if (checked) this._checkedRows.add(ri);\n else this._checkedRows.delete(ri);\n }\n\n checkAll(checked: boolean, totalRows: number): void {\n if (checked) {\n for (let i = 0; i < totalRows; i++) this._checkedRows.add(i);\n } else {\n this._checkedRows.clear();\n }\n }\n\n checkByValue(field: string, values: any[]): void {\n for (let i = 0; i < this._data.rowCount; i++) {\n if (values.includes(this._data.getCellValue(i, field))) this._checkedRows.add(i);\n }\n }\n\n uncheckAll(): void { this._checkedRows.clear(); }\n\n checkById(_ids: string[]): void {}\n addCheckById(_ids: string[]): void {}\n uncheckById(_ids: string[]): void {}\n\n // ─── 선택 쿼리 API ───────────────────────────────────────\n getSelections(): T[] {\n return [...this._selectedRows]\n .map(i => this._data.getRowByIndex(i))\n .filter(Boolean) as T[];\n }\n\n getChecked(): Array<{ row: T; rowIndex: number }> {\n return [...this._checkedRows].map(i => ({\n row: this._data.getRowByIndex(i) as T,\n rowIndex: i,\n }));\n }\n\n getAllChecked(): T[] { return this.getChecked().map(r => r.row); }\n\n getActiveRow(): number {\n return this._selectedRows.size > 0 ? [...this._selectedRows][0]! : -1;\n }\n\n activate(index: number): void {\n this._selectedRows.clear();\n this._selectedRows.add(index);\n }\n\n deselect(): void { this._selectedRows.clear(); }\n\n // ─── 전체 초기화 (setData / clearData 시) ────────────────\n reset(): void {\n this._selectedRows.clear();\n this._checkedRows.clear();\n }\n}\n","import type { CellEditor } from './CellEditor.js';\nimport type { RenderContext } from '../renderers/CellRenderer.js';\nimport { formatDate } from '../renderers/CellRenderer.js';\n\nexport class DateEditor implements CellEditor {\n private input!: HTMLInputElement;\n private _container!: HTMLElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._container = container;\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n container.setAttribute('aria-haspopup', 'dialog');\n container.setAttribute('aria-expanded', 'true');\n\n this.input = document.createElement('input');\n this.input.type = 'date';\n this.input.className = 'og-cell-input';\n this.input.setAttribute('aria-label', ctx.column.header ?? '날짜 선택');\n\n const raw = ctx.value;\n if (raw) {\n const d = raw instanceof Date ? raw : new Date(raw);\n if (!isNaN(d.getTime())) {\n this.input.value = formatDate(d, 'yyyy-MM-dd');\n }\n }\n\n this.input.addEventListener('keydown', this._onKeyDown);\n this.input.addEventListener('blur', this._onBlur);\n container.appendChild(this.input);\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n e.stopPropagation();\n if (e.key === 'Enter') { e.preventDefault(); this._onCommit(this.input.value); }\n else if (e.key === 'Escape') this._onCancel();\n };\n\n private _onBlur = (): void => { this._onCommit(this.input.value); };\n\n getValue(): any { return this.input?.value; }\n focus(): void { this.input?.focus(); }\n\n destroy(): void {\n this._container?.setAttribute('aria-expanded', 'false');\n this.input?.removeEventListener('keydown', this._onKeyDown);\n this.input?.removeEventListener('blur', this._onBlur);\n }\n}\n","import type { CellEditor } from './CellEditor.js';\nimport type { RenderContext } from '../renderers/CellRenderer.js';\n\nexport type SelectOption = string | { label?: string; text?: string; value: any };\n\nfunction normalizeOptions(raw: SelectOption[]): Array<{ label: string; value: any }> {\n return raw.map(o => {\n if (typeof o === 'string') return { label: o, value: o };\n const label = (o as any).label ?? (o as any).text ?? String((o as any).value ?? '');\n return { label, value: (o as any).value };\n });\n}\n\nexport class SelectEditor implements CellEditor {\n private select!: HTMLSelectElement;\n private _container!: HTMLElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n private _options: Array<{ label: string; value: any }>;\n private _optionsFn: ((row: any, rowIndex: number) => SelectOption[]) | null;\n\n constructor(\n options: SelectOption[] = [],\n optionsFn?: (row: any, rowIndex: number) => SelectOption[]\n ) {\n this._options = normalizeOptions(options);\n this._optionsFn = optionsFn ?? null;\n }\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._container = container;\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n container.setAttribute('aria-haspopup', 'listbox');\n container.setAttribute('aria-expanded', 'true');\n\n this.select = document.createElement('select');\n this.select.className = 'og-cell-select';\n this.select.setAttribute('aria-label', ctx.column.header ?? '선택');\n\n const resolved = this._optionsFn\n ? normalizeOptions(this._optionsFn(ctx.row, ctx.rowIndex))\n : this._options;\n\n for (const opt of resolved) {\n const el = document.createElement('option');\n el.value = String(opt.value);\n el.textContent = opt.label;\n this.select.appendChild(el);\n }\n\n const cur = ctx.value == null ? '' : String(ctx.value);\n if (resolved.some(o => String(o.value) === cur)) this.select.value = cur;\n\n this.select.addEventListener('change', () => onCommit(this.select.value));\n this.select.addEventListener('blur', () => onCommit(this.select.value));\n this.select.addEventListener('keydown', (e) => { if (e.key === 'Escape') onCancel(); });\n container.appendChild(this.select);\n }\n\n getValue(): any { return this.select?.value; }\n focus(): void { this.select?.focus(); }\n\n destroy(): void {\n this._container?.setAttribute('aria-expanded', 'false');\n }\n}\n","import type { ColumnDef } from '../types.js';\nimport type { RenderContext } from '../renderers/CellRenderer.js';\nexport { DateEditor } from './DateEditor.js';\nexport { SelectEditor } from './SelectEditor.js';\nimport { DateEditor } from './DateEditor.js';\nimport { SelectEditor } from './SelectEditor.js';\n\nexport interface EditorResult {\n committed: boolean;\n value: any;\n}\n\nexport interface CellEditor {\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (value: any) => void, onCancel: () => void): void;\n getValue(): any;\n focus(): void;\n destroy(): void;\n}\n\n// ─── TextEditor ───────────────────────────────────────────\nexport class TextEditor implements CellEditor {\n private input!: HTMLInputElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n this.input = document.createElement('input');\n this.input.type = 'text';\n this.input.value = ctx.value == null ? '' : String(ctx.value);\n this.input.style.cssText = `\n width:100%;height:100%;border:none;outline:none;padding:0 8px;\n font-size:var(--og-font-size,13px);font-family:var(--og-font-family,sans-serif);\n background:var(--og-row-bg,#fff);box-sizing:border-box;\n `;\n\n this.input.addEventListener('keydown', this._onKeyDown);\n this.input.addEventListener('blur', this._onBlur);\n container.appendChild(this.input);\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n e.stopPropagation();\n if (e.key === 'Enter' || e.key === 'Tab') {\n e.preventDefault();\n this._onCommit(this.input.value);\n } else if (e.key === 'Escape') {\n this._onCancel();\n }\n };\n\n private _onBlur = (): void => {\n this._onCommit(this.input.value);\n };\n\n getValue(): any { return this.input?.value; }\n\n focus(): void {\n this.input?.focus();\n this.input?.select();\n }\n\n destroy(): void {\n this.input?.removeEventListener('keydown', this._onKeyDown);\n this.input?.removeEventListener('blur', this._onBlur);\n }\n}\n\n// ─── NumberEditor ─────────────────────────────────────────\nexport class NumberEditor implements CellEditor {\n private input!: HTMLInputElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n private min: number | undefined;\n private max: number | undefined;\n private step: number | undefined;\n\n constructor(opts?: { min?: number; max?: number; step?: number }) {\n this.min = opts?.min;\n this.max = opts?.max;\n this.step = opts?.step;\n }\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n this.input = document.createElement('input');\n this.input.type = 'number';\n this.input.value = ctx.value == null ? '' : String(ctx.value);\n if (this.min != null) this.input.min = String(this.min);\n if (this.max != null) this.input.max = String(this.max);\n if (this.step != null) this.input.step = String(this.step);\n this.input.style.cssText = `\n width:100%;height:100%;border:none;outline:none;padding:0 8px;\n font-size:var(--og-font-size,13px);text-align:right;\n background:var(--og-row-bg,#fff);box-sizing:border-box;\n `;\n this.input.addEventListener('keydown', this._onKeyDown);\n this.input.addEventListener('blur', this._onBlur);\n container.appendChild(this.input);\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n e.stopPropagation();\n if (e.key === 'Enter' || e.key === 'Tab') { e.preventDefault(); this._commit(); }\n else if (e.key === 'Escape') this._onCancel();\n };\n\n private _onBlur = (): void => { this._commit(); };\n\n private _commit(): void {\n const v = this.input.value === '' ? null : Number(this.input.value);\n this._onCommit(v);\n }\n\n getValue(): any { return this.input?.value === '' ? null : Number(this.input?.value); }\n focus(): void { this.input?.focus(); this.input?.select(); }\n destroy(): void {\n this.input?.removeEventListener('keydown', this._onKeyDown);\n this.input?.removeEventListener('blur', this._onBlur);\n }\n}\n\n\n// ─── CheckboxEditor ───────────────────────────────────────\nexport class CheckboxEditor implements CellEditor {\n private chk!: HTMLInputElement;\n private _onCommit!: (v: any) => void;\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, _onCancel: () => void): void {\n this._onCommit = onCommit;\n container.style.cssText += 'display:flex;align-items:center;justify-content:center;';\n\n this.chk = document.createElement('input');\n this.chk.type = 'checkbox';\n this.chk.checked = !!ctx.value;\n this.chk.style.cursor = 'pointer';\n this.chk.addEventListener('change', () => onCommit(this.chk.checked));\n container.appendChild(this.chk);\n }\n\n getValue(): any { return this.chk?.checked; }\n focus(): void { this.chk?.focus(); }\n destroy(): void {}\n}\n\n// ─── Editor 팩토리 ────────────────────────────────────────\nexport function createEditor(col: ColumnDef): CellEditor {\n const editor = col.editor;\n if (!editor) {\n switch (col.type as string) {\n case 'number': return new NumberEditor();\n case 'date': return new DateEditor();\n case 'boolean': return new CheckboxEditor();\n case 'select': return new SelectEditor(col.options ?? [], col.optionsFn as any);\n default: return new TextEditor();\n }\n }\n if (typeof editor === 'string') {\n switch (editor) {\n case 'number': return new NumberEditor();\n case 'date': return new DateEditor();\n case 'select': return new SelectEditor(col.options ?? [], col.optionsFn as any);\n case 'checkbox': return new CheckboxEditor();\n default: return new TextEditor();\n }\n }\n // EditorDef 객체\n switch (editor.type) {\n case 'number': {\n const opts: { min?: number; max?: number; step?: number } = {};\n if (editor.min != null) opts.min = editor.min;\n if (editor.max != null) opts.max = editor.max;\n if (editor.step != null) opts.step = editor.step;\n return new NumberEditor(opts);\n }\n case 'date': return new DateEditor();\n case 'select': return new SelectEditor(editor.options ?? [], col.optionsFn as any);\n case 'checkbox': return new CheckboxEditor();\n default: return new TextEditor();\n }\n}\n","import type { ColumnDef } from './types.js';\n\nexport function isToggleCol<T>(col: ColumnDef<T>): boolean {\n const rendType = typeof col.renderer === 'string'\n ? col.renderer\n : (col.renderer && typeof col.renderer === 'object' ? (col.renderer as any).type : '');\n return col.type === 'boolean' || (col.type as string) === 'checkbox'\n || rendType === 'checkbox' || rendType === 'switch';\n}\n\nexport function isSelectCol<T>(col: ColumnDef<T>): boolean {\n return (col.type as string) === 'select';\n}\n\nexport function isRadioCol<T>(col: ColumnDef<T>): boolean {\n return (col.type as string) === 'radio';\n}\n","import { DataLayer } from './DataLayer.js';\nimport { ColumnLayout } from './ColumnLayout.js';\nimport { GridRenderer } from './GridRenderer.js';\nimport { createEditor } from './editors/CellEditor.js';\nimport type { CellEditor } from './editors/CellEditor.js';\nimport type { ColumnDef, EditEvent } from './types.js';\nimport { isToggleCol } from './CellTypeRegistry.js';\n\nexport interface CellEditDeps<T extends Record<string, any>> {\n data: DataLayer<T>;\n colLayout: ColumnLayout<T>;\n getRenderer: () => GridRenderer | null;\n getContainer: () => HTMLElement;\n getOptions: () => any;\n emit: (event: string, ...args: any[]) => void;\n doRender: () => void;\n announce: (msg: string) => void;\n writeCell: (ri: number, field: string, value: any) => void;\n scrollToRow: (ri: number) => void;\n getVisibleLeaves: () => ColumnDef<T>[];\n}\n\nexport class CellEditManager<T extends Record<string, any> = any> {\n private _activeEditor: CellEditor | null = null;\n private _editCell: { ri: number; ci: number } | null = null;\n private _focusCell: { ri: number; ci: number } | null = null;\n private _dragColIdx: number | null = null;\n\n private _d: CellEditDeps<T>;\n\n constructor(deps: CellEditDeps<T>) {\n this._d = deps;\n }\n\n // ─── 상태 접근자 ─────────────────────────────────────────\n get activeEditor(): CellEditor | null { return this._activeEditor; }\n get editCell(): { ri: number; ci: number } | null { return this._editCell; }\n get focusCell(): { ri: number; ci: number } | null { return this._focusCell; }\n get dragColIdx(): number | null { return this._dragColIdx; }\n set dragColIdx(v: number | null) { this._dragColIdx = v; }\n\n // ─── 포커스 셀 ───────────────────────────────────────────\n setFocusCell(ri: number, ci: number): void {\n this._focusCell = { ri, ci };\n this._d.scrollToRow(ri);\n this._d.doRender();\n const col = this._d.getVisibleLeaves()[ci];\n const row = this._d.data.getRowByIndex(ri);\n if (col && row) {\n const val = (row as any)[col.field];\n this._d.announce(\n `${ri + 1}행 ${ci + 1}열, ${col.header}: ${val == null ? '빈 값' : String(val)}`\n );\n }\n }\n\n clearFocusCell(): void { this._focusCell = null; }\n\n // ─── 편집 시작 (키보드) ──────────────────────────────────\n startEditByKey(rowIndex: number, colIndex: number): void {\n const col = this._d.getVisibleLeaves()[colIndex];\n if (!col) return;\n\n if (isToggleCol(col)) {\n const opts = this._d.getOptions();\n const colEditable = col.editable !== false && (col.editable !== undefined || opts.editable);\n if (colEditable) {\n const row = this._d.data.getRowByIndex(rowIndex);\n if (row) this._d.writeCell(rowIndex, col.field as unknown as string, !(row as any)[col.field]);\n }\n return;\n }\n\n const row = this._d.data.getRowByIndex(rowIndex);\n if (col.editable === false) return;\n if (typeof col.editable === 'function' && !col.editable(row as T, rowIndex)) return;\n\n this.commitEdit();\n const cellEl = this._d.getRenderer()?.getCellEl(rowIndex, colIndex);\n if (!cellEl) return;\n cellEl.innerHTML = '';\n\n const editor = createEditor(col);\n this._activeEditor = editor;\n this._editCell = { ri: rowIndex, ci: colIndex };\n\n const startEvt: EditEvent<T> = {\n type: 'editStart', rowIndex, columnIndex: colIndex,\n field: col.field, oldValue: row?.[col.field], newValue: row?.[col.field],\n row: row as T, column: col as any\n };\n this._d.emit('editStart', startEvt);\n this._d.getOptions().onEditStart?.(startEvt);\n\n cellEl.classList.add('og-editing');\n const ctx = {\n value: row?.[col.field], row: row as any, rowIndex,\n column: col as any, colIndex, isSelected: true, rowState: 'none' as any\n };\n editor.mount(cellEl, ctx,\n (value) => this.commitEditWithValue(rowIndex, colIndex, value),\n () => this.cancelEdit()\n );\n requestAnimationFrame(() => editor.focus());\n }\n\n // ─── 편집 시작 (마우스) ──────────────────────────────────\n startEdit(rowIndex: number, colIndex: number, _e: MouseEvent): void {\n const opts = this._d.getOptions();\n if (!opts.editable) return;\n const col = this._d.getVisibleLeaves()[colIndex];\n if (!col) return;\n\n if (isToggleCol(col)) return;\n\n const row = this._d.data.getRowByIndex(rowIndex);\n if (col.editable === false) return;\n if (typeof col.editable === 'function' && !col.editable(row as T, rowIndex)) return;\n if (!col.editable && !opts.editable) return;\n\n this.commitEdit();\n\n const cellEl = this._d.getRenderer()?.getCellEl(rowIndex, colIndex);\n if (!cellEl) return;\n cellEl.innerHTML = '';\n\n const editor = createEditor(col);\n this._activeEditor = editor;\n this._editCell = { ri: rowIndex, ci: colIndex };\n\n const startEvt: EditEvent<T> = {\n type: 'editStart', rowIndex, columnIndex: colIndex,\n field: col.field, oldValue: row?.[col.field], newValue: row?.[col.field],\n row: row as T, column: col as any\n };\n this._d.emit('editStart', startEvt);\n opts.onEditStart?.(startEvt);\n\n cellEl.classList.add('og-editing');\n const ctx = {\n value: row?.[col.field], row: row as any, rowIndex,\n column: col as any, colIndex, isSelected: true, rowState: 'none' as any\n };\n editor.mount(cellEl, ctx,\n (value) => this.commitEditWithValue(rowIndex, colIndex, value),\n () => this.cancelEdit()\n );\n requestAnimationFrame(() => editor.focus());\n }\n\n // ─── 편집 종료 ───────────────────────────────────────────\n commitEdit(): void {\n if (!this._activeEditor || !this._editCell) return;\n const val = this._activeEditor.getValue();\n const { ri, ci } = this._editCell;\n this._finishEdit(ri, ci, val, false);\n }\n\n commitEditWithValue(ri: number, ci: number, value: any): void {\n this._finishEdit(ri, ci, value, false);\n }\n\n cancelEdit(): void {\n if (!this._editCell) return;\n const { ri, ci } = this._editCell;\n this._finishEdit(ri, ci, undefined, true);\n }\n\n private _finishEdit(ri: number, ci: number, value: any, cancel: boolean): void {\n if (!this._activeEditor) return;\n const col = this._d.getVisibleLeaves()[ci];\n const cellEl = this._d.getRenderer()?.getCellEl(ri, ci);\n if (cellEl) {\n this._activeEditor.destroy();\n cellEl.classList.remove('og-editing');\n }\n this._activeEditor = null;\n this._editCell = null;\n\n if (!cancel && col) {\n const old = this._d.data.getCellValue(ri, col.field);\n if (value !== old) {\n this._d.data.updateCell(ri, col.field, value);\n const row = this._d.data.getRowByIndex(ri);\n const opts = this._d.getOptions();\n const evt: EditEvent<T> = {\n type: 'editEnd', rowIndex: ri, columnIndex: ci,\n field: col.field, oldValue: old, newValue: value,\n row: row as T, column: col as any\n };\n this._d.emit('editEnd', evt);\n opts.onEditEnd?.(evt);\n this._d.emit('dataChange', this._d.data.getData());\n opts.onDataChange?.(this._d.data.getData());\n }\n }\n this._d.doRender();\n requestAnimationFrame(() => this._d.getContainer().focus({ preventScroll: true }));\n }\n}\n","import type { FilterItem } from './types.js';\n\n// ─── 공개 타입 ────────────────────────────────────────────\n\nexport interface FilterSelectOption {\n value: string;\n text: string;\n}\n\n/**\n * 캐스케이딩 필터 셀렉트 컬럼 정의.\n *\n * ### 데이터 공급 방식 (택 1)\n *\n * **A. JSON 배열 바인딩** (권장)\n * ```ts\n * {\n * field: 'brand',\n * label: '브랜드',\n * data: brandList, // any[] ← JSON 배열\n * valueKey: 'brandCode', // 필터·선택값으로 사용할 키\n * textKey: 'brandName', // 화면에 표시할 텍스트 키\n * filterKey: 'brand', // 그리드 행 데이터의 필터 기준 키 (기본: field)\n * dependsOn: 'category', // 부모 컬럼 field\n * dependsOnKey: 'catCode', // 자식 data[]에서 부모값과 매칭할 키\n * }\n * ```\n *\n * **B. 정적 옵션 배열**\n * ```ts\n * { field: 'status', options: [{ value: 'Y', text: '활성' }] }\n * ```\n */\nexport interface FilterSelectColumn {\n /** 캐스케이딩 식별자 / 기본 필터 키 */\n field: string;\n /** 화면 표시 라벨 */\n label: string;\n\n // ── A. JSON 배열 바인딩 ──────────────────────────────\n /** 바인딩할 JSON 배열 */\n data?: any[];\n /** data[]에서 option value로 사용할 키 */\n valueKey?: string;\n /** data[]에서 화면 표시 text로 사용할 키 (미지정 시 valueKey 사용) */\n textKey?: string;\n /**\n * 그리드 행 데이터에서 실제 필터링할 키.\n * 미지정 시 `field` 값 그대로 사용.\n *\n * @example\n * // 그리드 row.category === selectedValue 로 필터링\n * filterKey: 'category'\n */\n filterKey?: string;\n\n // ── B. 정적 옵션 (data 대신 사용) ───────────────────\n options?: FilterSelectOption[];\n\n // ── 캐스케이딩 ────────────────────────────────────────\n /** 부모 컬럼의 field 명 */\n dependsOn?: string;\n /**\n * 자식 data[]에서 부모 선택값과 비교할 키.\n *\n * @example\n * // brandList.filter(b => b.catCode === parentSelectedValue)\n * dependsOnKey: 'catCode'\n */\n dependsOnKey?: string;\n}\n\nexport interface FilterSelectConfig {\n columns: FilterSelectColumn[];\n /** fieldset 제목 (기본: '필터') */\n legend?: string;\n}\n\ntype FilterFn = (field: string, items: FilterItem[]) => void;\ntype ResetFn = (field?: string) => void;\n\n// ─── FilterSelectPanel ────────────────────────────────────\nexport class FilterSelectPanel {\n private _el: HTMLFieldSetElement;\n private _selects = new Map<string, HTMLSelectElement>();\n /** 현재 선택 상태 { field → selectedValue } */\n private _selected: Record<string, string> = {};\n private _config: FilterSelectConfig;\n private _onFilter: FilterFn;\n private _onReset: ResetFn;\n\n constructor(\n container: HTMLElement,\n config: FilterSelectConfig,\n onFilter: FilterFn,\n onReset: ResetFn,\n gridId?: string,\n ) {\n this._config = config;\n this._onFilter = onFilter;\n this._onReset = onReset;\n\n /* fieldset */\n this._el = document.createElement('fieldset');\n this._el.className = 'og-filter-select';\n\n const legend = document.createElement('legend');\n legend.className = 'og-filter-select-legend';\n legend.textContent = config.legend ?? '필터';\n this._el.appendChild(legend);\n\n const row = document.createElement('div');\n row.className = 'og-filter-select-row';\n\n for (const col of config.columns) {\n const uid = `og-fsel-${col.field}`;\n\n const wrap = document.createElement('div');\n wrap.className = 'og-filter-select-group';\n\n const label = document.createElement('label');\n label.htmlFor = uid;\n label.textContent = col.label;\n label.className = 'og-filter-select-label';\n\n const select = document.createElement('select');\n select.id = uid;\n select.className = 'og-filter-select-sel';\n select.setAttribute('aria-label', col.label);\n if (gridId) select.setAttribute('aria-controls', gridId);\n\n if (!col.dependsOn) {\n /* 루트 컬럼 — 즉시 전체 옵션 로드 */\n this._fill(select, this._resolve(col, ''), true);\n } else {\n /* 종속 컬럼 — 부모 선택 전까지 비활성 */\n this._fill(select, [], false);\n }\n\n select.addEventListener('change', () => this._onChange(col.field, select.value));\n\n wrap.appendChild(label);\n wrap.appendChild(select);\n row.appendChild(wrap);\n this._selects.set(col.field, select);\n }\n\n /* 초기화 버튼 */\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = '초기화';\n btn.className = 'og-filter-select-reset';\n btn.setAttribute('aria-label', '필터 초기화');\n btn.addEventListener('click', () => this._reset());\n\n this._el.appendChild(row);\n this._el.appendChild(btn);\n\n /* 그리드 헤더 앞에 삽입 */\n container.insertBefore(this._el, container.firstChild);\n }\n\n // ─── 옵션 해결 ────────────────────────────────────────\n /**\n * 컬럼의 옵션 목록을 계산한다.\n *\n * @param col 대상 컬럼 정의\n * @param parentValue 부모 선택값 (캐스케이딩 필터에 사용)\n */\n private _resolve(col: FilterSelectColumn, parentValue: string): FilterSelectOption[] {\n /* B. 정적 옵션 배열 */\n if (col.options) return col.options;\n\n /* A. JSON 배열 + 키 매핑 */\n let rows = col.data ?? [];\n\n /* 캐스케이딩: dependsOnKey 기준으로 부모 선택값과 매칭 */\n if (col.dependsOn && col.dependsOnKey && parentValue) {\n rows = rows.filter(\n item => String(item[col.dependsOnKey!] ?? '') === parentValue,\n );\n }\n\n const vk = col.valueKey ?? 'value';\n const tk = col.textKey ?? vk;\n\n return rows.map(item => ({\n value: String(item[vk] ?? ''),\n text: String(item[tk] ?? item[vk] ?? ''),\n }));\n }\n\n // ─── select DOM 채우기 ────────────────────────────────\n private _fill(\n select: HTMLSelectElement,\n opts: FilterSelectOption[],\n enabled: boolean,\n ): void {\n select.innerHTML = '';\n const all = document.createElement('option');\n all.value = ''; all.textContent = '전체';\n select.appendChild(all);\n for (const o of opts) {\n const el = document.createElement('option');\n el.value = o.value; el.textContent = o.text;\n select.appendChild(el);\n }\n select.disabled = !enabled;\n }\n\n // ─── 선택 변경 처리 ───────────────────────────────────\n private _onChange(field: string, value: string): void {\n const col = this._config.columns.find(c => c.field === field)!;\n const fk = col.filterKey ?? col.field; // 실제 그리드 필터 키\n\n if (value) {\n this._selected[field] = value;\n this._onFilter(fk, [{ operator: '=', value }]);\n } else {\n delete this._selected[field];\n this._onReset(fk);\n }\n this._cascade(field);\n }\n\n /**\n * 부모 컬럼 변경 후 자식 컬럼 옵션을 재계산한다 (재귀).\n */\n private _cascade(parentField: string): void {\n const parentValue = this._selected[parentField] ?? '';\n\n for (const col of this._config.columns) {\n if (col.dependsOn !== parentField) continue;\n const sel = this._selects.get(col.field);\n if (!sel) continue;\n const fk = col.filterKey ?? col.field;\n\n if (!parentValue) {\n /* 부모 초기화 → 자식 비활성 */\n this._fill(sel, [], false);\n delete this._selected[col.field];\n this._onReset(fk);\n this._cascade(col.field); // 하위로 재귀\n } else {\n /* 부모 값 있음 → 자식 옵션 재로드 */\n this._fill(sel, this._resolve(col, parentValue), true);\n sel.value = '';\n delete this._selected[col.field];\n this._onReset(fk);\n }\n }\n }\n\n // ─── 전체 초기화 ──────────────────────────────────────\n private _reset(): void {\n this._selected = {};\n for (const col of this._config.columns) {\n const sel = this._selects.get(col.field);\n const fk = col.filterKey ?? col.field;\n if (!sel) continue;\n if (!col.dependsOn) {\n sel.value = ''; sel.disabled = false;\n } else {\n this._fill(sel, [], false);\n }\n this._onReset(fk);\n }\n }\n\n // ─── 공개 API ─────────────────────────────────────────\n reset(): void { this._reset(); }\n destroy(): void { this._el.remove(); }\n}\n","export interface PageChangeEvent {\n page: number;\n pageSize: number;\n totalRows: number;\n totalPages: number;\n}\n\nexport type PageChangeFn = (e: PageChangeEvent) => void;\n\n/**\n * 그리드 하단 페이지네이션 UI + 상태 관리.\n * DataLayer의 _displayIndexes 슬라이싱을 담당.\n */\nexport class Pagination {\n private _el: HTMLElement;\n private _page = 1;\n private _pageSize: number;\n private _totalRows = 0;\n private _onChange: PageChangeFn;\n\n constructor(container: HTMLElement, pageSize: number, onChange: PageChangeFn) {\n this._pageSize = pageSize;\n this._onChange = onChange;\n\n this._el = document.createElement('div');\n this._el.className = 'og-pagination';\n this._el.style.cssText = `\n display:flex;align-items:center;justify-content:center;gap:4px;\n padding:6px 8px;border-top:1px solid var(--og-border-color,#e0e0e0);\n background:var(--og-header-bg,#f5f5f5);flex-shrink:0;user-select:none;\n font-size:12px;color:var(--og-text-color,#333);\n `;\n container.appendChild(this._el);\n this._render();\n }\n\n get page() { return this._page; }\n get pageSize() { return this._pageSize; }\n get totalPages() { return Math.max(1, Math.ceil(this._totalRows / this._pageSize)); }\n\n /** 전체 행 수 갱신 → 현재 페이지 유효성 검사 후 재렌더 */\n setTotalRows(n: number): void {\n this._totalRows = n;\n if (this._page > this.totalPages) this._page = this.totalPages;\n this._render();\n }\n\n setPageSize(size: number): void {\n this._pageSize = size;\n this._page = 1;\n this._render();\n this._emit();\n }\n\n goTo(page: number): void {\n const p = Math.max(1, Math.min(page, this.totalPages));\n if (p === this._page) return;\n this._page = p;\n this._render();\n this._emit();\n }\n\n /** 현재 페이지의 [startIndex, endIndex] 반환 (DataLayer 인덱스 기준) */\n getRange(): { start: number; end: number } {\n const start = (this._page - 1) * this._pageSize;\n const end = Math.min(start + this._pageSize - 1, this._totalRows - 1);\n return { start, end };\n }\n\n private _emit(): void {\n this._onChange({\n page: this._page, pageSize: this._pageSize,\n totalRows: this._totalRows, totalPages: this.totalPages,\n });\n }\n\n private _render(): void {\n this._el.innerHTML = '';\n const total = this.totalPages;\n\n // 페이지 크기 선택\n const sizeWrap = document.createElement('span');\n sizeWrap.style.cssText = 'display:flex;align-items:center;gap:3px;margin-right:8px;';\n const sizeLabel = document.createElement('span');\n sizeLabel.textContent = '행/페이지:';\n sizeLabel.style.color = '#888';\n const sizeSel = document.createElement('select');\n sizeSel.style.cssText = `padding:2px 4px;border:1px solid var(--og-border-color,#e0e0e0);border-radius:3px;font-size:11px;cursor:pointer;`;\n for (const s of [10, 20, 50, 100, 200]) {\n const opt = document.createElement('option');\n opt.value = String(s);\n opt.textContent = String(s);\n if (s === this._pageSize) opt.selected = true;\n sizeSel.appendChild(opt);\n }\n sizeSel.addEventListener('change', () => this.setPageSize(Number(sizeSel.value)));\n sizeWrap.appendChild(sizeLabel);\n sizeWrap.appendChild(sizeSel);\n this._el.appendChild(sizeWrap);\n\n // 총 행 수\n const info = document.createElement('span');\n const { start, end } = this.getRange();\n info.textContent = this._totalRows > 0\n ? `${start + 1}–${end + 1} / ${this._totalRows}건`\n : '0건';\n info.style.cssText = 'margin-right:8px;color:#888;';\n this._el.appendChild(info);\n\n // 이전/다음 버튼 + 페이지 번호\n const mkBtn = (label: string, page: number, disabled: boolean) => {\n const btn = document.createElement('button');\n btn.textContent = label;\n btn.disabled = disabled;\n btn.style.cssText = `\n min-width:28px;height:24px;padding:0 6px;\n border:1px solid var(--og-border-color,#e0e0e0);border-radius:3px;\n background:${disabled ? '#f5f5f5' : '#fff'};\n color:${disabled ? '#bbb' : 'var(--og-text-color,#333)'};\n cursor:${disabled ? 'default' : 'pointer'};font-size:12px;\n `;\n if (!disabled) btn.addEventListener('click', () => this.goTo(page));\n return btn;\n };\n\n this._el.appendChild(mkBtn('«', 1, this._page === 1));\n this._el.appendChild(mkBtn('‹', this._page - 1, this._page === 1));\n\n // 페이지 번호 (최대 5개 표시)\n const range = _pageRange(this._page, total);\n for (const p of range) {\n if (p === -1) {\n const dot = document.createElement('span');\n dot.textContent = '…';\n dot.style.padding = '0 3px';\n this._el.appendChild(dot);\n } else {\n const btn = mkBtn(String(p), p, p === this._page);\n if (p === this._page) {\n btn.style.background = 'var(--og-primary,#1976d2)';\n btn.style.color = '#fff';\n btn.style.borderColor = 'var(--og-primary,#1976d2)';\n }\n this._el.appendChild(btn);\n }\n }\n\n this._el.appendChild(mkBtn('›', this._page + 1, this._page === total));\n this._el.appendChild(mkBtn('»', total, this._page === total));\n }\n\n destroy(): void {\n this._el.remove();\n }\n}\n\n/** 현재 페이지 기준 표시할 페이지 번호 배열 (-1 = ellipsis) */\nfunction _pageRange(current: number, total: number): number[] {\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);\n const pages: number[] = [1];\n if (current > 3) pages.push(-1);\n for (let p = Math.max(2, current - 1); p <= Math.min(total - 1, current + 1); p++) {\n pages.push(p);\n }\n if (current < total - 2) pages.push(-1);\n pages.push(total);\n return pages;\n}\n","export type RowDropCallback = (fromIndex: number, toIndex: number) => void;\n\ninterface DragState {\n fromIndex: number;\n startY: number;\n ghostEl: HTMLElement;\n indicator: HTMLElement;\n rowHeight: number;\n totalRows: number;\n bodyEl: HTMLElement;\n currentTarget: number;\n}\n\n/**\n * 행 드래그앤드롭 관리자.\n * 행 DOM에 드래그 핸들을 심고, 드롭 위치를 표시한 뒤 콜백으로 알림.\n */\nexport class RowDragDrop {\n private _drag: DragState | null = null;\n private _onDrop: RowDropCallback;\n private _bodyEl: HTMLElement;\n private _rowHeight: number;\n\n constructor(bodyEl: HTMLElement, rowHeight: number, onDrop: RowDropCallback) {\n this._bodyEl = bodyEl;\n this._rowHeight = rowHeight;\n this._onDrop = onDrop;\n\n this._onMouseMove = this._onMouseMove.bind(this);\n this._onMouseUp = this._onMouseUp.bind(this);\n }\n\n /** 행 엘리먼트에 드래그 핸들 삽입 */\n attachHandle(rowEl: HTMLElement, rowIndex: number, totalRows: number): HTMLElement {\n const handle = document.createElement('div');\n handle.className = 'og-drag-handle';\n handle.innerHTML = '⠿';\n handle.style.cssText = `\n width:18px;min-width:18px;height:100%;\n display:flex;align-items:center;justify-content:center;\n cursor:grab;font-size:14px;color:#bbb;flex-shrink:0;\n user-select:none;border-right:1px solid var(--og-border-color,#e0e0e0);\n `;\n handle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this._startDrag(e, rowEl, rowIndex, totalRows);\n });\n return handle;\n }\n\n private _startDrag(e: MouseEvent, rowEl: HTMLElement, fromIndex: number, totalRows: number): void {\n // 고스트 행 생성\n const rect = rowEl.getBoundingClientRect();\n const ghost = document.createElement('div');\n ghost.style.cssText = `\n position:fixed;left:${rect.left}px;top:${rect.top}px;\n width:${rect.width}px;height:${rect.height}px;\n background:rgba(25,118,210,0.12);border:2px dashed #1976d2;\n box-sizing:border-box;pointer-events:none;z-index:9999;\n border-radius:2px;opacity:0.9;\n `;\n document.body.appendChild(ghost);\n\n // 드롭 위치 인디케이터\n const indicator = document.createElement('div');\n indicator.style.cssText = `\n position:absolute;left:0;right:0;height:2px;\n background:#1976d2;pointer-events:none;z-index:9998;display:none;\n `;\n this._bodyEl.appendChild(indicator);\n\n this._drag = {\n fromIndex, startY: e.clientY,\n ghostEl: ghost, indicator,\n rowHeight: this._rowHeight,\n totalRows, bodyEl: this._bodyEl,\n currentTarget: fromIndex,\n };\n\n document.addEventListener('mousemove', this._onMouseMove);\n document.addEventListener('mouseup', this._onMouseUp);\n }\n\n private _onMouseMove(e: MouseEvent): void {\n if (!this._drag) return;\n const d = this._drag;\n\n // 고스트 이동\n const dy = e.clientY - d.startY;\n const ghostRect = d.ghostEl.getBoundingClientRect();\n d.ghostEl.style.top = `${ghostRect.top + dy}px`;\n d.startY = e.clientY;\n\n // 드롭 목표 행 계산\n const bodyRect = d.bodyEl.getBoundingClientRect();\n const relY = e.clientY - bodyRect.top + d.bodyEl.scrollTop;\n const targetIdx = Math.max(0, Math.min(d.totalRows - 1, Math.round(relY / d.rowHeight)));\n\n d.currentTarget = targetIdx;\n\n // 인디케이터 위치\n const indicatorY = targetIdx * d.rowHeight;\n d.indicator.style.display = 'block';\n d.indicator.style.top = `${indicatorY}px`;\n }\n\n private _onMouseUp(_e: MouseEvent): void {\n document.removeEventListener('mousemove', this._onMouseMove);\n document.removeEventListener('mouseup', this._onMouseUp);\n\n if (!this._drag) return;\n const { fromIndex, currentTarget, ghostEl, indicator } = this._drag;\n this._drag = null;\n\n ghostEl.remove();\n indicator.remove();\n\n if (fromIndex !== currentTarget) {\n this._onDrop(fromIndex, currentTarget);\n }\n }\n\n destroy(): void {\n document.removeEventListener('mousemove', this._onMouseMove);\n document.removeEventListener('mouseup', this._onMouseUp);\n this._drag?.ghostEl.remove();\n this._drag?.indicator.remove();\n this._drag = null;\n }\n}\n","/**\n * 셀 병합 관리 엔진.\n *\n * 두 가지 병합 방식 지원:\n * 1. 동적 병합: mergeCells([{row, col, rowSpan, colSpan}])\n * 2. 자동 병합: 같은 필드에 같은 값이 연속되면 자동으로 rowSpan\n */\n\nexport interface MergeCell {\n row: number; // display row index (0-based)\n col: number; // leaf column index (0-based)\n rowSpan?: number; // 1 이상 (기본 1)\n colSpan?: number; // 1 이상 (기본 1)\n}\n\nexport interface MergeInfo {\n rowSpan: number;\n colSpan: number;\n hidden: boolean; // 병합으로 숨겨진 셀 (렌더링 생략)\n}\n\nexport class MergeEngine {\n // (row, col) → MergeInfo\n private _map: Map<string, MergeInfo> = new Map();\n\n private static _key(row: number, col: number): string {\n return `${row}:${col}`;\n }\n\n /** 수동 병합 정의 목록으로 맵 구성 */\n applyMergeCells(cells: MergeCell[]): void {\n this._map.clear();\n for (const mc of cells) {\n const rs = Math.max(1, mc.rowSpan ?? 1);\n const cs = Math.max(1, mc.colSpan ?? 1);\n // 기준 셀\n this._map.set(MergeEngine._key(mc.row, mc.col), {\n rowSpan: rs, colSpan: cs, hidden: false,\n });\n // 병합된 하위 셀 — hidden:true\n for (let r = 0; r < rs; r++) {\n for (let c = 0; c < cs; c++) {\n if (r === 0 && c === 0) continue;\n this._map.set(MergeEngine._key(mc.row + r, mc.col + c), {\n rowSpan: 1, colSpan: 1, hidden: true,\n });\n }\n }\n }\n }\n\n /**\n * 자동 병합: 지정 컬럼 인덱스 목록에 대해 연속 같은 값을 rowSpan으로 병합.\n * data: 현재 표시 순서의 행 배열, colIndexes: 자동병합할 leaf 컬럼 인덱스\n * fields: colIndexes[i] 에 대응하는 field 이름\n */\n applyAutoMerge(\n data: Record<string, any>[],\n colIndexes: number[],\n fields: string[]\n ): void {\n this._map.clear();\n for (let ci = 0; ci < colIndexes.length; ci++) {\n const col = colIndexes[ci]!;\n const field = fields[ci]!;\n let spanStart = 0;\n\n for (let ri = 1; ri <= data.length; ri++) {\n const prevVal = data[ri - 1]?.[field];\n const curVal = ri < data.length ? data[ri]?.[field] : undefined;\n\n if (ri === data.length || curVal !== prevVal) {\n const span = ri - spanStart;\n if (span > 1) {\n this._map.set(MergeEngine._key(spanStart, col), {\n rowSpan: span, colSpan: 1, hidden: false,\n });\n for (let r = spanStart + 1; r < ri; r++) {\n this._map.set(MergeEngine._key(r, col), {\n rowSpan: 1, colSpan: 1, hidden: true,\n });\n }\n }\n spanStart = ri;\n }\n }\n }\n }\n\n /** 셀 병합 정보 조회. 없으면 null */\n getInfo(row: number, col: number): MergeInfo | null {\n return this._map.get(MergeEngine._key(row, col)) ?? null;\n }\n\n /** 병합 맵 초기화 */\n clear(): void {\n this._map.clear();\n }\n\n get isEmpty(): boolean {\n return this._map.size === 0;\n }\n}\n","// ============================================================\n// ContextMenu — 우클릭 팝업 컨텍스트 메뉴 관리자\n// 레이어: Orchestration (UI 생성 + 이벤트 조율)\n// 설계 근거(Why): 메뉴를 document.body가 아닌 그리드 컨테이너(_anchor)의\n// 자식으로 추가한다. position:fixed로 뷰포트 기준 배치를 유지하면서\n// CSS 변수(--og-*)를 컨테이너에서 자동 상속 → 테마 즉시 반영.\n// ============================================================\n\nimport type { ContextMenuItem } from './types.js';\n\nexport type { ContextMenuItem };\n\nexport interface ContextMenuActions {\n onSortAsc: () => void;\n onSortDesc: () => void;\n onFind: () => void;\n onExcel: () => void;\n onCsv: () => void;\n onPrint: () => void;\n}\n\nexport const DEFAULT_CONTEXT_ITEMS: ContextMenuItem[] = [\n { id: 'sort-asc', label: '오름차순 정렬', icon: '↑', action: 'sortAsc' },\n { id: 'sort-desc', label: '내림차순 정렬', icon: '↓', action: 'sortDesc' },\n { type: 'divider' },\n { id: 'find', label: '찾기', icon: '🔍', action: 'find' },\n { type: 'divider' },\n { id: 'excel', label: 'Excel로 저장', icon: '📊', action: 'excel' },\n { id: 'csv', label: 'CSV로 저장', icon: '📄', action: 'csv' },\n { id: 'print', label: '인쇄', icon: '🖨', action: 'print' },\n];\n\nexport class ContextMenuManager {\n private _el: HTMLElement | null = null;\n private _docClick: ((e: MouseEvent) => void) | null = null;\n private _docKey: ((e: KeyboardEvent) => void) | null = null;\n private _docScroll: (() => void) | null = null;\n private _docMouseMove: ((e: MouseEvent) => void) | null = null;\n private _focusIdx = -1;\n\n /**\n * @param _anchor 그리드 컨테이너 엘리먼트 — CSS 변수 상속 기준점\n * @param _actions 기본 액션 핸들러 (OpenGrid에서 주입)\n */\n constructor(\n private readonly _anchor: HTMLElement,\n private readonly _actions: ContextMenuActions,\n ) {}\n\n open(e: MouseEvent, customItems?: ContextMenuItem[]): void {\n this.close();\n\n const items = customItems ?? DEFAULT_CONTEXT_ITEMS;\n const menu = document.createElement('div');\n menu.className = 'og-context-menu';\n menu.setAttribute('role', 'menu');\n\n for (const item of items) {\n if (item.type === 'divider') {\n const hr = document.createElement('div');\n hr.className = 'og-cm-divider';\n hr.setAttribute('role', 'separator');\n menu.appendChild(hr);\n continue;\n }\n\n const btn = document.createElement('button');\n btn.className = 'og-cm-item';\n btn.setAttribute('role', 'menuitem');\n btn.setAttribute('tabindex', '-1');\n if (item.disabled) {\n btn.classList.add('og-cm-disabled');\n btn.setAttribute('aria-disabled', 'true');\n }\n\n if (item.icon) {\n const ic = document.createElement('span');\n ic.className = 'og-cm-icon';\n // CSS 클래스명(예: 'bi bi-star', 'fa fa-home')이면 <i> 태그로 렌더링\n // 이모지·특수문자·단일 기호면 textContent로 처리\n if (/^[a-zA-Z][\\w-]*(\\s+[\\w-]+)+$/.test(item.icon.trim())) {\n const i = document.createElement('i');\n i.className = item.icon;\n ic.appendChild(i);\n } else {\n ic.textContent = item.icon;\n }\n ic.setAttribute('aria-hidden', 'true');\n btn.appendChild(ic);\n }\n\n const lbl = document.createElement('span');\n lbl.className = 'og-cm-label';\n lbl.textContent = item.label ?? '';\n btn.appendChild(lbl);\n\n btn.addEventListener('click', (ev) => {\n ev.stopPropagation();\n if (!item.disabled) this._runAction(item);\n this.close();\n });\n menu.appendChild(btn);\n }\n\n // document.body 자식으로 추가 → position:fixed 가 항상 뷰포트 기준으로 동작.\n // Why: 그리드 컨테이너(_anchor)에 붙이면, 임베드 호스트(WordPress 글 등)의\n // 조상에 transform/filter 가 있을 때 fixed 기준점이 그 조상으로 바뀌어\n // 메뉴가 마우스 좌표에서 어긋난다(특히 그리드 너비를 넓힐 때). body 부착으로 회피.\n // 테마 CSS 변수(--og-cm-*, --og-*)는 menu 에 data-og-theme 를 복사해 보존한다.\n const themeEl = this._anchor.closest('[data-og-theme]') as HTMLElement | null;\n const theme = themeEl?.getAttribute('data-og-theme');\n if (theme) menu.setAttribute('data-og-theme', theme);\n document.body.appendChild(menu);\n this._el = menu;\n\n // mousemove capture 단계로 등록 — 셀의 stopPropagation() 우회\n // Why: 그리드 셀이 mousemove에 stopPropagation()을 호출해 bubble 단계 document 리스너가 차단됨\n this._docMouseMove = (ev) => {\n if (!this._el) return;\n const r = this._el.getBoundingClientRect();\n if (ev.clientX < r.left - 4 || ev.clientX > r.right + 4 ||\n ev.clientY < r.top - 4 || ev.clientY > r.bottom + 4) {\n this.close();\n }\n };\n\n // position:fixed 기준 좌표 설정 → 포지셔닝 완료 후 올바른 bounds로 리스너 등록\n this._position(menu, e.clientX, e.clientY, () => {\n if (this._el === menu) {\n document.addEventListener('mousemove', this._docMouseMove!, { capture: true, passive: true });\n }\n });\n\n // 외부 클릭 닫기 (다음 틱 — 현재 contextmenu 이벤트 전파 완료 후)\n this._docClick = (ev) => {\n if (!menu.contains(ev.target as Node)) this.close();\n };\n // 키보드 접근성\n this._docKey = (ev) => {\n if (ev.key === 'Escape') { this.close(); return; }\n if (ev.key === 'ArrowDown') { ev.preventDefault(); this._moveFocus(1); return; }\n if (ev.key === 'ArrowUp') { ev.preventDefault(); this._moveFocus(-1); return; }\n if (ev.key === 'Enter') {\n const focused = menu.querySelector<HTMLButtonElement>('.og-cm-item:focus');\n focused?.click();\n }\n };\n this._docScroll = () => this.close();\n\n setTimeout(() => {\n document.addEventListener('click', this._docClick!);\n document.addEventListener('keydown', this._docKey!);\n window.addEventListener('scroll', this._docScroll!, { passive: true });\n }, 0);\n\n // 첫 활성 항목에 포커스\n this._focusIdx = -1;\n this._moveFocus(1);\n }\n\n close(): void {\n this._el?.remove();\n this._el = null;\n if (this._docClick) document.removeEventListener('click', this._docClick);\n if (this._docKey) document.removeEventListener('keydown', this._docKey);\n if (this._docScroll) window.removeEventListener('scroll', this._docScroll);\n if (this._docMouseMove) document.removeEventListener('mousemove', this._docMouseMove, { capture: true });\n this._docClick = this._docKey = this._docScroll = this._docMouseMove = null;\n this._focusIdx = -1;\n }\n\n destroy(): void { this.close(); }\n\n // ── 위치 결정 ─────────────────────────────────────────────\n\n private _position(menu: HTMLElement, x: number, y: number, onPositioned?: () => void): void {\n menu.style.cssText = 'position:fixed;visibility:hidden;left:0;top:0;';\n\n requestAnimationFrame(() => {\n const { width, height } = menu.getBoundingClientRect();\n const vw = window.innerWidth, vh = window.innerHeight;\n const left = x + width > vw ? Math.max(0, x - width) : x;\n const top = y + height > vh ? Math.max(0, y - height) : y;\n menu.style.cssText = `position:fixed;left:${left}px;top:${top}px;z-index:9999;`;\n // 포지셔닝 완료 후 콜백 — mousemove 체크는 정확한 위치 기준으로만 동작\n onPositioned?.();\n });\n }\n\n // ── 키보드 포커스 이동 ────────────────────────────────────\n\n private _moveFocus(dir: 1 | -1): void {\n if (!this._el) return;\n const btns = Array.from(\n this._el.querySelectorAll<HTMLButtonElement>('.og-cm-item:not(.og-cm-disabled)')\n );\n if (!btns.length) return;\n this._focusIdx = (this._focusIdx + dir + btns.length) % btns.length;\n btns[this._focusIdx]?.focus();\n }\n\n // ── 액션 실행 ─────────────────────────────────────────────\n\n private _runAction(item: ContextMenuItem): void {\n if (typeof item.action === 'function') { item.action(); return; }\n switch (item.action) {\n case 'sortAsc': this._actions.onSortAsc(); break;\n case 'sortDesc': this._actions.onSortDesc(); break;\n case 'find': this._actions.onFind(); break;\n case 'excel': this._actions.onExcel(); break;\n case 'csv': this._actions.onCsv(); break;\n case 'print': this._actions.onPrint(); break;\n }\n }\n}\n","// ============================================================\n// WorksheetManager — 그리드 다중 워크시트(탭) 관리자\n// 레이어: Orchestration (시트 상태 관리 + 탭 UI 조율)\n// 설계 근거(Why): OpenGrid 내부에 _wsManager로 보유.\n// 시트별로 독립적인 columns + data를 Map으로 관리하고,\n// 탭 클릭 시 OpenGrid.setData/applyColumns로 화면 전환.\n// 탭 UI는 그리드 컨테이너 하단에 .og-sheet-tabs 영역으로 삽입.\n// ============================================================\n\nimport type { ColumnDef, WorksheetDef, WorksheetState } from './types.js';\n\nexport type SwitchCallback<T> = (name: string, state: WorksheetState<T>) => void;\n\nexport class WorksheetManager<T extends Record<string, any> = any> {\n private _sheets: Map<string, WorksheetState<T>> = new Map();\n private _active: string = '';\n private _tabBar: HTMLElement;\n private _onSwitch: SwitchCallback<T>;\n\n constructor(container: HTMLElement, onSwitch: SwitchCallback<T>) {\n this._onSwitch = onSwitch;\n this._tabBar = this._buildTabBar(container);\n }\n\n // ── 시트 CRUD ────────────────────────────────────────────\n\n add(name: string, columns: ColumnDef<T>[] = [], data: T[] = []): void {\n if (this._sheets.has(name)) {\n throw new Error(`WorksheetManager: 시트 '${name}'이 이미 존재합니다`);\n }\n this._sheets.set(name, { name, columns, data });\n this._renderTabs();\n\n // 첫 시트는 자동 활성\n if (this._sheets.size === 1) this.switch(name);\n }\n\n remove(name: string): void {\n if (!this._sheets.has(name)) return;\n if (this._sheets.size === 1) {\n throw new Error('WorksheetManager: 마지막 시트는 삭제할 수 없습니다');\n }\n const wasActive = this._active === name;\n this._sheets.delete(name);\n this._renderTabs();\n\n if (wasActive) {\n // 삭제 후 첫 번째 남은 시트로 전환\n this.switch(this._sheets.keys().next().value!);\n }\n }\n\n rename(oldName: string, newName: string): void {\n if (!this._sheets.has(oldName)) return;\n if (this._sheets.has(newName)) {\n throw new Error(`WorksheetManager: 시트 '${newName}'이 이미 존재합니다`);\n }\n const state = this._sheets.get(oldName)!;\n // Map 순서 유지를 위해 재삽입\n const entries = Array.from(this._sheets.entries()).map(([k, v]) =>\n k === oldName ? [newName, { ...v, name: newName }] as [string, WorksheetState<T>] : [k, v] as [string, WorksheetState<T>]\n );\n this._sheets = new Map(entries);\n if (this._active === oldName) this._active = newName;\n this._renderTabs();\n }\n\n switch(name: string): void {\n const state = this._sheets.get(name);\n if (!state) throw new Error(`WorksheetManager: 시트 '${name}'을 찾을 수 없습니다`);\n this._active = name;\n this._renderTabs();\n this._onSwitch(name, state);\n }\n\n get(name: string): WorksheetState<T> | undefined {\n return this._sheets.get(name);\n }\n\n getNames(): string[] {\n return Array.from(this._sheets.keys());\n }\n\n getActive(): string { return this._active; }\n\n /** 현재 활성 시트의 data를 갱신 (그리드 편집 동기화용) */\n syncData(name: string, data: T[]): void {\n const state = this._sheets.get(name);\n if (state) state.data = data;\n }\n\n destroy(): void {\n this._tabBar.remove();\n }\n\n // ── 탭 UI ────────────────────────────────────────────────\n\n private _buildTabBar(container: HTMLElement): HTMLElement {\n const bar = document.createElement('div');\n bar.className = 'og-sheet-tabs';\n container.appendChild(bar);\n return bar;\n }\n\n private _renderTabs(): void {\n this._tabBar.innerHTML = '';\n\n for (const name of this._sheets.keys()) {\n const tab = document.createElement('button');\n tab.className = 'og-sheet-tab';\n tab.textContent = name;\n tab.setAttribute('role', 'tab');\n tab.setAttribute('aria-selected', name === this._active ? 'true' : 'false');\n if (name === this._active) tab.classList.add('og-sheet-tab--active');\n\n // 단순 클릭: 시트 전환\n tab.addEventListener('click', () => {\n if (name !== this._active) this.switch(name);\n });\n\n // 더블클릭: 인라인 이름 변경\n tab.addEventListener('dblclick', () => this._startRename(tab, name));\n\n this._tabBar.appendChild(tab);\n }\n\n // '+' 새 시트 버튼\n const addBtn = document.createElement('button');\n addBtn.className = 'og-sheet-add';\n addBtn.textContent = '+';\n addBtn.setAttribute('aria-label', '새 워크시트 추가');\n addBtn.addEventListener('click', () => {\n const n = `Sheet${this._sheets.size + 1}`;\n this.add(n, [], []);\n this.switch(n);\n });\n this._tabBar.appendChild(addBtn);\n }\n\n /** 탭 더블클릭 → input으로 전환해 이름 변경 */\n private _startRename(tab: HTMLButtonElement, oldName: string): void {\n const input = document.createElement('input');\n input.className = 'og-sheet-tab-rename';\n input.value = oldName;\n tab.replaceWith(input);\n input.focus();\n input.select();\n\n const commit = () => {\n const newName = input.value.trim() || oldName;\n try {\n if (newName !== oldName) this.rename(oldName, newName);\n else this._renderTabs();\n } catch {\n this._renderTabs();\n }\n };\n\n input.addEventListener('blur', commit);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') { input.blur(); }\n if (e.key === 'Escape') { input.value = oldName; input.blur(); }\n });\n }\n}\n","import { ColumnLayout } from './ColumnLayout.js';\nimport { _downloadText } from './GridRenderer.js';\nimport { applyMask } from './MaskingEngine.js';\nimport type { WorksheetManager } from './WorksheetManager.js';\nimport type { ExportOptions } from './types.js';\n\nexport interface ExportDeps<T extends Record<string, any>> {\n getData: () => T[];\n getColLayout: () => ColumnLayout<T>;\n getColWidths: () => number[];\n getOptions: () => any;\n getContainer: () => HTMLElement;\n getMaskEnabled: (field: string) => boolean;\n getWsManager: () => WorksheetManager<T> | null;\n}\n\nexport class ExportManager<T extends Record<string, any> = any> {\n private _d: ExportDeps<T>;\n\n constructor(deps: ExportDeps<T>) {\n this._d = deps;\n }\n\n private _readCssVar(name: string): string {\n return getComputedStyle(this._d.getContainer()).getPropertyValue(name).trim();\n }\n\n private _hexToXlsxRgb(hex: string): string {\n const s = hex.trim();\n const rgbMatch = s.match(/^rgba?\\(\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)/i);\n if (rgbMatch) {\n return [rgbMatch[1], rgbMatch[2], rgbMatch[3]]\n .map(n => parseInt(n).toString(16).padStart(2, '0'))\n .join('').toUpperCase();\n }\n const h = s.replace('#', '').toUpperCase();\n if (h.length === 3) return h[0]+h[0]+h[1]+h[1]+h[2]+h[2];\n return h.length === 6 ? h : '';\n }\n\n exportExcel(options?: ExportOptions | string): void {\n const opts = typeof options === 'string' ? { filename: options } : (options ?? {});\n let fname = opts.filename ?? 'export';\n if (!fname.toLowerCase().endsWith('.xlsx')) fname += '.xlsx';\n const sheetName = opts.sheetName ?? (this._d.getOptions().ariaLabel || 'Sheet1');\n const data = this._d.getData();\n const cols = this._d.getColLayout().visibleLeaves.filter(c => !opts.exceptFields?.includes(c.field));\n const includeHeader = opts.includeHeader !== false;\n\n import('xlsx-js-style').then(({ utils, writeFile }) => {\n const rows: any[][] = [];\n if (includeHeader) rows.push(cols.map(c => c.header));\n for (const row of data) {\n rows.push(cols.map(c => {\n const raw = (row as any)[c.field];\n if (opts.maskOnExport && c.mask && this._d.getMaskEnabled(c.field)) {\n return applyMask(raw == null ? '' : String(raw), c.mask);\n }\n const v = raw;\n if (v == null || v === '') return '';\n if (c.type === 'number' && typeof v === 'number') return v;\n if (typeof v === 'boolean') return v ? '✓' : '';\n if (typeof v === 'object') return '';\n return String(v);\n }));\n }\n\n const ws = utils.aoa_to_sheet(rows);\n\n const colWidths = this._d.getColWidths();\n const colLayout = this._d.getColLayout();\n ws['!cols'] = cols.map(c => ({\n wpx: colWidths[colLayout.getColumnIndex(c.field)] ?? 100,\n }));\n ws['!rows'] = rows.map((_, ri) => ({ hpx: ri === 0 && includeHeader ? 22 : 19 }));\n\n const styleMode = opts.styleMode ?? 'theme';\n let hdrBgRgb = '1565C0', hdrFgRgb = 'FFFFFF';\n let rowBgRgb = 'FFFFFF', rowAltRgb = 'EEF2FF';\n let rowFgRgb = '212121', borderRgb = 'BDBDBD';\n let fontSize = 10;\n\n if (styleMode === 'theme') {\n const toRgb = (v: string) => this._hexToXlsxRgb(v);\n hdrBgRgb = toRgb(this._readCssVar('--og-header-bg')) || hdrBgRgb;\n hdrFgRgb = toRgb(this._readCssVar('--og-header-color')) || hdrFgRgb;\n rowBgRgb = toRgb(this._readCssVar('--og-row-bg')) || rowBgRgb;\n rowAltRgb = toRgb(this._readCssVar('--og-row-alt-bg')) || rowAltRgb;\n rowFgRgb = toRgb(this._readCssVar('--og-row-color')) || rowFgRgb;\n borderRgb = toRgb(this._readCssVar('--og-border-color')) || borderRgb;\n const fsStr = this._readCssVar('--og-font-size');\n if (fsStr) fontSize = Math.max(8, Math.round(parseFloat(fsStr) * 0.75));\n }\n\n const noStyle = styleMode === 'none';\n const S = {\n hdrFont: noStyle ? {} : { bold: true, color: { rgb: hdrFgRgb }, sz: fontSize, name: '맑은 고딕' },\n dataFont: noStyle ? {} : { sz: fontSize, color: { rgb: rowFgRgb }, name: '맑은 고딕' },\n hdrFill: noStyle ? {} : { patternType: 'solid' as const, fgColor: { rgb: hdrBgRgb } },\n evenFill: noStyle ? {} : { patternType: 'solid' as const, fgColor: { rgb: rowBgRgb } },\n oddFill: noStyle ? {} : { patternType: 'solid' as const, fgColor: { rgb: rowAltRgb } },\n hdrBorder: noStyle ? {} : {\n top: { style: 'medium', color: { rgb: hdrBgRgb } },\n bottom: { style: 'medium', color: { rgb: hdrBgRgb } },\n left: { style: 'thin', color: { rgb: hdrBgRgb } },\n right: { style: 'thin', color: { rgb: hdrBgRgb } },\n },\n dataBorder: noStyle ? {} : {\n top: { style: 'thin', color: { rgb: borderRgb } },\n bottom: { style: 'thin', color: { rgb: borderRgb } },\n left: { style: 'thin', color: { rgb: borderRgb } },\n right: { style: 'thin', color: { rgb: borderRgb } },\n },\n };\n\n rows.forEach((row, ri) => {\n const isHdr = includeHeader && ri === 0;\n const dataRi = includeHeader ? ri - 1 : ri;\n const isEven = dataRi % 2 === 0;\n\n row.forEach((_v, ci) => {\n const addr = utils.encode_cell({ r: ri, c: ci });\n if (!ws[addr]) ws[addr] = { t: 's', v: '' };\n\n const col = cols[ci]!;\n const isNum = col.type === 'number' || col.align === 'right';\n const hAlign = isHdr ? 'center' : isNum ? 'right' : (col.align ?? 'left');\n\n ws[addr].s = {\n font: isHdr ? S.hdrFont : S.dataFont,\n fill: isHdr ? S.hdrFill : (isEven ? S.evenFill : S.oddFill),\n border: isHdr ? S.hdrBorder : S.dataBorder,\n alignment: { horizontal: hAlign, vertical: 'center', wrapText: false },\n };\n });\n });\n\n const wb = utils.book_new();\n utils.book_append_sheet(wb, ws, sheetName);\n writeFile(wb, fname, { cellStyles: true } as any);\n opts.onAfter?.(new Blob([]));\n }).catch(() => {\n console.error('Excel 내보내기 실패: xlsx 패키지를 확인하세요.');\n });\n }\n\n exportCsv(options?: ExportOptions | string): void {\n const opts = typeof options === 'string' ? { filename: options } : (options ?? {});\n const data = this._d.getData();\n const cols = this._d.getColLayout().visibleLeaves;\n const hdr = cols.map(c => `\"${c.header}\"`).join(',');\n const rows = data.map(row => cols.map(c => {\n const raw = row[c.field] ?? '';\n if (opts.maskOnExport && c.mask && this._d.getMaskEnabled(c.field)) {\n return applyMask(String(raw), c.mask);\n }\n const v = raw;\n return typeof v === 'string' && v.includes(',') ? `\"${v}\"` : v;\n }).join(','));\n const fname = opts.filename ?? 'export.csv';\n _downloadText('' + [hdr, ...rows].join('\\n'), fname);\n }\n\n exportJson(options?: ExportOptions | string): void {\n const fname = typeof options === 'string' ? options : (options?.filename ?? 'export.json');\n _downloadText(JSON.stringify(this._d.getData(), null, 2), fname, 'application/json');\n }\n\n print(options?: { title?: string; excludeFields?: string[]; footerText?: string }): void {\n const title = options?.title ?? 'OPEN_GRID';\n const footerText = options?.footerText ?? '';\n const data = this._d.getData();\n const cols = this._d.getColLayout().visibleLeaves\n .filter(c => !options?.excludeFields?.includes(c.field));\n\n const headerRow = cols.map(c => `<th>${c.header ?? c.field}</th>`).join('');\n const bodyRows = data.map(row =>\n `<tr>${cols.map(c => `<td>${String(row[c.field] ?? '')}</td>`).join('')}</tr>`\n ).join('');\n const footerHtml = footerText\n ? `<div class=\"og-print-footer\">${footerText}</div>`\n : '';\n\n const html = `<!DOCTYPE html>\n<html lang=\"ko\"><head>\n<meta charset=\"UTF-8\"><title>${title}</title>\n<style>\n @page{margin:0;}\n body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:12px;margin:0;padding:1cm;}\n h2{margin:0 0 10px;font-size:14px;color:#333;}\n p{margin:0 0 8px;font-size:11px;color:#999;}\n table{border-collapse:collapse;width:100%;}\n th,td{border:1px solid #ccc;padding:5px 8px;text-align:left;white-space:nowrap;}\n th{background:#f5f5f5;font-weight:600;color:#333;}\n tr:nth-child(even) td{background:#fafafa;}\n .og-print-footer{position:fixed;bottom:0;left:0;right:0;padding:6px 1cm;font-size:10px;color:#888;border-top:1px solid #e5e7eb;background:#fff;text-align:center;}\n</style>\n</head><body>\n<h2>${title}</h2>\n<p>${data.length}행 × ${cols.length}열 · ${new Date().toLocaleString('ko-KR')}</p>\n<table>\n <thead><tr>${headerRow}</tr></thead>\n <tbody>${bodyRows}</tbody>\n</table>\n${footerHtml}\n<script>window.addEventListener('load',()=>{window.print();window.addEventListener('afterprint',()=>window.close());});<\\/script>\n</body></html>`;\n\n const win = window.open('', '_blank', 'width=960,height=640');\n if (win) { win.document.write(html); win.document.close(); }\n }\n\n exportSheetsExcel(filename?: string): void {\n const wsManager = this._d.getWsManager();\n if (!wsManager) { this.exportExcel(filename ?? 'workbook'); return; }\n const fname = filename ?? 'workbook.xlsx';\n\n import('xlsx-js-style').then(({ utils, writeFile }) => {\n const wb = utils.book_new();\n const opts = this._d.getOptions();\n for (const name of wsManager.getNames()) {\n const state = wsManager.get(name)!;\n const cols = state.columns.length ? state.columns : opts.columns;\n const rows: any[][] = [cols.map((c: any) => c.header)];\n for (const row of state.data) {\n rows.push(cols.map((c: any) => {\n const v = (row as any)[c.field];\n if (v == null) return '';\n if (typeof v === 'boolean') return v ? '✓' : '';\n return c.type === 'number' && typeof v === 'number' ? v : String(v);\n }));\n }\n const ws = utils.aoa_to_sheet(rows);\n ws['!cols'] = cols.map(() => ({ wpx: 100 }));\n utils.book_append_sheet(wb, ws, name);\n }\n writeFile(wb, fname.endsWith('.xlsx') ? fname : fname + '.xlsx', { cellStyles: true } as any);\n }).catch(() => console.error('exportSheetsExcel: xlsx 패키지를 확인하세요.'));\n }\n}\n","import { ColumnLayout } from './ColumnLayout.js';\nimport { OGDecimal } from './OGDecimal.js';\n\nexport interface FooterDeps<T extends Record<string, any>> {\n getData: () => T[];\n getColLayout: () => ColumnLayout<T>;\n getColWidths: () => number[];\n getOptions: () => any;\n getContainer: () => HTMLElement;\n}\n\nexport class FooterManager<T extends Record<string, any> = any> {\n private _d: FooterDeps<T>;\n\n constructor(deps: FooterDeps<T>) {\n this._d = deps;\n }\n\n fmtNum(value: number, fmt?: string): string {\n if (!fmt) {\n return Math.round(value).toLocaleString('ko-KR');\n }\n const useComma = fmt.includes('#') || fmt.includes(',');\n const dpMatch = fmt.match(/\\.(\\d+)$/);\n const dp = dpMatch\n ? parseInt(dpMatch[1]!, 10)\n : /^\\d+$/.test(fmt) ? parseInt(fmt, 10) : 0;\n\n const fixed = Math.abs(value).toFixed(dp);\n const [intPart = '0', decPart] = fixed.split('.');\n const intStr = useComma\n ? intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n : intPart;\n\n const result = decPart !== undefined ? `${intStr}.${decPart}` : intStr;\n return value < 0 ? `-${result}` : result;\n }\n\n computeValues(): any[] {\n const footerDefs = this._d.getOptions().footer;\n if (!footerDefs || footerDefs.length === 0) return [];\n\n const allData = this._d.getData();\n\n return footerDefs\n .filter((d: any) => d.field && d.op)\n .map((def: any) => {\n const field = def.field!;\n const op = def.op!;\n const nums = allData\n .map((r: any) => r[field])\n .filter((v: any) => v !== null && v !== undefined && v !== '');\n\n let result: OGDecimal | null = null;\n const opUC = (op as string).toUpperCase();\n if (opUC === 'SUM') {\n result = nums.length > 0 ? OGDecimal.sum(nums.map((v: any) => String(v))) : null;\n } else if (opUC === 'AVG') {\n result = nums.length > 0\n ? OGDecimal.sum(nums.map((v: any) => String(v))).div(OGDecimal.from(String(nums.length)))\n : null;\n } else if (opUC === 'COUNT') {\n const cnt = nums.length;\n return { _field: field, _value: cnt, _formatted: cnt.toLocaleString('ko-KR') };\n } else if (opUC === 'MAX') {\n result = nums.length > 0 ? OGDecimal.max(nums.map((v: any) => String(v))) : null;\n } else if (opUC === 'MIN') {\n result = nums.length > 0 ? OGDecimal.min(nums.map((v: any) => String(v))) : null;\n }\n\n if (!result) return { _field: field, _value: null, _formatted: '' };\n\n const numVal = result.toNumber();\n const formatted = this.fmtNum(numVal, def.format);\n return { _field: field, _value: numVal, _formatted: formatted };\n });\n }\n\n render(): void {\n const container = this._d.getContainer();\n const old = container.querySelector('.og-footer-bar');\n old?.remove();\n\n const opts = this._d.getOptions();\n const footerDefs = opts.footer;\n if (!footerDefs || footerDefs.length === 0) return;\n\n const leaves = this._d.getColLayout().visibleLeaves;\n const widths = this._d.getColWidths() ?? leaves.map((l: any) => l.width ?? 100);\n const valMap = new Map(\n this.computeValues().map((v: any) => [v._field, v])\n );\n\n const bar = document.createElement('div');\n bar.className = 'og-footer-bar';\n bar.style.cssText = [\n 'display:flex;align-items:stretch;',\n `min-height:${opts.footerHeight}px;`,\n 'border-top:2px solid var(--og-primary,#1976d2);',\n 'background:var(--og-header-bg,#f5f5f5);',\n 'overflow:hidden;flex-shrink:0;font-size:13px;font-weight:600;',\n ].join('');\n\n let extraW = 0;\n if (opts.stateColumn) extraW += 24;\n if (opts.draggable) extraW += 18;\n if (opts.rowNumber) extraW += 44;\n if (opts.checkColumn) extraW += 36;\n if (extraW > 0) {\n const spacer = document.createElement('div');\n spacer.style.cssText = `width:${extraW}px;flex-shrink:0;border-right:1px solid var(--og-border-color,#e0e0e0);`;\n bar.appendChild(spacer);\n }\n\n let leafCursor = 0;\n\n for (const def of footerDefs) {\n const colspan = Math.max(1, def.colspan ?? 1);\n\n let cellW = 0;\n for (let c = 0; c < colspan; c++) {\n cellW += widths[leafCursor + c] ?? 100;\n }\n const targetLeaf = leaves[leafCursor];\n leafCursor += colspan;\n\n const cell = document.createElement('div');\n cell.style.cssText = [\n `width:${cellW}px;min-width:${cellW}px;flex-shrink:0;`,\n 'padding:4px 8px;box-sizing:border-box;overflow:hidden;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n 'white-space:nowrap;text-overflow:ellipsis;',\n ].join('');\n\n const field = def.field;\n const val = field ? valMap.get(field) : null;\n\n if (val) {\n const displayVal = val._formatted ?? String(val._value ?? '');\n const prefix = def.label ? `${def.label}: ` : '';\n cell.textContent = prefix + displayVal;\n cell.title = `${(def.op as string)?.toUpperCase() ?? ''} = ${displayVal}`;\n cell.style.color = 'var(--og-primary,#1976d2)';\n cell.style.textAlign = def.align ?? (targetLeaf?.type === 'number' ? 'right' : 'right');\n } else if (def.label) {\n cell.textContent = def.label;\n cell.style.textAlign = def.align ?? 'left';\n cell.style.color = 'var(--og-row-color,#212121)';\n }\n\n bar.appendChild(cell);\n }\n\n if (opts.footerPosition === 'top') {\n container.insertBefore(bar, container.firstChild);\n } else {\n container.appendChild(bar);\n }\n }\n}\n","import type { DataLayer } from './DataLayer.js';\nimport type { ColumnLayout } from './ColumnLayout.js';\nimport type { CellEditManager } from './CellEditManager.js';\nimport type { RowManager } from './RowManager.js';\n\nexport interface KeyboardDeps<T extends Record<string, any>> {\n getEditMgr: () => CellEditManager<T>;\n getRowMgr: () => RowManager<T>;\n getData: () => DataLayer<T>;\n getColLayout: () => ColumnLayout<T>;\n getOptions: () => any;\n setFocusCell: (ri: number, ci: number) => void;\n handleRowDrop: (from: number, to: number) => void;\n doRender: () => void;\n announce: (msg: string) => void;\n emit: (event: string, ...args: any[]) => void;\n visRange: () => [number, number];\n handleCellKeyEvt: (eventName: 'cellKeyDown' | 'cellKeyUp' | 'cellKeyPress', e: KeyboardEvent) => void;\n}\n\nexport class KeyboardManager<T extends Record<string, any> = any> {\n private _d: KeyboardDeps<T>;\n\n constructor(deps: KeyboardDeps<T>) {\n this._d = deps;\n }\n\n handleKeyDown(e: KeyboardEvent): void {\n const editMgr = this._d.getEditMgr();\n if (editMgr.activeEditor) return;\n\n this._d.handleCellKeyEvt('cellKeyDown', e);\n\n const data = this._d.getData();\n const colLayout = this._d.getColLayout();\n const totalRows = data.rowCount;\n const totalCols = colLayout.visibleLeaves.length;\n if (totalRows === 0 || totalCols === 0) return;\n\n if ((e.ctrlKey || e.metaKey) && e.key === 'c') {\n e.preventDefault();\n this._copyToClipboard();\n return;\n }\n if ((e.ctrlKey || e.metaKey) && e.key === 'v') {\n e.preventDefault();\n this._pasteFromClipboard();\n return;\n }\n\n const opts = this._d.getOptions();\n if ((e.ctrlKey || e.metaKey) && opts.draggable && editMgr.focusCell) {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n const ri = editMgr.focusCell.ci !== undefined ? editMgr.focusCell.ri : 0;\n if (ri < totalRows - 1) {\n this._d.handleRowDrop(ri, ri + 1);\n this._d.setFocusCell(ri + 1, editMgr.focusCell.ci);\n this._d.announce(`행 ${ri + 1}을(를) ${ri + 2}번째 위치로 이동`);\n }\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n const ri = editMgr.focusCell.ri;\n if (ri > 0) {\n this._d.handleRowDrop(ri, ri - 1);\n this._d.setFocusCell(ri - 1, editMgr.focusCell.ci);\n this._d.announce(`행 ${ri + 1}을(를) ${ri}번째 위치로 이동`);\n }\n return;\n }\n }\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const nextRi = cur ? Math.min(cur.ri + 1, totalRows - 1) : 0;\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const nextRi = cur ? Math.max(cur.ri - 1, 0) : 0;\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case 'ArrowRight': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n if (!cur) { this._d.setFocusCell(0, 0); break; }\n if (cur.ci < totalCols - 1) {\n this._d.setFocusCell(cur.ri, cur.ci + 1);\n } else if (cur.ri < totalRows - 1) {\n this._d.setFocusCell(cur.ri + 1, 0);\n }\n break;\n }\n case 'ArrowLeft': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n if (!cur) { this._d.setFocusCell(0, 0); break; }\n if (cur.ci > 0) {\n this._d.setFocusCell(cur.ri, cur.ci - 1);\n } else if (cur.ri > 0) {\n this._d.setFocusCell(cur.ri - 1, totalCols - 1);\n }\n break;\n }\n case 'Tab': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n if (!cur) { this._d.setFocusCell(0, 0); break; }\n if (!e.shiftKey) {\n if (cur.ci < totalCols - 1) this._d.setFocusCell(cur.ri, cur.ci + 1);\n else if (cur.ri < totalRows - 1) this._d.setFocusCell(cur.ri + 1, 0);\n } else {\n if (cur.ci > 0) this._d.setFocusCell(cur.ri, cur.ci - 1);\n else if (cur.ri > 0) this._d.setFocusCell(cur.ri - 1, totalCols - 1);\n }\n break;\n }\n case 'Home': {\n e.preventDefault();\n if (e.ctrlKey || e.metaKey) {\n this._d.setFocusCell(0, 0);\n } else {\n const cur = editMgr.focusCell;\n this._d.setFocusCell(cur?.ri ?? 0, 0);\n }\n break;\n }\n case 'End': {\n e.preventDefault();\n if (e.ctrlKey || e.metaKey) {\n this._d.setFocusCell(totalRows - 1, totalCols - 1);\n } else {\n const cur = editMgr.focusCell;\n this._d.setFocusCell(cur?.ri ?? 0, totalCols - 1);\n }\n break;\n }\n case 'PageDown': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const step = this._d.getOptions().pageSize ?? 10;\n const nextRi = cur ? Math.min(cur.ri + step, totalRows - 1) : Math.min(step - 1, totalRows - 1);\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case 'PageUp': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const step = this._d.getOptions().pageSize ?? 10;\n const nextRi = cur ? Math.max(cur.ri - step, 0) : 0;\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case ' ': {\n if (editMgr.focusCell) {\n e.preventDefault();\n const ri = editMgr.focusCell.ri;\n const rowMgr = this._d.getRowMgr();\n if (this._d.getOptions().checkColumn) {\n rowMgr.check(ri, !rowMgr.checkedRows.has(ri));\n this._d.doRender();\n } else {\n rowMgr.selectToggle(ri);\n this._d.doRender();\n }\n }\n break;\n }\n case 'F2':\n case 'Enter': {\n if (editMgr.focusCell && this._d.getOptions().editable) {\n e.preventDefault();\n editMgr.startEditByKey(editMgr.focusCell.ri, editMgr.focusCell.ci);\n }\n break;\n }\n case 'Escape': {\n editMgr.clearFocusCell();\n this._d.doRender();\n break;\n }\n }\n }\n\n private _copyToClipboard(): void {\n const opts = this._d.getOptions();\n if (!opts.clipboard) return;\n\n const editMgr = this._d.getEditMgr();\n const colLayout = this._d.getColLayout();\n const data = this._d.getData();\n\n let text = '';\n if (editMgr.focusCell) {\n const { ri, ci } = editMgr.focusCell;\n const col = colLayout.visibleLeaves[ci];\n if (col) text = String(data.getCellValue(ri, col.field) ?? '');\n } else if (this._d.getRowMgr().selectedRows.size > 0) {\n const cols = colLayout.visibleLeaves;\n const rowTexts = [...this._d.getRowMgr().selectedRows].sort((a, b) => a - b).map(ri => {\n const row = data.getRowByIndex(ri);\n return cols.map(c => String(row?.[c.field] ?? '')).join('\\t');\n });\n text = rowTexts.join('\\n');\n }\n\n if (text) navigator.clipboard?.writeText(text).catch(() => {});\n }\n\n private _pasteFromClipboard(): void {\n const opts = this._d.getOptions();\n if (!opts.clipboard || !opts.editable) return;\n\n const editMgr = this._d.getEditMgr();\n if (!editMgr.focusCell) return;\n\n navigator.clipboard?.readText().then(text => {\n if (!text) return;\n const { ri, ci } = editMgr.focusCell!;\n const lines = text.split('\\n');\n const cols = this._d.getColLayout().visibleLeaves;\n const data = this._d.getData();\n\n for (let dr = 0; dr < lines.length; dr++) {\n const cells = lines[dr]!.split('\\t');\n for (let dc = 0; dc < cells.length; dc++) {\n const targetRi = ri + dr;\n const targetCi = ci + dc;\n const col = cols[targetCi];\n if (col && targetRi < data.rowCount) {\n data.updateCell(targetRi, col.field, cells[dc]);\n }\n }\n }\n this._d.emit('dataChange', data.getData());\n this._d.doRender();\n }).catch(() => {});\n }\n}\n","import type { ColumnLayout } from './ColumnLayout.js';\nimport type { DataLayer } from './DataLayer.js';\nimport type { Pagination } from './Pagination.js';\nimport type { VirtualScroll } from './VirtualScroll.js';\n\nexport interface FindBarDeps<T extends Record<string, any>> {\n getColLayout: () => ColumnLayout<T>;\n getData: () => DataLayer<T>;\n getFilters: () => Record<string, any[]>;\n getVs: () => VirtualScroll | null;\n getPagination: () => Pagination | null;\n doRender: () => void;\n}\n\nexport class FindBarManager<T extends Record<string, any> = any> {\n private _bar: HTMLElement | null = null;\n private _input: HTMLInputElement | null = null;\n private _count: HTMLElement | null = null;\n private _filter: string = '';\n private _d: FindBarDeps<T>;\n\n constructor(deps: FindBarDeps<T>) {\n this._d = deps;\n }\n\n get findFilter(): string { return this._filter; }\n\n init(container: HTMLElement): void {\n const bar = document.createElement('div');\n bar.className = 'og-find-bar';\n bar.hidden = true;\n\n const lbl = document.createElement('span');\n lbl.className = 'og-find-label';\n lbl.textContent = '찾기';\n\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'og-find-input';\n input.placeholder = '검색어 입력...';\n input.setAttribute('aria-label', '그리드 내 검색');\n\n const count = document.createElement('span');\n count.className = 'og-find-count';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'og-find-close';\n closeBtn.textContent = '✕';\n closeBtn.setAttribute('aria-label', '찾기 닫기');\n\n bar.appendChild(lbl);\n bar.appendChild(input);\n bar.appendChild(count);\n bar.appendChild(closeBtn);\n\n container.insertBefore(bar, container.firstChild);\n\n input.addEventListener('input', () => {\n this._filter = input.value.trim();\n this._apply();\n });\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') this.close();\n });\n closeBtn.addEventListener('click', () => this.close());\n\n this._bar = bar;\n this._input = input;\n this._count = count;\n }\n\n open(): void {\n if (!this._bar) return;\n this._bar.hidden = false;\n this._input!.focus();\n this._input!.select();\n }\n\n close(): void {\n if (!this._bar) return;\n this._bar.hidden = true;\n this._filter = '';\n this._input!.value = '';\n if (this._count) this._count.textContent = '';\n this._apply();\n }\n\n private _apply(): void {\n const data = this._d.getData();\n const fields = this._d.getColLayout().visibleLeaves.map(c => c.field);\n data.setFindFilter(this._filter, fields);\n data.applyFilter(this._d.getFilters());\n const n = data.rowCount;\n this._d.getVs()?.setTotalRows(n);\n this._d.getPagination()?.setTotalRows(n);\n if (this._count) this._count.textContent = this._filter ? `${n}건` : '';\n this._d.doRender();\n }\n}\n","import type { SummaryOp } from './types.js';\nimport { OGDecimal } from './OGDecimal.js';\n\nexport interface GroupRow<T = any> {\n _isGroup: true;\n _groupField: string;\n _groupValue: any;\n _groupLabel: string;\n _depth: number;\n _expanded: boolean;\n _childCount: number;\n _summary: Record<string, any>; // { field → 계산값(number) }\n _summaryFmt: Record<string, string>; // { field → 포맷된 문자열 }\n _states: { added: number; edited: number; removed: number };\n children: Array<GroupRow<T> | T>;\n}\n\nexport type GroupItem<T> = GroupRow<T> | T;\n\nexport interface SummaryDef {\n field: string;\n op: SummaryOp;\n label?: string;\n format?: string; // '#,##0' | '#,##0.00' | '0.00' | '2' 등\n}\n\nfunction _isGroup<T>(item: any): item is GroupRow<T> {\n return item && item._isGroup === true;\n}\n\n/** flat 데이터를 fields 기준으로 계층 그룹핑 */\nexport function buildGroups<T extends Record<string, any>>(\n data: T[],\n fields: string[],\n summaryDefs: SummaryDef[] = [],\n expandedKeys: Set<string> = new Set(),\n getRowState?: (row: T) => string\n): GroupRow<T>[] {\n if (!fields.length) return [];\n return _groupByFields(data, fields, 0, summaryDefs, expandedKeys, '', getRowState);\n}\n\nfunction _groupByFields<T extends Record<string, any>>(\n data: T[],\n fields: string[],\n depth: number,\n summaryDefs: SummaryDef[],\n expandedKeys: Set<string>,\n parentKey: string,\n getRowState?: (row: T) => string\n): GroupRow<T>[] {\n const field = fields[depth]!;\n const map = new Map<any, T[]>();\n\n for (const row of data) {\n const key = row[field];\n if (!map.has(key)) map.set(key, []);\n map.get(key)!.push(row);\n }\n\n const result: GroupRow<T>[] = [];\n for (const [value, rows] of map) {\n const groupKey = `${parentKey}__${field}:${value}`;\n const expanded = expandedKeys.has(groupKey);\n\n let children: Array<GroupRow<T> | T>;\n if (depth < fields.length - 1) {\n children = _groupByFields(rows, fields, depth + 1, summaryDefs, expandedKeys, groupKey, getRowState);\n } else {\n children = rows;\n }\n\n const { summary, summaryFmt } = _calcSummary(rows, summaryDefs);\n const states = _calcStates(rows, getRowState);\n\n result.push({\n _isGroup: true,\n _groupField: field,\n _groupValue: value,\n _groupLabel: value == null ? '(없음)' : String(value),\n _depth: depth,\n _expanded: expanded,\n _childCount: rows.length,\n _summary: summary,\n _summaryFmt: summaryFmt,\n _states: states,\n children,\n } as GroupRow<T>);\n }\n return result;\n}\n\n/** OGDecimal 정밀 계산으로 summary 집계 */\nfunction _calcSummary(\n data: Record<string, any>[],\n defs: SummaryDef[]\n): { summary: Record<string, any>; summaryFmt: Record<string, string> } {\n const summary: Record<string, any> = {};\n const summaryFmt: Record<string, string> = {};\n\n for (const def of defs) {\n const vals = data\n .map(r => r[def.field])\n .filter(v => v !== null && v !== undefined && v !== '');\n\n let result: OGDecimal | null = null;\n const opUC = (def.op as string).toUpperCase();\n\n if (opUC === 'SUM') {\n result = vals.length > 0 ? OGDecimal.sum(vals.map(String)) : null;\n } else if (opUC === 'AVG') {\n result = vals.length > 0\n ? OGDecimal.sum(vals.map(String)).div(OGDecimal.from(String(vals.length)))\n : null;\n } else if (opUC === 'COUNT') {\n summary[def.field] = data.length;\n summaryFmt[def.field] = data.length.toLocaleString('ko-KR');\n continue;\n } else if (opUC === 'MAX') {\n result = vals.length > 0 ? OGDecimal.max(vals.map(String)) : null;\n } else if (opUC === 'MIN') {\n result = vals.length > 0 ? OGDecimal.min(vals.map(String)) : null;\n }\n\n if (!result) { summary[def.field] = null; summaryFmt[def.field] = ''; continue; }\n\n const numVal = result.toNumber();\n summary[def.field] = numVal;\n summaryFmt[def.field] = _fmtNum(numVal, def.format);\n }\n\n return { summary, summaryFmt };\n}\n\n/** 그룹 내 행 편집 상태 집계 */\nfunction _calcStates<T extends Record<string, any>>(\n rows: T[],\n getRowState?: (row: T) => string\n): { added: number; edited: number; removed: number } {\n if (!getRowState) return { added: 0, edited: 0, removed: 0 };\n let added = 0, edited = 0, removed = 0;\n for (const r of rows) {\n const s = getRowState(r);\n if (s === 'added') added++;\n else if (s === 'edited') edited++;\n else if (s === 'removed') removed++;\n }\n return { added, edited, removed };\n}\n\n/**\n * 숫자 포맷팅 (GroupEngine 내부 + 외부 공용)\n * '#,##0' → 천단위 콤마, 정수\n * '#,##0.00' → 천단위 콤마, 소수 2자리\n * '0.00' → 소수 2자리 (콤마 없음)\n * '2' → 소수 2자리 (하위 호환)\n */\nexport function _fmtNum(value: number, fmt?: string): string {\n if (fmt === undefined || fmt === null) {\n return value % 1 === 0\n ? value.toLocaleString('ko-KR')\n : parseFloat(value.toFixed(6)).toLocaleString('ko-KR', {\n minimumFractionDigits: 2, maximumFractionDigits: 6,\n });\n }\n const useComma = fmt.includes('#') || fmt.includes(',');\n const dpMatch = fmt.match(/\\.(\\d+)$/);\n const dp = dpMatch ? parseInt(dpMatch[1]!, 10) : /^\\d+$/.test(fmt) ? parseInt(fmt, 10) : 0;\n\n const fixed = Math.abs(value).toFixed(dp);\n const [intPart = '0', decPart] = fixed.split('.');\n const intStr = useComma\n ? intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n : intPart;\n const result = decPart !== undefined ? `${intStr}.${decPart}` : intStr;\n return value < 0 ? `-${result}` : result;\n}\n\n/**\n * 그룹 트리를 화면에 표시할 flat 행 배열로 변환.\n * 접힌 그룹(expanded=false)의 자식은 포함하지 않음.\n */\nexport function flattenGroups<T>(groups: GroupRow<T>[]): Array<GroupRow<T> | T> {\n const result: Array<GroupRow<T> | T> = [];\n for (const g of groups) {\n result.push(g);\n if (g._expanded) {\n for (const child of g.children) {\n if (_isGroup(child)) {\n result.push(...flattenGroups([child as GroupRow<T>]));\n } else {\n result.push(child);\n }\n }\n }\n }\n return result;\n}\n\n/** 특정 그룹 키의 펼침 상태를 토글 */\nexport function toggleGroup<T>(\n groups: GroupRow<T>[],\n groupKey: string,\n expandedKeys: Set<string>\n): void {\n if (expandedKeys.has(groupKey)) {\n expandedKeys.delete(groupKey);\n } else {\n expandedKeys.add(groupKey);\n }\n}\n\n/** 모든 그룹 키 수집 */\nexport function collectAllKeys<T>(groups: GroupRow<T>[], parentKey = ''): string[] {\n const keys: string[] = [];\n for (const g of groups) {\n const key = `${parentKey}__${g._groupField}:${g._groupValue}`;\n keys.push(key);\n const nested = g.children.filter((c): c is GroupRow<T> => _isGroup(c));\n if (nested.length) keys.push(...collectAllKeys(nested, key));\n }\n return keys;\n}\n\nexport { _isGroup };\n","export interface TreeNode<T = any> {\n _isTree: true;\n _treeId: any;\n _treeParentId: any;\n _depth: number;\n _expanded: boolean;\n _hasChildren: boolean;\n _childCount: number;\n // 탐색기 스타일 트리 라인 렌더링용 메타\n _isLastChild: boolean; // true → └─ / false → ├─\n _ancestorHasMore: boolean[]; // [d] = true → 깊이 d 조상에 형제가 더 있어 │ 라인 표시\n data: T;\n children: TreeNode<T>[];\n}\n\nexport type TreeItem<T> = TreeNode<T>;\n\nexport function isTreeNode<T>(item: any): item is TreeNode<T> {\n return item != null && item._isTree === true;\n}\n\nexport interface TreeBuildOptions {\n idField: string;\n parentIdField: string;\n expandOnLoad?: boolean;\n}\n\n/**\n * flat 데이터를 트리 구조로 변환.\n * parentId가 null/undefined/''인 행이 루트 노드.\n */\nexport function buildTree<T extends Record<string, any>>(\n data: T[],\n opts: TreeBuildOptions,\n expandedKeys: Set<any> = new Set()\n): TreeNode<T>[] {\n const { idField, parentIdField, expandOnLoad = false } = opts;\n\n const nodeMap = new Map<any, TreeNode<T>>();\n const roots: TreeNode<T>[] = [];\n\n // 1단계: 모든 노드 생성\n for (const row of data) {\n const id = row[idField];\n const node: TreeNode<T> = {\n _isTree: true,\n _treeId: id,\n _treeParentId: row[parentIdField],\n _depth: 0,\n _expanded: expandOnLoad || expandedKeys.has(id),\n _hasChildren: false,\n _childCount: 0,\n _isLastChild: false,\n _ancestorHasMore: [],\n data: row,\n children: [],\n };\n nodeMap.set(id, node);\n }\n\n // 2단계: 부모-자식 연결\n for (const node of nodeMap.values()) {\n const pid = node._treeParentId;\n const isRoot = pid == null || pid === '' || !nodeMap.has(pid);\n if (isRoot) {\n roots.push(node);\n } else {\n const parent = nodeMap.get(pid)!;\n parent.children.push(node);\n parent._hasChildren = true;\n }\n }\n\n // 3단계: 깊이 설정 + childCount\n function assignDepth(nodes: TreeNode<T>[], depth: number): void {\n for (const n of nodes) {\n n._depth = depth;\n n._childCount = _countDescendants(n);\n assignDepth(n.children, depth + 1);\n }\n }\n assignDepth(roots, 0);\n\n // 4단계: 탐색기 라인 메타 (_isLastChild, _ancestorHasMore)\n // parentHasMoreChain[d] = true → 깊이 d 위치에서 아직 형제가 남아있음 → │ 라인\n function assignLineMeta(nodes: TreeNode<T>[], parentHasMoreChain: boolean[]): void {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i]!;\n const isLast = i === nodes.length - 1;\n node._isLastChild = isLast;\n node._ancestorHasMore = parentHasMoreChain;\n if (node.children.length > 0) {\n // 자식에게 전달: 이 노드가 마지막이 아니면 자식들 가이드에 │ 표시\n assignLineMeta(node.children, [...parentHasMoreChain, !isLast]);\n }\n }\n }\n assignLineMeta(roots, []);\n\n return roots;\n}\n\nfunction _countDescendants<T>(node: TreeNode<T>): number {\n let count = node.children.length;\n for (const child of node.children) count += _countDescendants(child);\n return count;\n}\n\n/**\n * 트리를 화면에 표시할 flat 배열로 변환.\n * 접힌 노드(_expanded=false)의 자식은 제외.\n */\nexport function flattenTree<T>(nodes: TreeNode<T>[]): TreeNode<T>[] {\n const result: TreeNode<T>[] = [];\n for (const node of nodes) {\n result.push(node);\n if (node._expanded && node.children.length > 0) {\n result.push(...flattenTree(node.children));\n }\n }\n return result;\n}\n\n/** 특정 id 노드의 펼침 상태 토글 */\nexport function toggleTreeNode<T>(\n expandedKeys: Set<any>,\n nodeId: any\n): void {\n if (expandedKeys.has(nodeId)) {\n expandedKeys.delete(nodeId);\n } else {\n expandedKeys.add(nodeId);\n }\n}\n\n/** 모든 노드 id 수집 */\nexport function collectAllTreeIds<T>(nodes: TreeNode<T>[]): any[] {\n const ids: any[] = [];\n for (const n of nodes) {\n ids.push(n._treeId);\n if (n.children.length) ids.push(...collectAllTreeIds(n.children));\n }\n return ids;\n}\n","import { DataLayer } from './DataLayer.js';\nimport { VirtualScroll } from './VirtualScroll.js';\nimport {\n buildGroups, flattenGroups, collectAllKeys,\n type GroupRow, type SummaryDef,\n} from './GroupEngine.js';\nimport {\n buildTree, flattenTree, toggleTreeNode, collectAllTreeIds,\n type TreeNode,\n} from './TreeEngine.js';\n\nexport interface GroupTreeDeps<T extends Record<string, any>> {\n getData: () => T[];\n getDataLayer: () => DataLayer<T>;\n getOptions: () => any;\n getVs: () => VirtualScroll | null;\n doRenderFull: (totalRows: number) => void;\n doRender: () => void;\n}\n\nexport class GroupTreeManager<T extends Record<string, any> = any> {\n private _groupFields: string[] = [];\n private _groupExpandedKeys: Set<string> = new Set();\n private _groupFlatRows: Array<GroupRow<T> | T> = [];\n private _isGroupMode = false;\n private _treeRoots: TreeNode<T>[] = [];\n private _treeFlatRows: TreeNode<T>[] = [];\n private _treeExpandedKeys: Set<any> = new Set();\n private _isTreeMode = false;\n private _d: GroupTreeDeps<T>;\n\n constructor(deps: GroupTreeDeps<T>) {\n this._d = deps;\n }\n\n // ─── 상태 접근자 ─────────────────────────────────────────\n get isGroupMode(): boolean { return this._isGroupMode; }\n get isTreeMode(): boolean { return this._isTreeMode; }\n get groupFlatRows(): Array<GroupRow<T> | T> { return this._groupFlatRows; }\n get treeFlatRows(): TreeNode<T>[] { return this._treeFlatRows; }\n\n // ─── 그룹 ─────────────────────────────────────────────────\n groupBy(fields: string[]): void {\n this._groupFields = fields;\n this._groupExpandedKeys.clear();\n this._isGroupMode = fields.length > 0;\n this.rebuildGroups();\n }\n\n clearGroup(): void {\n this._groupFields = [];\n this._groupExpandedKeys.clear();\n this._isGroupMode = false;\n this._groupFlatRows = [];\n const n = this._d.getData().length;\n this._d.getVs()?.setTotalRows(n);\n this._d.doRender();\n }\n\n expandAll(): void {\n if (!this._isGroupMode) return;\n const groups = buildGroups(this._d.getData(), this._groupFields, this._getSummaryDefs());\n collectAllKeys(groups).forEach(k => this._groupExpandedKeys.add(k));\n this.rebuildGroups();\n }\n\n collapseAll(): void {\n this._groupExpandedKeys.clear();\n if (this._isGroupMode) this.rebuildGroups();\n }\n\n handleGroupToggle(groupKey: string): void {\n if (this._groupExpandedKeys.has(groupKey)) {\n this._groupExpandedKeys.delete(groupKey);\n } else {\n this._groupExpandedKeys.add(groupKey);\n }\n this.rebuildGroups();\n }\n\n rebuildGroups(): void {\n const data = this._d.getData();\n const dl = this._d.getDataLayer();\n const getState = (row: any): string => {\n const idx = data.indexOf(row);\n return idx >= 0 ? dl.getRowState(idx) : 'none';\n };\n const groups = buildGroups(data, this._groupFields, this._getSummaryDefs(), this._groupExpandedKeys, getState);\n this._groupFlatRows = flattenGroups(groups);\n this._d.getVs()?.setTotalRows(this._groupFlatRows.length);\n this._d.doRenderFull(this._groupFlatRows.length);\n }\n\n // ─── 트리 ─────────────────────────────────────────────────\n enableTree(): void {\n this._isTreeMode = true;\n this._isGroupMode = false;\n const opts = this._d.getOptions();\n if (opts.expandOnLoad) {\n const temp = buildTree(this._d.getData(), {\n idField: opts.treeId,\n parentIdField: opts.treeParentId,\n });\n collectAllTreeIds(temp).forEach(id => this._treeExpandedKeys.add(id));\n }\n this.rebuildTree();\n }\n\n disableTree(): void {\n this._isTreeMode = false;\n this._treeRoots = [];\n this._treeFlatRows = [];\n this._treeExpandedKeys.clear();\n const n = this._d.getData().length;\n this._d.getVs()?.setTotalRows(n);\n this._d.doRender();\n }\n\n expandNodes(ids: any | any[], open = true): void {\n const arr = Array.isArray(ids) ? ids : [ids];\n for (const id of arr) {\n if (open) this._treeExpandedKeys.add(id);\n else this._treeExpandedKeys.delete(id);\n }\n if (this._isTreeMode) this.rebuildTree();\n }\n\n expandAllNodes(): void {\n if (!this._isTreeMode) return;\n collectAllTreeIds(this._treeRoots).forEach(id => this._treeExpandedKeys.add(id));\n this.rebuildTree();\n }\n\n collapseAllNodes(): void {\n if (!this._isTreeMode) return;\n this._treeExpandedKeys.clear();\n this.rebuildTree();\n }\n\n handleTreeToggle(nodeId: any): void {\n toggleTreeNode(this._treeExpandedKeys, nodeId);\n this.rebuildTree();\n }\n\n rebuildTree(): void {\n const opts = this._d.getOptions();\n this._treeRoots = buildTree(this._d.getData(), {\n idField: opts.treeId,\n parentIdField: opts.treeParentId,\n expandOnLoad: opts.expandOnLoad,\n }, this._treeExpandedKeys);\n this._treeFlatRows = flattenTree(this._treeRoots);\n this._d.getVs()?.setTotalRows(this._treeFlatRows.length);\n this._d.doRenderFull(this._treeFlatRows.length);\n }\n\n // ─── 내부 헬퍼 ───────────────────────────────────────────\n private _getSummaryDefs(): SummaryDef[] {\n const s = this._d.getOptions().summary;\n if (!s) return [];\n if (s.rows && s.rows.length > 0) {\n return s.fields.flatMap((f: string) =>\n s.rows!.map((r: any) => ({ field: f, op: r.op, format: r.format }))\n );\n }\n const ops = Array.isArray(s.ops) ? s.ops : (s.ops ? [s.ops] : ['SUM']);\n return s.fields.map((f: string) => ({ field: f, op: ops[0] ?? 'SUM', format: (s as any).format }));\n }\n}\n","import type { DataLayer } from './DataLayer.js';\nimport type { ColumnLayout } from './ColumnLayout.js';\nimport type { VirtualScroll } from './VirtualScroll.js';\nimport type { Pagination } from './Pagination.js';\nimport type { SortItem, FilterItem } from './types.js';\n\nexport interface SortFilterDeps<T extends Record<string, any>> {\n getData: () => DataLayer<T>;\n getColLayout: () => ColumnLayout<T>;\n getFindFilter: () => string;\n getVs: () => VirtualScroll | null;\n getPagination: () => Pagination | null;\n getOptions: () => any;\n renderHeader: () => void;\n doRender: () => void;\n announce: (msg: string) => void;\n emit: (event: string, ...args: any[]) => void;\n}\n\nexport class SortFilterManager<T extends Record<string, any> = any> {\n private _sortList: SortItem[] = [];\n private _filters: Record<string, FilterItem[]> = {};\n private _d: SortFilterDeps<T>;\n\n constructor(deps: SortFilterDeps<T>) {\n this._d = deps;\n }\n\n // ─── 상태 접근자 ─────────────────────────────────────────\n get sortList(): SortItem[] { return this._sortList; }\n get filters(): Record<string, FilterItem[]> { return this._filters; }\n\n // ─── 정렬 ─────────────────────────────────────────────────\n handleSortClick(field: string, shiftKey: boolean): void {\n const opts = this._d.getOptions();\n if (!opts.sortable) return;\n const idx = this._sortList.findIndex(s => s.field === field);\n if (idx >= 0) {\n const cur = this._sortList[idx]!;\n if (cur.dir === 'asc') {\n cur.dir = 'desc';\n } else {\n this._sortList.splice(idx, 1);\n }\n } else {\n if (!shiftKey || !opts.multiSort) this._sortList = [];\n this._sortList.push({ field, dir: 'asc' });\n }\n this._d.getData().applySort(this._sortList);\n this._d.renderHeader();\n this._d.doRender();\n const sortedItem = this._sortList.find(s => s.field === field);\n const dirLabel = sortedItem ? (sortedItem.dir === 'asc' ? '오름차순' : '내림차순') : '정렬 해제';\n this._d.announce(`${field} ${dirLabel} 정렬`);\n this._d.emit('sortChange', { sortList: this._sortList });\n opts.onSortChange?.({ field, dir: sortedItem?.dir ?? 'asc', sortList: this._sortList });\n }\n\n sort(fieldOrList: string | SortItem[], dir: 'asc' | 'desc' = 'asc'): void {\n if (Array.isArray(fieldOrList)) {\n this._sortList = fieldOrList;\n } else {\n const i = this._sortList.findIndex(s => s.field === fieldOrList);\n if (i >= 0) this._sortList[i]!.dir = dir;\n else this._sortList = [{ field: fieldOrList, dir }];\n if (!this._d.getOptions().multiSort) this._sortList = this._sortList.slice(-1);\n }\n this._d.getData().applySort(this._sortList);\n this._d.renderHeader();\n this._d.doRender();\n this._d.emit('sortChange', { sortList: this._sortList });\n }\n\n resetSort(): void {\n this._sortList = [];\n this._d.getData().applySort([]);\n this._d.renderHeader();\n this._d.doRender();\n }\n\n initSort(sortList: SortItem[]): void {\n this._sortList = [...sortList];\n this._d.getData().applySort(this._sortList);\n }\n\n getSortState(): SortItem[] { return [...this._sortList]; }\n\n // ─── 필터 ─────────────────────────────────────────────────\n setFilter(field: string, filterItems: FilterItem[]): void {\n this._filters[field] = filterItems;\n this.applyFilters();\n this._d.renderHeader();\n this._d.doRender();\n this._d.emit('filterChange', { field, filterItems, allFilters: this._filters });\n this._d.getOptions().onFilterChange?.({ field, filterItems, allFilters: this._filters });\n }\n\n resetFilter(field?: string): void {\n if (field) delete this._filters[field];\n else this._filters = {};\n this.applyFilters();\n this._d.renderHeader();\n this._d.doRender();\n }\n\n getFilterState(): Record<string, FilterItem[]> { return { ...this._filters }; }\n\n restoreFilter(state: Record<string, FilterItem[]>): void {\n this._filters = { ...state };\n this.applyFilters();\n }\n\n applyFilters(): void {\n const data = this._d.getData();\n data.setFindFilter(this._d.getFindFilter(), this._d.getColLayout().visibleLeaves.map(c => c.field));\n data.applyFilter(this._filters);\n const n = data.rowCount;\n this._d.getVs()?.setTotalRows(n);\n this._d.getPagination()?.setTotalRows(n);\n }\n}\n","import type { DataLayer } from './DataLayer.js';\nimport type { ColumnLayout } from './ColumnLayout.js';\nimport type { CellEditManager } from './CellEditManager.js';\nimport type { RowManager } from './RowManager.js';\nimport { isToggleCol } from './CellTypeRegistry.js';\nimport { evaluateFormula } from './FormulaEngine.js';\nimport { OGDecimal } from './OGDecimal.js';\n\nexport interface CellEventDeps<T extends Record<string, any>> {\n getData: () => DataLayer<T>;\n getColLayout: () => ColumnLayout<T>;\n getOptions: () => any;\n getEditMgr: () => CellEditManager<T>;\n getRowMgr: () => RowManager<T>;\n emit: (event: string, ...args: any[]) => void;\n writeCell: (ri: number, field: string, value: any) => void;\n doRender: () => void;\n getContainer: () => HTMLElement;\n}\n\nexport class CellEventHandler<T extends Record<string, any> = any> {\n private _d: CellEventDeps<T>;\n\n constructor(deps: CellEventDeps<T>) {\n this._d = deps;\n }\n\n handleCellClick(rowIndex: number, colIndex: number, e: MouseEvent): void {\n const opts = this._d.getOptions();\n const rowMgr = this._d.getRowMgr();\n const editMgr = this._d.getEditMgr();\n\n if (opts.selection === 'single' || opts.selection === 'row') {\n rowMgr.selectSingle(rowIndex);\n } else if (opts.selection === 'multiple') {\n if (e.ctrlKey || e.metaKey) {\n rowMgr.selectToggle(rowIndex);\n } else {\n rowMgr.selectSingle(rowIndex);\n }\n }\n\n const row = this._d.getData().getRowByIndex(rowIndex);\n const col = this._d.getColLayout().visibleLeaves[colIndex];\n\n if (row && col) {\n const colEditable = col.editable !== false && (col.editable !== undefined || opts.editable);\n if (isToggleCol(col) && colEditable) {\n const curVal = (row as any)[col.field];\n this._d.writeCell(rowIndex, col.field as unknown as string, !curVal);\n }\n\n if ((col.type as string) === 'radio') {\n const grp = (col as any).group;\n for (const c of this._d.getColLayout().visibleLeaves) {\n if ((c.type as string) === 'radio' && c.field !== col.field &&\n (!grp || (c as any).group === grp)) {\n this._d.getData().updateCell(rowIndex, c.field, false);\n }\n }\n this._d.writeCell(rowIndex, col.field as any, true);\n }\n\n let cellValue = (row as any)[col.field];\n if (cellValue === undefined && (col as any).formula) {\n try {\n const prec = (col as any).formulaPrecision ?? 30;\n const result = evaluateFormula((col as any).formula, row as any, prec);\n cellValue = result instanceof OGDecimal\n ? ((col as any).precision != null ? result.toFixed((col as any).precision) : result.toString())\n : String(result);\n } catch {}\n }\n const evt = {\n type: 'cellClick', rowIndex, columnIndex: colIndex,\n field: col.field, value: cellValue, row, column: col,\n target: e.target as HTMLElement, originalEvent: e,\n };\n this._d.emit('cellClick', evt);\n opts.onCellClick?.(evt);\n\n const rowEvt = { type: 'rowClick', rowIndex, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowClick', rowEvt);\n opts.onRowClick?.(rowEvt);\n\n const isSelectCol = (col.type as string) === 'select';\n const alreadyEditing = editMgr.activeEditor != null &&\n editMgr.editCell?.ri === rowIndex && editMgr.editCell?.ci === colIndex;\n if (!alreadyEditing && (opts.editMode === 'click' || isSelectCol) && !isToggleCol(col)) {\n editMgr.startEdit(rowIndex, colIndex, e);\n }\n }\n\n if (editMgr.activeEditor && editMgr.editCell?.ri === rowIndex && editMgr.editCell?.ci === colIndex) {\n return;\n }\n\n this._d.doRender();\n this._d.emit('selectionChange', {\n rows: rowMgr.getSelections(),\n rowIndexes: [...rowMgr.selectedRows],\n });\n opts.onSelectionChange?.({ rows: rowMgr.getSelections(), rowIndexes: [...rowMgr.selectedRows], cells: [] });\n }\n\n handleCellDblClick(rowIndex: number, colIndex: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(rowIndex);\n const col = this._d.getColLayout().visibleLeaves[colIndex];\n if (!row || !col) return;\n\n const opts = this._d.getOptions();\n const evt = {\n type: 'cellDblClick', rowIndex, columnIndex: colIndex,\n field: col.field, value: row[col.field], row, column: col,\n target: e.target as HTMLElement, originalEvent: e,\n };\n this._d.emit('cellDblClick', evt);\n opts.onCellDblClick?.(evt);\n\n const rowEvt = { type: 'rowDblClick', rowIndex, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowDblClick', rowEvt);\n opts.onRowDblClick?.(rowEvt);\n\n if (opts.editMode === 'dblclick') this._d.getEditMgr().startEdit(rowIndex, colIndex, e);\n }\n\n handleCellMouseOver(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseOver', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseOver', cellEvt);\n opts.onCellMouseOver?.(cellEvt);\n const rowEvt = { type: 'rowMouseOver', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseOver', rowEvt);\n opts.onRowMouseOver?.(rowEvt);\n }\n\n handleCellMouseOut(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseOut', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseOut', cellEvt);\n opts.onCellMouseOut?.(cellEvt);\n const rowEvt = { type: 'rowMouseOut', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseOut', rowEvt);\n opts.onRowMouseOut?.(rowEvt);\n }\n\n handleCellMouseDown(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseDown', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseDown', cellEvt);\n opts.onCellMouseDown?.(cellEvt);\n const rowEvt = { type: 'rowMouseDown', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseDown', rowEvt);\n opts.onRowMouseDown?.(rowEvt);\n }\n\n handleCellMouseUp(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseUp', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseUp', cellEvt);\n opts.onCellMouseUp?.(cellEvt);\n const rowEvt = { type: 'rowMouseUp', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseUp', rowEvt);\n opts.onRowMouseUp?.(rowEvt);\n }\n\n handleCellMouseMove(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseMove', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseMove', cellEvt);\n opts.onCellMouseMove?.(cellEvt);\n const rowEvt = { type: 'rowMouseMove', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseMove', rowEvt);\n opts.onRowMouseMove?.(rowEvt);\n }\n\n handleCellKeyEvt(eventName: 'cellKeyDown' | 'cellKeyUp' | 'cellKeyPress', e: KeyboardEvent): void {\n const editMgr = this._d.getEditMgr();\n if (!editMgr.focusCell || editMgr.activeEditor) return;\n const { ri, ci } = editMgr.focusCell;\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const evt = { type: eventName, rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, key: e.key, target: this._d.getContainer(), originalEvent: e };\n this._d.emit(eventName, evt);\n if (eventName === 'cellKeyDown') opts.onCellKeyDown?.(evt as any);\n else if (eventName === 'cellKeyUp') opts.onCellKeyUp?.(evt as any);\n else opts.onCellKeyPress?.(evt as any);\n }\n}\n","import type { TriggerContext, TriggerHandler, TriggerEvent } from './types.js';\n\nexport class TriggerManager {\n private _triggers = new Map<string, TriggerHandler[]>();\n\n add(event: TriggerEvent | string, handler: TriggerHandler): void {\n if (!this._triggers.has(event)) this._triggers.set(event, []);\n this._triggers.get(event)!.push(handler);\n }\n\n remove(event: TriggerEvent | string, handler: TriggerHandler): void {\n const arr = this._triggers.get(event);\n if (arr) {\n const idx = arr.indexOf(handler);\n if (idx >= 0) arr.splice(idx, 1);\n }\n }\n\n clear(event?: TriggerEvent | string): void {\n if (event) this._triggers.delete(event);\n else this._triggers.clear();\n }\n\n mkCtx(operation: string, args: any[]): TriggerContext {\n let _cancelled = false;\n return {\n operation, args, result: undefined, extra: {},\n timestamp: Date.now(),\n get cancelled() { return _cancelled; },\n cancel() { _cancelled = true; },\n };\n }\n\n exec(event: string, ctx: TriggerContext): boolean {\n const handlers = this._triggers.get(event) ?? [];\n for (const fn of handlers) {\n fn(ctx);\n if (ctx.cancelled) return false;\n }\n if (event.startsWith('after:')) {\n const completeHandlers = this._triggers.get('complete') ?? [];\n for (const fn of completeHandlers) fn(ctx);\n }\n return true;\n }\n}\n","import { EventEmitter } from './EventEmitter.js';\r\nimport { DataLayer } from './DataLayer.js';\r\nimport { VirtualScroll } from './VirtualScroll.js';\r\nimport { ColumnLayout } from './ColumnLayout.js';\r\nimport { FilterPanel } from './FilterPanel.js';\r\nimport { GridRenderer } from './GridRenderer.js';\r\nimport type { RendererCallbacks } from './GridRenderer.js';\r\nimport { RowManager } from './RowManager.js';\r\nimport { CellEditManager } from './CellEditManager.js';\r\nimport { isToggleCol } from './CellTypeRegistry.js';\r\nimport { FilterSelectPanel } from './FilterSelect.js';\r\nimport type { FilterSelectConfig } from './FilterSelect.js';\r\nimport { Pagination } from './Pagination.js';\r\nimport { RowDragDrop } from './RowDragDrop.js';\r\nimport { MergeEngine, type MergeCell } from './MergeEngine.js';\r\nimport { createRenderer } from './renderers/CellRenderer.js';\r\nimport { ContextMenuManager, DEFAULT_CONTEXT_ITEMS } from './ContextMenu.js';\r\nimport { WorksheetManager } from './WorksheetManager.js';\r\nimport { ExportManager } from './ExportManager.js';\r\nimport { FooterManager } from './FooterManager.js';\r\nimport { KeyboardManager } from './KeyboardManager.js';\r\nimport { FindBarManager } from './FindBarManager.js';\r\nimport { GroupTreeManager } from './GroupTreeManager.js';\r\nimport { SortFilterManager } from './SortFilterManager.js';\r\nimport { CellEventHandler } from './CellEventHandler.js';\r\nimport { TriggerManager } from './TriggerManager.js';\r\nimport type {\r\n GridOptions, OpenGridInstance, ColumnDef,\r\n SortItem, FilterItem, ExportOptions,\r\n EditEvent, Position,\r\n TriggerContext, TriggerHandler, TriggerEvent,\r\n} from './types.js';\r\n\r\nconst ROW_ID_FIELD = '_ogRowId';\r\n\r\nexport class OpenGrid<T extends Record<string, any> = any>\r\n extends EventEmitter\r\n implements OpenGridInstance<T>\r\n{\r\n private _container: HTMLElement;\r\n private _options: Required<GridOptions<T>>;\r\n private _data: DataLayer<T>;\r\n private _colLayout: ColumnLayout<T>;\r\n private _vs: VirtualScroll | null = null;\r\n private _ro: ResizeObserver | null = null;\r\n private _renderer: GridRenderer | null = null;\r\n private _sfMgr!: SortFilterManager<T>;\r\n private _rowMgr!: RowManager<T>;\r\n private _editMgr!: CellEditManager<T>;\r\n private _trigMgr = new TriggerManager();\r\n private _destroyed = false;\r\n private _colWidths: number[] = [];\r\n private _filterPanel: FilterPanel | null = null;\r\n private _filterSelect: FilterSelectPanel | null = null;\r\n private _pagination: Pagination | null = null;\r\n private _dnd: RowDragDrop | null = null;\r\n private _mergeEngine: MergeEngine = new MergeEngine();\r\n private _liveRegion: HTMLElement | null = null;\r\n private _ctxMenu: ContextMenuManager | null = null;\r\n private _cmHandler: ((e: MouseEvent) => void) | null = null;\r\n private _cmKbdHandler: ((e: KeyboardEvent) => void) | null = null;\r\n private _wsManager: WorksheetManager<T> | null = null;\r\n // 분리된 매니저들\r\n private _exportMgr!: ExportManager<T>;\r\n private _footerMgr!: FooterManager<T>;\r\n private _kbdMgr!: KeyboardManager<T>;\r\n private _findMgr!: FindBarManager<T>;\r\n private _grpMgr!: GroupTreeManager<T>;\r\n private _cellEvt!: CellEventHandler<T>;\r\n\r\n constructor(container: string | HTMLElement, options: GridOptions<T>) {\r\n super();\r\n const el = typeof container === 'string'\r\n ? (document.querySelector(container) as HTMLElement)\r\n : container;\r\n if (!el) throw new Error(`OpenGrid: container not found: ${container}`);\r\n this._container = el;\r\n\r\n this._options = {\r\n height: '100%', width: '100%',\r\n rowHeight: 32, headerHeight: 34, footerHeight: 30,\r\n autoHeight: false, fillWidth: false, defaultColumnWidth: 100,\r\n editable: false, editMode: 'dblclick', history: true, historySize: 100,\r\n selection: 'single', clipboard: true,\r\n sortable: true, multiSort: true, filterable: true, defaultSort: [],\r\n frozenColumns: 0, frozenRows: 0,\r\n rowNumber: false, stateColumn: false, checkColumn: false, draggable: false,\r\n mergeCells: false, groupBy: [], summary: undefined as any,\r\n treeMode: 'auto', treeId: 'id', treeParentId: 'parentId', expandOnLoad: false,\r\n pagination: false, pageSize: 50,\r\n footer: undefined as any, footerPosition: 'bottom',\r\n theme: 'default', cssVars: {}, ariaLabel: 'OPEN_GRID 데이터 그리드',\r\n ...options\r\n } as Required<GridOptions<T>>;\r\n\r\n this._data = new DataLayer<T>(ROW_ID_FIELD);\r\n this._rowMgr = new RowManager<T>(this._data);\r\n this._colLayout = new ColumnLayout<T>(this._options.columns, this._options.frozenColumns);\r\n this._editMgr = new CellEditManager<T>({\r\n data: this._data,\r\n colLayout: this._colLayout,\r\n getRenderer: () => this._renderer,\r\n getContainer: () => this._container,\r\n getOptions: () => this._options,\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n doRender: () => this._doRender(...this._visRange()),\r\n announce: (msg) => this._announce(msg),\r\n writeCell: (ri, field, value) => this.writeCell(ri, field, value),\r\n scrollToRow: (ri) => this._vs?.scrollToRow(ri),\r\n getVisibleLeaves: () => this._colLayout.visibleLeaves,\r\n });\r\n\r\n this._exportMgr = new ExportManager<T>({\r\n getData: () => this._data.getData(),\r\n getColLayout: () => this._colLayout,\r\n getColWidths: () => this._colWidths,\r\n getOptions: () => this._options,\r\n getContainer: () => this._container,\r\n getMaskEnabled: (field) => this.getMaskEnabled(field),\r\n getWsManager: () => this._wsManager,\r\n });\r\n this._footerMgr = new FooterManager<T>({\r\n getData: () => this._data.getData(),\r\n getColLayout: () => this._colLayout,\r\n getColWidths: () => this._colWidths,\r\n getOptions: () => this._options,\r\n getContainer: () => this._container,\r\n });\r\n this._kbdMgr = new KeyboardManager<T>({\r\n getEditMgr: () => this._editMgr,\r\n getRowMgr: () => this._rowMgr,\r\n getData: () => this._data,\r\n getColLayout: () => this._colLayout,\r\n getOptions: () => this._options,\r\n setFocusCell: (ri, ci) => this._setFocusCell(ri, ci),\r\n handleRowDrop: (from, to) => this._handleRowDrop(from, to),\r\n doRender: () => this._doRender(...this._visRange()),\r\n announce: (msg) => this._announce(msg),\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n visRange: () => this._visRange(),\r\n handleCellKeyEvt: (name, e) => this._handleCellKeyEvt(name, e),\r\n });\r\n this._sfMgr = new SortFilterManager<T>({\r\n getData: () => this._data,\r\n getColLayout: () => this._colLayout,\r\n getFindFilter: () => this._findMgr.findFilter,\r\n getVs: () => this._vs,\r\n getPagination: () => this._pagination,\r\n getOptions: () => this._options,\r\n renderHeader: () => this._renderHeader(),\r\n doRender: () => this._doRender(...this._visRange()),\r\n announce: (msg) => this._announce(msg),\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n });\r\n this._findMgr = new FindBarManager<T>({\r\n getColLayout: () => this._colLayout,\r\n getData: () => this._data,\r\n getFilters: () => this._sfMgr.filters,\r\n getVs: () => this._vs,\r\n getPagination: () => this._pagination,\r\n doRender: () => this._doRender(...this._visRange()),\r\n });\r\n this._cellEvt = new CellEventHandler<T>({\r\n getData: () => this._data,\r\n getColLayout: () => this._colLayout,\r\n getOptions: () => this._options,\r\n getEditMgr: () => this._editMgr,\r\n getRowMgr: () => this._rowMgr,\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n writeCell: (ri, field, val) => this.writeCell(ri, field, val),\r\n doRender: () => this._doRender(...this._visRange()),\r\n getContainer: () => this._container,\r\n });\r\n this._grpMgr = new GroupTreeManager<T>({\r\n getData: () => this._data.getData(),\r\n getDataLayer: () => this._data,\r\n getOptions: () => this._options,\r\n getVs: () => this._vs,\r\n doRenderFull: (n) => this._doRender(0, n - 1),\r\n doRender: () => this._doRender(...this._visRange()),\r\n });\r\n\r\n this._mount();\r\n this._bindOptionEvents();\r\n\r\n if (this._options.defaultSort?.length) {\r\n this._sfMgr.initSort(this._options.defaultSort);\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n this.emit('ready', this);\r\n this._options.onReady?.(this);\r\n });\r\n }\r\n private _mount(): void {\r\n this._container.classList.add('og-container');\r\n const h = this._options.height;\r\n const w = this._options.width;\r\n this._container.style.height = typeof h === 'number' ? `${h}px` : String(h);\r\n this._container.style.width = typeof w === 'number' ? `${w}px` : String(w);\r\n this._container.style.display = 'flex';\r\n this._container.style.flexDirection = 'column';\r\n this._container.style.overflow = 'hidden';\r\n this._container.style.boxSizing = 'border-box';\r\n this._container.style.border = '1px solid var(--og-border-color, #e0e0e0)';\r\n this._container.style.fontFamily = 'var(--og-font-family, -apple-system, sans-serif)';\r\n this._container.style.fontSize = 'var(--og-font-size, 13px)';\r\n this._container.setAttribute('data-og-theme', this._options.theme);\r\n\r\n for (const [k, v] of Object.entries(this._options.cssVars))\r\n this._container.style.setProperty(k, v);\r\n\r\n this._renderer = new GridRenderer(this._container, this._options, {\r\n onHeaderClick: (field, shiftKey) => this._handleSortClick(field, shiftKey),\r\n onCellClick: (ri, ci, e) => this._handleCellClick(ri, ci, e),\r\n onCellDblClick: (ri, ci, e) => this._handleCellDblClick(ri, ci, e),\r\n onCellMouseOver: (ri, ci, e) => this._handleCellMouseOver(ri, ci, e),\r\n onCellMouseOut: (ri, ci, e) => this._handleCellMouseOut(ri, ci, e),\r\n onCellMouseDown: (ri, ci, e) => this._handleCellMouseDown(ri, ci, e),\r\n onCellMouseUp: (ri, ci, e) => this._handleCellMouseUp(ri, ci, e),\r\n onCellMouseMove: (ri, ci, e) => this._handleCellMouseMove(ri, ci, e),\r\n onRowCheck: (ri, checked) => this._handleRowCheck(ri, checked),\r\n onAllCheck: (checked) => this._handleAllCheck(checked),\r\n onColResize: (ci, w) => this._handleColResize(ci, w),\r\n onFilterIconClick: (field, anchorEl) => this._handleFilterIconClick(field, anchorEl),\r\n getDndManager: () => this._dnd,\r\n onColDragStart: (ci) => { this._editMgr.dragColIdx = ci; },\r\n onColDrop: (toIdx) => {\r\n if (this._editMgr.dragColIdx !== null && this._editMgr.dragColIdx !== toIdx) {\r\n this._reorderColumn(this._editMgr.dragColIdx, toIdx);\r\n }\r\n this._editMgr.dragColIdx = null;\r\n },\r\n getColDragIdx: () => this._editMgr.dragColIdx,\r\n });\r\n\r\n this._filterPanel = new FilterPanel(\r\n this._container,\r\n (field, items) => this.setFilter(field, items),\r\n (field) => this.resetFilter(field)\r\n );\r\n // 웹 접근성 속성 설정 (role, aria 레이블, 행/열 수 알림)\r\n // ?묎렐?? role, aria-label, aria-rowcount, aria-colcount\r\n this._container.setAttribute('role', 'grid');\r\n this._container.setAttribute('aria-label', this._options.ariaLabel ?? this._options.cssVars?.['aria-label'] ?? 'OPEN_GRID 데이터 그리드');\r\n this._container.setAttribute('aria-rowcount', '0');\r\n this._container.setAttribute('aria-colcount', String(this._options.columns.filter(c => !c.hidden).length));\r\n // aria-live 영역: 스크린리더에게 상태 변화를 알린다\r\n this._liveRegion = document.createElement('div');\r\n this._liveRegion.setAttribute('aria-live', 'polite');\r\n this._liveRegion.setAttribute('aria-atomic', 'true');\r\n this._liveRegion.className = 'og-live-region';\r\n this._container.insertAdjacentElement('beforebegin', this._liveRegion);\r\n // 키보드로 그리드를 조작할 수 있도록 tabIndex 설정\r\n this._container.tabIndex = 0;\r\n this._container.addEventListener('keydown', (e) => this._handleKeyDown(e));\r\n this._container.addEventListener('keyup', (e) => this._handleCellKeyEvt('cellKeyUp', e));\r\n this._container.addEventListener('keypress', (e) => this._handleCellKeyEvt('cellKeyPress', e));\r\n\r\n this._vs = new VirtualScroll(this._renderer.bodyWrapper, {\r\n rowHeight: this._options.rowHeight,\r\n onRender: (s, e) => this._doRender(s, e),\r\n });\r\n\r\n if (this._options.draggable) {\r\n this._dnd = new RowDragDrop(\r\n this._renderer.bodyWrapper,\r\n this._options.rowHeight,\r\n (from, to) => this._handleRowDrop(from, to)\r\n );\r\n }\r\n // 스크롤 영역, 페이징 바 등 하단 UI 초기화\r\n // ?섏씠吏?UI (?듭뀡?먯꽌 pagination:true???뚮쭔)\r\n if (this._options.pagination) {\r\n this._pagination = new Pagination(\r\n this._container,\r\n this._options.pageSize,\r\n (e) => {\r\n this.emit('pageChange', e);\r\n this._doRender(...this._visRange());\r\n }\r\n );\r\n }\r\n // 찾기 바 초기화 (헤더 위에 삽입)\r\n this._findMgr.init(this._container);\r\n // 오른쪽 클릭 메뉴 초기화\r\n this._initContextMenu();\r\n // 워크시트(탭) 초기화\r\n if (this._options.worksheets?.length) {\r\n this._initWorksheets();\r\n }\r\n\r\n this._ro = new ResizeObserver(() => this._onResize());\r\n this._ro.observe(this._container);\r\n this._onResize();\r\n }\r\n\r\n private _initContextMenu(): void {\r\n const opt = this._options.contextMenu;\r\n if (opt === false) return;\r\n\r\n // 기존 핸들러 제거 — setOptions 재호출 시 중복 등록 방지\r\n if (this._cmHandler) this._container.removeEventListener('contextmenu', this._cmHandler);\r\n if (this._cmKbdHandler) this._container.removeEventListener('keydown', this._cmKbdHandler);\r\n this._cmHandler = this._cmKbdHandler = null;\r\n\r\n this._ctxMenu = new ContextMenuManager(this._container, {\r\n onSortAsc: () => {\r\n const active = this._colLayout.visibleLeaves[0];\r\n if (active) this.orderBy(active.field, 'asc');\r\n },\r\n onSortDesc: () => {\r\n const active = this._colLayout.visibleLeaves[0];\r\n if (active) this.orderBy(active.field, 'desc');\r\n },\r\n onFind: () => this._findMgr.open(),\r\n onExcel: () => this.exportExcel(),\r\n onCsv: () => this.exportCsv(),\r\n onPrint: () => this.print(),\r\n });\r\n\r\n this._cmHandler = (e: MouseEvent) => {\r\n const cell = (e.target as HTMLElement).closest<HTMLElement>('.og-cell');\r\n if (!cell) return;\r\n e.preventDefault();\r\n\r\n const colIdx = Number(cell.dataset.colIndex ?? -1);\r\n const col = this._colLayout.visibleLeaves[colIdx];\r\n\r\n if (col && this._ctxMenu) {\r\n this._ctxMenu['_actions'].onSortAsc = () => this.orderBy(col.field, 'asc');\r\n this._ctxMenu['_actions'].onSortDesc = () => this.orderBy(col.field, 'desc');\r\n }\r\n\r\n // 사용자 정의 메뉴는 단독 표시 (기본 메뉴와 합치지 않음)\r\n const customItems = Array.isArray(opt) ? opt : undefined;\r\n this._ctxMenu?.open(e, customItems);\r\n };\r\n this._container.addEventListener('contextmenu', this._cmHandler);\r\n\r\n this._cmKbdHandler = (e: KeyboardEvent) => {\r\n if (e.shiftKey && e.key === 'F10') {\r\n e.preventDefault();\r\n const rect = this._container.getBoundingClientRect();\r\n const fakeEvent = { clientX: rect.left + 80, clientY: rect.top + 40 } as MouseEvent;\r\n this._ctxMenu?.open(fakeEvent);\r\n }\r\n };\r\n this._container.addEventListener('keydown', this._cmKbdHandler);\r\n }\r\n // openContextMenu / closeContextMenu 공개 API\r\n openContextMenu(e: MouseEvent, items?: import('./types').ContextMenuItem[]): void {\r\n this._ctxMenu?.open(e, items);\r\n }\r\n closeContextMenu(): void {\r\n this._ctxMenu?.close();\r\n }\r\n setFilterSelect(config: FilterSelectConfig | null): void {\r\n this._filterSelect?.destroy();\r\n this._filterSelect = null;\r\n if (!config) return;\r\n if (!this._container.id) {\r\n this._container.id = `og-${Math.random().toString(36).slice(2, 7)}`;\r\n }\r\n this._filterSelect = new FilterSelectPanel(\r\n this._container, config,\r\n (field, items) => this.setFilter(field, items),\r\n (field?) => this.resetFilter(field),\r\n this._container.id\r\n );\r\n }\r\n // 옵션을 런타임에 바꿀 때 호출 (contextMenu 재초기화, groupBy 재구성 등)\r\n setOptions(opts: Partial<GridOptions<T>>): void {\r\n Object.assign(this._options, opts);\r\n if ('contextMenu' in opts) {\r\n this._ctxMenu?.destroy();\r\n this._ctxMenu = null;\r\n this._initContextMenu();\r\n }\r\n // groupBy / summary 변경 시 그룹 재구성\r\n if ('groupBy' in opts || 'summary' in opts) {\r\n const fields = (opts.groupBy ?? []) as string[];\r\n if (fields.length > 0) {\r\n this._grpMgr.groupBy(fields);\r\n } else {\r\n this.clearGroup();\r\n }\r\n return;\r\n }\r\n this._renderHeader();\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n /**\r\n * 컬럼 마스킹 ON/OFF 전환.\r\n * enabled=true → 마스킹 적용 (기본 상태)\r\n * enabled=false → 컬럼 전체 마스킹 해제 (원문 표시)\r\n */\r\n setMaskEnabled(field: string, enabled: boolean): void {\r\n const col = this._colLayout.getColumnByField(field) as any;\r\n if (!col) return;\r\n if (enabled) {\r\n // 마스킹 재활성화: 해제 상태 초기화\r\n col._maskRevealed = false;\r\n (col._maskRevealedRows as Set<number> | undefined)?.clear();\r\n } else {\r\n // 전체 해제\r\n col._maskRevealed = true;\r\n }\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n /** 현재 컬럼 마스킹 활성 여부 반환. true=마스킹 중, false=해제됨 */\r\n getMaskEnabled(field: string): boolean {\r\n const col = this._colLayout.getColumnByField(field) as any;\r\n if (!col) return false;\r\n return col._maskRevealed !== true;\r\n }\r\n private _initWorksheets(): void {\r\n const sheets = this._options.worksheets!;\r\n this._wsManager = new WorksheetManager<T>(\r\n this._container,\r\n (_name, state) => {\r\n // 탭을 전환할 때 데이터와 컬럼을 업데이트한다\r\n this._data.setData(state.data);\r\n this._colLayout = new ColumnLayout<T>(\r\n state.columns.length ? state.columns : this._options.columns,\r\n this._options.frozenColumns,\r\n );\r\n this._doRender(...this._visRange());\r\n this._renderHeader();\r\n }\r\n );\r\n for (const sheet of sheets) {\r\n this._wsManager.add(sheet.name, sheet.columns ?? this._options.columns, sheet.data ?? []);\r\n }\r\n }\r\n\r\n addWorksheet(name: string, columns?: import('./types').ColumnDef<T>[], data?: T[]): void {\r\n if (!this._wsManager) {\r\n this._wsManager = new WorksheetManager<T>(\r\n this._container,\r\n (_n, state) => {\r\n this._data.setData(state.data);\r\n this._colLayout = new ColumnLayout<T>(\r\n state.columns.length ? state.columns : this._options.columns,\r\n this._options.frozenColumns,\r\n );\r\n this._doRender(...this._visRange());\r\n this._renderHeader();\r\n }\r\n );\r\n }\r\n this._wsManager.add(name, columns ?? this._options.columns, data ?? []);\r\n }\r\n\r\n removeWorksheet(name: string): void {\r\n this._wsManager?.remove(name);\r\n }\r\n\r\n switchWorksheet(name: string): void {\r\n this._wsManager?.switch(name);\r\n }\r\n\r\n renameWorksheet(oldName: string, newName: string): void {\r\n this._wsManager?.rename(oldName, newName);\r\n }\r\n\r\n getWorksheet(name: string): import('./types').WorksheetState<T> | undefined {\r\n return this._wsManager?.get(name);\r\n }\r\n\r\n getWorksheetNames(): string[] {\r\n return this._wsManager?.getNames() ?? [];\r\n }\r\n\r\n exportSheetsExcel(filename?: string): void { this._exportMgr.exportSheetsExcel(filename); }\r\n\r\n private _paginationHeight(): number {\r\n return this._options.pagination ? 38 : 0;\r\n }\r\n\r\n private _onResize(): void {\r\n const { width, height } = this._container.getBoundingClientRect();\r\n if (!width) return;\r\n const bodyH = height - this._options.headerHeight - this._paginationHeight();\r\n this._renderer!.updateSize(height - this._paginationHeight(), this._options.headerHeight);\r\n this._vs!.setViewportHeight(bodyH);\r\n this._recalcWidths(width);\r\n this._renderHeader();\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n private _recalcWidths(totalWidth: number): void {\r\n this._colWidths = this._colLayout.computeWidths(\r\n totalWidth\r\n - (this._options.stateColumn ? 24 : 0)\r\n - (this._options.draggable ? 18 : 0)\r\n - (this._options.rowNumber ? 44 : 0)\r\n - (this._options.checkColumn ? 36 : 0),\r\n this._options.defaultColumnWidth\r\n );\r\n }\r\n // 헤더(컬럼 제목 행)를 다시 그린다\r\n private _renderHeader(): void {\r\n this._renderer?.renderHeader(\r\n this._colLayout.buildHeaderCells(),\r\n this._colLayout.visibleLeaves,\r\n this._colWidths,\r\n this._sfMgr.sortList,\r\n { ...this._options, _activeFilters: this._sfMgr.filters, _frozenCount: this._colLayout.frozenCount }\r\n );\r\n }\r\n private _doRender(startIndex: number, endIndex: number): void {\r\n if (!this._renderer || !this._vs) return;\r\n const range = this._vs.getVisibleRange();\r\n this._renderer.renderBody(\r\n startIndex, endIndex,\r\n this._data,\r\n this._colLayout.visibleLeaves,\r\n this._colWidths,\r\n this._options,\r\n range.offsetY,\r\n this._vs.getTotalHeight(),\r\n this._rowMgr.selectedRows,\r\n this._rowMgr.checkedRows,\r\n this._grpMgr.isGroupMode ? this._grpMgr.groupFlatRows : (this._grpMgr.isTreeMode ? this._grpMgr.treeFlatRows : null),\r\n (groupKey) => this._grpMgr.handleGroupToggle(groupKey),\r\n this._grpMgr.isTreeMode ? (nodeId) => this._grpMgr.handleTreeToggle(nodeId) : undefined,\r\n { _totalRows: this._data.rowCount, _frozenCount: this._colLayout.frozenCount, _focusCell: this._editMgr.focusCell },\r\n this._mergeEngine\r\n );\r\n // 데이터가 바뀌면 푸터 합계도 다시 계산한다\r\n if (this._options.footer?.length) this._renderFooterEl();\r\n }\r\n\r\n private _handleGroupToggle(groupKey: string): void { this._grpMgr.handleGroupToggle(groupKey); }\r\n\r\n // 현재 화면에 보이는 행 범위를 반환한다\r\n private _visRange(): [number, number] {\r\n if (this._options.pagination && this._pagination) {\r\n const { start, end } = this._pagination.getRange();\r\n return [start, end];\r\n }\r\n const r = this._vs?.getVisibleRange();\r\n return [r?.startIndex ?? 0, Math.min((r?.endIndex ?? 30) + this._visCount() + 5, this._data.rowCount - 1)];\r\n }\r\n\r\n private _visCount(): number {\r\n const h = this._container.getBoundingClientRect().height;\r\n return Math.ceil((h - this._options.headerHeight - this._paginationHeight()) / this._options.rowHeight) + 5;\r\n }\r\n private _handleSortClick(field: string, shiftKey: boolean): void { this._sfMgr.handleSortClick(field, shiftKey); }\r\n\r\n private _isToggleCol(col: ColumnDef<T>): boolean { return isToggleCol(col); }\r\n private _handleCellClick(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellClick(ri, ci, e); }\r\n private _handleCellDblClick(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellDblClick(ri, ci, e); }\r\n private _handleCellMouseOver(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseOver(ri, ci, e); }\r\n private _handleCellMouseOut(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseOut(ri, ci, e); }\r\n private _handleCellMouseDown(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseDown(ri, ci, e); }\r\n private _handleCellMouseUp(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseUp(ri, ci, e); }\r\n private _handleCellMouseMove(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseMove(ri, ci, e); }\r\n private _handleCellKeyEvt(name: 'cellKeyDown' | 'cellKeyUp' | 'cellKeyPress', e: KeyboardEvent): void { this._cellEvt.handleCellKeyEvt(name, e); }\r\n\r\n private _handleRowCheck(rowIndex: number, checked: boolean): void {\r\n this._rowMgr.check(rowIndex, checked);\r\n this._doRender(...this._visRange());\r\n this.emit('rowCheck', { rowIndex, checked, row: this._data.getRowByIndex(rowIndex) });\r\n }\r\n\r\n private _handleFilterIconClick(field: string, anchorEl: HTMLElement): void {\r\n if (this._filterPanel?.isOpen) {\r\n this._filterPanel.close();\r\n return;\r\n }\r\n const current = this._sfMgr.filters[field] ?? [];\r\n this._filterPanel?.open(field, anchorEl, current);\r\n }\r\n\r\n private _handleAllCheck(checked: boolean): void {\r\n this._rowMgr.checkAll(checked, this._data.rowCount);\r\n this._doRender(...this._visRange());\r\n this.emit('allCheck', { checked });\r\n }\r\n private _handleRowDrop(fromIndex: number, toIndex: number): void {\r\n this._data.moveRow(fromIndex, toIndex);\r\n this._doRender(...this._visRange());\r\n this.emit('rowDrop', { fromIndex, toIndex });\r\n this._options.onRowDrop?.({ fromIndex, toIndex });\r\n }\r\n /** 행을 드롭으로 이동할 때 실행된다 */\r\n /** ???꾩튂 ?대룞 */\r\n reorderRow(fromIndex: number, toIndex: number): void {\r\n this._data.moveRow(fromIndex, toIndex);\r\n this._doRender(...this._visRange());\r\n }\r\n private _handleColResize(colIndex: number, newWidth: number): void {\r\n if (this._colWidths[colIndex] !== undefined) {\r\n this._colWidths[colIndex] = newWidth;\r\n }\r\n this._doRender(...this._visRange());\r\n }\r\n private _handleKeyDown(e: KeyboardEvent): void { this._kbdMgr.handleKeyDown(e); }\r\n\r\n private _setFocusCell(ri: number, ci: number): void {\r\n this._rowMgr.selectSingle(ri);\r\n this._editMgr.setFocusCell(ri, ci);\r\n }\r\n // 스크린리더에게 텍스트를 읽어준다 (aria-live)\r\n private _announce(msg: string): void {\r\n if (!this._liveRegion) return;\r\n this._liveRegion.textContent = '';\r\n setTimeout(() => { if (this._liveRegion) this._liveRegion.textContent = msg; }, 50);\r\n }\r\n\r\n private _bindOptionEvents(): void {\r\n if (this._options.onCellClick) this.on('cellClick', this._options.onCellClick);\r\n if (this._options.onCellDblClick) this.on('cellDblClick', this._options.onCellDblClick);\r\n if (this._options.onRowClick) this.on('rowClick', this._options.onRowClick);\r\n if (this._options.onEditStart) this.on('editStart', this._options.onEditStart);\r\n if (this._options.onEditEnd) this.on('editEnd', this._options.onEditEnd);\r\n if (this._options.onSortChange) this.on('sortChange', this._options.onSortChange);\r\n if (this._options.onFilterChange) this.on('filterChange', this._options.onFilterChange);\r\n if (this._options.onScroll) this.on('scroll', this._options.onScroll);\r\n if (this._options.onDataChange) this.on('dataChange', this._options.onDataChange);\r\n if (this._options.onSelectionChange) this.on('selectionChange', this._options.onSelectionChange);\r\n // Sprint 35 ?좉퇋\r\n if (this._options.onRowDblClick) this.on('rowDblClick', this._options.onRowDblClick);\r\n if (this._options.onRowMouseOver) this.on('rowMouseOver', this._options.onRowMouseOver);\r\n if (this._options.onRowMouseOut) this.on('rowMouseOut', this._options.onRowMouseOut);\r\n if (this._options.onRowMouseDown) this.on('rowMouseDown', this._options.onRowMouseDown);\r\n if (this._options.onRowMouseUp) this.on('rowMouseUp', this._options.onRowMouseUp);\r\n if (this._options.onRowMouseMove) this.on('rowMouseMove', this._options.onRowMouseMove);\r\n if (this._options.onCellMouseOver) this.on('cellMouseOver', this._options.onCellMouseOver);\r\n if (this._options.onCellMouseOut) this.on('cellMouseOut', this._options.onCellMouseOut);\r\n if (this._options.onCellMouseDown) this.on('cellMouseDown', this._options.onCellMouseDown);\r\n if (this._options.onCellMouseUp) this.on('cellMouseUp', this._options.onCellMouseUp);\r\n if (this._options.onCellMouseMove) this.on('cellMouseMove', this._options.onCellMouseMove);\r\n if (this._options.onCellKeyDown) this.on('cellKeyDown', this._options.onCellKeyDown);\r\n if (this._options.onCellKeyUp) this.on('cellKeyUp', this._options.onCellKeyUp);\r\n if (this._options.onCellKeyPress) this.on('cellKeyPress', this._options.onCellKeyPress);\r\n }\r\n setData(data: T[]): void {\r\n const ctx = this._trigMgr.mkCtx('setData', [data]);\r\n if (!this._trigMgr.exec('before:setData', ctx)) return;\r\n this._rowMgr.reset();\r\n this._data.setData(data);\r\n this._applyFilters();\r\n if (this._grpMgr.isTreeMode) {\r\n this._grpMgr.rebuildTree();\r\n } else if (this._grpMgr.isGroupMode) {\r\n this._grpMgr.rebuildGroups();\r\n } else {\r\n this._vs?.setTotalRows(this._data.rowCount);\r\n }\r\n this._container.setAttribute('aria-rowcount', String(this._data.rowCount));\r\n this._container.setAttribute('aria-colcount', String(this._colLayout.visibleLeaves.length));\r\n this._announce(`${this._data.rowCount}행 데이터 로드됨`);\r\n this.emit('dataChange', this._data.getData());\r\n ctx.result = data.length;\r\n this._trigMgr.exec('after:setData', ctx);\r\n }\r\n\r\n getData(): T[] { return this._data.getData(); }\r\n getSourceRows(): T[] { return this._data.getOriginalData(); }\r\n\r\n pushData(data: T[]): void {\r\n const combined = [...this._data.getAllData(), ...data];\r\n this._data.setData(combined);\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n }\r\n\r\n prefixData(data: T[]): void {\r\n const combined = [...data, ...this._data.getAllData()];\r\n this._data.setData(combined);\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n }\r\n\r\n clearData(): void {\r\n this._rowMgr.reset();\r\n this._data.clearData();\r\n this._vs?.setTotalRows(0);\r\n this._pagination?.setTotalRows(0);\r\n this._doRender(0, -1);\r\n this.emit('dataChange', []);\r\n }\r\n\r\n insertRow(item: Partial<T>, position: Position = 'last'): void {\r\n const ctx = this._trigMgr.mkCtx('insertRow', [item, position]);\r\n if (!this._trigMgr.exec('before:insertRow', ctx)) return;\r\n const pos = position === 'before' ? 0\r\n : position === 'after' ? this._data.rowCount\r\n : position as any;\r\n this._data.addRow(item, pos);\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n ctx.result = { rowCount: n, item };\r\n this._trigMgr.exec('after:insertRow', ctx);\r\n }\r\n\r\n pushRow(items: Partial<T> | Partial<T>[]): void {\r\n const arr = Array.isArray(items) ? items : [items];\r\n arr.forEach(it => this._data.addRow(it, 'last'));\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n }\r\n\r\n /** @deprecated 하위호환 alias → pushRow */\r\n appendRows(items: Partial<T> | Partial<T>[]): void { this.pushRow(items); }\r\n\r\n unshiftRow(items: Partial<T> | Partial<T>[]): void {\r\n const arr = Array.isArray(items) ? items : [items];\r\n arr.forEach(it => this._data.addRow(it, 'first'));\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n }\r\n\r\n /** @deprecated 하위호환 alias → unshiftRow */\r\n prependRows(items: Partial<T> | Partial<T>[]): void { this.unshiftRow(items); }\r\n\r\n deleteRow(rowIndex: number | number[]): void {\r\n const ctx = this._trigMgr.mkCtx('deleteRow', [rowIndex]);\r\n const idxArr = Array.isArray(rowIndex) ? [...rowIndex] : [rowIndex];\r\n ctx.extra = { rows: idxArr.map(i => this._data.getRowByIndex(i)) };\r\n if (!this._trigMgr.exec('before:deleteRow', ctx)) return;\r\n const idxs = idxArr.sort((a, b) => b - a);\r\n idxs.forEach(i => this._data.removeRow(i));\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n ctx.result = { deleted: idxs.length, rowCount: n };\r\n this._trigMgr.exec('after:deleteRow', ctx);\r\n }\r\n\r\n deleteById(_ids: string[]): void { /* 異뷀썑 援ы쁽 */ }\r\n\r\n readCell(rowIndex: number, field: string): any {\r\n return this._data.getCellValue(rowIndex, field);\r\n }\r\n getDisplayValue(rowIndex: number, field: string): string {\r\n const val = this.readCell(rowIndex, field);\r\n return val == null ? '' : String(val);\r\n }\r\n\r\n writeCell(rowIndex: number, field: string, value: any): void {\r\n const old = this.readCell(rowIndex, field);\r\n const ctx = this._trigMgr.mkCtx('writeCell', [rowIndex, field, value]);\r\n ctx.extra = { oldValue: old, rowIndex, field };\r\n if (!this._trigMgr.exec('before:writeCell', ctx)) return;\r\n this._data.updateCell(rowIndex, field, value);\r\n const row = this._data.getRowByIndex(rowIndex);\r\n const col = this._colLayout.getColumnByField(field);\r\n const ci = this._colLayout.getColumnIndex(field);\r\n const evt: EditEvent<T> = { type: 'editEnd', rowIndex, columnIndex: ci, field, oldValue: old, newValue: value, row: row as T, column: col as any };\r\n this.emit('editEnd', evt);\r\n this._options.onEditEnd?.(evt);\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n this._doRender(...this._visRange());\r\n ctx.result = { rowIndex, field, oldValue: old, newValue: value };\r\n this._trigMgr.exec('after:writeCell', ctx);\r\n }\r\n\r\n getRowAt(rowIndex: number): T { return this._data.getRowByIndex(rowIndex) as T; }\r\n\r\n getChanges(): { added: T[]; edited: T[]; removed: T[] } { return this._data.getChanges(); }\r\n getEditedRows(): T[] { return this._data.getEditedRows(); }\r\n getChangedRows(): T[] { return this._data.getChangedRows(); } // ?섏쐞 ?명솚\r\n getChangedColumns(): Array<{ row: T; fields: string[]; diff: Array<{ field: string; oldValue: any; newValue: any }> }> {\r\n return this._data.getChangedColumns();\r\n }\r\n getAddedRows(): T[] { return this._data.getAddedRows(); }\r\n getRemovedRows(): T[] { return this._data.getRemovedRows(); }\r\n getOriginalRow(rowIndex: number): T | undefined { return this._data.getOriginalRow(rowIndex); }\r\n getRowsWithState(stateField: string): T[] { return this._data.getRowsWithState(stateField); }\r\n undo(): void {}\r\n redo(): void {}\r\n clearHistory(): void {}\r\n getColumnDefs(): ColumnDef<T>[] { return this._colLayout.visibleLeaves; }\r\n getAllColumnDefs(): ColumnDef<T>[] { return this._colLayout.leaves; }\r\n getColumnCount(): number { return this._colLayout.visibleLeaves.length; }\r\n applyColumns(columns: ColumnDef<T>[]): void {\r\n const ctx = this._trigMgr.mkCtx('applyColumns', [columns]);\r\n if (!this._trigMgr.exec('before:applyColumns', ctx)) return;\r\n this._colLayout.setColumns(columns);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader();\r\n this._doRender(...this._visRange());\r\n ctx.result = { columnCount: columns.length };\r\n this._trigMgr.exec('after:applyColumns', ctx);\r\n }\r\n insertColumn(colDef: ColumnDef<T>, position?: Position): void {\r\n this._colLayout.addColumn(colDef, position as any);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n deleteColumn(field: string): void {\r\n this._colLayout.removeColumn(field);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n\r\n private _reorderColumn(fromIdx: number, toIdx: number): void {\r\n const leaves = this._colLayout.visibleLeaves.map(l => l as ColumnDef<T>);\r\n if (fromIdx < 0 || toIdx < 0 || fromIdx >= leaves.length || toIdx >= leaves.length) return;\r\n const reordered = [...this._options.columns];\r\n const [moved] = reordered.splice(fromIdx, 1);\r\n reordered.splice(toIdx, 0, moved);\r\n this._options.columns = reordered;\r\n this.applyColumns(reordered);\r\n this._options.onColumnReorder?.({ fromIndex: fromIdx, toIndex: toIdx, field: moved.field ?? '' });\r\n }\r\n hideColumn(field: string | string[]): void {\r\n this._colLayout.hideColumn(field);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n showColumn(field: string | string[]): void {\r\n this._colLayout.showColumn(field);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n getColumnIndex(field: string): number { return this._colLayout.getColumnIndex(field); }\r\n getFieldAt(idx: number): string { return this._colLayout.getColumnByIndex(idx)?.field ?? ''; }\r\n getColValues(field: string, _all = false): any[] { return this._data.getData().map(r => r[field]); }\r\n getUniqueValues(field: string, all = false): any[] { return [...new Set(this.getColValues(field, all))]; }\r\n setColWidths(_widths: number[]): void {}\r\n calcColWidths(_fitToGrid = false): number[] { return []; }\r\n getSelections(): T[] { return this._rowMgr.getSelections(); }\r\n getActiveRow(): number { return this._rowMgr.getActiveRow(); }\r\n activate(index: number): void { this._rowMgr.activate(index); this._doRender(...this._visRange()); }\r\n deselect(): void { this._rowMgr.deselect(); this._doRender(...this._visRange()); }\r\n getChecked(): Array<{ row: T; rowIndex: number }> { return this._rowMgr.getChecked(); }\r\n getAllChecked(): T[] { return this._rowMgr.getAllChecked(); }\r\n checkById(_ids: string[]): void {}\r\n addCheckById(_ids: string[]): void {}\r\n checkByValue(field: string, values: any[]): void {\r\n this._rowMgr.checkByValue(field, values);\r\n this._doRender(...this._visRange());\r\n }\r\n uncheckById(_ids: string[]): void {}\r\n uncheckAll(): void { this._rowMgr.uncheckAll(); this._doRender(...this._visRange()); }\r\n orderBy(fieldOrList: string | SortItem[], dir: 'asc' | 'desc' = 'asc'): void {\r\n const ctx = this._trigMgr.mkCtx('orderBy', [fieldOrList, dir]);\r\n if (!this._trigMgr.exec('before:orderBy', ctx)) return;\r\n this._sfMgr.sort(fieldOrList, dir);\r\n ctx.result = { sortList: this._sfMgr.sortList };\r\n this._trigMgr.exec('after:orderBy', ctx);\r\n }\r\n resetOrder(): void { this._sfMgr.resetSort(); }\r\n setFilter(field: string, filterItems: FilterItem[]): void {\r\n const ctx = this._trigMgr.mkCtx('setFilter', [field, filterItems]);\r\n if (!this._trigMgr.exec('before:setFilter', ctx)) return;\r\n this._sfMgr.setFilter(field, filterItems);\r\n ctx.result = { field, filteredCount: this._data.rowCount };\r\n this._trigMgr.exec('after:setFilter', ctx);\r\n }\r\n resetFilter(field?: string): void { this._sfMgr.resetFilter(field); }\r\n getFilterState(): Record<string, FilterItem[]> { return this._sfMgr.getFilterState(); }\r\n restoreFilter(state: Record<string, FilterItem[]>): void { this._sfMgr.restoreFilter(state); }\r\n private _applyFilters(): void { this._sfMgr.applyFilters(); }\r\n freeze(n: number): void { this._colLayout.setFrozen(n); this._renderHeader(); this._doRender(...this._visRange()); }\r\n /** ?섎룞 蹂묓빀: [{row, col, rowSpan?, colSpan?}] */\r\n mergeCells(cells: MergeCell[]): void {\r\n this._mergeEngine.applyMergeCells(cells);\r\n this._doRender(...this._visRange());\r\n }\r\n /** 자동 병합: 지정 필드 컬럼에서 연속 같은 값을 rowSpan으로 묶는다 */\r\n /** ?먮룞 蹂묓빀: 吏€??field 而щ읆?먯꽌 ?곗냽 媛숈? 媛믪쓣 rowSpan */\r\n autoMerge(fields: string[]): void {\r\n const leaves = this._colLayout.visibleLeaves;\r\n const colIndexes: number[] = [];\r\n const fieldNames: string[] = [];\r\n for (const f of fields) {\r\n const ci = leaves.findIndex(l => l.field === f);\r\n if (ci >= 0) { colIndexes.push(ci); fieldNames.push(f); }\r\n }\r\n this._mergeEngine.applyAutoMerge(this._data.getData(), colIndexes, fieldNames);\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n /** 蹂묓빀 ?댁젣 */\r\n clearMerge(): void {\r\n this._mergeEngine.clear();\r\n this._doRender(...this._visRange());\r\n }\r\n freezeRows(_n: number): void {}\r\n groupBy(fields: string[]): void {\r\n const ctx = this._trigMgr.mkCtx('groupBy', [fields]);\r\n if (!this._trigMgr.exec('before:groupBy', ctx)) return;\r\n this._grpMgr.groupBy(fields);\r\n ctx.result = { fields };\r\n this._trigMgr.exec('after:groupBy', ctx);\r\n }\r\n clearGroup(): void { this._grpMgr.clearGroup(); }\r\n expandAll(): void { this._grpMgr.expandAll(); }\r\n collapseAll(): void { this._grpMgr.collapseAll(); }\r\n enableTree(): void { this._grpMgr.enableTree(); }\r\n disableTree(): void { this._grpMgr.disableTree(); }\r\n expandNodes(ids: any | any[], open = true): void { this._grpMgr.expandNodes(ids, open); }\r\n expandAllNodes(): void { this._grpMgr.expandAllNodes(); }\r\n collapseAllNodes(): void { this._grpMgr.collapseAllNodes(); }\r\n addTreeRow(_item: Partial<T>, _pid: string, _pos?: Position): void {}\r\n exportExcel(options?: ExportOptions | string): void { this._exportMgr.exportExcel(options); }\r\n exportCsv(options?: ExportOptions | string): void { this._exportMgr.exportCsv(options); }\r\n exportJson(options?: ExportOptions | string): void { this._exportMgr.exportJson(options); }\r\n print(options?: { title?: string; excludeFields?: string[] }): void { this._exportMgr.print(options); }\r\n\r\n toArray(keyValue = true): any[] {\r\n const data = this._data.getData();\r\n if (keyValue) return data;\r\n const cols = this._colLayout.visibleLeaves;\r\n return data.map(row => cols.map(c => row[c.field]));\r\n }\r\n jumpToRow(rowIndex: number): void {\r\n this._rowMgr.selectSingle(rowIndex);\r\n this._vs?.scrollToRow(rowIndex);\r\n this._doRender(...this._visRange());\r\n }\r\n jumpToCol(_field: string): void {}\r\n getScrollPos(): { x: number; y: number } {\r\n return { x: this._renderer?.bodyWrapper.scrollLeft ?? 0, y: this._renderer?.bodyWrapper.scrollTop ?? 0 };\r\n }\r\n setFooter(fd: any[]): void {\r\n this._options.footer = fd as any;\r\n this._renderFooterEl();\r\n }\r\n getFooterData(): any[] { return this._footerMgr.computeValues(); }\r\n getFooterValue(field: string): any {\r\n return this._footerMgr.computeValues().find((r: any) => r._field === field)?._value ?? null;\r\n }\r\n private _renderFooterEl(): void { this._footerMgr.render(); }\r\n\r\n resize(w?: number, h?: number): void {\r\n if (w) this._container.style.width = `${w}px`;\r\n if (h) this._container.style.height = `${h}px`;\r\n this._onResize();\r\n }\r\n setTheme(theme: string): void { this._container.setAttribute('data-og-theme', theme); }\r\n setThemeVar(k: string, v: string): void { this._container.style.setProperty(k, v); }\r\n addTrigger(event: TriggerEvent | string, handler: TriggerHandler): this {\r\n this._trigMgr.add(event, handler); return this;\r\n }\r\n removeTrigger(event: TriggerEvent | string, handler: TriggerHandler): this {\r\n this._trigMgr.remove(event, handler); return this;\r\n }\r\n clearTriggers(event?: TriggerEvent | string): this {\r\n this._trigMgr.clear(event); return this;\r\n }\r\n private _mkCtx(operation: string, args: any[]): TriggerContext { return this._trigMgr.mkCtx(operation, args); }\r\n private _trig(event: string, ctx: TriggerContext): boolean { return this._trigMgr.exec(event, ctx); }\r\n\r\n destroy(): void {\r\n if (this._destroyed) return;\r\n this._destroyed = true;\r\n this._trigMgr.clear();\r\n this._ro?.disconnect();\r\n this._vs?.destroy();\r\n this._filterPanel?.destroy();\r\n this._dnd?.destroy();\r\n if (this._cmHandler) this._container.removeEventListener('contextmenu', this._cmHandler);\r\n if (this._cmKbdHandler) this._container.removeEventListener('keydown', this._cmKbdHandler);\r\n this._cmHandler = this._cmKbdHandler = null;\r\n this._ctxMenu?.destroy();\r\n this._wsManager?.destroy();\r\n this._renderer?.destroy();\r\n this._liveRegion?.remove();\r\n this._liveRegion = null;\r\n this._container.innerHTML = '';\r\n this._container.classList.remove('og-container');\r\n this.removeAllListeners();\r\n }\r\n}\r\n\r\n\r\n"],"names":["EventEmitter","event","handler","list","filtered","e","args","remaining","entry","_a","_rowIdSeq","nextRowId","DataLayer","idField","data","row","id","item","r","_","i","position","idx","dispPos","dataIdx","rowIndex","meta","fromDisplayIdx","toDisplayIdx","fromDataIdx","toDataIdx","insertAt","field","value","added","edited","removed","state","orig","changedFields","k","diff","key","d","stateField","sortList","notRemoved","_b","keyed","s","a","b","si","dir","av","bv","cmp","sa","sb","filters","fields","val","matchFilter","fi","q","f","v","query","fv","VirtualScroll","container","options","range","visibleCount","startIndex","endIndex","offsetY","count","height","targetTop","targetBottom","viewBottom","newTop","spacer","ColumnLayout","columns","frozenCount","leaves","colIndex","walk","cols","depth","col","c","colDef","removeFromList","index","rows","span","childSpan","totalWidth","defaultWidth","visible","flexCols","fixedTotal","sum","flexTotal","FilterPanel","onApply","onClear","anchorEl","currentFilters","title","condRow","condSel","conditions","opt","valueInput","applyBtn","btnRow","clearBtn","rect","containerRect","DEFAULT_PREC","round","precision","factor","OGDecimal","coefficient","scale","str","isNeg","abs","dot","coeff","frac","other","ac","bc","o","result","dp","divisor","half","abs_c","rem","rounded","digits","intPart","fracPart","arr","acc","evaluateFormula","expr","ctx","divisionPrecision","_FormulaParser","src","_ctx","_prec","left","ch","right","start","numStr","applyMask","maskDef","def","char","_maskSSN","_maskPhone","_maskEmail","_maskCredit","_maskAccount","_maskName","_maskIP","_maskPartial","clean","sep","frontEnd","front","backFirst","maskLen","atIdx","local","domain","visLen","first4","last4","midLen","mid","parts","chunk","prefixLen","suffixLen","prefix","suffix","maskOctet","octet","resolveFormula","prec","formatNumber","format","num","decimals","formatDate","y","m","day","_renderMasked","original","masked","wrap","text","eye","TextRenderer","formulaResult","column","displayText","colRevealed","rowRevealed","SelectRenderer","opts","fn","rawVal","vs","found","NumberRenderer","DateRenderer","CheckboxRenderer","chk","ButtonRenderer","_c","btn","label","BadgeRenderer","colorMap","labelMap","badge","color","LinkRenderer","hrefFn","target","TemplateRenderer","templateFn","ImageRenderer","_d","_e","img","w","h","alt","ProgressRenderer","max","raw","pct","track","fill","lbl","SparklineRenderer","values","W","H","chartType","canvas","min","n","bw","bh","pts","p","SwitchRenderer","on","sw","knob","RatingRenderer","star","RadioRenderer","radio","ImgRenderer","_sanitizeHtml","html","div","el","attr","href","HtmlRenderer","doSanitize","_C128W","_C128_STOP","_c128Bits","out","bar","_encodeC128B","codes","BarcodeRenderer","_barcodeSvg","bits","MW","QZ","TW","rects","x","createRenderer","renderer","GridRenderer","root","cbs","_el","totalHeight","headerHeight","headerRows","widths","_extraW","totalColWidth","table","extraRows","extraHeaderLeft","addExtraCol","tr","extraClass","th","_style","ri","allChk","cell","leafIdx","l","sortInfo","sortable","next","prev","leftOff","icon","filterIcon","hasFilter","resizer","capturedLeafIdx","_addResizer","fromIdx","selectedRows","checkedRows","groupFlatRows","onGroupToggle","onTreeToggle","extraOpts","mergeEngine","_ew","_totalCW","frag","flatItem","isGroupRow","isTreeRow","g","groupKey","rowEl","top","extraW","stCell","st","labelPlaced","ci","hasSummary","fmt","arrow","treeNode","rowData","rowState","bg","localRowRi","colMap","extraBodyLeft","icons","colors","dnd","handle","numCell","chkCell","isEditable","isFirstCol","mergeInfo","ph","cellEl","rs","cs","mergedHeight","mergedWidth","dc","isFrozenCell","frozenLeftOff","_rawVal","_treeRenderTarget","treeCell","hasMoreChain","guide","conn","toggleWrap","nodeIcon","iconCls","_resolveTreeIcon","rendered","localRi","localCi","pc","rowTop","empty","hasChildren","expanded","tag","className","styles","_downloadText","content","filename","mime","blob","url","onChange","startX","startW","onMove","ev","onUp","RowManager","checked","totalRows","_ids","DateEditor","onCommit","onCancel","normalizeOptions","SelectEditor","optionsFn","resolved","cur","TextEditor","NumberEditor","CheckboxEditor","_onCancel","createEditor","editor","isToggleCol","rendType","CellEditManager","deps","startEvt","cancel","old","evt","FilterSelectPanel","config","onFilter","onReset","gridId","legend","uid","select","parentValue","vk","tk","enabled","all","fk","parentField","sel","Pagination","pageSize","size","page","end","total","sizeWrap","sizeLabel","sizeSel","info","mkBtn","disabled","_pageRange","current","pages","RowDragDrop","bodyEl","rowHeight","onDrop","fromIndex","ghost","indicator","dy","ghostRect","bodyRect","relY","targetIdx","indicatorY","currentTarget","ghostEl","MergeEngine","cells","mc","colIndexes","spanStart","prevVal","curVal","DEFAULT_CONTEXT_ITEMS","ContextMenuManager","_anchor","_actions","customItems","items","menu","hr","ic","themeEl","theme","focused","onPositioned","width","vw","vh","btns","WorksheetManager","onSwitch","name","wasActive","oldName","newName","entries","tab","addBtn","input","commit","ExportManager","hex","rgbMatch","fname","sheetName","includeHeader","utils","writeFile","ws","colWidths","colLayout","styleMode","hdrBgRgb","hdrFgRgb","rowBgRgb","rowAltRgb","rowFgRgb","borderRgb","fontSize","toRgb","fsStr","noStyle","S","isHdr","isEven","_v","addr","isNum","hAlign","wb","hdr","footerText","headerRow","bodyRows","footerHtml","win","wsManager","FooterManager","useComma","dpMatch","fixed","decPart","intStr","footerDefs","allData","op","nums","opUC","cnt","numVal","formatted","valMap","leafCursor","colspan","cellW","targetLeaf","displayVal","KeyboardManager","editMgr","totalCols","nextRi","step","rowMgr","lines","dr","targetRi","targetCi","FindBarManager","closeBtn","_isGroup","buildGroups","summaryDefs","expandedKeys","getRowState","_groupByFields","parentKey","map","children","summary","summaryFmt","_calcSummary","states","_calcStates","defs","vals","_fmtNum","flattenGroups","groups","child","collectAllKeys","keys","nested","buildTree","parentIdField","expandOnLoad","nodeMap","roots","node","pid","parent","assignDepth","nodes","_countDescendants","assignLineMeta","parentHasMoreChain","isLast","flattenTree","toggleTreeNode","nodeId","collectAllTreeIds","ids","GroupTreeManager","dl","getState","temp","open","ops","SortFilterManager","shiftKey","sortedItem","dirLabel","fieldOrList","filterItems","CellEventHandler","_f","_g","colEditable","grp","cellValue","rowEvt","isSelectCol","cellEvt","eventName","TriggerManager","operation","_cancelled","handlers","completeHandlers","ROW_ID_FIELD","OpenGrid","msg","from","to","toIdx","active","colIdx","fakeEvent","sheets","_name","sheet","_n","bodyH","toIndex","newWidth","combined","pos","it","idxArr","idxs","reordered","moved","_all","_widths","_fitToGrid","fieldNames","_item","_pid","_pos","keyValue","_field","fd","_h"],"mappings":"AAOO,MAAMA,GAAa;AAAA,EAAnB,cAAA;AACL,SAAQ,gCAA8C,IAAA;AAAA,EAAI;AAAA,EAE1D,GAAGC,GAAeC,GAAwB;AACxC,UAAMC,IAAO,KAAK,UAAU,IAAIF,CAAK,KAAK,CAAA;AAC1C,WAAAE,EAAK,KAAK,EAAE,SAAAD,GAAS,MAAM,IAAO,GAClC,KAAK,UAAU,IAAID,GAAOE,CAAI,GACvB;AAAA,EACT;AAAA,EAEA,KAAKF,GAAeC,GAAwB;AAC1C,UAAMC,IAAO,KAAK,UAAU,IAAIF,CAAK,KAAK,CAAA;AAC1C,WAAAE,EAAK,KAAK,EAAE,SAAAD,GAAS,MAAM,IAAM,GACjC,KAAK,UAAU,IAAID,GAAOE,CAAI,GACvB;AAAA,EACT;AAAA,EAEA,IAAIF,GAAeC,GAAyB;AAC1C,QAAI,CAACA;AACH,kBAAK,UAAU,OAAOD,CAAK,GACpB;AAET,UAAME,IAAO,KAAK,UAAU,IAAIF,CAAK;AACrC,QAAIE,GAAM;AACR,YAAMC,IAAWD,EAAK,OAAO,CAAAE,MAAKA,EAAE,YAAYH,CAAO;AACvD,MAAIE,EAAS,WAAW,IAAG,KAAK,UAAU,OAAOH,CAAK,IACjD,KAAK,UAAU,IAAIA,GAAOG,CAAQ;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,KAAKH,MAAkBK,GAAsB;AAC3C,UAAMH,IAAO,KAAK,UAAU,IAAIF,CAAK;AACrC,QAAI,CAACE,KAAQA,EAAK,WAAW,EAAG,QAAO;AAEvC,UAAMI,IAA6B,CAAA;AACnC,eAAWC,KAASL;AAClB,MAAAK,EAAM,QAAQ,GAAGF,CAAI,GAChBE,EAAM,QAAMD,EAAU,KAAKC,CAAK;AAGvC,WAAID,EAAU,WAAWJ,EAAK,WACxBI,EAAU,WAAW,IAAG,KAAK,UAAU,OAAON,CAAK,IAClD,KAAK,UAAU,IAAIA,GAAOM,CAAS,IAEnC;AAAA,EACT;AAAA,EAEA,mBAAmBN,GAAsB;AACvC,WAAIA,IAAO,KAAK,UAAU,OAAOA,CAAK,IACjC,KAAK,UAAU,MAAA,GACb;AAAA,EACT;AAAA,EAEA,cAAcA,GAAuB;AAtDhC,QAAAQ;AAuDH,aAAOA,IAAA,KAAK,UAAU,IAAIR,CAAK,MAAxB,gBAAAQ,EAA2B,WAAU;AAAA,EAC9C;AACF;ACtDA,IAAIC,KAAY;AAChB,SAASC,KAAoB;AAC3B,SAAO,QAAQ,EAAED,EAAS;AAC5B;AAEO,MAAME,GAA+C;AAAA,EAgB1D,YAAYC,IAAkB,YAAY;AAf1C,SAAQ,QAAa,CAAA,GACrB,KAAQ,YAAiB,CAAA,GACzB,KAAQ,4BAAkC,IAAA,GAI1C,KAAQ,kBAA4B,CAAA,GAGpC,KAAQ,6BAAkC,IAAA,GAG1C,KAAQ,aAAwB,IAChC,KAAQ,cAAwB,CAAA,GAG9B,KAAK,WAAWA;AAAA,EAClB;AAAA;AAAA,EAGA,QAAQC,GAAiB;AACvB,SAAK,QAAQA,EAAK,IAAI,CAAAC,MAAO;AAC3B,YAAMC,IAAKL,GAAA,GACLM,IAAO,EAAE,GAAGF,GAAK,CAAC,KAAK,QAAQ,GAAGC,EAAA;AACxC,kBAAK,MAAM,IAAIA,GAAI,EAAE,OAAO,QAAQ,OAAOA,GAAI,GACxCC;AAAA,IACT,CAAC,GACD,KAAK,YAAY,KAAK,MAAM,IAAI,QAAM,EAAE,GAAGC,IAAI,GAC/C,KAAK,cAAA,GACL,KAAK,kBAAkB,KAAK,MAAM,IAAI,CAACC,GAAGC,MAAMA,CAAC;AAAA,EACnD;AAAA,EAEA,UAAe;AACb,WAAO,KAAK,gBAAgB,IAAI,OAAK,KAAK,MAAMA,CAAC,CAAE;AAAA,EACrD;AAAA,EAEA,kBAAuB;AACrB,WAAO,CAAC,GAAG,KAAK,SAAS;AAAA,EAC3B;AAAA,EAEA,aAAkB;AAChB,WAAO,CAAC,GAAG,KAAK,KAAK;AAAA,EACvB;AAAA,EAEA,YAAkB;AAChB,SAAK,QAAQ,CAAA,GACb,KAAK,YAAY,CAAA,GACjB,KAAK,MAAM,MAAA,GACX,KAAK,OAAO,MAAA,GACZ,KAAK,kBAAkB,CAAA;AAAA,EACzB;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AAAA,EAEA,IAAI,gBAAwB;AAC1B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,OAAOH,GAAkBI,IAAsC,QAAc;AAC3E,UAAML,IAAKL,GAAA,GACLI,IAAM,EAAE,GAAGE,GAAM,CAAC,KAAK,QAAQ,GAAGD,EAAA;AAGxC,QAFA,KAAK,MAAM,IAAIA,GAAI,EAAE,OAAO,SAAS,OAAOA,GAAI,GAE5CK,MAAa,QAAQ;AACvB,YAAMC,IAAM,KAAK,MAAM,KAAKP,CAAG,IAAI;AACnC,WAAK,OAAO,IAAIC,GAAIM,CAAG,GACvB,KAAK,gBAAgB,KAAKA,CAAG;AAAA,IAC/B,WAAWD,MAAa;AACtB,WAAK,MAAM,QAAQN,CAAG,GACtB,KAAK,cAAA,GACL,KAAK,gBAAgB,QAAQ,CAAC;AAAA,SACzB;AACL,YAAMQ,IAAU,KAAK,IAAIF,GAAU,KAAK,gBAAgB,MAAM,GACxDG,IAAUD,IAAU,KAAK,gBAAgB,SAC3C,KAAK,gBAAgBA,CAAO,IAC5B,KAAK,MAAM;AACf,WAAK,MAAM,OAAOC,GAAS,GAAGT,CAAG,GACjC,KAAK,cAAA,GACL,KAAK,kBAAkB,KAAK,MAAM,IAAI,CAACI,GAAGC,MAAMA,CAAC;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,UAAUK,GAAiC;AACzC,UAAMD,IAAU,KAAK,gBAAgBC,CAAQ;AAC7C,QAAID,MAAY,OAAW;AAE3B,UAAMT,IAAM,KAAK,MAAMS,CAAO,GACxBR,IAAKD,EAAI,KAAK,QAAQ,GACtBW,IAAO,KAAK,MAAM,IAAIV,CAAE;AAE9B,YAAIU,KAAA,gBAAAA,EAAM,WAAU,WAElB,KAAK,MAAM,OAAOF,GAAS,CAAC,GAC5B,KAAK,MAAM,OAAOR,CAAE,KAGpB,KAAK,MAAM,IAAIA,GAAI,EAAE,GAAGU,GAAO,OAAO,WAAW,GAGnD,KAAK,cAAA,GACL,KAAK,kBAAkB,KAAK,MACzB,IAAI,CAACR,GAAGE,OAAO,EAAE,GAAAF,GAAG,GAAAE,EAAA,EAAI,EACxB,OAAO,CAAC,EAAE,GAAAF,QAAE;ADlHZ,UAAAT;ACkHkB,eAAAA,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,WAAU;AAAA,KAAS,EACjF,IAAI,CAAC,EAAE,GAAAW,EAAA,MAAQA,CAAC,GAEZL;AAAA,EACT;AAAA,EAEA,QAAQY,GAAwBC,GAA4B;AAC1D,UAAMC,IAAc,KAAK,gBAAgBF,CAAc,GACjDG,IAAc,KAAK,gBAAgBF,CAAY;AACrD,QAAIC,MAAgB,UAAaC,MAAc,OAAW;AAG1D,UAAM,CAACf,CAAG,IAAI,KAAK,MAAM,OAAOc,GAAa,CAAC,GACxCE,IAAWF,IAAcC,IAAYA,IAAY,IAAIA;AAC3D,SAAK,MAAM,OAAOC,GAAU,GAAGhB,CAAI,GAEnC,KAAK,cAAA,GACL,KAAK,kBAAkB,KAAK,MACzB,IAAI,CAACG,GAAGE,OAAO,EAAE,GAAAF,GAAG,GAAAE,EAAA,EAAI,EACxB,OAAO,CAAC,EAAE,GAAAF,QAAE;ADrIZ,UAAAT;ACqIkB,eAAAA,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,WAAU;AAAA,KAAS,EACjF,IAAI,CAAC,EAAE,GAAAW,EAAA,MAAQA,CAAC;AAAA,EACrB;AAAA,EAEA,WAAWK,GAAkBO,GAAeC,GAAqB;AAC/D,UAAMT,IAAU,KAAK,gBAAgBC,CAAQ;AAC7C,QAAID,MAAY,OAAW,QAAO;AAGlC,UAAMR,IADM,KAAK,MAAMQ,CAAO,EACf,KAAK,QAAQ,GACtBE,IAAO,KAAK,MAAM,IAAIV,CAAE;AAG9B,YAAIU,KAAA,gBAAAA,EAAM,WAAU,UAClB,KAAK,MAAM,IAAIV,GAAI;AAAA,MACjB,GAAGU;AAAA,MACH,OAAO;AAAA,MACP,UAAU,EAAE,GAAG,KAAK,UAAUF,CAAO,EAAA;AAAA,IAAE,CACxC,GAGF,KAAK,MAAMA,CAAO,EAAUQ,CAAK,IAAIC,GAC/B;AAAA,EACT;AAAA,EAEA,cAAcR,GAAiC;AAC7C,UAAMD,IAAU,KAAK,gBAAgBC,CAAQ;AAC7C,WAAOD,MAAY,SAAY,KAAK,MAAMA,CAAO,IAAI;AAAA,EACvD;AAAA,EAEA,aAAaC,GAAkBO,GAAoB;ADnK9C,QAAAvB;ACoKH,YAAOA,IAAA,KAAK,cAAcgB,CAAQ,MAA3B,gBAAAhB,EAA+BuB;AAAA,EACxC;AAAA;AAAA;AAAA,EAIA,gBAAqB;AACnB,WAAO,KAAK,MAAM;AAAA,MAAO,CAAAd,MAAA;AD1KtB,YAAAT;AC2KD,iBAAAA,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,WAAU;AAAA;AAAA,IAAA;AAAA,EAE1D;AAAA;AAAA,EAGA,iBAAsB;AAAE,WAAO,KAAK,cAAA;AAAA,EAAiB;AAAA,EAErD,eAAoB;AAClB,WAAO,KAAK,MAAM;AAAA,MAAO,CAAAS,MAAA;ADnLtB,YAAAT;ACoLD,iBAAAA,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,WAAU;AAAA;AAAA,IAAA;AAAA,EAE1D;AAAA,EAEA,iBAAsB;AACpB,WAAO,KAAK,MAAM;AAAA,MAAO,CAAAS,MAAA;ADzLtB,YAAAT;AC0LD,iBAAAA,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,WAAU;AAAA;AAAA,IAAA;AAAA,EAE1D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAwD;AACtD,UAAMyB,IAAe,CAAA,GACfC,IAAe,CAAA,GACfC,IAAe,CAAA;AAErB,eAAWrB,KAAO,KAAK,OAAO;AAC5B,YAAMC,IAAQD,EAAI,KAAK,QAAQ,GACzBW,IAAQ,KAAK,MAAM,IAAIV,CAAE,GACzBqB,KAAQX,KAAA,gBAAAA,EAAM,UAAS;AAC7B,UAAIW,MAAU;AAAa,QAAAH,EAAM,KAAK,EAAE,GAAGnB,GAAK;AAAA,eACvCsB,MAAU;AAAa,QAAAD,EAAQ,KAAK,EAAE,GAAGrB,GAAK;AAAA,eAC9CsB,MAAU,UAAU;AAC3B,cAAMC,IAAOZ,EAAM,YAAY,CAAA,GACzBa,IAAgB,OAAO,KAAKxB,CAAG,EAAE;AAAA,UACrC,CAAAyB,MAAKA,MAAM,KAAK,YAAYzB,EAAIyB,CAAC,MAAMF,EAAKE,CAAC;AAAA,QAAA;AAE/C,QAAAL,EAAO,KAAK,EAAE,GAAGpB,GAAK,gBAAgBwB,GAAsB;AAAA,MAC9D;AAAA,IACF;AACA,WAAO,EAAE,OAAAL,GAAO,QAAAC,GAAQ,SAAAC,EAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBAAuH;AACrH,WAAO,KAAK,MACT,OAAO,CAAAlB,MAAA;AD9NP,UAAAT;AC8NY,eAAAA,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,WAAU;AAAA,KAAQ,EAC1E,IAAI,CAAAM,MAAO;AD/NX,UAAAN;ACgOC,YAAM6B,MAAO7B,IAAA,KAAK,MAAM,IAAIM,EAAI,KAAK,QAAQ,CAAW,MAA3C,gBAAAN,EAA8C,aAAY,CAAA,GACjEgC,IAA+D,CAAA;AACrE,iBAAWC,KAAO,OAAO,KAAK3B,CAAG;AAC/B,QAAI2B,MAAQ,KAAK,YACb3B,EAAI2B,CAAG,MAAMJ,EAAKI,CAAG,KACvBD,EAAK,KAAK,EAAE,OAAOC,GAAK,UAAUJ,EAAKI,CAAG,GAAG,UAAU3B,EAAI2B,CAAG,EAAA,CAAG;AAGrE,aAAO,EAAE,KAAK,EAAE,GAAG3B,EAAA,GAAO,QAAQ0B,EAAK,IAAI,CAAAE,MAAKA,EAAE,KAAK,GAAG,MAAAF,EAAA;AAAA,IAC5D,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,eAAehB,GAAiC;AAC9C,UAAMD,IAAU,KAAK,gBAAgBC,CAAQ;AAC7C,QAAID,MAAY,OAAW;AAC3B,UAAMT,IAAO,KAAK,MAAMS,CAAO,GACzBE,IAAO,KAAK,MAAM,IAAIX,EAAI,KAAK,QAAQ,CAAW;AACxD,QAAI,GAACW,KAAQA,EAAK,UAAU;AAC5B,aAAIA,EAAK,UAAU,YAAYA,EAAK,WAAiB,EAAE,GAAGA,EAAK,SAAA,IACxD,EAAE,GAAG,KAAK,UAAUF,CAAO,EAAA;AAAA,EACpC;AAAA,EAEA,iBAAiBoB,GAAyB;AACxC,WAAO,KAAK,MAAM,IAAI,CAAA1B,MAAK;ADxPxB,UAAAT;ACyPD,YAAM4B,MAAQ5B,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,UAAS;AACnE,aAAO,EAAE,GAAGS,GAAG,CAAC0B,CAAU,GAAGP,EAAA;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,YAAYZ,GAA4B;AD9PnC,QAAAhB;AC+PH,UAAMM,IAAM,KAAK,cAAcU,CAAQ;AACvC,WAAKV,MACEN,IAAA,KAAK,MAAM,IAAIM,EAAI,KAAK,QAAQ,CAAW,MAA3C,gBAAAN,EAA8C,UAAS,SAD7C;AAAA,EAEnB;AAAA;AAAA,EAGA,UAAUoC,GAA4B;AACpC,UAAMC,IAAa,CAAC,MAAA;ADtQjB,UAAArC,GAAAsC;ACuQD,eAAAA,IAAA,KAAK,MAAM,KAAKtC,IAAA,KAAK,MAAM,CAAC,MAAZ,gBAAAA,EAAwB,KAAK,SAAS,MAAtD,gBAAAsC,EAAyD,WAAU;AAAA;AAErE,QAAIF,EAAS,WAAW,GAAG;AACzB,WAAK,kBAAkB,KAAK,MAAM,IAAI,CAAC1B,GAAGC,MAAMA,CAAC,EAAE,OAAO0B,CAAU;AACpE;AAAA,IACF;AAGA,UAAME,IAAQ,KAAK,gBAChB,OAAOF,CAAU,EACjB,IAAI,CAAAxB,MAAO;AACV,YAAMP,IAAM,KAAK,MAAMO,CAAG;AAC1B,aAAO;AAAA,QACL,KAAAA;AAAA,QACA,MAAMuB,EAAS,IAAI,OAAK9B,EAAIkC,EAAE,KAAK,CAAC;AAAA,MAAA;AAAA,IAExC,CAAC;AAEH,IAAAD,EAAM,KAAK,CAACE,GAAGC,MAAM;AACnB,eAASC,IAAK,GAAGA,IAAKP,EAAS,QAAQO,KAAM;AAC3C,cAAMC,IAAMR,EAASO,CAAE,EAAG,KACpBE,IAAKJ,EAAE,KAAKE,CAAE,GACdG,IAAKJ,EAAE,KAAKC,CAAE;AACpB,YAAII,IAAM;AACV,YAAIF,KAAM,QAAQC,KAAM,KAAM,CAAAC,IAAM;AAAA,iBAC3BF,KAAM,KAAM,CAAAE,IAAM;AAAA,iBAClBD,KAAM,KAAM,CAAAC,IAAM;AAAA,iBAClB,OAAOF,KAAO,YAAY,OAAOC,KAAO,cAAgBD,IAAKC;AAAA,aACjE;AACH,gBAAME,IAAK,OAAOH,CAAE,GAAGI,IAAK,OAAOH,CAAE;AACrC,UAAAC,IAAMC,IAAKC,IAAK,KAAKD,IAAKC,IAAK,IAAI;AAAA,QACrC;AACA,YAAIF,MAAQ,EAAG,QAAOH,MAAQ,QAAQG,IAAM,CAACA;AAAA,MAC/C;AACA,aAAO;AAAA,IACT,CAAC,GAED,KAAK,kBAAkBR,EAAM,IAAI,CAAAR,MAAKA,EAAE,GAAG;AAAA,EAC7C;AAAA;AAAA,EAGA,YAAYmB,GAA6C;AACvD,UAAMC,IAAS,OAAO,KAAKD,CAAO;AAElC,SAAK,kBAAkB,KAAK,MACzB,IAAI,CAACzC,GAAG,OAAO,EAAE,GAAAA,GAAG,EAAA,EAAI,EACxB,OAAO,CAAC,EAAE,GAAAA,QAAQ;ADrTlB,UAAAT;ACwTC,YAFIA,IAAA,KAAK,MAAM,IAAIS,EAAE,KAAK,QAAQ,CAAW,MAAzC,gBAAAT,EAA4C,WAAU,aAEtDmD,EAAO,SAAS,KACd,CAACA,EAAO,MAAM,CAAA5B,MAAS;AACzB,cAAM6B,IAAM3C,EAAEc,CAAK;AACnB,eAAO2B,EAAQ3B,CAAK,EAAG,MAAM,OAAM8B,GAAYD,GAAKE,CAAE,CAAC;AAAA,MACzD,CAAC;AAAG,eAAO;AAGb,UAAI,KAAK,cAAc,KAAK,YAAY,SAAS,GAAG;AAClD,cAAMC,IAAI,KAAK;AAKf,YAAI,CAJY,KAAK,YAAY,KAAK,CAAAC,MAAK;AACzC,gBAAMC,IAAIhD,EAAE+C,CAAC;AACb,iBAAOC,KAAK,QAAQ,OAAOA,CAAC,EAAE,YAAA,EAAc,SAASF,CAAC;AAAA,QACxD,CAAC,EACa,QAAO;AAAA,MACvB;AACA,aAAO;AAAA,IACT,CAAC,EACA,IAAI,CAAC,EAAE,GAAA5C,EAAA,MAAQA,CAAC;AAAA,EACrB;AAAA;AAAA,EAGA,cAAc+C,GAAeP,GAAwB;AACnD,SAAK,aAAcO,EAAM,YAAA,GACzB,KAAK,cAAcP;AAAA,EACrB;AAAA;AAAA,EAGQ,gBAAsB;AAC5B,SAAK,OAAO,MAAA,GACZ,KAAK,MAAM,QAAQ,CAAC1C,GAAGE,MAAM;AAC3B,WAAK,OAAO,IAAIF,EAAE,KAAK,QAAQ,GAAaE,CAAC;AAAA,IAC/C,CAAC;AAAA,EACH;AACF;AAEA,SAAS0C,GAAY7B,GAAY8B,GAAyB;AACxD,QAAMG,IAAIjC,GACJmC,IAAKL,EAAG;AACd,UAAQA,EAAG,UAAA;AAAA,IACT,KAAK;AAAc,aAAOG,KAAKE;AAAA,IAC/B,KAAK;AAAc,aAAOF,KAAKE;AAAA,IAC/B,KAAK;AAAc,aAAOF,IAAIE;AAAA,IAC9B,KAAK;AAAc,aAAOF,KAAKE;AAAA,IAC/B,KAAK;AAAc,aAAOF,IAAIE;AAAA,IAC9B,KAAK;AAAc,aAAOF,KAAKE;AAAA,IAC/B,KAAK;AAAc,aAAO,OAAOF,CAAC,EAAE,SAAS,OAAOE,CAAE,CAAC;AAAA,IACvD,KAAK;AAAc,aAAO,OAAOF,CAAC,EAAE,WAAW,OAAOE,CAAE,CAAC;AAAA,IACzD,KAAK;AAAc,aAAO,OAAOF,CAAC,EAAE,SAAS,OAAOE,CAAE,CAAC;AAAA,IACvD;AAAmB,aAAO;AAAA,EAAA;AAE9B;ACrWO,MAAMC,GAAc;AAAA,EAUzB,YAAYC,GAAwBC,GAA+B;AANnE,SAAQ,aAAqB,GAC7B,KAAQ,aAAqB,GAC7B,KAAQ,kBAA0B,GAClC,KAAQ,SAAwB,MAYhC,KAAQ,YAAY,MAAY;AAC9B,WAAK,aAAa,KAAK,UAAU,WACjC,KAAK,gBAAA;AAAA,IACP,GAXE,KAAK,YAAYD,GACjB,KAAK,YAAYC,EAAQ,WACzB,KAAK,WAAWA,EAAQ,YAAY,GACpC,KAAK,WAAWA,EAAQ,UAExB,KAAK,UAAU,iBAAiB,UAAU,KAAK,WAAW,EAAE,SAAS,IAAM;AAAA,EAC7E;AAAA,EAOQ,kBAAwB;AAC9B,IAAI,KAAK,WAAW,SACpB,KAAK,SAAS,sBAAsB,MAAM;AACxC,WAAK,SAAS;AACd,YAAMC,IAAQ,KAAK,gBAAA;AACnB,WAAK,SAASA,EAAM,YAAYA,EAAM,QAAQ;AAAA,IAChD,CAAC;AAAA,EACH;AAAA,EAEA,kBAAsC;AACpC,UAAMC,IAAe,KAAK,KAAK,KAAK,kBAAkB,KAAK,SAAS,GAC9DC,IAAa,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,aAAa,KAAK,SAAS,IAAI,KAAK,QAAQ,GACrFC,IAAW,KAAK;AAAA,MACpB,KAAK,aAAa;AAAA,MAClBD,IAAaD,IAAe,KAAK,WAAW;AAAA,IAAA,GAExCG,IAAUF,IAAa,KAAK;AAClC,WAAO,EAAE,YAAAA,GAAY,UAAAC,GAAU,SAAAC,EAAA;AAAA,EACjC;AAAA,EAEA,aAAaC,GAAqB;AAChC,SAAK,aAAaA,GAClB,KAAK,oBAAA,GACL,KAAK,gBAAA;AAAA,EACP;AAAA,EAEA,kBAAkBC,GAAsB;AACtC,SAAK,kBAAkBA,GACvB,KAAK,gBAAA;AAAA,EACP;AAAA,EAEA,aAAaA,GAAsB;AACjC,SAAK,YAAYA,GACjB,KAAK,oBAAA,GACL,KAAK,gBAAA;AAAA,EACP;AAAA,EAEA,YAAYrD,GAAwB;AAClC,UAAMsD,IAAYtD,IAAW,KAAK,WAC5BuD,IAAeD,IAAY,KAAK,WAChCE,IAAa,KAAK,aAAa,KAAK;AAE1C,QAAIF,IAAY,KAAK;AACnB,WAAK,aAAaA,GAClB,KAAK,UAAU,YAAYA;AAAA,aAClBC,IAAeC,GAAY;AACpC,YAAMC,IAASF,IAAe,KAAK;AACnC,WAAK,aAAaE,GAClB,KAAK,UAAU,YAAYA;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,aAAa,KAAK;AAAA,EAChC;AAAA,EAEQ,sBAA4B;AAElC,UAAMC,IAAS,KAAK,UAAU,cAA2B,YAAY;AACrE,IAAIA,MAAQA,EAAO,MAAM,SAAS,GAAG,KAAK,gBAAgB;AAAA,EAC5D;AAAA,EAEA,UAAgB;AACd,SAAK,UAAU,oBAAoB,UAAU,KAAK,SAAS,GACvD,KAAK,WAAW,QAAM,qBAAqB,KAAK,MAAM;AAAA,EAC5D;AACF;ACpFO,MAAMC,GAAsB;AAAA,EAMjC,YAAYC,GAAyBC,IAAsB,GAAG;AAJ9D,SAAQ,cAA+B,CAAA,GACvC,KAAQ,YAAoB,GAC5B,KAAQ,eAAuB,GAG7B,KAAK,WAAWD,GAChB,KAAK,eAAeC,GACpB,KAAK,SAAA;AAAA,EACP;AAAA,EAEQ,WAAiB;AACvB,UAAMC,IAA0B,CAAA;AAChC,QAAIC,IAAW;AAEf,UAAMC,IAAO,CAACC,GAAsBC,MAAwB;AAC1D,iBAAWC,KAAOF;AAChB,QAAIE,EAAI,YAAYA,EAAI,SAAS,SAAS,KACxCH,EAAKG,EAAI,UAAUD,IAAQ,CAAC,GAC5B,KAAK,YAAY,KAAK,IAAI,KAAK,WAAWA,IAAQ,CAAC,KAEnDJ,EAAO,KAAK,EAAE,GAAGK,GAAK,WAAWJ,KAAY,QAAQG,GAAO,OAAO,GAAA,CAAM;AAAA,IAG/E;AAEA,SAAK,YAAY,GACjBF,EAAK,KAAK,UAAU,CAAC,GACrB,KAAK,cAAcF;AAAA,EACrB;AAAA,EAEA,IAAI,SAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,gBAAiC;AACnC,WAAO,KAAK,YAAY,OAAO,CAAAM,MAAK,CAACA,EAAE,MAAM;AAAA,EAC/C;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAUhB,GAAqB;AAC7B,SAAK,eAAeA;AAAA,EACtB;AAAA,EAEA,WAAWQ,GAA+B;AACxC,SAAK,WAAWA,GAChB,KAAK,SAAA;AAAA,EACP;AAAA,EAEA,WAAWrD,GAAgC;AACzC,UAAM4B,IAAS,MAAM,QAAQ5B,CAAK,IAAIA,IAAQ,CAACA,CAAK;AACpD,SAAK,YAAY,QAAQ,CAAA6D,MAAK;AAC5B,MAAIjC,EAAO,SAASiC,EAAE,KAAK,QAAK,SAAS;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA,EAEA,WAAW7D,GAAgC;AACzC,UAAM4B,IAAS,MAAM,QAAQ5B,CAAK,IAAIA,IAAQ,CAACA,CAAK;AACpD,SAAK,YAAY,QAAQ,CAAA6D,MAAK;AAC5B,MAAIjC,EAAO,SAASiC,EAAE,KAAK,QAAK,SAAS;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA,EAEA,UAAUC,GAAsBzE,IAAsC,QAAc;AAClF,IAAIA,MAAa,SACf,KAAK,SAAS,KAAKyE,CAAM,IAChBzE,MAAa,UACtB,KAAK,SAAS,QAAQyE,CAAM,IAE5B,KAAK,SAAS,OAAOzE,GAAU,GAAGyE,CAAM,GAE1C,KAAK,SAAA;AAAA,EACP;AAAA,EAEA,aAAa9D,GAAqB;AAChC,UAAM+D,IAAiB,CAACL,MACfA,EAAK,OAAO,CAAAG,MACbA,EAAE,UAAU7D,IAAc,MAC1B6D,EAAE,aAAUA,EAAE,WAAWE,EAAeF,EAAE,QAAQ,IAC/C,GACR;AAEH,SAAK,WAAWE,EAAe,KAAK,QAAQ,GAC5C,KAAK,SAAA;AAAA,EACP;AAAA,EAEA,iBAAiB/D,GAA0C;AACzD,WAAO,KAAK,YAAY,KAAK,CAAA6D,MAAKA,EAAE,UAAU7D,CAAK;AAAA,EACrD;AAAA,EAEA,iBAAiBgE,GAA0C;AACzD,WAAO,KAAK,YAAYA,CAAK;AAAA,EAC/B;AAAA,EAEA,eAAehE,GAAuB;AACpC,WAAO,KAAK,YAAY,UAAU,CAAA6D,MAAKA,EAAE,UAAU7D,CAAK;AAAA,EAC1D;AAAA;AAAA,EAGA,mBAAmC;AACjC,UAAMiE,IAAuB,MAAM,KAAK,EAAE,QAAQ,KAAK,aAAa,MAAM,EAAE;AAC5E,QAAIT,IAAW;AAEf,UAAMC,IAAO,CAACC,GAAsBC,MAA0B;AAC5D,UAAIO,IAAO;AACX,iBAAWN,KAAOF;AAChB,YAAI,CAAAE,EAAI;AACR,cAAIA,EAAI,YAAYA,EAAI,SAAS,SAAS,GAAG;AAC3C,kBAAMO,IAAYV,EAAKG,EAAI,UAAUD,IAAQ,CAAC;AAC9C,YAAIQ,IAAY,MACdF,EAAKN,IAAQ,CAAC,EAAG,KAAK;AAAA,cACpB,QAAQC;AAAA,cACR,UAAAJ;AAAA,cACA,OAAAG;AAAA,cACA,SAASQ;AAAA,cACT,SAAS;AAAA,YAAA,CACV,GACDD,KAAQC;AAAA,UAEZ;AACE,YAAAF,EAAKN,IAAQ,CAAC,EAAG,KAAK;AAAA,cACpB,QAAQC;AAAA,cACR,UAAUJ;AAAA,cACV,OAAAG;AAAA,cACA,SAAS;AAAA,cACT,SAAS,KAAK,YAAYA,IAAQ;AAAA,YAAA,CACnC,GACDO;AAGJ,aAAOA;AAAA,IACT;AAEA,WAAAT,EAAK,KAAK,UAAU,CAAC,GACdQ;AAAA,EACT;AAAA;AAAA,EAGA,cAAcG,GAAoBC,IAAuB,KAAe;AACtE,UAAMC,IAAU,KAAK,eACfC,IAAWD,EAAQ,OAAO,CAAAT,MAAKA,EAAE,IAAI,GACrCW,IAAaF,EAChB,OAAO,CAAAT,MAAK,CAACA,EAAE,QAAQA,EAAE,KAAK,EAC9B,OAAO,CAACY,GAAKZ,MAAMY,IAAMZ,EAAE,OAAQ,CAAC,GAEjCa,IAAYH,EAAS,OAAO,CAACE,GAAKZ,MAAMY,KAAOZ,EAAE,QAAQ,IAAI,CAAC,GAC9DtF,IAAY,KAAK,IAAI,GAAG6F,IAAaI,CAAU;AAErD,WAAOF,EAAQ,IAAI,CAAAT,MACbA,EAAE,OAAa,KAAK,MAAOA,EAAE,OAAOa,IAAanG,CAAS,IACvDsF,EAAE,SAASQ,CACnB;AAAA,EACH;AACF;AC1KO,MAAMM,GAAY;AAAA,EAOvB,YAAYrC,GAAwBsC,GAAwBC,GAAwB;AALpF,SAAQ,SAAS,IAGjB,KAAQ,kBAAoD,MAG1D,KAAK,WAAWD,GAChB,KAAK,WAAWC,GAEhB,KAAK,MAAM,SAAS,cAAc,KAAK,GACvC,KAAK,IAAI,YAAY,mBACrB,KAAK,IAAI,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,OAMzBvC,EAAU,YAAY,KAAK,GAAG;AAAA,EAChC;AAAA,EAEA,KAAKtC,GAAe8E,GAAuBC,GAAoC;AJxB1E,QAAAtG;AIyBH,SAAK,SAASuB,GACd,KAAK,IAAI,YAAY;AAGrB,UAAMgF,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAM,cAAc,MACpBA,EAAM,MAAM,UAAU,sEACtB,KAAK,IAAI,YAAYA,CAAK;AAG1B,UAAMC,IAAU,SAAS,cAAc,KAAK;AAC5C,IAAAA,EAAQ,MAAM,UAAU;AAExB,UAAMC,IAAU,SAAS,cAAc,QAAQ;AAC/C,IAAAA,EAAQ,MAAM,UAAU;AACxB,UAAMC,IAAsE;AAAA,MAC1E,EAAE,OAAO,MAAM,OAAO,WAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,IAAA;AAAA,MACtB,EAAE,OAAO,SAAS,OAAO,KAAA;AAAA,MACzB,EAAE,OAAO,MAAM,OAAO,aAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,WAAA;AAAA,MACtB,EAAE,OAAO,QAAQ,OAAO,IAAA;AAAA,MACxB,EAAE,OAAO,SAAS,OAAO,IAAA;AAAA,MACzB,EAAE,OAAO,MAAM,OAAO,KAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,KAAA;AAAA,IAAK;AAE7B,eAAWtB,KAAKsB,GAAY;AAC1B,YAAMC,IAAM,SAAS,cAAc,QAAQ;AAC3C,MAAAA,EAAI,QAAQvB,EAAE,OACduB,EAAI,cAAcvB,EAAE,OACpBqB,EAAQ,YAAYE,CAAG;AAAA,IACzB;AACA,IAAIL,EAAe,CAAC,QAAW,QAAQA,EAAe,CAAC,EAAE,WACzDE,EAAQ,YAAYC,CAAO,GAC3B,KAAK,IAAI,YAAYD,CAAO;AAG5B,UAAMI,IAAa,SAAS,cAAc,OAAO;AACjD,IAAAA,EAAW,OAAO,QAClBA,EAAW,cAAc,cACzBA,EAAW,UAAQ5G,IAAAsG,EAAe,CAAC,MAAhB,gBAAAtG,EAAmB,UAAS,IAC/C4G,EAAW,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,OAK3BA,EAAW,iBAAiB,WAAW,CAAChH,MAAM;AAC5C,MAAIA,EAAE,QAAQ,UAASiH,EAAS,MAAA,IACvBjH,EAAE,QAAQ,YAAU,KAAK,MAAA;AAAA,IACpC,CAAC,GACD,KAAK,IAAI,YAAYgH,CAAU;AAG/B,UAAME,IAAS,SAAS,cAAc,KAAK;AAC3C,IAAAA,EAAO,MAAM,UAAU;AAEvB,UAAMC,IAAW,SAAS,cAAc,QAAQ;AAChD,IAAAA,EAAS,cAAc,OACvBA,EAAS,MAAM,UAAU;AAAA;AAAA;AAAA,OAIzBA,EAAS,iBAAiB,SAAS,MAAM;AACvC,WAAK,SAAS,KAAK,MAAM,GACzB,KAAK,MAAA;AAAA,IACP,CAAC;AAED,UAAMF,IAAW,SAAS,cAAc,QAAQ;AAChD,IAAAA,EAAS,cAAc,MACvBA,EAAS,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,OAKzBA,EAAS,iBAAiB,SAAS,MAAM;AACvC,YAAMzD,IAAMwD,EAAW,MAAM,KAAA;AAC7B,MAAKxD,IAGH,KAAK,SAAS,KAAK,QAAQ,CAAC,EAAE,UAAUqD,EAAQ,OAAiC,OAAOrD,EAAA,CAAK,CAAC,IAF9F,KAAK,SAAS,KAAK,MAAM,GAI3B,KAAK,MAAA;AAAA,IACP,CAAC,GAED0D,EAAO,YAAYC,CAAQ,GAC3BD,EAAO,YAAYD,CAAQ,GAC3B,KAAK,IAAI,YAAYC,CAAM;AAG3B,UAAME,IAAOX,EAAS,sBAAA,GAChBY,IAAgB,KAAK,IAAI,cAAe,sBAAA;AAC9C,SAAK,IAAI,MAAM,MAAM,GAAGD,EAAK,SAASC,EAAc,MAAM,CAAC,MAC3D,KAAK,IAAI,MAAM,OAAO,GAAG,KAAK,IAAID,EAAK,OAAOC,EAAc,MAAMA,EAAc,QAAQ,GAAG,CAAC,MAC5F,KAAK,IAAI,MAAM,UAAU,SAEzB,sBAAsB,MAAML,EAAW,OAAO,GAG1C,KAAK,mBAAiB,SAAS,oBAAoB,aAAa,KAAK,eAAe,GACxF,KAAK,kBAAkB,CAAChH,MAAkB;AACxC,MAAI,CAAC,KAAK,IAAI,SAASA,EAAE,MAAc,KAAKA,EAAE,WAAWyG,KACvD,KAAK,MAAA;AAAA,IAET,GACA,WAAW,MAAM,SAAS,iBAAiB,aAAa,KAAK,eAAgB,GAAG,CAAC;AAAA,EACnF;AAAA,EAEA,QAAc;AACZ,SAAK,IAAI,MAAM,UAAU,QACrB,KAAK,oBACP,SAAS,oBAAoB,aAAa,KAAK,eAAe,GAC9D,KAAK,kBAAkB;AAAA,EAE3B;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK,IAAI,MAAM,YAAY;AAAA,EACpC;AAAA,EAEA,UAAgB;AACd,SAAK,MAAA,GACL,KAAK,IAAI,OAAA;AAAA,EACX;AACF;ACpJA,MAAMa,KAAe;AAMd,SAASC,GAAM/D,GAAagE,IAAoBF,IAAsB;AAC3E,QAAMG,IAAS,KAAK,IAAI,IAAID,CAAS;AACrC,SAAO,KAAK,MAAMhE,IAAMiE,CAAM,IAAIA;AACpC;ACHO,MAAMC,EAAU;AAAA;AAAA,EAIrB,YAAYC,GAAqBC,GAAe;AAC9C,SAAK,KAAKD,GACV,KAAK,KAAKC,IAAQ,IAAI,IAAIA;AAAA,EAC5B;AAAA;AAAA,EAIA,OAAO,KAAKhG,GAAiC;AAC3C,QAAIA,aAAiB8F,EAAW,QAAO9F;AACvC,QAAI,OAAOA,KAAU,iBAAiB,IAAI8F,EAAU9F,GAAO,CAAC;AAE5D,UAAMiG,IAAM,OAAOjG,CAAK,EAAE,KAAA;AAC1B,QAAI,CAACiG,KAAOA,MAAQ,UAAUA,MAAQ,eAAeA,MAAQ;AAC3D,aAAO,IAAIH,EAAU,IAAI,CAAC;AAG5B,UAAMI,IAAQD,EAAI,WAAW,GAAG,GAC1BE,IAAQD,IAAQD,EAAI,MAAM,CAAC,IAAIA,GAC/BG,IAAQD,EAAI,QAAQ,GAAG;AAE7B,QAAIE,GACAL;AAEJ,QAAII,MAAQ;AACV,MAAAC,IAAQ,OAAOF,CAAG,GAClBH,IAAQ;AAAA,SACH;AACL,YAAMM,IAAOH,EAAI,MAAMC,IAAM,CAAC;AAC9B,MAAAC,IAAQ,OAAOF,EAAI,MAAM,GAAGC,CAAG,IAAIE,CAAI,GACvCN,IAAQM,EAAK;AAAA,IACf;AAEA,WAAO,IAAIR,EAAUI,IAAQ,CAACG,IAAQA,GAAOL,CAAK;AAAA,EACpD;AAAA,EAEA,OAAO,OAAkB;AAAE,WAAO,IAAIF,EAAU,IAAI,CAAC;AAAA,EAAG;AAAA,EACxD,OAAO,MAAkB;AAAE,WAAO,IAAIA,EAAU,IAAI,CAAC;AAAA,EAAG;AAAA;AAAA,EAIxD,OAAe,OAAO7E,GAAcC,GAAwC;AAC1E,WAAID,EAAE,OAAOC,EAAE,KAAW,CAACD,EAAE,IAAIC,EAAE,IAAID,EAAE,EAAE,IACvCA,EAAE,KAAKC,EAAE,KACJ,CAACD,EAAE,IAAIC,EAAE,KAAM,OAAO,OAAOD,EAAE,KAAKC,EAAE,EAAE,GAAID,EAAE,EAAE,IAElD,CAACA,EAAE,KAAM,OAAO,OAAOC,EAAE,KAAKD,EAAE,EAAE,GAAIC,EAAE,IAAIA,EAAE,EAAE;AAAA,EACzD;AAAA;AAAA,EAIA,IAAIqF,GAAiC;AACnC,UAAM,CAACC,GAAIC,GAAIzF,CAAC,IAAI8E,EAAU,OAAO,MAAMA,EAAU,KAAKS,CAAK,CAAC;AAChE,WAAO,IAAIT,EAAUU,IAAKC,GAAIzF,CAAC;AAAA,EACjC;AAAA,EAEA,IAAIuF,GAAiC;AACnC,UAAM,CAACC,GAAIC,GAAIzF,CAAC,IAAI8E,EAAU,OAAO,MAAMA,EAAU,KAAKS,CAAK,CAAC;AAChE,WAAO,IAAIT,EAAUU,IAAKC,GAAIzF,CAAC;AAAA,EACjC;AAAA,EAEA,IAAIuF,GAAiC;AACnC,UAAMG,IAAIZ,EAAU,KAAKS,CAAK;AAC9B,WAAO,IAAIT,EAAU,KAAK,KAAKY,EAAE,IAAI,KAAK,KAAKA,EAAE,EAAE;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAIH,GAAsBX,IAAY,IAAe;AACnD,UAAMc,IAAIZ,EAAU,KAAKS,CAAK;AAC9B,QAAIG,EAAE,OAAO,GAAI,OAAM,IAAI,MAAM,6BAA6B;AAG9D,UAAMC,IADkB,KAAK,KAAM,OAAO,OAAOf,IAAYc,EAAE,EAAE,IAChCA,EAAE;AACnC,WAAO,IAAIZ,EAAUa,GAAQf,IAAY,KAAK,EAAE;AAAA,EAClD;AAAA;AAAA,EAGA,IAAIW,GAAiC;AACnC,UAAMG,IAAIZ,EAAU,KAAKS,CAAK,GACxB,CAACC,GAAIC,GAAIzF,CAAC,IAAI8E,EAAU,OAAO,MAAMY,CAAC;AAC5C,WAAO,IAAIZ,EAAUU,IAAKC,GAAIzF,CAAC;AAAA,EACjC;AAAA;AAAA,EAGA,MAAiB;AAAE,WAAO,IAAI8E,EAAU,CAAC,KAAK,IAAI,KAAK,EAAE;AAAA,EAAG;AAAA;AAAA,EAG5D,MAAiB;AACf,WAAO,IAAIA,EAAU,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE;AAAA,EACjE;AAAA;AAAA,EAIA,GAAGS,GAA+B;AAChC,UAAM,CAACC,GAAIC,CAAE,IAAIX,EAAU,OAAO,MAAMA,EAAU,KAAKS,CAAK,CAAC;AAC7D,WAAOC,MAAOC;AAAA,EAChB;AAAA,EACA,GAAGF,GAA+B;AAChC,UAAM,CAACC,GAAIC,CAAE,IAAIX,EAAU,OAAO,MAAMA,EAAU,KAAKS,CAAK,CAAC;AAC7D,WAAOC,IAAKC;AAAA,EACd;AAAA,EACA,GAAGF,GAA+B;AAChC,UAAM,CAACC,GAAIC,CAAE,IAAIX,EAAU,OAAO,MAAMA,EAAU,KAAKS,CAAK,CAAC;AAC7D,WAAOC,IAAKC;AAAA,EACd;AAAA,EACA,IAAIF,GAA+B;AAAE,WAAO,CAAC,KAAK,GAAGA,CAAK;AAAA,EAAG;AAAA,EAC7D,IAAIA,GAA+B;AAAE,WAAO,CAAC,KAAK,GAAGA,CAAK;AAAA,EAAG;AAAA,EAC7D,SAAkB;AAAE,WAAO,KAAK,OAAO;AAAA,EAAI;AAAA,EAC3C,QAAkB;AAAE,WAAO,KAAK,KAAK;AAAA,EAAI;AAAA,EACzC,QAAkB;AAAE,WAAO,KAAK,KAAK;AAAA,EAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzC,QAAQK,GAAoB;AAC1B,QAAIhD,IAAI,KAAK,IACT,IAAI,KAAK;AAEb,QAAI,IAAIgD;AACN,MAAAhD,IAAIA,IAAK,OAAO,OAAOgD,IAAK,CAAC;AAAA,aACpB,IAAIA,GAAI;AAEjB,YAAMC,IAAU,OADA,OAAO,IAAID,CAAE,GAEvBE,IAAUD,IAAU,IACpBX,IAAUtC,IAAI,IACdmD,IAAUb,IAAQ,CAACtC,IAAIA,GACvBoD,IAAUD,IAAQF;AACxB,UAAMI,IAAUF,IAAQF;AACxB,MAAIG,KAAOF,MAAMG,KAAW,KAC5BrD,IAAIsC,IAAQ,CAACe,IAAUA;AAAA,IACzB;AACA,QAAIL;AAEJ,UAAMV,IAAStC,IAAI,IAEbsD,KADShB,IAAQ,CAACtC,IAAIA,GACP,SAAA,EAAW,SAASgD,IAAK,GAAG,GAAG,GAC9CO,IAAWD,EAAO,MAAM,GAAGA,EAAO,SAASN,CAAE,KAAK,KAClDQ,IAAWR,IAAK,IAAI,MAAMM,EAAO,MAAMA,EAAO,SAASN,CAAE,IAAI;AACnE,YAAQV,IAAQ,MAAM,MAAMiB,IAAUC;AAAA,EACxC;AAAA;AAAA,EAGA,WAAmB;AACjB,QAAI,KAAK,OAAO,EAAG,QAAO,KAAK,GAAG,SAAA;AAElC,QAAIxD,IAAI,KAAK,IAAI5C,IAAI,KAAK;AAC1B,WAAOA,IAAI,KAAK4C,MAAM,MAAMA,IAAI,QAAQ;AAAM,MAAAA,KAAK,KAAK5C;AACxD,WAAO,IAAI8E,EAAUlC,GAAG5C,CAAC,EAAE,QAAQA,CAAC;AAAA,EACtC;AAAA;AAAA,EAGA,WAAmB;AAAE,WAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;AAAA,EAAG;AAAA;AAAA;AAAA,EAK1D,OAAO,IAAIqG,GAAiC;AAC1C,WAAOA,EAAI,OAAkB,CAACC,GAAKrF,MAAMqF,EAAI,IAAIrF,CAAC,GAAG6D,EAAU,KAAA,CAAM;AAAA,EACvE;AAAA;AAAA,EAGA,OAAO,IAAIuB,GAAsBzB,IAAY,IAAe;AAC1D,WAAKyB,EAAI,SACFvB,EAAU,IAAIuB,CAAG,EAAE,IAAIA,EAAI,QAAQzB,CAAS,IAD3BE,EAAU,KAAA;AAAA,EAEpC;AAAA;AAAA,EAGA,OAAO,IAAIuB,GAAiC;AAC1C,QAAI,CAACA,EAAI,OAAQ,OAAM,IAAI,MAAM,4BAA4B;AAC7D,WAAOA,EAAI,IAAIvB,EAAU,IAAI,EAAE,OAAO,CAAC7E,GAAGC,MAAMD,EAAE,GAAGC,CAAC,IAAID,IAAIC,CAAC;AAAA,EACjE;AAAA;AAAA,EAGA,OAAO,IAAImG,GAAiC;AAC1C,QAAI,CAACA,EAAI,OAAQ,OAAM,IAAI,MAAM,4BAA4B;AAC7D,WAAOA,EAAI,IAAIvB,EAAU,IAAI,EAAE,OAAO,CAAC7E,GAAGC,MAAMD,EAAE,GAAGC,CAAC,IAAID,IAAIC,CAAC;AAAA,EACjE;AACF;AC3KO,SAASqG,GACdC,GACAC,GACAC,IAAoB,IACT;AACX,SAAO,IAAIC,GAAeH,GAAMC,GAAKC,CAAiB,EAAE,MAAA;AAC1D;AAIA,MAAMC,GAAe;AAAA,EAInB,YACEC,GACiBC,GACAC,GACjB;AAFiB,SAAA,OAAAD,GACA,KAAA,QAAAC,GANnB,KAAQ,OAAO,GAQb,KAAK,OAAOF,EAAI,KAAA;AAAA,EAClB;AAAA,EAEA,QAAmB;AACjB,UAAMjB,IAAS,KAAK,UAAA;AAEpB,QADA,KAAK,MAAA,GACD,KAAK,OAAO,KAAK,KAAK;AACxB,YAAM,IAAI;AAAA,QACR,6BAA6B,KAAK,KAAK,KAAK,IAAI,CAAC,SAAS,KAAK,IAAI;AAAA,MAAA;AAGvE,WAAOA;AAAA,EACT;AAAA;AAAA,EAIQ,YAAuB;AAC7B,QAAIoB,IAAO,KAAK,gBAAA;AAEhB,SADA,KAAK,MAAA,GACE,KAAK,OAAO,KAAK,KAAK,UAAQ;AACnC,YAAMC,IAAK,KAAK,KAAK,KAAK,IAAI;AAC9B,UAAIA,MAAO,OAAOA,MAAO,IAAK;AAC9B,WAAK,QACL,KAAK,MAAA;AACL,YAAMC,IAAQ,KAAK,gBAAA;AACnB,MAAAF,IAAOC,MAAO,MAAMD,EAAK,IAAIE,CAAK,IAAIF,EAAK,IAAIE,CAAK,GACpD,KAAK,MAAA;AAAA,IACP;AACA,WAAOF;AAAA,EACT;AAAA,EAEQ,kBAA6B;AACnC,QAAIA,IAAO,KAAK,OAAA;AAEhB,SADA,KAAK,MAAA,GACE,KAAK,OAAO,KAAK,KAAK,UAAQ;AACnC,YAAMC,IAAK,KAAK,KAAK,KAAK,IAAI;AAC9B,UAAIA,MAAO,OAAOA,MAAO,OAAOA,MAAO,IAAK;AAC5C,WAAK,QACL,KAAK,MAAA;AACL,YAAMC,IAAQ,KAAK,OAAA;AACnB,MAASD,MAAO,MAAKD,IAAOA,EAAK,IAAIE,CAAK,IACjCD,MAAO,MAAKD,IAAOA,EAAK,IAAIE,GAAO,KAAK,KAAK,IACjCF,IAAOA,EAAK,IAAIE,CAAK,GAC1C,KAAK,MAAA;AAAA,IACP;AACA,WAAOF;AAAA,EACT;AAAA,EAEQ,SAAoB;AAE1B,WADA,KAAK,MAAA,GACD,KAAK,KAAK,KAAK,IAAI,MAAM,OAC3B,KAAK,QACE,KAAK,OAAA,EAAS,IAAA,KAEhB,KAAK,SAAA;AAAA,EACd;AAAA,EAEQ,WAAsB;AAC5B,SAAK,MAAA;AACL,UAAMC,IAAK,KAAK,KAAK,KAAK,IAAI;AAE9B,QAAIA,MAAO,KAAK;AACd,WAAK;AACL,YAAMpG,IAAM,KAAK,UAAA;AAEjB,UADA,KAAK,MAAA,GACD,KAAK,KAAK,KAAK,IAAI,MAAM;AAC3B,cAAM,IAAI,YAAY,2BAA2B;AAEnD,kBAAK,QACEA;AAAA,IACT;AAEA,WAAIoG,MAAO,MAAY,KAAK,UAAA,IAErB,KAAK,SAAA;AAAA,EACd;AAAA;AAAA;AAAA,EAKQ,YAAuB;AAC7B,SAAK;AACL,UAAME,IAAQ,KAAK;AACnB,WAAO,KAAK,OAAO,KAAK,KAAK,UAAU,KAAK,KAAK,KAAK,IAAI,MAAM;AAC9D,WAAK;AAEP,QAAI,KAAK,QAAQ,KAAK,KAAK;AACzB,YAAM,IAAI,YAAY,wBAAwB;AAEhD,UAAMnI,IAAQ,KAAK,KAAK,MAAMmI,GAAO,KAAK,IAAI;AAC9C,SAAK;AAEL,UAAMtG,IAAM,KAAK,KAAK7B,CAAK;AAC3B,QAAI6B,KAAO;AACT,YAAM,IAAI,eAAe,uBAAuB7B,CAAK,iBAAiB;AAExE,WAAO+F,EAAU,KAAKlE,CAAG;AAAA,EAC3B;AAAA;AAAA,EAGQ,WAAsB;AAC5B,UAAMsG,IAAQ,KAAK;AACnB,WAAO,KAAK,OAAO,KAAK,KAAK,UAAU,SAAS,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;AACvE,WAAK;AAEP,UAAMC,IAAS,KAAK,KAAK,MAAMD,GAAO,KAAK,IAAI;AAC/C,QAAI,CAACC;AACH,YAAM,IAAI;AAAA,QACR,qCAAqC,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,YAAYD,CAAK;AAAA,MAAA;AAGvF,WAAOpC,EAAU,KAAKqC,CAAM;AAAA,EAC9B;AAAA;AAAA,EAGQ,QAAc;AACpB,WAAO,KAAK,OAAO,KAAK,KAAK,UAAU,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;AACnE,WAAK;AAAA,EAET;AACF;ACxGO,SAASC,GAAUpI,GAAeqI,GAAqC;AAC5E,MAAIrI,KAAS,QAAQA,MAAU,WAAWA,KAAS;AACnD,QAAMsI,IAAe,OAAOD,KAAY,WAAW,EAAE,MAAMA,MAAYA,GACjEE,IAAOD,EAAI,QAAQ;AAEzB,UAAQA,EAAI,MAAA;AAAA,IACV,KAAK;AAAW,aAAOE,GAASxI,GAAOuI,CAAI;AAAA,IAC3C,KAAK;AAAA,IACL,KAAK;AAAW,aAAOE,GAAWzI,GAAOuI,CAAI;AAAA,IAC7C,KAAK;AAAW,aAAOG,GAAW1I,GAAOuI,CAAI;AAAA,IAC7C,KAAK;AAAW,aAAOI,GAAY3I,GAAOuI,CAAI;AAAA,IAC9C,KAAK;AAAW,aAAOK,GAAa5I,GAAOuI,GAAMD,EAAI,iBAAiB,GAAGA,EAAI,iBAAiB,CAAC;AAAA,IAC/F,KAAK;AAAY,aAAOC,EAAK,OAAO,KAAK,IAAIvI,EAAM,QAAQ,CAAC,CAAC;AAAA,IAC7D,KAAK;AAAW,aAAO6I,GAAU7I,GAAOuI,CAAI;AAAA,IAC5C,KAAK;AAAW,aAAOO,GAAQ9I,GAAOuI,CAAI;AAAA,IAC1C,KAAK;AAAW,aAAOQ,GAAa/I,GAAOuI,GAAMD,EAAI,iBAAiB,GAAGA,EAAI,iBAAiB,CAAC;AAAA,IAC/F;AAAgB,aAAOtI;AAAA,EAAA;AAE3B;AAWA,SAASwI,GAASvG,GAAW2B,GAAmB;AAC9C,QAAMoF,IAAQ/G,EAAE,QAAQ,WAAW,EAAE;AACrC,MAAI+G,EAAM,SAAS,GAAG;AAEpB,UAAMC,IAAMhH,EAAE,SAAS,GAAG,IAAI,MAAM,IAC9BiH,IAAWjH,EAAE,QAAQ,GAAG,KAAK,IAAIA,EAAE,QAAQ,GAAG,IAAI;AACxD,WAAOA,EAAE,MAAM,GAAGiH,CAAQ,IAAID,IAAMrF,EAAE,OAAO,KAAK,IAAI,GAAG3B,EAAE,SAASiH,IAAWD,EAAI,MAAM,CAAC;AAAA,EAC5F;AACA,QAAME,IAAQH,EAAM,MAAM,GAAG,CAAC,GACxBI,IAAYJ,EAAM,CAAC,GACnBK,IAAUL,EAAM,SAAS;AAC/B,SAAO,GAAGG,CAAK,IAAIC,CAAS,GAAGxF,EAAE,OAAOyF,CAAO,CAAC;AAClD;AAQA,SAASZ,GAAWxG,GAAW2B,GAAmB;AAChD,QAAMoF,IAAQ/G,EAAE,QAAQ,WAAW,EAAE;AACrC,SAAI+G,EAAM,WAAW,KAEZ,GAAGA,EAAM,MAAM,GAAG,CAAC,CAAC,IAAIpF,EAAE,OAAO,CAAC,CAAC,IAAIoF,EAAM,MAAM,CAAC,CAAC,KACnDA,EAAM,WAAW,KACtBA,EAAM,WAAW,IAAI,IAEhB,GAAGA,EAAM,MAAM,GAAG,CAAC,CAAC,IAAIpF,EAAE,OAAO,CAAC,CAAC,IAAIoF,EAAM,MAAM,CAAC,CAAC,KAGvD,GAAGA,EAAM,MAAM,GAAG,CAAC,CAAC,IAAIpF,EAAE,OAAO,CAAC,CAAC,IAAIoF,EAAM,MAAM,CAAC,CAAC,KACnDA,EAAM,WAAW,IAEnB,GAAGA,EAAM,MAAM,GAAG,CAAC,CAAC,IAAIpF,EAAE,OAAO,CAAC,CAAC,IAAIoF,EAAM,MAAM,CAAC,CAAC,KAGvDD,GAAa9G,GAAG2B,GAAG,GAAG,CAAC;AAChC;AAOA,SAAS8E,GAAWzG,GAAW2B,GAAmB;AAChD,QAAM0F,IAAQrH,EAAE,QAAQ,GAAG;AAC3B,MAAIqH,IAAQ,EAAG,QAAOP,GAAa9G,GAAG2B,GAAG,GAAG,CAAC;AAC7C,QAAM2F,IAAQtH,EAAE,MAAM,GAAGqH,CAAK,GACxBE,IAASvH,EAAE,MAAMqH,CAAK,GACtBG,IAAS,KAAK,IAAI,GAAGF,EAAM,MAAM,GACjClF,IAAUkF,EAAM,MAAM,GAAGE,CAAM,GAE/BJ,IAAU,KAAK,IAAIE,EAAM,SAASE,GAAQ,CAAC;AACjD,SAAO,GAAGpF,CAAO,GAAGT,EAAE,OAAOyF,CAAO,CAAC,GAAGG,CAAM;AAChD;AAOA,SAASb,GAAY1G,GAAW2B,GAAmB;AACjD,QAAMoF,IAAQ/G,EAAE,QAAQ,WAAW,EAAE;AACrC,MAAI+G,EAAM,SAAS,EAAG,QAAO/G;AAC7B,QAAMyH,IAASV,EAAM,MAAM,GAAG,CAAC,GACzBW,IAASX,EAAM,MAAM,EAAE,GACvBY,IAASZ,EAAM,SAAS,GAExBa,IAAMjG,EAAE,OAAO,KAAK,IAAIgG,GAAQ,CAAC,CAAC,GAClCE,IAAkB,CAACJ,CAAM;AAC/B,WAASvK,IAAI,GAAGA,IAAI0K,EAAI,QAAQ1K,KAAK,GAAG;AACtC,UAAM4K,IAAQF,EAAI,MAAM1K,GAAGA,IAAI,CAAC;AAChC,IAAI4K,KAAOD,EAAM,KAAKC,CAAK;AAAA,EAC7B;AACA,SAAAD,EAAM,KAAKH,CAAK,GACTG,EAAM,KAAK,GAAG;AACvB;AAOA,SAASlB,GAAa3G,GAAW2B,GAAWoG,GAAmBC,GAA2B;AACxF,QAAMjB,IAAQ/G,EAAE,QAAQ,WAAW,EAAE;AACrC,MAAI+G,EAAM,UAAUgB,IAAYC;AAC9B,WAAOlB,GAAaC,GAAOpF,GAAGoG,GAAWC,CAAS;AAEpD,QAAMC,IAASlB,EAAM,MAAM,GAAGgB,CAAS,GACjCG,IAASnB,EAAM,MAAM,CAACiB,CAAS,GAC/BL,IAASZ,EAAM,SAASgB,IAAYC;AAC1C,SAAO,GAAGC,CAAM,IAAItG,EAAE,OAAOgG,CAAM,CAAC,IAAIO,CAAM;AAChD;AAQA,SAAStB,GAAU5G,GAAW2B,GAAmB;AAC/C,QAAM,IAAI3B,EAAE,KAAA;AACZ,SAAI,EAAE,WAAW,IAAUA,IACvB,EAAE,WAAW,IAAU2B,IACvB,EAAE,WAAW,IAAU,GAAG,EAAE,CAAC,CAAC,GAAGA,CAAC,KAE/B,GAAG,EAAE,CAAC,CAAC,GAAGA,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;AAC3D;AAOA,SAASkF,GAAQ7G,GAAW2B,GAAmB;AAC7C,QAAMkG,IAAQ7H,EAAE,MAAM,GAAG;AACzB,MAAI6H,EAAM,WAAW,EAAG,QAAOf,GAAa9G,GAAG2B,GAAG,GAAG,CAAC;AACtD,QAAMwG,IAAY,CAACC,MAAkBzG,EAAE,OAAO,KAAK,IAAIyG,EAAM,QAAQ,CAAC,CAAC;AACvE,SAAO,GAAGP,EAAM,CAAC,CAAC,IAAIA,EAAM,CAAC,CAAC,IAAIM,EAAUN,EAAM,CAAC,CAAE,CAAC,IAAIM,EAAUN,EAAM,CAAC,CAAE,CAAC;AAChF;AAQA,SAASf,GAAa9G,GAAW2B,GAAWoG,GAAmBC,GAA2B;AACxF,MAAIhI,EAAE,UAAU+H,IAAYC,EAAW,QAAOhI;AAC9C,QAAMiI,IAASjI,EAAE,MAAM,GAAG+H,CAAS,GAC7BG,IAASF,IAAY,IAAIhI,EAAE,MAAM,CAACgI,CAAS,IAAI,IAC/CL,IAAS3H,EAAE,SAAS+H,IAAYC;AACtC,SAAO,GAAGC,CAAM,GAAGtG,EAAE,OAAOgG,CAAM,CAAC,GAAGO,CAAM;AAC9C;ACzMO,SAASG,GAAe7C,GAAmC;AAChE,QAAM9D,IAAM8D,EAAI;AAChB,MAAI,CAAC9D,EAAI,QAAS,QAAO;AACzB,QAAM4G,IAAO5G,EAAI,oBAAoB;AACrC,MAAI;AACF,QAAIgD;AAOJ,WANI,OAAOhD,EAAI,WAAY,aACzBgD,IAAShD,EAAI,QAAQ8D,EAAI,KAAK3B,CAAS,IAEvCa,IAASY,GAAgB5D,EAAI,SAAS8D,EAAI,KAA4B8C,CAAI,GAGxE5D,aAAkBb,IACbnC,EAAI,aAAa,OAAOgD,EAAO,QAAQhD,EAAI,SAAS,IAAIgD,EAAO,SAAA,IAGpE,OAAOA,KAAW,WAAiBA,IAEhChD,EAAI,aAAa,OACpBmC,EAAU,KAAKa,CAAM,EAAE,QAAQhD,EAAI,SAAS,IAC5C,OAAOgD,CAAM;AAAA,EACnB,SAASvI,GAAG;AACV,mBAAQ,KAAK,6BAA6BA,CAAC,GACpC;AAAA,EACT;AACF;AAGO,SAASoM,GAAaxK,GAAYyK,GAAiB7E,GAA4B;AACpF,MAAI5F,KAAS,QAAQA,MAAU,GAAI,QAAO;AAC1C,MAAI0K,IAAM,OAAO1K,CAAK;AACtB,MAAI,MAAM0K,CAAG,EAAG,QAAO,OAAO1K,CAAK;AAKnC,MAFI4F,KAAa,SAAM8E,IAAM/E,GAAM+E,GAAK9E,CAAS,IAE7C,CAAC6E;AAEH,WAAO7E,KAAa,OAAO8E,EAAI,QAAQ9E,CAAS,IAAI,OAAO8E,CAAG;AAIhE,MAAID,EAAO,SAAS,GAAG,GAAG;AACxB,UAAME,IAAWF,EAAO,SAAS,GAAG,IAAIA,EAAO,MAAM,GAAG,EAAE,CAAC,EAAG,SAAU7E,KAAa;AACrF,WAAO8E,EAAI,eAAe,SAAS;AAAA,MACjC,uBAAuBC;AAAA,MACvB,uBAAuBA;AAAA,IAAA,CACxB;AAAA,EACH;AACA,SAAO,OAAOD,CAAG;AACnB;AAGO,SAASE,GAAW5K,GAAYyK,IAAS,cAAsB;AACpE,MAAI,CAACzK,EAAO,QAAO;AACnB,QAAMU,IAAIV,aAAiB,OAAOA,IAAQ,IAAI,KAAKA,CAAK;AACxD,MAAI,MAAMU,EAAE,QAAA,CAAS,EAAG,QAAO,OAAOV,CAAK;AAC3C,QAAM6K,IAAInK,EAAE,YAAA,GACNoK,IAAI,OAAOpK,EAAE,SAAA,IAAa,CAAC,EAAE,SAAS,GAAG,GAAG,GAC5CqK,IAAM,OAAOrK,EAAE,QAAA,CAAS,EAAE,SAAS,GAAG,GAAG;AAC/C,SAAO+J,EACJ,QAAQ,QAAQ,OAAOI,CAAC,CAAC,EACzB,QAAQ,MAAMC,CAAC,EACf,QAAQ,MAAMC,CAAG;AACtB;AAUA,SAASC,GAAcC,GAAkBtH,GAAgBnE,GAA+B;AACtF,QAAM0L,IAAS9C,GAAU6C,GAAUtH,EAAI,IAAK,GAEtCwH,IAAO,SAAS,cAAc,MAAM;AAC1C,EAAAA,EAAK,MAAM,UACT;AAEF,QAAMC,IAAO,SAAS,cAAc,MAAM;AAC1C,EAAAA,EAAK,MAAM,UACT,+IAEFA,EAAK,cAAcF;AAGnB,QAAMG,IAAM,SAAS,cAAc,QAAQ;AAC3C,SAAAA,EAAI,QAAQ,cACZA,EAAI,aAAa,cAAc,QAAQ,GACvCA,EAAI,YACF,8PAIFA,EAAI,MAAM,UACR,2JAIFA,EAAI,iBAAiB,aAAa,MAAM;AACtC,IAAAA,EAAI,MAAM,QAAQ,6BAClBA,EAAI,MAAM,aAAa;AAAA,EACzB,CAAC,GACDA,EAAI,iBAAiB,YAAY,MAAM;AACrC,IAAAA,EAAI,MAAM,QAAQ,WAClBA,EAAI,MAAM,aAAa;AAAA,EACzB,CAAC,GAEDA,EAAI,iBAAiB,SAAS,CAACjN,MAAkB;AAC/C,IAAAA,EAAE,gBAAA,GAEFgN,EAAK,cAAcH,GACnBG,EAAK,MAAM,aAAa,IACxBA,EAAK,MAAM,gBAAgB,IAC3BA,EAAK,MAAM,QAAQ,IACnBC,EAAI,OAAA,IAEF1H,EAAY,sBACTA,EAAY,wCAAwB,IAAA,IAAgC,IAAInE,CAAQ;AAAA,EACvF,CAAC,GAED2L,EAAK,YAAYC,CAAI,GACrBD,EAAK,YAAYE,CAAG,GACbF;AACT;AAGO,MAAMG,GAAqC;AAAA,EAChD,OAAO7D,GAAiC;ATpJnC,QAAAjJ;ASqJH,UAAMyF,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,YAAY;AAEjB,UAAMsH,IAAgBjB,GAAe7C,CAAG;AACxC,QAAI8D,MAAkB;AACpB,aAAAtH,EAAK,cAAcsH,GACnBtH,EAAK,MAAM,UAAU,4EACdA;AAET,UAAM,EAAE,OAAAjE,GAAO,QAAAwL,GAAQ,UAAAhM,EAAA,IAAaiI;AAEpC,QAAIgE;AASJ,QARID,EAAO,YAAYxL,KAAS,QAAQwL,EAAO,SAASxL,CAAK,IAC3DyL,IAAcD,EAAO,SAASxL,CAAK,IAEnCyL,IAAczL,KAAS,OAAO,KAAK,OAAOA,CAAK,GAK7CwL,EAAO,MAAM;AACf,YAAME,IAAeF,EAAe,kBAAkB,IAChDG,MAAgBnN,IAAAgN,EAAe,sBAAf,gBAAAhN,EAA8D,IAAIgB,QAAc;AACtG,UAAI,CAACkM,KAAe,CAACC;AACnB,eAAOX,GAAcS,GAAaD,GAAQhM,CAAQ;AAAA,IAEtD;AAEA,WAAAyE,EAAK,cAAcwH,GACnBxH,EAAK,MAAM,UAAU,4EACdA;AAAA,EACT;AACF;AAGO,MAAM2H,GAAuC;AAAA,EAIlD,YACEC,IAA6D,CAAA,GAC7DC,GACA;AACA,SAAK,QAAQD,EAAK;AAAA,MAAI,CAAAnF,MACpB,OAAOA,KAAM,WAAW,EAAE,OAAOA,GAAG,OAAOA,EAAA,IACvC,EAAE,OAAQA,EAAU,SAAUA,EAAU,QAAQ,OAAQA,EAAU,SAAS,EAAE,GAAG,OAAQA,EAAU,MAAA;AAAA,IAAM,GAE9G,KAAK,MAAMoF,KAAM;AAAA,EACnB;AAAA,EAEA,OAAOrE,GAAiC;AACtC,UAAMxD,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,YAAY,gBACjBA,EAAK,MAAM,UAAU;AACrB,UAAM8H,IAAStE,EAAI;AACnB,QAAIsE,KAAU,QAAQA,MAAW,GAAI,QAAO9H;AAC5C,UAAM+H,IAAK,OAAOD,CAAM,GAMlBE,KALO,KAAK,MACd,KAAK,IAAIxE,EAAI,KAAKA,EAAI,QAAQ,EAAE,IAAI,CAACf,MACnC,OAAOA,KAAM,WAAW,EAAE,OAAOA,GAAG,OAAOA,EAAA,IACvC,EAAE,OAAOA,EAAE,SAASA,EAAE,QAAQ,OAAOA,EAAE,SAAS,EAAE,GAAG,OAAOA,EAAE,MAAA,CAAO,IAC3E,KAAK,OACU,KAAK,CAAAA,MAAK,OAAOA,EAAE,KAAK,MAAMsF,CAAE;AACnD,WAAA/H,EAAK,cAAcgI,IAAQA,EAAM,QAAQD,GAClC/H;AAAA,EACT;AACF;AAGO,MAAMiI,GAAuC;AAAA,EAClD,OAAOzE,GAAiC;AACtC,UAAMxD,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,YAAY;AAEjB,UAAMsH,IAAgBjB,GAAe7C,CAAG;AACxC,WAAI8D,MAAkB,QACpBtH,EAAK,cAAcsH,GACnBtH,EAAK,MAAM,UAAU,wGACdA,MAGTA,EAAK,cAAcuG,GAAa/C,EAAI,OAAOA,EAAI,OAAO,UAAU,SAASA,EAAI,OAAO,SAAS,GAC7FxD,EAAK,MAAM,UAAU,wGACdA;AAAA,EACT;AACF;AAGO,MAAMkI,GAAqC;AAAA,EAChD,OAAO1E,GAAiC;AACtC,UAAMxD,IAAO,SAAS,cAAc,MAAM;AAC1C,WAAAA,EAAK,YAAY,gBACjBA,EAAK,cAAc2G,GAAWnD,EAAI,OAAOA,EAAI,OAAO,MAAM,GAC1DxD,EAAK,MAAM,UAAU,4EACdA;AAAA,EACT;AACF;AAGO,MAAMmI,GAAyC;AAAA,EACpD,OAAO3E,GAAiC;AACtC,UAAM0D,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,YAAY,oBACjBA,EAAK,MAAM,UAAU;AACrB,UAAMkB,IAAM,SAAS,cAAc,OAAO;AAC1C,WAAAA,EAAI,OAAO,YACXA,EAAI,UAAU,CAAC,CAAC5E,EAAI,OACpB4E,EAAI,WAAW,IACfA,EAAI,MAAM,WAAW,uCACrBlB,EAAK,YAAYkB,CAAG,GACblB;AAAA,EACT;AACF;AAUO,MAAMmB,GAAuC;AAAA,EAClD,YAAoBhE,GAAyB;AAAzB,SAAA,MAAAA;AAAA,EAA0B;AAAA,EAE9C,OAAOb,GAAiC;ATlRnC,QAAAjJ,GAAAsC,GAAAyL;ASmRH,UAAMpB,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAMqB,IAAM,SAAS,cAAc,QAAQ;AAC3C,IAAAA,EAAI,YAAY,eAAchO,IAAA,KAAK,QAAL,QAAAA,EAAU,cAAc,MAAM,KAAK,IAAI,cAAc,EAAE;AACrF,UAAMiO,KAAQ3L,IAAA,KAAK,QAAL,gBAAAA,EAAU;AACxB,WAAI,OAAO2L,KAAU,aAAYD,EAAI,cAAcC,EAAMhF,EAAI,OAAOA,EAAI,GAAG,MAClE,cAAcgF,KAAS,OAAOhF,EAAI,SAAS,KAAK,GACzD+E,EAAI,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,UAIhBD,IAAA,KAAK,QAAL,gBAAAA,EAAU,UAAS,EAAE;AAAA,OAEzBC,EAAI,iBAAiB,aAAa,MAAMA,EAAI,MAAM,aAAa,iCAAiC,GAChGA,EAAI,iBAAiB,YAAa,MAAMA,EAAI,MAAM,aAAa,uBAAuB,GACtFrB,EAAK,YAAYqB,CAAG,GACbrB;AAAA,EACT;AACF;AAGO,MAAMuB,GAAsC;AAAA,EACjD,YACUC,GACAC,GACR;AAFQ,SAAA,WAAAD,GACA,KAAA,WAAAC;AAAA,EACP;AAAA,EAEH,OAAOnF,GAAiC;AT9SnC,QAAAjJ,GAAAsC,GAAAyL;AS+SH,UAAMpB,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAM0B,IAAQ,SAAS,cAAc,MAAM,GACrCjL,IAAM6F,EAAI,SAAS,OAAO,KAAK,OAAOA,EAAI,KAAK,GAE/CgF,MAAQjO,IAAA,KAAK,aAAL,gBAAAA,EAAgBoD,SAAQd,IAAA2G,EAAI,OAAO,aAAX,gBAAA3G,EAAsBc,OAAQA;AACpE,IAAAiL,EAAM,cAAcJ;AACpB,UAAMK,MAAQP,IAAA,KAAK,aAAL,gBAAAA,EAAgB3K,OAAQ;AACtC,WAAAiL,EAAM,MAAM,UAAU;AAAA;AAAA,mBAEPC,CAAK,YAAYA,CAAK,qBAAqBA,CAAK;AAAA;AAAA,OAG/D3B,EAAK,YAAY0B,CAAK,GACf1B;AAAA,EACT;AACF;AAGO,MAAM4B,GAAqC;AAAA,EAChD,YACUC,GACAC,GACR;AAFQ,SAAA,SAAAD,GACA,KAAA,SAAAC;AAAA,EACP;AAAA,EAEH,OAAOxF,GAAiC;AACtC,UAAMxG,IAAI,SAAS,cAAc,GAAG;AACpC,WAAAA,EAAE,YAAY,gBACdA,EAAE,cAAcwG,EAAI,SAAS,OAAO,KAAK,OAAOA,EAAI,KAAK,GACzDxG,EAAE,OAAO,KAAK,SAAS,KAAK,OAAOwG,EAAI,OAAOA,EAAI,GAAG,IAAI,KACrD,KAAK,WAAQxG,EAAE,SAAS,KAAK,SACjCA,EAAE,MAAM,UAAU,qJACb,KAAK,UAAQA,EAAE,iBAAiB,SAAS,CAAA7C,MAAKA,EAAE,gBAAgB,GAC9D6C;AAAA,EACT;AACF;AAGO,MAAMiM,GAAyC;AAAA,EACpD,YAAoBC,GAAgE;AAAhE,SAAA,aAAAA;AAAA,EAAiE;AAAA,EAErF,OAAO1F,GAAiC;AACtC,UAAM0D,IAAO,SAAS,cAAc,KAAK;AACzC,WAAAA,EAAK,YAAY,oBACjBA,EAAK,MAAM,UAAU,gEACrBA,EAAK,YAAY,KAAK,WAAW1D,EAAI,OAAOA,EAAI,KAAKA,EAAI,QAAQ,GAC1D0D;AAAA,EACT;AACF;AAYO,MAAMiC,GAAsC;AAAA,EACjD,YAAoB9E,GAAwB;AAAxB,SAAA,MAAAA;AAAA,EAAyB;AAAA,EAE7C,OAAOb,GAAiC;AT9WnC,QAAAjJ,GAAAsC,GAAAyL,GAAAc,GAAAC;AS+WH,UAAMnC,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAMoC,IAAM,SAAS,cAAc,KAAK,GAClC3F,KAAMpJ,IAAA,KAAK,QAAL,QAAAA,EAAU,QAAQ,KAAK,IAAI,MAAMiJ,EAAI,OAAOA,EAAI,GAAG,IAAI,OAAOA,EAAI,SAAS,EAAE;AACzF,IAAA8F,EAAI,MAAM3F;AACV,UAAM4F,MAAI1M,IAAA,KAAK,QAAL,gBAAAA,EAAU,UAAS,IACvB2M,MAAIlB,IAAA,KAAK,QAAL,gBAAAA,EAAU,WAAU,IACxBtN,MAAIoO,IAAA,KAAK,QAAL,gBAAAA,EAAU,WAAU;AAC9B,IAAAE,EAAI,MAAM,UAAU,SAASC,CAAC,aAAaC,CAAC,qCAAqCxO,CAAC;AAClF,UAAMyO,KAAMJ,IAAA,KAAK,QAAL,gBAAAA,EAAU;AACtB,WAAAC,EAAI,MAAM,OAAOG,KAAQ,aAAaA,EAAIjG,EAAI,OAAOA,EAAI,GAAG,IAAKiG,KAAO,IACxEH,EAAI,UAAU,MAAM;AAAE,MAAAA,EAAI,MAAM,UAAU;AAAA,IAAQ,GAClDpC,EAAK,YAAYoC,CAAG,GACbpC;AAAA,EACT;AACF;AAWO,MAAMwC,GAAyC;AAAA,EACpD,YAAoBrF,GAA2B;AAA3B,SAAA,MAAAA;AAAA,EAA4B;AAAA,EAEhD,OAAOb,GAAiC;AT5YnC,QAAAjJ,GAAAsC,GAAAyL,GAAAc;AS6YH,UAAMlC,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAMyC,MAAMpP,IAAA,KAAK,QAAL,gBAAAA,EAAU,QAAO,KACvBqP,IAAM,OAAOpG,EAAI,KAAK,KAAK,GAC3BqG,IAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAID,IAAMD,IAAO,GAAG,CAAC,GAClDd,KAAQhM,IAAA,KAAK,QAAL,QAAAA,EAAU,UACpB,KAAK,IAAI,QAAQ+M,CAAG,MACnBtB,IAAA,KAAK,QAAL,gBAAAA,EAAU,UAAS,6BAElBwB,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAM,YAAY,qBAClBA,EAAM,MAAM,UAAU;AACtB,UAAMC,IAAO,SAAS,cAAc,KAAK;AAMzC,QALAA,EAAK,YAAY,oBACjBA,EAAK,MAAM,UAAU,SAASF,CAAG,4BAA4BhB,CAAK,uBAClEiB,EAAM,YAAYC,CAAI,GACtB7C,EAAK,YAAY4C,CAAK,KAElBV,IAAA,KAAK,QAAL,gBAAAA,EAAU,eAAc,IAAO;AACjC,YAAMY,IAAM,SAAS,cAAc,MAAM;AACzC,MAAAA,EAAI,MAAM,UAAU,iFACpBA,EAAI,cAAc,GAAG,KAAK,MAAMH,CAAG,CAAC,KACpC3C,EAAK,YAAY8C,CAAG;AAAA,IACtB;AACA,WAAO9C;AAAA,EACT;AACF;AAWO,MAAM+C,GAA0C;AAAA,EACrD,YAAoB5F,GAA4B;AAA5B,SAAA,MAAAA;AAAA,EAA6B;AAAA,EAEjD,OAAOb,GAAiC;ATrbnC,QAAAjJ,GAAAsC,GAAAyL,GAAAc;ASsbH,UAAMlC,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AAErB,UAAMgD,IAAmB,MAAM,QAAQ1G,EAAI,KAAK,IAAIA,EAAI,MAAM,IAAI,MAAM,IAAI,CAAA;AAC5E,QAAI,CAAC0G,EAAO;AACV,aAAAhD,EAAK,cAAc,KACZA;AAGT,UAAMiD,MAAI5P,IAAA,KAAK,QAAL,gBAAAA,EAAU,UAAS,IACvB6P,MAAIvN,IAAA,KAAK,QAAL,gBAAAA,EAAU,WAAU,IACxBgM,MAAQP,IAAA,KAAK,QAAL,gBAAAA,EAAU,UAAS,WAC3B+B,MAAYjB,IAAA,KAAK,QAAL,gBAAAA,EAAU,cAAa,OAEnCkB,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,EAAO,QAAQH,GACfG,EAAO,SAASF,GAChBE,EAAO,MAAM,UAAU;AAEvB,UAAM3K,IAAI2K,EAAO,WAAW,IAAI;AAChC,QAAI3K,GAAG;AACL,YAAMgK,IAAM,KAAK,IAAI,GAAGO,GAAQ,CAAC,GAC3BK,IAAM,KAAK,IAAI,GAAGL,GAAQ,CAAC,GAC3B5L,IAAQqL,IAAMY,KAAO,GACrBC,IAAIN,EAAO;AAEjB,UAAIG,MAAc,OAAO;AACvB,cAAMI,IAAKN,IAAIK;AACf,QAAAN,EAAO,QAAQ,CAAClM,GAAG9C,MAAM;AACvB,gBAAMwP,KAAO1M,IAAIuM,KAAOjM,KAAU8L,IAAI;AACtC,UAAAzK,EAAE,YAAYkJ,GACdlJ,EAAE,SAASzE,IAAIuP,IAAK,GAAGL,IAAIM,IAAK,GAAGD,IAAK,GAAGC,CAAE;AAAA,QAC/C,CAAC;AAAA,MACH,OAAO;AACL,cAAMC,IAAMT,EAAO,IAAI,CAAClM,GAAG9C,OAAO;AAAA,UAChC,GAAIA,KAAKsP,IAAI,KAAK,KAAML;AAAA,UACxB,GAAGC,KAAMpM,IAAIuM,KAAOjM,KAAU8L,IAAI,KAAK;AAAA,QAAA,EACvC;AACF,QAAIC,MAAc,WAChB1K,EAAE,YAAYkJ,IAAQ,MACtBlJ,EAAE,UAAA,GACFA,EAAE,OAAOgL,EAAI,CAAC,EAAG,GAAGP,CAAC,GACrBO,EAAI,QAAQ,OAAKhL,EAAE,OAAOiL,EAAE,GAAGA,EAAE,CAAC,CAAC,GACnCjL,EAAE,OAAOgL,EAAIA,EAAI,SAAS,CAAC,EAAG,GAAGP,CAAC,GAClCzK,EAAE,UAAA,GACFA,EAAE,KAAA,IAEJA,EAAE,cAAckJ,GAChBlJ,EAAE,YAAY,KACdA,EAAE,UAAA,GACFgL,EAAI,QAAQ,CAACC,GAAG1P,MAAOA,MAAM,IAAIyE,EAAE,OAAOiL,EAAE,GAAGA,EAAE,CAAC,IAAIjL,EAAE,OAAOiL,EAAE,GAAGA,EAAE,CAAC,CAAE,GACzEjL,EAAE,OAAA;AAAA,MACJ;AAAA,IACF;AAEA,WAAAuH,EAAK,YAAYoD,CAAM,GAChBpD;AAAA,EACT;AACF;AAGO,MAAM2D,GAAuC;AAAA,EAClD,OAAOrH,GAAiC;AACtC,UAAM0D,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAM4D,IAAK,CAAC,CAACtH,EAAI,OACXuH,IAAK,SAAS,cAAc,MAAM;AACxC,IAAAA,EAAG,YAAY,eAAeD,IAAK,mBAAmB,KACtDC,EAAG,MAAM,UAAU;AAAA,mBACJD,IAAK,8BAA8B,SAAS;AAAA;AAE3D,UAAME,IAAO,SAAS,cAAc,MAAM;AAC1C,WAAAA,EAAK,MAAM,UAAU,kCAAkCF,IAAK,SAAS,KAAK;AAAA;AAAA,mEAG1EC,EAAG,YAAYC,CAAI,GACnB9D,EAAK,YAAY6D,CAAE,GACZ7D;AAAA,EACT;AACF;AASO,MAAM+D,GAAuC;AAAA,EAClD,YAAoB5G,GAAyB;AAAzB,SAAA,MAAAA;AAAA,EAA0B;AAAA,EAE9C,OAAOb,GAAiC;ATjhBnC,QAAAjJ,GAAAsC;ASkhBH,UAAMqK,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAMyC,MAAMpP,IAAA,KAAK,QAAL,gBAAAA,EAAU,QAAO,GACvBoD,IAAM,KAAK,MAAM,OAAO6F,EAAI,KAAK,KAAK,CAAC,GACvCqF,MAAQhM,IAAA,KAAK,QAAL,gBAAAA,EAAU,UAAS;AACjC,aAAS3B,IAAI,GAAGA,KAAKyO,GAAKzO,KAAK;AAC7B,YAAMgQ,IAAO,SAAS,cAAc,MAAM;AAC1C,MAAAA,EAAK,cAAc,KACnBA,EAAK,MAAM,UAAU,wBAAwBhQ,KAAKyC,IAAMkL,IAAQ,SAAS,mBACzE3B,EAAK,YAAYgE,CAAI;AAAA,IACvB;AACA,WAAOhE;AAAA,EACT;AACF;AAGO,MAAMiE,GAAsC;AAAA,EACjD,OAAO3H,GAAiC;AACtC,UAAM0D,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAMkE,IAAQ,SAAS,cAAc,OAAO;AAC5C,WAAAA,EAAM,OAAO,SACbA,EAAM,UAAU,CAAC,CAAC5H,EAAI,OACtB4H,EAAM,aAAa,gBAAgB5H,EAAI,QAAQ,SAAS,OAAO,GAC/D4H,EAAM,aAAa,cAAc5H,EAAI,OAAO,UAAU,IAAI,GACtDA,EAAI,OAAO,UAAO4H,EAAM,OAAO,YAAY5H,EAAI,QAAQ,IAAIA,EAAI,OAAO,KAAK,KAC/E4H,EAAM,MAAM,UAAU,iFACtBlE,EAAK,YAAYkE,CAAK,GACflE;AAAA,EACT;AACF;AAGO,MAAMmE,GAAoC;AAAA,EAC/C,OAAO7H,GAAiC;AACtC,UAAM0D,IAAO,SAAS,cAAc,MAAM;AAE1C,QADAA,EAAK,MAAM,UAAU,uFACjB,CAAC1D,EAAI,MAAO,QAAO0D;AACvB,UAAMoC,IAAM,SAAS,cAAc,KAAK;AACxC,WAAAA,EAAI,MAAM,OAAO9F,EAAI,KAAK,GAC1B8F,EAAI,MAAO9F,EAAI,OAAe,OAAOA,EAAI,OAAO,OAChD8F,EAAI,MAAM,UAAU,oEACpBA,EAAI,aAAa,QAAQ,KAAK,GAC9BpC,EAAK,YAAYoC,CAAG,GACbpC;AAAA,EACT;AACF;AAGA,SAASoE,GAAcC,GAAsB;AAC3C,QAAMC,IAAM,SAAS,cAAc,KAAK;AACxC,SAAAA,EAAI,YAAYD,GAChBC,EAAI,iBAAiB,4BAA4B,EAAE,QAAQ,CAAAC,MAAMA,EAAG,QAAQ,GAC5ED,EAAI,iBAAiB,GAAG,EAAE,QAAQ,CAAAC,MAAM;AACtC,eAAWC,KAAQ,CAAC,GAAGD,EAAG,UAAU;AAClC,MAAIC,EAAK,KAAK,WAAW,IAAI,KAAGD,EAAG,gBAAgBC,EAAK,IAAI;AAE9D,QAAID,EAAG,YAAY,KAAK;AACtB,YAAME,IAAOF,EAAG,aAAa,MAAM,KAAK;AACxC,MAAI,gBAAgB,KAAKE,CAAI,KAAGF,EAAG,gBAAgB,MAAM;AAAA,IAC3D;AAAA,EACF,CAAC,GACMD,EAAI;AACb;AAEO,MAAMI,GAAqC;AAAA,EAChD,OAAOpI,GAAiC;AACtC,UAAM0D,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,UAAU;AACrB,UAAM2E,IAAcrI,EAAI,OAAe,aAAa,IAC9C+H,IAAO,OAAO/H,EAAI,SAAS,EAAE;AACnC,WAAA0D,EAAK,YAAY2E,IAAaP,GAAcC,CAAI,IAAIA,GAC7CrE;AAAA,EACT;AACF;AAGA,MAAM4E,KAAmB;AAAA,EACvB;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAC/D;AAAA,EAAS;AAAA;AACX,GACMC,KAAa;AAEnB,SAASC,GAAUzC,GAAmB;AACpC,MAAI0C,IAAM,IAAIC,IAAM;AACpB,aAAWnI,KAAMwF;AAAK,IAAA0C,MAAQC,IAAM,MAAM,KAAK,OAAO,CAACnI,CAAE,GAAGmI,IAAM,CAACA;AACnE,SAAOD;AACT;AAEA,SAASE,GAAahF,GAAsB;AAC1C,QAAMiF,IAAkB,CAAC,GAAG;AAC5B,aAAWrI,KAAMoD,GAAM;AACrB,UAAMxH,IAAIoE,EAAG,WAAW,CAAC,IAAI;AAC7B,IAAIpE,KAAK,KAAKA,KAAK,MAAIyM,EAAM,KAAKzM,CAAC;AAAA,EACrC;AACA,MAAIY,IAAM;AACV,WAASrF,IAAI,GAAGA,IAAIkR,EAAM,QAAQlR,IAAK,CAAAqF,KAAO6L,EAAMlR,CAAC,IAAKA;AAC1D,SAAAkR,EAAM,KAAK7L,IAAM,GAAG,GACb6L,EAAM,IAAI,CAAAzM,MAAKqM,GAAUF,GAAOnM,CAAC,CAAE,CAAC,EAAE,KAAK,EAAE,IAAIqM,GAAUD,EAAU,IAAI;AAClF;AAEO,MAAMM,GAAwC;AAAA,EACnD,OAAO7I,GAAiC;AACtC,UAAM7F,IAAM,OAAO6F,EAAI,SAAS,EAAE,GAC5BgG,IAAKhG,EAAI,OAAe,iBAAiB,IACzC0D,IAAO,SAAS,cAAc,KAAK;AACzC,IAAAA,EAAK,MAAM,UAAU,qHACrBA,EAAK,aAAa,QAAQ,KAAK,GAC/BA,EAAK,aAAa,cAAc,QAAQvJ,CAAG,EAAE,GAC7CuJ,EAAK,YAAYoF,GAAY3O,GAAK6L,CAAC;AACnC,UAAMhB,IAAQ,SAAS,cAAc,MAAM;AAC3C,WAAAA,EAAM,cAAc7K,GACpB6K,EAAM,MAAM,UAAU,iHACtBtB,EAAK,YAAYsB,CAAK,GACftB;AAAA,EACT;AACF;AAEA,SAASoF,GAAYnF,GAAciD,GAAmB;AACpD,MAAI,CAACjD,EAAM,QAAO;AAClB,QAAMoF,IAAOJ,GAAahF,CAAI,GACxBqF,IAAK,KAAKC,IAAK,GACfC,IAAKH,EAAK,SAASC,IAAKC,IAAK,GAC7BE,IAAkB,CAAA;AACxB,MAAIzR,IAAI,GAAG0R,IAAIH;AACf,SAAOvR,IAAIqR,EAAK;AACd,QAAIA,EAAKrR,CAAC,MAAM,KAAK;AACnB,UAAIsP,IAAI;AACR,aAAOtP,IAAIsP,IAAI+B,EAAK,UAAUA,EAAKrR,IAAIsP,CAAC,MAAM,MAAK,CAAAA;AACnD,MAAAmC,EAAM,KAAK,YAAYC,EAAE,QAAQ,CAAC,CAAC,mBAAmBpC,IAAIgC,GAAI,QAAQ,CAAC,CAAC,aAAapC,CAAC,KAAK,GAC3FwC,KAAKpC,IAAIgC,GAAItR,KAAKsP;AAAA,IACpB;AAAS,MAAAoC,KAAKJ,GAAItR;AAEpB,SAAO,wDAAwDwR,EAAG,QAAQ,CAAC,CAAC,IAAItC,CAAC,YAAYsC,EAAG,QAAQ,CAAC,CAAC,aAAatC,CAAC,qEAAqEuC,EAAM,KAAK,EAAE,CAAC;AAC7M;AAGO,SAASE,GAAenN,GAA8B;AAC3D,QAAMoN,IAAWpN,EAAI;AACrB,MAAI,CAACoN;AACH,YAAQpN,EAAI,MAAA;AAAA,MACV,KAAK;AAAY,eAAO,IAAIuI,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIC,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIC,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIgD,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIE,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIO,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIS,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAI1E,GAAejI,EAAI,WAAkB,CAAA,GAAIA,EAAI,SAAgB;AAAA,MACzF;AAAiB,eAAO,IAAI2H,GAAA;AAAA,IAAa;AAG7C,MAAI,OAAOyF,KAAa;AACtB,YAAQA,GAAA;AAAA,MACN,KAAK;AAAY,eAAO,IAAI7E,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIC,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIC,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIE,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIS,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIL,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIoC,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIM,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIE,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIO,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIS,GAAA;AAAA,MAC5B;AAAiB,eAAO,IAAIhF,GAAA;AAAA,IAAa;AAI7C,UAAQyF,EAAS,MAAA;AAAA,IACf,KAAK;AAAa,aAAO,IAAIzE,GAAeyE,CAA6B;AAAA,IACzE,KAAK;AAAa,aAAO,IAAI3E,GAAA;AAAA,IAC7B,KAAK;AAAa,aAAO,IAAIW,GAAagE,EAAS,QAAQA,EAAS,MAAM;AAAA,IAC1E,KAAK;AAAa,aAAO,IAAI7D,GAAiB6D,EAAS,UAAU;AAAA,IACjE,KAAK;AAAa,aAAO,IAAIrE,GAAcqE,EAAS,UAAUA,EAAS,YAAYA,EAAS,QAAQ;AAAA,IACpG,KAAK;AAAa,aAAO,IAAI3D,GAAc2D,CAA4B;AAAA,IACvE,KAAK;AAAa,aAAO,IAAIpD,GAAiBoD,CAA+B;AAAA,IAC7E,KAAK;AAAa,aAAO,IAAI7C,GAAkB6C,CAAgC;AAAA,IAC/E,KAAK;AAAa,aAAO,IAAIjC,GAAA;AAAA,IAC7B,KAAK;AAAa,aAAO,IAAII,GAAe6B,CAA6B;AAAA,IACzE,KAAK;AAAa,aAAO,IAAI7E,GAAA;AAAA,IAC7B,KAAK;AAAa,aAAO,IAAIC,GAAA;AAAA,IAC7B,KAAK;AAAa,aAAO,IAAIiD,GAAA;AAAA,IAC7B,KAAK;AAAa,aAAO,IAAIE,GAAA;AAAA,IAC7B,KAAK;AAAa,aAAO,IAAIO,GAAA;AAAA,IAC7B,KAAK;AAAa,aAAO,IAAIS,GAAA;AAAA,IAC7B;AAAkB,aAAO,IAAIhF,GAAA;AAAA,EAAa;AAE9C;ACtsBO,MAAM0F,GAAa;AAAA,EAYxB,YAAYC,GAAmBpF,GAAWqF,GAAwB;AAJlE,SAAQ,+BAAsD,IAAA,GAK5D,KAAK,QAAQD,GACb,KAAK,QAAQpF,GACb,KAAK,OAAOqF,GAEZ,KAAK,UAAUC,EAAI,OAAO,WAAW,GAIrC,KAAK,QAAQ,MAAM,UAAU,yIAE7B,KAAK,YAAYA,EAAI,OAAO,iBAAiB,GAC7C,KAAK,UAAU,MAAM,UAAU,2CAC/B,KAAK,UAAU,MAAM,YAAY,oBAAoB,KAAK,GAE1D,KAAK,QAAQA,EAAI,OAAO,SAAS,GACjC,KAAK,MAAM,MAAM,UAAU,sBAC3B,KAAK,UAAU,YAAY,KAAK,KAAK,GAErCF,EAAK,YAAY,KAAK,OAAO,GAC7BA,EAAK,YAAY,KAAK,SAAS,GAG/B,KAAK,UAAU,iBAAiB,UAAU,MAAM;AAC9C,WAAK,QAAQ,aAAa,KAAK,UAAU;AAAA,IAC3C,GAAG,EAAE,SAAS,IAAM;AAAA,EACtB;AAAA,EA5BA,IAAI,cAAc;AAAE,WAAO,KAAK;AAAA,EAAW;AAAA,EA8B3C,WAAWG,GAAqBC,GAA4B;AAC1D,SAAK,UAAU,MAAM,SAAS,GAAGD,IAAcC,CAAY;AAAA,EAC7D;AAAA,EAEA,aACEC,GACAhO,GACAiO,GACA3Q,GACAiL,GACM;AVtEH,QAAArN,GAAAsC;AUuEH,SAAK,QAAQ,YAAY;AACzB,UAAMuC,IAAsBwI,EAAK,gBAAgB;AAGjD,QAAI2F,IAAU;AACd,IAAI3F,EAAK,gBAAa2F,KAAW,KAC7B3F,EAAK,cAAa2F,KAAW,KAC7B3F,EAAK,cAAa2F,KAAW,KAC7B3F,EAAK,gBAAa2F,KAAW;AACjC,UAAMC,IAAgBD,IAAUlO,EAAO,OAAO,CAACtC,GAAW9B,GAAQC,MAAc6B,KAAKuQ,EAAOpS,CAAC,KAAK0M,EAAK,qBAAqB,CAAC;AAG7H,SAAK,QAAQ,MAAM,aAAa;AAEhC,UAAM6F,IAAQP,EAAI,SAAS,iBAAiB;AAC5C,IAAAO,EAAM,aAAa,QAAQ,cAAc,GAGzCA,EAAM,MAAM,UAAU,+EAA+ED,CAAa;AAGlH,UAAME,IAAYL,EAAW;AAC7B,QAAIM,IAAkB;AACtB,UAAMC,IAAc,CAACC,GAAiBtE,GAAWf,GAAesF,IAAa,OAAO;AAClF,YAAMC,IAAKb,EAAI,MAAM,+BAA+BY,CAAU,EAAE;AAChE,MAAAC,EAAG,aAAa,WAAW,OAAOL,CAAS,CAAC,GAC5CK,EAAG,cAAcvF,GACjBwF,GAAOD,GAAI;AAAA,QACT,OAAO,GAAGxE,CAAC;AAAA,QAAM,UAAU,GAAGA,CAAC;AAAA,QAAM,WAAW;AAAA,QAChD,aAAa;AAAA,QACb,cAAc;AAAA;AAAA,QAEd,WAAW;AAAA,QAAK,YAAY;AAAA,QAAK,YAAY;AAAA,QAAU,eAAe;AAAA,QACtE,SAAS;AAAA,QAAK,UAAU;AAAA,QAAQ,OAAO;AAAA,QACvC,YAAY;AAAA,QAAQ,WAAW;AAAA,QAC/B,YAAY;AAAA,MAAA,CACb,GACGnK,IAAc,MAChB2O,EAAG,MAAM,WAAW,UACpBA,EAAG,MAAM,OAAO,GAAGJ,CAAe,MAClCI,EAAG,MAAM,SAAS,MAEpBJ,KAAmBpE,GACnBsE,EAAG,YAAYE,CAAE;AAAA,IACnB;AAEA,aAASE,IAAK,GAAGA,IAAKZ,EAAW,QAAQY,KAAM;AAC7C,YAAMJ,IAAKX,EAAI,MAAM,eAAe;AAGpC,UAFAW,EAAG,MAAM,SAAS,GAAGjG,EAAK,YAAY,MAElCqG,MAAO,MAELrG,EAAK,eAAagG,EAAYC,GAAI,IAAI,EAAE,GACxCjG,EAAK,aAAagG,EAAYC,GAAI,IAAI,EAAE,GACxCjG,EAAK,aAAagG,EAAYC,GAAI,IAAI,IAAI,GAC1CjG,EAAK,cAAa;AACpB,cAAMmG,IAAKb,EAAI,MAAM,6BAA6B;AAClD,QAAAa,EAAG,aAAa,WAAW,OAAOL,CAAS,CAAC,GAC5CK,EAAG,MAAM,UAAU,8RACf3O,IAAc,MAChB2O,EAAG,MAAM,WAAW,UACpBA,EAAG,MAAM,OAAO,GAAGJ,CAAe,MAClCI,EAAG,MAAM,SAAS,MAEpBJ,KAAmB;AACnB,cAAMO,IAAS,SAAS,cAAc,OAAO;AAC7C,QAAAA,EAAO,OAAO,YACdA,EAAO,aAAa,cAAc,SAAS,GAC3CA,EAAO,MAAM,UAAU,2BACvBA,EAAO,iBAAiB,UAAU,MAAM,KAAK,KAAK,WAAWA,EAAO,OAAO,CAAC,GAC5EH,EAAG,YAAYG,CAAM,GACrBL,EAAG,YAAYE,CAAE;AAAA,MACnB;AAGF,iBAAWI,KAASd,EAAWY,CAAE,KAAK,CAAA,GAAK;AACzC,cAAMF,IAAKb,EAAI,MAAM,gBAAgB,GAC/BxN,IAAiByO,EAAK;AAC5B,QAAIA,EAAK,UAAU,MAAGJ,EAAG,UAAUI,EAAK,UACpCA,EAAK,UAAU,MAAGJ,EAAG,UAAUI,EAAK;AAGxC,cAAMC,IAAUD,EAAK,YAAY,IAAI9O,EAAO,UAAU,CAAAgP,MAAKA,EAAE,UAAU3O,EAAI,KAAK,IAAI;AACpF,YAAIyO,EAAK,YAAY,GAAG;AACtB,gBAAM5E,IAAI6E,KAAW,IAAKd,EAAOc,CAAO,KAAKxG,EAAK,qBAAuBlI,EAAI,SAASkI,EAAK;AAC3F,UAAAmG,EAAG,MAAM,QAAQ,GAAGxE,CAAC,MACrBwE,EAAG,MAAM,WAAW,GAAGxE,CAAC;AAAA,QAC1B;AAEA,cAAM+E,IAAW3R,EAAS,KAAK,OAAKI,EAAE,UAAU2C,EAAI,KAAK,GACnD6O,IAAW7O,EAAI,aAAa,MAASkI,EAAK,YAAYuG,EAAK,YAAY;AA0B7E,YAvBAJ,EAAG,aAAa,QAAQ,cAAc,GACtCA,EAAG,aAAa,SAAS,KAAK,GAC1BQ,MACFR,EAAG,aAAa,aAAaO,IAAYA,EAAS,QAAQ,QAAQ,cAAc,eAAgB,MAAM,GAEtGP,EAAG,WAAWK,MAAY,IAAI,IAAI,IAClCL,EAAG,iBAAiB,WAAW,CAAC5T,MAAqB;AACnD,cAAIA,EAAE,QAAQ,WAAWA,EAAE,QAAQ;AACjC,YAAAA,EAAE,eAAA,GACF,KAAK,KAAK,cAAcuF,EAAI,OAAOvF,EAAE,QAAQ;AAAA,mBACpCA,EAAE,QAAQ,cAAc;AACjC,YAAAA,EAAE,eAAA;AACF,kBAAMqU,IAAOT,EAAG;AAChB,aAAIS,KAAA,gBAAAA,EAAM,aAAY,QAAMA,EAAK,MAAA;AAAA,UACnC,WAAWrU,EAAE,QAAQ,aAAa;AAChC,YAAAA,EAAE,eAAA;AACF,kBAAMsU,IAAOV,EAAG;AAChB,aAAIU,KAAA,gBAAAA,EAAM,aAAY,QAAMA,EAAK,MAAA;AAAA,UACnC;AAAA,QACF,CAAC,IAICL,KAAW,KAAKA,IAAUhP,GAAa;AACzC,cAAIsP,IAAU;AAEd,UAAI9G,EAAK,gBAAa8G,KAAW,KAC7B9G,EAAK,cAAa8G,KAAW,KAC7B9G,EAAK,cAAa8G,KAAW,KAC7B9G,EAAK,gBAAa8G,KAAW;AACjC,mBAASxT,IAAI,GAAGA,IAAIkT,GAASlT,IAAK,CAAAwT,KAAWpB,EAAOpS,CAAC,KAAK0M,EAAK;AAC/D,UAAAmG,EAAG,UAAU,IAAI,WAAW,GACxBK,MAAYhP,IAAc,KAAG2O,EAAG,UAAU,IAAI,gBAAgB,GAClEA,EAAG,MAAM,OAAO,GAAGW,CAAO;AAAA,QAC5B;AAEA,QAAAV,GAAOD,GAAI;AAAA,UACT,SAAS;AAAA,UAAW,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,UAK/B,YAAY;AAAA,UAAuB,OAAO;AAAA,UAC1C,YAAY;AAAA,UAAU,eAAe;AAAA,UACrC,UAAU;AAAA,UACV,WAAWrO,EAAI,eAAe;AAAA,UAC9B,WAAW;AAAA,UAAK,YAAY;AAAA,UAC5B,aAAa;AAAA,UACb,cAAc;AAAA,UACd,YAAY;AAAA,UAAQ,QAAQ6O,IAAW,YAAY;AAAA,UACnD,YAAY;AAAA,UAAU,UAAU;AAAA,UAAU,cAAc;AAAA,UACxD,UAAU;AAAA,QAAA,CACX,GAGDR,EAAG,SAAS,OAAOrO,EAAI,WAAY,WAAWA,EAAI,UAAWA,EAAI,UAAUA,EAAI,UAAW;AAE1F,cAAM8I,IAAQ0E,EAAI,MAAM;AAMxB,YALA1E,EAAM,cAAc9I,EAAI,UAAUA,EAAI,OACtC8I,EAAM,MAAM,UAAU,8DACtBuF,EAAG,YAAYvF,CAAK,GAGhB8F,GAAU;AACZ,UAAAP,EAAG,UAAU,IAAI,WAAW;AAC5B,gBAAMY,IAAOzB,EAAI,QAAQ,cAAc;AACvC,UAAAyB,EAAK,cAAcL,EAAS,QAAQ,QAAQ,OAAO,MACnDP,EAAG,YAAYY,CAAI;AAAA,QACrB;AAIA,YADmBjP,EAAI,eAAe,MAASkI,EAAK,cAAcuG,EAAK,YAAY,GACnE;AACd,gBAAMS,IAAa1B,EAAI,QAAQ,gBAAgB,GACzC2B,MAAYhS,KAAAtC,IAAAqN,EAAK,mBAAL,gBAAArN,EAAsBmF,EAAI,WAA1B,gBAAA7C,EAAkC,UAAS;AAC7D,UAAA+R,EAAW,cAAcC,IAAY,MAAM,KAC3CD,EAAW,QAAQ,MACnBA,EAAW,MAAM,UAAU,8DACvBC,KAAWD,EAAW,UAAU,IAAI,wBAAwB,GAChEA,EAAW,iBAAiB,SAAS,CAACzU,MAAM;AAC1C,YAAAA,EAAE,gBAAA,GACF,KAAK,KAAK,kBAAkBuF,EAAI,OAAOkP,CAAU;AAAA,UACnD,CAAC,GACDb,EAAG,YAAYa,CAAU;AAAA,QAC3B;AAGA,YAAIlP,EAAI,cAAc,IAAO;AAC3B,gBAAMoP,IAAU5B,EAAI,OAAO,kBAAkB;AAC7C,UAAA4B,EAAQ,MAAM,UAAU,mFACxBf,EAAG,YAAYe,CAAO;AACtB,gBAAMC,IAAkBX;AACxB,UAAAY,GAAYF,GAASf,GAAI,CAACxE,MAAM;AAC9B,YAAIwF,KAAmB,KAAG,KAAK,KAAK,YAAYA,GAAiBxF,CAAC;AAAA,UACpE,CAAC;AAAA,QACH;AAGA,QAAI3B,EAAK,iBAAiBwG,KAAW,KAAKD,EAAK,YAAY,MACzDJ,EAAG,YAAY,IACfA,EAAG,iBAAiB,aAAa,CAAC5T,MAAM;AVxQ3C,cAAAI;AUyQK,eAAK,KAAK,eAAe6T,CAAO,GAChCL,EAAG,UAAU,IAAI,iBAAiB,IAClCxT,IAAAJ,EAAE,iBAAF,QAAAI,EAAgB,QAAQ,cAAc,OAAO6T,CAAO;AAAA,QACtD,CAAC,GACDL,EAAG,iBAAiB,WAAW,MAAM;AACnC,UAAAA,EAAG,UAAU,OAAO,iBAAiB,GACrC,KAAK,QAAQ,iBAAiB,mBAAmB,EAAE,QAAQ,OAAMtC,EAAG,UAAU,OAAO,kBAAkB,CAAC;AAAA,QAC1G,CAAC,GACDsC,EAAG,iBAAiB,YAAY,CAAC5T,MAAM;AACrC,UAAAA,EAAE,eAAA;AACF,gBAAM8U,IAAU,KAAK,KAAK,cAAA;AAC1B,UAAIA,MAAY,QAAQA,MAAYb,MAClC,KAAK,QAAQ,iBAAiB,mBAAmB,EAAE,QAAQ,OAAM3C,EAAG,UAAU,OAAO,kBAAkB,CAAC,GACxGsC,EAAG,UAAU,IAAI,kBAAkB;AAAA,QAEvC,CAAC,GACDA,EAAG,iBAAiB,aAAa,MAAM;AACrC,UAAAA,EAAG,UAAU,OAAO,kBAAkB;AAAA,QACxC,CAAC,GACDA,EAAG,iBAAiB,QAAQ,CAAC5T,MAAM;AACjC,UAAAA,EAAE,eAAA,GACF4T,EAAG,UAAU,OAAO,kBAAkB,GACtC,KAAK,KAAK,UAAUK,CAAO;AAAA,QAC7B,CAAC,IAGCG,KACFR,EAAG,iBAAiB,SAAS,CAAC5T,MAAM;AAClC,UAAKA,EAAE,OAAuB,UAAU,SAAS,kBAAkB,KACnE,KAAK,KAAK,cAAcuF,EAAI,OAAOvF,EAAE,QAAQ;AAAA,QAC/C,CAAC,GAGH0T,EAAG,YAAYE,CAAE;AAAA,MACnB;AACA,MAAAN,EAAM,YAAYI,CAAE;AAAA,IACtB;AACA,SAAK,QAAQ,YAAYJ,CAAK;AAAA,EAChC;AAAA,EAEA,WACEjP,GAAoBC,GACpB7D,GACAyE,GACAiO,GACA1F,GACAlJ,GACAyO,GACA+B,GACAC,GACAC,IAAmC,MACnCC,GACAC,GACAC,IAAiC,CAAA,GACjCC,GACM;AVhUH,QAAAjV,GAAAsC;AUkUH,IAAI,OAAO,KAAK0S,CAAS,EAAE,eAAe,EAAE,GAAG3H,GAAM,GAAG2H,EAAA,IACxD,KAAK,MAAM,YAAY,IACvB,KAAK,SAAS,MAAA,GACd,KAAK,MAAM,MAAM,SAAS,GAAGpC,CAAW;AACxC,UAAM/N,IAAsBwI,EAAK,gBAAgB;AAGjD;AACE,UAAI6H,IAAM;AACV,MAAI7H,EAAK,gBAAa6H,KAAO,KACzB7H,EAAK,cAAa6H,KAAO,KACzB7H,EAAK,cAAa6H,KAAO,KACzB7H,EAAK,gBAAa6H,KAAO;AAC7B,YAAMC,IAAWD,IAAMpQ,EAAO,OAAO,CAACtC,GAAW9B,GAAQC,MAAc6B,KAAKuQ,EAAOpS,CAAC,KAAK0M,EAAK,qBAAqB,CAAC;AACpH,WAAK,MAAM,MAAM,WAAW,GAAG8H,CAAQ;AAAA,IACzC;AAEA,QAAIjR,IAAWD,EAAY;AAE3B,UAAMmR,IAAO,SAAS,uBAAA;AACtB,aAAS1B,IAAKzP,GAAYyP,KAAMxP,GAAUwP,KAAM;AAE9C,YAAM2B,IAAWR,IAAgBA,EAAcnB,CAAE,IAAI,MAC/C4B,IAAaD,KAAaA,EAAiB,aAAa,IACxDE,IAAYF,KAAaA,EAAiB,YAAY;AAE5D,UAAIC,GAAY;AACd,cAAME,IAAIH,GACJI,IAAW,KAAKD,EAAE,WAAW,IAAIA,EAAE,WAAW,IAC9CE,IAAQ/C,EAAI,OAAO,cAAc,GACjCgD,KAAMxR,KAAWuP,IAAKzP,KAAcoJ,EAAK;AAC/CqI,QAAAA,EAAM,MAAM,UAAU;AAAA,UACpB,OAAOC,EAAG,aAAatI,EAAK,SAAS;AAAA,UACrC;AAAA,UACA,gBAAgB,IAAImI,EAAE,SAAS,EAAE;AAAA,UACjC;AAAA;AAAA,UAEA;AAAA,QAAA,EACA,KAAK,EAAE,GACTE,EAAM,aAAa,QAAQ,KAAK,GAChCA,EAAM,aAAa,iBAAiBF,EAAE,YAAY,SAAS,OAAO,GAClEE,EAAM,aAAa,iBAAiB,OAAOhC,IAAK,CAAC,CAAC,GAClDgC,EAAM,aAAa,cAAc,OAAOF,EAAE,SAAS,CAAC,CAAC;AAGrD,YAAII,IAAS;AAOb,YANIvI,EAAK,gBAAauI,KAAU,KAC5BvI,EAAK,cAAauI,KAAU,KAC5BvI,EAAK,cAAauI,KAAU,KAC5BvI,EAAK,gBAAauI,KAAU,KAG5BA,IAAS,GAAG;AACd,gBAAMC,IAASlD,EAAI,OAAO,qBAAqB;AAC/C,UAAAkD,EAAO,MAAM,UAAU;AAAA,YACrB,SAASD,CAAM,gBAAgBA,CAAM;AAAA,YACrC;AAAA,YACA;AAAA,YACA;AAAA,UAAA,EACA,KAAK,EAAE;AACT,gBAAME,IAAKN,EAAE,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,EAAA;AACxD,cAAIM,EAAG,QAAQ,GAAK;AAAE,kBAAMpT,IAAIiQ,EAAI,MAAM;AAAG,YAAAjQ,EAAE,cAAY,IAAIoT,EAAG,KAAK,IAAIpT,EAAE,MAAM,UAAQ,8FAA8FmT,EAAO,YAAYnT,CAAC;AAAA,UAAG;AAChN,cAAIoT,EAAG,SAAS,GAAI;AAAE,kBAAMpT,IAAIiQ,EAAI,MAAM;AAAG,YAAAjQ,EAAE,cAAY,IAAIoT,EAAG,MAAM,IAAIpT,EAAE,MAAM,UAAQ,uEAAuEmT,EAAO,YAAYnT,CAAC;AAAA,UAAG;AAC1L,cAAIoT,EAAG,UAAU,GAAG;AAAE,kBAAMpT,IAAIiQ,EAAI,MAAM;AAAG,YAAAjQ,EAAE,cAAY,IAAIoT,EAAG,OAAO,IAAIpT,EAAE,MAAM,UAAQ,gGAAgGmT,EAAO,YAAYnT,CAAC;AAAA,UAAG;AACpNgT,UAAAA,EAAM,YAAYG,CAAM;AAAA,QAC1B;AAGA,YAAIE,IAAc;AAClB,iBAASC,IAAK,GAAGA,IAAKlR,EAAO,QAAQkR,KAAM;AACzC,gBAAM7Q,IAAML,EAAOkR,CAAE,GACfhH,IAAM+D,EAAOiD,CAAE,KAAK3I,EAAK,oBACzB4I,KAAaT,EAAE,gBAAgB,UAAarQ,EAAI,UAAUqQ,EAAE,eAAe,KAE3E5B,IAAOjB,EAAI,OAAO,eAAe;AASvC,cARAiB,EAAK,MAAM,UAAU;AAAA,YACnB,SAAS5E,CAAC,gBAAgBA,CAAC;AAAA,YAC3B;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA,EACA,KAAK,EAAE,GAELiH,IAAY;AAEd,kBAAMC,IAAMV,EAAE,YAAYrQ,EAAI,KAAK;AACnC,YAAAyO,EAAK,cAAcsC,MAAQ,KAAKA,IAAM,KACtCtC,EAAK,MAAM,iBAAiB,YAC5BA,EAAK,MAAM,QAAQ,6BACnBA,EAAK,MAAM,aAAa;AAAA,UAC1B,WAAW,CAACmC,GAAa;AAEvB,YAAAA,IAAc;AACd,kBAAMI,IAAQxD,EAAI,QAAQ,gBAAgB;AAC1C,YAAAwD,EAAM,cAAcX,EAAE,YAAY,OAAO,MACzCW,EAAM,MAAM,UAAU,mEACtBvC,EAAK,YAAYuC,CAAK;AAEtB,kBAAM1G,IAAMkD,EAAI,QAAQ,gBAAgB;AACxC,YAAAlD,EAAI,cAAc,GAAG+F,EAAE,WAAW,MAAMA,EAAE,WAAW,MACrD/F,EAAI,MAAM,UAAU,2DACpBmE,EAAK,YAAYnE,CAAG,GACpBmE,EAAK,MAAM,MAAM;AAAA,UACnB;AAGA8B,UAAAA,EAAM,YAAY9B,CAAI;AAAA,QACxB;AAEA8B,QAAAA,EAAM,iBAAiB,SAAS,MAAMZ,KAAA,gBAAAA,EAAgBW,EAAS,GAC/DL,EAAK,YAAYM,CAAK;AACtB;AAAA,MACF;AAGA,YAAMU,IAAuBb,IAAaF,IAAmB,MACvDgB,IAAUD,IAAWA,EAAS,OAAQvB,IAAgBQ,IAAWhV,EAAK,cAAcqT,CAAE;AAC5F,UAAI,CAAC2C,EAAS;AACd,YAAMC,IAAYf,KAAaD,IAAc,SAASjV,EAAK,YAAYqT,CAAE,GAEnEgC,IAAQ/C,EAAI,OAAO,QAAQ;AACjC,MAAA+C,EAAM,aAAa,QAAQ,KAAK,GAChCA,EAAM,aAAa,iBAAiB,OAAOhC,IAAK,CAAC,CAAC;AAClD,YAAMiC,IAAMxR,KAAWuP,IAAKzP,KAAcoJ,EAAK;AAC/C,MAAAqI,EAAM,MAAM,MAAS,GAAGC,CAAG,MAC3BD,EAAM,MAAM,SAAS,GAAGrI,EAAK,SAAS;AAGtC,UAAIkJ,IAAK7C,IAAK,MAAM,IAAI,0BAA0B;AAClD,MAAAgC,EAAM,MAAM,aAAaa,GAGrBD,MAAa,WAAWZ,EAAM,UAAU,IAAI,gBAAgB,GAC5DY,MAAa,YAAWZ,EAAM,UAAU,IAAI,iBAAiB,GAC7DY,MAAa,aAAWZ,EAAM,UAAU,IAAI,kBAAkB,GAC9Df,EAAa,IAAIjB,CAAE,KAAKgC,EAAM,UAAU,IAAI,aAAa,GAC7DA,EAAM,aAAa,iBAAiBf,EAAa,IAAIjB,CAAE,IAAI,SAAS,OAAO,GAGvE4C,MAAa,YAAWC,IAAK,mCAC7BD,MAAa,aAAWC,IAAK,oCAC7BD,MAAa,cAAWC,IAAK,qCAC7B5B,EAAa,IAAIjB,CAAE,MAAK6C,IAAK;AAGjC,YAAMC,KAAa9C;AACnB,MAAAgC,EAAM,iBAAiB,SAAS,CAAC9V,MAAM;AAAE,aAAK,KAAK,YAAY4W,IAAY,IAAI5W,CAAC;AAAA,MAAG,CAAC;AAEpF,YAAM6W,yBAAa,IAAA;AAGnB,UAAIC,IAAgB;AAGpB,UAAIrJ,EAAK,aAAa;AACpB,cAAMwI,IAASlD,EAAI,OAAO,sBAAsB,GAC1CgE,IAAgC,EAAE,OAAO,KAAK,QAAQ,KAAK,SAAS,KAAK,MAAM,GAAA,GAC/EC,IAAiC,EAAE,OAAO,WAAW,QAAQ,WAAW,SAAS,WAAW,MAAM,GAAA;AACxG,QAAAf,EAAO,cAAcc,EAAML,CAAQ,KAAK,IACxCT,EAAO,MAAM,QAAQe,EAAON,CAAQ,KAAK,IACzCT,EAAO,QAAQS,GACXzR,IAAc,MAChBgR,EAAO,MAAM,WAAW,UACxBA,EAAO,MAAM,OAAO,GAAGa,CAAa,MACpCb,EAAO,MAAM,SAAS,KACtBA,EAAO,MAAM,aAAaU,IAE5BG,KAAiB,IACjBhB,EAAM,YAAYG,CAAM;AAAA,MAC1B;AAGA,YAAMgB,IAAM,KAAK,KAAK,cAAA;AACtB,UAAIxJ,EAAK,aAAawJ,GAAK;AACzB,cAAMC,IAASD,EAAI,aAAanB,GAAOhC,GAAIrG,EAAK,cAAcnJ,IAAW,CAAC;AAC1E,QAAIW,IAAc,MAChBiS,EAAO,MAAM,WAAW,UACxBA,EAAO,MAAM,OAAO,GAAGJ,CAAa,MACpCI,EAAO,MAAM,SAAS,KACtBA,EAAO,MAAM,aAAaP,IAE5BG,KAAiB,IACjBhB,EAAM,YAAYoB,CAAM;AAAA,MAC1B;AAGA,UAAIzJ,EAAK,WAAW;AAClB,cAAM0J,IAAUpE,EAAI,OAAO,uBAAuB;AAClD,QAAAoE,EAAQ,cAAc,OAAOrD,IAAK,CAAC,GAC/B7O,IAAc,MAChBkS,EAAQ,MAAM,WAAW,UACzBA,EAAQ,MAAM,OAAO,GAAGL,CAAa,MACrCK,EAAQ,MAAM,SAAS,KACvBA,EAAQ,MAAM,aAAaR,IAE7BG,KAAiB,IACjBhB,EAAM,YAAYqB,CAAO;AAAA,MAC3B;AAGA,UAAI1J,EAAK,aAAa;AACpB,cAAM2J,IAAUrE,EAAI,OAAO,sBAAsB,GAC3C9E,IAAM,SAAS,cAAc,OAAO;AAC1C,QAAAA,EAAI,OAAO,YACXA,EAAI,UAAU+G,EAAY,IAAIlB,CAAE,GAChC7F,EAAI,aAAa,cAAc,GAAG6F,IAAK,CAAC,MAAM,GAC9C7F,EAAI,iBAAiB,SAAS,CAACjO,MAAMA,EAAE,iBAAiB,GACxDiO,EAAI,iBAAiB,UAAU,CAACjO,MAAM;AACpC,UAAAA,EAAE,gBAAA,GACF,KAAK,KAAK,WAAW8T,GAAI7F,EAAI,OAAO;AAAA,QACtC,CAAC,GACDmJ,EAAQ,YAAYnJ,CAAG,GACnBhJ,IAAc,MAChBmS,EAAQ,MAAM,WAAW,UACzBA,EAAQ,MAAM,OAAO,GAAGN,CAAa,MACrCM,EAAQ,MAAM,SAAS,KACvBA,EAAQ,MAAM,aAAaT,IAE7BG,KAAiB,IACjBhB,EAAM,YAAYsB,CAAO;AAAA,MAC3B;AAGA,eAAShB,IAAK,GAAGA,IAAKlR,EAAO,QAAQkR,KAAM;AACzC,cAAM7Q,IAAML,EAAOkR,CAAE,GACfhH,IAAI+D,EAAOiD,CAAE,KAAK3I,EAAK,oBACvB4J,KAAa5J,EAAK,YAAYlI,EAAI,aAAa,IAC/C+R,IAAalB,MAAO,GAGpBmB,IAAYlC,KAAe,CAACA,EAAY,UAC1CA,EAAY,QAAQvB,GAAIsC,CAAE,IAC1B;AACJ,YAAImB,KAAA,QAAAA,EAAW,QAAQ;AAErB,gBAAMC,IAAKzE,EAAI,OAAO,2BAA2B;AACjD,UAAAyE,EAAG,MAAM,UAAU,SAASpI,CAAC,gBAAgBA,CAAC,6DAC9C0G,EAAM,YAAY0B,CAAE;AACpB;AAAA,QACF;AAEA,cAAMC,IAAS1E,EAAI,OAAO,SAAS;AACnC,QAAA0E,EAAO,aAAa,QAAQ,UAAU,GACtCA,EAAO,aAAa,iBAAiB,OAAOrB,IAAK,CAAC,CAAC;AAGnD,cAAMsB,KAAKH,KAAA,gBAAAA,EAAW,YAAW,GAC3BI,KAAKJ,KAAA,gBAAAA,EAAW,YAAW,GAC3BK,KAAeF,IAAK,IAAIA,IAAKjK,EAAK,YAAYA,EAAK;AAEzD,YAAIoK,IAAczI;AAClB,YAAIuI,IAAK;AACP,mBAASG,IAAK,GAAGA,IAAKH,GAAIG;AACxB,YAAAD,KAAe1E,EAAOiD,IAAK0B,CAAE,KAAKrK,EAAK;AAO3C,cAAMsK,IAAe3B,IAAKnR;AAC1B,YAAI+S,IAAgB;AACpB,YAAID,GAAc;AAEhB,UAAItK,EAAK,gBAAauK,KAAiB,KACnCvK,EAAK,cAAauK,KAAiB,KACnCvK,EAAK,cAAauK,KAAiB,KACnCvK,EAAK,gBAAauK,KAAiB;AACvC,mBAASjX,IAAI,GAAGA,IAAIqV,GAAIrV,IAAK,CAAAiX,KAAiB7E,EAAOpS,CAAC,KAAK0M,EAAK;AAChE,UAAAgK,EAAO,UAAU,IAAI,gBAAgB,GACjCrB,MAAOnR,IAAc,KAAGwS,EAAO,UAAU,IAAI,gBAAgB;AAAA,QACnE;AAIA,QAAAA,EAAO,MAAM,QAAW,GAAGI,CAAW,MACtCJ,EAAO,MAAM,WAAW,GAAGI,CAAW,MACtCJ,EAAO,MAAM,WAAW,GAAGI,CAAW,MAClCH,IAAK,MAAGD,EAAO,MAAM,SAAS,GAAGG,EAAY,OAC7CG,MAAcN,EAAO,MAAM,aAAad,IACxCH,KAAYc,MAAYG,EAAO,MAAM,UAAU,MACnDA,EAAO,MAAM,WAAW,UACpBC,IAAK,KAEPD,EAAO,MAAM,SAAa,GAAGG,EAAY,MACzCH,EAAO,MAAM,WAAa,YAC1BA,EAAO,MAAM,SAAa,KAE1BA,EAAO,MAAM,aAAcd,KAAMA,MAAO,YAAaA,IAAK,0BAE1Dc,EAAO,MAAM,YAAY,KACzBA,EAAO,MAAM,aAAa,KAC1BA,EAAO,MAAM,eAAe,+CACnBM,MACTN,EAAO,MAAM,WAAW,UACxBA,EAAO,MAAM,OAAW,GAAGO,CAAa,MACxCP,EAAO,MAAM,SAAW,MAEtBlS,EAAI,SAAS,YAAYA,EAAI,UAAU,UAASkS,EAAO,UAAU,IAAI,gBAAgB,IAChFlS,EAAI,UAAU,YAAUkS,EAAO,UAAU,IAAI,iBAAiB,GACnEJ,MAAYI,EAAO,UAAU,IAAI,mBAAmB,GAEpDlS,EAAI,QAAMkS,EAAO,UAAU,IAAI,eAAe,GAG7CJ,MAAYI,EAAO,aAAa,iBAAiB,MAAM,GACxDE,IAAK,KAAGF,EAAO,aAAa,gBAAgB,OAAOE,CAAE,CAAC,GACtDD,IAAK,KAAGD,EAAO,aAAa,gBAAgB,OAAOC,CAAE,CAAC,KAExCtX,IAAAqN,EAAK,eAAL,gBAAArN,EAAiB,QAAO0T,OAAMpR,IAAA+K,EAAK,eAAL,gBAAA/K,EAAiB,QAAO0T,MAEtEqB,EAAO,UAAU,IAAI,iBAAiB,GACtCA,EAAO,WAAW;AAGpB,cAAMQ,IAAUxB,IAAUA,EAAQlR,EAAI,KAAK,IAAI;AAC/C,QAAAkS,EAAO,aAAa,cAAc,GAAGlS,EAAI,MAAM,KAAK0S,KAAW,OAAO,KAAK,OAAOA,CAAO,CAAC,EAAE,GAGxF1S,EAAI,WAAW,OACjBkS,EAAO,QAAQ,OAAOlS,EAAI,WAAY,aAClC,OAAOA,EAAI,QAAQ0S,GAASxB,CAAc,KAAK,EAAE,IACjD,OAAOlR,EAAI,OAAO,IACbkI,EAAK,YAAYwK,KAAW,QAAQA,MAAY,OACzDR,EAAO,QAAQ,OAAOQ,CAAO;AAI/B,YAAIC,KAAiCT;AAErC,YAAIjB,KAAYc,GAAY;AAC1B,gBAAMa,IAAWpF,EAAI,OAAO,cAAc,GAGpCqF,IAA0B5B,EAAS,oBAAoB,CAAA;AAC7D,mBAASlU,IAAI,GAAGA,IAAIkU,EAAS,QAAQlU,KAAK;AACxC,kBAAM+V,IAAQtF,EAAI,QAAQ,eAAe;AACzC,YAAIqF,EAAa9V,CAAC,KAAG+V,EAAM,UAAU,IAAI,qBAAqB,GAC9DF,EAAS,YAAYE,CAAK;AAAA,UAC5B;AAGA,cAAI7B,EAAS,SAAS,GAAG;AACvB,kBAAM8B,IAAOvF,EAAI,QAAQ,mBAAmB;AAC5C,YAAAuF,EAAK,UAAU;AAAA,cACb9B,EAAS,eAAe,4BAA4B;AAAA,YAAA,GAEtD2B,EAAS,YAAYG,CAAI;AAAA,UAC3B;AAGA,gBAAMC,KAAaxF,EAAI,QAAQ,qBAAqB;AACpD,cAAI,CAACyD,EAAS,cAAc;AAC1B,kBAAMxO,IAAM+K,EAAI,QAAQ,kBAAkB;AAC1C,YAAAwF,GAAW,YAAYvQ,CAAG;AAAA,UAC5B;AACA,UAAAmQ,EAAS,YAAYI,EAAU;AAG/B,gBAAMC,IAAW,SAAS,cAAc,GAAG;AAC3C,cAAIhC,EAAS,cAAc;AACzB,kBAAMiC,IAAUC,GAAiBnT,EAAI,cAAckR,GAAS,IAAMD,EAAS,SAAS;AACpF,YAAAgC,EAAS,YAAYhC,EAAS,YAC1B,GAAGiC,CAAO,mGACV,GAAGA,CAAO,0EACdD,EAAS,aAAa,QAAQ,QAAQ,GACtCA,EAAS,aAAa,YAAY,GAAG,GACrCA,EAAS,aAAa,iBAAiBhC,EAAS,YAAY,SAAS,OAAO,GAC5EgC,EAAS,aAAa,cAAchC,EAAS,YAAY,OAAO,KAAK,GACrEgC,EAAS,iBAAiB,SAAS,CAACxY,MAAkB;AACpD,cAAAA,EAAE,gBAAA,GACFmV,KAAA,QAAAA,EAAeqB,EAAS;AAAA,YAC1B,CAAC,GACDgC,EAAS,iBAAiB,WAAW,CAACxY,MAAqB;AACzD,eAAIA,EAAE,QAAQ,WAAWA,EAAE,QAAQ,SACjCA,EAAE,eAAA,GACFA,EAAE,gBAAA,GACFmV,KAAA,QAAAA,EAAeqB,EAAS;AAAA,YAE5B,CAAC;AAAA,UACH,OAAO;AACL,kBAAMiC,IAAUC,GAAiBnT,EAAI,cAAckR,GAAS,IAAO,EAAK;AACxE,YAAA+B,EAAS,aAAa,eAAe,MAAM,GAC3CA,EAAS,YAAY,GAAGC,CAAO;AAAA,UACjC;AACA,UAAAN,EAAS,YAAYK,CAAQ,GAE7Bf,EAAO,YAAYU,CAAQ,GAC3BD,KAAoBC;AAAA,QACtB;AAGA,YAAI5S,EAAI,WAAW;AACjB,gBAAM/B,IAAMiT,EAAQlR,EAAI,KAAK,GACvB3C,IAAI,OAAO2C,EAAI,aAAc,aAAaA,EAAI,UAAU/B,GAAKiT,GAAgB3C,CAAE,IAAIvO,EAAI;AAC7F,iBAAO,OAAOkS,EAAO,OAAO7U,CAAC;AAAA,QAC/B;AAIA,cAAM+V,KADWjG,GAAenN,CAAG,EACT,OAAO;AAAA,UAC/B,OAAOkR,EAAQlR,EAAI,KAAK;AAAA,UAAG,KAAKkR;AAAA,UAAS,UAAU3C;AAAA,UACnD,QAAQvO;AAAA,UAAY,UAAU6Q;AAAA,UAC9B,YAAYrB,EAAa,IAAIjB,CAAE;AAAA,UAAG,UAAA4C;AAAA,QAAA,CACnC;AACD,QAAAwB,GAAkB,YAAYS,EAAQ;AAGtC,cAAMC,IAAU9E,GAAI+E,IAAUzC;AAW9B,YAVAqB,EAAO,iBAAiB,SAAa,CAACzX,MAAM;AAAE,UAAAA,EAAE,gBAAA,GAAmB,KAAK,KAAK,YAAY4Y,GAASC,GAAS7Y,CAAC;AAAA,QAAG,CAAC,GAChHyX,EAAO,iBAAiB,YAAa,CAACzX,MAAM;AAAE,UAAAA,EAAE,gBAAA,GAAmB,KAAK,KAAK,eAAe4Y,GAASC,GAAS7Y,CAAC;AAAA,QAAG,CAAC,GACnHyX,EAAO,iBAAiB,aAAa,CAACzX,MAAM;AAAE,UAAAA,EAAE,gBAAA,GAAmB,KAAK,KAAK,gBAAgB4Y,GAASC,GAAS7Y,CAAC;AAAA,QAAG,CAAC,GACpHyX,EAAO,iBAAiB,YAAa,CAACzX,MAAM;AAAE,UAAAA,EAAE,gBAAA,GAAmB,KAAK,KAAK,eAAe4Y,GAASC,GAAS7Y,CAAC;AAAA,QAAG,CAAC,GACnHyX,EAAO,iBAAiB,aAAa,CAACzX,MAAM;AAAE,UAAAA,EAAE,gBAAA,GAAmB,KAAK,KAAK,gBAAgB4Y,GAASC,GAAS7Y,CAAC;AAAA,QAAG,CAAC,GACpHyX,EAAO,iBAAiB,WAAa,CAACzX,MAAM;AAAE,UAAAA,EAAE,gBAAA,GAAmB,KAAK,KAAK,cAAc4Y,GAASC,GAAS7Y,CAAC;AAAA,QAAG,CAAC,GAClHyX,EAAO,iBAAiB,aAAa,CAACzX,MAAM;AAAE,UAAAA,EAAE,gBAAA,GAAmB,KAAK,KAAK,gBAAgB4Y,GAASC,GAAS7Y,CAAC;AAAA,QAAG,CAAC,GAEpH6W,GAAO,IAAIT,GAAIqB,CAAM,GAEjBC,IAAK,GAAG;AAEV,gBAAMF,IAAK,SAAS,cAAc,KAAK;AACvC,UAAAA,EAAG,MAAM,UAAU;AAAA,YACjB,SAASpI,CAAC,gBAAgBA,CAAC,aAAa3B,EAAK,SAAS;AAAA,YACtD;AAAA,YACA;AAAA,UAAA,EACA,KAAK,EAAE,GACTqI,EAAM,YAAY0B,CAAE;AAGpB,cAAIjD,IAAU;AACd,UAAI9G,EAAK,gBAAa8G,KAAW,KAC7B9G,EAAK,cAAa8G,KAAW,KAC7B9G,EAAK,cAAa8G,KAAW,KAC7B9G,EAAK,gBAAa8G,KAAW;AACjC,mBAASuE,IAAK,GAAGA,IAAK1C,GAAI0C,IAAM,CAAAvE,KAAWpB,EAAO2F,CAAE,KAAKrL,EAAK;AAC9D,gBAAMsL,KAASxU,KAAWuP,IAAKzP,KAAcoJ,EAAK;AAClD,UAAAgK,EAAO,MAAM,OAAO,GAAGlD,CAAO,MAC9BkD,EAAO,MAAM,MAAO,GAAGsB,EAAM,MAC7BvD,EAAK,YAAYiC,CAAM;AAAA,QACzB;AACE,UAAA3B,EAAM,YAAY2B,CAAM;AAAA,MAE5B;AAEA,WAAK,SAAS,IAAI3D,GAAI+C,EAAM,GAC5BrB,EAAK,YAAYM,CAAK;AAAA,IACxB;AAGA,QAAIrV,EAAK,aAAa,GAAG;AACvB,YAAMuY,IAAQjG,EAAI,OAAO,kBAAkB;AAC3C,MAAAiG,EAAM,cAAc,cACpBA,EAAM,MAAM,UAAU,eACtBxD,EAAK,YAAYwD,CAAK;AAAA,IACxB;AAEA,SAAK,MAAM,YAAYxD,CAAI;AAAA,EAC7B;AAAA,EAEA,UAAUpU,GAAkB+D,GAA2C;AV9wBlE,QAAA/E;AU+wBH,YAAOA,IAAA,KAAK,SAAS,IAAIgB,CAAQ,MAA1B,gBAAAhB,EAA6B,IAAI+E;AAAA,EAC1C;AAAA,EAEA,UAAgB;AACd,SAAK,MAAM,YAAY;AAAA,EACzB;AACF;AAGA,SAASuT,GACPxO,GACAxJ,GACAuY,GACAC,GACQ;AACR,MAAI1E;AACJ,SAAKtK,IAEM,OAAOA,KAAQ,aACxBsK,IAAOtK,EAAIxJ,GAAKuY,GAAaC,CAAQ,IAEjCD,IACFzE,IAAO0E,IAAYhP,EAAI,cAAc,oBAAsBA,EAAI,UAAU,eAEzEsK,IAAOtK,EAAI,QAAQ,oBAPrBsK,IAAOyE,IAAeC,IAAW,oBAAoB,eAAgB,mBAUhE1E,EAAK,WAAW,KAAK,IAAIA,IAAO,MAAMA,CAAI;AACnD;AAGO,SAASzB,EAAIoG,GAAaC,GAAiC;AAChE,QAAMpZ,IAAI,SAAS,cAAcmZ,CAAG;AACpC,SAAIC,QAAa,YAAYA,IACtBpZ;AACT;AAEO,SAAS6T,GAAOvC,GAAiB+H,GAA4C;AAClF,SAAO,OAAO/H,EAAG,OAAO+H,CAAM;AAChC;AAEO,SAASC,GAAcC,GAAiBC,GAAkBC,IAAO,4BAAkC;AACxG,QAAMC,IAAO,IAAI,KAAK,CAACH,CAAO,GAAG,EAAE,MAAME,GAAM,GACzCE,IAAM,IAAI,gBAAgBD,CAAI,GAC9B7W,IAAI,SAAS,cAAc,GAAG;AACpC,EAAAA,EAAE,OAAO8W,GAAK9W,EAAE,WAAW2W,GAAU3W,EAAE,MAAA,GACvC,IAAI,gBAAgB8W,CAAG;AACzB;AAGA,SAAS9E,GAAYqC,GAAqBtD,GAAiBgG,GAAqC;AAC9F,MAAIC,IAAS,GAAGC,IAAS;AAEzB,EAAA5C,EAAO,iBAAiB,aAAa,CAAClX,MAAkB;AACtD,IAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA,GACF6Z,IAAS7Z,EAAE,SACX8Z,IAASlG,EAAG;AAEZ,UAAMmG,IAAS,CAACC,MAAmB;AACjC,YAAM5K,IAAI,KAAK,IAAI,IAAI0K,IAASE,EAAG,UAAUH,CAAM;AACnD,MAAAjG,EAAG,MAAM,QAAQ,GAAGxE,CAAC,MACrBwE,EAAG,MAAM,WAAW,GAAGxE,CAAC;AAAA,IAC1B,GACM6K,IAAO,CAACD,MAAmB;AAC/B,eAAS,oBAAoB,aAAaD,CAAM,GAChD,SAAS,oBAAoB,WAAWE,CAAI,GAC5CL,EAAS,KAAK,IAAI,IAAIE,IAASE,EAAG,UAAUH,CAAM,CAAC;AAAA,IACrD;AACA,aAAS,iBAAiB,aAAaE,CAAM,GAC7C,SAAS,iBAAiB,WAAWE,CAAI;AAAA,EAC3C,CAAC;AACH;AC51BO,MAAMC,GAAgD;AAAA,EAK3D,YAAYzZ,GAAoB;AAJhC,SAAQ,oCAAiC,IAAA,GACzC,KAAQ,mCAAgC,IAAA,GAItC,KAAK,QAAQA;AAAA,EACf;AAAA;AAAA,EAGA,IAAI,eAA4B;AAAE,WAAO,KAAK;AAAA,EAAe;AAAA,EAC7D,IAAI,cAA2B;AAAE,WAAO,KAAK;AAAA,EAAc;AAAA;AAAA,EAG3D,aAAaqT,GAAkB;AAC7B,SAAK,cAAc,MAAA,GACnB,KAAK,cAAc,IAAIA,CAAE;AAAA,EAC3B;AAAA,EAEA,aAAaA,GAAkB;AAC7B,IAAI,KAAK,cAAc,IAAIA,CAAE,IAAG,KAAK,cAAc,OAAOA,CAAE,IACvD,KAAK,cAAc,IAAIA,CAAE;AAAA,EAChC;AAAA,EAEA,iBAAuB;AAAE,SAAK,cAAc,MAAA;AAAA,EAAS;AAAA;AAAA,EAGrD,MAAMA,GAAYqG,GAAwB;AACxC,IAAIA,IAAS,KAAK,aAAa,IAAIrG,CAAE,IAChC,KAAK,aAAa,OAAOA,CAAE;AAAA,EAClC;AAAA,EAEA,SAASqG,GAAkBC,GAAyB;AAClD,QAAID;AACF,eAASpZ,IAAI,GAAGA,IAAIqZ,GAAWrZ,IAAK,MAAK,aAAa,IAAIA,CAAC;AAAA;AAE3D,WAAK,aAAa,MAAA;AAAA,EAEtB;AAAA,EAEA,aAAaY,GAAeoO,GAAqB;AAC/C,aAAShP,IAAI,GAAGA,IAAI,KAAK,MAAM,UAAUA;AACvC,MAAIgP,EAAO,SAAS,KAAK,MAAM,aAAahP,GAAGY,CAAK,CAAC,KAAG,KAAK,aAAa,IAAIZ,CAAC;AAAA,EAEnF;AAAA,EAEA,aAAmB;AAAE,SAAK,aAAa,MAAA;AAAA,EAAS;AAAA,EAEhD,UAAUsZ,GAAsB;AAAA,EAAC;AAAA,EACjC,aAAaA,GAAsB;AAAA,EAAC;AAAA,EACpC,YAAYA,GAAsB;AAAA,EAAC;AAAA;AAAA,EAGnC,gBAAqB;AACnB,WAAO,CAAC,GAAG,KAAK,aAAa,EAC1B,IAAI,CAAAtZ,MAAK,KAAK,MAAM,cAAcA,CAAC,CAAC,EACpC,OAAO,OAAO;AAAA,EACnB;AAAA,EAEA,aAAkD;AAChD,WAAO,CAAC,GAAG,KAAK,YAAY,EAAE,IAAI,CAAAA,OAAM;AAAA,MACtC,KAAK,KAAK,MAAM,cAAcA,CAAC;AAAA,MAC/B,UAAUA;AAAA,IAAA,EACV;AAAA,EACJ;AAAA,EAEA,gBAAqB;AAAE,WAAO,KAAK,aAAa,IAAI,CAAAF,MAAKA,EAAE,GAAG;AAAA,EAAG;AAAA,EAEjE,eAAuB;AACrB,WAAO,KAAK,cAAc,OAAO,IAAI,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC,IAAK;AAAA,EACrE;AAAA,EAEA,SAAS8E,GAAqB;AAC5B,SAAK,cAAc,MAAA,GACnB,KAAK,cAAc,IAAIA,CAAK;AAAA,EAC9B;AAAA,EAEA,WAAiB;AAAE,SAAK,cAAc,MAAA;AAAA,EAAS;AAAA;AAAA,EAG/C,QAAc;AACZ,SAAK,cAAc,MAAA,GACnB,KAAK,aAAa,MAAA;AAAA,EACpB;AACF;AClFO,MAAM2U,GAAiC;AAAA,EAAvC,cAAA;AAgCL,SAAQ,aAAa,CAAC,MAA2B;AAC/C,QAAE,gBAAA,GACE,EAAE,QAAQ,WAAW,EAAE,eAAA,GAAkB,KAAK,UAAU,KAAK,MAAM,KAAK,KACnE,EAAE,QAAQ,iBAAe,UAAA;AAAA,IACpC,GAEA,KAAQ,UAAU,MAAY;AAAE,WAAK,UAAU,KAAK,MAAM,KAAK;AAAA,IAAG;AAAA,EAAA;AAAA,EAhClE,MAAMrW,GAAwBoF,GAAoBkR,GAA4BC,GAA4B;AACxG,SAAK,aAAavW,GAClB,KAAK,YAAasW,GAClB,KAAK,YAAaC,GAElBvW,EAAU,aAAa,iBAAiB,QAAQ,GAChDA,EAAU,aAAa,iBAAiB,MAAM,GAE9C,KAAK,QAAQ,SAAS,cAAc,OAAO,GAC3C,KAAK,MAAM,OAAO,QAClB,KAAK,MAAM,YAAY,iBACvB,KAAK,MAAM,aAAa,cAAcoF,EAAI,OAAO,UAAU,OAAO;AAElE,UAAMoG,IAAMpG,EAAI;AAChB,QAAIoG,GAAK;AACP,YAAMnN,IAAImN,aAAe,OAAOA,IAAM,IAAI,KAAKA,CAAG;AAClD,MAAK,MAAMnN,EAAE,QAAA,CAAS,MACpB,KAAK,MAAM,QAAQkK,GAAWlK,GAAG,YAAY;AAAA,IAEjD;AAEA,SAAK,MAAM,iBAAiB,WAAW,KAAK,UAAU,GACtD,KAAK,MAAM,iBAAiB,QAAW,KAAK,OAAO,GACnD2B,EAAU,YAAY,KAAK,KAAK;AAAA,EAClC;AAAA,EAUA,WAAgB;AZrCX,QAAA7D;AYqCa,YAAOA,IAAA,KAAK,UAAL,gBAAAA,EAAY;AAAA,EAAO;AAAA,EAC5C,QAAgB;AZtCX,QAAAA;AYsCa,KAAAA,IAAA,KAAK,UAAL,QAAAA,EAAY;AAAA,EAAS;AAAA,EAEvC,UAAgB;AZxCX,QAAAA,GAAAsC,GAAAyL;AYyCH,KAAA/N,IAAA,KAAK,eAAL,QAAAA,EAAiB,aAAa,iBAAiB,WAC/CsC,IAAA,KAAK,UAAL,QAAAA,EAAY,oBAAoB,WAAW,KAAK,cAChDyL,IAAA,KAAK,UAAL,QAAAA,EAAY,oBAAoB,QAAW,KAAK;AAAA,EAClD;AACF;AC/CA,SAASsM,GAAiBhL,GAA2D;AACnF,SAAOA,EAAI,IAAI,CAAAnH,MACT,OAAOA,KAAM,WAAiB,EAAE,OAAOA,GAAG,OAAOA,EAAA,IAE9C,EAAE,OADMA,EAAU,SAAUA,EAAU,QAAQ,OAAQA,EAAU,SAAS,EAAE,GAClE,OAAQA,EAAU,MAAA,CACnC;AACH;AAEO,MAAMoS,GAAmC;AAAA,EAQ9C,YACExW,IAA0B,CAAA,GAC1ByW,GACA;AACA,SAAK,WAAaF,GAAiBvW,CAAO,GAC1C,KAAK,aAAayW,KAAa;AAAA,EACjC;AAAA,EAEA,MAAM1W,GAAwBoF,GAAoBkR,GAA4BC,GAA4B;AACxG,SAAK,aAAavW,GAClB,KAAK,YAAasW,GAClB,KAAK,YAAaC,GAElBvW,EAAU,aAAa,iBAAiB,SAAS,GACjDA,EAAU,aAAa,iBAAiB,MAAM,GAE9C,KAAK,SAAS,SAAS,cAAc,QAAQ,GAC7C,KAAK,OAAO,YAAY,kBACxB,KAAK,OAAO,aAAa,cAAcoF,EAAI,OAAO,UAAU,IAAI;AAEhE,UAAMuR,IAAW,KAAK,aAClBH,GAAiB,KAAK,WAAWpR,EAAI,KAAKA,EAAI,QAAQ,CAAC,IACvD,KAAK;AAET,eAAWtC,KAAO6T,GAAU;AAC1B,YAAMtJ,IAAK,SAAS,cAAc,QAAQ;AAC1C,MAAAA,EAAG,QAAc,OAAOvK,EAAI,KAAK,GACjCuK,EAAG,cAAcvK,EAAI,OACrB,KAAK,OAAO,YAAYuK,CAAE;AAAA,IAC5B;AAEA,UAAMuJ,IAAMxR,EAAI,SAAS,OAAO,KAAK,OAAOA,EAAI,KAAK;AACrD,IAAIuR,EAAS,KAAK,CAAAtS,MAAK,OAAOA,EAAE,KAAK,MAAMuS,CAAG,MAAG,KAAK,OAAO,QAAQA,IAErE,KAAK,OAAO,iBAAiB,UAAW,MAAMN,EAAS,KAAK,OAAO,KAAK,CAAC,GACzE,KAAK,OAAO,iBAAiB,QAAW,MAAMA,EAAS,KAAK,OAAO,KAAK,CAAC,GACzE,KAAK,OAAO,iBAAiB,WAAW,CAACva,MAAM;AAAE,MAAIA,EAAE,QAAQ,YAAUwa,EAAA;AAAA,IAAY,CAAC,GACtFvW,EAAU,YAAY,KAAK,MAAM;AAAA,EACnC;AAAA,EAEA,WAAgB;AbtDX,QAAA7D;AasDa,YAAOA,IAAA,KAAK,WAAL,gBAAAA,EAAa;AAAA,EAAO;AAAA,EAC7C,QAAgB;AbvDX,QAAAA;AauDa,KAAAA,IAAA,KAAK,WAAL,QAAAA,EAAa;AAAA,EAAS;AAAA,EAExC,UAAgB;AbzDX,QAAAA;Aa0DH,KAAAA,IAAA,KAAK,eAAL,QAAAA,EAAiB,aAAa,iBAAiB;AAAA,EACjD;AACF;AC/CO,MAAM0a,GAAiC;AAAA,EAAvC,cAAA;AAuBL,SAAQ,aAAa,CAAC,MAA2B;AAC/C,QAAE,gBAAA,GACE,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAA,GACF,KAAK,UAAU,KAAK,MAAM,KAAK,KACtB,EAAE,QAAQ,YACnB,KAAK,UAAA;AAAA,IAET,GAEA,KAAQ,UAAU,MAAY;AAC5B,WAAK,UAAU,KAAK,MAAM,KAAK;AAAA,IACjC;AAAA,EAAA;AAAA,EA9BA,MAAM7W,GAAwBoF,GAAoBkR,GAA4BC,GAA4B;AACxG,SAAK,YAAYD,GACjB,KAAK,YAAYC,GAEjB,KAAK,QAAQ,SAAS,cAAc,OAAO,GAC3C,KAAK,MAAM,OAAO,QAClB,KAAK,MAAM,QAAQnR,EAAI,SAAS,OAAO,KAAK,OAAOA,EAAI,KAAK,GAC5D,KAAK,MAAM,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,OAM3B,KAAK,MAAM,iBAAiB,WAAW,KAAK,UAAU,GACtD,KAAK,MAAM,iBAAiB,QAAQ,KAAK,OAAO,GAChDpF,EAAU,YAAY,KAAK,KAAK;AAAA,EAClC;AAAA,EAgBA,WAAgB;AdlDX,QAAA7D;AckDa,YAAOA,IAAA,KAAK,UAAL,gBAAAA,EAAY;AAAA,EAAO;AAAA,EAE5C,QAAc;AdpDT,QAAAA,GAAAsC;AcqDH,KAAAtC,IAAA,KAAK,UAAL,QAAAA,EAAY,UACZsC,IAAA,KAAK,UAAL,QAAAA,EAAY;AAAA,EACd;AAAA,EAEA,UAAgB;AdzDX,QAAAtC,GAAAsC;Ac0DH,KAAAtC,IAAA,KAAK,UAAL,QAAAA,EAAY,oBAAoB,WAAW,KAAK,cAChDsC,IAAA,KAAK,UAAL,QAAAA,EAAY,oBAAoB,QAAQ,KAAK;AAAA,EAC/C;AACF;AAGO,MAAMqY,GAAmC;AAAA,EAQ9C,YAAYtN,GAAsD;AA0BlE,SAAQ,aAAa,CAACzN,MAA2B;AAC/C,MAAAA,EAAE,gBAAA,GACEA,EAAE,QAAQ,WAAWA,EAAE,QAAQ,SAASA,EAAE,eAAA,GAAkB,KAAK,QAAA,KAC5DA,EAAE,QAAQ,iBAAe,UAAA;AAAA,IACpC,GAEA,KAAQ,UAAU,MAAY;AAAE,WAAK,QAAA;AAAA,IAAW,GA/B9C,KAAK,MAAMyN,KAAA,gBAAAA,EAAM,KACjB,KAAK,MAAMA,KAAA,gBAAAA,EAAM,KACjB,KAAK,OAAOA,KAAA,gBAAAA,EAAM;AAAA,EACpB;AAAA,EAEA,MAAMxJ,GAAwBoF,GAAoBkR,GAA4BC,GAA4B;AACxG,SAAK,YAAYD,GACjB,KAAK,YAAYC,GAEjB,KAAK,QAAQ,SAAS,cAAc,OAAO,GAC3C,KAAK,MAAM,OAAO,UAClB,KAAK,MAAM,QAAQnR,EAAI,SAAS,OAAO,KAAK,OAAOA,EAAI,KAAK,GACxD,KAAK,OAAO,SAAM,KAAK,MAAM,MAAM,OAAO,KAAK,GAAG,IAClD,KAAK,OAAO,SAAM,KAAK,MAAM,MAAM,OAAO,KAAK,GAAG,IAClD,KAAK,QAAQ,SAAM,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,IACzD,KAAK,MAAM,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,OAK3B,KAAK,MAAM,iBAAiB,WAAW,KAAK,UAAU,GACtD,KAAK,MAAM,iBAAiB,QAAQ,KAAK,OAAO,GAChDpF,EAAU,YAAY,KAAK,KAAK;AAAA,EAClC;AAAA,EAUQ,UAAgB;AACtB,UAAMJ,IAAI,KAAK,MAAM,UAAU,KAAK,OAAO,OAAO,KAAK,MAAM,KAAK;AAClE,SAAK,UAAUA,CAAC;AAAA,EAClB;AAAA,EAEA,WAAgB;Ad/GX,QAAAzD,GAAAsC;Ac+Ga,aAAOtC,IAAA,KAAK,UAAL,gBAAAA,EAAY,WAAU,KAAK,OAAO,QAAOsC,IAAA,KAAK,UAAL,gBAAAA,EAAY,KAAK;AAAA,EAAG;AAAA,EACtF,QAAc;AdhHT,QAAAtC,GAAAsC;AcgHW,KAAAtC,IAAA,KAAK,UAAL,QAAAA,EAAY,UAASsC,IAAA,KAAK,UAAL,QAAAA,EAAY;AAAA,EAAU;AAAA,EAC3D,UAAgB;AdjHX,QAAAtC,GAAAsC;AckHH,KAAAtC,IAAA,KAAK,UAAL,QAAAA,EAAY,oBAAoB,WAAW,KAAK,cAChDsC,IAAA,KAAK,UAAL,QAAAA,EAAY,oBAAoB,QAAQ,KAAK;AAAA,EAC/C;AACF;AAIO,MAAMsY,GAAqC;AAAA,EAIhD,MAAM/W,GAAwBoF,GAAoBkR,GAA4BU,GAA6B;AACzG,SAAK,YAAYV,GACjBtW,EAAU,MAAM,WAAW,2DAE3B,KAAK,MAAM,SAAS,cAAc,OAAO,GACzC,KAAK,IAAI,OAAO,YAChB,KAAK,IAAI,UAAU,CAAC,CAACoF,EAAI,OACzB,KAAK,IAAI,MAAM,SAAS,WACxB,KAAK,IAAI,iBAAiB,UAAU,MAAMkR,EAAS,KAAK,IAAI,OAAO,CAAC,GACpEtW,EAAU,YAAY,KAAK,GAAG;AAAA,EAChC;AAAA,EAEA,WAAgB;AdzIX,QAAA7D;AcyIa,YAAOA,IAAA,KAAK,QAAL,gBAAAA,EAAU;AAAA,EAAS;AAAA,EAC5C,QAAc;Ad1IT,QAAAA;Ac0IW,KAAAA,IAAA,KAAK,QAAL,QAAAA,EAAU;AAAA,EAAS;AAAA,EACnC,UAAgB;AAAA,EAAC;AACnB;AAGO,SAAS8a,GAAa3V,GAA4B;AACvD,QAAM4V,IAAS5V,EAAI;AACnB,MAAI,CAAC4V;AACH,YAAQ5V,EAAI,MAAA;AAAA,MACV,KAAK;AAAW,eAAO,IAAIwV,GAAA;AAAA,MAC3B,KAAK;AAAW,eAAO,IAAIT,GAAAA;AAAAA,MAC3B,KAAK;AAAW,eAAO,IAAIU,GAAA;AAAA,MAC3B,KAAK;AAAW,eAAO,IAAIN,GAAanV,EAAI,WAAW,CAAA,GAAIA,EAAI,SAAgB;AAAA,MAC/E;AAAgB,eAAO,IAAIuV,GAAA;AAAA,IAAW;AAG1C,MAAI,OAAOK,KAAW;AACpB,YAAQA,GAAA;AAAA,MACN,KAAK;AAAY,eAAO,IAAIJ,GAAA;AAAA,MAC5B,KAAK;AAAY,eAAO,IAAIT,GAAAA;AAAAA,MAC5B,KAAK;AAAY,eAAO,IAAII,GAAanV,EAAI,WAAW,CAAA,GAAIA,EAAI,SAAgB;AAAA,MAChF,KAAK;AAAY,eAAO,IAAIyV,GAAA;AAAA,MAC5B;AAAiB,eAAO,IAAIF,GAAA;AAAA,IAAW;AAI3C,UAAQK,EAAO,MAAA;AAAA,IACb,KAAK,UAAU;AACb,YAAM1N,IAAsD,CAAA;AAC5D,aAAI0N,EAAO,OAAO,SAAM1N,EAAK,MAAM0N,EAAO,MACtCA,EAAO,OAAO,SAAM1N,EAAK,MAAM0N,EAAO,MACtCA,EAAO,QAAQ,SAAM1N,EAAK,OAAO0N,EAAO,OACrC,IAAIJ,GAAatN,CAAI;AAAA,IAC9B;AAAA,IACA,KAAK;AAAY,aAAO,IAAI6M,GAAAA;AAAAA,IAC5B,KAAK;AAAY,aAAO,IAAII,GAAaS,EAAO,WAAW,CAAA,GAAI5V,EAAI,SAAgB;AAAA,IACnF,KAAK;AAAY,aAAO,IAAIyV,GAAA;AAAA,IAC5B;AAAiB,aAAO,IAAIF,GAAA;AAAA,EAAW;AAE3C;ACtLO,SAASM,GAAe7V,GAA4B;AACzD,QAAM8V,IAAW,OAAO9V,EAAI,YAAa,WACrCA,EAAI,WACHA,EAAI,YAAY,OAAOA,EAAI,YAAa,WAAYA,EAAI,SAAiB,OAAO;AACrF,SAAOA,EAAI,SAAS,aAAcA,EAAI,SAAoB,cACrD8V,MAAa,cAAcA,MAAa;AAC/C;ACcO,MAAMC,GAAqD;AAAA,EAQhE,YAAYC,GAAuB;AAPnC,SAAQ,gBAAmC,MAC3C,KAAQ,YAA+C,MACvD,KAAQ,aAAgD,MACxD,KAAQ,cAA6B,MAKnC,KAAK,KAAKA;AAAA,EACZ;AAAA;AAAA,EAGA,IAAI,eAAkC;AAAE,WAAO,KAAK;AAAA,EAAe;AAAA,EACnE,IAAI,WAA8C;AAAE,WAAO,KAAK;AAAA,EAAW;AAAA,EAC3E,IAAI,YAA+C;AAAE,WAAO,KAAK;AAAA,EAAY;AAAA,EAC7E,IAAI,aAA4B;AAAE,WAAO,KAAK;AAAA,EAAa;AAAA,EAC3D,IAAI,WAAW1X,GAAkB;AAAE,SAAK,cAAcA;AAAA,EAAG;AAAA;AAAA,EAGzD,aAAaiQ,GAAYsC,GAAkB;AACzC,SAAK,aAAa,EAAE,IAAAtC,GAAI,IAAAsC,EAAA,GACxB,KAAK,GAAG,YAAYtC,CAAE,GACtB,KAAK,GAAG,SAAA;AACR,UAAMvO,IAAM,KAAK,GAAG,iBAAA,EAAmB6Q,CAAE,GACnC1V,IAAM,KAAK,GAAG,KAAK,cAAcoT,CAAE;AACzC,QAAIvO,KAAO7E,GAAK;AACd,YAAM8C,IAAO9C,EAAY6E,EAAI,KAAK;AAClC,WAAK,GAAG;AAAA,QACN,GAAGuO,IAAK,CAAC,KAAKsC,IAAK,CAAC,MAAM7Q,EAAI,MAAM,KAAK/B,KAAO,OAAO,QAAQ,OAAOA,CAAG,CAAC;AAAA,MAAA;AAAA,IAE9E;AAAA,EACF;AAAA,EAEA,iBAAuB;AAAE,SAAK,aAAa;AAAA,EAAM;AAAA;AAAA,EAGjD,eAAepC,GAAkB+D,GAAwB;AhBpDpD,QAAA/E,GAAAsC,GAAAyL;AgBqDH,UAAM5I,IAAM,KAAK,GAAG,iBAAA,EAAmBJ,CAAQ;AAC/C,QAAI,CAACI,EAAK;AAEV,QAAI6V,GAAY7V,CAAG,GAAG;AACpB,YAAMkI,IAAO,KAAK,GAAG,WAAA;AAErB,UADoBlI,EAAI,aAAa,OAAUA,EAAI,aAAa,UAAakI,EAAK,WACjE;AACf,cAAM/M,IAAM,KAAK,GAAG,KAAK,cAAcU,CAAQ;AAC/C,QAAIV,KAAK,KAAK,GAAG,UAAUU,GAAUmE,EAAI,OAA4B,CAAE7E,EAAY6E,EAAI,KAAK,CAAC;AAAA,MAC/F;AACA;AAAA,IACF;AAEA,UAAM7E,IAAM,KAAK,GAAG,KAAK,cAAcU,CAAQ;AAE/C,QADImE,EAAI,aAAa,MACjB,OAAOA,EAAI,YAAa,cAAc,CAACA,EAAI,SAAS7E,GAAUU,CAAQ,EAAG;AAE7E,SAAK,WAAA;AACL,UAAMqW,KAASrX,IAAA,KAAK,GAAG,kBAAR,gBAAAA,EAAuB,UAAUgB,GAAU+D;AAC1D,QAAI,CAACsS,EAAQ;AACb,IAAAA,EAAO,YAAY;AAEnB,UAAM0D,IAASD,GAAa3V,CAAG;AAC/B,SAAK,gBAAgB4V,GACrB,KAAK,YAAY,EAAE,IAAI/Z,GAAU,IAAI+D,EAAA;AAErC,UAAMqW,IAAyB;AAAA,MAC7B,MAAM;AAAA,MAAa,UAAApa;AAAA,MAAU,aAAa+D;AAAA,MAC1C,OAAOI,EAAI;AAAA,MAAO,UAAU7E,KAAA,gBAAAA,EAAM6E,EAAI;AAAA,MAAQ,UAAU7E,KAAA,gBAAAA,EAAM6E,EAAI;AAAA,MAClE,KAAA7E;AAAA,MAAe,QAAQ6E;AAAA,IAAA;AAEzB,SAAK,GAAG,KAAK,aAAaiW,CAAQ,IAClCrN,KAAAzL,IAAA,KAAK,GAAG,cAAa,gBAArB,QAAAyL,EAAA,KAAAzL,GAAmC8Y,IAEnC/D,EAAO,UAAU,IAAI,YAAY;AACjC,UAAMpO,IAAM;AAAA,MACV,OAAO3I,KAAA,gBAAAA,EAAM6E,EAAI;AAAA,MAAQ,KAAA7E;AAAA,MAAiB,UAAAU;AAAA,MAC1C,QAAQmE;AAAA,MAAY,UAAAJ;AAAA,MAAU,YAAY;AAAA,MAAM,UAAU;AAAA,IAAA;AAE5D,IAAAgW,EAAO;AAAA,MAAM1D;AAAA,MAAQpO;AAAA,MACnB,CAACzH,MAAU,KAAK,oBAAoBR,GAAU+D,GAAUvD,CAAK;AAAA,MAC7D,MAAM,KAAK,WAAA;AAAA,IAAW,GAExB,sBAAsB,MAAMuZ,EAAO,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,UAAU/Z,GAAkB+D,GAAkB+J,GAAsB;AhBpG/D,QAAA9O,GAAAsC;AgBqGH,UAAM+K,IAAO,KAAK,GAAG,WAAA;AACrB,QAAI,CAACA,EAAK,SAAU;AACpB,UAAMlI,IAAM,KAAK,GAAG,iBAAA,EAAmBJ,CAAQ;AAG/C,QAFI,CAACI,KAED6V,GAAY7V,CAAG,EAAG;AAEtB,UAAM7E,IAAM,KAAK,GAAG,KAAK,cAAcU,CAAQ;AAG/C,QAFImE,EAAI,aAAa,MACjB,OAAOA,EAAI,YAAa,cAAc,CAACA,EAAI,SAAS7E,GAAUU,CAAQ,KACtE,CAACmE,EAAI,YAAY,CAACkI,EAAK,SAAU;AAErC,SAAK,WAAA;AAEL,UAAMgK,KAASrX,IAAA,KAAK,GAAG,kBAAR,gBAAAA,EAAuB,UAAUgB,GAAU+D;AAC1D,QAAI,CAACsS,EAAQ;AACb,IAAAA,EAAO,YAAY;AAEnB,UAAM0D,IAASD,GAAa3V,CAAG;AAC/B,SAAK,gBAAgB4V,GACrB,KAAK,YAAY,EAAE,IAAI/Z,GAAU,IAAI+D,EAAA;AAErC,UAAMqW,IAAyB;AAAA,MAC7B,MAAM;AAAA,MAAa,UAAApa;AAAA,MAAU,aAAa+D;AAAA,MAC1C,OAAOI,EAAI;AAAA,MAAO,UAAU7E,KAAA,gBAAAA,EAAM6E,EAAI;AAAA,MAAQ,UAAU7E,KAAA,gBAAAA,EAAM6E,EAAI;AAAA,MAClE,KAAA7E;AAAA,MAAe,QAAQ6E;AAAA,IAAA;AAEzB,SAAK,GAAG,KAAK,aAAaiW,CAAQ,IAClC9Y,IAAA+K,EAAK,gBAAL,QAAA/K,EAAA,KAAA+K,GAAmB+N,IAEnB/D,EAAO,UAAU,IAAI,YAAY;AACjC,UAAMpO,IAAM;AAAA,MACV,OAAO3I,KAAA,gBAAAA,EAAM6E,EAAI;AAAA,MAAQ,KAAA7E;AAAA,MAAiB,UAAAU;AAAA,MAC1C,QAAQmE;AAAA,MAAY,UAAAJ;AAAA,MAAU,YAAY;AAAA,MAAM,UAAU;AAAA,IAAA;AAE5D,IAAAgW,EAAO;AAAA,MAAM1D;AAAA,MAAQpO;AAAA,MACnB,CAACzH,MAAU,KAAK,oBAAoBR,GAAU+D,GAAUvD,CAAK;AAAA,MAC7D,MAAM,KAAK,WAAA;AAAA,IAAW,GAExB,sBAAsB,MAAMuZ,EAAO,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,aAAmB;AACjB,QAAI,CAAC,KAAK,iBAAiB,CAAC,KAAK,UAAW;AAC5C,UAAM3X,IAAM,KAAK,cAAc,SAAA,GACzB,EAAE,IAAAsQ,GAAI,IAAAsC,EAAA,IAAO,KAAK;AACxB,SAAK,YAAYtC,GAAIsC,GAAI5S,GAAK,EAAK;AAAA,EACrC;AAAA,EAEA,oBAAoBsQ,GAAYsC,GAAYxU,GAAkB;AAC5D,SAAK,YAAYkS,GAAIsC,GAAIxU,GAAO,EAAK;AAAA,EACvC;AAAA,EAEA,aAAmB;AACjB,QAAI,CAAC,KAAK,UAAW;AACrB,UAAM,EAAE,IAAAkS,GAAI,IAAAsC,EAAA,IAAO,KAAK;AACxB,SAAK,YAAYtC,GAAIsC,GAAI,QAAW,EAAI;AAAA,EAC1C;AAAA,EAEQ,YAAYtC,GAAYsC,GAAYxU,GAAY6Z,GAAuB;AhBjK1E,QAAArb,GAAAsC,GAAAyL;AgBkKH,QAAI,CAAC,KAAK,cAAe;AACzB,UAAM5I,IAAM,KAAK,GAAG,iBAAA,EAAmB6Q,CAAE,GACnCqB,KAASrX,IAAA,KAAK,GAAG,kBAAR,gBAAAA,EAAuB,UAAU0T,GAAIsC;AAQpD,QAPIqB,MACF,KAAK,cAAc,QAAA,GACnBA,EAAO,UAAU,OAAO,YAAY,IAEtC,KAAK,gBAAgB,MACrB,KAAK,YAAY,MAEb,CAACgE,KAAUlW,GAAK;AAClB,YAAMmW,IAAM,KAAK,GAAG,KAAK,aAAa5H,GAAIvO,EAAI,KAAK;AACnD,UAAI3D,MAAU8Z,GAAK;AACjB,aAAK,GAAG,KAAK,WAAW5H,GAAIvO,EAAI,OAAO3D,CAAK;AAC5C,cAAMlB,IAAM,KAAK,GAAG,KAAK,cAAcoT,CAAE,GACnCrG,IAAO,KAAK,GAAG,WAAA,GACfkO,IAAoB;AAAA,UACxB,MAAM;AAAA,UAAW,UAAU7H;AAAA,UAAI,aAAasC;AAAA,UAC5C,OAAO7Q,EAAI;AAAA,UAAO,UAAUmW;AAAA,UAAK,UAAU9Z;AAAA,UAC3C,KAAAlB;AAAA,UAAe,QAAQ6E;AAAA,QAAA;AAEzB,aAAK,GAAG,KAAK,WAAWoW,CAAG,IAC3BjZ,IAAA+K,EAAK,cAAL,QAAA/K,EAAA,KAAA+K,GAAiBkO,IACjB,KAAK,GAAG,KAAK,cAAc,KAAK,GAAG,KAAK,SAAS,IACjDxN,IAAAV,EAAK,iBAAL,QAAAU,EAAA,KAAAV,GAAoB,KAAK,GAAG,KAAK;MACnC;AAAA,IACF;AACA,SAAK,GAAG,SAAA,GACR,sBAAsB,MAAM,KAAK,GAAG,aAAA,EAAe,MAAM,EAAE,eAAe,GAAA,CAAM,CAAC;AAAA,EACnF;AACF;ACrHO,MAAMmO,GAAkB;AAAA,EAS7B,YACE3X,GACA4X,GACAC,GACAC,GACAC,GACA;AAbF,SAAQ,+BAAiB,IAAA,GAEzB,KAAQ,YAAoC,CAAA,GAY1C,KAAK,UAAYH,GACjB,KAAK,YAAYC,GACjB,KAAK,WAAYC,GAGjB,KAAK,MAAM,SAAS,cAAc,UAAU,GAC5C,KAAK,IAAI,YAAY;AAErB,UAAME,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,EAAO,YAAc,2BACrBA,EAAO,cAAcJ,EAAO,UAAU,MACtC,KAAK,IAAI,YAAYI,CAAM;AAE3B,UAAMvb,IAAM,SAAS,cAAc,KAAK;AACxC,IAAAA,EAAI,YAAY;AAEhB,eAAW6E,KAAOsW,EAAO,SAAS;AAChC,YAAMK,IAAM,WAAW3W,EAAI,KAAK,IAE1BwH,IAAO,SAAS,cAAc,KAAK;AACzC,MAAAA,EAAK,YAAY;AAEjB,YAAMsB,IAAQ,SAAS,cAAc,OAAO;AAC5C,MAAAA,EAAM,UAAc6N,GACpB7N,EAAM,cAAc9I,EAAI,OACxB8I,EAAM,YAAc;AAEpB,YAAM8N,IAAS,SAAS,cAAc,QAAQ;AAC9C,MAAAA,EAAO,KAAYD,GACnBC,EAAO,YAAY,wBACnBA,EAAO,aAAa,cAAc5W,EAAI,KAAK,GACvCyW,KAAQG,EAAO,aAAa,iBAAiBH,CAAM,GAElDzW,EAAI,YAKP,KAAK,MAAM4W,GAAQ,CAAA,GAAI,EAAK,IAH5B,KAAK,MAAMA,GAAQ,KAAK,SAAS5W,GAAK,EAAE,GAAG,EAAI,GAMjD4W,EAAO,iBAAiB,UAAU,MAAM,KAAK,UAAU5W,EAAI,OAAO4W,EAAO,KAAK,CAAC,GAE/EpP,EAAK,YAAYsB,CAAK,GACtBtB,EAAK,YAAYoP,CAAM,GACvBzb,EAAI,YAAYqM,CAAI,GACpB,KAAK,SAAS,IAAIxH,EAAI,OAAO4W,CAAM;AAAA,IACrC;AAGA,UAAM/N,IAAM,SAAS,cAAc,QAAQ;AAC3C,IAAAA,EAAI,OAAc,UAClBA,EAAI,cAAc,OAClBA,EAAI,YAAc,0BAClBA,EAAI,aAAa,cAAc,QAAQ,GACvCA,EAAI,iBAAiB,SAAS,MAAM,KAAK,QAAQ,GAEjD,KAAK,IAAI,YAAY1N,CAAG,GACxB,KAAK,IAAI,YAAY0N,CAAG,GAGxBnK,EAAU,aAAa,KAAK,KAAKA,EAAU,UAAU;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,SAASsB,GAAyB6W,GAA2C;AAEnF,QAAI7W,EAAI,QAAS,QAAOA,EAAI;AAG5B,QAAIK,IAAOL,EAAI,QAAQ,CAAA;AAGvB,IAAIA,EAAI,aAAaA,EAAI,gBAAgB6W,MACvCxW,IAAOA,EAAK;AAAA,MACV,OAAQ,OAAOhF,EAAK2E,EAAI,YAAa,KAAK,EAAE,MAAM6W;AAAA,IAAA;AAItD,UAAMC,IAAK9W,EAAI,YAAY,SACrB+W,IAAK/W,EAAI,WAAY8W;AAE3B,WAAOzW,EAAK,IAAI,CAAAhF,OAAS;AAAA,MACvB,OAAO,OAAOA,EAAKyb,CAAE,KAAK,EAAE;AAAA,MAC5B,MAAO,OAAOzb,EAAK0b,CAAE,KAAK1b,EAAKyb,CAAE,KAAK,EAAE;AAAA,IAAA,EACxC;AAAA,EACJ;AAAA;AAAA,EAGQ,MACNF,GACA1O,GACA8O,GACM;AACN,IAAAJ,EAAO,YAAY;AACnB,UAAMK,IAAM,SAAS,cAAc,QAAQ;AAC3C,IAAAA,EAAI,QAAQ,IAAIA,EAAI,cAAc,MAClCL,EAAO,YAAYK,CAAG;AACtB,eAAWlU,KAAKmF,GAAM;AACpB,YAAM6D,IAAK,SAAS,cAAc,QAAQ;AAC1C,MAAAA,EAAG,QAAQhJ,EAAE,OAAOgJ,EAAG,cAAchJ,EAAE,MACvC6T,EAAO,YAAY7K,CAAE;AAAA,IACvB;AACA,IAAA6K,EAAO,WAAW,CAACI;AAAA,EACrB;AAAA;AAAA,EAGQ,UAAU5a,GAAeC,GAAqB;AACpD,UAAM2D,IAAM,KAAK,QAAQ,QAAQ,KAAK,CAAAC,MAAKA,EAAE,UAAU7D,CAAK,GACtD8a,IAAMlX,EAAI,aAAaA,EAAI;AAEjC,IAAI3D,KACF,KAAK,UAAUD,CAAK,IAAIC,GACxB,KAAK,UAAU6a,GAAI,CAAC,EAAE,UAAU,KAAK,OAAA7a,EAAA,CAAO,CAAC,MAE7C,OAAO,KAAK,UAAUD,CAAK,GAC3B,KAAK,SAAS8a,CAAE,IAElB,KAAK,SAAS9a,CAAK;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS+a,GAA2B;AAC1C,UAAMN,IAAc,KAAK,UAAUM,CAAW,KAAK;AAEnD,eAAWnX,KAAO,KAAK,QAAQ,SAAS;AACtC,UAAIA,EAAI,cAAcmX,EAAa;AACnC,YAAMC,IAAM,KAAK,SAAS,IAAIpX,EAAI,KAAK;AACvC,UAAI,CAACoX,EAAK;AACV,YAAMF,IAAKlX,EAAI,aAAaA,EAAI;AAEhC,MAAK6W,KAQH,KAAK,MAAMO,GAAK,KAAK,SAASpX,GAAK6W,CAAW,GAAG,EAAI,GACrDO,EAAI,QAAQ,IACZ,OAAO,KAAK,UAAUpX,EAAI,KAAK,GAC/B,KAAK,SAASkX,CAAE,MAThB,KAAK,MAAME,GAAK,CAAA,GAAI,EAAK,GACzB,OAAO,KAAK,UAAUpX,EAAI,KAAK,GAC/B,KAAK,SAASkX,CAAE,GAChB,KAAK,SAASlX,EAAI,KAAK;AAAA,IAQ3B;AAAA,EACF;AAAA;AAAA,EAGQ,SAAe;AACrB,SAAK,YAAY,CAAA;AACjB,eAAWA,KAAO,KAAK,QAAQ,SAAS;AACtC,YAAMoX,IAAM,KAAK,SAAS,IAAIpX,EAAI,KAAK,GACjCkX,IAAMlX,EAAI,aAAaA,EAAI;AACjC,MAAKoX,MACApX,EAAI,YAGP,KAAK,MAAMoX,GAAK,CAAA,GAAI,EAAK,KAFzBA,EAAI,QAAQ,IAAIA,EAAI,WAAW,KAIjC,KAAK,SAASF,CAAE;AAAA,IAClB;AAAA,EACF;AAAA;AAAA,EAGA,QAAgB;AAAE,SAAK,OAAA;AAAA,EAAU;AAAA,EACjC,UAAgB;AAAE,SAAK,IAAI,OAAA;AAAA,EAAU;AACvC;ACnQO,MAAMG,GAAW;AAAA,EAOtB,YAAY3Y,GAAwB4Y,GAAkBjD,GAAwB;AAL9E,SAAQ,QAAQ,GAEhB,KAAQ,aAAa,GAInB,KAAK,YAAYiD,GACjB,KAAK,YAAYjD,GAEjB,KAAK,MAAM,SAAS,cAAc,KAAK,GACvC,KAAK,IAAI,YAAY,iBACrB,KAAK,IAAI,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,OAMzB3V,EAAU,YAAY,KAAK,GAAG,GAC9B,KAAK,QAAA;AAAA,EACP;AAAA,EAEA,IAAI,OAAO;AAAE,WAAO,KAAK;AAAA,EAAO;AAAA,EAChC,IAAI,WAAW;AAAE,WAAO,KAAK;AAAA,EAAW;AAAA,EACxC,IAAI,aAAa;AAAE,WAAO,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,aAAa,KAAK,SAAS,CAAC;AAAA,EAAG;AAAA;AAAA,EAGpF,aAAaoM,GAAiB;AAC5B,SAAK,aAAaA,GACd,KAAK,QAAQ,KAAK,eAAY,KAAK,QAAQ,KAAK,aACpD,KAAK,QAAA;AAAA,EACP;AAAA,EAEA,YAAYyM,GAAoB;AAC9B,SAAK,YAAYA,GACjB,KAAK,QAAQ,GACb,KAAK,QAAA,GACL,KAAK,MAAA;AAAA,EACP;AAAA,EAEA,KAAKC,GAAoB;AACvB,UAAMtM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAIsM,GAAM,KAAK,UAAU,CAAC;AACrD,IAAItM,MAAM,KAAK,UACf,KAAK,QAAQA,GACb,KAAK,QAAA,GACL,KAAK,MAAA;AAAA,EACP;AAAA;AAAA,EAGA,WAA2C;AACzC,UAAM3G,KAAS,KAAK,QAAQ,KAAK,KAAK,WAChCkT,IAAQ,KAAK,IAAIlT,IAAQ,KAAK,YAAY,GAAG,KAAK,aAAa,CAAC;AACtE,WAAO,EAAE,OAAAA,GAAO,KAAAkT,EAAA;AAAA,EAClB;AAAA,EAEQ,QAAc;AACpB,SAAK,UAAU;AAAA,MACb,MAAM,KAAK;AAAA,MAAO,UAAU,KAAK;AAAA,MACjC,WAAW,KAAK;AAAA,MAAY,YAAY,KAAK;AAAA,IAAA,CAC9C;AAAA,EACH;AAAA,EAEQ,UAAgB;AACtB,SAAK,IAAI,YAAY;AACrB,UAAMC,IAAQ,KAAK,YAGbC,IAAW,SAAS,cAAc,MAAM;AAC9C,IAAAA,EAAS,MAAM,UAAU;AACzB,UAAMC,IAAY,SAAS,cAAc,MAAM;AAC/C,IAAAA,EAAU,cAAc,UACxBA,EAAU,MAAM,QAAQ;AACxB,UAAMC,IAAU,SAAS,cAAc,QAAQ;AAC/C,IAAAA,EAAQ,MAAM,UAAU;AACxB,eAAWxa,KAAK,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,GAAG;AACtC,YAAMmE,IAAM,SAAS,cAAc,QAAQ;AAC3C,MAAAA,EAAI,QAAQ,OAAOnE,CAAC,GACpBmE,EAAI,cAAc,OAAOnE,CAAC,GACtBA,MAAM,KAAK,cAAWmE,EAAI,WAAW,KACzCqW,EAAQ,YAAYrW,CAAG;AAAA,IACzB;AACA,IAAAqW,EAAQ,iBAAiB,UAAU,MAAM,KAAK,YAAY,OAAOA,EAAQ,KAAK,CAAC,CAAC,GAChFF,EAAS,YAAYC,CAAS,GAC9BD,EAAS,YAAYE,CAAO,GAC5B,KAAK,IAAI,YAAYF,CAAQ;AAG7B,UAAMG,IAAO,SAAS,cAAc,MAAM,GACpC,EAAE,OAAAvT,GAAO,KAAAkT,MAAQ,KAAK,SAAA;AAC5B,IAAAK,EAAK,cAAc,KAAK,aAAa,IACjC,GAAGvT,IAAQ,CAAC,IAAIkT,IAAM,CAAC,MAAM,KAAK,UAAU,MAC5C,MACJK,EAAK,MAAM,UAAU,gCACrB,KAAK,IAAI,YAAYA,CAAI;AAGzB,UAAMC,IAAQ,CAACjP,GAAe0O,GAAcQ,MAAsB;AAChE,YAAMnP,IAAM,SAAS,cAAc,QAAQ;AAC3C,aAAAA,EAAI,cAAcC,GAClBD,EAAI,WAAWmP,GACfnP,EAAI,MAAM,UAAU;AAAA;AAAA;AAAA,qBAGLmP,IAAW,YAAY,MAAM;AAAA,gBAClCA,IAAW,SAAS,2BAA2B;AAAA,iBAC9CA,IAAW,YAAY,SAAS;AAAA,SAEtCA,KAAUnP,EAAI,iBAAiB,SAAS,MAAM,KAAK,KAAK2O,CAAI,CAAC,GAC3D3O;AAAA,IACT;AAEA,SAAK,IAAI,YAAYkP,EAAM,KAAK,GAAG,KAAK,UAAU,CAAC,CAAC,GACpD,KAAK,IAAI,YAAYA,EAAM,KAAK,KAAK,QAAQ,GAAG,KAAK,UAAU,CAAC,CAAC;AAGjE,UAAMnZ,IAAQqZ,GAAW,KAAK,OAAOP,CAAK;AAC1C,eAAWxM,KAAKtM;AACd,UAAIsM,MAAM,IAAI;AACZ,cAAMzI,IAAM,SAAS,cAAc,MAAM;AACzC,QAAAA,EAAI,cAAc,KAClBA,EAAI,MAAM,UAAU,SACpB,KAAK,IAAI,YAAYA,CAAG;AAAA,MAC1B,OAAO;AACL,cAAMoG,IAAMkP,EAAM,OAAO7M,CAAC,GAAGA,GAAGA,MAAM,KAAK,KAAK;AAChD,QAAIA,MAAM,KAAK,UACbrC,EAAI,MAAM,aAAa,6BACvBA,EAAI,MAAM,QAAQ,QAClBA,EAAI,MAAM,cAAc,8BAE1B,KAAK,IAAI,YAAYA,CAAG;AAAA,MAC1B;AAGF,SAAK,IAAI,YAAYkP,EAAM,KAAK,KAAK,QAAQ,GAAG,KAAK,UAAUL,CAAK,CAAC,GACrE,KAAK,IAAI,YAAYK,EAAM,KAAKL,GAAO,KAAK,UAAUA,CAAK,CAAC;AAAA,EAC9D;AAAA,EAEA,UAAgB;AACd,SAAK,IAAI,OAAA;AAAA,EACX;AACF;AAGA,SAASO,GAAWC,GAAiBR,GAAyB;AAC5D,MAAIA,KAAS,EAAG,QAAO,MAAM,KAAK,EAAE,QAAQA,EAAA,GAAS,CAACnc,GAAG,MAAM,IAAI,CAAC;AACpE,QAAM4c,IAAkB,CAAC,CAAC;AAC1B,EAAID,IAAU,KAAGC,EAAM,KAAK,EAAE;AAC9B,WAASjN,IAAI,KAAK,IAAI,GAAGgN,IAAU,CAAC,GAAGhN,KAAK,KAAK,IAAIwM,IAAQ,GAAGQ,IAAU,CAAC,GAAGhN;AAC5E,IAAAiN,EAAM,KAAKjN,CAAC;AAEd,SAAIgN,IAAUR,IAAQ,KAAGS,EAAM,KAAK,EAAE,GACtCA,EAAM,KAAKT,CAAK,GACTS;AACT;ACtJO,MAAMC,GAAY;AAAA,EAMvB,YAAYC,GAAqBC,GAAmBC,GAAyB;AAL7E,SAAQ,QAA0B,MAMhC,KAAK,UAAUF,GACf,KAAK,aAAaC,GAClB,KAAK,UAAUC,GAEf,KAAK,eAAe,KAAK,aAAa,KAAK,IAAI,GAC/C,KAAK,aAAe,KAAK,WAAW,KAAK,IAAI;AAAA,EAC/C;AAAA;AAAA,EAGA,aAAahI,GAAoB1U,GAAkBgZ,GAAgC;AACjF,UAAMlD,IAAS,SAAS,cAAc,KAAK;AAC3C,WAAAA,EAAO,YAAY,kBACnBA,EAAO,YAAY,KACnBA,EAAO,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,OAMvBA,EAAO,iBAAiB,aAAa,CAAClX,MAAM;AAC1C,MAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA,GACF,KAAK,WAAWA,GAAG8V,GAAO1U,GAAUgZ,CAAS;AAAA,IAC/C,CAAC,GACMlD;AAAA,EACT;AAAA,EAEQ,WAAW,GAAepB,GAAoBiI,GAAmB3D,GAAyB;AAEhG,UAAMhT,IAAO0O,EAAM,sBAAA,GACbkI,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAM,MAAM,UAAU;AAAA,4BACE5W,EAAK,IAAI,UAAUA,EAAK,GAAG;AAAA,cACzCA,EAAK,KAAK,aAAaA,EAAK,MAAM;AAAA;AAAA;AAAA;AAAA,OAK5C,SAAS,KAAK,YAAY4W,CAAK;AAG/B,UAAMC,IAAY,SAAS,cAAc,KAAK;AAC9C,IAAAA,EAAU,MAAM,UAAU;AAAA;AAAA;AAAA,OAI1B,KAAK,QAAQ,YAAYA,CAAS,GAElC,KAAK,QAAQ;AAAA,MACX,WAAAF;AAAA,MAAW,QAAQ,EAAE;AAAA,MACrB,SAASC;AAAA,MAAO,WAAAC;AAAA,MAChB,WAAW,KAAK;AAAA,MAChB,WAAA7D;AAAA,MAAW,QAAQ,KAAK;AAAA,MACxB,eAAe2D;AAAA,IAAA,GAGjB,SAAS,iBAAiB,aAAa,KAAK,YAAY,GACxD,SAAS,iBAAiB,WAAW,KAAK,UAAU;AAAA,EACtD;AAAA,EAEQ,aAAa,GAAqB;AACxC,QAAI,CAAC,KAAK,MAAO;AACjB,UAAMzb,IAAI,KAAK,OAGT4b,IAAK,EAAE,UAAU5b,EAAE,QACnB6b,IAAY7b,EAAE,QAAQ,sBAAA;AAC5B,IAAAA,EAAE,QAAQ,MAAM,MAAM,GAAG6b,EAAU,MAAMD,CAAE,MAC3C5b,EAAE,SAAS,EAAE;AAGb,UAAM8b,IAAW9b,EAAE,OAAO,sBAAA,GACpB+b,IAAO,EAAE,UAAUD,EAAS,MAAM9b,EAAE,OAAO,WAC3Cgc,IAAY,KAAK,IAAI,GAAG,KAAK,IAAIhc,EAAE,YAAY,GAAG,KAAK,MAAM+b,IAAO/b,EAAE,SAAS,CAAC,CAAC;AAEvF,IAAAA,EAAE,gBAAgBgc;AAGlB,UAAMC,IAAaD,IAAYhc,EAAE;AACjC,IAAAA,EAAE,UAAU,MAAM,UAAU,SAC5BA,EAAE,UAAU,MAAM,MAAM,GAAGic,CAAU;AAAA,EACvC;AAAA,EAEQ,WAAWrP,GAAsB;AAIvC,QAHA,SAAS,oBAAoB,aAAa,KAAK,YAAY,GAC3D,SAAS,oBAAoB,WAAW,KAAK,UAAU,GAEnD,CAAC,KAAK,MAAO;AACjB,UAAM,EAAE,WAAA6O,GAAW,eAAAS,GAAe,SAAAC,GAAS,WAAAR,EAAA,IAAc,KAAK;AAC9D,SAAK,QAAQ,MAEbQ,EAAQ,OAAA,GACRR,EAAU,OAAA,GAENF,MAAcS,KAChB,KAAK,QAAQT,GAAWS,CAAa;AAAA,EAEzC;AAAA,EAEA,UAAgB;AnBpHX,QAAApe,GAAAsC;AmBqHH,aAAS,oBAAoB,aAAa,KAAK,YAAY,GAC3D,SAAS,oBAAoB,WAAW,KAAK,UAAU,IACvDtC,IAAA,KAAK,UAAL,QAAAA,EAAY,QAAQ,WACpBsC,IAAA,KAAK,UAAL,QAAAA,EAAY,UAAU,UACtB,KAAK,QAAQ;AAAA,EACf;AACF;AC7GO,MAAMgc,EAAY;AAAA,EAAlB,cAAA;AAEL,SAAQ,2BAAmC,IAAA;AAAA,EAAI;AAAA,EAE/C,OAAe,KAAKhe,GAAa6E,GAAqB;AACpD,WAAO,GAAG7E,CAAG,IAAI6E,CAAG;AAAA,EACtB;AAAA;AAAA,EAGA,gBAAgBoZ,GAA0B;AACxC,SAAK,KAAK,MAAA;AACV,eAAWC,KAAMD,GAAO;AACtB,YAAMjH,IAAK,KAAK,IAAI,GAAGkH,EAAG,WAAW,CAAC,GAChCjH,IAAK,KAAK,IAAI,GAAGiH,EAAG,WAAW,CAAC;AAEtC,WAAK,KAAK,IAAIF,EAAY,KAAKE,EAAG,KAAKA,EAAG,GAAG,GAAG;AAAA,QAC9C,SAASlH;AAAA,QAAI,SAASC;AAAA,QAAI,QAAQ;AAAA,MAAA,CACnC;AAED,eAAS9W,IAAI,GAAGA,IAAI6W,GAAI7W;AACtB,iBAAS2E,IAAI,GAAGA,IAAImS,GAAInS;AACtB,UAAI3E,MAAM,KAAK2E,MAAM,KACrB,KAAK,KAAK,IAAIkZ,EAAY,KAAKE,EAAG,MAAM/d,GAAG+d,EAAG,MAAMpZ,CAAC,GAAG;AAAA,YACtD,SAAS;AAAA,YAAG,SAAS;AAAA,YAAG,QAAQ;AAAA,UAAA,CACjC;AAAA,IAGP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eACE/E,GACAoe,GACAtb,GACM;ApBrDH,QAAAnD,GAAAsC;AoBsDH,SAAK,KAAK,MAAA;AACV,aAAS0T,IAAK,GAAGA,IAAKyI,EAAW,QAAQzI,KAAM;AAC7C,YAAM7Q,IAAMsZ,EAAWzI,CAAE,GACnBzU,IAAQ4B,EAAO6S,CAAE;AACvB,UAAI0I,IAAY;AAEhB,eAAShL,IAAK,GAAGA,KAAMrT,EAAK,QAAQqT,KAAM;AACxC,cAAMiL,KAAU3e,IAAAK,EAAKqT,IAAK,CAAC,MAAX,gBAAA1T,EAAeuB,IACzBqd,IAAUlL,IAAKrT,EAAK,UAASiC,IAAAjC,EAAKqT,CAAE,MAAP,gBAAApR,EAAWf,KAAS;AAEvD,YAAImS,MAAOrT,EAAK,UAAUue,MAAWD,GAAS;AAC5C,gBAAMlZ,IAAOiO,IAAKgL;AAClB,cAAIjZ,IAAO,GAAG;AACZ,iBAAK,KAAK,IAAI6Y,EAAY,KAAKI,GAAWvZ,CAAG,GAAG;AAAA,cAC9C,SAASM;AAAA,cAAM,SAAS;AAAA,cAAG,QAAQ;AAAA,YAAA,CACpC;AACD,qBAAShF,IAAIie,IAAY,GAAGje,IAAIiT,GAAIjT;AAClC,mBAAK,KAAK,IAAI6d,EAAY,KAAK7d,GAAG0E,CAAG,GAAG;AAAA,gBACtC,SAAS;AAAA,gBAAG,SAAS;AAAA,gBAAG,QAAQ;AAAA,cAAA,CACjC;AAAA,UAEL;AACA,UAAAuZ,IAAYhL;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,QAAQpT,GAAa6E,GAA+B;AAClD,WAAO,KAAK,KAAK,IAAImZ,EAAY,KAAKhe,GAAK6E,CAAG,CAAC,KAAK;AAAA,EACtD;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,KAAK,MAAA;AAAA,EACZ;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK,KAAK,SAAS;AAAA,EAC5B;AACF;ACjFO,MAAM0Z,KAA2C;AAAA,EACtD,EAAE,IAAI,YAAa,OAAO,WAAW,MAAM,KAAK,QAAQ,UAAA;AAAA,EACxD,EAAE,IAAI,aAAa,OAAO,WAAW,MAAM,KAAK,QAAQ,WAAA;AAAA,EACxD,EAAE,MAAM,UAAA;AAAA,EACR,EAAE,IAAI,QAAS,OAAO,MAAc,MAAM,MAAM,QAAQ,OAAA;AAAA,EACxD,EAAE,MAAM,UAAA;AAAA,EACR,EAAE,IAAI,SAAS,OAAO,aAAa,MAAM,MAAM,QAAQ,QAAA;AAAA,EACvD,EAAE,IAAI,OAAS,OAAO,WAAa,MAAM,MAAM,QAAQ,MAAA;AAAA,EACvD,EAAE,IAAI,SAAS,OAAO,MAAc,MAAM,MAAM,QAAQ,QAAA;AAC1D;AAEO,MAAMC,GAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,EAY9B,YACmBC,GACAC,GACjB;AAFiB,SAAA,UAAAD,GACA,KAAA,WAAAC,GAbnB,KAAQ,MAA0B,MAClC,KAAQ,YAAqD,MAC7D,KAAQ,UAAqD,MAC7D,KAAQ,aAAqD,MAC7D,KAAQ,gBAAqD,MAC7D,KAAQ,YAAY;AAAA,EASjB;AAAA,EAEH,KAAK,GAAeC,GAAuC;AACzD,SAAK,MAAA;AAEL,UAAMC,IAAQD,KAAeJ,IACvBM,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAK,YAAa,mBAClBA,EAAK,aAAa,QAAQ,MAAM;AAEhC,eAAW3e,KAAQ0e,GAAO;AACxB,UAAI1e,EAAK,SAAS,WAAW;AAC3B,cAAM4e,IAAK,SAAS,cAAc,KAAK;AACvC,QAAAA,EAAG,YAAY,iBACfA,EAAG,aAAa,QAAQ,WAAW,GACnCD,EAAK,YAAYC,CAAE;AACnB;AAAA,MACF;AAEA,YAAMpR,IAAM,SAAS,cAAc,QAAQ;AAS3C,UARAA,EAAI,YAAa,cACjBA,EAAI,aAAa,QAAQ,UAAU,GACnCA,EAAI,aAAa,YAAY,IAAI,GAC7BxN,EAAK,aACPwN,EAAI,UAAU,IAAI,gBAAgB,GAClCA,EAAI,aAAa,iBAAiB,MAAM,IAGtCxN,EAAK,MAAM;AACb,cAAM6e,IAAK,SAAS,cAAc,MAAM;AAIxC,YAHAA,EAAG,YAAY,cAGX,+BAA+B,KAAK7e,EAAK,KAAK,KAAA,CAAM,GAAG;AACzD,gBAAMG,IAAI,SAAS,cAAc,GAAG;AACpC,UAAAA,EAAE,YAAYH,EAAK,MACnB6e,EAAG,YAAY1e,CAAC;AAAA,QAClB;AACE,UAAA0e,EAAG,cAAc7e,EAAK;AAExB,QAAA6e,EAAG,aAAa,eAAe,MAAM,GACrCrR,EAAI,YAAYqR,CAAE;AAAA,MACpB;AAEA,YAAM5P,IAAM,SAAS,cAAc,MAAM;AACzC,MAAAA,EAAI,YAAc,eAClBA,EAAI,cAAcjP,EAAK,SAAS,IAChCwN,EAAI,YAAYyB,CAAG,GAEnBzB,EAAI,iBAAiB,SAAS,CAAC4L,MAAO;AACpC,QAAAA,EAAG,gBAAA,GACEpZ,EAAK,YAAU,KAAK,WAAWA,CAAI,GACxC,KAAK,MAAA;AAAA,MACP,CAAC,GACD2e,EAAK,YAAYnR,CAAG;AAAA,IACtB;AAOA,UAAMsR,IAAU,KAAK,QAAQ,QAAQ,iBAAiB,GAChDC,IAAQD,KAAA,gBAAAA,EAAS,aAAa;AACpC,IAAIC,KAAOJ,EAAK,aAAa,iBAAiBI,CAAK,GACnD,SAAS,KAAK,YAAYJ,CAAI,GAC9B,KAAK,MAAMA,GAIX,KAAK,gBAAgB,CAACvF,MAAO;AAC3B,UAAI,CAAC,KAAK,IAAK;AACf,YAAM,IAAI,KAAK,IAAI,sBAAA;AACnB,OAAIA,EAAG,UAAU,EAAE,OAAO,KAAKA,EAAG,UAAU,EAAE,QAAS,KACnDA,EAAG,UAAU,EAAE,MAAO,KAAKA,EAAG,UAAU,EAAE,SAAS,MACrD,KAAK,MAAA;AAAA,IAET,GAGA,KAAK,UAAUuF,GAAM,EAAE,SAAS,EAAE,SAAS,MAAM;AAC/C,MAAI,KAAK,QAAQA,KACf,SAAS,iBAAiB,aAAa,KAAK,eAAgB,EAAE,SAAS,IAAM,SAAS,IAAM;AAAA,IAEhG,CAAC,GAGD,KAAK,YAAY,CAACvF,MAAO;AACvB,MAAKuF,EAAK,SAASvF,EAAG,MAAc,UAAQ,MAAA;AAAA,IAC9C,GAEA,KAAK,UAAU,CAACA,MAAO;AACrB,UAAIA,EAAG,QAAQ,UAAa;AAAE,aAAK,MAAA;AAAS;AAAA,MAAQ;AACpD,UAAIA,EAAG,QAAQ,aAAa;AAAE,QAAAA,EAAG,eAAA,GAAkB,KAAK,WAAW,CAAC;AAAI;AAAA,MAAQ;AAChF,UAAIA,EAAG,QAAQ,WAAa;AAAE,QAAAA,EAAG,eAAA,GAAkB,KAAK,WAAW,EAAE;AAAG;AAAA,MAAQ;AAChF,UAAIA,EAAG,QAAQ,SAAS;AACtB,cAAM4F,IAAUL,EAAK,cAAiC,mBAAmB;AACzE,QAAAK,KAAA,QAAAA,EAAS;AAAA,MACX;AAAA,IACF,GACA,KAAK,aAAa,MAAM,KAAK,MAAA,GAE7B,WAAW,MAAM;AACf,eAAS,iBAAiB,SAAW,KAAK,SAAU,GACpD,SAAS,iBAAiB,WAAW,KAAK,OAAQ,GAClD,OAAO,iBAAiB,UAAa,KAAK,YAAa,EAAE,SAAS,IAAM;AAAA,IAC1E,GAAG,CAAC,GAGJ,KAAK,YAAY,IACjB,KAAK,WAAW,CAAC;AAAA,EACnB;AAAA,EAEA,QAAc;ArBzJT,QAAAxf;AqB0JH,KAAAA,IAAA,KAAK,QAAL,QAAAA,EAAU,UACV,KAAK,MAAM,MACP,KAAK,aAAe,SAAS,oBAAoB,SAAa,KAAK,SAAS,GAC5E,KAAK,WAAe,SAAS,oBAAoB,WAAa,KAAK,OAAO,GAC1E,KAAK,cAAe,OAAO,oBAAoB,UAAe,KAAK,UAAU,GAC7E,KAAK,iBAAe,SAAS,oBAAoB,aAAa,KAAK,eAAe,EAAE,SAAS,IAAM,GACvG,KAAK,YAAY,KAAK,UAAU,KAAK,aAAa,KAAK,gBAAgB,MACvE,KAAK,YAAY;AAAA,EACnB;AAAA,EAEA,UAAgB;AAAE,SAAK,MAAA;AAAA,EAAS;AAAA;AAAA,EAIxB,UAAUmf,GAAmB9M,GAAWhG,GAAWoT,GAAiC;AAC1F,IAAAN,EAAK,MAAM,UAAU,kDAErB,sBAAsB,MAAM;AAC1B,YAAM,EAAE,OAAAO,GAAO,QAAArb,MAAW8a,EAAK,sBAAA,GACzBQ,IAAK,OAAO,YAAYC,IAAK,OAAO,aACpCrW,IAAO8I,IAAIqN,IAASC,IAAK,KAAK,IAAI,GAAGtN,IAAIqN,CAAK,IAAKrN,GACnDsD,IAAOtJ,IAAIhI,IAASub,IAAK,KAAK,IAAI,GAAGvT,IAAIhI,CAAM,IAAIgI;AACzD,MAAA8S,EAAK,MAAM,UAAU,uBAAuB5V,CAAI,UAAUoM,CAAG,oBAE7D8J,KAAA,QAAAA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,WAAW7c,GAAmB;ArBxLjC,QAAA5C;AqByLH,QAAI,CAAC,KAAK,IAAK;AACf,UAAM6f,IAAO,MAAM;AAAA,MACjB,KAAK,IAAI,iBAAoC,kCAAkC;AAAA,IAAA;AAEjF,IAAKA,EAAK,WACV,KAAK,aAAa,KAAK,YAAYjd,IAAMid,EAAK,UAAUA,EAAK,SAC7D7f,IAAA6f,EAAK,KAAK,SAAS,MAAnB,QAAA7f,EAAsB;AAAA,EACxB;AAAA;AAAA,EAIQ,WAAWQ,GAA6B;AAC9C,QAAI,OAAOA,EAAK,UAAW,YAAY;AAAE,MAAAA,EAAK,OAAA;AAAU;AAAA,IAAQ;AAChE,YAAQA,EAAK,QAAA;AAAA,MACX,KAAK;AAAY,aAAK,SAAS,UAAA;AAAc;AAAA,MAC7C,KAAK;AAAY,aAAK,SAAS,WAAA;AAAc;AAAA,MAC7C,KAAK;AAAY,aAAK,SAAS,OAAA;AAAc;AAAA,MAC7C,KAAK;AAAY,aAAK,SAAS,QAAA;AAAc;AAAA,MAC7C,KAAK;AAAY,aAAK,SAAS,MAAA;AAAc;AAAA,MAC7C,KAAK;AAAY,aAAK,SAAS,QAAA;AAAc;AAAA,IAAA;AAAA,EAEjD;AACF;ACzMO,MAAMsf,GAAsD;AAAA,EAMjE,YAAYjc,GAAwBkc,GAA6B;AALjE,SAAQ,8BAA8C,IAAA,GACtD,KAAQ,UAAkB,IAKxB,KAAK,YAAYA,GACjB,KAAK,UAAY,KAAK,aAAalc,CAAS;AAAA,EAC9C;AAAA;AAAA,EAIA,IAAImc,GAAcpb,IAA0B,CAAA,GAAIvE,IAAY,CAAA,GAAU;AACpE,QAAI,KAAK,QAAQ,IAAI2f,CAAI;AACvB,YAAM,IAAI,MAAM,yBAAyBA,CAAI,aAAa;AAE5D,SAAK,QAAQ,IAAIA,GAAM,EAAE,MAAAA,GAAM,SAAApb,GAAS,MAAAvE,GAAM,GAC9C,KAAK,YAAA,GAGD,KAAK,QAAQ,SAAS,KAAG,KAAK,OAAO2f,CAAI;AAAA,EAC/C;AAAA,EAEA,OAAOA,GAAoB;AACzB,QAAI,CAAC,KAAK,QAAQ,IAAIA,CAAI,EAAG;AAC7B,QAAI,KAAK,QAAQ,SAAS;AACxB,YAAM,IAAI,MAAM,sCAAsC;AAExD,UAAMC,IAAY,KAAK,YAAYD;AACnC,SAAK,QAAQ,OAAOA,CAAI,GACxB,KAAK,YAAA,GAEDC,KAEF,KAAK,OAAO,KAAK,QAAQ,OAAO,KAAA,EAAO,KAAM;AAAA,EAEjD;AAAA,EAEA,OAAOC,GAAiBC,GAAuB;AAC7C,QAAI,CAAC,KAAK,QAAQ,IAAID,CAAO,EAAG;AAChC,QAAI,KAAK,QAAQ,IAAIC,CAAO;AAC1B,YAAM,IAAI,MAAM,yBAAyBA,CAAO,aAAa;AAEjD,SAAK,QAAQ,IAAID,CAAO;AAEtC,UAAME,IAAU,MAAM,KAAK,KAAK,QAAQ,QAAA,CAAS,EAAE;AAAA,MAAI,CAAC,CAACre,GAAG0B,CAAC,MAC3D1B,MAAMme,IAAU,CAACC,GAAS,EAAE,GAAG1c,GAAG,MAAM0c,EAAA,CAAS,IAAmC,CAACpe,GAAG0B,CAAC;AAAA,IAAA;AAE3F,SAAK,UAAU,IAAI,IAAI2c,CAAO,GAC1B,KAAK,YAAYF,MAAS,KAAK,UAAUC,IAC7C,KAAK,YAAA;AAAA,EACP;AAAA,EAEA,OAAOH,GAAoB;AACzB,UAAMpe,IAAQ,KAAK,QAAQ,IAAIoe,CAAI;AACnC,QAAI,CAACpe,EAAO,OAAM,IAAI,MAAM,yBAAyBoe,CAAI,cAAc;AACvE,SAAK,UAAUA,GACf,KAAK,YAAA,GACL,KAAK,UAAUA,GAAMpe,CAAK;AAAA,EAC5B;AAAA,EAEA,IAAIoe,GAA6C;AAC/C,WAAO,KAAK,QAAQ,IAAIA,CAAI;AAAA,EAC9B;AAAA,EAEA,WAAqB;AACnB,WAAO,MAAM,KAAK,KAAK,QAAQ,MAAM;AAAA,EACvC;AAAA,EAEA,YAAoB;AAAE,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG3C,SAASA,GAAc3f,GAAiB;AACtC,UAAMuB,IAAQ,KAAK,QAAQ,IAAIoe,CAAI;AACnC,IAAIpe,QAAa,OAAOvB;AAAA,EAC1B;AAAA,EAEA,UAAgB;AACd,SAAK,QAAQ,OAAA;AAAA,EACf;AAAA;AAAA,EAIQ,aAAawD,GAAqC;AACxD,UAAM8N,IAAM,SAAS,cAAc,KAAK;AACxC,WAAAA,EAAI,YAAY,iBAChB9N,EAAU,YAAY8N,CAAG,GAClBA;AAAA,EACT;AAAA,EAEQ,cAAoB;AAC1B,SAAK,QAAQ,YAAY;AAEzB,eAAWqO,KAAQ,KAAK,QAAQ,KAAA,GAAQ;AACtC,YAAMK,IAAM,SAAS,cAAc,QAAQ;AAC3C,MAAAA,EAAI,YAAc,gBAClBA,EAAI,cAAcL,GAClBK,EAAI,aAAa,QAAQ,KAAK,GAC9BA,EAAI,aAAa,iBAAiBL,MAAS,KAAK,UAAU,SAAS,OAAO,GACtEA,MAAS,KAAK,WAASK,EAAI,UAAU,IAAI,sBAAsB,GAGnEA,EAAI,iBAAiB,SAAS,MAAM;AAClC,QAAIL,MAAS,KAAK,WAAS,KAAK,OAAOA,CAAI;AAAA,MAC7C,CAAC,GAGDK,EAAI,iBAAiB,YAAY,MAAM,KAAK,aAAaA,GAAKL,CAAI,CAAC,GAEnE,KAAK,QAAQ,YAAYK,CAAG;AAAA,IAC9B;AAGA,UAAMC,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,EAAO,YAAc,gBACrBA,EAAO,cAAc,KACrBA,EAAO,aAAa,cAAc,WAAW,GAC7CA,EAAO,iBAAiB,SAAS,MAAM;AACrC,YAAMrQ,IAAI,QAAQ,KAAK,QAAQ,OAAO,CAAC;AACvC,WAAK,IAAIA,GAAG,CAAA,GAAI,CAAA,CAAE,GAClB,KAAK,OAAOA,CAAC;AAAA,IACf,CAAC,GACD,KAAK,QAAQ,YAAYqQ,CAAM;AAAA,EACjC;AAAA;AAAA,EAGQ,aAAaD,GAAwBH,GAAuB;AAClE,UAAMK,IAAQ,SAAS,cAAc,OAAO;AAC5C,IAAAA,EAAM,YAAY,uBAClBA,EAAM,QAAYL,GAClBG,EAAI,YAAYE,CAAK,GACrBA,EAAM,MAAA,GACNA,EAAM,OAAA;AAEN,UAAMC,IAAS,MAAM;AACnB,YAAML,IAAUI,EAAM,MAAM,KAAA,KAAUL;AACtC,UAAI;AACF,QAAIC,MAAYD,IAAS,KAAK,OAAOA,GAASC,CAAO,SAC3C,YAAA;AAAA,MACZ,QAAQ;AACN,aAAK,YAAA;AAAA,MACP;AAAA,IACF;AAEA,IAAAI,EAAM,iBAAiB,QAAUC,CAAM,GACvCD,EAAM,iBAAiB,WAAW,CAAC3gB,MAAM;AACvC,MAAIA,EAAE,QAAQ,WAAY2gB,EAAM,KAAA,GAC5B3gB,EAAE,QAAQ,aAAY2gB,EAAM,QAAQL,GAASK,EAAM,KAAA;AAAA,IACzD,CAAC;AAAA,EACH;AACF;ACpJO,MAAME,GAAmD;AAAA,EAG9D,YAAYtF,GAAqB;AAC/B,SAAK,KAAKA;AAAA,EACZ;AAAA,EAEQ,YAAY6E,GAAsB;AACxC,WAAO,iBAAiB,KAAK,GAAG,aAAA,CAAc,EAAE,iBAAiBA,CAAI,EAAE,KAAA;AAAA,EACzE;AAAA,EAEQ,cAAcU,GAAqB;AACzC,UAAMle,IAAIke,EAAI,KAAA,GACRC,IAAWne,EAAE,MAAM,qCAAqC;AAC9D,QAAIme;AACF,aAAO,CAACA,EAAS,CAAC,GAAGA,EAAS,CAAC,GAAGA,EAAS,CAAC,CAAC,EAC1C,IAAI,CAAA,MAAK,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAClD,KAAK,EAAE,EAAE,YAAA;AAEd,UAAM1R,IAAIzM,EAAE,QAAQ,KAAK,EAAE,EAAE,YAAA;AAC7B,WAAIyM,EAAE,WAAW,IAAUA,EAAE,CAAC,IAAEA,EAAE,CAAC,IAAEA,EAAE,CAAC,IAAEA,EAAE,CAAC,IAAEA,EAAE,CAAC,IAAEA,EAAE,CAAC,IAChDA,EAAE,WAAW,IAAIA,IAAI;AAAA,EAC9B;AAAA,EAEA,YAAYnL,GAAwC;AAClD,UAAMuJ,IAAO,OAAOvJ,KAAY,WAAW,EAAE,UAAUA,EAAA,IAAaA,KAAW,CAAA;AAC/E,QAAI8c,IAAQvT,EAAK,YAAY;AAC7B,IAAKuT,EAAM,YAAA,EAAc,SAAS,OAAO,MAAGA,KAAS;AACrD,UAAMC,IAAYxT,EAAK,cAAc,KAAK,GAAG,WAAA,EAAa,aAAa,WACjEhN,IAAQ,KAAK,GAAG,QAAA,GAChB4E,IAAQ,KAAK,GAAG,aAAA,EAAe,cAAc,OAAO,CAAAG,MAAA;AvBvCvD,UAAApF;AuBuC4D,gBAACA,IAAAqN,EAAK,iBAAL,QAAArN,EAAmB,SAASoF,EAAE;AAAA,KAAM,GAC9F0b,IAAgBzT,EAAK,kBAAkB;AAE7C,WAAO,wBAAe,EAAA,KAAA,CAAA4C,MAAAA,EAAA,CAAA,EAAE,KAAK,CAAC,EAAE,OAAA8Q,GAAO,WAAAC,QAAgB;AvB1CpD,UAAAhhB;AuB2CD,YAAMwF,IAAgB,CAAA;AACtB,MAAIsb,OAAoB,KAAK7b,EAAK,IAAI,CAAAG,MAAKA,EAAE,MAAM,CAAC;AACpD,iBAAW9E,KAAOD;AAChB,QAAAmF,EAAK,KAAKP,EAAK,IAAI,CAAAG,MAAK;AACtB,gBAAMiK,IAAO/O,EAAY8E,EAAE,KAAK;AAChC,cAAIiI,EAAK,gBAAgBjI,EAAE,QAAQ,KAAK,GAAG,eAAeA,EAAE,KAAK;AAC/D,mBAAOwE,GAAUyF,KAAO,OAAO,KAAK,OAAOA,CAAG,GAAGjK,EAAE,IAAI;AAEzD,gBAAM3B,IAAI4L;AACV,iBAAI5L,KAAK,QAAQA,MAAM,KAAW,KAC9B2B,EAAE,SAAS,YAAY,OAAO3B,KAAM,WAAiBA,IACrD,OAAOA,KAAM,YAAkBA,IAAI,MAAM,KACzC,OAAOA,KAAM,WAAiB,KAC3B,OAAOA,CAAC;AAAA,QACjB,CAAC,CAAC;AAGJ,YAAMwd,IAAKF,EAAM,aAAavb,CAAI,GAE5B0b,IAAY,KAAK,GAAG,aAAA,GACpBC,IAAY,KAAK,GAAG,aAAA;AAC1B,MAAAF,EAAG,OAAO,IAAIhc,EAAK,IAAI,CAAAG,OAAM;AAAA,QAC3B,KAAK8b,EAAUC,EAAU,eAAe/b,EAAE,KAAK,CAAC,KAAK;AAAA,MAAA,EACrD,GACF6b,EAAG,OAAO,IAAIzb,EAAK,IAAI,CAAC9E,GAAGgT,OAAQ,EAAE,KAAKA,MAAO,KAAKoN,IAAgB,KAAK,KAAK;AAEhF,YAAMM,IAAY/T,EAAK,aAAa;AACpC,UAAIgU,IAAY,UAAUC,IAAY,UAClCC,IAAY,UAAUC,IAAY,UAClCC,IAAY,UAAUC,IAAY,UAClCC,IAAY;AAEhB,UAAIP,MAAc,SAAS;AACzB,cAAMQ,IAAQ,CAACne,MAAc,KAAK,cAAcA,CAAC;AACjD,QAAA4d,IAAYO,EAAM,KAAK,YAAY,gBAAgB,CAAC,KAAQP,GAC5DC,IAAYM,EAAM,KAAK,YAAY,mBAAmB,CAAC,KAAMN,GAC7DC,IAAYK,EAAM,KAAK,YAAY,aAAa,CAAC,KAAYL,GAC7DC,IAAYI,EAAM,KAAK,YAAY,iBAAiB,CAAC,KAAQJ,GAC7DC,IAAYG,EAAM,KAAK,YAAY,gBAAgB,CAAC,KAASH,GAC7DC,IAAYE,EAAM,KAAK,YAAY,mBAAmB,CAAC,KAAMF;AAC7D,cAAMG,IAAQ,KAAK,YAAY,gBAAgB;AAC/C,QAAIA,MAAOF,IAAW,KAAK,IAAI,GAAG,KAAK,MAAM,WAAWE,CAAK,IAAI,IAAI,CAAC;AAAA,MACxE;AAEA,YAAMC,IAAUV,MAAc,QACxBW,IAAI;AAAA,QACR,SAAWD,IAAU,CAAA,IAAK,EAAE,MAAM,IAAM,OAAO,EAAE,KAAKR,EAAA,GAAY,IAAIK,GAAU,MAAM,QAAA;AAAA,QACtF,UAAWG,IAAU,KAAK,EAAE,IAAIH,GAAU,OAAO,EAAE,KAAKF,KAAY,MAAM,QAAA;AAAA,QAC1E,SAAWK,IAAU,CAAA,IAAK,EAAE,aAAa,SAAkB,SAAS,EAAE,KAAKT,IAAS;AAAA,QACpF,UAAWS,IAAU,CAAA,IAAK,EAAE,aAAa,SAAkB,SAAS,EAAE,KAAKP,IAAS;AAAA,QACpF,SAAWO,IAAU,CAAA,IAAK,EAAE,aAAa,SAAkB,SAAS,EAAE,KAAKN,IAAU;AAAA,QACrF,WAAWM,IAAU,KAAK;AAAA,UACxB,KAAQ,EAAE,OAAO,UAAU,OAAO,EAAE,KAAKT,IAAS;AAAA,UAClD,QAAQ,EAAE,OAAO,UAAU,OAAO,EAAE,KAAKA,IAAS;AAAA,UAClD,MAAQ,EAAE,OAAO,QAAU,OAAO,EAAE,KAAKA,IAAS;AAAA,UAClD,OAAQ,EAAE,OAAO,QAAU,OAAO,EAAE,KAAKA,IAAS;AAAA,QAAE;AAAA,QAEtD,YAAYS,IAAU,KAAK;AAAA,UACzB,KAAQ,EAAE,OAAO,QAAQ,OAAO,EAAE,KAAKJ,IAAU;AAAA,UACjD,QAAQ,EAAE,OAAO,QAAQ,OAAO,EAAE,KAAKA,IAAU;AAAA,UACjD,MAAQ,EAAE,OAAO,QAAQ,OAAO,EAAE,KAAKA,IAAU;AAAA,UACjD,OAAQ,EAAE,OAAO,QAAQ,OAAO,EAAE,KAAKA,IAAU;AAAA,QAAE;AAAA,MACrD;AAGF,MAAAlc,EAAK,QAAQ,CAAClF,GAAKoT,MAAO;AACxB,cAAMsO,IAASlB,KAAiBpN,MAAO,GAEjCuO,MADSnB,IAAgBpN,IAAK,IAAIA,KAChB,MAAM;AAE9B,QAAApT,EAAI,QAAQ,CAAC4hB,IAAIlM,MAAO;AACtB,gBAAMmM,IAAOpB,EAAM,YAAY,EAAE,GAAGrN,GAAI,GAAGsC,GAAI;AAC/C,UAAKiL,EAAGkB,CAAI,MAAGlB,EAAGkB,CAAI,IAAI,EAAE,GAAG,KAAK,GAAG,GAAA;AAEvC,gBAAMhd,IAAMF,EAAK+Q,CAAE,GACboM,IAASjd,EAAI,SAAS,YAAYA,EAAI,UAAU,SAChDkd,IAASL,IAAQ,WAAWI,IAAQ,UAAWjd,EAAI,SAAS;AAElE,UAAA8b,EAAGkB,CAAI,EAAE,IAAI;AAAA,YACX,MAAWH,IAAQD,EAAE,UAAUA,EAAE;AAAA,YACjC,MAAWC,IAAQD,EAAE,UAAWE,KAASF,EAAE,WAAWA,EAAE;AAAA,YACxD,QAAWC,IAAQD,EAAE,YAAYA,EAAE;AAAA,YACnC,WAAW,EAAE,YAAYM,GAAQ,UAAU,UAAU,UAAU,GAAA;AAAA,UAAM;AAAA,QAEzE,CAAC;AAAA,MACH,CAAC;AAED,YAAMC,IAAKvB,EAAM,SAAA;AACjB,MAAAA,EAAM,kBAAkBuB,GAAIrB,GAAIJ,CAAS,GACzCG,EAAUsB,GAAI1B,GAAO,EAAE,YAAY,IAAa,IAChD5gB,IAAAqN,EAAK,YAAL,QAAArN,EAAA,KAAAqN,GAAe,IAAI,KAAK,CAAA,CAAE;AAAA,IAC5B,CAAC,EAAE,MAAM,MAAM;AACb,cAAQ,MAAM,iCAAiC;AAAA,IACjD,CAAC;AAAA,EACH;AAAA,EAEA,UAAUvJ,GAAwC;AAChD,UAAMuJ,IAAO,OAAOvJ,KAAY,WAAW,EAAE,UAAUA,EAAA,IAAaA,KAAW,CAAA,GACzEzD,IAAO,KAAK,GAAG,QAAA,GACf4E,IAAO,KAAK,GAAG,aAAA,EAAe,eAC9Bsd,IAAMtd,EAAK,IAAI,CAAAG,MAAK,IAAIA,EAAE,MAAM,GAAG,EAAE,KAAK,GAAG,GAC7CI,IAAOnF,EAAK,IAAI,CAAAC,MAAO2E,EAAK,IAAI,CAAAG,MAAK;AACzC,YAAMiK,IAAM/O,EAAI8E,EAAE,KAAK,KAAK;AAC5B,UAAIiI,EAAK,gBAAgBjI,EAAE,QAAQ,KAAK,GAAG,eAAeA,EAAE,KAAK;AAC/D,eAAOwE,GAAU,OAAOyF,CAAG,GAAGjK,EAAE,IAAI;AAEtC,YAAM3B,IAAI4L;AACV,aAAO,OAAO5L,KAAM,YAAYA,EAAE,SAAS,GAAG,IAAI,IAAIA,CAAC,MAAMA;AAAA,IAC/D,CAAC,EAAE,KAAK,GAAG,CAAC,GACNmd,IAAQvT,EAAK,YAAY;AAC/B,IAAA6L,GAAc,WAAM,CAACqJ,GAAK,GAAG/c,CAAI,EAAE,KAAK;AAAA,CAAI,GAAGob,CAAK;AAAA,EACtD;AAAA,EAEA,WAAW9c,GAAwC;AACjD,UAAM8c,IAAQ,OAAO9c,KAAY,WAAWA,KAAWA,KAAA,gBAAAA,EAAS,aAAY;AAC5E,IAAAoV,GAAc,KAAK,UAAU,KAAK,GAAG,QAAA,GAAW,MAAM,CAAC,GAAG0H,GAAO,kBAAkB;AAAA,EACrF;AAAA,EAEA,MAAM9c,GAAmF;AACvF,UAAMyC,KAAazC,KAAA,gBAAAA,EAAS,UAAc,aACpC0e,KAAa1e,KAAA,gBAAAA,EAAS,eAAc,IACpCzD,IAAO,KAAK,GAAG,QAAA,GACf4E,IAAO,KAAK,GAAG,aAAA,EAAe,cACjC,OAAO,CAAAG,MAAA;AvBtKP,UAAApF;AuBsKY,gBAACA,IAAA8D,KAAA,gBAAAA,EAAS,kBAAT,QAAA9D,EAAwB,SAASoF,EAAE;AAAA,KAAM,GAEnDqd,IAAaxd,EAAK,IAAI,CAAAG,MAAK,OAAOA,EAAE,UAAUA,EAAE,KAAK,OAAO,EAAE,KAAK,EAAE,GACrEsd,IAAariB,EAAK;AAAA,MAAI,OAC1B,OAAO4E,EAAK,IAAI,CAAAG,MAAK,OAAO,OAAO9E,EAAI8E,EAAE,KAAK,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA,IAAA,EACvE,KAAK,EAAE,GACHud,IAAaH,IACf,gCAAgCA,CAAU,WAC1C,IAEExR,IAAO;AAAA;AAAA,+BAEczK,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAa9BA,CAAK;AAAA,KACNlG,EAAK,MAAM,OAAO4E,EAAK,MAAM,QAAO,oBAAI,KAAA,GAAO,eAAe,OAAO,CAAC;AAAA;AAAA,eAE5Dwd,CAAS;AAAA,WACbC,CAAQ;AAAA;AAAA,EAEjBC,CAAU;AAAA;AAAA,iBAIFC,IAAM,OAAO,KAAK,IAAI,UAAU,sBAAsB;AAC5D,IAAIA,MAAOA,EAAI,SAAS,MAAM5R,CAAI,GAAG4R,EAAI,SAAS,MAAA;AAAA,EACpD;AAAA,EAEA,kBAAkBxJ,GAAyB;AACzC,UAAMyJ,IAAY,KAAK,GAAG,aAAA;AAC1B,QAAI,CAACA,GAAW;AAAE,WAAK,YAAYzJ,KAAY,UAAU;AAAG;AAAA,IAAQ;AACpE,UAAMwH,IAAQxH,KAAY;AAE1B,WAAO,wBAAe,EAAA,KAAA,CAAAnJ,MAAAA,EAAA,CAAA,EAAE,KAAK,CAAC,EAAE,OAAA8Q,GAAO,WAAAC,QAAgB;AACrD,YAAMsB,IAAKvB,EAAM,SAAA,GACX1T,IAAO,KAAK,GAAG,WAAA;AACrB,iBAAW2S,KAAQ6C,EAAU,YAAY;AACvC,cAAMjhB,IAAQihB,EAAU,IAAI7C,CAAI,GAC1B/a,IAAQrD,EAAM,QAAQ,SAASA,EAAM,UAAUyL,EAAK,SACpD7H,IAAgB,CAACP,EAAK,IAAI,CAACG,MAAWA,EAAE,MAAM,CAAC;AACrD,mBAAW9E,KAAOsB,EAAM;AACtB,UAAA4D,EAAK,KAAKP,EAAK,IAAI,CAACG,MAAW;AAC7B,kBAAM3B,IAAKnD,EAAY8E,EAAE,KAAK;AAC9B,mBAAI3B,KAAK,OAAa,KAClB,OAAOA,KAAM,YAAkBA,IAAI,MAAM,KACtC2B,EAAE,SAAS,YAAY,OAAO3B,KAAM,WAAWA,IAAI,OAAOA,CAAC;AAAA,UACpE,CAAC,CAAC;AAEJ,cAAMwd,IAAKF,EAAM,aAAavb,CAAI;AAClC,QAAAyb,EAAG,OAAO,IAAIhc,EAAK,IAAI,OAAO,EAAE,KAAK,MAAM,GAC3C8b,EAAM,kBAAkBuB,GAAIrB,GAAIjB,CAAI;AAAA,MACtC;AACA,MAAAgB,EAAUsB,GAAI1B,EAAM,SAAS,OAAO,IAAIA,IAAQA,IAAQ,SAAS,EAAE,YAAY,GAAA,CAAa;AAAA,IAC9F,CAAC,EAAE,MAAM,MAAM,QAAQ,MAAM,qCAAqC,CAAC;AAAA,EACrE;AACF;ACpOO,MAAMkC,GAAmD;AAAA,EAG9D,YAAY3H,GAAqB;AAC/B,SAAK,KAAKA;AAAA,EACZ;AAAA,EAEA,OAAO3Z,GAAe0U,GAAsB;AAC1C,QAAI,CAACA;AACH,aAAO,KAAK,MAAM1U,CAAK,EAAE,eAAe,OAAO;AAEjD,UAAMuhB,IAAW7M,EAAI,SAAS,GAAG,KAAKA,EAAI,SAAS,GAAG,GAChD8M,IAAW9M,EAAI,MAAM,UAAU,GAC/B9N,IAAK4a,IACP,SAASA,EAAQ,CAAC,GAAI,EAAE,IACxB,QAAQ,KAAK9M,CAAG,IAAI,SAASA,GAAK,EAAE,IAAI,GAEtC+M,IAAQ,KAAK,IAAIzhB,CAAK,EAAE,QAAQ4G,CAAE,GAClC,CAACO,IAAU,KAAKua,CAAO,IAAID,EAAM,MAAM,GAAG,GAC1CE,IAASJ,IACXpa,EAAQ,QAAQ,yBAAyB,GAAG,IAC5CA,GAEER,IAAS+a,MAAY,SAAY,GAAGC,CAAM,IAAID,CAAO,KAAKC;AAChE,WAAO3hB,IAAQ,IAAI,IAAI2G,CAAM,KAAKA;AAAA,EACpC;AAAA,EAEA,gBAAuB;AACrB,UAAMib,IAAa,KAAK,GAAG,WAAA,EAAa;AACxC,QAAI,CAACA,KAAcA,EAAW,WAAW,UAAU,CAAA;AAEnD,UAAMC,IAAU,KAAK,GAAG,QAAA;AAExB,WAAOD,EACJ,OAAO,CAAClhB,MAAWA,EAAE,SAASA,EAAE,EAAE,EAClC,IAAI,CAAC4H,MAAa;AACjB,YAAMvI,IAASuI,EAAI,OACbwZ,IAASxZ,EAAI,IACbyZ,IAASF,EACZ,IAAI,CAAC5iB,MAAWA,EAAEc,CAAK,CAAC,EACxB,OAAO,CAACkC,MAAWA,KAAM,QAA2BA,MAAM,EAAE;AAE/D,UAAI0E,IAA2B;AAC/B,YAAMqb,IAAQF,EAAc,YAAA;AAC5B,UAAIE,MAAS;AACX,QAAArb,IAASob,EAAK,SAAS,IAAIjc,EAAU,IAAIic,EAAK,IAAI,CAAC9f,MAAW,OAAOA,CAAC,CAAC,CAAC,IAAI;AAAA,eACnE+f,MAAS;AAClB,QAAArb,IAASob,EAAK,SAAS,IACnBjc,EAAU,IAAIic,EAAK,IAAI,CAAC9f,MAAW,OAAOA,CAAC,CAAC,CAAC,EAAE,IAAI6D,EAAU,KAAK,OAAOic,EAAK,MAAM,CAAC,CAAC,IACtF;AAAA,eACKC,MAAS,SAAS;AAC3B,cAAMC,IAAMF,EAAK;AACjB,eAAO,EAAE,QAAQhiB,GAAO,QAAQkiB,GAAK,YAAYA,EAAI,eAAe,OAAO,EAAA;AAAA,MAC7E,MAAA,CAAWD,MAAS,QAClBrb,IAASob,EAAK,SAAS,IAAIjc,EAAU,IAAIic,EAAK,IAAI,CAAC9f,MAAW,OAAOA,CAAC,CAAC,CAAC,IAAI,OACnE+f,MAAS,UAClBrb,IAASob,EAAK,SAAS,IAAIjc,EAAU,IAAIic,EAAK,IAAI,CAAC9f,MAAW,OAAOA,CAAC,CAAC,CAAC,IAAI;AAG9E,UAAI,CAAC0E,EAAQ,QAAO,EAAE,QAAQ5G,GAAO,QAAQ,MAAM,YAAY,GAAA;AAE/D,YAAMmiB,IAAYvb,EAAO,SAAA,GACnBwb,IAAY,KAAK,OAAOD,GAAQ5Z,EAAI,MAAM;AAChD,aAAO,EAAE,QAAQvI,GAAO,QAAQmiB,GAAQ,YAAYC,EAAA;AAAA,IACtD,CAAC;AAAA,EACL;AAAA,EAEA,SAAe;AxBvEV,QAAA3jB;AwBwEH,UAAM6D,IAAY,KAAK,GAAG,aAAA,GACpByX,IAAMzX,EAAU,cAAc,gBAAgB;AACpD,IAAAyX,KAAA,QAAAA,EAAK;AAEL,UAAMjO,IAAO,KAAK,GAAG,WAAA,GACf+V,IAAa/V,EAAK;AACxB,QAAI,CAAC+V,KAAcA,EAAW,WAAW,EAAG;AAE5C,UAAMte,IAAS,KAAK,GAAG,aAAA,EAAe,eAChCiO,IAAS,KAAK,GAAG,aAAA,KAAkBjO,EAAO,IAAI,CAACgP,MAAWA,EAAE,SAAS,GAAG,GACxE8P,IAAS,IAAI;AAAA,MACjB,KAAK,cAAA,EAAgB,IAAI,CAACngB,MAAW,CAACA,EAAE,QAAQA,CAAC,CAAC;AAAA,IAAA,GAG9CkO,IAAM,SAAS,cAAc,KAAK;AACxC,IAAAA,EAAI,YAAY,iBAChBA,EAAI,MAAM,UAAU;AAAA,MAClB;AAAA,MACA,cAActE,EAAK,YAAY;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,IAAA,EACA,KAAK,EAAE;AAET,QAAIuI,IAAS;AAKb,QAJIvI,EAAK,gBAAauI,KAAU,KAC5BvI,EAAK,cAAauI,KAAU,KAC5BvI,EAAK,cAAauI,KAAU,KAC5BvI,EAAK,gBAAauI,KAAU,KAC5BA,IAAS,GAAG;AACd,YAAMlR,IAAS,SAAS,cAAc,KAAK;AAC3C,MAAAA,EAAO,MAAM,UAAU,SAASkR,CAAM,2EACtCjE,EAAI,YAAYjN,CAAM;AAAA,IACxB;AAEA,QAAImf,IAAa;AAEjB,eAAW/Z,KAAOsZ,GAAY;AAC5B,YAAMU,IAAU,KAAK,IAAI,GAAGha,EAAI,WAAW,CAAC;AAE5C,UAAIia,IAAQ;AACZ,eAAS3e,IAAI,GAAGA,IAAI0e,GAAS1e;AAC3B,QAAA2e,KAAShR,EAAO8Q,IAAaze,CAAC,KAAK;AAErC,YAAM4e,IAAalf,EAAO+e,CAAU;AACpC,MAAAA,KAAcC;AAEd,YAAMlQ,IAAO,SAAS,cAAc,KAAK;AACzC,MAAAA,EAAK,MAAM,UAAU;AAAA,QACnB,SAASmQ,CAAK,gBAAgBA,CAAK;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,MAAA,EACA,KAAK,EAAE;AAET,YAAMxiB,IAAQuI,EAAI,OACZ1G,IAAQ7B,IAAQqiB,EAAO,IAAIriB,CAAK,IAAI;AAE1C,UAAI6B,GAAK;AACP,cAAM6gB,IAAa7gB,EAAI,cAAc,OAAOA,EAAI,UAAU,EAAE,GACtDsI,IAAS5B,EAAI,QAAQ,GAAGA,EAAI,KAAK,OAAO;AAC9C,QAAA8J,EAAK,cAAclI,IAASuY,GAC5BrQ,EAAK,QAAQ,KAAI5T,IAAA8J,EAAI,OAAJ,gBAAA9J,EAAmB,kBAAiB,EAAE,MAAMikB,CAAU,IACvErQ,EAAK,MAAM,QAAQ,6BACnBA,EAAK,MAAM,YAAY9J,EAAI,WAAUka,KAAA,gBAAAA,EAAY,UAAS,UAAW;AAAA,MACvE,MAAA,CAAWla,EAAI,UACb8J,EAAK,cAAc9J,EAAI,OACvB8J,EAAK,MAAM,YAAY9J,EAAI,SAAS,QACpC8J,EAAK,MAAM,QAAQ;AAGrB,MAAAjC,EAAI,YAAYiC,CAAI;AAAA,IACtB;AAEA,IAAIvG,EAAK,mBAAmB,QAC1BxJ,EAAU,aAAa8N,GAAK9N,EAAU,UAAU,IAEhDA,EAAU,YAAY8N,CAAG;AAAA,EAE7B;AACF;AC3IO,MAAMuS,GAAqD;AAAA,EAGhE,YAAY/I,GAAuB;AACjC,SAAK,KAAKA;AAAA,EACZ;AAAA,EAEA,cAAc,GAAwB;AACpC,UAAMgJ,IAAU,KAAK,GAAG,WAAA;AACxB,QAAIA,EAAQ,aAAc;AAE1B,SAAK,GAAG,iBAAiB,eAAe,CAAC;AAEzC,UAAM9jB,IAAO,KAAK,GAAG,QAAA,GACf8gB,IAAY,KAAK,GAAG,aAAA,GACpBnH,IAAY3Z,EAAK,UACjB+jB,IAAYjD,EAAU,cAAc;AAC1C,QAAInH,MAAc,KAAKoK,MAAc,EAAG;AAExC,SAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,KAAK;AAC7C,QAAE,eAAA,GACF,KAAK,iBAAA;AACL;AAAA,IACF;AACA,SAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,KAAK;AAC7C,QAAE,eAAA,GACF,KAAK,oBAAA;AACL;AAAA,IACF;AAEA,UAAM/W,IAAO,KAAK,GAAG,WAAA;AACrB,SAAK,EAAE,WAAW,EAAE,YAAYA,EAAK,aAAa8W,EAAQ,WAAW;AACnE,UAAI,EAAE,QAAQ,aAAa;AACzB,UAAE,eAAA;AACF,cAAMzQ,IAAKyQ,EAAQ,UAAU,OAAO,SAAYA,EAAQ,UAAU,KAAK;AACvE,QAAIzQ,IAAKsG,IAAY,MACnB,KAAK,GAAG,cAActG,GAAIA,IAAK,CAAC,GAChC,KAAK,GAAG,aAAaA,IAAK,GAAGyQ,EAAQ,UAAU,EAAE,GACjD,KAAK,GAAG,SAAS,KAAKzQ,IAAK,CAAC,QAAQA,IAAK,CAAC,WAAW;AAEvD;AAAA,MACF;AACA,UAAI,EAAE,QAAQ,WAAW;AACvB,UAAE,eAAA;AACF,cAAMA,IAAKyQ,EAAQ,UAAU;AAC7B,QAAIzQ,IAAK,MACP,KAAK,GAAG,cAAcA,GAAIA,IAAK,CAAC,GAChC,KAAK,GAAG,aAAaA,IAAK,GAAGyQ,EAAQ,UAAU,EAAE,GACjD,KAAK,GAAG,SAAS,KAAKzQ,IAAK,CAAC,QAAQA,CAAE,WAAW;AAEnD;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK,aAAa;AAChB,UAAE,eAAA;AACF,cAAM+G,IAAM0J,EAAQ,WACdE,IAAS5J,IAAM,KAAK,IAAIA,EAAI,KAAK,GAAGT,IAAY,CAAC,IAAI;AAC3D,aAAK,GAAG,aAAaqK,IAAQ5J,KAAA,gBAAAA,EAAK,OAAM,CAAC;AACzC;AAAA,MACF;AAAA,MACA,KAAK,WAAW;AACd,UAAE,eAAA;AACF,cAAMA,IAAM0J,EAAQ,WACdE,IAAS5J,IAAM,KAAK,IAAIA,EAAI,KAAK,GAAG,CAAC,IAAI;AAC/C,aAAK,GAAG,aAAa4J,IAAQ5J,KAAA,gBAAAA,EAAK,OAAM,CAAC;AACzC;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,UAAE,eAAA;AACF,cAAMA,IAAM0J,EAAQ;AACpB,YAAI,CAAC1J,GAAK;AAAE,eAAK,GAAG,aAAa,GAAG,CAAC;AAAG;AAAA,QAAO;AAC/C,QAAIA,EAAI,KAAK2J,IAAY,IACvB,KAAK,GAAG,aAAa3J,EAAI,IAAIA,EAAI,KAAK,CAAC,IAC9BA,EAAI,KAAKT,IAAY,KAC9B,KAAK,GAAG,aAAaS,EAAI,KAAK,GAAG,CAAC;AAEpC;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,UAAE,eAAA;AACF,cAAMA,IAAM0J,EAAQ;AACpB,YAAI,CAAC1J,GAAK;AAAE,eAAK,GAAG,aAAa,GAAG,CAAC;AAAG;AAAA,QAAO;AAC/C,QAAIA,EAAI,KAAK,IACX,KAAK,GAAG,aAAaA,EAAI,IAAIA,EAAI,KAAK,CAAC,IAC9BA,EAAI,KAAK,KAClB,KAAK,GAAG,aAAaA,EAAI,KAAK,GAAG2J,IAAY,CAAC;AAEhD;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AACV,UAAE,eAAA;AACF,cAAM3J,IAAM0J,EAAQ;AACpB,YAAI,CAAC1J,GAAK;AAAE,eAAK,GAAG,aAAa,GAAG,CAAC;AAAG;AAAA,QAAO;AAC/C,QAAK,EAAE,WAIDA,EAAI,KAAK,IAAG,KAAK,GAAG,aAAaA,EAAI,IAAIA,EAAI,KAAK,CAAC,IAC9CA,EAAI,KAAK,KAAG,KAAK,GAAG,aAAaA,EAAI,KAAK,GAAG2J,IAAY,CAAC,IAJ/D3J,EAAI,KAAK2J,IAAY,IAAG,KAAK,GAAG,aAAa3J,EAAI,IAAIA,EAAI,KAAK,CAAC,IAC1DA,EAAI,KAAKT,IAAY,KAAG,KAAK,GAAG,aAAaS,EAAI,KAAK,GAAG,CAAC;AAKrE;AAAA,MACF;AAAA,MACA,KAAK,QAAQ;AAEX,YADA,EAAE,eAAA,GACE,EAAE,WAAW,EAAE;AACjB,eAAK,GAAG,aAAa,GAAG,CAAC;AAAA,aACpB;AACL,gBAAMA,IAAM0J,EAAQ;AACpB,eAAK,GAAG,cAAa1J,KAAA,gBAAAA,EAAK,OAAM,GAAG,CAAC;AAAA,QACtC;AACA;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AAEV,YADA,EAAE,eAAA,GACE,EAAE,WAAW,EAAE;AACjB,eAAK,GAAG,aAAaT,IAAY,GAAGoK,IAAY,CAAC;AAAA,aAC5C;AACL,gBAAM3J,IAAM0J,EAAQ;AACpB,eAAK,GAAG,cAAa1J,KAAA,gBAAAA,EAAK,OAAM,GAAG2J,IAAY,CAAC;AAAA,QAClD;AACA;AAAA,MACF;AAAA,MACA,KAAK,YAAY;AACf,UAAE,eAAA;AACF,cAAM3J,IAAM0J,EAAQ,WACdG,IAAO,KAAK,GAAG,WAAA,EAAa,YAAY,IACxCD,IAAe,KAAK,IAAX5J,IAAeA,EAAI,KAAK6J,IAAgCA,IAAO,GAAjCtK,IAAY,CAAC;AAC1D,aAAK,GAAG,aAAaqK,IAAQ5J,KAAA,gBAAAA,EAAK,OAAM,CAAC;AACzC;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,UAAE,eAAA;AACF,cAAMA,IAAM0J,EAAQ,WACdG,IAAO,KAAK,GAAG,WAAA,EAAa,YAAY,IACxCD,IAAS5J,IAAM,KAAK,IAAIA,EAAI,KAAK6J,GAAM,CAAC,IAAI;AAClD,aAAK,GAAG,aAAaD,IAAQ5J,KAAA,gBAAAA,EAAK,OAAM,CAAC;AACzC;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,YAAI0J,EAAQ,WAAW;AACrB,YAAE,eAAA;AACF,gBAAMzQ,IAAKyQ,EAAQ,UAAU,IACvBI,IAAS,KAAK,GAAG,UAAA;AACvB,UAAI,KAAK,GAAG,WAAA,EAAa,eACvBA,EAAO,MAAM7Q,GAAI,CAAC6Q,EAAO,YAAY,IAAI7Q,CAAE,CAAC,GAC5C,KAAK,GAAG,SAAA,MAER6Q,EAAO,aAAa7Q,CAAE,GACtB,KAAK,GAAG,SAAA;AAAA,QAEZ;AACA;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK,SAAS;AACZ,QAAIyQ,EAAQ,aAAa,KAAK,GAAG,WAAA,EAAa,aAC5C,EAAE,eAAA,GACFA,EAAQ,eAAeA,EAAQ,UAAU,IAAIA,EAAQ,UAAU,EAAE;AAEnE;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,QAAAA,EAAQ,eAAA,GACR,KAAK,GAAG,SAAA;AACR;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEQ,mBAAyB;AzBxL5B,QAAAnkB;AyB0LH,QAAI,CADS,KAAK,GAAG,WAAA,EACX,UAAW;AAErB,UAAMmkB,IAAU,KAAK,GAAG,WAAA,GAClBhD,IAAY,KAAK,GAAG,aAAA,GACpB9gB,IAAO,KAAK,GAAG,QAAA;AAErB,QAAIuM,IAAO;AACX,QAAIuX,EAAQ,WAAW;AACrB,YAAM,EAAE,IAAAzQ,GAAI,IAAAsC,EAAA,IAAOmO,EAAQ,WACrBhf,IAAMgc,EAAU,cAAcnL,CAAE;AACtC,MAAI7Q,UAAY,OAAO9E,EAAK,aAAaqT,GAAIvO,EAAI,KAAK,KAAK,EAAE;AAAA,IAC/D,WAAW,KAAK,GAAG,YAAY,aAAa,OAAO,GAAG;AACpD,YAAMF,IAAOkc,EAAU;AAKvB,MAAAvU,IAJiB,CAAC,GAAG,KAAK,GAAG,YAAY,YAAY,EAAE,KAAK,CAAC,GAAGlK,MAAM,IAAIA,CAAC,EAAE,IAAI,CAAAgR,MAAM;AACrF,cAAMpT,IAAMD,EAAK,cAAcqT,CAAE;AACjC,eAAOzO,EAAK,IAAI,CAAAG,MAAK,QAAO9E,KAAA,gBAAAA,EAAM8E,EAAE,WAAU,EAAE,CAAC,EAAE,KAAK,GAAI;AAAA,MAC9D,CAAC,EACe,KAAK;AAAA,CAAI;AAAA,IAC3B;AAEA,IAAIwH,OAAM5M,IAAA,UAAU,cAAV,QAAAA,EAAqB,UAAU4M,GAAM,MAAM,MAAM;AAAA,IAAC;AAAA,EAC9D;AAAA,EAEQ,sBAA4B;AzBjN/B,QAAA5M;AyBkNH,UAAMqN,IAAO,KAAK,GAAG,WAAA;AACrB,QAAI,CAACA,EAAK,aAAa,CAACA,EAAK,SAAU;AAEvC,UAAM8W,IAAU,KAAK,GAAG,WAAA;AACxB,IAAKA,EAAQ,eAEbnkB,IAAA,UAAU,cAAV,QAAAA,EAAqB,WAAW,KAAK,CAAA4M,MAAQ;AAC3C,UAAI,CAACA,EAAM;AACX,YAAM,EAAE,IAAA8G,GAAI,IAAAsC,EAAA,IAAOmO,EAAQ,WACrBK,IAAQ5X,EAAK,MAAM;AAAA,CAAI,GACvB3H,IAAO,KAAK,GAAG,aAAA,EAAe,eAC9B5E,IAAO,KAAK,GAAG,QAAA;AAErB,eAASokB,IAAK,GAAGA,IAAKD,EAAM,QAAQC,KAAM;AACxC,cAAMlG,IAAQiG,EAAMC,CAAE,EAAG,MAAM,GAAI;AACnC,iBAAS/M,IAAK,GAAGA,IAAK6G,EAAM,QAAQ7G,KAAM;AACxC,gBAAMgN,IAAWhR,IAAK+Q,GAChBE,IAAW3O,IAAK0B,GAChBvS,IAAMF,EAAK0f,CAAQ;AACzB,UAAIxf,KAAOuf,IAAWrkB,EAAK,YACzBA,EAAK,WAAWqkB,GAAUvf,EAAI,OAAOoZ,EAAM7G,CAAE,CAAC;AAAA,QAElD;AAAA,MACF;AACA,WAAK,GAAG,KAAK,cAAcrX,EAAK,SAAS,GACzC,KAAK,GAAG,SAAA;AAAA,IACV,GAAG,MAAM,MAAM;AAAA,IAAC;AAAA,EAClB;AACF;ACvOO,MAAMukB,GAAoD;AAAA,EAO/D,YAAYzJ,GAAsB;AANlC,SAAQ,OAA8B,MACtC,KAAQ,SAAmC,MAC3C,KAAQ,SAA8B,MACtC,KAAQ,UAAkB,IAIxB,KAAK,KAAKA;AAAA,EACZ;AAAA,EAEA,IAAI,aAAqB;AAAE,WAAO,KAAK;AAAA,EAAS;AAAA,EAEhD,KAAKtX,GAA8B;AACjC,UAAM8N,IAAM,SAAS,cAAc,KAAK;AACxC,IAAAA,EAAI,YAAY,eAChBA,EAAI,SAAY;AAEhB,UAAMlC,IAAM,SAAS,cAAc,MAAM;AACzC,IAAAA,EAAI,YAAc,iBAClBA,EAAI,cAAc;AAElB,UAAM8Q,IAAQ,SAAS,cAAc,OAAO;AAC5C,IAAAA,EAAM,OAAc,QACpBA,EAAM,YAAc,iBACpBA,EAAM,cAAc,aACpBA,EAAM,aAAa,cAAc,UAAU;AAE3C,UAAMnc,IAAQ,SAAS,cAAc,MAAM;AAC3C,IAAAA,EAAM,YAAY;AAElB,UAAMygB,IAAW,SAAS,cAAc,QAAQ;AAChD,IAAAA,EAAS,YAAc,iBACvBA,EAAS,cAAc,KACvBA,EAAS,aAAa,cAAc,OAAO,GAE3ClT,EAAI,YAAYlC,CAAG,GACnBkC,EAAI,YAAY4O,CAAK,GACrB5O,EAAI,YAAYvN,CAAK,GACrBuN,EAAI,YAAYkT,CAAQ,GAExBhhB,EAAU,aAAa8N,GAAK9N,EAAU,UAAU,GAEhD0c,EAAM,iBAAiB,SAAS,MAAM;AACpC,WAAK,UAAUA,EAAM,MAAM,KAAA,GAC3B,KAAK,OAAA;AAAA,IACP,CAAC,GACDA,EAAM,iBAAiB,WAAW,CAAC3gB,MAAM;AACvC,MAAIA,EAAE,QAAQ,YAAU,KAAK,MAAA;AAAA,IAC/B,CAAC,GACDilB,EAAS,iBAAiB,SAAS,MAAM,KAAK,OAAO,GAErD,KAAK,OAASlT,GACd,KAAK,SAAS4O,GACd,KAAK,SAASnc;AAAA,EAChB;AAAA,EAEA,OAAa;AACX,IAAK,KAAK,SACV,KAAK,KAAK,SAAS,IACnB,KAAK,OAAQ,MAAA,GACb,KAAK,OAAQ,OAAA;AAAA,EACf;AAAA,EAEA,QAAc;AACZ,IAAK,KAAK,SACV,KAAK,KAAK,SAAW,IACrB,KAAK,UAAgB,IACrB,KAAK,OAAQ,QAAQ,IACjB,KAAK,WAAQ,KAAK,OAAO,cAAc,KAC3C,KAAK,OAAA;AAAA,EACP;AAAA,EAEQ,SAAe;A1BhFlB,QAAApE,GAAAsC;A0BiFH,UAAMjC,IAAS,KAAK,GAAG,QAAA,GACjB8C,IAAS,KAAK,GAAG,aAAA,EAAe,cAAc,IAAI,CAAAiC,MAAKA,EAAE,KAAK;AACpE,IAAA/E,EAAK,cAAc,KAAK,SAAS8C,CAAM,GACvC9C,EAAK,YAAY,KAAK,GAAG,WAAA,CAAY;AACrC,UAAM4P,IAAI5P,EAAK;AACf,KAAAL,IAAA,KAAK,GAAG,YAAR,QAAAA,EAAiB,aAAaiQ,KAC9B3N,IAAA,KAAK,GAAG,oBAAR,QAAAA,EAAyB,aAAa2N,IAClC,KAAK,WAAQ,KAAK,OAAO,cAAc,KAAK,UAAU,GAAGA,CAAC,MAAM,KACpE,KAAK,GAAG,SAAA;AAAA,EACV;AACF;ACxEA,SAAS6U,GAAYtkB,GAAgC;AACnD,SAAOA,KAAQA,EAAK,aAAa;AACnC;AAGO,SAASukB,GACd1kB,GACA8C,GACA6hB,IAA4B,CAAA,GAC5BC,IAA4B,oBAAI,IAAA,GAChCC,GACe;AACf,SAAK/hB,EAAO,SACLgiB,GAAe9kB,GAAM8C,GAAQ,GAAG6hB,GAAaC,GAAc,IAAIC,CAAW,IADtD,CAAA;AAE7B;AAEA,SAASC,GACP9kB,GACA8C,GACA+B,GACA8f,GACAC,GACAG,GACAF,GACe;AACf,QAAM3jB,IAAQ4B,EAAO+B,CAAK,GACpBmgB,wBAAU,IAAA;AAEhB,aAAW/kB,KAAOD,GAAM;AACtB,UAAM4B,IAAM3B,EAAIiB,CAAK;AACrB,IAAK8jB,EAAI,IAAIpjB,CAAG,KAAGojB,EAAI,IAAIpjB,GAAK,EAAE,GAClCojB,EAAI,IAAIpjB,CAAG,EAAG,KAAK3B,CAAG;AAAA,EACxB;AAEA,QAAM6H,IAAwB,CAAA;AAC9B,aAAW,CAAC3G,GAAOgE,CAAI,KAAK6f,GAAK;AAC/B,UAAM5P,IAAW,GAAG2P,CAAS,KAAK7jB,CAAK,IAAIC,CAAK,IAC1CsX,IAAWmM,EAAa,IAAIxP,CAAQ;AAE1C,QAAI6P;AACJ,IAAIpgB,IAAQ/B,EAAO,SAAS,IAC1BmiB,IAAWH,GAAe3f,GAAMrC,GAAQ+B,IAAQ,GAAG8f,GAAaC,GAAcxP,GAAUyP,CAAW,IAEnGI,IAAW9f;AAGb,UAAM,EAAE,SAAA+f,GAAS,YAAAC,EAAA,IAAeC,GAAajgB,GAAMwf,CAAW,GACxDU,IAASC,GAAYngB,GAAM0f,CAAW;AAE5C,IAAA/c,EAAO,KAAK;AAAA,MACV,UAAU;AAAA,MACV,aAAa5G;AAAA,MACb,aAAaC;AAAA,MACb,aAAaA,KAAS,OAAO,SAAS,OAAOA,CAAK;AAAA,MAClD,QAAQ0D;AAAA,MACR,WAAW4T;AAAA,MACX,aAAatT,EAAK;AAAA,MAClB,UAAU+f;AAAA,MACV,aAAaC;AAAA,MACb,SAASE;AAAA,MACT,UAAAJ;AAAA,IAAA,CACc;AAAA,EAClB;AACA,SAAOnd;AACT;AAGA,SAASsd,GACPplB,GACAulB,GACsE;AACtE,QAAML,IAAqC,CAAA,GACrCC,IAAqC,CAAA;AAE3C,aAAW1b,KAAO8b,GAAM;AACtB,UAAMC,IAAOxlB,EACV,IAAI,CAAAI,MAAKA,EAAEqJ,EAAI,KAAK,CAAC,EACrB,OAAO,OAAKrG,KAAM,QAA2BA,MAAM,EAAE;AAExD,QAAI0E,IAA2B;AAC/B,UAAMqb,IAAQ1Z,EAAI,GAAc,YAAA;AAEhC,QAAI0Z,MAAS;AACX,MAAArb,IAAS0d,EAAK,SAAS,IAAIve,EAAU,IAAIue,EAAK,IAAI,MAAM,CAAC,IAAI;AAAA,aACpDrC,MAAS;AAClB,MAAArb,IAAS0d,EAAK,SAAS,IACnBve,EAAU,IAAIue,EAAK,IAAI,MAAM,CAAC,EAAE,IAAIve,EAAU,KAAK,OAAOue,EAAK,MAAM,CAAC,CAAC,IACvE;AAAA,aACKrC,MAAS,SAAS;AAC3B,MAAA+B,EAAQzb,EAAI,KAAK,IAAOzJ,EAAK,QAC7BmlB,EAAW1b,EAAI,KAAK,IAAIzJ,EAAK,OAAO,eAAe,OAAO;AAC1D;AAAA,IACF,MAAA,CAAWmjB,MAAS,QAClBrb,IAAS0d,EAAK,SAAS,IAAIve,EAAU,IAAIue,EAAK,IAAI,MAAM,CAAC,IAAI,OACpDrC,MAAS,UAClBrb,IAAS0d,EAAK,SAAS,IAAIve,EAAU,IAAIue,EAAK,IAAI,MAAM,CAAC,IAAI;AAG/D,QAAI,CAAC1d,GAAQ;AAAE,MAAAod,EAAQzb,EAAI,KAAK,IAAI,MAAM0b,EAAW1b,EAAI,KAAK,IAAI;AAAI;AAAA,IAAU;AAEhF,UAAM4Z,IAASvb,EAAO,SAAA;AACtB,IAAAod,EAAQzb,EAAI,KAAK,IAAO4Z,GACxB8B,EAAW1b,EAAI,KAAK,IAAIgc,GAAQpC,GAAQ5Z,EAAI,MAAM;AAAA,EACpD;AAEA,SAAO,EAAE,SAAAyb,GAAS,YAAAC,EAAA;AACpB;AAGA,SAASG,GACPngB,GACA0f,GACoD;AACpD,MAAI,CAACA,EAAa,QAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,EAAA;AACzD,MAAIzjB,IAAQ,GAAGC,IAAS,GAAGC,IAAU;AACrC,aAAWlB,KAAK+E,GAAM;AACpB,UAAMhD,IAAI0iB,EAAYzkB,CAAC;AACvB,IAAI+B,MAAM,UAAgBf,MACjBe,MAAM,WAAWd,MACjBc,MAAM,aAAWb;AAAA,EAC5B;AACA,SAAO,EAAE,OAAAF,GAAO,QAAAC,GAAQ,SAAAC,EAAA;AAC1B;AASO,SAASmkB,GAAQtkB,GAAe0U,GAAsB;AAC3D,MAAyBA,KAAQ;AAC/B,WAAO1U,IAAQ,MAAM,IACjBA,EAAM,eAAe,OAAO,IAC5B,WAAWA,EAAM,QAAQ,CAAC,CAAC,EAAE,eAAe,SAAS;AAAA,MACnD,uBAAuB;AAAA,MAAG,uBAAuB;AAAA,IAAA,CAClD;AAEP,QAAMuhB,IAAW7M,EAAI,SAAS,GAAG,KAAKA,EAAI,SAAS,GAAG,GAChD8M,IAAW9M,EAAI,MAAM,UAAU,GAC/B9N,IAAK4a,IAAU,SAASA,EAAQ,CAAC,GAAI,EAAE,IAAI,QAAQ,KAAK9M,CAAG,IAAI,SAASA,GAAK,EAAE,IAAI,GAEnF+M,IAAQ,KAAK,IAAIzhB,CAAK,EAAE,QAAQ4G,CAAE,GAClC,CAACO,IAAU,KAAKua,CAAO,IAAID,EAAM,MAAM,GAAG,GAC1CE,IAASJ,IACXpa,EAAQ,QAAQ,yBAAyB,GAAG,IAC5CA,GACER,IAAS+a,MAAY,SAAY,GAAGC,CAAM,IAAID,CAAO,KAAKC;AAChE,SAAO3hB,IAAQ,IAAI,IAAI2G,CAAM,KAAKA;AACpC;AAMO,SAAS4d,GAAiBC,GAA+C;AAC9E,QAAM7d,IAAiC,CAAA;AACvC,aAAWqN,KAAKwQ;AAEd,QADA7d,EAAO,KAAKqN,CAAC,GACTA,EAAE;AACJ,iBAAWyQ,KAASzQ,EAAE;AACpB,QAAIsP,GAASmB,CAAK,IAChB9d,EAAO,KAAK,GAAG4d,GAAc,CAACE,CAAoB,CAAC,CAAC,IAEpD9d,EAAO,KAAK8d,CAAK;AAKzB,SAAO9d;AACT;AAgBO,SAAS+d,GAAkBF,GAAuBZ,IAAY,IAAc;AACjF,QAAMe,IAAiB,CAAA;AACvB,aAAW3Q,KAAKwQ,GAAQ;AACtB,UAAM/jB,IAAM,GAAGmjB,CAAS,KAAK5P,EAAE,WAAW,IAAIA,EAAE,WAAW;AAC3D,IAAA2Q,EAAK,KAAKlkB,CAAG;AACb,UAAMmkB,IAAS5Q,EAAE,SAAS,OAAO,CAACpQ,MAAwB0f,GAAS1f,CAAC,CAAC;AACrE,IAAIghB,EAAO,UAAQD,EAAK,KAAK,GAAGD,GAAeE,GAAQnkB,CAAG,CAAC;AAAA,EAC7D;AACA,SAAOkkB;AACT;AC/LO,SAASE,GACdhmB,GACAgN,GACA4X,IAAyB,oBAAI,OACd;AACf,QAAM,EAAE,SAAA7kB,GAAS,eAAAkmB,GAAe,cAAAC,IAAe,OAAUlZ,GAEnDmZ,wBAAc,IAAA,GACdC,IAAuB,CAAA;AAG7B,aAAWnmB,KAAOD,GAAM;AACtB,UAAME,IAAKD,EAAIF,CAAO,GAChBsmB,IAAoB;AAAA,MACxB,SAAS;AAAA,MACT,SAASnmB;AAAA,MACT,eAAeD,EAAIgmB,CAAa;AAAA,MAChC,QAAQ;AAAA,MACR,WAAWC,KAAgBtB,EAAa,IAAI1kB,CAAE;AAAA,MAC9C,cAAc;AAAA,MACd,aAAa;AAAA,MACb,cAAc;AAAA,MACd,kBAAkB,CAAA;AAAA,MAClB,MAAMD;AAAA,MACN,UAAU,CAAA;AAAA,IAAC;AAEb,IAAAkmB,EAAQ,IAAIjmB,GAAImmB,CAAI;AAAA,EACtB;AAGA,aAAWA,KAAQF,EAAQ,UAAU;AACnC,UAAMG,IAAMD,EAAK;AAEjB,QADeC,KAAO,QAAQA,MAAQ,MAAM,CAACH,EAAQ,IAAIG,CAAG;AAE1D,MAAAF,EAAM,KAAKC,CAAI;AAAA,SACV;AACL,YAAME,IAASJ,EAAQ,IAAIG,CAAG;AAC9B,MAAAC,EAAO,SAAS,KAAKF,CAAI,GACzBE,EAAO,eAAe;AAAA,IACxB;AAAA,EACF;AAGA,WAASC,EAAYC,GAAsB5hB,GAAqB;AAC9D,eAAW+K,KAAK6W;AACd,MAAA7W,EAAE,SAAS/K,GACX+K,EAAE,cAAc8W,GAAkB9W,CAAC,GACnC4W,EAAY5W,EAAE,UAAU/K,IAAQ,CAAC;AAAA,EAErC;AACA,EAAA2hB,EAAYJ,GAAO,CAAC;AAIpB,WAASO,EAAeF,GAAsBG,GAAqC;AACjF,aAAStmB,IAAI,GAAGA,IAAImmB,EAAM,QAAQnmB,KAAK;AACrC,YAAM+lB,IAAOI,EAAMnmB,CAAC,GACdumB,IAASvmB,MAAMmmB,EAAM,SAAS;AACpC,MAAAJ,EAAK,eAAkBQ,GACvBR,EAAK,mBAAmBO,GACpBP,EAAK,SAAS,SAAS,KAEzBM,EAAeN,EAAK,UAAU,CAAC,GAAGO,GAAoB,CAACC,CAAM,CAAC;AAAA,IAElE;AAAA,EACF;AACA,SAAAF,EAAeP,GAAO,EAAE,GAEjBA;AACT;AAEA,SAASM,GAAqBL,GAA2B;AACvD,MAAItiB,IAAQsiB,EAAK,SAAS;AAC1B,aAAWT,KAASS,EAAK,SAAU,CAAAtiB,KAAS2iB,GAAkBd,CAAK;AACnE,SAAO7hB;AACT;AAMO,SAAS+iB,GAAeL,GAAqC;AAClE,QAAM3e,IAAwB,CAAA;AAC9B,aAAWue,KAAQI;AACjB,IAAA3e,EAAO,KAAKue,CAAI,GACZA,EAAK,aAAaA,EAAK,SAAS,SAAS,KAC3Cve,EAAO,KAAK,GAAGgf,GAAYT,EAAK,QAAQ,CAAC;AAG7C,SAAOve;AACT;AAGO,SAASif,GACdnC,GACAoC,GACM;AACN,EAAIpC,EAAa,IAAIoC,CAAM,IACzBpC,EAAa,OAAOoC,CAAM,IAE1BpC,EAAa,IAAIoC,CAAM;AAE3B;AAGO,SAASC,GAAqBR,GAA6B;AAChE,QAAMS,IAAa,CAAA;AACnB,aAAWtX,KAAK6W;AACd,IAAAS,EAAI,KAAKtX,EAAE,OAAO,GACdA,EAAE,SAAS,UAAQsX,EAAI,KAAK,GAAGD,GAAkBrX,EAAE,QAAQ,CAAC;AAElE,SAAOsX;AACT;AC3HO,MAAMC,GAAsD;AAAA,EAWjE,YAAYrM,GAAwB;AAVpC,SAAQ,eAAyB,CAAA,GACjC,KAAQ,yCAAsC,IAAA,GAC9C,KAAQ,iBAAyC,CAAA,GACjD,KAAQ,eAAe,IACvB,KAAQ,aAA4B,CAAA,GACpC,KAAQ,gBAA+B,CAAA,GACvC,KAAQ,wCAAkC,IAAA,GAC1C,KAAQ,cAAc,IAIpB,KAAK,KAAKA;AAAA,EACZ;AAAA;AAAA,EAGA,IAAI,cAAuB;AAAE,WAAO,KAAK;AAAA,EAAc;AAAA,EACvD,IAAI,aAAsB;AAAE,WAAO,KAAK;AAAA,EAAa;AAAA,EACrD,IAAI,gBAAwC;AAAE,WAAO,KAAK;AAAA,EAAgB;AAAA,EAC1E,IAAI,eAA8B;AAAE,WAAO,KAAK;AAAA,EAAe;AAAA;AAAA,EAG/D,QAAQhY,GAAwB;AAC9B,SAAK,eAAeA,GACpB,KAAK,mBAAmB,MAAA,GACxB,KAAK,eAAeA,EAAO,SAAS,GACpC,KAAK,cAAA;AAAA,EACP;AAAA,EAEA,aAAmB;A7B1Cd,QAAAnD;A6B2CH,SAAK,eAAe,CAAA,GACpB,KAAK,mBAAmB,MAAA,GACxB,KAAK,eAAe,IACpB,KAAK,iBAAiB,CAAA;AACtB,UAAMiQ,IAAI,KAAK,GAAG,QAAA,EAAU;AAC5B,KAAAjQ,IAAA,KAAK,GAAG,YAAR,QAAAA,EAAiB,aAAaiQ,IAC9B,KAAK,GAAG,SAAA;AAAA,EACV;AAAA,EAEA,YAAkB;AAChB,QAAI,CAAC,KAAK,aAAc;AACxB,UAAM+V,IAASjB,GAAY,KAAK,GAAG,WAAW,KAAK,cAAc,KAAK,iBAAiB;AACvF,IAAAmB,GAAeF,CAAM,EAAE,QAAQ,CAAAjkB,MAAK,KAAK,mBAAmB,IAAIA,CAAC,CAAC,GAClE,KAAK,cAAA;AAAA,EACP;AAAA,EAEA,cAAoB;AAClB,SAAK,mBAAmB,MAAA,GACpB,KAAK,gBAAc,KAAK,cAAA;AAAA,EAC9B;AAAA,EAEA,kBAAkB0T,GAAwB;AACxC,IAAI,KAAK,mBAAmB,IAAIA,CAAQ,IACtC,KAAK,mBAAmB,OAAOA,CAAQ,IAEvC,KAAK,mBAAmB,IAAIA,CAAQ,GAEtC,KAAK,cAAA;AAAA,EACP;AAAA,EAEA,gBAAsB;A7BzEjB,QAAAzV;A6B0EH,UAAMK,IAAO,KAAK,GAAG,QAAA,GACfonB,IAAO,KAAK,GAAG,aAAA,GACfC,IAAW,CAACpnB,MAAqB;AACrC,YAAMO,IAAMR,EAAK,QAAQC,CAAG;AAC5B,aAAOO,KAAO,IAAI4mB,EAAG,YAAY5mB,CAAG,IAAI;AAAA,IAC1C,GACMmlB,IAASjB,GAAY1kB,GAAM,KAAK,cAAc,KAAK,gBAAA,GAAmB,KAAK,oBAAoBqnB,CAAQ;AAC7G,SAAK,iBAAiB3B,GAAcC,CAAM,IAC1ChmB,IAAA,KAAK,GAAG,MAAA,MAAR,QAAAA,EAAiB,aAAa,KAAK,eAAe,SAClD,KAAK,GAAG,aAAa,KAAK,eAAe,MAAM;AAAA,EACjD;AAAA;AAAA,EAGA,aAAmB;AACjB,SAAK,cAAe,IACpB,KAAK,eAAe;AACpB,UAAMqN,IAAO,KAAK,GAAG,WAAA;AACrB,QAAIA,EAAK,cAAc;AACrB,YAAMsa,IAAOtB,GAAU,KAAK,GAAG,WAAW;AAAA,QACxC,SAAShZ,EAAK;AAAA,QACd,eAAeA,EAAK;AAAA,MAAA,CACrB;AACD,MAAAia,GAAkBK,CAAI,EAAE,QAAQ,CAAApnB,MAAM,KAAK,kBAAkB,IAAIA,CAAE,CAAC;AAAA,IACtE;AACA,SAAK,YAAA;AAAA,EACP;AAAA,EAEA,cAAoB;A7BrGf,QAAAP;A6BsGH,SAAK,cAAc,IACnB,KAAK,aAAc,CAAA,GACnB,KAAK,gBAAgB,CAAA,GACrB,KAAK,kBAAkB,MAAA;AACvB,UAAMiQ,IAAI,KAAK,GAAG,QAAA,EAAU;AAC5B,KAAAjQ,IAAA,KAAK,GAAG,YAAR,QAAAA,EAAiB,aAAaiQ,IAC9B,KAAK,GAAG,SAAA;AAAA,EACV;AAAA,EAEA,YAAYsX,GAAkBK,IAAO,IAAY;AAC/C,UAAM/e,IAAM,MAAM,QAAQ0e,CAAG,IAAIA,IAAM,CAACA,CAAG;AAC3C,eAAWhnB,KAAMsI;AACf,MAAI+e,IAAM,KAAK,kBAAkB,IAAIrnB,CAAE,IAC7B,KAAK,kBAAkB,OAAOA,CAAE;AAE5C,IAAI,KAAK,eAAa,KAAK,YAAA;AAAA,EAC7B;AAAA,EAEA,iBAAuB;AACrB,IAAK,KAAK,gBACV+mB,GAAkB,KAAK,UAAU,EAAE,QAAQ,OAAM,KAAK,kBAAkB,IAAI/mB,CAAE,CAAC,GAC/E,KAAK,YAAA;AAAA,EACP;AAAA,EAEA,mBAAyB;AACvB,IAAK,KAAK,gBACV,KAAK,kBAAkB,MAAA,GACvB,KAAK,YAAA;AAAA,EACP;AAAA,EAEA,iBAAiB8mB,GAAmB;AAClC,IAAAD,GAAe,KAAK,mBAAmBC,CAAM,GAC7C,KAAK,YAAA;AAAA,EACP;AAAA,EAEA,cAAoB;A7BzIf,QAAArnB;A6B0IH,UAAMqN,IAAO,KAAK,GAAG,WAAA;AACrB,SAAK,aAAagZ,GAAU,KAAK,GAAG,WAAW;AAAA,MAC7C,SAAShZ,EAAK;AAAA,MACd,eAAeA,EAAK;AAAA,MACpB,cAAcA,EAAK;AAAA,IAAA,GAClB,KAAK,iBAAiB,GACzB,KAAK,gBAAgB8Z,GAAY,KAAK,UAAU,IAChDnnB,IAAA,KAAK,GAAG,MAAA,MAAR,QAAAA,EAAiB,aAAa,KAAK,cAAc,SACjD,KAAK,GAAG,aAAa,KAAK,cAAc,MAAM;AAAA,EAChD;AAAA;AAAA,EAGQ,kBAAgC;AACtC,UAAMwC,IAAI,KAAK,GAAG,WAAA,EAAa;AAC/B,QAAI,CAACA,EAAG,QAAO,CAAA;AACf,QAAIA,EAAE,QAAQA,EAAE,KAAK,SAAS;AAC5B,aAAOA,EAAE,OAAO;AAAA,QAAQ,CAACgB,MACvBhB,EAAE,KAAM,IAAI,CAAC/B,OAAY,EAAE,OAAO+C,GAAG,IAAI/C,EAAE,IAAI,QAAQA,EAAE,SAAS;AAAA,MAAA;AAGtE,UAAMonB,IAAM,MAAM,QAAQrlB,EAAE,GAAG,IAAIA,EAAE,MAAOA,EAAE,MAAM,CAACA,EAAE,GAAG,IAAI,CAAC,KAAK;AACpE,WAAOA,EAAE,OAAO,IAAI,CAACgB,OAAe,EAAE,OAAOA,GAAG,IAAIqkB,EAAI,CAAC,KAAK,OAAO,QAASrlB,EAAU,SAAS;AAAA,EACnG;AACF;ACrJO,MAAMslB,GAAuD;AAAA,EAKlE,YAAY3M,GAAyB;AAJrC,SAAQ,YAAwB,CAAA,GAChC,KAAQ,WAAyC,CAAA,GAI/C,KAAK,KAAKA;AAAA,EACZ;AAAA;AAAA,EAGA,IAAI,WAAuB;AAAE,WAAO,KAAK;AAAA,EAAW;AAAA,EACpD,IAAI,UAAwC;AAAE,WAAO,KAAK;AAAA,EAAU;AAAA;AAAA,EAGpE,gBAAgB5Z,GAAewmB,GAAyB;A9B1BnD,QAAA/nB;A8B2BH,UAAMqN,IAAO,KAAK,GAAG,WAAA;AACrB,QAAI,CAACA,EAAK,SAAU;AACpB,UAAMxM,IAAM,KAAK,UAAU,UAAU,CAAA2B,MAAKA,EAAE,UAAUjB,CAAK;AAC3D,QAAIV,KAAO,GAAG;AACZ,YAAM4Z,IAAM,KAAK,UAAU5Z,CAAG;AAC9B,MAAI4Z,EAAI,QAAQ,QACdA,EAAI,MAAM,SAEV,KAAK,UAAU,OAAO5Z,GAAK,CAAC;AAAA,IAEhC;AACE,OAAI,CAACknB,KAAY,CAAC1a,EAAK,eAAW,KAAK,YAAY,CAAA,IACnD,KAAK,UAAU,KAAK,EAAE,OAAA9L,GAAO,KAAK,OAAO;AAE3C,SAAK,GAAG,QAAA,EAAU,UAAU,KAAK,SAAS,GAC1C,KAAK,GAAG,aAAA,GACR,KAAK,GAAG,SAAA;AACR,UAAMymB,IAAa,KAAK,UAAU,KAAK,CAAAxlB,MAAKA,EAAE,UAAUjB,CAAK,GACvD0mB,IAAWD,IAAcA,EAAW,QAAQ,QAAQ,SAAS,SAAU;AAC7E,SAAK,GAAG,SAAS,GAAGzmB,CAAK,IAAI0mB,CAAQ,KAAK,GAC1C,KAAK,GAAG,KAAK,cAAc,EAAE,UAAU,KAAK,WAAW,IACvDjoB,IAAAqN,EAAK,iBAAL,QAAArN,EAAA,KAAAqN,GAAoB,EAAE,OAAA9L,GAAO,MAAKymB,KAAA,gBAAAA,EAAY,QAAO,OAAO,UAAU,KAAK,UAAA;AAAA,EAC7E;AAAA,EAEA,KAAKE,GAAkCtlB,IAAsB,OAAa;AACxE,QAAI,MAAM,QAAQslB,CAAW;AAC3B,WAAK,YAAYA;AAAA,SACZ;AACL,YAAMvnB,IAAI,KAAK,UAAU,UAAU,CAAA6B,MAAKA,EAAE,UAAU0lB,CAAW;AAC/D,MAAIvnB,KAAK,IAAG,KAAK,UAAUA,CAAC,EAAG,MAAMiC,SAC3B,YAAY,CAAC,EAAE,OAAOslB,GAAa,KAAAtlB,GAAK,GAC7C,KAAK,GAAG,WAAA,EAAa,cAAW,KAAK,YAAY,KAAK,UAAU,MAAM,EAAE;AAAA,IAC/E;AACA,SAAK,GAAG,QAAA,EAAU,UAAU,KAAK,SAAS,GAC1C,KAAK,GAAG,aAAA,GACR,KAAK,GAAG,SAAA,GACR,KAAK,GAAG,KAAK,cAAc,EAAE,UAAU,KAAK,WAAW;AAAA,EACzD;AAAA,EAEA,YAAkB;AAChB,SAAK,YAAY,CAAA,GACjB,KAAK,GAAG,UAAU,UAAU,CAAA,CAAE,GAC9B,KAAK,GAAG,aAAA,GACR,KAAK,GAAG,SAAA;AAAA,EACV;AAAA,EAEA,SAASR,GAA4B;AACnC,SAAK,YAAY,CAAC,GAAGA,CAAQ,GAC7B,KAAK,GAAG,QAAA,EAAU,UAAU,KAAK,SAAS;AAAA,EAC5C;AAAA,EAEA,eAA2B;AAAE,WAAO,CAAC,GAAG,KAAK,SAAS;AAAA,EAAG;AAAA;AAAA,EAGzD,UAAUb,GAAe4mB,GAAiC;A9BjFrD,QAAAnoB,GAAAsC;A8BkFH,SAAK,SAASf,CAAK,IAAI4mB,GACvB,KAAK,aAAA,GACL,KAAK,GAAG,aAAA,GACR,KAAK,GAAG,SAAA,GACR,KAAK,GAAG,KAAK,gBAAgB,EAAE,OAAA5mB,GAAO,aAAA4mB,GAAa,YAAY,KAAK,UAAU,IAC9E7lB,KAAAtC,IAAA,KAAK,GAAG,WAAA,GAAa,mBAArB,QAAAsC,EAAA,KAAAtC,GAAsC,EAAE,OAAAuB,GAAO,aAAA4mB,GAAa,YAAY,KAAK;EAC/E;AAAA,EAEA,YAAY5mB,GAAsB;AAChC,IAAIA,IAAO,OAAO,KAAK,SAASA,CAAK,IAChC,KAAK,WAAW,CAAA,GACrB,KAAK,aAAA,GACL,KAAK,GAAG,aAAA,GACR,KAAK,GAAG,SAAA;AAAA,EACV;AAAA,EAEA,iBAA+C;AAAE,WAAO,EAAE,GAAG,KAAK,SAAA;AAAA,EAAY;AAAA,EAE9E,cAAcK,GAA2C;AACvD,SAAK,WAAW,EAAE,GAAGA,EAAA,GACrB,KAAK,aAAA;AAAA,EACP;AAAA,EAEA,eAAqB;A9BzGhB,QAAA5B,GAAAsC;A8B0GH,UAAMjC,IAAO,KAAK,GAAG,QAAA;AACrB,IAAAA,EAAK,cAAc,KAAK,GAAG,cAAA,GAAiB,KAAK,GAAG,aAAA,EAAe,cAAc,IAAI,CAAA+E,MAAKA,EAAE,KAAK,CAAC,GAClG/E,EAAK,YAAY,KAAK,QAAQ;AAC9B,UAAM4P,IAAI5P,EAAK;AACf,KAAAL,IAAA,KAAK,GAAG,YAAR,QAAAA,EAAiB,aAAaiQ,KAC9B3N,IAAA,KAAK,GAAG,oBAAR,QAAAA,EAAyB,aAAa2N;AAAA,EACxC;AACF;ACpGO,MAAMmY,GAAsD;AAAA,EAGjE,YAAYjN,GAAwB;AAClC,SAAK,KAAKA;AAAA,EACZ;AAAA,EAEA,gBAAgBna,GAAkB+D,GAAkBnF,GAAqB;A/BpBpE,QAAAI,GAAAsC,GAAAyL,GAAAc,GAAAC,GAAAuZ,GAAAC;A+BqBH,UAAMjb,IAAO,KAAK,GAAG,WAAA,GACfkX,IAAS,KAAK,GAAG,UAAA,GACjBJ,IAAU,KAAK,GAAG,WAAA;AAExB,IAAI9W,EAAK,cAAc,YAAYA,EAAK,cAAc,QACpDkX,EAAO,aAAavjB,CAAQ,IACnBqM,EAAK,cAAc,eACxBzN,EAAE,WAAWA,EAAE,UACjB2kB,EAAO,aAAavjB,CAAQ,IAE5BujB,EAAO,aAAavjB,CAAQ;AAIhC,UAAMV,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcU,CAAQ,GAC9CmE,IAAM,KAAK,GAAG,aAAA,EAAe,cAAcJ,CAAQ;AAEzD,QAAIzE,KAAO6E,GAAK;AACd,YAAMojB,IAAcpjB,EAAI,aAAa,OAAUA,EAAI,aAAa,UAAakI,EAAK;AAClF,UAAI2N,GAAY7V,CAAG,KAAKojB,GAAa;AACnC,cAAM3J,IAAUte,EAAY6E,EAAI,KAAK;AACrC,aAAK,GAAG,UAAUnE,GAAUmE,EAAI,OAA4B,CAACyZ,CAAM;AAAA,MACrE;AAEA,UAAKzZ,EAAI,SAAoB,SAAS;AACpC,cAAMqjB,IAAOrjB,EAAY;AACzB,mBAAWC,KAAK,KAAK,GAAG,aAAA,EAAe;AACrC,UAAKA,EAAE,SAAoB,WAAWA,EAAE,UAAUD,EAAI,UACjD,CAACqjB,KAAQpjB,EAAU,UAAUojB,MAChC,KAAK,GAAG,UAAU,WAAWxnB,GAAUoE,EAAE,OAAO,EAAK;AAGzD,aAAK,GAAG,UAAUpE,GAAUmE,EAAI,OAAc,EAAI;AAAA,MACpD;AAEA,UAAIsjB,IAAanoB,EAAY6E,EAAI,KAAK;AACtC,UAAIsjB,MAAc,UAActjB,EAAY;AAC1C,YAAI;AACF,gBAAM4G,IAAQ5G,EAAY,oBAAoB,IACxCgD,IAASY,GAAiB5D,EAAY,SAAS7E,GAAYyL,CAAI;AACrE,UAAA0c,IAAYtgB,aAAkBb,IACxBnC,EAAY,aAAa,OAAOgD,EAAO,QAAShD,EAAY,SAAS,IAAIgD,EAAO,SAAA,IAClF,OAAOA,CAAM;AAAA,QACnB,QAAQ;AAAA,QAAC;AAEX,YAAMoT,IAAM;AAAA,QACV,MAAM;AAAA,QAAa,UAAAva;AAAA,QAAU,aAAa+D;AAAA,QAC1C,OAAOI,EAAI;AAAA,QAAO,OAAOsjB;AAAA,QAAW,KAAAnoB;AAAA,QAAK,QAAQ6E;AAAA,QACjD,QAAQvF,EAAE;AAAA,QAAuB,eAAeA;AAAA,MAAA;AAElD,WAAK,GAAG,KAAK,aAAa2b,CAAG,IAC7Bvb,IAAAqN,EAAK,gBAAL,QAAArN,EAAA,KAAAqN,GAAmBkO;AAEnB,YAAMmN,IAAS,EAAE,MAAM,YAAY,UAAA1nB,GAAU,KAAAV,GAAK,QAAQV,EAAE,QAAuB,eAAeA,EAAA;AAClG,WAAK,GAAG,KAAK,YAAY8oB,CAAM,IAC/BpmB,IAAA+K,EAAK,eAAL,QAAA/K,EAAA,KAAA+K,GAAkBqb;AAElB,YAAMC,IAAexjB,EAAI,SAAoB;AAG7C,MAAI,EAFmBgf,EAAQ,gBAAgB,UAC7CpW,IAAAoW,EAAQ,aAAR,gBAAApW,EAAkB,QAAO/M,OAAY6N,IAAAsV,EAAQ,aAAR,gBAAAtV,EAAkB,QAAO9J,OACxCsI,EAAK,aAAa,WAAWsb,MAAgB,CAAC3N,GAAY7V,CAAG,KACnFgf,EAAQ,UAAUnjB,GAAU+D,GAAUnF,CAAC;AAAA,IAE3C;AAEA,IAAIukB,EAAQ,kBAAgBrV,IAAAqV,EAAQ,aAAR,gBAAArV,EAAkB,QAAO9N,OAAYqnB,IAAAlE,EAAQ,aAAR,gBAAAkE,EAAkB,QAAOtjB,MAI1F,KAAK,GAAG,SAAA,GACR,KAAK,GAAG,KAAK,mBAAmB;AAAA,MAC9B,MAAMwf,EAAO,cAAA;AAAA,MACb,YAAY,CAAC,GAAGA,EAAO,YAAY;AAAA,IAAA,CACpC,IACD+D,IAAAjb,EAAK,sBAAL,QAAAib,EAAA,KAAAjb,GAAyB,EAAE,MAAMkX,EAAO,iBAAiB,YAAY,CAAC,GAAGA,EAAO,YAAY,GAAG,OAAO,CAAA;EACxG;AAAA,EAEA,mBAAmBvjB,GAAkB+D,GAAkBnF,GAAqB;A/BlGvE,QAAAI,GAAAsC;A+BmGH,UAAMhC,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcU,CAAQ,GAC9CmE,IAAM,KAAK,GAAG,aAAA,EAAe,cAAcJ,CAAQ;AACzD,QAAI,CAACzE,KAAO,CAAC6E,EAAK;AAElB,UAAMkI,IAAO,KAAK,GAAG,WAAA,GACfkO,IAAM;AAAA,MACV,MAAM;AAAA,MAAgB,UAAAva;AAAA,MAAU,aAAa+D;AAAA,MAC7C,OAAOI,EAAI;AAAA,MAAO,OAAO7E,EAAI6E,EAAI,KAAK;AAAA,MAAG,KAAA7E;AAAA,MAAK,QAAQ6E;AAAA,MACtD,QAAQvF,EAAE;AAAA,MAAuB,eAAeA;AAAA,IAAA;AAElD,SAAK,GAAG,KAAK,gBAAgB2b,CAAG,IAChCvb,IAAAqN,EAAK,mBAAL,QAAArN,EAAA,KAAAqN,GAAsBkO;AAEtB,UAAMmN,IAAS,EAAE,MAAM,eAAe,UAAA1nB,GAAU,KAAAV,GAAK,QAAQV,EAAE,QAAuB,eAAeA,EAAA;AACrG,SAAK,GAAG,KAAK,eAAe8oB,CAAM,IAClCpmB,IAAA+K,EAAK,kBAAL,QAAA/K,EAAA,KAAA+K,GAAqBqb,IAEjBrb,EAAK,aAAa,cAAY,KAAK,GAAG,aAAa,UAAUrM,GAAU+D,GAAUnF,CAAC;AAAA,EACxF;AAAA,EAEA,oBAAoB8T,GAAYsC,GAAYpW,GAAqB;A/BvH5D,QAAAI,GAAAsC;A+BwHH,UAAMhC,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcoT,CAAE,GACxCvO,IAAM,KAAK,GAAG,aAAA,EAAe,cAAc6Q,CAAE;AACnD,QAAI,CAAC1V,KAAO,CAAC6E,EAAK;AAClB,UAAMkI,IAAO,KAAK,GAAG,WAAA,GACfub,IAAU,EAAE,MAAM,iBAAiB,UAAUlV,GAAI,aAAasC,GAAI,OAAO7Q,EAAI,OAAO,OAAQ7E,EAAY6E,EAAI,KAAK,GAAG,KAAA7E,GAAK,QAAQ6E,GAAY,QAAQvF,EAAE,QAAuB,eAAeA,EAAA;AACnM,SAAK,GAAG,KAAK,iBAAiBgpB,CAAO,IACrC5oB,IAAAqN,EAAK,oBAAL,QAAArN,EAAA,KAAAqN,GAAuBub;AACvB,UAAMF,IAAS,EAAE,MAAM,gBAAgB,UAAUhV,GAAI,KAAApT,GAAK,QAAQV,EAAE,QAAuB,eAAeA,EAAA;AAC1G,SAAK,GAAG,KAAK,gBAAgB8oB,CAAM,IACnCpmB,IAAA+K,EAAK,mBAAL,QAAA/K,EAAA,KAAA+K,GAAsBqb;AAAA,EACxB;AAAA,EAEA,mBAAmBhV,GAAYsC,GAAYpW,GAAqB;A/BpI3D,QAAAI,GAAAsC;A+BqIH,UAAMhC,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcoT,CAAE,GACxCvO,IAAM,KAAK,GAAG,aAAA,EAAe,cAAc6Q,CAAE;AACnD,QAAI,CAAC1V,KAAO,CAAC6E,EAAK;AAClB,UAAMkI,IAAO,KAAK,GAAG,WAAA,GACfub,IAAU,EAAE,MAAM,gBAAgB,UAAUlV,GAAI,aAAasC,GAAI,OAAO7Q,EAAI,OAAO,OAAQ7E,EAAY6E,EAAI,KAAK,GAAG,KAAA7E,GAAK,QAAQ6E,GAAY,QAAQvF,EAAE,QAAuB,eAAeA,EAAA;AAClM,SAAK,GAAG,KAAK,gBAAgBgpB,CAAO,IACpC5oB,IAAAqN,EAAK,mBAAL,QAAArN,EAAA,KAAAqN,GAAsBub;AACtB,UAAMF,IAAS,EAAE,MAAM,eAAe,UAAUhV,GAAI,KAAApT,GAAK,QAAQV,EAAE,QAAuB,eAAeA,EAAA;AACzG,SAAK,GAAG,KAAK,eAAe8oB,CAAM,IAClCpmB,IAAA+K,EAAK,kBAAL,QAAA/K,EAAA,KAAA+K,GAAqBqb;AAAA,EACvB;AAAA,EAEA,oBAAoBhV,GAAYsC,GAAYpW,GAAqB;A/BjJ5D,QAAAI,GAAAsC;A+BkJH,UAAMhC,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcoT,CAAE,GACxCvO,IAAM,KAAK,GAAG,aAAA,EAAe,cAAc6Q,CAAE;AACnD,QAAI,CAAC1V,KAAO,CAAC6E,EAAK;AAClB,UAAMkI,IAAO,KAAK,GAAG,WAAA,GACfub,IAAU,EAAE,MAAM,iBAAiB,UAAUlV,GAAI,aAAasC,GAAI,OAAO7Q,EAAI,OAAO,OAAQ7E,EAAY6E,EAAI,KAAK,GAAG,KAAA7E,GAAK,QAAQ6E,GAAY,QAAQvF,EAAE,QAAuB,eAAeA,EAAA;AACnM,SAAK,GAAG,KAAK,iBAAiBgpB,CAAO,IACrC5oB,IAAAqN,EAAK,oBAAL,QAAArN,EAAA,KAAAqN,GAAuBub;AACvB,UAAMF,IAAS,EAAE,MAAM,gBAAgB,UAAUhV,GAAI,KAAApT,GAAK,QAAQV,EAAE,QAAuB,eAAeA,EAAA;AAC1G,SAAK,GAAG,KAAK,gBAAgB8oB,CAAM,IACnCpmB,IAAA+K,EAAK,mBAAL,QAAA/K,EAAA,KAAA+K,GAAsBqb;AAAA,EACxB;AAAA,EAEA,kBAAkBhV,GAAYsC,GAAYpW,GAAqB;A/B9J1D,QAAAI,GAAAsC;A+B+JH,UAAMhC,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcoT,CAAE,GACxCvO,IAAM,KAAK,GAAG,aAAA,EAAe,cAAc6Q,CAAE;AACnD,QAAI,CAAC1V,KAAO,CAAC6E,EAAK;AAClB,UAAMkI,IAAO,KAAK,GAAG,WAAA,GACfub,IAAU,EAAE,MAAM,eAAe,UAAUlV,GAAI,aAAasC,GAAI,OAAO7Q,EAAI,OAAO,OAAQ7E,EAAY6E,EAAI,KAAK,GAAG,KAAA7E,GAAK,QAAQ6E,GAAY,QAAQvF,EAAE,QAAuB,eAAeA,EAAA;AACjM,SAAK,GAAG,KAAK,eAAegpB,CAAO,IACnC5oB,IAAAqN,EAAK,kBAAL,QAAArN,EAAA,KAAAqN,GAAqBub;AACrB,UAAMF,IAAS,EAAE,MAAM,cAAc,UAAUhV,GAAI,KAAApT,GAAK,QAAQV,EAAE,QAAuB,eAAeA,EAAA;AACxG,SAAK,GAAG,KAAK,cAAc8oB,CAAM,IACjCpmB,IAAA+K,EAAK,iBAAL,QAAA/K,EAAA,KAAA+K,GAAoBqb;AAAA,EACtB;AAAA,EAEA,oBAAoBhV,GAAYsC,GAAYpW,GAAqB;A/B3K5D,QAAAI,GAAAsC;A+B4KH,UAAMhC,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcoT,CAAE,GACxCvO,IAAM,KAAK,GAAG,aAAA,EAAe,cAAc6Q,CAAE;AACnD,QAAI,CAAC1V,KAAO,CAAC6E,EAAK;AAClB,UAAMkI,IAAO,KAAK,GAAG,WAAA,GACfub,IAAU,EAAE,MAAM,iBAAiB,UAAUlV,GAAI,aAAasC,GAAI,OAAO7Q,EAAI,OAAO,OAAQ7E,EAAY6E,EAAI,KAAK,GAAG,KAAA7E,GAAK,QAAQ6E,GAAY,QAAQvF,EAAE,QAAuB,eAAeA,EAAA;AACnM,SAAK,GAAG,KAAK,iBAAiBgpB,CAAO,IACrC5oB,IAAAqN,EAAK,oBAAL,QAAArN,EAAA,KAAAqN,GAAuBub;AACvB,UAAMF,IAAS,EAAE,MAAM,gBAAgB,UAAUhV,GAAI,KAAApT,GAAK,QAAQV,EAAE,QAAuB,eAAeA,EAAA;AAC1G,SAAK,GAAG,KAAK,gBAAgB8oB,CAAM,IACnCpmB,IAAA+K,EAAK,mBAAL,QAAA/K,EAAA,KAAA+K,GAAsBqb;AAAA,EACxB;AAAA,EAEA,iBAAiBG,GAAyDjpB,GAAwB;A/BxL7F,QAAAI,GAAAsC,GAAAyL;A+ByLH,UAAMoW,IAAU,KAAK,GAAG,WAAA;AACxB,QAAI,CAACA,EAAQ,aAAaA,EAAQ,aAAc;AAChD,UAAM,EAAE,IAAAzQ,GAAI,IAAAsC,EAAA,IAAOmO,EAAQ,WACrB7jB,IAAM,KAAK,GAAG,QAAA,EAAU,cAAcoT,CAAE,GACxCvO,IAAM,KAAK,GAAG,aAAA,EAAe,cAAc6Q,CAAE;AACnD,QAAI,CAAC1V,KAAO,CAAC6E,EAAK;AAClB,UAAMkI,IAAO,KAAK,GAAG,WAAA,GACfkO,IAAM,EAAE,MAAMsN,GAAW,UAAUnV,GAAI,aAAasC,GAAI,OAAO7Q,EAAI,OAAO,OAAQ7E,EAAY6E,EAAI,KAAK,GAAG,KAAA7E,GAAK,QAAQ6E,GAAY,KAAKvF,EAAE,KAAK,QAAQ,KAAK,GAAG,aAAA,GAAgB,eAAeA,EAAA;AACpM,SAAK,GAAG,KAAKipB,GAAWtN,CAAG,GACvBsN,MAAc,iBAAe7oB,IAAAqN,EAAK,kBAAL,QAAArN,EAAA,KAAAqN,GAAqBkO,KAC7CsN,MAAc,eAAavmB,IAAA+K,EAAK,gBAAL,QAAA/K,EAAA,KAAA+K,GAAmBkO,MAClDxN,IAAAV,EAAK,mBAAL,QAAAU,EAAA,KAAAV,GAAsBkO;AAAA,EAC7B;AACF;AC3MO,MAAMuN,GAAe;AAAA,EAArB,cAAA;AACL,SAAQ,gCAAgB,IAAA;AAAA,EAA8B;AAAA,EAEtD,IAAItpB,GAA8BC,GAA+B;AAC/D,IAAK,KAAK,UAAU,IAAID,CAAK,KAAG,KAAK,UAAU,IAAIA,GAAO,EAAE,GAC5D,KAAK,UAAU,IAAIA,CAAK,EAAG,KAAKC,CAAO;AAAA,EACzC;AAAA,EAEA,OAAOD,GAA8BC,GAA+B;AAClE,UAAMoJ,IAAM,KAAK,UAAU,IAAIrJ,CAAK;AACpC,QAAIqJ,GAAK;AACP,YAAMhI,IAAMgI,EAAI,QAAQpJ,CAAO;AAC/B,MAAIoB,KAAO,KAAGgI,EAAI,OAAOhI,GAAK,CAAC;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,MAAMrB,GAAqC;AACzC,IAAIA,IAAO,KAAK,UAAU,OAAOA,CAAK,IACjC,KAAK,UAAU,MAAA;AAAA,EACtB;AAAA,EAEA,MAAMupB,GAAmBlpB,GAA6B;AACpD,QAAImpB,IAAa;AACjB,WAAO;AAAA,MACL,WAAAD;AAAA,MAAW,MAAAlpB;AAAA,MAAM,QAAQ;AAAA,MAAW,OAAO,CAAA;AAAA,MAC3C,WAAW,KAAK,IAAA;AAAA,MAChB,IAAI,YAAY;AAAE,eAAOmpB;AAAA,MAAY;AAAA,MACrC,SAAS;AAAE,QAAAA,IAAa;AAAA,MAAM;AAAA,IAAA;AAAA,EAElC;AAAA,EAEA,KAAKxpB,GAAeyJ,GAA8B;AAChD,UAAMggB,IAAW,KAAK,UAAU,IAAIzpB,CAAK,KAAK,CAAA;AAC9C,eAAW8N,KAAM2b;AAEf,UADA3b,EAAGrE,CAAG,GACFA,EAAI,UAAW,QAAO;AAE5B,QAAIzJ,EAAM,WAAW,QAAQ,GAAG;AAC9B,YAAM0pB,IAAmB,KAAK,UAAU,IAAI,UAAU,KAAK,CAAA;AAC3D,iBAAW5b,KAAM4b,EAAkB,CAAA5b,EAAGrE,CAAG;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AACF;ACZA,MAAMkgB,KAAe;AAEd,MAAMC,WACH7pB,GAEV;AAAA,EAgCE,YAAYsE,GAAiCC,GAAyB;AjC/DjE,QAAA9D;AiCgEH,UAAA,GA5BF,KAAQ,MAA4B,MACpC,KAAQ,MAA6B,MACrC,KAAQ,YAAiC,MAIzC,KAAQ,WAAW,IAAI8oB,GAAA,GACvB,KAAQ,aAAa,IACrB,KAAQ,aAAuB,CAAA,GAC/B,KAAQ,eAAmC,MAC3C,KAAQ,gBAA0C,MAClD,KAAQ,cAAiC,MACzC,KAAQ,OAA2B,MACnC,KAAQ,eAA4B,IAAIxK,EAAA,GACxC,KAAQ,cAAkC,MAC1C,KAAQ,WAAsC,MAC9C,KAAQ,aAAqD,MAC7D,KAAQ,gBAAqD,MAC7D,KAAQ,aAAyC;AAW/C,UAAMpN,IAAK,OAAOrN,KAAc,WAC3B,SAAS,cAAcA,CAAS,IACjCA;AACJ,QAAI,CAACqN,EAAI,OAAM,IAAI,MAAM,kCAAkCrN,CAAS,EAAE;AACtE,SAAK,aAAaqN,GAElB,KAAK,WAAW;AAAA,MACd,QAAQ;AAAA,MAAQ,OAAO;AAAA,MACvB,WAAW;AAAA,MAAI,cAAc;AAAA,MAAI,cAAc;AAAA,MAC/C,YAAY;AAAA,MAAO,WAAW;AAAA,MAAO,oBAAoB;AAAA,MACzD,UAAU;AAAA,MAAO,UAAU;AAAA,MAAY,SAAS;AAAA,MAAM,aAAa;AAAA,MACnE,WAAW;AAAA,MAAU,WAAW;AAAA,MAChC,UAAU;AAAA,MAAM,WAAW;AAAA,MAAM,YAAY;AAAA,MAAM,aAAa,CAAA;AAAA,MAChE,eAAe;AAAA,MAAG,YAAY;AAAA,MAC9B,WAAW;AAAA,MAAO,aAAa;AAAA,MAAO,aAAa;AAAA,MAAO,WAAW;AAAA,MACrE,YAAY;AAAA,MAAO,SAAS,CAAA;AAAA,MAAI,SAAS;AAAA,MACzC,UAAU;AAAA,MAAQ,QAAQ;AAAA,MAAM,cAAc;AAAA,MAAY,cAAc;AAAA,MACxE,YAAY;AAAA,MAAO,UAAU;AAAA,MAC7B,QAAQ;AAAA,MAAkB,gBAAgB;AAAA,MAC1C,OAAO;AAAA,MAAW,SAAS,CAAA;AAAA,MAAI,WAAW;AAAA,MAC1C,GAAGpN;AAAA,IAAA,GAGL,KAAK,QAAQ,IAAI3D,GAAagpB,EAAY,GAC1C,KAAK,UAAU,IAAIrP,GAAc,KAAK,KAAK,GAC3C,KAAK,aAAa,IAAInV,GAAgB,KAAK,SAAS,SAAS,KAAK,SAAS,aAAa,GACxF,KAAK,WAAW,IAAIuW,GAAmB;AAAA,MACrC,MAAM,KAAK;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,aAAa,MAAM,KAAK;AAAA,MACxB,cAAc,MAAM,KAAK;AAAA,MACzB,YAAY,MAAM,KAAK;AAAA,MACvB,MAAM,CAACtB,MAAO/Z,MAAS,KAAK,KAAK+Z,GAAI,GAAG/Z,CAAI;AAAA,MAC5C,UAAU,MAAM,KAAK,UAAU,GAAG,KAAK,WAAW;AAAA,MAClD,UAAU,CAACwpB,MAAQ,KAAK,UAAUA,CAAG;AAAA,MACrC,WAAW,CAAC3V,GAAInS,GAAOC,MAAU,KAAK,UAAUkS,GAAInS,GAAOC,CAAK;AAAA,MAChE,aAAa,CAACkS,MAAA;AjCrGb,YAAA1T;AiCqGoB,gBAAAA,IAAA,KAAK,QAAL,gBAAAA,EAAU,YAAY0T;AAAA;AAAA,MAC3C,kBAAkB,MAAM,KAAK,WAAW;AAAA,IAAA,CACzC,GAED,KAAK,aAAa,IAAI+M,GAAiB;AAAA,MACrC,SAAS,MAAM,KAAK,MAAM,QAAA;AAAA,MAC1B,cAAc,MAAM,KAAK;AAAA,MACzB,cAAc,MAAM,KAAK;AAAA,MACzB,YAAY,MAAM,KAAK;AAAA,MACvB,cAAc,MAAM,KAAK;AAAA,MACzB,gBAAgB,CAAClf,MAAU,KAAK,eAAeA,CAAK;AAAA,MACpD,cAAc,MAAM,KAAK;AAAA,IAAA,CAC1B,GACD,KAAK,aAAa,IAAIuhB,GAAiB;AAAA,MACrC,SAAS,MAAM,KAAK,MAAM,QAAA;AAAA,MAC1B,cAAc,MAAM,KAAK;AAAA,MACzB,cAAc,MAAM,KAAK;AAAA,MACzB,YAAY,MAAM,KAAK;AAAA,MACvB,cAAc,MAAM,KAAK;AAAA,IAAA,CAC1B,GACD,KAAK,UAAU,IAAIoB,GAAmB;AAAA,MACpC,YAAY,MAAM,KAAK;AAAA,MACvB,WAAW,MAAM,KAAK;AAAA,MACtB,SAAS,MAAM,KAAK;AAAA,MACpB,cAAc,MAAM,KAAK;AAAA,MACzB,YAAY,MAAM,KAAK;AAAA,MACvB,cAAc,CAACxQ,GAAIsC,MAAO,KAAK,cAActC,GAAIsC,CAAE;AAAA,MACnD,eAAe,CAACsT,GAAMC,MAAO,KAAK,eAAeD,GAAMC,CAAE;AAAA,MACzD,UAAU,MAAM,KAAK,UAAU,GAAG,KAAK,WAAW;AAAA,MAClD,UAAU,CAACF,MAAQ,KAAK,UAAUA,CAAG;AAAA,MACrC,MAAM,CAACzP,MAAO/Z,MAAS,KAAK,KAAK+Z,GAAI,GAAG/Z,CAAI;AAAA,MAC5C,UAAU,MAAM,KAAK,UAAA;AAAA,MACrB,kBAAkB,CAACmgB,GAAMpgB,MAAM,KAAK,kBAAkBogB,GAAMpgB,CAAC;AAAA,IAAA,CAC9D,GACD,KAAK,SAAS,IAAIkoB,GAAqB;AAAA,MACrC,SAAS,MAAM,KAAK;AAAA,MACpB,cAAc,MAAM,KAAK;AAAA,MACzB,eAAe,MAAM,KAAK,SAAS;AAAA,MACnC,OAAO,MAAM,KAAK;AAAA,MAClB,eAAe,MAAM,KAAK;AAAA,MAC1B,YAAY,MAAM,KAAK;AAAA,MACvB,cAAc,MAAM,KAAK,cAAA;AAAA,MACzB,UAAU,MAAM,KAAK,UAAU,GAAG,KAAK,WAAW;AAAA,MAClD,UAAU,CAACuB,MAAQ,KAAK,UAAUA,CAAG;AAAA,MACrC,MAAM,CAACzP,MAAO/Z,MAAS,KAAK,KAAK+Z,GAAI,GAAG/Z,CAAI;AAAA,IAAA,CAC7C,GACD,KAAK,WAAW,IAAI+kB,GAAkB;AAAA,MACpC,cAAc,MAAM,KAAK;AAAA,MACzB,SAAS,MAAM,KAAK;AAAA,MACpB,YAAY,MAAM,KAAK,OAAO;AAAA,MAC9B,OAAO,MAAM,KAAK;AAAA,MAClB,eAAe,MAAM,KAAK;AAAA,MAC1B,UAAU,MAAM,KAAK,UAAU,GAAG,KAAK,WAAW;AAAA,IAAA,CACnD,GACD,KAAK,WAAW,IAAIwD,GAAoB;AAAA,MACtC,SAAS,MAAM,KAAK;AAAA,MACpB,cAAc,MAAM,KAAK;AAAA,MACzB,YAAY,MAAM,KAAK;AAAA,MACvB,YAAY,MAAM,KAAK;AAAA,MACvB,WAAW,MAAM,KAAK;AAAA,MACtB,MAAM,CAACxO,MAAO/Z,MAAS,KAAK,KAAK+Z,GAAI,GAAG/Z,CAAI;AAAA,MAC5C,WAAW,CAAC6T,GAAInS,GAAO6B,MAAQ,KAAK,UAAUsQ,GAAInS,GAAO6B,CAAG;AAAA,MAC5D,UAAU,MAAM,KAAK,UAAU,GAAG,KAAK,WAAW;AAAA,MAClD,cAAc,MAAM,KAAK;AAAA,IAAA,CAC1B,GACD,KAAK,UAAU,IAAIokB,GAAoB;AAAA,MACrC,SAAS,MAAM,KAAK,MAAM,QAAA;AAAA,MAC1B,cAAc,MAAM,KAAK;AAAA,MACzB,YAAY,MAAM,KAAK;AAAA,MACvB,OAAO,MAAM,KAAK;AAAA,MAClB,cAAc,CAAC,MAAM,KAAK,UAAU,GAAG,IAAI,CAAC;AAAA,MAC5C,UAAU,MAAM,KAAK,UAAU,GAAG,KAAK,WAAW;AAAA,IAAA,CACnD,GAED,KAAK,OAAA,GACL,KAAK,kBAAA,IAEDxnB,IAAA,KAAK,SAAS,gBAAd,QAAAA,EAA2B,UAC7B,KAAK,OAAO,SAAS,KAAK,SAAS,WAAW,GAGhD,sBAAsB,MAAM;AjCtLzB,UAAAA,GAAAsC;AiCuLD,WAAK,KAAK,SAAS,IAAI,IACvBA,KAAAtC,IAAA,KAAK,UAAS,YAAd,QAAAsC,EAAA,KAAAtC,GAAwB;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EACQ,SAAe;AjC3LlB,QAAAA,GAAAsC;AiC4LH,SAAK,WAAW,UAAU,IAAI,cAAc;AAC5C,UAAM2M,IAAI,KAAK,SAAS,QAClBD,IAAI,KAAK,SAAS;AACxB,SAAK,WAAW,MAAM,SAAS,OAAOC,KAAM,WAAW,GAAGA,CAAC,OAAO,OAAOA,CAAC,GAC1E,KAAK,WAAW,MAAM,QAAS,OAAOD,KAAM,WAAW,GAAGA,CAAC,OAAO,OAAOA,CAAC,GAC1E,KAAK,WAAW,MAAM,UAAU,QAChC,KAAK,WAAW,MAAM,gBAAgB,UACtC,KAAK,WAAW,MAAM,WAAW,UACjC,KAAK,WAAW,MAAM,YAAY,cAClC,KAAK,WAAW,MAAM,SAAS,6CAC/B,KAAK,WAAW,MAAM,aAAa,oDACnC,KAAK,WAAW,MAAM,WAAW,6BACjC,KAAK,WAAW,aAAa,iBAAiB,KAAK,SAAS,KAAK;AAEjE,eAAW,CAACjN,GAAG0B,CAAC,KAAK,OAAO,QAAQ,KAAK,SAAS,OAAO;AACvD,WAAK,WAAW,MAAM,YAAY1B,GAAG0B,CAAC;AAExC,SAAK,YAAY,IAAI+O,GAAa,KAAK,YAAY,KAAK,UAAU;AAAA,MAChE,eAAmB,CAACjR,GAAOwmB,MAAa,KAAK,iBAAiBxmB,GAAOwmB,CAAQ;AAAA,MAC7E,aAAmB,CAACrU,GAAIsC,GAAIpW,MAAM,KAAK,iBAAiB8T,GAAIsC,GAAIpW,CAAC;AAAA,MACjE,gBAAmB,CAAC8T,GAAIsC,GAAIpW,MAAM,KAAK,oBAAoB8T,GAAIsC,GAAIpW,CAAC;AAAA,MACpE,iBAAmB,CAAC8T,GAAIsC,GAAIpW,MAAM,KAAK,qBAAqB8T,GAAIsC,GAAIpW,CAAC;AAAA,MACrE,gBAAmB,CAAC8T,GAAIsC,GAAIpW,MAAM,KAAK,oBAAoB8T,GAAIsC,GAAIpW,CAAC;AAAA,MACpE,iBAAmB,CAAC8T,GAAIsC,GAAIpW,MAAM,KAAK,qBAAqB8T,GAAIsC,GAAIpW,CAAC;AAAA,MACrE,eAAmB,CAAC8T,GAAIsC,GAAIpW,MAAM,KAAK,mBAAmB8T,GAAIsC,GAAIpW,CAAC;AAAA,MACnE,iBAAmB,CAAC8T,GAAIsC,GAAIpW,MAAM,KAAK,qBAAqB8T,GAAIsC,GAAIpW,CAAC;AAAA,MACrE,YAAmB,CAAC8T,GAAIqG,MAAY,KAAK,gBAAgBrG,GAAIqG,CAAO;AAAA,MACpE,YAAmB,CAACA,MAAY,KAAK,gBAAgBA,CAAO;AAAA,MAC5D,aAAmB,CAAC/D,GAAIhH,MAAM,KAAK,iBAAiBgH,GAAIhH,CAAC;AAAA,MACzD,mBAAmB,CAACzN,GAAO8E,MAAa,KAAK,uBAAuB9E,GAAO8E,CAAQ;AAAA,MACnF,eAAmB,MAAM,KAAK;AAAA,MAC9B,gBAAmB,CAAC2P,MAAO;AAAE,aAAK,SAAS,aAAaA;AAAA,MAAI;AAAA,MAC5D,WAAmB,CAACwT,MAAU;AAC5B,QAAI,KAAK,SAAS,eAAe,QAAQ,KAAK,SAAS,eAAeA,KACpE,KAAK,eAAe,KAAK,SAAS,YAAYA,CAAK,GAErD,KAAK,SAAS,aAAa;AAAA,MAC7B;AAAA,MACA,eAAmB,MAAM,KAAK,SAAS;AAAA,IAAA,CACxC,GAED,KAAK,eAAe,IAAItjB;AAAA,MACtB,KAAK;AAAA,MACL,CAAC3E,GAAO2d,MAAU,KAAK,UAAU3d,GAAO2d,CAAK;AAAA,MAC7C,CAAC3d,MAAU,KAAK,YAAYA,CAAK;AAAA,IAAA,GAInC,KAAK,WAAW,aAAa,QAAQ,MAAM,GAC3C,KAAK,WAAW,aAAa,cAAc,KAAK,SAAS,eAAavB,IAAA,KAAK,SAAS,YAAd,gBAAAA,EAAwB,kBAAiB,mBAAmB,GAClI,KAAK,WAAW,aAAa,iBAAiB,GAAG,GACjD,KAAK,WAAW,aAAa,iBAAiB,OAAO,KAAK,SAAS,QAAQ,OAAO,CAAAoF,MAAK,CAACA,EAAE,MAAM,EAAE,MAAM,CAAC,GAEzG,KAAK,cAAc,SAAS,cAAc,KAAK,GAC/C,KAAK,YAAY,aAAa,aAAa,QAAQ,GACnD,KAAK,YAAY,aAAa,eAAe,MAAM,GACnD,KAAK,YAAY,YAAY,kBAC7B,KAAK,WAAW,sBAAsB,eAAe,KAAK,WAAW,GAErE,KAAK,WAAW,WAAW,GAC3B,KAAK,WAAW,iBAAiB,WAAY,CAACxF,MAAM,KAAK,eAAeA,CAAC,CAAC,GAC1E,KAAK,WAAW,iBAAiB,SAAY,CAACA,MAAM,KAAK,kBAAkB,aAAaA,CAAC,CAAC,GAC1F,KAAK,WAAW,iBAAiB,YAAY,CAACA,MAAM,KAAK,kBAAkB,gBAAgBA,CAAC,CAAC,GAE7F,KAAK,MAAM,IAAIgE,GAAc,KAAK,UAAU,aAAa;AAAA,MACvD,WAAW,KAAK,SAAS;AAAA,MACzB,UAAU,CAACpB,GAAG5C,MAAM,KAAK,UAAU4C,GAAG5C,CAAC;AAAA,IAAA,CACxC,GAEG,KAAK,SAAS,cAChB,KAAK,OAAO,IAAI2d;AAAA,MACd,KAAK,UAAU;AAAA,MACf,KAAK,SAAS;AAAA,MACd,CAAC+L,GAAMC,MAAO,KAAK,eAAeD,GAAMC,CAAE;AAAA,IAAA,IAK1C,KAAK,SAAS,eAChB,KAAK,cAAc,IAAI/M;AAAA,MACrB,KAAK;AAAA,MACL,KAAK,SAAS;AAAA,MACd,CAAC5c,MAAM;AACL,aAAK,KAAK,cAAcA,CAAC,GACzB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,MACpC;AAAA,IAAA,IAIJ,KAAK,SAAS,KAAK,KAAK,UAAU,GAElC,KAAK,iBAAA,IAED0C,IAAA,KAAK,SAAS,eAAd,QAAAA,EAA0B,UAC5B,KAAK,gBAAA,GAGP,KAAK,MAAM,IAAI,eAAe,MAAM,KAAK,WAAW,GACpD,KAAK,IAAI,QAAQ,KAAK,UAAU,GAChC,KAAK,UAAA;AAAA,EACP;AAAA,EAEQ,mBAAyB;AAC/B,UAAMqE,IAAM,KAAK,SAAS;AAC1B,IAAIA,MAAQ,OAGR,KAAK,cAAe,KAAK,WAAW,oBAAoB,eAAe,KAAK,UAAU,GACtF,KAAK,iBAAe,KAAK,WAAW,oBAAoB,WAAe,KAAK,aAAa,GAC7F,KAAK,aAAa,KAAK,gBAAgB,MAEvC,KAAK,WAAW,IAAImY,GAAmB,KAAK,YAAY;AAAA,MACtD,WAAY,MAAM;AAChB,cAAM2K,IAAS,KAAK,WAAW,cAAc,CAAC;AAC9C,QAAIA,KAAQ,KAAK,QAAQA,EAAO,OAAO,KAAK;AAAA,MAC9C;AAAA,MACA,YAAY,MAAM;AAChB,cAAMA,IAAS,KAAK,WAAW,cAAc,CAAC;AAC9C,QAAIA,KAAQ,KAAK,QAAQA,EAAO,OAAO,MAAM;AAAA,MAC/C;AAAA,MACA,QAAW,MAAM,KAAK,SAAS,KAAA;AAAA,MAC/B,SAAW,MAAM,KAAK,YAAA;AAAA,MACtB,OAAW,MAAM,KAAK,UAAA;AAAA,MACtB,SAAW,MAAM,KAAK,MAAA;AAAA,IAAM,CAC7B,GAED,KAAK,aAAa,CAAC7pB,MAAkB;AjC1TlC,UAAAI;AiC2TD,YAAM4T,IAAQhU,EAAE,OAAuB,QAAqB,UAAU;AACtE,UAAI,CAACgU,EAAM;AACX,MAAAhU,EAAE,eAAA;AAEF,YAAM8pB,IAAS,OAAO9V,EAAK,QAAQ,YAAY,EAAE,GAC3CzO,IAAM,KAAK,WAAW,cAAcukB,CAAM;AAEhD,MAAIvkB,KAAO,KAAK,aACd,KAAK,SAAS,SAAY,YAAa,MAAM,KAAK,QAAQA,EAAI,OAAO,KAAK,GAC1E,KAAK,SAAS,SAAY,aAAa,MAAM,KAAK,QAAQA,EAAI,OAAO,MAAM;AAI7E,YAAM8Z,IAAc,MAAM,QAAQtY,CAAG,IAAIA,IAAM;AAC/C,OAAA3G,IAAA,KAAK,aAAL,QAAAA,EAAe,KAAKJ,GAAGqf;AAAA,IACzB,GACA,KAAK,WAAW,iBAAiB,eAAe,KAAK,UAAU,GAE/D,KAAK,gBAAgB,CAACrf,MAAqB;AjC7UxC,UAAAI;AiC8UD,UAAIJ,EAAE,YAAYA,EAAE,QAAQ,OAAO;AACjC,QAAAA,EAAE,eAAA;AACF,cAAMoH,IAAO,KAAK,WAAW,sBAAA,GACvB2iB,IAAY,EAAE,SAAS3iB,EAAK,OAAO,IAAI,SAASA,EAAK,MAAM,GAAA;AACjE,SAAAhH,IAAA,KAAK,aAAL,QAAAA,EAAe,KAAK2pB;AAAA,MACtB;AAAA,IACF,GACA,KAAK,WAAW,iBAAiB,WAAW,KAAK,aAAa;AAAA,EAChE;AAAA;AAAA,EAEA,gBAAgB,GAAezK,GAAmD;AjCxV7E,QAAAlf;AiCyVH,KAAAA,IAAA,KAAK,aAAL,QAAAA,EAAe,KAAK,GAAGkf;AAAA,EACzB;AAAA,EACA,mBAAyB;AjC3VpB,QAAAlf;AiC4VH,KAAAA,IAAA,KAAK,aAAL,QAAAA,EAAe;AAAA,EACjB;AAAA,EACA,gBAAgByb,GAAyC;AjC9VpD,QAAAzb;AiCiWH,KAFAA,IAAA,KAAK,kBAAL,QAAAA,EAAoB,WACpB,KAAK,gBAAgB,MAChByb,MACA,KAAK,WAAW,OACnB,KAAK,WAAW,KAAK,MAAM,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,KAEnE,KAAK,gBAAgB,IAAID;AAAA,MACvB,KAAK;AAAA,MAAYC;AAAA,MACjB,CAACla,GAAO2d,MAAU,KAAK,UAAU3d,GAAO2d,CAAK;AAAA,MAC7C,CAAC3d,MAAiB,KAAK,YAAYA,CAAK;AAAA,MACxC,KAAK,WAAW;AAAA,IAAA;AAAA,EAEpB;AAAA;AAAA,EAEA,WAAW8L,GAAqC;AjC7W3C,QAAArN;AiCqXH,QAPA,OAAO,OAAO,KAAK,UAAUqN,CAAI,GAC7B,iBAAiBA,OACnBrN,IAAA,KAAK,aAAL,QAAAA,EAAe,WACf,KAAK,WAAW,MAChB,KAAK,iBAAA,IAGH,aAAaqN,KAAQ,aAAaA,GAAM;AAC1C,YAAMlK,IAAUkK,EAAK,WAAW,CAAA;AAChC,MAAIlK,EAAO,SAAS,IAClB,KAAK,QAAQ,QAAQA,CAAM,IAE3B,KAAK,WAAA;AAEP;AAAA,IACF;AACA,SAAK,cAAA,GACL,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe5B,GAAe4a,GAAwB;AjCvYjD,QAAAnc;AiCwYH,UAAMmF,IAAM,KAAK,WAAW,iBAAiB5D,CAAK;AAClD,IAAK4D,MACDgX,KAEFhX,EAAI,gBAAgB,KACnBnF,IAAAmF,EAAI,sBAAJ,QAAAnF,EAAmD,WAGpDmF,EAAI,gBAAgB,IAEtB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA;AAAA,EAGA,eAAe5D,GAAwB;AACrC,UAAM4D,IAAM,KAAK,WAAW,iBAAiB5D,CAAK;AAClD,WAAK4D,IACEA,EAAI,kBAAkB,KADZ;AAAA,EAEnB;AAAA,EACQ,kBAAwB;AAC9B,UAAMykB,IAAS,KAAK,SAAS;AAC7B,SAAK,aAAa,IAAI9J;AAAA,MACpB,KAAK;AAAA,MACL,CAAC+J,GAAOjoB,MAAU;AAEhB,aAAK,MAAM,QAAQA,EAAM,IAAI,GAC7B,KAAK,aAAa,IAAI+C;AAAA,UACpB/C,EAAM,QAAQ,SAASA,EAAM,UAAU,KAAK,SAAS;AAAA,UACrD,KAAK,SAAS;AAAA,QAAA,GAEhB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,cAAA;AAAA,MACP;AAAA,IAAA;AAEF,eAAWkoB,KAASF;AAClB,WAAK,WAAW,IAAIE,EAAM,MAAMA,EAAM,WAAW,KAAK,SAAS,SAASA,EAAM,QAAQ,CAAA,CAAE;AAAA,EAE5F;AAAA,EAEA,aAAa9J,GAAcpb,GAA4CvE,GAAkB;AACvF,IAAK,KAAK,eACR,KAAK,aAAa,IAAIyf;AAAA,MACpB,KAAK;AAAA,MACL,CAACiK,GAAInoB,MAAU;AACb,aAAK,MAAM,QAAQA,EAAM,IAAI,GAC7B,KAAK,aAAa,IAAI+C;AAAA,UACpB/C,EAAM,QAAQ,SAASA,EAAM,UAAU,KAAK,SAAS;AAAA,UACrD,KAAK,SAAS;AAAA,QAAA,GAEhB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,cAAA;AAAA,MACP;AAAA,IAAA,IAGJ,KAAK,WAAW,IAAIoe,GAAMpb,KAAW,KAAK,SAAS,SAASvE,KAAQ,EAAE;AAAA,EACxE;AAAA,EAEA,gBAAgB2f,GAAoB;AjCjc/B,QAAAhgB;AiCkcH,KAAAA,IAAA,KAAK,eAAL,QAAAA,EAAiB,OAAOggB;AAAA,EAC1B;AAAA,EAEA,gBAAgBA,GAAoB;AjCrc/B,QAAAhgB;AiCscH,KAAAA,IAAA,KAAK,eAAL,QAAAA,EAAiB,OAAOggB;AAAA,EAC1B;AAAA,EAEA,gBAAgBE,GAAiBC,GAAuB;AjCzcnD,QAAAngB;AiC0cH,KAAAA,IAAA,KAAK,eAAL,QAAAA,EAAiB,OAAOkgB,GAASC;AAAA,EACnC;AAAA,EAEA,aAAaH,GAA+D;AjC7cvE,QAAAhgB;AiC8cH,YAAOA,IAAA,KAAK,eAAL,gBAAAA,EAAiB,IAAIggB;AAAA,EAC9B;AAAA,EAEA,oBAA8B;AjCjdzB,QAAAhgB;AiCkdH,aAAOA,IAAA,KAAK,eAAL,gBAAAA,EAAiB,eAAc,CAAA;AAAA,EACxC;AAAA,EAEA,kBAAkBoZ,GAAyB;AAAE,SAAK,WAAW,kBAAkBA,CAAQ;AAAA,EAAG;AAAA,EAElF,oBAA4B;AAClC,WAAO,KAAK,SAAS,aAAa,KAAK;AAAA,EACzC;AAAA,EAEQ,YAAkB;AACxB,UAAM,EAAE,OAAAsG,GAAO,QAAArb,EAAA,IAAW,KAAK,WAAW,sBAAA;AAC1C,QAAI,CAACqb,EAAO;AACZ,UAAMsK,IAAQ3lB,IAAS,KAAK,SAAS,eAAe,KAAK,kBAAA;AACzD,SAAK,UAAW,WAAWA,IAAS,KAAK,qBAAqB,KAAK,SAAS,YAAY,GACxF,KAAK,IAAK,kBAAkB2lB,CAAK,GACjC,KAAK,cAActK,CAAK,GACxB,KAAK,cAAA,GACL,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA,EAEQ,cAAc/Z,GAA0B;AAC9C,SAAK,aAAa,KAAK,WAAW;AAAA,MAChCA,KACK,KAAK,SAAS,cAAc,KAAK,MACjC,KAAK,SAAS,YAAc,KAAK,MACjC,KAAK,SAAS,YAAc,KAAK,MACjC,KAAK,SAAS,cAAc,KAAK;AAAA,MACtC,KAAK,SAAS;AAAA,IAAA;AAAA,EAElB;AAAA;AAAA,EAEQ,gBAAsB;AjCjfzB,QAAA3F;AiCkfH,KAAAA,IAAA,KAAK,cAAL,QAAAA,EAAgB;AAAA,MACd,KAAK,WAAW,iBAAA;AAAA,MAChB,KAAK,WAAW;AAAA,MAChB,KAAK;AAAA,MACL,KAAK,OAAO;AAAA,MACZ,EAAE,GAAG,KAAK,UAAU,gBAAgB,KAAK,OAAO,SAAS,cAAc,KAAK,WAAW,YAAA;AAAA;AAAA,EAE3F;AAAA,EACQ,UAAUiE,GAAoBC,GAAwB;AjC1fzD,QAAAlE;AiC2fH,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,IAAK;AAClC,UAAM+D,IAAQ,KAAK,IAAI,gBAAA;AACvB,SAAK,UAAU;AAAA,MACbE;AAAA,MAAYC;AAAA,MACZ,KAAK;AAAA,MACL,KAAK,WAAW;AAAA,MAChB,KAAK;AAAA,MACL,KAAK;AAAA,MACLH,EAAM;AAAA,MACN,KAAK,IAAI,eAAA;AAAA,MACT,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAiB,KAAK,QAAQ,aAAa,KAAK,QAAQ,eAAe;AAAA,MAC/G,CAAC0R,MAAa,KAAK,QAAQ,kBAAkBA,CAAQ;AAAA,MACrD,KAAK,QAAQ,aAAa,CAAC4R,MAAW,KAAK,QAAQ,iBAAiBA,CAAM,IAAI;AAAA,MAC9E,EAAE,YAAY,KAAK,MAAM,UAAU,cAAc,KAAK,WAAW,aAAa,YAAY,KAAK,SAAS,UAAA;AAAA,MACxG,KAAK;AAAA,IAAA,IAGHrnB,IAAA,KAAK,SAAS,WAAd,QAAAA,EAAsB,eAAa,gBAAA;AAAA,EACzC;AAAA,EAEQ,mBAAmByV,GAAwB;AAAE,SAAK,QAAQ,kBAAkBA,CAAQ;AAAA,EAAG;AAAA;AAAA,EAGvF,YAA8B;AjCphBjC,QAAAzV;AiCqhBH,QAAI,KAAK,SAAS,cAAc,KAAK,aAAa;AAChD,YAAM,EAAE,OAAA0J,GAAO,KAAAkT,EAAA,IAAQ,KAAK,YAAY,SAAA;AACxC,aAAO,CAAClT,GAAOkT,CAAG;AAAA,IACpB;AACA,UAAMnc,KAAIT,IAAA,KAAK,QAAL,gBAAAA,EAAU;AACpB,WAAO,EAACS,KAAA,gBAAAA,EAAG,eAAc,GAAG,KAAK,MAAKA,KAAA,gBAAAA,EAAG,aAAY,MAAM,KAAK,cAAc,GAAG,KAAK,MAAM,WAAW,CAAC,CAAC;AAAA,EAC3G;AAAA,EAEQ,YAAoB;AAC1B,UAAMwO,IAAI,KAAK,WAAW,sBAAA,EAAwB;AAClD,WAAO,KAAK,MAAMA,IAAI,KAAK,SAAS,eAAe,KAAK,kBAAA,KAAuB,KAAK,SAAS,SAAS,IAAI;AAAA,EAC5G;AAAA,EACQ,iBAAiB1N,GAAewmB,GAAyB;AAAE,SAAK,OAAO,gBAAgBxmB,GAAOwmB,CAAQ;AAAA,EAAG;AAAA,EAEzG,aAAa5iB,GAA4B;AAAE,WAAO6V,GAAY7V,CAAG;AAAA,EAAG;AAAA,EACpE,iBAAiBuO,GAAYsC,GAAYpW,GAAqB;AAAE,SAAK,SAAS,gBAAgB8T,GAAIsC,GAAIpW,CAAC;AAAA,EAAG;AAAA,EAC1G,oBAAoB8T,GAAYsC,GAAYpW,GAAqB;AAAE,SAAK,SAAS,mBAAmB8T,GAAIsC,GAAIpW,CAAC;AAAA,EAAG;AAAA,EAChH,qBAAqB8T,GAAYsC,GAAYpW,GAAqB;AAAE,SAAK,SAAS,oBAAoB8T,GAAIsC,GAAIpW,CAAC;AAAA,EAAG;AAAA,EAClH,oBAAoB8T,GAAYsC,GAAYpW,GAAqB;AAAE,SAAK,SAAS,mBAAmB8T,GAAIsC,GAAIpW,CAAC;AAAA,EAAG;AAAA,EAChH,qBAAqB8T,GAAYsC,GAAYpW,GAAqB;AAAE,SAAK,SAAS,oBAAoB8T,GAAIsC,GAAIpW,CAAC;AAAA,EAAG;AAAA,EAClH,mBAAmB8T,GAAYsC,GAAYpW,GAAqB;AAAE,SAAK,SAAS,kBAAkB8T,GAAIsC,GAAIpW,CAAC;AAAA,EAAG;AAAA,EAC9G,qBAAqB8T,GAAYsC,GAAYpW,GAAqB;AAAE,SAAK,SAAS,oBAAoB8T,GAAIsC,GAAIpW,CAAC;AAAA,EAAG;AAAA,EAClH,kBAAkBogB,GAAoDpgB,GAAwB;AAAE,SAAK,SAAS,iBAAiBogB,GAAMpgB,CAAC;AAAA,EAAG;AAAA,EAEzI,gBAAgBoB,GAAkB+Y,GAAwB;AAChE,SAAK,QAAQ,MAAM/Y,GAAU+Y,CAAO,GACpC,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,KAAK,YAAY,EAAE,UAAA/Y,GAAU,SAAA+Y,GAAS,KAAK,KAAK,MAAM,cAAc/Y,CAAQ,EAAA,CAAG;AAAA,EACtF;AAAA,EAEQ,uBAAuBO,GAAe8E,GAA6B;AjCnjBtE,QAAArG,GAAAsC;AiCojBH,SAAItC,IAAA,KAAK,iBAAL,QAAAA,EAAmB,QAAQ;AAC7B,WAAK,aAAa,MAAA;AAClB;AAAA,IACF;AACA,UAAMqd,IAAU,KAAK,OAAO,QAAQ9b,CAAK,KAAK,CAAA;AAC9C,KAAAe,IAAA,KAAK,iBAAL,QAAAA,EAAmB,KAAKf,GAAO8E,GAAUgX;AAAA,EAC3C;AAAA,EAEQ,gBAAgBtD,GAAwB;AAC9C,SAAK,QAAQ,SAASA,GAAS,KAAK,MAAM,QAAQ,GAClD,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,KAAK,YAAY,EAAE,SAAAA,EAAA,CAAS;AAAA,EACnC;AAAA,EACQ,eAAe4D,GAAmBsM,GAAuB;AjCjkB5D,QAAAjqB,GAAAsC;AiCkkBH,SAAK,MAAM,QAAQqb,GAAWsM,CAAO,GACrC,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,KAAK,WAAW,EAAE,WAAAtM,GAAW,SAAAsM,GAAS,IAC3C3nB,KAAAtC,IAAA,KAAK,UAAS,cAAd,QAAAsC,EAAA,KAAAtC,GAA0B,EAAE,WAAA2d,GAAW,SAAAsM;EACzC;AAAA;AAAA;AAAA,EAGA,WAAWtM,GAAmBsM,GAAuB;AACnD,SAAK,MAAM,QAAQtM,GAAWsM,CAAO,GACrC,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA,EACQ,iBAAiBllB,GAAkBmlB,GAAwB;AACjE,IAAI,KAAK,WAAWnlB,CAAQ,MAAM,WAChC,KAAK,WAAWA,CAAQ,IAAImlB,IAE9B,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA,EACQ,eAAe,GAAwB;AAAE,SAAK,QAAQ,cAAc,CAAC;AAAA,EAAG;AAAA,EAExE,cAAcxW,GAAYsC,GAAkB;AAClD,SAAK,QAAQ,aAAatC,CAAE,GAC5B,KAAK,SAAS,aAAaA,GAAIsC,CAAE;AAAA,EACnC;AAAA;AAAA,EAEQ,UAAUqT,GAAmB;AACnC,IAAK,KAAK,gBACV,KAAK,YAAY,cAAc,IAC/B,WAAW,MAAM;AAAE,MAAI,KAAK,gBAAa,KAAK,YAAY,cAAcA;AAAA,IAAK,GAAG,EAAE;AAAA,EACpF;AAAA,EAEQ,oBAA0B;AAChC,IAAI,KAAK,SAAS,eAAa,KAAK,GAAG,aAAa,KAAK,SAAS,WAAW,GACzE,KAAK,SAAS,kBAAgB,KAAK,GAAG,gBAAgB,KAAK,SAAS,cAAc,GAClF,KAAK,SAAS,cAAY,KAAK,GAAG,YAAY,KAAK,SAAS,UAAU,GACtE,KAAK,SAAS,eAAa,KAAK,GAAG,aAAa,KAAK,SAAS,WAAW,GACzE,KAAK,SAAS,aAAW,KAAK,GAAG,WAAW,KAAK,SAAS,SAAS,GACnE,KAAK,SAAS,gBAAc,KAAK,GAAG,cAAc,KAAK,SAAS,YAAY,GAC5E,KAAK,SAAS,kBAAgB,KAAK,GAAG,gBAAgB,KAAK,SAAS,cAAc,GAClF,KAAK,SAAS,YAAU,KAAK,GAAG,UAAU,KAAK,SAAS,QAAQ,GAChE,KAAK,SAAS,gBAAc,KAAK,GAAG,cAAc,KAAK,SAAS,YAAY,GAC5E,KAAK,SAAS,qBAAmB,KAAK,GAAG,mBAAmB,KAAK,SAAS,iBAAiB,GAE3F,KAAK,SAAS,iBAAkB,KAAK,GAAG,eAAkB,KAAK,SAAS,aAAa,GACrF,KAAK,SAAS,kBAAkB,KAAK,GAAG,gBAAkB,KAAK,SAAS,cAAc,GACtF,KAAK,SAAS,iBAAkB,KAAK,GAAG,eAAkB,KAAK,SAAS,aAAa,GACrF,KAAK,SAAS,kBAAkB,KAAK,GAAG,gBAAkB,KAAK,SAAS,cAAc,GACtF,KAAK,SAAS,gBAAkB,KAAK,GAAG,cAAkB,KAAK,SAAS,YAAY,GACpF,KAAK,SAAS,kBAAkB,KAAK,GAAG,gBAAkB,KAAK,SAAS,cAAc,GACtF,KAAK,SAAS,mBAAkB,KAAK,GAAG,iBAAkB,KAAK,SAAS,eAAe,GACvF,KAAK,SAAS,kBAAkB,KAAK,GAAG,gBAAkB,KAAK,SAAS,cAAc,GACtF,KAAK,SAAS,mBAAkB,KAAK,GAAG,iBAAkB,KAAK,SAAS,eAAe,GACvF,KAAK,SAAS,iBAAkB,KAAK,GAAG,eAAkB,KAAK,SAAS,aAAa,GACrF,KAAK,SAAS,mBAAkB,KAAK,GAAG,iBAAkB,KAAK,SAAS,eAAe,GACvF,KAAK,SAAS,iBAAkB,KAAK,GAAG,eAAkB,KAAK,SAAS,aAAa,GACrF,KAAK,SAAS,eAAkB,KAAK,GAAG,aAAkB,KAAK,SAAS,WAAW,GACnF,KAAK,SAAS,kBAAkB,KAAK,GAAG,gBAAkB,KAAK,SAAS,cAAc;AAAA,EAC5F;AAAA,EACA,QAAQhpB,GAAiB;AjC3nBpB,QAAAL;AiC4nBH,UAAMiJ,IAAM,KAAK,SAAS,MAAM,WAAW,CAAC5I,CAAI,CAAC;AACjD,IAAK,KAAK,SAAS,KAAK,kBAAkB4I,CAAG,MAC7C,KAAK,QAAQ,MAAA,GACb,KAAK,MAAM,QAAQ5I,CAAI,GACvB,KAAK,cAAA,GACD,KAAK,QAAQ,aACf,KAAK,QAAQ,YAAA,IACJ,KAAK,QAAQ,cACtB,KAAK,QAAQ,cAAA,KAEbL,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAa,KAAK,MAAM,WAEpC,KAAK,WAAW,aAAa,iBAAiB,OAAO,KAAK,MAAM,QAAQ,CAAC,GACzE,KAAK,WAAW,aAAa,iBAAiB,OAAO,KAAK,WAAW,cAAc,MAAM,CAAC,GAC1F,KAAK,UAAU,GAAG,KAAK,MAAM,QAAQ,WAAW,GAChD,KAAK,KAAK,cAAc,KAAK,MAAM,SAAS,GAC5CiJ,EAAI,SAAS5I,EAAK,QAClB,KAAK,SAAS,KAAK,iBAAiB4I,CAAG;AAAA,EACzC;AAAA,EAEA,UAAe;AAAE,WAAO,KAAK,MAAM,QAAA;AAAA,EAAW;AAAA,EAC9C,gBAAqB;AAAE,WAAO,KAAK,MAAM,gBAAA;AAAA,EAAmB;AAAA,EAE5D,SAAS5I,GAAiB;AjCnpBrB,QAAAL,GAAAsC;AiCopBH,UAAM6nB,IAAW,CAAC,GAAG,KAAK,MAAM,WAAA,GAAc,GAAG9pB,CAAI;AACrD,SAAK,MAAM,QAAQ8pB,CAAQ;AAC3B,UAAMla,IAAI,KAAK,MAAM;AACrB,KAAAjQ,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAaiQ,KACvB3N,IAAA,KAAK,gBAAL,QAAAA,EAAkB,aAAa2N;AAAA,EACjC;AAAA,EAEA,WAAW5P,GAAiB;AjC3pBvB,QAAAL,GAAAsC;AiC4pBH,UAAM6nB,IAAW,CAAC,GAAG9pB,GAAM,GAAG,KAAK,MAAM,YAAY;AACrD,SAAK,MAAM,QAAQ8pB,CAAQ;AAC3B,UAAMla,IAAI,KAAK,MAAM;AACrB,KAAAjQ,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAaiQ,KACvB3N,IAAA,KAAK,gBAAL,QAAAA,EAAkB,aAAa2N;AAAA,EACjC;AAAA,EAEA,YAAkB;AjCnqBb,QAAAjQ,GAAAsC;AiCoqBH,SAAK,QAAQ,MAAA,GACb,KAAK,MAAM,UAAA,IACXtC,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAa,KACvBsC,IAAA,KAAK,gBAAL,QAAAA,EAAkB,aAAa,IAC/B,KAAK,UAAU,GAAG,EAAE,GACpB,KAAK,KAAK,cAAc,EAAE;AAAA,EAC5B;AAAA,EAEA,UAAU9B,GAAkBI,IAAqB,QAAc;AjC5qB1D,QAAAZ,GAAAsC,GAAAyL,GAAAc;AiC6qBH,UAAM5F,IAAM,KAAK,SAAS,MAAM,aAAa,CAACzI,GAAMI,CAAQ,CAAC;AAC7D,QAAI,CAAC,KAAK,SAAS,KAAK,oBAAoBqI,CAAG,EAAG;AAClD,UAAMmhB,IAAMxpB,MAAa,WAAW,IAChCA,MAAa,UAAU,KAAK,MAAM,WAClCA;AACJ,SAAK,MAAM,OAAOJ,GAAM4pB,CAAG;AAC3B,UAAM,IAAI,KAAK,MAAM;AACrB,KAAApqB,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAa,KACvBsC,IAAA,KAAK,gBAAL,QAAAA,EAAkB,aAAa,IAC/B,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,KAAK,cAAc,KAAK,MAAM,SAAS,IAC5CuM,KAAAd,IAAA,KAAK,UAAS,iBAAd,QAAAc,EAAA,KAAAd,GAA6B,KAAK,MAAM,YACxC9E,EAAI,SAAS,EAAE,UAAU,GAAG,MAAAzI,EAAA,GAC5B,KAAK,SAAS,KAAK,mBAAmByI,CAAG;AAAA,EAC3C;AAAA,EAEA,QAAQiW,GAAwC;AjC7rB3C,QAAAlf,GAAAsC,GAAAyL,GAAAc;AiC+rBH,KADY,MAAM,QAAQqQ,CAAK,IAAIA,IAAQ,CAACA,CAAK,GAC7C,QAAQ,CAAAmL,MAAM,KAAK,MAAM,OAAOA,GAAI,MAAM,CAAC;AAC/C,UAAMpa,IAAI,KAAK,MAAM;AACrB,KAAAjQ,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAaiQ,KACvB3N,IAAA,KAAK,gBAAL,QAAAA,EAAkB,aAAa2N,IAC/B,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,KAAK,cAAc,KAAK,MAAM,SAAS,IAC5CpB,KAAAd,IAAA,KAAK,UAAS,iBAAd,QAAAc,EAAA,KAAAd,GAA6B,KAAK,MAAM;EAC1C;AAAA;AAAA,EAGA,WAAWmR,GAAwC;AAAE,SAAK,QAAQA,CAAK;AAAA,EAAG;AAAA,EAE1E,WAAWA,GAAwC;AjC3sB9C,QAAAlf,GAAAsC,GAAAyL,GAAAc;AiC6sBH,KADY,MAAM,QAAQqQ,CAAK,IAAIA,IAAQ,CAACA,CAAK,GAC7C,QAAQ,CAAAmL,MAAM,KAAK,MAAM,OAAOA,GAAI,OAAO,CAAC;AAChD,UAAMpa,IAAI,KAAK,MAAM;AACrB,KAAAjQ,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAaiQ,KACvB3N,IAAA,KAAK,gBAAL,QAAAA,EAAkB,aAAa2N,IAC/B,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,KAAK,cAAc,KAAK,MAAM,SAAS,IAC5CpB,KAAAd,IAAA,KAAK,UAAS,iBAAd,QAAAc,EAAA,KAAAd,GAA6B,KAAK,MAAM;EAC1C;AAAA;AAAA,EAGA,YAAYmR,GAAwC;AAAE,SAAK,WAAWA,CAAK;AAAA,EAAG;AAAA,EAE9E,UAAUle,GAAmC;AjCztBxC,QAAAhB,GAAAsC,GAAAyL,GAAAc;AiC0tBH,UAAM5F,IAAM,KAAK,SAAS,MAAM,aAAa,CAACjI,CAAQ,CAAC,GACjDspB,IAAS,MAAM,QAAQtpB,CAAQ,IAAI,CAAC,GAAGA,CAAQ,IAAI,CAACA,CAAQ;AAElE,QADAiI,EAAI,QAAQ,EAAE,MAAMqhB,EAAO,IAAI,CAAA3pB,MAAK,KAAK,MAAM,cAAcA,CAAC,CAAC,EAAA,GAC3D,CAAC,KAAK,SAAS,KAAK,oBAAoBsI,CAAG,EAAG;AAClD,UAAMshB,IAAOD,EAAO,KAAK,CAAC7nB,GAAGC,MAAMA,IAAID,CAAC;AACxC,IAAA8nB,EAAK,QAAQ,CAAA5pB,MAAK,KAAK,MAAM,UAAUA,CAAC,CAAC;AACzC,UAAM,IAAI,KAAK,MAAM;AACrB,KAAAX,IAAA,KAAK,QAAL,QAAAA,EAAU,aAAa,KACvBsC,IAAA,KAAK,gBAAL,QAAAA,EAAkB,aAAa,IAC/B,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC,KAAK,KAAK,cAAc,KAAK,MAAM,SAAS,IAC5CuM,KAAAd,IAAA,KAAK,UAAS,iBAAd,QAAAc,EAAA,KAAAd,GAA6B,KAAK,MAAM,YACxC9E,EAAI,SAAS,EAAE,SAASshB,EAAK,QAAQ,UAAU,EAAA,GAC/C,KAAK,SAAS,KAAK,mBAAmBthB,CAAG;AAAA,EAC3C;AAAA,EAEA,WAAWgR,GAAsB;AAAA,EAAgB;AAAA,EAEjD,SAASjZ,GAAkBO,GAAoB;AAC7C,WAAO,KAAK,MAAM,aAAaP,GAAUO,CAAK;AAAA,EAChD;AAAA,EACA,gBAAgBP,GAAkBO,GAAuB;AACvD,UAAM6B,IAAM,KAAK,SAASpC,GAAUO,CAAK;AACzC,WAAO6B,KAAO,OAAO,KAAK,OAAOA,CAAG;AAAA,EACtC;AAAA,EAEA,UAAUpC,GAAkBO,GAAeC,GAAkB;AjCpvBxD,QAAAxB,GAAAsC,GAAAyL,GAAAc;AiCqvBH,UAAMyM,IAAM,KAAK,SAASta,GAAUO,CAAK,GACnC0H,IAAM,KAAK,SAAS,MAAM,aAAa,CAACjI,GAAUO,GAAOC,CAAK,CAAC;AAErE,QADAyH,EAAI,QAAQ,EAAE,UAAUqS,GAAK,UAAAta,GAAU,OAAAO,EAAA,GACnC,CAAC,KAAK,SAAS,KAAK,oBAAoB0H,CAAG,EAAG;AAClD,SAAK,MAAM,WAAWjI,GAAUO,GAAOC,CAAK;AAC5C,UAAMlB,IAAM,KAAK,MAAM,cAAcU,CAAQ,GACvCmE,IAAM,KAAK,WAAW,iBAAiB5D,CAAK,GAC5CyU,IAAK,KAAK,WAAW,eAAezU,CAAK,GACzCga,IAAoB,EAAE,MAAM,WAAW,UAAAva,GAAU,aAAagV,GAAI,OAAAzU,GAAO,UAAU+Z,GAAK,UAAU9Z,GAAO,KAAAlB,GAAe,QAAQ6E,EAAA;AACtI,SAAK,KAAK,WAAWoW,CAAG,IACxBjZ,KAAAtC,IAAA,KAAK,UAAS,cAAd,QAAAsC,EAAA,KAAAtC,GAA0Bub,IAC1B,KAAK,KAAK,cAAc,KAAK,MAAM,SAAS,IAC5C1M,KAAAd,IAAA,KAAK,UAAS,iBAAd,QAAAc,EAAA,KAAAd,GAA6B,KAAK,MAAM,YACxC,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClC9E,EAAI,SAAS,EAAE,UAAAjI,GAAU,OAAAO,GAAO,UAAU+Z,GAAK,UAAU9Z,EAAA,GACzD,KAAK,SAAS,KAAK,mBAAmByH,CAAG;AAAA,EAC3C;AAAA,EAEA,SAASjI,GAAqB;AAAE,WAAO,KAAK,MAAM,cAAcA,CAAQ;AAAA,EAAQ;AAAA,EAEhF,aAAwD;AAAE,WAAO,KAAK,MAAM,WAAA;AAAA,EAAc;AAAA,EAC1F,gBAAqB;AAAE,WAAO,KAAK,MAAM,cAAA;AAAA,EAAiB;AAAA,EAC1D,iBAAsB;AAAE,WAAO,KAAK,MAAM,eAAA;AAAA,EAAkB;AAAA;AAAA,EAC5D,oBAAuH;AACrH,WAAO,KAAK,MAAM,kBAAA;AAAA,EACpB;AAAA,EACA,eAAoB;AAAE,WAAO,KAAK,MAAM,aAAA;AAAA,EAAgB;AAAA,EACxD,iBAAsB;AAAE,WAAO,KAAK,MAAM,eAAA;AAAA,EAAkB;AAAA,EAC5D,eAAeA,GAAiC;AAAE,WAAO,KAAK,MAAM,eAAeA,CAAQ;AAAA,EAAG;AAAA,EAC9F,iBAAiBmB,GAAyB;AAAE,WAAO,KAAK,MAAM,iBAAiBA,CAAU;AAAA,EAAG;AAAA,EAC5F,OAAa;AAAA,EAAC;AAAA,EACd,OAAa;AAAA,EAAC;AAAA,EACd,eAAqB;AAAA,EAAC;AAAA,EACtB,gBAAgC;AAAE,WAAO,KAAK,WAAW;AAAA,EAAe;AAAA,EACxE,mBAAmC;AAAE,WAAO,KAAK,WAAW;AAAA,EAAQ;AAAA,EACpE,iBAAyB;AAAE,WAAO,KAAK,WAAW,cAAc;AAAA,EAAQ;AAAA,EACxE,aAAayC,GAA+B;AAC1C,UAAMqE,IAAM,KAAK,SAAS,MAAM,gBAAgB,CAACrE,CAAO,CAAC;AACzD,IAAK,KAAK,SAAS,KAAK,uBAAuBqE,CAAG,MAClD,KAAK,WAAW,WAAWrE,CAAO,GAClC,KAAK,cAAc,KAAK,WAAW,sBAAA,EAAwB,KAAK,GAChE,KAAK,cAAA,GACL,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW,GAClCqE,EAAI,SAAS,EAAE,aAAarE,EAAQ,OAAA,GACpC,KAAK,SAAS,KAAK,sBAAsBqE,CAAG;AAAA,EAC9C;AAAA,EACA,aAAa5D,GAAsBzE,GAA2B;AAC5D,SAAK,WAAW,UAAUyE,GAAQzE,CAAe,GACjD,KAAK,cAAc,KAAK,WAAW,sBAAA,EAAwB,KAAK,GAChE,KAAK,cAAA,GAAiB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAC1D;AAAA,EACA,aAAaW,GAAqB;AAChC,SAAK,WAAW,aAAaA,CAAK,GAClC,KAAK,cAAc,KAAK,WAAW,sBAAA,EAAwB,KAAK,GAChE,KAAK,cAAA,GAAiB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAC1D;AAAA,EAEQ,eAAemT,GAAiB8U,GAAqB;AjC9yBxD,QAAAxpB,GAAAsC;AiC+yBH,UAAMwC,IAAS,KAAK,WAAW,cAAc,IAAI,OAAKgP,CAAiB;AACvE,QAAIY,IAAU,KAAK8U,IAAQ,KAAK9U,KAAW5P,EAAO,UAAU0kB,KAAS1kB,EAAO,OAAQ;AACpF,UAAM0lB,IAAY,CAAC,GAAG,KAAK,SAAS,OAAO,GACrC,CAACC,CAAK,IAAID,EAAU,OAAO9V,GAAS,CAAC;AAC3C,IAAA8V,EAAU,OAAOhB,GAAO,GAAGiB,CAAK,GAChC,KAAK,SAAS,UAAUD,GACxB,KAAK,aAAaA,CAAS,IAC3BloB,KAAAtC,IAAA,KAAK,UAAS,oBAAd,QAAAsC,EAAA,KAAAtC,GAAgC,EAAE,WAAW0U,GAAS,SAAS8U,GAAO,OAAOiB,EAAM,SAAS,GAAA;AAAA,EAC9F;AAAA,EACA,WAAWlpB,GAAgC;AACzC,SAAK,WAAW,WAAWA,CAAK,GAChC,KAAK,cAAc,KAAK,WAAW,sBAAA,EAAwB,KAAK,GAChE,KAAK,cAAA,GAAiB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAC1D;AAAA,EACA,WAAWA,GAAgC;AACzC,SAAK,WAAW,WAAWA,CAAK,GAChC,KAAK,cAAc,KAAK,WAAW,sBAAA,EAAwB,KAAK,GAChE,KAAK,cAAA,GAAiB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAC1D;AAAA,EACA,eAAeA,GAAuB;AAAE,WAAO,KAAK,WAAW,eAAeA,CAAK;AAAA,EAAG;AAAA,EACtF,WAAWV,GAAqB;AjCn0B3B,QAAAb;AiCm0B6B,aAAOA,IAAA,KAAK,WAAW,iBAAiBa,CAAG,MAApC,gBAAAb,EAAuC,UAAS;AAAA,EAAI;AAAA,EAC7F,aAAauB,GAAempB,IAAO,IAAc;AAAE,WAAO,KAAK,MAAM,QAAA,EAAU,IAAI,CAAAjqB,MAAKA,EAAEc,CAAK,CAAC;AAAA,EAAG;AAAA,EACnG,gBAAgBA,GAAe6a,IAAM,IAAc;AAAE,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,aAAa7a,GAAO6a,CAAG,CAAC,CAAC;AAAA,EAAG;AAAA,EACzG,aAAauO,GAAyB;AAAA,EAAC;AAAA,EACvC,cAAcC,IAAa,IAAiB;AAAE,WAAO,CAAA;AAAA,EAAI;AAAA,EACzD,gBAAqB;AAAE,WAAO,KAAK,QAAQ,cAAA;AAAA,EAAiB;AAAA,EAC5D,eAAuB;AAAE,WAAO,KAAK,QAAQ,aAAA;AAAA,EAAgB;AAAA,EAC7D,SAASrlB,GAAqB;AAAE,SAAK,QAAQ,SAASA,CAAK,GAAG,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAAG;AAAA,EACnG,WAAiB;AAAE,SAAK,QAAQ,SAAA,GAAY,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAAG;AAAA,EACjF,aAAkD;AAAE,WAAO,KAAK,QAAQ,WAAA;AAAA,EAAc;AAAA,EACtF,gBAAqB;AAAE,WAAO,KAAK,QAAQ,cAAA;AAAA,EAAiB;AAAA,EAC5D,UAAU0U,GAAsB;AAAA,EAAC;AAAA,EACjC,aAAaA,GAAsB;AAAA,EAAC;AAAA,EACpC,aAAa1Y,GAAeoO,GAAqB;AAC/C,SAAK,QAAQ,aAAapO,GAAOoO,CAAM,GACvC,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA,EACA,YAAYsK,GAAsB;AAAA,EAAC;AAAA,EACnC,aAAmB;AAAE,SAAK,QAAQ,WAAA,GAAc,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAAG;AAAA,EACrF,QAAQiO,GAAkCtlB,IAAsB,OAAa;AAC3E,UAAMqG,IAAM,KAAK,SAAS,MAAM,WAAW,CAACif,GAAatlB,CAAG,CAAC;AAC7D,IAAK,KAAK,SAAS,KAAK,kBAAkBqG,CAAG,MAC7C,KAAK,OAAO,KAAKif,GAAatlB,CAAG,GACjCqG,EAAI,SAAS,EAAE,UAAU,KAAK,OAAO,SAAA,GACrC,KAAK,SAAS,KAAK,iBAAiBA,CAAG;AAAA,EACzC;AAAA,EACA,aAAmB;AAAE,SAAK,OAAO,UAAA;AAAA,EAAa;AAAA,EAC9C,UAAU1H,GAAe4mB,GAAiC;AACxD,UAAMlf,IAAM,KAAK,SAAS,MAAM,aAAa,CAAC1H,GAAO4mB,CAAW,CAAC;AACjE,IAAK,KAAK,SAAS,KAAK,oBAAoBlf,CAAG,MAC/C,KAAK,OAAO,UAAU1H,GAAO4mB,CAAW,GACxClf,EAAI,SAAS,EAAE,OAAA1H,GAAO,eAAe,KAAK,MAAM,SAAA,GAChD,KAAK,SAAS,KAAK,mBAAmB0H,CAAG;AAAA,EAC3C;AAAA,EACA,YAAY1H,GAAsB;AAAE,SAAK,OAAO,YAAYA,CAAK;AAAA,EAAG;AAAA,EACpE,iBAA+C;AAAE,WAAO,KAAK,OAAO,eAAA;AAAA,EAAkB;AAAA,EACtF,cAAcK,GAA2C;AAAE,SAAK,OAAO,cAAcA,CAAK;AAAA,EAAG;AAAA,EACrF,gBAAsB;AAAE,SAAK,OAAO,aAAA;AAAA,EAAgB;AAAA,EAC5D,OAAOqO,GAAiB;AAAE,SAAK,WAAW,UAAUA,CAAC,GAAG,KAAK,cAAA,GAAiB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EAAG;AAAA;AAAA,EAEnH,WAAWsO,GAA0B;AACnC,SAAK,aAAa,gBAAgBA,CAAK,GACvC,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA;AAAA;AAAA,EAGA,UAAUpb,GAAwB;AAChC,UAAM2B,IAAS,KAAK,WAAW,eACzB2Z,IAAuB,CAAA,GACvBoM,IAAuB,CAAA;AAC7B,eAAWrnB,KAAKL,GAAQ;AACtB,YAAM6S,IAAKlR,EAAO,UAAU,CAAA,MAAK,EAAE,UAAUtB,CAAC;AAC9C,MAAIwS,KAAM,MAAKyI,EAAW,KAAKzI,CAAE,GAAG6U,EAAW,KAAKrnB,CAAC;AAAA,IACvD;AACA,SAAK,aAAa,eAAe,KAAK,MAAM,QAAA,GAAWib,GAAYoM,CAAU,GAC7E,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA;AAAA,EAGA,aAAmB;AACjB,SAAK,aAAa,MAAA,GAClB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA,EACA,WAAWd,GAAkB;AAAA,EAAC;AAAA,EAC9B,QAAQ5mB,GAAwB;AAC9B,UAAM8F,IAAM,KAAK,SAAS,MAAM,WAAW,CAAC9F,CAAM,CAAC;AACnD,IAAK,KAAK,SAAS,KAAK,kBAAkB8F,CAAG,MAC7C,KAAK,QAAQ,QAAQ9F,CAAM,GAC3B8F,EAAI,SAAS,EAAE,QAAA9F,EAAA,GACf,KAAK,SAAS,KAAK,iBAAiB8F,CAAG;AAAA,EACzC;AAAA,EACA,aAAmB;AAAE,SAAK,QAAQ,WAAA;AAAA,EAAc;AAAA,EAChD,YAAkB;AAAE,SAAK,QAAQ,UAAA;AAAA,EAAa;AAAA,EAC9C,cAAoB;AAAE,SAAK,QAAQ,YAAA;AAAA,EAAe;AAAA,EAClD,aAAmB;AAAE,SAAK,QAAQ,WAAA;AAAA,EAAc;AAAA,EAChD,cAAoB;AAAE,SAAK,QAAQ,YAAA;AAAA,EAAe;AAAA,EAClD,YAAYse,GAAkBK,IAAO,IAAY;AAAE,SAAK,QAAQ,YAAYL,GAAKK,CAAI;AAAA,EAAG;AAAA,EACxF,iBAAuB;AAAE,SAAK,QAAQ,eAAA;AAAA,EAAkB;AAAA,EACxD,mBAAyB;AAAE,SAAK,QAAQ,iBAAA;AAAA,EAAoB;AAAA,EAC5D,WAAWkD,GAAmBC,GAAcC,GAAuB;AAAA,EAAC;AAAA,EACpE,YAAYlnB,GAAwC;AAAE,SAAK,WAAW,YAAYA,CAAO;AAAA,EAAG;AAAA,EAC5F,UAAUA,GAAwC;AAAE,SAAK,WAAW,UAAUA,CAAO;AAAA,EAAG;AAAA,EACxF,WAAWA,GAAwC;AAAE,SAAK,WAAW,WAAWA,CAAO;AAAA,EAAG;AAAA,EAC1F,MAAMA,GAA8D;AAAE,SAAK,WAAW,MAAMA,CAAO;AAAA,EAAG;AAAA,EAEtG,QAAQmnB,IAAW,IAAa;AAC9B,UAAM5qB,IAAO,KAAK,MAAM,QAAA;AACxB,QAAI4qB,EAAU,QAAO5qB;AACrB,UAAM4E,IAAO,KAAK,WAAW;AAC7B,WAAO5E,EAAK,IAAI,CAAAC,MAAO2E,EAAK,IAAI,OAAK3E,EAAI8E,EAAE,KAAK,CAAC,CAAC;AAAA,EACpD;AAAA,EACA,UAAUpE,GAAwB;AjC95B7B,QAAAhB;AiC+5BH,SAAK,QAAQ,aAAagB,CAAQ,IAClChB,IAAA,KAAK,QAAL,QAAAA,EAAU,YAAYgB,IACtB,KAAK,UAAU,GAAG,KAAK,UAAA,CAAW;AAAA,EACpC;AAAA,EACA,UAAUkqB,GAAsB;AAAA,EAAC;AAAA,EACjC,eAAyC;AjCp6BpC,QAAAlrB,GAAAsC;AiCq6BH,WAAO,EAAE,KAAGtC,IAAA,KAAK,cAAL,gBAAAA,EAAgB,YAAY,eAAc,GAAG,KAAGsC,IAAA,KAAK,cAAL,gBAAAA,EAAgB,YAAY,cAAa,EAAA;AAAA,EACvG;AAAA,EACA,UAAU6oB,GAAiB;AACzB,SAAK,SAAS,SAASA,GACvB,KAAK,gBAAA;AAAA,EACP;AAAA,EACA,gBAAuB;AAAE,WAAO,KAAK,WAAW,cAAA;AAAA,EAAiB;AAAA,EACjE,eAAe5pB,GAAoB;AjC56B9B,QAAAvB;AiC66BH,aAAOA,IAAA,KAAK,WAAW,cAAA,EAAgB,KAAK,CAACS,MAAWA,EAAE,WAAWc,CAAK,MAAnE,gBAAAvB,EAAsE,WAAU;AAAA,EACzF;AAAA,EACQ,kBAAwB;AAAE,SAAK,WAAW,OAAA;AAAA,EAAU;AAAA,EAE5D,OAAOgP,GAAYC,GAAkB;AACnC,IAAID,MAAG,KAAK,WAAW,MAAM,QAAQ,GAAGA,CAAC,OACrCC,MAAG,KAAK,WAAW,MAAM,SAAS,GAAGA,CAAC,OAC1C,KAAK,UAAA;AAAA,EACP;AAAA,EACA,SAASsQ,GAAqB;AAAE,SAAK,WAAW,aAAa,iBAAiBA,CAAK;AAAA,EAAG;AAAA,EACtF,YAAYxd,GAAW0B,GAAiB;AAAE,SAAK,WAAW,MAAM,YAAY1B,GAAG0B,CAAC;AAAA,EAAG;AAAA,EACnF,WAAWjE,GAA8BC,GAA+B;AACtE,gBAAK,SAAS,IAAID,GAAOC,CAAO,GAAU;AAAA,EAC5C;AAAA,EACA,cAAcD,GAA8BC,GAA+B;AACzE,gBAAK,SAAS,OAAOD,GAAOC,CAAO,GAAU;AAAA,EAC/C;AAAA,EACA,cAAcD,GAAqC;AACjD,gBAAK,SAAS,MAAMA,CAAK,GAAU;AAAA,EACrC;AAAA,EACQ,OAAOupB,GAAmBlpB,GAA6B;AAAE,WAAO,KAAK,SAAS,MAAMkpB,GAAWlpB,CAAI;AAAA,EAAG;AAAA,EACtG,MAAML,GAAeyJ,GAA8B;AAAE,WAAO,KAAK,SAAS,KAAKzJ,GAAOyJ,CAAG;AAAA,EAAG;AAAA,EAEpG,UAAgB;AjCp8BX,QAAAjJ,GAAAsC,GAAAyL,GAAAc,GAAAC,GAAAuZ,GAAAC,GAAA8C;AiCq8BH,IAAI,KAAK,eACT,KAAK,aAAa,IAClB,KAAK,SAAS,MAAA,IACdprB,IAAA,KAAK,QAAL,QAAAA,EAAU,eACVsC,IAAA,KAAK,QAAL,QAAAA,EAAU,YACVyL,IAAA,KAAK,iBAAL,QAAAA,EAAmB,YACnBc,IAAA,KAAK,SAAL,QAAAA,EAAW,WACP,KAAK,cAAe,KAAK,WAAW,oBAAoB,eAAe,KAAK,UAAU,GACtF,KAAK,iBAAe,KAAK,WAAW,oBAAoB,WAAe,KAAK,aAAa,GAC7F,KAAK,aAAa,KAAK,gBAAgB,OACvCC,IAAA,KAAK,aAAL,QAAAA,EAAe,YACfuZ,IAAA,KAAK,eAAL,QAAAA,EAAiB,YACjBC,IAAA,KAAK,cAAL,QAAAA,EAAgB,YAChB8C,IAAA,KAAK,gBAAL,QAAAA,EAAkB,UAClB,KAAK,cAAc,MACnB,KAAK,WAAW,YAAY,IAC5B,KAAK,WAAW,UAAU,OAAO,cAAc,GAC/C,KAAK,mBAAA;AAAA,EACP;AACF;"}