hwpkit-dev 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ .npmignore +1 -0
- package/dist/index.d.mts +34 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +2138 -245
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2134 -245
- package/dist/index.mjs.map +1 -1
- package/hwp-analyze.ts +90 -0
- package/inspect-doc.ts +57 -0
- package/output_test.hwp +0 -0
- package/package.json +3 -1
- package/src/decoders/docx/DocxDecoder.ts +155 -30
- package/src/decoders/hwp/HwpScanner.ts +258 -37
- package/src/decoders/hwpx/HwpxDecoder.ts +9 -1
- package/src/encoders/docx/DocxEncoder.ts +199 -158
- package/src/encoders/html/HtmlEncoder.ts +205 -0
- package/src/encoders/hwp/HwpEncoder.ts +864 -222
- package/src/encoders/hwpx/HwpxEncoder.ts +119 -59
- package/src/encoders/md/MdEncoder.ts +98 -16
- package/src/index.ts +1 -0
- package/src/model/builders.ts +4 -2
- package/src/model/doc-tree.ts +1 -1
- package/src/pipeline/Pipeline.ts +14 -1
- package/src/safety/StyleBridge.ts +1 -1
- package/test-docx-to-hwp.ts +45 -0
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contract/result.ts","../src/pipeline/registry.ts","../src/model/doc-props.ts","../src/model/builders.ts","../src/safety/ShieldedParser.ts","../src/safety/StyleBridge.ts","../src/toolkit/ArchiveKit.ts","../src/toolkit/XmlKit.ts","../src/toolkit/TextKit.ts","../src/decoders/hwpx/HwpxDecoder.ts","../src/toolkit/BinaryKit.ts","../src/decoders/hwp/HwpScanner.ts","../src/decoders/docx/DocxDecoder.ts","../src/decoders/md/MdDecoder.ts","../src/encoders/hwpx/HwpxEncoder.ts","../src/encoders/docx/DocxEncoder.ts","../src/encoders/md/MdEncoder.ts","../src/pipeline/Pipeline.ts","../src/walk/TreeWalker.ts","../src/walk/tree-ops.ts"],"sourcesContent":["export type Outcome<T> = Ok<T> | Fail;\n\nexport interface Ok<T> {\n ok: true;\n data: T;\n warns: string[];\n}\n\nexport interface Fail {\n ok: false;\n error: string;\n warns: string[];\n}\n\nexport function succeed<T>(data: T, warns: string[] = []): Ok<T> {\n return { ok: true, data, warns };\n}\n\nexport function fail(error: string, warns: string[] = []): Fail {\n return { ok: false, error, warns };\n}\n","import type { Decoder } from '../contract/decoder';\nimport type { Encoder } from '../contract/encoder';\n\nclass FormatRegistry {\n private decoders = new Map<string, Decoder>();\n private encoders = new Map<string, Encoder>();\n\n registerDecoder(d: Decoder): void { this.decoders.set(d.format, d); }\n registerEncoder(e: Encoder): void { this.encoders.set(e.format, e); }\n\n getDecoder(fmt: string): Decoder | undefined { return this.decoders.get(fmt); }\n getEncoder(fmt: string): Encoder | undefined { return this.encoders.get(fmt); }\n\n supportedInputs(): string[] { return [...this.decoders.keys()]; }\n supportedOutputs(): string[] { return [...this.encoders.keys()]; }\n}\n\nexport const registry = new FormatRegistry();\n","export type Align = 'left' | 'center' | 'right' | 'justify';\nexport type VAlign = 'top' | 'mid' | 'bot';\nexport type Heading = 1 | 2 | 3 | 4 | 5 | 6;\nexport type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none';\n\nexport interface TextProps {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n sup?: boolean;\n sub?: boolean;\n font?: string;\n pt?: number;\n color?: string;\n bg?: string;\n}\n\nexport interface ParaProps {\n align?: Align;\n heading?: Heading;\n indentPt?: number;\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n listLv?: number;\n listOrd?: boolean;\n listMark?: string;\n}\n\nexport interface Stroke {\n kind: StrokeKind;\n pt: number;\n color: string;\n}\n\nexport interface CellProps {\n top?: Stroke;\n bot?: Stroke;\n left?: Stroke;\n right?: Stroke;\n bg?: string;\n padPt?: number;\n align?: Align;\n va?: VAlign;\n isHeader?: boolean;\n}\n\nexport interface TableLook {\n firstRow?: boolean;\n lastRow?: boolean;\n firstCol?: boolean;\n lastCol?: boolean;\n bandedRows?: boolean;\n bandedCols?: boolean;\n}\n\nexport interface GridProps {\n widthPct?: number;\n colWidths?: number[]; // column widths in points\n defaultStroke?: Stroke;\n look?: TableLook;\n headerRow?: boolean;\n}\n\nexport interface PageDims {\n wPt: number;\n hPt: number;\n mt: number;\n mb: number;\n ml: number;\n mr: number;\n orient?: 'portrait' | 'landscape';\n}\n\nexport interface DocMeta {\n title?: string;\n author?: string;\n subject?: string;\n desc?: string;\n keywords?: string;\n created?: string;\n modified?: string;\n}\n\nexport const A4: PageDims = {\n wPt: 595.28, hPt: 841.89,\n mt: 56.69, mb: 56.69, ml: 70.87, mr: 70.87,\n orient: 'portrait',\n};\n\nexport const DEFAULT_STROKE: Stroke = { kind: 'solid', pt: 0.5, color: '000000' };\n","import type {\n DocRoot, SheetNode, ParaNode, SpanNode, ImgNode,\n GridNode, RowNode, CellNode, ContentNode, TxtNode, PageNumNode,\n} from './doc-tree';\nimport type { TextProps, ParaProps, CellProps, GridProps, DocMeta, PageDims } from './doc-props';\nimport { A4 } from './doc-props';\n\nexport function buildRoot(meta: DocMeta = {}, kids: SheetNode[] = []): DocRoot {\n return { tag: 'root', meta, kids };\n}\n\nexport function buildSheet(\n kids: ContentNode[] = [],\n dims: PageDims = A4,\n opts?: { header?: ParaNode[]; footer?: ParaNode[] },\n): SheetNode {\n const node: SheetNode = { tag: 'sheet', dims, kids };\n if (opts?.header) node.header = opts.header;\n if (opts?.footer) node.footer = opts.footer;\n return node;\n}\n\nexport function buildPageNum(format?: PageNumNode['format']): PageNumNode {\n return { tag: 'pagenum', format };\n}\n\nexport function buildPara(kids: ParaNode['kids'] = [], props: ParaProps = {}): ParaNode {\n return { tag: 'para', props, kids };\n}\n\nexport function buildSpan(content: string, props: TextProps = {}): SpanNode {\n const txt: TxtNode = { tag: 'txt', content };\n return { tag: 'span', props, kids: [txt] };\n}\n\nexport function buildImg(\n b64: string,\n mime: ImgNode['mime'],\n w: number,\n h: number,\n alt?: string,\n): ImgNode {\n return { tag: 'img', b64, mime, w, h, alt };\n}\n\nexport function buildGrid(kids: RowNode[], props: GridProps = {}): GridNode {\n return { tag: 'grid', props, kids };\n}\n\nexport function buildRow(kids: CellNode[]): RowNode {\n return { tag: 'row', kids };\n}\n\nexport function buildCell(\n kids: ParaNode[],\n opts: { cs?: number; rs?: number; props?: CellProps } = {},\n): CellNode {\n return { tag: 'cell', cs: opts.cs ?? 1, rs: opts.rs ?? 1, props: opts.props ?? {}, kids };\n}\n","export class ShieldedParser {\n private log: string[] = [];\n\n /** 단일 요소 안전 파싱 */\n guard<T>(fn: () => T, fallback: T, label: string): T {\n try {\n const v = fn();\n if (v == null) {\n this.warn(label, 'returned null/undefined');\n return fallback;\n }\n return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n return fallback;\n }\n }\n\n /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */\n guardAll<I, O>(\n items: I[],\n fn: (x: I, i: number) => O,\n fb: (x: I, i: number) => O,\n label: string,\n ): O[] {\n return items.map((x, i) =>\n this.guard(() => fn(x, i), fb(x, i), `${label}[${i}]`),\n );\n }\n\n /**\n * 표 전용 4단계 폴백\n * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text\n */\n guardGrid<T>(\n node: unknown,\n lv1Full: (n: unknown) => T,\n lv2Grid: (n: unknown) => T,\n lv3Flat: (n: unknown) => T,\n lv4Text: (n: unknown) => T,\n label: string,\n ): { value: T; level: 1 | 2 | 3 | 4 } {\n const levels: [(n: unknown) => T, 1 | 2 | 3 | 4][] = [\n [lv1Full, 1], [lv2Grid, 2], [lv3Flat, 3], [lv4Text, 4],\n ];\n\n for (const [fn, lv] of levels) {\n try {\n const v = fn(node);\n if (v != null) {\n if (lv > 1) this.warn(label, `degraded to level ${lv}`);\n return { value: v, level: lv };\n }\n } catch (e: any) {\n this.warn(label, `Lv${lv} failed: ${e?.message ?? String(e)}`);\n }\n }\n\n this.warn(label, 'ALL LEVELS FAILED — returning lv4Text forced');\n return { value: lv4Text(null), level: 4 };\n }\n\n /** 이미지 안전 파싱 */\n guardImg<T>(\n node: unknown,\n fn: (n: unknown) => T,\n placeholder: (alt: string) => T,\n label: string,\n ): T {\n try {\n const v = fn(node);\n if (v != null) return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n }\n this.warn(label, 'using placeholder image');\n return placeholder(`[이미지 로드 실패: ${label}]`);\n }\n\n private warn(label: string, msg: string): void {\n const w = `[SHIELD] ${label}: ${msg}`;\n console.warn(w);\n this.log.push(w);\n }\n\n flush(): string[] {\n const r = [...this.log];\n this.log = [];\n return r;\n }\n}\n","import type { Align, StrokeKind, Stroke } from '../model/doc-props';\n\n// ─── 단위 변환 ─────────────────────────────────────────────\nexport const Metric = {\n // HWP 세계 (1 inch = 7200 HWPUNIT)\n hwpToPt: (v: number) => v / 100,\n ptToHwp: (v: number) => Math.round(v * 100),\n hwpToDxa: (v: number) => Math.round(v / 5),\n dxaToHwp: (v: number) => Math.round(v * 5),\n hwpToEmu: (v: number) => Math.round(v * 127),\n emuToHwp: (v: number) => Math.round(v / 127),\n\n // DOCX 세계 (1 inch = 1440 dxa, 1 pt = 20 dxa)\n dxaToPt: (v: number) => v / 20,\n ptToDxa: (v: number) => Math.round(v * 20),\n dxaToEmu: (v: number) => Math.round(v * 635),\n emuToDxa: (v: number) => Math.round(v / 635),\n emuToPt: (v: number) => v / 12700,\n ptToEmu: (v: number) => Math.round(v * 12700),\n\n // HWPX charPr height: 1000 = 10pt\n hHeightToPt: (v: number) => v / 100,\n ptToHHeight: (v: number) => Math.round(v * 100),\n\n // DOCX half-point: 24 = 12pt\n halfPtToPt: (v: number) => v / 2,\n ptToHalfPt: (v: number) => Math.round(v * 2),\n} as const;\n\n// ─── 색상 정규화 ───────────────────────────────────────────\nexport function safeHex(raw: string | number | null | undefined): string | undefined {\n if (raw == null) return undefined;\n if (typeof raw === 'number') {\n if (raw <= 0) return '000000';\n if (raw >= 0xFFFFFF) return undefined;\n return raw.toString(16).padStart(6, '0').toUpperCase();\n }\n let s = String(raw).replace(/^#/, '').toUpperCase();\n if (/^[0-9A-F]{3}$/.test(s)) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2];\n if (/^[0-9A-F]{6}$/.test(s)) return s;\n if (s === 'AUTO' || s === 'NONE' || s === 'TRANSPARENT') return undefined;\n return undefined;\n}\n\n// ─── 정렬 정규화 ───────────────────────────────────────────\nconst ALIGN_MAP: Record<string, Align> = {\n LEFT: 'left', CENTER: 'center', RIGHT: 'right', JUSTIFY: 'justify',\n BOTH: 'justify', DISTRIBUTE: 'justify',\n left: 'left', center: 'center', right: 'right', both: 'justify',\n start: 'left', end: 'right',\n};\nexport function safeAlign(raw?: string): Align {\n return ALIGN_MAP[raw ?? ''] ?? 'justify';\n}\n\n// ─── 테두리 정규화 ─────────────────────────────────────────\nconst HWPX_STROKE: Record<string, StrokeKind> = {\n SOLID: 'solid', NONE: 'none', DASH: 'dash', DOT: 'dot',\n DOUBLE: 'double', LONG_DASH: 'dash', DASH_DOT: 'dash',\n};\nconst DOCX_STROKE: Record<string, StrokeKind> = {\n single: 'solid', none: 'none', nil: 'none', dashed: 'dash',\n dotted: 'dot', double: 'double', wave: 'solid',\n};\n\nexport function safeStrokeHwpx(type?: string, w?: number, c?: string): Stroke {\n return {\n kind: HWPX_STROKE[type ?? ''] ?? 'solid',\n pt: w != null ? Metric.hwpToPt(w) : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\nexport function safeStrokeDocx(val?: string, sz?: number, c?: string): Stroke {\n return {\n kind: DOCX_STROKE[val ?? ''] ?? 'solid',\n pt: sz != null ? sz / 8 : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\n// ─── 폰트 정규화 ───────────────────────────────────────────\nconst FONT_MAP: Record<string, string> = {\n '맑은 고딕': 'Malgun Gothic',\n '바탕': 'Batang',\n '돋움': 'Dotum',\n '굴림': 'Gulim',\n '한컴바탕': 'Batang',\n '한컴돋움': 'Malgun Gothic',\n '함초롬바탕': 'Batang',\n '함초롬돋움': 'Malgun Gothic',\n};\nexport function safeFont(raw?: string): string {\n return FONT_MAP[raw ?? ''] ?? raw ?? 'Malgun Gothic';\n}\n\n// Reverse mapping: English → Korean (for HWPX encoding)\nconst FONT_MAP_KR: Record<string, string> = {\n 'Malgun Gothic': '맑은 고딕',\n 'Batang': '바탕',\n 'Dotum': '돋움',\n 'Gulim': '굴림',\n};\nexport function safeFontToKr(raw?: string): string {\n return FONT_MAP_KR[raw ?? ''] ?? raw ?? '맑은 고딕';\n}\n","import pako from 'pako';\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nexport const ArchiveKit = {\n async inflate(compressed: Uint8Array): Promise<Uint8Array> {\n return pako.inflate(compressed);\n },\n\n async deflate(data: Uint8Array): Promise<Uint8Array> {\n return pako.deflate(data, { level: 6 });\n },\n\n async unzip(zipData: Uint8Array): Promise<Map<string, Uint8Array>> {\n const files = new Map<string, Uint8Array>();\n const view = new DataView(zipData.buffer, zipData.byteOffset, zipData.byteLength);\n\n let offset = 0;\n while (offset < zipData.length - 4) {\n const sig = view.getUint32(offset, true);\n\n if (sig === 0x04034b50) {\n const compressionMethod = view.getUint16(offset + 8, true);\n const compressedSize = view.getUint32(offset + 18, true);\n const uncompressedSize = view.getUint32(offset + 22, true);\n const fileNameLength = view.getUint16(offset + 26, true);\n const extraLength = view.getUint16(offset + 28, true);\n\n const nameBytes = zipData.subarray(offset + 30, offset + 30 + fileNameLength);\n const name = new TextDecoder('utf-8').decode(nameBytes);\n\n const dataOffset = offset + 30 + fileNameLength + extraLength;\n let fileData: Uint8Array;\n\n if (compressionMethod === 0) {\n fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize);\n } else if (compressionMethod === 8) {\n const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize);\n fileData = pako.inflateRaw(compressed);\n } else {\n throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`);\n }\n\n files.set(name, new Uint8Array(fileData));\n offset = dataOffset + compressedSize;\n } else if (sig === 0x02014b50 || sig === 0x06054b50) {\n break;\n } else {\n offset++;\n }\n }\n\n return files;\n },\n\n async zip(entries: ZipEntry[]): Promise<Uint8Array> {\n const localHeaders: Uint8Array[] = [];\n const centralHeaders: Uint8Array[] = [];\n let localOffset = 0;\n\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n const crc = crc32(entry.data);\n\n // 'mimetype' and 'version.xml' must be stored uncompressed per HWPX spec\n const store = entry.name === 'mimetype' || entry.name === 'version.xml';\n const method = store ? 0 : 8;\n const payload = store ? entry.data : pako.deflateRaw(entry.data, { level: 6 });\n\n // Local file header (30 bytes + name + data)\n const local = new Uint8Array(30 + nameBytes.length + payload.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0, true);\n lv.setUint16(8, method, true);\n lv.setUint16(10, 0, true);\n lv.setUint16(12, 0x0021, true); // date (1980-01-01)\n lv.setUint32(14, crc, true);\n lv.setUint32(18, payload.length, true);\n lv.setUint32(22, entry.data.length, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n local.set(payload, 30 + nameBytes.length);\n\n // Central directory header (46 bytes + name)\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0, true);\n cv.setUint16(10, method, true);\n cv.setUint16(12, 0, true); // mod time\n cv.setUint16(14, 0x0021, true); // mod date (1980-01-01)\n cv.setUint32(16, crc, true);\n cv.setUint32(20, payload.length, true);\n cv.setUint32(24, entry.data.length, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, localOffset, true);\n central.set(nameBytes, 46);\n\n localHeaders.push(local);\n centralHeaders.push(central);\n localOffset += local.length;\n }\n\n const centralDir = concat(centralHeaders);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDir.length, true);\n ev.setUint32(16, localOffset, true);\n ev.setUint16(20, 0, true);\n\n return concat([...localHeaders, centralDir, eocd]);\n },\n};\n\nfunction concat(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const a of arrays) { out.set(a, offset); offset += a.length; }\n return out;\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xFFFFFFFF;\n for (const byte of data) {\n crc ^= byte;\n for (let i = 0; i < 8; i++) {\n crc = (crc & 1) ? (crc >>> 1) ^ 0xEDB88320 : crc >>> 1;\n }\n }\n return (crc ^ 0xFFFFFFFF) >>> 0;\n}\n","import { SaxesParser } from 'saxes';\n\n// Parses XML into an xml2js-compatible object structure:\n// { tagName: [{ _attr: { k: v }, _text: '...', childTag: [...] }] }\nfunction parseXmlStrict(xml: string): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const parser = new SaxesParser({ xmlns: false });\n\n interface Frame { tag: string; obj: Record<string, unknown> }\n const stack: Frame[] = [];\n let result: unknown = null;\n\n parser.on('error', (err: Error) => reject(err));\n\n parser.on('opentag', (node: any) => {\n const obj: Record<string, unknown> = {};\n const attrs = node.attributes as Record<string, string>;\n if (attrs && Object.keys(attrs).length > 0) {\n obj['_attr'] = { ...attrs };\n }\n stack.push({ tag: node.name as string, obj });\n });\n\n const appendText = (text: string) => {\n if (stack.length > 0 && text) {\n const frame = stack[stack.length - 1];\n const cur = frame.obj['_text'];\n frame.obj['_text'] = typeof cur === 'string' ? cur + text : text;\n }\n };\n\n parser.on('text', (text: string) => appendText(text));\n parser.on('cdata', (cdata: string) => appendText(cdata));\n\n parser.on('closetag', () => {\n const frame = stack.pop();\n if (!frame) return;\n const { tag, obj } = frame;\n\n // Drop whitespace-only _text\n if (typeof obj['_text'] === 'string' && !(obj['_text'] as string).trim()) {\n delete obj['_text'];\n }\n\n if (stack.length === 0) {\n result = { [tag]: [obj] };\n } else {\n const parent = stack[stack.length - 1].obj;\n const existing = parent[tag];\n if (Array.isArray(existing)) {\n (existing as unknown[]).push(obj);\n } else {\n parent[tag] = [obj];\n }\n // Track child order for document-order iteration\n if (!parent['_childOrder']) parent['_childOrder'] = [];\n (parent['_childOrder'] as string[]).push(tag);\n }\n });\n\n try {\n parser.write(xml).close();\n resolve(result);\n } catch (e) {\n reject(e);\n }\n });\n}\n\nexport const XmlKit = {\n /** @deprecated Use parseStrict instead */\n async parse(xml: string): Promise<unknown> {\n return parseXmlStrict(xml);\n },\n\n async parseStrict(xml: string): Promise<unknown> {\n return parseXmlStrict(xml);\n },\n\n attr(node: Record<string, unknown>, key: string): string | undefined {\n const a = node['_attr'] as Record<string, string> | undefined;\n return a?.[key];\n },\n\n text(node: Record<string, unknown> | string | undefined): string {\n if (node == null) return '';\n if (typeof node === 'string') return node;\n const t = node['_text'];\n return typeof t === 'string' ? t : '';\n },\n};\n","export const TextKit = {\n decode(data: Uint8Array, encoding = 'utf-8'): string {\n try {\n return new TextDecoder(encoding, { fatal: true }).decode(data);\n } catch {\n return new TextDecoder('utf-8', { fatal: false }).decode(data);\n }\n },\n\n encode(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n },\n\n escapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n },\n\n unescapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\");\n },\n\n normalizeWhitespace(s: string): string {\n return s.replace(/\\s+/g, ' ').trim();\n },\n\n stripControl(s: string): string {\n // eslint-disable-next-line no-control-regex\n return s.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n },\n\n base64Encode(data: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < data.length; i++) {\n binary += String.fromCharCode(data[i]);\n }\n return btoa(binary);\n },\n\n base64Decode(b64: string): Uint8Array {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n },\n};\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, GridNode, ImgNode, PageNumNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { DocMeta, PageDims, TextProps, ParaProps, CellProps, GridProps, Stroke } from '../../model/doc-props';\nimport { A4 } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildImg, buildGrid, buildRow, buildCell } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { Metric, safeAlign, safeFont, safeHex, safeStrokeHwpx } from '../../safety/StyleBridge';\nimport { ArchiveKit } from '../../toolkit/ArchiveKit';\nimport { XmlKit } from '../../toolkit/XmlKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\ninterface BorderFillInfo {\n stroke?: Stroke;\n bgColor?: string;\n}\n\ninterface CharPrInfo {\n b?: boolean; i?: boolean; u?: boolean; s?: boolean;\n pt?: number; color?: string; font?: string; bg?: string;\n}\n\ninterface DecCtx {\n files: Map<string, Uint8Array>;\n shield: ShieldedParser;\n borderFills: Map<number, BorderFillInfo>;\n charPrs: Map<number, CharPrInfo>;\n paraPrs: Map<number, { align?: string }>;\n warns: string[];\n}\n\nexport class HwpxDecoder implements Decoder {\n readonly format = 'hwpx';\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const bodyXml = files.get('Contents/section0.xml')\n ?? files.get('section0.xml')\n ?? findSectionFile(files);\n\n if (!bodyXml) return fail('HWPX: section0.xml not found in archive');\n\n const headXml = files.get('Contents/header.xml') ?? files.get('header.xml');\n\n let meta: DocMeta = {};\n let dims: PageDims = { ...A4 };\n let borderFills = new Map<number, BorderFillInfo>();\n let charPrs = new Map<number, CharPrInfo>();\n let paraPrs = new Map<number, { align?: string }>();\n\n if (headXml) {\n try {\n const headStr = TextKit.decode(headXml);\n const headObj: any = await XmlKit.parseStrict(headStr);\n if (headObj) {\n meta = extractMeta(headObj);\n dims = extractDims(headObj) ?? dims;\n borderFills = extractBorderFills(headObj);\n charPrs = extractCharPrs(headObj);\n paraPrs = extractParaPrs(headObj);\n }\n } catch {\n // header parse failure is non-fatal\n }\n }\n\n const ctx: DecCtx = { files, shield, borderFills, charPrs, paraPrs, warns };\n\n const bodyStr = TextKit.decode(bodyXml);\n const bodyObj: any = await XmlKit.parseStrict(bodyStr);\n\n const sections = normalizeSections(bodyObj);\n const kids = shield.guardAll(\n sections,\n (sec: any) => decodeSection(sec, dims, ctx),\n () => buildSheet([buildPara([buildSpan('[섹션 파싱 실패]')])], dims),\n 'hwpx:section',\n );\n\n warns.push(...shield.flush());\n return succeed(buildRoot(meta, kids), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWPX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction findSectionFile(files: Map<string, Uint8Array>): Uint8Array | undefined {\n for (const [key, val] of files) {\n if (key.toLowerCase().includes('section') && key.endsWith('.xml')) return val;\n }\n return undefined;\n}\n\nfunction normalizeSections(bodyObj: any): any[] {\n // <hs:sec> (real HWPX), <hp:SEC> (legacy)\n if (bodyObj?.['hs:sec']) return toArr(bodyObj['hs:sec']);\n if (bodyObj?.['hp:SEC']) return toArr(bodyObj['hp:SEC']);\n\n const root = bodyObj?.['hp:HWPML'] ?? bodyObj?.HWPML ?? bodyObj;\n const body = root?.['hp:BODY']?.[0] ?? root?.BODY?.[0] ?? root?.['hp:BODY'] ?? root?.BODY;\n if (!body) return [bodyObj];\n const sections = body?.['hp:SECTION'] ?? body?.SECTION ?? [];\n return Array.isArray(sections) ? sections : [sections];\n}\n\n// Get a tag regardless of namespace/case variations\nfunction getTag(obj: any, ...names: string[]): any[] {\n for (const n of names) {\n const v = obj?.[n];\n if (v != null) return toArr(v);\n }\n return [];\n}\n\nfunction extractMeta(headObj: any): DocMeta {\n try {\n // Support both <hh:HEAD> and <hh:head>\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const info = root?.['hh:DOCSUMMARY']?.[0] ?? root?.DOCSUMMARY?.[0];\n if (!info) return {};\n const a = (k: string) => info?.[`hh:${k}`]?.[0]?._text ?? info?.[k]?.[0]?._text ?? '';\n return { title: a('TITLE') || undefined, author: a('AUTHOR') || undefined, subject: a('SUBJECT') || undefined };\n } catch { return {}; }\n}\n\nfunction extractDims(headObj: any): PageDims | null {\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return null;\n\n const secPrList = refList?.['hh:SECPRLST']?.[0]?.['hh:SECPR']\n ?? refList?.SECPRLST?.[0]?.SECPR;\n const sec = Array.isArray(secPrList) ? secPrList[0] : secPrList;\n if (!sec) return null;\n\n const pa = sec?.['hh:PAGEPROPERTY']?.[0]?._attr ?? sec?.PAGEPROPERTY?.[0]?._attr;\n if (!pa) return null;\n\n return {\n wPt: Metric.hwpToPt(Number(pa.Width ?? 59528)),\n hPt: Metric.hwpToPt(Number(pa.Height ?? 84188)),\n mt: Metric.hwpToPt(Number(pa.TopMargin ?? 5670)),\n mb: Metric.hwpToPt(Number(pa.BottomMargin ?? 4252)),\n ml: Metric.hwpToPt(Number(pa.LeftMargin ?? 8504)),\n mr: Metric.hwpToPt(Number(pa.RightMargin ?? 8504)),\n orient: Number(pa.Landscape) === 1 ? 'landscape' : 'portrait',\n };\n } catch { return null; }\n}\n\nfunction extractBorderFills(headObj: any): Map<number, BorderFillInfo> {\n const map = new Map<number, BorderFillInfo>();\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return map;\n\n const bfList = refList?.['hh:borderFills']?.[0] ?? refList?.['hh:BORDERFILLLIST']?.[0] ?? refList?.BORDERFILLLIST?.[0];\n if (!bfList) return map;\n\n const bfs = getTag(bfList, 'hh:borderFill', 'hh:BORDERFILL');\n for (const bf of bfs) {\n const attr = bf?._attr ?? {};\n const id = Number(attr.id ?? 0);\n if (id === 0) continue;\n\n const info: BorderFillInfo = {};\n\n // Parse border (take top as representative)\n const top = bf?.['hh:topBorder']?.[0]?._attr ?? bf?.['hh:top']?.[0]?._attr ?? bf?.top?.[0]?._attr;\n if (top) {\n // width is in mm (e.g. \"0.18 mm\"), convert mm → pt (1mm ≈ 2.835pt), then pt → hwp (*100) for safeStrokeHwpx\n const mmVal = parseFloat(top.width) || undefined;\n const hwpVal = mmVal != null ? mmVal * 2.835 * 100 : undefined;\n info.stroke = safeStrokeHwpx(top.type, hwpVal, top.color);\n }\n\n // Parse fill (real HWPX uses hc:fillBrush, not hh:fillBrush)\n const fillBrush = bf?.['hc:fillBrush']?.[0] ?? bf?.['hh:fillBrush']?.[0] ?? bf?.['hh:fill']?.[0] ?? bf?.fill?.[0] ?? bf?.fillBrush?.[0];\n if (fillBrush) {\n const winBrush = fillBrush?.['hc:winBrush']?.[0]?._attr ?? fillBrush?.['hh:winBrush']?.[0]?._attr ?? fillBrush?.winBrush?.[0]?._attr;\n if (winBrush?.faceColor && winBrush.faceColor !== 'none') {\n info.bgColor = safeHex(winBrush.faceColor);\n }\n }\n\n map.set(id, info);\n }\n } catch { /* non-fatal */ }\n return map;\n}\n\nfunction extractCharPrs(headObj: any): Map<number, CharPrInfo> {\n const map = new Map<number, CharPrInfo>();\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return map;\n\n const cpList = refList?.['hh:charProperties']?.[0] ?? refList?.['hh:CHARPROPERTIES']?.[0];\n if (!cpList) return map;\n\n const cps = getTag(cpList, 'hh:charPr', 'hh:CHARPR');\n for (const cp of cps) {\n const attr = cp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const info: CharPrInfo = {};\n\n // height → pt\n if (attr.height) info.pt = Metric.hHeightToPt(Number(attr.height));\n\n // textColor\n if (attr.textColor) info.color = safeHex(attr.textColor);\n\n // bold\n if (cp?.['hh:bold']?.[0] != null) info.b = true;\n\n // italic\n if (cp?.['hh:italic']?.[0] != null) info.i = true;\n\n // underline\n const ulAttr = cp?.['hh:underline']?.[0]?._attr;\n if (ulAttr?.type && ulAttr.type !== 'NONE') info.u = true;\n\n // strikeout — shape=\"3D\" is default \"no strikeout\" in real HWPX; only SOLID/etc means active\n const stAttr = cp?.['hh:strikeout']?.[0]?._attr;\n if (stAttr?.shape && stAttr.shape !== 'NONE' && stAttr.shape !== '3D') info.s = true;\n\n // font — from fontRef + fontface\n // (simplified: just store what we find)\n\n map.set(id, info);\n }\n } catch { /* non-fatal */ }\n return map;\n}\n\nfunction extractParaPrs(headObj: any): Map<number, { align?: string }> {\n const map = new Map<number, { align?: string }>();\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return map;\n\n const ppList = refList?.['hh:paraProperties']?.[0] ?? refList?.['hh:PARAPROPERTIES']?.[0];\n if (!ppList) return map;\n\n const pps = getTag(ppList, 'hh:paraPr', 'hh:PARAPR');\n for (const pp of pps) {\n const attr = pp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const alignNode = pp?.['hh:align']?.[0]?._attr ?? pp?.['hh:ALIGN']?.[0]?._attr;\n const align = alignNode?.horizontal ?? alignNode?.Horizontal;\n\n map.set(id, { align });\n }\n } catch { /* non-fatal */ }\n return map;\n}\n\n// ─── Section decoding ──────────────────────────────────────\n\nfunction addParaItems(p: any, items: { type: string; node: any }[]): void {\n // Check if this paragraph contains a table in its runs\n const runs = getTag(p, 'hp:run', 'hp:RUN');\n let hasTable = false;\n for (const run of runs) {\n const tbls = getTag(run, 'hp:tbl', 'hp:TABLE');\n for (const tbl of tbls) {\n items.push({ type: 'table', node: tbl });\n hasTable = true;\n }\n }\n // Also add as paragraph unless it's just a table container\n const hasText = runs.some((run: any) => {\n const ts = getTag(run, 'hp:t', 'hp:T', 'hp:CHAR');\n return ts.some((t: any) => {\n const text = typeof t === 'string' ? t : t?._text ?? '';\n return text.trim().length > 0;\n });\n });\n if (hasText || !hasTable) {\n items.push({ type: 'para', node: p });\n }\n}\n\nfunction decodeSection(sec: any, dims: PageDims, ctx: DecCtx) {\n // Try to extract dims from first paragraph's secPr\n const firstParas = getTag(sec, 'hp:p', 'hp:P');\n const pageDims = extractSecPrDims(firstParas[0]) ?? dims;\n\n // Build items list preserving document order via _childOrder\n const items: { type: string; node: any }[] = [];\n const paras = getTag(sec, 'hp:p', 'hp:P');\n const childOrder = sec?.['_childOrder'] as string[] | undefined;\n\n if (Array.isArray(childOrder)) {\n let pi = 0;\n for (const tag of childOrder) {\n if ((tag === 'hp:p' || tag === 'hp:P') && pi < paras.length) {\n const p = paras[pi++];\n addParaItems(p, items);\n }\n }\n // Append any remaining\n while (pi < paras.length) addParaItems(paras[pi++], items);\n } else {\n // No order info — process paragraphs sequentially\n for (const p of paras) addParaItems(p, items);\n }\n\n const kids: ContentNode[] = ctx.shield.guardAll(\n items,\n (item: any) => {\n if (item.type === 'table') {\n const { value } = ctx.shield.guardGrid(\n item.node,\n (n) => decodeGrid(n, ctx),\n (n) => decodeGridSimple(n, ctx),\n (n) => decodeGridFlat(n),\n (n) => decodeGridText(n) as unknown as GridNode,\n 'hwpx:table',\n );\n return value;\n }\n return decodePara(item.node, ctx);\n },\n () => buildPara([buildSpan('[파싱 실패]')]),\n 'hwpx:content',\n );\n\n // Decode header/footer\n const headerParas = decodeHeaderFooter(sec, 'header', ctx);\n const footerParas = decodeHeaderFooter(sec, 'footer', ctx);\n\n return buildSheet(\n kids.filter(Boolean) as ContentNode[],\n pageDims,\n { header: headerParas, footer: footerParas },\n );\n}\n\nfunction extractSecPrDims(p: any): PageDims | null {\n if (!p) return null;\n try {\n const runs = getTag(p, 'hp:run', 'hp:RUN');\n for (const run of runs) {\n const secPr = run?.['hp:secPr']?.[0] ?? run?.['hp:SECPR']?.[0];\n if (!secPr) continue;\n const pagePr = secPr?.['hp:pagePr']?.[0]?._attr ?? secPr?.['hp:PAGEPR']?.[0]?._attr;\n if (!pagePr) continue;\n const margin = secPr?.['hp:pagePr']?.[0]?.['hp:margin']?.[0]?._attr\n ?? secPr?.['hp:PAGEPR']?.[0]?.['hp:MARGIN']?.[0]?._attr ?? {};\n return {\n wPt: Metric.hwpToPt(Number(pagePr.width ?? 59528)),\n hPt: Metric.hwpToPt(Number(pagePr.height ?? 84188)),\n mt: Metric.hwpToPt(Number(margin.top ?? 5670)),\n mb: Metric.hwpToPt(Number(margin.bottom ?? 4252)),\n ml: Metric.hwpToPt(Number(margin.left ?? 8504)),\n mr: Metric.hwpToPt(Number(margin.right ?? 8504)),\n orient: pagePr.landscape === 'NARROWLY' ? 'landscape' : 'portrait',\n };\n }\n } catch { /* ignore */ }\n return null;\n}\n\nfunction decodeHeaderFooter(sec: any, kind: 'header' | 'footer', ctx: DecCtx): ParaNode[] | undefined {\n try {\n const hf = sec?.['hp:headerFooter']?.[0] ?? sec?.['hp:HEADERFOOTER']?.[0]\n ?? sec?.headerFooter?.[0] ?? sec?.HEADERFOOTER?.[0];\n if (!hf) return undefined;\n\n const part = hf?.['hp:' + kind]?.[0] ?? hf?.['hp:' + kind.toUpperCase()]?.[0]\n ?? hf?.[kind]?.[0] ?? hf?.[kind.toUpperCase()]?.[0];\n if (!part) return undefined;\n\n const paras = getTag(part, 'hp:p', 'hp:P');\n if (paras.length === 0) return undefined;\n\n return paras.map((p: any) => decodePara(p, ctx));\n } catch {\n return undefined;\n }\n}\n\n// ─── Paragraph & run decoding ──────────────────────────────\n\nfunction decodePara(p: any, ctx: DecCtx): ParaNode {\n const pAttr = p?._attr ?? {};\n const paraPrIdRef = Number(pAttr.paraPrIDRef ?? -1);\n\n // Resolve paraPr from IDRef or inline\n let align: string | undefined;\n const paraPrDef = ctx.paraPrs.get(paraPrIdRef);\n if (paraPrDef?.align) align = paraPrDef.align;\n\n // Check inline PARAPR too\n const inlineParaPr = p?.['hp:PARAPR']?.[0] ?? p?.['hp:paraPr']?.[0] ?? p?.PARAPR?.[0];\n if (inlineParaPr) {\n const alignNode = inlineParaPr?.['hp:ALIGN']?.[0]?._attr ?? inlineParaPr?.['hp:align']?.[0]?._attr\n ?? inlineParaPr?.ALIGN?.[0]?._attr;\n if (alignNode?.Type) align = alignNode.Type;\n if (alignNode?.horizontal) align = alignNode.horizontal;\n }\n\n const inlineAttr = inlineParaPr?._attr ?? {};\n const props: ParaProps = { align: safeAlign(align) };\n\n // List support (from inline attr)\n if (inlineAttr.listType) {\n props.listOrd = inlineAttr.listType === 'DIGIT' || inlineAttr.listType === 'DECIMAL';\n props.listLv = Number(inlineAttr.listLevel ?? 0);\n }\n\n const runs = getTag(p, 'hp:run', 'hp:RUN');\n const kids: (SpanNode | ImgNode)[] = [];\n\n for (const run of runs) {\n // Images inside run\n const pics = getTag(run, 'hp:pic', 'hp:PIC');\n for (const pic of pics) {\n const img = decodePic(pic, ctx);\n if (img) kids.push(img);\n }\n\n // Page number\n const pageNums = getTag(run, 'hp:pageNum', 'hp:PAGENUM');\n if (pageNums.length > 0) {\n const pn = pageNums[0]?._attr ?? {};\n const fmt = pn.formatType === 'ROMAN_LOWER' ? 'roman' as const\n : pn.formatType === 'ROMAN_UPPER' ? 'romanCaps' as const\n : 'decimal' as const;\n const pageNumNode: PageNumNode = { tag: 'pagenum', format: fmt };\n const spanProps = resolveCharPr(run, ctx);\n kids.push({ tag: 'span', props: spanProps, kids: [pageNumNode] });\n continue;\n }\n\n // Text\n const textNodes = getTag(run, 'hp:t', 'hp:T', 'hp:CHAR');\n const content = textNodes.map((t: any) => typeof t === 'string' ? t : t?._text ?? t?._ ?? '').join('');\n\n // Skip empty secPr-only runs\n if (content === '' && (run?.['hp:secPr']?.[0] || run?.['hp:SECPR']?.[0]) && pics.length === 0) continue;\n\n const spanProps = resolveCharPr(run, ctx);\n kids.push(buildSpan(content, spanProps));\n }\n\n return buildPara(kids.filter(Boolean) as ParaNode['kids'], props);\n}\n\nfunction resolveCharPr(run: any, ctx: DecCtx): TextProps {\n const runAttr = run?._attr ?? {};\n const charPrIdRef = Number(runAttr.charPrIDRef ?? -1);\n\n // Try IDRef first\n const def = ctx.charPrs.get(charPrIdRef);\n if (def) {\n return {\n b: def.b, i: def.i, u: def.u, s: def.s,\n pt: def.pt, color: def.color, font: def.font, bg: def.bg,\n };\n }\n\n // Fallback: inline CHARPR\n const ca = run?.['hp:CHARPR']?.[0]?._attr ?? run?.['hp:charPr']?.[0]?._attr ?? run?.CHARPR?.[0]?._attr ?? {};\n return {\n b: ca.Bold === '1' || ca.Bold === 'true' || undefined,\n i: ca.Italic === '1' || ca.Italic === 'true' || undefined,\n u: ca.Underline ? ca.Underline !== 'NONE' : undefined,\n s: ca.Strikeout ? ca.Strikeout !== 'NONE' : undefined,\n font: safeFont(ca.FontName ?? ca.FaceNameHangul),\n pt: ca.Height ? Metric.hHeightToPt(Number(ca.Height)) : undefined,\n color: safeHex(ca.TextColor),\n bg: safeHex(ca.BgColor),\n };\n}\n\n// ─── Image decoding ────────────────────────────────────────\n\nfunction decodePic(pic: any, ctx: DecCtx): ImgNode | null {\n try {\n const szAttr = pic?.['hp:sz']?.[0]?._attr ?? pic?.sz?.[0]?._attr ?? {};\n const w = Metric.hwpToPt(Number(szAttr.width ?? 0));\n const h = Metric.hwpToPt(Number(szAttr.height ?? 0));\n\n // Try multiple tag patterns for image reference\n const imgNode = pic?.['hp:img']?.[0]?._attr ?? pic?.['hc:img']?.[0]?._attr\n ?? pic?.img?.[0]?._attr ?? {};\n const binRef = imgNode.binaryItemIDRef ?? imgNode.BinaryItemIDRef;\n if (!binRef) return null;\n\n // Find binary data\n let imgData: Uint8Array | undefined;\n for (const [key, val] of ctx.files) {\n if (key.includes(binRef) || key.toLowerCase().includes(binRef.toLowerCase())) {\n imgData = val;\n break;\n }\n }\n if (!imgData) return null;\n\n const ext = binRef.split('.').pop()?.toLowerCase() ?? 'png';\n const mimeMap: Record<string, ImgNode['mime']> = {\n png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg',\n gif: 'image/gif', bmp: 'image/bmp',\n };\n\n return buildImg(TextKit.base64Encode(imgData), mimeMap[ext] ?? 'image/png', w, h);\n } catch {\n return null;\n }\n}\n\n// ─── Table decoding ────────────────────────────────────────\n\nfunction decodeGrid(tbl: any, ctx: DecCtx): GridNode {\n const tblAttr = tbl?._attr ?? {};\n const borderFillId = Number(tblAttr.borderFillIDRef ?? 0);\n const borderFill = ctx.borderFills.get(borderFillId);\n const headerRow = tblAttr.repeatHeader === '1';\n\n const gridProps: GridProps = { headerRow: headerRow || undefined };\n if (borderFill?.stroke) gridProps.defaultStroke = borderFill.stroke;\n\n const rowArr = getTag(tbl, 'hp:tr', 'hp:ROW');\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, 'hp:tc', 'hp:CELL');\n const cellNodes = cellArr.map((cell: any) => {\n const ca = cell?._attr ?? {};\n\n // Cell borderFill\n const cellBfId = Number(ca.borderFillIDRef ?? 0);\n const cellBf = ctx.borderFills.get(cellBfId);\n\n const cellProps: CellProps = {\n bg: cellBf?.bgColor ?? safeHex(ca.BgColor),\n };\n\n if (cellBf?.stroke) {\n cellProps.top = cellBf.stroke;\n cellProps.bot = cellBf.stroke;\n cellProps.left = cellBf.stroke;\n cellProps.right = cellBf.stroke;\n }\n\n // Vertical alignment from subList\n const subList = cell?.['hp:subList']?.[0] ?? cell?.subList?.[0];\n const subAttr = subList?._attr ?? {};\n if (subAttr.vertAlign) {\n const vaMap: Record<string, 'top' | 'mid' | 'bot'> = {\n TOP: 'top', CENTER: 'mid', BOTTOM: 'bot',\n };\n cellProps.va = vaMap[subAttr.vertAlign];\n }\n\n // Colspan/rowspan from cellSpan element or attributes\n const cellSpan = cell?.['hp:cellSpan']?.[0]?._attr ?? {};\n const cs = Number(cellSpan.colSpan ?? ca.ColSpan ?? 1);\n const rs = Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1);\n\n // Parse paragraphs\n let paras: ParaNode[];\n if (subList) {\n const subParas = getTag(subList, 'hp:p', 'hp:P');\n paras = subParas.map((p: any) => decodePara(p, ctx));\n } else {\n paras = getTag(cell, 'hp:p', 'hp:P').map((p: any) => decodePara(p, ctx));\n }\n\n return buildCell(\n paras.length > 0 ? paras : [buildPara([buildSpan('')])],\n { cs, rs, props: cellProps },\n );\n });\n return buildRow(cellNodes);\n });\n return buildGrid(rowNodes, gridProps);\n}\n\nfunction decodeGridSimple(tbl: any, ctx: DecCtx): GridNode {\n const rowArr = getTag(tbl, 'hp:tr', 'hp:ROW');\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, 'hp:tc', 'hp:CELL');\n return buildRow(cellArr.map((cell: any) => buildCell([buildPara([buildSpan(cellText(cell))])])));\n });\n return buildGrid(rowNodes);\n}\n\nfunction decodeGridFlat(tbl: any): GridNode {\n return buildGrid([buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])])]);\n}\n\nfunction decodeGridText(tbl: any): ParaNode {\n return buildPara([buildSpan(tableText(tbl))]);\n}\n\nfunction cellText(cell: any): string {\n const subList = cell?.['hp:subList']?.[0] ?? cell?.subList?.[0];\n const source = subList ?? cell;\n return getTag(source, 'hp:p', 'hp:P').map((p: any) =>\n getTag(p, 'hp:run', 'hp:RUN').map((r: any) =>\n getTag(r, 'hp:t', 'hp:T').map((t: any) => typeof t === 'string' ? t : t?._text ?? t?._ ?? '').join(''),\n ).join(''),\n ).join(' ');\n}\n\nfunction tableText(tbl: any): string {\n return getTag(tbl, 'hp:tr', 'hp:ROW').map((row: any) =>\n getTag(row, 'hp:tc', 'hp:CELL').map((c: any) => cellText(c)).join('\\t'),\n ).join('\\n');\n}\n\nfunction toArr(v: any): any[] { return v == null ? [] : Array.isArray(v) ? v : [v]; }\n\n// Auto-register\nregistry.registerDecoder(new HwpxDecoder());\n","/**\n * OLE2 Compound File Binary Format (CFB) parser.\n * Used for legacy HWP 5.0 files.\n */\n\nexport const BinaryKit = {\n readU16LE(buf: Uint8Array, offset: number): number {\n return buf[offset] | (buf[offset + 1] << 8);\n },\n\n readU32LE(buf: Uint8Array, offset: number): number {\n return (\n (buf[offset] | (buf[offset + 1] << 8) | (buf[offset + 2] << 16)) >>> 0\n ) + buf[offset + 3] * 0x1000000;\n },\n\n isOle2(data: Uint8Array): boolean {\n return (\n data.length >= 8 &&\n data[0] === 0xD0 && data[1] === 0xCF &&\n data[2] === 0x11 && data[3] === 0xE0 &&\n data[4] === 0xA1 && data[5] === 0xB1 &&\n data[6] === 0x1A && data[7] === 0xE1\n );\n },\n\n parseCfb(data: Uint8Array): Map<string, Uint8Array> {\n const streams = new Map<string, Uint8Array>();\n\n if (!this.isOle2(data)) {\n throw new Error('Not a valid OLE2 file');\n }\n\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const sectorSize = 1 << view.getUint16(30, true);\n const miniSectorSz = 1 << view.getUint16(32, true);\n const dirFirstSec = view.getUint32(48, true);\n const miniStreamCutoff = view.getUint32(56, true);\n const miniFatFirst = view.getUint32(60, true);\n const miniFatCnt = view.getUint32(64, true);\n const difatFirst = view.getUint32(68, true);\n\n const ENDOFCHAIN = 0xFFFFFFFE;\n const FREESECT = 0xFFFFFFFF;\n\n const sectorAt = (sec: number): Uint8Array =>\n data.subarray(512 + sec * sectorSize, 512 + (sec + 1) * sectorSize);\n\n // Build FAT from DIFAT\n const fatSecNums: number[] = [];\n for (let i = 0; i < 109; i++) {\n const s = view.getUint32(76 + i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n if (difatFirst !== ENDOFCHAIN && difatFirst !== FREESECT) {\n let difSec = difatFirst;\n while (difSec !== ENDOFCHAIN && difSec !== FREESECT) {\n const sec = sectorAt(difSec);\n const sv = new DataView(sec.buffer, sec.byteOffset, sec.byteLength);\n for (let i = 0; i < (sectorSize / 4) - 1; i++) {\n const s = sv.getUint32(i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n difSec = sv.getUint32(sectorSize - 4, true);\n }\n }\n\n const fat: number[] = [];\n for (const sec of fatSecNums) {\n const s = sectorAt(sec);\n const sv = new DataView(s.buffer, s.byteOffset, s.byteLength);\n for (let i = 0; i < sectorSize / 4; i++) {\n fat.push(sv.getUint32(i * 4, true));\n }\n }\n\n const readChain = (startSec: number): Uint8Array => {\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < fat.length) {\n chunks.push(sectorAt(sec));\n sec = fat[sec];\n }\n return concatUint8(chunks);\n };\n\n // Directory entries\n const dirData = readChain(dirFirstSec);\n const dirView = new DataView(dirData.buffer, dirData.byteOffset, dirData.byteLength);\n const dirCount = dirData.length / 128;\n\n interface DirEntry {\n name: string;\n type: number;\n startSec: number;\n size: number;\n childId: number;\n siblingLeftId: number;\n siblingRightId: number;\n }\n\n const dirEntries: DirEntry[] = [];\n for (let i = 0; i < dirCount; i++) {\n const base = i * 128;\n const nameLen = dirView.getUint16(base + 64, true);\n const nameBytes = dirData.subarray(base, base + Math.max(0, nameLen - 2));\n const name = new TextDecoder('utf-16le').decode(nameBytes);\n const type = dirData[base + 66];\n const childId = dirView.getInt32(base + 76, true);\n const sibLeft = dirView.getInt32(base + 68, true);\n const sibRight = dirView.getInt32(base + 72, true);\n const startSec = dirView.getUint32(base + 116, true);\n const size = dirView.getUint32(base + 120, true);\n dirEntries.push({ name, type, startSec, size, childId, siblingLeftId: sibLeft, siblingRightId: sibRight });\n }\n\n // Mini stream\n const rootEntry = dirEntries[0];\n let miniStreamData: Uint8Array | null = null;\n let miniFat: number[] = [];\n\n if (rootEntry && rootEntry.startSec !== ENDOFCHAIN && rootEntry.startSec !== FREESECT) {\n miniStreamData = readChain(rootEntry.startSec);\n }\n\n if (miniFatCnt > 0 && miniFatFirst !== ENDOFCHAIN && miniFatFirst !== FREESECT) {\n const mfData = readChain(miniFatFirst);\n const mfv = new DataView(mfData.buffer, mfData.byteOffset, mfData.byteLength);\n for (let i = 0; i < mfData.length / 4; i++) {\n miniFat.push(mfv.getUint32(i * 4, true));\n }\n }\n\n const readMiniChain = (startSec: number, size: number): Uint8Array => {\n if (!miniStreamData) return new Uint8Array(0);\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n let remaining = size;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < miniFat.length && remaining > 0) {\n const off = sec * miniSectorSz;\n const chunk = miniStreamData.subarray(off, off + Math.min(miniSectorSz, remaining));\n chunks.push(chunk);\n remaining -= chunk.length;\n sec = miniFat[sec];\n }\n return concatUint8(chunks).subarray(0, size);\n };\n\n // DFS traversal\n const visit = (id: number, path: string): void => {\n if (id < 0 || id >= dirEntries.length) return;\n const entry = dirEntries[id];\n const fullPath = path ? `${path}/${entry.name}` : entry.name;\n\n if (entry.type === 2) {\n let streamData: Uint8Array;\n if (entry.size < miniStreamCutoff && miniStreamData) {\n streamData = readMiniChain(entry.startSec, entry.size);\n } else {\n streamData = readChain(entry.startSec).subarray(0, entry.size);\n }\n streams.set(fullPath, streamData);\n streams.set(entry.name, streamData);\n }\n\n if (entry.childId >= 0) visit(entry.childId, fullPath);\n if (entry.siblingLeftId >= 0) visit(entry.siblingLeftId, path);\n if (entry.siblingRightId >= 0) visit(entry.siblingRightId, path);\n };\n\n if (dirEntries.length > 0 && dirEntries[0].childId >= 0) {\n visit(dirEntries[0].childId, '');\n }\n\n return streams;\n },\n};\n\nfunction concatUint8(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const a of arrays) { out.set(a, off); off += a.length; }\n return out;\n}\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { Align, Stroke, StrokeKind, PageDims, TextProps, ParaProps, CellProps, GridProps } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildGrid, buildRow, buildCell } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { BinaryKit } from '../../toolkit/BinaryKit';\nimport { Metric, safeHex, safeFont } from '../../safety/StyleBridge';\nimport { registry } from '../../pipeline/registry';\nimport { A4 } from '../../model/doc-props';\nimport pako from 'pako';\n\n/* ═══════════════════════════════════════════════════════════════\n HWP 5.0 Tag Constants\n ═══════════════════════════════════════════════════════════════ */\n\nconst HWPTAG_BEGIN = 16;\n\nconst TAG_FACE_NAME = HWPTAG_BEGIN + 3; // 19\nconst TAG_BORDER_FILL = HWPTAG_BEGIN + 4; // 20\nconst TAG_CHAR_SHAPE = HWPTAG_BEGIN + 5; // 21\nconst TAG_PARA_SHAPE = HWPTAG_BEGIN + 9; // 25\nconst TAG_PARA_HEADER = HWPTAG_BEGIN + 50; // 66\nconst TAG_PARA_TEXT = HWPTAG_BEGIN + 51; // 67\nconst TAG_PARA_CHAR_SHAPE = HWPTAG_BEGIN + 52; // 68\nconst TAG_CTRL_HEADER = HWPTAG_BEGIN + 55; // 71\nconst TAG_PAGE_DEF = HWPTAG_BEGIN + 57; // 73\n\n// TABLE / CELL tags vary by HWP version\nconst TAG_LIST_HEADER = HWPTAG_BEGIN + 56; // 72\nconst TAG_TABLE_A = HWPTAG_BEGIN + 61; // 77\nconst TAG_CELL_A = HWPTAG_BEGIN + 62; // 78\nconst TAG_TABLE_B = HWPTAG_BEGIN + 64; // 80\nconst TAG_CELL_B = HWPTAG_BEGIN + 65; // 81\n\nfunction isTableTag(t: number) { return t === TAG_TABLE_A || t === TAG_TABLE_B; }\nfunction isCellTag(t: number) { return t === TAG_CELL_A || t === TAG_CELL_B || t === TAG_LIST_HEADER; }\n\n// CTRL_HEADER ctrlId for table: ' lbt' as UINT32-LE = 0x74626C20\nconst CTRL_TABLE = 0x74626C20;\n\n/* ═══════════════════════════════════════════════════════════════\n Types\n ═══════════════════════════════════════════════════════════════ */\n\ninterface HwpRecord {\n tag: number;\n level: number;\n data: Uint8Array;\n}\n\ninterface HwpCharShape {\n faceIds: number[];\n height: number;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikeout: boolean;\n superscript: boolean;\n subscript: boolean;\n textColor: string;\n}\n\ninterface HwpParaShape {\n align: Align;\n spaceBefore: number;\n spaceAfter: number;\n lineSpacing: number;\n indent: number;\n}\n\ninterface HwpBorderFill {\n borders: { type: number; widthPt: number; color: string }[];\n bgColor?: string;\n}\n\ninterface DocInfo {\n faceNames: string[];\n charShapes: HwpCharShape[];\n paraShapes: HwpParaShape[];\n borderFills: HwpBorderFill[];\n}\n\ninterface ParsedChar { pos: number; ch: string }\ninterface ParaTextResult { chars: ParsedChar[]; controlPositions: number[] }\n\n/* ═══════════════════════════════════════════════════════════════\n Low-level record parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseRecords(data: Uint8Array): HwpRecord[] {\n const out: HwpRecord[] = [];\n let off = 0;\n while (off + 4 <= data.length) {\n const hdr = BinaryKit.readU32LE(data, off);\n const tag = hdr & 0x3FF;\n const level = (hdr >> 10) & 0x3FF;\n let size = (hdr >> 20) & 0xFFF;\n off += 4;\n if (size === 0xFFF) {\n if (off + 4 > data.length) break;\n size = BinaryKit.readU32LE(data, off);\n off += 4;\n }\n if (off + size > data.length) break;\n out.push({ tag, level, data: data.subarray(off, off + size) });\n off += size;\n }\n return out;\n}\n\nfunction tryInflate(data: Uint8Array): Uint8Array {\n try { return pako.inflateRaw(data); } catch { return data; }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n FileHeader\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseFileHeader(buf: Uint8Array) {\n if (buf.length < 40) return { compressed: true, encrypted: false };\n const props = BinaryKit.readU32LE(buf, 36);\n return { compressed: (props & 1) !== 0, encrypted: (props & 2) !== 0 };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n DocInfo parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseDocInfo(data: Uint8Array, compressed: boolean): DocInfo {\n const raw = compressed ? tryInflate(data) : data;\n const recs = parseRecords(raw);\n const info: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n\n for (const r of recs) {\n try {\n if (r.tag === TAG_FACE_NAME) info.faceNames.push(parseFaceName(r.data));\n if (r.tag === TAG_CHAR_SHAPE) info.charShapes.push(parseCharShape(r.data));\n if (r.tag === TAG_PARA_SHAPE) info.paraShapes.push(parseParaShape(r.data));\n if (r.tag === TAG_BORDER_FILL) info.borderFills.push(parseBorderFill(r.data));\n } catch { /* skip malformed record */ }\n }\n return info;\n}\n\n/* ── FACE_NAME ──────────────────────────────────────────────── */\n\nfunction parseFaceName(d: Uint8Array): string {\n if (d.length < 3) return '';\n const len = BinaryKit.readU16LE(d, 1); // UTF-16 char count\n if (d.length < 3 + len * 2) return '';\n return new TextDecoder('utf-16le').decode(d.subarray(3, 3 + len * 2));\n}\n\n/* ── CHAR_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 14 faceId[7] (UINT16 × 7)\n 14 7 ratio[7]\n 21 7 spacing[7]\n 28 7 relSize[7]\n 35 7 offset[7]\n 42 4 height (UINT32, HWP-units 100 = 1pt)\n 46 4 attr (UINT32, bit flags)\n 50 1 shadowX\n 51 1 shadowY\n 52 4 textColor (COLORREF R,G,B,0) */\n\nfunction parseCharShape(d: Uint8Array): HwpCharShape {\n const faceIds: number[] = [];\n for (let i = 0; i < 7; i++) faceIds.push(d.length >= (i + 1) * 2 ? BinaryKit.readU16LE(d, i * 2) : 0);\n\n const height = d.length >= 46 ? BinaryKit.readU32LE(d, 42) : 1000;\n const attr = d.length >= 50 ? BinaryKit.readU32LE(d, 46) : 0;\n\n // attr bit layout (HWP 5.0 spec Table 35):\n // 0: italic, 1: bold, 2-4: underline type(3), 5-8: underline shape(4),\n // 9-11: outline(3), 12-13: shadow(2), 14: emboss, 15: engrave,\n // 16-17: super/sub(2, 0=none,1=super,2=sub), 18-20: strikeout type(3),\n // 21-24: strikeout shape(4), 25: annotLine, 26-28: annotLine type,\n // 29: useFontSpace, 30: kerning\n const ulType = (attr >> 2) & 0x7; // 3 bits at 2-4\n const skType = (attr >> 18) & 0x7; // 3 bits at 18-20\n const suType = (attr >> 16) & 0x3; // 2 bits at 16-17 (0=none,1=super,2=sub)\n\n return {\n faceIds,\n height: (height > 0 && height < 100000) ? height : 1000,\n italic: (attr & 1) !== 0,\n bold: ((attr >> 1) & 1) !== 0,\n underline: ulType !== 0,\n strikeout: skType !== 0,\n superscript: suType === 1,\n subscript: suType === 2,\n textColor: d.length >= 56 ? colorRef(d, 52) : '000000',\n };\n}\n\n/* ── PARA_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 4 attr1 (bits 0-1 = alignment: 0=justify,1=left,2=right,3=center)\n 4 4 leftMargin (HWPUNIT)\n 8 4 rightMargin\n 12 4 indent\n 16 4 spaceBefore\n 20 4 spaceAfter\n 24 4 lineSpacing */\n\nconst ALIGN_TBL: Record<number, Align> = { 0: 'justify', 1: 'left', 2: 'right', 3: 'center', 4: 'justify' };\n\nfunction parseParaShape(d: Uint8Array): HwpParaShape {\n if (d.length < 4) return { align: 'left', spaceBefore: 0, spaceAfter: 0, lineSpacing: 160, indent: 0 };\n const attr = BinaryKit.readU32LE(d, 0);\n return {\n align: ALIGN_TBL[attr & 0x7] ?? 'left',\n indent: d.length >= 16 ? i32(d, 12) : 0,\n spaceBefore: d.length >= 20 ? i32(d, 16) : 0,\n spaceAfter: d.length >= 24 ? i32(d, 20) : 0,\n lineSpacing: d.length >= 28 ? i32(d, 24) : 160,\n };\n}\n\n/* ── BORDER_FILL ────────────────────────────────────────────── */\n/* [0:2] attr\n For each of 5 borders (left,right,top,bottom,diagonal): 6 bytes\n +0 type(BYTE) +1 widthIdx(BYTE) +2 color(COLORREF)\n [32:4] fillType\n [36:4] faceColor (bgColor for solid fill) */\n\nconst BORDER_W_PT = [0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.70, 1.98, 2.84, 4.25, 5.67, 8.50, 11.34, 14.17];\nconst BORDER_KIND: Record<number, StrokeKind> = { 0:'none',1:'solid',2:'dash',3:'dot',4:'dash',5:'dash',6:'dash',7:'dot',8:'double',9:'double',10:'double' };\n\nfunction parseBorderFill(d: Uint8Array): HwpBorderFill {\n const borders: HwpBorderFill['borders'] = [];\n for (let i = 0; i < 4; i++) {\n const b = 2 + i * 6;\n if (b + 6 <= d.length) {\n borders.push({ type: d[b], widthPt: BORDER_W_PT[d[b + 1]] ?? 0.5, color: colorRef(d, b + 2) });\n } else {\n borders.push({ type: 0, widthPt: 0.5, color: '000000' });\n }\n }\n let bgColor: string | undefined;\n const fOff = 32; // after attr(2) + 5 borders(30)\n if (d.length >= fOff + 8) {\n const ft = BinaryKit.readU32LE(d, fOff);\n if (ft & 1) bgColor = colorRef(d, fOff + 4);\n }\n return { borders, bgColor };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Body section parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseBody(\n raw: Uint8Array, compressed: boolean, di: DocInfo, shield: ShieldedParser,\n): { content: ContentNode[]; pageDims?: PageDims } {\n const recs = parseRecords(compressed ? tryInflate(raw) : raw);\n const content: ContentNode[] = [];\n let pageDims: PageDims | undefined;\n let i = 0;\n\n while (i < recs.length) {\n if (recs[i].tag === TAG_PAGE_DEF) {\n pageDims = shield.guard(() => parsePageDef(recs[i].data), A4, 'hwp:pageDef');\n i++;\n } else if (recs[i].tag === TAG_PARA_HEADER) {\n const r = shield.guard(\n () => parseParagraphGroup(recs, i, di, shield),\n { nodes: [] as ContentNode[], next: i + 1 },\n `hwp:para@${i}`,\n );\n content.push(...r.nodes);\n i = r.next;\n } else {\n i++;\n }\n }\n return { content, pageDims };\n}\n\n/* ── Paragraph group ────────────────────────────────────────── */\n\nfunction parseParagraphGroup(\n recs: HwpRecord[], start: number, di: DocInfo, shield: ShieldedParser,\n): { nodes: ContentNode[]; next: number } {\n const hdr = recs[start];\n const lv = hdr.level;\n\n // paraShapeId at offset 8 (UINT16)\n const psId = hdr.data.length >= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n\n let text: ParaTextResult | null = null;\n let csPairs: [number, number][] = [];\n const grids: ContentNode[] = [];\n let i = start + 1;\n\n while (i < recs.length && recs[i].level > lv) {\n const r = recs[i];\n\n if (r.tag === TAG_PARA_TEXT && r.level === lv + 1) {\n text = decodeParaText(r.data);\n i++;\n } else if (r.tag === TAG_PARA_CHAR_SHAPE && r.level === lv + 1) {\n csPairs = parseCharShapePairs(r.data);\n i++;\n } else if (r.tag === TAG_CTRL_HEADER && r.level === lv + 1) {\n if (r.data.length >= 4 && BinaryKit.readU32LE(r.data, 0) === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, i, di, shield),\n { grid: null, next: skipKids(recs, i) },\n `hwp:tbl@${i}`,\n );\n if (tr.grid) grids.push(tr.grid);\n i = tr.next;\n } else {\n i = skipKids(recs, i);\n }\n } else {\n i++;\n }\n }\n\n const nodes: ContentNode[] = [];\n\n // Build paragraph from text\n if (text && text.chars.length > 0) {\n const joined = text.chars.map(c => c.ch).join('');\n if (joined.trim()) {\n const spans = resolveCharShapes(text.chars, csPairs, di);\n nodes.push(buildPara(spans, buildParaProps(ps)));\n }\n }\n\n nodes.push(...grids);\n return { nodes, next: i };\n}\n\nfunction skipKids(recs: HwpRecord[], idx: number): number {\n const lv = recs[idx].level;\n let i = idx + 1;\n while (i < recs.length && recs[i].level > lv) i++;\n return i;\n}\n\n/* ── PARA_TEXT ───────────────────────────────────────────────── */\n\n// Extended controls: 8 WORDs, associated CTRL_HEADER\nconst EXT_CTRL = new Set([2, 3, 11, 12, 14, 15]);\n// Inline controls: 8 WORDs, no CTRL_HEADER\nconst INL_CTRL = new Set([4, 5, 6, 7, 8]);\n\nfunction decodeParaText(d: Uint8Array): ParaTextResult {\n const chars: ParsedChar[] = [];\n const controlPositions: number[] = [];\n let i = 0, pos = 0;\n\n while (i + 1 < d.length) {\n const c = d[i] | (d[i + 1] << 8);\n if (c === 0) { i += 2; pos++; continue; }\n if (c === 13) { break; } // paragraph end\n if (c === 10) { chars.push({ pos, ch: '\\n' }); i += 2; pos++; continue; }\n\n if (EXT_CTRL.has(c)) {\n controlPositions.push(pos);\n i += 16; pos += 8; continue; // 8 WORDs\n }\n if (INL_CTRL.has(c)) {\n i += 16; pos += 8; continue;\n }\n if (c === 9) { // tab (inline 8 WORDs)\n chars.push({ pos, ch: '\\t' });\n i += 16; pos += 8; continue;\n }\n if (c >= 1 && c <= 31) { i += 2; pos++; continue; } // other control\n\n chars.push({ pos, ch: String.fromCharCode(c) });\n i += 2; pos++;\n }\n return { chars, controlPositions };\n}\n\n/* ── PARA_CHAR_SHAPE ────────────────────────────────────────── */\n\nfunction parseCharShapePairs(d: Uint8Array): [number, number][] {\n const out: [number, number][] = [];\n for (let i = 0; i + 7 < d.length; i += 8)\n out.push([BinaryKit.readU32LE(d, i), BinaryKit.readU32LE(d, i + 4)]);\n return out;\n}\n\n/* ── Char-shape → SpanNode resolution ───────────────────────── */\n\nfunction resolveCharShapes(chars: ParsedChar[], pairs: [number, number][], di: DocInfo): SpanNode[] {\n if (chars.length === 0) return [buildSpan('')];\n\n const defaultId = pairs.length > 0 ? pairs[0][1] : 0;\n\n function idFor(pos: number): number {\n let id = defaultId;\n for (const [p, sid] of pairs) { if (p <= pos) id = sid; else break; }\n return id;\n }\n\n const spans: SpanNode[] = [];\n let curId = idFor(chars[0].pos);\n let buf = chars[0].ch;\n\n for (let k = 1; k < chars.length; k++) {\n const sid = idFor(chars[k].pos);\n if (sid !== curId) { spans.push(styledSpan(buf, curId, di)); buf = ''; curId = sid; }\n buf += chars[k].ch;\n }\n if (buf) spans.push(styledSpan(buf, curId, di));\n return spans;\n}\n\nfunction styledSpan(text: string, shapeId: number, di: DocInfo): SpanNode {\n const cs = di.charShapes[shapeId];\n if (!cs) return buildSpan(text);\n\n const props: TextProps = {};\n const fid = cs.faceIds[0] ?? 0;\n if (fid < di.faceNames.length && di.faceNames[fid]) props.font = safeFont(di.faceNames[fid]);\n if (cs.height > 0) props.pt = Metric.hwpToPt(cs.height);\n if (cs.bold) props.b = true;\n if (cs.italic) props.i = true;\n if (cs.underline) props.u = true;\n if (cs.strikeout) props.s = true;\n if (cs.superscript) props.sup = true;\n if (cs.subscript) props.sub = true;\n\n const hex = safeHex(cs.textColor);\n if (hex && hex !== '000000') props.color = hex;\n\n return buildSpan(text, props);\n}\n\n/* ── Table control parsing ──────────────────────────────────── */\n\nfunction parseTableCtrl(\n recs: HwpRecord[], ctrlIdx: number, di: DocInfo, shield: ShieldedParser,\n): { grid: ContentNode | null; next: number } {\n const ctrlLv = recs[ctrlIdx].level;\n let i = ctrlIdx + 1;\n\n let tblData: Uint8Array | null = null;\n const cells: { data: Uint8Array; tag: number; cStart: number; cEnd: number }[] = [];\n\n // Collect TABLE and cell records within this control's scope\n const tblLevel = ctrlLv + 1;\n\n while (i < recs.length && recs[i].level > ctrlLv) {\n const r = recs[i];\n\n if (isTableTag(r.tag) && r.level === tblLevel) {\n tblData = r.data;\n i++;\n } else if (r.tag === TAG_LIST_HEADER && r.level === tblLevel) {\n // LIST_HEADER as cell: paraCount tells how many paragraphs follow\n const cellData = r.data;\n const paraCount = cellData.length >= 2 ? BinaryKit.readU16LE(cellData, 0) : 0;\n i++;\n const cStart = i;\n // Consume exactly paraCount paragraphs (each with its child records)\n let consumed = 0;\n while (i < recs.length && consumed < paraCount) {\n if (recs[i].tag === TAG_PARA_HEADER && recs[i].level === tblLevel) {\n consumed++;\n i++;\n // Skip child records of this paragraph\n while (i < recs.length && recs[i].level > tblLevel) i++;\n } else if (recs[i].level > tblLevel) {\n i++;\n } else {\n break; // hit next sibling at same level\n }\n }\n cells.push({ data: cellData, tag: TAG_LIST_HEADER, cStart, cEnd: i });\n } else if (isCellTag(r.tag) && r.level === tblLevel) {\n // Full CELL record (with cell-specific fields)\n const cellData = r.data;\n const cellTag = r.tag;\n i++;\n const cStart = i;\n while (i < recs.length && recs[i].level > tblLevel) i++;\n cells.push({ data: cellData, tag: cellTag, cStart, cEnd: i });\n } else {\n i++;\n }\n }\n\n if (!tblData || cells.length === 0) return { grid: null, next: i };\n\n const rowCnt = tblData.length >= 6 ? BinaryKit.readU16LE(tblData, 4) : 1;\n const colCnt = tblData.length >= 8 ? BinaryKit.readU16LE(tblData, 6) : 1;\n\n interface PC { row: number; col: number; cs: number; rs: number; widthHwp: number; props: CellProps; paras: ParaNode[] }\n const parsed: PC[] = [];\n\n for (let ci = 0; ci < cells.length; ci++) {\n const c = cells[ci];\n const seqIdx = ci;\n const pc = shield.guard(\n () => parseCellRec(c.data, c.tag, recs, c.cStart, c.cEnd, di, shield, seqIdx, colCnt),\n { row: Math.floor(ci / (colCnt || 1)), col: ci % (colCnt || 1), cs: 1, rs: 1, widthHwp: 0, props: {}, paras: [buildPara([buildSpan('')])] },\n `hwp:cell@${c.cStart}`,\n );\n parsed.push(pc);\n }\n\n // Determine actual row count from cell data (may exceed rowCnt for merged cells)\n const maxRow = parsed.reduce((m, c) => Math.max(m, c.row + c.rs), 0);\n const actualRowCnt = Math.max(rowCnt, maxRow);\n\n // Validate cell positions; fallback to sequential layout if invalid\n const posValid = parsed.every(c => c.row >= 0 && c.col >= 0 && c.col < colCnt);\n if (!posValid) {\n let idx = 0;\n for (const c of parsed) { c.row = Math.floor(idx / colCnt); c.col = idx % colCnt; idx++; }\n }\n\n // Compute column widths in points from cell widths\n const colWidthsPt: number[] = new Array(colCnt).fill(0);\n // Pass 1: use cells with cs=1 for exact column widths\n for (const c of parsed) {\n if (c.cs === 1 && c.widthHwp > 0) {\n const wPt = Metric.hwpToPt(c.widthHwp);\n if (wPt > colWidthsPt[c.col]) colWidthsPt[c.col] = wPt;\n }\n }\n // Pass 2: for columns still 0, try to derive from multi-span cells\n const zeroColumns = colWidthsPt.filter(w => w === 0).length;\n if (zeroColumns > 0) {\n for (const c of parsed) {\n if (c.cs > 1 && c.widthHwp > 0) {\n // Subtract known column widths from the span\n let known = 0;\n let unknownCols = 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci] > 0) known += colWidthsPt[ci];\n else unknownCols++;\n }\n if (unknownCols > 0) {\n const remaining = Metric.hwpToPt(c.widthHwp) - known;\n const each = remaining > 0 ? remaining / unknownCols : 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci] === 0 && each > 0) colWidthsPt[ci] = each;\n }\n }\n }\n }\n }\n\n const rows = [];\n for (let r = 0; r < actualRowCnt; r++) {\n const rc = parsed.filter(c => c.row === r).sort((a, b) => a.col - b.col);\n if (rc.length === 0) continue;\n rows.push(buildRow(rc.map(c =>\n buildCell(c.paras.length ? c.paras : [buildPara([buildSpan('')])], { cs: c.cs, rs: c.rs, props: c.props }),\n )));\n }\n if (rows.length === 0) return { grid: null, next: i };\n\n // Table-level default stroke\n let defStroke: Stroke | undefined;\n const bfOff = 18 + rowCnt * 2;\n if (tblData.length >= bfOff + 2) {\n const bfId = BinaryKit.readU16LE(tblData, bfOff);\n defStroke = strokeFromBF(bfId, di);\n }\n\n const gp: GridProps = {};\n if (defStroke) gp.defaultStroke = defStroke;\n const hasWidths = colWidthsPt.some(w => w > 0);\n if (hasWidths) gp.colWidths = colWidthsPt;\n return { grid: buildGrid(rows, gp), next: i };\n}\n\n/* ── Cell record ────────────────────────────────────────────── */\n/* LIST_HEADER for cells (HWP 5.0/5.1):\n [0:2] paraCount [2:4] attr (bits 6-7 = vertAlign)\n [6:2] unknown [8:2] rowAddr [10:2] colAddr\n [12:2] rowSpan [14:2] colSpan\n [16:4] width(HWPUNIT) [20:4] height(HWPUNIT)\n [24:8] padding[4] [32:2] borderFillId */\n\nfunction parseCellRec(\n d: Uint8Array, tag: number, recs: HwpRecord[], cStart: number, cEnd: number,\n di: DocInfo, shield: ShieldedParser, seqIdx: number, colCnt: number,\n) {\n let col: number, row: number, cs = 1, rs = 1;\n let widthHwp = 0;\n const props: CellProps = {};\n\n const attr = d.length >= 6 ? BinaryKit.readU32LE(d, 2) : 0;\n const va = (attr >> 6) & 0x3;\n if (va === 1) props.va = 'mid';\n else if (va === 2) props.va = 'bot';\n\n if (tag === TAG_LIST_HEADER && d.length >= 22) {\n // LIST_HEADER with cell-specific fields\n // offset 8: colAddr, offset 10: rowAddr (HWP 5.0 spec)\n col = BinaryKit.readU16LE(d, 8);\n row = BinaryKit.readU16LE(d, 10);\n rs = Math.max(1, BinaryKit.readU16LE(d, 12));\n cs = Math.max(1, BinaryKit.readU16LE(d, 14));\n widthHwp = BinaryKit.readU32LE(d, 16);\n\n const bfId = d.length >= 34 ? BinaryKit.readU16LE(d, 32) : 0;\n if (bfId > 0 && bfId <= di.borderFills.length) {\n const bf = di.borderFills[bfId - 1];\n if (bf.borders.length >= 4) {\n props.left = toStroke(bf.borders[0]);\n props.right = toStroke(bf.borders[1]);\n props.top = toStroke(bf.borders[2]);\n props.bot = toStroke(bf.borders[3]);\n }\n if (bf.bgColor && bf.bgColor !== 'FFFFFF') props.bg = bf.bgColor;\n }\n } else if (tag !== TAG_LIST_HEADER) {\n // Full CELL record with position/span/borderFill\n col = d.length >= 8 ? BinaryKit.readU16LE(d, 6) : seqIdx % (colCnt || 1);\n row = d.length >= 10 ? BinaryKit.readU16LE(d, 8) : Math.floor(seqIdx / (colCnt || 1));\n cs = d.length >= 12 ? Math.max(1, BinaryKit.readU16LE(d, 10)) : 1;\n rs = d.length >= 14 ? Math.max(1, BinaryKit.readU16LE(d, 12)) : 1;\n widthHwp = d.length >= 18 ? BinaryKit.readU32LE(d, 14) : 0;\n\n const bfId = d.length >= 32 ? BinaryKit.readU16LE(d, 30) : 0;\n if (bfId > 0 && bfId <= di.borderFills.length) {\n const bf = di.borderFills[bfId - 1];\n if (bf.borders.length >= 4) {\n props.left = toStroke(bf.borders[0]);\n props.right = toStroke(bf.borders[1]);\n props.top = toStroke(bf.borders[2]);\n props.bot = toStroke(bf.borders[3]);\n }\n if (bf.bgColor && bf.bgColor !== 'FFFFFF') props.bg = bf.bgColor;\n }\n } else {\n // Fallback: LIST_HEADER too short, compute sequentially\n row = Math.floor(seqIdx / (colCnt || 1));\n col = seqIdx % (colCnt || 1);\n }\n\n // Parse cell content paragraphs\n const paras: ParaNode[] = [];\n let k = cStart;\n while (k < cEnd) {\n if (recs[k].tag === TAG_PARA_HEADER) {\n // For cell paragraphs, they might be at various nesting levels\n const r = shield.guard(\n () => {\n const hdr = recs[k];\n const lv = hdr.level;\n const psId = hdr.data.length >= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n let txt: ParaTextResult | null = null;\n let csp: [number, number][] = [];\n let j = k + 1;\n while (j < cEnd && recs[j].level > lv) {\n if (recs[j].tag === TAG_PARA_TEXT) { txt = decodeParaText(recs[j].data); j++; }\n else if (recs[j].tag === TAG_PARA_CHAR_SHAPE) { csp = parseCharShapePairs(recs[j].data); j++; }\n else j++;\n }\n const spans = txt && txt.chars.length > 0 ? resolveCharShapes(txt.chars, csp, di) : [buildSpan('')];\n return { para: buildPara(spans, buildParaProps(ps)), next: j };\n },\n { para: buildPara([buildSpan('')]), next: k + 1 },\n `hwp:cellP@${k}`,\n );\n paras.push(r.para);\n k = r.next;\n } else { k++; }\n }\n\n return { row, col, cs, rs, props, widthHwp, paras: paras.length ? paras : [buildPara([buildSpan('')])] };\n}\n\n/* ── PAGE_DEF ───────────────────────────────────────────────── */\n/* [0:4] width [4:4] height [8:4] ml [12:4] mr\n [16:4] mt [20:4] mb [36:4] attr (bit0=landscape) */\n\nfunction parsePageDef(d: Uint8Array): PageDims {\n if (d.length < 24) return A4;\n const w = BinaryKit.readU32LE(d, 0);\n const h = BinaryKit.readU32LE(d, 4);\n const ml = BinaryKit.readU32LE(d, 8);\n const mr = BinaryKit.readU32LE(d, 12);\n const mt = BinaryKit.readU32LE(d, 16);\n const mb = BinaryKit.readU32LE(d, 20);\n const at = d.length >= 40 ? BinaryKit.readU32LE(d, 36) : 0;\n return {\n wPt: Metric.hwpToPt(w), hPt: Metric.hwpToPt(h),\n ml: Metric.hwpToPt(ml), mr: Metric.hwpToPt(mr),\n mt: Metric.hwpToPt(mt), mb: Metric.hwpToPt(mb),\n orient: (at & 1) ? 'landscape' : 'portrait',\n };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Helpers\n ═══════════════════════════════════════════════════════════════ */\n\nfunction i32(d: Uint8Array, o: number): number {\n const u = BinaryKit.readU32LE(d, o);\n return u > 0x7FFFFFFF ? u - 0x100000000 : u;\n}\n\nfunction colorRef(d: Uint8Array, o: number): string {\n if (o + 3 > d.length) return '000000';\n return ((d[o] << 16) | (d[o + 1] << 8) | d[o + 2]).toString(16).padStart(6, '0').toUpperCase();\n}\n\nfunction toStroke(b: { type: number; widthPt: number; color: string }): Stroke {\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\nfunction strokeFromBF(bfId: number, di: DocInfo): Stroke | undefined {\n if (bfId <= 0 || bfId > di.borderFills.length) return undefined;\n const bf = di.borderFills[bfId - 1];\n if (!bf.borders.length) return undefined;\n const b = bf.borders[0];\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\nfunction buildParaProps(ps?: HwpParaShape): ParaProps {\n if (!ps) return {};\n const p: ParaProps = {};\n if (ps.align && ps.align !== 'left') p.align = ps.align;\n if (ps.spaceBefore > 0) p.spaceBefore = Metric.hwpToPt(ps.spaceBefore);\n if (ps.spaceAfter > 0) p.spaceAfter = Metric.hwpToPt(ps.spaceAfter);\n if (ps.lineSpacing > 0 && ps.lineSpacing !== 160) p.lineHeight = ps.lineSpacing / 100;\n if (ps.indent > 0) p.indentPt = Metric.hwpToPt(ps.indent);\n return p;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Decoder class\n ═══════════════════════════════════════════════════════════════ */\n\nexport class HwpScanner implements Decoder {\n readonly format = 'hwp';\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n if (!BinaryKit.isOle2(data)) return fail('HWP: Invalid OLE2 signature');\n const streams = BinaryKit.parseCfb(data);\n\n // FileHeader\n const fh = streams.get('FileHeader');\n const { compressed, encrypted } = fh ? parseFileHeader(fh) : { compressed: true, encrypted: false };\n if (encrypted) return fail('HWP: 암호화된 파일은 지원하지 않습니다');\n\n // DocInfo\n const diRaw = streams.get('DocInfo');\n let di: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n if (diRaw) {\n di = shield.guard(() => parseDocInfo(diRaw, compressed), di, 'hwp:docInfo');\n }\n\n // Body sections\n const allContent: ContentNode[] = [];\n let pageDims: PageDims = A4;\n\n for (let s = 0; s < 100; s++) {\n const sec = streams.get(`BodyText/Section${s}`) ?? streams.get(`Section${s}`);\n if (!sec) {\n if (s === 0) {\n const fb = findBodySection(streams);\n if (fb) {\n const r = parseBody(fb, compressed, di, shield);\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n }\n break;\n }\n const r = shield.guard(\n () => parseBody(sec, compressed, di, shield),\n { content: [], pageDims: undefined },\n `hwp:sec${s}`,\n );\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n\n warns.push(...shield.flush());\n const content = allContent.length > 0 ? allContent : [buildPara([buildSpan('')])];\n return succeed(buildRoot({}, [buildSheet(content, pageDims)]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWP decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\nfunction findBodySection(streams: Map<string, Uint8Array>): Uint8Array | undefined {\n for (const [k, v] of streams)\n if (k.includes('Section') && !k.includes('Header') && !k.includes('Info')) return v;\n return undefined;\n}\n\nregistry.registerDecoder(new HwpScanner());\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, GridNode, ImgNode, PageNumNode, CellNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { DocMeta, PageDims, TextProps, ParaProps, CellProps, GridProps, TableLook } from '../../model/doc-props';\nimport { A4 } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildImg, buildGrid, buildRow, buildCell } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { Metric, safeAlign, safeFont, safeHex, safeStrokeDocx } from '../../safety/StyleBridge';\nimport { ArchiveKit } from '../../toolkit/ArchiveKit';\nimport { XmlKit } from '../../toolkit/XmlKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\nexport class DocxDecoder implements Decoder {\n readonly format = 'docx';\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const docXml = files.get('word/document.xml');\n if (!docXml) return fail('DOCX: word/document.xml not found');\n\n const relsXml = files.get('word/_rels/document.xml.rels');\n const relsMap = relsXml ? await parseRels(TextKit.decode(relsXml)) : new Map<string, string>();\n\n const coreXml = files.get('docProps/core.xml');\n let meta: DocMeta = {};\n if (coreXml) {\n try {\n meta = await parseCoreProps(TextKit.decode(coreXml));\n } catch {\n // ignore — meta is optional\n }\n }\n\n // Parse numbering.xml for list support\n const numXml = files.get('word/numbering.xml');\n let numMap: NumMap = new Map();\n if (numXml) {\n try {\n numMap = await parseNumbering(TextKit.decode(numXml));\n } catch { /* non-fatal */ }\n }\n\n const docStr = TextKit.decode(docXml);\n const docObj: any = await XmlKit.parseStrict(docStr);\n\n const body = getBody(docObj);\n const dims = extractDims(body) ?? { ...A4 };\n const elements = getBodyElements(body);\n\n const decCtx: DecCtx = { relsMap, files, shield, numMap, warns };\n\n const kids: ContentNode[] = shield.guardAll(\n elements,\n (el: any) => decodeElement(el, decCtx),\n () => buildPara([buildSpan('[요소 파싱 실패]')]),\n 'docx:bodyElement',\n );\n\n // Decode header/footer\n const headerParas = await decodeHeaderFooter('header', body, relsMap, files, decCtx);\n const footerParas = await decodeHeaderFooter('footer', body, relsMap, files, decCtx);\n\n warns.push(...shield.flush());\n const sheet = buildSheet(\n kids.filter(Boolean) as ContentNode[],\n dims,\n { header: headerParas, footer: footerParas },\n );\n return succeed(buildRoot(meta, [sheet]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`DOCX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── types ─────────────────────────────────────────────────\n\ninterface DecCtx {\n relsMap: Map<string, string>;\n files: Map<string, Uint8Array>;\n shield: ShieldedParser;\n numMap: NumMap;\n warns: string[];\n}\n\n// numId → { abstractNumId, levels: Map<ilvl, { fmt, isOrdered }> }\ntype NumMap = Map<number, { levels: Map<number, { fmt: string; isOrdered: boolean }> }>;\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction toArr(v: any): any[] { return v == null ? [] : Array.isArray(v) ? v : [v]; }\n\nasync function parseRels(xml: string): Promise<Map<string, string>> {\n const map = new Map<string, string>();\n try {\n const obj: any = await XmlKit.parseStrict(xml);\n for (const rel of toArr(obj?.Relationships?.[0]?.Relationship)) {\n const a = rel?._attr ?? {};\n if (a.Id && a.Target) map.set(a.Id, a.Target);\n }\n } catch { /* ignore */ }\n return map;\n}\n\nasync function parseCoreProps(xml: string): Promise<DocMeta> {\n try {\n const obj: any = await XmlKit.parseStrict(xml);\n const c = obj?.['cp:coreProperties']?.[0] ?? obj?.coreProperties?.[0] ?? {};\n return {\n title: c?.['dc:title']?.[0]?._text ?? undefined,\n author: c?.['dc:creator']?.[0]?._text ?? undefined,\n subject: c?.['dc:subject']?.[0]?._text ?? undefined,\n created: c?.['dcterms:created']?.[0]?._text ?? undefined,\n modified: c?.['dcterms:modified']?.[0]?._text ?? undefined,\n };\n } catch { return {}; }\n}\n\nasync function parseNumbering(xml: string): Promise<NumMap> {\n const map: NumMap = new Map();\n try {\n const obj: any = await XmlKit.parseStrict(xml);\n const root = obj?.['w:numbering']?.[0] ?? obj?.numbering?.[0] ?? obj;\n\n // Parse abstractNums\n const absMap = new Map<number, Map<number, { fmt: string; isOrdered: boolean }>>();\n for (const abs of toArr(root?.['w:abstractNum'] ?? root?.abstractNum)) {\n const absId = Number(abs?._attr?.['w:abstractNumId'] ?? abs?._attr?.abstractNumId ?? 0);\n const levels = new Map<number, { fmt: string; isOrdered: boolean }>();\n for (const lvl of toArr(abs?.['w:lvl'] ?? abs?.lvl)) {\n const ilvl = Number(lvl?._attr?.['w:ilvl'] ?? lvl?._attr?.ilvl ?? 0);\n const fmtNode = lvl?.['w:numFmt']?.[0]?._attr ?? lvl?.numFmt?.[0]?._attr ?? {};\n const fmt = fmtNode?.['w:val'] ?? fmtNode?.val ?? 'decimal';\n levels.set(ilvl, { fmt, isOrdered: fmt !== 'bullet' });\n }\n absMap.set(absId, levels);\n }\n\n // Parse nums\n for (const num of toArr(root?.['w:num'] ?? root?.num)) {\n const numId = Number(num?._attr?.['w:numId'] ?? num?._attr?.numId ?? 0);\n const absRef = num?.['w:abstractNumId']?.[0]?._attr ?? num?.abstractNumId?.[0]?._attr ?? {};\n const absId = Number(absRef?.['w:val'] ?? absRef?.val ?? 0);\n const levels = absMap.get(absId) ?? new Map();\n map.set(numId, { levels });\n }\n } catch { /* non-fatal */ }\n return map;\n}\n\nfunction getBody(obj: any): any {\n return obj?.['w:document']?.[0]?.['w:body']?.[0] ?? obj?.document?.[0]?.body?.[0] ?? obj;\n}\n\nfunction extractDims(body: any): PageDims | null {\n try {\n const sp = body?.['w:sectPr']?.[0] ?? body?.sectPr?.[0];\n if (!sp) return null;\n const sz = sp?.['w:pgSz']?.[0]?._attr ?? sp?.pgSz?.[0]?._attr;\n const mar = sp?.['w:pgMar']?.[0]?._attr ?? sp?.pgMar?.[0]?._attr;\n if (!sz) return null;\n return {\n wPt: Metric.dxaToPt(Number(sz['w:w'] ?? sz.w ?? 11906)),\n hPt: Metric.dxaToPt(Number(sz['w:h'] ?? sz.h ?? 16838)),\n mt: Metric.dxaToPt(Number(mar?.['w:top'] ?? mar?.top ?? 1440)),\n mb: Metric.dxaToPt(Number(mar?.['w:bottom'] ?? mar?.bottom ?? 1440)),\n ml: Metric.dxaToPt(Number(mar?.['w:left'] ?? mar?.left ?? 1800)),\n mr: Metric.dxaToPt(Number(mar?.['w:right'] ?? mar?.right ?? 1800)),\n orient: (sz['w:orient'] ?? sz.orient) === 'landscape' ? 'landscape' : 'portrait',\n };\n } catch { return null; }\n}\n\nfunction getBodyElements(body: any): { type: string; node: any }[] {\n const paras = toArr(body?.['w:p'] ?? body?.p);\n const tables = toArr(body?.['w:tbl'] ?? body?.tbl);\n\n if (tables.length === 0) return paras.map((n: any) => ({ type: 'para', node: n }));\n if (paras.length === 0) return tables.map((n: any) => ({ type: 'table', node: n }));\n\n // Use _childOrder from XmlKit to preserve document order\n const childOrder = body?.['_childOrder'] as string[] | undefined;\n if (Array.isArray(childOrder)) {\n const items: { type: string; node: any }[] = [];\n let pi = 0, ti = 0;\n for (const tag of childOrder) {\n if ((tag === 'w:p' || tag === 'p') && pi < paras.length) {\n items.push({ type: 'para', node: paras[pi++] });\n } else if ((tag === 'w:tbl' || tag === 'tbl') && ti < tables.length) {\n items.push({ type: 'table', node: tables[ti++] });\n }\n }\n while (pi < paras.length) items.push({ type: 'para', node: paras[pi++] });\n while (ti < tables.length) items.push({ type: 'table', node: tables[ti++] });\n return items;\n }\n\n // Fallback: paragraphs first, then tables\n return [\n ...paras.map((n: any) => ({ type: 'para', node: n })),\n ...tables.map((n: any) => ({ type: 'table', node: n })),\n ];\n}\n\n// ─── Header/Footer decoding ────────────────────────────────\n\nasync function decodeHeaderFooter(\n kind: 'header' | 'footer',\n body: any,\n relsMap: Map<string, string>,\n files: Map<string, Uint8Array>,\n ctx: DecCtx,\n): Promise<ParaNode[] | undefined> {\n try {\n const sp = body?.['w:sectPr']?.[0] ?? body?.sectPr?.[0];\n if (!sp) return undefined;\n\n const refTag = kind === 'header' ? 'w:headerReference' : 'w:footerReference';\n const refs = toArr(sp?.[refTag] ?? sp?.[refTag.replace('w:', '')]);\n if (refs.length === 0) return undefined;\n\n const rId = refs[0]?._attr?.['r:id'] ?? refs[0]?._attr?.['r:Id'] ?? refs[0]?._attr?.id;\n if (!rId) return undefined;\n\n const target = relsMap.get(rId);\n if (!target) return undefined;\n\n const filePath = target.startsWith('/') ? target.slice(1) : `word/${target}`;\n const fileData = files.get(filePath);\n if (!fileData) return undefined;\n\n const xmlStr = TextKit.decode(fileData);\n const obj: any = await XmlKit.parseStrict(xmlStr);\n\n const rootTag = kind === 'header' ? 'w:hdr' : 'w:ftr';\n const root = obj?.[rootTag]?.[0] ?? obj?.[rootTag.replace('w:', '')]?.[0] ?? obj;\n\n const paras = toArr(root?.['w:p'] ?? root?.p);\n if (paras.length === 0) return undefined;\n\n return paras.map((p: any) => decodePara(p, ctx));\n } catch {\n return undefined;\n }\n}\n\n// ─── Element decoding ──────────────────────────────────────\n\nfunction decodeElement(\n el: { type: string; node: any },\n ctx: DecCtx,\n): ContentNode {\n if (el.type === 'table') {\n const { value } = ctx.shield.guardGrid(\n el.node,\n (n) => decodeGrid(n as any, ctx),\n (n) => decodeGridSimple(n as any),\n (n) => decodeGridFlat(n as any),\n (n) => decodeGridText(n as any) as unknown as GridNode,\n 'docx:table',\n );\n return value;\n }\n return decodePara(el.node, ctx);\n}\n\nfunction decodePara(\n p: any,\n ctx: DecCtx,\n): ParaNode {\n const pPr = p?.['w:pPr']?.[0] ?? {};\n const alignVal = pPr?.['w:jc']?.[0]?._attr?.['w:val'] ?? pPr?.['w:jc']?.[0]?._attr?.val;\n const headStyle = pPr?.['w:pStyle']?.[0]?._attr?.['w:val'] ?? pPr?.['w:pStyle']?.[0]?._attr?.val ?? '';\n\n const props: ParaProps = {\n align: safeAlign(alignVal),\n heading: parseHeading(headStyle),\n };\n\n // List/numbering\n const numPr = pPr?.['w:numPr']?.[0] ?? pPr?.numPr?.[0];\n if (numPr) {\n const ilvlNode = numPr?.['w:ilvl']?.[0]?._attr ?? numPr?.ilvl?.[0]?._attr ?? {};\n const numIdNode = numPr?.['w:numId']?.[0]?._attr ?? numPr?.numId?.[0]?._attr ?? {};\n const ilvl = Number(ilvlNode?.['w:val'] ?? ilvlNode?.val ?? 0);\n const numId = Number(numIdNode?.['w:val'] ?? numIdNode?.val ?? 0);\n\n props.listLv = ilvl;\n const numEntry = ctx.numMap.get(numId);\n if (numEntry) {\n const lvlInfo = numEntry.levels.get(ilvl) ?? numEntry.levels.get(0);\n props.listOrd = lvlInfo?.isOrdered ?? false;\n } else {\n // Fallback: numId=1 is typically bullet, numId=2 is numbered\n props.listOrd = numId >= 2;\n }\n }\n\n const runs = toArr(p?.['w:r'] ?? p?.r);\n const kids: (SpanNode | ImgNode)[] = ctx.shield.guardAll(\n runs,\n (run: any) => decodeRunOrImage(run, ctx),\n () => buildSpan(''),\n 'docx:run',\n );\n\n return buildPara(kids.filter(Boolean) as ParaNode['kids'], props);\n}\n\nfunction decodeRunOrImage(run: any, ctx: DecCtx): SpanNode | ImgNode {\n // Check for drawing (image)\n const drawing = run?.['w:drawing']?.[0] ?? run?.drawing?.[0];\n if (drawing) {\n const img = decodeDrawing(drawing, ctx);\n if (img) return img;\n }\n return decodeRun(run, ctx);\n}\n\nfunction decodeDrawing(drawing: any, ctx: DecCtx): ImgNode | null {\n try {\n const inline = drawing?.['wp:inline']?.[0] ?? drawing?.inline?.[0];\n const anchor = drawing?.['wp:anchor']?.[0] ?? drawing?.anchor?.[0];\n const container = inline ?? anchor;\n if (!container) return null;\n\n // Get dimensions\n const extent = container?.['wp:extent']?.[0]?._attr ?? container?.extent?.[0]?._attr ?? {};\n const cx = Number(extent?.cx ?? 0);\n const cy = Number(extent?.cy ?? 0);\n const wPt = Metric.emuToPt(cx);\n const hPt = Metric.emuToPt(cy);\n\n // Get alt text\n const docPr = container?.['wp:docPr']?.[0]?._attr ?? container?.docPr?.[0]?._attr ?? {};\n const alt = docPr?.descr ?? docPr?.name ?? '';\n\n // Navigate to blip\n const graphic = container?.['a:graphic']?.[0] ?? container?.graphic?.[0];\n const graphicData = graphic?.['a:graphicData']?.[0] ?? graphic?.graphicData?.[0];\n const pic = graphicData?.['pic:pic']?.[0] ?? graphicData?.pic?.[0];\n const blipFill = pic?.['pic:blipFill']?.[0] ?? pic?.blipFill?.[0];\n const blip = blipFill?.['a:blip']?.[0]?._attr ?? blipFill?.blip?.[0]?._attr ?? {};\n const rId = blip?.['r:embed'] ?? blip?.embed;\n\n if (!rId) return null;\n\n const target = ctx.relsMap.get(rId);\n if (!target) return null;\n\n const filePath = target.startsWith('/') ? target.slice(1) : `word/${target}`;\n const fileData = ctx.files.get(filePath);\n if (!fileData) return null;\n\n const ext = target.split('.').pop()?.toLowerCase() ?? 'png';\n const mimeMap: Record<string, ImgNode['mime']> = {\n png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg',\n gif: 'image/gif', bmp: 'image/bmp',\n };\n const mime = mimeMap[ext] ?? 'image/png';\n\n return buildImg(TextKit.base64Encode(fileData), mime, wPt, hPt, alt || undefined);\n } catch {\n return null;\n }\n}\n\nfunction decodeRun(run: any, ctx: DecCtx): SpanNode {\n const rPr = run?.['w:rPr']?.[0] ?? run?.rPr?.[0] ?? {};\n\n const szAttr = rPr?.['w:sz']?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {};\n const szVal = szAttr?.['w:val'] ?? szAttr?.val;\n\n const colorAttr = rPr?.['w:color']?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {};\n const colorVal = colorAttr?.['w:val'] ?? colorAttr?.val;\n\n const fontAttr = rPr?.['w:rFonts']?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {};\n const fontName = fontAttr?.['w:ascii'] ?? fontAttr?.ascii\n ?? fontAttr?.['w:hAnsi'] ?? fontAttr?.hAnsi\n ?? fontAttr?.['w:eastAsia'] ?? fontAttr?.eastAsia;\n\n const underVal = rPr?.['w:u']?.[0]?._attr?.['w:val'] ?? rPr?.['w:u']?.[0]?._attr?.val;\n\n // Background/highlight\n const shdAttr = rPr?.['w:shd']?.[0]?._attr ?? rPr?.shd?.[0]?._attr ?? {};\n const bgVal = safeHex(shdAttr?.['w:fill'] ?? shdAttr?.fill);\n\n // Superscript/subscript\n const vertAlignVal = rPr?.['w:vertAlign']?.[0]?._attr?.['w:val'] ?? rPr?.['w:vertAlign']?.[0]?._attr?.val;\n\n // Check bold/italic/strike — val=\"0\" means explicitly OFF\n const bNode = rPr?.['w:b']?.[0] ?? rPr?.b?.[0];\n const isBold = bNode != null && (bNode?._attr?.['w:val'] ?? bNode?._attr?.val ?? '1') !== '0';\n const iNode = rPr?.['w:i']?.[0] ?? rPr?.i?.[0];\n const isItalic = iNode != null && (iNode?._attr?.['w:val'] ?? iNode?._attr?.val ?? '1') !== '0';\n const sNode = rPr?.['w:strike']?.[0] ?? rPr?.strike?.[0];\n const isStrike = sNode != null && (sNode?._attr?.['w:val'] ?? sNode?._attr?.val ?? '1') !== '0';\n\n const props: TextProps = {\n b: isBold || undefined,\n i: isItalic || undefined,\n u: underVal && underVal !== 'none' ? true : undefined,\n s: isStrike || undefined,\n sup: vertAlignVal === 'superscript' || undefined,\n sub: vertAlignVal === 'subscript' || undefined,\n pt: szVal ? Metric.halfPtToPt(Number(szVal)) : undefined,\n color: safeHex(colorVal),\n font: fontName ? safeFont(fontName) : undefined,\n bg: bgVal,\n };\n\n // Check for field codes (PAGE number)\n const fldChar = run?.['w:fldChar']?.[0]?._attr ?? run?.fldChar?.[0]?._attr;\n const instrText = run?.['w:instrText']?.[0];\n\n const textNodes = toArr(run?.['w:t'] ?? run?.t);\n const content = textNodes.map((t: any) => typeof t === 'string' ? t : t?._ ?? t?._text ?? '').join('');\n\n // Handle page number field in instrText\n if (instrText) {\n const instrStr = typeof instrText === 'string' ? instrText : instrText?._text ?? '';\n if (instrStr.trim().toUpperCase() === 'PAGE') {\n const pageNum: PageNumNode = { tag: 'pagenum', format: 'decimal' };\n return { tag: 'span', props, kids: [pageNum] };\n }\n }\n\n return buildSpan(content, props);\n}\n\nfunction decodeGrid(\n tbl: any,\n ctx: DecCtx,\n): GridNode {\n // Parse tblPr for table styles\n const tblPr = tbl?.['w:tblPr']?.[0] ?? tbl?.tblPr?.[0] ?? {};\n const tblLookAttr = tblPr?.['w:tblLook']?.[0]?._attr ?? tblPr?.tblLook?.[0]?._attr ?? {};\n\n const look: TableLook = {\n firstRow: tblLookAttr?.['w:firstRow'] === '1' || undefined,\n lastRow: tblLookAttr?.['w:lastRow'] === '1' || undefined,\n firstCol: tblLookAttr?.['w:firstColumn'] === '1' || tblLookAttr?.['w:firstCol'] === '1' || undefined,\n lastCol: tblLookAttr?.['w:lastColumn'] === '1' || tblLookAttr?.['w:lastCol'] === '1' || undefined,\n bandedRows: tblLookAttr?.['w:noHBand'] === '0' || undefined,\n bandedCols: tblLookAttr?.['w:noVBand'] === '0' || undefined,\n };\n\n // Parse table borders for defaultStroke\n const tblBorders = tblPr?.['w:tblBorders']?.[0] ?? tblPr?.tblBorders?.[0];\n let defaultStroke = undefined;\n if (tblBorders) {\n const top = tblBorders?.['w:top']?.[0]?._attr ?? tblBorders?.top?.[0]?._attr;\n if (top) {\n defaultStroke = safeStrokeDocx(\n top?.['w:val'] ?? top?.val,\n Number(top?.['w:sz'] ?? top?.sz ?? 4),\n top?.['w:color'] ?? top?.color,\n );\n }\n }\n\n const gridProps: GridProps = { look, defaultStroke };\n\n const rowArr = toArr(tbl?.['w:tr'] ?? tbl?.tr);\n\n // ── Pass 1: parse raw cells with vMerge info ──\n interface RawCell {\n cell: any; gridSpan: number;\n vMergeRestart: boolean; vMergeContinue: boolean;\n }\n const rawGrid: RawCell[][] = rowArr.map((row: any) => {\n const cellArr = toArr(row?.['w:tc'] ?? row?.tc);\n return cellArr.map((cell: any): RawCell => {\n const tcPr = cell?.['w:tcPr']?.[0] ?? {};\n const gridSpan = Number(tcPr?.['w:gridSpan']?.[0]?._attr?.['w:val'] ?? 1);\n const vMergeNode = tcPr?.['w:vMerge']?.[0];\n const vMergeVal = vMergeNode?._attr?.['w:val'] ?? vMergeNode?._attr?.val;\n const vMergeRestart = vMergeVal === 'restart';\n // vMerge present but val is not \"restart\" → continuation cell\n const vMergeContinue = vMergeNode != null && !vMergeRestart;\n return { cell, gridSpan, vMergeRestart, vMergeContinue };\n });\n });\n\n // ── Pass 2: compute rowSpan for restart cells ──\n // rsMap[ri][ci] = computed rowSpan (only set for restart cells)\n const rsMap: Map<string, number> = new Map();\n for (let ri = 0; ri < rawGrid.length; ri++) {\n let gridCol = 0;\n for (let ci = 0; ci < rawGrid[ri].length; ci++) {\n const rc = rawGrid[ri][ci];\n if (rc.vMergeRestart) {\n let span = 1;\n for (let nr = ri + 1; nr < rawGrid.length; nr++) {\n // Find the cell at the same grid column in the next row\n let col = 0;\n let found = false;\n for (const nc of rawGrid[nr]) {\n if (col === gridCol && nc.vMergeContinue) {\n span++;\n found = true;\n break;\n }\n col += nc.gridSpan;\n }\n if (!found) break;\n }\n rsMap.set(`${ri},${ci}`, span);\n }\n gridCol += rc.gridSpan;\n }\n }\n\n // ── Pass 3: build CellNodes, skip continuation cells ──\n const rowNodes = rawGrid.map((rawRow, ri) => {\n // Check for header row\n const row = rowArr[ri];\n const trPr = row?.['w:trPr']?.[0] ?? row?.trPr?.[0] ?? {};\n const isHeaderRow = trPr?.['w:tblHeader']?.[0] != null || trPr?.tblHeader?.[0] != null;\n if (ri === 0 && isHeaderRow) gridProps.headerRow = true;\n\n const cellNodes: CellNode[] = [];\n for (let ci = 0; ci < rawRow.length; ci++) {\n const rc = rawRow[ci];\n // Skip continuation cells — they are part of a vertical merge\n if (rc.vMergeContinue) continue;\n\n const cell = rc.cell;\n const tcPr = cell?.['w:tcPr']?.[0] ?? {};\n\n // Cell background\n const bgAttr = tcPr?.['w:shd']?.[0]?._attr ?? {};\n const bg = safeHex(bgAttr?.['w:fill'] ?? bgAttr?.fill);\n\n // Cell borders\n const tcBorders = tcPr?.['w:tcBorders']?.[0] ?? tcPr?.tcBorders?.[0];\n const cp: CellProps = { bg, isHeader: isHeaderRow || undefined };\n\n if (tcBorders) {\n const dirs: Array<[string, 'top' | 'bot' | 'left' | 'right']> = [\n ['top', 'top'], ['bottom', 'bot'], ['left', 'left'], ['right', 'right'],\n ];\n for (const [xmlTag, propKey] of dirs) {\n const bdr = tcBorders?.['w:' + xmlTag]?.[0]?._attr ?? tcBorders?.[xmlTag]?.[0]?._attr;\n if (bdr) {\n cp[propKey] = safeStrokeDocx(\n bdr?.['w:val'] ?? bdr?.val,\n Number(bdr?.['w:sz'] ?? bdr?.sz ?? 4),\n bdr?.['w:color'] ?? bdr?.color,\n );\n }\n }\n }\n\n // Vertical alignment\n const vaAttr = tcPr?.['w:vAlign']?.[0]?._attr ?? tcPr?.vAlign?.[0]?._attr ?? {};\n const vaVal = vaAttr?.['w:val'] ?? vaAttr?.val;\n if (vaVal) {\n const vaMap: Record<string, 'top' | 'mid' | 'bot'> = { top: 'top', center: 'mid', bottom: 'bot' };\n cp.va = vaMap[vaVal];\n }\n\n const rs = rsMap.get(`${ri},${ci}`) ?? 1;\n\n const paras = toArr(cell?.['w:p'] ?? cell?.p).map((p: any) => decodePara(p, ctx));\n cellNodes.push(buildCell(\n paras.length > 0 ? paras : [buildPara([buildSpan('')])],\n { cs: rc.gridSpan, rs, props: cp },\n ));\n }\n return buildRow(cellNodes);\n });\n return buildGrid(rowNodes, gridProps);\n}\n\nfunction decodeGridSimple(tbl: any): GridNode {\n const rowArr = toArr(tbl?.['w:tr'] ?? tbl?.tr);\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = toArr(row?.['w:tc'] ?? row?.tc);\n return buildRow(cellArr.map((c: any) => buildCell([buildPara([buildSpan(cellText(c))])])));\n });\n return buildGrid(rowNodes);\n}\n\nfunction decodeGridFlat(tbl: any): GridNode {\n return buildGrid([buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])])]);\n}\n\nfunction decodeGridText(tbl: any): ParaNode {\n return buildPara([buildSpan(tableText(tbl))]);\n}\n\nfunction cellText(cell: any): string {\n return toArr(cell?.['w:p'] ?? cell?.p).map((p: any) =>\n toArr(p?.['w:r'] ?? p?.r).map((r: any) =>\n toArr(r?.['w:t'] ?? r?.t).map((t: any) => typeof t === 'string' ? t : t?._ ?? '').join(''),\n ).join(''),\n ).join(' ');\n}\n\nfunction tableText(tbl: any): string {\n return toArr(tbl?.['w:tr'] ?? tbl?.tr).map((row: any) =>\n toArr(row?.['w:tc'] ?? row?.tc).map((c: any) => cellText(c)).join('\\t'),\n ).join('\\n');\n}\n\nfunction parseHeading(style?: string): 1 | 2 | 3 | 4 | 5 | 6 | undefined {\n if (!style) return undefined;\n const m = style.match(/[Hh]eading(\\d)/);\n if (m) { const n = Number(m[1]); if (n >= 1 && n <= 6) return n as any; }\n return undefined;\n}\n\nregistry.registerDecoder(new DocxDecoder());\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, ImgNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { ParaProps, TextProps } from '../../model/doc-props';\nimport { A4 } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildImg, buildGrid, buildRow, buildCell } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\nexport class MdDecoder implements Decoder {\n readonly format = 'md';\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const text = TextKit.decode(data);\n const lines = text.split(/\\r?\\n/);\n const kids: ContentNode[] = [];\n\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n\n // Heading\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length as 1 | 2 | 3 | 4 | 5 | 6;\n kids.push(buildPara([buildSpan(headingMatch[2], { b: level <= 2 })], { heading: level }));\n i++; continue;\n }\n\n // Table (pipe + separator line)\n if (line.includes('|') && i + 1 < lines.length && lines[i + 1].match(/^\\s*\\|?\\s*[-:]+\\s*\\|/)) {\n const tableResult = shield.guard(() => parseMdTable(lines, i), null, `md:table@${i}`);\n if (tableResult) { kids.push(tableResult.node); i = tableResult.nextLine; continue; }\n }\n\n // HR\n if (line.match(/^[-*_]{3,}$/)) { kids.push(buildPara([buildSpan('')], {})); i++; continue; }\n\n // List item\n const listMatch = line.match(/^(\\s*)([-*+]|\\d+\\.)\\s+(.+)$/);\n if (listMatch) {\n kids.push(buildPara(parseInline(listMatch[3]), {\n listLv: Math.floor(listMatch[1].length / 2),\n listOrd: /\\d+\\./.test(listMatch[2]),\n }));\n i++; continue;\n }\n\n // Blockquote\n const bqMatch = line.match(/^>\\s*(.*)$/);\n if (bqMatch) { kids.push(buildPara([buildSpan(bqMatch[1])], { indentPt: 28 })); i++; continue; }\n\n // Code block\n if (line.startsWith('```')) {\n const codeLines: string[] = [];\n i++;\n while (i < lines.length && !lines[i].startsWith('```')) { codeLines.push(lines[i]); i++; }\n i++;\n kids.push(buildPara([buildSpan(codeLines.join('\\n'), { font: 'Courier New' })], {}));\n continue;\n }\n\n // Empty line\n if (line.trim() === '') { i++; continue; }\n\n // Regular paragraph — check for alignment div\n const alignMatch = line.match(/^<div\\s+align=\"(center|right|left)\">(.*?)<\\/div>$/i);\n if (alignMatch) {\n const align = alignMatch[1].toLowerCase() as 'left' | 'center' | 'right';\n kids.push(buildPara(parseInline(alignMatch[2]), { align }));\n i++; continue;\n }\n\n // Regular paragraph\n kids.push(buildPara(parseInline(line), {}));\n i++;\n }\n\n warns.push(...shield.flush());\n const sheet = buildSheet(kids.length > 0 ? kids : [buildPara([buildSpan('')])], A4);\n return succeed(buildRoot({}, [sheet]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`MD decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\nfunction parseInline(text: string): (SpanNode | ImgNode)[] {\n const result: (SpanNode | ImgNode)[] = [];\n let rem = text;\n\n while (rem.length > 0) {\n // Image: \n let m = rem.match(/^(.*?)!\\[([^\\]]*)\\]\\((data:([^;]+);base64,([^)]+))\\)(.*)/s);\n if (m) {\n if (m[1]) result.push(buildSpan(m[1]));\n const mime = m[4] as ImgNode['mime'];\n const validMimes = ['image/png', 'image/jpeg', 'image/gif', 'image/bmp'];\n result.push(buildImg(m[5], validMimes.includes(mime) ? mime : 'image/png', 100, 100, m[2] || undefined));\n rem = m[6]; continue;\n }\n\n // Image:  — non-base64\n m = rem.match(/^(.*?)!\\[([^\\]]*)\\]\\(([^)]+)\\)(.*)/s);\n if (m) {\n if (m[1]) result.push(buildSpan(m[1]));\n // Can't convert URL to base64, just preserve alt text\n result.push(buildSpan(`[이미지: ${m[2] || m[3]}]`));\n rem = m[4]; continue;\n }\n\n // Bold+italic\n m = rem.match(/^(.*?)\\*\\*\\*(.+?)\\*\\*\\*(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { b: true, i: true })); rem = m[3]; continue; }\n\n // Bold\n m = rem.match(/^(.*?)\\*\\*(.+?)\\*\\*(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { b: true })); rem = m[3]; continue; }\n\n // Italic\n m = rem.match(/^(.*?)\\*(.+?)\\*(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { i: true })); rem = m[3]; continue; }\n\n // Strikethrough ~~text~~\n m = rem.match(/^(.*?)~~(.+?)~~(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { s: true })); rem = m[3]; continue; }\n\n // Underline <u>text</u>\n m = rem.match(/^(.*?)<u>(.+?)<\\/u>(.*)/si);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { u: true })); rem = m[3]; continue; }\n\n // Superscript <sup>text</sup>\n m = rem.match(/^(.*?)<sup>(.+?)<\\/sup>(.*)/si);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { sup: true })); rem = m[3]; continue; }\n\n // Subscript <sub>text</sub>\n m = rem.match(/^(.*?)<sub>(.+?)<\\/sub>(.*)/si);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { sub: true })); rem = m[3]; continue; }\n\n // Inline code\n m = rem.match(/^(.*?)`(.+?)`(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { font: 'Courier New' })); rem = m[3]; continue; }\n\n result.push(buildSpan(rem));\n break;\n }\n\n return result.length > 0 ? result : [buildSpan(text)];\n}\n\nfunction parseMdTable(lines: string[], startLine: number): { node: any; nextLine: number } | null {\n const parse = (line: string) => line.split('|').map(c => c.trim()).filter((c, i, arr) => i > 0 || c !== '');\n const headers = parse(lines[startLine]);\n\n let cur = startLine + 2;\n const rows: string[][] = [];\n while (cur < lines.length) {\n if (!lines[cur].includes('|')) break;\n const cells = parse(lines[cur]);\n if (cells.length === 0) break;\n rows.push(cells);\n cur++;\n }\n\n const allRows = [headers, ...rows];\n const gridRows = allRows.map((row, ri) =>\n buildRow(row.map(cell => buildCell([buildPara([buildSpan(cell, ri === 0 ? { b: true } : {})])]))),\n );\n\n return { node: buildGrid(gridRows), nextLine: cur };\n}\n\nregistry.registerDecoder(new MdDecoder());\n","import type { Encoder } from '../../contract/encoder';\nimport type { DocRoot, ParaNode, SpanNode, GridNode, ContentNode, ImgNode, SheetNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { PageDims, TextProps, ParaProps, CellProps, Stroke } from '../../model/doc-props';\nimport { A4, DEFAULT_STROKE } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { Metric, safeFontToKr } from '../../safety/StyleBridge';\nimport { ArchiveKit } from '../../toolkit/ArchiveKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\n// ─── All HWPX namespaces ────────────────────────────────────\nconst NS = [\n 'xmlns:ha=\"http://www.hancom.co.kr/hwpml/2011/app\"',\n 'xmlns:hp=\"http://www.hancom.co.kr/hwpml/2011/paragraph\"',\n 'xmlns:hp10=\"http://www.hancom.co.kr/hwpml/2016/paragraph\"',\n 'xmlns:hs=\"http://www.hancom.co.kr/hwpml/2011/section\"',\n 'xmlns:hc=\"http://www.hancom.co.kr/hwpml/2011/core\"',\n 'xmlns:hh=\"http://www.hancom.co.kr/hwpml/2011/head\"',\n 'xmlns:hhs=\"http://www.hancom.co.kr/hwpml/2011/history\"',\n 'xmlns:hm=\"http://www.hancom.co.kr/hwpml/2011/master-page\"',\n 'xmlns:hpf=\"http://www.hancom.co.kr/schema/2011/hpf\"',\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\"',\n 'xmlns:opf=\"http://www.idpf.org/2007/opf/\"',\n 'xmlns:ooxmlchart=\"http://www.hancom.co.kr/hwpml/2016/ooxmlchart\"',\n 'xmlns:epub=\"http://www.idpf.org/2007/ops\"',\n 'xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"',\n].join(' ');\n\n// ─── Registries for IDRef system ────────────────────────────\n\ninterface CharPrDef {\n id: number;\n height: number;\n bold: boolean;\n italic: boolean;\n underline: string;\n strikeout: string;\n textColor: string;\n fontName: string;\n fontId: number;\n bg?: string;\n}\n\ninterface ParaPrDef {\n id: number;\n align: string;\n listType?: string;\n listLevel?: number;\n}\n\ninterface BinEntry { id: string; name: string; data: Uint8Array }\n\ninterface HwpxCtx {\n charPrs: CharPrDef[];\n charPrMap: Map<string, number>;\n paraPrs: ParaPrDef[];\n paraPrMap: Map<string, number>;\n borderFills: { id: number; xml: string }[];\n bins: BinEntry[];\n nextBinNum: number;\n nextElementId: number;\n availableWidth: number; // HWPUNIT — page width minus margins\n fonts: string[];\n fontMap: Map<string, number>;\n}\n\nfunction charPrKey(p: TextProps): string {\n return `${p.b ? 1 : 0}|${p.i ? 1 : 0}|${p.u ? 1 : 0}|${p.s ? 1 : 0}|${p.pt ?? 10}|${p.color ?? '000000'}|${p.font ?? ''}|${p.bg ?? ''}`;\n}\n\nfunction paraPrKey(p: ParaProps): string {\n return `${p.align ?? 'left'}|${p.listOrd ?? ''}|${p.listLv ?? 0}`;\n}\n\nfunction registerFont(name: string, ctx: HwpxCtx): number {\n const n = name || '굴림체';\n const existing = ctx.fontMap.get(n);\n if (existing !== undefined) return existing;\n const id = ctx.fonts.length;\n ctx.fonts.push(n);\n ctx.fontMap.set(n, id);\n return id;\n}\n\nfunction registerCharPr(props: TextProps, ctx: HwpxCtx): number {\n const key = charPrKey(props);\n const existing = ctx.charPrMap.get(key);\n if (existing !== undefined) return existing;\n\n const fontName = safeFontToKr(props.font) || '굴림체';\n const fontId = registerFont(fontName, ctx);\n\n const id = ctx.charPrs.length;\n const def: CharPrDef = {\n id,\n height: Metric.ptToHHeight(props.pt ?? 10),\n bold: !!props.b,\n italic: !!props.i,\n underline: props.u ? 'BOTTOM' : 'NONE',\n strikeout: props.s ? 'SOLID' : 'NONE',\n textColor: props.color ? `#${props.color}` : '#000000',\n fontName,\n fontId,\n bg: props.bg,\n };\n ctx.charPrs.push(def);\n ctx.charPrMap.set(key, id);\n return id;\n}\n\nfunction registerParaPr(props: ParaProps, ctx: HwpxCtx): number {\n const key = paraPrKey(props);\n const existing = ctx.paraPrMap.get(key);\n if (existing !== undefined) return existing;\n\n const id = ctx.paraPrs.length;\n const def: ParaPrDef = {\n id,\n align: (props.align ?? 'left').toUpperCase(),\n };\n if (props.listOrd !== undefined) {\n def.listType = props.listOrd ? 'DIGIT' : 'BULLET';\n def.listLevel = props.listLv ?? 0;\n }\n ctx.paraPrs.push(def);\n ctx.paraPrMap.set(key, id);\n return id;\n}\n\n// ─── Pre-scan: collect all charPr/paraPr used ───────────────\n\nfunction scanContent(kids: ContentNode[], ctx: HwpxCtx): void {\n for (const kid of kids) {\n if (kid.tag === 'para') scanPara(kid, ctx);\n else if (kid.tag === 'grid') scanGrid(kid, ctx);\n }\n}\n\nfunction scanPara(para: ParaNode, ctx: HwpxCtx): void {\n registerParaPr(para.props, ctx);\n for (const kid of para.kids) {\n if (kid.tag === 'span') registerCharPr(kid.props, ctx);\n else if (kid.tag === 'img') registerImage(kid, ctx);\n }\n}\n\nfunction scanGrid(grid: GridNode, ctx: HwpxCtx): void {\n for (const row of grid.kids)\n for (const cell of row.kids)\n for (const p of cell.kids) scanPara(p, ctx);\n}\n\nfunction scanParas(paras: ParaNode[], ctx: HwpxCtx): void {\n for (const p of paras) scanPara(p, ctx);\n}\n\n// ─── Image handling ─────────────────────────────────────────\n\nfunction mimeToExt(mime: string): string {\n if (mime.includes('jpeg')) return 'jpg';\n if (mime.includes('gif')) return 'gif';\n if (mime.includes('bmp')) return 'bmp';\n return 'png';\n}\n\nfunction registerImage(img: ImgNode, ctx: HwpxCtx): void {\n if ((img as any)._binId) return;\n const ext = mimeToExt(img.mime);\n const id = `BIN${String(ctx.nextBinNum).padStart(4, '0')}`;\n const name = `${id}.${ext}`;\n ctx.nextBinNum++;\n const data = TextKit.base64Decode(img.b64);\n ctx.bins.push({ id, name, data });\n (img as any)._binId = id;\n}\n\n// ─── BorderFill ─────────────────────────────────────────────\n\nfunction addBorderFill(ctx: HwpxCtx, stroke?: Stroke, bgColor?: string): number {\n const id = ctx.borderFills.length + 1;\n const s = stroke ?? DEFAULT_STROKE;\n const kindMap: Record<string, string> = { solid: 'SOLID', dash: 'DASH', dot: 'DOT', double: 'DOUBLE', none: 'NONE' };\n const type = kindMap[s.kind] ?? 'SOLID';\n const w = `${(s.pt * 0.3528).toFixed(2)} mm`;\n const c = s.color.startsWith('#') ? s.color : `#${s.color}`;\n\n let fill = '';\n if (bgColor) {\n const bc = bgColor.startsWith('#') ? bgColor : `#${bgColor}`;\n fill = `<hc:fillBrush><hc:winBrush faceColor=\"${bc}\" hatchColor=\"none\" alpha=\"0\"/></hc:fillBrush>`;\n }\n\n const xml = `<hh:borderFill id=\"${id}\" threeD=\"0\" shadow=\"0\" centerLine=\"NONE\" breakCellSeparateLine=\"0\"><hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/><hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/><hh:leftBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:rightBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:topBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:bottomBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:diagonal type=\"SOLID\" width=\"0.1 mm\" color=\"#000000\"/>${fill}</hh:borderFill>`;\n ctx.borderFills.push({ id, xml });\n return id;\n}\n\n// ─── Encoder class ──────────────────────────────────────────\n\nexport class HwpxEncoder implements Encoder {\n readonly format = 'hwpx';\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n const sheet = doc.kids[0];\n const dims = sheet?.dims ?? A4;\n\n // Available width = page width - left margin - right margin (in HWPUNIT)\n const availableWidth = Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr);\n\n const ctx: HwpxCtx = {\n charPrs: [], charPrMap: new Map(),\n paraPrs: [], paraPrMap: new Map(),\n borderFills: [], bins: [], nextBinNum: 1, nextElementId: 10000,\n availableWidth,\n fonts: [], fontMap: new Map(),\n };\n\n // Default borderFill (id=1, no border)\n addBorderFill(ctx, { kind: 'none', pt: 0.1, color: '000000' });\n // Table border borderFill (id=2)\n addBorderFill(ctx, DEFAULT_STROKE);\n // Default no-border for text areas (id=3)\n addBorderFill(ctx, { kind: 'none', pt: 0.1, color: '000000' });\n\n // Register default charPr (id=0) and paraPr (id=0)\n registerCharPr({}, ctx);\n registerParaPr({}, ctx);\n\n // Pre-scan all content to collect charPr/paraPr/images\n scanContent(sheet?.kids ?? [], ctx);\n if (sheet?.header) scanParas(sheet.header, ctx);\n if (sheet?.footer) scanParas(sheet.footer, ctx);\n\n // Extract plain text preview from document\n const previewText = extractPreviewText(sheet);\n\n // IMPORTANT: Generate section XML FIRST so that borderFills created\n // during table encoding are registered in ctx before headerXml runs.\n const sectionData = TextKit.encode(sectionXml(sheet, dims, ctx));\n const headerData = TextKit.encode(headerXml(dims, doc.meta, ctx));\n\n const entries: { name: string; data: Uint8Array }[] = [\n { name: 'mimetype', data: TextKit.encode('application/hwp+zip') },\n { name: 'version.xml', data: TextKit.encode(VERSION_XML) },\n { name: 'Contents/header.xml', data: headerData },\n { name: 'Contents/section0.xml', data: sectionData },\n { name: 'Preview/PrvText.txt', data: TextKit.encode(previewText) },\n { name: 'settings.xml', data: TextKit.encode(SETTINGS_XML) },\n { name: 'META-INF/container.rdf', data: TextKit.encode(CONTAINER_RDF) },\n { name: 'Contents/content.hpf', data: TextKit.encode(contentHpf(ctx, doc.meta)) },\n { name: 'META-INF/container.xml', data: TextKit.encode(CONTAINER_XML) },\n { name: 'META-INF/manifest.xml', data: TextKit.encode(MANIFEST_XML) },\n ];\n\n for (const bin of ctx.bins) {\n entries.push({ name: `BinData/${bin.name}`, data: bin.data });\n }\n\n return succeed(await ArchiveKit.zip(entries));\n } catch (e: any) {\n return fail(`HWPX encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\n// ─── Constants ──────────────────────────────────────────────\n\nconst VERSION_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><hv:HCFVersion xmlns:hv=\"http://www.hancom.co.kr/hwpml/2011/version\" tagetApplication=\"WORDPROCESSOR\" major=\"5\" minor=\"1\" micro=\"0\" buildNumber=\"1\" os=\"6\" xmlVersion=\"1.2\" application=\"Hancom Office Hangul\" appVersion=\"11, 0, 0, 0\"/>`;\n\nconst CONTAINER_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><ocf:container xmlns:ocf=\"urn:oasis:names:tc:opendocument:xmlns:container\" xmlns:hpf=\"http://www.hancom.co.kr/schema/2011/hpf\"><ocf:rootfiles><ocf:rootfile full-path=\"Contents/content.hpf\" media-type=\"application/hwpml-package+xml\"/><ocf:rootfile full-path=\"Preview/PrvText.txt\" media-type=\"text/plain\"/><ocf:rootfile full-path=\"META-INF/container.rdf\" media-type=\"application/rdf+xml\"/></ocf:rootfiles></ocf:container>`;\n\nconst CONTAINER_RDF = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"><rdf:Description rdf:about=\"\"><ns0:hasPart xmlns:ns0=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#\" rdf:resource=\"Contents/header.xml\"/></rdf:Description><rdf:Description rdf:about=\"Contents/header.xml\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#HeaderFile\"/></rdf:Description><rdf:Description rdf:about=\"\"><ns0:hasPart xmlns:ns0=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#\" rdf:resource=\"Contents/section0.xml\"/></rdf:Description><rdf:Description rdf:about=\"Contents/section0.xml\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#SectionFile\"/></rdf:Description><rdf:Description rdf:about=\"\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#Document\"/></rdf:Description></rdf:RDF>`;\n\nconst MANIFEST_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><odf:manifest xmlns:odf=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\"/>`;\n\nconst SETTINGS_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><ha:HWPApplicationSetting xmlns:ha=\"http://www.hancom.co.kr/hwpml/2011/app\" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"><ha:CaretPosition listIDRef=\"0\" paraIDRef=\"0\" pos=\"0\"/><config:config-item-set name=\"PrintInfo\"><config:config-item name=\"PrintMethod\" type=\"short\">0</config:config-item><config:config-item name=\"ZoomX\" type=\"short\">100</config:config-item><config:config-item name=\"ZoomY\" type=\"short\">100</config:config-item></config:config-item-set></ha:HWPApplicationSetting>`;\n\nfunction contentHpf(ctx: HwpxCtx, meta?: any): string {\n const title = esc(meta?.title ?? '');\n const now = new Date().toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n\n let items = `<opf:item id=\"header\" href=\"Contents/header.xml\" media-type=\"application/xml\"/>`\n + `<opf:item id=\"section0\" href=\"Contents/section0.xml\" media-type=\"application/xml\"/>`\n + `<opf:item id=\"settings\" href=\"settings.xml\" media-type=\"application/xml\"/>`;\n for (const bin of ctx.bins) {\n const ext = bin.name.split('.').pop()?.toLowerCase() ?? 'png';\n const ct = ext === 'png' ? 'image/png' : ext === 'jpg' || ext === 'jpeg' ? 'image/jpeg' : ext === 'gif' ? 'image/gif' : 'image/bmp';\n items += `<opf:item id=\"${bin.id}\" href=\"BinData/${bin.name}\" media-type=\"${ct}\" isEmbeded=\"1\"/>`;\n }\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><opf:package ${NS} version=\"\" unique-identifier=\"\" id=\"\"><opf:metadata><opf:title>${title}</opf:title><opf:language>ko</opf:language><opf:meta name=\"creator\" content=\"text\"/><opf:meta name=\"subject\" content=\"text\"/><opf:meta name=\"description\" content=\"text\"/><opf:meta name=\"CreatedDate\" content=\"text\">${now}</opf:meta><opf:meta name=\"ModifiedDate\" content=\"text\">${now}</opf:meta><opf:meta name=\"keyword\" content=\"text\"/></opf:metadata><opf:manifest>${items}</opf:manifest><opf:spine><opf:itemref idref=\"header\" linear=\"no\"/><opf:itemref idref=\"section0\" linear=\"yes\"/></opf:spine></opf:package>`;\n}\n\n// ─── header.xml ─────────────────────────────────────────────\n\nfunction headerXml(dims: PageDims, meta: any, ctx: HwpxCtx): string {\n // Font face definitions — register all unique fonts per language group\n const fontCount = ctx.fonts.length || 1;\n const langs = ['HANGUL', 'LATIN', 'HANJA', 'JAPANESE', 'OTHER', 'SYMBOL', 'USER'];\n let fontFaces = `<hh:fontfaces itemCnt=\"${langs.length}\">`;\n for (const lang of langs) {\n fontFaces += `<hh:fontface lang=\"${lang}\" fontCnt=\"${fontCount}\">`;\n for (let fi = 0; fi < ctx.fonts.length; fi++) {\n fontFaces += `<hh:font id=\"${fi}\" face=\"${esc(ctx.fonts[fi])}\" type=\"TTF\" isEmbedded=\"0\"><hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/></hh:font>`;\n }\n if (ctx.fonts.length === 0) {\n fontFaces += `<hh:font id=\"0\" face=\"굴림체\" type=\"TTF\" isEmbedded=\"0\"><hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/></hh:font>`;\n }\n fontFaces += `</hh:fontface>`;\n }\n fontFaces += `</hh:fontfaces>`;\n\n // CharPr definitions\n let charPrXml = '';\n for (const cp of ctx.charPrs) {\n const bold = cp.bold ? '<hh:bold/>' : '';\n const italic = cp.italic ? '<hh:italic/>' : '';\n const fid = cp.fontId ?? 0;\n charPrXml += `<hh:charPr id=\"${cp.id}\" height=\"${cp.height}\" textColor=\"${cp.textColor}\" shadeColor=\"none\" useFontSpace=\"0\" useKerning=\"0\" symMark=\"NONE\" borderFillIDRef=\"3\"><hh:fontRef hangul=\"${fid}\" latin=\"${fid}\" hanja=\"${fid}\" japanese=\"${fid}\" other=\"${fid}\" symbol=\"${fid}\" user=\"${fid}\"/><hh:ratio hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/><hh:spacing hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/><hh:relSz hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/><hh:offset hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>${bold}${italic}<hh:underline type=\"${cp.underline}\" shape=\"SOLID\" color=\"#000000\"/><hh:strikeout shape=\"${cp.strikeout}\" color=\"#000000\"/><hh:outline type=\"NONE\"/><hh:shadow type=\"NONE\" color=\"#C0C0C0\" offsetX=\"10\" offsetY=\"10\"/></hh:charPr>`;\n }\n\n // ParaPr definitions\n let paraPrXml = '';\n for (const pp of ctx.paraPrs) {\n paraPrXml += `<hh:paraPr id=\"${pp.id}\" tabPrIDRef=\"0\" condense=\"0\" fontLineHeight=\"0\" snapToGrid=\"0\" suppressLineNumbers=\"0\" checked=\"0\"><hh:align horizontal=\"${pp.align}\" vertical=\"BASELINE\"/><hh:heading type=\"NONE\" idRef=\"0\" level=\"0\"/><hh:breakSetting breakLatinWord=\"KEEP_WORD\" breakNonLatinWord=\"BREAK_WORD\" widowOrphan=\"0\" keepWithNext=\"0\" keepLines=\"0\" pageBreakBefore=\"0\" lineWrap=\"BREAK\"/><hh:autoSpacing eAsianEng=\"0\" eAsianNum=\"0\"/><hh:margin><hc:intent value=\"0\" unit=\"HWPUNIT\"/><hc:left value=\"0\" unit=\"HWPUNIT\"/><hc:right value=\"0\" unit=\"HWPUNIT\"/><hc:prev value=\"0\" unit=\"HWPUNIT\"/><hc:next value=\"0\" unit=\"HWPUNIT\"/></hh:margin><hh:lineSpacing type=\"PERCENT\" value=\"160\" unit=\"HWPUNIT\"/><hh:border borderFillIDRef=\"1\" offsetLeft=\"0\" offsetRight=\"0\" offsetTop=\"0\" offsetBottom=\"0\" connect=\"0\" ignoreMargin=\"0\"/></hh:paraPr>`;\n }\n\n // BorderFill definitions\n const borderFillXml = ctx.borderFills.map(bf => bf.xml).join('');\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><hh:head ${NS} version=\"1.2\" secCnt=\"1\"><hh:beginNum page=\"1\" footnote=\"1\" endnote=\"1\" pic=\"1\" tbl=\"1\" equation=\"1\"/><hh:refList>${fontFaces}<hh:borderFills itemCnt=\"${ctx.borderFills.length}\">${borderFillXml}</hh:borderFills><hh:charProperties itemCnt=\"${ctx.charPrs.length}\">${charPrXml}</hh:charProperties><hh:paraProperties itemCnt=\"${ctx.paraPrs.length}\">${paraPrXml}</hh:paraProperties><hh:tabProperties itemCnt=\"1\"><hh:tabPr id=\"0\" autoTabLeft=\"0\" autoTabRight=\"0\"/></hh:tabProperties><hh:styles itemCnt=\"1\"><hh:style id=\"0\" type=\"PARA\" name=\"바탕글\" engName=\"Normal\" paraPrIDRef=\"0\" charPrIDRef=\"0\" nextStyleIDRef=\"0\" langID=\"1042\" lockForm=\"0\"/></hh:styles></hh:refList><hh:compatibleDocument targetProgram=\"HWP201X\"><hh:layoutCompatibility/></hh:compatibleDocument><hh:docOption><hh:linkinfo path=\"\" pageInherit=\"1\" footnoteInherit=\"0\"/></hh:docOption><hh:trackchageConfig flags=\"56\"/></hh:head>`;\n}\n\n// ─── section0.xml ───────────────────────────────────────────\n\nfunction sectionXml(sheet: SheetNode | undefined, dims: PageDims, ctx: HwpxCtx): string {\n const kids = sheet?.kids ?? [];\n\n // First paragraph includes secPr\n // WIDELY = portrait (standard), NARROWLY = landscape\n const secPr = `<hp:secPr id=\"\" textDirection=\"HORIZONTAL\" spaceColumns=\"1134\" tabStop=\"8000\" outlineShapeIDRef=\"0\" memoShapeIDRef=\"0\" textVerticalWidthHead=\"0\" masterPageCnt=\"0\"><hp:grid lineGrid=\"0\" charGrid=\"0\" wonggojiFormat=\"0\"/><hp:startNum pageStartsOn=\"BOTH\" page=\"0\" pic=\"0\" tbl=\"0\" equation=\"0\"/><hp:visibility hideFirstHeader=\"0\" hideFirstFooter=\"0\" hideFirstMasterPage=\"0\" border=\"SHOW_ALL\" fill=\"SHOW_ALL\" hideFirstPageNum=\"0\" hideFirstEmptyLine=\"0\" showLineNumber=\"0\"/><hp:lineNumberShape restartType=\"0\" countBy=\"0\" distance=\"0\" startNumber=\"0\"/><hp:pagePr landscape=\"${dims.orient === 'landscape' ? 'NARROWLY' : 'WIDELY'}\" width=\"${Metric.ptToHwp(dims.wPt)}\" height=\"${Metric.ptToHwp(dims.hPt)}\" gutterType=\"LEFT_ONLY\"><hp:margin header=\"2834\" footer=\"2834\" gutter=\"0\" left=\"${Metric.ptToHwp(dims.ml)}\" right=\"${Metric.ptToHwp(dims.mr)}\" top=\"${Metric.ptToHwp(dims.mt)}\" bottom=\"${Metric.ptToHwp(dims.mb)}\"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"-1\" type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"284\" belowLine=\"568\" aboveLine=\"852\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"EACH_COLUMN\" beneathText=\"0\"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"0\" type=\"NONE\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"0\" belowLine=\"576\" aboveLine=\"864\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"END_OF_DOCUMENT\" beneathText=\"0\"/></hp:endNotePr><hp:pageBorderFill type=\"BOTH\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\"><hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/></hp:pageBorderFill><hp:pageBorderFill type=\"EVEN\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\"><hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/></hp:pageBorderFill><hp:pageBorderFill type=\"ODD\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\"><hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/></hp:pageBorderFill></hp:secPr><hp:ctrl><hp:colPr id=\"\" type=\"NEWSPAPER\" layout=\"LEFT\" colCount=\"1\" sameSz=\"1\" sameGap=\"0\"/></hp:ctrl>`;\n\n let contentXml = '';\n let isFirst = true;\n\n const defaultLineseg = `<hp:linesegarray><hp:lineseg textpos=\"0\" vertpos=\"0\" vertsize=\"1000\" textheight=\"1000\" baseline=\"850\" spacing=\"600\" horzpos=\"0\" horzsize=\"${ctx.availableWidth}\" flags=\"393216\"/></hp:linesegarray>`;\n\n for (const kid of kids) {\n if (kid.tag === 'para') {\n contentXml += encodePara(kid, ctx, isFirst ? secPr : '');\n isFirst = false;\n } else if (kid.tag === 'grid') {\n // Grid is embedded inside a paragraph's run\n const gridXml = encodeGrid(kid, ctx);\n const prefix = isFirst ? secPr : '';\n contentXml += `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"0\" styleIDRef=\"0\" pageBreak=\"0\" columnBreak=\"0\" merged=\"0\"><hp:run charPrIDRef=\"0\">${prefix}${gridXml}</hp:run>${defaultLineseg}</hp:p>`;\n isFirst = false;\n }\n }\n\n // If empty, add one empty paragraph with secPr\n if (contentXml === '') {\n contentXml = `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"0\" styleIDRef=\"0\" pageBreak=\"0\" columnBreak=\"0\" merged=\"0\"><hp:run charPrIDRef=\"0\">${secPr}<hp:t></hp:t></hp:run>${defaultLineseg}</hp:p>`;\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><hs:sec ${NS}>${contentXml}</hs:sec>`;\n}\n\nfunction encodePara(para: ParaNode, ctx: HwpxCtx, secPr: string = ''): string {\n const paraPrId = registerParaPr(para.props, ctx);\n\n let runs = '';\n for (const kid of para.kids) {\n if (kid.tag === 'span') {\n runs += encodeRun(kid, ctx);\n } else if (kid.tag === 'img') {\n runs += encodeImage(kid, ctx);\n }\n }\n\n // If no runs, add default empty run\n if (runs === '') {\n runs = `<hp:run charPrIDRef=\"0\"><hp:t></hp:t></hp:run>`;\n }\n\n // Inject secPr into first run\n if (secPr) {\n // Insert secPr after the first charPrIDRef attribute close\n const firstRunEnd = runs.indexOf('>');\n if (firstRunEnd > -1) {\n runs = runs.substring(0, firstRunEnd + 1) + secPr + runs.substring(firstRunEnd + 1);\n }\n }\n\n // Compute lineseg values based on font size\n const fontSize = getFontSizeForPara(para, ctx);\n const vertsize = fontSize;\n const textheight = fontSize;\n const baseline = Math.round(fontSize * 0.85);\n const spacing = Math.round(fontSize * 0.6);\n const linesegarray = `<hp:linesegarray><hp:lineseg textpos=\"0\" vertpos=\"0\" vertsize=\"${vertsize}\" textheight=\"${textheight}\" baseline=\"${baseline}\" spacing=\"${spacing}\" horzpos=\"0\" horzsize=\"${ctx.availableWidth}\" flags=\"393216\"/></hp:linesegarray>`;\n\n return `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"${paraPrId}\" styleIDRef=\"0\" pageBreak=\"0\" columnBreak=\"0\" merged=\"0\">${runs}${linesegarray}</hp:p>`;\n}\n\n/** Get the font size (in HWPX height units, 1000=10pt) for lineseg computation */\nfunction getFontSizeForPara(para: ParaNode, ctx: HwpxCtx): number {\n for (const kid of para.kids) {\n if (kid.tag === 'span') {\n const charPrId = ctx.charPrMap.get(charPrKey(kid.props));\n if (charPrId !== undefined && ctx.charPrs[charPrId]) {\n return ctx.charPrs[charPrId].height;\n }\n }\n }\n return 1000; // default 10pt\n}\n\nfunction encodeRun(span: SpanNode, ctx: HwpxCtx): string {\n const charPrId = registerCharPr(span.props, ctx);\n\n const parts: string[] = [];\n for (const kid of span.kids) {\n if (kid.tag === 'txt') {\n if (kid.content) {\n parts.push(`<hp:t>${esc(kid.content)}</hp:t>`);\n } else {\n parts.push(`<hp:t></hp:t>`);\n }\n } else if (kid.tag === 'pagenum') {\n const fmt = kid.format === 'roman' ? 'ROMAN_LOWER' : kid.format === 'romanCaps' ? 'ROMAN_UPPER' : 'DIGIT';\n parts.push(`<hp:pageNum pageStartsOn=\"BOTH\" formatType=\"${fmt}\"/>`);\n } else if (kid.tag === 'br') {\n parts.push(`<hp:t>\\n</hp:t>`);\n }\n }\n\n return `<hp:run charPrIDRef=\"${charPrId}\">${parts.join('')}</hp:run>`;\n}\n\nfunction encodeImage(img: ImgNode, ctx: HwpxCtx): string {\n const binId = (img as any)._binId;\n if (!binId) return '';\n\n const charPrId = registerCharPr({}, ctx);\n const w = Metric.ptToHwp(img.w);\n const h = Metric.ptToHwp(img.h);\n\n return `<hp:run charPrIDRef=\"${charPrId}\"><hp:pic id=\"${ctx.nextElementId++}\" zOrder=\"0\" numberingType=\"PICTURE\" textWrap=\"TOP_AND_BOTTOM\" textFlow=\"BOTH_SIDES\" lock=\"0\" dropcapstyle=\"None\" pageBreak=\"CELL\" treatAsChar=\"1\"><hp:sz width=\"${w}\" widthRelTo=\"ABSOLUTE\" height=\"${h}\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/><hp:pos treatAsChar=\"1\" affectLSpacing=\"0\" flowWithText=\"1\" allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" vertAlign=\"TOP\" horzAlign=\"LEFT\" vertOffset=\"0\" horzOffset=\"0\"/><hp:outMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/><hp:imgRect x=\"0\" y=\"0\" w=\"${w}\" h=\"${h}\"/><hp:imgClip left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/><hp:img binaryItemIDRef=\"${binId}\" bright=\"0\" contrast=\"0\" effect=\"REAL_PIC\" alpha=\"0\"/></hp:pic></hp:run>`;\n}\n\nfunction encodeGrid(grid: GridNode, ctx: HwpxCtx): string {\n const rowCount = grid.kids.length;\n\n // Compute true column count: max total colSpan across all rows\n let colCount = 0;\n for (const row of grid.kids) {\n let rowCols = 0;\n for (const cell of row.kids) rowCols += cell.cs;\n if (rowCols > colCount) colCount = rowCols;\n }\n if (colCount === 0) colCount = grid.kids[0]?.kids.length ?? 1;\n\n // Calculate column widths in HWPUNIT\n const totalWidth = ctx.availableWidth;\n const defaultColW = Math.round(totalWidth / (colCount || 1));\n const colWidths: number[] = [];\n if (grid.props.colWidths && grid.props.colWidths.length === colCount) {\n // Fill zero-width columns by distributing remaining space\n const srcPt = [...grid.props.colWidths];\n const knownTotal = srcPt.filter(w => w > 0).reduce((s, w) => s + w, 0);\n const zeroCount = srcPt.filter(w => w <= 0).length;\n const remaining = Math.max(0, Metric.hwpToPt(totalWidth) - knownTotal);\n const zeroFill = zeroCount > 0 ? remaining / zeroCount : 0;\n for (let i = 0; i < srcPt.length; i++) {\n if (srcPt[i] <= 0) srcPt[i] = zeroFill > 0 ? zeroFill : Metric.hwpToPt(defaultColW);\n }\n for (const wPt of srcPt) colWidths.push(Metric.ptToHwp(wPt));\n } else {\n for (let c = 0; c < colCount; c++) colWidths.push(defaultColW);\n }\n // Scale to fit available width\n const rawTotal = colWidths.reduce((s, w) => s + w, 0);\n if (rawTotal > totalWidth * 1.05) {\n const scale = totalWidth / rawTotal;\n for (let i = 0; i < colWidths.length; i++) colWidths[i] = Math.round(colWidths[i] * scale);\n }\n const actualTotal = colWidths.reduce((s, w) => s + w, 0);\n\n // Table borderFillIDRef\n const tblBfId = grid.props.defaultStroke\n ? addBorderFill(ctx, grid.props.defaultStroke)\n : 2; // default table border\n\n // Rows\n let rowsXml = '';\n for (let ri = 0; ri < grid.kids.length; ri++) {\n const row = grid.kids[ri];\n let cellsXml = '';\n let colIdx = 0;\n for (let ci = 0; ci < row.kids.length; ci++) {\n const cell = row.kids[ci];\n\n // Cell borderFill\n let cellBfId = tblBfId;\n if (cell.props.bg) {\n cellBfId = addBorderFill(ctx, grid.props.defaultStroke ?? DEFAULT_STROKE, cell.props.bg);\n }\n\n // Encode cell paragraphs\n const parasXml = cell.kids.map(p => encodePara(p, ctx)).join('');\n\n // Calculate cell width from column widths\n let cellW = 0;\n for (let sc = colIdx; sc < colIdx + cell.cs && sc < colWidths.length; sc++) cellW += colWidths[sc];\n if (cellW === 0) cellW = defaultColW * cell.cs;\n\n cellsXml += `<hp:tc name=\"\" header=\"0\" hasMargin=\"1\" protect=\"0\" editable=\"0\" dirty=\"0\" borderFillIDRef=\"${cellBfId}\"><hp:subList id=\"\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"${cell.props.va === 'mid' ? 'CENTER' : cell.props.va === 'bot' ? 'BOTTOM' : 'TOP'}\" linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"0\" textHeight=\"0\" hasTextRef=\"0\" hasNumRef=\"0\">${parasXml}</hp:subList><hp:cellAddr colAddr=\"${colIdx}\" rowAddr=\"${ri}\"/><hp:cellSpan colSpan=\"${cell.cs}\" rowSpan=\"${cell.rs}\"/><hp:cellSz width=\"${cellW}\" height=\"1000\"/><hp:cellMargin left=\"141\" right=\"141\" top=\"141\" bottom=\"141\"/></hp:tc>`;\n colIdx += cell.cs;\n }\n rowsXml += `<hp:tr>${cellsXml}</hp:tr>`;\n }\n\n const headerRow = grid.props.headerRow ? ' repeatHeader=\"1\"' : '';\n\n return `<hp:tbl id=\"${ctx.nextElementId++}\" zOrder=\"0\" numberingType=\"TABLE\" textWrap=\"TOP_AND_BOTTOM\" textFlow=\"BOTH_SIDES\" lock=\"0\" dropcapstyle=\"None\" pageBreak=\"CELL\"${headerRow} rowCnt=\"${rowCount}\" colCnt=\"${colCount}\" cellSpacing=\"0\" borderFillIDRef=\"${tblBfId}\" noAdjust=\"0\"><hp:sz width=\"${actualTotal}\" widthRelTo=\"ABSOLUTE\" height=\"1000\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/><hp:pos treatAsChar=\"1\" affectLSpacing=\"0\" flowWithText=\"1\" allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" vertAlign=\"TOP\" horzAlign=\"LEFT\" vertOffset=\"0\" horzOffset=\"0\"/><hp:outMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/><hp:inMargin left=\"138\" right=\"138\" top=\"138\" bottom=\"138\"/>${rowsXml}</hp:tbl>`;\n}\n\nfunction extractPreviewText(sheet?: SheetNode): string {\n if (!sheet) return '';\n const lines: string[] = [];\n for (const kid of sheet.kids) {\n if (kid.tag === 'para') {\n const text = kid.kids.map(k => {\n if (k.tag === 'span') return k.kids.map(c => c.tag === 'txt' ? c.content : '').join('');\n return '';\n }).join('');\n if (text) lines.push(text);\n } else if (kid.tag === 'grid') {\n for (const row of kid.kids) {\n const cells = row.kids.map(cell =>\n cell.kids.map(p => p.kids.map(k => {\n if (k.tag === 'span') return k.kids.map(c => c.tag === 'txt' ? c.content : '').join('');\n return '';\n }).join('')).join('')\n );\n lines.push(cells.join('\\t'));\n }\n }\n }\n return lines.join('\\r\\n');\n}\n\nfunction esc(s: string): string { return TextKit.escapeXml(s); }\n\nregistry.registerEncoder(new HwpxEncoder());\n","import type { Encoder } from '../../contract/encoder';\nimport type { DocRoot, ParaNode, SpanNode, GridNode, ContentNode, ImgNode, SheetNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { PageDims, GridProps, CellProps } from '../../model/doc-props';\nimport { A4 } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { Metric } from '../../safety/StyleBridge';\nimport { ArchiveKit } from '../../toolkit/ArchiveKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\ninterface ImageEntry { rId: string; name: string; data: Uint8Array; ext: string }\n\nexport class DocxEncoder implements Encoder {\n readonly format = 'docx';\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n const sheet = doc.kids[0];\n const dims = sheet?.dims ?? A4;\n const kids = sheet?.kids ?? [];\n\n const images: ImageEntry[] = [];\n const ctx: EncCtx = { images, nextId: 10, nextImgNum: 1, warns: [] };\n\n // Collect images from content\n collectImages(kids, ctx);\n\n // Header / footer\n let headerParas = sheet?.header;\n let footerParas = sheet?.footer;\n const hasHeader = headerParas && headerParas.length > 0;\n const hasFooter = footerParas && footerParas.length > 0;\n\n // Collect images from header/footer\n if (hasHeader) collectImagesFromParas(headerParas!, ctx);\n if (hasFooter) collectImagesFromParas(footerParas!, ctx);\n\n const headerRId = hasHeader ? `rId${ctx.nextId++}` : '';\n const footerRId = hasFooter ? `rId${ctx.nextId++}` : '';\n\n // Numbering: collect list info\n const numInfo = collectNumbering(kids);\n\n const entries: { name: string; data: Uint8Array }[] = [\n { name: '[Content_Types].xml', data: TextKit.encode(contentTypes(images, hasHeader, hasFooter)) },\n { name: '_rels/.rels', data: TextKit.encode(pkgRels()) },\n { name: 'word/document.xml', data: TextKit.encode(documentXml(kids, dims, ctx, headerRId, footerRId)) },\n { name: 'word/styles.xml', data: TextKit.encode(stylesXml()) },\n { name: 'word/settings.xml', data: TextKit.encode(settingsXml()) },\n { name: 'word/_rels/document.xml.rels', data: TextKit.encode(docRels(images, headerRId, footerRId, numInfo.hasLists)) },\n { name: 'docProps/app.xml', data: TextKit.encode(appXml()) },\n { name: 'docProps/core.xml', data: TextKit.encode(coreXml(doc.meta)) },\n ];\n\n // Add numbering.xml if needed\n if (numInfo.hasLists) {\n entries.push({ name: 'word/numbering.xml', data: TextKit.encode(numberingXml(numInfo)) });\n }\n\n // Add header/footer files\n if (hasHeader) {\n entries.push({ name: 'word/header1.xml', data: TextKit.encode(headerFooterXml('hdr', headerParas!, ctx)) });\n }\n if (hasFooter) {\n entries.push({ name: 'word/footer1.xml', data: TextKit.encode(headerFooterXml('ftr', footerParas!, ctx)) });\n }\n\n // Add image media files\n for (const img of images) {\n entries.push({ name: `word/media/${img.name}`, data: img.data });\n }\n\n return succeed(await ArchiveKit.zip(entries));\n } catch (e: any) {\n return fail(`DOCX encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\n// ─── Context ────────────────────────────────────────────────\n\ninterface EncCtx {\n images: ImageEntry[];\n nextId: number;\n nextImgNum: number;\n warns: string[];\n}\n\n// ─── Image collection ───────────────────────────────────────\n\nfunction mimeToExt(mime: string): string {\n if (mime.includes('jpeg')) return 'jpeg';\n if (mime.includes('gif')) return 'gif';\n if (mime.includes('bmp')) return 'bmp';\n return 'png';\n}\n\nfunction collectImages(kids: ContentNode[], ctx: EncCtx): void {\n for (const kid of kids) {\n if (kid.tag === 'para') collectImagesFromPara(kid, ctx);\n else if (kid.tag === 'grid') {\n for (const row of kid.kids)\n for (const cell of row.kids)\n for (const p of cell.kids) collectImagesFromPara(p, ctx);\n }\n }\n}\n\nfunction collectImagesFromParas(paras: ParaNode[], ctx: EncCtx): void {\n for (const p of paras) collectImagesFromPara(p, ctx);\n}\n\nfunction collectImagesFromPara(para: ParaNode, ctx: EncCtx): void {\n for (const kid of para.kids) {\n if (kid.tag === 'img') registerImage(kid, ctx);\n }\n}\n\nfunction registerImage(img: ImgNode, ctx: EncCtx): void {\n // Check if already registered (by b64 reference)\n if ((img as any)._rId) return;\n const ext = mimeToExt(img.mime);\n const name = `image${ctx.nextImgNum++}.${ext}`;\n const rId = `rId${ctx.nextId++}`;\n const data = TextKit.base64Decode(img.b64);\n ctx.images.push({ rId, name, data, ext });\n (img as any)._rId = rId;\n}\n\n// ─── List/numbering collection ──────────────────────────────\n\ninterface NumInfo {\n hasLists: boolean;\n hasBullet: boolean;\n hasNumbered: boolean;\n}\n\nfunction collectNumbering(kids: ContentNode[]): NumInfo {\n let hasBullet = false;\n let hasNumbered = false;\n for (const kid of kids) {\n if (kid.tag === 'para') {\n if (kid.props.listOrd === true) hasNumbered = true;\n else if (kid.props.listOrd === false) hasBullet = true;\n }\n }\n return { hasLists: hasBullet || hasNumbered, hasBullet, hasNumbered };\n}\n\n// ─── OOXML boilerplate ──────────────────────────────────────\n\nfunction contentTypes(images: ImageEntry[], hasHeader?: boolean, hasFooter?: boolean): string {\n const imgDefaults = new Set<string>();\n for (const img of images) imgDefaults.add(img.ext);\n\n let defaults = `<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>`;\n\n for (const ext of imgDefaults) {\n const ct = ext === 'png' ? 'image/png' : ext === 'jpeg' ? 'image/jpeg' : ext === 'gif' ? 'image/gif' : 'image/bmp';\n defaults += `\\n <Default Extension=\"${ext}\" ContentType=\"${ct}\"/>`;\n }\n\n let overrides = `<Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>\n <Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>\n <Override PartName=\"/word/settings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/>\n <Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>\n <Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>`;\n\n if (hasHeader) overrides += `\\n <Override PartName=\"/word/header1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml\"/>`;\n if (hasFooter) overrides += `\\n <Override PartName=\"/word/footer1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml\"/>`;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n ${defaults}\n ${overrides}\n</Types>`;\n}\n\nfunction pkgRels(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>\n <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>\n</Relationships>`;\n}\n\nfunction docRels(images: ImageEntry[], headerRId?: string, footerRId?: string, hasLists?: boolean): string {\n let rels = `<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>`;\n\n // Numbering relationship — only when lists exist\n if (hasLists) {\n rels += `\\n <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>`;\n }\n\n for (const img of images) {\n rels += `\\n <Relationship Id=\"${img.rId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/${img.name}\"/>`;\n }\n\n if (headerRId) {\n rels += `\\n <Relationship Id=\"${headerRId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/>`;\n }\n if (footerRId) {\n rels += `\\n <Relationship Id=\"${footerRId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/>`;\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n ${rels}\n</Relationships>`;\n}\n\nfunction appXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\">\n <Application>hwpkit</Application>\n</Properties>`;\n}\n\nfunction coreXml(meta: any): string {\n const now = new Date().toISOString();\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n <dc:title>${esc(meta.title ?? '')}</dc:title>\n <dc:creator>${esc(meta.author ?? '')}</dc:creator>\n <dcterms:created xsi:type=\"dcterms:W3CDTF\">${meta.created ?? now}</dcterms:created>\n <dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>\n</cp:coreProperties>`;\n}\n\nfunction stylesXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:docDefaults>\n <w:rPrDefault><w:rPr>\n <w:rFonts w:ascii=\"맑은 고딕\" w:eastAsia=\"맑은 고딕\" w:hAnsi=\"맑은 고딕\"/>\n <w:sz w:val=\"20\"/>\n <w:szCs w:val=\"20\"/>\n </w:rPr></w:rPrDefault>\n <w:pPrDefault><w:pPr>\n <w:spacing w:after=\"0\" w:line=\"384\" w:lineRule=\"auto\"/>\n <w:jc w:val=\"both\"/>\n </w:pPr></w:pPrDefault>\n </w:docDefaults>\n <w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading1\"><w:name w:val=\"heading 1\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:keepNext/><w:outlineLvl w:val=\"0\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"44\"/><w:szCs w:val=\"44\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading2\"><w:name w:val=\"heading 2\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:keepNext/><w:outlineLvl w:val=\"1\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"36\"/><w:szCs w:val=\"36\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading3\"><w:name w:val=\"heading 3\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:keepNext/><w:outlineLvl w:val=\"2\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Header\"><w:name w:val=\"header\"/><w:basedOn w:val=\"Normal\"/></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Footer\"><w:name w:val=\"footer\"/><w:basedOn w:val=\"Normal\"/></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"ListParagraph\"><w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:ind w:left=\"720\"/></w:pPr></w:style>\n <w:style w:type=\"table\" w:styleId=\"TableGrid\"><w:name w:val=\"Table Grid\"/><w:tblPr><w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/></w:tblBorders></w:tblPr></w:style>\n</w:styles>`;\n}\n\nfunction settingsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:zoom w:percent=\"100\"/>\n <w:bordersDoNotSurroundHeader/>\n <w:bordersDoNotSurroundFooter/>\n <w:defaultTabStop w:val=\"800\"/>\n <w:compat>\n <w:spaceForUL/>\n <w:balanceSingleByteDoubleByteWidth/>\n <w:doNotLeaveBackslashAlone/>\n <w:ulTrailSpace/>\n <w:doNotExpandShiftReturn/>\n <w:adjustLineHeightInTable/>\n <w:useFELayout/>\n </w:compat>\n</w:settings>`;\n}\n\n// ─── numbering.xml ──────────────────────────────────────────\n\nfunction numberingXml(info: NumInfo): string {\n let abstractNums = '';\n let nums = '';\n\n // Bullet list: abstractNumId=0, numId=1\n if (info.hasBullet) {\n abstractNums += `<w:abstractNum w:abstractNumId=\"0\">`;\n for (let lvl = 0; lvl < 9; lvl++) {\n const marker = lvl === 0 ? '●' : lvl === 1 ? '○' : '■';\n const indent = (lvl + 1) * 720;\n abstractNums += `<w:lvl w:ilvl=\"${lvl}\"><w:numFmt w:val=\"bullet\"/><w:lvlText w:val=\"${marker}\"/><w:pPr><w:ind w:left=\"${indent}\" w:hanging=\"360\"/></w:pPr></w:lvl>`;\n }\n abstractNums += `</w:abstractNum>`;\n nums += `<w:num w:numId=\"1\"><w:abstractNumId w:val=\"0\"/></w:num>`;\n }\n\n // Numbered list: abstractNumId=1, numId=2\n if (info.hasNumbered) {\n abstractNums += `<w:abstractNum w:abstractNumId=\"1\">`;\n for (let lvl = 0; lvl < 9; lvl++) {\n const fmt = lvl % 3 === 0 ? 'decimal' : lvl % 3 === 1 ? 'lowerLetter' : 'lowerRoman';\n const indent = (lvl + 1) * 720;\n abstractNums += `<w:lvl w:ilvl=\"${lvl}\"><w:start w:val=\"1\"/><w:numFmt w:val=\"${fmt}\"/><w:lvlText w:val=\"%${lvl + 1}.\"/><w:pPr><w:ind w:left=\"${indent}\" w:hanging=\"360\"/></w:pPr></w:lvl>`;\n }\n abstractNums += `</w:abstractNum>`;\n nums += `<w:num w:numId=\"2\"><w:abstractNumId w:val=\"1\"/></w:num>`;\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:numbering xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n ${abstractNums}\n ${nums}\n</w:numbering>`;\n}\n\n// ─── header / footer xml ────────────────────────────────────\n\nfunction headerFooterXml(type: 'hdr' | 'ftr', paras: ParaNode[], ctx: EncCtx): string {\n const tag = type === 'hdr' ? 'w:hdr' : 'w:ftr';\n const body = paras.map(p => encodeParaInner(p, ctx)).join('\\n');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<${tag} xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n${body}\n</${tag}>`;\n}\n\n// ─── document.xml ───────────────────────────────────────────\n\nfunction documentXml(kids: ContentNode[], dims: PageDims, ctx: EncCtx, headerRId?: string, footerRId?: string): string {\n const body = kids.map(k => encodeContent(k, ctx, dims)).join('\\n');\n\n let sectRefs = '';\n if (headerRId) sectRefs += `\\n <w:headerReference w:type=\"default\" r:id=\"${headerRId}\"/>`;\n if (footerRId) sectRefs += `\\n <w:footerReference w:type=\"default\" r:id=\"${footerRId}\"/>`;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:document xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n <w:body>\n${body}\n <w:sectPr>${sectRefs}\n <w:pgSz w:w=\"${Metric.ptToDxa(dims.wPt)}\" w:h=\"${Metric.ptToDxa(dims.hPt)}\" w:orient=\"${dims.orient ?? 'portrait'}\"/>\n <w:pgMar w:top=\"${Metric.ptToDxa(dims.mt)}\" w:right=\"${Metric.ptToDxa(dims.mr)}\" w:bottom=\"${Metric.ptToDxa(dims.mb)}\" w:left=\"${Metric.ptToDxa(dims.ml)}\" w:header=\"709\" w:footer=\"709\" w:gutter=\"0\"/>\n </w:sectPr>\n </w:body>\n</w:document>`;\n}\n\nfunction encodeContent(node: ContentNode, ctx: EncCtx, dims?: PageDims): string {\n return node.tag === 'grid' ? encodeGrid(node, ctx, dims) : encodeParaInner(node, ctx);\n}\n\nfunction encodeParaInner(para: ParaNode, ctx: EncCtx): string {\n const align = para.props.align ?? 'left';\n const headStyle = para.props.heading ? `<w:pStyle w:val=\"Heading${para.props.heading}\"/>` : '';\n\n // List numbering\n let numPr = '';\n if (para.props.listOrd !== undefined) {\n const numId = para.props.listOrd ? 2 : 1;\n const ilvl = para.props.listLv ?? 0;\n numPr = `<w:pStyle w:val=\"ListParagraph\"/><w:numPr><w:ilvl w:val=\"${ilvl}\"/><w:numId w:val=\"${numId}\"/></w:numPr>`;\n }\n\n const runs = para.kids.map(k => {\n if (k.tag === 'span') return encodeRun(k, ctx);\n if (k.tag === 'img') return encodeImage(k, ctx);\n return '';\n }).join('');\n\n return ` <w:p>\n <w:pPr>${headStyle}${numPr}<w:jc w:val=\"${align === 'justify' ? 'both' : align}\"/></w:pPr>\n ${runs}\n </w:p>`;\n}\n\nfunction encodeRun(span: SpanNode, _ctx: EncCtx): string {\n const p = span.props;\n const rPr: string[] = [];\n if (p.b) rPr.push('<w:b/>');\n if (p.i) rPr.push('<w:i/>');\n if (p.u) rPr.push('<w:u w:val=\"single\"/>');\n if (p.s) rPr.push('<w:strike/>');\n if (p.sup) rPr.push('<w:vertAlign w:val=\"superscript\"/>');\n if (p.sub) rPr.push('<w:vertAlign w:val=\"subscript\"/>');\n if (p.pt) rPr.push(`<w:sz w:val=\"${Metric.ptToHalfPt(p.pt)}\"/><w:szCs w:val=\"${Metric.ptToHalfPt(p.pt)}\"/>`);\n if (p.color) rPr.push(`<w:color w:val=\"${p.color}\"/>`);\n if (p.font) rPr.push(`<w:rFonts w:ascii=\"${esc(p.font)}\" w:hAnsi=\"${esc(p.font)}\" w:eastAsia=\"${esc(p.font)}\"/>`);\n if (p.bg) rPr.push(`<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${p.bg}\"/>`);\n\n // Process kids — text and pagenum\n const parts: string[] = [];\n for (const kid of span.kids) {\n if (kid.tag === 'txt') {\n parts.push(`<w:r><w:rPr>${rPr.join('')}</w:rPr><w:t xml:space=\"preserve\">${esc(kid.content)}</w:t></w:r>`);\n } else if (kid.tag === 'pagenum') {\n parts.push(`<w:r><w:rPr>${rPr.join('')}</w:rPr><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:instrText> PAGE </w:instrText></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:fldChar w:fldCharType=\"separate\"/></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:t>1</w:t></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:fldChar w:fldCharType=\"end\"/></w:r>`);\n } else if (kid.tag === 'br') {\n parts.push(`<w:r><w:br/></w:r>`);\n } else if (kid.tag === 'pb') {\n parts.push(`<w:r><w:br w:type=\"page\"/></w:r>`);\n }\n }\n\n return parts.join('');\n}\n\nfunction encodeImage(img: ImgNode, _ctx: EncCtx): string {\n const rId = (img as any)._rId;\n if (!rId) return '';\n\n const cx = Metric.ptToEmu(img.w);\n const cy = Metric.ptToEmu(img.h);\n const alt = esc(img.alt ?? '');\n\n return `<w:r><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\"${cx}\" cy=\"${cy}\"/><wp:docPr id=\"${_ctx.nextId++}\" name=\"Image\" descr=\"${alt}\"/><a:graphic><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic><pic:nvPicPr><pic:cNvPr id=\"0\" name=\"Image\"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"${rId}\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"${cx}\" cy=\"${cy}\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;\n}\n\nfunction encodeGrid(grid: GridNode, ctx: EncCtx, dims?: PageDims): string {\n const gp = grid.props;\n const look = gp.look;\n\n // tblLook attributes\n const firstRow = look?.firstRow ? '1' : '0';\n const lastRow = look?.lastRow ? '1' : '0';\n const firstCol = look?.firstCol ? '1' : '0';\n const lastCol = look?.lastCol ? '1' : '0';\n const noHBand = look?.bandedRows ? '0' : '1';\n const noVBand = look?.bandedCols ? '0' : '1';\n\n // Determine actual grid column count from colWidths or by scanning all rows\n const d = dims ?? A4;\n const availDxa = Metric.ptToDxa(d.wPt - d.ml - d.mr);\n\n // Compute true column count: max total colSpan across all rows\n let colCount = 0;\n for (const row of grid.kids) {\n let rowCols = 0;\n for (const cell of row.kids) rowCols += cell.cs;\n if (rowCols > colCount) colCount = rowCols;\n }\n if (colCount === 0) colCount = grid.kids[0]?.kids.length ?? 1;\n\n const defaultColDxa = Math.round(availDxa / colCount);\n\n // Use actual column widths if available from source format\n const colWidthsDxa: number[] = [];\n if (grid.props.colWidths && grid.props.colWidths.length === colCount) {\n // Fill zero-width columns by distributing remaining space\n const srcPt = [...grid.props.colWidths];\n const knownTotal = srcPt.filter(w => w > 0).reduce((s, w) => s + w, 0);\n const zeroCount = srcPt.filter(w => w <= 0).length;\n const remaining = Math.max(0, Metric.dxaToPt(availDxa) - knownTotal);\n const zeroFill = zeroCount > 0 ? remaining / zeroCount : 0;\n for (let i = 0; i < srcPt.length; i++) {\n if (srcPt[i] <= 0) srcPt[i] = zeroFill > 0 ? zeroFill : Metric.dxaToPt(defaultColDxa);\n }\n const srcWidths = srcPt.map(w => Metric.ptToDxa(w));\n const srcTotal = srcWidths.reduce((s, w) => s + w, 0);\n // Normalize to fit available page width if source widths exceed it\n const scale = srcTotal > availDxa ? availDxa / srcTotal : 1;\n for (const w of srcWidths) colWidthsDxa.push(Math.round(w * scale));\n } else {\n for (let c = 0; c < colCount; c++) colWidthsDxa.push(defaultColDxa);\n }\n const totalDxa = colWidthsDxa.reduce((s, w) => s + w, 0);\n\n // Grid columns\n const gridCols = colWidthsDxa.map(w => `<w:gridCol w:w=\"${Math.round(w)}\"/>`).join('');\n\n // Pre-compute vMerge map: for each (ri, colIdx), track if a cell with rs>1 spans into this row\n // Key: \"ri,colIdx\", Value: 'restart' | 'continue'\n const vMergeMap = new Map<string, 'restart' | 'continue'>();\n for (let ri = 0; ri < grid.kids.length; ri++) {\n let colIdx = 0;\n for (const cell of grid.kids[ri].kids) {\n if (cell.rs > 1) {\n vMergeMap.set(`${ri},${colIdx}`, 'restart');\n for (let sr = 1; sr < cell.rs; sr++) {\n vMergeMap.set(`${ri + sr},${colIdx}`, 'continue');\n }\n }\n colIdx += cell.cs;\n }\n }\n\n const rows = grid.kids.map((row, ri) => {\n let colIdx = 0;\n\n // Build actual cells including continuation cells for vMerge\n const cellXmls: string[] = [];\n let srcCellIdx = 0;\n\n // Walk through grid columns, emitting either real cells or vMerge continue cells\n while (srcCellIdx < row.kids.length) {\n const cell = row.kids[srcCellIdx];\n const mergeType = vMergeMap.get(`${ri},${colIdx}`);\n\n const cp = cell.props;\n const tcPrParts: string[] = [];\n\n // Cell width in DXA (sum of spanned columns)\n let cellW = 0;\n for (let sc = colIdx; sc < colIdx + cell.cs && sc < colWidthsDxa.length; sc++) cellW += colWidthsDxa[sc];\n if (cellW === 0) cellW = defaultColDxa * cell.cs;\n tcPrParts.push(`<w:tcW w:w=\"${Math.round(cellW)}\" w:type=\"dxa\"/>`);\n\n if (cell.cs > 1) tcPrParts.push(`<w:gridSpan w:val=\"${cell.cs}\"/>`);\n\n // vMerge\n if (cell.rs > 1) {\n tcPrParts.push(`<w:vMerge w:val=\"restart\"/>`);\n }\n\n // Cell borders\n const borders = encodeCellBorders(cp);\n if (borders) tcPrParts.push(borders);\n\n // Cell background\n if (cp.bg) tcPrParts.push(`<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${cp.bg}\"/>`);\n\n // Vertical alignment\n if (cp.va) {\n const vaMap: Record<string, string> = { top: 'top', mid: 'center', bot: 'bottom' };\n tcPrParts.push(`<w:vAlign w:val=\"${vaMap[cp.va] ?? 'top'}\"/>`);\n }\n\n const tcPr = `<w:tcPr>${tcPrParts.join('')}</w:tcPr>`;\n cellXmls.push(` <w:tc>${tcPr}${cell.kids.map(p => encodeParaInner(p, ctx)).join('')}</w:tc>`);\n colIdx += cell.cs;\n srcCellIdx++;\n }\n\n // Now emit vMerge continue cells for rows that are spanned into\n // We need to check if any cells from rows above span into this row\n // Re-walk grid columns looking for continue cells not covered by this row's cells\n const finalCells: string[] = [];\n let finalColIdx = 0;\n let cellIter = 0;\n\n // Use the computed colCount (max across all rows)\n const totalGridCols = colCount;\n\n // Re-check: we need to interleave vMerge continue cells\n // The current row may have fewer cells because the model already skipped continuation cells\n // So we need to insert continuation cells where vMergeMap says 'continue' for this row\n finalColIdx = 0;\n cellIter = 0;\n for (let gc = 0; gc < totalGridCols; ) {\n const mergeType = vMergeMap.get(`${ri},${gc}`);\n if (mergeType === 'continue') {\n // Find the original cell's cs from the restart row\n let origCs = 1;\n for (let sr = ri - 1; sr >= 0; sr--) {\n const mt = vMergeMap.get(`${sr},${gc}`);\n if (mt === 'restart') {\n // Find the cell at this column in that row\n let col = 0;\n for (const c of grid.kids[sr].kids) {\n if (col === gc) { origCs = c.cs; break; }\n col += c.cs;\n }\n break;\n }\n }\n let cw = 0;\n for (let sc = gc; sc < gc + origCs && sc < colWidthsDxa.length; sc++) cw += colWidthsDxa[sc];\n if (cw === 0) cw = defaultColDxa * origCs;\n let contParts = `<w:tcW w:w=\"${Math.round(cw)}\" w:type=\"dxa\"/>`;\n if (origCs > 1) contParts += `<w:gridSpan w:val=\"${origCs}\"/>`;\n contParts += `<w:vMerge/>`;\n finalCells.push(` <w:tc><w:tcPr>${contParts}</w:tcPr><w:p><w:pPr/></w:p></w:tc>`);\n gc += origCs;\n } else {\n if (cellIter < cellXmls.length) {\n finalCells.push(cellXmls[cellIter]);\n gc += row.kids[cellIter]?.cs ?? 1;\n cellIter++;\n } else {\n gc++;\n }\n }\n }\n\n // Header row\n let trPr = '';\n if (ri === 0 && (gp.headerRow || look?.firstRow)) {\n trPr = '<w:trPr><w:tblHeader/></w:trPr>';\n }\n\n return ` <w:tr>${trPr}\\n${finalCells.join('\\n')}\\n </w:tr>`;\n }).join('\\n');\n\n // Table borders from defaultStroke\n let tblBorders = '';\n if (gp.defaultStroke) {\n const s = gp.defaultStroke;\n const strokeKindMap: Record<string, string> = { solid: 'single', dash: 'dashed', dot: 'dotted', double: 'double', none: 'none' };\n const val = strokeKindMap[s.kind] ?? 'single';\n const sz = Math.round(s.pt * 8);\n const bdr = `w:val=\"${val}\" w:sz=\"${sz}\" w:space=\"0\" w:color=\"${s.color}\"`;\n tblBorders = `<w:tblBorders><w:top ${bdr}/><w:left ${bdr}/><w:bottom ${bdr}/><w:right ${bdr}/><w:insideH ${bdr}/><w:insideV ${bdr}/></w:tblBorders>`;\n }\n\n return ` <w:tbl>\n <w:tblPr><w:tblStyle w:val=\"TableGrid\"/><w:tblW w:w=\"${Math.round(totalDxa)}\" w:type=\"dxa\"/><w:tblLayout w:type=\"fixed\"/><w:tblLook w:val=\"04A0\" w:firstRow=\"${firstRow}\" w:lastRow=\"${lastRow}\" w:firstColumn=\"${firstCol}\" w:lastColumn=\"${lastCol}\" w:noHBand=\"${noHBand}\" w:noVBand=\"${noVBand}\"/>${tblBorders}<w:tblCellMar><w:top w:w=\"28\" w:type=\"dxa\"/><w:left w:w=\"102\" w:type=\"dxa\"/><w:bottom w:w=\"28\" w:type=\"dxa\"/><w:right w:w=\"102\" w:type=\"dxa\"/></w:tblCellMar></w:tblPr>\n <w:tblGrid>${gridCols}</w:tblGrid>\n${rows}\n </w:tbl>`;\n}\n\nfunction encodeCellBorders(cp: CellProps): string {\n if (!cp.top && !cp.bot && !cp.left && !cp.right) return '';\n const strokeKindMap: Record<string, string> = { solid: 'single', dash: 'dashed', dot: 'dotted', double: 'double', none: 'none' };\n\n const encode = (s?: { kind: string; pt: number; color: string }, tag?: string) => {\n if (!s || !tag) return '';\n const val = strokeKindMap[s.kind] ?? 'single';\n return `<w:${tag} w:val=\"${val}\" w:sz=\"${Math.round(s.pt * 8)}\" w:space=\"0\" w:color=\"${s.color}\"/>`;\n };\n\n return `<w:tcBorders>${encode(cp.top, 'top')}${encode(cp.bot, 'bottom')}${encode(cp.left, 'left')}${encode(cp.right, 'right')}</w:tcBorders>`;\n}\n\nfunction esc(s: string): string { return TextKit.escapeXml(s); }\n\nregistry.registerEncoder(new DocxEncoder());\n","import type { Encoder } from '../../contract/encoder';\nimport type { DocRoot, ParaNode, SpanNode, GridNode, ContentNode, ImgNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport { succeed, fail } from '../../contract/result';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\nexport class MdEncoder implements Encoder {\n readonly format = 'md';\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n const warns: string[] = [];\n const parts: string[] = [];\n for (const sheet of doc.kids) {\n // Warn about header/footer loss\n if (sheet.header && sheet.header.length > 0) warns.push('[SHIELD] MD: 머리글(header) 표현 불가 — 손실됨');\n if (sheet.footer && sheet.footer.length > 0) warns.push('[SHIELD] MD: 바닥글(footer) 표현 불가 — 손실됨');\n\n for (const kid of sheet.kids) parts.push(encodeContent(kid, warns));\n }\n return succeed(TextKit.encode(parts.join('\\n\\n')), warns);\n } catch (e: any) {\n return fail(`MD encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\nfunction encodeContent(node: ContentNode, warns: string[]): string {\n return node.tag === 'grid' ? encodeGrid(node, warns) : encodePara(node, warns);\n}\n\nfunction encodePara(para: ParaNode, warns: string[]): string {\n const text = para.kids.map(k => {\n if (k.tag === 'span') return encodeSpan(k, warns);\n if (k.tag === 'img') return encodeImage(k);\n return '';\n }).join('');\n\n if (para.props.heading) return `${'#'.repeat(para.props.heading)} ${text}`;\n\n if (para.props.listOrd !== undefined) {\n const indent = ' '.repeat(para.props.listLv ?? 0);\n return `${indent}${para.props.listOrd ? '1.' : '-'} ${text}`;\n }\n\n // Alignment: use HTML fallback for non-left\n if (para.props.align && para.props.align !== 'left' && para.props.align !== 'justify') {\n return `<div align=\"${para.props.align}\">${text}</div>`;\n }\n\n return text;\n}\n\nfunction encodeSpan(span: SpanNode, warns: string[]): string {\n // Warn about properties that can't be represented in MD\n if (span.props.font) warns.push(`[SHIELD] MD: 글꼴(${span.props.font}) 표현 불가 — 손실됨`);\n if (span.props.pt) warns.push(`[SHIELD] MD: 글자 크기(${span.props.pt}pt) 표현 불가 — 손실됨`);\n if (span.props.color) warns.push(`[SHIELD] MD: 글자 색상(#${span.props.color}) 표현 불가 — 손실됨`);\n if (span.props.bg) warns.push(`[SHIELD] MD: 배경 색상(#${span.props.bg}) 표현 불가 — 손실됨`);\n\n let hasPageNum = false;\n const textParts: string[] = [];\n for (const kid of span.kids) {\n if (kid.tag === 'txt') textParts.push(kid.content);\n else if (kid.tag === 'pagenum') {\n hasPageNum = true;\n warns.push('[SHIELD] MD: 페이지 번호 표현 불가 — 손실됨');\n }\n }\n\n let r = textParts.join('');\n if (hasPageNum && r === '') r = '[페이지 번호]';\n\n if (span.props.b && span.props.i) r = `***${r}***`;\n else if (span.props.b) r = `**${r}**`;\n else if (span.props.i) r = `*${r}*`;\n if (span.props.s) r = `~~${r}~~`;\n if (span.props.u) r = `<u>${r}</u>`;\n if (span.props.sup) r = `<sup>${r}</sup>`;\n if (span.props.sub) r = `<sub>${r}</sub>`;\n\n return r;\n}\n\nfunction encodeImage(img: ImgNode): string {\n return ``;\n}\n\nfunction encodeGrid(grid: GridNode, warns: string[]): string {\n if (grid.kids.length === 0) return '';\n\n // Warn about table style loss\n if (grid.props.look) warns.push('[SHIELD] MD: 표 스타일(색상, 테두리, 머리행 강조) 표현 불가 — 손실됨');\n\n const rows = grid.kids.map(row =>\n `| ${row.kids.map(cell => cell.kids.map(p => encodePara(p, warns)).join(' ')).join(' | ')} |`,\n );\n\n if (rows.length > 0) {\n const cols = grid.kids[0].kids.length;\n rows.splice(1, 0, `| ${Array(cols).fill('---').join(' | ')} |`);\n }\n\n return rows.join('\\n');\n}\n\nregistry.registerEncoder(new MdEncoder());\n","import type { DocRoot } from '../model/doc-tree';\nimport type { Outcome } from '../contract/result';\nimport { fail } from '../contract/result';\nimport { registry } from './registry';\n\n// Side-effect imports: auto-register all decoders and encoders\nimport '../decoders/hwpx/HwpxDecoder';\nimport '../decoders/hwp/HwpScanner';\nimport '../decoders/docx/DocxDecoder';\nimport '../decoders/md/MdDecoder';\nimport '../encoders/hwpx/HwpxEncoder';\nimport '../encoders/docx/DocxEncoder';\nimport '../encoders/md/MdEncoder';\n\nexport class Pipeline {\n private constructor(private raw: Uint8Array, private srcFmt: string) {}\n\n /** 파일을 열고 포맷을 자동 감지하거나 명시 */\n static open(input: Uint8Array | string, fmt?: string): Pipeline {\n if (typeof input === 'string') {\n return new Pipeline(new TextEncoder().encode(input), fmt ?? 'md');\n }\n return new Pipeline(input, fmt ?? detectFormat(input));\n }\n\n /** File/Blob 비동기 입력 */\n static async openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise<Pipeline> {\n if (input instanceof Uint8Array || typeof input === 'string') {\n return Pipeline.open(input, fmt);\n }\n const buf = await input.arrayBuffer();\n const data = new Uint8Array(buf);\n const detectedFmt = fmt ?? (input instanceof File ? getExt(input.name) : undefined) ?? detectFormat(data);\n return new Pipeline(data, detectedFmt);\n }\n\n /** 목표 포맷으로 변환 */\n async to(targetFmt: string): Promise<Outcome<Uint8Array>> {\n const decoder = registry.getDecoder(this.srcFmt);\n const encoder = registry.getEncoder(targetFmt);\n\n if (!decoder) return fail(`지원하지 않는 입력 포맷: ${this.srcFmt}`);\n if (!encoder) return fail(`지원하지 않는 출력 포맷: ${targetFmt}`);\n\n const docResult = await decoder.decode(this.raw);\n if (!docResult.ok) return docResult;\n\n const encResult = await encoder.encode(docResult.data);\n if (!encResult.ok) return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n\n return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n }\n\n /** DocRoot만 추출 (인코딩 없이) */\n async inspect(): Promise<Outcome<DocRoot>> {\n const decoder = registry.getDecoder(this.srcFmt);\n if (!decoder) return fail(`디코더 없음: ${this.srcFmt}`);\n return decoder.decode(this.raw);\n }\n}\n\nfunction detectFormat(data: Uint8Array): string {\n if (data[0] === 0x50 && data[1] === 0x4B) return 'zip';\n if (data[0] === 0xD0 && data[1] === 0xCF && data[2] === 0x11 && data[3] === 0xE0) return 'hwp';\n return 'md';\n}\n\nfunction getExt(name: string): string | undefined {\n const parts = name.split('.');\n return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : undefined;\n}\n","import type { AnyNode, DocRoot } from '../model/doc-tree';\n\nexport type WalkCallback = (node: AnyNode, parent: AnyNode | null, depth: number) => void | 'stop';\n\nexport function walkNode(\n node: AnyNode,\n cb: WalkCallback,\n parent: AnyNode | null = null,\n depth = 0,\n): boolean {\n const result = cb(node, parent, depth);\n if (result === 'stop') return false;\n\n if ('kids' in node && Array.isArray((node as any).kids)) {\n for (const kid of (node as any).kids) {\n if (!walkNode(kid as AnyNode, cb, node, depth + 1)) return false;\n }\n }\n return true;\n}\n\nexport class TreeWalker {\n walk(root: DocRoot, cb: WalkCallback): void {\n walkNode(root, cb);\n }\n\n findAll<T extends AnyNode>(root: DocRoot, predicate: (n: AnyNode) => n is T): T[] {\n const results: T[] = [];\n walkNode(root, (n) => { if (predicate(n)) results.push(n); });\n return results;\n }\n\n extractText(root: DocRoot): string {\n const parts: string[] = [];\n walkNode(root, (n) => {\n if (n.tag === 'txt') parts.push(n.content);\n if (n.tag === 'br') parts.push('\\n');\n if (n.tag === 'pb') parts.push('\\n\\n');\n });\n return parts.join('');\n }\n}\n","import type { DocRoot, GridNode } from '../model/doc-tree';\nimport { walkNode } from './TreeWalker';\n\nexport function countNodes(root: DocRoot): Record<string, number> {\n const counts: Record<string, number> = {};\n walkNode(root, (n) => { counts[n.tag] = (counts[n.tag] ?? 0) + 1; });\n return counts;\n}\n\nexport function validateRoot(root: DocRoot): string[] {\n const errors: string[] = [];\n if (root.tag !== 'root') errors.push('Root node must have tag \"root\"');\n if (!Array.isArray(root.kids)) errors.push('Root.kids must be an array');\n if (root.kids.length === 0) errors.push('Document has no sheets');\n\n walkNode(root, (n) => {\n if (n.tag === 'cell' && n.kids.length === 0) {\n errors.push('CellNode must have at least one ParaNode child');\n }\n if (n.tag === 'grid' && (n as GridNode).kids.length === 0) {\n errors.push('GridNode must have at least one RowNode');\n }\n });\n\n return errors;\n}\n"],"mappings":";AAcO,SAAS,QAAW,MAAS,QAAkB,CAAC,GAAU;AAC/D,SAAO,EAAE,IAAI,MAAM,MAAM,MAAM;AACjC;AAEO,SAAS,KAAK,OAAe,QAAkB,CAAC,GAAS;AAC9D,SAAO,EAAE,IAAI,OAAO,OAAO,MAAM;AACnC;;;ACjBA,IAAM,iBAAN,MAAqB;AAAA,EAArB;AACE,SAAQ,WAAW,oBAAI,IAAqB;AAC5C,SAAQ,WAAW,oBAAI,IAAqB;AAAA;AAAA,EAE5C,gBAAgB,GAAkB;AAAE,SAAK,SAAS,IAAI,EAAE,QAAQ,CAAC;AAAA,EAAG;AAAA,EACpE,gBAAgB,GAAkB;AAAE,SAAK,SAAS,IAAI,EAAE,QAAQ,CAAC;AAAA,EAAG;AAAA,EAEpE,WAAW,KAAkC;AAAE,WAAO,KAAK,SAAS,IAAI,GAAG;AAAA,EAAG;AAAA,EAC9E,WAAW,KAAkC;AAAE,WAAO,KAAK,SAAS,IAAI,GAAG;AAAA,EAAG;AAAA,EAE9E,kBAA6B;AAAE,WAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,EAAG;AAAA,EACjE,mBAA6B;AAAE,WAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,EAAG;AACnE;AAEO,IAAM,WAAW,IAAI,eAAe;;;ACoEpC,IAAM,KAAe;AAAA,EAC1B,KAAK;AAAA,EAAQ,KAAK;AAAA,EAClB,IAAI;AAAA,EAAO,IAAI;AAAA,EAAO,IAAI;AAAA,EAAO,IAAI;AAAA,EACrC,QAAQ;AACV;AAEO,IAAM,iBAAyB,EAAE,MAAM,SAAS,IAAI,KAAK,OAAO,SAAS;;;ACpFzE,SAAS,UAAU,OAAgB,CAAC,GAAG,OAAoB,CAAC,GAAY;AAC7E,SAAO,EAAE,KAAK,QAAQ,MAAM,KAAK;AACnC;AAEO,SAAS,WACd,OAAsB,CAAC,GACvB,OAAiB,IACjB,MACW;AACX,QAAM,OAAkB,EAAE,KAAK,SAAS,MAAM,KAAK;AACnD,MAAI,MAAM,OAAQ,MAAK,SAAS,KAAK;AACrC,MAAI,MAAM,OAAQ,MAAK,SAAS,KAAK;AACrC,SAAO;AACT;AAEO,SAAS,aAAa,QAA6C;AACxE,SAAO,EAAE,KAAK,WAAW,OAAO;AAClC;AAEO,SAAS,UAAU,OAAyB,CAAC,GAAG,QAAmB,CAAC,GAAa;AACtF,SAAO,EAAE,KAAK,QAAQ,OAAO,KAAK;AACpC;AAEO,SAAS,UAAU,SAAiB,QAAmB,CAAC,GAAa;AAC1E,QAAM,MAAe,EAAE,KAAK,OAAO,QAAQ;AAC3C,SAAO,EAAE,KAAK,QAAQ,OAAO,MAAM,CAAC,GAAG,EAAE;AAC3C;AAEO,SAAS,SACd,KACA,MACA,GACA,GACA,KACS;AACT,SAAO,EAAE,KAAK,OAAO,KAAK,MAAM,GAAG,GAAG,IAAI;AAC5C;AAEO,SAAS,UAAU,MAAiB,QAAmB,CAAC,GAAa;AAC1E,SAAO,EAAE,KAAK,QAAQ,OAAO,KAAK;AACpC;AAEO,SAAS,SAAS,MAA2B;AAClD,SAAO,EAAE,KAAK,OAAO,KAAK;AAC5B;AAEO,SAAS,UACd,MACA,OAAwD,CAAC,GAC/C;AACV,SAAO,EAAE,KAAK,QAAQ,IAAI,KAAK,MAAM,GAAG,IAAI,KAAK,MAAM,GAAG,OAAO,KAAK,SAAS,CAAC,GAAG,KAAK;AAC1F;;;AC1DO,IAAM,iBAAN,MAAqB;AAAA,EAArB;AACL,SAAQ,MAAgB,CAAC;AAAA;AAAA;AAAA,EAGzB,MAAS,IAAa,UAAa,OAAkB;AACnD,QAAI;AACF,YAAM,IAAI,GAAG;AACb,UAAI,KAAK,MAAM;AACb,aAAK,KAAK,OAAO,yBAAyB;AAC1C,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,SAAS,GAAQ;AACf,WAAK,KAAK,OAAO,GAAG,WAAW,OAAO,CAAC,CAAC;AACxC,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,SACE,OACA,IACA,IACA,OACK;AACL,WAAO,MAAM;AAAA,MAAI,CAAC,GAAG,MACnB,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC,GAAG;AAAA,IACvD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UACE,MACA,SACA,SACA,SACA,SACA,OACoC;AACpC,UAAM,SAA+C;AAAA,MACnD,CAAC,SAAS,CAAC;AAAA,MAAG,CAAC,SAAS,CAAC;AAAA,MAAG,CAAC,SAAS,CAAC;AAAA,MAAG,CAAC,SAAS,CAAC;AAAA,IACvD;AAEA,eAAW,CAAC,IAAI,EAAE,KAAK,QAAQ;AAC7B,UAAI;AACF,cAAM,IAAI,GAAG,IAAI;AACjB,YAAI,KAAK,MAAM;AACb,cAAI,KAAK,EAAG,MAAK,KAAK,OAAO,qBAAqB,EAAE,EAAE;AACtD,iBAAO,EAAE,OAAO,GAAG,OAAO,GAAG;AAAA,QAC/B;AAAA,MACF,SAAS,GAAQ;AACf,aAAK,KAAK,OAAO,KAAK,EAAE,YAAY,GAAG,WAAW,OAAO,CAAC,CAAC,EAAE;AAAA,MAC/D;AAAA,IACF;AAEA,SAAK,KAAK,OAAO,mDAA8C;AAC/D,WAAO,EAAE,OAAO,QAAQ,IAAI,GAAG,OAAO,EAAE;AAAA,EAC1C;AAAA;AAAA,EAGA,SACE,MACA,IACA,aACA,OACG;AACH,QAAI;AACF,YAAM,IAAI,GAAG,IAAI;AACjB,UAAI,KAAK,KAAM,QAAO;AAAA,IACxB,SAAS,GAAQ;AACf,WAAK,KAAK,OAAO,GAAG,WAAW,OAAO,CAAC,CAAC;AAAA,IAC1C;AACA,SAAK,KAAK,OAAO,yBAAyB;AAC1C,WAAO,YAAY,kDAAe,KAAK,GAAG;AAAA,EAC5C;AAAA,EAEQ,KAAK,OAAe,KAAmB;AAC7C,UAAM,IAAI,YAAY,KAAK,KAAK,GAAG;AACnC,YAAQ,KAAK,CAAC;AACd,SAAK,IAAI,KAAK,CAAC;AAAA,EACjB;AAAA,EAEA,QAAkB;AAChB,UAAM,IAAI,CAAC,GAAG,KAAK,GAAG;AACtB,SAAK,MAAM,CAAC;AACZ,WAAO;AAAA,EACT;AACF;;;ACvFO,IAAM,SAAS;AAAA;AAAA,EAEpB,SAAa,CAAC,MAAc,IAAI;AAAA,EAChC,SAAa,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG;AAAA,EAC9C,UAAa,CAAC,MAAc,KAAK,MAAM,IAAI,CAAC;AAAA,EAC5C,UAAa,CAAC,MAAc,KAAK,MAAM,IAAI,CAAC;AAAA,EAC5C,UAAa,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG;AAAA,EAC9C,UAAa,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG;AAAA;AAAA,EAG9C,SAAa,CAAC,MAAc,IAAI;AAAA,EAChC,SAAa,CAAC,MAAc,KAAK,MAAM,IAAI,EAAE;AAAA,EAC7C,UAAa,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG;AAAA,EAC9C,UAAa,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG;AAAA,EAC9C,SAAa,CAAC,MAAc,IAAI;AAAA,EAChC,SAAa,CAAC,MAAc,KAAK,MAAM,IAAI,KAAK;AAAA;AAAA,EAGhD,aAAa,CAAC,MAAc,IAAI;AAAA,EAChC,aAAa,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG;AAAA;AAAA,EAG9C,YAAa,CAAC,MAAc,IAAI;AAAA,EAChC,YAAa,CAAC,MAAc,KAAK,MAAM,IAAI,CAAC;AAC9C;AAGO,SAAS,QAAQ,KAA6D;AACnF,MAAI,OAAO,KAAM,QAAO;AACxB,MAAI,OAAO,QAAQ,UAAU;AAC3B,QAAI,OAAO,EAAG,QAAO;AACrB,QAAI,OAAO,SAAU,QAAO;AAC5B,WAAO,IAAI,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,EAAE,YAAY;AAAA,EACvD;AACA,MAAI,IAAI,OAAO,GAAG,EAAE,QAAQ,MAAM,EAAE,EAAE,YAAY;AAClD,MAAI,gBAAgB,KAAK,CAAC,EAAG,KAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AACvE,MAAI,gBAAgB,KAAK,CAAC,EAAG,QAAO;AACpC,MAAI,MAAM,UAAU,MAAM,UAAU,MAAM,cAAe,QAAO;AAChE,SAAO;AACT;AAGA,IAAM,YAAmC;AAAA,EACvC,MAAM;AAAA,EAAQ,QAAQ;AAAA,EAAU,OAAO;AAAA,EAAS,SAAS;AAAA,EACzD,MAAM;AAAA,EAAW,YAAY;AAAA,EAC7B,MAAM;AAAA,EAAQ,QAAQ;AAAA,EAAU,OAAO;AAAA,EAAS,MAAM;AAAA,EACtD,OAAO;AAAA,EAAQ,KAAK;AACtB;AACO,SAAS,UAAU,KAAqB;AAC7C,SAAO,UAAU,OAAO,EAAE,KAAK;AACjC;AAGA,IAAM,cAA0C;AAAA,EAC9C,OAAO;AAAA,EAAS,MAAM;AAAA,EAAQ,MAAM;AAAA,EAAQ,KAAK;AAAA,EACjD,QAAQ;AAAA,EAAU,WAAW;AAAA,EAAQ,UAAU;AACjD;AACA,IAAM,cAA0C;AAAA,EAC9C,QAAQ;AAAA,EAAS,MAAM;AAAA,EAAQ,KAAK;AAAA,EAAQ,QAAQ;AAAA,EACpD,QAAQ;AAAA,EAAO,QAAQ;AAAA,EAAU,MAAM;AACzC;AAEO,SAAS,eAAe,MAAe,GAAY,GAAoB;AAC5E,SAAO;AAAA,IACL,MAAM,YAAY,QAAQ,EAAE,KAAK;AAAA,IACjC,IAAI,KAAK,OAAO,OAAO,QAAQ,CAAC,IAAI;AAAA,IACpC,OAAO,QAAQ,CAAC,KAAK;AAAA,EACvB;AACF;AAEO,SAAS,eAAe,KAAc,IAAa,GAAoB;AAC5E,SAAO;AAAA,IACL,MAAM,YAAY,OAAO,EAAE,KAAK;AAAA,IAChC,IAAI,MAAM,OAAO,KAAK,IAAI;AAAA,IAC1B,OAAO,QAAQ,CAAC,KAAK;AAAA,EACvB;AACF;AAGA,IAAM,WAAmC;AAAA,EACvC,6BAAS;AAAA,EACT,gBAAM;AAAA,EACN,gBAAM;AAAA,EACN,gBAAM;AAAA,EACN,4BAAQ;AAAA,EACR,4BAAQ;AAAA,EACR,kCAAS;AAAA,EACT,kCAAS;AACX;AACO,SAAS,SAAS,KAAsB;AAC7C,SAAO,SAAS,OAAO,EAAE,KAAK,OAAO;AACvC;AAGA,IAAM,cAAsC;AAAA,EAC1C,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AACX;AACO,SAAS,aAAa,KAAsB;AACjD,SAAO,YAAY,OAAO,EAAE,KAAK,OAAO;AAC1C;;;ACzGA,OAAO,UAAU;AAOV,IAAM,aAAa;AAAA,EACxB,MAAM,QAAQ,YAA6C;AACzD,WAAO,KAAK,QAAQ,UAAU;AAAA,EAChC;AAAA,EAEA,MAAM,QAAQ,MAAuC;AACnD,WAAO,KAAK,QAAQ,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EACxC;AAAA,EAEA,MAAM,MAAM,SAAuD;AACjE,UAAM,QAAQ,oBAAI,IAAwB;AAC1C,UAAM,OAAO,IAAI,SAAS,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,UAAU;AAEhF,QAAI,SAAS;AACb,WAAO,SAAS,QAAQ,SAAS,GAAG;AAClC,YAAM,MAAM,KAAK,UAAU,QAAQ,IAAI;AAEvC,UAAI,QAAQ,UAAY;AACtB,cAAM,oBAAoB,KAAK,UAAU,SAAS,GAAG,IAAI;AACzD,cAAM,iBAAoB,KAAK,UAAU,SAAS,IAAI,IAAI;AAC1D,cAAM,mBAAoB,KAAK,UAAU,SAAS,IAAI,IAAI;AAC1D,cAAM,iBAAoB,KAAK,UAAU,SAAS,IAAI,IAAI;AAC1D,cAAM,cAAoB,KAAK,UAAU,SAAS,IAAI,IAAI;AAE1D,cAAM,YAAY,QAAQ,SAAS,SAAS,IAAI,SAAS,KAAK,cAAc;AAC5E,cAAM,OAAO,IAAI,YAAY,OAAO,EAAE,OAAO,SAAS;AAEtD,cAAM,aAAa,SAAS,KAAK,iBAAiB;AAClD,YAAI;AAEJ,YAAI,sBAAsB,GAAG;AAC3B,qBAAW,QAAQ,SAAS,YAAY,aAAa,gBAAgB;AAAA,QACvE,WAAW,sBAAsB,GAAG;AAClC,gBAAM,aAAa,QAAQ,SAAS,YAAY,aAAa,cAAc;AAC3E,qBAAW,KAAK,WAAW,UAAU;AAAA,QACvC,OAAO;AACL,gBAAM,IAAI,MAAM,uCAAuC,iBAAiB,EAAE;AAAA,QAC5E;AAEA,cAAM,IAAI,MAAM,IAAI,WAAW,QAAQ,CAAC;AACxC,iBAAS,aAAa;AAAA,MACxB,WAAW,QAAQ,YAAc,QAAQ,WAAY;AACnD;AAAA,MACF,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,SAA0C;AAClD,UAAM,eAA6B,CAAC;AACpC,UAAM,iBAA+B,CAAC;AACtC,QAAI,cAAc;AAElB,eAAW,SAAS,SAAS;AAC3B,YAAM,YAAY,IAAI,YAAY,EAAE,OAAO,MAAM,IAAI;AACrD,YAAM,MAAM,MAAM,MAAM,IAAI;AAG5B,YAAM,QAAQ,MAAM,SAAS,cAAc,MAAM,SAAS;AAC1D,YAAM,SAAS,QAAQ,IAAI;AAC3B,YAAM,UAAU,QAAQ,MAAM,OAAO,KAAK,WAAW,MAAM,MAAM,EAAE,OAAO,EAAE,CAAC;AAG7E,YAAM,QAAQ,IAAI,WAAW,KAAK,UAAU,SAAS,QAAQ,MAAM;AACnE,YAAM,KAAK,IAAI,SAAS,MAAM,MAAM;AACpC,SAAG,UAAU,GAAG,UAAY,IAAI;AAChC,SAAG,UAAU,GAAG,IAAI,IAAI;AACxB,SAAG,UAAU,GAAG,GAAG,IAAI;AACvB,SAAG,UAAU,GAAG,QAAQ,IAAI;AAC5B,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,SAAG,UAAU,IAAI,IAAQ,IAAI;AAC7B,SAAG,UAAU,IAAI,KAAK,IAAI;AAC1B,SAAG,UAAU,IAAI,QAAQ,QAAQ,IAAI;AACrC,SAAG,UAAU,IAAI,MAAM,KAAK,QAAQ,IAAI;AACxC,SAAG,UAAU,IAAI,UAAU,QAAQ,IAAI;AACvC,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,YAAM,IAAI,WAAW,EAAE;AACvB,YAAM,IAAI,SAAS,KAAK,UAAU,MAAM;AAGxC,YAAM,UAAU,IAAI,WAAW,KAAK,UAAU,MAAM;AACpD,YAAM,KAAK,IAAI,SAAS,QAAQ,MAAM;AACtC,SAAG,UAAU,GAAG,UAAY,IAAI;AAChC,SAAG,UAAU,GAAG,IAAI,IAAI;AACxB,SAAG,UAAU,GAAG,IAAI,IAAI;AACxB,SAAG,UAAU,GAAG,GAAG,IAAI;AACvB,SAAG,UAAU,IAAI,QAAQ,IAAI;AAC7B,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,SAAG,UAAU,IAAI,IAAQ,IAAI;AAC7B,SAAG,UAAU,IAAI,KAAK,IAAI;AAC1B,SAAG,UAAU,IAAI,QAAQ,QAAQ,IAAI;AACrC,SAAG,UAAU,IAAI,MAAM,KAAK,QAAQ,IAAI;AACxC,SAAG,UAAU,IAAI,UAAU,QAAQ,IAAI;AACvC,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,SAAG,UAAU,IAAI,GAAG,IAAI;AACxB,SAAG,UAAU,IAAI,aAAa,IAAI;AAClC,cAAQ,IAAI,WAAW,EAAE;AAEzB,mBAAa,KAAK,KAAK;AACvB,qBAAe,KAAK,OAAO;AAC3B,qBAAe,MAAM;AAAA,IACvB;AAEA,UAAM,aAAa,OAAO,cAAc;AACxC,UAAM,OAAO,IAAI,WAAW,EAAE;AAC9B,UAAM,KAAK,IAAI,SAAS,KAAK,MAAM;AACnC,OAAG,UAAU,GAAG,WAAY,IAAI;AAChC,OAAG,UAAU,GAAG,GAAG,IAAI;AACvB,OAAG,UAAU,GAAG,GAAG,IAAI;AACvB,OAAG,UAAU,GAAG,QAAQ,QAAQ,IAAI;AACpC,OAAG,UAAU,IAAI,QAAQ,QAAQ,IAAI;AACrC,OAAG,UAAU,IAAI,WAAW,QAAQ,IAAI;AACxC,OAAG,UAAU,IAAI,aAAa,IAAI;AAClC,OAAG,UAAU,IAAI,GAAG,IAAI;AAExB,WAAO,OAAO,CAAC,GAAG,cAAc,YAAY,IAAI,CAAC;AAAA,EACnD;AACF;AAEA,SAAS,OAAO,QAAkC;AAChD,QAAM,QAAQ,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,QAAQ,CAAC;AACrD,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,KAAK,QAAQ;AAAE,QAAI,IAAI,GAAG,MAAM;AAAG,cAAU,EAAE;AAAA,EAAQ;AAClE,SAAO;AACT;AAEA,SAAS,MAAM,MAA0B;AACvC,MAAI,MAAM;AACV,aAAW,QAAQ,MAAM;AACvB,WAAO;AACP,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAO,MAAM,IAAM,QAAQ,IAAK,aAAa,QAAQ;AAAA,IACvD;AAAA,EACF;AACA,UAAQ,MAAM,gBAAgB;AAChC;;;ACrJA,SAAS,mBAAmB;AAI5B,SAAS,eAAe,KAA+B;AACrD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,IAAI,YAAY,EAAE,OAAO,MAAM,CAAC;AAG/C,UAAM,QAAiB,CAAC;AACxB,QAAI,SAAkB;AAEtB,WAAO,GAAG,SAAS,CAAC,QAAe,OAAO,GAAG,CAAC;AAE9C,WAAO,GAAG,WAAW,CAAC,SAAc;AAClC,YAAM,MAA+B,CAAC;AACtC,YAAM,QAAQ,KAAK;AACnB,UAAI,SAAS,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AAC1C,YAAI,OAAO,IAAI,EAAE,GAAG,MAAM;AAAA,MAC5B;AACA,YAAM,KAAK,EAAE,KAAK,KAAK,MAAgB,IAAI,CAAC;AAAA,IAC9C,CAAC;AAED,UAAM,aAAa,CAAC,SAAiB;AACnC,UAAI,MAAM,SAAS,KAAK,MAAM;AAC5B,cAAM,QAAQ,MAAM,MAAM,SAAS,CAAC;AACpC,cAAM,MAAM,MAAM,IAAI,OAAO;AAC7B,cAAM,IAAI,OAAO,IAAI,OAAO,QAAQ,WAAW,MAAM,OAAO;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO,GAAG,QAAQ,CAAC,SAAiB,WAAW,IAAI,CAAC;AACpD,WAAO,GAAG,SAAS,CAAC,UAAkB,WAAW,KAAK,CAAC;AAEvD,WAAO,GAAG,YAAY,MAAM;AAC1B,YAAM,QAAQ,MAAM,IAAI;AACxB,UAAI,CAAC,MAAO;AACZ,YAAM,EAAE,KAAK,IAAI,IAAI;AAGrB,UAAI,OAAO,IAAI,OAAO,MAAM,YAAY,CAAE,IAAI,OAAO,EAAa,KAAK,GAAG;AACxE,eAAO,IAAI,OAAO;AAAA,MACpB;AAEA,UAAI,MAAM,WAAW,GAAG;AACtB,iBAAS,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE;AAAA,MAC1B,OAAO;AACL,cAAM,SAAS,MAAM,MAAM,SAAS,CAAC,EAAE;AACvC,cAAM,WAAW,OAAO,GAAG;AAC3B,YAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,UAAC,SAAuB,KAAK,GAAG;AAAA,QAClC,OAAO;AACL,iBAAO,GAAG,IAAI,CAAC,GAAG;AAAA,QACpB;AAEA,YAAI,CAAC,OAAO,aAAa,EAAG,QAAO,aAAa,IAAI,CAAC;AACrD,QAAC,OAAO,aAAa,EAAe,KAAK,GAAG;AAAA,MAC9C;AAAA,IACF,CAAC;AAED,QAAI;AACF,aAAO,MAAM,GAAG,EAAE,MAAM;AACxB,cAAQ,MAAM;AAAA,IAChB,SAAS,GAAG;AACV,aAAO,CAAC;AAAA,IACV;AAAA,EACF,CAAC;AACH;AAEO,IAAM,SAAS;AAAA;AAAA,EAEpB,MAAM,MAAM,KAA+B;AACzC,WAAO,eAAe,GAAG;AAAA,EAC3B;AAAA,EAEA,MAAM,YAAY,KAA+B;AAC/C,WAAO,eAAe,GAAG;AAAA,EAC3B;AAAA,EAEA,KAAK,MAA+B,KAAiC;AACnE,UAAM,IAAI,KAAK,OAAO;AACtB,WAAO,IAAI,GAAG;AAAA,EAChB;AAAA,EAEA,KAAK,MAA4D;AAC/D,QAAI,QAAQ,KAAM,QAAO;AACzB,QAAI,OAAO,SAAS,SAAU,QAAO;AACrC,UAAM,IAAI,KAAK,OAAO;AACtB,WAAO,OAAO,MAAM,WAAW,IAAI;AAAA,EACrC;AACF;;;AC1FO,IAAM,UAAU;AAAA,EACrB,OAAO,MAAkB,WAAW,SAAiB;AACnD,QAAI;AACF,aAAO,IAAI,YAAY,UAAU,EAAE,OAAO,KAAK,CAAC,EAAE,OAAO,IAAI;AAAA,IAC/D,QAAQ;AACN,aAAO,IAAI,YAAY,SAAS,EAAE,OAAO,MAAM,CAAC,EAAE,OAAO,IAAI;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,OAAO,MAA0B;AAC/B,WAAO,IAAI,YAAY,EAAE,OAAO,IAAI;AAAA,EACtC;AAAA,EAEA,UAAU,GAAmB;AAC3B,WAAO,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAAA,EAC3B;AAAA,EAEA,YAAY,GAAmB;AAC7B,WAAO,EACJ,QAAQ,UAAU,GAAG,EACrB,QAAQ,SAAS,GAAG,EACpB,QAAQ,SAAS,GAAG,EACpB,QAAQ,WAAW,GAAG,EACtB,QAAQ,WAAW,GAAG;AAAA,EAC3B;AAAA,EAEA,oBAAoB,GAAmB;AACrC,WAAO,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAAA,EACrC;AAAA,EAEA,aAAa,GAAmB;AAE9B,WAAO,EAAE,QAAQ,qCAAqC,EAAE;AAAA,EAC1D;AAAA,EAEA,aAAa,MAA0B;AACrC,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,gBAAU,OAAO,aAAa,KAAK,CAAC,CAAC;AAAA,IACvC;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,aAAa,KAAyB;AACpC,UAAM,SAAS,KAAK,GAAG;AACvB,UAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AACF;;;ACvBO,IAAM,cAAN,MAAqC;AAAA,EAArC;AACL,SAAS,SAAS;AAAA;AAAA,EAElB,MAAM,OAAO,MAA6C;AACxD,UAAM,SAAS,IAAI,eAAe;AAClC,UAAM,QAAkB,CAAC;AAEzB,QAAI;AACF,YAAM,QAAQ,MAAM,WAAW,MAAM,IAAI;AAEzC,YAAM,UAAU,MAAM,IAAI,uBAAuB,KAC5C,MAAM,IAAI,cAAc,KACxB,gBAAgB,KAAK;AAE1B,UAAI,CAAC,QAAS,QAAO,KAAK,yCAAyC;AAEnE,YAAM,UAAU,MAAM,IAAI,qBAAqB,KAAK,MAAM,IAAI,YAAY;AAE1E,UAAI,OAAgB,CAAC;AACrB,UAAI,OAAiB,EAAE,GAAG,GAAG;AAC7B,UAAI,cAAc,oBAAI,IAA4B;AAClD,UAAI,UAAU,oBAAI,IAAwB;AAC1C,UAAI,UAAU,oBAAI,IAAgC;AAElD,UAAI,SAAS;AACX,YAAI;AACF,gBAAM,UAAU,QAAQ,OAAO,OAAO;AACtC,gBAAM,UAAe,MAAM,OAAO,YAAY,OAAO;AACrD,cAAI,SAAS;AACX,mBAAO,YAAY,OAAO;AAC1B,mBAAO,YAAY,OAAO,KAAK;AAC/B,0BAAc,mBAAmB,OAAO;AACxC,sBAAU,eAAe,OAAO;AAChC,sBAAU,eAAe,OAAO;AAAA,UAClC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,YAAM,MAAc,EAAE,OAAO,QAAQ,aAAa,SAAS,SAAS,MAAM;AAE1E,YAAM,UAAU,QAAQ,OAAO,OAAO;AACtC,YAAM,UAAe,MAAM,OAAO,YAAY,OAAO;AAErD,YAAM,WAAW,kBAAkB,OAAO;AAC1C,YAAM,OAAO,OAAO;AAAA,QAClB;AAAA,QACA,CAAC,QAAa,cAAc,KAAK,MAAM,GAAG;AAAA,QAC1C,MAAM,WAAW,CAAC,UAAU,CAAC,UAAU,0CAAY,CAAC,CAAC,CAAC,GAAG,IAAI;AAAA,QAC7D;AAAA,MACF;AAEA,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,aAAO,QAAQ,UAAU,MAAM,IAAI,GAAG,KAAK;AAAA,IAC7C,SAAS,GAAQ;AACf,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,aAAO,KAAK,sBAAsB,GAAG,WAAW,OAAO,CAAC,CAAC,IAAI,KAAK;AAAA,IACpE;AAAA,EACF;AACF;AAIA,SAAS,gBAAgB,OAAwD;AAC/E,aAAW,CAAC,KAAK,GAAG,KAAK,OAAO;AAC9B,QAAI,IAAI,YAAY,EAAE,SAAS,SAAS,KAAK,IAAI,SAAS,MAAM,EAAG,QAAO;AAAA,EAC5E;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,SAAqB;AAE9C,MAAI,UAAU,QAAQ,EAAG,QAAO,MAAM,QAAQ,QAAQ,CAAC;AACvD,MAAI,UAAU,QAAQ,EAAG,QAAO,MAAM,QAAQ,QAAQ,CAAC;AAEvD,QAAM,OAAO,UAAU,UAAU,KAAK,SAAS,SAAS;AACxD,QAAM,OAAO,OAAO,SAAS,IAAI,CAAC,KAAK,MAAM,OAAO,CAAC,KAAK,OAAO,SAAS,KAAK,MAAM;AACrF,MAAI,CAAC,KAAM,QAAO,CAAC,OAAO;AAC1B,QAAM,WAAW,OAAO,YAAY,KAAK,MAAM,WAAW,CAAC;AAC3D,SAAO,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AACvD;AAGA,SAAS,OAAO,QAAa,OAAwB;AACnD,aAAW,KAAK,OAAO;AACrB,UAAM,IAAI,MAAM,CAAC;AACjB,QAAI,KAAK,KAAM,QAAO,MAAM,CAAC;AAAA,EAC/B;AACA,SAAO,CAAC;AACV;AAEA,SAAS,YAAY,SAAuB;AAC1C,MAAI;AAEF,UAAM,OAAO,UAAU,SAAS,IAAI,CAAC,KAAK,UAAU,SAAS,IAAI,CAAC,KAAK,SAAS,OAAO,CAAC,KAAK;AAC7F,UAAM,OAAO,OAAO,eAAe,IAAI,CAAC,KAAK,MAAM,aAAa,CAAC;AACjE,QAAI,CAAC,KAAM,QAAO,CAAC;AACnB,UAAM,IAAI,CAAC,MAAc,OAAO,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,SAAS,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS;AACnF,WAAO,EAAE,OAAO,EAAE,OAAO,KAAK,QAAW,QAAQ,EAAE,QAAQ,KAAK,QAAW,SAAS,EAAE,SAAS,KAAK,OAAU;AAAA,EAChH,QAAQ;AAAE,WAAO,CAAC;AAAA,EAAG;AACvB;AAEA,SAAS,YAAY,SAA+B;AAClD,MAAI;AACF,UAAM,OAAO,UAAU,SAAS,IAAI,CAAC,KAAK,UAAU,SAAS,IAAI,CAAC,KAAK,SAAS,OAAO,CAAC,KAAK;AAC7F,UAAM,UAAU,OAAO,YAAY,IAAI,CAAC,KAAK,OAAO,YAAY,IAAI,CAAC,KAAK,MAAM,UAAU,CAAC;AAC3F,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,YAAY,UAAU,aAAa,IAAI,CAAC,IAAI,UAAU,KACvD,SAAS,WAAW,CAAC,GAAG;AAC7B,UAAM,MAAM,MAAM,QAAQ,SAAS,IAAI,UAAU,CAAC,IAAI;AACtD,QAAI,CAAC,IAAK,QAAO;AAEjB,UAAM,KAAK,MAAM,iBAAiB,IAAI,CAAC,GAAG,SAAS,KAAK,eAAe,CAAC,GAAG;AAC3E,QAAI,CAAC,GAAI,QAAO;AAEhB,WAAO;AAAA,MACL,KAAQ,OAAO,QAAQ,OAAO,GAAG,SAAS,KAAK,CAAC;AAAA,MAChD,KAAQ,OAAO,QAAQ,OAAO,GAAG,UAAU,KAAK,CAAC;AAAA,MACjD,IAAQ,OAAO,QAAQ,OAAO,GAAG,aAAa,IAAI,CAAC;AAAA,MACnD,IAAQ,OAAO,QAAQ,OAAO,GAAG,gBAAgB,IAAI,CAAC;AAAA,MACtD,IAAQ,OAAO,QAAQ,OAAO,GAAG,cAAc,IAAI,CAAC;AAAA,MACpD,IAAQ,OAAO,QAAQ,OAAO,GAAG,eAAe,IAAI,CAAC;AAAA,MACrD,QAAQ,OAAO,GAAG,SAAS,MAAM,IAAI,cAAc;AAAA,IACrD;AAAA,EACF,QAAQ;AAAE,WAAO;AAAA,EAAM;AACzB;AAEA,SAAS,mBAAmB,SAA2C;AACrE,QAAM,MAAM,oBAAI,IAA4B;AAC5C,MAAI;AACF,UAAM,OAAO,UAAU,SAAS,IAAI,CAAC,KAAK,UAAU,SAAS,IAAI,CAAC,KAAK,SAAS,OAAO,CAAC,KAAK;AAC7F,UAAM,UAAU,OAAO,YAAY,IAAI,CAAC,KAAK,OAAO,YAAY,IAAI,CAAC,KAAK,MAAM,UAAU,CAAC;AAC3F,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,SAAS,UAAU,gBAAgB,IAAI,CAAC,KAAK,UAAU,mBAAmB,IAAI,CAAC,KAAK,SAAS,iBAAiB,CAAC;AACrH,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,MAAM,OAAO,QAAQ,iBAAiB,eAAe;AAC3D,eAAW,MAAM,KAAK;AACpB,YAAM,OAAO,IAAI,SAAS,CAAC;AAC3B,YAAM,KAAK,OAAO,KAAK,MAAM,CAAC;AAC9B,UAAI,OAAO,EAAG;AAEd,YAAM,OAAuB,CAAC;AAG9B,YAAM,MAAM,KAAK,cAAc,IAAI,CAAC,GAAG,SAAS,KAAK,QAAQ,IAAI,CAAC,GAAG,SAAS,IAAI,MAAM,CAAC,GAAG;AAC5F,UAAI,KAAK;AAEP,cAAM,QAAQ,WAAW,IAAI,KAAK,KAAK;AACvC,cAAM,SAAS,SAAS,OAAO,QAAQ,QAAQ,MAAM;AACrD,aAAK,SAAS,eAAe,IAAI,MAAM,QAAQ,IAAI,KAAK;AAAA,MAC1D;AAGA,YAAM,YAAY,KAAK,cAAc,IAAI,CAAC,KAAK,KAAK,cAAc,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;AACtI,UAAI,WAAW;AACb,cAAM,WAAW,YAAY,aAAa,IAAI,CAAC,GAAG,SAAS,YAAY,aAAa,IAAI,CAAC,GAAG,SAAS,WAAW,WAAW,CAAC,GAAG;AAC/H,YAAI,UAAU,aAAa,SAAS,cAAc,QAAQ;AACxD,eAAK,UAAU,QAAQ,SAAS,SAAS;AAAA,QAC3C;AAAA,MACF;AAEA,UAAI,IAAI,IAAI,IAAI;AAAA,IAClB;AAAA,EACF,QAAQ;AAAA,EAAkB;AAC1B,SAAO;AACT;AAEA,SAAS,eAAe,SAAuC;AAC7D,QAAM,MAAM,oBAAI,IAAwB;AACxC,MAAI;AACF,UAAM,OAAO,UAAU,SAAS,IAAI,CAAC,KAAK,UAAU,SAAS,IAAI,CAAC,KAAK,SAAS,OAAO,CAAC,KAAK;AAC7F,UAAM,UAAU,OAAO,YAAY,IAAI,CAAC,KAAK,OAAO,YAAY,IAAI,CAAC,KAAK,MAAM,UAAU,CAAC;AAC3F,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,SAAS,UAAU,mBAAmB,IAAI,CAAC,KAAK,UAAU,mBAAmB,IAAI,CAAC;AACxF,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,MAAM,OAAO,QAAQ,aAAa,WAAW;AACnD,eAAW,MAAM,KAAK;AACpB,YAAM,OAAO,IAAI,SAAS,CAAC;AAC3B,YAAM,KAAK,OAAO,KAAK,MAAM,EAAE;AAC/B,UAAI,KAAK,EAAG;AAEZ,YAAM,OAAmB,CAAC;AAG1B,UAAI,KAAK,OAAQ,MAAK,KAAK,OAAO,YAAY,OAAO,KAAK,MAAM,CAAC;AAGjE,UAAI,KAAK,UAAW,MAAK,QAAQ,QAAQ,KAAK,SAAS;AAGvD,UAAI,KAAK,SAAS,IAAI,CAAC,KAAK,KAAM,MAAK,IAAI;AAG3C,UAAI,KAAK,WAAW,IAAI,CAAC,KAAK,KAAM,MAAK,IAAI;AAG7C,YAAM,SAAS,KAAK,cAAc,IAAI,CAAC,GAAG;AAC1C,UAAI,QAAQ,QAAQ,OAAO,SAAS,OAAQ,MAAK,IAAI;AAGrD,YAAM,SAAS,KAAK,cAAc,IAAI,CAAC,GAAG;AAC1C,UAAI,QAAQ,SAAS,OAAO,UAAU,UAAU,OAAO,UAAU,KAAM,MAAK,IAAI;AAKhF,UAAI,IAAI,IAAI,IAAI;AAAA,IAClB;AAAA,EACF,QAAQ;AAAA,EAAkB;AAC1B,SAAO;AACT;AAEA,SAAS,eAAe,SAA+C;AACrE,QAAM,MAAM,oBAAI,IAAgC;AAChD,MAAI;AACF,UAAM,OAAO,UAAU,SAAS,IAAI,CAAC,KAAK,UAAU,SAAS,IAAI,CAAC,KAAK,SAAS,OAAO,CAAC,KAAK;AAC7F,UAAM,UAAU,OAAO,YAAY,IAAI,CAAC,KAAK,OAAO,YAAY,IAAI,CAAC,KAAK,MAAM,UAAU,CAAC;AAC3F,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,SAAS,UAAU,mBAAmB,IAAI,CAAC,KAAK,UAAU,mBAAmB,IAAI,CAAC;AACxF,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,MAAM,OAAO,QAAQ,aAAa,WAAW;AACnD,eAAW,MAAM,KAAK;AACpB,YAAM,OAAO,IAAI,SAAS,CAAC;AAC3B,YAAM,KAAK,OAAO,KAAK,MAAM,EAAE;AAC/B,UAAI,KAAK,EAAG;AAEZ,YAAM,YAAY,KAAK,UAAU,IAAI,CAAC,GAAG,SAAS,KAAK,UAAU,IAAI,CAAC,GAAG;AACzE,YAAM,QAAQ,WAAW,cAAc,WAAW;AAElD,UAAI,IAAI,IAAI,EAAE,MAAM,CAAC;AAAA,IACvB;AAAA,EACF,QAAQ;AAAA,EAAkB;AAC1B,SAAO;AACT;AAIA,SAAS,aAAa,GAAQ,OAA4C;AAExE,QAAM,OAAO,OAAO,GAAG,UAAU,QAAQ;AACzC,MAAI,WAAW;AACf,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,OAAO,KAAK,UAAU,UAAU;AAC7C,eAAW,OAAO,MAAM;AACtB,YAAM,KAAK,EAAE,MAAM,SAAS,MAAM,IAAI,CAAC;AACvC,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,QAAM,UAAU,KAAK,KAAK,CAAC,QAAa;AACtC,UAAM,KAAK,OAAO,KAAK,QAAQ,QAAQ,SAAS;AAChD,WAAO,GAAG,KAAK,CAAC,MAAW;AACzB,YAAM,OAAO,OAAO,MAAM,WAAW,IAAI,GAAG,SAAS;AACrD,aAAO,KAAK,KAAK,EAAE,SAAS;AAAA,IAC9B,CAAC;AAAA,EACH,CAAC;AACD,MAAI,WAAW,CAAC,UAAU;AACxB,UAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,EAAE,CAAC;AAAA,EACtC;AACF;AAEA,SAAS,cAAc,KAAU,MAAgB,KAAa;AAE5D,QAAM,aAAa,OAAO,KAAK,QAAQ,MAAM;AAC7C,QAAM,WAAW,iBAAiB,WAAW,CAAC,CAAC,KAAK;AAGpD,QAAM,QAAuC,CAAC;AAC9C,QAAM,QAAQ,OAAO,KAAK,QAAQ,MAAM;AACxC,QAAM,aAAa,MAAM,aAAa;AAEtC,MAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,QAAI,KAAK;AACT,eAAW,OAAO,YAAY;AAC5B,WAAK,QAAQ,UAAU,QAAQ,WAAW,KAAK,MAAM,QAAQ;AAC3D,cAAM,IAAI,MAAM,IAAI;AACpB,qBAAa,GAAG,KAAK;AAAA,MACvB;AAAA,IACF;AAEA,WAAO,KAAK,MAAM,OAAQ,cAAa,MAAM,IAAI,GAAG,KAAK;AAAA,EAC3D,OAAO;AAEL,eAAW,KAAK,MAAO,cAAa,GAAG,KAAK;AAAA,EAC9C;AAEA,QAAM,OAAsB,IAAI,OAAO;AAAA,IACrC;AAAA,IACA,CAAC,SAAc;AACb,UAAI,KAAK,SAAS,SAAS;AACzB,cAAM,EAAE,MAAM,IAAI,IAAI,OAAO;AAAA,UAC3B,KAAK;AAAA,UACL,CAAC,MAAM,WAAW,GAAG,GAAG;AAAA,UACxB,CAAC,MAAM,iBAAiB,GAAG,GAAG;AAAA,UAC9B,CAAC,MAAM,eAAe,CAAC;AAAA,UACvB,CAAC,MAAM,eAAe,CAAC;AAAA,UACvB;AAAA,QACF;AACA,eAAO;AAAA,MACT;AACA,aAAO,WAAW,KAAK,MAAM,GAAG;AAAA,IAClC;AAAA,IACA,MAAM,UAAU,CAAC,UAAU,6BAAS,CAAC,CAAC;AAAA,IACtC;AAAA,EACF;AAGA,QAAM,cAAc,mBAAmB,KAAK,UAAU,GAAG;AACzD,QAAM,cAAc,mBAAmB,KAAK,UAAU,GAAG;AAEzD,SAAO;AAAA,IACL,KAAK,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,EAAE,QAAQ,aAAa,QAAQ,YAAY;AAAA,EAC7C;AACF;AAEA,SAAS,iBAAiB,GAAyB;AACjD,MAAI,CAAC,EAAG,QAAO;AACf,MAAI;AACF,UAAM,OAAO,OAAO,GAAG,UAAU,QAAQ;AACzC,eAAW,OAAO,MAAM;AACtB,YAAM,QAAQ,MAAM,UAAU,IAAI,CAAC,KAAK,MAAM,UAAU,IAAI,CAAC;AAC7D,UAAI,CAAC,MAAO;AACZ,YAAM,SAAS,QAAQ,WAAW,IAAI,CAAC,GAAG,SAAS,QAAQ,WAAW,IAAI,CAAC,GAAG;AAC9E,UAAI,CAAC,OAAQ;AACb,YAAM,SAAS,QAAQ,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG,SACzD,QAAQ,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG,SAAS,CAAC;AAC9D,aAAO;AAAA,QACL,KAAQ,OAAO,QAAQ,OAAO,OAAO,SAAS,KAAK,CAAC;AAAA,QACpD,KAAQ,OAAO,QAAQ,OAAO,OAAO,UAAU,KAAK,CAAC;AAAA,QACrD,IAAQ,OAAO,QAAQ,OAAO,OAAO,OAAO,IAAI,CAAC;AAAA,QACjD,IAAQ,OAAO,QAAQ,OAAO,OAAO,UAAU,IAAI,CAAC;AAAA,QACpD,IAAQ,OAAO,QAAQ,OAAO,OAAO,QAAQ,IAAI,CAAC;AAAA,QAClD,IAAQ,OAAO,QAAQ,OAAO,OAAO,SAAS,IAAI,CAAC;AAAA,QACnD,QAAQ,OAAO,cAAc,aAAa,cAAc;AAAA,MAC1D;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAAe;AACvB,SAAO;AACT;AAEA,SAAS,mBAAmB,KAAU,MAA2B,KAAqC;AACpG,MAAI;AACF,UAAM,KAAK,MAAM,iBAAiB,IAAI,CAAC,KAAK,MAAM,iBAAiB,IAAI,CAAC,KACnE,KAAK,eAAe,CAAC,KAAK,KAAK,eAAe,CAAC;AACpD,QAAI,CAAC,GAAI,QAAO;AAEhB,UAAM,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,KAAK,YAAY,CAAC,IAAI,CAAC,KACvE,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,YAAY,CAAC,IAAI,CAAC;AACpD,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,QAAQ,OAAO,MAAM,QAAQ,MAAM;AACzC,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,MAAM,IAAI,CAAC,MAAW,WAAW,GAAG,GAAG,CAAC;AAAA,EACjD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,WAAW,GAAQ,KAAuB;AACjD,QAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,QAAM,cAAc,OAAO,MAAM,eAAe,EAAE;AAGlD,MAAI;AACJ,QAAM,YAAY,IAAI,QAAQ,IAAI,WAAW;AAC7C,MAAI,WAAW,MAAO,SAAQ,UAAU;AAGxC,QAAM,eAAe,IAAI,WAAW,IAAI,CAAC,KAAK,IAAI,WAAW,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;AACpF,MAAI,cAAc;AAChB,UAAM,YAAY,eAAe,UAAU,IAAI,CAAC,GAAG,SAAS,eAAe,UAAU,IAAI,CAAC,GAAG,SACxF,cAAc,QAAQ,CAAC,GAAG;AAC/B,QAAI,WAAW,KAAM,SAAQ,UAAU;AACvC,QAAI,WAAW,WAAY,SAAQ,UAAU;AAAA,EAC/C;AAEA,QAAM,aAAa,cAAc,SAAS,CAAC;AAC3C,QAAM,QAAmB,EAAE,OAAO,UAAU,KAAK,EAAE;AAGnD,MAAI,WAAW,UAAU;AACvB,UAAM,UAAU,WAAW,aAAa,WAAW,WAAW,aAAa;AAC3E,UAAM,SAAS,OAAO,WAAW,aAAa,CAAC;AAAA,EACjD;AAEA,QAAM,OAAO,OAAO,GAAG,UAAU,QAAQ;AACzC,QAAM,OAA+B,CAAC;AAEtC,aAAW,OAAO,MAAM;AAEtB,UAAM,OAAO,OAAO,KAAK,UAAU,QAAQ;AAC3C,eAAW,OAAO,MAAM;AACtB,YAAM,MAAM,UAAU,KAAK,GAAG;AAC9B,UAAI,IAAK,MAAK,KAAK,GAAG;AAAA,IACxB;AAGA,UAAM,WAAW,OAAO,KAAK,cAAc,YAAY;AACvD,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC;AAClC,YAAM,MAAM,GAAG,eAAe,gBAAgB,UAC1C,GAAG,eAAe,gBAAgB,cAClC;AACJ,YAAM,cAA2B,EAAE,KAAK,WAAW,QAAQ,IAAI;AAC/D,YAAMA,aAAY,cAAc,KAAK,GAAG;AACxC,WAAK,KAAK,EAAE,KAAK,QAAQ,OAAOA,YAAW,MAAM,CAAC,WAAW,EAAE,CAAC;AAChE;AAAA,IACF;AAGA,UAAM,YAAY,OAAO,KAAK,QAAQ,QAAQ,SAAS;AACvD,UAAM,UAAU,UAAU,IAAI,CAAC,MAAW,OAAO,MAAM,WAAW,IAAI,GAAG,SAAS,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE;AAGrG,QAAI,YAAY,OAAO,MAAM,UAAU,IAAI,CAAC,KAAK,MAAM,UAAU,IAAI,CAAC,MAAM,KAAK,WAAW,EAAG;AAE/F,UAAM,YAAY,cAAc,KAAK,GAAG;AACxC,SAAK,KAAK,UAAU,SAAS,SAAS,CAAC;AAAA,EACzC;AAEA,SAAO,UAAU,KAAK,OAAO,OAAO,GAAuB,KAAK;AAClE;AAEA,SAAS,cAAc,KAAU,KAAwB;AACvD,QAAM,UAAU,KAAK,SAAS,CAAC;AAC/B,QAAM,cAAc,OAAO,QAAQ,eAAe,EAAE;AAGpD,QAAM,MAAM,IAAI,QAAQ,IAAI,WAAW;AACvC,MAAI,KAAK;AACP,WAAO;AAAA,MACL,GAAG,IAAI;AAAA,MAAG,GAAG,IAAI;AAAA,MAAG,GAAG,IAAI;AAAA,MAAG,GAAG,IAAI;AAAA,MACrC,IAAI,IAAI;AAAA,MAAI,OAAO,IAAI;AAAA,MAAO,MAAM,IAAI;AAAA,MAAM,IAAI,IAAI;AAAA,IACxD;AAAA,EACF;AAGA,QAAM,KAAK,MAAM,WAAW,IAAI,CAAC,GAAG,SAAS,MAAM,WAAW,IAAI,CAAC,GAAG,SAAS,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC;AAC3G,SAAO;AAAA,IACL,GAAO,GAAG,SAAS,OAAO,GAAG,SAAS,UAAU;AAAA,IAChD,GAAO,GAAG,WAAW,OAAO,GAAG,WAAW,UAAU;AAAA,IACpD,GAAO,GAAG,YAAY,GAAG,cAAc,SAAS;AAAA,IAChD,GAAO,GAAG,YAAY,GAAG,cAAc,SAAS;AAAA,IAChD,MAAO,SAAS,GAAG,YAAY,GAAG,cAAc;AAAA,IAChD,IAAO,GAAG,SAAS,OAAO,YAAY,OAAO,GAAG,MAAM,CAAC,IAAI;AAAA,IAC3D,OAAO,QAAQ,GAAG,SAAS;AAAA,IAC3B,IAAO,QAAQ,GAAG,OAAO;AAAA,EAC3B;AACF;AAIA,SAAS,UAAU,KAAU,KAA6B;AACxD,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,IAAI,CAAC,GAAG,SAAS,KAAK,KAAK,CAAC,GAAG,SAAS,CAAC;AACrE,UAAM,IAAI,OAAO,QAAQ,OAAO,OAAO,SAAS,CAAC,CAAC;AAClD,UAAM,IAAI,OAAO,QAAQ,OAAO,OAAO,UAAU,CAAC,CAAC;AAGnD,UAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,GAAG,SAAS,MAAM,QAAQ,IAAI,CAAC,GAAG,SAChE,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;AAC9B,UAAM,SAAS,QAAQ,mBAAmB,QAAQ;AAClD,QAAI,CAAC,OAAQ,QAAO;AAGpB,QAAI;AACJ,eAAW,CAAC,KAAK,GAAG,KAAK,IAAI,OAAO;AAClC,UAAI,IAAI,SAAS,MAAM,KAAK,IAAI,YAAY,EAAE,SAAS,OAAO,YAAY,CAAC,GAAG;AAC5E,kBAAU;AACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,MAAM,OAAO,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY,KAAK;AACtD,UAAM,UAA2C;AAAA,MAC/C,KAAK;AAAA,MAAa,KAAK;AAAA,MAAc,MAAM;AAAA,MAC3C,KAAK;AAAA,MAAa,KAAK;AAAA,IACzB;AAEA,WAAO,SAAS,QAAQ,aAAa,OAAO,GAAG,QAAQ,GAAG,KAAK,aAAa,GAAG,CAAC;AAAA,EAClF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,WAAW,KAAU,KAAuB;AACnD,QAAM,UAAU,KAAK,SAAS,CAAC;AAC/B,QAAM,eAAe,OAAO,QAAQ,mBAAmB,CAAC;AACxD,QAAM,aAAa,IAAI,YAAY,IAAI,YAAY;AACnD,QAAM,YAAY,QAAQ,iBAAiB;AAE3C,QAAM,YAAuB,EAAE,WAAW,aAAa,OAAU;AACjE,MAAI,YAAY,OAAQ,WAAU,gBAAgB,WAAW;AAE7D,QAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;AAC5C,QAAM,WAAW,OAAO,IAAI,CAAC,QAAa;AACxC,UAAM,UAAU,OAAO,KAAK,SAAS,SAAS;AAC9C,UAAM,YAAY,QAAQ,IAAI,CAAC,SAAc;AAC3C,YAAM,KAAK,MAAM,SAAS,CAAC;AAG3B,YAAM,WAAW,OAAO,GAAG,mBAAmB,CAAC;AAC/C,YAAM,SAAS,IAAI,YAAY,IAAI,QAAQ;AAE3C,YAAM,YAAuB;AAAA,QAC3B,IAAI,QAAQ,WAAW,QAAQ,GAAG,OAAO;AAAA,MAC3C;AAEA,UAAI,QAAQ,QAAQ;AAClB,kBAAU,MAAM,OAAO;AACvB,kBAAU,MAAM,OAAO;AACvB,kBAAU,OAAO,OAAO;AACxB,kBAAU,QAAQ,OAAO;AAAA,MAC3B;AAGA,YAAM,UAAU,OAAO,YAAY,IAAI,CAAC,KAAK,MAAM,UAAU,CAAC;AAC9D,YAAM,UAAU,SAAS,SAAS,CAAC;AACnC,UAAI,QAAQ,WAAW;AACrB,cAAM,QAA+C;AAAA,UACnD,KAAK;AAAA,UAAO,QAAQ;AAAA,UAAO,QAAQ;AAAA,QACrC;AACA,kBAAU,KAAK,MAAM,QAAQ,SAAS;AAAA,MACxC;AAGA,YAAM,WAAW,OAAO,aAAa,IAAI,CAAC,GAAG,SAAS,CAAC;AACvD,YAAM,KAAK,OAAO,SAAS,WAAW,GAAG,WAAW,CAAC;AACrD,YAAM,KAAK,OAAO,SAAS,WAAW,GAAG,WAAW,CAAC;AAGrD,UAAI;AACJ,UAAI,SAAS;AACX,cAAM,WAAW,OAAO,SAAS,QAAQ,MAAM;AAC/C,gBAAQ,SAAS,IAAI,CAAC,MAAW,WAAW,GAAG,GAAG,CAAC;AAAA,MACrD,OAAO;AACL,gBAAQ,OAAO,MAAM,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAW,WAAW,GAAG,GAAG,CAAC;AAAA,MACzE;AAEA,aAAO;AAAA,QACL,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAAA,QACtD,EAAE,IAAI,IAAI,OAAO,UAAU;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,WAAO,SAAS,SAAS;AAAA,EAC3B,CAAC;AACD,SAAO,UAAU,UAAU,SAAS;AACtC;AAEA,SAAS,iBAAiB,KAAU,KAAuB;AACzD,QAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;AAC5C,QAAM,WAAW,OAAO,IAAI,CAAC,QAAa;AACxC,UAAM,UAAU,OAAO,KAAK,SAAS,SAAS;AAC9C,WAAO,SAAS,QAAQ,IAAI,CAAC,SAAc,UAAU,CAAC,UAAU,CAAC,UAAU,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,EACjG,CAAC;AACD,SAAO,UAAU,QAAQ;AAC3B;AAEA,SAAS,eAAe,KAAoB;AAC1C,SAAO,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF;AAEA,SAAS,eAAe,KAAoB;AAC1C,SAAO,UAAU,CAAC,UAAU,UAAU,GAAG,CAAC,CAAC,CAAC;AAC9C;AAEA,SAAS,SAAS,MAAmB;AACnC,QAAM,UAAU,OAAO,YAAY,IAAI,CAAC,KAAK,MAAM,UAAU,CAAC;AAC9D,QAAM,SAAS,WAAW;AAC1B,SAAO,OAAO,QAAQ,QAAQ,MAAM,EAAE;AAAA,IAAI,CAAC,MACzC,OAAO,GAAG,UAAU,QAAQ,EAAE;AAAA,MAAI,CAAC,MACjC,OAAO,GAAG,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAW,OAAO,MAAM,WAAW,IAAI,GAAG,SAAS,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE;AAAA,IACvG,EAAE,KAAK,EAAE;AAAA,EACX,EAAE,KAAK,GAAG;AACZ;AAEA,SAAS,UAAU,KAAkB;AACnC,SAAO,OAAO,KAAK,SAAS,QAAQ,EAAE;AAAA,IAAI,CAAC,QACzC,OAAO,KAAK,SAAS,SAAS,EAAE,IAAI,CAAC,MAAW,SAAS,CAAC,CAAC,EAAE,KAAK,GAAI;AAAA,EACxE,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,MAAM,GAAe;AAAE,SAAO,KAAK,OAAO,CAAC,IAAI,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;AAAG;AAGpF,SAAS,gBAAgB,IAAI,YAAY,CAAC;;;ACrnBnC,IAAM,YAAY;AAAA,EACvB,UAAU,KAAiB,QAAwB;AACjD,WAAO,IAAI,MAAM,IAAK,IAAI,SAAS,CAAC,KAAK;AAAA,EAC3C;AAAA,EAEA,UAAU,KAAiB,QAAwB;AACjD,aACG,IAAI,MAAM,IAAK,IAAI,SAAS,CAAC,KAAK,IAAM,IAAI,SAAS,CAAC,KAAK,QAAS,KACnE,IAAI,SAAS,CAAC,IAAI;AAAA,EACxB;AAAA,EAEA,OAAO,MAA2B;AAChC,WACE,KAAK,UAAU,KACf,KAAK,CAAC,MAAM,OAAQ,KAAK,CAAC,MAAM,OAChC,KAAK,CAAC,MAAM,MAAQ,KAAK,CAAC,MAAM,OAChC,KAAK,CAAC,MAAM,OAAQ,KAAK,CAAC,MAAM,OAChC,KAAK,CAAC,MAAM,MAAQ,KAAK,CAAC,MAAM;AAAA,EAEpC;AAAA,EAEA,SAAS,MAA2C;AAClD,UAAM,UAAU,oBAAI,IAAwB;AAE5C,QAAI,CAAC,KAAK,OAAO,IAAI,GAAG;AACtB,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,UAAM,OAAO,IAAI,SAAS,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;AACvE,UAAM,aAAe,KAAK,KAAK,UAAU,IAAI,IAAI;AACjD,UAAM,eAAe,KAAK,KAAK,UAAU,IAAI,IAAI;AACjD,UAAM,cAAe,KAAK,UAAU,IAAI,IAAI;AAC5C,UAAM,mBAAmB,KAAK,UAAU,IAAI,IAAI;AAChD,UAAM,eAAe,KAAK,UAAU,IAAI,IAAI;AAC5C,UAAM,aAAe,KAAK,UAAU,IAAI,IAAI;AAC5C,UAAM,aAAe,KAAK,UAAU,IAAI,IAAI;AAE5C,UAAM,aAAa;AACnB,UAAM,WAAa;AAEnB,UAAM,WAAW,CAAC,QAChB,KAAK,SAAS,MAAM,MAAM,YAAY,OAAO,MAAM,KAAK,UAAU;AAGpE,UAAM,aAAuB,CAAC;AAC9B,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,YAAM,IAAI,KAAK,UAAU,KAAK,IAAI,GAAG,IAAI;AACzC,UAAI,MAAM,YAAY,MAAM,WAAY;AACxC,iBAAW,KAAK,CAAC;AAAA,IACnB;AACA,QAAI,eAAe,cAAc,eAAe,UAAU;AACxD,UAAI,SAAS;AACb,aAAO,WAAW,cAAc,WAAW,UAAU;AACnD,cAAM,MAAM,SAAS,MAAM;AAC3B,cAAM,KAAK,IAAI,SAAS,IAAI,QAAQ,IAAI,YAAY,IAAI,UAAU;AAClE,iBAAS,IAAI,GAAG,IAAK,aAAa,IAAK,GAAG,KAAK;AAC7C,gBAAM,IAAI,GAAG,UAAU,IAAI,GAAG,IAAI;AAClC,cAAI,MAAM,YAAY,MAAM,WAAY;AACxC,qBAAW,KAAK,CAAC;AAAA,QACnB;AACA,iBAAS,GAAG,UAAU,aAAa,GAAG,IAAI;AAAA,MAC5C;AAAA,IACF;AAEA,UAAM,MAAgB,CAAC;AACvB,eAAW,OAAO,YAAY;AAC5B,YAAM,IAAI,SAAS,GAAG;AACtB,YAAM,KAAK,IAAI,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU;AAC5D,eAAS,IAAI,GAAG,IAAI,aAAa,GAAG,KAAK;AACvC,YAAI,KAAK,GAAG,UAAU,IAAI,GAAG,IAAI,CAAC;AAAA,MACpC;AAAA,IACF;AAEA,UAAM,YAAY,CAAC,aAAiC;AAClD,YAAM,SAAuB,CAAC;AAC9B,UAAI,MAAM;AACV,aAAO,QAAQ,cAAc,QAAQ,YAAY,MAAM,IAAI,QAAQ;AACjE,eAAO,KAAK,SAAS,GAAG,CAAC;AACzB,cAAM,IAAI,GAAG;AAAA,MACf;AACA,aAAO,YAAY,MAAM;AAAA,IAC3B;AAGA,UAAM,UAAU,UAAU,WAAW;AACrC,UAAM,UAAU,IAAI,SAAS,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,UAAU;AACnF,UAAM,WAAW,QAAQ,SAAS;AAYlC,UAAM,aAAyB,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,OAAO,IAAI;AACjB,YAAM,UAAU,QAAQ,UAAU,OAAO,IAAI,IAAI;AACjD,YAAM,YAAY,QAAQ,SAAS,MAAM,OAAO,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;AACxE,YAAM,OAAO,IAAI,YAAY,UAAU,EAAE,OAAO,SAAS;AACzD,YAAM,OAAO,QAAQ,OAAO,EAAE;AAC9B,YAAM,UAAe,QAAQ,SAAS,OAAO,IAAI,IAAI;AACrD,YAAM,UAAgB,QAAQ,SAAS,OAAO,IAAI,IAAI;AACtD,YAAM,WAAgB,QAAQ,SAAS,OAAO,IAAI,IAAI;AACtD,YAAM,WAAe,QAAQ,UAAU,OAAO,KAAK,IAAI;AACvD,YAAM,OAAe,QAAQ,UAAU,OAAO,KAAK,IAAI;AACvD,iBAAW,KAAK,EAAE,MAAM,MAAM,UAAU,MAAM,SAAS,eAAe,SAAS,gBAAgB,SAAS,CAAC;AAAA,IAC3G;AAGA,UAAM,YAAY,WAAW,CAAC;AAC9B,QAAI,iBAAoC;AACxC,QAAI,UAAoB,CAAC;AAEzB,QAAI,aAAa,UAAU,aAAa,cAAc,UAAU,aAAa,UAAU;AACrF,uBAAiB,UAAU,UAAU,QAAQ;AAAA,IAC/C;AAEA,QAAI,aAAa,KAAK,iBAAiB,cAAc,iBAAiB,UAAU;AAC9E,YAAM,SAAS,UAAU,YAAY;AACrC,YAAM,MAAM,IAAI,SAAS,OAAO,QAAQ,OAAO,YAAY,OAAO,UAAU;AAC5E,eAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,gBAAQ,KAAK,IAAI,UAAU,IAAI,GAAG,IAAI,CAAC;AAAA,MACzC;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,UAAkB,SAA6B;AACpE,UAAI,CAAC,eAAgB,QAAO,IAAI,WAAW,CAAC;AAC5C,YAAM,SAAuB,CAAC;AAC9B,UAAI,MAAM;AACV,UAAI,YAAY;AAChB,aAAO,QAAQ,cAAc,QAAQ,YAAY,MAAM,QAAQ,UAAU,YAAY,GAAG;AACtF,cAAM,MAAM,MAAM;AAClB,cAAM,QAAQ,eAAe,SAAS,KAAK,MAAM,KAAK,IAAI,cAAc,SAAS,CAAC;AAClF,eAAO,KAAK,KAAK;AACjB,qBAAa,MAAM;AACnB,cAAM,QAAQ,GAAG;AAAA,MACnB;AACA,aAAO,YAAY,MAAM,EAAE,SAAS,GAAG,IAAI;AAAA,IAC7C;AAGA,UAAM,QAAQ,CAAC,IAAY,SAAuB;AAChD,UAAI,KAAK,KAAK,MAAM,WAAW,OAAQ;AACvC,YAAM,QAAQ,WAAW,EAAE;AAC3B,YAAM,WAAW,OAAO,GAAG,IAAI,IAAI,MAAM,IAAI,KAAK,MAAM;AAExD,UAAI,MAAM,SAAS,GAAG;AACpB,YAAI;AACJ,YAAI,MAAM,OAAO,oBAAoB,gBAAgB;AACnD,uBAAa,cAAc,MAAM,UAAU,MAAM,IAAI;AAAA,QACvD,OAAO;AACL,uBAAa,UAAU,MAAM,QAAQ,EAAE,SAAS,GAAG,MAAM,IAAI;AAAA,QAC/D;AACA,gBAAQ,IAAI,UAAU,UAAU;AAChC,gBAAQ,IAAI,MAAM,MAAM,UAAU;AAAA,MACpC;AAEA,UAAI,MAAM,WAAW,EAAG,OAAM,MAAM,SAAS,QAAQ;AACrD,UAAI,MAAM,iBAAiB,EAAG,OAAM,MAAM,eAAe,IAAI;AAC7D,UAAI,MAAM,kBAAkB,EAAG,OAAM,MAAM,gBAAgB,IAAI;AAAA,IACjE;AAEA,QAAI,WAAW,SAAS,KAAK,WAAW,CAAC,EAAE,WAAW,GAAG;AACvD,YAAM,WAAW,CAAC,EAAE,SAAS,EAAE;AAAA,IACjC;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,QAAkC;AACrD,QAAM,QAAQ,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,QAAQ,CAAC;AACrD,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,MAAM;AACV,aAAW,KAAK,QAAQ;AAAE,QAAI,IAAI,GAAG,GAAG;AAAG,WAAO,EAAE;AAAA,EAAQ;AAC5D,SAAO;AACT;;;AC/KA,OAAOC,WAAU;AAMjB,IAAM,eAAe;AAErB,IAAM,gBAAsB,eAAe;AAC3C,IAAM,kBAAsB,eAAe;AAC3C,IAAM,iBAAsB,eAAe;AAC3C,IAAM,iBAAsB,eAAe;AAC3C,IAAM,kBAAsB,eAAe;AAC3C,IAAM,gBAAsB,eAAe;AAC3C,IAAM,sBAAsB,eAAe;AAC3C,IAAM,kBAAsB,eAAe;AAC3C,IAAM,eAAsB,eAAe;AAG3C,IAAM,kBAAkB,eAAe;AACvC,IAAM,cAAc,eAAe;AACnC,IAAM,aAAc,eAAe;AACnC,IAAM,cAAc,eAAe;AACnC,IAAM,aAAc,eAAe;AAEnC,SAAS,WAAW,GAAW;AAAE,SAAO,MAAM,eAAe,MAAM;AAAa;AAChF,SAAS,UAAU,GAAY;AAAE,SAAO,MAAM,cAAc,MAAM,cAAc,MAAM;AAAiB;AAGvG,IAAM,aAAa;AAmDnB,SAAS,aAAa,MAA+B;AACnD,QAAM,MAAmB,CAAC;AAC1B,MAAI,MAAM;AACV,SAAO,MAAM,KAAK,KAAK,QAAQ;AAC7B,UAAM,MAAM,UAAU,UAAU,MAAM,GAAG;AACzC,UAAM,MAAQ,MAAM;AACpB,UAAM,QAAS,OAAO,KAAM;AAC5B,QAAI,OAAW,OAAO,KAAM;AAC5B,WAAO;AACP,QAAI,SAAS,MAAO;AAClB,UAAI,MAAM,IAAI,KAAK,OAAQ;AAC3B,aAAO,UAAU,UAAU,MAAM,GAAG;AACpC,aAAO;AAAA,IACT;AACA,QAAI,MAAM,OAAO,KAAK,OAAQ;AAC9B,QAAI,KAAK,EAAE,KAAK,OAAO,MAAM,KAAK,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC;AAC7D,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAA8B;AAChD,MAAI;AAAE,WAAOA,MAAK,WAAW,IAAI;AAAA,EAAG,QAAQ;AAAE,WAAO;AAAA,EAAM;AAC7D;AAMA,SAAS,gBAAgB,KAAiB;AACxC,MAAI,IAAI,SAAS,GAAI,QAAO,EAAE,YAAY,MAAM,WAAW,MAAM;AACjE,QAAM,QAAQ,UAAU,UAAU,KAAK,EAAE;AACzC,SAAO,EAAE,aAAa,QAAQ,OAAO,GAAG,YAAY,QAAQ,OAAO,EAAE;AACvE;AAMA,SAAS,aAAa,MAAkB,YAA8B;AACpE,QAAM,MAAM,aAAa,WAAW,IAAI,IAAI;AAC5C,QAAM,OAAO,aAAa,GAAG;AAC7B,QAAM,OAAgB,EAAE,WAAW,CAAC,GAAG,YAAY,CAAC,GAAG,YAAY,CAAC,GAAG,aAAa,CAAC,EAAE;AAEvF,aAAW,KAAK,MAAM;AACpB,QAAI;AACF,UAAI,EAAE,QAAQ,cAAiB,MAAK,UAAU,KAAK,cAAc,EAAE,IAAI,CAAC;AACxE,UAAI,EAAE,QAAQ,eAAiB,MAAK,WAAW,KAAK,eAAe,EAAE,IAAI,CAAC;AAC1E,UAAI,EAAE,QAAQ,eAAiB,MAAK,WAAW,KAAK,eAAe,EAAE,IAAI,CAAC;AAC1E,UAAI,EAAE,QAAQ,gBAAiB,MAAK,YAAY,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAAA,IAC9E,QAAQ;AAAA,IAA8B;AAAA,EACxC;AACA,SAAO;AACT;AAIA,SAAS,cAAc,GAAuB;AAC5C,MAAI,EAAE,SAAS,EAAG,QAAO;AACzB,QAAM,MAAM,UAAU,UAAU,GAAG,CAAC;AACpC,MAAI,EAAE,SAAS,IAAI,MAAM,EAAG,QAAO;AACnC,SAAO,IAAI,YAAY,UAAU,EAAE,OAAO,EAAE,SAAS,GAAG,IAAI,MAAM,CAAC,CAAC;AACtE;AAeA,SAAS,eAAe,GAA6B;AACnD,QAAM,UAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,SAAQ,KAAK,EAAE,WAAW,IAAI,KAAK,IAAI,UAAU,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;AAEpG,QAAM,SAAS,EAAE,UAAU,KAAK,UAAU,UAAU,GAAG,EAAE,IAAI;AAC7D,QAAM,OAAS,EAAE,UAAU,KAAK,UAAU,UAAU,GAAG,EAAE,IAAI;AAQ7D,QAAM,SAAW,QAAQ,IAAM;AAC/B,QAAM,SAAW,QAAQ,KAAM;AAC/B,QAAM,SAAW,QAAQ,KAAM;AAE/B,SAAO;AAAA,IACL;AAAA,IACA,QAAS,SAAS,KAAK,SAAS,MAAU,SAAS;AAAA,IACnD,SAAc,OAAO,OAAO;AAAA,IAC5B,OAAe,QAAQ,IAAK,OAAO;AAAA,IACnC,WAAa,WAAW;AAAA,IACxB,WAAa,WAAW;AAAA,IACxB,aAAa,WAAW;AAAA,IACxB,WAAa,WAAW;AAAA,IACxB,WAAa,EAAE,UAAU,KAAK,SAAS,GAAG,EAAE,IAAI;AAAA,EAClD;AACF;AAYA,IAAM,YAAmC,EAAE,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU;AAE1G,SAAS,eAAe,GAA6B;AACnD,MAAI,EAAE,SAAS,EAAG,QAAO,EAAE,OAAO,QAAQ,aAAa,GAAG,YAAY,GAAG,aAAa,KAAK,QAAQ,EAAE;AACrG,QAAM,OAAO,UAAU,UAAU,GAAG,CAAC;AACrC,SAAO;AAAA,IACL,OAAa,UAAU,OAAO,CAAG,KAAK;AAAA,IACtC,QAAa,EAAE,UAAU,KAAK,IAAI,GAAG,EAAE,IAAI;AAAA,IAC3C,aAAa,EAAE,UAAU,KAAK,IAAI,GAAG,EAAE,IAAI;AAAA,IAC3C,YAAa,EAAE,UAAU,KAAK,IAAI,GAAG,EAAE,IAAI;AAAA,IAC3C,aAAa,EAAE,UAAU,KAAK,IAAI,GAAG,EAAE,IAAI;AAAA,EAC7C;AACF;AASA,IAAM,cAAc,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,KAAM,MAAM,MAAM,MAAM,MAAM,KAAM,OAAO,KAAK;AACrH,IAAM,cAA0C,EAAE,GAAE,QAAO,GAAE,SAAQ,GAAE,QAAO,GAAE,OAAM,GAAE,QAAO,GAAE,QAAO,GAAE,QAAO,GAAE,OAAM,GAAE,UAAS,GAAE,UAAS,IAAG,SAAS;AAE3J,SAAS,gBAAgB,GAA8B;AACrD,QAAM,UAAoC,CAAC;AAC3C,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,IAAI,IAAI,IAAI;AAClB,QAAI,IAAI,KAAK,EAAE,QAAQ;AACrB,cAAQ,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,YAAY,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC;AAAA,IAC/F,OAAO;AACL,cAAQ,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,SAAS,CAAC;AAAA,IACzD;AAAA,EACF;AACA,MAAI;AACJ,QAAM,OAAO;AACb,MAAI,EAAE,UAAU,OAAO,GAAG;AACxB,UAAM,KAAK,UAAU,UAAU,GAAG,IAAI;AACtC,QAAI,KAAK,EAAG,WAAU,SAAS,GAAG,OAAO,CAAC;AAAA,EAC5C;AACA,SAAO,EAAE,SAAS,QAAQ;AAC5B;AAMA,SAAS,UACP,KAAiB,YAAqB,IAAa,QACF;AACjD,QAAM,OAAO,aAAa,aAAa,WAAW,GAAG,IAAI,GAAG;AAC5D,QAAM,UAAyB,CAAC;AAChC,MAAI;AACJ,MAAI,IAAI;AAER,SAAO,IAAI,KAAK,QAAQ;AACtB,QAAI,KAAK,CAAC,EAAE,QAAQ,cAAc;AAChC,iBAAW,OAAO,MAAM,MAAM,aAAa,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,aAAa;AAC3E;AAAA,IACF,WAAW,KAAK,CAAC,EAAE,QAAQ,iBAAiB;AAC1C,YAAM,IAAI,OAAO;AAAA,QACf,MAAM,oBAAoB,MAAM,GAAG,IAAI,MAAM;AAAA,QAC7C,EAAE,OAAO,CAAC,GAAoB,MAAM,IAAI,EAAE;AAAA,QAC1C,YAAY,CAAC;AAAA,MACf;AACA,cAAQ,KAAK,GAAG,EAAE,KAAK;AACvB,UAAI,EAAE;AAAA,IACR,OAAO;AACL;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,SAAS,SAAS;AAC7B;AAIA,SAAS,oBACP,MAAmB,OAAe,IAAa,QACP;AACxC,QAAM,MAAM,KAAK,KAAK;AACtB,QAAM,KAAM,IAAI;AAGhB,QAAM,OAAO,IAAI,KAAK,UAAU,KAAK,UAAU,UAAU,IAAI,MAAM,CAAC,IAAI;AACxE,QAAM,KAAO,GAAG,WAAW,IAAI;AAE/B,MAAI,OAA8B;AAClC,MAAI,UAA8B,CAAC;AACnC,QAAM,QAAuB,CAAC;AAC9B,MAAI,IAAI,QAAQ;AAEhB,SAAO,IAAI,KAAK,UAAU,KAAK,CAAC,EAAE,QAAQ,IAAI;AAC5C,UAAM,IAAI,KAAK,CAAC;AAEhB,QAAI,EAAE,QAAQ,iBAAiB,EAAE,UAAU,KAAK,GAAG;AACjD,aAAO,eAAe,EAAE,IAAI;AAC5B;AAAA,IACF,WAAW,EAAE,QAAQ,uBAAuB,EAAE,UAAU,KAAK,GAAG;AAC9D,gBAAU,oBAAoB,EAAE,IAAI;AACpC;AAAA,IACF,WAAW,EAAE,QAAQ,mBAAmB,EAAE,UAAU,KAAK,GAAG;AAC1D,UAAI,EAAE,KAAK,UAAU,KAAK,UAAU,UAAU,EAAE,MAAM,CAAC,MAAM,YAAY;AACvE,cAAM,KAAK,OAAO;AAAA,UAChB,MAAM,eAAe,MAAM,GAAG,IAAI,MAAM;AAAA,UACxC,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,CAAC,EAAE;AAAA,UACtC,WAAW,CAAC;AAAA,QACd;AACA,YAAI,GAAG,KAAM,OAAM,KAAK,GAAG,IAAI;AAC/B,YAAI,GAAG;AAAA,MACT,OAAO;AACL,YAAI,SAAS,MAAM,CAAC;AAAA,MACtB;AAAA,IACF,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAuB,CAAC;AAG9B,MAAI,QAAQ,KAAK,MAAM,SAAS,GAAG;AACjC,UAAM,SAAS,KAAK,MAAM,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,EAAE;AAChD,QAAI,OAAO,KAAK,GAAG;AACjB,YAAM,QAAQ,kBAAkB,KAAK,OAAO,SAAS,EAAE;AACvD,YAAM,KAAK,UAAU,OAAO,eAAe,EAAE,CAAC,CAAC;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,KAAK,GAAG,KAAK;AACnB,SAAO,EAAE,OAAO,MAAM,EAAE;AAC1B;AAEA,SAAS,SAAS,MAAmB,KAAqB;AACxD,QAAM,KAAK,KAAK,GAAG,EAAE;AACrB,MAAI,IAAI,MAAM;AACd,SAAO,IAAI,KAAK,UAAU,KAAK,CAAC,EAAE,QAAQ,GAAI;AAC9C,SAAO;AACT;AAKA,IAAM,WAAW,oBAAI,IAAI,CAAC,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;AAE/C,IAAM,WAAW,oBAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AAExC,SAAS,eAAe,GAA+B;AACrD,QAAM,QAAsB,CAAC;AAC7B,QAAM,mBAA6B,CAAC;AACpC,MAAI,IAAI,GAAG,MAAM;AAEjB,SAAO,IAAI,IAAI,EAAE,QAAQ;AACvB,UAAM,IAAI,EAAE,CAAC,IAAK,EAAE,IAAI,CAAC,KAAK;AAC9B,QAAI,MAAM,GAAI;AAAE,WAAK;AAAG;AAAO;AAAA,IAAU;AACzC,QAAI,MAAM,IAAI;AAAE;AAAA,IAAO;AACvB,QAAI,MAAM,IAAI;AAAE,YAAM,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC;AAAG,WAAK;AAAG;AAAO;AAAA,IAAU;AAExE,QAAI,SAAS,IAAI,CAAC,GAAG;AACnB,uBAAiB,KAAK,GAAG;AACzB,WAAK;AAAI,aAAO;AAAG;AAAA,IACrB;AACA,QAAI,SAAS,IAAI,CAAC,GAAG;AACnB,WAAK;AAAI,aAAO;AAAG;AAAA,IACrB;AACA,QAAI,MAAM,GAAG;AACX,YAAM,KAAK,EAAE,KAAK,IAAI,IAAK,CAAC;AAC5B,WAAK;AAAI,aAAO;AAAG;AAAA,IACrB;AACA,QAAI,KAAK,KAAK,KAAK,IAAI;AAAE,WAAK;AAAG;AAAO;AAAA,IAAU;AAElD,UAAM,KAAK,EAAE,KAAK,IAAI,OAAO,aAAa,CAAC,EAAE,CAAC;AAC9C,SAAK;AAAG;AAAA,EACV;AACA,SAAO,EAAE,OAAO,iBAAiB;AACnC;AAIA,SAAS,oBAAoB,GAAmC;AAC9D,QAAM,MAA0B,CAAC;AACjC,WAAS,IAAI,GAAG,IAAI,IAAI,EAAE,QAAQ,KAAK;AACrC,QAAI,KAAK,CAAC,UAAU,UAAU,GAAG,CAAC,GAAG,UAAU,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;AACrE,SAAO;AACT;AAIA,SAAS,kBAAkB,OAAqB,OAA2B,IAAyB;AAClG,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC,UAAU,EAAE,CAAC;AAE7C,QAAM,YAAY,MAAM,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI;AAEnD,WAAS,MAAM,KAAqB;AAClC,QAAI,KAAK;AACT,eAAW,CAAC,GAAG,GAAG,KAAK,OAAO;AAAE,UAAI,KAAK,IAAK,MAAK;AAAA,UAAU;AAAA,IAAO;AACpE,WAAO;AAAA,EACT;AAEA,QAAM,QAAoB,CAAC;AAC3B,MAAI,QAAQ,MAAM,MAAM,CAAC,EAAE,GAAG;AAC9B,MAAI,MAAQ,MAAM,CAAC,EAAE;AAErB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,MAAM,MAAM,MAAM,CAAC,EAAE,GAAG;AAC9B,QAAI,QAAQ,OAAO;AAAE,YAAM,KAAK,WAAW,KAAK,OAAO,EAAE,CAAC;AAAG,YAAM;AAAI,cAAQ;AAAA,IAAK;AACpF,WAAO,MAAM,CAAC,EAAE;AAAA,EAClB;AACA,MAAI,IAAK,OAAM,KAAK,WAAW,KAAK,OAAO,EAAE,CAAC;AAC9C,SAAO;AACT;AAEA,SAAS,WAAW,MAAc,SAAiB,IAAuB;AACxE,QAAM,KAAK,GAAG,WAAW,OAAO;AAChC,MAAI,CAAC,GAAI,QAAO,UAAU,IAAI;AAE9B,QAAM,QAAmB,CAAC;AAC1B,QAAM,MAAM,GAAG,QAAQ,CAAC,KAAK;AAC7B,MAAI,MAAM,GAAG,UAAU,UAAU,GAAG,UAAU,GAAG,EAAG,OAAM,OAAO,SAAS,GAAG,UAAU,GAAG,CAAC;AAC3F,MAAI,GAAG,SAAS,EAAG,OAAM,KAAK,OAAO,QAAQ,GAAG,MAAM;AACtD,MAAI,GAAG,KAAa,OAAM,IAAI;AAC9B,MAAI,GAAG,OAAa,OAAM,IAAI;AAC9B,MAAI,GAAG,UAAa,OAAM,IAAI;AAC9B,MAAI,GAAG,UAAa,OAAM,IAAI;AAC9B,MAAI,GAAG,YAAa,OAAM,MAAM;AAChC,MAAI,GAAG,UAAa,OAAM,MAAM;AAEhC,QAAM,MAAM,QAAQ,GAAG,SAAS;AAChC,MAAI,OAAO,QAAQ,SAAU,OAAM,QAAQ;AAE3C,SAAO,UAAU,MAAM,KAAK;AAC9B;AAIA,SAAS,eACP,MAAmB,SAAiB,IAAa,QACL;AAC5C,QAAM,SAAS,KAAK,OAAO,EAAE;AAC7B,MAAI,IAAI,UAAU;AAElB,MAAI,UAA6B;AACjC,QAAM,QAA2E,CAAC;AAGlF,QAAM,WAAW,SAAS;AAE1B,SAAO,IAAI,KAAK,UAAU,KAAK,CAAC,EAAE,QAAQ,QAAQ;AAChD,UAAM,IAAI,KAAK,CAAC;AAEhB,QAAI,WAAW,EAAE,GAAG,KAAK,EAAE,UAAU,UAAU;AAC7C,gBAAU,EAAE;AACZ;AAAA,IACF,WAAW,EAAE,QAAQ,mBAAmB,EAAE,UAAU,UAAU;AAE5D,YAAM,WAAW,EAAE;AACnB,YAAM,YAAY,SAAS,UAAU,IAAI,UAAU,UAAU,UAAU,CAAC,IAAI;AAC5E;AACA,YAAM,SAAS;AAEf,UAAI,WAAW;AACf,aAAO,IAAI,KAAK,UAAU,WAAW,WAAW;AAC9C,YAAI,KAAK,CAAC,EAAE,QAAQ,mBAAmB,KAAK,CAAC,EAAE,UAAU,UAAU;AACjE;AACA;AAEA,iBAAO,IAAI,KAAK,UAAU,KAAK,CAAC,EAAE,QAAQ,SAAU;AAAA,QACtD,WAAW,KAAK,CAAC,EAAE,QAAQ,UAAU;AACnC;AAAA,QACF,OAAO;AACL;AAAA,QACF;AAAA,MACF;AACA,YAAM,KAAK,EAAE,MAAM,UAAU,KAAK,iBAAiB,QAAQ,MAAM,EAAE,CAAC;AAAA,IACtE,WAAW,UAAU,EAAE,GAAG,KAAK,EAAE,UAAU,UAAU;AAEnD,YAAM,WAAW,EAAE;AACnB,YAAM,UAAU,EAAE;AAClB;AACA,YAAM,SAAS;AACf,aAAO,IAAI,KAAK,UAAU,KAAK,CAAC,EAAE,QAAQ,SAAU;AACpD,YAAM,KAAK,EAAE,MAAM,UAAU,KAAK,SAAS,QAAQ,MAAM,EAAE,CAAC;AAAA,IAC9D,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,WAAW,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,MAAM,MAAM,EAAE;AAEjE,QAAM,SAAS,QAAQ,UAAU,IAAI,UAAU,UAAU,SAAS,CAAC,IAAI;AACvE,QAAM,SAAS,QAAQ,UAAU,IAAI,UAAU,UAAU,SAAS,CAAC,IAAI;AAGvE,QAAM,SAAe,CAAC;AAEtB,WAAS,KAAK,GAAG,KAAK,MAAM,QAAQ,MAAM;AACxC,UAAM,IAAI,MAAM,EAAE;AAClB,UAAM,SAAS;AACf,UAAM,KAAK,OAAO;AAAA,MAChB,MAAM,aAAa,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,QAAQ,QAAQ,MAAM;AAAA,MACpF,EAAE,KAAK,KAAK,MAAM,MAAM,UAAU,EAAE,GAAG,KAAK,MAAM,UAAU,IAAI,IAAI,GAAG,IAAI,GAAG,UAAU,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;AAAA,MAC1I,YAAY,EAAE,MAAM;AAAA,IACtB;AACA,WAAO,KAAK,EAAE;AAAA,EAChB;AAGA,QAAM,SAAS,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC;AACnE,QAAM,eAAe,KAAK,IAAI,QAAQ,MAAM;AAG5C,QAAM,WAAW,OAAO,MAAM,OAAK,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,MAAM;AAC7E,MAAI,CAAC,UAAU;AACb,QAAI,MAAM;AACV,eAAW,KAAK,QAAQ;AAAE,QAAE,MAAM,KAAK,MAAM,MAAM,MAAM;AAAG,QAAE,MAAM,MAAM;AAAQ;AAAA,IAAO;AAAA,EAC3F;AAGA,QAAM,cAAwB,IAAI,MAAM,MAAM,EAAE,KAAK,CAAC;AAEtD,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,OAAO,KAAK,EAAE,WAAW,GAAG;AAChC,YAAM,MAAM,OAAO,QAAQ,EAAE,QAAQ;AACrC,UAAI,MAAM,YAAY,EAAE,GAAG,EAAG,aAAY,EAAE,GAAG,IAAI;AAAA,IACrD;AAAA,EACF;AAEA,QAAM,cAAc,YAAY,OAAO,OAAK,MAAM,CAAC,EAAE;AACrD,MAAI,cAAc,GAAG;AACnB,eAAW,KAAK,QAAQ;AACtB,UAAI,EAAE,KAAK,KAAK,EAAE,WAAW,GAAG;AAE9B,YAAI,QAAQ;AACZ,YAAI,cAAc;AAClB,iBAAS,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,MAAM;AAC3D,cAAI,YAAY,EAAE,IAAI,EAAG,UAAS,YAAY,EAAE;AAAA,cAC3C;AAAA,QACP;AACA,YAAI,cAAc,GAAG;AACnB,gBAAM,YAAY,OAAO,QAAQ,EAAE,QAAQ,IAAI;AAC/C,gBAAM,OAAO,YAAY,IAAI,YAAY,cAAc;AACvD,mBAAS,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,MAAM;AAC3D,gBAAI,YAAY,EAAE,MAAM,KAAK,OAAO,EAAG,aAAY,EAAE,IAAI;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,CAAC;AACd,WAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,UAAM,KAAK,OAAO,OAAO,OAAK,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;AACvE,QAAI,GAAG,WAAW,EAAG;AACrB,SAAK,KAAK,SAAS,GAAG;AAAA,MAAI,OACxB,UAAU,EAAE,MAAM,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,IAAI,OAAO,EAAE,MAAM,CAAC;AAAA,IAC3G,CAAC,CAAC;AAAA,EACJ;AACA,MAAI,KAAK,WAAW,EAAG,QAAO,EAAE,MAAM,MAAM,MAAM,EAAE;AAGpD,MAAI;AACJ,QAAM,QAAQ,KAAK,SAAS;AAC5B,MAAI,QAAQ,UAAU,QAAQ,GAAG;AAC/B,UAAM,OAAO,UAAU,UAAU,SAAS,KAAK;AAC/C,gBAAY,aAAa,MAAM,EAAE;AAAA,EACnC;AAEA,QAAM,KAAgB,CAAC;AACvB,MAAI,UAAW,IAAG,gBAAgB;AAClC,QAAM,YAAY,YAAY,KAAK,OAAK,IAAI,CAAC;AAC7C,MAAI,UAAW,IAAG,YAAY;AAC9B,SAAO,EAAE,MAAM,UAAU,MAAM,EAAE,GAAG,MAAM,EAAE;AAC9C;AAUA,SAAS,aACP,GAAe,KAAa,MAAmB,QAAgB,MAC/D,IAAa,QAAwB,QAAgB,QACrD;AACA,MAAI,KAAa,KAAa,KAAK,GAAG,KAAK;AAC3C,MAAI,WAAW;AACf,QAAM,QAAmB,CAAC;AAE1B,QAAM,OAAO,EAAE,UAAU,IAAI,UAAU,UAAU,GAAG,CAAC,IAAI;AACzD,QAAM,KAAM,QAAQ,IAAK;AACzB,MAAI,OAAO,EAAG,OAAM,KAAK;AAAA,WAChB,OAAO,EAAG,OAAM,KAAK;AAE9B,MAAI,QAAQ,mBAAmB,EAAE,UAAU,IAAI;AAG7C,UAAM,UAAU,UAAU,GAAG,CAAC;AAC9B,UAAM,UAAU,UAAU,GAAG,EAAE;AAC/B,SAAM,KAAK,IAAI,GAAG,UAAU,UAAU,GAAG,EAAE,CAAC;AAC5C,SAAM,KAAK,IAAI,GAAG,UAAU,UAAU,GAAG,EAAE,CAAC;AAC5C,eAAW,UAAU,UAAU,GAAG,EAAE;AAEpC,UAAM,OAAO,EAAE,UAAU,KAAK,UAAU,UAAU,GAAG,EAAE,IAAI;AAC3D,QAAI,OAAO,KAAK,QAAQ,GAAG,YAAY,QAAQ;AAC7C,YAAM,KAAK,GAAG,YAAY,OAAO,CAAC;AAClC,UAAI,GAAG,QAAQ,UAAU,GAAG;AAC1B,cAAM,OAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AACpC,cAAM,QAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AACpC,cAAM,MAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AACpC,cAAM,MAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AAAA,MACtC;AACA,UAAI,GAAG,WAAW,GAAG,YAAY,SAAU,OAAM,KAAK,GAAG;AAAA,IAC3D;AAAA,EACF,WAAW,QAAQ,iBAAiB;AAElC,UAAM,EAAE,UAAU,IAAK,UAAU,UAAU,GAAG,CAAC,IAAI,UAAU,UAAU;AACvE,UAAM,EAAE,UAAU,KAAK,UAAU,UAAU,GAAG,CAAC,IAAI,KAAK,MAAM,UAAU,UAAU,EAAE;AACpF,SAAM,EAAE,UAAU,KAAK,KAAK,IAAI,GAAG,UAAU,UAAU,GAAG,EAAE,CAAC,IAAI;AACjE,SAAM,EAAE,UAAU,KAAK,KAAK,IAAI,GAAG,UAAU,UAAU,GAAG,EAAE,CAAC,IAAI;AACjE,eAAW,EAAE,UAAU,KAAK,UAAU,UAAU,GAAG,EAAE,IAAI;AAEzD,UAAM,OAAO,EAAE,UAAU,KAAK,UAAU,UAAU,GAAG,EAAE,IAAI;AAC3D,QAAI,OAAO,KAAK,QAAQ,GAAG,YAAY,QAAQ;AAC7C,YAAM,KAAK,GAAG,YAAY,OAAO,CAAC;AAClC,UAAI,GAAG,QAAQ,UAAU,GAAG;AAC1B,cAAM,OAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AACpC,cAAM,QAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AACpC,cAAM,MAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AACpC,cAAM,MAAQ,SAAS,GAAG,QAAQ,CAAC,CAAC;AAAA,MACtC;AACA,UAAI,GAAG,WAAW,GAAG,YAAY,SAAU,OAAM,KAAK,GAAG;AAAA,IAC3D;AAAA,EACF,OAAO;AAEL,UAAM,KAAK,MAAM,UAAU,UAAU,EAAE;AACvC,UAAM,UAAU,UAAU;AAAA,EAC5B;AAGA,QAAM,QAAoB,CAAC;AAC3B,MAAI,IAAI;AACR,SAAO,IAAI,MAAM;AACf,QAAI,KAAK,CAAC,EAAE,QAAQ,iBAAiB;AAEnC,YAAM,IAAI,OAAO;AAAA,QACf,MAAM;AACJ,gBAAM,MAAM,KAAK,CAAC;AAClB,gBAAM,KAAK,IAAI;AACf,gBAAM,OAAO,IAAI,KAAK,UAAU,KAAK,UAAU,UAAU,IAAI,MAAM,CAAC,IAAI;AACxE,gBAAM,KAAK,GAAG,WAAW,IAAI;AAC7B,cAAI,MAA6B;AACjC,cAAI,MAA0B,CAAC;AAC/B,cAAI,IAAI,IAAI;AACZ,iBAAO,IAAI,QAAQ,KAAK,CAAC,EAAE,QAAQ,IAAI;AACrC,gBAAI,KAAK,CAAC,EAAE,QAAQ,eAAe;AAAE,oBAAM,eAAe,KAAK,CAAC,EAAE,IAAI;AAAG;AAAA,YAAK,WACrE,KAAK,CAAC,EAAE,QAAQ,qBAAqB;AAAE,oBAAM,oBAAoB,KAAK,CAAC,EAAE,IAAI;AAAG;AAAA,YAAK,MACzF;AAAA,UACP;AACA,gBAAM,QAAQ,OAAO,IAAI,MAAM,SAAS,IAAI,kBAAkB,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;AAClG,iBAAO,EAAE,MAAM,UAAU,OAAO,eAAe,EAAE,CAAC,GAAG,MAAM,EAAE;AAAA,QAC/D;AAAA,QACA,EAAE,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,IAAI,EAAE;AAAA,QAChD,aAAa,CAAC;AAAA,MAChB;AACA,YAAM,KAAK,EAAE,IAAI;AACjB,UAAI,EAAE;AAAA,IACR,OAAO;AAAE;AAAA,IAAK;AAAA,EAChB;AAEA,SAAO,EAAE,KAAK,KAAK,IAAI,IAAI,OAAO,UAAU,OAAO,MAAM,SAAS,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;AACzG;AAMA,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,SAAS,GAAI,QAAO;AAC1B,QAAM,IAAK,UAAU,UAAU,GAAG,CAAC;AACnC,QAAM,IAAK,UAAU,UAAU,GAAG,CAAC;AACnC,QAAM,KAAK,UAAU,UAAU,GAAG,CAAC;AACnC,QAAM,KAAK,UAAU,UAAU,GAAG,EAAE;AACpC,QAAM,KAAK,UAAU,UAAU,GAAG,EAAE;AACpC,QAAM,KAAK,UAAU,UAAU,GAAG,EAAE;AACpC,QAAM,KAAK,EAAE,UAAU,KAAK,UAAU,UAAU,GAAG,EAAE,IAAI;AACzD,SAAO;AAAA,IACL,KAAK,OAAO,QAAQ,CAAC;AAAA,IAAI,KAAK,OAAO,QAAQ,CAAC;AAAA,IAC9C,IAAI,OAAO,QAAQ,EAAE;AAAA,IAAI,IAAI,OAAO,QAAQ,EAAE;AAAA,IAC9C,IAAI,OAAO,QAAQ,EAAE;AAAA,IAAI,IAAI,OAAO,QAAQ,EAAE;AAAA,IAC9C,QAAS,KAAK,IAAK,cAAc;AAAA,EACnC;AACF;AAMA,SAAS,IAAI,GAAe,GAAmB;AAC7C,QAAM,IAAI,UAAU,UAAU,GAAG,CAAC;AAClC,SAAO,IAAI,aAAa,IAAI,aAAc;AAC5C;AAEA,SAAS,SAAS,GAAe,GAAmB;AAClD,MAAI,IAAI,IAAI,EAAE,OAAQ,QAAO;AAC7B,UAAS,EAAE,CAAC,KAAK,KAAO,EAAE,IAAI,CAAC,KAAK,IAAK,EAAE,IAAI,CAAC,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,EAAE,YAAY;AAC/F;AAEA,SAAS,SAAS,GAA6D;AAC7E,SAAO,EAAE,MAAM,YAAY,EAAE,IAAI,KAAK,SAAS,IAAI,EAAE,SAAS,OAAO,EAAE,MAAM;AAC/E;AAEA,SAAS,aAAa,MAAc,IAAiC;AACnE,MAAI,QAAQ,KAAK,OAAO,GAAG,YAAY,OAAQ,QAAO;AACtD,QAAM,KAAK,GAAG,YAAY,OAAO,CAAC;AAClC,MAAI,CAAC,GAAG,QAAQ,OAAQ,QAAO;AAC/B,QAAM,IAAI,GAAG,QAAQ,CAAC;AACtB,SAAO,EAAE,MAAM,YAAY,EAAE,IAAI,KAAK,SAAS,IAAI,EAAE,SAAS,OAAO,EAAE,MAAM;AAC/E;AAEA,SAAS,eAAe,IAA8B;AACpD,MAAI,CAAC,GAAI,QAAO,CAAC;AACjB,QAAM,IAAe,CAAC;AACtB,MAAI,GAAG,SAAS,GAAG,UAAU,OAAQ,GAAE,QAAQ,GAAG;AAClD,MAAI,GAAG,cAAc,EAAG,GAAE,cAAc,OAAO,QAAQ,GAAG,WAAW;AACrE,MAAI,GAAG,aAAa,EAAI,GAAE,aAAc,OAAO,QAAQ,GAAG,UAAU;AACpE,MAAI,GAAG,cAAc,KAAK,GAAG,gBAAgB,IAAK,GAAE,aAAa,GAAG,cAAc;AAClF,MAAI,GAAG,SAAS,EAAG,GAAE,WAAW,OAAO,QAAQ,GAAG,MAAM;AACxD,SAAO;AACT;AAMO,IAAM,aAAN,MAAoC;AAAA,EAApC;AACL,SAAS,SAAS;AAAA;AAAA,EAElB,MAAM,OAAO,MAA6C;AACxD,UAAM,SAAS,IAAI,eAAe;AAClC,UAAM,QAAkB,CAAC;AAEzB,QAAI;AACF,UAAI,CAAC,UAAU,OAAO,IAAI,EAAG,QAAO,KAAK,6BAA6B;AACtE,YAAM,UAAU,UAAU,SAAS,IAAI;AAGvC,YAAM,KAAK,QAAQ,IAAI,YAAY;AACnC,YAAM,EAAE,YAAY,UAAU,IAAI,KAAK,gBAAgB,EAAE,IAAI,EAAE,YAAY,MAAM,WAAW,MAAM;AAClG,UAAI,UAAW,QAAO,KAAK,oGAAyB;AAGpD,YAAM,QAAQ,QAAQ,IAAI,SAAS;AACnC,UAAI,KAAc,EAAE,WAAW,CAAC,GAAG,YAAY,CAAC,GAAG,YAAY,CAAC,GAAG,aAAa,CAAC,EAAE;AACnF,UAAI,OAAO;AACT,aAAK,OAAO,MAAM,MAAM,aAAa,OAAO,UAAU,GAAG,IAAI,aAAa;AAAA,MAC5E;AAGA,YAAM,aAA4B,CAAC;AACnC,UAAI,WAAqB;AAEzB,eAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,cAAM,MAAM,QAAQ,IAAI,mBAAmB,CAAC,EAAE,KAAK,QAAQ,IAAI,UAAU,CAAC,EAAE;AAC5E,YAAI,CAAC,KAAK;AACR,cAAI,MAAM,GAAG;AACX,kBAAM,KAAK,gBAAgB,OAAO;AAClC,gBAAI,IAAI;AACN,oBAAMC,KAAI,UAAU,IAAI,YAAY,IAAI,MAAM;AAC9C,yBAAW,KAAK,GAAGA,GAAE,OAAO;AAC5B,kBAAIA,GAAE,SAAU,YAAWA,GAAE;AAAA,YAC/B;AAAA,UACF;AACA;AAAA,QACF;AACA,cAAM,IAAI,OAAO;AAAA,UACf,MAAM,UAAU,KAAK,YAAY,IAAI,MAAM;AAAA,UAC3C,EAAE,SAAS,CAAC,GAAG,UAAU,OAAU;AAAA,UACnC,UAAU,CAAC;AAAA,QACb;AACA,mBAAW,KAAK,GAAG,EAAE,OAAO;AAC5B,YAAI,EAAE,SAAU,YAAW,EAAE;AAAA,MAC/B;AAEA,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,YAAM,UAAU,WAAW,SAAS,IAAI,aAAa,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAChF,aAAO,QAAQ,UAAU,CAAC,GAAG,CAAC,WAAW,SAAS,QAAQ,CAAC,CAAC,GAAG,KAAK;AAAA,IACtE,SAAS,GAAQ;AACf,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,aAAO,KAAK,qBAAqB,GAAG,WAAW,OAAO,CAAC,CAAC,IAAI,KAAK;AAAA,IACnE;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,SAA0D;AACjF,aAAW,CAAC,GAAG,CAAC,KAAK;AACnB,QAAI,EAAE,SAAS,SAAS,KAAK,CAAC,EAAE,SAAS,QAAQ,KAAK,CAAC,EAAE,SAAS,MAAM,EAAG,QAAO;AACpF,SAAO;AACT;AAEA,SAAS,gBAAgB,IAAI,WAAW,CAAC;;;AC1xBlC,IAAM,cAAN,MAAqC;AAAA,EAArC;AACL,SAAS,SAAS;AAAA;AAAA,EAElB,MAAM,OAAO,MAA6C;AACxD,UAAM,SAAS,IAAI,eAAe;AAClC,UAAM,QAAkB,CAAC;AAEzB,QAAI;AACF,YAAM,QAAQ,MAAM,WAAW,MAAM,IAAI;AAEzC,YAAM,SAAS,MAAM,IAAI,mBAAmB;AAC5C,UAAI,CAAC,OAAQ,QAAO,KAAK,mCAAmC;AAE5D,YAAM,UAAU,MAAM,IAAI,8BAA8B;AACxD,YAAM,UAAU,UAAU,MAAM,UAAU,QAAQ,OAAO,OAAO,CAAC,IAAI,oBAAI,IAAoB;AAE7F,YAAMC,WAAU,MAAM,IAAI,mBAAmB;AAC7C,UAAI,OAAgB,CAAC;AACrB,UAAIA,UAAS;AACX,YAAI;AACF,iBAAO,MAAM,eAAe,QAAQ,OAAOA,QAAO,CAAC;AAAA,QACrD,QAAQ;AAAA,QAER;AAAA,MACF;AAGA,YAAM,SAAS,MAAM,IAAI,oBAAoB;AAC7C,UAAI,SAAiB,oBAAI,IAAI;AAC7B,UAAI,QAAQ;AACV,YAAI;AACF,mBAAS,MAAM,eAAe,QAAQ,OAAO,MAAM,CAAC;AAAA,QACtD,QAAQ;AAAA,QAAkB;AAAA,MAC5B;AAEA,YAAM,SAAS,QAAQ,OAAO,MAAM;AACpC,YAAM,SAAc,MAAM,OAAO,YAAY,MAAM;AAEnD,YAAM,OAAO,QAAQ,MAAM;AAC3B,YAAM,OAAOC,aAAY,IAAI,KAAK,EAAE,GAAG,GAAG;AAC1C,YAAM,WAAW,gBAAgB,IAAI;AAErC,YAAM,SAAiB,EAAE,SAAS,OAAO,QAAQ,QAAQ,MAAM;AAE/D,YAAM,OAAsB,OAAO;AAAA,QACjC;AAAA,QACA,CAAC,OAAY,cAAc,IAAI,MAAM;AAAA,QACrC,MAAM,UAAU,CAAC,UAAU,0CAAY,CAAC,CAAC;AAAA,QACzC;AAAA,MACF;AAGA,YAAM,cAAc,MAAMC,oBAAmB,UAAU,MAAM,SAAS,OAAO,MAAM;AACnF,YAAM,cAAc,MAAMA,oBAAmB,UAAU,MAAM,SAAS,OAAO,MAAM;AAEnF,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,YAAM,QAAQ;AAAA,QACZ,KAAK,OAAO,OAAO;AAAA,QACnB;AAAA,QACA,EAAE,QAAQ,aAAa,QAAQ,YAAY;AAAA,MAC7C;AACA,aAAO,QAAQ,UAAU,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK;AAAA,IAChD,SAAS,GAAQ;AACf,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,aAAO,KAAK,sBAAsB,GAAG,WAAW,OAAO,CAAC,CAAC,IAAI,KAAK;AAAA,IACpE;AAAA,EACF;AACF;AAiBA,SAASC,OAAM,GAAe;AAAE,SAAO,KAAK,OAAO,CAAC,IAAI,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;AAAG;AAEpF,eAAe,UAAU,KAA2C;AAClE,QAAM,MAAM,oBAAI,IAAoB;AACpC,MAAI;AACF,UAAM,MAAW,MAAM,OAAO,YAAY,GAAG;AAC7C,eAAW,OAAOA,OAAM,KAAK,gBAAgB,CAAC,GAAG,YAAY,GAAG;AAC9D,YAAM,IAAI,KAAK,SAAS,CAAC;AACzB,UAAI,EAAE,MAAM,EAAE,OAAQ,KAAI,IAAI,EAAE,IAAI,EAAE,MAAM;AAAA,IAC9C;AAAA,EACF,QAAQ;AAAA,EAAe;AACvB,SAAO;AACT;AAEA,eAAe,eAAe,KAA+B;AAC3D,MAAI;AACF,UAAM,MAAW,MAAM,OAAO,YAAY,GAAG;AAC7C,UAAM,IAAI,MAAM,mBAAmB,IAAI,CAAC,KAAK,KAAK,iBAAiB,CAAC,KAAK,CAAC;AAC1E,WAAO;AAAA,MACL,OAAU,IAAI,UAAU,IAAI,CAAC,GAAG,SAAS;AAAA,MACzC,QAAU,IAAI,YAAY,IAAI,CAAC,GAAG,SAAS;AAAA,MAC3C,SAAU,IAAI,YAAY,IAAI,CAAC,GAAG,SAAS;AAAA,MAC3C,SAAU,IAAI,iBAAiB,IAAI,CAAC,GAAG,SAAS;AAAA,MAChD,UAAU,IAAI,kBAAkB,IAAI,CAAC,GAAG,SAAS;AAAA,IACnD;AAAA,EACF,QAAQ;AAAE,WAAO,CAAC;AAAA,EAAG;AACvB;AAEA,eAAe,eAAe,KAA8B;AAC1D,QAAM,MAAc,oBAAI,IAAI;AAC5B,MAAI;AACF,UAAM,MAAW,MAAM,OAAO,YAAY,GAAG;AAC7C,UAAM,OAAO,MAAM,aAAa,IAAI,CAAC,KAAK,KAAK,YAAY,CAAC,KAAK;AAGjE,UAAM,SAAS,oBAAI,IAA8D;AACjF,eAAW,OAAOA,OAAM,OAAO,eAAe,KAAK,MAAM,WAAW,GAAG;AACrE,YAAM,QAAQ,OAAO,KAAK,QAAQ,iBAAiB,KAAK,KAAK,OAAO,iBAAiB,CAAC;AACtF,YAAM,SAAS,oBAAI,IAAiD;AACpE,iBAAW,OAAOA,OAAM,MAAM,OAAO,KAAK,KAAK,GAAG,GAAG;AACnD,cAAM,OAAO,OAAO,KAAK,QAAQ,QAAQ,KAAK,KAAK,OAAO,QAAQ,CAAC;AACnE,cAAM,UAAU,MAAM,UAAU,IAAI,CAAC,GAAG,SAAS,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC;AAC7E,cAAM,MAAM,UAAU,OAAO,KAAK,SAAS,OAAO;AAClD,eAAO,IAAI,MAAM,EAAE,KAAK,WAAW,QAAQ,SAAS,CAAC;AAAA,MACvD;AACA,aAAO,IAAI,OAAO,MAAM;AAAA,IAC1B;AAGA,eAAW,OAAOA,OAAM,OAAO,OAAO,KAAK,MAAM,GAAG,GAAG;AACrD,YAAM,QAAQ,OAAO,KAAK,QAAQ,SAAS,KAAK,KAAK,OAAO,SAAS,CAAC;AACtE,YAAM,SAAS,MAAM,iBAAiB,IAAI,CAAC,GAAG,SAAS,KAAK,gBAAgB,CAAC,GAAG,SAAS,CAAC;AAC1F,YAAM,QAAQ,OAAO,SAAS,OAAO,KAAK,QAAQ,OAAO,CAAC;AAC1D,YAAM,SAAS,OAAO,IAAI,KAAK,KAAK,oBAAI,IAAI;AAC5C,UAAI,IAAI,OAAO,EAAE,OAAO,CAAC;AAAA,IAC3B;AAAA,EACF,QAAQ;AAAA,EAAkB;AAC1B,SAAO;AACT;AAEA,SAAS,QAAQ,KAAe;AAC9B,SAAO,MAAM,YAAY,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,GAAG,OAAO,CAAC,KAAK;AACvF;AAEA,SAASF,aAAY,MAA4B;AAC/C,MAAI;AACF,UAAM,KAAK,OAAO,UAAU,IAAI,CAAC,KAAK,MAAM,SAAS,CAAC;AACtD,QAAI,CAAC,GAAI,QAAO;AAChB,UAAM,KAAM,KAAK,QAAQ,IAAI,CAAC,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG;AACzD,UAAM,MAAM,KAAK,SAAS,IAAI,CAAC,GAAG,SAAS,IAAI,QAAQ,CAAC,GAAG;AAC3D,QAAI,CAAC,GAAI,QAAO;AAChB,WAAO;AAAA,MACL,KAAQ,OAAO,QAAQ,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,CAAC;AAAA,MACzD,KAAQ,OAAO,QAAQ,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,CAAC;AAAA,MACzD,IAAQ,OAAO,QAAQ,OAAO,MAAM,OAAO,KAAK,KAAK,OAAO,IAAI,CAAC;AAAA,MACjE,IAAQ,OAAO,QAAQ,OAAO,MAAM,UAAU,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,MACvE,IAAQ,OAAO,QAAQ,OAAO,MAAM,QAAQ,KAAK,KAAK,QAAQ,IAAI,CAAC;AAAA,MACnE,IAAQ,OAAO,QAAQ,OAAO,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,CAAC;AAAA,MACrE,SAAS,GAAG,UAAU,KAAK,GAAG,YAAY,cAAc,cAAc;AAAA,IACxE;AAAA,EACF,QAAQ;AAAE,WAAO;AAAA,EAAM;AACzB;AAEA,SAAS,gBAAgB,MAA0C;AACjE,QAAM,QAAQE,OAAM,OAAO,KAAK,KAAK,MAAM,CAAC;AAC5C,QAAM,SAASA,OAAM,OAAO,OAAO,KAAK,MAAM,GAAG;AAEjD,MAAI,OAAO,WAAW,EAAG,QAAO,MAAM,IAAI,CAAC,OAAY,EAAE,MAAM,QAAQ,MAAM,EAAE,EAAE;AACjF,MAAI,MAAM,WAAW,EAAG,QAAO,OAAO,IAAI,CAAC,OAAY,EAAE,MAAM,SAAS,MAAM,EAAE,EAAE;AAGlF,QAAM,aAAa,OAAO,aAAa;AACvC,MAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,UAAM,QAAuC,CAAC;AAC9C,QAAI,KAAK,GAAG,KAAK;AACjB,eAAW,OAAO,YAAY;AAC5B,WAAK,QAAQ,SAAS,QAAQ,QAAQ,KAAK,MAAM,QAAQ;AACvD,cAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,MAAM,IAAI,EAAE,CAAC;AAAA,MAChD,YAAY,QAAQ,WAAW,QAAQ,UAAU,KAAK,OAAO,QAAQ;AACnE,cAAM,KAAK,EAAE,MAAM,SAAS,MAAM,OAAO,IAAI,EAAE,CAAC;AAAA,MAClD;AAAA,IACF;AACA,WAAO,KAAK,MAAM,OAAQ,OAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,MAAM,IAAI,EAAE,CAAC;AACxE,WAAO,KAAK,OAAO,OAAQ,OAAM,KAAK,EAAE,MAAM,SAAS,MAAM,OAAO,IAAI,EAAE,CAAC;AAC3E,WAAO;AAAA,EACT;AAGA,SAAO;AAAA,IACL,GAAG,MAAM,IAAI,CAAC,OAAY,EAAE,MAAM,QAAQ,MAAM,EAAE,EAAE;AAAA,IACpD,GAAG,OAAO,IAAI,CAAC,OAAY,EAAE,MAAM,SAAS,MAAM,EAAE,EAAE;AAAA,EACxD;AACF;AAIA,eAAeD,oBACb,MACA,MACA,SACA,OACA,KACiC;AACjC,MAAI;AACF,UAAM,KAAK,OAAO,UAAU,IAAI,CAAC,KAAK,MAAM,SAAS,CAAC;AACtD,QAAI,CAAC,GAAI,QAAO;AAEhB,UAAM,SAAS,SAAS,WAAW,sBAAsB;AACzD,UAAM,OAAOC,OAAM,KAAK,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,EAAE,CAAC,CAAC;AACjE,QAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,UAAM,MAAM,KAAK,CAAC,GAAG,QAAQ,MAAM,KAAK,KAAK,CAAC,GAAG,QAAQ,MAAM,KAAK,KAAK,CAAC,GAAG,OAAO;AACpF,QAAI,CAAC,IAAK,QAAO;AAEjB,UAAM,SAAS,QAAQ,IAAI,GAAG;AAC9B,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,WAAW,OAAO,WAAW,GAAG,IAAI,OAAO,MAAM,CAAC,IAAI,QAAQ,MAAM;AAC1E,UAAM,WAAW,MAAM,IAAI,QAAQ;AACnC,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,SAAS,QAAQ,OAAO,QAAQ;AACtC,UAAM,MAAW,MAAM,OAAO,YAAY,MAAM;AAEhD,UAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,UAAM,OAAO,MAAM,OAAO,IAAI,CAAC,KAAK,MAAM,QAAQ,QAAQ,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK;AAE7E,UAAM,QAAQA,OAAM,OAAO,KAAK,KAAK,MAAM,CAAC;AAC5C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,MAAM,IAAI,CAAC,MAAWC,YAAW,GAAG,GAAG,CAAC;AAAA,EACjD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,cACP,IACA,KACa;AACb,MAAI,GAAG,SAAS,SAAS;AACvB,UAAM,EAAE,MAAM,IAAI,IAAI,OAAO;AAAA,MAC3B,GAAG;AAAA,MACH,CAAC,MAAMC,YAAW,GAAU,GAAG;AAAA,MAC/B,CAAC,MAAMC,kBAAiB,CAAQ;AAAA,MAChC,CAAC,MAAMC,gBAAe,CAAQ;AAAA,MAC9B,CAAC,MAAMC,gBAAe,CAAQ;AAAA,MAC9B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAOJ,YAAW,GAAG,MAAM,GAAG;AAChC;AAEA,SAASA,YACP,GACA,KACU;AACV,QAAM,MAAM,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC;AAClC,QAAM,WAAW,MAAM,MAAM,IAAI,CAAC,GAAG,QAAQ,OAAO,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO;AACpF,QAAM,YAAY,MAAM,UAAU,IAAI,CAAC,GAAG,QAAQ,OAAO,KAAK,MAAM,UAAU,IAAI,CAAC,GAAG,OAAO,OAAO;AAEpG,QAAM,QAAmB;AAAA,IACvB,OAAO,UAAU,QAAQ;AAAA,IACzB,SAAS,aAAa,SAAS;AAAA,EACjC;AAGA,QAAM,QAAQ,MAAM,SAAS,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC;AACrD,MAAI,OAAO;AACT,UAAM,WAAW,QAAQ,QAAQ,IAAI,CAAC,GAAG,SAAS,OAAO,OAAO,CAAC,GAAG,SAAS,CAAC;AAC9E,UAAM,YAAY,QAAQ,SAAS,IAAI,CAAC,GAAG,SAAS,OAAO,QAAQ,CAAC,GAAG,SAAS,CAAC;AACjF,UAAM,OAAO,OAAO,WAAW,OAAO,KAAK,UAAU,OAAO,CAAC;AAC7D,UAAM,QAAQ,OAAO,YAAY,OAAO,KAAK,WAAW,OAAO,CAAC;AAEhE,UAAM,SAAS;AACf,UAAM,WAAW,IAAI,OAAO,IAAI,KAAK;AACrC,QAAI,UAAU;AACZ,YAAM,UAAU,SAAS,OAAO,IAAI,IAAI,KAAK,SAAS,OAAO,IAAI,CAAC;AAClE,YAAM,UAAU,SAAS,aAAa;AAAA,IACxC,OAAO;AAEL,YAAM,UAAU,SAAS;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,OAAOD,OAAM,IAAI,KAAK,KAAK,GAAG,CAAC;AACrC,QAAM,OAA+B,IAAI,OAAO;AAAA,IAC9C;AAAA,IACA,CAAC,QAAa,iBAAiB,KAAK,GAAG;AAAA,IACvC,MAAM,UAAU,EAAE;AAAA,IAClB;AAAA,EACF;AAEA,SAAO,UAAU,KAAK,OAAO,OAAO,GAAuB,KAAK;AAClE;AAEA,SAAS,iBAAiB,KAAU,KAAiC;AAEnE,QAAM,UAAU,MAAM,WAAW,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC;AAC3D,MAAI,SAAS;AACX,UAAM,MAAM,cAAc,SAAS,GAAG;AACtC,QAAI,IAAK,QAAO;AAAA,EAClB;AACA,SAAO,UAAU,KAAK,GAAG;AAC3B;AAEA,SAAS,cAAc,SAAc,KAA6B;AAChE,MAAI;AACF,UAAM,SAAS,UAAU,WAAW,IAAI,CAAC,KAAK,SAAS,SAAS,CAAC;AACjE,UAAM,SAAS,UAAU,WAAW,IAAI,CAAC,KAAK,SAAS,SAAS,CAAC;AACjE,UAAM,YAAY,UAAU;AAC5B,QAAI,CAAC,UAAW,QAAO;AAGvB,UAAM,SAAS,YAAY,WAAW,IAAI,CAAC,GAAG,SAAS,WAAW,SAAS,CAAC,GAAG,SAAS,CAAC;AACzF,UAAM,KAAK,OAAO,QAAQ,MAAM,CAAC;AACjC,UAAM,KAAK,OAAO,QAAQ,MAAM,CAAC;AACjC,UAAM,MAAM,OAAO,QAAQ,EAAE;AAC7B,UAAM,MAAM,OAAO,QAAQ,EAAE;AAG7B,UAAM,QAAQ,YAAY,UAAU,IAAI,CAAC,GAAG,SAAS,WAAW,QAAQ,CAAC,GAAG,SAAS,CAAC;AACtF,UAAM,MAAM,OAAO,SAAS,OAAO,QAAQ;AAG3C,UAAM,UAAU,YAAY,WAAW,IAAI,CAAC,KAAK,WAAW,UAAU,CAAC;AACvE,UAAM,cAAc,UAAU,eAAe,IAAI,CAAC,KAAK,SAAS,cAAc,CAAC;AAC/E,UAAM,MAAM,cAAc,SAAS,IAAI,CAAC,KAAK,aAAa,MAAM,CAAC;AACjE,UAAM,WAAW,MAAM,cAAc,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC;AAChE,UAAM,OAAO,WAAW,QAAQ,IAAI,CAAC,GAAG,SAAS,UAAU,OAAO,CAAC,GAAG,SAAS,CAAC;AAChF,UAAM,MAAM,OAAO,SAAS,KAAK,MAAM;AAEvC,QAAI,CAAC,IAAK,QAAO;AAEjB,UAAM,SAAS,IAAI,QAAQ,IAAI,GAAG;AAClC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,WAAW,OAAO,WAAW,GAAG,IAAI,OAAO,MAAM,CAAC,IAAI,QAAQ,MAAM;AAC1E,UAAM,WAAW,IAAI,MAAM,IAAI,QAAQ;AACvC,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,MAAM,OAAO,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY,KAAK;AACtD,UAAM,UAA2C;AAAA,MAC/C,KAAK;AAAA,MAAa,KAAK;AAAA,MAAc,MAAM;AAAA,MAC3C,KAAK;AAAA,MAAa,KAAK;AAAA,IACzB;AACA,UAAM,OAAO,QAAQ,GAAG,KAAK;AAE7B,WAAO,SAAS,QAAQ,aAAa,QAAQ,GAAG,MAAM,KAAK,KAAK,OAAO,MAAS;AAAA,EAClF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,UAAU,KAAU,KAAuB;AAClD,QAAM,MAAM,MAAM,OAAO,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC;AAErD,QAAM,SAAS,MAAM,MAAM,IAAI,CAAC,GAAG,SAAS,KAAK,KAAK,CAAC,GAAG,SAAS,CAAC;AACpE,QAAM,QAAS,SAAS,OAAO,KAAK,QAAQ;AAE5C,QAAM,YAAY,MAAM,SAAS,IAAI,CAAC,GAAG,SAAS,KAAK,QAAQ,CAAC,GAAG,SAAS,CAAC;AAC7E,QAAM,WAAY,YAAY,OAAO,KAAK,WAAW;AAErD,QAAM,WAAW,MAAM,UAAU,IAAI,CAAC,GAAG,SAAS,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC;AAC9E,QAAM,WAAW,WAAW,SAAS,KAAK,UAAU,SAC/C,WAAW,SAAS,KAAK,UAAU,SACnC,WAAW,YAAY,KAAK,UAAU;AAE3C,QAAM,WAAW,MAAM,KAAK,IAAI,CAAC,GAAG,QAAQ,OAAO,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,OAAO;AAGlF,QAAM,UAAU,MAAM,OAAO,IAAI,CAAC,GAAG,SAAS,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;AACvE,QAAM,QAAQ,QAAQ,UAAU,QAAQ,KAAK,SAAS,IAAI;AAG1D,QAAM,eAAe,MAAM,aAAa,IAAI,CAAC,GAAG,QAAQ,OAAO,KAAK,MAAM,aAAa,IAAI,CAAC,GAAG,OAAO;AAGtG,QAAM,QAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC;AAC7C,QAAM,SAAS,SAAS,SAAS,OAAO,QAAQ,OAAO,KAAK,OAAO,OAAO,OAAO,SAAS;AAC1F,QAAM,QAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC;AAC7C,QAAM,WAAW,SAAS,SAAS,OAAO,QAAQ,OAAO,KAAK,OAAO,OAAO,OAAO,SAAS;AAC5F,QAAM,QAAQ,MAAM,UAAU,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC;AACvD,QAAM,WAAW,SAAS,SAAS,OAAO,QAAQ,OAAO,KAAK,OAAO,OAAO,OAAO,SAAS;AAE5F,QAAM,QAAmB;AAAA,IACvB,GAAO,UAAU;AAAA,IACjB,GAAO,YAAY;AAAA,IACnB,GAAO,YAAY,aAAa,SAAS,OAAO;AAAA,IAChD,GAAO,YAAY;AAAA,IACnB,KAAO,iBAAiB,iBAAiB;AAAA,IACzC,KAAO,iBAAiB,eAAe;AAAA,IACvC,IAAO,QAAQ,OAAO,WAAW,OAAO,KAAK,CAAC,IAAI;AAAA,IAClD,OAAO,QAAQ,QAAQ;AAAA,IACvB,MAAO,WAAW,SAAS,QAAQ,IAAI;AAAA,IACvC,IAAO;AAAA,EACT;AAGA,QAAM,UAAU,MAAM,WAAW,IAAI,CAAC,GAAG,SAAS,KAAK,UAAU,CAAC,GAAG;AACrE,QAAM,YAAY,MAAM,aAAa,IAAI,CAAC;AAE1C,QAAM,YAAYA,OAAM,MAAM,KAAK,KAAK,KAAK,CAAC;AAC9C,QAAM,UAAU,UAAU,IAAI,CAAC,MAAW,OAAO,MAAM,WAAW,IAAI,GAAG,KAAK,GAAG,SAAS,EAAE,EAAE,KAAK,EAAE;AAGrG,MAAI,WAAW;AACb,UAAM,WAAW,OAAO,cAAc,WAAW,YAAY,WAAW,SAAS;AACjF,QAAI,SAAS,KAAK,EAAE,YAAY,MAAM,QAAQ;AAC5C,YAAM,UAAuB,EAAE,KAAK,WAAW,QAAQ,UAAU;AACjE,aAAO,EAAE,KAAK,QAAQ,OAAO,MAAM,CAAC,OAAO,EAAE;AAAA,IAC/C;AAAA,EACF;AAEA,SAAO,UAAU,SAAS,KAAK;AACjC;AAEA,SAASE,YACP,KACA,KACU;AAEV,QAAM,QAAQ,MAAM,SAAS,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC;AAC3D,QAAM,cAAc,QAAQ,WAAW,IAAI,CAAC,GAAG,SAAS,OAAO,UAAU,CAAC,GAAG,SAAS,CAAC;AAEvF,QAAM,OAAkB;AAAA,IACtB,UAAY,cAAc,YAAY,MAAM,OAAO;AAAA,IACnD,SAAY,cAAc,WAAW,MAAM,OAAO;AAAA,IAClD,UAAY,cAAc,eAAe,MAAM,OAAO,cAAc,YAAY,MAAM,OAAO;AAAA,IAC7F,SAAY,cAAc,cAAc,MAAM,OAAO,cAAc,WAAW,MAAM,OAAO;AAAA,IAC3F,YAAY,cAAc,WAAW,MAAM,OAAO;AAAA,IAClD,YAAY,cAAc,WAAW,MAAM,OAAO;AAAA,EACpD;AAGA,QAAM,aAAa,QAAQ,cAAc,IAAI,CAAC,KAAK,OAAO,aAAa,CAAC;AACxE,MAAI,gBAAgB;AACpB,MAAI,YAAY;AACd,UAAM,MAAM,aAAa,OAAO,IAAI,CAAC,GAAG,SAAS,YAAY,MAAM,CAAC,GAAG;AACvE,QAAI,KAAK;AACP,sBAAgB;AAAA,QACd,MAAM,OAAO,KAAK,KAAK;AAAA,QACvB,OAAO,MAAM,MAAM,KAAK,KAAK,MAAM,CAAC;AAAA,QACpC,MAAM,SAAS,KAAK,KAAK;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAuB,EAAE,MAAM,cAAc;AAEnD,QAAM,SAASF,OAAM,MAAM,MAAM,KAAK,KAAK,EAAE;AAO7C,QAAM,UAAuB,OAAO,IAAI,CAAC,QAAa;AACpD,UAAM,UAAUA,OAAM,MAAM,MAAM,KAAK,KAAK,EAAE;AAC9C,WAAO,QAAQ,IAAI,CAAC,SAAuB;AACzC,YAAM,OAAO,OAAO,QAAQ,IAAI,CAAC,KAAK,CAAC;AACvC,YAAM,WAAW,OAAO,OAAO,YAAY,IAAI,CAAC,GAAG,QAAQ,OAAO,KAAK,CAAC;AACxE,YAAM,aAAa,OAAO,UAAU,IAAI,CAAC;AACzC,YAAM,YAAY,YAAY,QAAQ,OAAO,KAAK,YAAY,OAAO;AACrE,YAAM,gBAAgB,cAAc;AAEpC,YAAM,iBAAiB,cAAc,QAAQ,CAAC;AAC9C,aAAO,EAAE,MAAM,UAAU,eAAe,eAAe;AAAA,IACzD,CAAC;AAAA,EACH,CAAC;AAID,QAAM,QAA6B,oBAAI,IAAI;AAC3C,WAAS,KAAK,GAAG,KAAK,QAAQ,QAAQ,MAAM;AAC1C,QAAI,UAAU;AACd,aAAS,KAAK,GAAG,KAAK,QAAQ,EAAE,EAAE,QAAQ,MAAM;AAC9C,YAAM,KAAK,QAAQ,EAAE,EAAE,EAAE;AACzB,UAAI,GAAG,eAAe;AACpB,YAAI,OAAO;AACX,iBAAS,KAAK,KAAK,GAAG,KAAK,QAAQ,QAAQ,MAAM;AAE/C,cAAI,MAAM;AACV,cAAI,QAAQ;AACZ,qBAAW,MAAM,QAAQ,EAAE,GAAG;AAC5B,gBAAI,QAAQ,WAAW,GAAG,gBAAgB;AACxC;AACA,sBAAQ;AACR;AAAA,YACF;AACA,mBAAO,GAAG;AAAA,UACZ;AACA,cAAI,CAAC,MAAO;AAAA,QACd;AACA,cAAM,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI;AAAA,MAC/B;AACA,iBAAW,GAAG;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,WAAW,QAAQ,IAAI,CAAC,QAAQ,OAAO;AAE3C,UAAM,MAAM,OAAO,EAAE;AACrB,UAAM,OAAO,MAAM,QAAQ,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC;AACxD,UAAM,cAAc,OAAO,aAAa,IAAI,CAAC,KAAK,QAAQ,MAAM,YAAY,CAAC,KAAK;AAClF,QAAI,OAAO,KAAK,YAAa,WAAU,YAAY;AAEnD,UAAM,YAAwB,CAAC;AAC/B,aAAS,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM;AACzC,YAAM,KAAK,OAAO,EAAE;AAEpB,UAAI,GAAG,eAAgB;AAEvB,YAAM,OAAO,GAAG;AAChB,YAAM,OAAO,OAAO,QAAQ,IAAI,CAAC,KAAK,CAAC;AAGvC,YAAM,SAAS,OAAO,OAAO,IAAI,CAAC,GAAG,SAAS,CAAC;AAC/C,YAAM,KAAK,QAAQ,SAAS,QAAQ,KAAK,QAAQ,IAAI;AAGrD,YAAM,YAAY,OAAO,aAAa,IAAI,CAAC,KAAK,MAAM,YAAY,CAAC;AACnE,YAAM,KAAgB,EAAE,IAAI,UAAU,eAAe,OAAU;AAE/D,UAAI,WAAW;AACb,cAAM,OAA0D;AAAA,UAC9D,CAAC,OAAO,KAAK;AAAA,UAAG,CAAC,UAAU,KAAK;AAAA,UAAG,CAAC,QAAQ,MAAM;AAAA,UAAG,CAAC,SAAS,OAAO;AAAA,QACxE;AACA,mBAAW,CAAC,QAAQ,OAAO,KAAK,MAAM;AACpC,gBAAM,MAAM,YAAY,OAAO,MAAM,IAAI,CAAC,GAAG,SAAS,YAAY,MAAM,IAAI,CAAC,GAAG;AAChF,cAAI,KAAK;AACP,eAAG,OAAO,IAAI;AAAA,cACZ,MAAM,OAAO,KAAK,KAAK;AAAA,cACvB,OAAO,MAAM,MAAM,KAAK,KAAK,MAAM,CAAC;AAAA,cACpC,MAAM,SAAS,KAAK,KAAK;AAAA,YAC3B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,YAAM,SAAS,OAAO,UAAU,IAAI,CAAC,GAAG,SAAS,MAAM,SAAS,CAAC,GAAG,SAAS,CAAC;AAC9E,YAAM,QAAQ,SAAS,OAAO,KAAK,QAAQ;AAC3C,UAAI,OAAO;AACT,cAAM,QAA+C,EAAE,KAAK,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAChG,WAAG,KAAK,MAAM,KAAK;AAAA,MACrB;AAEA,YAAM,KAAK,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK;AAEvC,YAAM,QAAQA,OAAM,OAAO,KAAK,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,MAAWC,YAAW,GAAG,GAAG,CAAC;AAChF,gBAAU,KAAK;AAAA,QACb,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAAA,QACtD,EAAE,IAAI,GAAG,UAAU,IAAI,OAAO,GAAG;AAAA,MACnC,CAAC;AAAA,IACH;AACA,WAAO,SAAS,SAAS;AAAA,EAC3B,CAAC;AACD,SAAO,UAAU,UAAU,SAAS;AACtC;AAEA,SAASE,kBAAiB,KAAoB;AAC5C,QAAM,SAASH,OAAM,MAAM,MAAM,KAAK,KAAK,EAAE;AAC7C,QAAM,WAAW,OAAO,IAAI,CAAC,QAAa;AACxC,UAAM,UAAUA,OAAM,MAAM,MAAM,KAAK,KAAK,EAAE;AAC9C,WAAO,SAAS,QAAQ,IAAI,CAAC,MAAW,UAAU,CAAC,UAAU,CAAC,UAAUM,UAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,EAC3F,CAAC;AACD,SAAO,UAAU,QAAQ;AAC3B;AAEA,SAASF,gBAAe,KAAoB;AAC1C,SAAO,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,UAAUG,WAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF;AAEA,SAASF,gBAAe,KAAoB;AAC1C,SAAO,UAAU,CAAC,UAAUE,WAAU,GAAG,CAAC,CAAC,CAAC;AAC9C;AAEA,SAASD,UAAS,MAAmB;AACnC,SAAON,OAAM,OAAO,KAAK,KAAK,MAAM,CAAC,EAAE;AAAA,IAAI,CAAC,MAC1CA,OAAM,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE;AAAA,MAAI,CAAC,MAC7BA,OAAM,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,MAAW,OAAO,MAAM,WAAW,IAAI,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE;AAAA,IAC3F,EAAE,KAAK,EAAE;AAAA,EACX,EAAE,KAAK,GAAG;AACZ;AAEA,SAASO,WAAU,KAAkB;AACnC,SAAOP,OAAM,MAAM,MAAM,KAAK,KAAK,EAAE,EAAE;AAAA,IAAI,CAAC,QAC1CA,OAAM,MAAM,MAAM,KAAK,KAAK,EAAE,EAAE,IAAI,CAAC,MAAWM,UAAS,CAAC,CAAC,EAAE,KAAK,GAAI;AAAA,EACxE,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,aAAa,OAAmD;AACvE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,IAAI,MAAM,MAAM,gBAAgB;AACtC,MAAI,GAAG;AAAE,UAAM,IAAI,OAAO,EAAE,CAAC,CAAC;AAAG,QAAI,KAAK,KAAK,KAAK,EAAG,QAAO;AAAA,EAAU;AACxE,SAAO;AACT;AAEA,SAAS,gBAAgB,IAAI,YAAY,CAAC;;;AClmBnC,IAAM,YAAN,MAAmC;AAAA,EAAnC;AACL,SAAS,SAAS;AAAA;AAAA,EAElB,MAAM,OAAO,MAA6C;AACxD,UAAM,SAAS,IAAI,eAAe;AAClC,UAAM,QAAkB,CAAC;AAEzB,QAAI;AACF,YAAM,OAAO,QAAQ,OAAO,IAAI;AAChC,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAM,OAAsB,CAAC;AAE7B,UAAI,IAAI;AACR,aAAO,IAAI,MAAM,QAAQ;AACvB,cAAM,OAAO,MAAM,CAAC;AAGpB,cAAM,eAAe,KAAK,MAAM,mBAAmB;AACnD,YAAI,cAAc;AAChB,gBAAM,QAAQ,aAAa,CAAC,EAAE;AAC9B,eAAK,KAAK,UAAU,CAAC,UAAU,aAAa,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC,CAAC;AACxF;AAAK;AAAA,QACP;AAGA,YAAI,KAAK,SAAS,GAAG,KAAK,IAAI,IAAI,MAAM,UAAU,MAAM,IAAI,CAAC,EAAE,MAAM,sBAAsB,GAAG;AAC5F,gBAAM,cAAc,OAAO,MAAM,MAAM,aAAa,OAAO,CAAC,GAAG,MAAM,YAAY,CAAC,EAAE;AACpF,cAAI,aAAa;AAAE,iBAAK,KAAK,YAAY,IAAI;AAAG,gBAAI,YAAY;AAAU;AAAA,UAAU;AAAA,QACtF;AAGA,YAAI,KAAK,MAAM,aAAa,GAAG;AAAE,eAAK,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AAAG;AAAK;AAAA,QAAU;AAG3F,cAAM,YAAY,KAAK,MAAM,6BAA6B;AAC1D,YAAI,WAAW;AACb,eAAK,KAAK,UAAU,YAAY,UAAU,CAAC,CAAC,GAAG;AAAA,YAC7C,QAAQ,KAAK,MAAM,UAAU,CAAC,EAAE,SAAS,CAAC;AAAA,YAC1C,SAAS,QAAQ,KAAK,UAAU,CAAC,CAAC;AAAA,UACpC,CAAC,CAAC;AACF;AAAK;AAAA,QACP;AAGA,cAAM,UAAU,KAAK,MAAM,YAAY;AACvC,YAAI,SAAS;AAAE,eAAK,KAAK,UAAU,CAAC,UAAU,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,GAAG,CAAC,CAAC;AAAG;AAAK;AAAA,QAAU;AAG/F,YAAI,KAAK,WAAW,KAAK,GAAG;AAC1B,gBAAM,YAAsB,CAAC;AAC7B;AACA,iBAAO,IAAI,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,GAAG;AAAE,sBAAU,KAAK,MAAM,CAAC,CAAC;AAAG;AAAA,UAAK;AACzF;AACA,eAAK,KAAK,UAAU,CAAC,UAAU,UAAU,KAAK,IAAI,GAAG,EAAE,MAAM,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACnF;AAAA,QACF;AAGA,YAAI,KAAK,KAAK,MAAM,IAAI;AAAE;AAAK;AAAA,QAAU;AAGzC,cAAM,aAAa,KAAK,MAAM,oDAAoD;AAClF,YAAI,YAAY;AACd,gBAAM,QAAQ,WAAW,CAAC,EAAE,YAAY;AACxC,eAAK,KAAK,UAAU,YAAY,WAAW,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC1D;AAAK;AAAA,QACP;AAGA,aAAK,KAAK,UAAU,YAAY,IAAI,GAAG,CAAC,CAAC,CAAC;AAC1C;AAAA,MACF;AAEA,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,YAAM,QAAQ,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;AAClF,aAAO,QAAQ,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK;AAAA,IAC9C,SAAS,GAAQ;AACf,YAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAC5B,aAAO,KAAK,oBAAoB,GAAG,WAAW,OAAO,CAAC,CAAC,IAAI,KAAK;AAAA,IAClE;AAAA,EACF;AACF;AAEA,SAAS,YAAY,MAAsC;AACzD,QAAM,SAAiC,CAAC;AACxC,MAAI,MAAM;AAEV,SAAO,IAAI,SAAS,GAAG;AAErB,QAAI,IAAI,IAAI,MAAM,2DAA2D;AAC7E,QAAI,GAAG;AACL,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AACrC,YAAM,OAAO,EAAE,CAAC;AAChB,YAAM,aAAa,CAAC,aAAa,cAAc,aAAa,WAAW;AACvE,aAAO,KAAK,SAAS,EAAE,CAAC,GAAG,WAAW,SAAS,IAAI,IAAI,OAAO,aAAa,KAAK,KAAK,EAAE,CAAC,KAAK,MAAS,CAAC;AACvG,YAAM,EAAE,CAAC;AAAG;AAAA,IACd;AAGA,QAAI,IAAI,MAAM,qCAAqC;AACnD,QAAI,GAAG;AACL,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAErC,aAAO,KAAK,UAAU,wBAAS,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC;AAC/C,YAAM,EAAE,CAAC;AAAG;AAAA,IACd;AAGA,QAAI,IAAI,MAAM,8BAA8B;AAC5C,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAG3H,QAAI,IAAI,MAAM,0BAA0B;AACxC,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAGlH,QAAI,IAAI,MAAM,sBAAsB;AACpC,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAGlH,QAAI,IAAI,MAAM,sBAAsB;AACpC,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAGlH,QAAI,IAAI,MAAM,2BAA2B;AACzC,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAGlH,QAAI,IAAI,MAAM,+BAA+B;AAC7C,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAGpH,QAAI,IAAI,MAAM,+BAA+B;AAC7C,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAGpH,QAAI,IAAI,MAAM,oBAAoB;AAClC,QAAI,GAAG;AAAE,UAAI,EAAE,CAAC,EAAG,QAAO,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;AAAG,aAAO,KAAK,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,cAAc,CAAC,CAAC;AAAG,YAAM,EAAE,CAAC;AAAG;AAAA,IAAU;AAE9H,WAAO,KAAK,UAAU,GAAG,CAAC;AAC1B;AAAA,EACF;AAEA,SAAO,OAAO,SAAS,IAAI,SAAS,CAAC,UAAU,IAAI,CAAC;AACtD;AAEA,SAAS,aAAa,OAAiB,WAA2D;AAChG,QAAM,QAAQ,CAAC,SAAiB,KAAK,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,GAAG,GAAG,QAAQ,IAAI,KAAK,MAAM,EAAE;AAC1G,QAAM,UAAU,MAAM,MAAM,SAAS,CAAC;AAEtC,MAAI,MAAM,YAAY;AACtB,QAAM,OAAmB,CAAC;AAC1B,SAAO,MAAM,MAAM,QAAQ;AACzB,QAAI,CAAC,MAAM,GAAG,EAAE,SAAS,GAAG,EAAG;AAC/B,UAAM,QAAQ,MAAM,MAAM,GAAG,CAAC;AAC9B,QAAI,MAAM,WAAW,EAAG;AACxB,SAAK,KAAK,KAAK;AACf;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,SAAS,GAAG,IAAI;AACjC,QAAM,WAAW,QAAQ;AAAA,IAAI,CAAC,KAAK,OACjC,SAAS,IAAI,IAAI,UAAQ,UAAU,CAAC,UAAU,CAAC,UAAU,MAAM,OAAO,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,EAClG;AAEA,SAAO,EAAE,MAAM,UAAU,QAAQ,GAAG,UAAU,IAAI;AACpD;AAEA,SAAS,gBAAgB,IAAI,UAAU,CAAC;;;ACvKxC,IAAM,KAAK;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAwCV,SAAS,UAAU,GAAsB;AACvC,SAAO,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,QAAQ,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE;AACvI;AAEA,SAAS,UAAU,GAAsB;AACvC,SAAO,GAAG,EAAE,SAAS,MAAM,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,CAAC;AACjE;AAEA,SAAS,aAAa,MAAc,KAAsB;AACxD,QAAM,IAAI,QAAQ;AAClB,QAAM,WAAW,IAAI,QAAQ,IAAI,CAAC;AAClC,MAAI,aAAa,OAAW,QAAO;AACnC,QAAM,KAAK,IAAI,MAAM;AACrB,MAAI,MAAM,KAAK,CAAC;AAChB,MAAI,QAAQ,IAAI,GAAG,EAAE;AACrB,SAAO;AACT;AAEA,SAAS,eAAe,OAAkB,KAAsB;AAC9D,QAAM,MAAM,UAAU,KAAK;AAC3B,QAAM,WAAW,IAAI,UAAU,IAAI,GAAG;AACtC,MAAI,aAAa,OAAW,QAAO;AAEnC,QAAM,WAAW,aAAa,MAAM,IAAI,KAAK;AAC7C,QAAM,SAAS,aAAa,UAAU,GAAG;AAEzC,QAAM,KAAK,IAAI,QAAQ;AACvB,QAAM,MAAiB;AAAA,IACrB;AAAA,IACA,QAAQ,OAAO,YAAY,MAAM,MAAM,EAAE;AAAA,IACzC,MAAM,CAAC,CAAC,MAAM;AAAA,IACd,QAAQ,CAAC,CAAC,MAAM;AAAA,IAChB,WAAW,MAAM,IAAI,WAAW;AAAA,IAChC,WAAW,MAAM,IAAI,UAAU;AAAA,IAC/B,WAAW,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAK;AAAA,IAC7C;AAAA,IACA;AAAA,IACA,IAAI,MAAM;AAAA,EACZ;AACA,MAAI,QAAQ,KAAK,GAAG;AACpB,MAAI,UAAU,IAAI,KAAK,EAAE;AACzB,SAAO;AACT;AAEA,SAAS,eAAe,OAAkB,KAAsB;AAC9D,QAAM,MAAM,UAAU,KAAK;AAC3B,QAAM,WAAW,IAAI,UAAU,IAAI,GAAG;AACtC,MAAI,aAAa,OAAW,QAAO;AAEnC,QAAM,KAAK,IAAI,QAAQ;AACvB,QAAM,MAAiB;AAAA,IACrB;AAAA,IACA,QAAQ,MAAM,SAAS,QAAQ,YAAY;AAAA,EAC7C;AACA,MAAI,MAAM,YAAY,QAAW;AAC/B,QAAI,WAAW,MAAM,UAAU,UAAU;AACzC,QAAI,YAAY,MAAM,UAAU;AAAA,EAClC;AACA,MAAI,QAAQ,KAAK,GAAG;AACpB,MAAI,UAAU,IAAI,KAAK,EAAE;AACzB,SAAO;AACT;AAIA,SAAS,YAAY,MAAqB,KAAoB;AAC5D,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,QAAQ,OAAQ,UAAS,KAAK,GAAG;AAAA,aAChC,IAAI,QAAQ,OAAQ,UAAS,KAAK,GAAG;AAAA,EAChD;AACF;AAEA,SAAS,SAAS,MAAgB,KAAoB;AACpD,iBAAe,KAAK,OAAO,GAAG;AAC9B,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,IAAI,QAAQ,OAAQ,gBAAe,IAAI,OAAO,GAAG;AAAA,aAC5C,IAAI,QAAQ,MAAO,eAAc,KAAK,GAAG;AAAA,EACpD;AACF;AAEA,SAAS,SAAS,MAAgB,KAAoB;AACpD,aAAW,OAAO,KAAK;AACrB,eAAW,QAAQ,IAAI;AACrB,iBAAW,KAAK,KAAK,KAAM,UAAS,GAAG,GAAG;AAChD;AAEA,SAAS,UAAU,OAAmB,KAAoB;AACxD,aAAW,KAAK,MAAO,UAAS,GAAG,GAAG;AACxC;AAIA,SAAS,UAAU,MAAsB;AACvC,MAAI,KAAK,SAAS,MAAM,EAAG,QAAO;AAClC,MAAI,KAAK,SAAS,KAAK,EAAG,QAAO;AACjC,MAAI,KAAK,SAAS,KAAK,EAAG,QAAO;AACjC,SAAO;AACT;AAEA,SAAS,cAAc,KAAc,KAAoB;AACvD,MAAK,IAAY,OAAQ;AACzB,QAAM,MAAM,UAAU,IAAI,IAAI;AAC9B,QAAM,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,SAAS,GAAG,GAAG,CAAC;AACxD,QAAM,OAAO,GAAG,EAAE,IAAI,GAAG;AACzB,MAAI;AACJ,QAAM,OAAO,QAAQ,aAAa,IAAI,GAAG;AACzC,MAAI,KAAK,KAAK,EAAE,IAAI,MAAM,KAAK,CAAC;AAChC,EAAC,IAAY,SAAS;AACxB;AAIA,SAAS,cAAc,KAAc,QAAiB,SAA0B;AAC9E,QAAM,KAAK,IAAI,YAAY,SAAS;AACpC,QAAM,IAAI,UAAU;AACpB,QAAM,UAAkC,EAAE,OAAO,SAAS,MAAM,QAAQ,KAAK,OAAO,QAAQ,UAAU,MAAM,OAAO;AACnH,QAAM,OAAO,QAAQ,EAAE,IAAI,KAAK;AAChC,QAAM,IAAI,IAAI,EAAE,KAAK,QAAQ,QAAQ,CAAC,CAAC;AACvC,QAAM,IAAI,EAAE,MAAM,WAAW,GAAG,IAAI,EAAE,QAAQ,IAAI,EAAE,KAAK;AAEzD,MAAI,OAAO;AACX,MAAI,SAAS;AACX,UAAM,KAAK,QAAQ,WAAW,GAAG,IAAI,UAAU,IAAI,OAAO;AAC1D,WAAO,yCAAyC,EAAE;AAAA,EACpD;AAEA,QAAM,MAAM,sBAAsB,EAAE,kMAAkM,IAAI,YAAY,CAAC,YAAY,CAAC,4BAA4B,IAAI,YAAY,CAAC,YAAY,CAAC,0BAA0B,IAAI,YAAY,CAAC,YAAY,CAAC,6BAA6B,IAAI,YAAY,CAAC,YAAY,CAAC,gEAAgE,IAAI;AACrf,MAAI,YAAY,KAAK,EAAE,IAAI,IAAI,CAAC;AAChC,SAAO;AACT;AAIO,IAAM,cAAN,MAAqC;AAAA,EAArC;AACL,SAAS,SAAS;AAAA;AAAA,EAElB,MAAM,OAAO,KAA4C;AACvD,QAAI;AACF,YAAM,QAAQ,IAAI,KAAK,CAAC;AACxB,YAAM,OAAO,OAAO,QAAQ;AAG5B,YAAM,iBAAiB,OAAO,QAAQ,KAAK,GAAG,IAAI,OAAO,QAAQ,KAAK,EAAE,IAAI,OAAO,QAAQ,KAAK,EAAE;AAElG,YAAM,MAAe;AAAA,QACnB,SAAS,CAAC;AAAA,QAAG,WAAW,oBAAI,IAAI;AAAA,QAChC,SAAS,CAAC;AAAA,QAAG,WAAW,oBAAI,IAAI;AAAA,QAChC,aAAa,CAAC;AAAA,QAAG,MAAM,CAAC;AAAA,QAAG,YAAY;AAAA,QAAG,eAAe;AAAA,QACzD;AAAA,QACA,OAAO,CAAC;AAAA,QAAG,SAAS,oBAAI,IAAI;AAAA,MAC9B;AAGA,oBAAc,KAAK,EAAE,MAAM,QAAQ,IAAI,KAAK,OAAO,SAAS,CAAC;AAE7D,oBAAc,KAAK,cAAc;AAEjC,oBAAc,KAAK,EAAE,MAAM,QAAQ,IAAI,KAAK,OAAO,SAAS,CAAC;AAG7D,qBAAe,CAAC,GAAG,GAAG;AACtB,qBAAe,CAAC,GAAG,GAAG;AAGtB,kBAAY,OAAO,QAAQ,CAAC,GAAG,GAAG;AAClC,UAAI,OAAO,OAAQ,WAAU,MAAM,QAAQ,GAAG;AAC9C,UAAI,OAAO,OAAQ,WAAU,MAAM,QAAQ,GAAG;AAG9C,YAAM,cAAc,mBAAmB,KAAK;AAI5C,YAAM,cAAc,QAAQ,OAAO,WAAW,OAAO,MAAM,GAAG,CAAC;AAC/D,YAAM,aAAa,QAAQ,OAAO,UAAU,MAAM,IAAI,MAAM,GAAG,CAAC;AAEhE,YAAM,UAAgD;AAAA,QACpD,EAAE,MAAM,YAA8B,MAAM,QAAQ,OAAO,qBAAqB,EAAE;AAAA,QAClF,EAAE,MAAM,eAA8B,MAAM,QAAQ,OAAO,WAAW,EAAE;AAAA,QACxE,EAAE,MAAM,uBAA+B,MAAM,WAAW;AAAA,QACxD,EAAE,MAAM,yBAA+B,MAAM,YAAY;AAAA,QACzD,EAAE,MAAM,uBAA+B,MAAM,QAAQ,OAAO,WAAW,EAAE;AAAA,QACzE,EAAE,MAAM,gBAA8B,MAAM,QAAQ,OAAO,YAAY,EAAE;AAAA,QACzE,EAAE,MAAM,0BAA+B,MAAM,QAAQ,OAAO,aAAa,EAAE;AAAA,QAC3E,EAAE,MAAM,wBAA+B,MAAM,QAAQ,OAAO,WAAW,KAAK,IAAI,IAAI,CAAC,EAAE;AAAA,QACvF,EAAE,MAAM,0BAA+B,MAAM,QAAQ,OAAO,aAAa,EAAE;AAAA,QAC3E,EAAE,MAAM,yBAA+B,MAAM,QAAQ,OAAO,YAAY,EAAE;AAAA,MAC5E;AAEA,iBAAW,OAAO,IAAI,MAAM;AAC1B,gBAAQ,KAAK,EAAE,MAAM,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;AAAA,MAC9D;AAEA,aAAO,QAAQ,MAAM,WAAW,IAAI,OAAO,CAAC;AAAA,IAC9C,SAAS,GAAQ;AACf,aAAO,KAAK,sBAAsB,GAAG,WAAW,OAAO,CAAC,CAAC,EAAE;AAAA,IAC7D;AAAA,EACF;AACF;AAIA,IAAM,cAAc;AAEpB,IAAM,gBAAgB;AAEtB,IAAM,gBAAgB;AAEtB,IAAM,eAAe;AAErB,IAAM,eAAe;AAErB,SAAS,WAAW,KAAc,MAAoB;AACpD,QAAM,QAAQ,IAAI,MAAM,SAAS,EAAE;AACnC,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,aAAa,GAAG;AAE7D,MAAI,QAAQ;AAGZ,aAAW,OAAO,IAAI,MAAM;AAC1B,UAAM,MAAM,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY,KAAK;AACxD,UAAM,KAAK,QAAQ,QAAQ,cAAc,QAAQ,SAAS,QAAQ,SAAS,eAAe,QAAQ,QAAQ,cAAc;AACxH,aAAS,iBAAiB,IAAI,EAAE,mBAAmB,IAAI,IAAI,iBAAiB,EAAE;AAAA,EAChF;AACA,SAAO,wEAAwE,EAAE,mEAAmE,KAAK,yNAAyN,GAAG,2DAA2D,GAAG,oFAAoF,KAAK;AAC9gB;AAIA,SAAS,UAAU,MAAgB,MAAW,KAAsB;AAElE,QAAM,YAAY,IAAI,MAAM,UAAU;AACtC,QAAM,QAAQ,CAAC,UAAU,SAAS,SAAS,YAAY,SAAS,UAAU,MAAM;AAChF,MAAI,YAAY,0BAA0B,MAAM,MAAM;AACtD,aAAW,QAAQ,OAAO;AACxB,iBAAa,sBAAsB,IAAI,cAAc,SAAS;AAC9D,aAAS,KAAK,GAAG,KAAK,IAAI,MAAM,QAAQ,MAAM;AAC5C,mBAAa,gBAAgB,EAAE,WAAW,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC;AAAA,IAC9D;AACA,QAAI,IAAI,MAAM,WAAW,GAAG;AAC1B,mBAAa;AAAA,IACf;AACA,iBAAa;AAAA,EACf;AACA,eAAa;AAGb,MAAI,YAAY;AAChB,aAAW,MAAM,IAAI,SAAS;AAC5B,UAAM,OAAO,GAAG,OAAO,eAAe;AACtC,UAAM,SAAS,GAAG,SAAS,iBAAiB;AAC5C,UAAM,MAAM,GAAG,UAAU;AACzB,iBAAa,kBAAkB,GAAG,EAAE,aAAa,GAAG,MAAM,gBAAgB,GAAG,SAAS,8GAA8G,GAAG,YAAY,GAAG,YAAY,GAAG,eAAe,GAAG,YAAY,GAAG,aAAa,GAAG,WAAW,GAAG,yXAAyX,IAAI,GAAG,MAAM,uBAAuB,GAAG,SAAS,yDAAyD,GAAG,SAAS;AAAA,EACpxB;AAGA,MAAI,YAAY;AAChB,aAAW,MAAM,IAAI,SAAS;AAC5B,iBAAa,kBAAkB,GAAG,EAAE,6HAA6H,GAAG,KAAK;AAAA,EAC3K;AAGA,QAAM,gBAAgB,IAAI,YAAY,IAAI,QAAM,GAAG,GAAG,EAAE,KAAK,EAAE;AAE/D,SAAO,oEAAoE,EAAE,sHAAsH,SAAS,4BAA4B,IAAI,YAAY,MAAM,KAAK,aAAa,gDAAgD,IAAI,QAAQ,MAAM,KAAK,SAAS,mDAAmD,IAAI,QAAQ,MAAM,KAAK,SAAS;AACrb;AAIA,SAAS,WAAW,OAA8B,MAAgB,KAAsB;AACtF,QAAM,OAAO,OAAO,QAAQ,CAAC;AAI7B,QAAM,QAAQ,0jBAA0jB,KAAK,WAAW,cAAc,aAAa,QAAQ,YAAY,OAAO,QAAQ,KAAK,GAAG,CAAC,aAAa,OAAO,QAAQ,KAAK,GAAG,CAAC,oFAAoF,OAAO,QAAQ,KAAK,EAAE,CAAC,YAAY,OAAO,QAAQ,KAAK,EAAE,CAAC,UAAU,OAAO,QAAQ,KAAK,EAAE,CAAC,aAAa,OAAO,QAAQ,KAAK,EAAE,CAAC;AAEv5B,MAAI,aAAa;AACjB,MAAI,UAAU;AAEd,QAAM,iBAAiB,6IAA6I,IAAI,cAAc;AAEtL,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,QAAQ,QAAQ;AACtB,oBAAc,WAAW,KAAK,KAAK,UAAU,QAAQ,EAAE;AACvD,gBAAU;AAAA,IACZ,WAAW,IAAI,QAAQ,QAAQ;AAE7B,YAAM,UAAU,WAAW,KAAK,GAAG;AACnC,YAAM,SAAS,UAAU,QAAQ;AACjC,oBAAc,aAAa,IAAI,eAAe,qGAAqG,MAAM,GAAG,OAAO,YAAY,cAAc;AAC7L,gBAAU;AAAA,IACZ;AAAA,EACF;AAGA,MAAI,eAAe,IAAI;AACrB,iBAAa,aAAa,IAAI,eAAe,qGAAqG,KAAK,yBAAyB,cAAc;AAAA,EAChM;AAEA,SAAO,mEAAmE,EAAE,IAAI,UAAU;AAC5F;AAEA,SAAS,WAAW,MAAgB,KAAc,QAAgB,IAAY;AAC5E,QAAM,WAAW,eAAe,KAAK,OAAO,GAAG;AAE/C,MAAI,OAAO;AACX,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,IAAI,QAAQ,QAAQ;AACtB,cAAQ,UAAU,KAAK,GAAG;AAAA,IAC5B,WAAW,IAAI,QAAQ,OAAO;AAC5B,cAAQ,YAAY,KAAK,GAAG;AAAA,IAC9B;AAAA,EACF;AAGA,MAAI,SAAS,IAAI;AACf,WAAO;AAAA,EACT;AAGA,MAAI,OAAO;AAET,UAAM,cAAc,KAAK,QAAQ,GAAG;AACpC,QAAI,cAAc,IAAI;AACpB,aAAO,KAAK,UAAU,GAAG,cAAc,CAAC,IAAI,QAAQ,KAAK,UAAU,cAAc,CAAC;AAAA,IACpF;AAAA,EACF;AAGA,QAAM,WAAW,mBAAmB,MAAM,GAAG;AAC7C,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,WAAW,KAAK,MAAM,WAAW,IAAI;AAC3C,QAAM,UAAU,KAAK,MAAM,WAAW,GAAG;AACzC,QAAM,eAAe,kEAAkE,QAAQ,iBAAiB,UAAU,eAAe,QAAQ,cAAc,OAAO,2BAA2B,IAAI,cAAc;AAEnN,SAAO,aAAa,IAAI,eAAe,kBAAkB,QAAQ,6DAA6D,IAAI,GAAG,YAAY;AACnJ;AAGA,SAAS,mBAAmB,MAAgB,KAAsB;AAChE,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,IAAI,QAAQ,QAAQ;AACtB,YAAM,WAAW,IAAI,UAAU,IAAI,UAAU,IAAI,KAAK,CAAC;AACvD,UAAI,aAAa,UAAa,IAAI,QAAQ,QAAQ,GAAG;AACnD,eAAO,IAAI,QAAQ,QAAQ,EAAE;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,UAAU,MAAgB,KAAsB;AACvD,QAAM,WAAW,eAAe,KAAK,OAAO,GAAG;AAE/C,QAAM,QAAkB,CAAC;AACzB,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,IAAI,QAAQ,OAAO;AACrB,UAAI,IAAI,SAAS;AACf,cAAM,KAAK,SAAS,IAAI,IAAI,OAAO,CAAC,SAAS;AAAA,MAC/C,OAAO;AACL,cAAM,KAAK,eAAe;AAAA,MAC5B;AAAA,IACF,WAAW,IAAI,QAAQ,WAAW;AAChC,YAAM,MAAM,IAAI,WAAW,UAAU,gBAAgB,IAAI,WAAW,cAAc,gBAAgB;AAClG,YAAM,KAAK,+CAA+C,GAAG,KAAK;AAAA,IACpE,WAAW,IAAI,QAAQ,MAAM;AAC3B,YAAM,KAAK;AAAA,QAAiB;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO,wBAAwB,QAAQ,KAAK,MAAM,KAAK,EAAE,CAAC;AAC5D;AAEA,SAAS,YAAY,KAAc,KAAsB;AACvD,QAAM,QAAS,IAAY;AAC3B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,WAAW,eAAe,CAAC,GAAG,GAAG;AACvC,QAAM,IAAI,OAAO,QAAQ,IAAI,CAAC;AAC9B,QAAM,IAAI,OAAO,QAAQ,IAAI,CAAC;AAE9B,SAAO,wBAAwB,QAAQ,iBAAiB,IAAI,eAAe,oKAAoK,CAAC,mCAAmC,CAAC,4TAA4T,CAAC,QAAQ,CAAC,kFAAkF,KAAK;AACnrB;AAEA,SAAS,WAAW,MAAgB,KAAsB;AACxD,QAAM,WAAW,KAAK,KAAK;AAG3B,MAAI,WAAW;AACf,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,eAAW,QAAQ,IAAI,KAAM,YAAW,KAAK;AAC7C,QAAI,UAAU,SAAU,YAAW;AAAA,EACrC;AACA,MAAI,aAAa,EAAG,YAAW,KAAK,KAAK,CAAC,GAAG,KAAK,UAAU;AAG5D,QAAM,aAAa,IAAI;AACvB,QAAM,cAAc,KAAK,MAAM,cAAc,YAAY,EAAE;AAC3D,QAAM,YAAsB,CAAC;AAC7B,MAAI,KAAK,MAAM,aAAa,KAAK,MAAM,UAAU,WAAW,UAAU;AAEpE,UAAM,QAAQ,CAAC,GAAG,KAAK,MAAM,SAAS;AACtC,UAAM,aAAa,MAAM,OAAO,OAAK,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AACrE,UAAM,YAAY,MAAM,OAAO,OAAK,KAAK,CAAC,EAAE;AAC5C,UAAM,YAAY,KAAK,IAAI,GAAG,OAAO,QAAQ,UAAU,IAAI,UAAU;AACrE,UAAM,WAAW,YAAY,IAAI,YAAY,YAAY;AACzD,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAI,MAAM,CAAC,KAAK,EAAG,OAAM,CAAC,IAAI,WAAW,IAAI,WAAW,OAAO,QAAQ,WAAW;AAAA,IACpF;AACA,eAAW,OAAO,MAAO,WAAU,KAAK,OAAO,QAAQ,GAAG,CAAC;AAAA,EAC7D,OAAO;AACL,aAAS,IAAI,GAAG,IAAI,UAAU,IAAK,WAAU,KAAK,WAAW;AAAA,EAC/D;AAEA,QAAM,WAAW,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AACpD,MAAI,WAAW,aAAa,MAAM;AAChC,UAAM,QAAQ,aAAa;AAC3B,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,IAAK,WAAU,CAAC,IAAI,KAAK,MAAM,UAAU,CAAC,IAAI,KAAK;AAAA,EAC3F;AACA,QAAM,cAAc,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAGvD,QAAM,UAAU,KAAK,MAAM,gBACvB,cAAc,KAAK,KAAK,MAAM,aAAa,IAC3C;AAGJ,MAAI,UAAU;AACd,WAAS,KAAK,GAAG,KAAK,KAAK,KAAK,QAAQ,MAAM;AAC5C,UAAM,MAAM,KAAK,KAAK,EAAE;AACxB,QAAI,WAAW;AACf,QAAI,SAAS;AACb,aAAS,KAAK,GAAG,KAAK,IAAI,KAAK,QAAQ,MAAM;AAC3C,YAAM,OAAO,IAAI,KAAK,EAAE;AAGxB,UAAI,WAAW;AACf,UAAI,KAAK,MAAM,IAAI;AACjB,mBAAW,cAAc,KAAK,KAAK,MAAM,iBAAiB,gBAAgB,KAAK,MAAM,EAAE;AAAA,MACzF;AAGA,YAAM,WAAW,KAAK,KAAK,IAAI,OAAK,WAAW,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAG/D,UAAI,QAAQ;AACZ,eAAS,KAAK,QAAQ,KAAK,SAAS,KAAK,MAAM,KAAK,UAAU,QAAQ,KAAM,UAAS,UAAU,EAAE;AACjG,UAAI,UAAU,EAAG,SAAQ,cAAc,KAAK;AAE5C,kBAAY,+FAA+F,QAAQ,8EAA8E,KAAK,MAAM,OAAO,QAAQ,WAAW,KAAK,MAAM,OAAO,QAAQ,WAAW,KAAK,uGAAuG,QAAQ,sCAAsC,MAAM,cAAc,EAAE,4BAA4B,KAAK,EAAE,cAAc,KAAK,EAAE,wBAAwB,KAAK;AAChhB,gBAAU,KAAK;AAAA,IACjB;AACA,eAAW,UAAU,QAAQ;AAAA,EAC/B;AAEA,QAAM,YAAY,KAAK,MAAM,YAAY,sBAAsB;AAE/D,SAAO,eAAe,IAAI,eAAe,mIAAmI,SAAS,YAAY,QAAQ,aAAa,QAAQ,sCAAsC,OAAO,gCAAgC,WAAW,iYAAiY,OAAO;AAChsB;AAEA,SAAS,mBAAmB,OAA2B;AACrD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAkB,CAAC;AACzB,aAAW,OAAO,MAAM,MAAM;AAC5B,QAAI,IAAI,QAAQ,QAAQ;AACtB,YAAM,OAAO,IAAI,KAAK,IAAI,OAAK;AAC7B,YAAI,EAAE,QAAQ,OAAQ,QAAO,EAAE,KAAK,IAAI,OAAK,EAAE,QAAQ,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE;AACtF,eAAO;AAAA,MACT,CAAC,EAAE,KAAK,EAAE;AACV,UAAI,KAAM,OAAM,KAAK,IAAI;AAAA,IAC3B,WAAW,IAAI,QAAQ,QAAQ;AAC7B,iBAAW,OAAO,IAAI,MAAM;AAC1B,cAAM,QAAQ,IAAI,KAAK;AAAA,UAAI,UACzB,KAAK,KAAK,IAAI,OAAK,EAAE,KAAK,IAAI,OAAK;AACjC,gBAAI,EAAE,QAAQ,OAAQ,QAAO,EAAE,KAAK,IAAI,OAAK,EAAE,QAAQ,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE;AACtF,mBAAO;AAAA,UACT,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE;AAAA,QACtB;AACA,cAAM,KAAK,MAAM,KAAK,GAAI,CAAC;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AACA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAEA,SAAS,IAAI,GAAmB;AAAE,SAAO,QAAQ,UAAU,CAAC;AAAG;AAE/D,SAAS,gBAAgB,IAAI,YAAY,CAAC;;;AC/hBnC,IAAM,cAAN,MAAqC;AAAA,EAArC;AACL,SAAS,SAAS;AAAA;AAAA,EAElB,MAAM,OAAO,KAA4C;AACvD,QAAI;AACF,YAAM,QAAQ,IAAI,KAAK,CAAC;AACxB,YAAM,OAAQ,OAAO,QAAQ;AAC7B,YAAM,OAAQ,OAAO,QAAQ,CAAC;AAE9B,YAAM,SAAuB,CAAC;AAC9B,YAAM,MAAc,EAAE,QAAQ,QAAQ,IAAI,YAAY,GAAG,OAAO,CAAC,EAAE;AAGnE,oBAAc,MAAM,GAAG;AAGvB,UAAI,cAAc,OAAO;AACzB,UAAI,cAAc,OAAO;AACzB,YAAM,YAAY,eAAe,YAAY,SAAS;AACtD,YAAM,YAAY,eAAe,YAAY,SAAS;AAGtD,UAAI,UAAW,wBAAuB,aAAc,GAAG;AACvD,UAAI,UAAW,wBAAuB,aAAc,GAAG;AAEvD,YAAM,YAAY,YAAY,MAAM,IAAI,QAAQ,KAAK;AACrD,YAAM,YAAY,YAAY,MAAM,IAAI,QAAQ,KAAK;AAGrD,YAAM,UAAU,iBAAiB,IAAI;AAErC,YAAM,UAAgD;AAAA,QACpD,EAAE,MAAM,uBAAkC,MAAM,QAAQ,OAAO,aAAa,QAAQ,WAAW,SAAS,CAAC,EAAE;AAAA,QAC3G,EAAE,MAAM,eAAkC,MAAM,QAAQ,OAAO,QAAQ,CAAC,EAAE;AAAA,QAC1E,EAAE,MAAM,qBAAkC,MAAM,QAAQ,OAAO,YAAY,MAAM,MAAM,KAAK,WAAW,SAAS,CAAC,EAAE;AAAA,QACnH,EAAE,MAAM,mBAAkC,MAAM,QAAQ,OAAO,UAAU,CAAC,EAAE;AAAA,QAC5E,EAAE,MAAM,qBAAkC,MAAM,QAAQ,OAAO,YAAY,CAAC,EAAE;AAAA,QAC9E,EAAE,MAAM,gCAAkC,MAAM,QAAQ,OAAO,QAAQ,QAAQ,WAAW,WAAW,QAAQ,QAAQ,CAAC,EAAE;AAAA,QACxH,EAAE,MAAM,oBAAkC,MAAM,QAAQ,OAAO,OAAO,CAAC,EAAE;AAAA,QACzE,EAAE,MAAM,qBAAkC,MAAM,QAAQ,OAAO,QAAQ,IAAI,IAAI,CAAC,EAAE;AAAA,MACpF;AAGA,UAAI,QAAQ,UAAU;AACpB,gBAAQ,KAAK,EAAE,MAAM,sBAAsB,MAAM,QAAQ,OAAO,aAAa,OAAO,CAAC,EAAE,CAAC;AAAA,MAC1F;AAGA,UAAI,WAAW;AACb,gBAAQ,KAAK,EAAE,MAAM,oBAAoB,MAAM,QAAQ,OAAO,gBAAgB,OAAO,aAAc,GAAG,CAAC,EAAE,CAAC;AAAA,MAC5G;AACA,UAAI,WAAW;AACb,gBAAQ,KAAK,EAAE,MAAM,oBAAoB,MAAM,QAAQ,OAAO,gBAAgB,OAAO,aAAc,GAAG,CAAC,EAAE,CAAC;AAAA,MAC5G;AAGA,iBAAW,OAAO,QAAQ;AACxB,gBAAQ,KAAK,EAAE,MAAM,cAAc,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;AAAA,MACjE;AAEA,aAAO,QAAQ,MAAM,WAAW,IAAI,OAAO,CAAC;AAAA,IAC9C,SAAS,GAAQ;AACf,aAAO,KAAK,sBAAsB,GAAG,WAAW,OAAO,CAAC,CAAC,EAAE;AAAA,IAC7D;AAAA,EACF;AACF;AAaA,SAASE,WAAU,MAAsB;AACvC,MAAI,KAAK,SAAS,MAAM,EAAG,QAAO;AAClC,MAAI,KAAK,SAAS,KAAK,EAAG,QAAO;AACjC,MAAI,KAAK,SAAS,KAAK,EAAG,QAAO;AACjC,SAAO;AACT;AAEA,SAAS,cAAc,MAAqB,KAAmB;AAC7D,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,QAAQ,OAAQ,uBAAsB,KAAK,GAAG;AAAA,aAC7C,IAAI,QAAQ,QAAQ;AAC3B,iBAAW,OAAO,IAAI;AACpB,mBAAW,QAAQ,IAAI;AACrB,qBAAW,KAAK,KAAK,KAAM,uBAAsB,GAAG,GAAG;AAAA,IAC7D;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,OAAmB,KAAmB;AACpE,aAAW,KAAK,MAAO,uBAAsB,GAAG,GAAG;AACrD;AAEA,SAAS,sBAAsB,MAAgB,KAAmB;AAChE,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,IAAI,QAAQ,MAAO,CAAAC,eAAc,KAAK,GAAG;AAAA,EAC/C;AACF;AAEA,SAASA,eAAc,KAAc,KAAmB;AAEtD,MAAK,IAAY,KAAM;AACvB,QAAM,MAAMD,WAAU,IAAI,IAAI;AAC9B,QAAM,OAAO,QAAQ,IAAI,YAAY,IAAI,GAAG;AAC5C,QAAM,MAAM,MAAM,IAAI,QAAQ;AAC9B,QAAM,OAAO,QAAQ,aAAa,IAAI,GAAG;AACzC,MAAI,OAAO,KAAK,EAAE,KAAK,MAAM,MAAM,IAAI,CAAC;AACxC,EAAC,IAAY,OAAO;AACtB;AAUA,SAAS,iBAAiB,MAA8B;AACtD,MAAI,YAAY;AAChB,MAAI,cAAc;AAClB,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,QAAQ,QAAQ;AACtB,UAAI,IAAI,MAAM,YAAY,KAAM,eAAc;AAAA,eACrC,IAAI,MAAM,YAAY,MAAO,aAAY;AAAA,IACpD;AAAA,EACF;AACA,SAAO,EAAE,UAAU,aAAa,aAAa,WAAW,YAAY;AACtE;AAIA,SAAS,aAAa,QAAsB,WAAqB,WAA6B;AAC5F,QAAM,cAAc,oBAAI,IAAY;AACpC,aAAW,OAAO,OAAQ,aAAY,IAAI,IAAI,GAAG;AAEjD,MAAI,WAAW;AAAA;AAGf,aAAW,OAAO,aAAa;AAC7B,UAAM,KAAK,QAAQ,QAAQ,cAAc,QAAQ,SAAS,eAAe,QAAQ,QAAQ,cAAc;AACvG,gBAAY;AAAA,wBAA2B,GAAG,kBAAkB,EAAE;AAAA,EAChE;AAEA,MAAI,YAAY;AAAA;AAAA;AAAA;AAAA;AAMhB,MAAI,UAAW,cAAa;AAAA;AAC5B,MAAI,UAAW,cAAa;AAAA;AAE5B,SAAO;AAAA;AAAA,IAEL,QAAQ;AAAA,IACR,SAAS;AAAA;AAEb;AAEA,SAAS,UAAkB;AACzB,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAMT;AAEA,SAAS,QAAQ,QAAsB,WAAoB,WAAoB,UAA4B;AACzG,MAAI,OAAO;AAAA;AAIX,MAAI,UAAU;AACZ,YAAQ;AAAA;AAAA,EACV;AAEA,aAAW,OAAO,QAAQ;AACxB,YAAQ;AAAA,sBAAyB,IAAI,GAAG,oGAAoG,IAAI,IAAI;AAAA,EACtJ;AAEA,MAAI,WAAW;AACb,YAAQ;AAAA,sBAAyB,SAAS;AAAA,EAC5C;AACA,MAAI,WAAW;AACb,YAAQ;AAAA,sBAAyB,SAAS;AAAA,EAC5C;AAEA,SAAO;AAAA;AAAA,IAEL,IAAI;AAAA;AAER;AAEA,SAAS,SAAiB;AACxB,SAAO;AAAA;AAAA;AAAA;AAIT;AAEA,SAAS,QAAQ,MAAmB;AAClC,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA;AAAA,cAEKE,KAAI,KAAK,SAAS,EAAE,CAAC;AAAA,gBACnBA,KAAI,KAAK,UAAU,EAAE,CAAC;AAAA,+CACS,KAAK,WAAW,GAAG;AAAA,gDAClB,GAAG;AAAA;AAEnD;AAEA,SAAS,YAAoB;AAC3B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBT;AAEA,SAAS,cAAsB;AAC7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBT;AAIA,SAAS,aAAa,MAAuB;AAC3C,MAAI,eAAe;AACnB,MAAI,OAAO;AAGX,MAAI,KAAK,WAAW;AAClB,oBAAgB;AAChB,aAAS,MAAM,GAAG,MAAM,GAAG,OAAO;AAChC,YAAM,SAAS,QAAQ,IAAI,WAAM,QAAQ,IAAI,WAAM;AACnD,YAAM,UAAU,MAAM,KAAK;AAC3B,sBAAgB,kBAAkB,GAAG,iDAAiD,MAAM,4BAA4B,MAAM;AAAA,IAChI;AACA,oBAAgB;AAChB,YAAQ;AAAA,EACV;AAGA,MAAI,KAAK,aAAa;AACpB,oBAAgB;AAChB,aAAS,MAAM,GAAG,MAAM,GAAG,OAAO;AAChC,YAAM,MAAM,MAAM,MAAM,IAAI,YAAY,MAAM,MAAM,IAAI,gBAAgB;AACxE,YAAM,UAAU,MAAM,KAAK;AAC3B,sBAAgB,kBAAkB,GAAG,0CAA0C,GAAG,yBAAyB,MAAM,CAAC,6BAA6B,MAAM;AAAA,IACvJ;AACA,oBAAgB;AAChB,YAAQ;AAAA,EACV;AAEA,SAAO;AAAA;AAAA,IAEL,YAAY;AAAA,IACZ,IAAI;AAAA;AAER;AAIA,SAAS,gBAAgB,MAAqB,OAAmB,KAAqB;AACpF,QAAM,MAAM,SAAS,QAAQ,UAAU;AACvC,QAAM,OAAO,MAAM,IAAI,OAAK,gBAAgB,GAAG,GAAG,CAAC,EAAE,KAAK,IAAI;AAC9D,SAAO;AAAA,GACN,GAAG;AAAA,EACJ,IAAI;AAAA,IACF,GAAG;AACP;AAIA,SAAS,YAAY,MAAqB,MAAgB,KAAa,WAAoB,WAA4B;AACrH,QAAM,OAAO,KAAK,IAAI,OAAK,cAAc,GAAG,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI;AAEjE,MAAI,WAAW;AACf,MAAI,UAAW,aAAY;AAAA,kDAAqD,SAAS;AACzF,MAAI,UAAW,aAAY;AAAA,kDAAqD,SAAS;AAEzF,SAAO;AAAA;AAAA;AAAA,EAGP,IAAI;AAAA,gBACU,QAAQ;AAAA,qBACH,OAAO,QAAQ,KAAK,GAAG,CAAC,UAAU,OAAO,QAAQ,KAAK,GAAG,CAAC,eAAe,KAAK,UAAU,UAAU;AAAA,wBAC/F,OAAO,QAAQ,KAAK,EAAE,CAAC,cAAc,OAAO,QAAQ,KAAK,EAAE,CAAC,eAAe,OAAO,QAAQ,KAAK,EAAE,CAAC,aAAa,OAAO,QAAQ,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA;AAI9J;AAEA,SAAS,cAAc,MAAmB,KAAa,MAAyB;AAC9E,SAAO,KAAK,QAAQ,SAASC,YAAW,MAAM,KAAK,IAAI,IAAI,gBAAgB,MAAM,GAAG;AACtF;AAEA,SAAS,gBAAgB,MAAgB,KAAqB;AAC5D,QAAM,QAAQ,KAAK,MAAM,SAAS;AAClC,QAAM,YAAY,KAAK,MAAM,UAAU,2BAA2B,KAAK,MAAM,OAAO,QAAQ;AAG5F,MAAI,QAAQ;AACZ,MAAI,KAAK,MAAM,YAAY,QAAW;AACpC,UAAM,QAAQ,KAAK,MAAM,UAAU,IAAI;AACvC,UAAM,OAAO,KAAK,MAAM,UAAU;AAClC,YAAQ,4DAA4D,IAAI,sBAAsB,KAAK;AAAA,EACrG;AAEA,QAAM,OAAO,KAAK,KAAK,IAAI,OAAK;AAC9B,QAAI,EAAE,QAAQ,OAAQ,QAAOC,WAAU,GAAG,GAAG;AAC7C,QAAI,EAAE,QAAQ,MAAO,QAAOC,aAAY,GAAG,GAAG;AAC9C,WAAO;AAAA,EACT,CAAC,EAAE,KAAK,EAAE;AAEV,SAAO;AAAA,eACM,SAAS,GAAG,KAAK,gBAAgB,UAAU,YAAY,SAAS,KAAK;AAAA,QAC5E,IAAI;AAAA;AAEZ;AAEA,SAASD,WAAU,MAAgB,MAAsB;AACvD,QAAM,IAAI,KAAK;AACf,QAAM,MAAgB,CAAC;AACvB,MAAI,EAAE,EAAG,KAAI,KAAK,QAAQ;AAC1B,MAAI,EAAE,EAAG,KAAI,KAAK,QAAQ;AAC1B,MAAI,EAAE,EAAG,KAAI,KAAK,uBAAuB;AACzC,MAAI,EAAE,EAAG,KAAI,KAAK,aAAa;AAC/B,MAAI,EAAE,IAAK,KAAI,KAAK,oCAAoC;AACxD,MAAI,EAAE,IAAK,KAAI,KAAK,kCAAkC;AACtD,MAAI,EAAE,GAAI,KAAI,KAAK,gBAAgB,OAAO,WAAW,EAAE,EAAE,CAAC,qBAAqB,OAAO,WAAW,EAAE,EAAE,CAAC,KAAK;AAC3G,MAAI,EAAE,MAAO,KAAI,KAAK,mBAAmB,EAAE,KAAK,KAAK;AACrD,MAAI,EAAE,KAAM,KAAI,KAAK,sBAAsBF,KAAI,EAAE,IAAI,CAAC,cAAcA,KAAI,EAAE,IAAI,CAAC,iBAAiBA,KAAI,EAAE,IAAI,CAAC,KAAK;AAChH,MAAI,EAAE,GAAI,KAAI,KAAK,+CAA+C,EAAE,EAAE,KAAK;AAG3E,QAAM,QAAkB,CAAC;AACzB,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,IAAI,QAAQ,OAAO;AACrB,YAAM,KAAK,eAAe,IAAI,KAAK,EAAE,CAAC,qCAAqCA,KAAI,IAAI,OAAO,CAAC,cAAc;AAAA,IAC3G,WAAW,IAAI,QAAQ,WAAW;AAChC,YAAM,KAAK,eAAe,IAAI,KAAK,EAAE,CAAC,+DAA+D,IAAI,KAAK,EAAE,CAAC,8DAA8D,IAAI,KAAK,EAAE,CAAC,kEAAkE,IAAI,KAAK,EAAE,CAAC,yCAAyC,IAAI,KAAK,EAAE,CAAC,gDAAgD;AAAA,IAChX,WAAW,IAAI,QAAQ,MAAM;AAC3B,YAAM,KAAK,oBAAoB;AAAA,IACjC,WAAW,IAAI,QAAQ,MAAM;AAC3B,YAAM,KAAK,kCAAkC;AAAA,IAC/C;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,EAAE;AACtB;AAEA,SAASG,aAAY,KAAc,MAAsB;AACvD,QAAM,MAAO,IAAY;AACzB,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,KAAK,OAAO,QAAQ,IAAI,CAAC;AAC/B,QAAM,KAAK,OAAO,QAAQ,IAAI,CAAC;AAC/B,QAAM,MAAMH,KAAI,IAAI,OAAO,EAAE;AAE7B,SAAO,qFAAqF,EAAE,SAAS,EAAE,oBAAoB,KAAK,QAAQ,yBAAyB,GAAG,iNAAiN,GAAG,0GAA0G,EAAE,SAAS,EAAE;AACnf;AAEA,SAASC,YAAW,MAAgB,KAAa,MAAyB;AACxE,QAAM,KAAK,KAAK;AAChB,QAAM,OAAO,GAAG;AAGhB,QAAM,WAAY,MAAM,WAAY,MAAM;AAC1C,QAAM,UAAY,MAAM,UAAY,MAAM;AAC1C,QAAM,WAAY,MAAM,WAAY,MAAM;AAC1C,QAAM,UAAY,MAAM,UAAY,MAAM;AAC1C,QAAM,UAAY,MAAM,aAAa,MAAM;AAC3C,QAAM,UAAY,MAAM,aAAa,MAAM;AAG3C,QAAM,IAAI,QAAQ;AAClB,QAAM,WAAW,OAAO,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;AAGnD,MAAI,WAAW;AACf,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,eAAW,QAAQ,IAAI,KAAM,YAAW,KAAK;AAC7C,QAAI,UAAU,SAAU,YAAW;AAAA,EACrC;AACA,MAAI,aAAa,EAAG,YAAW,KAAK,KAAK,CAAC,GAAG,KAAK,UAAU;AAE5D,QAAM,gBAAgB,KAAK,MAAM,WAAW,QAAQ;AAGpD,QAAM,eAAyB,CAAC;AAChC,MAAI,KAAK,MAAM,aAAa,KAAK,MAAM,UAAU,WAAW,UAAU;AAEpE,UAAM,QAAQ,CAAC,GAAG,KAAK,MAAM,SAAS;AACtC,UAAM,aAAa,MAAM,OAAO,OAAK,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AACrE,UAAM,YAAY,MAAM,OAAO,OAAK,KAAK,CAAC,EAAE;AAC5C,UAAM,YAAY,KAAK,IAAI,GAAG,OAAO,QAAQ,QAAQ,IAAI,UAAU;AACnE,UAAM,WAAW,YAAY,IAAI,YAAY,YAAY;AACzD,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAI,MAAM,CAAC,KAAK,EAAG,OAAM,CAAC,IAAI,WAAW,IAAI,WAAW,OAAO,QAAQ,aAAa;AAAA,IACtF;AACA,UAAM,YAAY,MAAM,IAAI,OAAK,OAAO,QAAQ,CAAC,CAAC;AAClD,UAAM,WAAW,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAEpD,UAAM,QAAQ,WAAW,WAAW,WAAW,WAAW;AAC1D,eAAW,KAAK,UAAW,cAAa,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC;AAAA,EACpE,OAAO;AACL,aAAS,IAAI,GAAG,IAAI,UAAU,IAAK,cAAa,KAAK,aAAa;AAAA,EACpE;AACA,QAAM,WAAW,aAAa,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAGvD,QAAM,WAAW,aAAa,IAAI,OAAK,mBAAmB,KAAK,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE;AAIrF,QAAM,YAAY,oBAAI,IAAoC;AAC1D,WAAS,KAAK,GAAG,KAAK,KAAK,KAAK,QAAQ,MAAM;AAC5C,QAAI,SAAS;AACb,eAAW,QAAQ,KAAK,KAAK,EAAE,EAAE,MAAM;AACrC,UAAI,KAAK,KAAK,GAAG;AACf,kBAAU,IAAI,GAAG,EAAE,IAAI,MAAM,IAAI,SAAS;AAC1C,iBAAS,KAAK,GAAG,KAAK,KAAK,IAAI,MAAM;AACnC,oBAAU,IAAI,GAAG,KAAK,EAAE,IAAI,MAAM,IAAI,UAAU;AAAA,QAClD;AAAA,MACF;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,OAAO,KAAK,KAAK,IAAI,CAAC,KAAK,OAAO;AACtC,QAAI,SAAS;AAGb,UAAM,WAAqB,CAAC;AAC5B,QAAI,aAAa;AAGjB,WAAO,aAAa,IAAI,KAAK,QAAQ;AACnC,YAAM,OAAO,IAAI,KAAK,UAAU;AAChC,YAAM,YAAY,UAAU,IAAI,GAAG,EAAE,IAAI,MAAM,EAAE;AAEjD,YAAM,KAAK,KAAK;AAChB,YAAM,YAAsB,CAAC;AAG7B,UAAI,QAAQ;AACZ,eAAS,KAAK,QAAQ,KAAK,SAAS,KAAK,MAAM,KAAK,aAAa,QAAQ,KAAM,UAAS,aAAa,EAAE;AACvG,UAAI,UAAU,EAAG,SAAQ,gBAAgB,KAAK;AAC9C,gBAAU,KAAK,eAAe,KAAK,MAAM,KAAK,CAAC,kBAAkB;AAEjE,UAAI,KAAK,KAAK,EAAG,WAAU,KAAK,sBAAsB,KAAK,EAAE,KAAK;AAGlE,UAAI,KAAK,KAAK,GAAG;AACf,kBAAU,KAAK,6BAA6B;AAAA,MAC9C;AAGA,YAAM,UAAU,kBAAkB,EAAE;AACpC,UAAI,QAAS,WAAU,KAAK,OAAO;AAGnC,UAAI,GAAG,GAAI,WAAU,KAAK,+CAA+C,GAAG,EAAE,KAAK;AAGnF,UAAI,GAAG,IAAI;AACT,cAAM,QAAgC,EAAE,KAAK,OAAO,KAAK,UAAU,KAAK,SAAS;AACjF,kBAAU,KAAK,oBAAoB,MAAM,GAAG,EAAE,KAAK,KAAK,KAAK;AAAA,MAC/D;AAEA,YAAM,OAAO,WAAW,UAAU,KAAK,EAAE,CAAC;AAC1C,eAAS,KAAK,eAAe,IAAI,GAAG,KAAK,KAAK,IAAI,OAAK,gBAAgB,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,SAAS;AACjG,gBAAU,KAAK;AACf;AAAA,IACF;AAKA,UAAM,aAAuB,CAAC;AAC9B,QAAI,cAAc;AAClB,QAAI,WAAW;AAGf,UAAM,gBAAgB;AAKtB,kBAAc;AACd,eAAW;AACX,aAAS,KAAK,GAAG,KAAK,iBAAiB;AACrC,YAAM,YAAY,UAAU,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE;AAC7C,UAAI,cAAc,YAAY;AAE5B,YAAI,SAAS;AACb,iBAAS,KAAK,KAAK,GAAG,MAAM,GAAG,MAAM;AACnC,gBAAM,KAAK,UAAU,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE;AACtC,cAAI,OAAO,WAAW;AAEpB,gBAAI,MAAM;AACV,uBAAW,KAAK,KAAK,KAAK,EAAE,EAAE,MAAM;AAClC,kBAAI,QAAQ,IAAI;AAAE,yBAAS,EAAE;AAAI;AAAA,cAAO;AACxC,qBAAO,EAAE;AAAA,YACX;AACA;AAAA,UACF;AAAA,QACF;AACA,YAAI,KAAK;AACT,iBAAS,KAAK,IAAI,KAAK,KAAK,UAAU,KAAK,aAAa,QAAQ,KAAM,OAAM,aAAa,EAAE;AAC3F,YAAI,OAAO,EAAG,MAAK,gBAAgB;AACnC,YAAI,YAAY,eAAe,KAAK,MAAM,EAAE,CAAC;AAC7C,YAAI,SAAS,EAAG,cAAa,sBAAsB,MAAM;AACzD,qBAAa;AACb,mBAAW,KAAK,uBAAuB,SAAS,qCAAqC;AACrF,cAAM;AAAA,MACR,OAAO;AACL,YAAI,WAAW,SAAS,QAAQ;AAC9B,qBAAW,KAAK,SAAS,QAAQ,CAAC;AAClC,gBAAM,IAAI,KAAK,QAAQ,GAAG,MAAM;AAChC;AAAA,QACF,OAAO;AACL;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO;AACX,QAAI,OAAO,MAAM,GAAG,aAAa,MAAM,WAAW;AAChD,aAAO;AAAA,IACT;AAEA,WAAO,aAAa,IAAI;AAAA,EAAK,WAAW,KAAK,IAAI,CAAC;AAAA;AAAA,EACpD,CAAC,EAAE,KAAK,IAAI;AAGZ,MAAI,aAAa;AACjB,MAAI,GAAG,eAAe;AACpB,UAAM,IAAI,GAAG;AACb,UAAM,gBAAwC,EAAE,OAAO,UAAU,MAAM,UAAU,KAAK,UAAU,QAAQ,UAAU,MAAM,OAAO;AAC/H,UAAM,MAAM,cAAc,EAAE,IAAI,KAAK;AACrC,UAAM,KAAK,KAAK,MAAM,EAAE,KAAK,CAAC;AAC9B,UAAM,MAAM,UAAU,GAAG,WAAW,EAAE,0BAA0B,EAAE,KAAK;AACvE,iBAAa,wBAAwB,GAAG,aAAa,GAAG,eAAe,GAAG,cAAc,GAAG,gBAAgB,GAAG,gBAAgB,GAAG;AAAA,EACnI;AAEA,SAAO;AAAA,6DACoD,KAAK,MAAM,QAAQ,CAAC,oFAAoF,QAAQ,gBAAgB,OAAO,oBAAoB,QAAQ,mBAAmB,OAAO,gBAAgB,OAAO,gBAAgB,OAAO,MAAM,UAAU;AAAA,mBACrS,QAAQ;AAAA,EACzB,IAAI;AAAA;AAEN;AAEA,SAAS,kBAAkB,IAAuB;AAChD,MAAI,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAO,QAAO;AACxD,QAAM,gBAAwC,EAAE,OAAO,UAAU,MAAM,UAAU,KAAK,UAAU,QAAQ,UAAU,MAAM,OAAO;AAE/H,QAAM,SAAS,CAAC,GAAiD,QAAiB;AAChF,QAAI,CAAC,KAAK,CAAC,IAAK,QAAO;AACvB,UAAM,MAAM,cAAc,EAAE,IAAI,KAAK;AACrC,WAAO,MAAM,GAAG,WAAW,GAAG,WAAW,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,0BAA0B,EAAE,KAAK;AAAA,EAChG;AAEA,SAAO,gBAAgB,OAAO,GAAG,KAAK,KAAK,CAAC,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,GAAG,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,OAAO,GAAG,OAAO,OAAO,CAAC;AAC/H;AAEA,SAASD,KAAI,GAAmB;AAAE,SAAO,QAAQ,UAAU,CAAC;AAAG;AAE/D,SAAS,gBAAgB,IAAI,YAAY,CAAC;;;ACzmBnC,IAAM,YAAN,MAAmC;AAAA,EAAnC;AACL,SAAS,SAAS;AAAA;AAAA,EAElB,MAAM,OAAO,KAA4C;AACvD,QAAI;AACF,YAAM,QAAkB,CAAC;AACzB,YAAM,QAAkB,CAAC;AACzB,iBAAW,SAAS,IAAI,MAAM;AAE5B,YAAI,MAAM,UAAU,MAAM,OAAO,SAAS,EAAG,OAAM,KAAK,6FAAsC;AAC9F,YAAI,MAAM,UAAU,MAAM,OAAO,SAAS,EAAG,OAAM,KAAK,6FAAsC;AAE9F,mBAAW,OAAO,MAAM,KAAM,OAAM,KAAKI,eAAc,KAAK,KAAK,CAAC;AAAA,MACpE;AACA,aAAO,QAAQ,QAAQ,OAAO,MAAM,KAAK,MAAM,CAAC,GAAG,KAAK;AAAA,IAC1D,SAAS,GAAQ;AACf,aAAO,KAAK,oBAAoB,GAAG,WAAW,OAAO,CAAC,CAAC,EAAE;AAAA,IAC3D;AAAA,EACF;AACF;AAEA,SAASA,eAAc,MAAmB,OAAyB;AACjE,SAAO,KAAK,QAAQ,SAASC,YAAW,MAAM,KAAK,IAAIC,YAAW,MAAM,KAAK;AAC/E;AAEA,SAASA,YAAW,MAAgB,OAAyB;AAC3D,QAAM,OAAO,KAAK,KAAK,IAAI,OAAK;AAC9B,QAAI,EAAE,QAAQ,OAAQ,QAAO,WAAW,GAAG,KAAK;AAChD,QAAI,EAAE,QAAQ,MAAO,QAAOC,aAAY,CAAC;AACzC,WAAO;AAAA,EACT,CAAC,EAAE,KAAK,EAAE;AAEV,MAAI,KAAK,MAAM,QAAS,QAAO,GAAG,IAAI,OAAO,KAAK,MAAM,OAAO,CAAC,IAAI,IAAI;AAExE,MAAI,KAAK,MAAM,YAAY,QAAW;AACpC,UAAM,SAAS,KAAK,OAAO,KAAK,MAAM,UAAU,CAAC;AACjD,WAAO,GAAG,MAAM,GAAG,KAAK,MAAM,UAAU,OAAO,GAAG,IAAI,IAAI;AAAA,EAC5D;AAGA,MAAI,KAAK,MAAM,SAAS,KAAK,MAAM,UAAU,UAAU,KAAK,MAAM,UAAU,WAAW;AACrF,WAAO,eAAe,KAAK,MAAM,KAAK,KAAK,IAAI;AAAA,EACjD;AAEA,SAAO;AACT;AAEA,SAAS,WAAW,MAAgB,OAAyB;AAE3D,MAAI,KAAK,MAAM,KAAM,OAAM,KAAK,6BAAmB,KAAK,MAAM,IAAI,uDAAe;AACjF,MAAI,KAAK,MAAM,GAAI,OAAM,KAAK,0CAAsB,KAAK,MAAM,EAAE,yDAAiB;AAClF,MAAI,KAAK,MAAM,MAAO,OAAM,KAAK,2CAAuB,KAAK,MAAM,KAAK,uDAAe;AACvF,MAAI,KAAK,MAAM,GAAI,OAAM,KAAK,2CAAuB,KAAK,MAAM,EAAE,uDAAe;AAEjF,MAAI,aAAa;AACjB,QAAM,YAAsB,CAAC;AAC7B,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,IAAI,QAAQ,MAAO,WAAU,KAAK,IAAI,OAAO;AAAA,aACxC,IAAI,QAAQ,WAAW;AAC9B,mBAAa;AACb,YAAM,KAAK,kGAAiC;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,IAAI,UAAU,KAAK,EAAE;AACzB,MAAI,cAAc,MAAM,GAAI,KAAI;AAEhC,MAAI,KAAK,MAAM,KAAK,KAAK,MAAM,EAAG,KAAI,MAAM,CAAC;AAAA,WACpC,KAAK,MAAM,EAAG,KAAI,KAAK,CAAC;AAAA,WACxB,KAAK,MAAM,EAAG,KAAI,IAAI,CAAC;AAChC,MAAI,KAAK,MAAM,EAAG,KAAI,KAAK,CAAC;AAC5B,MAAI,KAAK,MAAM,EAAG,KAAI,MAAM,CAAC;AAC7B,MAAI,KAAK,MAAM,IAAK,KAAI,QAAQ,CAAC;AACjC,MAAI,KAAK,MAAM,IAAK,KAAI,QAAQ,CAAC;AAEjC,SAAO;AACT;AAEA,SAASA,aAAY,KAAsB;AACzC,SAAO,KAAK,IAAI,OAAO,EAAE,UAAU,IAAI,IAAI,WAAW,IAAI,GAAG;AAC/D;AAEA,SAASF,YAAW,MAAgB,OAAyB;AAC3D,MAAI,KAAK,KAAK,WAAW,EAAG,QAAO;AAGnC,MAAI,KAAK,MAAM,KAAM,OAAM,KAAK,+JAAiD;AAEjF,QAAM,OAAO,KAAK,KAAK;AAAA,IAAI,SACzB,KAAK,IAAI,KAAK,IAAI,UAAQ,KAAK,KAAK,IAAI,OAAKC,YAAW,GAAG,KAAK,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC;AAAA,EAC3F;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,OAAO,KAAK,KAAK,CAAC,EAAE,KAAK;AAC/B,SAAK,OAAO,GAAG,GAAG,KAAK,MAAM,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,CAAC,IAAI;AAAA,EAChE;AAEA,SAAO,KAAK,KAAK,IAAI;AACvB;AAEA,SAAS,gBAAgB,IAAI,UAAU,CAAC;;;AC7FjC,IAAM,WAAN,MAAM,UAAS;AAAA,EACZ,YAAoB,KAAyB,QAAgB;AAAzC;AAAyB;AAAA,EAAiB;AAAA;AAAA,EAGtE,OAAO,KAAK,OAA4B,KAAwB;AAC9D,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,IAAI,UAAS,IAAI,YAAY,EAAE,OAAO,KAAK,GAAG,OAAO,IAAI;AAAA,IAClE;AACA,WAAO,IAAI,UAAS,OAAO,OAAO,aAAa,KAAK,CAAC;AAAA,EACvD;AAAA;AAAA,EAGA,aAAa,UAAU,OAA0C,KAAiC;AAChG,QAAI,iBAAiB,cAAc,OAAO,UAAU,UAAU;AAC5D,aAAO,UAAS,KAAK,OAAO,GAAG;AAAA,IACjC;AACA,UAAM,MAAM,MAAM,MAAM,YAAY;AACpC,UAAM,OAAO,IAAI,WAAW,GAAG;AAC/B,UAAM,cAAc,QAAQ,iBAAiB,OAAO,OAAO,MAAM,IAAI,IAAI,WAAc,aAAa,IAAI;AACxG,WAAO,IAAI,UAAS,MAAM,WAAW;AAAA,EACvC;AAAA;AAAA,EAGA,MAAM,GAAG,WAAiD;AACxD,UAAM,UAAU,SAAS,WAAW,KAAK,MAAM;AAC/C,UAAM,UAAU,SAAS,WAAW,SAAS;AAE7C,QAAI,CAAC,QAAS,QAAO,KAAK,oEAAkB,KAAK,MAAM,EAAE;AACzD,QAAI,CAAC,QAAS,QAAO,KAAK,oEAAkB,SAAS,EAAE;AAEvD,UAAM,YAAY,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/C,QAAI,CAAC,UAAU,GAAI,QAAO;AAE1B,UAAM,YAAY,MAAM,QAAQ,OAAO,UAAU,IAAI;AACrD,QAAI,CAAC,UAAU,GAAI,QAAO,EAAE,GAAG,WAAW,OAAO,CAAC,GAAG,UAAU,OAAO,GAAG,UAAU,KAAK,EAAE;AAE1F,WAAO,EAAE,GAAG,WAAW,OAAO,CAAC,GAAG,UAAU,OAAO,GAAG,UAAU,KAAK,EAAE;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,UAAqC;AACzC,UAAM,UAAU,SAAS,WAAW,KAAK,MAAM;AAC/C,QAAI,CAAC,QAAS,QAAO,KAAK,oCAAW,KAAK,MAAM,EAAE;AAClD,WAAO,QAAQ,OAAO,KAAK,GAAG;AAAA,EAChC;AACF;AAEA,SAAS,aAAa,MAA0B;AAC9C,MAAI,KAAK,CAAC,MAAM,MAAQ,KAAK,CAAC,MAAM,GAAM,QAAO;AACjD,MAAI,KAAK,CAAC,MAAM,OAAQ,KAAK,CAAC,MAAM,OAAQ,KAAK,CAAC,MAAM,MAAQ,KAAK,CAAC,MAAM,IAAM,QAAO;AACzF,SAAO;AACT;AAEA,SAAS,OAAO,MAAkC;AAChD,QAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,EAAE,YAAY,IAAI;AACpE;;;AClEO,SAAS,SACd,MACA,IACA,SAAyB,MACzB,QAAQ,GACC;AACT,QAAM,SAAS,GAAG,MAAM,QAAQ,KAAK;AACrC,MAAI,WAAW,OAAQ,QAAO;AAE9B,MAAI,UAAU,QAAQ,MAAM,QAAS,KAAa,IAAI,GAAG;AACvD,eAAW,OAAQ,KAAa,MAAM;AACpC,UAAI,CAAC,SAAS,KAAgB,IAAI,MAAM,QAAQ,CAAC,EAAG,QAAO;AAAA,IAC7D;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,aAAN,MAAiB;AAAA,EACtB,KAAK,MAAe,IAAwB;AAC1C,aAAS,MAAM,EAAE;AAAA,EACnB;AAAA,EAEA,QAA2B,MAAe,WAAwC;AAChF,UAAM,UAAe,CAAC;AACtB,aAAS,MAAM,CAAC,MAAM;AAAE,UAAI,UAAU,CAAC,EAAG,SAAQ,KAAK,CAAC;AAAA,IAAG,CAAC;AAC5D,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,MAAuB;AACjC,UAAM,QAAkB,CAAC;AACzB,aAAS,MAAM,CAAC,MAAM;AACpB,UAAI,EAAE,QAAQ,MAAO,OAAM,KAAK,EAAE,OAAO;AACzC,UAAI,EAAE,QAAQ,KAAM,OAAM,KAAK,IAAI;AACnC,UAAI,EAAE,QAAQ,KAAM,OAAM,KAAK,MAAM;AAAA,IACvC,CAAC;AACD,WAAO,MAAM,KAAK,EAAE;AAAA,EACtB;AACF;;;ACtCO,SAAS,WAAW,MAAuC;AAChE,QAAM,SAAiC,CAAC;AACxC,WAAS,MAAM,CAAC,MAAM;AAAE,WAAO,EAAE,GAAG,KAAK,OAAO,EAAE,GAAG,KAAK,KAAK;AAAA,EAAG,CAAC;AACnE,SAAO;AACT;AAEO,SAAS,aAAa,MAAyB;AACpD,QAAM,SAAmB,CAAC;AAC1B,MAAI,KAAK,QAAQ,OAAQ,QAAO,KAAK,gCAAgC;AACrE,MAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,EAAG,QAAO,KAAK,4BAA4B;AACvE,MAAI,KAAK,KAAK,WAAW,EAAG,QAAO,KAAK,wBAAwB;AAEhE,WAAS,MAAM,CAAC,MAAM;AACpB,QAAI,EAAE,QAAQ,UAAU,EAAE,KAAK,WAAW,GAAG;AAC3C,aAAO,KAAK,gDAAgD;AAAA,IAC9D;AACA,QAAI,EAAE,QAAQ,UAAW,EAAe,KAAK,WAAW,GAAG;AACzD,aAAO,KAAK,yCAAyC;AAAA,IACvD;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":["spanProps","pako","r","coreXml","extractDims","decodeHeaderFooter","toArr","decodePara","decodeGrid","decodeGridSimple","decodeGridFlat","decodeGridText","cellText","tableText","mimeToExt","registerImage","esc","encodeGrid","encodeRun","encodeImage","encodeContent","encodeGrid","encodePara","encodeImage"]}
|
|
1
|
+
{"version":3,"sources":["../src/contract/result.ts","../src/pipeline/registry.ts","../src/model/doc-props.ts","../src/model/builders.ts","../src/safety/ShieldedParser.ts","../src/safety/StyleBridge.ts","../src/toolkit/ArchiveKit.ts","../src/toolkit/XmlKit.ts","../src/toolkit/TextKit.ts","../src/decoders/hwpx/HwpxDecoder.ts","../src/toolkit/BinaryKit.ts","../src/decoders/hwp/HwpScanner.ts","../src/decoders/docx/DocxDecoder.ts","../src/decoders/md/MdDecoder.ts","../src/encoders/hwpx/HwpxEncoder.ts","../src/encoders/docx/DocxEncoder.ts","../src/encoders/md/MdEncoder.ts","../src/pipeline/Pipeline.ts","../src/encoders/html/HtmlEncoder.ts","../src/encoders/hwp/HwpEncoder.ts","../src/walk/TreeWalker.ts","../src/walk/tree-ops.ts"],"sourcesContent":["export type Outcome<T> = Ok<T> | Fail;\n\nexport interface Ok<T> {\n ok: true;\n data: T;\n warns: string[];\n}\n\nexport interface Fail {\n ok: false;\n error: string;\n warns: string[];\n}\n\nexport function succeed<T>(data: T, warns: string[] = []): Ok<T> {\n return { ok: true, data, warns };\n}\n\nexport function fail(error: string, warns: string[] = []): Fail {\n return { ok: false, error, warns };\n}\n","import type { Decoder } from '../contract/decoder';\nimport type { Encoder } from '../contract/encoder';\n\nclass FormatRegistry {\n private decoders = new Map<string, Decoder>();\n private encoders = new Map<string, Encoder>();\n\n registerDecoder(d: Decoder): void { this.decoders.set(d.format, d); }\n registerEncoder(e: Encoder): void { this.encoders.set(e.format, e); }\n\n getDecoder(fmt: string): Decoder | undefined { return this.decoders.get(fmt); }\n getEncoder(fmt: string): Encoder | undefined { return this.encoders.get(fmt); }\n\n supportedInputs(): string[] { return [...this.decoders.keys()]; }\n supportedOutputs(): string[] { return [...this.encoders.keys()]; }\n}\n\nexport const registry = new FormatRegistry();\n","export type Align = 'left' | 'center' | 'right' | 'justify';\n\n// ─── 이미지 배치 ────────────────────────────────────────────\nexport type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front';\nexport type ImgHorzAlign = 'left' | 'center' | 'right';\nexport type ImgVertAlign = 'top' | 'center' | 'bottom';\nexport type ImgHorzRelTo = 'margin' | 'column' | 'page' | 'para';\nexport type ImgVertRelTo = 'margin' | 'line' | 'page' | 'para';\n\nexport interface ImgLayout {\n wrap: ImgWrap;\n horzAlign?: ImgHorzAlign; // 정렬 기준 (xPt 없을 때)\n vertAlign?: ImgVertAlign; // 정렬 기준 (yPt 없을 때)\n horzRelTo?: ImgHorzRelTo; // 가로 기준점\n vertRelTo?: ImgVertRelTo; // 세로 기준점\n xPt?: number; // 명시적 가로 오프셋 (pt)\n yPt?: number; // 명시적 세로 오프셋 (pt)\n distT?: number; // 텍스트와의 거리 top (pt)\n distB?: number;\n distL?: number;\n distR?: number;\n behindDoc?: boolean; // 텍스트 뒤에 배치\n zOrder?: number;\n}\nexport type VAlign = 'top' | 'mid' | 'bot';\nexport type Heading = 1 | 2 | 3 | 4 | 5 | 6;\nexport type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none';\n\nexport interface TextProps {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n sup?: boolean;\n sub?: boolean;\n font?: string;\n pt?: number;\n color?: string;\n bg?: string;\n}\n\nexport interface ParaProps {\n align?: Align;\n heading?: Heading;\n indentPt?: number;\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n listLv?: number;\n listOrd?: boolean;\n listMark?: string;\n}\n\nexport interface Stroke {\n kind: StrokeKind;\n pt: number;\n color: string;\n}\n\nexport interface CellProps {\n top?: Stroke;\n bot?: Stroke;\n left?: Stroke;\n right?: Stroke;\n bg?: string;\n padPt?: number;\n align?: Align;\n va?: VAlign;\n isHeader?: boolean;\n}\n\nexport interface TableLook {\n firstRow?: boolean;\n lastRow?: boolean;\n firstCol?: boolean;\n lastCol?: boolean;\n bandedRows?: boolean;\n bandedCols?: boolean;\n}\n\nexport interface GridProps {\n widthPct?: number;\n colWidths?: number[]; // column widths in points\n defaultStroke?: Stroke;\n look?: TableLook;\n headerRow?: boolean;\n}\n\nexport interface PageDims {\n wPt: number;\n hPt: number;\n mt: number;\n mb: number;\n ml: number;\n mr: number;\n orient?: 'portrait' | 'landscape';\n}\n\nexport interface DocMeta {\n title?: string;\n author?: string;\n subject?: string;\n desc?: string;\n keywords?: string;\n created?: string;\n modified?: string;\n}\n\nexport const A4: PageDims = {\n wPt: 595.28, hPt: 841.89,\n mt: 56.69, mb: 56.69, ml: 70.87, mr: 70.87,\n orient: 'portrait',\n};\n\nexport const A4_LANDSCAPE: PageDims = {\n wPt: 841.89, hPt: 595.28,\n mt: 56.69, mb: 56.69, ml: 70.87, mr: 70.87,\n orient: 'landscape',\n};\n\n/**\n * orient === 'landscape'일 때 wPt < hPt이면 swap,\n * orient === 'portrait'일 때 wPt > hPt이면 swap하여\n * 방향과 치수가 항상 일치하도록 정규화합니다.\n */\n\nexport function normalizeDims(dims: PageDims): PageDims {\n const orient = dims.orient ?? 'portrait';\n if (orient === 'landscape' && dims.wPt < dims.hPt) {\n return { ...dims, wPt: dims.hPt, hPt: dims.wPt };\n }\n if (orient === 'portrait' && dims.wPt > dims.hPt) {\n return { ...dims, wPt: dims.hPt, hPt: dims.wPt };\n }\n return dims;\n}\n\nexport const DEFAULT_STROKE: Stroke = { kind: 'solid', pt: 0.5, color: '000000' };\n","import type {\n DocRoot, SheetNode, ParaNode, SpanNode, ImgNode,\n GridNode, RowNode, CellNode, ContentNode, TxtNode, PageNumNode, BrNode, PbNode,\n} from './doc-tree';\nimport type { TextProps, ParaProps, CellProps, GridProps, DocMeta, PageDims, ImgLayout } from './doc-props';\nimport { A4 } from './doc-props';\n\nexport function buildRoot(meta: DocMeta = {}, kids: SheetNode[] = []): DocRoot {\n return { tag: 'root', meta, kids };\n}\n\nexport function buildSheet(\n kids: ContentNode[] = [],\n dims: PageDims = A4,\n opts?: { header?: ParaNode[]; footer?: ParaNode[] },\n): SheetNode {\n const node: SheetNode = { tag: 'sheet', dims, kids };\n if (opts?.header) node.header = opts.header;\n if (opts?.footer) node.footer = opts.footer;\n return node;\n}\n\nexport function buildPageNum(format?: PageNumNode['format']): PageNumNode {\n return { tag: 'pagenum', format };\n}\n\nexport function buildBr(): BrNode { return { tag: 'br' }; }\nexport function buildPb(): PbNode { return { tag: 'pb' }; }\n\nexport function buildPara(kids: ParaNode['kids'] = [], props: ParaProps = {}): ParaNode {\n return { tag: 'para', props, kids };\n}\n\nexport function buildSpan(content: string, props: TextProps = {}): SpanNode {\n const txt: TxtNode = { tag: 'txt', content };\n return { tag: 'span', props, kids: [txt] };\n}\n\nexport function buildImg(\n b64: string,\n mime: ImgNode['mime'],\n w: number,\n h: number,\n alt?: string,\n layout?: ImgLayout,\n): ImgNode {\n const node: ImgNode = { tag: 'img', b64, mime, w, h };\n if (alt) node.alt = alt;\n if (layout) node.layout = layout;\n return node;\n}\n\nexport function buildGrid(kids: RowNode[], props: GridProps = {}): GridNode {\n return { tag: 'grid', props, kids };\n}\n\nexport function buildRow(kids: CellNode[], heightPt?: number): RowNode {\n const node: RowNode = { tag: 'row', kids };\n if (heightPt != null) node.heightPt = heightPt;\n return node;\n}\n\nexport function buildCell(\n kids: ParaNode[],\n opts: { cs?: number; rs?: number; props?: CellProps } = {},\n): CellNode {\n return { tag: 'cell', cs: opts.cs ?? 1, rs: opts.rs ?? 1, props: opts.props ?? {}, kids };\n}\n","export class ShieldedParser {\n private log: string[] = [];\n\n /** 단일 요소 안전 파싱 */\n guard<T>(fn: () => T, fallback: T, label: string): T {\n try {\n const v = fn();\n if (v == null) {\n this.warn(label, 'returned null/undefined');\n return fallback;\n }\n return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n return fallback;\n }\n }\n\n /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */\n guardAll<I, O>(\n items: I[],\n fn: (x: I, i: number) => O,\n fb: (x: I, i: number) => O,\n label: string,\n ): O[] {\n return items.map((x, i) =>\n this.guard(() => fn(x, i), fb(x, i), `${label}[${i}]`),\n );\n }\n\n /**\n * 표 전용 4단계 폴백\n * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text\n */\n guardGrid<T>(\n node: unknown,\n lv1Full: (n: unknown) => T,\n lv2Grid: (n: unknown) => T,\n lv3Flat: (n: unknown) => T,\n lv4Text: (n: unknown) => T,\n label: string,\n ): { value: T; level: 1 | 2 | 3 | 4 } {\n const levels: [(n: unknown) => T, 1 | 2 | 3 | 4][] = [\n [lv1Full, 1], [lv2Grid, 2], [lv3Flat, 3], [lv4Text, 4],\n ];\n\n for (const [fn, lv] of levels) {\n try {\n const v = fn(node);\n if (v != null) {\n if (lv > 1) this.warn(label, `degraded to level ${lv}`);\n return { value: v, level: lv };\n }\n } catch (e: any) {\n this.warn(label, `Lv${lv} failed: ${e?.message ?? String(e)}`);\n }\n }\n\n this.warn(label, 'ALL LEVELS FAILED — returning lv4Text forced');\n return { value: lv4Text(null), level: 4 };\n }\n\n /** 이미지 안전 파싱 */\n guardImg<T>(\n node: unknown,\n fn: (n: unknown) => T,\n placeholder: (alt: string) => T,\n label: string,\n ): T {\n try {\n const v = fn(node);\n if (v != null) return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n }\n this.warn(label, 'using placeholder image');\n return placeholder(`[이미지 로드 실패: ${label}]`);\n }\n\n private warn(label: string, msg: string): void {\n const w = `[SHIELD] ${label}: ${msg}`;\n console.warn(w);\n this.log.push(w);\n }\n\n flush(): string[] {\n const r = [...this.log];\n this.log = [];\n return r;\n }\n}\n","import type { Align, StrokeKind, Stroke } from '../model/doc-props';\n\n// ─── 단위 변환 ─────────────────────────────────────────────\nexport const Metric = {\n // HWP 세계 (1 inch = 7200 HWPUNIT)\n hwpToPt: (v: number) => v / 100,\n ptToHwp: (v: number) => Math.round(v * 100),\n hwpToDxa: (v: number) => Math.round(v / 5),\n dxaToHwp: (v: number) => Math.round(v * 5),\n hwpToEmu: (v: number) => Math.round(v * 127),\n emuToHwp: (v: number) => Math.round(v / 127),\n\n // DOCX 세계 (1 inch = 1440 dxa, 1 pt = 20 dxa)\n dxaToPt: (v: number) => v / 20,\n ptToDxa: (v: number) => Math.round(v * 20),\n dxaToEmu: (v: number) => Math.round(v * 635),\n emuToDxa: (v: number) => Math.round(v / 635),\n emuToPt: (v: number) => v / 12700,\n ptToEmu: (v: number) => Math.round(v * 12700),\n\n // HWPX charPr height: 1000 = 10pt\n hHeightToPt: (v: number) => v / 100,\n ptToHHeight: (v: number) => Math.round(v * 100),\n\n // DOCX half-point: 24 = 12pt\n halfPtToPt: (v: number) => v / 2,\n ptToHalfPt: (v: number) => Math.round(v * 2),\n} as const;\n\n// ─── 색상 정규화 ───────────────────────────────────────────\nexport function safeHex(raw: string | number | null | undefined): string | undefined {\n if (raw == null) return undefined;\n if (typeof raw === 'number') {\n if (raw <= 0) return '000000';\n if (raw >= 0xFFFFFF) return undefined;\n return raw.toString(16).padStart(6, '0').toUpperCase();\n }\n let s = String(raw).replace(/^#/, '').toUpperCase();\n if (/^[0-9A-F]{3}$/.test(s)) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2];\n if (/^[0-9A-F]{6}$/.test(s)) return s;\n if (s === 'AUTO' || s === 'NONE' || s === 'TRANSPARENT') return undefined;\n return undefined;\n}\n\n// ─── 정렬 정규화 ───────────────────────────────────────────\nconst ALIGN_MAP: Record<string, Align> = {\n LEFT: 'left', CENTER: 'center', RIGHT: 'right', JUSTIFY: 'justify',\n BOTH: 'justify', DISTRIBUTE: 'justify',\n left: 'left', center: 'center', right: 'right', both: 'justify',\n start: 'left', end: 'right',\n};\nexport function safeAlign(raw?: string): Align {\n return ALIGN_MAP[raw ?? ''] ?? 'left';\n}\n\n// ─── 테두리 정규화 ─────────────────────────────────────────\nconst HWPX_STROKE: Record<string, StrokeKind> = {\n SOLID: 'solid', NONE: 'none', DASH: 'dash', DOT: 'dot',\n DOUBLE: 'double', LONG_DASH: 'dash', DASH_DOT: 'dash',\n};\nconst DOCX_STROKE: Record<string, StrokeKind> = {\n single: 'solid', none: 'none', nil: 'none', dashed: 'dash',\n dotted: 'dot', double: 'double', wave: 'solid',\n};\n\nexport function safeStrokeHwpx(type?: string, w?: number, c?: string): Stroke {\n return {\n kind: HWPX_STROKE[type ?? ''] ?? 'solid',\n pt: w != null ? Metric.hwpToPt(w) : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\nexport function safeStrokeDocx(val?: string, sz?: number, c?: string): Stroke {\n return {\n kind: DOCX_STROKE[val ?? ''] ?? 'solid',\n pt: sz != null ? sz / 8 : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\n// ─── 폰트 정규화 ───────────────────────────────────────────\nconst FONT_MAP: Record<string, string> = {\n '맑은 고딕': 'Malgun Gothic',\n '바탕': 'Batang',\n '돋움': 'Dotum',\n '굴림': 'Gulim',\n '한컴바탕': 'Batang',\n '한컴돋움': 'Malgun Gothic',\n '함초롬바탕': 'Batang',\n '함초롬돋움': 'Malgun Gothic',\n};\nexport function safeFont(raw?: string): string {\n return FONT_MAP[raw ?? ''] ?? raw ?? 'Malgun Gothic';\n}\n\n// Reverse mapping: English → Korean (for HWPX encoding)\nconst FONT_MAP_KR: Record<string, string> = {\n 'Malgun Gothic': '맑은 고딕',\n 'Batang': '바탕',\n 'Dotum': '돋움',\n 'Gulim': '굴림',\n};\nexport function safeFontToKr(raw?: string): string {\n return FONT_MAP_KR[raw ?? ''] ?? raw ?? '맑은 고딕';\n}\n","import pako from 'pako';\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nexport const ArchiveKit = {\n async inflate(compressed: Uint8Array): Promise<Uint8Array> {\n return pako.inflate(compressed);\n },\n\n async deflate(data: Uint8Array): Promise<Uint8Array> {\n return pako.deflate(data, { level: 6 });\n },\n\n async unzip(zipData: Uint8Array): Promise<Map<string, Uint8Array>> {\n const files = new Map<string, Uint8Array>();\n const view = new DataView(zipData.buffer, zipData.byteOffset, zipData.byteLength);\n\n let offset = 0;\n while (offset < zipData.length - 4) {\n const sig = view.getUint32(offset, true);\n\n if (sig === 0x04034b50) {\n const compressionMethod = view.getUint16(offset + 8, true);\n const compressedSize = view.getUint32(offset + 18, true);\n const uncompressedSize = view.getUint32(offset + 22, true);\n const fileNameLength = view.getUint16(offset + 26, true);\n const extraLength = view.getUint16(offset + 28, true);\n\n const nameBytes = zipData.subarray(offset + 30, offset + 30 + fileNameLength);\n const name = new TextDecoder('utf-8').decode(nameBytes);\n\n const dataOffset = offset + 30 + fileNameLength + extraLength;\n let fileData: Uint8Array;\n\n if (compressionMethod === 0) {\n fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize);\n } else if (compressionMethod === 8) {\n const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize);\n fileData = pako.inflateRaw(compressed);\n } else {\n throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`);\n }\n\n files.set(name, new Uint8Array(fileData));\n offset = dataOffset + compressedSize;\n } else if (sig === 0x02014b50 || sig === 0x06054b50) {\n break;\n } else {\n offset++;\n }\n }\n\n return files;\n },\n\n async zip(entries: ZipEntry[]): Promise<Uint8Array> {\n const localHeaders: Uint8Array[] = [];\n const centralHeaders: Uint8Array[] = [];\n let localOffset = 0;\n\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n const crc = crc32(entry.data);\n\n // 'mimetype' and 'version.xml' must be stored uncompressed per HWPX spec\n const store = entry.name === 'mimetype' || entry.name === 'version.xml';\n const method = store ? 0 : 8;\n const payload = store ? entry.data : pako.deflateRaw(entry.data, { level: 6 });\n\n // Local file header (30 bytes + name + data)\n const local = new Uint8Array(30 + nameBytes.length + payload.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0, true);\n lv.setUint16(8, method, true);\n lv.setUint16(10, 0, true);\n lv.setUint16(12, 0x0021, true); // date (1980-01-01)\n lv.setUint32(14, crc, true);\n lv.setUint32(18, payload.length, true);\n lv.setUint32(22, entry.data.length, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n local.set(payload, 30 + nameBytes.length);\n\n // Central directory header (46 bytes + name)\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0, true);\n cv.setUint16(10, method, true);\n cv.setUint16(12, 0, true); // mod time\n cv.setUint16(14, 0x0021, true); // mod date (1980-01-01)\n cv.setUint32(16, crc, true);\n cv.setUint32(20, payload.length, true);\n cv.setUint32(24, entry.data.length, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, localOffset, true);\n central.set(nameBytes, 46);\n\n localHeaders.push(local);\n centralHeaders.push(central);\n localOffset += local.length;\n }\n\n const centralDir = concat(centralHeaders);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDir.length, true);\n ev.setUint32(16, localOffset, true);\n ev.setUint16(20, 0, true);\n\n return concat([...localHeaders, centralDir, eocd]);\n },\n};\n\nfunction concat(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const a of arrays) { out.set(a, offset); offset += a.length; }\n return out;\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xFFFFFFFF;\n for (const byte of data) {\n crc ^= byte;\n for (let i = 0; i < 8; i++) {\n crc = (crc & 1) ? (crc >>> 1) ^ 0xEDB88320 : crc >>> 1;\n }\n }\n return (crc ^ 0xFFFFFFFF) >>> 0;\n}\n","import { SaxesParser } from 'saxes';\n\n// Parses XML into an xml2js-compatible object structure:\n// { tagName: [{ _attr: { k: v }, _text: '...', childTag: [...] }] }\nfunction parseXmlStrict(xml: string): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const parser = new SaxesParser({ xmlns: false });\n\n interface Frame { tag: string; obj: Record<string, unknown> }\n const stack: Frame[] = [];\n let result: unknown = null;\n\n parser.on('error', (err: Error) => reject(err));\n\n parser.on('opentag', (node: any) => {\n const obj: Record<string, unknown> = {};\n const attrs = node.attributes as Record<string, string>;\n if (attrs && Object.keys(attrs).length > 0) {\n obj['_attr'] = { ...attrs };\n }\n stack.push({ tag: node.name as string, obj });\n });\n\n const appendText = (text: string) => {\n if (stack.length > 0 && text) {\n const frame = stack[stack.length - 1];\n const cur = frame.obj['_text'];\n frame.obj['_text'] = typeof cur === 'string' ? cur + text : text;\n }\n };\n\n parser.on('text', (text: string) => appendText(text));\n parser.on('cdata', (cdata: string) => appendText(cdata));\n\n parser.on('closetag', () => {\n const frame = stack.pop();\n if (!frame) return;\n const { tag, obj } = frame;\n\n // Drop whitespace-only _text\n if (typeof obj['_text'] === 'string' && !(obj['_text'] as string).trim()) {\n delete obj['_text'];\n }\n\n if (stack.length === 0) {\n result = { [tag]: [obj] };\n } else {\n const parent = stack[stack.length - 1].obj;\n const existing = parent[tag];\n if (Array.isArray(existing)) {\n (existing as unknown[]).push(obj);\n } else {\n parent[tag] = [obj];\n }\n // Track child order for document-order iteration\n if (!parent['_childOrder']) parent['_childOrder'] = [];\n (parent['_childOrder'] as string[]).push(tag);\n }\n });\n\n try {\n parser.write(xml).close();\n resolve(result);\n } catch (e) {\n reject(e);\n }\n });\n}\n\nexport const XmlKit = {\n /** @deprecated Use parseStrict instead */\n async parse(xml: string): Promise<unknown> {\n return parseXmlStrict(xml);\n },\n\n async parseStrict(xml: string): Promise<unknown> {\n return parseXmlStrict(xml);\n },\n\n attr(node: Record<string, unknown>, key: string): string | undefined {\n const a = node['_attr'] as Record<string, string> | undefined;\n return a?.[key];\n },\n\n text(node: Record<string, unknown> | string | undefined): string {\n if (node == null) return '';\n if (typeof node === 'string') return node;\n const t = node['_text'];\n return typeof t === 'string' ? t : '';\n },\n};\n","export const TextKit = {\n decode(data: Uint8Array, encoding = 'utf-8'): string {\n try {\n return new TextDecoder(encoding, { fatal: true }).decode(data);\n } catch {\n return new TextDecoder('utf-8', { fatal: false }).decode(data);\n }\n },\n\n encode(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n },\n\n escapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n },\n\n unescapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\");\n },\n\n normalizeWhitespace(s: string): string {\n return s.replace(/\\s+/g, ' ').trim();\n },\n\n stripControl(s: string): string {\n // eslint-disable-next-line no-control-regex\n return s.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n },\n\n base64Encode(data: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < data.length; i++) {\n binary += String.fromCharCode(data[i]);\n }\n return btoa(binary);\n },\n\n base64Decode(b64: string): Uint8Array {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n },\n};\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, GridNode, ImgNode, PageNumNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { DocMeta, PageDims, TextProps, ParaProps, CellProps, GridProps, Stroke, ImgLayout, ImgWrap, ImgHorzAlign, ImgVertAlign, ImgHorzRelTo, ImgVertRelTo } from '../../model/doc-props';\nimport { A4 } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildImg, buildGrid, buildRow, buildCell, buildPb } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { Metric, safeAlign, safeFont, safeHex, safeStrokeHwpx } from '../../safety/StyleBridge';\nimport { ArchiveKit } from '../../toolkit/ArchiveKit';\nimport { XmlKit } from '../../toolkit/XmlKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\ninterface BorderFillInfo {\n stroke?: Stroke;\n bgColor?: string;\n}\n\ninterface CharPrInfo {\n b?: boolean; i?: boolean; u?: boolean; s?: boolean;\n pt?: number; color?: string; font?: string; bg?: string;\n}\n\ninterface ParaPrInfo {\n align?: string;\n indentPt?: number;\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n}\n\ninterface DecCtx {\n files: Map<string, Uint8Array>;\n shield: ShieldedParser;\n borderFills: Map<number, BorderFillInfo>;\n charPrs: Map<number, CharPrInfo>;\n paraPrs: Map<number, ParaPrInfo>;\n warns: string[];\n}\n\nexport class HwpxDecoder implements Decoder {\n readonly format = 'hwpx';\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const bodyXml = files.get('Contents/section0.xml')\n ?? files.get('section0.xml')\n ?? findSectionFile(files);\n\n if (!bodyXml) return fail('HWPX: section0.xml not found in archive');\n\n const headXml = files.get('Contents/header.xml') ?? files.get('header.xml');\n\n let meta: DocMeta = {};\n let dims: PageDims = { ...A4 };\n let borderFills = new Map<number, BorderFillInfo>();\n let charPrs = new Map<number, CharPrInfo>();\n let paraPrs = new Map<number, ParaPrInfo>();\n\n if (headXml) {\n try {\n const headStr = TextKit.decode(headXml);\n const headObj: any = await XmlKit.parseStrict(headStr);\n if (headObj) {\n meta = extractMeta(headObj);\n dims = extractDims(headObj) ?? dims;\n borderFills = extractBorderFills(headObj);\n charPrs = extractCharPrs(headObj);\n paraPrs = extractParaPrs(headObj);\n }\n } catch {\n // header parse failure is non-fatal\n }\n }\n\n const ctx: DecCtx = { files, shield, borderFills, charPrs, paraPrs, warns };\n\n const bodyStr = TextKit.decode(bodyXml);\n const bodyObj: any = await XmlKit.parseStrict(bodyStr);\n\n const sections = normalizeSections(bodyObj);\n const kids = shield.guardAll(\n sections,\n (sec: any) => decodeSection(sec, dims, ctx),\n () => buildSheet([buildPara([buildSpan('[섹션 파싱 실패]')])], dims),\n 'hwpx:section',\n );\n\n warns.push(...shield.flush());\n return succeed(buildRoot(meta, kids), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWPX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction findSectionFile(files: Map<string, Uint8Array>): Uint8Array | undefined {\n for (const [key, val] of files) {\n if (key.toLowerCase().includes('section') && key.endsWith('.xml')) return val;\n }\n return undefined;\n}\n\nfunction normalizeSections(bodyObj: any): any[] {\n // <hs:sec> (real HWPX), <hp:SEC> (legacy)\n if (bodyObj?.['hs:sec']) return toArr(bodyObj['hs:sec']);\n if (bodyObj?.['hp:SEC']) return toArr(bodyObj['hp:SEC']);\n\n const root = bodyObj?.['hp:HWPML'] ?? bodyObj?.HWPML ?? bodyObj;\n const body = root?.['hp:BODY']?.[0] ?? root?.BODY?.[0] ?? root?.['hp:BODY'] ?? root?.BODY;\n if (!body) return [bodyObj];\n const sections = body?.['hp:SECTION'] ?? body?.SECTION ?? [];\n return Array.isArray(sections) ? sections : [sections];\n}\n\n// Get a tag regardless of namespace/case variations\nfunction getTag(obj: any, ...names: string[]): any[] {\n for (const n of names) {\n const v = obj?.[n];\n if (v != null) return toArr(v);\n }\n return [];\n}\n\nfunction extractMeta(headObj: any): DocMeta {\n try {\n // Support both <hh:HEAD> and <hh:head>\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const info = root?.['hh:DOCSUMMARY']?.[0] ?? root?.DOCSUMMARY?.[0];\n if (!info) return {};\n const a = (k: string) => info?.[`hh:${k}`]?.[0]?._text ?? info?.[k]?.[0]?._text ?? '';\n return { title: a('TITLE') || undefined, author: a('AUTHOR') || undefined, subject: a('SUBJECT') || undefined };\n } catch { return {}; }\n}\n\nfunction extractDims(headObj: any): PageDims | null {\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return null;\n\n const secPrList = refList?.['hh:SECPRLST']?.[0]?.['hh:SECPR']\n ?? refList?.SECPRLST?.[0]?.SECPR;\n const sec = Array.isArray(secPrList) ? secPrList[0] : secPrList;\n if (!sec) return null;\n\n const pa = sec?.['hh:PAGEPROPERTY']?.[0]?._attr ?? sec?.PAGEPROPERTY?.[0]?._attr;\n if (!pa) return null;\n\n return {\n wPt: Metric.hwpToPt(Number(pa.Width ?? 59528)),\n hPt: Metric.hwpToPt(Number(pa.Height ?? 84188)),\n mt: Metric.hwpToPt(Number(pa.TopMargin ?? 5670)),\n mb: Metric.hwpToPt(Number(pa.BottomMargin ?? 4252)),\n ml: Metric.hwpToPt(Number(pa.LeftMargin ?? 8504)),\n mr: Metric.hwpToPt(Number(pa.RightMargin ?? 8504)),\n orient: Number(pa.Landscape) === 1 ? 'landscape' : 'portrait',\n };\n } catch { return null; }\n}\n\nfunction extractBorderFills(headObj: any): Map<number, BorderFillInfo> {\n const map = new Map<number, BorderFillInfo>();\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return map;\n\n const bfList = refList?.['hh:borderFills']?.[0] ?? refList?.['hh:BORDERFILLLIST']?.[0] ?? refList?.BORDERFILLLIST?.[0];\n if (!bfList) return map;\n\n const bfs = getTag(bfList, 'hh:borderFill', 'hh:BORDERFILL');\n for (const bf of bfs) {\n const attr = bf?._attr ?? {};\n const id = Number(attr.id ?? 0);\n if (id === 0) continue;\n\n const info: BorderFillInfo = {};\n\n // Parse border (take top as representative)\n const top = bf?.['hh:topBorder']?.[0]?._attr ?? bf?.['hh:top']?.[0]?._attr ?? bf?.top?.[0]?._attr;\n if (top) {\n // width is in mm (e.g. \"0.18 mm\"), convert mm → pt (1mm ≈ 2.835pt), then pt → hwp (*100) for safeStrokeHwpx\n const mmVal = parseFloat(top.width) || undefined;\n const hwpVal = mmVal != null ? mmVal * 2.835 * 100 : undefined;\n info.stroke = safeStrokeHwpx(top.type, hwpVal, top.color);\n }\n\n // Parse fill (real HWPX uses hc:fillBrush, not hh:fillBrush)\n const fillBrush = bf?.['hc:fillBrush']?.[0] ?? bf?.['hh:fillBrush']?.[0] ?? bf?.['hh:fill']?.[0] ?? bf?.fill?.[0] ?? bf?.fillBrush?.[0];\n if (fillBrush) {\n const winBrush = fillBrush?.['hc:winBrush']?.[0]?._attr ?? fillBrush?.['hh:winBrush']?.[0]?._attr ?? fillBrush?.winBrush?.[0]?._attr;\n if (winBrush?.faceColor && winBrush.faceColor !== 'none') {\n info.bgColor = safeHex(winBrush.faceColor);\n }\n }\n\n map.set(id, info);\n }\n } catch { /* non-fatal */ }\n return map;\n}\n\nfunction extractCharPrs(headObj: any): Map<number, CharPrInfo> {\n const map = new Map<number, CharPrInfo>();\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return map;\n\n const cpList = refList?.['hh:charProperties']?.[0] ?? refList?.['hh:CHARPROPERTIES']?.[0];\n if (!cpList) return map;\n\n const cps = getTag(cpList, 'hh:charPr', 'hh:CHARPR');\n for (const cp of cps) {\n const attr = cp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const info: CharPrInfo = {};\n\n // height → pt\n if (attr.height) info.pt = Metric.hHeightToPt(Number(attr.height));\n\n // textColor\n if (attr.textColor) info.color = safeHex(attr.textColor);\n\n // bold\n if (cp?.['hh:bold']?.[0] != null) info.b = true;\n\n // italic\n if (cp?.['hh:italic']?.[0] != null) info.i = true;\n\n // underline\n const ulAttr = cp?.['hh:underline']?.[0]?._attr;\n if (ulAttr?.type && ulAttr.type !== 'NONE') info.u = true;\n\n // strikeout — shape=\"3D\" is default \"no strikeout\" in real HWPX; only SOLID/etc means active\n const stAttr = cp?.['hh:strikeout']?.[0]?._attr;\n if (stAttr?.shape && stAttr.shape !== 'NONE' && stAttr.shape !== '3D') info.s = true;\n\n // font — from fontRef + fontface\n // (simplified: just store what we find)\n\n map.set(id, info);\n }\n } catch { /* non-fatal */ }\n return map;\n}\n\nfunction extractParaPrs(headObj: any): Map<number, ParaPrInfo> {\n const map = new Map<number, ParaPrInfo>();\n try {\n const root = headObj?.['hh:head']?.[0] ?? headObj?.['hh:HEAD']?.[0] ?? headObj?.HEAD?.[0] ?? headObj;\n const refList = root?.['hh:refList']?.[0] ?? root?.['hh:REFLIST']?.[0] ?? root?.REFLIST?.[0];\n if (!refList) return map;\n\n const ppList = refList?.['hh:paraProperties']?.[0] ?? refList?.['hh:PARAPROPERTIES']?.[0];\n if (!ppList) return map;\n\n const pps = getTag(ppList, 'hh:paraPr', 'hh:PARAPR');\n for (const pp of pps) {\n const attr = pp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const alignNode = pp?.['hh:align']?.[0]?._attr ?? pp?.['hh:ALIGN']?.[0]?._attr;\n const align = alignNode?.horizontal ?? alignNode?.Horizontal;\n\n // Read margin and lineSpacing from direct child OR hp:switch > hp:default/hp:case\n let marginEl = pp?.['hh:margin']?.[0] ?? null;\n let lineSpEl = pp?.['hh:lineSpacing']?.[0] ?? null;\n if (!marginEl) {\n const sw = pp?.['hp:switch']?.[0];\n const container = sw?.['hp:default']?.[0] ?? sw?.['hp:case']?.[0];\n marginEl = container?.['hh:margin']?.[0] ?? null;\n lineSpEl = lineSpEl ?? container?.['hh:lineSpacing']?.[0] ?? null;\n }\n\n let indentPt: number | undefined;\n let spaceBefore: number | undefined;\n let spaceAfter: number | undefined;\n let lineHeight: number | undefined;\n\n if (marginEl) {\n // Handle both hc:intent (our encoder) and hc:indent (Hancom standard)\n const intentEl = marginEl?.['hc:intent']?.[0] ?? marginEl?.['hc:indent']?.[0];\n const prevEl = marginEl?.['hc:prev']?.[0];\n const nextEl = marginEl?.['hc:next']?.[0];\n const intentVal = Number(intentEl?._attr?.value ?? 0);\n const prevVal = Number(prevEl?._attr?.value ?? 0);\n const nextVal = Number(nextEl?._attr?.value ?? 0);\n if (intentVal !== 0) indentPt = Metric.hwpToPt(intentVal);\n if (prevVal > 0) spaceBefore = Metric.hwpToPt(prevVal);\n if (nextVal > 0) spaceAfter = Metric.hwpToPt(nextVal);\n }\n\n if (lineSpEl) {\n const lsAttr = lineSpEl._attr ?? {};\n const lsType = lsAttr.type ?? 'PERCENT';\n const lsVal = Number(lsAttr.value ?? 160);\n if (lsType === 'PERCENT' && lsVal > 0) lineHeight = lsVal / 100;\n }\n\n map.set(id, { align, indentPt, spaceBefore, spaceAfter, lineHeight });\n }\n } catch { /* non-fatal */ }\n return map;\n}\n\n// ─── Section decoding ──────────────────────────────────────\n\nfunction addParaItems(p: any, items: { type: string; node: any }[]): void {\n // Check if this paragraph contains a table in its runs\n const runs = getTag(p, 'hp:run', 'hp:RUN');\n let hasTable = false;\n for (const run of runs) {\n const tbls = getTag(run, 'hp:tbl', 'hp:TABLE');\n for (const tbl of tbls) {\n items.push({ type: 'table', node: tbl });\n hasTable = true;\n }\n }\n // Also add as paragraph unless it's just a table container\n const hasText = runs.some((run: any) => {\n const ts = getTag(run, 'hp:t', 'hp:T', 'hp:CHAR');\n return ts.some((t: any) => {\n const text = typeof t === 'string' ? t : t?._text ?? '';\n return text.trim().length > 0;\n });\n });\n if (hasText || !hasTable) {\n items.push({ type: 'para', node: p });\n }\n}\n\nfunction decodeSection(sec: any, dims: PageDims, ctx: DecCtx) {\n // Try to extract dims from first paragraph's secPr\n const firstParas = getTag(sec, 'hp:p', 'hp:P');\n const pageDims = extractSecPrDims(firstParas[0]) ?? dims;\n\n // Build items list preserving document order via _childOrder\n const items: { type: string; node: any }[] = [];\n const paras = getTag(sec, 'hp:p', 'hp:P');\n const childOrder = sec?.['_childOrder'] as string[] | undefined;\n\n if (Array.isArray(childOrder)) {\n let pi = 0;\n for (const tag of childOrder) {\n if ((tag === 'hp:p' || tag === 'hp:P') && pi < paras.length) {\n const p = paras[pi++];\n addParaItems(p, items);\n }\n }\n // Append any remaining\n while (pi < paras.length) addParaItems(paras[pi++], items);\n } else {\n // No order info — process paragraphs sequentially\n for (const p of paras) addParaItems(p, items);\n }\n\n const kids: ContentNode[] = ctx.shield.guardAll(\n items,\n (item: any) => {\n if (item.type === 'table') {\n const { value } = ctx.shield.guardGrid(\n item.node,\n (n) => decodeGrid(n, ctx),\n (n) => decodeGridSimple(n, ctx),\n (n) => decodeGridFlat(n),\n (n) => decodeGridText(n) as unknown as GridNode,\n 'hwpx:table',\n );\n return value;\n }\n return decodePara(item.node, ctx);\n },\n () => buildPara([buildSpan('[파싱 실패]')]),\n 'hwpx:content',\n );\n\n // Decode header/footer\n const headerParas = decodeHeaderFooter(sec, 'header', ctx);\n const footerParas = decodeHeaderFooter(sec, 'footer', ctx);\n\n return buildSheet(\n kids.filter(Boolean) as ContentNode[],\n pageDims,\n { header: headerParas, footer: footerParas },\n );\n}\n\nfunction extractSecPrDims(p: any): PageDims | null {\n if (!p) return null;\n try {\n const runs = getTag(p, 'hp:run', 'hp:RUN');\n for (const run of runs) {\n const secPr = run?.['hp:secPr']?.[0] ?? run?.['hp:SECPR']?.[0];\n if (!secPr) continue;\n const pagePr = secPr?.['hp:pagePr']?.[0]?._attr ?? secPr?.['hp:PAGEPR']?.[0]?._attr;\n if (!pagePr) continue;\n const margin = secPr?.['hp:pagePr']?.[0]?.['hp:margin']?.[0]?._attr\n ?? secPr?.['hp:PAGEPR']?.[0]?.['hp:MARGIN']?.[0]?._attr ?? {};\n return {\n wPt: Metric.hwpToPt(Number(pagePr.width ?? 59528)),\n hPt: Metric.hwpToPt(Number(pagePr.height ?? 84188)),\n mt: Metric.hwpToPt(Number(margin.top ?? 5670)),\n mb: Metric.hwpToPt(Number(margin.bottom ?? 4252)),\n ml: Metric.hwpToPt(Number(margin.left ?? 8504)),\n mr: Metric.hwpToPt(Number(margin.right ?? 8504)),\n orient: pagePr.landscape === 'NARROWLY' ? 'landscape' : 'portrait',\n };\n }\n } catch { /* ignore */ }\n return null;\n}\n\nfunction decodeHeaderFooter(sec: any, kind: 'header' | 'footer', ctx: DecCtx): ParaNode[] | undefined {\n try {\n const hf = sec?.['hp:headerFooter']?.[0] ?? sec?.['hp:HEADERFOOTER']?.[0]\n ?? sec?.headerFooter?.[0] ?? sec?.HEADERFOOTER?.[0];\n if (!hf) return undefined;\n\n const part = hf?.['hp:' + kind]?.[0] ?? hf?.['hp:' + kind.toUpperCase()]?.[0]\n ?? hf?.[kind]?.[0] ?? hf?.[kind.toUpperCase()]?.[0];\n if (!part) return undefined;\n\n const paras = getTag(part, 'hp:p', 'hp:P');\n if (paras.length === 0) return undefined;\n\n return paras.map((p: any) => decodePara(p, ctx));\n } catch {\n return undefined;\n }\n}\n\n// ─── Paragraph & run decoding ──────────────────────────────\n\nfunction decodePara(p: any, ctx: DecCtx): ParaNode {\n const pAttr = p?._attr ?? {};\n const paraPrIdRef = Number(pAttr.paraPrIDRef ?? -1);\n\n // Resolve paraPr from IDRef or inline\n let align: string | undefined;\n const paraPrDef = ctx.paraPrs.get(paraPrIdRef);\n if (paraPrDef?.align) align = paraPrDef.align;\n\n // Check inline PARAPR too\n const inlineParaPr = p?.['hp:PARAPR']?.[0] ?? p?.['hp:paraPr']?.[0] ?? p?.PARAPR?.[0];\n if (inlineParaPr) {\n const alignNode = inlineParaPr?.['hp:ALIGN']?.[0]?._attr ?? inlineParaPr?.['hp:align']?.[0]?._attr\n ?? inlineParaPr?.ALIGN?.[0]?._attr;\n if (alignNode?.Type) align = alignNode.Type;\n if (alignNode?.horizontal) align = alignNode.horizontal;\n }\n\n const inlineAttr = inlineParaPr?._attr ?? {};\n const props: ParaProps = { align: safeAlign(align) };\n\n // Apply spacing/indent/lineHeight from paraPr definition\n if (paraPrDef) {\n if (paraPrDef.indentPt !== undefined) props.indentPt = paraPrDef.indentPt;\n if (paraPrDef.spaceBefore !== undefined) props.spaceBefore = paraPrDef.spaceBefore;\n if (paraPrDef.spaceAfter !== undefined) props.spaceAfter = paraPrDef.spaceAfter;\n if (paraPrDef.lineHeight !== undefined) props.lineHeight = paraPrDef.lineHeight;\n }\n\n // List support (from inline attr)\n if (inlineAttr.listType) {\n props.listOrd = inlineAttr.listType === 'DIGIT' || inlineAttr.listType === 'DECIMAL';\n props.listLv = Number(inlineAttr.listLevel ?? 0);\n }\n\n const runs = getTag(p, 'hp:run', 'hp:RUN');\n const kids: (SpanNode | ImgNode)[] = [];\n\n for (const run of runs) {\n // Images inside run\n const pics = getTag(run, 'hp:pic', 'hp:PIC');\n for (const pic of pics) {\n const img = decodePic(pic, ctx);\n if (img) kids.push(img);\n }\n\n // Page number\n const pageNums = getTag(run, 'hp:pageNum', 'hp:PAGENUM');\n if (pageNums.length > 0) {\n const pn = pageNums[0]?._attr ?? {};\n const fmt = pn.formatType === 'ROMAN_LOWER' ? 'roman' as const\n : pn.formatType === 'ROMAN_UPPER' ? 'romanCaps' as const\n : 'decimal' as const;\n const pageNumNode: PageNumNode = { tag: 'pagenum', format: fmt };\n const spanProps = resolveCharPr(run, ctx);\n kids.push({ tag: 'span', props: spanProps, kids: [pageNumNode] });\n continue;\n }\n\n // Text\n const textNodes = getTag(run, 'hp:t', 'hp:T', 'hp:CHAR');\n const content = textNodes.map((t: any) => typeof t === 'string' ? t : t?._text ?? t?._ ?? '').join('');\n\n // Skip empty secPr-only runs\n if (content === '' && (run?.['hp:secPr']?.[0] || run?.['hp:SECPR']?.[0]) && pics.length === 0) continue;\n\n const spanProps = resolveCharPr(run, ctx);\n kids.push(buildSpan(content, spanProps));\n }\n\n // pageBreak=\"1\" → prepend a pb node in its own span\n if (pAttr.pageBreak === '1') {\n kids.unshift({ tag: 'span', props: {}, kids: [buildPb()] });\n }\n\n return buildPara(kids.filter(Boolean) as ParaNode['kids'], props);\n}\n\nfunction resolveCharPr(run: any, ctx: DecCtx): TextProps {\n const runAttr = run?._attr ?? {};\n const charPrIdRef = Number(runAttr.charPrIDRef ?? -1);\n\n // Try IDRef first\n const def = ctx.charPrs.get(charPrIdRef);\n if (def) {\n return {\n b: def.b, i: def.i, u: def.u, s: def.s,\n pt: def.pt, color: def.color, font: def.font, bg: def.bg,\n };\n }\n\n // Fallback: inline CHARPR\n const ca = run?.['hp:CHARPR']?.[0]?._attr ?? run?.['hp:charPr']?.[0]?._attr ?? run?.CHARPR?.[0]?._attr ?? {};\n return {\n b: ca.Bold === '1' || ca.Bold === 'true' || undefined,\n i: ca.Italic === '1' || ca.Italic === 'true' || undefined,\n u: ca.Underline ? ca.Underline !== 'NONE' : undefined,\n s: ca.Strikeout ? ca.Strikeout !== 'NONE' : undefined,\n font: safeFont(ca.FontName ?? ca.FaceNameHangul),\n pt: ca.Height ? Metric.hHeightToPt(Number(ca.Height)) : undefined,\n color: safeHex(ca.TextColor),\n bg: safeHex(ca.BgColor),\n };\n}\n\n// ─── Image decoding ────────────────────────────────────────\n\nfunction decodePic(pic: any, ctx: DecCtx): ImgNode | null {\n try {\n const szAttr = pic?.['hp:sz']?.[0]?._attr ?? pic?.sz?.[0]?._attr ?? {};\n const w = Metric.hwpToPt(Number(szAttr.width ?? 0));\n const h = Metric.hwpToPt(Number(szAttr.height ?? 0));\n\n // Try multiple tag patterns for image reference\n const imgNode = pic?.['hp:img']?.[0]?._attr ?? pic?.['hc:img']?.[0]?._attr\n ?? pic?.img?.[0]?._attr ?? {};\n const binRef = imgNode.binaryItemIDRef ?? imgNode.BinaryItemIDRef;\n if (!binRef) return null;\n\n // Find binary data\n let imgData: Uint8Array | undefined;\n for (const [key, val] of ctx.files) {\n if (key.includes(binRef) || key.toLowerCase().includes(binRef.toLowerCase())) {\n imgData = val;\n break;\n }\n }\n if (!imgData) return null;\n\n const ext = binRef.split('.').pop()?.toLowerCase() ?? 'png';\n const mimeMap: Record<string, ImgNode['mime']> = {\n png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg',\n gif: 'image/gif', bmp: 'image/bmp',\n };\n\n // ── hp:pos에서 layout 추출 ───────────────────────────────\n const posAttr = pic?.['hp:pos']?.[0]?._attr ?? pic?.pos?.[0]?._attr ?? {};\n const layout = extractHwpxLayout(posAttr, pic);\n\n return buildImg(TextKit.base64Encode(imgData), mimeMap[ext] ?? 'image/png', w, h, undefined, layout);\n } catch {\n return null;\n }\n}\n\nfunction extractHwpxLayout(posAttr: any, pic: any): ImgLayout {\n const treatAsChar = posAttr.treatAsChar === '1' || posAttr.treatAsChar === 'true';\n if (treatAsChar) return { wrap: 'inline' };\n\n // textWrap → wrap\n const textWrap: string = (pic?._attr?.textWrap ?? pic?.['hp:pic']?.[0]?._attr?.textWrap ?? 'TOP_AND_BOTTOM');\n const wrapMap: Record<string, ImgWrap> = {\n TOP_AND_BOTTOM: 'square',\n SQUARE: 'square',\n BOTH_SIDES: 'tight',\n LEFT: 'tight',\n RIGHT: 'tight',\n LARGER_ONLY: 'tight',\n SMALLER_ONLY: 'tight',\n LARGEST_ONLY: 'tight',\n BEHIND_TEXT: 'behind',\n FRONT_TEXT: 'none',\n };\n const wrap: ImgWrap = wrapMap[textWrap] ?? 'square';\n\n // 기준점\n const horzRelToMap: Record<string, ImgHorzRelTo> = {\n PARA: 'para', MARGIN: 'margin', PAGE: 'page', COLUMN: 'column',\n };\n const vertRelToMap: Record<string, ImgVertRelTo> = {\n PARA: 'para', MARGIN: 'margin', PAGE: 'page', PAPER: 'page', LINE: 'line',\n };\n const horzRelTo = horzRelToMap[posAttr.horzRelTo ?? ''] ?? 'para';\n const vertRelTo = vertRelToMap[posAttr.vertRelTo ?? ''] ?? 'para';\n\n // 정렬\n const horzAlignMap: Record<string, ImgHorzAlign> = { LEFT: 'left', CENTER: 'center', RIGHT: 'right' };\n const vertAlignMap: Record<string, ImgVertAlign> = { TOP: 'top', CENTER: 'center', BOTTOM: 'bottom' };\n const horzAlign = horzAlignMap[posAttr.horzAlign ?? ''];\n const vertAlign = vertAlignMap[posAttr.vertAlign ?? ''];\n\n // 오프셋\n const horzOffset = Number(posAttr.horzOffset ?? 0);\n const vertOffset = Number(posAttr.vertOffset ?? 0);\n const xPt = horzOffset !== 0 ? Metric.hwpToPt(horzOffset) : undefined;\n const yPt = vertOffset !== 0 ? Metric.hwpToPt(vertOffset) : undefined;\n\n return { wrap, horzAlign, vertAlign, horzRelTo, vertRelTo, xPt, yPt };\n}\n\n// ─── Table decoding ────────────────────────────────────────\n\nfunction decodeGrid(tbl: any, ctx: DecCtx): GridNode {\n const tblAttr = tbl?._attr ?? {};\n const borderFillId = Number(tblAttr.borderFillIDRef ?? 0);\n const borderFill = ctx.borderFills.get(borderFillId);\n const headerRow = tblAttr.repeatHeader === '1';\n\n const gridProps: GridProps = { headerRow: headerRow || undefined };\n if (borderFill?.stroke) gridProps.defaultStroke = borderFill.stroke;\n\n const rowArr = getTag(tbl, 'hp:tr', 'hp:ROW');\n\n // Read column widths from the first row that has all cs=1 cells\n for (const row of rowArr) {\n const cells = getTag(row, 'hp:tc', 'hp:CELL');\n const rowWidths: number[] = [];\n let allSingle = true;\n for (const cell of cells) {\n const cellSpanAttr = cell?.['hp:cellSpan']?.[0]?._attr ?? {};\n const cs = Number(cellSpanAttr.colSpan ?? cell?._attr?.ColSpan ?? 1);\n if (cs > 1) { allSingle = false; break; }\n const szAttr = cell?.['hp:cellSz']?.[0]?._attr ?? {};\n const w = Number(szAttr.width ?? 0);\n rowWidths.push(Metric.hwpToPt(w));\n }\n if (allSingle && rowWidths.length > 0 && rowWidths.some(w => w > 0)) {\n gridProps.colWidths = rowWidths;\n break;\n }\n }\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, 'hp:tc', 'hp:CELL');\n const cellNodes = cellArr.map((cell: any) => {\n const ca = cell?._attr ?? {};\n\n // Cell borderFill\n const cellBfId = Number(ca.borderFillIDRef ?? 0);\n const cellBf = ctx.borderFills.get(cellBfId);\n\n const cellProps: CellProps = {\n bg: cellBf?.bgColor ?? safeHex(ca.BgColor),\n };\n\n if (cellBf?.stroke) {\n cellProps.top = cellBf.stroke;\n cellProps.bot = cellBf.stroke;\n cellProps.left = cellBf.stroke;\n cellProps.right = cellBf.stroke;\n }\n\n // Vertical alignment from subList\n const subList = cell?.['hp:subList']?.[0] ?? cell?.subList?.[0];\n const subAttr = subList?._attr ?? {};\n if (subAttr.vertAlign) {\n const vaMap: Record<string, 'top' | 'mid' | 'bot'> = {\n TOP: 'top', CENTER: 'mid', BOTTOM: 'bot',\n };\n cellProps.va = vaMap[subAttr.vertAlign];\n }\n\n // Colspan/rowspan from cellSpan element or attributes\n const cellSpan = cell?.['hp:cellSpan']?.[0]?._attr ?? {};\n const cs = Number(cellSpan.colSpan ?? ca.ColSpan ?? 1);\n const rs = Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1);\n\n // Parse paragraphs\n let paras: ParaNode[];\n if (subList) {\n const subParas = getTag(subList, 'hp:p', 'hp:P');\n paras = subParas.map((p: any) => decodePara(p, ctx));\n } else {\n paras = getTag(cell, 'hp:p', 'hp:P').map((p: any) => decodePara(p, ctx));\n }\n\n return buildCell(\n paras.length > 0 ? paras : [buildPara([buildSpan('')])],\n { cs, rs, props: cellProps },\n );\n });\n // Row height: read from the first cell's cellSz height\n let rowHeightPt: number | undefined;\n const firstCellForH = cellArr[0];\n if (firstCellForH) {\n const hSz = firstCellForH?.['hp:cellSz']?.[0]?._attr ?? {};\n const hVal = Number(hSz.height ?? 0);\n if (hVal > 0) rowHeightPt = Metric.hwpToPt(hVal);\n }\n return buildRow(cellNodes, rowHeightPt);\n });\n return buildGrid(rowNodes, gridProps);\n}\n\nfunction decodeGridSimple(tbl: any, ctx: DecCtx): GridNode {\n const rowArr = getTag(tbl, 'hp:tr', 'hp:ROW');\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, 'hp:tc', 'hp:CELL');\n return buildRow(cellArr.map((cell: any) => buildCell([buildPara([buildSpan(cellText(cell))])])));\n });\n return buildGrid(rowNodes);\n}\n\nfunction decodeGridFlat(tbl: any): GridNode {\n return buildGrid([buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])])]);\n}\n\nfunction decodeGridText(tbl: any): ParaNode {\n return buildPara([buildSpan(tableText(tbl))]);\n}\n\nfunction cellText(cell: any): string {\n const subList = cell?.['hp:subList']?.[0] ?? cell?.subList?.[0];\n const source = subList ?? cell;\n return getTag(source, 'hp:p', 'hp:P').map((p: any) =>\n getTag(p, 'hp:run', 'hp:RUN').map((r: any) =>\n getTag(r, 'hp:t', 'hp:T').map((t: any) => typeof t === 'string' ? t : t?._text ?? t?._ ?? '').join(''),\n ).join(''),\n ).join(' ');\n}\n\nfunction tableText(tbl: any): string {\n return getTag(tbl, 'hp:tr', 'hp:ROW').map((row: any) =>\n getTag(row, 'hp:tc', 'hp:CELL').map((c: any) => cellText(c)).join('\\t'),\n ).join('\\n');\n}\n\nfunction toArr(v: any): any[] { return v == null ? [] : Array.isArray(v) ? v : [v]; }\n\n// Auto-register\nregistry.registerDecoder(new HwpxDecoder());\n","/**\n * OLE2 Compound File Binary Format (CFB) parser.\n * Used for legacy HWP 5.0 files.\n */\n\nexport const BinaryKit = {\n readU16LE(buf: Uint8Array, offset: number): number {\n return buf[offset] | (buf[offset + 1] << 8);\n },\n\n readU32LE(buf: Uint8Array, offset: number): number {\n return (\n (buf[offset] | (buf[offset + 1] << 8) | (buf[offset + 2] << 16)) >>> 0\n ) + buf[offset + 3] * 0x1000000;\n },\n\n isOle2(data: Uint8Array): boolean {\n return (\n data.length >= 8 &&\n data[0] === 0xD0 && data[1] === 0xCF &&\n data[2] === 0x11 && data[3] === 0xE0 &&\n data[4] === 0xA1 && data[5] === 0xB1 &&\n data[6] === 0x1A && data[7] === 0xE1\n );\n },\n\n parseCfb(data: Uint8Array): Map<string, Uint8Array> {\n const streams = new Map<string, Uint8Array>();\n\n if (!this.isOle2(data)) {\n throw new Error('Not a valid OLE2 file');\n }\n\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const sectorSize = 1 << view.getUint16(30, true);\n const miniSectorSz = 1 << view.getUint16(32, true);\n const dirFirstSec = view.getUint32(48, true);\n const miniStreamCutoff = view.getUint32(56, true);\n const miniFatFirst = view.getUint32(60, true);\n const miniFatCnt = view.getUint32(64, true);\n const difatFirst = view.getUint32(68, true);\n\n const ENDOFCHAIN = 0xFFFFFFFE;\n const FREESECT = 0xFFFFFFFF;\n\n const sectorAt = (sec: number): Uint8Array =>\n data.subarray(512 + sec * sectorSize, 512 + (sec + 1) * sectorSize);\n\n // Build FAT from DIFAT\n const fatSecNums: number[] = [];\n for (let i = 0; i < 109; i++) {\n const s = view.getUint32(76 + i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n if (difatFirst !== ENDOFCHAIN && difatFirst !== FREESECT) {\n let difSec = difatFirst;\n while (difSec !== ENDOFCHAIN && difSec !== FREESECT) {\n const sec = sectorAt(difSec);\n const sv = new DataView(sec.buffer, sec.byteOffset, sec.byteLength);\n for (let i = 0; i < (sectorSize / 4) - 1; i++) {\n const s = sv.getUint32(i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n difSec = sv.getUint32(sectorSize - 4, true);\n }\n }\n\n const fat: number[] = [];\n for (const sec of fatSecNums) {\n const s = sectorAt(sec);\n const sv = new DataView(s.buffer, s.byteOffset, s.byteLength);\n for (let i = 0; i < sectorSize / 4; i++) {\n fat.push(sv.getUint32(i * 4, true));\n }\n }\n\n const readChain = (startSec: number): Uint8Array => {\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < fat.length) {\n chunks.push(sectorAt(sec));\n sec = fat[sec];\n }\n return concatUint8(chunks);\n };\n\n // Directory entries\n const dirData = readChain(dirFirstSec);\n const dirView = new DataView(dirData.buffer, dirData.byteOffset, dirData.byteLength);\n const dirCount = dirData.length / 128;\n\n interface DirEntry {\n name: string;\n type: number;\n startSec: number;\n size: number;\n childId: number;\n siblingLeftId: number;\n siblingRightId: number;\n }\n\n const dirEntries: DirEntry[] = [];\n for (let i = 0; i < dirCount; i++) {\n const base = i * 128;\n const nameLen = dirView.getUint16(base + 64, true);\n const nameBytes = dirData.subarray(base, base + Math.max(0, nameLen - 2));\n const name = new TextDecoder('utf-16le').decode(nameBytes);\n const type = dirData[base + 66];\n const childId = dirView.getInt32(base + 76, true);\n const sibLeft = dirView.getInt32(base + 68, true);\n const sibRight = dirView.getInt32(base + 72, true);\n const startSec = dirView.getUint32(base + 116, true);\n const size = dirView.getUint32(base + 120, true);\n dirEntries.push({ name, type, startSec, size, childId, siblingLeftId: sibLeft, siblingRightId: sibRight });\n }\n\n // Mini stream\n const rootEntry = dirEntries[0];\n let miniStreamData: Uint8Array | null = null;\n let miniFat: number[] = [];\n\n if (rootEntry && rootEntry.startSec !== ENDOFCHAIN && rootEntry.startSec !== FREESECT) {\n miniStreamData = readChain(rootEntry.startSec);\n }\n\n if (miniFatCnt > 0 && miniFatFirst !== ENDOFCHAIN && miniFatFirst !== FREESECT) {\n const mfData = readChain(miniFatFirst);\n const mfv = new DataView(mfData.buffer, mfData.byteOffset, mfData.byteLength);\n for (let i = 0; i < mfData.length / 4; i++) {\n miniFat.push(mfv.getUint32(i * 4, true));\n }\n }\n\n const readMiniChain = (startSec: number, size: number): Uint8Array => {\n if (!miniStreamData) return new Uint8Array(0);\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n let remaining = size;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < miniFat.length && remaining > 0) {\n const off = sec * miniSectorSz;\n const chunk = miniStreamData.subarray(off, off + Math.min(miniSectorSz, remaining));\n chunks.push(chunk);\n remaining -= chunk.length;\n sec = miniFat[sec];\n }\n return concatUint8(chunks).subarray(0, size);\n };\n\n // DFS traversal\n const visit = (id: number, path: string): void => {\n if (id < 0 || id >= dirEntries.length) return;\n const entry = dirEntries[id];\n const fullPath = path ? `${path}/${entry.name}` : entry.name;\n\n if (entry.type === 2) {\n let streamData: Uint8Array;\n if (entry.size < miniStreamCutoff && miniStreamData) {\n streamData = readMiniChain(entry.startSec, entry.size);\n } else {\n streamData = readChain(entry.startSec).subarray(0, entry.size);\n }\n streams.set(fullPath, streamData);\n streams.set(entry.name, streamData);\n }\n\n if (entry.childId >= 0) visit(entry.childId, fullPath);\n if (entry.siblingLeftId >= 0) visit(entry.siblingLeftId, path);\n if (entry.siblingRightId >= 0) visit(entry.siblingRightId, path);\n };\n\n if (dirEntries.length > 0 && dirEntries[0].childId >= 0) {\n visit(dirEntries[0].childId, '');\n }\n\n return streams;\n },\n};\n\nfunction concatUint8(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const a of arrays) { out.set(a, off); off += a.length; }\n return out;\n}\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, ImgNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { Align, Stroke, StrokeKind, PageDims, TextProps, ParaProps, CellProps, GridProps } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildGrid, buildRow, buildCell, buildImg } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { BinaryKit } from '../../toolkit/BinaryKit';\nimport { Metric, safeHex, safeFont } from '../../safety/StyleBridge';\nimport { registry } from '../../pipeline/registry';\nimport { A4 } from '../../model/doc-props';\nimport pako from 'pako';\n\n/* ═══════════════════════════════════════════════════════════════\n HWP 5.0 Tag Constants\n ═══════════════════════════════════════════════════════════════ */\n\nconst HWPTAG_BEGIN = 16;\n\nconst TAG_FACE_NAME = HWPTAG_BEGIN + 3; // 19\nconst TAG_BORDER_FILL = HWPTAG_BEGIN + 4; // 20\nconst TAG_CHAR_SHAPE = HWPTAG_BEGIN + 5; // 21\nconst TAG_PARA_SHAPE = HWPTAG_BEGIN + 9; // 25\nconst TAG_PARA_HEADER = HWPTAG_BEGIN + 50; // 66\nconst TAG_PARA_TEXT = HWPTAG_BEGIN + 51; // 67\nconst TAG_PARA_CHAR_SHAPE = HWPTAG_BEGIN + 52; // 68\nconst TAG_CTRL_HEADER = HWPTAG_BEGIN + 55; // 71\nconst TAG_PAGE_DEF = HWPTAG_BEGIN + 57; // 73\n\n// TABLE / CELL tags vary by HWP version\nconst TAG_LIST_HEADER = HWPTAG_BEGIN + 56; // 72\nconst TAG_TABLE_A = HWPTAG_BEGIN + 61; // 77\nconst TAG_CELL_A = HWPTAG_BEGIN + 62; // 78\nconst TAG_TABLE_B = HWPTAG_BEGIN + 64; // 80\nconst TAG_CELL_B = HWPTAG_BEGIN + 65; // 81\n\nfunction isTableTag(t: number) { return t === TAG_TABLE_A || t === TAG_TABLE_B; }\nfunction isCellTag(t: number) { return t === TAG_CELL_A || t === TAG_CELL_B || t === TAG_LIST_HEADER; }\n\n// CTRL_HEADER ctrlId values (UINT32-LE as ASCII)\nconst CTRL_TABLE = 0x74626C20; // ' lbt'\nconst CTRL_IMAGE = 0x696D6720; // 'img '\nconst CTRL_OBJ = 0x6F626A20; // 'obj '\nconst CTRL_FIG = 0x66696720; // 'fig '\n\n/* ═══════════════════════════════════════════════════════════════\n Types\n ═══════════════════════════════════════════════════════════════ */\n\ninterface HwpRecord {\n tag: number;\n level: number;\n data: Uint8Array;\n}\n\ninterface HwpCharShape {\n faceIds: number[];\n height: number;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikeout: boolean;\n superscript: boolean;\n subscript: boolean;\n textColor: string;\n}\n\ninterface HwpParaShape {\n align: Align;\n spaceBefore: number;\n spaceAfter: number;\n lineSpacing: number;\n indent: number;\n}\n\ninterface HwpBorderFill {\n borders: { type: number; widthPt: number; color: string }[];\n bgColor?: string;\n}\n\ninterface DocInfo {\n faceNames: string[];\n charShapes: HwpCharShape[];\n paraShapes: HwpParaShape[];\n borderFills: HwpBorderFill[];\n}\n\ninterface ParsedChar { pos: number; ch: string }\ninterface ParsedCtrl { pos: number; ctrlId: number; objId: number; matched: boolean }\ninterface ParaTextResult { chars: ParsedChar[]; controls: ParsedCtrl[] }\n\ninterface OleObject {\n id: number;\n data: Uint8Array;\n mimeType: string;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Low-level record parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseRecords(data: Uint8Array): HwpRecord[] {\n const out: HwpRecord[] = [];\n let off = 0;\n while (off + 4 <= data.length) {\n const hdr = BinaryKit.readU32LE(data, off);\n const tag = hdr & 0x3FF;\n const level = (hdr >> 10) & 0x3FF;\n let size = (hdr >> 20) & 0xFFF;\n off += 4;\n if (size === 0xFFF) {\n if (off + 4 > data.length) break;\n size = BinaryKit.readU32LE(data, off);\n off += 4;\n }\n if (off + size > data.length) break;\n out.push({ tag, level, data: data.subarray(off, off + size) });\n off += size;\n }\n return out;\n}\n\nfunction tryInflate(data: Uint8Array): Uint8Array {\n try { return pako.inflate(data); } catch {\n try { return pako.inflateRaw(data); } catch { return data; }\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n FileHeader\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseFileHeader(buf: Uint8Array) {\n if (buf.length < 40) return { compressed: true, encrypted: false };\n const props = BinaryKit.readU32LE(buf, 36);\n return { compressed: (props & 1) !== 0, encrypted: (props & 2) !== 0 };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n DocInfo parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseDocInfo(data: Uint8Array, compressed: boolean): DocInfo {\n const raw = compressed ? tryInflate(data) : data;\n const recs = parseRecords(raw);\n const info: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n\n for (const r of recs) {\n try {\n if (r.tag === TAG_FACE_NAME) info.faceNames.push(parseFaceName(r.data));\n if (r.tag === TAG_CHAR_SHAPE) info.charShapes.push(parseCharShape(r.data));\n if (r.tag === TAG_PARA_SHAPE) info.paraShapes.push(parseParaShape(r.data));\n if (r.tag === TAG_BORDER_FILL) info.borderFills.push(parseBorderFill(r.data));\n } catch { /* skip malformed record */ }\n }\n return info;\n}\n\n/* ── FACE_NAME ──────────────────────────────────────────────── */\n\nfunction parseFaceName(d: Uint8Array): string {\n if (d.length < 3) return '';\n const len = BinaryKit.readU16LE(d, 1); // UTF-16 char count\n if (d.length < 3 + len * 2) return '';\n return new TextDecoder('utf-16le').decode(d.subarray(3, 3 + len * 2));\n}\n\n/* ── CHAR_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 14 faceId[7] (UINT16 × 7)\n 14 7 ratio[7]\n 21 7 spacing[7]\n 28 7 relSize[7]\n 35 7 offset[7]\n 42 4 height (UINT32, HWP-units 100 = 1pt)\n 46 4 attr (UINT32, bit flags)\n 50 1 shadowX\n 51 1 shadowY\n 52 4 textColor (COLORREF R,G,B,0) */\n\nfunction parseCharShape(d: Uint8Array): HwpCharShape {\n const faceIds: number[] = [];\n for (let i = 0; i < 7; i++) faceIds.push(d.length >= (i + 1) * 2 ? BinaryKit.readU16LE(d, i * 2) : 0);\n\n const height = d.length >= 46 ? BinaryKit.readU32LE(d, 42) : 1000;\n const attr = d.length >= 50 ? BinaryKit.readU32LE(d, 46) : 0;\n\n // attr bit layout (HWP 5.0 spec Table 35):\n // 0: italic, 1: bold, 2-4: underline type(3), 5-8: underline shape(4),\n // 9-11: outline(3), 12-13: shadow(2), 14: emboss, 15: engrave,\n // 16-17: super/sub(2, 0=none,1=super,2=sub), 18-20: strikeout type(3),\n // 21-24: strikeout shape(4), 25: annotLine, 26-28: annotLine type,\n // 29: useFontSpace, 30: kerning\n const ulType = (attr >> 2) & 0x7; // 3 bits at 2-4\n const skType = (attr >> 18) & 0x7; // 3 bits at 18-20\n const suType = (attr >> 16) & 0x3; // 2 bits at 16-17 (0=none,1=super,2=sub)\n\n return {\n faceIds,\n height: (height > 0 && height < 100000) ? height : 1000,\n italic: (attr & 1) !== 0,\n bold: ((attr >> 1) & 1) !== 0,\n underline: ulType !== 0,\n strikeout: skType !== 0,\n superscript: suType === 1,\n subscript: suType === 2,\n textColor: d.length >= 56 ? colorRef(d, 52) : '000000',\n };\n}\n\n/* ── PARA_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 4 attr1 (bits 0-1 = alignment: 0=justify,1=left,2=right,3=center)\n 4 4 leftMargin (HWPUNIT)\n 8 4 rightMargin\n 12 4 indent\n 16 4 spaceBefore\n 20 4 spaceAfter\n 24 4 lineSpacing */\n\nconst ALIGN_TBL: Record<number, Align> = { 0: 'justify', 1: 'left', 2: 'right', 3: 'center', 4: 'justify' };\n\nfunction parseParaShape(d: Uint8Array): HwpParaShape {\n if (d.length < 4) return { align: 'left', spaceBefore: 0, spaceAfter: 0, lineSpacing: 160, indent: 0 };\n const attr = BinaryKit.readU32LE(d, 0);\n return {\n align: ALIGN_TBL[(attr >> 2) & 0x7] ?? 'left',\n indent: d.length >= 16 ? i32(d, 12) : 0,\n spaceBefore: d.length >= 20 ? i32(d, 16) : 0,\n spaceAfter: d.length >= 24 ? i32(d, 20) : 0,\n lineSpacing: d.length >= 28 ? i32(d, 24) : 160,\n };\n}\n\n/* ── BORDER_FILL ────────────────────────────────────────────── */\n/* [0:2] attr\n For each of 5 borders (left,right,top,bottom,diagonal): 6 bytes\n +0 type(BYTE) +1 widthIdx(BYTE) +2 color(COLORREF)\n [32:4] fillType\n [36:4] faceColor (bgColor for solid fill) */\n\nconst BORDER_W_PT = [0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.70, 1.98, 2.84, 4.25, 5.67, 8.50, 11.34, 14.17];\nconst BORDER_KIND: Record<number, StrokeKind> = { 0:'solid',1:'dash',2:'dash',3:'dot',4:'dash',5:'dash',6:'dash',7:'double',8:'double',9:'double',10:'none' };\n\nfunction parseBorderFill(d: Uint8Array): HwpBorderFill {\n // Spec grouped format (표 23):\n // [0:2] attr\n // [2:4] 4 border types (left, right, top, bottom) — 1 byte each\n // [6:4] 4 border widths (left, right, top, bottom) — 1 byte each (index into BORDER_W_PT)\n // [10:16] 4 border colors (left, right, top, bottom) — 4 bytes each (COLORREF)\n // [26:3] diagonal: type(1) + width(1) + color(4) = 6 bytes actually [26:6]\n // [32:4] fillType\n // [36:4] faceColor (bgColor for solid fill)\n const borders: HwpBorderFill['borders'] = [];\n const BASE_TYPE = 2; // 4 type bytes\n const BASE_WIDTH = 6; // 4 width bytes\n const BASE_COLOR = 10; // 4 × 4-byte colors\n for (let i = 0; i < 4; i++) {\n const type = BASE_TYPE + i < d.length ? d[BASE_TYPE + i] : 0;\n const widthPt = BASE_WIDTH + i < d.length ? (BORDER_W_PT[d[BASE_WIDTH + i]] ?? 0.5) : 0.5;\n const color = BASE_COLOR + i * 4 + 4 <= d.length ? colorRef(d, BASE_COLOR + i * 4) : '000000';\n borders.push({ type, widthPt, color });\n }\n let bgColor: string | undefined;\n // after attr(2) + 4 types(4) + 4 widths(4) + 4 colors(16) + diagonal(6) = offset 32\n const fOff = 32;\n if (d.length >= fOff + 8) {\n const ft = BinaryKit.readU32LE(d, fOff);\n if (ft & 1) bgColor = colorRef(d, fOff + 4);\n }\n return { borders, bgColor };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Body section parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseBody(\n raw: Uint8Array, compressed: boolean, di: DocInfo, shield: ShieldedParser,\n): { content: ContentNode[]; pageDims?: PageDims } {\n const recs = parseRecords(compressed ? tryInflate(raw) : raw);\n const content: ContentNode[] = [];\n let pageDims: PageDims | undefined;\n\n // Pre-scan for PAGE_DEF at any nesting level (real HWP stores it at level 2 inside section ctrl)\n for (const r of recs) {\n if (r.tag === TAG_PAGE_DEF) {\n pageDims = shield.guard(() => parsePageDef(r.data), A4, 'hwp:pageDef');\n break;\n }\n }\n\n let i = 0;\n while (i < recs.length) {\n if (recs[i].tag === TAG_PAGE_DEF) {\n i++; // already handled above; skip at top level\n } else if (recs[i].tag === TAG_PARA_HEADER) {\n const r = shield.guard(\n () => parseParagraphGroup(recs, i, di, shield),\n { nodes: [] as ContentNode[], next: i + 1 },\n `hwp:para@${i}`,\n );\n content.push(...r.nodes);\n i = r.next;\n } else {\n i++;\n }\n }\n return { content, pageDims };\n}\n\n/* ── Paragraph group ────────────────────────────────────────── */\n\nfunction parseParagraphGroup(\n recs: HwpRecord[], start: number, di: DocInfo, shield: ShieldedParser,\n): { nodes: ContentNode[]; next: number } {\n const hdr = recs[start];\n const lv = hdr.level;\n\n // paraShapeId at offset 8 (UINT16)\n const psId = hdr.data.length >= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n\n let text: ParaTextResult | null = null;\n let csPairs: [number, number][] = [];\n const grids: ContentNode[] = [];\n const ctrlHeaders: { ctrlId: number; objId: number }[] = [];\n let i = start + 1;\n\n while (i < recs.length && recs[i].level > lv) {\n const r = recs[i];\n\n if (r.tag === TAG_PARA_TEXT && r.level === lv + 1) {\n text = decodeParaText(r.data);\n i++;\n } else if (r.tag === TAG_PARA_CHAR_SHAPE && r.level === lv + 1) {\n csPairs = parseCharShapePairs(r.data);\n i++;\n } else if (r.tag === TAG_CTRL_HEADER && r.level === lv + 1) {\n if (r.data.length >= 4) {\n const ctrlId = BinaryKit.readU32LE(r.data, 0);\n // objId at offset 4 (UINT16) - identifies the image/object in BinData\n const objId = r.data.length >= 6 ? BinaryKit.readU16LE(r.data, 4) : 0;\n ctrlHeaders.push({ ctrlId, objId });\n\n if (ctrlId === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, i, di, shield),\n { grid: null, next: skipKids(recs, i) },\n `hwp:tbl@${i}`,\n );\n if (tr.grid) grids.push(tr.grid);\n i = tr.next;\n } else {\n i = skipKids(recs, i);\n }\n } else {\n i = skipKids(recs, i);\n }\n } else {\n i++;\n }\n }\n\n // Match extended controls with CTRL_HEADER entries\n if (text && ctrlHeaders.length > 0) {\n for (let ci = 0; ci < text.controls.length; ci++) {\n if (ci < ctrlHeaders.length) {\n text.controls[ci].ctrlId = ctrlHeaders[ci].ctrlId;\n text.controls[ci].matched = true;\n }\n }\n }\n\n const nodes: ContentNode[] = [];\n\n // Build paragraph from text and inline controls (images)\n if (text && (text.chars.length > 0 || text.controls.length > 0)) {\n const paraContent: (SpanNode | ContentNode)[] = [];\n\n // Process text chars and controls together\n if (text.chars.length > 0) {\n const spans = resolveCharShapes(text.chars, csPairs, di);\n paraContent.push(...spans);\n }\n\n // Add placeholder spans for extended controls (images)\n if (text.controls.length > 0) {\n for (let ci = 0; ci < text.controls.length; ci++) {\n // Create placeholder for all extended controls\n // Image replacement will happen later in injectImagesIntoContent\n paraContent.push(buildSpan(`__EXT_${ci}__`));\n }\n }\n\n if (paraContent.length > 0) {\n nodes.push(buildPara(paraContent as any, buildParaProps(ps)));\n }\n }\n\n nodes.push(...grids);\n return { nodes, next: i };\n}\n\nfunction skipKids(recs: HwpRecord[], idx: number): number {\n const lv = recs[idx].level;\n let i = idx + 1;\n while (i < recs.length && recs[i].level > lv) i++;\n return i;\n}\n\n/* ── PARA_TEXT ───────────────────────────────────────────────── */\n\n// Extended controls: 8 WORDs, associated CTRL_HEADER\nconst EXT_CTRL = new Set([2, 3, 11, 12, 14, 15]);\n// Inline controls: 8 WORDs, no CTRL_HEADER\nconst INL_CTRL = new Set([4, 5, 6, 7, 8]);\n\nfunction decodeParaText(d: Uint8Array): ParaTextResult {\n const chars: ParsedChar[] = [];\n const controls: ParsedCtrl[] = [];\n let i = 0, pos = 0;\n\n while (i + 1 < d.length) {\n const c = d[i] | (d[i + 1] << 8);\n if (c === 0) { i += 2; pos++; continue; }\n if (c === 13) { break; } // paragraph end\n if (c === 10) { chars.push({ pos, ch: '\\n' }); i += 2; pos++; continue; }\n\n if (EXT_CTRL.has(c)) {\n // Extended control: 8 WORDs (16 bytes)\n // WORD 4 contains objId (for images, charts, etc.)\n let objId = 0;\n if (i + 16 <= d.length) {\n objId = BinaryKit.readU16LE(d, i + 8); // 4th WORD (offset 8) contains objId\n }\n controls.push({ pos, ctrlId: 0, objId, matched: false });\n i += 16; pos += 8; continue;\n }\n if (INL_CTRL.has(c)) {\n i += 16; pos += 8; continue;\n }\n if (c === 9) { // tab (inline 8 WORDs)\n chars.push({ pos, ch: '\\t' });\n i += 16; pos += 8; continue;\n }\n if (c >= 1 && c <= 31) { i += 2; pos++; continue; } // other control\n\n chars.push({ pos, ch: String.fromCharCode(c) });\n i += 2; pos++;\n }\n return { chars, controls };\n}\n\n/* ── PARA_CHAR_SHAPE ────────────────────────────────────────── */\n\nfunction parseCharShapePairs(d: Uint8Array): [number, number][] {\n const out: [number, number][] = [];\n for (let i = 0; i + 7 < d.length; i += 8)\n out.push([BinaryKit.readU32LE(d, i), BinaryKit.readU32LE(d, i + 4)]);\n return out;\n}\n\n/* ── Char-shape → SpanNode resolution ───────────────────────── */\n\nfunction resolveCharShapes(chars: ParsedChar[], pairs: [number, number][], di: DocInfo): SpanNode[] {\n if (chars.length === 0) return [buildSpan('')];\n\n const defaultId = pairs.length > 0 ? pairs[0][1] : 0;\n\n function idFor(pos: number): number {\n let id = defaultId;\n for (const [p, sid] of pairs) { if (p <= pos) id = sid; else break; }\n return id;\n }\n\n const spans: SpanNode[] = [];\n let curId = idFor(chars[0].pos);\n let buf = chars[0].ch;\n\n for (let k = 1; k < chars.length; k++) {\n const sid = idFor(chars[k].pos);\n if (sid !== curId) { spans.push(styledSpan(buf, curId, di)); buf = ''; curId = sid; }\n buf += chars[k].ch;\n }\n if (buf) spans.push(styledSpan(buf, curId, di));\n return spans;\n}\n\nfunction styledSpan(text: string, shapeId: number, di: DocInfo): SpanNode {\n const cs = di.charShapes[shapeId];\n if (!cs) return buildSpan(text);\n\n const props: TextProps = {};\n const fid = cs.faceIds[0] ?? 0;\n if (fid < di.faceNames.length && di.faceNames[fid]) props.font = safeFont(di.faceNames[fid]);\n if (cs.height > 0) props.pt = Metric.hwpToPt(cs.height);\n if (cs.bold) props.b = true;\n if (cs.italic) props.i = true;\n if (cs.underline) props.u = true;\n if (cs.strikeout) props.s = true;\n if (cs.superscript) props.sup = true;\n if (cs.subscript) props.sub = true;\n\n const hex = safeHex(cs.textColor);\n if (hex && hex !== '000000') props.color = hex;\n\n return buildSpan(text, props);\n}\n\n/* ── Table control parsing ──────────────────────────────────── */\n\nfunction parseTableCtrl(\n recs: HwpRecord[], ctrlIdx: number, di: DocInfo, shield: ShieldedParser,\n): { grid: ContentNode | null; next: number } {\n const ctrlLv = recs[ctrlIdx].level;\n let i = ctrlIdx + 1;\n\n let tblData: Uint8Array | null = null;\n const cells: { data: Uint8Array; tag: number; cStart: number; cEnd: number }[] = [];\n\n // Collect TABLE and cell records within this control's scope\n const tblLevel = ctrlLv + 1;\n\n while (i < recs.length && recs[i].level > ctrlLv) {\n const r = recs[i];\n\n if (isTableTag(r.tag) && r.level === tblLevel) {\n tblData = r.data;\n i++;\n } else if (r.tag === TAG_LIST_HEADER && r.level === tblLevel) {\n // LIST_HEADER as cell: paraCount tells how many paragraphs follow\n const cellData = r.data;\n const paraCount = cellData.length >= 2 ? BinaryKit.readU16LE(cellData, 0) : 0;\n i++;\n const cStart = i;\n // Consume exactly paraCount paragraphs (each with its child records)\n let consumed = 0;\n while (i < recs.length && consumed < paraCount) {\n if (recs[i].tag === TAG_PARA_HEADER && recs[i].level === tblLevel) {\n consumed++;\n i++;\n // Skip child records of this paragraph\n while (i < recs.length && recs[i].level > tblLevel) i++;\n } else if (recs[i].level > tblLevel) {\n i++;\n } else {\n break; // hit next sibling at same level\n }\n }\n cells.push({ data: cellData, tag: TAG_LIST_HEADER, cStart, cEnd: i });\n } else if (isCellTag(r.tag) && r.level === tblLevel) {\n // Full CELL record (with cell-specific fields)\n const cellData = r.data;\n const cellTag = r.tag;\n i++;\n const cStart = i;\n while (i < recs.length && recs[i].level > tblLevel) i++;\n cells.push({ data: cellData, tag: cellTag, cStart, cEnd: i });\n } else {\n i++;\n }\n }\n\n if (!tblData || cells.length === 0) return { grid: null, next: i };\n\n const rowCnt = tblData.length >= 6 ? BinaryKit.readU16LE(tblData, 4) : 1;\n const colCnt = tblData.length >= 8 ? BinaryKit.readU16LE(tblData, 6) : 1;\n\n interface PC { row: number; col: number; cs: number; rs: number; widthHwp: number; props: CellProps; paras: ParaNode[] }\n const parsed: PC[] = [];\n\n for (let ci = 0; ci < cells.length; ci++) {\n const c = cells[ci];\n const seqIdx = ci;\n const pc = shield.guard(\n () => parseCellRec(c.data, c.tag, recs, c.cStart, c.cEnd, di, shield, seqIdx, colCnt),\n { row: Math.floor(ci / (colCnt || 1)), col: ci % (colCnt || 1), cs: 1, rs: 1, widthHwp: 0, props: {}, paras: [buildPara([buildSpan('')])] },\n `hwp:cell@${c.cStart}`,\n );\n parsed.push(pc);\n }\n\n // Determine actual row count from cell data (may exceed rowCnt for merged cells)\n const maxRow = parsed.reduce((m, c) => Math.max(m, c.row + c.rs), 0);\n const actualRowCnt = Math.max(rowCnt, maxRow);\n\n // Validate cell positions; fallback to sequential layout if invalid\n const posValid = parsed.every(c => c.row >= 0 && c.col >= 0 && c.col < colCnt);\n if (!posValid) {\n let idx = 0;\n for (const c of parsed) { c.row = Math.floor(idx / colCnt); c.col = idx % colCnt; idx++; }\n }\n\n // Compute column widths in points from cell widths\n const colWidthsPt: number[] = new Array(colCnt).fill(0);\n // Pass 1: use cells with cs=1 for exact column widths\n for (const c of parsed) {\n if (c.cs === 1 && c.widthHwp > 0) {\n const wPt = Metric.hwpToPt(c.widthHwp);\n if (wPt > colWidthsPt[c.col]) colWidthsPt[c.col] = wPt;\n }\n }\n // Pass 2: for columns still 0, try to derive from multi-span cells\n const zeroColumns = colWidthsPt.filter(w => w === 0).length;\n if (zeroColumns > 0) {\n for (const c of parsed) {\n if (c.cs > 1 && c.widthHwp > 0) {\n // Subtract known column widths from the span\n let known = 0;\n let unknownCols = 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci] > 0) known += colWidthsPt[ci];\n else unknownCols++;\n }\n if (unknownCols > 0) {\n const remaining = Metric.hwpToPt(c.widthHwp) - known;\n const each = remaining > 0 ? remaining / unknownCols : 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci] === 0 && each > 0) colWidthsPt[ci] = each;\n }\n }\n }\n }\n }\n\n const rows = [];\n for (let r = 0; r < actualRowCnt; r++) {\n const rc = parsed.filter(c => c.row === r).sort((a, b) => a.col - b.col);\n if (rc.length === 0) continue;\n rows.push(buildRow(rc.map(c =>\n buildCell(c.paras.length ? c.paras : [buildPara([buildSpan('')])], { cs: c.cs, rs: c.rs, props: c.props }),\n )));\n }\n if (rows.length === 0) return { grid: null, next: i };\n\n // Table-level default stroke\n let defStroke: Stroke | undefined;\n const bfOff = 18 + rowCnt * 2;\n if (tblData.length >= bfOff + 2) {\n const bfId = BinaryKit.readU16LE(tblData, bfOff);\n defStroke = strokeFromBF(bfId, di);\n }\n\n const gp: GridProps = {};\n if (defStroke) gp.defaultStroke = defStroke;\n const hasWidths = colWidthsPt.some(w => w > 0);\n if (hasWidths) gp.colWidths = colWidthsPt;\n return { grid: buildGrid(rows, gp), next: i };\n}\n\n/* ── Cell record ────────────────────────────────────────────── */\n/* LIST_HEADER for cells (HWP 5.0/5.1):\n [0:2] paraCount [2:4] attr (bits 6-7 = vertAlign)\n [6:2] unknown [8:2] rowAddr [10:2] colAddr\n [12:2] rowSpan [14:2] colSpan\n [16:4] width(HWPUNIT) [20:4] height(HWPUNIT)\n [24:8] padding[4] [32:2] borderFillId */\n\nfunction parseCellRec(\n d: Uint8Array, tag: number, recs: HwpRecord[], cStart: number, cEnd: number,\n di: DocInfo, shield: ShieldedParser, seqIdx: number, colCnt: number,\n) {\n let col: number, row: number, cs = 1, rs = 1;\n let widthHwp = 0;\n const props: CellProps = {};\n\n const attr = d.length >= 6 ? BinaryKit.readU32LE(d, 2) : 0;\n const va = (attr >> 6) & 0x3;\n if (va === 1) props.va = 'mid';\n else if (va === 2) props.va = 'bot';\n\n if (tag === TAG_LIST_HEADER && d.length >= 22) {\n // LIST_HEADER with cell-specific fields\n // offset 8: colAddr, offset 10: rowAddr (HWP 5.0 spec)\n col = BinaryKit.readU16LE(d, 8);\n row = BinaryKit.readU16LE(d, 10);\n cs = Math.max(1, BinaryKit.readU16LE(d, 12));\n rs = Math.max(1, BinaryKit.readU16LE(d, 14));\n widthHwp = BinaryKit.readU32LE(d, 16);\n\n const bfId = d.length >= 34 ? BinaryKit.readU16LE(d, 32) : 0;\n if (bfId > 0 && bfId <= di.borderFills.length) {\n const bf = di.borderFills[bfId - 1];\n if (bf.borders.length >= 4) {\n props.left = toStroke(bf.borders[0]);\n props.right = toStroke(bf.borders[1]);\n props.top = toStroke(bf.borders[2]);\n props.bot = toStroke(bf.borders[3]);\n }\n if (bf.bgColor && bf.bgColor !== 'FFFFFF') props.bg = bf.bgColor;\n }\n } else if (tag !== TAG_LIST_HEADER) {\n // Full CELL record with position/span/borderFill\n col = d.length >= 8 ? BinaryKit.readU16LE(d, 6) : seqIdx % (colCnt || 1);\n row = d.length >= 10 ? BinaryKit.readU16LE(d, 8) : Math.floor(seqIdx / (colCnt || 1));\n cs = d.length >= 12 ? Math.max(1, BinaryKit.readU16LE(d, 10)) : 1;\n rs = d.length >= 14 ? Math.max(1, BinaryKit.readU16LE(d, 12)) : 1;\n widthHwp = d.length >= 18 ? BinaryKit.readU32LE(d, 14) : 0;\n\n const bfId = d.length >= 32 ? BinaryKit.readU16LE(d, 30) : 0;\n if (bfId > 0 && bfId <= di.borderFills.length) {\n const bf = di.borderFills[bfId - 1];\n if (bf.borders.length >= 4) {\n props.left = toStroke(bf.borders[0]);\n props.right = toStroke(bf.borders[1]);\n props.top = toStroke(bf.borders[2]);\n props.bot = toStroke(bf.borders[3]);\n }\n if (bf.bgColor && bf.bgColor !== 'FFFFFF') props.bg = bf.bgColor;\n }\n } else {\n // Fallback: LIST_HEADER too short, compute sequentially\n row = Math.floor(seqIdx / (colCnt || 1));\n col = seqIdx % (colCnt || 1);\n }\n\n // Parse cell content paragraphs\n const paras: ParaNode[] = [];\n let k = cStart;\n while (k < cEnd) {\n if (recs[k].tag === TAG_PARA_HEADER) {\n // For cell paragraphs, they might be at various nesting levels\n const r = shield.guard(\n () => {\n const hdr = recs[k];\n const lv = hdr.level;\n const psId = hdr.data.length >= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n let txt: ParaTextResult | null = null;\n let csp: [number, number][] = [];\n let j = k + 1;\n while (j < cEnd && recs[j].level > lv) {\n if (recs[j].tag === TAG_PARA_TEXT) { txt = decodeParaText(recs[j].data); j++; }\n else if (recs[j].tag === TAG_PARA_CHAR_SHAPE) { csp = parseCharShapePairs(recs[j].data); j++; }\n else j++;\n }\n const spans = txt && txt.chars.length > 0 ? resolveCharShapes(txt.chars, csp, di) : [buildSpan('')];\n return { para: buildPara(spans, buildParaProps(ps)), next: j };\n },\n { para: buildPara([buildSpan('')]), next: k + 1 },\n `hwp:cellP@${k}`,\n );\n paras.push(r.para);\n k = r.next;\n } else { k++; }\n }\n\n return { row, col, cs, rs, props, widthHwp, paras: paras.length ? paras : [buildPara([buildSpan('')])] };\n}\n\n/* ── PAGE_DEF ───────────────────────────────────────────────── */\n/* [0:4] width [4:4] height [8:4] ml [12:4] mr\n [16:4] mt [20:4] mb [36:4] attr (bit0=landscape) */\n\nfunction parsePageDef(d: Uint8Array): PageDims {\n if (d.length < 24) return A4;\n const w = BinaryKit.readU32LE(d, 0);\n const h = BinaryKit.readU32LE(d, 4);\n const ml = BinaryKit.readU32LE(d, 8);\n const mr = BinaryKit.readU32LE(d, 12);\n const mt = BinaryKit.readU32LE(d, 16);\n const mb = BinaryKit.readU32LE(d, 20);\n const at = d.length >= 40 ? BinaryKit.readU32LE(d, 36) : 0;\n return {\n wPt: Metric.hwpToPt(w), hPt: Metric.hwpToPt(h),\n ml: Metric.hwpToPt(ml), mr: Metric.hwpToPt(mr),\n mt: Metric.hwpToPt(mt), mb: Metric.hwpToPt(mb),\n orient: (at & 1) ? 'landscape' : 'portrait',\n };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Helpers\n ═══════════════════════════════════════════════════════════════ */\n\nfunction i32(d: Uint8Array, o: number): number {\n const u = BinaryKit.readU32LE(d, o);\n return u > 0x7FFFFFFF ? u - 0x100000000 : u;\n}\n\nfunction colorRef(d: Uint8Array, o: number): string {\n if (o + 3 > d.length) return '000000';\n return ((d[o] << 16) | (d[o + 1] << 8) | d[o + 2]).toString(16).padStart(6, '0').toUpperCase();\n}\n\nfunction toStroke(b: { type: number; widthPt: number; color: string }): Stroke {\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\nfunction strokeFromBF(bfId: number, di: DocInfo): Stroke | undefined {\n if (bfId <= 0 || bfId > di.borderFills.length) return undefined;\n const bf = di.borderFills[bfId - 1];\n if (!bf.borders.length) return undefined;\n const b = bf.borders[0];\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\nfunction buildParaProps(ps?: HwpParaShape): ParaProps {\n if (!ps) return {};\n const p: ParaProps = {};\n if (ps.align && ps.align !== 'left') p.align = ps.align;\n if (ps.spaceBefore > 0) p.spaceBefore = Metric.hwpToPt(ps.spaceBefore);\n if (ps.spaceAfter > 0) p.spaceAfter = Metric.hwpToPt(ps.spaceAfter);\n if (ps.lineSpacing > 0 && ps.lineSpacing !== 160) p.lineHeight = ps.lineSpacing / 100;\n if (ps.indent > 0) p.indentPt = Metric.hwpToPt(ps.indent);\n return p;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Decoder class\n ═══════════════════════════════════════════════════════════════ */\n\nexport class HwpScanner implements Decoder {\n readonly format = 'hwp';\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n if (!BinaryKit.isOle2(data)) return fail('HWP: Invalid OLE2 signature');\n const streams = BinaryKit.parseCfb(data);\n\n // FileHeader\n const fh = streams.get('FileHeader');\n const { compressed, encrypted } = fh ? parseFileHeader(fh) : { compressed: true, encrypted: false };\n if (encrypted) return fail('HWP: 암호화된 파일은 지원하지 않습니다');\n\n // DocInfo\n const diRaw = streams.get('DocInfo');\n let di: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n if (diRaw) {\n di = shield.guard(() => parseDocInfo(diRaw, compressed), di, 'hwp:docInfo');\n }\n\n // Extract images from BinData streams\n const imageStreams: { path: string; data: Uint8Array }[] = [];\n for (const [path, data] of streams) {\n if ((path.includes('BinData') || path.includes('.jpg') || path.includes('.jpeg') || path.includes('.png') || path.includes('.gif') || path.includes('.bmp'))\n && !path.includes('FileHeader') && !path.includes('DocInfo') && !path.includes('BodyText') && !path.includes('Section')) {\n imageStreams.push({ path, data });\n console.log(`[HwpScanner] Image stream found: ${path} (${data.length} bytes)`);\n }\n }\n\n // Create image nodes for each image stream (deduplicated by hash)\n const objectMap = new Map<number, ImgNode>();\n const seenHashes = new Set<string>();\n let imgIdx = 0;\n for (const { path, data } of imageStreams) {\n // Determine MIME type from extension or signature\n let mimeType = 'image/jpeg';\n const lowerPath = path.toLowerCase();\n if (lowerPath.includes('.png')) mimeType = 'image/png';\n else if (lowerPath.includes('.gif')) mimeType = 'image/gif';\n else if (lowerPath.includes('.bmp')) mimeType = 'image/bmp';\n\n // Also check signature\n if (data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4E && data[3] === 0x47) mimeType = 'image/png';\n else if (data[0] === 0x47 && data[1] === 0x49 && data[2] === 0x46 && data[3] === 0x3538) mimeType = 'image/gif';\n else if (data[0] === 0x42 && data[1] === 0x4D) mimeType = 'image/bmp';\n\n const imgData = Buffer.from(data);\n const base64 = imgData.toString('base64');\n const hash = base64.slice(0, 20); // Use first 20 chars as simple hash\n if (!seenHashes.has(hash)) {\n seenHashes.add(hash);\n objectMap.set(imgIdx++, buildImg(\n base64,\n mimeType as any,\n 0, // w\n 0, // h\n `Image from ${path}`,\n ));\n console.log(`[HwpScanner] Added unique image: ${hash}... (${data.length} bytes)`);\n } else {\n console.log(`[HwpScanner] Duplicate image skipped: ${hash}...`);\n }\n }\n\n console.log(`[HwpScanner] Found ${imageStreams.length} image streams, ${objectMap.size} unique images`);\n\n // Body sections\n const allContent: ContentNode[] = [];\n let pageDims: PageDims = A4;\n\n for (let s = 0; s < 100; s++) {\n const sec = streams.get(`BodyText/Section${s}`) ?? streams.get(`Section${s}`);\n if (!sec) {\n if (s === 0) {\n const fb = findBodySection(streams);\n if (fb) {\n const r = parseBody(fb, compressed, di, shield);\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n }\n break;\n }\n const r = shield.guard(\n () => parseBody(sec, compressed, di, shield),\n { content: [], pageDims: undefined },\n `hwp:sec${s}`,\n );\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n\n // Inject images into paragraphs (only if images are available)\n console.log(`[HwpScanner] Before injection: ${allContent.length} nodes, ${objectMap.size} images available`);\n if (objectMap.size > 0) {\n injectImagesIntoContent(allContent, objectMap);\n console.log(`[HwpScanner] After injection: ${allContent.length} nodes`);\n }\n\n // Count images (recursively)\n const countImages = (nodes: ContentNode[]): number => {\n let count = 0;\n for (const node of nodes) {\n if ((node as any).tag === 'img') count++;\n if ((node as any).tag === 'para' && (node as any).kids) count += countImages((node as any).kids);\n if ((node as any).tag === 'grid' && (node as any).kids) {\n for (const row of (node as any).kids) {\n if (row.kids) count += countImages(row.kids);\n }\n }\n }\n return count;\n };\n const imgCount = countImages(allContent);\n console.log(`[HwpScanner] Images in content: ${imgCount}`);\n\n warns.push(...shield.flush());\n const content = allContent.length > 0 ? allContent : [buildPara([buildSpan('')])];\n return succeed(buildRoot({}, [buildSheet(content, pageDims)]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWP decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\nfunction findBodySection(streams: Map<string, Uint8Array>): Uint8Array | undefined {\n for (const [k, v] of streams)\n if (k.includes('Section') && !k.includes('Header') && !k.includes('Info')) return v;\n return undefined;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n OLE Object extraction (images)\n ════════════════════════════════════════════════════════════ */\n\nfunction extractImagesFromOleObjectLink(data: Uint8Array): OleObject[] {\n const objects: OleObject[] = [];\n let off = 0;\n\n while (off + 8 <= data.length) {\n const objId = BinaryKit.readU32LE(data, off);\n const dataSize = BinaryKit.readU32LE(data, off + 4);\n const reserved = BinaryKit.readU32LE(data, off + 8);\n\n if (objId === 0 || dataSize === 0) break;\n\n const objOff = off + 16;\n if (objOff + dataSize > data.length) break;\n\n const objData = data.subarray(objOff, objOff + dataSize);\n\n // Detect MIME type from signature\n let mimeType = 'application/octet-stream';\n if (objData[0] === 0xFF && objData[1] === 0xD8 && objData[2] === 0xFF) {\n mimeType = 'image/jpeg';\n } else if (objData[0] === 0x89 && objData[1] === 0x50 && objData[2] === 0x4E && objData[3] === 0x47) {\n mimeType = 'image/png';\n } else if (objData[0] === 0x47 && objData[1] === 0x49 && objData[2] === 0x46 && objData[3] === 0x3538) {\n mimeType = 'image/gif';\n } else if (objData[0] === 0x42 && objData[1] === 0x4D) {\n mimeType = 'image/bmp';\n }\n\n objects.push({ id: objId, data: objData, mimeType });\n off = objOff + dataSize;\n }\n\n return objects;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Helper to inject images into paragraph content\n ════════════════════════════════════════════════════════════ */\n\nfunction injectImagesIntoContent(\n content: ContentNode[],\n objectMap: Map<number, ImgNode>\n): void {\n const imageArray = Array.from(objectMap.values());\n if (imageArray.length === 0) return;\n\n // Get unique images (deduplicate by base64 content)\n const uniqueImages = Array.from(new Set(imageArray.map(img => img.b64))).map(b64 => {\n return imageArray.find(img => img.b64 === b64)!;\n });\n if (uniqueImages.length === 0) return;\n\n let imgIdx = 0;\n for (const node of content) {\n if (node.tag === 'para' && node.kids) {\n for (let i = 0; i < node.kids.length; i++) {\n const kid = node.kids[i];\n // Span node structure: { tag: 'span', props, kids: [{ tag: 'txt', content }] }\n if (kid.tag === 'span' && kid.kids && kid.kids[0]?.tag === 'txt') {\n const text = kid.kids[0].content;\n // Support both __IMG_N__ and __EXT_N__ patterns\n const match = text.match?.(/^__(?:IMG|EXT)_(\\d+)__$/);\n if (match) {\n // Replace placeholder with next available image (round-robin)\n const imgNode = uniqueImages[imgIdx % uniqueImages.length];\n if (imgNode) {\n node.kids[i] = imgNode;\n imgIdx++;\n }\n }\n }\n }\n }\n }\n}\n\nregistry.registerDecoder(new HwpScanner());\n","import type { Decoder } from \"../../contract/decoder\";\nimport type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n PageNumNode,\n CellNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n DocMeta,\n PageDims,\n TextProps,\n ParaProps,\n CellProps,\n GridProps,\n TableLook,\n Stroke,\n ImgLayout,\n ImgHorzAlign,\n ImgVertAlign,\n ImgHorzRelTo,\n ImgVertRelTo,\n ImgWrap,\n} from \"../../model/doc-props\";\nimport { A4 } from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport {\n buildRoot,\n buildSheet,\n buildPara,\n buildSpan,\n buildImg,\n buildGrid,\n buildRow,\n buildCell,\n buildPb,\n} from \"../../model/builders\";\nimport { ShieldedParser } from \"../../safety/ShieldedParser\";\nimport {\n Metric,\n safeAlign,\n safeFont,\n safeHex,\n safeStrokeDocx,\n} from \"../../safety/StyleBridge\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { XmlKit } from \"../../toolkit/XmlKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\n\nexport class DocxDecoder implements Decoder {\n readonly format = \"docx\";\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const docXml = files.get(\"word/document.xml\");\n if (!docXml) return fail(\"DOCX: word/document.xml not found\");\n\n const relsXml = files.get(\"word/_rels/document.xml.rels\");\n const relsMap = relsXml\n ? await parseRels(TextKit.decode(relsXml))\n : new Map<string, string>();\n\n const coreXml = files.get(\"docProps/core.xml\");\n let meta: DocMeta = {};\n if (coreXml) {\n try {\n meta = await parseCoreProps(TextKit.decode(coreXml));\n } catch {\n // ignore — meta is optional\n }\n }\n\n // Parse numbering.xml for list support\n const numXml = files.get(\"word/numbering.xml\");\n let numMap: NumMap = new Map();\n if (numXml) {\n try {\n numMap = await parseNumbering(TextKit.decode(numXml));\n } catch {\n /* non-fatal */\n }\n }\n\n // Parse styles.xml for tblStyle defaults\n let stylesMap: StylesMap = new Map();\n const stylesXml = files.get(\"word/styles.xml\");\n if (stylesXml) {\n try {\n stylesMap = await parseStylesMap(TextKit.decode(stylesXml));\n } catch {\n /* non-fatal */\n }\n }\n\n const docStr = TextKit.decode(docXml);\n const docObj: any = await XmlKit.parseStrict(docStr);\n\n const body = getBody(docObj);\n const dims = extractDims(body) ?? { ...A4 };\n const elements = getBodyElements(body);\n\n const decCtx: DecCtx = { relsMap, files, shield, numMap, warns, stylesMap };\n\n const kids: ContentNode[] = [];\n for (const el of elements) {\n const node = shield.guard(\n () => decodeElement(el, decCtx),\n buildPara([buildSpan(\"[요소 파싱 실패]\")]),\n \"docx:bodyElement\",\n );\n kids.push(node);\n\n // Inline sectPr in pPr = section break → insert page-break paragraph after\n if (el.type === 'para') {\n const pPr = el.node?.[\"w:pPr\"]?.[0] ?? el.node?.pPr?.[0] ?? {};\n const inlineSectPr = pPr?.[\"w:sectPr\"]?.[0] ?? pPr?.sectPr?.[0];\n if (inlineSectPr) {\n const typeAttr = inlineSectPr?.[\"w:type\"]?.[0]?._attr;\n const sectType = typeAttr?.[\"w:val\"] ?? typeAttr?.val ?? 'nextPage';\n if (sectType !== 'continuous') {\n kids.push(buildPara([{ tag: 'span', props: {}, kids: [buildPb()] }]));\n }\n }\n }\n }\n\n // Decode header/footer\n const headerParas = await decodeHeaderFooter(\n \"header\",\n body,\n relsMap,\n files,\n decCtx,\n );\n const footerParas = await decodeHeaderFooter(\n \"footer\",\n body,\n relsMap,\n files,\n decCtx,\n );\n\n warns.push(...shield.flush());\n const sheet = buildSheet(kids.filter(Boolean) as ContentNode[], dims, {\n header: headerParas,\n footer: footerParas,\n });\n return succeed(buildRoot(meta, [sheet]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`DOCX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── types ─────────────────────────────────────────────────\n\ninterface TblBorderDef {\n top?: Stroke;\n bottom?: Stroke;\n left?: Stroke;\n right?: Stroke;\n insideH?: Stroke;\n insideV?: Stroke;\n}\n\n/** Parsed tblStyle defaults from styles.xml */\ninterface TblStyleDef {\n tblBorders?: TblBorderDef;\n cellBg?: string; // default cell background\n}\n\ntype StylesMap = Map<string, TblStyleDef>; // styleId → defaults\n\ninterface DecCtx {\n relsMap: Map<string, string>;\n files: Map<string, Uint8Array>;\n shield: ShieldedParser;\n numMap: NumMap;\n warns: string[];\n stylesMap: StylesMap;\n}\n\n// numId → { abstractNumId, levels: Map<ilvl, { fmt, isOrdered }> }\ntype NumMap = Map<\n number,\n { levels: Map<number, { fmt: string; isOrdered: boolean }> }\n>;\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction toArr(v: any): any[] {\n return v == null ? [] : Array.isArray(v) ? v : [v];\n}\n\n/** Resolve DOCX relative paths. e.g. (\"word\", \"../media/image1.png\") → \"word/media/image1.png\" */\nfunction resolveDocxPath(baseDir: string, target: string): string {\n if (target.startsWith(\"/\")) return target.slice(1);\n const parts = (baseDir + \"/\" + target).split(\"/\");\n const stack: string[] = [];\n for (const p of parts) {\n if (p === \"..\") {\n stack.pop();\n } else if (p !== \".\") {\n stack.push(p);\n }\n }\n return stack.join(\"/\");\n}\n\nasync function parseRels(xml: string): Promise<Map<string, string>> {\n const map = new Map<string, string>();\n try {\n const obj: any = await XmlKit.parseStrict(xml);\n for (const rel of toArr(obj?.Relationships?.[0]?.Relationship)) {\n const a = rel?._attr ?? {};\n if (a.Id && a.Target) map.set(a.Id, a.Target);\n }\n } catch {\n /* ignore */\n }\n return map;\n}\n\nasync function parseCoreProps(xml: string): Promise<DocMeta> {\n try {\n const obj: any = await XmlKit.parseStrict(xml);\n const c = obj?.[\"cp:coreProperties\"]?.[0] ?? obj?.coreProperties?.[0] ?? {};\n return {\n title: c?.[\"dc:title\"]?.[0]?._text ?? undefined,\n author: c?.[\"dc:creator\"]?.[0]?._text ?? undefined,\n subject: c?.[\"dc:subject\"]?.[0]?._text ?? undefined,\n created: c?.[\"dcterms:created\"]?.[0]?._text ?? undefined,\n modified: c?.[\"dcterms:modified\"]?.[0]?._text ?? undefined,\n };\n } catch {\n return {};\n }\n}\n\nasync function parseNumbering(xml: string): Promise<NumMap> {\n const map: NumMap = new Map();\n try {\n const obj: any = await XmlKit.parseStrict(xml);\n const root = obj?.[\"w:numbering\"]?.[0] ?? obj?.numbering?.[0] ?? obj;\n\n // Parse abstractNums\n const absMap = new Map<\n number,\n Map<number, { fmt: string; isOrdered: boolean }>\n >();\n for (const abs of toArr(root?.[\"w:abstractNum\"] ?? root?.abstractNum)) {\n const absId = Number(\n abs?._attr?.[\"w:abstractNumId\"] ?? abs?._attr?.abstractNumId ?? 0,\n );\n const levels = new Map<number, { fmt: string; isOrdered: boolean }>();\n for (const lvl of toArr(abs?.[\"w:lvl\"] ?? abs?.lvl)) {\n const ilvl = Number(lvl?._attr?.[\"w:ilvl\"] ?? lvl?._attr?.ilvl ?? 0);\n const fmtNode =\n lvl?.[\"w:numFmt\"]?.[0]?._attr ?? lvl?.numFmt?.[0]?._attr ?? {};\n const fmt = fmtNode?.[\"w:val\"] ?? fmtNode?.val ?? \"decimal\";\n levels.set(ilvl, { fmt, isOrdered: fmt !== \"bullet\" });\n }\n absMap.set(absId, levels);\n }\n\n // Parse nums\n for (const num of toArr(root?.[\"w:num\"] ?? root?.num)) {\n const numId = Number(num?._attr?.[\"w:numId\"] ?? num?._attr?.numId ?? 0);\n const absRef =\n num?.[\"w:abstractNumId\"]?.[0]?._attr ??\n num?.abstractNumId?.[0]?._attr ??\n {};\n const absId = Number(absRef?.[\"w:val\"] ?? absRef?.val ?? 0);\n const levels = absMap.get(absId) ?? new Map();\n map.set(numId, { levels });\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction getBody(obj: any): any {\n return (\n obj?.[\"w:document\"]?.[0]?.[\"w:body\"]?.[0] ??\n obj?.document?.[0]?.body?.[0] ??\n obj\n );\n}\n\nfunction extractDims(body: any): PageDims | null {\n try {\n const sp = body?.[\"w:sectPr\"]?.[0] ?? body?.sectPr?.[0];\n if (!sp) return null;\n const sz = sp?.[\"w:pgSz\"]?.[0]?._attr ?? sp?.pgSz?.[0]?._attr;\n const mar = sp?.[\"w:pgMar\"]?.[0]?._attr ?? sp?.pgMar?.[0]?._attr;\n if (!sz) return null;\n return {\n wPt: Metric.dxaToPt(Number(sz[\"w:w\"] ?? sz.w ?? 11906)),\n hPt: Metric.dxaToPt(Number(sz[\"w:h\"] ?? sz.h ?? 16838)),\n mt: Metric.dxaToPt(Number(mar?.[\"w:top\"] ?? mar?.top ?? 1440)),\n mb: Metric.dxaToPt(Number(mar?.[\"w:bottom\"] ?? mar?.bottom ?? 1440)),\n ml: Metric.dxaToPt(Number(mar?.[\"w:left\"] ?? mar?.left ?? 1800)),\n mr: Metric.dxaToPt(Number(mar?.[\"w:right\"] ?? mar?.right ?? 1800)),\n orient:\n (sz[\"w:orient\"] ?? sz.orient) === \"landscape\"\n ? \"landscape\"\n : \"portrait\",\n };\n } catch {\n return null;\n }\n}\n\nfunction getBodyElements(body: any): { type: string; node: any }[] {\n const paras = toArr(body?.[\"w:p\"] ?? body?.p);\n const tables = toArr(body?.[\"w:tbl\"] ?? body?.tbl);\n\n if (tables.length === 0)\n return paras.map((n: any) => ({ type: \"para\", node: n }));\n if (paras.length === 0)\n return tables.map((n: any) => ({ type: \"table\", node: n }));\n\n // Use _childOrder from XmlKit to preserve document order\n const childOrder = body?.[\"_childOrder\"] as string[] | undefined;\n if (Array.isArray(childOrder)) {\n const items: { type: string; node: any }[] = [];\n let pi = 0,\n ti = 0;\n for (const tag of childOrder) {\n if ((tag === \"w:p\" || tag === \"p\") && pi < paras.length) {\n items.push({ type: \"para\", node: paras[pi++] });\n } else if ((tag === \"w:tbl\" || tag === \"tbl\") && ti < tables.length) {\n items.push({ type: \"table\", node: tables[ti++] });\n }\n }\n while (pi < paras.length) items.push({ type: \"para\", node: paras[pi++] });\n while (ti < tables.length)\n items.push({ type: \"table\", node: tables[ti++] });\n return items;\n }\n\n // Fallback: paragraphs first, then tables\n return [\n ...paras.map((n: any) => ({ type: \"para\", node: n })),\n ...tables.map((n: any) => ({ type: \"table\", node: n })),\n ];\n}\n\n// ─── Header/Footer decoding ────────────────────────────────\n\nasync function decodeHeaderFooter(\n kind: \"header\" | \"footer\",\n body: any,\n relsMap: Map<string, string>,\n files: Map<string, Uint8Array>,\n ctx: DecCtx,\n): Promise<ParaNode[] | undefined> {\n try {\n const sp = body?.[\"w:sectPr\"]?.[0] ?? body?.sectPr?.[0];\n if (!sp) return undefined;\n\n const refTag =\n kind === \"header\" ? \"w:headerReference\" : \"w:footerReference\";\n const refs = toArr(sp?.[refTag] ?? sp?.[refTag.replace(\"w:\", \"\")]);\n if (refs.length === 0) return undefined;\n\n const rId =\n refs[0]?._attr?.[\"r:id\"] ??\n refs[0]?._attr?.[\"r:Id\"] ??\n refs[0]?._attr?.id;\n if (!rId) return undefined;\n\n const target = relsMap.get(rId);\n if (!target) return undefined;\n\n const filePath = resolveDocxPath(\"word\", target);\n const fileData = files.get(filePath);\n if (!fileData) return undefined;\n\n const xmlStr = TextKit.decode(fileData);\n const obj: any = await XmlKit.parseStrict(xmlStr);\n\n const rootTag = kind === \"header\" ? \"w:hdr\" : \"w:ftr\";\n const root =\n obj?.[rootTag]?.[0] ?? obj?.[rootTag.replace(\"w:\", \"\")]?.[0] ?? obj;\n\n const paras = toArr(root?.[\"w:p\"] ?? root?.p);\n if (paras.length === 0) return undefined;\n\n return paras.map((p: any) => decodePara(p, ctx));\n } catch {\n return undefined;\n }\n}\n\n// ─── Element decoding ──────────────────────────────────────\n\n//만약에 drawing 태그가 안에 있으면 true 반환\nfunction hasDrawingDeep(node: any): boolean {\n if (!node || typeof node !== \"object\") return false;\n\n if (node[\"w:drawing\"] || node[\"w:pict\"]) return true;\n\n return Object.values(node).some((v) => {\n if (Array.isArray(v)) return v.some(hasDrawingDeep);\n return hasDrawingDeep(v);\n });\n}\n\nfunction decodeElement(\n el: { type: string; node: any },\n ctx: DecCtx,\n): ContentNode {\n if (el.type === \"table\") {\n const { value } = ctx.shield.guardGrid(\n el.node,\n (n) => decodeGrid(n as any, ctx),\n (n) => decodeGridSimple(n as any),\n (n) => decodeGridFlat(n as any),\n (n) => decodeGridText(n as any) as unknown as GridNode,\n \"docx:table\",\n );\n return value;\n }\n return decodePara(el.node, ctx);\n}\n\nfunction decodePara(p: any, ctx: DecCtx): ParaNode {\n const pPr = p?.[\"w:pPr\"]?.[0] ?? {};\n const alignVal =\n pPr?.[\"w:jc\"]?.[0]?._attr?.[\"w:val\"] ?? pPr?.[\"w:jc\"]?.[0]?._attr?.val;\n const headStyle =\n pPr?.[\"w:pStyle\"]?.[0]?._attr?.[\"w:val\"] ??\n pPr?.[\"w:pStyle\"]?.[0]?._attr?.val ??\n \"\";\n\n const props: ParaProps = {\n align: safeAlign(alignVal),\n heading: parseHeading(headStyle),\n };\n\n // Spacing (before/after/line height)\n const spacingAttr =\n pPr?.[\"w:spacing\"]?.[0]?._attr ?? pPr?.spacing?.[0]?._attr ?? {};\n const beforeVal = Number(\n spacingAttr?.[\"w:before\"] ?? spacingAttr?.before ?? 0,\n );\n const afterVal = Number(spacingAttr?.[\"w:after\"] ?? spacingAttr?.after ?? 0);\n const lineVal = Number(spacingAttr?.[\"w:line\"] ?? spacingAttr?.line ?? 0);\n const lineRule =\n spacingAttr?.[\"w:lineRule\"] ?? spacingAttr?.lineRule ?? \"auto\";\n if (beforeVal > 0) props.spaceBefore = Metric.dxaToPt(beforeVal);\n if (afterVal > 0) props.spaceAfter = Metric.dxaToPt(afterVal);\n if (lineVal > 0 && lineRule === \"auto\") props.lineHeight = lineVal / 240;\n\n // Indentation\n const indAttr = pPr?.[\"w:ind\"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {};\n const leftVal = Number(indAttr?.[\"w:left\"] ?? indAttr?.left ?? 0);\n if (leftVal > 0) props.indentPt = Metric.dxaToPt(leftVal);\n\n // List/numbering\n const numPr = pPr?.[\"w:numPr\"]?.[0] ?? pPr?.numPr?.[0];\n if (numPr) {\n const ilvlNode =\n numPr?.[\"w:ilvl\"]?.[0]?._attr ?? numPr?.ilvl?.[0]?._attr ?? {};\n const numIdNode =\n numPr?.[\"w:numId\"]?.[0]?._attr ?? numPr?.numId?.[0]?._attr ?? {};\n const ilvl = Number(ilvlNode?.[\"w:val\"] ?? ilvlNode?.val ?? 0);\n const numId = Number(numIdNode?.[\"w:val\"] ?? numIdNode?.val ?? 0);\n\n props.listLv = ilvl;\n const numEntry = ctx.numMap.get(numId);\n if (numEntry) {\n const lvlInfo = numEntry.levels.get(ilvl) ?? numEntry.levels.get(0);\n props.listOrd = lvlInfo?.isOrdered ?? false;\n } else {\n // Fallback: numId=1 is typically bullet, numId=2 is numbered\n props.listOrd = numId >= 2;\n }\n }\n\n // pageBreakBefore: paragraph always starts on a new page\n const pbBeforeNode = pPr?.[\"w:pageBreakBefore\"]?.[0] ?? pPr?.pageBreakBefore?.[0];\n const hasPageBreakBefore = pbBeforeNode != null &&\n (pbBeforeNode?._attr?.[\"w:val\"] ?? pbBeforeNode?._attr?.val ?? \"1\") !== \"0\";\n\n const runs = toArr(p?.[\"w:r\"] ?? p?.r);\n\n // 3/28 이미지 태크를 찾을수 있기 때문에 별도 함수 구현\n const kids: (SpanNode | ImgNode)[] = ctx.shield.guardAll(\n runs,\n (run: any) =>\n hasDrawingDeep(run) ? decodeRunOrImage(run, ctx) : decodeRun(run, ctx),\n () => buildSpan(\"\"),\n \"docx:run\",\n );\n\n const filteredKids = kids.filter(Boolean) as ParaNode[\"kids\"];\n\n // Prepend pb span when pageBreakBefore is set\n if (hasPageBreakBefore) {\n filteredKids.unshift({ tag: 'span', props: {}, kids: [buildPb()] });\n }\n\n return buildPara(filteredKids, props);\n}\n\n// 3/28 코드 수정\nfunction decodeRunOrImage(run: any, ctx: DecCtx): SpanNode | ImgNode {\n function findFirstDrawing(node: any): any | null {\n if (!node || typeof node !== \"object\") return null;\n\n if (node[\"w:drawing\"]) return node[\"w:drawing\"][0];\n if (node[\"w:pict\"]) return node[\"w:pict\"][0];\n\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n const found = findFirstDrawing(v);\n if (found) return found;\n }\n } else {\n const found = findFirstDrawing(value);\n if (found) return found;\n }\n }\n\n return null;\n }\n\n const drawing = findFirstDrawing(run);\n\n if (drawing) {\n const img = decodeDrawing(drawing, ctx);\n if (img) return img;\n }\n\n return decodeRun(run, ctx);\n}\nfunction decodeDrawing(drawing: any, ctx: DecCtx): ImgNode | null {\n try {\n const inline = drawing?.[\"wp:inline\"]?.[0] ?? drawing?.inline?.[0];\n const anchor = drawing?.[\"wp:anchor\"]?.[0] ?? drawing?.anchor?.[0];\n const container = inline ?? anchor;\n if (!container) return null;\n\n // Get dimensions\n const extent =\n container?.[\"wp:extent\"]?.[0]?._attr ??\n container?.extent?.[0]?._attr ??\n {};\n const cx = Number(extent?.cx ?? 0);\n const cy = Number(extent?.cy ?? 0);\n const wPt = Metric.emuToPt(cx);\n const hPt = Metric.emuToPt(cy);\n\n // Get alt text\n const docPr =\n container?.[\"wp:docPr\"]?.[0]?._attr ?? container?.docPr?.[0]?._attr ?? {};\n const alt = docPr?.descr ?? docPr?.name ?? \"\";\n\n // Navigate to blip\n const graphic = container?.[\"a:graphic\"]?.[0] ?? container?.graphic?.[0];\n const graphicData =\n graphic?.[\"a:graphicData\"]?.[0] ?? graphic?.graphicData?.[0];\n const pic = graphicData?.[\"pic:pic\"]?.[0] ?? graphicData?.pic?.[0];\n const blipFill = pic?.[\"pic:blipFill\"]?.[0] ?? pic?.blipFill?.[0];\n const blip =\n blipFill?.[\"a:blip\"]?.[0]?._attr ?? blipFill?.blip?.[0]?._attr ?? {};\n const rId = blip?.[\"r:embed\"] ?? blip?.embed;\n\n if (!rId) return null;\n\n const target = ctx.relsMap.get(rId);\n if (!target) return null;\n\n const filePath = resolveDocxPath(\"word\", target);\n const fileData = ctx.files.get(filePath);\n if (!fileData) {\n console.warn(\n `[DocxDecoder] image not found in ZIP: \"${filePath}\" (rId=${rId}, target=${target})`,\n );\n return null;\n }\n\n const ext = target.split(\".\").pop()?.toLowerCase() ?? \"png\";\n const mimeMap: Record<string, ImgNode[\"mime\"]> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n const mime = mimeMap[ext] ?? \"image/png\";\n console.log(\n `[DocxDecoder] image loaded: ${filePath} (${mime}, ${fileData.length} bytes)`,\n );\n\n // ── layout 추출 ──────────────────────────────────────────\n const layout: ImgLayout = inline\n ? { wrap: 'inline' }\n : extractAnchorLayout(anchor);\n\n return buildImg(TextKit.base64Encode(fileData), mime, wPt, hPt, alt || undefined, layout);\n } catch {\n return null;\n }\n}\n\nfunction decodeRun(run: any, ctx: DecCtx): SpanNode {\n const rPr = run?.[\"w:rPr\"]?.[0] ?? run?.rPr?.[0] ?? {};\n\n const szAttr = rPr?.[\"w:sz\"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {};\n const szVal = szAttr?.[\"w:val\"] ?? szAttr?.val;\n\n const colorAttr =\n rPr?.[\"w:color\"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {};\n const colorVal = colorAttr?.[\"w:val\"] ?? colorAttr?.val;\n\n const fontAttr =\n rPr?.[\"w:rFonts\"]?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {};\n const fontName =\n fontAttr?.[\"w:ascii\"] ??\n fontAttr?.ascii ??\n fontAttr?.[\"w:hAnsi\"] ??\n fontAttr?.hAnsi ??\n fontAttr?.[\"w:eastAsia\"] ??\n fontAttr?.eastAsia;\n\n const underVal =\n rPr?.[\"w:u\"]?.[0]?._attr?.[\"w:val\"] ?? rPr?.[\"w:u\"]?.[0]?._attr?.val;\n\n // Background/highlight\n const shdAttr = rPr?.[\"w:shd\"]?.[0]?._attr ?? rPr?.shd?.[0]?._attr ?? {};\n const bgVal = safeHex(shdAttr?.[\"w:fill\"] ?? shdAttr?.fill);\n\n // Superscript/subscript\n const vertAlignVal =\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.[\"w:val\"] ??\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.val;\n\n // Check bold/italic/strike — val=\"0\" means explicitly OFF\n const bNode = rPr?.[\"w:b\"]?.[0] ?? rPr?.b?.[0];\n const isBold =\n bNode != null &&\n (bNode?._attr?.[\"w:val\"] ?? bNode?._attr?.val ?? \"1\") !== \"0\";\n const iNode = rPr?.[\"w:i\"]?.[0] ?? rPr?.i?.[0];\n const isItalic =\n iNode != null &&\n (iNode?._attr?.[\"w:val\"] ?? iNode?._attr?.val ?? \"1\") !== \"0\";\n const sNode = rPr?.[\"w:strike\"]?.[0] ?? rPr?.strike?.[0];\n const isStrike =\n sNode != null &&\n (sNode?._attr?.[\"w:val\"] ?? sNode?._attr?.val ?? \"1\") !== \"0\";\n\n const props: TextProps = {\n b: isBold || undefined,\n i: isItalic || undefined,\n u: underVal && underVal !== \"none\" ? true : undefined,\n s: isStrike || undefined,\n sup: vertAlignVal === \"superscript\" || undefined,\n sub: vertAlignVal === \"subscript\" || undefined,\n pt: szVal ? Metric.halfPtToPt(Number(szVal)) : undefined,\n color: safeHex(colorVal),\n font: fontName ? safeFont(fontName) : undefined,\n bg: bgVal,\n };\n\n // Check for field codes (PAGE number)\n const fldChar = run?.[\"w:fldChar\"]?.[0]?._attr ?? run?.fldChar?.[0]?._attr;\n const instrText = run?.[\"w:instrText\"]?.[0];\n\n // Page break: <w:br w:type=\"page\"/>\n const brNodes = toArr(run?.[\"w:br\"] ?? run?.br ?? []);\n for (const br of brNodes) {\n const brType = br?._attr?.[\"w:type\"] ?? br?._attr?.type;\n if (brType === \"page\") {\n return { tag: \"span\", props, kids: [buildPb()] };\n }\n }\n\n const textNodes = toArr(run?.[\"w:t\"] ?? run?.t);\n const content = textNodes\n .map((t: any) => (typeof t === \"string\" ? t : (t?._ ?? t?._text ?? \"\")))\n .join(\"\");\n\n // Handle page number field in instrText\n if (instrText) {\n const instrStr =\n typeof instrText === \"string\" ? instrText : (instrText?._text ?? \"\");\n if (instrStr.trim().toUpperCase() === \"PAGE\") {\n const pageNum: PageNumNode = { tag: \"pagenum\", format: \"decimal\" };\n return { tag: \"span\", props, kids: [pageNum] };\n }\n }\n\n return buildSpan(content, props);\n}\n\n/** Parse all 6 border sides from a w:tblBorders or w:tcBorders node */\nfunction parseBorderDef(bdrNode: any): TblBorderDef {\n const sides: [string, keyof TblBorderDef][] = [\n [\"top\", \"top\"], [\"bottom\", \"bottom\"], [\"left\", \"left\"], [\"right\", \"right\"],\n [\"insideH\", \"insideH\"], [\"insideV\", \"insideV\"],\n ];\n const result: TblBorderDef = {};\n for (const [xml, prop] of sides) {\n const bdr = bdrNode?.[\"w:\" + xml]?.[0]?._attr ?? bdrNode?.[xml]?.[0]?._attr;\n if (!bdr) continue;\n const val = bdr?.[\"w:val\"] ?? bdr?.val;\n if (val === \"none\" || val === \"nil\") continue; // explicit none → skip (no border)\n result[prop] = safeStrokeDocx(\n val,\n Number(bdr?.[\"w:sz\"] ?? bdr?.sz ?? 4),\n bdr?.[\"w:color\"] ?? bdr?.color,\n );\n }\n return result;\n}\n\n/** Parse styles.xml and build a map of tblStyle defaults */\nasync function parseStylesMap(xml: string): Promise<StylesMap> {\n const map: StylesMap = new Map();\n try {\n const obj: any = await XmlKit.parseStrict(xml);\n const stylesRoot = obj?.[\"w:styles\"]?.[0] ?? obj?.styles?.[0] ?? obj;\n const styleArr = toArr(stylesRoot?.[\"w:style\"] ?? stylesRoot?.style);\n for (const style of styleArr) {\n const attr = style?._attr ?? {};\n const type = attr?.[\"w:type\"] ?? attr?.type;\n if (type !== \"table\") continue;\n const id = attr?.[\"w:styleId\"] ?? attr?.styleId;\n if (!id) continue;\n const tblPr = style?.[\"w:tblPr\"]?.[0] ?? style?.tblPr?.[0];\n const tblBdrNode = tblPr?.[\"w:tblBorders\"]?.[0] ?? tblPr?.tblBorders?.[0];\n const tblBorders = tblBdrNode ? parseBorderDef(tblBdrNode) : undefined;\n // tcStyle > tcBdr for default cell borders\n const tcStyle = style?.[\"w:tcStyle\"]?.[0] ?? style?.tcStyle?.[0];\n const tcBdrNode = tcStyle?.[\"w:tcBdr\"]?.[0] ?? tcStyle?.tcBdr?.[0];\n if (tcBdrNode) {\n const cellDef = parseBorderDef(tcBdrNode);\n // merge into tblBorders as inner/outer defaults\n if (!tblBorders) {\n map.set(id, { tblBorders: cellDef });\n } else {\n map.set(id, { tblBorders: { ...cellDef, ...tblBorders } });\n }\n } else if (tblBorders) {\n map.set(id, { tblBorders });\n }\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\n/** Resolve final CellProps borders using 3-level priority chain */\nfunction resolveCellBorders(\n cp: CellProps,\n ri: number, ci: number, rs: number, cs: number,\n rowCount: number, colCount: number,\n tblBdr: TblBorderDef,\n): CellProps {\n const isTopEdge = ri === 0;\n const isBottomEdge = ri + rs >= rowCount;\n const isLeftEdge = ci === 0;\n const isRightEdge = ci + cs >= colCount;\n\n // Apply tblBorders only where no explicit tcBorder was set\n const resolved: CellProps = { ...cp };\n if (!resolved.top) resolved.top = isTopEdge ? tblBdr.top : tblBdr.insideH;\n if (!resolved.bot) resolved.bot = isBottomEdge ? tblBdr.bottom : tblBdr.insideH;\n if (!resolved.left) resolved.left = isLeftEdge ? tblBdr.left : tblBdr.insideV;\n if (!resolved.right) resolved.right = isRightEdge ? tblBdr.right : tblBdr.insideV;\n return resolved;\n}\n\nfunction decodeGrid(tbl: any, ctx: DecCtx): GridNode {\n // Parse tblPr for table styles\n const tblPr = tbl?.[\"w:tblPr\"]?.[0] ?? tbl?.tblPr?.[0] ?? {};\n const tblLookAttr =\n tblPr?.[\"w:tblLook\"]?.[0]?._attr ?? tblPr?.tblLook?.[0]?._attr ?? {};\n\n const look: TableLook = {\n firstRow: tblLookAttr?.[\"w:firstRow\"] === \"1\" || undefined,\n lastRow: tblLookAttr?.[\"w:lastRow\"] === \"1\" || undefined,\n firstCol:\n tblLookAttr?.[\"w:firstColumn\"] === \"1\" ||\n tblLookAttr?.[\"w:firstCol\"] === \"1\" ||\n undefined,\n lastCol:\n tblLookAttr?.[\"w:lastColumn\"] === \"1\" ||\n tblLookAttr?.[\"w:lastCol\"] === \"1\" ||\n undefined,\n bandedRows: tblLookAttr?.[\"w:noHBand\"] === \"0\" || undefined,\n bandedCols: tblLookAttr?.[\"w:noVBand\"] === \"0\" || undefined,\n };\n\n // ① tblStyle 기본값 로드\n const tblStyleId = (tblPr?.[\"w:tblStyle\"]?.[0]?._attr ?? tblPr?.tblStyle?.[0]?._attr)?.[\"w:val\"];\n const styleDef = tblStyleId ? ctx.stylesMap.get(tblStyleId) : undefined;\n let tblBdr: TblBorderDef = styleDef?.tblBorders ?? {};\n\n // ② tblBorders 재정의 (tblStyle보다 우선)\n const tblBordersNode = tblPr?.[\"w:tblBorders\"]?.[0] ?? tblPr?.tblBorders?.[0];\n if (tblBordersNode) {\n const parsed = parseBorderDef(tblBordersNode);\n tblBdr = { ...tblBdr, ...parsed };\n }\n\n // defaultStroke for HWPX/HWP encoders: use insideH (inner horizontal border)\n const defaultStroke = tblBdr.insideH ?? tblBdr.top;\n const gridProps: GridProps = { look, defaultStroke };\n\n // Read column widths from w:tblGrid\n const tblGrid = tbl?.[\"w:tblGrid\"]?.[0] ?? tbl?.tblGrid?.[0];\n if (tblGrid) {\n const gridCols = toArr(tblGrid?.[\"w:gridCol\"] ?? tblGrid?.gridCol ?? []);\n const colWidthsPt = gridCols\n .map((gc: any) =>\n Metric.dxaToPt(Number(gc?._attr?.[\"w:w\"] ?? gc?._attr?.w ?? 0)),\n )\n .filter((w: number) => w > 0);\n if (colWidthsPt.length > 0) gridProps.colWidths = colWidthsPt;\n }\n\n const rowArr = toArr(tbl?.[\"w:tr\"] ?? tbl?.tr);\n\n // ── Pass 1: parse raw cells with vMerge info ──\n interface RawCell {\n cell: any;\n gridSpan: number;\n vMergeRestart: boolean;\n vMergeContinue: boolean;\n }\n const rawGrid: RawCell[][] = rowArr.map((row: any) => {\n const cellArr = toArr(row?.[\"w:tc\"] ?? row?.tc);\n return cellArr.map((cell: any): RawCell => {\n const tcPr = cell?.[\"w:tcPr\"]?.[0] ?? {};\n const gridSpan = Number(tcPr?.[\"w:gridSpan\"]?.[0]?._attr?.[\"w:val\"] ?? 1);\n const vMergeNode = tcPr?.[\"w:vMerge\"]?.[0];\n const vMergeVal = vMergeNode?._attr?.[\"w:val\"] ?? vMergeNode?._attr?.val;\n const vMergeRestart = vMergeVal === \"restart\";\n // vMerge present but val is not \"restart\" → continuation cell\n const vMergeContinue = vMergeNode != null && !vMergeRestart;\n return { cell, gridSpan, vMergeRestart, vMergeContinue };\n });\n });\n\n // ── Pass 2: compute rowSpan for restart cells ──\n // rsMap[ri][ci] = computed rowSpan (only set for restart cells)\n const rsMap: Map<string, number> = new Map();\n for (let ri = 0; ri < rawGrid.length; ri++) {\n let gridCol = 0;\n for (let ci = 0; ci < rawGrid[ri].length; ci++) {\n const rc = rawGrid[ri][ci];\n if (rc.vMergeRestart) {\n let span = 1;\n for (let nr = ri + 1; nr < rawGrid.length; nr++) {\n // Find the cell at the same grid column in the next row\n let col = 0;\n let found = false;\n for (const nc of rawGrid[nr]) {\n if (col === gridCol && nc.vMergeContinue) {\n span++;\n found = true;\n break;\n }\n col += nc.gridSpan;\n }\n if (!found) break;\n }\n rsMap.set(`${ri},${ci}`, span);\n }\n gridCol += rc.gridSpan;\n }\n }\n\n // ── Pass 3: build CellNodes, skip continuation cells ──\n const rowNodes = rawGrid.map((rawRow, ri) => {\n // Check for header row\n const row = rowArr[ri];\n const trPr = row?.[\"w:trPr\"]?.[0] ?? row?.trPr?.[0] ?? {};\n const isHeaderRow =\n trPr?.[\"w:tblHeader\"]?.[0] != null || trPr?.tblHeader?.[0] != null;\n if (ri === 0 && isHeaderRow) gridProps.headerRow = true;\n\n // Row height from w:trHeight\n let rowHeightPt: number | undefined;\n const trHAttr = trPr?.[\"w:trHeight\"]?.[0]?._attr ?? trPr?.trHeight?.[0]?._attr;\n if (trHAttr) {\n const hDxa = Number(trHAttr?.[\"w:val\"] ?? trHAttr?.val ?? 0);\n if (hDxa > 0) rowHeightPt = Metric.dxaToPt(hDxa);\n }\n\n const cellNodes: CellNode[] = [];\n for (let ci = 0; ci < rawRow.length; ci++) {\n const rc = rawRow[ci];\n // Skip continuation cells — they are part of a vertical merge\n if (rc.vMergeContinue) continue;\n\n const cell = rc.cell;\n const tcPr = cell?.[\"w:tcPr\"]?.[0] ?? {};\n\n // Cell background\n const bgAttr = tcPr?.[\"w:shd\"]?.[0]?._attr ?? {};\n const bg = safeHex(bgAttr?.[\"w:fill\"] ?? bgAttr?.fill);\n\n // ③ tcBorders 셀 수준 재정의 (우선순위 가장 높음)\n const tcBordersNode = tcPr?.[\"w:tcBorders\"]?.[0] ?? tcPr?.tcBorders?.[0];\n const cp: CellProps = { bg, isHeader: isHeaderRow || undefined };\n\n if (tcBordersNode) {\n const dirs: Array<[string, \"top\" | \"bot\" | \"left\" | \"right\"]> = [\n [\"top\", \"top\"], [\"bottom\", \"bot\"], [\"left\", \"left\"], [\"right\", \"right\"],\n ];\n for (const [xmlTag, propKey] of dirs) {\n const bdr =\n tcBordersNode?.[\"w:\" + xmlTag]?.[0]?._attr ??\n tcBordersNode?.[xmlTag]?.[0]?._attr;\n if (!bdr) continue;\n const val = bdr?.[\"w:val\"] ?? bdr?.val;\n if (val === \"none\" || val === \"nil\") {\n // explicit none: keep as undefined (no border)\n } else {\n cp[propKey] = safeStrokeDocx(\n val,\n Number(bdr?.[\"w:sz\"] ?? bdr?.sz ?? 4),\n bdr?.[\"w:color\"] ?? bdr?.color,\n );\n }\n }\n }\n\n // Vertical alignment\n const vaAttr =\n tcPr?.[\"w:vAlign\"]?.[0]?._attr ?? tcPr?.vAlign?.[0]?._attr ?? {};\n const vaVal = vaAttr?.[\"w:val\"] ?? vaAttr?.val;\n if (vaVal) {\n const vaMap: Record<string, \"top\" | \"mid\" | \"bot\"> = {\n top: \"top\", center: \"mid\", bottom: \"bot\",\n };\n cp.va = vaMap[vaVal];\n }\n\n const rs = rsMap.get(`${ri},${ci}`) ?? 1;\n\n // Compute logical column index for this cell\n let gridColIdx = 0;\n for (let prevCi = 0; prevCi < ci; prevCi++) {\n if (!rawRow[prevCi].vMergeContinue) gridColIdx += rawRow[prevCi].gridSpan;\n }\n\n // Apply 3-level border resolution (tblStyle → tblBorders → tcBorders already in cp)\n const colCount = gridProps.colWidths?.length ?? rawGrid[0]?.reduce((s, c) => s + c.gridSpan, 0) ?? 1;\n const resolvedCp = resolveCellBorders(cp, ri, gridColIdx, rs, rc.gridSpan, rawGrid.length, colCount, tblBdr);\n\n const paras = toArr(cell?.[\"w:p\"] ?? cell?.p).map((p: any) =>\n decodePara(p, ctx),\n );\n cellNodes.push(\n buildCell(paras.length > 0 ? paras : [buildPara([buildSpan(\"\")])], {\n cs: rc.gridSpan,\n rs,\n props: resolvedCp,\n }),\n );\n }\n return buildRow(cellNodes, rowHeightPt);\n });\n return buildGrid(rowNodes, gridProps);\n}\n\nfunction decodeGridSimple(tbl: any): GridNode {\n const rowArr = toArr(tbl?.[\"w:tr\"] ?? tbl?.tr);\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = toArr(row?.[\"w:tc\"] ?? row?.tc);\n return buildRow(\n cellArr.map((c: any) => buildCell([buildPara([buildSpan(cellText(c))])])),\n );\n });\n return buildGrid(rowNodes);\n}\n\nfunction decodeGridFlat(tbl: any): GridNode {\n return buildGrid([\n buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])]),\n ]);\n}\n\nfunction decodeGridText(tbl: any): ParaNode {\n return buildPara([buildSpan(tableText(tbl))]);\n}\n\nfunction cellText(cell: any): string {\n return toArr(cell?.[\"w:p\"] ?? cell?.p)\n .map((p: any) =>\n toArr(p?.[\"w:r\"] ?? p?.r)\n .map((r: any) =>\n toArr(r?.[\"w:t\"] ?? r?.t)\n .map((t: any) => (typeof t === \"string\" ? t : (t?._ ?? \"\")))\n .join(\"\"),\n )\n .join(\"\"),\n )\n .join(\" \");\n}\n\nfunction tableText(tbl: any): string {\n return toArr(tbl?.[\"w:tr\"] ?? tbl?.tr)\n .map((row: any) =>\n toArr(row?.[\"w:tc\"] ?? row?.tc)\n .map((c: any) => cellText(c))\n .join(\"\\t\"),\n )\n .join(\"\\n\");\n}\n\nfunction parseHeading(style?: string): 1 | 2 | 3 | 4 | 5 | 6 | undefined {\n if (!style) return undefined;\n const m = style.match(/[Hh]eading(\\d)/);\n if (m) {\n const n = Number(m[1]);\n if (n >= 1 && n <= 6) return n as any;\n }\n return undefined;\n}\n\nregistry.registerDecoder(new DocxDecoder());\n\n// ─── Anchor layout 추출 ─────────────────────────────────────\n\nfunction extractAnchorLayout(anchor: any): ImgLayout {\n const attr = anchor?._attr ?? {};\n const behindDoc = attr.behindDoc === '1';\n\n // 텍스트 감싸기 타입\n let wrap: ImgWrap = 'square';\n if (anchor?.['wp:wrapNone']?.[0] != null) wrap = behindDoc ? 'behind' : 'none';\n else if (anchor?.['wp:wrapTight']?.[0] != null) wrap = 'tight';\n else if (anchor?.['wp:wrapThrough']?.[0] != null) wrap = 'through';\n else if (anchor?.['wp:wrapSquare']?.[0] != null) wrap = 'square';\n else if (anchor?.['wp:wrapTopAndBottom']?.[0] != null) wrap = 'square';\n else if (anchor?.['wp:wrapBehind']?.[0] != null || behindDoc) wrap = 'behind';\n\n // 가로 위치\n const posH = anchor?.['wp:positionH']?.[0];\n const horzRelTo = parseHorzRelTo(posH?._attr?.relativeFrom);\n const horzAlignTxt = posH?.['wp:align']?.[0]?._text;\n const horzOffsetTxt = posH?.['wp:posOffset']?.[0]?._text;\n const horzAlign = horzAlignTxt ? parseHorzAlign(horzAlignTxt) : undefined;\n const xPt = horzOffsetTxt && !horzAlignTxt\n ? Metric.emuToPt(Number(horzOffsetTxt))\n : undefined;\n\n // 세로 위치\n const posV = anchor?.['wp:positionV']?.[0];\n const vertRelTo = parseVertRelTo(posV?._attr?.relativeFrom);\n const vertAlignTxt = posV?.['wp:align']?.[0]?._text;\n const vertOffsetTxt = posV?.['wp:posOffset']?.[0]?._text;\n const vertAlign = vertAlignTxt ? parseVertAlign(vertAlignTxt) : undefined;\n const yPt = vertOffsetTxt && !vertAlignTxt\n ? Metric.emuToPt(Number(vertOffsetTxt))\n : undefined;\n\n // 텍스트와의 거리\n const distT = attr.distT ? Metric.emuToPt(Number(attr.distT)) : undefined;\n const distB = attr.distB ? Metric.emuToPt(Number(attr.distB)) : undefined;\n const distL = attr.distL ? Metric.emuToPt(Number(attr.distL)) : undefined;\n const distR = attr.distR ? Metric.emuToPt(Number(attr.distR)) : undefined;\n const zOrder = attr.relativeHeight ? Number(attr.relativeHeight) : undefined;\n\n return { wrap, horzAlign, vertAlign, horzRelTo, vertRelTo, xPt, yPt, distT, distB, distL, distR, behindDoc, zOrder };\n}\n\nconst HORZ_RELTO_MAP: Record<string, ImgHorzRelTo> = {\n margin: 'margin', leftMargin: 'margin', rightMargin: 'margin',\n insideMargin: 'margin', outsideMargin: 'margin',\n column: 'column', page: 'page', character: 'para', paragraph: 'para',\n};\nconst VERT_RELTO_MAP: Record<string, ImgVertRelTo> = {\n margin: 'margin', topMargin: 'margin', bottomMargin: 'margin',\n insideMargin: 'margin', outsideMargin: 'margin',\n line: 'line', page: 'page', paragraph: 'para',\n};\nconst HORZ_ALIGN_MAP: Record<string, ImgHorzAlign> = {\n left: 'left', center: 'center', right: 'right',\n inside: 'left', outside: 'right',\n};\nconst VERT_ALIGN_MAP: Record<string, ImgVertAlign> = {\n top: 'top', center: 'center', bottom: 'bottom',\n inside: 'top', outside: 'bottom',\n};\n\nfunction parseHorzRelTo(v?: string): ImgHorzRelTo { return HORZ_RELTO_MAP[v ?? ''] ?? 'column'; }\nfunction parseVertRelTo(v?: string): ImgVertRelTo { return VERT_RELTO_MAP[v ?? ''] ?? 'para'; }\nfunction parseHorzAlign(v?: string): ImgHorzAlign | undefined { return HORZ_ALIGN_MAP[v ?? '']; }\nfunction parseVertAlign(v?: string): ImgVertAlign | undefined { return VERT_ALIGN_MAP[v ?? '']; }\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, ImgNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { ParaProps, TextProps } from '../../model/doc-props';\nimport { A4 } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildImg, buildGrid, buildRow, buildCell } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\nexport class MdDecoder implements Decoder {\n readonly format = 'md';\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const text = TextKit.decode(data);\n const lines = text.split(/\\r?\\n/);\n const kids: ContentNode[] = [];\n\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n\n // Heading\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length as 1 | 2 | 3 | 4 | 5 | 6;\n kids.push(buildPara([buildSpan(headingMatch[2], { b: level <= 2 })], { heading: level }));\n i++; continue;\n }\n\n // Table (pipe + separator line)\n if (line.includes('|') && i + 1 < lines.length && lines[i + 1].match(/^\\s*\\|?\\s*[-:]+\\s*\\|/)) {\n const tableResult = shield.guard(() => parseMdTable(lines, i), null, `md:table@${i}`);\n if (tableResult) { kids.push(tableResult.node); i = tableResult.nextLine; continue; }\n }\n\n // HR\n if (line.match(/^[-*_]{3,}$/)) { kids.push(buildPara([buildSpan('')], {})); i++; continue; }\n\n // List item\n const listMatch = line.match(/^(\\s*)([-*+]|\\d+\\.)\\s+(.+)$/);\n if (listMatch) {\n kids.push(buildPara(parseInline(listMatch[3]), {\n listLv: Math.floor(listMatch[1].length / 2),\n listOrd: /\\d+\\./.test(listMatch[2]),\n }));\n i++; continue;\n }\n\n // Blockquote\n const bqMatch = line.match(/^>\\s*(.*)$/);\n if (bqMatch) { kids.push(buildPara([buildSpan(bqMatch[1])], { indentPt: 28 })); i++; continue; }\n\n // Code block\n if (line.startsWith('```')) {\n const codeLines: string[] = [];\n i++;\n while (i < lines.length && !lines[i].startsWith('```')) { codeLines.push(lines[i]); i++; }\n i++;\n kids.push(buildPara([buildSpan(codeLines.join('\\n'), { font: 'Courier New' })], {}));\n continue;\n }\n\n // Empty line\n if (line.trim() === '') { i++; continue; }\n\n // Regular paragraph — check for alignment div\n const alignMatch = line.match(/^<div\\s+align=\"(center|right|left)\">(.*?)<\\/div>$/i);\n if (alignMatch) {\n const align = alignMatch[1].toLowerCase() as 'left' | 'center' | 'right';\n kids.push(buildPara(parseInline(alignMatch[2]), { align }));\n i++; continue;\n }\n\n // Regular paragraph\n kids.push(buildPara(parseInline(line), {}));\n i++;\n }\n\n warns.push(...shield.flush());\n const sheet = buildSheet(kids.length > 0 ? kids : [buildPara([buildSpan('')])], A4);\n return succeed(buildRoot({}, [sheet]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`MD decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\nfunction parseInline(text: string): (SpanNode | ImgNode)[] {\n const result: (SpanNode | ImgNode)[] = [];\n let rem = text;\n\n while (rem.length > 0) {\n // Image: \n let m = rem.match(/^(.*?)!\\[([^\\]]*)\\]\\((data:([^;]+);base64,([^)]+))\\)(.*)/s);\n if (m) {\n if (m[1]) result.push(buildSpan(m[1]));\n const mime = m[4] as ImgNode['mime'];\n const validMimes = ['image/png', 'image/jpeg', 'image/gif', 'image/bmp'];\n result.push(buildImg(m[5], validMimes.includes(mime) ? mime : 'image/png', 100, 100, m[2] || undefined));\n rem = m[6]; continue;\n }\n\n // Image:  — non-base64\n m = rem.match(/^(.*?)!\\[([^\\]]*)\\]\\(([^)]+)\\)(.*)/s);\n if (m) {\n if (m[1]) result.push(buildSpan(m[1]));\n // Can't convert URL to base64, just preserve alt text\n result.push(buildSpan(`[이미지: ${m[2] || m[3]}]`));\n rem = m[4]; continue;\n }\n\n // Bold+italic\n m = rem.match(/^(.*?)\\*\\*\\*(.+?)\\*\\*\\*(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { b: true, i: true })); rem = m[3]; continue; }\n\n // Bold\n m = rem.match(/^(.*?)\\*\\*(.+?)\\*\\*(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { b: true })); rem = m[3]; continue; }\n\n // Italic\n m = rem.match(/^(.*?)\\*(.+?)\\*(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { i: true })); rem = m[3]; continue; }\n\n // Strikethrough ~~text~~\n m = rem.match(/^(.*?)~~(.+?)~~(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { s: true })); rem = m[3]; continue; }\n\n // Underline <u>text</u>\n m = rem.match(/^(.*?)<u>(.+?)<\\/u>(.*)/si);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { u: true })); rem = m[3]; continue; }\n\n // Superscript <sup>text</sup>\n m = rem.match(/^(.*?)<sup>(.+?)<\\/sup>(.*)/si);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { sup: true })); rem = m[3]; continue; }\n\n // Subscript <sub>text</sub>\n m = rem.match(/^(.*?)<sub>(.+?)<\\/sub>(.*)/si);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { sub: true })); rem = m[3]; continue; }\n\n // Inline code\n m = rem.match(/^(.*?)`(.+?)`(.*)/s);\n if (m) { if (m[1]) result.push(buildSpan(m[1])); result.push(buildSpan(m[2], { font: 'Courier New' })); rem = m[3]; continue; }\n\n result.push(buildSpan(rem));\n break;\n }\n\n return result.length > 0 ? result : [buildSpan(text)];\n}\n\nfunction parseMdTable(lines: string[], startLine: number): { node: any; nextLine: number } | null {\n const parse = (line: string) => line.split('|').map(c => c.trim()).filter((c, i, arr) => i > 0 || c !== '');\n const headers = parse(lines[startLine]);\n\n let cur = startLine + 2;\n const rows: string[][] = [];\n while (cur < lines.length) {\n if (!lines[cur].includes('|')) break;\n const cells = parse(lines[cur]);\n if (cells.length === 0) break;\n rows.push(cells);\n cur++;\n }\n\n const allRows = [headers, ...rows];\n const gridRows = allRows.map((row, ri) =>\n buildRow(row.map(cell => buildCell([buildPara([buildSpan(cell, ri === 0 ? { b: true } : {})])]))),\n );\n\n return { node: buildGrid(gridRows), nextLine: cur };\n}\n\nregistry.registerDecoder(new MdDecoder());\n","import type { Encoder } from \"../../contract/encoder\";\nimport type {\n DocRoot,\n ParaNode,\n SpanNode,\n GridNode,\n ContentNode,\n ImgNode,\n SheetNode,\n CellNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n PageDims,\n TextProps,\n ParaProps,\n CellProps,\n Stroke,\n} from \"../../model/doc-props\";\nimport { A4, DEFAULT_STROKE, normalizeDims } from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport { Metric, safeFontToKr } from \"../../safety/StyleBridge\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\n\n// ─── All HWPX namespaces ────────────────────────────────────\nconst NS = [\n 'xmlns:ha=\"http://www.hancom.co.kr/hwpml/2011/app\"',\n 'xmlns:hp=\"http://www.hancom.co.kr/hwpml/2011/paragraph\"',\n 'xmlns:hp10=\"http://www.hancom.co.kr/hwpml/2016/paragraph\"',\n 'xmlns:hs=\"http://www.hancom.co.kr/hwpml/2011/section\"',\n 'xmlns:hc=\"http://www.hancom.co.kr/hwpml/2011/core\"',\n 'xmlns:hh=\"http://www.hancom.co.kr/hwpml/2011/head\"',\n 'xmlns:hhs=\"http://www.hancom.co.kr/hwpml/2011/history\"',\n 'xmlns:hm=\"http://www.hancom.co.kr/hwpml/2011/master-page\"',\n 'xmlns:hpf=\"http://www.hancom.co.kr/schema/2011/hpf\"',\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\"',\n 'xmlns:opf=\"http://www.idpf.org/2007/opf/\"',\n 'xmlns:ooxmlchart=\"http://www.hancom.co.kr/hwpml/2016/ooxmlchart\"',\n 'xmlns:hwpunitchar=\"http://www.hancom.co.kr/hwpml/2016/HwpUnitChar\"',\n 'xmlns:epub=\"http://www.idpf.org/2007/ops\"',\n 'xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"',\n].join(\" \");\n\n// ─── Registries for IDRef system ────────────────────────────\n\ninterface CharPrDef {\n id: number;\n height: number;\n bold: boolean;\n italic: boolean;\n underline: string;\n strikeout: string;\n textColor: string;\n fontName: string;\n fontId: number;\n bg?: string;\n}\n\ninterface ParaPrDef {\n id: number;\n align: string;\n listType?: string;\n listLevel?: number;\n intentHwp: number; // first-line indent in HWPUNIT\n prevHwp: number; // space before paragraph in HWPUNIT\n nextHwp: number; // space after paragraph in HWPUNIT\n lineSpacing: number; // line spacing percentage (e.g., 160 = 160%)\n}\n\ninterface BinEntry {\n id: string;\n name: string;\n data: Uint8Array;\n}\n\ninterface HwpxCtx {\n charPrs: CharPrDef[];\n charPrMap: Map<string, number>;\n paraPrs: ParaPrDef[];\n paraPrMap: Map<string, number>;\n borderFills: { id: number; xml: string }[];\n bins: BinEntry[];\n nextBinNum: number;\n nextElementId: number;\n availableWidth: number; // HWPUNIT — page width minus margins\n fonts: string[];\n fontMap: Map<string, number>;\n imgMap: WeakMap<ImgNode, string>; // ImgNode → binId (no mutation)\n nextZOrder: number; // monotonically increasing z-order for images/objects\n}\n\nfunction charPrKey(p: TextProps): string {\n return `${p.b ? 1 : 0}|${p.i ? 1 : 0}|${p.u ? 1 : 0}|${p.s ? 1 : 0}|${p.pt ?? 10}|${p.color ?? \"000000\"}|${p.font ?? \"\"}|${p.bg ?? \"\"}`;\n}\n\nfunction paraPrKey(p: ParaProps): string {\n return `${p.align ?? \"left\"}|${p.listOrd ?? \"\"}|${p.listLv ?? 0}|${p.indentPt ?? 0}|${p.spaceBefore ?? 0}|${p.spaceAfter ?? 0}|${p.lineHeight ?? 0}`;\n}\n\nfunction registerFont(name: string, ctx: HwpxCtx): number {\n const n = name || \"굴림체\";\n const existing = ctx.fontMap.get(n);\n if (existing !== undefined) return existing;\n const id = ctx.fonts.length;\n ctx.fonts.push(n);\n ctx.fontMap.set(n, id);\n return id;\n}\n\nfunction registerCharPr(props: TextProps, ctx: HwpxCtx): number {\n const key = charPrKey(props);\n const existing = ctx.charPrMap.get(key);\n if (existing !== undefined) return existing;\n\n const fontName = safeFontToKr(props.font) || \"굴림체\";\n const fontId = registerFont(fontName, ctx);\n\n const id = ctx.charPrs.length;\n const def: CharPrDef = {\n id,\n height: Metric.ptToHHeight(props.pt ?? 10),\n bold: !!props.b,\n italic: !!props.i,\n underline: props.u ? \"BOTTOM\" : \"NONE\",\n strikeout: props.s ? \"SOLID\" : \"NONE\",\n textColor: props.color ? `#${props.color}` : \"#000000\",\n fontName,\n fontId,\n bg: props.bg,\n };\n ctx.charPrs.push(def);\n ctx.charPrMap.set(key, id);\n return id;\n}\n\nfunction registerParaPr(props: ParaProps, ctx: HwpxCtx): number {\n const key = paraPrKey(props);\n const existing = ctx.paraPrMap.get(key);\n if (existing !== undefined) return existing;\n\n const id = ctx.paraPrs.length;\n const def: ParaPrDef = {\n id,\n align: (props.align ?? \"left\").toUpperCase(),\n intentHwp: props.indentPt ? Metric.ptToHwp(props.indentPt) : 0,\n prevHwp: props.spaceBefore ? Metric.ptToHwp(props.spaceBefore) : 0,\n nextHwp: props.spaceAfter ? Metric.ptToHwp(props.spaceAfter) : 0,\n lineSpacing: props.lineHeight ? Math.round(props.lineHeight * 100) : 160,\n };\n if (props.listOrd !== undefined) {\n def.listType = props.listOrd ? \"DIGIT\" : \"BULLET\";\n def.listLevel = props.listLv ?? 0;\n }\n ctx.paraPrs.push(def);\n ctx.paraPrMap.set(key, id);\n return id;\n}\n\n// ─── Pre-scan: collect all charPr/paraPr used ───────────────\n\nfunction scanContent(kids: ContentNode[], ctx: HwpxCtx): void {\n for (const kid of kids) {\n if (kid.tag === \"para\") scanPara(kid, ctx);\n else if (kid.tag === \"grid\") scanGrid(kid, ctx);\n }\n}\n\nfunction scanPara(para: ParaNode, ctx: HwpxCtx): void {\n registerParaPr(para.props, ctx);\n for (const kid of para.kids) {\n if (kid.tag === \"span\") registerCharPr(kid.props, ctx);\n else if (kid.tag === \"img\") registerImage(kid, ctx);\n }\n}\n\nfunction scanGrid(grid: GridNode, ctx: HwpxCtx): void {\n for (const row of grid.kids)\n for (const cell of row.kids) for (const p of cell.kids) scanPara(p, ctx);\n}\n\nfunction scanParas(paras: ParaNode[], ctx: HwpxCtx): void {\n for (const p of paras) scanPara(p, ctx);\n}\n\n// ─── Image handling ─────────────────────────────────────────\n\nfunction mimeToExt(mime: string): string {\n if (mime.includes(\"jpeg\")) return \"jpg\";\n if (mime.includes(\"gif\")) return \"gif\";\n if (mime.includes(\"bmp\")) return \"bmp\";\n return \"png\";\n}\n\nfunction registerImage(img: ImgNode, ctx: HwpxCtx): void {\n if (ctx.imgMap.has(img)) return;\n const ext = mimeToExt(img.mime);\n const id = `BIN${String(ctx.nextBinNum).padStart(4, \"0\")}`;\n const name = `${id}.${ext}`;\n ctx.nextBinNum++;\n const data = TextKit.base64Decode(img.b64);\n ctx.bins.push({ id, name, data });\n ctx.imgMap.set(img, id);\n}\n\n// ─── BorderFill ─────────────────────────────────────────────\n\nfunction addBorderFill(\n ctx: HwpxCtx,\n stroke?: Stroke,\n bgColor?: string,\n): number {\n const id = ctx.borderFills.length + 1;\n const s = stroke ?? DEFAULT_STROKE;\n const kindMap: Record<string, string> = {\n solid: \"SOLID\",\n dash: \"DASH\",\n dot: \"DOT\",\n double: \"DOUBLE\",\n none: \"NONE\",\n };\n const type = kindMap[s.kind] ?? \"SOLID\";\n const w = `${(s.pt * 0.3528).toFixed(2)} mm`;\n const c = s.color.startsWith(\"#\") ? s.color : `#${s.color}`;\n\n let fill = \"\";\n if (bgColor) {\n const bc = bgColor.startsWith(\"#\") ? bgColor : `#${bgColor}`;\n fill = `<hc:fillBrush><hc:winBrush faceColor=\"${bc}\" hatchColor=\"none\" alpha=\"0\"/></hc:fillBrush>`;\n }\n\n const xml = `<hh:borderFill id=\"${id}\" threeD=\"0\" shadow=\"0\" centerLine=\"NONE\" breakCellSeparateLine=\"0\"><hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/><hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/><hh:leftBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:rightBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:topBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:bottomBorder type=\"${type}\" width=\"${w}\" color=\"${c}\"/><hh:diagonal type=\"NONE\" width=\"0.12 mm\" color=\"#000000\"/>${fill}</hh:borderFill>`;\n ctx.borderFills.push({ id, xml });\n return id;\n}\n\nfunction addBorderFillPerSide(\n ctx: HwpxCtx,\n top?: Stroke,\n right?: Stroke,\n bottom?: Stroke,\n left?: Stroke,\n bgColor?: string,\n): number {\n const id = ctx.borderFills.length + 1;\n const kindMap: Record<string, string> = {\n solid: \"SOLID\", dash: \"DASH\", dot: \"DOT\", double: \"DOUBLE\", none: \"NONE\",\n };\n function sideXml(tag: string, s?: Stroke): string {\n const type = s ? (kindMap[s.kind] ?? \"SOLID\") : \"NONE\";\n const w = s ? `${(s.pt * 0.3528).toFixed(2)} mm` : \"0.12 mm\";\n const c = s ? (s.color.startsWith(\"#\") ? s.color : `#${s.color}`) : \"#000000\";\n return `<hh:${tag} type=\"${type}\" width=\"${w}\" color=\"${c}\"/>`;\n }\n\n let fill = \"\";\n if (bgColor) {\n const bc = bgColor.startsWith(\"#\") ? bgColor : `#${bgColor}`;\n fill = `<hc:fillBrush><hc:winBrush faceColor=\"${bc}\" hatchColor=\"none\" alpha=\"0\"/></hc:fillBrush>`;\n }\n\n const xml = `<hh:borderFill id=\"${id}\" threeD=\"0\" shadow=\"0\" centerLine=\"NONE\" breakCellSeparateLine=\"0\"><hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/><hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>${sideXml(\"leftBorder\", left)}${sideXml(\"rightBorder\", right)}${sideXml(\"topBorder\", top)}${sideXml(\"bottomBorder\", bottom)}<hh:diagonal type=\"NONE\" width=\"0.12 mm\" color=\"#000000\"/>${fill}</hh:borderFill>`;\n ctx.borderFills.push({ id, xml });\n return id;\n}\n\n// ─── Encoder class ──────────────────────────────────────────\n\nexport class HwpxEncoder implements Encoder {\n readonly format = \"hwpx\";\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n const sheet = doc.kids[0];\n const dims = normalizeDims(sheet?.dims ?? A4);\n\n // Available width = page width - left margin - right margin (in HWPUNIT)\n const availableWidth =\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(dims.ml) -\n Metric.ptToHwp(dims.mr);\n\n const ctx: HwpxCtx = {\n charPrs: [],\n charPrMap: new Map(),\n paraPrs: [],\n paraPrMap: new Map(),\n borderFills: [],\n bins: [],\n nextBinNum: 1,\n nextElementId: 10000,\n availableWidth,\n fonts: [],\n fontMap: new Map(),\n imgMap: new WeakMap(),\n nextZOrder: 0,\n };\n\n // Default borderFill (id=1, no border)\n addBorderFill(ctx, { kind: \"none\", pt: 0.1, color: \"000000\" });\n // Table border borderFill (id=2)\n addBorderFill(ctx, DEFAULT_STROKE);\n // Default no-border for text areas (id=3)\n addBorderFill(ctx, { kind: \"none\", pt: 0.1, color: \"000000\" });\n\n // Register default charPr (id=0) and paraPr (id=0)\n registerCharPr({}, ctx);\n registerParaPr({}, ctx);\n\n // Pre-scan all content to collect charPr/paraPr/images\n scanContent(sheet?.kids ?? [], ctx);\n if (sheet?.header) scanParas(sheet.header, ctx);\n if (sheet?.footer) scanParas(sheet.footer, ctx);\n\n // Extract plain text preview from document\n const previewText = extractPreviewText(sheet);\n\n // IMPORTANT: Generate section XML FIRST so that borderFills created\n // during table encoding are registered in ctx before headerXml runs.\n const sectionData = TextKit.encode(sectionXml(sheet, dims, ctx));\n const headerData = TextKit.encode(headerXml(dims, doc.meta, ctx));\n\n const entries: { name: string; data: Uint8Array }[] = [\n { name: \"mimetype\", data: TextKit.encode(\"application/hwp+zip\") },\n { name: \"version.xml\", data: TextKit.encode(VERSION_XML) },\n { name: \"Contents/header.xml\", data: headerData },\n { name: \"Contents/section0.xml\", data: sectionData },\n { name: \"Preview/PrvText.txt\", data: TextKit.encode(previewText) },\n { name: \"settings.xml\", data: TextKit.encode(SETTINGS_XML) },\n { name: \"META-INF/container.rdf\", data: TextKit.encode(CONTAINER_RDF) },\n {\n name: \"Contents/content.hpf\",\n data: TextKit.encode(contentHpf(ctx, doc.meta)),\n },\n { name: \"META-INF/container.xml\", data: TextKit.encode(CONTAINER_XML) },\n { name: \"META-INF/manifest.xml\", data: TextKit.encode(MANIFEST_XML) },\n ];\n\n for (const bin of ctx.bins) {\n entries.push({ name: `BinData/${bin.name}`, data: bin.data });\n }\n\n return succeed(await ArchiveKit.zip(entries));\n } catch (e: any) {\n return fail(`HWPX encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\n// ─── Constants ──────────────────────────────────────────────\n\nconst VERSION_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><hv:HCFVersion xmlns:hv=\"http://www.hancom.co.kr/hwpml/2011/version\" tagetApplication=\"WORDPROCESSOR\" major=\"5\" minor=\"1\" micro=\"0\" buildNumber=\"1\" os=\"1\" xmlVersion=\"1.4\" application=\"Hancom Office Hangul\" appVersion=\"11, 0, 0, 0\"/>`;\n\nconst CONTAINER_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><ocf:container xmlns:ocf=\"urn:oasis:names:tc:opendocument:xmlns:container\" xmlns:hpf=\"http://www.hancom.co.kr/schema/2011/hpf\"><ocf:rootfiles><ocf:rootfile full-path=\"Contents/content.hpf\" media-type=\"application/hwpml-package+xml\"/><ocf:rootfile full-path=\"Preview/PrvText.txt\" media-type=\"text/plain\"/><ocf:rootfile full-path=\"META-INF/container.rdf\" media-type=\"application/rdf+xml\"/></ocf:rootfiles></ocf:container>`;\n\nconst CONTAINER_RDF = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"><rdf:Description rdf:about=\"\"><ns0:hasPart xmlns:ns0=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#\" rdf:resource=\"Contents/header.xml\"/></rdf:Description><rdf:Description rdf:about=\"Contents/header.xml\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#HeaderFile\"/></rdf:Description><rdf:Description rdf:about=\"\"><ns0:hasPart xmlns:ns0=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#\" rdf:resource=\"Contents/section0.xml\"/></rdf:Description><rdf:Description rdf:about=\"Contents/section0.xml\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#SectionFile\"/></rdf:Description><rdf:Description rdf:about=\"\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#Document\"/></rdf:Description></rdf:RDF>`;\n\nconst MANIFEST_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><odf:manifest xmlns:odf=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\"/>`;\n\nconst SETTINGS_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><ha:HWPApplicationSetting xmlns:ha=\"http://www.hancom.co.kr/hwpml/2011/app\" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"><ha:CaretPosition listIDRef=\"0\" paraIDRef=\"0\" pos=\"0\"/><config:config-item-set name=\"PrintInfo\"><config:config-item name=\"PrintMethod\" type=\"short\">0</config:config-item><config:config-item name=\"ZoomX\" type=\"short\">100</config:config-item><config:config-item name=\"ZoomY\" type=\"short\">100</config:config-item></config:config-item-set></ha:HWPApplicationSetting>`;\n\nfunction contentHpf(ctx: HwpxCtx, meta?: any): string {\n const title = esc(meta?.title ?? \"\");\n const now = new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\");\n\n let items =\n `<opf:item id=\"header\" href=\"Contents/header.xml\" media-type=\"application/xml\"/>` +\n `<opf:item id=\"section0\" href=\"Contents/section0.xml\" media-type=\"application/xml\"/>` +\n `<opf:item id=\"settings\" href=\"settings.xml\" media-type=\"application/xml\"/>`;\n for (const bin of ctx.bins) {\n const ext = bin.name.split(\".\").pop()?.toLowerCase() ?? \"png\";\n const ct =\n ext === \"png\"\n ? \"image/png\"\n : ext === \"jpg\" || ext === \"jpeg\"\n ? \"image/jpeg\"\n : ext === \"gif\"\n ? \"image/gif\"\n : \"image/bmp\";\n items += `<opf:item id=\"${bin.id}\" href=\"BinData/${bin.name}\" media-type=\"${ct}\" isEmbeded=\"1\"/>`;\n }\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><opf:package ${NS} version=\"\" unique-identifier=\"\" id=\"\"><opf:metadata><opf:title>${title}</opf:title><opf:language>ko</opf:language><opf:meta name=\"creator\" content=\"text\"/><opf:meta name=\"subject\" content=\"text\"/><opf:meta name=\"description\" content=\"text\"/><opf:meta name=\"CreatedDate\" content=\"text\">${now}</opf:meta><opf:meta name=\"ModifiedDate\" content=\"text\">${now}</opf:meta><opf:meta name=\"keyword\" content=\"text\"/></opf:metadata><opf:manifest>${items}</opf:manifest><opf:spine><opf:itemref idref=\"header\" linear=\"yes\"/><opf:itemref idref=\"section0\" linear=\"yes\"/></opf:spine></opf:package>`;\n}\n\n// ─── header.xml ─────────────────────────────────────────────\n\nfunction headerXml(dims: PageDims, meta: any, ctx: HwpxCtx): string {\n // Font face definitions — register all unique fonts per language group\n const fontCount = ctx.fonts.length || 1;\n const langs = [\n \"HANGUL\",\n \"LATIN\",\n \"HANJA\",\n \"JAPANESE\",\n \"OTHER\",\n \"SYMBOL\",\n \"USER\",\n ];\n let fontFaces = `<hh:fontfaces itemCnt=\"${langs.length}\">`;\n for (const lang of langs) {\n fontFaces += `<hh:fontface lang=\"${lang}\" fontCnt=\"${fontCount}\">`;\n for (let fi = 0; fi < ctx.fonts.length; fi++) {\n fontFaces += `<hh:font id=\"${fi}\" face=\"${esc(ctx.fonts[fi])}\" type=\"TTF\" isEmbedded=\"0\"><hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/></hh:font>`;\n }\n if (ctx.fonts.length === 0) {\n fontFaces += `<hh:font id=\"0\" face=\"굴림체\" type=\"TTF\" isEmbedded=\"0\"><hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/></hh:font>`;\n }\n fontFaces += `</hh:fontface>`;\n }\n fontFaces += `</hh:fontfaces>`;\n\n // CharPr definitions\n let charPrXml = \"\";\n for (const cp of ctx.charPrs) {\n const bold = cp.bold ? \"<hh:bold/>\" : \"\";\n const italic = cp.italic ? \"<hh:italic/>\" : \"\";\n const fid = cp.fontId ?? 0;\n charPrXml += `<hh:charPr id=\"${cp.id}\" height=\"${cp.height}\" textColor=\"${cp.textColor}\" shadeColor=\"none\" useFontSpace=\"0\" useKerning=\"0\" symMark=\"NONE\" borderFillIDRef=\"3\"><hh:fontRef hangul=\"${fid}\" latin=\"${fid}\" hanja=\"${fid}\" japanese=\"${fid}\" other=\"${fid}\" symbol=\"${fid}\" user=\"${fid}\"/><hh:ratio hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/><hh:spacing hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/><hh:relSz hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/><hh:offset hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>${bold}${italic}<hh:underline type=\"${cp.underline}\" shape=\"SOLID\" color=\"#000000\"/><hh:strikeout shape=\"${cp.strikeout}\" color=\"#000000\"/><hh:outline type=\"NONE\"/><hh:shadow type=\"NONE\" color=\"#C0C0C0\" offsetX=\"10\" offsetY=\"10\"/></hh:charPr>`;\n }\n\n // ParaPr definitions\n let paraPrXml = \"\";\n for (const pp of ctx.paraPrs) {\n const marginSwitch = `<hp:switch><hp:case hp:required-namespace=\"http://www.hancom.co.kr/hwpml/2016/HwpUnitChar\"><hh:margin><hc:intent value=\"${pp.intentHwp}\" unit=\"HWPUNIT\"/><hc:left value=\"0\" unit=\"HWPUNIT\"/><hc:right value=\"0\" unit=\"HWPUNIT\"/><hc:prev value=\"${pp.prevHwp}\" unit=\"HWPUNIT\"/><hc:next value=\"${pp.nextHwp}\" unit=\"HWPUNIT\"/></hh:margin><hh:lineSpacing type=\"PERCENT\" value=\"${pp.lineSpacing}\" unit=\"HWPUNIT\"/></hp:case><hp:default><hh:margin><hc:intent value=\"${pp.intentHwp}\" unit=\"HWPUNIT\"/><hc:left value=\"0\" unit=\"HWPUNIT\"/><hc:right value=\"0\" unit=\"HWPUNIT\"/><hc:prev value=\"${pp.prevHwp}\" unit=\"HWPUNIT\"/><hc:next value=\"${pp.nextHwp}\" unit=\"HWPUNIT\"/></hh:margin><hh:lineSpacing type=\"PERCENT\" value=\"${pp.lineSpacing}\" unit=\"HWPUNIT\"/></hp:default></hp:switch>`;\n paraPrXml += `<hh:paraPr id=\"${pp.id}\" tabPrIDRef=\"0\" condense=\"0\" fontLineHeight=\"0\" snapToGrid=\"0\" suppressLineNumbers=\"0\" checked=\"0\"><hh:align horizontal=\"${pp.align}\" vertical=\"BASELINE\"/><hh:heading type=\"NONE\" idRef=\"0\" level=\"0\"/><hh:breakSetting breakLatinWord=\"KEEP_WORD\" breakNonLatinWord=\"BREAK_WORD\" widowOrphan=\"0\" keepWithNext=\"0\" keepLines=\"0\" pageBreakBefore=\"0\" lineWrap=\"BREAK\"/><hh:autoSpacing eAsianEng=\"0\" eAsianNum=\"0\"/>${marginSwitch}<hh:border borderFillIDRef=\"1\" offsetLeft=\"0\" offsetRight=\"0\" offsetTop=\"0\" offsetBottom=\"0\" connect=\"0\" ignoreMargin=\"0\"/></hh:paraPr>`;\n }\n\n // BorderFill definitions\n const borderFillXml = ctx.borderFills.map((bf) => bf.xml).join(\"\");\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><hh:head ${NS} version=\"1.4\" secCnt=\"1\"><hh:beginNum page=\"1\" footnote=\"1\" endnote=\"1\" pic=\"1\" tbl=\"1\" equation=\"1\"/><hh:refList>${fontFaces}<hh:borderFills itemCnt=\"${ctx.borderFills.length}\">${borderFillXml}</hh:borderFills><hh:charProperties itemCnt=\"${ctx.charPrs.length}\">${charPrXml}</hh:charProperties><hh:paraProperties itemCnt=\"${ctx.paraPrs.length}\">${paraPrXml}</hh:paraProperties><hh:tabProperties itemCnt=\"1\"><hh:tabPr id=\"0\" autoTabLeft=\"0\" autoTabRight=\"0\"/></hh:tabProperties><hh:styles itemCnt=\"1\"><hh:style id=\"0\" type=\"PARA\" name=\"바탕글\" engName=\"Normal\" paraPrIDRef=\"0\" charPrIDRef=\"0\" nextStyleIDRef=\"0\" langID=\"1042\" lockForm=\"0\"/></hh:styles></hh:refList><hh:compatibleDocument targetProgram=\"HWP201X\"><hh:layoutCompatibility/></hh:compatibleDocument><hh:docOption><hh:linkinfo path=\"\" pageInherit=\"1\" footnoteInherit=\"0\"/></hh:docOption><hh:trackchageConfig flags=\"56\"/></hh:head>`;\n}\n\n// ─── section0.xml ───────────────────────────────────────────\n\nfunction sectionXml(\n sheet: SheetNode | undefined,\n dims: PageDims,\n ctx: HwpxCtx,\n): string {\n const kids = sheet?.kids ?? [];\n\n // First paragraph includes secPr\n // WIDELY = portrait (standard), NARROWLY = landscape\n const secPr = `<hp:secPr id=\"\" textDirection=\"HORIZONTAL\" spaceColumns=\"1134\" tabStop=\"8000\" tabStopVal=\"4000\" tabStopUnit=\"HWPUNIT\" outlineShapeIDRef=\"0\" memoShapeIDRef=\"0\" textVerticalWidthHead=\"0\" masterPageCnt=\"0\"><hp:grid lineGrid=\"0\" charGrid=\"0\" wonggojiFormat=\"0\"/><hp:startNum pageStartsOn=\"BOTH\" page=\"0\" pic=\"0\" tbl=\"0\" equation=\"0\"/><hp:visibility hideFirstHeader=\"0\" hideFirstFooter=\"0\" hideFirstMasterPage=\"0\" border=\"SHOW_ALL\" fill=\"SHOW_ALL\" hideFirstPageNum=\"0\" hideFirstEmptyLine=\"0\" showLineNumber=\"0\"/><hp:lineNumberShape restartType=\"0\" countBy=\"0\" distance=\"0\" startNumber=\"0\"/><hp:pagePr landscape=\"${dims.orient === \"landscape\" ? \"NARROWLY\" : \"WIDELY\"}\" width=\"${Metric.ptToHwp(dims.wPt)}\" height=\"${Metric.ptToHwp(dims.hPt)}\" gutterType=\"LEFT_ONLY\"><hp:margin header=\"2834\" footer=\"2834\" gutter=\"0\" left=\"${Metric.ptToHwp(dims.ml)}\" right=\"${Metric.ptToHwp(dims.mr)}\" top=\"${Metric.ptToHwp(dims.mt)}\" bottom=\"${Metric.ptToHwp(dims.mb)}\"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"-1\" type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"284\" belowLine=\"568\" aboveLine=\"852\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"EACH_COLUMN\" beneathText=\"0\"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"0\" type=\"NONE\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"0\" belowLine=\"576\" aboveLine=\"864\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"END_OF_DOCUMENT\" beneathText=\"0\"/></hp:endNotePr><hp:pageBorderFill type=\"BOTH\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\"><hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/></hp:pageBorderFill><hp:pageBorderFill type=\"EVEN\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\"><hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/></hp:pageBorderFill><hp:pageBorderFill type=\"ODD\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\"><hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/></hp:pageBorderFill></hp:secPr><hp:ctrl><hp:colPr id=\"\" type=\"NEWSPAPER\" layout=\"LEFT\" colCount=\"1\" sameSz=\"1\" sameGap=\"0\"/></hp:ctrl>`;\n\n let contentXml = \"\";\n let isFirst = true;\n\n const defaultLineseg = `<hp:linesegarray><hp:lineseg textpos=\"0\" vertpos=\"0\" vertsize=\"1000\" textheight=\"1000\" baseline=\"850\" spacing=\"600\" horzpos=\"0\" horzsize=\"${ctx.availableWidth}\" flags=\"393216\"/></hp:linesegarray>`;\n\n for (const kid of kids) {\n if (kid.tag === \"para\") {\n contentXml += encodePara(kid, ctx, isFirst ? secPr : \"\");\n isFirst = false;\n } else if (kid.tag === \"grid\") {\n // Grid is embedded inside a paragraph's run.\n // When secPr is present, put it in a separate run (matching real HWPX structure).\n const gridXml = encodeGrid(kid, ctx);\n const prefix = isFirst ? secPr : \"\";\n const runsXml = prefix\n ? `<hp:run charPrIDRef=\"0\">${prefix}</hp:run><hp:run charPrIDRef=\"0\">${gridXml}<hp:t></hp:t></hp:run>`\n : `<hp:run charPrIDRef=\"0\">${gridXml}<hp:t></hp:t></hp:run>`;\n contentXml += `<hp:p id=\"0\" paraPrIDRef=\"0\" styleIDRef=\"0\" pageBreak=\"0\" columnBreak=\"0\" merged=\"0\">${runsXml}${defaultLineseg}</hp:p>`;\n isFirst = false;\n }\n }\n\n // If empty, add one empty paragraph with secPr\n if (contentXml === \"\") {\n contentXml = `<hp:p id=\"0\" paraPrIDRef=\"0\" styleIDRef=\"0\" pageBreak=\"0\" columnBreak=\"0\" merged=\"0\"><hp:run charPrIDRef=\"0\">${secPr}<hp:t></hp:t></hp:run>${defaultLineseg}</hp:p>`;\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><hs:sec ${NS}>${contentXml}</hs:sec>`;\n}\n\nfunction estimateCellHeight(cell: CellNode, ctx: HwpxCtx): number {\n const topPad = 141;\n const botPad = 141;\n let contentHeight = 0;\n for (const para of cell.kids) {\n const fontSize = getFontSizeForPara(para, ctx);\n const paraPrId = ctx.paraPrMap.get(paraPrKey(para.props));\n const paraPr = paraPrId !== undefined ? ctx.paraPrs[paraPrId] : null;\n const lineSpacing = paraPr ? paraPr.lineSpacing : 160;\n const spaceBefore = paraPr ? paraPr.prevHwp : 0;\n const spaceAfter = paraPr ? paraPr.nextHwp : 0;\n const lineHeight = Math.round((fontSize * lineSpacing) / 100);\n contentHeight += lineHeight + spaceBefore + spaceAfter;\n }\n if (contentHeight === 0) contentHeight = Math.round(1000 * 1.6); // 10pt @ 160%\n return contentHeight + topPad + botPad;\n}\n\nfunction encodePara(\n para: ParaNode,\n ctx: HwpxCtx,\n secPr: string = \"\",\n availWidth?: number,\n): string {\n const paraPrId = registerParaPr(para.props, ctx);\n\n // Detect page break: paragraph starts on new page if any span contains a pb node\n const hasPageBreak = para.kids.some(\n (k) => k.tag === \"span\" && k.kids.some((c) => c.tag === \"pb\"),\n );\n\n let runs = \"\";\n for (const kid of para.kids) {\n if (kid.tag === \"span\") {\n runs += encodeRun(kid, ctx);\n } else if (kid.tag === \"img\") {\n runs += encodeImage(kid, ctx);\n }\n }\n\n // If no runs, add default empty run\n if (runs === \"\") {\n runs = `<hp:run charPrIDRef=\"0\"><hp:t></hp:t></hp:run>`;\n }\n\n // Inject secPr into first run\n if (secPr) {\n // Insert secPr after the first charPrIDRef attribute close\n const firstRunEnd = runs.indexOf(\">\");\n if (firstRunEnd > -1) {\n runs =\n runs.substring(0, firstRunEnd + 1) +\n secPr +\n runs.substring(firstRunEnd + 1);\n }\n }\n\n // Compute lineseg values based on font size and actual line spacing.\n // In HWPX, vertsize = font height and spacing = extra gap = fontSize * (lineSpacing/100 - 1).\n // Total rendered line height = vertsize + spacing.\n const fontSize = getFontSizeForPara(para, ctx);\n const paraPr = ctx.paraPrs[paraPrId];\n const lineSpacing = paraPr?.lineSpacing ?? 160;\n const vertsize = fontSize;\n const textheight = fontSize;\n const baseline = Math.round(fontSize * 0.85);\n const spacing = Math.max(0, Math.round(fontSize * (lineSpacing / 100 - 1)));\n const horzsize = availWidth ?? ctx.availableWidth;\n const linesegarray = `<hp:linesegarray><hp:lineseg textpos=\"0\" vertpos=\"0\" vertsize=\"${vertsize}\" textheight=\"${textheight}\" baseline=\"${baseline}\" spacing=\"${spacing}\" horzpos=\"0\" horzsize=\"${horzsize}\" flags=\"393216\"/></hp:linesegarray>`;\n\n return `<hp:p id=\"0\" paraPrIDRef=\"${paraPrId}\" styleIDRef=\"0\" pageBreak=\"${hasPageBreak ? \"1\" : \"0\"}\" columnBreak=\"0\" merged=\"0\">${runs}${linesegarray}</hp:p>`;\n}\n\n/** Get the font size (in HWPX height units, 1000=10pt) for lineseg computation */\nfunction getFontSizeForPara(para: ParaNode, ctx: HwpxCtx): number {\n for (const kid of para.kids) {\n if (kid.tag === \"span\") {\n const charPrId = ctx.charPrMap.get(charPrKey(kid.props));\n if (charPrId !== undefined && ctx.charPrs[charPrId]) {\n return ctx.charPrs[charPrId].height;\n }\n }\n }\n return 1000; // default 10pt\n}\n\nfunction encodeRun(span: SpanNode, ctx: HwpxCtx): string {\n const charPrId = registerCharPr(span.props, ctx);\n\n const parts: string[] = [];\n for (const kid of span.kids) {\n if (kid.tag === \"txt\") {\n if (kid.content) {\n parts.push(`<hp:t>${esc(kid.content)}</hp:t>`);\n } else {\n parts.push(`<hp:t></hp:t>`);\n }\n } else if (kid.tag === \"pagenum\") {\n const fmt =\n kid.format === \"roman\"\n ? \"ROMAN_LOWER\"\n : kid.format === \"romanCaps\"\n ? \"ROMAN_UPPER\"\n : \"DIGIT\";\n parts.push(`<hp:pageNum pageStartsOn=\"BOTH\" formatType=\"${fmt}\"/>`);\n } else if (kid.tag === \"br\") {\n parts.push(`<hp:t>\\n</hp:t>`);\n }\n // pb is handled at paragraph level (pageBreak attribute), skip here\n }\n\n return `<hp:run charPrIDRef=\"${charPrId}\">${parts.join(\"\")}</hp:run>`;\n}\n\n// HWPX textWrap 매핑\nconst WRAP_HWPX: Record<string, string> = {\n inline: 'TOP_AND_BOTTOM',\n square: 'SQUARE',\n tight: 'BOTH_SIDES',\n through: 'BOTH_SIDES',\n none: 'FRONT_TEXT',\n behind: 'BEHIND_TEXT',\n front: 'FRONT_TEXT',\n};\n// textFlow 매핑 (wrap 타입별)\nconst TEXT_FLOW_HWPX: Record<string, string> = {\n inline: 'BOTH_SIDES',\n square: 'LARGEST_ONLY',\n tight: 'BOTH_SIDES',\n through: 'BOTH_SIDES',\n none: 'BOTH_SIDES',\n behind: 'BOTH_SIDES',\n front: 'BOTH_SIDES',\n};\nconst HORZ_RELTO_HWPX: Record<string, string> = {\n para: 'PARA', margin: 'MARGIN', page: 'PAPER', column: 'COLUMN',\n};\nconst VERT_RELTO_HWPX: Record<string, string> = {\n para: 'PARA', margin: 'MARGIN', page: 'PAPER', line: 'LINE',\n};\n\nfunction encodeImage(img: ImgNode, ctx: HwpxCtx): string {\n const binId = ctx.imgMap.get(img);\n if (!binId) return \"\";\n\n const charPrId = registerCharPr({}, ctx);\n const w = Metric.ptToHwp(img.w);\n const h = Metric.ptToHwp(img.h);\n const cx = Math.round(w / 2);\n const cy = Math.round(h / 2);\n\n const layout = img.layout;\n const isInline = !layout || layout.wrap === 'inline';\n\n const textWrap = layout ? (WRAP_HWPX[layout.wrap] ?? 'TOP_AND_BOTTOM') : 'TOP_AND_BOTTOM';\n const textFlow = layout ? (TEXT_FLOW_HWPX[layout.wrap] ?? 'BOTH_SIDES') : 'BOTH_SIDES';\n const treatAsChar = isInline ? '1' : '0';\n const flowWithText = '1';\n // behind/front/inline 이미지는 다른 객체와 겹침 허용 불필요; square/tight는 허용\n const allowOverlap = (!isInline && layout?.wrap !== 'behind' && layout?.wrap !== 'front') ? '1' : '0';\n\n const horzRelTo = layout?.horzRelTo ? (HORZ_RELTO_HWPX[layout.horzRelTo] ?? 'PARA') : 'PARA';\n const vertRelTo = layout?.vertRelTo ? (VERT_RELTO_HWPX[layout.vertRelTo] ?? 'PARA') : 'PARA';\n\n const ALIGN_H: Record<string, string> = { left: 'LEFT', center: 'CENTER', right: 'RIGHT' };\n const ALIGN_V: Record<string, string> = { top: 'TOP', center: 'CENTER', bottom: 'BOTTOM' };\n const horzAlign = layout?.horzAlign ? (ALIGN_H[layout.horzAlign] ?? 'LEFT') : 'LEFT';\n const vertAlign = layout?.vertAlign ? (ALIGN_V[layout.vertAlign] ?? 'TOP') : 'TOP';\n const horzOffset = layout?.xPt != null ? Metric.ptToHwp(layout.xPt) : 0;\n const vertOffset = layout?.yPt != null ? Metric.ptToHwp(layout.yPt) : 0;\n\n // hp:pic children must follow the exact HWPX spec order.\n const zOrder = ctx.nextZOrder++;\n return `<hp:run charPrIDRef=\"${charPrId}\"><hp:pic id=\"${ctx.nextElementId++}\" zOrder=\"${zOrder}\" numberingType=\"PICTURE\" textWrap=\"${textWrap}\" textFlow=\"${textFlow}\" lock=\"0\" dropcapstyle=\"None\" href=\"\" groupLevel=\"0\" instid=\"0\" reverse=\"0\"><hp:offset x=\"0\" y=\"0\"/><hp:orgSz width=\"${w}\" height=\"${h}\"/><hp:curSz width=\"${w}\" height=\"${h}\"/><hp:flip horizontal=\"0\" vertical=\"0\"/><hp:rotationInfo angle=\"0\" centerX=\"${cx}\" centerY=\"${cy}\" rotateimage=\"1\"/><hp:renderingInfo><hc:transMatrix e1=\"1\" e2=\"0\" e3=\"0\" e4=\"0\" e5=\"1\" e6=\"0\"/><hc:scaMatrix e1=\"1\" e2=\"0\" e3=\"0\" e4=\"0\" e5=\"1\" e6=\"0\"/><hc:rotMatrix e1=\"1\" e2=\"0\" e3=\"0\" e4=\"0\" e5=\"1\" e6=\"0\"/></hp:renderingInfo><hp:imgRect><hc:pt0 x=\"0\" y=\"0\"/><hc:pt1 x=\"${w}\" y=\"0\"/><hc:pt2 x=\"${w}\" y=\"${h}\"/><hc:pt3 x=\"0\" y=\"${h}\"/></hp:imgRect><hp:imgClip left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/><hp:inMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/><hp:imgDim dimwidth=\"${w}\" dimheight=\"${h}\"/><hc:img binaryItemIDRef=\"${binId}\" bright=\"0\" contrast=\"0\" effect=\"REAL_PIC\" alpha=\"0\"/><hp:effects/><hp:sz width=\"${w}\" widthRelTo=\"ABSOLUTE\" height=\"${h}\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/><hp:pos treatAsChar=\"${treatAsChar}\" affectLSpacing=\"0\" flowWithText=\"${flowWithText}\" allowOverlap=\"${allowOverlap}\" holdAnchorAndSO=\"0\" vertRelTo=\"${vertRelTo}\" horzRelTo=\"${horzRelTo}\" vertAlign=\"${vertAlign}\" horzAlign=\"${horzAlign}\" vertOffset=\"${vertOffset}\" horzOffset=\"${horzOffset}\"/><hp:outMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/></hp:pic><hp:t></hp:t></hp:run>`;\n}\n\nfunction encodeGrid(grid: GridNode, ctx: HwpxCtx): string {\n const rowCount = grid.kids.length;\n\n // Build a per-row occupancy set that tracks which column indices are already\n // \"taken\" by a rowSpan cell from an earlier row. This must be done before\n // computing colCount so that we get the correct logical column count even for\n // rows whose cells were skipped (vMergeContinue) in the DocRoot model.\n const rowOccupancy: Set<number>[] = Array.from(\n { length: rowCount },\n () => new Set<number>(),\n );\n let colCount = 0;\n for (let ri = 0; ri < grid.kids.length; ri++) {\n const row = grid.kids[ri];\n let ci = 0;\n for (const cell of row.kids) {\n // Advance past columns occupied by rowSpan cells from above rows\n while (rowOccupancy[ri].has(ci)) ci++;\n // Mark columns taken by this cell's rowSpan in subsequent rows\n if (cell.rs > 1) {\n for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) {\n for (let c = ci; c < ci + cell.cs; c++) {\n rowOccupancy[r].add(c);\n }\n }\n }\n ci += cell.cs;\n }\n // Advance past any trailing occupied columns (edge case: last cell has rowSpan)\n while (rowOccupancy[ri].has(ci)) ci++;\n if (ci > colCount) colCount = ci;\n }\n if (colCount === 0) colCount = grid.kids[0]?.kids.length ?? 1;\n\n // Calculate column widths in HWPUNIT\n const totalWidth = ctx.availableWidth;\n const defaultColW = Math.round(totalWidth / (colCount || 1));\n const colWidths: number[] = [];\n if (grid.props.colWidths && grid.props.colWidths.length === colCount) {\n // Fill zero-width columns by distributing remaining space\n const srcPt = [...grid.props.colWidths];\n const knownTotal = srcPt.filter((w) => w > 0).reduce((s, w) => s + w, 0);\n const zeroCount = srcPt.filter((w) => w <= 0).length;\n const remaining = Math.max(0, Metric.hwpToPt(totalWidth) - knownTotal);\n const zeroFill = zeroCount > 0 ? remaining / zeroCount : 0;\n for (let i = 0; i < srcPt.length; i++) {\n if (srcPt[i] <= 0)\n srcPt[i] = zeroFill > 0 ? zeroFill : Metric.hwpToPt(defaultColW);\n }\n for (const wPt of srcPt) colWidths.push(Metric.ptToHwp(wPt));\n } else {\n for (let c = 0; c < colCount; c++) colWidths.push(defaultColW);\n }\n // Scale down to fit available width (only when table exceeds page by >5%)\n const rawTotal = colWidths.reduce((s, w) => s + w, 0);\n if (rawTotal > totalWidth * 1.05) {\n const scale = totalWidth / rawTotal;\n for (let i = 0; i < colWidths.length; i++)\n colWidths[i] = Math.round(colWidths[i] * scale);\n }\n const actualTotal = colWidths.reduce((s, w) => s + w, 0);\n\n // Table borderFillIDRef\n const tblBfId = grid.props.defaultStroke\n ? addBorderFill(ctx, grid.props.defaultStroke)\n : 2; // default table border\n\n // Pre-calculate row heights (max cell height per row)\n const rowHeights: number[] = [];\n for (const row of grid.kids) {\n if (row.heightPt != null && row.heightPt > 0) {\n rowHeights.push(Metric.ptToHwp(row.heightPt));\n } else {\n let maxH = 0;\n for (const cell of row.kids) {\n const h = estimateCellHeight(cell, ctx);\n if (h > maxH) maxH = h;\n }\n rowHeights.push(maxH);\n }\n }\n const totalTableHeight = rowHeights.reduce((s, h) => s + h, 0);\n\n // Rows — use the pre-computed rowOccupancy to get correct colAddr for each cell\n let rowsXml = \"\";\n for (let ri = 0; ri < grid.kids.length; ri++) {\n const row = grid.kids[ri];\n const rowH = rowHeights[ri];\n let cellsXml = \"\";\n let colIdx = 0;\n for (let ci = 0; ci < row.kids.length; ci++) {\n const cell = row.kids[ci];\n\n // Skip columns occupied by rowSpan cells from above rows\n while (rowOccupancy[ri].has(colIdx)) colIdx++;\n\n // Cell borderFill: use per-side if any side border is specified, else fallback to table default\n let cellBfId = tblBfId;\n const cp = cell.props;\n const hasPerSideBorder = cp.top || cp.bot || cp.left || cp.right;\n if (hasPerSideBorder || cp.bg) {\n if (hasPerSideBorder) {\n const defStroke = grid.props.defaultStroke ?? DEFAULT_STROKE;\n cellBfId = addBorderFillPerSide(\n ctx,\n cp.top ?? defStroke,\n cp.right ?? defStroke,\n cp.bot ?? defStroke,\n cp.left ?? defStroke,\n cp.bg,\n );\n } else {\n cellBfId = addBorderFill(\n ctx,\n grid.props.defaultStroke ?? DEFAULT_STROKE,\n cp.bg,\n );\n }\n }\n\n // Calculate cell width from column widths (sum colSpan columns)\n let cellW = 0;\n for (\n let sc = colIdx;\n sc < colIdx + cell.cs && sc < colWidths.length;\n sc++\n )\n cellW += colWidths[sc];\n if (cellW === 0) cellW = defaultColW * cell.cs;\n\n // Cell inner width for lineseg (subtract left + right cell margins: 141+141=282 HWPUNIT)\n const cellInnerW = Math.max(cellW - 282, 100);\n\n // Encode cell paragraphs with correct inner width\n const parasXml = cell.kids\n .map((p) => encodePara(p, ctx, \"\", cellInnerW))\n .join(\"\");\n\n cellsXml += `<hp:tc name=\"\" header=\"0\" hasMargin=\"1\" protect=\"0\" editable=\"0\" dirty=\"0\" borderFillIDRef=\"${cellBfId}\"><hp:subList id=\"\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"${cell.props.va === \"mid\" ? \"CENTER\" : cell.props.va === \"bot\" ? \"BOTTOM\" : \"TOP\"}\" linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"0\" textHeight=\"0\" hasTextRef=\"0\" hasNumRef=\"0\">${parasXml}</hp:subList><hp:cellAddr colAddr=\"${colIdx}\" rowAddr=\"${ri}\"/><hp:cellSpan colSpan=\"${cell.cs}\" rowSpan=\"${cell.rs}\"/><hp:cellSz width=\"${cellW}\" height=\"${rowH}\"/><hp:cellMargin left=\"141\" right=\"141\" top=\"141\" bottom=\"141\"/></hp:tc>`;\n colIdx += cell.cs;\n }\n rowsXml += `<hp:tr>${cellsXml}</hp:tr>`;\n }\n\n const headerRow = grid.props.headerRow ? ' repeatHeader=\"1\"' : \"\";\n\n return `<hp:tbl id=\"${ctx.nextElementId++}\" zOrder=\"0\" numberingType=\"TABLE\" textWrap=\"TOP_AND_BOTTOM\" textFlow=\"BOTH_SIDES\" lock=\"0\" dropcapstyle=\"None\" pageBreak=\"NONE\"${headerRow} rowCnt=\"${rowCount}\" colCnt=\"${colCount}\" cellSpacing=\"0\" borderFillIDRef=\"${tblBfId}\" noAdjust=\"0\"><hp:sz width=\"${actualTotal}\" widthRelTo=\"ABSOLUTE\" height=\"${totalTableHeight}\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/><hp:pos treatAsChar=\"1\" affectLSpacing=\"0\" flowWithText=\"1\" allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" vertAlign=\"TOP\" horzAlign=\"LEFT\" vertOffset=\"0\" horzOffset=\"0\"/><hp:outMargin left=\"138\" right=\"138\" top=\"138\" bottom=\"138\"/><hp:inMargin left=\"138\" right=\"138\" top=\"138\" bottom=\"138\"/>${rowsXml}</hp:tbl>`;\n}\n\nfunction extractPreviewText(sheet?: SheetNode): string {\n if (!sheet) return \"\";\n const lines: string[] = [];\n for (const kid of sheet.kids) {\n if (kid.tag === \"para\") {\n const text = kid.kids\n .map((k) => {\n if (k.tag === \"span\")\n return k.kids\n .map((c) => (c.tag === \"txt\" ? c.content : \"\"))\n .join(\"\");\n return \"\";\n })\n .join(\"\");\n if (text) lines.push(text);\n } else if (kid.tag === \"grid\") {\n for (const row of kid.kids) {\n const cells = row.kids.map((cell) =>\n cell.kids\n .map((p) =>\n p.kids\n .map((k) => {\n if (k.tag === \"span\")\n return k.kids\n .map((c) => (c.tag === \"txt\" ? c.content : \"\"))\n .join(\"\");\n return \"\";\n })\n .join(\"\"),\n )\n .join(\"\"),\n );\n lines.push(cells.join(\"\\t\"));\n }\n }\n }\n return lines.join(\"\\r\\n\");\n}\n\nfunction esc(s: string): string {\n return TextKit.escapeXml(s);\n}\n\nregistry.registerEncoder(new HwpxEncoder());\n","import type { Encoder } from '../../contract/encoder';\nimport type { DocRoot, ParaNode, SpanNode, GridNode, ContentNode, ImgNode, SheetNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { PageDims, GridProps, CellProps } from '../../model/doc-props';\nimport { A4, normalizeDims } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { Metric } from '../../safety/StyleBridge';\nimport { ArchiveKit } from '../../toolkit/ArchiveKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\ninterface ImageEntry { rId: string; name: string; data: Uint8Array; ext: string }\n\nexport class DocxEncoder implements Encoder {\n readonly format = 'docx';\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n const sheet = doc.kids[0];\n const dims = normalizeDims(sheet?.dims ?? A4);\n const kids = sheet?.kids ?? [];\n\n const images: ImageEntry[] = [];\n const ctx: EncCtx = { images, nextId: 10, nextImgNum: 1, warns: [], imgMap: new WeakMap() };\n\n // Collect images from content\n collectImages(kids, ctx);\n\n // Header / footer\n let headerParas = sheet?.header;\n let footerParas = sheet?.footer;\n const hasHeader = headerParas && headerParas.length > 0;\n const hasFooter = footerParas && footerParas.length > 0;\n\n // Collect images from header/footer\n if (hasHeader) collectImagesFromParas(headerParas!, ctx);\n if (hasFooter) collectImagesFromParas(footerParas!, ctx);\n\n const headerRId = hasHeader ? `rId${ctx.nextId++}` : '';\n const footerRId = hasFooter ? `rId${ctx.nextId++}` : '';\n\n // Numbering: collect list info\n const numInfo = collectNumbering(kids);\n\n const entries: { name: string; data: Uint8Array }[] = [\n { name: '[Content_Types].xml', data: TextKit.encode(contentTypes(images, hasHeader, hasFooter)) },\n { name: '_rels/.rels', data: TextKit.encode(pkgRels()) },\n { name: 'word/document.xml', data: TextKit.encode(documentXml(kids, dims, ctx, headerRId, footerRId)) },\n { name: 'word/styles.xml', data: TextKit.encode(stylesXml()) },\n { name: 'word/settings.xml', data: TextKit.encode(settingsXml()) },\n { name: 'word/_rels/document.xml.rels', data: TextKit.encode(docRels(images, headerRId, footerRId, numInfo.hasLists)) },\n { name: 'docProps/app.xml', data: TextKit.encode(appXml()) },\n { name: 'docProps/core.xml', data: TextKit.encode(coreXml(doc.meta)) },\n ];\n\n // Add numbering.xml if needed\n if (numInfo.hasLists) {\n entries.push({ name: 'word/numbering.xml', data: TextKit.encode(numberingXml(numInfo)) });\n }\n\n // Add header/footer files\n if (hasHeader) {\n entries.push({ name: 'word/header1.xml', data: TextKit.encode(headerFooterXml('hdr', headerParas!, ctx)) });\n }\n if (hasFooter) {\n entries.push({ name: 'word/footer1.xml', data: TextKit.encode(headerFooterXml('ftr', footerParas!, ctx)) });\n }\n\n // Add image media files\n for (const img of images) {\n entries.push({ name: `word/media/${img.name}`, data: img.data });\n }\n\n return succeed(await ArchiveKit.zip(entries));\n } catch (e: any) {\n return fail(`DOCX encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\n// ─── Context ────────────────────────────────────────────────\n\ninterface EncCtx {\n images: ImageEntry[];\n nextId: number;\n nextImgNum: number;\n warns: string[];\n imgMap: WeakMap<ImgNode, string>; // ImgNode → rId (no mutation)\n}\n\n// ─── Image collection ───────────────────────────────────────\n\nfunction mimeToExt(mime: string): string {\n if (mime.includes('jpeg')) return 'jpeg';\n if (mime.includes('gif')) return 'gif';\n if (mime.includes('bmp')) return 'bmp';\n return 'png';\n}\n\nfunction collectImages(kids: ContentNode[], ctx: EncCtx): void {\n for (const kid of kids) {\n if (kid.tag === 'para') collectImagesFromPara(kid, ctx);\n else if (kid.tag === 'grid') {\n for (const row of kid.kids)\n for (const cell of row.kids)\n for (const p of cell.kids) collectImagesFromPara(p, ctx);\n }\n }\n}\n\nfunction collectImagesFromParas(paras: ParaNode[], ctx: EncCtx): void {\n for (const p of paras) collectImagesFromPara(p, ctx);\n}\n\nfunction collectImagesFromPara(para: ParaNode, ctx: EncCtx): void {\n for (const kid of para.kids) {\n if (kid.tag === 'img') registerImage(kid, ctx);\n }\n}\n\nfunction registerImage(img: ImgNode, ctx: EncCtx): void {\n if (ctx.imgMap.has(img)) return;\n const ext = mimeToExt(img.mime);\n const name = `image${ctx.nextImgNum++}.${ext}`;\n const rId = `rId${ctx.nextId++}`;\n const data = TextKit.base64Decode(img.b64);\n ctx.images.push({ rId, name, data, ext });\n ctx.imgMap.set(img, rId);\n}\n\n// ─── List/numbering collection ──────────────────────────────\n\ninterface NumInfo {\n hasLists: boolean;\n hasBullet: boolean;\n hasNumbered: boolean;\n}\n\nfunction collectNumbering(kids: ContentNode[]): NumInfo {\n let hasBullet = false;\n let hasNumbered = false;\n for (const kid of kids) {\n if (kid.tag === 'para') {\n if (kid.props.listOrd === true) hasNumbered = true;\n else if (kid.props.listOrd === false) hasBullet = true;\n }\n }\n return { hasLists: hasBullet || hasNumbered, hasBullet, hasNumbered };\n}\n\n// ─── OOXML boilerplate ──────────────────────────────────────\n\nfunction contentTypes(images: ImageEntry[], hasHeader?: boolean, hasFooter?: boolean): string {\n const imgDefaults = new Set<string>();\n for (const img of images) imgDefaults.add(img.ext);\n\n let defaults = `<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>`;\n\n for (const ext of imgDefaults) {\n const ct = ext === 'png' ? 'image/png' : ext === 'jpeg' ? 'image/jpeg' : ext === 'gif' ? 'image/gif' : 'image/bmp';\n defaults += `\\n <Default Extension=\"${ext}\" ContentType=\"${ct}\"/>`;\n }\n\n let overrides = `<Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>\n <Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>\n <Override PartName=\"/word/settings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/>\n <Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>\n <Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>`;\n\n if (hasHeader) overrides += `\\n <Override PartName=\"/word/header1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml\"/>`;\n if (hasFooter) overrides += `\\n <Override PartName=\"/word/footer1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml\"/>`;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n ${defaults}\n ${overrides}\n</Types>`;\n}\n\nfunction pkgRels(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>\n <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>\n</Relationships>`;\n}\n\nfunction docRels(images: ImageEntry[], headerRId?: string, footerRId?: string, hasLists?: boolean): string {\n let rels = `<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>`;\n\n // Numbering relationship — only when lists exist\n if (hasLists) {\n rels += `\\n <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>`;\n }\n\n for (const img of images) {\n rels += `\\n <Relationship Id=\"${img.rId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/${img.name}\"/>`;\n }\n\n if (headerRId) {\n rels += `\\n <Relationship Id=\"${headerRId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/>`;\n }\n if (footerRId) {\n rels += `\\n <Relationship Id=\"${footerRId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/>`;\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n ${rels}\n</Relationships>`;\n}\n\nfunction appXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\">\n <Application>hwpkit</Application>\n</Properties>`;\n}\n\nfunction coreXml(meta: any): string {\n const now = new Date().toISOString();\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n <dc:title>${esc(meta.title ?? '')}</dc:title>\n <dc:creator>${esc(meta.author ?? '')}</dc:creator>\n <dcterms:created xsi:type=\"dcterms:W3CDTF\">${meta.created ?? now}</dcterms:created>\n <dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>\n</cp:coreProperties>`;\n}\n\nfunction stylesXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:docDefaults>\n <w:rPrDefault><w:rPr>\n <w:rFonts w:ascii=\"맑은 고딕\" w:eastAsia=\"맑은 고딕\" w:hAnsi=\"맑은 고딕\"/>\n <w:sz w:val=\"20\"/>\n <w:szCs w:val=\"20\"/>\n </w:rPr></w:rPrDefault>\n <w:pPrDefault><w:pPr>\n <w:spacing w:after=\"0\" w:line=\"384\" w:lineRule=\"auto\"/>\n <w:jc w:val=\"both\"/>\n </w:pPr></w:pPrDefault>\n </w:docDefaults>\n <w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading1\"><w:name w:val=\"heading 1\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:keepNext/><w:outlineLvl w:val=\"0\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"44\"/><w:szCs w:val=\"44\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading2\"><w:name w:val=\"heading 2\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:keepNext/><w:outlineLvl w:val=\"1\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"36\"/><w:szCs w:val=\"36\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading3\"><w:name w:val=\"heading 3\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:keepNext/><w:outlineLvl w:val=\"2\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Header\"><w:name w:val=\"header\"/><w:basedOn w:val=\"Normal\"/></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Footer\"><w:name w:val=\"footer\"/><w:basedOn w:val=\"Normal\"/></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"ListParagraph\"><w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"Normal\"/><w:pPr><w:ind w:left=\"720\"/></w:pPr></w:style>\n <w:style w:type=\"table\" w:styleId=\"TableGrid\"><w:name w:val=\"Table Grid\"/><w:tblPr><w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/></w:tblBorders></w:tblPr></w:style>\n</w:styles>`;\n}\n\nfunction settingsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:zoom w:percent=\"100\"/>\n <w:bordersDoNotSurroundHeader/>\n <w:bordersDoNotSurroundFooter/>\n <w:defaultTabStop w:val=\"800\"/>\n <w:compat>\n <w:spaceForUL/>\n <w:balanceSingleByteDoubleByteWidth/>\n <w:doNotLeaveBackslashAlone/>\n <w:ulTrailSpace/>\n <w:doNotExpandShiftReturn/>\n <w:adjustLineHeightInTable/>\n <w:useFELayout/>\n </w:compat>\n</w:settings>`;\n}\n\n// ─── numbering.xml ──────────────────────────────────────────\n\nfunction numberingXml(info: NumInfo): string {\n let abstractNums = '';\n let nums = '';\n\n // Bullet list: abstractNumId=0, numId=1\n if (info.hasBullet) {\n abstractNums += `<w:abstractNum w:abstractNumId=\"0\">`;\n for (let lvl = 0; lvl < 9; lvl++) {\n const marker = lvl === 0 ? '●' : lvl === 1 ? '○' : '■';\n const indent = (lvl + 1) * 720;\n abstractNums += `<w:lvl w:ilvl=\"${lvl}\"><w:numFmt w:val=\"bullet\"/><w:lvlText w:val=\"${marker}\"/><w:pPr><w:ind w:left=\"${indent}\" w:hanging=\"360\"/></w:pPr></w:lvl>`;\n }\n abstractNums += `</w:abstractNum>`;\n nums += `<w:num w:numId=\"1\"><w:abstractNumId w:val=\"0\"/></w:num>`;\n }\n\n // Numbered list: abstractNumId=1, numId=2\n if (info.hasNumbered) {\n abstractNums += `<w:abstractNum w:abstractNumId=\"1\">`;\n for (let lvl = 0; lvl < 9; lvl++) {\n const fmt = lvl % 3 === 0 ? 'decimal' : lvl % 3 === 1 ? 'lowerLetter' : 'lowerRoman';\n const indent = (lvl + 1) * 720;\n abstractNums += `<w:lvl w:ilvl=\"${lvl}\"><w:start w:val=\"1\"/><w:numFmt w:val=\"${fmt}\"/><w:lvlText w:val=\"%${lvl + 1}.\"/><w:pPr><w:ind w:left=\"${indent}\" w:hanging=\"360\"/></w:pPr></w:lvl>`;\n }\n abstractNums += `</w:abstractNum>`;\n nums += `<w:num w:numId=\"2\"><w:abstractNumId w:val=\"1\"/></w:num>`;\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:numbering xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n ${abstractNums}\n ${nums}\n</w:numbering>`;\n}\n\n// ─── header / footer xml ────────────────────────────────────\n\nfunction headerFooterXml(type: 'hdr' | 'ftr', paras: ParaNode[], ctx: EncCtx): string {\n const tag = type === 'hdr' ? 'w:hdr' : 'w:ftr';\n const body = paras.map(p => encodeParaInner(p, ctx)).join('\\n');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<${tag} xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n${body}\n</${tag}>`;\n}\n\n// ─── document.xml ───────────────────────────────────────────\n\nfunction documentXml(kids: ContentNode[], dims: PageDims, ctx: EncCtx, headerRId?: string, footerRId?: string): string {\n const body = kids.map(k => encodeContent(k, ctx, dims)).join('\\n');\n\n let sectRefs = '';\n if (headerRId) sectRefs += `\\n <w:headerReference w:type=\"default\" r:id=\"${headerRId}\"/>`;\n if (footerRId) sectRefs += `\\n <w:footerReference w:type=\"default\" r:id=\"${footerRId}\"/>`;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:document xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n <w:body>\n${body}\n <w:sectPr>${sectRefs}\n <w:pgSz w:w=\"${Metric.ptToDxa(dims.wPt)}\" w:h=\"${Metric.ptToDxa(dims.hPt)}\" w:orient=\"${dims.orient ?? 'portrait'}\"/>\n <w:pgMar w:top=\"${Metric.ptToDxa(dims.mt)}\" w:right=\"${Metric.ptToDxa(dims.mr)}\" w:bottom=\"${Metric.ptToDxa(dims.mb)}\" w:left=\"${Metric.ptToDxa(dims.ml)}\" w:header=\"709\" w:footer=\"709\" w:gutter=\"0\"/>\n </w:sectPr>\n </w:body>\n</w:document>`;\n}\n\nfunction encodeContent(node: ContentNode, ctx: EncCtx, dims?: PageDims): string {\n return node.tag === 'grid' ? encodeGrid(node, ctx, dims) : encodeParaInner(node, ctx);\n}\n\nfunction encodeParaInner(para: ParaNode, ctx: EncCtx): string {\n const align = para.props.align ?? 'left';\n const headStyle = para.props.heading ? `<w:pStyle w:val=\"Heading${para.props.heading}\"/>` : '';\n\n // List numbering\n let numPr = '';\n if (para.props.listOrd !== undefined) {\n const numId = para.props.listOrd ? 2 : 1;\n const ilvl = para.props.listLv ?? 0;\n numPr = `<w:pStyle w:val=\"ListParagraph\"/><w:numPr><w:ilvl w:val=\"${ilvl}\"/><w:numId w:val=\"${numId}\"/></w:numPr>`;\n }\n\n // Spacing (before / after / line height)\n let spacingXml = '';\n const { spaceBefore, spaceAfter, lineHeight } = para.props;\n if (spaceBefore !== undefined || spaceAfter !== undefined || lineHeight !== undefined) {\n const parts: string[] = [];\n if (spaceBefore !== undefined) parts.push(`w:before=\"${Metric.ptToDxa(spaceBefore)}\"`);\n if (spaceAfter !== undefined) parts.push(`w:after=\"${Metric.ptToDxa(spaceAfter)}\"`);\n if (lineHeight !== undefined) parts.push(`w:line=\"${Math.round(lineHeight * 240)}\" w:lineRule=\"auto\"`);\n spacingXml = `<w:spacing ${parts.join(' ')}/>`;\n }\n\n // Indentation\n let indentXml = '';\n if (para.props.indentPt !== undefined) {\n indentXml = `<w:ind w:left=\"${Metric.ptToDxa(para.props.indentPt)}\"/>`;\n }\n\n const runs = para.kids.map(k => {\n if (k.tag === 'span') return encodeRun(k, ctx);\n if (k.tag === 'img') return encodeImage(k, ctx);\n return '';\n }).join('');\n\n return ` <w:p>\n <w:pPr>${headStyle}${numPr}${spacingXml}${indentXml}<w:jc w:val=\"${align === 'justify' ? 'both' : align}\"/></w:pPr>\n ${runs}\n </w:p>`;\n}\n\nfunction encodeRun(span: SpanNode, _ctx: EncCtx): string {\n const p = span.props;\n const rPr: string[] = [];\n if (p.b) rPr.push('<w:b/>');\n if (p.i) rPr.push('<w:i/>');\n if (p.u) rPr.push('<w:u w:val=\"single\"/>');\n if (p.s) rPr.push('<w:strike/>');\n if (p.sup) rPr.push('<w:vertAlign w:val=\"superscript\"/>');\n if (p.sub) rPr.push('<w:vertAlign w:val=\"subscript\"/>');\n if (p.pt) rPr.push(`<w:sz w:val=\"${Metric.ptToHalfPt(p.pt)}\"/><w:szCs w:val=\"${Metric.ptToHalfPt(p.pt)}\"/>`);\n if (p.color) rPr.push(`<w:color w:val=\"${p.color}\"/>`);\n if (p.font) rPr.push(`<w:rFonts w:ascii=\"${esc(p.font)}\" w:hAnsi=\"${esc(p.font)}\" w:eastAsia=\"${esc(p.font)}\"/>`);\n if (p.bg) rPr.push(`<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${p.bg}\"/>`);\n\n // Process kids — text and pagenum\n const parts: string[] = [];\n for (const kid of span.kids) {\n if (kid.tag === 'txt') {\n parts.push(`<w:r><w:rPr>${rPr.join('')}</w:rPr><w:t xml:space=\"preserve\">${esc(kid.content)}</w:t></w:r>`);\n } else if (kid.tag === 'pagenum') {\n parts.push(`<w:r><w:rPr>${rPr.join('')}</w:rPr><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:instrText> PAGE </w:instrText></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:fldChar w:fldCharType=\"separate\"/></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:t>1</w:t></w:r><w:r><w:rPr>${rPr.join('')}</w:rPr><w:fldChar w:fldCharType=\"end\"/></w:r>`);\n } else if (kid.tag === 'br') {\n parts.push(`<w:r><w:br/></w:r>`);\n } else if (kid.tag === 'pb') {\n parts.push(`<w:r><w:br w:type=\"page\"/></w:r>`);\n }\n }\n\n return parts.join('');\n}\n\nfunction encodeImage(img: ImgNode, ctx: EncCtx): string {\n const rId = ctx.imgMap.get(img);\n if (!rId) return '';\n\n const cx = Metric.ptToEmu(img.w);\n const cy = Metric.ptToEmu(img.h);\n const alt = esc(img.alt ?? '');\n const docPrId = ctx.nextId++;\n\n const graphic = `<a:graphic><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic><pic:nvPicPr><pic:cNvPr id=\"0\" name=\"Image\"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"${rId}\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"${cx}\" cy=\"${cy}\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic>`;\n\n const layout = img.layout;\n const isInline = !layout || layout.wrap === 'inline';\n\n if (isInline) {\n return `<w:r><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\"${cx}\" cy=\"${cy}\"/><wp:docPr id=\"${docPrId}\" name=\"Image\" descr=\"${alt}\"/>${graphic}</wp:inline></w:drawing></w:r>`;\n }\n\n return `<w:r><w:drawing>${encodeAnchor(img, cx, cy, alt, docPrId, graphic, layout)}</w:drawing></w:r>`;\n}\n\nfunction encodeAnchor(\n _img: ImgNode, cx: number, cy: number, alt: string, docPrId: number,\n graphic: string, layout: NonNullable<ImgNode['layout']>,\n): string {\n const distT = Metric.ptToEmu(layout.distT ?? 0);\n const distB = Metric.ptToEmu(layout.distB ?? 0);\n const distL = Metric.ptToEmu(layout.distL ?? 9144); // DOCX 기본 0.18pt\n const distR = Metric.ptToEmu(layout.distR ?? 9144);\n const behindDoc = (layout.behindDoc || layout.wrap === 'behind') ? '1' : '0';\n const relH = layout.zOrder ?? 251658240;\n\n // 가로 위치\n const horzRelFrom = HORZ_RELTO_DOCX[layout.horzRelTo ?? 'column'] ?? 'column';\n let posH: string;\n if (layout.xPt != null) {\n posH = `<wp:positionH relativeFrom=\"${horzRelFrom}\"><wp:posOffset>${Metric.ptToEmu(layout.xPt)}</wp:posOffset></wp:positionH>`;\n } else {\n const ha = HORZ_ALIGN_DOCX[layout.horzAlign ?? 'left'] ?? 'left';\n posH = `<wp:positionH relativeFrom=\"${horzRelFrom}\"><wp:align>${ha}</wp:align></wp:positionH>`;\n }\n\n // 세로 위치\n const vertRelFrom = VERT_RELTO_DOCX[layout.vertRelTo ?? 'para'] ?? 'paragraph';\n let posV: string;\n if (layout.yPt != null) {\n posV = `<wp:positionV relativeFrom=\"${vertRelFrom}\"><wp:posOffset>${Metric.ptToEmu(layout.yPt)}</wp:posOffset></wp:positionV>`;\n } else {\n const va = VERT_ALIGN_DOCX[layout.vertAlign ?? 'top'] ?? 'top';\n posV = `<wp:positionV relativeFrom=\"${vertRelFrom}\"><wp:align>${va}</wp:align></wp:positionV>`;\n }\n\n // 텍스트 감싸기\n const wrapXml = WRAP_DOCX[layout.wrap] ?? '<wp:wrapSquare wrapText=\"bothSides\"/>';\n\n return `<wp:anchor distT=\"${distT}\" distB=\"${distB}\" distL=\"${distL}\" distR=\"${distR}\" simplePos=\"0\" relativeHeight=\"${relH}\" behindDoc=\"${behindDoc}\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\"><wp:simplePos x=\"0\" y=\"0\"/>${posH}${posV}<wp:extent cx=\"${cx}\" cy=\"${cy}\"/><wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>${wrapXml}<wp:docPr id=\"${docPrId}\" name=\"Image\" descr=\"${alt}\"/>${graphic}</wp:anchor>`;\n}\n\nconst HORZ_RELTO_DOCX: Record<string, string> = {\n margin: 'margin', column: 'column', page: 'page', para: 'paragraph',\n};\nconst VERT_RELTO_DOCX: Record<string, string> = {\n margin: 'margin', line: 'line', page: 'page', para: 'paragraph',\n};\nconst HORZ_ALIGN_DOCX: Record<string, string> = {\n left: 'left', center: 'center', right: 'right',\n};\nconst VERT_ALIGN_DOCX: Record<string, string> = {\n top: 'top', center: 'center', bottom: 'bottom',\n};\nconst WRAP_DOCX: Record<string, string> = {\n square: '<wp:wrapSquare wrapText=\"bothSides\"/>',\n tight: '<wp:wrapTight><wp:wrapPolygon edited=\"0\"><wp:start x=\"0\" y=\"0\"/><wp:lineTo x=\"0\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"0\"/><wp:lineTo x=\"0\" y=\"0\"/></wp:wrapPolygon></wp:wrapTight>',\n through: '<wp:wrapThrough wrapText=\"bothSides\"><wp:wrapPolygon edited=\"0\"><wp:start x=\"0\" y=\"0\"/><wp:lineTo x=\"0\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"0\"/><wp:lineTo x=\"0\" y=\"0\"/></wp:wrapPolygon></wp:wrapThrough>',\n none: '<wp:wrapNone/>',\n behind: '<wp:wrapNone/>',\n front: '<wp:wrapNone/>',\n};\n\nfunction encodeGrid(grid: GridNode, ctx: EncCtx, dims?: PageDims): string {\n const gp = grid.props;\n const look = gp.look;\n\n // tblLook attributes\n const firstRow = look?.firstRow ? '1' : '0';\n const lastRow = look?.lastRow ? '1' : '0';\n const firstCol = look?.firstCol ? '1' : '0';\n const lastCol = look?.lastCol ? '1' : '0';\n const noHBand = look?.bandedRows ? '0' : '1';\n const noVBand = look?.bandedCols ? '0' : '1';\n\n const d = dims ?? A4;\n const availDxa = Metric.ptToDxa(d.wPt - d.ml - d.mr);\n\n // 1단계: 표의 가상 2D 맵핑 (Virtual Table Map) 생성\n interface CellMap {\n type: 'real' | 'continue' | 'empty';\n cell?: any;\n width?: number;\n }\n const tableMap: CellMap[][] = Array.from({ length: grid.kids.length }, () => []);\n let colCount = 0;\n\n for (let ri = 0; ri < grid.kids.length; ri++) {\n let c = 0;\n for (const cell of grid.kids[ri].kids) {\n // 이미 위에서 병합되어 자리가 차지된 곳은 건너뜀\n while (tableMap[ri][c]) c++;\n\n // 실제 데이터 셀 배치\n tableMap[ri][c] = { type: 'real', cell, width: cell.cs };\n\n // 병합 영역(colspan, rowspan) 예약 처리\n for (let rr = 0; rr < cell.rs; rr++) {\n for (let cc = 0; cc < cell.cs; cc++) {\n if (rr === 0 && cc === 0) continue; // 원본 위치\n if (!tableMap[ri + rr]) tableMap[ri + rr] = [];\n\n if (rr > 0 && cc === 0) {\n // 세로 병합의 첫 번째 열은 <w:vMerge/> 처리용 셀\n tableMap[ri + rr][c + cc] = { type: 'continue', width: cell.cs };\n } else {\n // 가로 병합으로 흡수된 열은 아예 렌더링하지 않음\n tableMap[ri + rr][c + cc] = { type: 'empty' };\n }\n }\n }\n c += cell.cs;\n }\n if (c > colCount) colCount = c;\n }\n if (colCount === 0) colCount = grid.kids[0]?.kids.length ?? 1;\n\n // 빈 배열 빈칸 채우기 방어 로직\n for (let ri = 0; ri < grid.kids.length; ri++) {\n for (let c = 0; c < colCount; c++) {\n if (!tableMap[ri][c]) tableMap[ri][c] = { type: 'empty' };\n }\n }\n\n // 2단계: 컬럼 너비(dxa) 계산\n // 2단계: 컬럼 너비(dxa) 계산 (수정된 부분)\n const defaultColDxa = Math.round(availDxa / colCount);\n let colWidthsDxa: number[] = [];\n\n if (grid.props.colWidths && grid.props.colWidths.length > 0) {\n // 배열 길이가 colCount와 달라도 원본 너비를 버리지 않고 최대한 활용함\n const srcPt = [...grid.props.colWidths];\n\n // 계산된 컬럼 수보다 데이터가 부족하면 빈 공간(0)으로 채워 넣음\n while (srcPt.length < colCount) {\n srcPt.push(0);\n }\n // 데이터가 너무 많으면 colCount 크기에 맞춰 잘라냄\n srcPt.length = colCount;\n\n const knownTotalPt = srcPt.filter(w => w > 0).reduce((s, w) => s + w, 0);\n const zeroCount = srcPt.filter(w => w <= 0).length;\n const availPt = Metric.dxaToPt(availDxa);\n\n // 페이지 전체 너비에서 이미 값이 있는 컬럼들의 너비를 빼고 남은 공간 계산\n const remainingPt = Math.max(0, availPt - knownTotalPt);\n const zeroFillPt = zeroCount > 0 ? remainingPt / zeroCount : 0;\n\n for (let i = 0; i < srcPt.length; i++) {\n if (srcPt[i] <= 0) {\n srcPt[i] = zeroFillPt > 0 ? zeroFillPt : (availPt / colCount);\n }\n }\n\n // 포인트(Pt) 단위를 Word의 DXA 단위로 변환\n colWidthsDxa = srcPt.map(w => Math.round(Metric.ptToDxa(w)));\n\n // 전체 너비가 페이지 너비를 초과하면 페이지 너비에 맞춰 비율 축소\n const computedTotalDxa = colWidthsDxa.reduce((s, w) => s + w, 0);\n if (computedTotalDxa > availDxa) {\n const scale = availDxa / computedTotalDxa;\n colWidthsDxa = colWidthsDxa.map(w => Math.round(w * scale));\n }\n } else {\n // 너비 정보가 아예 없는 경우에만 균등 분배\n for (let c = 0; c < colCount; c++) colWidthsDxa.push(defaultColDxa);\n }\n\n const totalDxa = colWidthsDxa.reduce((s, w) => s + w, 0);\n const gridCols = colWidthsDxa.map(w => `<w:gridCol w:w=\"${w}\"/>`).join('');\n\n // 3단계: XML 렌더링\n const rows = grid.kids.map((row, ri) => {\n const cellXmls: string[] = [];\n\n for (let c = 0; c < colCount; c++) {\n const mapEntry = tableMap[ri][c];\n if (mapEntry.type === 'empty') continue; // colspan 흡수된 자리 건너뜀\n\n // 세로 병합되어 내려온 빈 셀 처리\n if (mapEntry.type === 'continue') {\n let cw = 0;\n for (let sc = c; sc < c + mapEntry.width! && sc < colWidthsDxa.length; sc++) cw += colWidthsDxa[sc];\n if (cw === 0) cw = defaultColDxa * mapEntry.width!;\n\n let contParts = `<w:tcW w:w=\"${Math.round(cw)}\" w:type=\"dxa\"/>`;\n if (mapEntry.width! > 1) contParts += `<w:gridSpan w:val=\"${mapEntry.width!}\"/>`;\n contParts += `<w:vMerge/>`;\n\n cellXmls.push(` <w:tc><w:tcPr>${contParts}</w:tcPr><w:p><w:pPr/></w:p></w:tc>`);\n }\n\n // 실제 내용이 들어있는 셀 처리\n if (mapEntry.type === 'real') {\n const cell = mapEntry.cell!;\n const cp = cell.props;\n const tcPrParts: string[] = [];\n\n let cellW = 0;\n for (let sc = c; sc < c + cell.cs && sc < colWidthsDxa.length; sc++) cellW += colWidthsDxa[sc];\n if (cellW === 0) cellW = defaultColDxa * cell.cs;\n\n tcPrParts.push(`<w:tcW w:w=\"${Math.round(cellW)}\" w:type=\"dxa\"/>`);\n if (cell.cs > 1) tcPrParts.push(`<w:gridSpan w:val=\"${cell.cs}\"/>`);\n if (cell.rs > 1) tcPrParts.push(`<w:vMerge w:val=\"restart\"/>`);\n\n const borders = encodeCellBorders(cp);\n if (borders) tcPrParts.push(borders);\n if (cp.bg) tcPrParts.push(`<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${cp.bg}\"/>`);\n if (cp.va) {\n const vaMap: Record<string, string> = { top: 'top', mid: 'center', bot: 'bottom' };\n tcPrParts.push(`<w:vAlign w:val=\"${vaMap[cp.va] ?? 'top'}\"/>`);\n }\n\n const tcPr = `<w:tcPr>${tcPrParts.join('')}</w:tcPr>`;\n cellXmls.push(` <w:tc>${tcPr}${cell.kids.map((p: any) => encodeParaInner(p, ctx)).join('')}</w:tc>`);\n }\n }\n\n const trPrParts: string[] = [];\n if (ri === 0 && (gp.headerRow || look?.firstRow)) {\n trPrParts.push('<w:tblHeader/>');\n }\n if (row.heightPt != null && row.heightPt > 0) {\n const hDxa = Math.round(Metric.ptToDxa(row.heightPt));\n trPrParts.push(`<w:trHeight w:val=\"${hDxa}\" w:hRule=\"exact\"/>`);\n }\n const trPr = trPrParts.length > 0 ? `<w:trPr>${trPrParts.join('')}</w:trPr>` : '';\n\n return ` <w:tr>${trPr}\\n${cellXmls.join('\\n')}\\n </w:tr>`;\n }).join('\\n');\n\n // 4단계: 테두리 및 최종 테이블 XML 조립\n let tblBorders = '';\n if (gp.defaultStroke) {\n const s = gp.defaultStroke;\n const strokeKindMap: Record<string, string> = { solid: 'single', dash: 'dash', dot: 'dot', double: 'double', none: 'none' };\n const val = strokeKindMap[s.kind] ?? 'single';\n const sz = Math.round(s.pt * 8);\n const bdr = `w:val=\"${val}\" w:sz=\"${sz}\" w:space=\"0\" w:color=\"${s.color}\"`;\n tblBorders = `<w:tblBorders><w:top ${bdr}/><w:left ${bdr}/><w:bottom ${bdr}/><w:right ${bdr}/><w:insideH ${bdr}/><w:insideV ${bdr}/></w:tblBorders>`;\n }\n\n return ` <w:tbl>\n <w:tblPr><w:tblStyle w:val=\"TableGrid\"/><w:tblW w:w=\"${Math.round(totalDxa)}\" w:type=\"dxa\"/><w:tblLayout w:type=\"fixed\"/><w:tblLook w:val=\"04A0\" w:firstRow=\"${firstRow}\" w:lastRow=\"${lastRow}\" w:firstColumn=\"${firstCol}\" w:lastColumn=\"${lastCol}\" w:noHBand=\"${noHBand}\" w:noVBand=\"${noVBand}\"/>${tblBorders}<w:tblCellMar><w:top w:w=\"28\" w:type=\"dxa\"/><w:left w:w=\"102\" w:type=\"dxa\"/><w:bottom w:w=\"28\" w:type=\"dxa\"/><w:right w:w=\"102\" w:type=\"dxa\"/></w:tblCellMar></w:tblPr>\n <w:tblGrid>${gridCols}</w:tblGrid>\n${rows}\n </w:tbl>`;\n}\nfunction encodeCellBorders(cp: CellProps): string {\n if (!cp.top && !cp.bot && !cp.left && !cp.right) return '';\n const strokeKindMap: Record<string, string> = { solid: 'single', dash: 'dash', dot: 'dot', double: 'double', none: 'none' };\n\n const encode = (s?: { kind: string; pt: number; color: string }, tag?: string) => {\n if (!s || !tag) return '';\n const val = strokeKindMap[s.kind] ?? 'single';\n return `<w:${tag} w:val=\"${val}\" w:sz=\"${Math.round(s.pt * 8)}\" w:space=\"0\" w:color=\"${s.color}\"/>`;\n };\n\n return `<w:tcBorders>${encode(cp.top, 'top')}${encode(cp.bot, 'bottom')}${encode(cp.left, 'left')}${encode(cp.right, 'right')}</w:tcBorders>`;\n}\n\nfunction esc(s: string): string {\n if (!s) return '';\n // 1. 내부 처리용 플레이스홀더(__EXT_0__ 등) 제거\n s = s.replace(/__EXT_\\d+__/g, '');\n\n // 2. 글자 깨짐을 유발하는 쓰레기값 및 BOM 기호 명시적 제거 (이 부분 추가!)\n s = s.replace(/湰灧/g, '');\n s = s.replace(/\\uFEFF/g, '');\n\n // 3. DOCX(XML 1.0)에서 허용하지 않는 보이지 않는 제어문자 모두 제거\n s = s.replace(/[^\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD]/g, '');\n\n return TextKit.escapeXml(s);\n}\n\nregistry.registerEncoder(new DocxEncoder());\n","import type { Encoder } from '../../contract/encoder';\nimport type { DocRoot, ParaNode, SpanNode, GridNode, ContentNode, ImgNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { Stroke } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\nexport class MdEncoder implements Encoder {\n readonly format = 'md';\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n const warns: string[] = [];\n const parts: string[] = [];\n for (const sheet of doc.kids) {\n // Warn about header/footer loss\n if (sheet.header && sheet.header.length > 0) warns.push('[SHIELD] MD: 머리글(header) 표현 불가 — 손실됨');\n if (sheet.footer && sheet.footer.length > 0) warns.push('[SHIELD] MD: 바닥글(footer) 표현 불가 — 손실됨');\n\n for (const kid of sheet.kids) parts.push(encodeContent(kid, warns));\n }\n return succeed(TextKit.encode(parts.join('\\n\\n')), warns);\n } catch (e: any) {\n return fail(`MD encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\nfunction encodeContent(node: ContentNode, warns: string[]): string {\n return node.tag === 'grid' ? encodeGrid(node, warns) : encodePara(node, warns);\n}\n\nfunction encodePara(para: ParaNode, warns: string[]): string {\n const text = para.kids.map(k => {\n if (k.tag === 'span') return encodeSpan(k, warns);\n if (k.tag === 'img') return encodeImage(k);\n return '';\n }).join('');\n\n if (para.props.heading) return `${'#'.repeat(para.props.heading)} ${text}`;\n\n if (para.props.listOrd !== undefined) {\n const indent = ' '.repeat(para.props.listLv ?? 0);\n return `${indent}${para.props.listOrd ? '1.' : '-'} ${text}`;\n }\n\n // Alignment: use HTML fallback for non-left\n if (para.props.align && para.props.align !== 'left' && para.props.align !== 'justify') {\n return `<div align=\"${para.props.align}\">${text}</div>`;\n }\n\n return text;\n}\n\nfunction encodeSpan(span: SpanNode, warns: string[]): string {\n let hasPageNum = false;\n const textParts: string[] = [];\n for (const kid of span.kids) {\n if (kid.tag === 'txt') textParts.push(kid.content);\n else if (kid.tag === 'pagenum') {\n hasPageNum = true;\n warns.push('[SHIELD] MD: 페이지 번호 표현 불가 — 손실됨');\n }\n }\n\n let r = textParts.join('');\n if (hasPageNum && r === '') r = '[페이지 번호]';\n\n // Collect CSS styles for font/color/size/bg — use HTML span so fonts can be\n // loaded externally via the page's stylesheet or @font-face rules.\n const cssStyles: string[] = [];\n if (span.props.font) cssStyles.push(`font-family: ${span.props.font}`);\n if (span.props.pt) cssStyles.push(`font-size: ${span.props.pt}pt`);\n if (span.props.color) cssStyles.push(`color: #${span.props.color}`);\n if (span.props.bg) cssStyles.push(`background-color: #${span.props.bg}`);\n\n const hasHtmlStyle = cssStyles.length > 0;\n\n if (hasHtmlStyle) {\n // When style properties are present, use HTML for all formatting so that\n // markdown markers inside an HTML element don't break parsers.\n if (span.props.b) cssStyles.push('font-weight: bold');\n if (span.props.i) cssStyles.push('font-style: italic');\n if (span.props.s) cssStyles.push('text-decoration: line-through');\n if (span.props.u) {\n // combine underline with possible line-through\n const existing = cssStyles.find(s => s.startsWith('text-decoration:'));\n if (existing) {\n const idx = cssStyles.indexOf(existing);\n cssStyles[idx] = existing.replace('line-through', 'underline line-through');\n if (!existing.includes('line-through')) cssStyles[idx] = existing + ' underline';\n } else {\n cssStyles.push('text-decoration: underline');\n }\n }\n const styleAttr = cssStyles.join('; ');\n if (span.props.sup) return `<sup style=\"${styleAttr}\">${r}</sup>`;\n if (span.props.sub) return `<sub style=\"${styleAttr}\">${r}</sub>`;\n return `<span style=\"${styleAttr}\">${r}</span>`;\n }\n\n // No CSS styles needed — use plain Markdown formatting\n if (span.props.b && span.props.i) r = `***${r}***`;\n else if (span.props.b) r = `**${r}**`;\n else if (span.props.i) r = `*${r}*`;\n if (span.props.s) r = `~~${r}~~`;\n if (span.props.u) r = `<u>${r}</u>`;\n if (span.props.sup) r = `<sup>${r}</sup>`;\n if (span.props.sub) r = `<sub>${r}</sub>`;\n\n return r;\n}\n\nfunction encodeImage(img: ImgNode): string {\n return ``;\n}\n\n/** pt → CSS border shorthand (only if stroke is visible) */\nfunction strokeToCss(s?: Stroke): string | undefined {\n if (!s || s.kind === 'none' || s.pt <= 0) return undefined;\n const kindMap: Record<string, string> = { solid: 'solid', dash: 'dashed', dot: 'dotted', double: 'double', none: 'none' };\n const style = kindMap[s.kind] ?? 'solid';\n const px = Math.max(1, Math.round(s.pt * 96 / 72));\n const color = s.color.startsWith('#') ? s.color : `#${s.color}`;\n return `${px}px ${style} ${color}`;\n}\n\nfunction encodeGrid(grid: GridNode, warns: string[]): string {\n if (grid.kids.length === 0) return '';\n\n // HTML 테이블로 출력 — 테두리/배경색을 인라인 스타일로 유지\n const rowCount = grid.kids.length;\n\n // Build occupancy map for rowspan\n const occupancy: Set<number>[] = Array.from({ length: rowCount }, () => new Set());\n let colCount = 0;\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let ci = 0;\n for (const cell of row.kids) {\n while (occupancy[ri].has(ci)) ci++;\n if (cell.rs > 1) {\n for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) {\n for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c);\n }\n }\n ci += cell.cs;\n }\n while (occupancy[ri].has(ci)) ci++;\n if (ci > colCount) colCount = ci;\n }\n\n let rows = '';\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let cells = '';\n let colIdx = 0;\n\n for (const cell of row.kids) {\n while (occupancy[ri].has(colIdx)) colIdx++;\n\n const cs = cell.cs > 1 ? ` colspan=\"${cell.cs}\"` : '';\n const rs = cell.rs > 1 ? ` rowspan=\"${cell.rs}\"` : '';\n\n const styles: string[] = ['padding:4px 6px', 'vertical-align:top'];\n const top = strokeToCss(cell.props.top);\n const bot = strokeToCss(cell.props.bot);\n const left = strokeToCss(cell.props.left);\n const right = strokeToCss(cell.props.right);\n if (top) styles.push(`border-top:${top}`);\n if (bot) styles.push(`border-bottom:${bot}`);\n if (left) styles.push(`border-left:${left}`);\n if (right) styles.push(`border-right:${right}`);\n if (cell.props.bg) styles.push(`background-color:#${cell.props.bg}`);\n if (cell.props.va === 'mid') styles[1] = 'vertical-align:middle';\n else if (cell.props.va === 'bot') styles[1] = 'vertical-align:bottom';\n\n const tag = (grid.props.headerRow && ri === 0) || cell.props.isHeader ? 'th' : 'td';\n const content = cell.kids.map(p => encodePara(p, warns)).join('\\n');\n cells += `<${tag}${cs}${rs} style=\"${styles.join(';')}\">${content}</${tag}>`;\n colIdx += cell.cs;\n }\n rows += `<tr>${cells}</tr>\\n`;\n }\n\n return `<table style=\"border-collapse:collapse;width:100%\">\\n<tbody>\\n${rows}</tbody>\\n</table>\\n`;\n}\n\nregistry.registerEncoder(new MdEncoder());\n","import type { DocRoot } from '../model/doc-tree';\nimport type { Outcome } from '../contract/result';\nimport { fail } from '../contract/result';\nimport { registry } from './registry';\n\n// Side-effect imports: auto-register all decoders and encoders\nimport '../decoders/hwpx/HwpxDecoder';\nimport '../decoders/hwp/HwpScanner';\nimport '../decoders/docx/DocxDecoder';\nimport '../decoders/md/MdDecoder';\nimport '../encoders/hwpx/HwpxEncoder';\nimport '../encoders/docx/DocxEncoder';\nimport '../encoders/md/MdEncoder';\n\nexport class Pipeline {\n private constructor(private raw: Uint8Array, private srcFmt: string) {}\n\n /** 파일을 열고 포맷을 자동 감지하거나 명시 */\n static open(input: Uint8Array | string, fmt?: string): Pipeline {\n if (typeof input === 'string') {\n return new Pipeline(new TextEncoder().encode(input), fmt ?? 'md');\n }\n return new Pipeline(input, fmt ?? detectFormat(input));\n }\n\n /** File/Blob 비동기 입력 */\n static async openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise<Pipeline> {\n if (input instanceof Uint8Array || typeof input === 'string') {\n return Pipeline.open(input, fmt);\n }\n const buf = await input.arrayBuffer();\n const data = new Uint8Array(buf);\n const detectedFmt = fmt ?? (input instanceof File ? getExt(input.name) : undefined) ?? detectFormat(data);\n return new Pipeline(data, detectedFmt);\n }\n\n /** 목표 포맷으로 변환 */\n async to(targetFmt: string): Promise<Outcome<Uint8Array>> {\n const decoder = registry.getDecoder(this.srcFmt);\n const encoder = registry.getEncoder(targetFmt);\n\n if (!decoder) return fail(`지원하지 않는 입력 포맷: ${this.srcFmt}`);\n if (!encoder) return fail(`지원하지 않는 출력 포맷: ${targetFmt}`);\n\n const docResult = await decoder.decode(this.raw);\n if (!docResult.ok) return docResult;\n\n const encResult = await encoder.encode(docResult.data);\n if (!encResult.ok) return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n\n return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n }\n\n /** DocRoot만 추출 (인코딩 없이) */\n async inspect(): Promise<Outcome<DocRoot>> {\n const decoder = registry.getDecoder(this.srcFmt);\n if (!decoder) return fail(`디코더 없음: ${this.srcFmt}`);\n return decoder.decode(this.raw);\n }\n}\n\nfunction detectFormat(data: Uint8Array): string {\n // HWP 파일 (OLE Compound Document)\n if (data[0] === 0xD0 && data[1] === 0xCF && data[2] === 0x11 && data[3] === 0xE0) return 'hwp';\n\n // ZIP 기반 파일 (DOCX, HWPX)\n if (data[0] === 0x50 && data[1] === 0x4B) {\n // DOCX 는 [Content_Types].xml 에 application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml 이 있음\n // HWPX 는 application/ha-xml-core-document\n const str = new TextDecoder('utf-8', { fatal: false }).decode(data.slice(0, 4096));\n if (str.includes('wordprocessingml')) return 'docx';\n if (str.includes('ha-xml')) return 'hwpx';\n if (str.includes('hwpml/')) return 'hwpx';\n if (str.includes('word/')) return 'docx';\n return 'hwpx'; // 기본값\n }\n\n return 'md';\n}\n\nfunction getExt(name: string): string | undefined {\n const parts = name.split('.');\n return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : undefined;\n}\n","import type { Encoder } from '../../contract/encoder';\nimport type { DocRoot, ParaNode, SpanNode, GridNode, ContentNode, ImgNode, LinkNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport { succeed, fail } from '../../contract/result';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\n\nexport class HtmlEncoder implements Encoder {\n readonly format = 'html';\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n const warns: string[] = [];\n const bodyParts: string[] = [];\n\n for (const sheet of doc.kids) {\n // Header/footer as comments\n if (sheet.header && sheet.header.length > 0) {\n const hText = sheet.header.map(p => encodePara(p, warns)).join('');\n bodyParts.push(`<div class=\"hwp-header\">${hText}</div>`);\n }\n\n for (const kid of sheet.kids) {\n bodyParts.push(encodeContent(kid, warns));\n }\n\n if (sheet.footer && sheet.footer.length > 0) {\n const fText = sheet.footer.map(p => encodePara(p, warns)).join('');\n bodyParts.push(`<div class=\"hwp-footer\">${fText}</div>`);\n }\n }\n\n const title = esc(doc.meta?.title ?? '');\n const html = `<!DOCTYPE html>\\n<html lang=\"ko\">\\n<head>\\n<meta charset=\"UTF-8\">\\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\\n<title>${title}</title>\\n<style>\\n${BASE_CSS}\\n</style>\\n</head>\\n<body>\\n<div class=\"hwp-doc\">\\n${bodyParts.join('\\n')}\\n</div>\\n</body>\\n</html>`;\n\n return succeed(TextKit.encode(html), warns);\n } catch (e: any) {\n return fail(`HTML encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\nconst BASE_CSS = `\nbody { margin: 0; padding: 0; background: #f0f0f0; }\n.hwp-doc { max-width: 800px; margin: 0 auto; background: #fff; padding: 40px 60px; box-shadow: 0 0 8px rgba(0,0,0,0.15); }\n.hwp-header, .hwp-footer { color: #666; font-size: 0.9em; border-bottom: 1px solid #ddd; margin-bottom: 8px; padding-bottom: 4px; }\n.hwp-footer { border-top: 1px solid #ddd; border-bottom: none; margin-top: 8px; padding-top: 4px; }\np { margin: 0; padding: 0; line-height: 1.6; }\ntable { border-collapse: collapse; width: 100%; margin: 8px 0; }\ntd, th { border: 1px solid #ccc; padding: 4px 8px; vertical-align: top; }\nimg { max-width: 100%; height: auto; }\n`.trim();\n\nfunction encodeContent(node: ContentNode, warns: string[]): string {\n return node.tag === 'grid' ? encodeGrid(node, warns) : encodePara(node, warns);\n}\n\nfunction encodePara(para: ParaNode, warns: string[]): string {\n const kids = para.kids.map((k): string => {\n if (k.tag === 'span') return encodeSpan(k, warns);\n if (k.tag === 'img') return encodeImage(k);\n if (k.tag === 'link') {\n const link = k as LinkNode;\n const inner = link.kids.map(s => encodeSpan(s, warns)).join('');\n return `<a href=\"${esc(link.href)}\">${inner}</a>`;\n }\n return '';\n }).join('');\n\n // Heading\n if (para.props.heading) {\n const tag = `h${para.props.heading}`;\n return `<${tag}>${kids}</${tag}>\\n`;\n }\n\n // List\n if (para.props.listOrd !== undefined) {\n const indent = (para.props.listLv ?? 0) * 20;\n const style = indent > 0 ? ` style=\"margin-left:${indent}px\"` : '';\n const marker = para.props.listOrd ? `<span class=\"list-marker\">1. </span>` : `<span class=\"list-marker\">• </span>`;\n return `<p${style}>${marker}${kids}</p>\\n`;\n }\n\n // Alignment\n const align = para.props.align;\n const styleAttrs: string[] = [];\n if (align && align !== 'left') styleAttrs.push(`text-align:${align}`);\n if (para.props.indentPt) styleAttrs.push(`margin-left:${para.props.indentPt.toFixed(1)}pt`);\n if (para.props.spaceBefore) styleAttrs.push(`margin-top:${para.props.spaceBefore.toFixed(1)}pt`);\n if (para.props.spaceAfter) styleAttrs.push(`margin-bottom:${para.props.spaceAfter.toFixed(1)}pt`);\n if (para.props.lineHeight) styleAttrs.push(`line-height:${para.props.lineHeight}`);\n\n const styleAttr = styleAttrs.length > 0 ? ` style=\"${styleAttrs.join(';')}\"` : '';\n return `<p${styleAttr}>${kids || ' '}</p>\\n`;\n}\n\nfunction encodeSpan(span: SpanNode, warns: string[]): string {\n const parts: string[] = [];\n let hasPageNum = false;\n\n for (const kid of span.kids) {\n if (kid.tag === 'txt') {\n parts.push(esc(kid.content));\n } else if (kid.tag === 'br') {\n parts.push('<br>');\n } else if (kid.tag === 'pb') {\n parts.push('<div style=\"page-break-after:always\"></div>');\n } else if (kid.tag === 'pagenum') {\n hasPageNum = true;\n warns.push('[SHIELD] HTML: 페이지 번호 — 정적 값으로 대체됨');\n parts.push('<span class=\"page-num\">[페이지]</span>');\n }\n }\n\n let text = parts.join('');\n if (hasPageNum && text.trim() === '<span class=\"page-num\">[페이지]</span>') {\n // keep as-is\n }\n\n const p = span.props;\n const css: string[] = [];\n if (p.font) css.push(`font-family:${esc(p.font)}`);\n if (p.pt) css.push(`font-size:${p.pt}pt`);\n if (p.color) css.push(`color:#${p.color}`);\n if (p.bg) css.push(`background-color:#${p.bg}`);\n if (p.b) css.push('font-weight:bold');\n if (p.i) css.push('font-style:italic');\n\n const decorations: string[] = [];\n if (p.u) decorations.push('underline');\n if (p.s) decorations.push('line-through');\n if (decorations.length > 0) css.push(`text-decoration:${decorations.join(' ')}`);\n\n if (p.sup) return `<sup${css.length ? ` style=\"${css.join(';')}\"` : ''}>${text}</sup>`;\n if (p.sub) return `<sub${css.length ? ` style=\"${css.join(';')}\"` : ''}>${text}</sub>`;\n if (css.length > 0) return `<span style=\"${css.join(';')}\">${text}</span>`;\n return text;\n}\n\nfunction encodeImage(img: ImgNode): string {\n const wStyle = img.w ? ` width=\"${Math.round(img.w / 72 * 96)}px\"` : '';\n const hStyle = img.h ? ` height=\"${Math.round(img.h / 72 * 96)}px\"` : '';\n const alt = esc(img.alt ?? '');\n return `<img src=\"data:${img.mime};base64,${img.b64}\" alt=\"${alt}\"${wStyle}${hStyle}>`;\n}\n\nfunction encodeGrid(grid: GridNode, warns: string[]): string {\n if (grid.kids.length === 0) return '';\n\n // Build occupancy map for rowspan\n const rowCount = grid.kids.length;\n const occupancy: Set<number>[] = Array.from({ length: rowCount }, () => new Set());\n let colCount = 0;\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let ci = 0;\n for (const cell of row.kids) {\n while (occupancy[ri].has(ci)) ci++;\n if (cell.rs > 1) {\n for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) {\n for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c);\n }\n }\n ci += cell.cs;\n }\n while (occupancy[ri].has(ci)) ci++;\n if (ci > colCount) colCount = ci;\n }\n\n let rows = '';\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let cells = '';\n let ci = 0;\n for (const cell of row.kids) {\n while (occupancy[ri].has(ci)) ci++;\n\n const isHeader = cell.props.isHeader || (grid.props.headerRow && ri === 0);\n const tag = isHeader ? 'th' : 'td';\n\n const cs = cell.cs > 1 ? ` colspan=\"${cell.cs}\"` : '';\n const rs = cell.rs > 1 ? ` rowspan=\"${cell.rs}\"` : '';\n\n const styleAttrs: string[] = [];\n if (cell.props.bg) styleAttrs.push(`background-color:#${cell.props.bg}`);\n const va = cell.props.va;\n if (va === 'mid') styleAttrs.push('vertical-align:middle');\n else if (va === 'bot') styleAttrs.push('vertical-align:bottom');\n const styleAttr = styleAttrs.length > 0 ? ` style=\"${styleAttrs.join(';')}\"` : '';\n\n const content = cell.kids.map(p => encodePara(p, warns)).join('');\n cells += `<${tag}${cs}${rs}${styleAttr}>${content}</${tag}>`;\n ci += cell.cs;\n }\n rows += `<tr>${cells}</tr>\\n`;\n }\n\n return `<table>\\n<tbody>\\n${rows}</tbody>\\n</table>\\n`;\n}\n\nfunction esc(s: string): string {\n return TextKit.escapeXml(s);\n}\n\nregistry.registerEncoder(new HtmlEncoder());\n","/**\n * HWP 5.0 encoder — DocRoot → HWP binary (OLE2/CFB container)\n *\n * OLE2 layout:\n * FileHeader (stream) — 256-byte HWP signature + flags\n * DocInfo (stream) — compressed FACE_NAME / CHAR_SHAPE / PARA_SHAPE records\n * BodyText (storage)\n * Section0 (stream) — compressed PAGE_DEF + paragraph/table records\n */\n\nimport type { Encoder } from '../../contract/encoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, GridNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { TextProps, ParaProps, Stroke, PageDims } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { Metric } from '../../safety/StyleBridge';\nimport { registry } from '../../pipeline/registry';\nimport { A4 } from '../../model/doc-props';\nimport pako from 'pako';\nimport { TextKit } from '../../toolkit/TextKit';\n\n/* ═══════════════════════════════════════════════════════════════\n HWP 5.0 tag IDs (HWP 5.0 spec 표 13, 표 57)\n HWPTAG_BEGIN = 16 (0x10)\n ═══════════════════════════════════════════════════════════════ */\n\nconst T = 16; // HWPTAG_BEGIN\n\n// DocInfo tags (표 13)\nconst TAG_DOCUMENT_PROPERTIES = T + 0; // 16 - HWPTAG_DOCUMENT_PROPERTIES\nconst TAG_ID_MAPPINGS = T + 1; // 17 - HWPTAG_ID_MAPPINGS\nconst TAG_FACE_NAME = T + 3; // 19 - HWPTAG_FACE_NAME\nconst TAG_BORDER_FILL = T + 4; // 20 - HWPTAG_BORDER_FILL\nconst TAG_CHAR_SHAPE = T + 5; // 21 - HWPTAG_CHAR_SHAPE\nconst TAG_PARA_SHAPE = T + 9; // 25 - HWPTAG_PARA_SHAPE\n\n// DocInfo tags (additional)\nconst TAG_BIN_DATA = T + 2; // 18 - HWPTAG_BIN_DATA\n\n// BodyText tags (표 57)\nconst TAG_PARA_HEADER = T + 50; // 66 - HWPTAG_PARA_HEADER\nconst TAG_PARA_TEXT = T + 51; // 67 - HWPTAG_PARA_TEXT\nconst TAG_PARA_CHAR_SHAPE = T + 52; // 68 - HWPTAG_PARA_CHAR_SHAPE\nconst TAG_PARA_LINE_SEG = T + 53; // 69 - HWPTAG_PARA_LINE_SEG\nconst TAG_CTRL_HEADER = T + 55; // 71 - HWPTAG_CTRL_HEADER\nconst TAG_LIST_HEADER = T + 56; // 72 - HWPTAG_LIST_HEADER\nconst TAG_PAGE_DEF = T + 57; // 73 - HWPTAG_PAGE_DEF\nconst TAG_FOOTNOTE_SHAPE = T + 58; // 74 - HWPTAG_FOOTNOTE_SHAPE\nconst TAG_TABLE = T + 61; // 77 - HWPTAG_TABLE (표 개체)\nconst TAG_SHAPE_COMPONENT_PICTURE = T + 69; // 85 - HWPTAG_SHAPE_COMPONENT_PICTURE\n\n// Control IDs (stored as LE UINT32, MAKE_4CHID order)\nconst CTRL_TABLE = 0x74626C20; // 'tbl ' table\nconst CTRL_SECD = 0x73656364; // 'secd' section definition\nconst CTRL_PIC = 0x24706963; // '$pic' picture/image\n\n/** Border width index table (points) — 표 26 테두리선 굵기 (mm→pt conversion) */\nconst BORDER_W_PT = [\n 0.28, 0.34, 0.43, 0.57, 0.71, 0.85,\n 1.13, 1.42, 1.70, 1.98, 2.84, 4.25,\n 5.67, 8.50, 11.34, 14.17,\n];\n\n/** 표 25 테두리선 종류: 0=실선(solid), 2=점선(dash), 3=dash-dot, 7=2중선(double) */\nconst BORDER_KIND_IDX: Record<string, number> = {\n solid: 0, dash: 2, dot: 3, double: 7, none: 0,\n};\n\n/**\n * 표 44 문단 모양 속성1:\n * bits 2-4 = 정렬 방식 (0=양쪽, 1=왼쪽, 2=오른쪽, 3=가운데)\n */\nconst ALIGN_CODE: Record<string, number> = {\n justify: 0, left: 1, right: 2, center: 3,\n};\n\n/* ═══════════════════════════════════════════════════════════════\n Binary buffer writer\n ═══════════════════════════════════════════════════════════════ */\n\nclass BufWriter {\n private chunks: Uint8Array[] = [];\n private _sz = 0;\n\n get size() { return this._sz; }\n\n u8(v: number): this {\n this.chunks.push(new Uint8Array([v & 0xFF]));\n this._sz++;\n return this;\n }\n\n u16(v: number): this {\n this.chunks.push(new Uint8Array([v & 0xFF, (v >> 8) & 0xFF]));\n this._sz += 2;\n return this;\n }\n\n u32(v: number): this {\n const b = new Uint8Array(4);\n b[0] = v & 0xFF;\n b[1] = (v >>> 8) & 0xFF;\n b[2] = (v >>> 16) & 0xFF;\n b[3] = (v >>> 24) & 0xFF;\n this.chunks.push(b);\n this._sz += 4;\n return this;\n }\n\n i32(v: number): this { return this.u32(v < 0 ? v + 0x100000000 : v); }\n\n i16(v: number): this { return this.u16(v < 0 ? v + 0x10000 : v); }\n\n bytes(d: Uint8Array): this { this.chunks.push(d); this._sz += d.length; return this; }\n zeros(n: number): this { this.chunks.push(new Uint8Array(n)); this._sz += n; return this; }\n\n /** Write each char as UTF-16LE UINT16 (BMP only) */\n utf16(s: string): this {\n for (let i = 0; i < s.length; i++) this.u16(s.charCodeAt(i));\n return this;\n }\n\n /** Write 4-byte COLORREF (R, G, B, 0) from 6-hex string */\n colorRef(hex: string): this {\n const h = (hex || '000000').replace('#', '').padStart(6, '0');\n return this\n .u8(parseInt(h.slice(0, 2), 16))\n .u8(parseInt(h.slice(2, 4), 16))\n .u8(parseInt(h.slice(4, 6), 16))\n .u8(0);\n }\n\n build(): Uint8Array {\n const out = new Uint8Array(this._sz);\n let off = 0;\n for (const c of this.chunks) { out.set(c, off); off += c.length; }\n return out;\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n HWP record builder\n Format: 32-bit header = size(12)|level(10)|tag(10)\n If size >= 0xFFF, append UINT32 with actual size.\n ═══════════════════════════════════════════════════════════════ */\n\nfunction mkRec(tag: number, level: number, data: Uint8Array): Uint8Array {\n const sz = data.length;\n const enc = Math.min(sz, 0xFFF);\n const hdr = (enc << 20) | ((level & 0x3FF) << 10) | (tag & 0x3FF);\n const w = new BufWriter().u32(hdr);\n if (enc >= 0xFFF) w.u32(sz);\n w.bytes(data);\n return w.build();\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Style collector (first pass — deduplicates fonts/shapes)\n ═══════════════════════════════════════════════════════════════ */\n\nfunction csKey(p: TextProps): string {\n return [p.font ?? '', p.pt ?? 10, p.b ? 1 : 0, p.i ? 1 : 0, p.u ? 1 : 0,\n p.s ? 1 : 0, p.sup ? 1 : 0, p.sub ? 1 : 0, p.color ?? '000000'].join('|');\n}\nfunction psKey(p: ParaProps): string {\n return [p.align ?? 'left', p.indentPt ?? 0, p.spaceBefore ?? 0,\n p.spaceAfter ?? 0, p.lineHeight ?? 1].join('|');\n}\nfunction bfKey(s: Stroke, bg?: string): string {\n return `${s.kind}|${s.pt}|${s.color}|${bg ?? ''}`;\n}\nfunction bfPerSideKey(l: Stroke, r: Stroke, t: Stroke, b: Stroke, bg?: string): string {\n return `${bfKey(l)}/${bfKey(r)}/${bfKey(t)}/${bfKey(b)}/${bg ?? ''}`;\n}\n\ntype BfEntry =\n | { uniform: true; s: Stroke; bg?: string }\n | { uniform: false; l: Stroke; r: Stroke; t: Stroke; b: Stroke; bg?: string };\n\nclass StyleCollector {\n readonly DEF_STROKE: Stroke = { kind: 'solid', pt: 0.5, color: '000000' };\n\n fonts: string[] = ['Malgun Gothic'];\n private fontIdx = new Map<string, number>([['Malgun Gothic', 0]]);\n\n csProps: TextProps[] = [{}];\n private csIdx = new Map<string, number>([[csKey({}), 0]]);\n\n psProps: ParaProps[] = [{}];\n private psIdx = new Map<string, number>([[psKey({}), 0]]);\n\n bfData: BfEntry[] = [];\n private bfIdx = new Map<string, number>();\n\n constructor() {\n this.addBorderFill(this.DEF_STROKE); // bfId=1\n }\n\n font(name: string): number {\n const n = name || 'Malgun Gothic';\n if (this.fontIdx.has(n)) return this.fontIdx.get(n)!;\n const id = this.fonts.length;\n this.fonts.push(n);\n this.fontIdx.set(n, id);\n return id;\n }\n\n addCharShape(p: TextProps): number {\n const k = csKey(p);\n if (this.csIdx.has(k)) return this.csIdx.get(k)!;\n const id = this.csProps.length;\n this.csProps.push(p);\n this.csIdx.set(k, id);\n if (p.font) this.font(p.font);\n return id;\n }\n\n addParaShape(p: ParaProps): number {\n const k = psKey(p);\n if (this.psIdx.has(k)) return this.psIdx.get(k)!;\n const id = this.psProps.length;\n this.psProps.push(p);\n this.psIdx.set(k, id);\n return id;\n }\n\n /** Returns 1-based border fill ID */\n addBorderFill(s: Stroke, bg?: string): number {\n const k = bfKey(s, bg);\n if (this.bfIdx.has(k)) return this.bfIdx.get(k)!;\n const id = this.bfData.length + 1;\n this.bfData.push({ uniform: true, s, bg });\n this.bfIdx.set(k, id);\n return id;\n }\n\n addBorderFillPerSide(l: Stroke, r: Stroke, t: Stroke, b: Stroke, bg?: string): number {\n const k = bfPerSideKey(l, r, t, b, bg);\n if (this.bfIdx.has(k)) return this.bfIdx.get(k)!;\n const id = this.bfData.length + 1;\n this.bfData.push({ uniform: false, l, r, t, b, bg });\n this.bfIdx.set(k, id);\n return id;\n }\n}\n\nfunction collectNode(node: ContentNode, col: StyleCollector): void {\n if (node.tag === 'para') {\n col.addParaShape(node.props);\n for (const kid of node.kids) {\n if (kid.tag === 'span') col.addCharShape((kid as SpanNode).props);\n }\n } else if (node.tag === 'grid') {\n if (node.props.defaultStroke) col.addBorderFill(node.props.defaultStroke);\n for (const row of node.kids) {\n for (const cell of row.kids) {\n const defStroke = node.props.defaultStroke ?? col.DEF_STROKE;\n const cp = cell.props;\n if (cp.top || cp.bot || cp.left || cp.right) {\n col.addBorderFillPerSide(\n cp.left ?? defStroke, cp.right ?? defStroke,\n cp.top ?? defStroke, cp.bot ?? defStroke,\n cp.bg,\n );\n } else {\n col.addBorderFill(defStroke, cp.bg);\n }\n for (const para of cell.kids) collectNode(para, col);\n }\n }\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n DocInfo record builders\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * HWPTAG_DOCUMENT_PROPERTIES (표 14 문서 속성) — 26 bytes\n * level 0 in DocInfo\n */\nfunction mkDocumentProperties(): Uint8Array {\n return new BufWriter()\n .u16(1) // nSection (구역 개수)\n .u16(1) // pageStart (페이지 시작 번호)\n .u16(1) // footnoteStart (각주 시작 번호)\n .u16(1) // endnoteStart (미주 시작 번호)\n .u16(1) // pictureStart (그림 시작 번호)\n .u16(1) // tableStart (표 시작 번호)\n .u16(1) // formulaStart (수식 시작 번호)\n .u32(0) // listId (캐럿 위치: 리스트 아이디)\n .u32(0) // paraId (캐럿 위치: 문단 아이디)\n .u32(0) // charUnitPos (캐럿 위치: 글자 단위 위치)\n .build(); // 26 bytes\n}\n\n/**\n * HWPTAG_ID_MAPPINGS (표 15 아이디 매핑 헤더) — 72 bytes (INT32 array[18])\n * 표 16 아이디 매핑 개수 인덱스:\n * [0]=binData, [1]=한글글꼴, [2]=영어글꼴, [3]=한자글꼴, [4]=일어글꼴,\n * [5]=기타글꼴, [6]=기호글꼴, [7]=사용자글꼴,\n * [8]=테두리/배경, [9]=글자모양, [10]=탭정의, [11]=문단번호,\n * [12]=글머리표, [13]=문단모양, [14]=스타일, [15]=메모모양,\n * [16]=변경추적, [17]=변경추적사용자\n * level 1 in DocInfo\n */\nfunction mkIdMappings(col: StyleCollector, nBinData = 0): Uint8Array {\n const w = new BufWriter();\n w.u32(nBinData); // [0] nBinData\n // [1-7]: 7 font language categories — all use same font list\n for (let i = 0; i < 7; i++) w.u32(col.fonts.length);\n w.u32(col.bfData.length); // [8] nBorderFill\n w.u32(col.csProps.length); // [9] nCharShape\n w.u32(0); // [10] nTabDef\n w.u32(0); // [11] nNumbering\n w.u32(0); // [12] nBullet\n w.u32(col.psProps.length); // [13] nParaShape\n w.u32(0); // [14] nStyle\n w.u32(0); // [15] nMemoShape (5.0.2.1+)\n w.u32(0); // [16] nTrackChange (5.0.3.2+)\n w.u32(0); // [17] nTrackChangeAuthor (5.0.3.2+)\n return w.build(); // 18 × 4 = 72 bytes\n}\n\n/**\n * HWPTAG_FACE_NAME (표 19 글꼴) — variable length\n * Complete structure: attr + name + altFontType + altLen + fontTypeInfo[10] + basicLen\n * level 1 in DocInfo\n */\nfunction mkFaceName(name: string): Uint8Array {\n return new BufWriter()\n .u8(0) // attr (0 = no alt/base font available)\n .u16(name.length) // len1: 글꼴 이름 길이\n .utf16(name) // 글꼴 이름 (UTF-16LE)\n .u8(0) // altFontType: 대체 글꼴 유형 (0)\n .u16(0) // altFontLen (0 = no alt font name)\n .zeros(10) // fontTypeInfo[10]: 글꼴 유형 정보 (표 22)\n .u16(0) // basicFontLen (0 = no basic font name)\n .build();\n}\n\nfunction borderWidthIdx(pt: number): number {\n let best = 0;\n for (let i = 0; i < BORDER_W_PT.length; i++) {\n if (Math.abs(BORDER_W_PT[i] - pt) < Math.abs(BORDER_W_PT[best] - pt)) best = i;\n }\n return best;\n}\n\n/**\n * HWPTAG_BORDER_FILL (표 23 테두리/배경) — 32+n bytes\n * Field layout (GROUPED, not interleaved):\n * offset 0: UINT16 attr\n * offset 2: UINT8[4] border types [left, right, top, bottom]\n * offset 6: UINT8[4] border widths [left, right, top, bottom]\n * offset 10: COLORREF[4] border colors [left, right, top, bottom]\n * offset 26: UINT8 diagonal type\n * offset 27: UINT8 diagonal width\n * offset 28: COLORREF diagonal color\n * offset 32: fill info (채우기 정보, 표 28)\n * level 1 in DocInfo\n */\nfunction mkBorderFill(s: Stroke, bg?: string): Uint8Array {\n const w = new BufWriter();\n const t = BORDER_KIND_IDX[s.kind] ?? 0;\n const wi = borderWidthIdx(s.pt);\n const col = s.color || '000000';\n\n w.u16(0); // attr (UINT16)\n // 4 border types: [left, right, top, bottom]\n for (let i = 0; i < 4; i++) w.u8(t);\n // 4 border widths: [left, right, top, bottom]\n for (let i = 0; i < 4; i++) w.u8(wi);\n // 4 border colors: [left, right, top, bottom]\n for (let i = 0; i < 4; i++) w.colorRef(col);\n // diagonal: type, width, color\n w.u8(0).u8(0).colorRef('000000');\n // fill info (채우기 정보, 표 28): type + optional color data\n if (bg) {\n w.u32(1); // type = 0x01 (단색 채우기)\n w.colorRef(bg); // 배경색\n w.colorRef('FFFFFF'); // 무늬색 (no pattern = white)\n w.u32(0); // 무늬 종류 (0 = none)\n } else {\n w.u32(0); // type = 0x00 (채우기 없음)\n }\n return w.build(); // 36 bytes (no fill) or 48 bytes (solid fill)\n}\n\nfunction mkBorderFillPerSide(\n left: Stroke, right: Stroke, top: Stroke, bottom: Stroke, bg?: string,\n): Uint8Array {\n const w = new BufWriter();\n w.u16(0); // attr\n // 4 border types [left, right, top, bottom]\n w.u8(BORDER_KIND_IDX[left.kind] ?? 0);\n w.u8(BORDER_KIND_IDX[right.kind] ?? 0);\n w.u8(BORDER_KIND_IDX[top.kind] ?? 0);\n w.u8(BORDER_KIND_IDX[bottom.kind] ?? 0);\n // 4 border widths\n w.u8(borderWidthIdx(left.pt));\n w.u8(borderWidthIdx(right.pt));\n w.u8(borderWidthIdx(top.pt));\n w.u8(borderWidthIdx(bottom.pt));\n // 4 border colors\n w.colorRef(left.color || '000000');\n w.colorRef(right.color || '000000');\n w.colorRef(top.color || '000000');\n w.colorRef(bottom.color || '000000');\n // diagonal\n w.u8(0).u8(0).colorRef('000000');\n // fill info\n if (bg) {\n w.u32(1).colorRef(bg).colorRef('FFFFFF').u32(0);\n } else {\n w.u32(0);\n }\n return w.build();\n}\n\n/**\n * HWPTAG_CHAR_SHAPE (표 33 글자 모양) — 72+ bytes\n * Field layout:\n * offset 0: WORD[7] faceId (언어별 글꼴 ID) — 14 bytes\n * offset 14: UINT8[7] ratio (장평 50~200%) — 7 bytes\n * offset 21: INT8[7] spacing(자간 -50~50%) — 7 bytes\n * offset 28: UINT8[7] relSize(상대크기 10~250%)— 7 bytes\n * offset 35: INT8[7] offset (글자위치) — 7 bytes\n * offset 42: INT32 height (기준크기, HWP단위 = pt×100)\n * offset 46: UINT32 attr (표 35 글자 모양 속성)\n * offset 50: INT8 shadowX\n * offset 51: INT8 shadowY\n * offset 52: COLORREF textColor (글자 색)\n * offset 56: COLORREF underlineColor (밑줄 색)\n * offset 60: COLORREF shadeColor (음영 색)\n * offset 64: COLORREF shadowColor (그림자 색)\n * offset 68: UINT16 borderFillId (5.0.2.1+)\n * offset 70: COLORREF strikeColor (취소선 색, 5.0.3.0+)\n * level 1 in DocInfo\n */\nfunction mkCharShape(p: TextProps, col: StyleCollector): Uint8Array {\n const fontId = p.font ? col.font(p.font) : 0;\n const height = Math.round((p.pt ?? 10) * 100); // HWP단위: pt×100\n\n // 표 35 글자 모양 속성:\n // bit 0: 기울임(italic), bit 1: 진하게(bold)\n // bits 2-4: 밑줄 종류 (1=글자아래), bits 5-8: 밑줄 모양\n // bits 16-17: 위/아래 첨자 (0=없음, 1=위첨자, 2=아래첨자)\n // bits 18-20: 취소선 종류 (1=실선)\n let attr = 0;\n if (p.i) attr |= (1 << 0);\n if (p.b) attr |= (1 << 1);\n if (p.u) attr |= (1 << 2); // 밑줄 종류 = 1 (글자 아래)\n if (p.s) attr |= (1 << 18); // 취소선 종류 = 1\n if (p.sup) attr |= (1 << 16); // 위 첨자\n if (p.sub) attr |= (2 << 16); // 아래 첨자\n\n const textColor = p.color ?? '000000';\n\n const w = new BufWriter();\n // faceId[7]: WORD[7] — 언어별 글꼴 ID (한글, 영어, 한자, 일어, 기타, 기호, 사용자)\n for (let i = 0; i < 7; i++) w.u16(fontId);\n // ratio[7]: UINT8[7] = 100 (100%)\n for (let i = 0; i < 7; i++) w.u8(100);\n // spacing[7]: INT8[7] = 0 (자간 0%)\n for (let i = 0; i < 7; i++) w.u8(0);\n // relSize[7]: UINT8[7] = 100 (100%)\n for (let i = 0; i < 7; i++) w.u8(100);\n // offset[7]: INT8[7] = 0 (글자 위치 0%)\n for (let i = 0; i < 7; i++) w.u8(0);\n // height: INT32\n w.i32(height);\n // attr: UINT32\n w.u32(attr);\n // shadowX, shadowY: INT8\n w.u8(0).u8(0);\n // textColor: COLORREF\n w.colorRef(textColor);\n // underlineColor: COLORREF (밑줄 색)\n w.colorRef('000000');\n // shadeColor: COLORREF (음영 색) — FFFFFF = no shade\n w.colorRef('FFFFFF');\n // shadowColor: COLORREF (그림자 색)\n w.colorRef('000000');\n // borderFillId: UINT16 (글자 테두리/배경 ID, 5.0.2.1+)\n w.u16(0);\n // strikeColor: COLORREF (취소선 색, 5.0.3.0+)\n w.colorRef('000000');\n return w.build(); // 42 + 4 + 4 + 1 + 1 + 4×4 + 2 + 4 = 74 bytes\n}\n\n/**\n * HWPTAG_PARA_SHAPE (표 43 문단 모양) — 54 bytes\n * Field layout:\n * offset 0: UINT32 attr1 (표 44 문단 모양 속성1, bits 2-4 = 정렬 방식)\n * offset 4: INT32 leftMargin\n * offset 8: INT32 rightMargin\n * offset 12: INT32 indent (들여/내어 쓰기)\n * offset 16: INT32 spaceBefore (문단 간격 위)\n * offset 20: INT32 spaceAfter (문단 간격 아래)\n * offset 24: INT32 lineSpacing (줄 간격, 한글 2007 이하, 5.0.2.5 미만)\n * offset 28: UINT16 tabDefId\n * offset 30: UINT16 numberingId/bulletId\n * offset 32: UINT16 borderFillId\n * offset 34: INT16 borderLeft\n * offset 36: INT16 borderRight\n * offset 38: INT16 borderTop\n * offset 40: INT16 borderBottom\n * offset 42: UINT32 attr2 (5.0.1.7+)\n * offset 46: UINT32 attr3 (5.0.2.5+, bits 0-4 = 줄 간격 종류)\n * offset 50: UINT32 lineSpacing2 (5.0.2.5+, 실제 줄 간격)\n * level 1 in DocInfo\n */\nfunction mkParaShape(p: ParaProps): Uint8Array {\n // 표 44 bits 2-4: 정렬 방식 (0=양쪽, 1=왼쪽, 2=오른쪽, 3=가운데)\n const alignVal = ALIGN_CODE[p.align ?? 'left'] ?? 1;\n const attr1 = (alignVal & 0x7) << 2; // alignment at bits 2-4\n\n // 줄 간격: 비율(%) 표현, 160 = 160%\n const lineSpacePct = p.lineHeight ? Math.round(p.lineHeight * 100) : 160;\n\n return new BufWriter()\n .u32(attr1) // 0: attr1\n .i32(Metric.ptToHwp(p.indentPt ?? 0)) // 4: leftMargin (HWPUNIT)\n .i32(0) // 8: rightMargin\n .i32(0) // 12: indent\n .i32(Metric.ptToHwp(p.spaceBefore ?? 0)) // 16: spaceBefore\n .i32(Metric.ptToHwp(p.spaceAfter ?? 0)) // 20: spaceAfter\n .i32(lineSpacePct) // 24: lineSpacing (old format)\n .u16(0) // 28: tabDefId\n .u16(0) // 30: numberingId\n .u16(0) // 32: borderFillId\n .i16(0) // 34: borderLeft\n .i16(0) // 36: borderRight\n .i16(0) // 38: borderTop\n .i16(0) // 40: borderBottom\n .u32(0) // 42: attr2 (5.0.1.7+)\n .u32(0) // 46: attr3 (줄 간격 종류 bits 0-4 = 0: 글자에 따라)\n .u32(lineSpacePct) // 50: lineSpacing2 (5.0.2.5+)\n .build(); // 54 bytes\n}\n\n/**\n * HWPTAG_BIN_DATA (표 17 바이너리 데이터) — variable\n * Storage type 2 = embedded in BinData storage\n * level 1 in DocInfo\n */\nfunction mkBinData(id: number, ext: string): Uint8Array {\n const w = new BufWriter();\n w.u16(0x0002); // attr: storage type = 2 (내장 파일)\n w.u16(id); // binDataId (1-based)\n w.u16(ext.length); // extLen (number of UTF-16LE chars)\n w.utf16(ext); // extension string (e.g. \"jpg\", \"png\")\n return w.build();\n}\n\ninterface BinImage {\n id: number; // 1-based BIN ID\n ext: string; // file extension without dot\n data: Uint8Array; // raw image bytes\n}\n\nfunction buildDocInfoStream(col: StyleCollector, images: BinImage[] = []): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n // HWPTAG_DOCUMENT_PROPERTIES at level 0 (required first record)\n chunks.push(mkRec(TAG_DOCUMENT_PROPERTIES, 0, mkDocumentProperties()));\n\n // HWPTAG_ID_MAPPINGS at level 1 (child of DOCUMENT_PROPERTIES)\n chunks.push(mkRec(TAG_ID_MAPPINGS, 1, mkIdMappings(col, images.length)));\n\n // HWPTAG_BIN_DATA at level 1: one record per image\n for (const img of images) {\n chunks.push(mkRec(TAG_BIN_DATA, 1, mkBinData(img.id, img.ext)));\n }\n\n // HWPTAG_FACE_NAME at level 1: 7 language categories × nFonts records\n // Order: all hangul fonts, then all english fonts, ..., then all user fonts\n for (let cat = 0; cat < 7; cat++) {\n for (const name of col.fonts) {\n chunks.push(mkRec(TAG_FACE_NAME, 1, mkFaceName(name)));\n }\n }\n\n // HWPTAG_BORDER_FILL at level 1\n for (const entry of col.bfData) {\n chunks.push(mkRec(TAG_BORDER_FILL, 1,\n entry.uniform\n ? mkBorderFill(entry.s, entry.bg)\n : mkBorderFillPerSide(entry.l, entry.r, entry.t, entry.b, entry.bg)));\n }\n\n // HWPTAG_CHAR_SHAPE at level 1\n for (const p of col.csProps) {\n chunks.push(mkRec(TAG_CHAR_SHAPE, 1, mkCharShape(p, col)));\n }\n\n // HWPTAG_PARA_SHAPE at level 1\n for (const p of col.psProps) {\n chunks.push(mkRec(TAG_PARA_SHAPE, 1, mkParaShape(p)));\n }\n\n return concatU8(chunks);\n}\n\n/* ═══════════════════════════════════════════════════════════════\n BodyText record builders\n ═══════════════════════════════════════════════════════════════ */\n\nfunction mkPageDef(dims: PageDims): Uint8Array {\n return new BufWriter()\n .u32(Metric.ptToHwp(dims.wPt))\n .u32(Metric.ptToHwp(dims.hPt))\n .u32(Metric.ptToHwp(dims.ml))\n .u32(Metric.ptToHwp(dims.mr))\n .u32(Metric.ptToHwp(dims.mt))\n .u32(Metric.ptToHwp(dims.mb))\n .zeros(12) // header/footer/gutter margins (3 × INT32)\n .u32(dims.orient === 'landscape' ? 1 : 0) // attr @ offset 36\n .build(); // 40 bytes\n}\n\n/**\n * HWPTAG_PARA_HEADER (표 58 문단 헤더) — 24 bytes\n * offset 0: UINT32 nchars (문단 내 글자 수, 컨트롤 포함)\n * offset 4: UINT32 ctrlMask (컨트롤 마스크: 1<<ctrlCode)\n * offset 8: UINT16 paraShapeId (문단 모양 아이디)\n * offset 10: UINT8 styleId (문단 스타일 아이디, 0=기본)\n * offset 11: UINT8 columnBreak (단 나누기 종류)\n * offset 12: UINT16 csCount (글자 모양 정보 수)\n * offset 14: UINT16 rangeTagCount(range tag 정보 수)\n * offset 16: UINT16 lineAlignCount(각 줄 align 정보 수)\n * offset 18: UINT32 instanceId (문단 Instance ID, unique)\n * offset 22: UINT16 trackChange (변경추적 병합 여부, 5.0.3.2+)\n */\nfunction mkParaHeader(\n nchars: number,\n ctrlMask: number,\n psId: number,\n csCount: number,\n lineAlignCount: number = 0,\n instanceId: number = 0,\n): Uint8Array {\n return new BufWriter()\n .u32(nchars) // 0: nchars\n .u32(ctrlMask) // 4: ctrlMask\n .u16(psId) // 8: paraShapeId\n .u8(0) // 10: styleId (0 = default)\n .u8(0) // 11: columnBreak (0 = none)\n .u16(csCount) // 12: charShapeCount\n .u16(0) // 14: rangeTagCount\n .u16(lineAlignCount)// 16: lineAlignCount\n .u32(instanceId) // 18: instanceId (unique)\n .u16(0) // 22: trackChange\n .build(); // 24 bytes\n}\n\nfunction mkParaText(text: string): Uint8Array {\n const w = new BufWriter();\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i);\n w.u16(c < 32 ? 0 : c);\n }\n w.u16(13); // paragraph terminator (0x000D = para break)\n return w.build();\n}\n\nfunction mkParaCharShape(pairs: [pos: number, id: number][]): Uint8Array {\n const w = new BufWriter();\n for (const [pos, id] of pairs) w.u32(pos).u32(id);\n return w.build();\n}\n\n/**\n * PARA_TEXT for section definition paragraph.\n * 확장 컨트롤(size=8): ctrl_code(1) + ctrlId_lo(1) + ctrlId_hi(1) + ptr[4] + ctrl_code(1)\n * + para terminator = 9 WCHAR total → nchars = 9\n */\nfunction mkSecdParaText(): Uint8Array {\n const lo = CTRL_SECD & 0xFFFF;\n const hi = (CTRL_SECD >>> 16) & 0xFFFF;\n return new BufWriter()\n .u16(0x0002).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(0x0002) // 8 WCHAR ctrl ref\n .u16(0x000D) // para terminator\n .build(); // 9 WCHAR = 18 bytes\n}\n\n/**\n * PARA_TEXT for table container paragraph.\n * ctrl code for 그리기 개체/표 = 11 (0x000B)\n * 확장 컨트롤(size=8): 0x000B + tbl_lo + tbl_hi + 4×0 + 0x000B + terminator = 9 WCHAR\n */\nfunction mkTableParaText(): Uint8Array {\n const lo = CTRL_TABLE & 0xFFFF;\n const hi = (CTRL_TABLE >>> 16) & 0xFFFF;\n return new BufWriter()\n .u16(0x000B).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(0x000B) // 8 WCHAR ctrl ref\n .u16(0x000D) // para terminator\n .build(); // 9 WCHAR = 18 bytes\n}\n\n/**\n * PARA_TEXT for picture container paragraph.\n * ctrl code for 그리기 개체/표/수식 등 = 11 (0x000B)\n * 확장 컨트롤(size=8): 0x000B + pic_lo + pic_hi + 4×0 + 0x000B + terminator = 9 WCHAR\n */\nfunction mkPicParaText(): Uint8Array {\n const lo = CTRL_PIC & 0xFFFF;\n const hi = (CTRL_PIC >>> 16) & 0xFFFF;\n return new BufWriter()\n .u16(0x000B).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(0x000B)\n .u16(0x000D) // para terminator\n .build(); // 9 WCHAR = 18 bytes\n}\n\n/**\n * HWPTAG_SHAPE_COMPONENT_PICTURE (tag 85) — 97 bytes\n * Contains drawing common attrs + picture-specific attrs (표 107)\n * Critical field: BINDATA_ID at offset 87 (2 bytes)\n */\nfunction mkShapeComponentPicture(binDataId: number, wHwp: number, hHwp: number): Uint8Array {\n const w = new BufWriter();\n // Drawing common attributes (19 bytes)\n w.u32(CTRL_PIC); // ctrlId: '$pic' (4)\n w.zeros(15); // border style, fill type (all default/none)\n // Picture attributes (표 107, 78 bytes total = up to offset 97)\n // Geometric region (HWPUNIT bounds)\n w.u32(0); // left (4)\n w.u32(0); // top (4)\n w.u32(wHwp); // right = width (4)\n w.u32(hHwp); // bottom = height (4)\n // Drawing bounding box\n w.u32(0); // left (4)\n w.u32(0); // top (4)\n w.u32(wHwp); // right (4)\n w.u32(hHwp); // bottom (4)\n // Rotation / effect (zeros = no rotation, no effect)\n w.zeros(20); // rotate angle, rotation center X/Y, effect flags (20)\n // imageInfo (5 bytes at offset 87 from start)\n // Currently at offset: 19 + 4+4+4+4 + 4+4+4+4 + 20 = 19+16+16+20 = 71... need 87\n // Gap: 87 - 71 = 16 more bytes of zeros before binDataId\n w.zeros(16); // padding to reach offset 87\n w.u16(binDataId); // BINDATA_ID (2) — which BIN stream to use\n w.u8(0); // image type (0 = stored in BinData storage)\n w.u8(0); // flags\n w.u8(0); // padding\n w.zeros(5); // remaining (to reach 97 bytes total)\n // Total: 19+16+16+20+16+2+1+1+1+5 = 97\n return w.build(); // 97 bytes\n}\n\n/** Encode an image node as a picture paragraph (level lv) */\nfunction encodePicPara(\n imgNode: { b64: string; mime: string; w: number; h: number },\n binDataId: number,\n col: StyleCollector,\n lv: number,\n idGen: () => number,\n): Uint8Array[] {\n // imgNode.w / imgNode.h are in pt (set by all decoders)\n const wHwp = Metric.ptToHwp(Math.max(imgNode.w, 10));\n const hHwp = Metric.ptToHwp(Math.max(imgNode.h, 10));\n\n const TABLE_CTRL_MASK = 1 << 11;\n const instanceId = idGen();\n const psId = col.addParaShape({});\n\n return [\n mkRec(TAG_PARA_HEADER, lv, mkParaHeader(9, TABLE_CTRL_MASK, psId, 1, 0, instanceId)),\n mkRec(TAG_PARA_TEXT, lv + 1, mkPicParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape([[0, 0]])),\n // $pic CTRL_HEADER (GHDR) at level lv+1\n mkRec(TAG_CTRL_HEADER, lv + 1, mkPicCtrl(wHwp, hHwp, idGen())),\n // SHAPE_COMPONENT_PICTURE at level lv+2\n mkRec(TAG_SHAPE_COMPONENT_PICTURE, lv + 2, mkShapeComponentPicture(binDataId, wHwp, hHwp)),\n ];\n}\n\nfunction encodePara(para: ParaNode, col: StyleCollector, lv: number, instanceId: number): Uint8Array[] {\n let text = '';\n const csPairs: [number, number][] = [];\n let pos = 0;\n\n for (const kid of para.kids) {\n if (kid.tag === 'span') {\n const span = kid as SpanNode;\n const csId = col.addCharShape(span.props);\n if (csPairs.length === 0 || csPairs[csPairs.length - 1][1] !== csId) {\n csPairs.push([pos, csId]);\n }\n for (const t of span.kids) {\n if (t.tag === 'txt') { text += t.content; pos += t.content.length; }\n }\n }\n }\n\n if (csPairs.length === 0) csPairs.push([0, 0]);\n\n const psId = col.addParaShape(para.props);\n const nchars = text.length + 1; // text + para terminator\n\n return [\n mkRec(TAG_PARA_HEADER, lv, mkParaHeader(nchars, 0, psId, csPairs.length, 0, instanceId)),\n mkRec(TAG_PARA_TEXT, lv + 1, mkParaText(text)),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape(csPairs)),\n ];\n}\n\n/* ── Table encoding ─────────────────────────────────────────── */\n\n/**\n * CTRL_HEADER for table ctrl — 46-byte GHDR (개체 공통 속성, 표 68)\n * Layout: ctrlId(4)+attr(4)+vOff(4)+hOff(4)+w(4)+h(4)+z(4)+margins(8)+instanceId(4)+pageBreak(4)+captionLen(2)\n */\nfunction mkTableCtrl(wHwp: number, hHwp: number, instanceId: number): Uint8Array {\n return new BufWriter()\n .u32(CTRL_TABLE) // ctrlId: 'tbl ' (4)\n .u32(0x082a2211) // attr — value from real file (4)\n .i32(0) // vOff (4)\n .i32(0) // hOff (4)\n .u32(wHwp) // width in HWPUNIT (4)\n .u32(hHwp) // height in HWPUNIT (4)\n .i32(7) // z-order — value from real file (4)\n .u16(140).u16(140).u16(140).u16(140) // outer margins left/right/top/bottom (8)\n .u32(instanceId) // instanceId (4)\n .i32(0) // pageBreak (4)\n .u16(0) // captionLen (2)\n .build(); // 46 bytes\n}\n\n/**\n * CTRL_HEADER for picture ctrl — 46-byte GHDR ($pic)\n */\nfunction mkPicCtrl(wHwp: number, hHwp: number, instanceId: number): Uint8Array {\n return new BufWriter()\n .u32(CTRL_PIC) // ctrlId: '$pic' (4)\n .u32(0x082a2211) // attr — same flags as table (4)\n .i32(0) // vOff (4)\n .i32(0) // hOff (4)\n .u32(wHwp) // width in HWPUNIT (4)\n .u32(hHwp) // height in HWPUNIT (4)\n .i32(0) // z-order (4)\n .u16(0).u16(0).u16(0).u16(0) // outer margins (8)\n .u32(instanceId) // instanceId (4)\n .i32(0) // pageBreak (4)\n .u16(0) // captionLen (2)\n .build(); // 46 bytes\n}\n\n/**\n * HWPTAG_TABLE (표 75) — variable\n * Layout (verified from real HWP file):\n * UINT32 attr (0x04000006)\n * UINT16 rowCnt\n * UINT16 colCnt\n * UINT16 cellSpacing\n * UINT16[4] innerMargins: left=510, right=510, top=141, bottom=141 (HWPUNIT16)\n * UINT16[rowCnt] rowSizes (nominal, actual height from cell LIST_HEADER)\n * UINT16 borderFillId\n * UINT16 validZoneCount\n */\nfunction mkTableRecord(rowCnt: number, colCnt: number, rowHwp: number[], bfId: number): Uint8Array {\n const w = new BufWriter();\n w.u32(0x04000006); // attr — from real file\n w.u16(rowCnt);\n w.u16(colCnt);\n w.u16(0); // cellSpacing\n w.u16(510); // inner margin left (0x01fe HWPUNIT16) — from real file\n w.u16(510); // inner margin right\n w.u16(141); // inner margin top (0x008d HWPUNIT16) — from real file\n w.u16(141); // inner margin bottom\n for (const h of rowHwp) w.u16(Math.max(1, h & 0xFFFF)); // row sizes as UINT16\n w.u16(bfId); // borderFillId\n w.u16(0); // validZoneCount\n return w.build();\n}\n\nfunction mkCellListHeader(\n paraCount: number,\n row: number, col: number,\n rs: number, cs: number,\n wHwp: number, hHwp: number,\n bfId: number,\n): Uint8Array {\n // 표 65 문단 리스트 헤더 (cell variant) — 47 bytes from real file:\n // offset 0: UINT16 paraCount\n // offset 2: UINT32 attr\n // offset 6: UINT16 (extended attr)\n // offset 8: UINT16 colAddr\n // offset 10: UINT16 rowAddr\n // offset 12: UINT16 rowSpan\n // offset 14: UINT16 colSpan\n // offset 16: UINT32 width\n // offset 20: UINT32 height\n // offset 24: UINT16 margin left (510 = 0x01fe HWPUNIT16)\n // offset 26: UINT16 margin right\n // offset 28: UINT16 margin top (141 = 0x008d HWPUNIT16)\n // offset 30: UINT16 margin bottom\n // offset 32: UINT16 borderFillId\n // offset 34-46: extended (13 bytes, zeros)\n return new BufWriter()\n .u16(paraCount) // 0: paraCount\n .u32(0) // 2: attr\n .u16(0) // 6: extended attr\n .u16(col) // 8: colAddr\n .u16(row) // 10: rowAddr\n .u16(rs) // 12: rowSpan\n .u16(cs) // 14: colSpan\n .u32(wHwp) // 16: width\n .u32(hHwp) // 20: height\n .u16(510) // 24: margin left (from real file)\n .u16(510) // 26: margin right\n .u16(141) // 28: margin top\n .u16(141) // 30: margin bottom\n .u16(bfId) // 32: borderFillId\n .zeros(13) // 34-46: extended fields\n .build(); // 47 bytes\n}\n\nconst DEFAULT_ROW_HEIGHT_PT = 14;\n\nfunction encodeGrid(grid: GridNode, col: StyleCollector, lv: number, idGen: () => number): Uint8Array[] {\n const records: Uint8Array[] = [];\n const rowCnt = grid.kids.length;\n const colCnt = Math.max(1, grid.kids[0]?.kids.length ?? 1);\n\n const cwPt = (grid.props as any).colWidths ?? [];\n const totalPt = cwPt.reduce((s: number, w: number) => s + w, 0) || 453;\n const defColPt = totalPt / colCnt;\n\n const defStroke = grid.props.defaultStroke ?? col.DEF_STROKE;\n const defBfId = col.addBorderFill(defStroke);\n\n const rowHwp = grid.kids.map((row: any) =>\n row.heightPt != null && row.heightPt > 0\n ? Metric.ptToHwp(row.heightPt)\n : Metric.ptToHwp(DEFAULT_ROW_HEIGHT_PT));\n\n // Compute total table dimensions for GHDR\n const totalWPt = cwPt.length > 0 ? cwPt.reduce((s: number, w: number) => s + w, 0) : totalPt;\n const totalHPt = grid.kids.reduce((s: number, row: any) =>\n s + (row.heightPt != null && row.heightPt > 0 ? row.heightPt : DEFAULT_ROW_HEIGHT_PT), 0);\n const tblWHwp = Metric.ptToHwp(totalWPt);\n const tblHHwp = Metric.ptToHwp(totalHPt);\n const tblInstanceId = idGen();\n\n // Table ctrl header at level lv (CTRL_HEADER for table — full 46-byte GHDR)\n records.push(mkRec(TAG_CTRL_HEADER, lv, mkTableCtrl(tblWHwp, tblHHwp, tblInstanceId)));\n\n // HWPTAG_TABLE at level lv+1 (child of ctrl header)\n records.push(mkRec(TAG_TABLE, lv + 1, mkTableRecord(rowCnt, colCnt, rowHwp, defBfId)));\n\n for (let r = 0; r < grid.kids.length; r++) {\n for (let c = 0; c < grid.kids[r].kids.length; c++) {\n const cell = grid.kids[r].kids[c];\n const wHwp = Metric.ptToHwp(cwPt[c] ?? defColPt);\n const hHwp = rowHwp[r];\n const cp = cell.props;\n const hasPerSide = cp.top || cp.bot || cp.left || cp.right;\n const bfId = hasPerSide\n ? col.addBorderFillPerSide(\n cp.left ?? defStroke, cp.right ?? defStroke,\n cp.top ?? defStroke, cp.bot ?? defStroke,\n cp.bg,\n )\n : col.addBorderFill(defStroke, cp.bg);\n\n const paras = cell.kids.length > 0\n ? cell.kids\n : [{ tag: 'para' as const, props: {}, kids: [] }];\n\n // LIST_HEADER at level lv+1 (sibling of TABLE)\n records.push(mkRec(TAG_LIST_HEADER, lv + 1,\n mkCellListHeader(paras.length, r, c, cell.rs, cell.cs, wHwp, hHwp, bfId)));\n\n // Cell paragraphs at level lv+2 (children of LIST_HEADER)\n for (const para of paras) {\n records.push(...encodePara(para as ParaNode, col, lv + 2, idGen()));\n }\n }\n }\n\n return records;\n}\n\n/**\n * CTRL_HEADER for section definition — 47 bytes (matched from real HWP files)\n * Layout: ctrlId(4) + attr(4) + colGap(4) + u16+u16(4) + zeros(31)\n */\nfunction mkSectionCtrl(): Uint8Array {\n return new BufWriter()\n .u32(CTRL_SECD) // ctrlId: 'secd' (4)\n .u32(0) // attr (4)\n .u32(1134) // column gap in HWPUNIT — value from real file (4)\n .u16(0x4000) // (2) — from real file\n .u16(0x001f) // (2) — from real file\n .zeros(31) // padding to reach 47 bytes total\n .build(); // 4+4+4+2+2+31 = 47 bytes\n}\n\n/**\n * Section definition paragraph structure:\n * Level 0: PARA_HEADER (nchars=9, ctrlMask=1<<2, lineAlignCount=1)\n * Level 1: PARA_TEXT (secd ctrl reference + terminator, 9 WCHAR)\n * Level 1: PARA_CHAR_SHAPE\n * Level 1: PARA_LINE_SEG (36 bytes for 1 line)\n * Level 1: CTRL_HEADER ('secd', 4 bytes)\n * Level 2: PAGE_DEF (40 bytes)\n * Level 2: FOOTNOTE_SHAPE (28 bytes, for footnotes)\n * Level 2: FOOTNOTE_SHAPE (28 bytes, for endnotes)\n */\nfunction buildSectionParagraph(dims: PageDims, instanceId: number): Uint8Array[] {\n const SECD_CTRL_MASK = 1 << 2; // code 2 = 구역 정의/단 정의\n const nchars = 9; // 8 ctrl wchars + 1 terminator\n\n return [\n mkRec(TAG_PARA_HEADER, 0, mkParaHeader(nchars, SECD_CTRL_MASK, 0, 1, 1, instanceId)),\n mkRec(TAG_PARA_TEXT, 1, mkSecdParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])),\n mkRec(TAG_PARA_LINE_SEG, 1, new Uint8Array(36)), // 1 line × 36 bytes = 36 bytes\n mkRec(TAG_CTRL_HEADER, 1, mkSectionCtrl()), // 'secd' at level 1\n mkRec(TAG_PAGE_DEF, 2, mkPageDef(dims)), // page def at level 2\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)), // footnote shape (defaults)\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)), // endnote shape (defaults)\n ];\n}\n\nfunction buildBodyTextStream(\n doc: DocRoot,\n col: StyleCollector,\n images: BinImage[],\n): Uint8Array {\n const chunks: Uint8Array[] = [];\n const dims = doc.kids[0]?.dims ?? A4;\n let instanceIdCounter = 1;\n const idGen = () => instanceIdCounter++;\n\n // Section definition paragraph\n for (const r of buildSectionParagraph(dims, idGen())) chunks.push(r);\n\n const TABLE_CTRL_MASK = 1 << 11; // code 11 = 그리기 개체/표 (확장 컨트롤)\n\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) {\n if (node.tag === 'para') {\n const para = node as ParaNode;\n // Check if the paragraph contains images\n const hasImg = para.kids.some((k: any) => k.tag === 'img');\n if (hasImg) {\n // Emit one image paragraph per img node found\n for (const kid of para.kids) {\n if ((kid as any).tag === 'img') {\n const img = kid as any;\n // Find matching BinImage\n const binImg = images.find(b => b64Matches(b, img.b64));\n if (binImg) {\n for (const r of encodePicPara(img, binImg.id, col, 0, idGen)) chunks.push(r);\n }\n }\n }\n // Also emit any text in the paragraph (spans)\n const textKids = para.kids.filter((k: any) => k.tag !== 'img');\n if (textKids.length > 0) {\n const textPara: ParaNode = { tag: 'para', props: para.props, kids: textKids as any };\n for (const r of encodePara(textPara, col, 0, idGen())) chunks.push(r);\n }\n } else {\n for (const r of encodePara(para, col, 0, idGen())) chunks.push(r);\n }\n } else if (node.tag === 'grid') {\n // Table container paragraph at level 0\n // nchars=9 (8 ctrl wchars + terminator), ctrlMask has bit 11 set for table ctrl\n chunks.push(mkRec(TAG_PARA_HEADER, 0, mkParaHeader(9, TABLE_CTRL_MASK, 0, 1, 0, idGen())));\n chunks.push(mkRec(TAG_PARA_TEXT, 1, mkTableParaText()));\n chunks.push(mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])));\n // Table ctrl at level 1, TABLE record and cells at levels 2/3\n for (const r of encodeGrid(node as GridNode, col, 1, idGen)) chunks.push(r);\n }\n }\n }\n\n return concatU8(chunks);\n}\n\nfunction b64Matches(binImg: BinImage, b64: string): boolean {\n const a = TextKit.base64Encode(binImg.data).replace(/\\s/g, '');\n const b = b64.replace(/\\s/g, '');\n return a === b;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n HWP FileHeader stream (256 bytes)\n ═══════════════════════════════════════════════════════════════ */\n\nfunction buildHwpFileHeader(): Uint8Array {\n const buf = new Uint8Array(256);\n // Signature: \"HWP Document File\\x00\" padded to 32 bytes\n const sig = 'HWP Document File';\n for (let i = 0; i < sig.length; i++) buf[i] = sig.charCodeAt(i);\n const dv = new DataView(buf.buffer);\n dv.setUint32(32, 0x05000300, true); // version 5.0.3.0\n dv.setUint32(36, 0x00000001, true); // flags: bit 0 = compressed (zlib)\n return buf;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n OLE2 / CFB container builder\n ═══════════════════════════════════════════════════════════════ */\n\nfunction buildHwpOle2(\n fileHeaderData: Uint8Array,\n docInfoData: Uint8Array,\n section0Data: Uint8Array,\n binImages: BinImage[] = [],\n): Uint8Array {\n const SS = 512;\n const ENDOFCHAIN = 0xFFFFFFFE;\n const FREESECT = 0xFFFFFFFF;\n const FATSECT = 0xFFFFFFFD;\n\n function padSector(d: Uint8Array): Uint8Array {\n const n = Math.ceil(Math.max(d.length, 1) / SS) * SS;\n if (d.length === n) return d;\n const out = new Uint8Array(n);\n out.set(d);\n return out;\n }\n\n // Pad all data to sector boundaries\n const fhPad = padSector(fileHeaderData);\n const diPad = padSector(docInfoData);\n const s0Pad = padSector(section0Data);\n const imgPads = binImages.map(img => padSector(img.data));\n\n const fhN = fhPad.length / SS;\n const diN = diPad.length / SS;\n const s0N = s0Pad.length / SS;\n const imgNs = imgPads.map(p => p.length / SS);\n const totalImgN = imgNs.reduce((s, n) => s + n, 0);\n\n // Directory sectors: 4 entries per sector\n // Entries: Root, FileHeader, DocInfo, BodyText, Section0 [+ BinData + images]\n const numDirEntries = 5 + (binImages.length > 0 ? 1 + binImages.length : 0);\n const dirN = Math.max(2, Math.ceil(numDirEntries / 4));\n\n // Compute FAT sector count iteratively\n let fatN = 1;\n for (let iter = 0; iter < 10; iter++) {\n const total = fatN + dirN + fhN + diN + s0N + totalImgN;\n const needed = Math.ceil(total / 128);\n if (needed <= fatN) break;\n fatN = needed;\n }\n\n const dir1Sec = fatN;\n const fhSec = fatN + dirN;\n const diSec = fhSec + fhN;\n const s0Sec = diSec + diN;\n\n // Image sectors come after section0\n const imgSecs: number[] = [];\n let curSec = s0Sec + s0N;\n for (const n of imgNs) { imgSecs.push(curSec); curSec += n; }\n const totalSec = curSec;\n\n // Build FAT\n const fatBuf = new Uint8Array(fatN * SS).fill(0xFF);\n const setFat = (i: number, v: number) => {\n fatBuf[i * 4] = v & 0xFF;\n fatBuf[i * 4 + 1] = (v >>> 8) & 0xFF;\n fatBuf[i * 4 + 2] = (v >>> 16) & 0xFF;\n fatBuf[i * 4 + 3] = (v >>> 24) & 0xFF;\n };\n\n for (let i = 0; i < fatN; i++) setFat(i, FATSECT);\n for (let i = 0; i < dirN; i++) setFat(dir1Sec + i, i + 1 < dirN ? dir1Sec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < fhN; i++) setFat(fhSec + i, i + 1 < fhN ? fhSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < diN; i++) setFat(diSec + i, i + 1 < diN ? diSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < s0N; i++) setFat(s0Sec + i, i + 1 < s0N ? s0Sec + i + 1 : ENDOFCHAIN);\n for (let ii = 0; ii < imgNs.length; ii++) {\n const start = imgSecs[ii];\n const n = imgNs[ii];\n for (let i = 0; i < n; i++) setFat(start + i, i + 1 < n ? start + i + 1 : ENDOFCHAIN);\n }\n\n // Build directory\n const dirBuf = new Uint8Array(dirN * SS);\n const dv = new DataView(dirBuf.buffer);\n\n function writeDirEntry(\n idx: number, name: string, type: number,\n left: number, right: number, child: number,\n startSec: number, size: number,\n ) {\n const base = idx * 128;\n const nl = Math.min(name.length, 31);\n for (let i = 0; i < nl; i++) dv.setUint16(base + i * 2, name.charCodeAt(i), true);\n dv.setUint16(base + 64, (nl + 1) * 2, true);\n dirBuf[base + 66] = type;\n dirBuf[base + 67] = 1; // color = black\n dv.setInt32(base + 68, left, true);\n dv.setInt32(base + 72, right, true);\n dv.setInt32(base + 76, child, true);\n dv.setUint32(base + 116, startSec >>> 0, true);\n dv.setUint32(base + 120, size >>> 0, true);\n }\n\n if (binImages.length > 0) {\n // Tree: Root(0)→FileHeader(1)→DocInfo(2)→BodyText(3)→Section0(4)\n // BodyText sibling=BinData(5)\n // BinData(5)→BIN0001.xxx(6)→BIN0002.xxx(7)→...\n writeDirEntry(0, 'Root Entry', 5, -1, -1, 1, ENDOFCHAIN, 0);\n writeDirEntry(1, 'FileHeader', 2, -1, 2, -1, fhSec, fileHeaderData.length);\n writeDirEntry(2, 'DocInfo', 2, -1, 3, -1, diSec, docInfoData.length);\n writeDirEntry(3, 'BodyText', 1, -1, 5, 4, ENDOFCHAIN, 0); // sibling=BinData(5)\n writeDirEntry(4, 'Section0', 2, -1, -1, -1, s0Sec, section0Data.length);\n writeDirEntry(5, 'BinData', 1, -1, -1, 6, ENDOFCHAIN, 0); // child=first image(6)\n for (let ii = 0; ii < binImages.length; ii++) {\n const img = binImages[ii];\n const streamName = `BIN${String(img.id).padStart(4, '0')}.${img.ext}`;\n const sibling = ii + 1 < binImages.length ? 7 + ii : -1;\n writeDirEntry(6 + ii, streamName, 2, -1, sibling, -1, imgSecs[ii], img.data.length);\n }\n } else {\n // No images — original 5-entry structure\n writeDirEntry(0, 'Root Entry', 5, -1, -1, 1, ENDOFCHAIN, 0);\n writeDirEntry(1, 'FileHeader', 2, -1, 2, -1, fhSec, fileHeaderData.length);\n writeDirEntry(2, 'DocInfo', 2, -1, 3, -1, diSec, docInfoData.length);\n writeDirEntry(3, 'BodyText', 1, -1, -1, 4, ENDOFCHAIN, 0);\n writeDirEntry(4, 'Section0', 2, -1, -1, -1, s0Sec, section0Data.length);\n }\n\n // Build OLE2 file header (512 bytes)\n const hdr = new Uint8Array(SS);\n const hdv = new DataView(hdr.buffer);\n const MAGIC = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];\n MAGIC.forEach((b, i) => { hdr[i] = b; });\n hdv.setUint16(24, 0x003E, true); // minor version\n hdv.setUint16(26, 0x0003, true); // major version\n hdv.setUint16(28, 0xFFFE, true); // byte order (LE)\n hdv.setUint16(30, 9, true); // sector size = 2^9 = 512\n hdv.setUint16(32, 6, true); // mini sector size = 2^6 = 64\n hdv.setUint32(40, 0, true); // num dir sectors (0 for v3)\n hdv.setUint32(44, fatN, true); // num FAT sectors\n hdv.setUint32(48, dir1Sec, true); // first directory sector\n hdv.setUint32(52, 0, true); // transaction signature (0)\n hdv.setUint32(56, 0x1000, true); // mini stream cutoff = 4096\n hdv.setUint32(60, ENDOFCHAIN, true); // first mini FAT sector (none)\n hdv.setUint32(64, 0, true); // num mini FAT sectors (0)\n hdv.setUint32(68, ENDOFCHAIN, true); // first DIFAT extension (none)\n hdv.setUint32(72, 0, true); // num DIFAT extensions (0)\n for (let i = 0; i < 109; i++) {\n hdv.setUint32(76 + i * 4, i < fatN ? i : FREESECT, true);\n }\n\n // Assemble output\n const out = new Uint8Array(SS + totalSec * SS);\n out.set(hdr, 0);\n for (let i = 0; i < fatN; i++) {\n out.set(fatBuf.subarray(i * SS, (i + 1) * SS), SS + i * SS);\n }\n for (let i = 0; i < dirN; i++) {\n out.set(dirBuf.subarray(i * SS, (i + 1) * SS), SS + (dir1Sec + i) * SS);\n }\n out.set(fhPad, SS + fhSec * SS);\n out.set(diPad, SS + diSec * SS);\n out.set(s0Pad, SS + s0Sec * SS);\n for (let ii = 0; ii < imgPads.length; ii++) {\n out.set(imgPads[ii], SS + imgSecs[ii] * SS);\n }\n return out;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Utility\n ═══════════════════════════════════════════════════════════════ */\n\nfunction concatU8(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const a of arrays) { out.set(a, off); off += a.length; }\n return out;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Encoder entry point\n ═══════════════════════════════════════════════════════════════ */\n\nexport class HwpEncoder implements Encoder {\n readonly format = 'hwp';\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n // First pass: collect unique styles\n const col = new StyleCollector();\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectNode(node, col);\n }\n\n // Collect images from all paragraphs\n const images: BinImage[] = [];\n const seenB64 = new Set<string>();\n let binIdCounter = 1;\n\n function collectImages(node: any): void {\n if (node.tag === 'para') {\n for (const kid of node.kids) {\n if (kid.tag === 'img') {\n const key = kid.b64.substring(0, 50);\n if (!seenB64.has(key)) {\n seenB64.add(key);\n const raw = TextKit.base64Decode(kid.b64);\n let ext = 'jpg';\n if (kid.mime === 'image/png') ext = 'png';\n else if (kid.mime === 'image/gif') ext = 'gif';\n else if (kid.mime === 'image/bmp') ext = 'bmp';\n images.push({ id: binIdCounter++, ext, data: new Uint8Array(raw) });\n }\n }\n }\n } else if (node.tag === 'grid') {\n for (const row of node.kids) {\n for (const cell of row.kids) {\n for (const para of cell.kids) collectImages(para);\n }\n }\n }\n }\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectImages(node);\n }\n\n // Build streams (raw, uncompressed)\n const docInfoRaw = buildDocInfoStream(col, images);\n const bodyRaw = buildBodyTextStream(doc, col, images);\n\n // Compress with zlib (HWP uses zlib deflate for DocInfo and BodyText streams)\n const docInfoCmp = pako.deflate(docInfoRaw);\n const bodyCmp = pako.deflate(bodyRaw);\n\n // Assemble OLE2 file (images go as raw streams in BinData storage, NOT compressed)\n const fileHdr = buildHwpFileHeader();\n const hwp = buildHwpOle2(fileHdr, docInfoCmp, bodyCmp, images);\n\n return succeed(hwp);\n } catch (e: any) {\n return fail(`HwpEncoder: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n}\n\nregistry.registerEncoder(new HwpEncoder());\n","import type { AnyNode, DocRoot } from '../model/doc-tree';\n\nexport type WalkCallback = (node: AnyNode, parent: AnyNode | null, depth: number) => void | 'stop';\n\nexport function walkNode(\n node: AnyNode,\n cb: WalkCallback,\n parent: AnyNode | null = null,\n depth = 0,\n): boolean {\n const result = cb(node, parent, depth);\n if (result === 'stop') return false;\n\n if ('kids' in node && Array.isArray((node as any).kids)) {\n for (const kid of (node as any).kids) {\n if (!walkNode(kid as AnyNode, cb, node, depth + 1)) return false;\n }\n }\n return true;\n}\n\nexport class TreeWalker {\n walk(root: DocRoot, cb: WalkCallback): void {\n walkNode(root, cb);\n }\n\n findAll<T extends AnyNode>(root: DocRoot, predicate: (n: AnyNode) => n is T): T[] {\n const results: T[] = [];\n walkNode(root, (n) => { if (predicate(n)) results.push(n); });\n return results;\n }\n\n extractText(root: DocRoot): string {\n const parts: string[] = [];\n walkNode(root, (n) => {\n if (n.tag === 'txt') parts.push(n.content);\n if (n.tag === 'br') parts.push('\\n');\n if (n.tag === 'pb') parts.push('\\n\\n');\n });\n return parts.join('');\n }\n}\n","import type { DocRoot, GridNode } from '../model/doc-tree';\nimport { walkNode } from './TreeWalker';\n\nexport function countNodes(root: DocRoot): Record<string, number> {\n const counts: Record<string, number> = {};\n walkNode(root, (n) => { counts[n.tag] = (counts[n.tag] ?? 0) + 1; });\n return counts;\n}\n\nexport function validateRoot(root: DocRoot): string[] {\n const errors: string[] = [];\n if (root.tag !== 'root') errors.push('Root node must have tag \"root\"');\n if (!Array.isArray(root.kids)) errors.push('Root.kids must be an array');\n if (root.kids.length === 0) errors.push('Document has no sheets');\n\n walkNode(root, (n) => {\n if (n.tag === 'cell' && n.kids.length === 0) {\n errors.push('CellNode must have at least one ParaNode child');\n }\n if (n.tag === 'grid' && (n as GridNode).kids.length === 0) {\n errors.push('GridNode must have at least one RowNode');\n }\n });\n\n return errors;\n}\n"],"mappings":"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","names":["spanProps","pako","pako","data","r","coreXml","stylesXml","extractDims","decodeHeaderFooter","toArr","decodePara","decodeGrid","decodeGridSimple","decodeGridFlat","decodeGridText","cellText","tableText","mimeToExt","registerImage","esc","encodeGrid","encodeRun","encodeImage","encodeContent","encodeGrid","encodePara","encodeImage","encodePara","encodeContent","esc","encodeGrid","encodeSpan","encodeImage","pako","TAG_FACE_NAME","TAG_BORDER_FILL","TAG_CHAR_SHAPE","TAG_PARA_SHAPE","TAG_PARA_HEADER","TAG_PARA_TEXT","TAG_PARA_CHAR_SHAPE","TAG_CTRL_HEADER","TAG_LIST_HEADER","TAG_PAGE_DEF","CTRL_TABLE","BORDER_W_PT","encodePara","encodeGrid","out","collectImages","pako"]}
|