hwpkit-dev 0.0.2 → 0.0.3
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 +4 -2
- package/README.md +39 -2
- package/dist/index.d.mts +41 -14
- package/dist/index.d.ts +41 -14
- package/dist/index.js +3553 -1159
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3553 -1159
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/playground/index.html +346 -0
- package/playground/main.ts +302 -0
- package/playground/vite.config.ts +16 -0
- package/src/contract/decoder.ts +1 -0
- package/src/contract/encoder.ts +6 -1
- package/src/core/BaseDecoder.ts +118 -0
- package/src/core/BaseEncoder.ts +146 -0
- package/src/decoders/docx/DocxDecoder.ts +743 -151
- package/src/decoders/html/HtmlDecoder.ts +366 -0
- package/src/decoders/hwp/HwpScanner.ts +325 -157
- package/src/decoders/hwpx/HwpxDecoder.ts +785 -297
- package/src/decoders/md/MdDecoder.ts +4 -4
- package/src/encoders/docx/DocxEncoder.ts +504 -240
- package/src/encoders/html/HtmlEncoder.ts +17 -19
- package/src/encoders/hwp/HwpEncoder.ts +1466 -859
- package/src/encoders/hwpx/HwpxEncoder.ts +1477 -469
- package/src/encoders/hwpx/constants.ts +148 -0
- package/src/encoders/hwpx/utils.ts +198 -0
- package/src/encoders/md/MdEncoder.ts +20 -15
- package/src/model/builders.ts +4 -4
- package/src/model/doc-props.ts +19 -5
- package/src/model/doc-tree.ts +12 -4
- package/src/pipeline/Pipeline.ts +7 -3
- package/src/pipeline/registry.ts +13 -2
- package/src/safety/StyleBridge.ts +51 -6
- package/src/toolkit/ArchiveKit.ts +56 -0
- package/src/toolkit/StyleMapper.ts +221 -0
- package/src/toolkit/UnitConverter.ts +138 -0
- package/src/toolkit/XmlKit.ts +0 -5
- package/test-styling.ts +210 -0
- package/hwp-analyze.ts +0 -90
- package/inspect-doc.ts +0 -57
- package/output_test.hwp +0 -0
- package/test-docx-to-hwp.ts +0 -45
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/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"]}
|
|
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/core/BaseDecoder.ts","../src/encoders/hwpx/constants.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/decoders/html/HtmlDecoder.ts","../src/core/BaseEncoder.ts","../src/encoders/hwpx/HwpxEncoder.ts","../src/encoders/docx/DocxEncoder.ts","../src/encoders/md/MdEncoder.ts","../src/encoders/html/HtmlEncoder.ts","../src/encoders/hwp/HwpEncoder.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 {\n this.decoders.set(d.format, d);\n if (d.aliases) {\n for (const alias of d.aliases) this.decoders.set(alias, d);\n }\n }\n\n registerEncoder(e: Encoder): void {\n this.encoders.set(e.format, e);\n if (e.aliases) {\n for (const alias of e.aliases) this.encoders.set(alias, e);\n }\n }\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' | 'topAndBottom';\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' | 'dashDot' | 'dashDotDot' | 'wave';\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 styleId?: string; // DOCX pStyle styleId (e.g. \"Heading1\", \"TOC1\")\n indentPt?: number; // 문단 왼쪽 전체 들여쓰기 (pt) — OWPML hc:left\n indentRightPt?: number; // 문단 오른쪽 전체 들여쓰기 (pt) — OWPML hc:right\n firstLineIndentPt?: number; // 첫 줄 들여쓰기 (pt, 음수=내어쓰기) — OWPML hc:indent\n leftMargin?: number; // 문단 왼쪽 여백 (HWP leftMargin, pt)\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number; // 줄 간격 배율 (예: 1.5 = 150%)\n lineHeightFixed?: number; // 고정 줄 높이 (pt) — OWPML lineSpacing type=\"FIXED\"\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 padT?: number; // 상단 패딩 (pt)\n padB?: number; // 하단 패딩\n padL?: number; // 좌측 패딩\n padR?: 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 align?: Align; // 표 정렬: 'left' | 'center' | 'right' | 'justify'\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 headerPt?: number; // distance from paper top to header top (DOCX w:header)\n footerPt?: number; // distance from paper bottom to footer bottom (DOCX w:footer)\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 zoom?: number;\n viewMode?: 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?: { headers?: SheetNode[\"headers\"]; footers?: SheetNode[\"footers\"] },\n): SheetNode {\n const node: SheetNode = { tag: 'sheet', dims, kids };\n if (opts?.headers) node.headers = opts.headers;\n if (opts?.footers) node.footers = opts.footers;\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 | GridNode)[],\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\",\n NONE: \"none\",\n DASH: \"dash\",\n DOT: \"dot\",\n DOUBLE: \"double\",\n LONG_DASH: \"dash\",\n DASH_DOT: \"dashDot\",\n DASH_DOT_DOT: \"dashDotDot\",\n THICK_THIN: \"double\",\n THIN_THICK: \"double\",\n TRIPLE: \"double\",\n};\nconst DOCX_STROKE: Record<string, StrokeKind> = {\n single: \"solid\",\n none: \"none\",\n nil: \"none\",\n dashed: \"dash\",\n dotted: \"dot\",\n double: \"double\",\n dotDash: \"dashDot\",\n dotDotDash: \"dashDotDot\",\n thickThin: \"double\",\n thinThick: \"double\",\n triple: \"double\",\n wave: \"wave\",\n dashDotStroked: \"dashDot\",\n threeDEmboss: \"solid\",\n threeDEngrave: \"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 // 맑은 고딕 계열\n '맑은 고딕': 'Malgun Gothic',\n '맑은고딕': 'Malgun Gothic',\n // 바탕 계열 (serif)\n '바탕': 'Batang',\n '바탕체': 'BatangChe',\n '한컴바탕': 'Batang',\n '함초롬바탕': 'Batang',\n 'HY신명조': 'Batang',\n 'HY견명조': 'Batang',\n 'HY그래픽': 'Batang',\n '궁서': 'Gungsuh',\n '궁서체': 'GungsuhChe',\n // 고딕 계열 (sans-serif)\n '돋움': 'Dotum',\n '돋움체': 'DotumChe',\n '굴림': 'Gulim',\n '굴림체': 'GulimChe',\n '한컴돋움': 'Malgun Gothic',\n '함초롬돋움': 'Malgun Gothic',\n 'HY견고딕': 'Malgun Gothic',\n 'HY중고딕': 'Malgun Gothic',\n 'HY헤드라인M': 'Malgun Gothic',\n 'HY강B': 'Malgun Gothic',\n 'HY나무M': 'Malgun Gothic',\n 'HY목각파임B': 'Malgun Gothic',\n 'HY엽서M': 'Malgun Gothic',\n 'HY엽서L': 'Malgun Gothic',\n // 나눔 계열\n '나눔고딕': 'Malgun Gothic',\n '나눔명조': 'Batang',\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 // Find EOCD by scanning backward from end (supports ZIP comment up to 64KB)\n let eocdOffset = -1;\n const searchStart = Math.max(0, zipData.length - 65558);\n for (let i = zipData.length - 22; i >= searchStart; i--) {\n if (view.getUint32(i, true) === 0x06054b50) {\n eocdOffset = i;\n break;\n }\n }\n\n if (eocdOffset !== -1) {\n // Parse central directory — always has correct sizes even with data descriptors\n const entryCount = view.getUint16(eocdOffset + 10, true);\n const centralDirOffset = view.getUint32(eocdOffset + 16, true);\n\n let cdOffset = centralDirOffset;\n for (let i = 0; i < entryCount; i++) {\n if (cdOffset + 46 > zipData.length) break;\n if (view.getUint32(cdOffset, true) !== 0x02014b50) break;\n\n const compressionMethod = view.getUint16(cdOffset + 10, true);\n const compressedSize = view.getUint32(cdOffset + 20, true);\n const uncompressedSize = view.getUint32(cdOffset + 24, true);\n const fileNameLength = view.getUint16(cdOffset + 28, true);\n const extraLength = view.getUint16(cdOffset + 30, true);\n const commentLength = view.getUint16(cdOffset + 32, true);\n const localHeaderOffset = view.getUint32(cdOffset + 42, true);\n\n const nameBytes = zipData.subarray(cdOffset + 46, cdOffset + 46 + fileNameLength);\n const name = new TextDecoder('utf-8').decode(nameBytes);\n cdOffset += 46 + fileNameLength + extraLength + commentLength;\n\n if (name.endsWith('/')) continue; // directory entry\n\n // Read actual data using the local header offset from central directory\n const localFnLen = view.getUint16(localHeaderOffset + 26, true);\n const localExtraLen = view.getUint16(localHeaderOffset + 28, true);\n const dataOffset = localHeaderOffset + 30 + localFnLen + localExtraLen;\n\n let fileData: Uint8Array;\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 }\n\n return files;\n }\n\n // Fallback: scan local headers sequentially (no EOCD found — truncated ZIP)\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 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","/**\n * BaseDecoder - 모든 디코더의 기본 클래스\n *\n * 공통 로직을 제공하여 각 포맷별 디코더가 포맷 특유의 로직만 구현하도록 합니다.\n */\n\nimport type { Decoder } from '../contract/decoder';\nimport type { Outcome } from '../contract/result';\nimport type { DocRoot } from '../model/doc-tree';\nimport { TextKit } from '../toolkit/TextKit';\nimport { ArchiveKit } from '../toolkit/ArchiveKit';\n\n// ─── BaseDecoder ───────────────────────────────────\n\nexport abstract class BaseDecoder implements Decoder {\n readonly format: string = this.getFormat();\n readonly aliases: string[] = this.getAliases();\n\n /** 포맷 이름 반환 (하위 클래스에서 오버라이드) */\n protected abstract getFormat(): string;\n\n /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */\n protected getAliases(): string[] { return []; }\n\n /** 데이터 디코딩 (하위 클래스에서 오버라이드) */\n abstract decode(data: Uint8Array): Promise<Outcome<DocRoot>>;\n\n // ─── 공통 유틸리티 메서드 ──────────────────────────\n\n /** 바이트를 UTF-8 문자열로 변환 */\n protected bytesToString(data: Uint8Array): string {\n return TextKit.decode(data);\n }\n\n /** 문자열을 UTF-8 바이트로 변환 */\n protected stringToBytes(s: string): Uint8Array {\n return TextKit.encode(s);\n }\n\n /** XML 이스케이프 */\n protected escapeXml(s: string): string {\n return TextKit.escapeXml(s);\n }\n\n /** XML 언이스케이프 */\n protected unescapeXml(s: string): string {\n return TextKit.unescapeXml(s);\n }\n\n /** base64 문자열을 Uint8Array 로 변환 */\n protected base64ToBytes(b64: string): Uint8Array {\n return TextKit.base64Decode(b64);\n }\n\n /** Uint8Array 를 base64 문자열로 변환 */\n protected bytesToBase64(data: Uint8Array): string {\n return TextKit.base64Encode(data);\n }\n\n /** ZIP 해제 */\n protected async unzip(data: Uint8Array): Promise<Map<string, Uint8Array>> {\n return ArchiveKit.unzip(data);\n }\n\n /** ZIP 압축 */\n protected async zip(entries: { name: string; data: Uint8Array }[]): Promise<Uint8Array> {\n return ArchiveKit.zip(entries);\n }\n\n /** inflate 해제 */\n protected async inflate(data: Uint8Array): Promise<Uint8Array> {\n return ArchiveKit.inflate(data);\n }\n\n /** deflate 압축 */\n protected async deflate(data: Uint8Array): Promise<Uint8Array> {\n return ArchiveKit.deflate(data);\n }\n\n /** 제어 문자 제거 */\n protected stripControl(s: string): string {\n return TextKit.stripControl(s);\n }\n\n /** 공백 정규화 */\n protected normalizeWhitespace(s: string): string {\n return TextKit.normalizeWhitespace(s);\n }\n\n /** XML 파싱 (DOMParser 사용) */\n protected parseXml(xmlString: string): Document {\n const parser = new DOMParser();\n return parser.parseFromString(xmlString, 'text/xml');\n }\n\n /** XML 요소에서 텍스트 내용 추출 */\n protected getTextContent(element: Element | null | undefined): string {\n if (!element) return '';\n return element.textContent ?? '';\n }\n\n /** XML 요소의 속성 값 추출 */\n protected getAttr(element: Element | null | undefined, name: string): string | null {\n return element?.getAttribute(name) ?? null;\n }\n\n /** XML 요소의 자식 요소 찾기 */\n protected getChild(element: Element | null | undefined, tagName: string): Element | null {\n if (!element) return null;\n return element.querySelector(`>${tagName}`) ?? null;\n }\n\n /** XML 요소의 모든 자식 요소 찾기 */\n protected getChildren(element: Element | null | undefined, tagName: string): Element[] {\n if (!element) return [];\n return Array.from(element.querySelectorAll(`>${tagName}`));\n }\n}\n","/**\n * HWPX 인코더 관련 상수\n *\n * HWPX 파일 생성에 필요한 모든 설정값을 한곳에 모아 관리합니다.\n * 초중급 개발자도 쉽게 수정할 수 있도록 명확한 주석을 포함했습니다.\n */\n\n// ==================== 파일 형식 관련 ====================\n\n/** HWPX 파일의 MIME 타입 (ZIP 파일 내 mimetype 파일에 저장됨) */\nexport const HWPX_MIME_TYPE = \"application/hwp+zip\";\n\n/** HWPX 파일의 버전 */\nexport const HWPX_VERSION = \"1.2\";\n\n// ==================== XML 네임스페이스 ====================\n\n/** HWPX XML 문서에서 사용되는 네임스페이스 */\nexport const NAMESPACES = {\n /** Hancom 문서 네임스페이스 */\n HANCOM: \"http://www.hancom.co.kr/hwp/xml\",\n /** Hancom 공통 네임스페이스 */\n HANCOM_COMMON: \"http://www.hancom.co.kr/hwp/xml/common\",\n /** Hancom 버전 네임스페이스 */\n HANCOM_VERSION: \"http://www.hancom.co.kr/hwp/xml/version\",\n /** Hancom 속성 네임스페이스 */\n HANCOM_PROP: \"http://www.hancom.co.kr/hwp/xml/property\",\n} as const;\n\n/** XML 헤더에 포함될 네임스페이스 선언 문자열 */\nexport const NAMESPACE_DECLARATIONS = {\n HEAD: `xmlns:hh=\"${NAMESPACES.HANCOM}\" xmlns:hc=\"${NAMESPACES.HANCOM_COMMON}\" xmlns:hv=\"${NAMESPACES.HANCOM_VERSION}\" xmlns:hp=\"${NAMESPACES.HANCOM_PROP}\"`,\n SECTION: `xmlns:hs=\"${NAMESPACES.HANCOM}\" xmlns:hp=\"${NAMESPACES.HANCOM_PROP}\"`,\n} as const;\n\n// ==================== 단위 변환 ====================\n\n/** 1 포인트 (pt) 를 HWPUNIT 으로 변환한 값 (HWPX 내부 단위) */\nexport const HWPUNIT_PER_PT = 1000;\n\n/** 1 인치 (inch) 를 포인트 (pt) 로 변환한 값 */\nexport const PT_PER_INCH = 72;\n\n/** 1 인치 (inch) 를 픽셀로 변환한 값 (표준 96 DPI 기준) */\nexport const PIXELS_PER_INCH = 96;\n\n/** 픽셀을 포인트로 변환하는 계수 */\nexport const PT_PER_PIXEL = PT_PER_INCH / PIXELS_PER_INCH; // 0.75\n\n// ==================== 페이지 크기 (A4 기준) ====================\n\n/** A4 용지 너비 (포인트) */\nexport const A4_WIDTH_PT = 794;\n\n/** A4 용지 높이 (포인트) */\nexport const A4_HEIGHT_PT = 1123;\n\n/** A4 용지 상단 여백 (포인트) */\nexport const A4_TOP_MARGIN_PT = 72;\n\n/** A4 용지 하단 여백 (포인트) */\nexport const A4_BOTTOM_MARGIN_PT = 72;\n\n/** A4 용지 왼쪽 여백 (포인트) */\nexport const A4_LEFT_MARGIN_PT = 83;\n\n/** A4 용지 오른쪽 여백 (포인트) */\nexport const A4_RIGHT_MARGIN_PT = 83;\n\n/** A4 용지 상단 머리글 영역 (포인트) */\nexport const A4_HEADER_MARGIN_PT = 40;\n\n/** A4 용지 하단 바닥글 영역 (포인트) */\nexport const A4_FOOTER_MARGIN_PT = 40;\n\n// ==================== 폰트 관련 ====================\n\n/** 기본 한글 폰트 */\nexport const DEFAULT_KOREAN_FONT = \"Batang\";\n\n/** 기본 영문 폰트 */\nexport const DEFAULT_LATIN_FONT = \"Arial\";\n\n/** 기본 폰트 크기 (포인트) */\nexport const DEFAULT_FONT_SIZE_PT = 10;\n\n// ==================== 줄 간격 ====================\n\n/** 기본 줄 간격 (폰트 크기의 %) */\nexport const DEFAULT_LINE_SPACING_PERCENT = 160;\n\n/** 최소 줄 간격 (HWPUNIT) */\nexport const MIN_LINE_SPACING_HWPUNIT = 1000;\n\n// ==================== 스타일 ID ====================\n\n/** 바탕글 스타일 ID */\nexport const STYLE_ID_BATANGGUL = \"0\";\n\n/** 개요 1 스타일 ID */\nexport const STYLE_ID_GYEYOE1 = \"1\";\n\n/** 개요 2 스타일 ID */\nexport const STYLE_ID_GYEYOE2 = \"2\";\n\n// ==================== 이미지 관련 ====================\n\n/** 이미지 파일이 저장될 디렉토리 경로 (ZIP 내) */\nexport const IMAGE_DIR_PATH = \"image/\";\n\n/** 이미지 파일명 접미사 */\nexport const IMAGE_FILE_EXTENSION = \".png\";\n\n// ==================== 테이블 관련 ====================\n\n/** 테이블 테두리 기본 두께 (HWPUNIT) */\nexport const TABLE_BORDER_WIDTH_HWPUNIT = 500; // 0.5pt\n\n/** 테이블 셀 기본 패딩 (HWPUNIT) */\nexport const TABLE_CELL_PADDING_HWPUNIT = 200; // 0.2pt\n\n// ==================== 색상 코드 ====================\n\n/** 검정색 (hex) */\nexport const COLOR_BLACK = \"#000000\";\n\n/** 흰색 (hex) */\nexport const COLOR_WHITE = \"#FFFFFF\";\n\n/** 회색 (워터마크용) */\nexport const COLOR_GRAY = \"#CCCCCC\";\n\n/** 코드 블록 배경색 */\nexport const COLOR_CODE_BLOCK_BG = \"#f4f4f4\";\n\n// ==================== ZIP 파일 구조 ====================\n\n/** HWPX 파일 내 파일 목록 */\nexport const HWPX_FILE_STRUCTURE = [\n { name: \"mimetype\", mimeType: \"\" },\n { name: \".hwpversions/version.xml\", mimeType: \"application/xml\" },\n { name: \"header.xml\", mimeType: \"application/xml\" },\n { name: \"section0.xml\", mimeType: \"application/xml\" },\n { name: \"content.hpf\", mimeType: \"application/octet-stream\" },\n] as const;\n\n/** ZIP 파일 생성 시 사용할 압축 레벨 (0=압축안함, 9=최대압축) */\nexport const ZIP_COMPRESSION_LEVEL = 9;\n","import type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n PageNumNode,\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 Stroke,\n ImgLayout,\n ImgWrap,\n ImgHorzAlign,\n ImgVertAlign,\n ImgHorzRelTo,\n ImgVertRelTo,\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 safeStrokeHwpx,\n} from \"../../safety/StyleBridge\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { XmlKit } from \"../../toolkit/XmlKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\nimport { BaseDecoder } from \"../../core/BaseDecoder\";\nimport { HWPX_MIME_TYPE } from \"../../encoders/hwpx/constants\";\n\ninterface BorderFillInfo {\n stroke?: Stroke; // uniform fallback (used when all sides are the same)\n top?: Stroke;\n right?: Stroke;\n bottom?: Stroke;\n left?: Stroke;\n bgColor?: string;\n}\n\ninterface CharPrInfo {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n pt?: number;\n color?: string;\n font?: string;\n bg?: string;\n}\n\ninterface ParaPrInfo {\n align?: string;\n indentPt?: number; // hc:left → 문단 전체 왼쪽 여백\n indentRightPt?: number; // hc:right → 문단 전체 오른쪽 여백\n firstLineIndentPt?: number; // hc:indent → 첫 줄 들여쓰기 (양수=들여쓰기, 음수=내어쓰기)\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n lineHeightFixed?: number; // FIXED 행 높이 (pt)\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 extends BaseDecoder {\n protected getFormat(): string {\n return \"hwpx\";\n }\n protected getAliases(): string[] {\n return [HWPX_MIME_TYPE, \"application/hwp+zip\"];\n }\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 sectionFiles: Uint8Array[] = [];\n for (let i = 0; ; i++) {\n const sec =\n files.get(`Contents/section${i}.xml`) ?? files.get(`section${i}.xml`);\n if (!sec) break;\n sectionFiles.push(sec);\n }\n if (sectionFiles.length === 0) {\n const fallback = findSectionFile(files);\n if (fallback) sectionFiles.push(fallback);\n }\n\n if (sectionFiles.length === 0)\n return fail(\"HWPX: No section files found\");\n\n const headXml =\n 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 = {\n files,\n shield,\n borderFills,\n charPrs,\n paraPrs,\n warns,\n };\n\n const allSections: any[] = [];\n for (const secFile of sectionFiles) {\n const bodyStr = TextKit.decode(secFile);\n const bodyObj: any = await XmlKit.parseStrict(bodyStr);\n allSections.push(...normalizeSections(bodyObj));\n }\n\n const kids = shield.guardAll(\n allSections,\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(\n files: Map<string, Uint8Array>,\n): Uint8Array | undefined {\n for (const [key, val] of files) {\n if (key.toLowerCase().includes(\"section\") && key.endsWith(\".xml\"))\n 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 =\n root?.[\"hp:BODY\"]?.[0] ??\n root?.BODY?.[0] ??\n root?.[\"hp:BODY\"] ??\n 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 =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const info = root?.[\"hh:DOCSUMMARY\"]?.[0] ?? root?.DOCSUMMARY?.[0];\n if (!info) return {};\n const a = (k: string) =>\n info?.[`hh:${k}`]?.[0]?._text ?? info?.[k]?.[0]?._text ?? \"\";\n return {\n title: a(\"TITLE\") || undefined,\n author: a(\"AUTHOR\") || undefined,\n subject: a(\"SUBJECT\") || undefined,\n };\n } catch {\n return {};\n }\n}\n\nfunction extractDims(headObj: any): PageDims | null {\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return null;\n\n const secPrList =\n 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 =\n sec?.[\"hh:PAGEPROPERTY\"]?.[0]?._attr ?? sec?.PAGEPROPERTY?.[0]?._attr;\n if (!pa) return null;\n\n const ew = Number(pa.Width ?? 59528);\n const eh = Number(pa.Height ?? 84188);\n return {\n wPt: Metric.hwpToPt(ew),\n hPt: Metric.hwpToPt(eh),\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: ew > eh ? \"landscape\" : \"portrait\",\n };\n } catch {\n return null;\n }\n}\n\nfunction extractBorderFills(headObj: any): Map<number, BorderFillInfo> {\n const map = new Map<number, BorderFillInfo>();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n const bfList =\n refList?.[\"hh:borderFills\"]?.[0] ??\n refList?.[\"hh:BORDERFILLLIST\"]?.[0] ??\n 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 // Helper: parse a border element into a Stroke\n const parseBorderEl = (el: any): Stroke | undefined => {\n if (!el) return undefined;\n const a = el?._attr ?? {};\n const mmVal = parseFloat(a.width) || undefined;\n const hwpVal = mmVal != null ? mmVal * 2.835 * 100 : undefined;\n return safeStrokeHwpx(a.type, hwpVal, a.color);\n };\n\n // Parse all four sides\n const topEl =\n bf?.[\"hh:topBorder\"]?.[0] ?? bf?.[\"hh:top\"]?.[0] ?? bf?.top?.[0];\n const rightEl =\n bf?.[\"hh:rightBorder\"]?.[0] ?? bf?.[\"hh:right\"]?.[0] ?? bf?.right?.[0];\n const bottomEl =\n bf?.[\"hh:bottomBorder\"]?.[0] ??\n bf?.[\"hh:bottom\"]?.[0] ??\n bf?.bottom?.[0];\n const leftEl =\n bf?.[\"hh:leftBorder\"]?.[0] ?? bf?.[\"hh:left\"]?.[0] ?? bf?.left?.[0];\n\n info.top = parseBorderEl(topEl);\n info.right = parseBorderEl(rightEl);\n info.bottom = parseBorderEl(bottomEl);\n info.left = parseBorderEl(leftEl);\n\n // Set uniform stroke fallback = top border (for defaultStroke etc.)\n info.stroke = info.top ?? info.left ?? info.right ?? info.bottom;\n\n // Parse fill (real HWPX uses hc:fillBrush, not hh:fillBrush)\n const fillBrush =\n bf?.[\"hc:fillBrush\"]?.[0] ??\n bf?.[\"hh:fillBrush\"]?.[0] ??\n bf?.[\"hh:fill\"]?.[0] ??\n bf?.fill?.[0] ??\n bf?.fillBrush?.[0];\n if (fillBrush) {\n const winBrush =\n fillBrush?.[\"hc:winBrush\"]?.[0]?._attr ??\n fillBrush?.[\"hh:winBrush\"]?.[0]?._attr ??\n 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 {\n /* non-fatal */\n }\n return map;\n}\n\nfunction buildFontIdMap(headObj: any): Map<number, string> {\n const fontMap = new Map<number, string>();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return fontMap;\n\n const fontfaces =\n refList?.[\"hh:fontfaces\"]?.[0] ?? refList?.[\"hh:FONTFACES\"]?.[0];\n if (!fontfaces) return fontMap;\n\n // Try each fontface group (HANGUL, LATIN, etc.) — use the first group that has entries\n const ffGroups = getTag(fontfaces, \"hh:fontface\", \"hh:FONTFACE\");\n for (const ff of ffGroups) {\n const fonts = getTag(ff, \"hh:font\", \"hh:FONT\");\n for (const font of fonts) {\n const fa = font?._attr ?? {};\n const fid = Number(fa.id ?? -1);\n const name = fa.face ?? fa.name ?? fa.Face ?? \"\";\n if (fid >= 0 && name && !fontMap.has(fid)) fontMap.set(fid, name);\n }\n if (fontMap.size > 0) break; // use first group (usually HANGUL)\n }\n } catch {\n /* non-fatal */\n }\n return fontMap;\n}\n\nfunction extractCharPrs(headObj: any): Map<number, CharPrInfo> {\n const map = new Map<number, CharPrInfo>();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n // Build font id → name map from fontfaces\n const fontIdMap = buildFontIdMap(headObj);\n\n const cpList =\n refList?.[\"hh:charProperties\"]?.[0] ??\n 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\")\n info.s = true;\n\n // font name — resolve from fontRef.hangul → fontfaces\n const fontRefAttr =\n cp?.[\"hh:fontRef\"]?.[0]?._attr ?? cp?.[\"hh:FONTREF\"]?.[0]?._attr;\n if (fontRefAttr) {\n const fid = Number(\n fontRefAttr.hangul ?? fontRefAttr.latin ?? fontRefAttr.Hangul ?? 0,\n );\n const name = fontIdMap.get(fid);\n if (name) info.font = safeFont(name);\n }\n\n map.set(id, info);\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction extractParaPrs(headObj: any): Map<number, ParaPrInfo> {\n const map = new Map<number, ParaPrInfo>();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n const ppList =\n refList?.[\"hh:paraProperties\"]?.[0] ??\n 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 =\n 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 indentRightPt: number | undefined;\n let firstLineIndentPt: number | undefined;\n let spaceBefore: number | undefined;\n let spaceAfter: number | undefined;\n let lineHeight: number | undefined;\n let lineHeightFixed: number | undefined;\n\n if (marginEl) {\n // OWPML §7.5.4.4: hc:left=전체왼쪽여백, hc:right=전체오른쪽여백,\n // hc:indent=첫줄들여쓰기(양수)/내어쓰기(음수)\n // hc:intent는 자사 인코더가 생성하는 오기 표기로, hc:indent와 동일하게 처리\n const leftEl = marginEl?.[\"hc:left\"]?.[0];\n const rightEl = marginEl?.[\"hc:right\"]?.[0];\n const indentEl =\n marginEl?.[\"hc:intent\"]?.[0] ?? marginEl?.[\"hc:indent\"]?.[0];\n const prevEl = marginEl?.[\"hc:prev\"]?.[0];\n const nextEl = marginEl?.[\"hc:next\"]?.[0];\n\n const leftVal = Number(leftEl?._attr?.value ?? 0);\n const rightVal = Number(rightEl?._attr?.value ?? 0);\n const indentVal = Number(indentEl?._attr?.value ?? 0);\n const prevVal = Number(prevEl?._attr?.value ?? 0);\n const nextVal = Number(nextEl?._attr?.value ?? 0);\n\n if (leftVal !== 0) indentPt = Metric.hwpToPt(leftVal);\n if (rightVal !== 0) indentRightPt = Metric.hwpToPt(rightVal);\n if (indentVal !== 0) firstLineIndentPt = Metric.hwpToPt(indentVal);\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 // OWPML §7.5.4.6: PERCENT(비율), FIXED(고정), BETWEEN_LINE(줄간격), AT_LEAST(최소)\n if (lsType === \"PERCENT\" && lsVal > 0 && lsVal !== 160) {\n lineHeight = lsVal / 100;\n } else if (lsType === \"FIXED\" && lsVal > 0) {\n // FIXED: 값이 HWPUNIT 단위의 고정 줄 높이\n lineHeightFixed = Metric.hwpToPt(lsVal);\n }\n }\n\n map.set(id, {\n align,\n indentPt,\n indentRightPt,\n firstLineIndentPt,\n spaceBefore,\n spaceAfter,\n lineHeight,\n lineHeightFixed,\n });\n }\n } catch {\n /* non-fatal */\n }\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 if (tbls.length > 0) {\n for (const tbl of tbls) {\n items.push({ type: \"table\", node: tbl });\n }\n hasTable = true;\n }\n }\n // 테이블을 포함한 단락은 일반 단락으로 다시 추가하지 않음 (중복 방지)\n if (!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 tbls = getTag(sec, \"hp:tbl\", \"hp:TABLE\");\n\n const childOrder = sec?.[\"_childOrder\"] as string[] | undefined;\n\n if (Array.isArray(childOrder)) {\n let pi = 0;\n let ti = 0;\n for (const tag of childOrder) {\n if ((tag === \"hp:p\" || tag === \"hp:P\") && pi < paras.length) {\n addParaItems(paras[pi++], items);\n } else if ((tag === \"hp:tbl\" || tag === \"hp:TABLE\") && ti < tbls.length) {\n items.push({ type: \"table\", node: tbls[ti++] });\n }\n }\n // Append any remaining (fallback)\n while (pi < paras.length) addParaItems(paras[pi++], items);\n while (ti < tbls.length) items.push({ type: \"table\", node: tbls[ti++] });\n } else {\n // No order info — process paragraphs sequentially (fallback to previous logic)\n for (const p of paras) addParaItems(p, items);\n // Note: direct tables are appended after paras in this fallback\n for (const t of tbls) items.push({ type: \"table\", node: t });\n }\n\n const kids: ContentNode[] = ctx.shield.guardAll(\n items,\n (item: any) => {\n if (item.type === \"table\") {\n try {\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 } catch {\n return buildPara([buildSpan(\"[표 파싱 실패]\")]);\n }\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(kids.filter(Boolean) as ContentNode[], pageDims, {\n headers: { default: headerParas },\n footers: { default: footerParas },\n });\n}\n\nfunction parseSecPrDims(secPr: any): PageDims | null {\n const pagePr =\n secPr?.[\"hp:pagePr\"]?.[0]?._attr ?? secPr?.[\"hp:PAGEPR\"]?.[0]?._attr;\n if (!pagePr) return null;\n const margin =\n secPr?.[\"hp:pagePr\"]?.[0]?.[\"hp:margin\"]?.[0]?._attr ??\n secPr?.[\"hp:PAGEPR\"]?.[0]?.[\"hp:MARGIN\"]?.[0]?._attr ??\n {};\n const pw = Number(pagePr.width ?? 59528);\n const ph = Number(pagePr.height ?? 84188);\n return {\n wPt: Metric.hwpToPt(pw),\n hPt: Metric.hwpToPt(ph),\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: pw > ph ? \"landscape\" : \"portrait\",\n };\n}\n\nfunction extractSecPrDims(p: any): PageDims | null {\n if (!p) return null;\n try {\n // Primary: hp:secPr is a DIRECT child of hp:p (as generated by HwpxEncoder)\n const secPrDirect = p?.[\"hp:secPr\"]?.[0] ?? p?.[\"hp:SECPR\"]?.[0];\n if (secPrDirect) {\n const dims = parseSecPrDims(secPrDirect);\n if (dims) return dims;\n }\n // Fallback: legacy format may nest hp:secPr inside hp:run\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 dims = parseSecPrDims(secPr);\n if (dims) return dims;\n }\n } catch {\n /* ignore */\n }\n return null;\n}\n\nfunction decodeHeaderFooter(\n sec: any,\n kind: \"header\" | \"footer\",\n ctx: DecCtx,\n): ParaNode[] | undefined {\n try {\n const hf =\n sec?.[\"hp:headerFooter\"]?.[0] ??\n sec?.[\"hp:HEADERFOOTER\"]?.[0] ??\n sec?.headerFooter?.[0] ??\n sec?.HEADERFOOTER?.[0];\n if (!hf) return undefined;\n\n const part =\n hf?.[\"hp:\" + kind]?.[0] ??\n hf?.[\"hp:\" + kind.toUpperCase()]?.[0] ??\n hf?.[kind]?.[0] ??\n 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 =\n p?.[\"hp:PARAPR\"]?.[0] ?? p?.[\"hp:paraPr\"]?.[0] ?? p?.PARAPR?.[0];\n if (inlineParaPr) {\n const alignNode =\n inlineParaPr?.[\"hp:ALIGN\"]?.[0]?._attr ??\n 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.indentRightPt !== undefined)\n props.indentRightPt = paraPrDef.indentRightPt;\n if (paraPrDef.firstLineIndentPt !== undefined)\n props.firstLineIndentPt = paraPrDef.firstLineIndentPt;\n if (paraPrDef.spaceBefore !== undefined)\n props.spaceBefore = paraPrDef.spaceBefore;\n if (paraPrDef.spaceAfter !== undefined)\n props.spaceAfter = paraPrDef.spaceAfter;\n if (paraPrDef.lineHeight !== undefined)\n props.lineHeight = paraPrDef.lineHeight;\n if (paraPrDef.lineHeightFixed !== undefined)\n props.lineHeightFixed = paraPrDef.lineHeightFixed;\n }\n\n // List support (from inline attr)\n if (inlineAttr.listType) {\n props.listOrd =\n 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 // Helper: collect hp:pic elements from a container (direct child OR inside hp:ctrl)\n const collectPics = (container: any): any[] => {\n const direct = getTag(container, \"hp:pic\", \"hp:PIC\");\n const ctrls = getTag(container, \"hp:ctrl\", \"hp:CTRL\");\n const nested = ctrls.flatMap((c: any) => getTag(c, \"hp:pic\", \"hp:PIC\"));\n return [...direct, ...nested];\n };\n\n // Images that are direct children of <hp:p> (common in table cells and floats)\n for (const pic of collectPics(p)) {\n const img = decodePic(pic, ctx);\n if (img) kids.push(img);\n }\n\n for (const run of runs) {\n // Images: directly in run OR in run→ctrl (both patterns appear in practice)\n for (const pic of collectPics(run)) {\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 =\n pn.formatType === \"ROMAN_LOWER\"\n ? (\"roman\" as const)\n : pn.formatType === \"ROMAN_UPPER\"\n ? (\"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 runPics = collectPics(run);\n const textNodes = getTag(run, \"hp:t\", \"hp:T\", \"hp:CHAR\");\n const content = textNodes\n .map((t: any) => {\n const val =\n typeof t === \"string\" ? t : (t?._text ?? t?._ ?? t?.[\"#text\"] ?? \"\");\n return val.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n })\n .join(\"\");\n\n // Skip empty secPr-only runs that produced no images\n if (\n content === \"\" &&\n (run?.[\"hp:secPr\"]?.[0] || run?.[\"hp:SECPR\"]?.[0]) &&\n runPics.length === 0 &&\n pageNums.length === 0\n )\n continue;\n\n // Only push text span when there's actual content and no image already pushed for this run\n if (content !== \"\" || (runPics.length === 0 && pageNums.length === 0)) {\n const spanProps = resolveCharPr(run, ctx);\n kids.push(buildSpan(content, spanProps));\n }\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 ?? runAttr.CharPrIDRef ?? -1);\n\n // IDRef로 먼저 조회\n const def = ctx.charPrs.get(charPrIdRef);\n if (def) {\n return {\n b: def.b,\n i: def.i,\n u: def.u,\n s: def.s,\n pt: def.pt,\n color: def.color,\n font: def.font,\n bg: def.bg,\n };\n }\n\n // 인라인 CHARPR fallback — 대소문자 모두 시도\n const inlinePr =\n run?.[\"hp:CHARPR\"]?.[0] ??\n run?.[\"hp:charPr\"]?.[0] ??\n run?.CHARPR?.[0] ??\n run?.charPr?.[0];\n const ca = inlinePr?._attr ?? {};\n\n const bVal = ca.Bold ?? ca.bold ?? ca.B ?? \"\";\n const iVal = ca.Italic ?? ca.italic ?? ca.I ?? \"\";\n const uVal = ca.Underline ?? ca.underline ?? \"\";\n const sVal = ca.Strikeout ?? ca.strikeout ?? \"\";\n const fontName =\n ca.FontName ?? ca.fontName ?? ca.FaceNameHangul ?? ca.faceNameHangul ?? \"\";\n const heightVal = ca.Height ?? ca.height ?? \"\";\n\n return {\n b: bVal === \"1\" || bVal === \"true\" || bVal === \"True\" || undefined,\n i: iVal === \"1\" || iVal === \"true\" || iVal === \"True\" || undefined,\n u: uVal && uVal !== \"NONE\" ? true : undefined,\n s: sVal && sVal !== \"NONE\" && sVal !== \"3D\" ? true : undefined,\n font: fontName ? safeFont(fontName) : undefined,\n pt: heightVal ? Metric.hHeightToPt(Number(heightVal)) : undefined,\n color: safeHex(ca.TextColor ?? ca.textColor),\n bg: safeHex(ca.BgColor ?? 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 =\n pic?.[\"hp:img\"]?.[0]?._attr ??\n pic?.[\"hc:img\"]?.[0]?._attr ??\n pic?.img?.[0]?._attr ??\n {};\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 (\n key.includes(binRef) ||\n key.toLowerCase().includes(binRef.toLowerCase())\n ) {\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\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n 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(\n TextKit.base64Encode(imgData),\n mimeMap[ext] ?? \"image/png\",\n w,\n h,\n undefined,\n layout,\n );\n } catch {\n return null;\n }\n}\n\nfunction extractHwpxLayout(posAttr: any, pic: any): ImgLayout {\n const treatAsChar =\n posAttr.treatAsChar === \"1\" || posAttr.treatAsChar === \"true\";\n if (treatAsChar) return { wrap: \"inline\" };\n\n // textWrap → wrap (direct attribute of hp:pic element)\n const textWrap: string =\n pic?._attr?.textWrap ?? pic?.pic?.[0]?._attr?.textWrap ?? \"TOP_AND_BOTTOM\";\n // OWPML §7.5.8.1 textWrap → ImgWrap 매핑\n // TOP_AND_BOTTOM: 텍스트가 이미지 위아래로만 흐름 → DOCX wrapTopAndBottom (float anchor)\n const wrapMap: Record<string, ImgWrap> = {\n TOP_AND_BOTTOM: \"topAndBottom\", // float, 위아래 텍스트 흐름\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: \"front\",\n };\n const wrap: ImgWrap = wrapMap[textWrap] ?? \"square\";\n\n // 기준점\n const horzRelToMap: Record<string, ImgHorzRelTo> = {\n PARA: \"para\",\n MARGIN: \"margin\",\n PAGE: \"page\",\n COLUMN: \"column\",\n };\n const vertRelToMap: Record<string, ImgVertRelTo> = {\n PARA: \"para\",\n MARGIN: \"margin\",\n PAGE: \"page\",\n PAPER: \"page\",\n 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> = {\n LEFT: \"left\",\n CENTER: \"center\",\n RIGHT: \"right\",\n };\n const vertAlignMap: Record<string, ImgVertAlign> = {\n TOP: \"top\",\n CENTER: \"center\",\n BOTTOM: \"bottom\",\n };\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: first try a row where ALL cells have cs=1\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) {\n allSingle = false;\n break;\n }\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\n // Fallback: proportional distribution when no all-single row exists\n if (!gridProps.colWidths) {\n // Determine colCount first: max column index reached across all rows\n let detectedCols = 0;\n for (const row of rowArr) {\n let ci = 0;\n for (const cell of getTag(row, \"hp:tc\", \"hp:CELL\")) {\n const csEl = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n ci += Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1);\n }\n if (ci > detectedCols) detectedCols = ci;\n }\n if (detectedCols > 0) {\n const sums = new Float64Array(detectedCols);\n const counts = new Int32Array(detectedCols);\n for (const row of rowArr) {\n let ci = 0;\n for (const cell of getTag(row, \"hp:tc\", \"hp:CELL\")) {\n const csEl = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cs = Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1);\n const szAttr = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const w = Number(szAttr.width ?? 0);\n if (w > 0 && cs > 0) {\n const perCol = w / cs;\n for (let k = 0; k < cs && ci + k < detectedCols; k++) {\n sums[ci + k] += perCol;\n counts[ci + k]++;\n }\n }\n ci += cs;\n }\n }\n const estimated = Array.from(sums).map((s, i) =>\n counts[i] > 0 ? Metric.hwpToPt(s / counts[i]) : 0,\n );\n if (estimated.some((w) => w > 0)) gridProps.colWidths = estimated;\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) {\n // Preserve explicit NONE so it overrides table-level defaultStroke in DOCX tcBorders.\n // Only skip when the side is truly undefined (not specified in borderFill).\n cellProps.top = cellBf.top ?? cellBf.stroke;\n cellProps.bot = cellBf.bottom ?? cellBf.stroke;\n cellProps.left = cellBf.left ?? cellBf.stroke;\n cellProps.right = cellBf.right ?? cellBf.stroke;\n }\n\n // Vertical alignment and cell padding 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\",\n CENTER: \"mid\",\n BOTTOM: \"bot\",\n };\n cellProps.va = vaMap[subAttr.vertAlign];\n }\n // Cell margins (stored in HWPUNIT on subList attributes)\n const HWPX_DEFAULT_MARGIN_LR = 360; // typical default: 3.6pt\n const HWPX_DEFAULT_MARGIN_TB = 141; // typical default: ~1.4pt\n const mL = Number(subAttr.marginLeft ?? HWPX_DEFAULT_MARGIN_LR);\n const mR = Number(subAttr.marginRight ?? HWPX_DEFAULT_MARGIN_LR);\n const mT = Number(subAttr.marginTop ?? HWPX_DEFAULT_MARGIN_TB);\n const mB = Number(subAttr.marginBottom ?? HWPX_DEFAULT_MARGIN_TB);\n if (mL !== HWPX_DEFAULT_MARGIN_LR) cellProps.padL = Metric.hwpToPt(mL);\n if (mR !== HWPX_DEFAULT_MARGIN_LR) cellProps.padR = Metric.hwpToPt(mR);\n if (mT !== HWPX_DEFAULT_MARGIN_TB) cellProps.padT = Metric.hwpToPt(mT);\n if (mB !== HWPX_DEFAULT_MARGIN_TB) cellProps.padB = Metric.hwpToPt(mB);\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 cell content — paragraphs and nested tables (중첩 표)\n const cellKids: (ParaNode | GridNode)[] = [];\n const source = subList ?? cell;\n const sourcePSource = getTag(source, \"hp:p\", \"hp:P\");\n for (const sp of sourcePSource) {\n try {\n // Check if this paragraph contains a nested table in its runs\n const runs = getTag(sp, \"hp:run\", \"hp:RUN\");\n let hasNestedTable = false;\n for (const run of runs) {\n const nestedTbls = getTag(run, \"hp:tbl\", \"hp:TABLE\");\n for (const nestedTbl of nestedTbls) {\n try {\n cellKids.push(decodeGrid(nestedTbl, ctx));\n } catch {\n /* skip malformed nested table */\n }\n hasNestedTable = true;\n }\n }\n if (!hasNestedTable) {\n cellKids.push(decodePara(sp, ctx));\n }\n } catch {\n /* skip corrupted para in cell */\n }\n }\n\n return buildCell(\n cellKids.length > 0 ? cellKids : [buildPara([buildSpan(\"\")])],\n { cs, rs, props: cellProps },\n );\n });\n // Row height: prefer a non-merged cell (rs=1) for accuracy.\n // For merged cells, divide total height by rowSpan to get per-row height.\n let rowHeightPt: number | undefined;\n for (const cell of cellArr) {\n const ca = cell?._attr ?? {};\n const cellSpan = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cellRs = Math.max(1, Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1));\n const hSz = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const hVal = Number(hSz.height ?? 0);\n if (hVal > 0) {\n rowHeightPt = Metric.hwpToPt(hVal) / cellRs;\n if (cellRs === 1) break; // exact match — stop searching\n }\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(\n cellArr.map((cell: any) =>\n buildCell([buildPara([buildSpan(cellText(cell))])]),\n ),\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 const subList = cell?.[\"hp:subList\"]?.[0] ?? cell?.subList?.[0];\n const source = subList ?? cell;\n return getTag(source, \"hp:p\", \"hp:P\")\n .map((p: any) =>\n getTag(p, \"hp:run\", \"hp:RUN\")\n .map((r: any) =>\n getTag(r, \"hp:t\", \"hp:T\")\n .map((t: any) => {\n const val =\n typeof t === \"string\"\n ? t\n : (t?._text ?? t?._ ?? t?.[\"#text\"] ?? \"\");\n return val.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n })\n .join(\"\"),\n )\n .join(\"\"),\n )\n .join(\" \");\n}\n\nfunction tableText(tbl: any): string {\n return getTag(tbl, \"hp:tr\", \"hp:ROW\")\n .map((row: any) =>\n getTag(row, \"hp:tc\", \"hp:CELL\")\n .map((c: any) => cellText(c))\n .join(\"\\t\"),\n )\n .join(\"\\n\");\n}\n\nfunction toArr(v: any): any[] {\n return v == null ? [] : Array.isArray(v) ? v : [v];\n}\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, GridNode } 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 { TextKit } from '../../toolkit/TextKit';\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' = 표(table)\nconst CTRL_IMAGE = 0x696D6720; // 'img '\nconst CTRL_OBJ = 0x6F626A20; // 'obj '\nconst CTRL_FIG = 0x66696720; // 'fig '\nconst CTRL_GSO = 0x67736F20; // 'gso ' = 그리기 객체 (drawing object, contains embedded images)\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 leftMargin: 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, leftMargin: 0, indent: 0 };\n const attr = BinaryKit.readU32LE(d, 0);\n return {\n align: ALIGN_TBL[(attr >> 2) & 0x7] ?? 'left',\n leftMargin: d.length >= 8 ? i32(d, 4) : 0, // offset 4: leftMargin (들여쓰기)\n indent: d.length >= 16 ? i32(d, 12) : 0, // offset 12: first-line indent\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\n// gsoCtx: shared mutable counter for 'gso ' drawing objects.\n// Each 'gso ' CTRL_HEADER encountered increments this counter.\n// objectMap is keyed by 0-based gso order = sequential BinData insertion order.\ninterface GsoCtx { count: number }\n\nfunction parseBody(\n raw: Uint8Array, compressed: boolean, di: DocInfo, shield: ShieldedParser, gsoCtx: GsoCtx,\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, gsoCtx),\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, gsoCtx: GsoCtx,\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 // imgId: for 'gso' uses sequential gsoCtx.count; for others uses flags-based objId\n const ctrlHeaders: { ctrlId: number; imgId: number; wPt: number; hPt: 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\n // HWP 5.0 general-object layout:\n // [0:4] ctrlId [4:4] flags [8:4] xOff [12:4] yOff\n // [16:4] width(HWPUNIT) [20:4] height(HWPUNIT)\n const MAX_HWP = 1_000_000;\n const rawW = r.data.length >= 24 ? BinaryKit.readU32LE(r.data, 16) : 0;\n const rawH = r.data.length >= 28 ? BinaryKit.readU32LE(r.data, 20) : 0;\n const wPt = rawW > 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH > 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n\n // 'gso ' (그리기 객체) uses sequential counter; others use flags-based id\n const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : (r.data.length >= 6 ? BinaryKit.readU16LE(r.data, 4) : 0);\n ctrlHeaders.push({ ctrlId, imgId, wPt, hPt });\n\n if (ctrlId === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, i, di, shield, gsoCtx),\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 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 if (text.chars.length > 0) {\n const spans = resolveCharShapes(text.chars, csPairs, di);\n paraContent.push(...spans);\n }\n\n // Image placeholder spans: only for actual image controls.\n // Non-image controls (footnotes, TOC entries, etc.) are silently skipped.\n if (text.controls.length > 0) {\n for (let ci = 0; ci < text.controls.length; ci++) {\n const ch = ctrlHeaders[ci];\n if (!ch) continue; // anchor-only ctrl (gso is sibling, not inline)\n const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO;\n if (!isImg) continue; // skip footnotes, TOC, page num, etc.\n const dimStr = (ch.wPt > 0 && ch.hPt > 0)\n ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}`\n : '';\n paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`));\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, gsoCtx: GsoCtx,\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; heightHwp?: number; props: CellProps; cellChildren: (ParaNode | GridNode)[] }\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, gsoCtx),\n { row: Math.floor(ci / (colCnt || 1)), col: ci % (colCnt || 1), cs: 1, rs: 1, widthHwp: 0, heightHwp: undefined, props: {}, cellChildren: [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 // Sort by span size ascending so smaller, more precise spans fill widths before larger spans\n const zeroColumns = colWidthsPt.filter(w => w === 0).length;\n if (zeroColumns > 0) {\n const spanCells = parsed.filter(c => c.cs > 1 && c.widthHwp > 0).sort((a, b) => a.cs - b.cs);\n for (const c of spanCells) {\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 // Post-process: clamp near-zero column widths (< 1pt = floating-point artifact) to minimum 1pt\n for (let i = 0; i < colWidthsPt.length; i++) {\n if (colWidthsPt[i] > 0 && colWidthsPt[i] < 1) colWidthsPt[i] = 1;\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\n // Calculate row height — prefer rs=1 cells (exact per-row height)\n let rowHeightPt: number | undefined = undefined;\n for (const c of rc) {\n if (c.heightHwp && c.heightHwp > 0 && c.rs === 1) {\n const hPt = Metric.hwpToPt(c.heightHwp);\n if (rowHeightPt == null || hPt > rowHeightPt) rowHeightPt = hPt;\n }\n }\n // Fallback: all cells span multiple rows → approximate height per row\n if (rowHeightPt == null) {\n for (const c of rc) {\n if (c.heightHwp && c.heightHwp > 0) {\n const hPt = Metric.hwpToPt(c.heightHwp) / c.rs;\n if (rowHeightPt == null || hPt > rowHeightPt) rowHeightPt = hPt;\n }\n }\n }\n\n rows.push(buildRow(rc.map(c => {\n return buildCell(c.cellChildren, { cs: c.cs, rs: c.rs, props: c.props });\n }), rowHeightPt));\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, gsoCtx: GsoCtx,\n) {\n let col: number, row: number, cs = 1, rs = 1;\n let widthHwp = 0;\n let heightHwp = 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 const HWP_PAD_LR_DEFAULT = 360;\n const HWP_PAD_TB_DEFAULT = 141;\n\n if (tag === TAG_LIST_HEADER && d.length >= 22) {\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 heightHwp = d.length >= 24 ? BinaryKit.readU32LE(d, 20) : 0;\n if (d.length >= 32) {\n const pL = BinaryKit.readU16LE(d, 24); const pR = BinaryKit.readU16LE(d, 26);\n const pT = BinaryKit.readU16LE(d, 28); const pB = BinaryKit.readU16LE(d, 30);\n if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL);\n if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR);\n if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT);\n if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB);\n }\n const bfId = d.length >= 34 ? BinaryKit.readU16LE(d, 32) : 0;\n if (bfId > 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props);\n } else if (tag !== TAG_LIST_HEADER) {\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 heightHwp = d.length >= 22 ? BinaryKit.readU32LE(d, 18) : 0;\n if (d.length >= 30) {\n const pL = BinaryKit.readU16LE(d, 22); const pR = BinaryKit.readU16LE(d, 24);\n const pT = BinaryKit.readU16LE(d, 26); const pB = BinaryKit.readU16LE(d, 28);\n if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL);\n if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR);\n if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT);\n if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB);\n }\n const bfId = d.length >= 32 ? BinaryKit.readU16LE(d, 30) : 0;\n if (bfId > 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props);\n } else {\n row = Math.floor(seqIdx / (colCnt || 1));\n col = seqIdx % (colCnt || 1);\n }\n\n const cellChildren: (ParaNode | GridNode)[] = [];\n const MAX_HWP = 1_000_000;\n let k = cStart;\n\n while (k < cEnd) {\n if (recs[k].tag === TAG_PARA_HEADER) {\n // Parse paragraph inside cell — also extracts nested tables within the paragraph\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 const ctrlHdrs: { ctrlId: number; imgId: number; wPt: number; hPt: number }[] = [];\n const innerGrids: GridNode[] = [];\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 if (recs[j].tag === TAG_CTRL_HEADER && recs[j].level === lv + 1) {\n if (recs[j].data.length >= 4) {\n const ctrlId = BinaryKit.readU32LE(recs[j].data, 0);\n if (ctrlId === CTRL_TABLE) {\n // Nested table inside a cell paragraph — recurse into parseTableCtrl\n const nestedTr = shield.guard(\n () => parseTableCtrl(recs, j, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, j) },\n `hwp:innerNestedTbl@${j}`,\n );\n if (nestedTr.grid) innerGrids.push(nestedTr.grid as GridNode);\n j = nestedTr.next;\n } else {\n const rawW = recs[j].data.length >= 24 ? BinaryKit.readU32LE(recs[j].data, 16) : 0;\n const rawH = recs[j].data.length >= 28 ? BinaryKit.readU32LE(recs[j].data, 20) : 0;\n const wPt = rawW > 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH > 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : (recs[j].data.length >= 6 ? BinaryKit.readU16LE(recs[j].data, 4) : 0);\n ctrlHdrs.push({ ctrlId, imgId, wPt, hPt });\n j = skipKids(recs, j);\n }\n } else {\n j = skipKids(recs, j);\n }\n }\n else j++;\n }\n const paraContent: (SpanNode | ContentNode)[] = [];\n if (txt && txt.chars.length > 0) paraContent.push(...resolveCharShapes(txt.chars, csp, di));\n if (txt && txt.controls.length > 0) {\n for (let ci = 0; ci < txt.controls.length; ci++) {\n const ch = ctrlHdrs[ci];\n if (!ch) continue;\n const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO;\n if (!isImg) continue;\n const dimStr = (ch.wPt > 0 && ch.hPt > 0) ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}` : '';\n paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`));\n }\n }\n const kids = paraContent.length > 0 ? paraContent as any : [buildSpan('')];\n const items: (ParaNode | GridNode)[] = [buildPara(kids, buildParaProps(ps)), ...innerGrids];\n return { items, next: j };\n },\n { items: [buildPara([buildSpan('')])] as (ParaNode | GridNode)[], next: k + 1 },\n `hwp:cellP@${k}`,\n );\n cellChildren.push(...r.items);\n k = r.next;\n } else if (recs[k].tag === TAG_CTRL_HEADER && recs[k].data.length >= 4) {\n // CTRL_HEADER at cell level (sibling of PARA_HEADER) — anchored 'gso' images and outer-level nested tables\n const cellCtrlId = BinaryKit.readU32LE(recs[k].data, 0);\n if (cellCtrlId === CTRL_GSO) {\n const gsoId = gsoCtx.count++;\n const rawW = recs[k].data.length >= 24 ? BinaryKit.readU32LE(recs[k].data, 16) : 0;\n const rawH = recs[k].data.length >= 28 ? BinaryKit.readU32LE(recs[k].data, 20) : 0;\n const wPt = rawW > 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH > 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n const dimStr = (wPt > 0 && hPt > 0) ? `_W${Math.round(wPt)}_H${Math.round(hPt)}` : '';\n cellChildren.push(buildPara([buildSpan(`__EXT_${gsoId}${dimStr}__`)]));\n k = skipKids(recs, k);\n } else if (cellCtrlId === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, k, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, k) },\n `hwp:nestedTbl@${k}`,\n );\n if (tr.grid) cellChildren.push(tr.grid as GridNode);\n k = tr.next;\n } else {\n k = skipKids(recs, k);\n }\n } else { k++; }\n }\n\n return {\n row, col, cs, rs, props, widthHwp,\n heightHwp: heightHwp || undefined,\n cellChildren: cellChildren.length ? cellChildren : [buildPara([buildSpan('')])],\n };\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\n// Apply borderFill to CellProps. Preserve explicit NONE so DOCX tcBorders can\n// override the table-level tblBorders. Filtering NONE would let tblBorders bleed through.\nfunction applyCellBorderFill(bf: HwpBorderFill, props: CellProps): void {\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\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 // leftMargin (offset 4) = 문단 몸체 왼쪽 여백 → leftMargin (pt), ensure non-negative\n const leftMarginPt = Math.max(0, Metric.hwpToPt(ps.leftMargin));\n if (leftMarginPt > 0) p.leftMargin = leftMarginPt;\n // indent (offset 12) = 첫 줄 들여쓰기(양수) / 내어쓰기(음수) → firstLineIndentPt\n if (ps.indent !== 0) p.firstLineIndentPt = 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 readonly aliases = ['application/vnd.hancom.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 // HWP duplicates each BinData entry: once as \"BinData/BIN0001.jpg\" and once as \"BIN0001.jpg\".\n // We keep only the \"BinData/\" prefixed versions, sort by BIN number, then assign 0-based keys\n // matching the order 'gso' CTRL_HEADER records are encountered during body parsing.\n const binEntries: { binNum: number; data: Uint8Array }[] = [];\n for (const [path, streamData] of streams) {\n // Match \"BinData/BIN0001.jpg\" style — the canonical form\n const m = path.match(/^BinData[/\\\\]BIN(\\d+)\\.\\w+$/i);\n if (m) binEntries.push({ binNum: parseInt(m[1], 10), data: streamData });\n }\n // Sort by BIN number (ascending) so BIN0001→idx0, BIN0002→idx1, …\n binEntries.sort((a, b) => a.binNum - b.binNum);\n\n const objectMap = new Map<number, ImgNode>();\n for (let idx = 0; idx < binEntries.length; idx++) {\n const { data: imgData } = binEntries[idx];\n\n // Determine MIME type from binary signature first, then fall back to extension\n let mimeType: ImgNode['mime'] = 'image/jpeg';\n if (imgData[0] === 0x89 && imgData[1] === 0x50) mimeType = 'image/png';\n else if (imgData[0] === 0x47 && imgData[1] === 0x49) mimeType = 'image/gif';\n else if (imgData[0] === 0x42 && imgData[1] === 0x4D) mimeType = 'image/bmp';\n\n const base64 = TextKit.base64Encode(imgData);\n const { wPt, hPt } = getImageDimsPt(imgData, mimeType);\n objectMap.set(idx, buildImg(base64, mimeType, wPt, hPt));\n }\n\n // gsoCtx tracks sequential 'gso' encounter order — must be shared across all sections\n const gsoCtx: GsoCtx = { count: 0 };\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, gsoCtx);\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, gsoCtx),\n { content: [], pageDims: undefined },\n `hwp:sec${s}`,\n );\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n\n if (objectMap.size > 0) {\n injectImagesIntoContent(allContent, objectMap);\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\n/* ═══════════════════════════════════════════════════════════════\n Image dimension extraction from binary headers\n ════════════════════════════════════════════════════════════ */\n\n// Returns { wPt, hPt } by parsing image headers; falls back to { wPt: 72, hPt: 72 } (1-inch)\nfunction getImageDimsPt(data: Uint8Array, mime: string): { wPt: number; hPt: number } {\n const fallback = { wPt: 72, hPt: 72 };\n try {\n if (mime === 'image/png' && data.length >= 24) {\n // PNG IHDR: sig(8) + length(4) + type(4) + width(4) + height(4) — all big-endian\n const w = (data[16] << 24 | data[17] << 16 | data[18] << 8 | data[19]) >>> 0;\n const h = (data[20] << 24 | data[21] << 16 | data[22] << 8 | data[23]) >>> 0;\n if (w > 0 && h > 0) return { wPt: w * 0.75, hPt: h * 0.75 }; // 96 DPI → pt\n }\n if (mime === 'image/jpeg') {\n // Scan for SOF markers: FF C0 / C1 / C2 / C3\n let i = 2;\n while (i + 8 < data.length) {\n if (data[i] !== 0xFF) { i++; continue; }\n const marker = data[i + 1];\n if (marker >= 0xC0 && marker <= 0xC3) {\n // SOF: 2-byte marker + 2-byte length + 1-byte precision + 2-byte height + 2-byte width\n const h = (data[i + 5] << 8 | data[i + 6]) >>> 0;\n const w = (data[i + 7] << 8 | data[i + 8]) >>> 0;\n if (w > 0 && h > 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n const segLen = data[i + 2] << 8 | data[i + 3];\n i += 2 + (segLen > 0 ? segLen : 2);\n }\n }\n if (mime === 'image/bmp' && data.length >= 26) {\n // BMP DIB header: width at 18, height at 22 (signed int32 LE; negative = top-down)\n const w = BinaryKit.readU32LE(data, 18);\n const h = Math.abs(BinaryKit.readU32LE(data, 22) | 0);\n if (w > 0 && h > 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n if (mime === 'image/gif' && data.length >= 10) {\n // GIF: width at 6, height at 8 (uint16 LE)\n const w = data[6] | data[7] << 8;\n const h = data[8] | data[9] << 8;\n if (w > 0 && h > 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n } catch { /* ignore */ }\n return fallback;\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 if (objectMap.size === 0) return;\n\n // Helper function to process a list of kids (spans, images, etc.)\n const processKids = (kids: any[]) => {\n for (let i = 0; i < kids.length; i++) {\n const kid = 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 // __EXT_N__ or __EXT_N_W<wPt>_H<hPt>__ (with encoded display size)\n // N is the objId that matches the index in objectMap\n const match = text.match?.(/^__(?:IMG|EXT)_(\\d+)(?:_W(\\d+)_H(\\d+))?__$/);\n if (match) {\n const objId = parseInt(match[1], 10);\n const base = objectMap.get(objId);\n if (base) {\n const wPt = match[2] ? parseInt(match[2], 10) : 0;\n const hPt = match[3] ? parseInt(match[3], 10) : 0;\n // Use encoded display size when valid; otherwise keep pixel-based dims\n kids[i] = (wPt > 0 && hPt > 0) ? { ...base, w: wPt, h: hPt } : base;\n }\n }\n }\n }\n };\n\n // Recursively process a grid (table): resolves image placeholders in all cells,\n // including nested grids inside cells.\n const processGridKids = (grid: any) => {\n if (!grid.kids || !Array.isArray(grid.kids)) return;\n\n for (const row of grid.kids) {\n if (!row.kids || !Array.isArray(row.kids)) continue;\n\n for (const cell of row.kids) {\n if (!cell.kids || !Array.isArray(cell.kids)) continue;\n\n for (const cellKid of cell.kids) {\n if (cellKid.tag === 'grid') {\n // Nested table inside cell — recurse\n processGridKids(cellKid);\n } else if (cellKid.tag === 'para' && cellKid.kids) {\n processKids(cellKid.kids);\n }\n }\n }\n }\n };\n\n for (const node of content) {\n if (node.tag === 'para' && node.kids) {\n // Process paragraph kids (spans, images, links, grids)\n processKids(node.kids);\n\n // Also process any nested grids inside the paragraph\n for (const kid of node.kids) {\n if (kid.tag === 'grid') {\n processGridKids(kid);\n }\n }\n } else if (node.tag === 'grid') {\n // Process grid nodes (tables)\n processGridKids(node);\n }\n }\n}\n\nregistry.registerDecoder(new HwpScanner());\n","import type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n LinkNode,\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 { BaseDecoder } from \"../../core/BaseDecoder\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { XmlKit } from \"../../toolkit/XmlKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\n\nexport class DocxDecoder extends BaseDecoder {\n protected getFormat(): string {\n return \"docx\";\n }\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 getFile = (path: string) => {\n const lower = path.toLowerCase();\n for (const [name, data] of files.entries()) {\n if (name.toLowerCase() === lower) return data;\n }\n return undefined;\n };\n\n const docXml = getFile(\"word/document.xml\");\n if (!docXml) return fail(\"DOCX: word/document.xml not found\");\n\n const relsXml = getFile(\"word/_rels/document.xml.rels\");\n const relsMap = relsXml\n ? await parseRels(TextKit.decode(relsXml))\n : new Map<string, string>();\n\n const coreXml = getFile(\"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 = getFile(\"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 table and paragraph/character style defaults\n let stylesMap: StylesMap = new Map();\n let paraStyleMap: ParaStyleMap = new Map();\n const stylesXml = getFile(\"word/styles.xml\");\n if (stylesXml) {\n try {\n const stylesStr = TextKit.decode(stylesXml);\n stylesMap = await parseStylesMap(stylesStr);\n paraStyleMap = await parseParaStyleMap(stylesStr);\n } catch {\n /* non-fatal */\n }\n }\n\n let docStr = TextKit.decode(docXml).trim();\n if (!docStr) {\n warns.push(\n \"DOCX: word/document.xml is empty, using fallback empty document\",\n );\n docStr =\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:document xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:body/></w:document>';\n }\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 console.log(\n `[DocxDecoder] 파싱된 전체 본문 요소 개수: ${elements.length}`,\n );\n\n const decCtx: DecCtx = {\n relsMap,\n files,\n shield,\n numMap,\n warns,\n stylesMap,\n paraStyleMap,\n };\n\n const kids: ContentNode[] = [];\n for (const el of elements) {\n const nodes = shield.guard(\n () => decodeElement(el, decCtx),\n [buildPara([buildSpan(\"[요소 파싱 실패]\")])],\n \"docx:bodyElement\",\n );\n if (Array.isArray(nodes)) {\n kids.push(...nodes);\n } else {\n kids.push(nodes);\n }\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(\n buildPara([{ tag: \"span\", props: {}, kids: [buildPb()] }]),\n );\n }\n }\n }\n }\n\n // Decode header/footer\n const headersMap = await decodeHeaderFooter(\n \"header\",\n body,\n relsMap,\n files,\n decCtx,\n );\n const footersMap = 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 headers: headersMap,\n footers: footersMap,\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\n/** Parsed paragraph/character style defaults */\ninterface ParaStyleDef {\n rPr?: {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n pt?: number;\n color?: string;\n font?: string;\n };\n pPr?: {\n align?: string;\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n indentPt?: number;\n indentRightPt?: number;\n firstLineIndentPt?: number;\n };\n basedOn?: string; // parent style id\n}\n\ntype StylesMap = Map<string, TblStyleDef>; // styleId → table style defaults\ntype ParaStyleMap = Map<string, ParaStyleDef>; // styleId → para/char style 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 paraStyleMap: ParaStyleMap;\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 const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\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 const trimmed = xml.trim();\n if (!trimmed) return {};\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\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 const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\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 // XML 파서에 따라 w:document 또는 document 형태일 수 있음\n const doc = obj?.[\"w:document\"]?.[0] ?? obj?.document?.[0] ?? obj;\n const body = doc?.[\"w:body\"]?.[0] ?? doc?.body?.[0] ?? doc;\n\n if (!body) {\n console.error(\"[DocxDecoder] 본문(body)을 찾을 수 없습니다.\");\n }\n return body;\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 const headerDxa = Number(mar?.[\"w:header\"] ?? mar?.header ?? 0);\n const footerDxa = Number(mar?.[\"w:footer\"] ?? mar?.footer ?? 0);\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 headerPt: headerDxa > 0 ? Metric.dxaToPt(headerDxa) : undefined,\n footerPt: footerDxa > 0 ? Metric.dxaToPt(footerDxa) : undefined,\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 const sdts = toArr(body?.[\"w:sdt\"] ?? body?.sdt);\n\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 si = 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 } else if ((tag === \"w:sdt\" || tag === \"sdt\") && si < sdts.length) {\n items.push({ type: \"sdt\", node: sdts[si++] });\n }\n }\n // Append any remainders\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 while (si < sdts.length) items.push({ type: \"sdt\", node: sdts[si++] });\n return items;\n }\n\n // Fallback: paragraphs, then tables, then sdts\n return [\n ...paras.map((n: any) => ({ type: \"para\", node: n })),\n ...tables.map((n: any) => ({ type: \"table\", node: n })),\n ...sdts.map((n: any) => ({ type: \"sdt\", 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>, // document.xml.rels (기존)\n files: Map<string, Uint8Array>,\n ctx: DecCtx,\n): Promise<Record<string, 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 result: Record<string, ParaNode[]> = {};\n\n for (const ref of refs) {\n const type = ref._attr?.[\"w:type\"] ?? ref._attr?.type ?? \"default\";\n const rId = ref._attr?.[\"r:id\"] ?? ref._attr?.[\"r:Id\"] ?? ref._attr?.id;\n if (!rId) continue;\n\n const target = relsMap.get(rId);\n if (!target) continue;\n\n const filePath = resolveDocxPath(\"word\", target);\n const fileData = files.get(filePath);\n if (!fileData) continue;\n\n // ★ 핵심 수정: 헤더/풋터 전용 rels 파일 로드\n const hfFileName = filePath.split(\"/\").pop() ?? \"\";\n const hfRelsPath = `word/_rels/${hfFileName}.rels`;\n const hfRelsData = files.get(hfRelsPath);\n // 헤더/풋터 rels를 document rels와 병합\n let hfRelsMap = relsMap;\n if (hfRelsData) {\n const hfRelsStr = TextKit.decode(hfRelsData).trim();\n const parsed = hfRelsStr\n ? await parseRels(hfRelsStr)\n : new Map<string, string>();\n // 병합 (헤더/풋터 rels 우선)\n hfRelsMap = new Map([...relsMap, ...parsed]);\n }\n\n const xmlStr = TextKit.decode(fileData).trim();\n if (!xmlStr) continue;\n\n const watermark = extractWatermark(xmlStr);\n if (watermark) {\n result[type] = [\n buildPara([\n buildSpan(watermark, { pt: 80, color: \"CCCCCC\", b: true }),\n ]),\n ];\n continue;\n }\n\n try {\n const obj: any = await XmlKit.parseStrict(xmlStr);\n const rootTag = kind === \"header\" ? \"w:hdr\" : \"w:ftr\";\n const root =\n obj?.[rootTag]?.[0] ?? obj?.[rootTag.replace(\"w:\", \"\")]?.[0] ?? obj;\n\n // ctx에 hfRelsMap 임시 적용\n const origRelsMap = ctx.relsMap;\n (ctx as any).relsMap = hfRelsMap;\n const paras = toArr(root?.[\"w:p\"] ?? root?.p);\n result[type] = paras.map((p: any) => decodePara(p, ctx));\n (ctx as any).relsMap = origRelsMap;\n } catch (err) {\n console.warn(`[DocxDecoder] ${kind} (${type}) XML 파싱 실패:`, err);\n continue;\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** 워터마크 텍스트 추출 (VML v:textpath 기반) */\nfunction extractWatermark(xml: string): string | null {\n if (!xml.includes(\"v:textpath\")) return null;\n const m = xml.match(/string=\"([^\"]+)\"/);\n return m ? m[1] : null;\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 | 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 } else if (el.type === \"sdt\") {\n return decodeSdt(el.node, ctx);\n }\n return decodePara(el.node, ctx);\n}\n\nfunction decodeSdt(sdt: any, ctx: DecCtx): ContentNode[] {\n const content = sdt?.[\"w:sdtContent\"]?.[0] ?? sdt?.sdtContent?.[0];\n if (!content) return [];\n const elements = getBodyElements(content);\n const kids: ContentNode[] = [];\n for (const el of elements) {\n const res = decodeElement(el, ctx);\n if (Array.isArray(res)) kids.push(...res);\n else kids.push(res);\n }\n return kids;\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 // Resolve paragraph style inheritance chain\n const styleInherited = resolveParaStyle(\n headStyle || undefined,\n ctx.paraStyleMap,\n );\n\n const props: ParaProps = {\n align: safeAlign(alignVal),\n heading: parseHeading(headStyle),\n styleId: headStyle || undefined,\n };\n\n // Spacing (before/after/line height) — inline pPr wins over style\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 else if (styleInherited.pPr?.spaceBefore)\n props.spaceBefore = styleInherited.pPr.spaceBefore;\n if (afterVal > 0) props.spaceAfter = Metric.dxaToPt(afterVal);\n else if (styleInherited.pPr?.spaceAfter)\n props.spaceAfter = styleInherited.pPr.spaceAfter;\n if (lineVal > 0 && lineRule === \"auto\") props.lineHeight = lineVal / 240;\n else if (styleInherited.pPr?.lineHeight)\n props.lineHeight = styleInherited.pPr.lineHeight;\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 const rightVal = Number(indAttr?.[\"w:right\"] ?? indAttr?.right ?? 0);\n const firstLineVal = Number(\n indAttr?.[\"w:firstLine\"] ?? indAttr?.firstLine ?? 0,\n );\n const hangingVal = Number(indAttr?.[\"w:hanging\"] ?? indAttr?.hanging ?? 0);\n if (leftVal > 0) props.indentPt = Metric.dxaToPt(leftVal);\n else if (styleInherited.pPr?.indentPt)\n props.indentPt = styleInherited.pPr.indentPt;\n if (rightVal > 0) props.indentRightPt = Metric.dxaToPt(rightVal);\n else if (styleInherited.pPr?.indentRightPt)\n props.indentRightPt = styleInherited.pPr.indentRightPt;\n if (firstLineVal > 0) props.firstLineIndentPt = Metric.dxaToPt(firstLineVal);\n else if (hangingVal > 0)\n props.firstLineIndentPt = -Metric.dxaToPt(hangingVal);\n else if (styleInherited.pPr?.firstLineIndentPt)\n props.firstLineIndentPt = styleInherited.pPr.firstLineIndentPt;\n\n // Alignment from style if not set inline\n if (!alignVal && styleInherited.pPr?.align)\n props.align = safeAlign(styleInherited.pPr.align);\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 =\n pPr?.[\"w:pageBreakBefore\"]?.[0] ?? pPr?.pageBreakBefore?.[0];\n const hasPageBreakBefore =\n pbBeforeNode != null &&\n (pbBeforeNode?._attr?.[\"w:val\"] ?? pbBeforeNode?._attr?.val ?? \"1\") !== \"0\";\n\n // Resolve all children (runs AND hyperlinks) in document order\n const children = p?.[\"_childOrder\"] as string[] | undefined;\n const kids: (SpanNode | ImgNode | LinkNode)[] = [];\n\n if (Array.isArray(children)) {\n const runsArr = toArr(p?.[\"w:r\"] ?? p?.r);\n const hlArr = toArr(p?.[\"w:hyperlink\"] ?? p?.hyperlink);\n const sdtArr = toArr(p?.[\"w:sdt\"] ?? p?.sdt);\n let ri = 0;\n let hi = 0;\n let si = 0;\n\n for (const tag of children) {\n if (tag === \"w:r\" || tag === \"r\") {\n const run = runsArr[ri++];\n if (run) {\n kids.push(\n ctx.shield.guard(\n () =>\n hasDrawingDeep(run)\n ? decodeRunOrImage(run, ctx)\n : decodeRun(run, ctx, styleInherited.rPr),\n buildSpan(\"\"),\n \"docx:run\",\n ),\n );\n }\n } else if (tag === \"w:hyperlink\" || tag === \"hyperlink\") {\n const hl = hlArr[hi++];\n if (hl) {\n const rId = hl?._attr?.[\"r:id\"] ?? hl?._attr?.id;\n const url = rId ? ctx.relsMap.get(rId) : \"\";\n const hlRuns = toArr(hl?.[\"w:r\"] ?? hl?.r);\n const hlKids = hlRuns.map((r: any) =>\n decodeRun(r, ctx, {\n ...styleInherited.rPr,\n u: true,\n color: \"0000FF\",\n }),\n );\n kids.push({\n tag: \"link\",\n href: url || \"\",\n kids: hlKids,\n });\n }\n } else if (tag === \"w:sdt\" || tag === \"sdt\") {\n const sdt = sdtArr[si++];\n if (sdt) {\n const sdtContent = sdt?.[\"w:sdtContent\"]?.[0] ?? sdt?.sdtContent?.[0];\n if (sdtContent) {\n const innerRuns = toArr(sdtContent?.[\"w:r\"] ?? sdtContent?.r);\n for (const ir of innerRuns) {\n kids.push(\n ctx.shield.guard(\n () =>\n hasDrawingDeep(ir)\n ? decodeRunOrImage(ir, ctx)\n : decodeRun(ir, ctx, styleInherited.rPr),\n buildSpan(\"\"),\n \"docx:run\",\n ),\n );\n }\n }\n }\n }\n }\n } else {\n // Fallback if _childOrder is missing\n const runs = toArr(p?.[\"w:r\"] ?? p?.r);\n const legacyKids: (SpanNode | ImgNode)[] = ctx.shield.guardAll(\n runs,\n (run: any) =>\n hasDrawingDeep(run)\n ? decodeRunOrImage(run, ctx)\n : decodeRun(run, ctx, styleInherited.rPr),\n () => buildSpan(\"\"),\n \"docx:run\",\n );\n kids.push(...legacyKids);\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}\n/** Decode image layout from anchor element */\nfunction decodeImageLayout(anchor: any): ImgLayout {\n const wrap = anchor?.[\"wp:wrapTop\"]?.[0] ?? anchor?.wrapTop?.[0];\n const anchorPos =\n anchor?.[\"wp:anchorPos\"]?.[0]?._attr ?? anchor?.anchorPos?.[0]?._attr ?? {};\n\n const layout: ImgLayout = {\n wrap: \"square\",\n horzAlign: \"left\",\n vertAlign: \"top\",\n horzRelTo: \"page\",\n vertRelTo: \"page\",\n xPt: Number(anchorPos?.x ?? 0) / 12700, // emu to pt\n yPt: Number(anchorPos?.y ?? 0) / 12700, // emu to pt\n };\n\n // Parse wrap type\n if (wrap?.[\"wp:none\"]) layout.wrap = \"none\";\n else if (wrap?.[\"wp:square\"]) layout.wrap = \"square\";\n else if (wrap?.[\"wp:tight\"]) layout.wrap = \"tight\";\n else if (wrap?.[\"wp:through\"]) layout.wrap = \"through\";\n else if (wrap?.[\"wp:behind\"]) layout.wrap = \"behind\";\n else if (wrap?.[\"wp:inFront\"]) layout.wrap = \"front\";\n\n return layout;\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 =\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\n // 1. 차트 감지\n if (graphicData?.[\"c:chart\"] || graphicData?.chart) {\n return {\n tag: \"img\",\n b64: \"\", // 플레이스홀더\n mime: \"image/png\",\n w: wPt,\n h: hPt,\n alt: `[차트: ${alt || \"차트\"}]`,\n layout: decodeImageLayout(anchor),\n };\n }\n\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 let filePath = resolveDocxPath(\"word\", target);\n let fileData = ctx.files.get(filePath);\n\n if (!fileData) {\n filePath = resolveDocxPath(\"word/_rels\", target);\n fileData = ctx.files.get(filePath);\n }\n\n if (!fileData) {\n const fileName = target.split(\"/\").pop() ?? \"\";\n for (const [k, v] of ctx.files) {\n if (fileName && (k.endsWith(\"/\" + fileName) || k === fileName)) {\n fileData = v;\n filePath = k;\n break;\n }\n }\n }\n\n if (!fileData) {\n console.warn(`[DocxDecoder] image not found: \"${target}\"`);\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(\n TextKit.base64Encode(fileData),\n mime,\n wPt,\n hPt,\n alt || undefined,\n layout,\n );\n } catch {\n return null;\n }\n}\n\n/** w:highlight val → hex 색상 매핑 (OOXML 명세) */\nconst HIGHLIGHT_COLOR_MAP: Record<string, string> = {\n yellow: \"FFFF00\",\n green: \"00FF00\",\n cyan: \"00FFFF\",\n magenta: \"FF00FF\",\n blue: \"0000FF\",\n red: \"FF0000\",\n darkBlue: \"00008B\",\n darkCyan: \"008B8B\",\n darkGreen: \"006400\",\n darkMagenta: \"8B008B\",\n darkRed: \"8B0000\",\n darkYellow: \"808000\",\n darkGray: \"A9A9A9\",\n lightGray: \"D3D3D3\",\n black: \"000000\",\n white: \"FFFFFF\",\n};\n\nfunction decodeRun(\n run: any,\n ctx: DecCtx,\n styleRpr?: ParaStyleDef[\"rPr\"],\n): SpanNode {\n const rPr = run?.[\"w:rPr\"]?.[0] ?? run?.rPr?.[0] ?? {};\n\n // w:vanish — 숨긴 텍스트: run 전체 건너뜀 (빈 span 반환)\n const vanishNode = rPr?.[\"w:vanish\"]?.[0] ?? rPr?.vanish?.[0];\n if (vanishNode != null) {\n const vanishVal =\n vanishNode?._attr?.[\"w:val\"] ?? vanishNode?._attr?.val ?? \"1\";\n if (vanishVal !== \"0\") return buildSpan(\"\");\n }\n\n // w:sz → 없으면 w:szCs 로 fallback (한글 글꼴 크기)\n const szAttr = rPr?.[\"w:sz\"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {};\n const szVal = szAttr?.[\"w:val\"] ?? szAttr?.val;\n const szCsAttr = rPr?.[\"w:szCs\"]?.[0]?._attr ?? rPr?.szCs?.[0]?._attr ?? {};\n const szCsVal = szCsAttr?.[\"w:val\"] ?? szCsAttr?.val;\n const effectiveSzVal = szVal ?? szCsVal;\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 // w:shd — 배경색 (낮은 우선순위)\n const shdAttr = rPr?.[\"w:shd\"]?.[0]?._attr ?? rPr?.shd?.[0]?._attr ?? {};\n const shdBg = safeHex(shdAttr?.[\"w:fill\"] ?? shdAttr?.fill);\n\n // w:highlight — 형광펜 색상 (w:shd보다 우선)\n const hlAttr =\n rPr?.[\"w:highlight\"]?.[0]?._attr ?? rPr?.highlight?.[0]?._attr ?? {};\n const hlVal = hlAttr?.[\"w:val\"] ?? hlAttr?.val;\n const bgVal = (hlVal ? HIGHLIGHT_COLOR_MAP[hlVal] : undefined) ?? shdBg;\n\n // w:vertAlign — superscript / subscript\n const vertAlignVal =\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.[\"w:val\"] ??\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.val;\n\n // w:position — 글자 상하 이동 (half-point, 양수=위, 음수=아래)\n // vertAlign이 없을 때 보조 판단: ±4 half-pt(≈2pt) 이상이면 sup/sub\n const posAttr =\n rPr?.[\"w:position\"]?.[0]?._attr ?? rPr?.position?.[0]?._attr ?? {};\n const posVal = Number(posAttr?.[\"w:val\"] ?? posAttr?.val ?? 0);\n let isSup = vertAlignVal === \"superscript\";\n let isSub = vertAlignVal === \"subscript\";\n if (!isSup && !isSub && posVal !== 0) {\n if (posVal >= 4) isSup = true;\n else if (posVal <= -4) isSub = true;\n }\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 // Run-level properties: run wins, then fall back to paragraph style inheritance\n const props: TextProps = {\n b: (bNode != null ? isBold : styleRpr?.b) || undefined,\n i: (iNode != null ? isItalic : styleRpr?.i) || undefined,\n u: (underVal ? underVal !== \"none\" : styleRpr?.u) || undefined,\n s: (sNode != null ? isStrike : styleRpr?.s) || undefined,\n sup: isSup || undefined,\n sub: isSub || undefined,\n pt: effectiveSzVal\n ? Metric.halfPtToPt(Number(effectiveSzVal))\n : styleRpr?.pt,\n color: safeHex(colorVal) ?? styleRpr?.color,\n font: fontName ? safeFont(fontName) : styleRpr?.font,\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\"],\n [\"bottom\", \"bottom\"],\n [\"left\", \"left\"],\n [\"right\", \"right\"],\n [\"insideH\", \"insideH\"],\n [\"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 const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\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/** Parse styles.xml and build a map of paragraph/character style defaults */\nasync function parseParaStyleMap(xml: string): Promise<ParaStyleMap> {\n const map: ParaStyleMap = new Map();\n const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\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 !== \"paragraph\" && type !== \"character\") continue;\n const id = attr?.[\"w:styleId\"] ?? attr?.styleId;\n if (!id) continue;\n const basedOn = (style?.[\"w:basedOn\"]?.[0]?._attr ??\n style?.basedOn?.[0]?._attr)?.[\"w:val\"];\n\n const def: ParaStyleDef = { basedOn };\n\n // rPr from run properties\n const rPr = style?.[\"w:rPr\"]?.[0] ?? style?.rPr?.[0];\n if (rPr) {\n const szAttr = rPr?.[\"w:sz\"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {};\n const szVal = szAttr?.[\"w:val\"] ?? szAttr?.val;\n const colorAttr =\n rPr?.[\"w:color\"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {};\n const colorVal = colorAttr?.[\"w:val\"] ?? colorAttr?.val;\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:eastAsia\"] ??\n fontAttr?.eastAsia;\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 underVal =\n rPr?.[\"w:u\"]?.[0]?._attr?.[\"w:val\"] ?? rPr?.[\"w:u\"]?.[0]?._attr?.val;\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 def.rPr = {\n b: isBold || undefined,\n i: isItalic || undefined,\n u: underVal && underVal !== \"none\" ? true : undefined,\n s: isStrike || undefined,\n pt: szVal ? Metric.halfPtToPt(Number(szVal)) : undefined,\n color: safeHex(colorVal),\n font: fontName ? safeFont(fontName) : undefined,\n };\n }\n\n // pPr from paragraph properties\n const pPr = style?.[\"w:pPr\"]?.[0] ?? style?.pPr?.[0];\n if (pPr) {\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(\n spacingAttr?.[\"w:after\"] ?? spacingAttr?.after ?? 0,\n );\n const lineVal = Number(\n spacingAttr?.[\"w:line\"] ?? spacingAttr?.line ?? 0,\n );\n const lineRule =\n spacingAttr?.[\"w:lineRule\"] ?? spacingAttr?.lineRule ?? \"auto\";\n const indAttr =\n pPr?.[\"w:ind\"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {};\n const leftVal = Number(indAttr?.[\"w:left\"] ?? indAttr?.left ?? 0);\n const rightVal = Number(indAttr?.[\"w:right\"] ?? indAttr?.right ?? 0);\n const firstLineVal = Number(\n indAttr?.[\"w:firstLine\"] ?? indAttr?.firstLine ?? 0,\n );\n const hangingVal = Number(\n indAttr?.[\"w:hanging\"] ?? indAttr?.hanging ?? 0,\n );\n const alignVal =\n pPr?.[\"w:jc\"]?.[0]?._attr?.[\"w:val\"] ??\n pPr?.[\"w:jc\"]?.[0]?._attr?.val;\n def.pPr = {\n align: alignVal,\n spaceBefore: beforeVal > 0 ? Metric.dxaToPt(beforeVal) : undefined,\n spaceAfter: afterVal > 0 ? Metric.dxaToPt(afterVal) : undefined,\n lineHeight:\n lineVal > 0 && lineRule === \"auto\" ? lineVal / 240 : undefined,\n indentPt: leftVal > 0 ? Metric.dxaToPt(leftVal) : undefined,\n indentRightPt: rightVal > 0 ? Metric.dxaToPt(rightVal) : undefined,\n firstLineIndentPt:\n firstLineVal > 0\n ? Metric.dxaToPt(firstLineVal)\n : hangingVal > 0\n ? -Metric.dxaToPt(hangingVal)\n : undefined,\n };\n }\n\n map.set(id, def);\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\n/** Resolve paragraph style inheritance chain (max depth 8) */\nfunction resolveParaStyle(\n styleId: string | undefined,\n map: ParaStyleMap,\n): ParaStyleDef {\n let merged: ParaStyleDef = {};\n const visited = new Set<string>();\n let cur = styleId;\n while (cur && !visited.has(cur)) {\n visited.add(cur);\n const def = map.get(cur);\n if (!def) break;\n // Merge: child values win over parent\n if (def.rPr) {\n merged.rPr = { ...def.rPr, ...merged.rPr };\n }\n if (def.pPr) {\n merged.pPr = { ...def.pPr, ...merged.pPr };\n }\n cur = def.basedOn;\n }\n return merged;\n}\n\n/** Resolve final CellProps borders using 3-level priority chain */\nfunction resolveCellBorders(\n cp: CellProps,\n ri: number,\n ci: number,\n rs: number,\n cs: number,\n rowCount: number,\n 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)\n resolved.bot = isBottomEdge ? tblBdr.bottom : tblBdr.insideH;\n if (!resolved.left) resolved.left = isLeftEdge ? tblBdr.left : tblBdr.insideV;\n if (!resolved.right)\n 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 ??\n 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 =\n 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\"],\n [\"bottom\", \"bot\"],\n [\"left\", \"left\"],\n [\"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\",\n center: \"mid\",\n bottom: \"bot\",\n };\n cp.va = vaMap[vaVal];\n }\n\n // Cell margins (padding)\n const tcMar = tcPr?.[\"w:tcMar\"]?.[0] ?? tcPr?.tcMar?.[0];\n if (tcMar) {\n const top = tcMar?.[\"w:top\"]?.[0]?._attr ?? tcMar?.top?.[0]?._attr;\n const bot =\n tcMar?.[\"w:bottom\"]?.[0]?._attr ?? tcMar?.bottom?.[0]?._attr;\n const left = tcMar?.[\"w:left\"]?.[0]?._attr ?? tcMar?.left?.[0]?._attr;\n const right =\n tcMar?.[\"w:right\"]?.[0]?._attr ?? tcMar?.right?.[0]?._attr;\n\n if (top) cp.padT = Metric.dxaToPt(Number(top?.[\"w:w\"] ?? top?.w ?? 0));\n if (bot) cp.padB = Metric.dxaToPt(Number(bot?.[\"w:w\"] ?? bot?.w ?? 0));\n if (left)\n cp.padL = Metric.dxaToPt(Number(left?.[\"w:w\"] ?? left?.w ?? 0));\n if (right)\n cp.padR = Metric.dxaToPt(Number(right?.[\"w:w\"] ?? right?.w ?? 0));\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)\n gridColIdx += rawRow[prevCi].gridSpan;\n }\n\n // Apply 3-level border resolution (tblStyle → tblBorders → tcBorders already in cp)\n const colCount =\n gridProps.colWidths?.length ??\n rawGrid[0]?.reduce((s, c) => s + c.gridSpan, 0) ??\n 1;\n const resolvedCp = resolveCellBorders(\n cp,\n ri,\n gridColIdx,\n rs,\n rc.gridSpan,\n rawGrid.length,\n colCount,\n tblBdr,\n );\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)\n 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 =\n 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 =\n 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 {\n wrap,\n horzAlign,\n vertAlign,\n horzRelTo,\n vertRelTo,\n xPt,\n yPt,\n distT,\n distB,\n distL,\n distR,\n behindDoc,\n zOrder,\n };\n}\n\nconst HORZ_RELTO_MAP: Record<string, ImgHorzRelTo> = {\n margin: \"margin\",\n leftMargin: \"margin\",\n rightMargin: \"margin\",\n insideMargin: \"margin\",\n outsideMargin: \"margin\",\n column: \"column\",\n page: \"page\",\n character: \"para\",\n paragraph: \"para\",\n};\nconst VERT_RELTO_MAP: Record<string, ImgVertRelTo> = {\n margin: \"margin\",\n topMargin: \"margin\",\n bottomMargin: \"margin\",\n insideMargin: \"margin\",\n outsideMargin: \"margin\",\n line: \"line\",\n page: \"page\",\n paragraph: \"para\",\n};\nconst HORZ_ALIGN_MAP: Record<string, ImgHorzAlign> = {\n left: \"left\",\n center: \"center\",\n right: \"right\",\n inside: \"left\",\n outside: \"right\",\n};\nconst VERT_ALIGN_MAP: Record<string, ImgVertAlign> = {\n top: \"top\",\n center: \"center\",\n bottom: \"bottom\",\n inside: \"top\",\n outside: \"bottom\",\n};\n\nfunction parseHorzRelTo(v?: string): ImgHorzRelTo {\n return HORZ_RELTO_MAP[v ?? \"\"] ?? \"column\";\n}\nfunction parseVertRelTo(v?: string): ImgVertRelTo {\n return VERT_RELTO_MAP[v ?? \"\"] ?? \"para\";\n}\nfunction parseHorzAlign(v?: string): ImgHorzAlign | undefined {\n return HORZ_ALIGN_MAP[v ?? \"\"];\n}\nfunction parseVertAlign(v?: string): ImgVertAlign | undefined {\n return VERT_ALIGN_MAP[v ?? \"\"];\n}\n","import 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';\nimport { BaseDecoder } from '../../core/BaseDecoder';\n\nexport class MdDecoder extends BaseDecoder {\n protected getFormat(): string { return '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 = this.bytesToString(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","/**\n * HtmlDecoder — HTML → DocRoot\n * 간단한 HTML 파서 (표, 이미지, 스타일 지원)\n */\n\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, ImgNode, GridNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { TextProps, ParaProps } 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';\nimport { BaseDecoder } from '../../core/BaseDecoder';\n\ninterface Token {\n type: 'tag' | 'text' | 'comment';\n name?: string;\n attrs?: Record<string, string>;\n selfClose?: boolean;\n close?: boolean;\n content?: string;\n}\n\nexport class HtmlDecoder extends BaseDecoder {\n protected getFormat(): string { return 'html'; }\n\n async decode(data: Uint8Array): Promise<Outcome<DocRoot>> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const html = this.bytesToString(data);\n const tokens = shield.guard(() => tokenize(html), [], 'html:tokenize');\n const kids = shield.guard(() => parseTokens(tokens), [], 'html:parse');\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(`HTML decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\nfunction tokenize(html: string): Token[] {\n const tokens: Token[] = [];\n let i = 0;\n\n while (i < html.length) {\n if (html[i] === '<') {\n if (html[i + 1] === '!') {\n const end = html.indexOf('>', i);\n i = end + 1;\n continue;\n }\n\n const isClose = html[i + 1] === '/';\n const start = isClose ? i + 2 : i + 1;\n const end = html.indexOf('>', i);\n if (end === -1) break;\n\n const tagContent = html.slice(start, end).trim();\n const spaceIdx = tagContent.search(/\\s/);\n const name = spaceIdx > 0 ? tagContent.slice(0, spaceIdx) : tagContent;\n const attrsStr = spaceIdx > 0 ? tagContent.slice(spaceIdx + 1).trim() : '';\n\n const attrs: Record<string, string> = {};\n if (attrsStr) {\n const attrRegex = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'=<>`]+)))?/g;\n let m;\n while ((m = attrRegex.exec(attrsStr)) !== null) {\n attrs[m[1].toLowerCase()] = m[2] ?? m[3] ?? m[4] ?? '';\n }\n }\n\n tokens.push({\n type: 'tag',\n name: name.toLowerCase(),\n attrs,\n selfClose: html[end - 1] === '/',\n close: isClose,\n });\n\n i = end + 1;\n } else {\n const end = html.indexOf('<', i);\n const text = end === -1 ? html.slice(i) : html.slice(i, end);\n if (text.trim()) {\n tokens.push({ type: 'text', content: text });\n }\n i = end === -1 ? html.length : end;\n }\n }\n\n return tokens;\n}\n\nfunction parseTokens(tokens: Token[]): ContentNode[] {\n const kids: ContentNode[] = [];\n let i = 0;\n\n while (i < tokens.length) {\n const t = tokens[i];\n\n if (t.type === 'tag' && !t.close) {\n switch (t.name) {\n case 'html':\n // Extract body content\n i++;\n let bodyStart = -1;\n let depth = 1;\n while (i < tokens.length && depth > 0) {\n if (tokens[i].type === 'tag' && !tokens[i].close && tokens[i].name === 'html') depth++;\n else if (tokens[i].type === 'tag' && tokens[i].close && tokens[i].name === 'html') depth--;\n else if (tokens[i].type === 'tag' && !tokens[i].close && tokens[i].name === 'body') {\n bodyStart = i + 1;\n }\n i++;\n }\n if (bodyStart > 0) {\n // Find body end\n let bodyEnd = bodyStart;\n let bodyDepth = 1;\n while (bodyEnd < tokens.length && bodyDepth > 0) {\n if (tokens[bodyEnd].type === 'tag' && !tokens[bodyEnd].close && tokens[bodyEnd].name === 'body') bodyDepth++;\n else if (tokens[bodyEnd].type === 'tag' && tokens[bodyEnd].close && tokens[bodyEnd].name === 'body') bodyDepth--;\n bodyEnd++;\n }\n bodyEnd--;\n const bodyTokens = tokens.slice(bodyStart, bodyEnd);\n const bodyKids = parseTokens(bodyTokens);\n kids.push(...bodyKids);\n }\n continue;\n\n case 'head':\n case 'style':\n case 'script':\n i = skipBlock(tokens, i, t.name);\n continue;\n\n case 'body':\n case 'div':\n case 'section':\n case 'article':\n case 'main':\n // Find closing tag and process contents\n const start = i + 1;\n let end = start;\n let divDepth = 1;\n while (end < tokens.length && divDepth > 0) {\n const t = tokens[end];\n if (t.type === 'tag' && !t.close) {\n if (['html', 'head', 'body', 'div', 'section', 'article', 'main'].includes(t.name ?? '')) divDepth++;\n } else if (t.type === 'tag' && t.close) {\n if (['html', 'head', 'body', 'div', 'section', 'article', 'main'].includes(t.name ?? '')) divDepth--;\n }\n end++;\n }\n end--;\n\n // Process tokens between start and end\n const subTokens = tokens.slice(start, end);\n const subKids = parseTokens(subTokens);\n kids.push(...subKids);\n\n i = end + 1;\n continue;\n\n case 'p':\n i++;\n const paraKids = collectInline(tokens, i, ['p', 'div', 'br']);\n i = paraKids.nextI;\n const align = t.attrs?.style?.includes('text-align: center') ? 'center'\n : t.attrs?.style?.includes('text-align: right') ? 'right'\n : t.attrs?.style?.includes('text-align: left') ? 'left'\n : undefined;\n kids.push(buildPara(paraKids.nodes, { align }));\n continue;\n\n case 'br':\n kids.push(buildPara([buildSpan('')], {}));\n i++;\n continue;\n\n case 'img':\n i++;\n const src = t.attrs?.src;\n const alt = t.attrs?.alt || '';\n if (src?.startsWith('data:')) {\n const match = src.match(/^data:([^;]+);base64,(.+)$/);\n if (match) {\n kids.push(buildPara([buildImg(match[2], match[1] as any, 100, 100, alt)], {}));\n }\n }\n continue;\n\n case 'table':\n i++;\n const rows: any[] = [];\n while (i < tokens.length) {\n if (tokens[i].type === 'tag' && tokens[i].close && tokens[i].name === 'table') {\n i++;\n break;\n }\n if (tokens[i].type === 'tag' && tokens[i].name === 'tr' && !tokens[i].close) {\n i++;\n const cells: any[] = [];\n while (i < tokens.length) {\n if (tokens[i].type === 'tag' && tokens[i].close && tokens[i].name === 'tr') {\n i++;\n break;\n }\n if (tokens[i].type === 'tag' && (tokens[i].name === 'td' || tokens[i].name === 'th') && !tokens[i].close) {\n i++;\n const cellKids = collectInline(tokens, i, ['td', 'th', 'tr']);\n i = cellKids.nextI;\n const isHeader = tokens[i - 2]?.name === 'th';\n const paraKids = cellKids.nodes.map(n => n.tag === 'span' ? { ...n, props: { ...n.props, b: isHeader } } : n);\n cells.push(buildCell([buildPara(paraKids, {})]));\n } else if (tokens[i].type === 'text' && tokens[i].content?.trim()) {\n cells.push(buildCell([buildPara([buildSpan(tokens[i].content!.trim())])]));\n i++;\n } else {\n i++;\n }\n }\n if (cells.length > 0) rows.push(buildRow(cells));\n } else {\n i++;\n }\n }\n if (rows.length > 0) kids.push(buildGrid(rows));\n continue;\n\n case 'ul':\n case 'ol':\n i++;\n const isOrdered = t.name === 'ol';\n while (i < tokens.length) {\n if (tokens[i].type === 'tag' && tokens[i].close && tokens[i].name === t.name) {\n i++;\n break;\n }\n if (tokens[i].type === 'tag' && tokens[i].name === 'li' && !tokens[i].close) {\n i++;\n const liKids = collectInline(tokens, i, ['li', 'ul', 'ol']);\n i = liKids.nextI;\n kids.push(buildPara(liKids.nodes, { listOrd: isOrdered }));\n } else {\n i++;\n }\n }\n continue;\n\n default:\n i++;\n }\n } else if (t.type === 'text' && t.content?.trim()) {\n kids.push(buildPara([buildSpan(t.content!.trim())], {}));\n i++;\n } else {\n i++;\n }\n }\n\n return kids;\n}\n\nfunction collectInline(tokens: Token[], start: number, stopTags: string[]): { nodes: (SpanNode | ImgNode)[]; nextI: number } {\n const nodes: (SpanNode | ImgNode)[] = [];\n let i = start;\n\n while (i < tokens.length) {\n const t = tokens[i];\n\n if (t.type === 'tag' && !t.close) {\n if (t.name && stopTags.includes(t.name)) {\n break;\n }\n\n switch (t.name) {\n case 'b':\n case 'strong':\n i++;\n const boldKids = collectInline(tokens, i, ['b', 'strong', ...stopTags]);\n i = boldKids.nextI;\n nodes.push(...boldKids.nodes.map(n => n.tag === 'span' ? { ...n, props: { ...n.props, b: true } } : n));\n continue;\n\n case 'i':\n case 'em':\n i++;\n const italicKids = collectInline(tokens, i, ['i', 'em', ...stopTags]);\n i = italicKids.nextI;\n nodes.push(...italicKids.nodes.map(n => n.tag === 'span' ? { ...n, props: { ...n.props, i: true } } : n));\n continue;\n\n case 'u':\n i++;\n const underlineKids = collectInline(tokens, i, ['u', ...stopTags]);\n i = underlineKids.nextI;\n nodes.push(...underlineKids.nodes.map(n => n.tag === 'span' ? { ...n, props: { ...n.props, u: true } } : n));\n continue;\n\n case 's':\n case 'strike':\n i++;\n const strikeKids = collectInline(tokens, i, ['s', 'strike', ...stopTags]);\n i = strikeKids.nextI;\n nodes.push(...strikeKids.nodes.map(n => n.tag === 'span' ? { ...n, props: { ...n.props, s: true } } : n));\n continue;\n\n case 'span':\n i++;\n const spanKids = collectInline(tokens, i, ['span', ...stopTags]);\n i = spanKids.nextI;\n const color = t.attrs?.style?.match(/color:\\s*([^;]+)/)?.[1];\n nodes.push(...spanKids.nodes.map(n => n.tag === 'span' ? { ...n, props: { ...n.props, color: color || n.props.color } } : n));\n continue;\n\n case 'img':\n const src = t.attrs?.src;\n const alt = t.attrs?.alt || '';\n if (src?.startsWith('data:')) {\n const match = src.match(/^data:([^;]+);base64,(.+)$/);\n if (match) {\n nodes.push(buildImg(match[2], match[1] as any, 100, 100, alt));\n }\n }\n i++;\n continue;\n\n default:\n i++;\n }\n } else if (t.type === 'text') {\n if (t.content?.trim()) {\n nodes.push(buildSpan(t.content!.trim()));\n }\n i++;\n } else {\n i++;\n }\n }\n\n return { nodes: nodes.length > 0 ? nodes : [buildSpan('')], nextI: i };\n}\n\nfunction skipBlock(tokens: Token[], start: number, name: string): number {\n let i = start + 1;\n let depth = 1;\n while (i < tokens.length && depth > 0) {\n if (tokens[i].type === 'tag') {\n if (!tokens[i].close && tokens[i].name === name) depth++;\n if (tokens[i].close && tokens[i].name === name) depth--;\n }\n i++;\n }\n return i;\n}\n\nregistry.registerDecoder(new HtmlDecoder());\n","/**\n * BaseEncoder - 모든 인코더의 기본 클래스\n *\n * 공통 로직을 제공하여 각 포맷별 인코더가 포맷 특유의 로직만 구현하도록 합니다.\n */\n\nimport type { Encoder } from '../contract/encoder';\nimport type { Outcome } from '../contract/result';\nimport type { DocRoot, AnyNode, ImgNode } from '../model/doc-tree';\nimport { TextKit } from '../toolkit/TextKit';\nimport { ArchiveKit } from '../toolkit/ArchiveKit';\n\n// ─── 타입 정의 ───────────────────────────────────\n\nexport interface ImageData {\n node: ImgNode;\n path: string;\n data: Uint8Array;\n}\n\nexport interface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\n// ─── BaseEncoder ───────────────────────────────\n\nexport abstract class BaseEncoder implements Encoder {\n readonly format: string = this.getFormat();\n readonly aliases: string[] = this.getAliases();\n\n /** 포맷 이름 반환 (하위 클래스에서 오버라이드) */\n protected abstract getFormat(): string;\n\n /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */\n protected getAliases(): string[] { return []; }\n\n /** 문서 인코딩 (하위 클래스에서 오버라이드) */\n abstract encode(doc: DocRoot): Promise<Outcome<Uint8Array>>;\n\n // ─── 공통 유틸리티 메서드 ───────────────────────────\n\n /** 문서 내 모든 이미지 노드 수집 */\n protected collectImages(doc: DocRoot): ImgNode[] {\n const images: ImgNode[] = [];\n this.collectImagesRecursive(doc, images);\n return images;\n }\n\n /** 재귀적으로 이미지 수집 */\n private collectImagesRecursive(node: AnyNode, images: ImgNode[]): void {\n if (node.tag === 'img') {\n images.push(node);\n return;\n }\n\n const children = this.getChildren(node);\n for (const child of children) {\n this.collectImagesRecursive(child, images);\n }\n }\n\n /** 노드의 자식 노드 반환 */\n private getChildren(node: AnyNode): AnyNode[] {\n switch (node.tag) {\n case 'root':\n return node.kids;\n case 'sheet':\n return [...node.kids, ...(node.headers?.default ?? []), ...(node.footers?.default ?? [])];\n case 'para':\n return node.kids;\n case 'span':\n return node.kids;\n case 'link':\n return node.kids;\n case 'row':\n return node.kids;\n case 'cell':\n return node.kids;\n case 'grid':\n return node.kids;\n default:\n return [];\n }\n }\n\n /** base64 문자열을 Uint8Array 로 변환 */\n protected base64ToBytes(b64: string): Uint8Array {\n return TextKit.base64Decode(b64);\n }\n\n /** Uint8Array 를 base64 문자열로 변환 */\n protected bytesToBase64(data: Uint8Array): string {\n return TextKit.base64Encode(data);\n }\n\n /** XML 이스케이프 */\n protected escapeXml(s: string): string {\n return TextKit.escapeXml(s);\n }\n\n /** XML 언이스케이프 */\n protected unescapeXml(s: string): string {\n return TextKit.unescapeXml(s);\n }\n\n /** 문자열을 UTF-8 바이트로 변환 */\n protected stringToBytes(s: string): Uint8Array {\n return TextKit.encode(s);\n }\n\n /** 바이트를 UTF-8 문자열로 변환 */\n protected bytesToString(data: Uint8Array): string {\n return TextKit.decode(data);\n }\n\n /** ZIP 압축 */\n protected async zip(entries: ZipEntry[]): Promise<Uint8Array> {\n return ArchiveKit.zip(entries);\n }\n\n /** ZIP 해제 */\n protected async unzip(data: Uint8Array): Promise<Map<string, Uint8Array>> {\n return ArchiveKit.unzip(data);\n }\n\n /** deflate 압축 */\n protected async deflate(data: Uint8Array): Promise<Uint8Array> {\n return ArchiveKit.deflate(data);\n }\n\n /** inflate 해제 */\n protected async inflate(data: Uint8Array): Promise<Uint8Array> {\n return ArchiveKit.inflate(data);\n }\n\n /** 제어 문자 제거 */\n protected stripControl(s: string): string {\n return TextKit.stripControl(s);\n }\n\n /** 공백 정규화 */\n protected normalizeWhitespace(s: string): string {\n return TextKit.normalizeWhitespace(s);\n }\n}\n","/**\n * HwpxEncoder — DocRoot → HWPX (ZIP + XML)\n *\n * ANYTOHWP에서 영감받은 개선 사항:\n * 1. LangFontBank — 7개 언어 그룹 독립 폰트 레지스트리 (HANGUL/LATIN/HANJA/…)\n * 2. BorderFillBank — 정확한 ID 관리 (하드코딩 \"1\" 제거)\n * 3. readPixelDims — PNG/JPEG 바이너리 헤더에서 실제 픽셀 치수 추출\n * 4. 두 패스 구조 — Pre-scan(등록) → Encode(생성)\n */\n\nimport type {\n DocRoot,\n ParaNode,\n SpanNode,\n GridNode,\n ContentNode,\n ImgNode,\n SheetNode,\n CellNode,\n LinkNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport { BaseEncoder } from \"../../core/BaseEncoder\";\nimport type {\n DocMeta,\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\";\nimport { HWPX_MIME_TYPE } from \"./constants\";\n\n// ─── HWPX 네임스페이스 ──────────────────────────────────────\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// ─── LinesegArray Flags 상수 (HWPX 스펙) ─────────────────\n// 첫 번째 lineseg: 0x160000 = 1441792 (시작 줄, 고정 위치)\n// 이후 lineseg: 0x60000 = 393216 (일반 줄)\nconst LINESEG_FLAGS_FIRST = 0x160000; // 1441792 - 첫 줄 (시작, 고정)\nconst LINESEG_FLAGS_OTHER = 0x60000; // 393216 - 이후 줄\n\n// ─── ANYTOHWP 영감: 언어별 폰트 레지스트리 ─────────────────\n// 7개 언어 그룹을 독립적으로 관리 — charPr fontRef의 정확한 ID 생성\nconst LANG_GROUPS = [\n \"HANGUL\",\n \"LATIN\",\n \"HANJA\",\n \"JAPANESE\",\n \"OTHER\",\n \"SYMBOL\",\n \"USER\",\n] as const;\ntype LangGroup = (typeof LANG_GROUPS)[number];\n\nclass LangFontBank {\n // 언어 그룹별 독립 폰트 맵: face → localId (0-based)\n private maps = new Map<LangGroup, Map<string, number>>(\n LANG_GROUPS.map((g) => [g, new Map<string, number>()]),\n );\n\n constructor() {\n // ANYTOHWP 기본값: 모든 그룹에 한컴 기본 폰트 등록 (id=0)\n this.registerAll(\"함초롬바탕\");\n }\n\n /** 모든 언어 그룹에 동일 폰트 등록 */\n registerAll(face: string): void {\n for (const g of LANG_GROUPS) {\n const m = this.maps.get(g)!;\n if (!m.has(face)) m.set(face, m.size);\n }\n }\n\n /** 특정 언어 그룹에 폰트 등록, 이미 있으면 기존 ID 반환 */\n register(lang: LangGroup, face: string): number {\n const m = this.maps.get(lang)!;\n if (m.has(face)) return m.get(face)!;\n const id = m.size;\n m.set(face, id);\n return id;\n }\n\n /** 폰트 이름 → 한글 폰트 여부 판별 (ANYTOHWP 방식) */\n private isKorean(face: string): boolean {\n return (\n /[\\uAC00-\\uD7A3\\u3131-\\u318E]/.test(face) ||\n [\"맑은\", \"나눔\", \"굴림\", \"돋움\", \"바탕\", \"함초롬\", \"한컴\", \"HY\"].some(\n (k) => face.includes(k),\n )\n );\n }\n\n /** TextProps.font 문자열에서 적절한 HANGUL/LATIN 그룹에 등록 */\n registerFont(rawFace: string): { hangulId: number; latinId: number } {\n const face = safeFontToKr(rawFace) || \"함초롬바탕\";\n const isKor = this.isKorean(face);\n // 한글 폰트: HANGUL/HANJA/JAPANESE/OTHER/SYMBOL/USER에 등록\n // 라틴 폰트: LATIN에 등록, 나머지는 기본값(0) 유지\n const hangulId = this.register(\"HANGUL\", isKor ? face : \"함초롬바탕\");\n const latinId = this.register(\"LATIN\", isKor ? \"함초롬바탕\" : face);\n for (const g of [\n \"HANJA\",\n \"JAPANESE\",\n \"OTHER\",\n \"SYMBOL\",\n \"USER\",\n ] as LangGroup[]) {\n this.register(g, isKor ? face : \"함초롬바탕\");\n }\n return { hangulId, latinId };\n }\n\n /** 언어 그룹별 폰트 목록 반환 */\n getFaces(lang: LangGroup): string[] {\n return [...this.maps.get(lang)!.keys()];\n }\n\n getId(lang: LangGroup, face: string): number {\n return this.maps.get(lang)!.get(face) ?? 0;\n }\n\n /** hh:fontfaces XML 생성 */\n toXml(): string {\n let xml = `<hh:fontfaces itemCnt=\"${LANG_GROUPS.length}\">`;\n for (const lang of LANG_GROUPS) {\n const faces = this.getFaces(lang);\n xml += `<hh:fontface lang=\"${lang}\" fontCnt=\"${faces.length}\">`;\n faces.forEach((face, i) => {\n xml +=\n `<hh:font id=\"${i}\" face=\"${esc(face)}\" type=\"TTF\" isEmbedded=\"0\">` +\n `<hh:typeInfo familyType=\"FCAT_UNKNOWN\" weight=\"0\" proportion=\"0\" contrast=\"0\" strokeVariation=\"0\" armStyle=\"0\" letterform=\"0\" midline=\"252\" xHeight=\"255\"/>` +\n `</hh:font>`;\n });\n xml += `</hh:fontface>`;\n }\n return xml + `</hh:fontfaces>`;\n }\n}\n\n// ─── ANYTOHWP 영감: BorderFill 레지스트리 ───────────────────\n// 하드코딩 \"1\" 제거 — 모든 셀/표의 실제 테두리를 추적\n\nconst KIND_MAP: Record<string, string> = {\n solid: \"SOLID\",\n dash: \"DASH\",\n dot: \"DOT\",\n double: \"DOUBLE\",\n none: \"NONE\",\n dash_dot: \"DASH_DOT\",\n dash_dot_dot: \"DASH_DOT_DOT\",\n};\n\nclass BorderFillBank {\n private fills: { id: number; xml: string }[] = [];\n private keyMap = new Map<string, number>();\n\n constructor() {\n // id=1: 기본 (테두리 없음) — ANYTOHWP의 기본 초기화 방식\n this._addXml(\n this._buildXml(undefined, undefined, undefined, undefined, undefined),\n );\n // id=2: 표 기본 테두리 (solid 0.5pt black)\n const defS: Stroke = { kind: \"solid\", pt: 0.5, color: \"000000\" };\n this._addXml(this._buildXml(defS, defS, defS, defS, undefined));\n }\n\n private _strokeXml(tag: string, s?: Stroke): string {\n const type =\n s && s.kind !== \"none\" ? (KIND_MAP[s.kind] ?? \"SOLID\") : \"NONE\";\n const w =\n s && s.kind !== \"none\" ? `${(s.pt * 0.3528).toFixed(2)} mm` : \"0.12 mm\";\n const c = s\n ? s.color.startsWith(\"#\")\n ? s.color\n : `#${s.color}`\n : \"#000000\";\n return `<hh:${tag} type=\"${type}\" width=\"${w}\" color=\"${c}\"/>`;\n }\n\n private _buildXml(\n top?: Stroke,\n right?: Stroke,\n bottom?: Stroke,\n left?: Stroke,\n bg?: string,\n ): string {\n const fill = bg\n ? `<hc:fillBrush><hc:winBrush faceColor=\"${bg.startsWith(\"#\") ? bg : \"#\" + bg}\" hatchColor=\"none\" alpha=\"0\"/></hc:fillBrush>`\n : \"\";\n return (\n `<hh:borderFill id=\"__ID__\" threeD=\"0\" shadow=\"0\" centerLine=\"NONE\" breakCellSeparateLine=\"0\">` +\n `<hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>` +\n `<hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>` +\n this._strokeXml(\"leftBorder\", left) +\n this._strokeXml(\"rightBorder\", right) +\n this._strokeXml(\"topBorder\", top) +\n this._strokeXml(\"bottomBorder\", bottom) +\n `<hh:diagonal type=\"NONE\" width=\"0.12 mm\" color=\"#000000\"/>` +\n fill +\n `</hh:borderFill>`\n );\n }\n\n private _addXml(xml: string): number {\n const id = this.fills.length + 1;\n this.fills.push({ id, xml: xml.replace(\"__ID__\", String(id)) });\n return id;\n }\n\n private _key(\n top?: Stroke,\n right?: Stroke,\n bottom?: Stroke,\n left?: Stroke,\n bg?: string,\n ): string {\n const sk = (s?: Stroke) =>\n s ? `${s.kind}:${s.pt.toFixed(2)}:${s.color}` : \"none\";\n return `${sk(top)}|${sk(right)}|${sk(bottom)}|${sk(left)}|${bg ?? \"\"}`;\n }\n\n /** 균일 테두리 등록 */\n addUniform(s?: Stroke, bg?: string): number {\n const key = this._key(s, s, s, s, bg);\n if (this.keyMap.has(key)) return this.keyMap.get(key)!;\n const id = this._addXml(this._buildXml(s, s, s, s, bg));\n this.keyMap.set(key, id);\n return id;\n }\n\n /** 방향별 테두리 등록 */\n addPerSide(\n top?: Stroke,\n right?: Stroke,\n bottom?: Stroke,\n left?: Stroke,\n bg?: string,\n ): number {\n const key = this._key(top, right, bottom, left, bg);\n if (this.keyMap.has(key)) return this.keyMap.get(key)!;\n const id = this._addXml(this._buildXml(top, right, bottom, left, bg));\n this.keyMap.set(key, id);\n return id;\n }\n\n /** CellProps에서 적절한 borderFill ID 계산 (하드코딩 \"1\" 완전 제거) */\n addFromCellProps(cp: CellProps, defStroke?: Stroke): number {\n const d = defStroke ?? DEFAULT_STROKE;\n const top = cp.top ?? d;\n const right = cp.right ?? d;\n const bottom = cp.bot ?? d;\n const left = cp.left ?? d;\n const bg = cp.bg;\n const uniform =\n top.kind === right.kind &&\n top.kind === bottom.kind &&\n top.kind === left.kind &&\n top.pt === right.pt &&\n top.pt === bottom.pt &&\n top.pt === left.pt &&\n top.color === right.color &&\n top.color === bottom.color &&\n top.color === left.color;\n return uniform\n ? this.addUniform(top, bg)\n : this.addPerSide(top, right, bottom, left, bg);\n }\n\n toXml(): string {\n return `<hh:borderFills itemCnt=\"${this.fills.length}\">${this.fills.map((f) => f.xml).join(\"\")}</hh:borderFills>`;\n }\n}\n\n// ─── ANYTOHWP 영감: PNG/JPEG 바이너리 헤더에서 픽셀 치수 추출\nfunction readPixelDims(\n b64: string,\n mime: string,\n): { w: number; h: number } | null {\n try {\n const raw = TextKit.base64Decode(b64);\n const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);\n\n if (mime.includes(\"png\")) {\n // PNG: 시그니처 8바이트 + IHDR 청크 길이(4) + 타입(4) + 너비(4) + 높이(4)\n if (\n raw.length >= 24 &&\n view.getUint32(0) === 0x89504e47 &&\n view.getUint32(4) === 0x0d0a1a0a\n ) {\n return { w: view.getUint32(16), h: view.getUint32(20) };\n }\n } else if (mime.includes(\"jpeg\") || mime.includes(\"jpg\")) {\n // JPEG: SOI(FF D8) 후 SOF0(FF C0) 또는 SOF2(FF C2) 마커 탐색\n let off = 2;\n while (off < raw.length - 4) {\n const marker = view.getUint16(off);\n off += 2;\n if (marker === 0xffc0 || marker === 0xffc2) {\n // SOF: length(2) + precision(1) + height(2) + width(2)\n return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) };\n }\n if ((marker & 0xff00) !== 0xff00) break;\n const segLen = view.getUint16(off);\n off += segLen;\n }\n }\n } catch {\n /* 무시 */\n }\n return null;\n}\n\n// ─── charPr / paraPr 레지스트리 ─────────────────────────────\n\ninterface CharPrDef {\n id: number;\n height: number; // HWPX height 단위 (1000 = 10pt)\n bold: boolean;\n italic: boolean;\n underline: string; // \"NONE\" | \"BOTTOM\"\n strikeout: string; // \"NONE\" | \"SOLID\"\n textColor: string; // \"#RRGGBB\"\n hangulId: number; // HANGUL 그룹 폰트 ID\n latinId: number; // LATIN 그룹 폰트 ID\n bg?: string;\n}\n\ninterface ParaPrDef {\n id: number;\n align: string;\n leftHwp: number;\n rightHwp: number;\n intentHwp: number;\n prevHwp: number;\n nextHwp: number;\n lineSpacing: number;\n listType?: string;\n listLevel?: number;\n}\n\ninterface StyleEntry {\n id: number;\n name: string;\n engName: string;\n paraPrIDRef: number;\n charPrIDRef: number;\n}\n\ninterface BinEntry {\n id: string; // \"BIN0001\"\n name: string; // \"BIN0001.png\"\n data: Uint8Array;\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\n/**\n * ParaProps 를 해시 키로 변환 (동일 포맷팅 감지용)\n * null/undefined는 0 으로 처리하여 일관성 유지\n */\nfunction paraPrKey(p: ParaProps): string {\n return `${p.align ?? \"left\"}|${p.listOrd ?? \"\"}|${p.listLv ?? 0}|${p.indentPt ?? 0}|${p.firstLineIndentPt ?? 0}|${p.spaceBefore ?? 0}|${p.spaceAfter ?? 0}|${p.lineHeight ?? 0}|${p.styleId ?? \"\"}`;\n}\n\n// ─── 인코딩 컨텍스트 ─────────────────────────────────────────\n\ninterface HwpxCtx {\n fontBank: LangFontBank;\n borderFillBank: BorderFillBank;\n charPrs: CharPrDef[];\n charPrMap: Map<string, number>;\n paraPrs: ParaPrDef[];\n paraPrMap: Map<string, number>;\n bins: BinEntry[];\n nextBinNum: number;\n nextElementId: number;\n availableWidth: number; // HWPUNIT\n imgMap: WeakMap<ImgNode, string>;\n nextZOrder: number;\n styleIdToHwpxId: Map<string, number>;\n hwpxStyles: StyleEntry[];\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 rawFont = props.font ?? \"함초롬바탕\";\n const { hangulId, latinId } = ctx.fontBank.registerFont(rawFont);\n const id = ctx.charPrs.length;\n\n ctx.charPrs.push({\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 hangulId,\n latinId,\n bg: props.bg,\n });\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 leftHwp: Metric.ptToHwp(props.indentPt ?? 0),\n rightHwp: Metric.ptToHwp(props.indentRightPt ?? 0),\n intentHwp: Metric.ptToHwp(props.firstLineIndentPt ?? 0),\n prevHwp: Metric.ptToHwp(props.spaceBefore ?? 0),\n nextHwp: 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// ─── 이미지 등록 ─────────────────────────────────────────────\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// ─── 스타일 등록 ─────────────────────────────────────────────\n\nconst STYLE_NAME_MAP: Record<string, string> = {\n Normal: \"바탕글\",\n \"Heading 1\": \"개요 1\",\n \"Heading 2\": \"개요 2\",\n \"Heading 3\": \"개요 3\",\n \"Heading 4\": \"개요 4\",\n \"Heading 5\": \"개요 5\",\n \"Heading 6\": \"개요 6\",\n \"Body Text\": \"본문\",\n};\n\nfunction registerStyle(\n styleId: string,\n paraPrId: number,\n charPrId: number,\n ctx: HwpxCtx,\n): void {\n if (!styleId || ctx.styleIdToHwpxId.has(styleId)) return;\n if (styleId === \"Normal\") {\n ctx.styleIdToHwpxId.set(styleId, 0);\n return;\n }\n const hwpxId = ctx.hwpxStyles.length;\n ctx.styleIdToHwpxId.set(styleId, hwpxId);\n ctx.hwpxStyles.push({\n id: hwpxId,\n name: STYLE_NAME_MAP[styleId] ?? styleId,\n engName: \"\",\n paraPrIDRef: paraPrId,\n charPrIDRef: charPrId,\n });\n}\n\n// ─── Pre-scan: 콘텐츠 순회하며 모든 ID 사전 등록 ─────────────\n\nfunction scanPara(para: ParaNode, ctx: HwpxCtx): void {\n const paraPrId = registerParaPr(para.props, ctx);\n let firstCharPrId = 0;\n let hasFirstSpan = false;\n\n function scanKids(kids: ParaNode[\"kids\"]): void {\n for (const kid of kids) {\n if (kid.tag === \"span\") {\n const cId = registerCharPr(kid.props, ctx);\n if (!hasFirstSpan) {\n firstCharPrId = cId;\n hasFirstSpan = true;\n }\n } else if (kid.tag === \"img\") {\n registerImage(kid, ctx);\n } else if (kid.tag === \"link\") {\n scanKids((kid as LinkNode).kids as ParaNode[\"kids\"]);\n }\n }\n }\n scanKids(para.kids);\n if (para.props.styleId)\n registerStyle(para.props.styleId, paraPrId, firstCharPrId, ctx);\n}\n\nfunction scanGrid(grid: GridNode, ctx: HwpxCtx): void {\n const defStroke = grid.props.defaultStroke ?? DEFAULT_STROKE;\n // 표 기본 테두리 사전 등록\n ctx.borderFillBank.addUniform(defStroke);\n for (const row of grid.kids) {\n for (const cell of row.kids) {\n ctx.borderFillBank.addFromCellProps(cell.props, defStroke);\n for (const p of cell.kids) {\n if (p.tag === 'grid') scanGrid(p, ctx);\n else scanPara(p, ctx);\n }\n }\n }\n}\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\n// ─── Encoder 클래스 ──────────────────────────────────────────\n\nexport class HwpxEncoder extends BaseEncoder {\n protected getFormat(): string { return \"hwpx\"; }\n protected getAliases(): string[] { return [HWPX_MIME_TYPE, \"application/hwp+zip\"]; }\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 const safeML = dims.ml > 0 ? dims.ml : 70.87;\n const safeMR = dims.mr > 0 ? dims.mr : 70.87;\n const availableWidth = Math.round(\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(safeML) -\n Metric.ptToHwp(safeMR),\n );\n\n // 컨텍스트 초기화\n const ctx: HwpxCtx = {\n fontBank: new LangFontBank(), // ANYTOHWP 방식 언어별 폰트\n borderFillBank: new BorderFillBank(), // 하드코딩 없는 테두리 관리\n charPrs: [],\n charPrMap: new Map(),\n paraPrs: [],\n paraPrMap: new Map(),\n bins: [],\n nextBinNum: 1,\n nextElementId: 10000,\n availableWidth,\n imgMap: new WeakMap(),\n nextZOrder: 0,\n styleIdToHwpxId: new Map(),\n hwpxStyles: [],\n };\n\n // id=0 기본 charPr/paraPr 등록\n registerCharPr({}, ctx);\n registerParaPr({}, ctx);\n\n // 바탕글(Normal) 스타일 id=0으로 고정\n ctx.hwpxStyles.push({\n id: 0,\n name: \"바탕글\",\n engName: \"Normal\",\n paraPrIDRef: 0,\n charPrIDRef: 0,\n });\n ctx.styleIdToHwpxId.set(\"Normal\", 0);\n\n // 패스 1: Pre-scan — 모든 charPr/paraPr/이미지/테두리 사전 등록\n scanContent(sheet?.kids ?? [], ctx);\n if (sheet?.headers?.default) for (const p of sheet.headers.default) scanPara(p, ctx);\n if (sheet?.footers?.default) for (const p of sheet.footers.default) scanPara(p, ctx);\n\n // 패스 2: Encode — section 먼저 (borderFill 동적 등록 완료 후 header 생성)\n const sectionData = this.stringToBytes(buildSectionXml(sheet, dims, ctx));\n const headerData = this.stringToBytes(buildHeaderXml(dims, doc.meta, ctx));\n const previewText = extractPreviewText(sheet);\n\n const entries: { name: string; data: Uint8Array; mime: string; compression?: 'STORE' | 'DEFLATE' }[] = [\n {\n name: \"mimetype\",\n data: new TextEncoder().encode(HWPX_MIME_TYPE),\n compression: \"STORE\",\n mime: \"\",\n },\n {\n name: \"version.xml\",\n data: this.stringToBytes(VERSION_XML),\n mime: \"application/xml\",\n },\n {\n name: \"META-INF/container.xml\",\n data: this.stringToBytes(CONTAINER_XML),\n mime: \"application/xml\",\n },\n {\n name: \"META-INF/container.rdf\",\n data: this.stringToBytes(CONTAINER_RDF),\n mime: \"application/rdf+xml\",\n },\n {\n name: \"Contents/content.hpf\",\n data: this.stringToBytes(buildContentHpf(ctx, doc.meta)),\n mime: \"application/hwpml-package+xml\",\n },\n {\n name: \"Contents/header.xml\",\n data: headerData,\n mime: \"application/xml\",\n },\n {\n name: \"Contents/section0.xml\",\n data: sectionData,\n mime: \"application/xml\",\n },\n {\n name: \"Preview/PrvText.txt\",\n data: this.stringToBytes(previewText),\n mime: \"text/plain\",\n },\n {\n name: \"settings.xml\",\n data: this.stringToBytes(buildSettingsXml()),\n mime: \"application/xml\",\n },\n ];\n\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 entries.push({ name: `BinData/${bin.name}`, data: bin.data, mime: ct });\n }\n\n return succeed(await this.zip(entries));\n } catch (e: any) {\n return fail(`HWPX 인코딩 오류: ${e?.message ?? String(e)}`);\n }\n }\n}\n\n// ─── 상수 XML ────────────────────────────────────────────────\n\nconst VERSION_XML =\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>` +\n `<hv:HCFVersion xmlns:hv=\"http://www.owpml.org/owpml/2024/version\" ` +\n `targetApplication=\"WORDPROCESSING\" major=\"5\" minor=\"1\" micro=\"0\" buildNumber=\"1\" ` +\n `os=\"1\" xmlVersion=\"1.4\" application=\"Hancom Office Hangul\" appVersion=\"11, 0, 0, 0\"/>`;\n\nconst CONTAINER_XML =\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>` +\n `<ocf:container xmlns:ocf=\"urn:oasis:names:tc:opendocument:xmlns:container\" ` +\n `xmlns:hpf=\"http://www.hancom.co.kr/schema/2011/hpf\">` +\n `<ocf:rootfiles>` +\n `<ocf:rootfile full-path=\"Contents/content.hpf\" media-type=\"application/hwpml-package+xml\"/>` +\n `<ocf:rootfile full-path=\"Preview/PrvText.txt\" media-type=\"text/plain\"/>` +\n `<ocf:rootfile full-path=\"META-INF/container.rdf\" media-type=\"application/rdf+xml\"/>` +\n `</ocf:rootfiles></ocf:container>`;\n\nconst CONTAINER_RDF =\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>` +\n `<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">` +\n `<rdf:Description rdf:about=\"\"><ns0:hasPart xmlns:ns0=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#\" rdf:resource=\"Contents/header.xml\"/></rdf:Description>` +\n `<rdf:Description rdf:about=\"Contents/header.xml\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#HeaderFile\"/></rdf:Description>` +\n `<rdf:Description rdf:about=\"\"><ns0:hasPart xmlns:ns0=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#\" rdf:resource=\"Contents/section0.xml\"/></rdf:Description>` +\n `<rdf:Description rdf:about=\"Contents/section0.xml\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#SectionFile\"/></rdf:Description>` +\n `<rdf:Description rdf:about=\"\"><rdf:type rdf:resource=\"http://www.hancom.co.kr/hwpml/2016/meta/pkg#Document\"/></rdf:Description>` +\n `</rdf:RDF>`;\n\nconst MANIFEST_XML =\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>` +\n `<odf:manifest xmlns:odf=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\"/>`;\n\n// ─── content.hpf ─────────────────────────────────────────────\n\nfunction buildContentHpf(ctx: HwpxCtx, meta?: DocMeta): string {\n const title = esc(meta?.title ?? \"\");\n const creator = esc(meta?.author ?? \"text\");\n const subject = esc(meta?.subject ?? \"text\");\n const desc = esc(meta?.desc ?? \"text\");\n const keyword = esc(meta?.keywords ?? \"text\");\n const created =\n meta?.created ?? new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\");\n const modified = meta?.modified ?? created;\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\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\n return (\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>` +\n `<opf:package ${NS} version=\"\" unique-identifier=\"\" id=\"\">` +\n `<opf:metadata>` +\n `<opf:title>${title}</opf:title><opf:language>ko</opf:language>` +\n `<opf:meta name=\"creator\" content=\"text\">${creator}</opf:meta>` +\n `<opf:meta name=\"subject\" content=\"text\">${subject}</opf:meta>` +\n `<opf:meta name=\"description\" content=\"text\">${desc}</opf:meta>` +\n `<opf:meta name=\"CreatedDate\" content=\"text\">${created}</opf:meta>` +\n `<opf:meta name=\"ModifiedDate\" content=\"text\">${modified}</opf:meta>` +\n `<opf:meta name=\"keyword\" content=\"text\">${keyword}</opf:meta>` +\n `<opf:meta name=\"trackchageConfig\" content=\"text\">0</opf:meta>` +\n `</opf:metadata>` +\n `<opf:manifest>${items}</opf:manifest>` +\n `<opf:spine><opf:itemref idref=\"header\"/><opf:itemref idref=\"section0\"/></opf:spine>` +\n `</opf:package>`\n );\n}\n\n// ─── settings.xml ────────────────────────────────────────────\n\nfunction buildSettingsXml(): string {\n return (\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>` +\n `<ha:HWPApplicationSetting xmlns:ha=\"http://www.hancom.co.kr/hwpml/2011/app\" ` +\n `xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\">` +\n `<ha:CaretPosition listIDRef=\"0\" paraIDRef=\"0\" pos=\"0\"/>` +\n `<config:config-item-set name=\"PrintInfo\">` +\n `<config:config-item name=\"PrintAutoFootNote\" type=\"boolean\">false</config:config-item>` +\n `<config:config-item name=\"PrintAutoHeadNote\" type=\"boolean\">false</config:config-item>` +\n `<config:config-item name=\"PrintMethod\" type=\"short\">4</config:config-item>` +\n `<config:config-item name=\"OverlapSize\" type=\"short\">0</config:config-item>` +\n `<config:config-item name=\"PrintCropMark\" type=\"short\">0</config:config-item>` +\n `<config:config-item name=\"BinderHoleType\" type=\"short\">0</config:config-item>` +\n `<config:config-item name=\"ZoomX\" type=\"short\">100</config:config-item>` +\n `<config:config-item name=\"ZoomY\" type=\"short\">100</config:config-item>` +\n `</config:config-item-set>` +\n `</ha:HWPApplicationSetting>`\n );\n}\n\nfunction buildNumberingsXml(): string {\n return (\n `<hh:numberings itemCnt=\"1\">` +\n `<hh:numbering id=\"1\" start=\"1\">` +\n `<hh:paraHead start=\"1\" level=\"1\" align=\"LEFT\" ` +\n `useInstWidth=\"1\" autoIndent=\"0\" widthAdjust=\"0\" ` +\n `textOffsetType=\"PERCENT\" textOffset=\"50\" ` +\n `numFormat=\"BULLET\" charPrIDRef=\"0\" checkable=\"0\"/>` +\n `</hh:numbering></hh:numberings>`\n );\n}\n\nfunction buildBulletsXml(): string {\n return (\n `<hh:bullets itemCnt=\"1\">` +\n `<hh:bullet id=\"1\" charPrIDRef=\"0\" start=\"1\" numFormat=\"BULLET\">` +\n `<hh:paraHead level=\"1\" numChar=\"•\"/>` +\n `<hh:paraHead level=\"2\" numChar=\"•\"/>` +\n `<hh:paraHead level=\"3\" numChar=\"•\"/>` +\n `</hh:bullet></hh:bullets>`\n );\n}\n\n// ─── header.xml ──────────────────────────────────────────────\n\nfunction buildHeaderXml(dims: PageDims, meta: DocMeta, ctx: HwpxCtx): string {\n // 언어별 폰트 (LangFontBank → XML)\n const fontFacesXml = ctx.fontBank.toXml();\n\n // charPr 목록 — 언어별 폰트 ID를 fontRef에 반영 (ANYTOHWP 핵심 개선)\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 hid = cp.hangulId;\n const lid = cp.latinId;\n const shadeColor = cp.bg ? (cp.bg.startsWith(\"#\") ? cp.bg : `#${cp.bg}`) : \"none\";\n charPrXml +=\n `<hh:charPr id=\"${cp.id}\" height=\"${cp.height}\" textColor=\"${cp.textColor}\" ` +\n `shadeColor=\"${shadeColor}\" useFontSpace=\"0\" useKerning=\"0\" symMark=\"NONE\" borderFillIDRef=\"1\">` +\n `<hh:fontRef hangul=\"${hid}\" latin=\"${lid}\" hanja=\"${hid}\" japanese=\"${hid}\" other=\"${lid}\" symbol=\"${lid}\" user=\"${lid}\"/>` +\n `<hh:ratio hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/>` +\n `<hh:spacing hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>` +\n `<hh:relSz hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/>` +\n `<hh:offset hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>` +\n bold +\n italic +\n `<hh:underline type=\"${cp.underline}\" shape=\"SOLID\" color=\"#000000\"/>` +\n `<hh:strikeout shape=\"${cp.strikeout}\" color=\"#000000\"/>` +\n `<hh:outline type=\"NONE\"/>` +\n `<hh:shadow type=\"NONE\" color=\"#C0C0C0\" offsetX=\"10\" offsetY=\"10\"/>` +\n `</hh:charPr>`;\n }\n\n // paraPr 목록\n let paraPrXml = \"\";\n for (const pp of ctx.paraPrs) {\n paraPrXml +=\n `<hh:paraPr id=\"${pp.id}\" tabPrIDRef=\"0\" condense=\"0\" fontLineHeight=\"0\" snapToGrid=\"0\" suppressLineNumbers=\"0\" checked=\"0\">` +\n `<hh:align horizontal=\"${pp.align}\" vertical=\"BASELINE\"/>` +\n `<hh:heading type=\"NONE\" idRef=\"0\" level=\"0\"/>` +\n `<hh:breakSetting breakLatinWord=\"KEEP_WORD\" breakNonLatinWord=\"BREAK_WORD\" widowOrphan=\"0\" keepWithNext=\"0\" keepLines=\"0\" pageBreakBefore=\"0\" lineWrap=\"BREAK\"/>` +\n `<hh:autoSpacing eAsianEng=\"0\" eAsianNum=\"0\"/>` +\n `<hh:margin>` +\n `<hc:intent value=\"${pp.intentHwp}\" unit=\"HWPUNIT\"/>` +\n `<hc:left value=\"${pp.leftHwp}\" unit=\"HWPUNIT\"/>` +\n `<hc:right value=\"${pp.rightHwp}\" unit=\"HWPUNIT\"/>` +\n `<hc:prev value=\"${pp.prevHwp}\" unit=\"HWPUNIT\"/>` +\n `<hc:next value=\"${pp.nextHwp}\" unit=\"HWPUNIT\"/>` +\n `</hh:margin>` +\n `<hh:lineSpacing type=\"PERCENT\" value=\"${pp.lineSpacing}\" unit=\"HWPUNIT\"/>` +\n `<hh:border borderFillIDRef=\"1\" offsetLeft=\"0\" offsetRight=\"0\" offsetTop=\"0\" offsetBottom=\"0\" connect=\"0\" ignoreMargin=\"0\"/>` +\n `</hh:paraPr>`;\n }\n\n // borderFill 목록 (BorderFillBank → XML)\n const borderFillXml = ctx.borderFillBank.toXml();\n\n // 스타일 목록\n const stylesXml =\n `<hh:styles itemCnt=\"${ctx.hwpxStyles.length}\">` +\n ctx.hwpxStyles\n .map(\n (s) =>\n `<hh:style id=\"${s.id}\" type=\"PARA\" name=\"${esc(s.name)}\" engName=\"${esc(s.engName)}\" ` +\n `paraPrIDRef=\"${s.paraPrIDRef}\" charPrIDRef=\"${s.charPrIDRef}\" nextStyleIDRef=\"0\" langID=\"1042\" lockForm=\"0\"/>`,\n )\n .join(\"\") +\n `</hh:styles>`;\n\n return (\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>` +\n `<hh:head ${NS} version=\"1.2\" secCnt=\"1\">` +\n `<hh:beginNum page=\"1\" footnote=\"1\" endnote=\"1\" pic=\"1\" tbl=\"1\" equation=\"1\"/>` +\n `<hh:refList>` +\n fontFacesXml +\n borderFillXml +\n `<hh:charProperties itemCnt=\"${ctx.charPrs.length}\">${charPrXml}</hh:charProperties>` +\n `<hh:tabProperties itemCnt=\"1\"><hh:tabPr id=\"0\" autoTabLeft=\"0\" autoTabRight=\"0\"/></hh:tabProperties>` +\n buildNumberingsXml() +\n buildBulletsXml() +\n `<hh:paraProperties itemCnt=\"${ctx.paraPrs.length}\">${paraPrXml}</hh:paraProperties>` +\n stylesXml +\n `</hh:refList>` +\n `<hh:compatibleDocument targetProgram=\"MS_WORD\"> \n <hh:layoutCompatibility>\n <hh:applyFontWeightToBold />\n <hh:useInnerUnderline />\n <hh:useLowercaseStrikeout />\n <hh:extendLineheightToOffset />\n <hh:treatQuotationAsLatin />\n <hh:doNotAlignWhitespaceOnRight />\n <hh:doNotAdjustWordInJustify />\n <hh:baseCharUnitOnEAsian />\n <hh:baseCharUnitOfIndentOnFirstChar />\n <hh:adjustLineheightToFont />\n <hh:adjustBaselineInFixedLinespacing />\n <hh:applyPrevspacingBeneathObject />\n <hh:applyNextspacingOfLastPara />\n <hh:adjustParaBorderfillToSpacing />\n <hh:connectParaBorderfillOfEqualBorder />\n <hh:adjustParaBorderOffsetWithBorder />\n <hh:extendLineheightToParaBorderOffset />\n <hh:applyParaBorderToOutside />\n <hh:applyMinColumnWidthTo1mm />\n <hh:applyTabPosBasedOnSegment />\n <hh:breakTabOverLine />\n <hh:adjustVertPosOfLine />\n <hh:doNotAlignLastForbidden />\n <hh:adjustMarginFromAdjustLineheight />\n <hh:baseLineSpacingOnLineGrid />\n <hh:applyCharSpacingToCharGrid />\n <hh:doNotApplyGridInHeaderFooter />\n <hh:applyExtendHeaderFooterEachSection />\n <hh:doNotApplyLinegridAtNoLinespacing />\n <hh:doNotAdjustEmptyAnchorLine />\n <hh:overlapBothAllowOverlap />\n <hh:extendVertLimitToPageMargins />\n <hh:doNotHoldAnchorOfTable />\n <hh:doNotFormattingAtBeneathAnchor />\n <hh:adjustBaselineOfObjectToBottom />\n </hh:layoutCompatibility>\n </hh:compatibleDocument>` +\n `<hh:docOption><hh:linkinfo path=\"\" pageInherit=\"0\" footnoteInherit=\"0\"/></hh:docOption>` +\n `<hh:trackchageConfig flags=\"56\"/>` +\n `</hh:head>`\n );\n}\n\n// ─── section0.xml ────────────────────────────────────────────\n\nfunction buildHeaderFooterRunXml(\n sheet: SheetNode,\n dims: PageDims,\n ctx: HwpxCtx,\n): string {\n const headers = sheet.headers || {};\n const footers = sheet.footers || {};\n const hasAny = Object.keys(headers).length > 0 || Object.keys(footers).length > 0;\n if (!hasAny) return \"\";\n\n const availW = ctx.availableWidth;\n const mtHwp = Metric.ptToHwp(dims.mt);\n const mbHwp = Metric.ptToHwp(dims.mb);\n const headerZoneH = dims.headerPt ? Math.max(100, mtHwp - Metric.ptToHwp(dims.headerPt)) : 3600;\n const footerZoneH = dims.footerPt ? Math.max(100, mbHwp - Metric.ptToHwp(dims.footerPt)) : 3600;\n\n let inner = \"\";\n\n // 1. 첫 페이지 숨김 설정 (first 헤더/푸터가 있으면 활성화)\n const hideFirst = !!(headers.first || footers.first);\n inner += `<hp:ctrl><hp:pageHiding hideHeader=\"${hideFirst ? 1 : 0}\" hideFooter=\"${hideFirst ? 1 : 0}\" hideMasterPage=\"0\" hideBorder=\"0\" hideFill=\"0\" hidePageNum=\"0\"/></hp:ctrl>`;\n\n // 2. 헤더들 생성\n for (const [type, paras] of Object.entries(headers)) {\n const applyPageType = type === \"even\" ? \"EVEN\" : (type === \"default\" || type === \"first\" ? \"BOTH\" : \"ODD\");\n const savedId = ctx.nextElementId;\n ctx.nextElementId = 0;\n const parasXml = paras.map((p) => encodeParaPositioned(p, ctx, 0, \"\", availW).xml).join(\"\");\n ctx.nextElementId = savedId;\n inner +=\n `<hp:ctrl>` +\n `<hp:header id=\"1\" applyPageType=\"${applyPageType}\">` +\n `<hp:subList id=\"\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"TOP\" ` +\n `linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"${availW}\" textHeight=\"${headerZoneH}\" ` +\n `hasTextRef=\"0\" hasNumRef=\"0\">` +\n parasXml +\n `</hp:subList>` +\n `</hp:header>` +\n `</hp:ctrl>`;\n }\n\n // 3. 푸터들 생성\n for (const [type, paras] of Object.entries(footers)) {\n const applyPageType = type === \"even\" ? \"EVEN\" : (type === \"default\" || type === \"first\" ? \"BOTH\" : \"ODD\");\n const savedId = ctx.nextElementId;\n ctx.nextElementId = 0;\n const parasXml = paras.map((p) => encodeParaPositioned(p, ctx, 0, \"\", availW).xml).join(\"\");\n ctx.nextElementId = savedId;\n inner +=\n `<hp:ctrl>` +\n `<hp:footer id=\"2\" applyPageType=\"${applyPageType}\">` +\n `<hp:subList id=\"\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"BOTTOM\" ` +\n `linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"${availW}\" textHeight=\"${footerZoneH}\" ` +\n `hasTextRef=\"0\" hasNumRef=\"0\">` +\n parasXml +\n `</hp:subList>` +\n `</hp:footer>` +\n `</hp:ctrl>`;\n }\n\n return `<hp:run charPrIDRef=\"0\" charTcId=\"0\">${inner}</hp:run>`;\n}\n\nfunction buildSectionXml(\n sheet: SheetNode | undefined,\n dims: PageDims,\n ctx: HwpxCtx,\n): string {\n const secPrXml = buildSecPrXml(dims);\n const kids = sheet?.kids ?? [];\n const hfRunXml = sheet ? buildHeaderFooterRunXml(sheet, dims, ctx) : \"\";\n\n // 가용 너비 계산 (HWPUNIT)\n const availWidth = Math.max(\n 1000,\n Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr),\n );\n ctx.availableWidth = availWidth;\n\n let contentXml = \"\";\n let vertPos = 0;\n\n for (let i = 0; i < kids.length; i++) {\n const kid = kids[i];\n const isFirst = i === 0;\n const curSecPr = isFirst ? secPrXml : \"\";\n const curHfRun = isFirst ? hfRunXml : \"\";\n\n if (kid.tag === \"para\") {\n const { xml, nextVertPos } = encodeParaPositioned(\n kid,\n ctx,\n vertPos,\n curSecPr,\n availWidth,\n curHfRun,\n );\n contentXml += xml;\n vertPos = nextVertPos;\n } else if (kid.tag === \"grid\") {\n const { xml, nextVertPos } = encodeGridPositioned(\n kid,\n ctx,\n vertPos,\n curSecPr,\n curHfRun,\n );\n contentXml += xml;\n vertPos = nextVertPos;\n }\n }\n\n if (kids.length === 0) {\n // 빈 문서 — 최소 단락 1개 필수\n const fs = 1000;\n const vs = 1600;\n const { xml: linesegXml } = buildLinesegarray(\" \", 0, fs, vs / (fs / 100), availWidth);\n contentXml =\n `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"0\" styleIDRef=\"0\" pageBreak=\"0\" columnBreak=\"0\" merged=\"0\" paraTcId=\"0\">` +\n secPrXml +\n hfRunXml +\n `<hp:run charPrIDRef=\"0\" charTcId=\"0\"><hp:t xml:space=\"preserve\"> </hp:t></hp:run>` +\n linesegXml +\n `</hp:p>`;\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><hs:sec ${NS} xmlns:hwpunitchar=\"http://www.hancom.co.kr/hwpml/2016/HwpUnitChar\">${contentXml}</hs:sec>`;\n}\n\nfunction buildSecPrXml(dims: PageDims): string {\n const wHwp = Metric.ptToHwp(dims.wPt);\n const hHwp = Metric.ptToHwp(dims.hPt);\n const ml = Metric.ptToHwp(dims.ml);\n const mr = Metric.ptToHwp(dims.mr);\n const mt = Metric.ptToHwp(dims.mt);\n const mb = Metric.ptToHwp(dims.mb);\n // HWPX margin header/footer = header/footer ZONE HEIGHT (not distance from paper edge)\n // = top_hwp - header_from_top_hwp (and bottom_hwp - footer_from_bottom_hwp)\n const headerZone = dims.headerPt\n ? Math.max(0, mt - Metric.ptToHwp(dims.headerPt))\n : 0;\n const footerZone = dims.footerPt\n ? Math.max(0, mb - Metric.ptToHwp(dims.footerPt))\n : 0;\n\n const pageBorderFill =\n `<hp:pageBorderFill type=\"BOTH\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\">` +\n `<hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/>` +\n `</hp:pageBorderFill>` +\n `<hp:pageBorderFill type=\"EVEN\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\">` +\n `<hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/>` +\n `</hp:pageBorderFill>` +\n `<hp:pageBorderFill type=\"ODD\" borderFillIDRef=\"1\" textBorder=\"PAPER\" headerInside=\"0\" footerInside=\"0\" fillArea=\"PAPER\">` +\n `<hp:offset left=\"1417\" right=\"1417\" top=\"1417\" bottom=\"1417\"/>` +\n `</hp:pageBorderFill>`;\n\n return (\n `<hp:secPr id=\"0\" textDirection=\"HORIZONTAL\" spaceColumns=\"1134\" tabStop=\"8000\" outlineShapeIDRef=\"0\" memoShapeIDRef=\"0\" textVerticalWidthHead=\"0\" masterPageCnt=\"0\">` +\n `<hp:grid lineGrid=\"0\" charGrid=\"0\" wonggojiFormat=\"0\"/>` +\n `<hp:startNum pageStartsOn=\"BOTH\" page=\"0\" pic=\"0\" tbl=\"0\" equation=\"0\"/>` +\n `<hp:visibility hideFirstHeader=\"0\" hideFirstFooter=\"0\" hideFirstMasterPage=\"0\" border=\"SHOW_ALL\" fill=\"SHOW_ALL\" hideFirstPageNum=\"0\" hideFirstEmptyLine=\"0\" showLineNumber=\"0\"/>` +\n `<hp:lineNumberShape restartType=\"0\" countBy=\"0\" distance=\"0\" startNumber=\"0\"/>` +\n `<hp:pagePr landscape=\"${dims.wPt >= dims.hPt ? 'WIDELY' : 'NARROWLY'}\" width=\"${wHwp}\" height=\"${hHwp}\" gutterType=\"LEFT_ONLY\">` +\n `<hp:margin header=\"${headerZone}\" footer=\"${footerZone}\" gutter=\"0\" left=\"${ml}\" right=\"${mr}\" top=\"${mt}\" bottom=\"${mb}\"/>` +\n `</hp:pagePr>` +\n `<hp:colPr id=\"\" type=\"NEWSPAPER\" layout=\"LEFT\" colCount=\"1\" sameSz=\"1\" sameGap=\"0\"/>` +\n `<hp:footNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\"\" supscript=\"1\"/>` +\n `<hp:noteLine length=\"-1\" type=\"SOLID\" width=\"0.25 mm\" color=\"#000000\"/>` +\n `<hp:noteSpacing betweenNotes=\"283\" belowLine=\"0\" aboveLine=\"1000\"/>` +\n `<hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/>` +\n `<hp:placement place=\"EACH_COLUMN\" beneathText=\"0\"/>` +\n `</hp:footNotePr>` +\n `<hp:endNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\"\" supscript=\"1\"/>` +\n `<hp:noteLine length=\"-1\" type=\"SOLID\" width=\"0.25 mm\" color=\"#000000\"/>` +\n `<hp:noteSpacing betweenNotes=\"0\" belowLine=\"0\" aboveLine=\"1000\"/>` +\n `<hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/>` +\n `<hp:placement place=\"END_OF_DOCUMENT\" beneathText=\"0\"/>` +\n `</hp:endNotePr>` +\n pageBorderFill +\n `</hp:secPr>`\n );\n}\n\n// ─── 줄 정보 XML (linesegarray) ──────────────────────────────\n// 가이드 준수: 실제 시각적 줄 단위로 lineseg 생성\n\nfunction buildLinesegarray(\n text: string,\n vertPosStart: number,\n fontSize: number,\n lineSpacingPct: number,\n horzSize: number,\n): { xml: string; totalHeight: number } {\n const vertsizeLine = Math.round((fontSize * lineSpacingPct) / 100);\n const spacing = vertsizeLine - fontSize;\n const baseline = Math.round(fontSize * 0.83);\n\n // 글자 너비 추정 (영문 0.47, 한글 1.0)\n const isKorean = /[\\uAC00-\\uD7A3\\u3131-\\u318E]/.test(text);\n const charW = isKorean ? fontSize : Math.round(fontSize * 0.47);\n const charsPerLine = Math.max(1, Math.floor(horzSize / charW));\n const lineCount = text.length === 0 ? 1 : Math.ceil(text.length / charsPerLine);\n\n // 성능 최적화: 문자열 병합 대신 배열 수집 후 join 사용 (O(n²) → O(n))\n const linesegParts: string[] = [];\n for (let i = 0; i < lineCount; i++) {\n const flags = i === 0 ? LINESEG_FLAGS_FIRST : LINESEG_FLAGS_OTHER;\n linesegParts.push(\n `<hp:lineseg textpos=\"${i * charsPerLine}\" ` +\n `vertpos=\"${vertPosStart + i * vertsizeLine}\" ` +\n `vertsize=\"${vertsizeLine}\" textheight=\"${fontSize}\" ` +\n `baseline=\"${baseline}\" spacing=\"${spacing}\" ` +\n `horzpos=\"0\" horzsize=\"${horzSize}\" ` +\n `flags=\"${flags}\"/>`,\n );\n }\n\n return {\n xml: `<hp:linesegarray>${linesegParts.join(\"\")}</hp:linesegarray>`,\n totalHeight: lineCount * vertsizeLine,\n };\n}\n\n/** 단락에서 순수 텍스트 추출 (줄바꿈 계산용) */\nfunction extractParaText(para: ParaNode): string {\n let text = \"\";\n const walk = (kids: any[]) => {\n for (const k of kids) {\n if (k.tag === \"span\") {\n for (const c of k.kids) if (c.tag === \"txt\") text += c.content;\n } else if (k.tag === \"link\") {\n walk(k.kids);\n }\n }\n };\n walk(para.kids);\n return text;\n}\n\nfunction fontSizeForPara(para: ParaNode, ctx: HwpxCtx): number {\n for (const kid of para.kids) {\n if (kid.tag === \"span\") {\n const id = ctx.charPrMap.get(charPrKey(kid.props));\n if (id !== undefined && ctx.charPrs[id]) return ctx.charPrs[id].height;\n }\n }\n return 1000; // 기본 10pt\n}\n\n// ─── 단락 인코딩 ─────────────────────────────────────────────\n\nfunction encodeParaPositioned(\n para: ParaNode,\n ctx: HwpxCtx,\n vertPos: number,\n secPr = \"\",\n availWidth?: number,\n hfRun = \"\",\n): { xml: string; nextVertPos: number } {\n // ✅ 표(Grid)를 포함하는 단락인지 확인\n const gridKid = para.kids.find((k): k is GridNode => k.tag === \"grid\");\n if (gridKid) {\n return encodeTablePara(para, gridKid, ctx, vertPos, secPr, hfRun);\n }\n\n const paraPrId = ctx.paraPrMap.get(paraPrKey(para.props)) ?? 0;\n const styleIDRef = para.props.styleId\n ? (ctx.styleIdToHwpxId.get(para.props.styleId) ?? 0)\n : 0;\n const fontSize = fontSizeForPara(para, ctx);\n const paraPr = ctx.paraPrs[paraPrId];\n const lineSpacing = paraPr?.lineSpacing ?? 160;\n const spacing = Math.max(0, Math.round(fontSize * (lineSpacing / 100 - 1)));\n let vertSize = fontSize + spacing;\n const horzSize = availWidth ?? ctx.availableWidth;\n\n // 코드 블록 감지 (Courier 폰트 또는 styleId \"code\")\n const isCourierFont = (kids: ParaNode[\"kids\"]): boolean =>\n kids.some(\n (k) =>\n (k.tag === \"span\" && k.props.font?.toLowerCase().includes(\"courier\")) ||\n (k.tag === \"link\" &&\n isCourierFont((k as LinkNode).kids as ParaNode[\"kids\"])),\n );\n const isCode =\n availWidth === undefined &&\n (para.props.styleId?.toLowerCase().includes(\"code\") ||\n isCourierFont(para.kids));\n\n if (isCode)\n return encodeCodeBlockPositioned(\n para,\n ctx,\n vertPos,\n secPr,\n fontSize,\n spacing,\n vertSize,\n );\n\n let runsXml = encodeParaKids(para.kids, ctx);\n if (!runsXml) runsXml = `<hp:run charPrIDRef=\"0\" charTcId=\"0\"><hp:t xml:space=\"preserve\"> </hp:t></hp:run>`;\n\n const paraText = extractParaText(para);\n const { xml: linesegXml, totalHeight } = buildLinesegarray(\n paraText,\n vertPos,\n fontSize,\n lineSpacing,\n horzSize,\n );\n\n const hasPageBreak = para.kids.some(\n (k) => k.tag === \"span\" && k.kids.some((c) => c.tag === \"pb\"),\n );\n\n const xml =\n `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"${paraPrId}\" styleIDRef=\"${styleIDRef}\" ` +\n `pageBreak=\"${hasPageBreak ? 1 : 0}\" columnBreak=\"0\" merged=\"0\" paraTcId=\"0\">` +\n secPr +\n hfRun +\n runsXml +\n linesegXml +\n `</hp:p>`;\n\n return { xml, nextVertPos: vertPos + totalHeight };\n}\n\n/** ✅ 가이드 준수: 표를 포함하는 단락 인코딩 */\nfunction encodeTablePara(\n para: ParaNode,\n grid: GridNode,\n ctx: HwpxCtx,\n vertPos: number,\n secPr: string,\n hfRun: string,\n): { xml: string; nextVertPos: number } {\n const paraPrId = ctx.paraPrMap.get(paraPrKey(para.props)) ?? 0;\n \n // 표 알맹이 생성 (기존 로직 재사용)\n const { xml: gridXml, height: tblHeight } = buildGridXml(grid, ctx);\n \n // 가이드: 표 단락의 lineseg는 1개여야 하고, vertsize는 표 전체 높이여야 함\n const fontSize = 1000; \n const totalHeight = Math.max(1600, tblHeight);\n const baseline = 850;\n const spacing = Math.max(0, totalHeight - fontSize);\n\n const linesegXml =\n `<hp:linesegarray>` +\n `<hp:lineseg textpos=\"0\" vertpos=\"${vertPos}\" vertsize=\"${totalHeight}\" ` +\n `textheight=\"${fontSize}\" baseline=\"${baseline}\" spacing=\"${spacing}\" ` +\n `horzpos=\"0\" horzsize=\"${ctx.availableWidth}\" flags=\"1441792\"/>` +\n `</hp:linesegarray>`;\n\n const xml =\n `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"${paraPrId}\" styleIDRef=\"0\" ` +\n `pageBreak=\"0\" columnBreak=\"0\" merged=\"0\" paraTcId=\"0\">` +\n secPr +\n gridXml +\n hfRun +\n linesegXml +\n `</hp:p>`;\n\n return { xml, nextVertPos: vertPos + totalHeight };\n}\n\nfunction encodeCodeBlockPositioned(\n para: ParaNode,\n ctx: HwpxCtx,\n vertPos: number,\n secPr: string,\n fontSize: number,\n spacing: number,\n vertSize: number,\n): { xml: string; nextVertPos: number } {\n const codeBfId = ctx.borderFillBank.addUniform(\n { kind: \"solid\", pt: 0.5, color: \"aaaaaa\" },\n \"f4f4f4\",\n );\n const cellW = ctx.availableWidth;\n const innerW = Math.max(cellW - 510, 100);\n const subListId = ctx.nextElementId++;\n const { xml: innerXml } = encodeParaPositioned(para, ctx, 0, \"\", innerW);\n\n const paraText = extractParaText(para);\n const { xml: linesegXml, totalHeight } = buildLinesegarray(\n paraText,\n vertPos,\n fontSize,\n 160, // 코드 블록 기본 줄간격 160%\n ctx.availableWidth,\n );\n\n const xml =\n `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"0\" styleIDRef=\"0\" paraTcId=\"0\">` +\n secPr +\n `<hp:run charPrIDRef=\"0\" charTcId=\"0\">` +\n `<hp:tbl id=\"${ctx.nextElementId++}\" zOrder=\"0\" numberingType=\"TABLE\" textWrap=\"TOP_AND_BOTTOM\" textFlow=\"BOTH_SIDES\" lock=\"0\" dropcapstyle=\"None\" pageBreak=\"NONE\" rowCnt=\"1\" colCnt=\"1\" cellSpacing=\"0\" borderFillIDRef=\"${codeBfId}\" noAdjust=\"0\">` +\n `<hp:sz width=\"${cellW}\" widthRelTo=\"ABSOLUTE\" height=\"0\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/>` +\n `<hp:pos treatAsChar=\"1\" affectLSpacing=\"0\" flowWithText=\"1\" allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" vertAlign=\"TOP\" horzAlign=\"LEFT\" vertOffset=\"0\" horzOffset=\"0\"/>` +\n `<hp:outMargin left=\"138\" right=\"138\" top=\"138\" bottom=\"138\"/>` +\n `<hp:inMargin left=\"138\" right=\"138\" top=\"138\" bottom=\"138\"/>` +\n `<hp:tr><hp:tc name=\"\" header=\"0\" hasMargin=\"1\" protect=\"0\" editable=\"0\" dirty=\"0\" borderFillIDRef=\"${codeBfId}\">` +\n `<hp:subList id=\"${subListId}\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"CENTER\" linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"0\" textHeight=\"0\" hasTextRef=\"0\" hasNumRef=\"0\">` +\n innerXml +\n `</hp:subList>` +\n `<hp:cellAddr colAddr=\"0\" rowAddr=\"0\"/>` +\n `<hp:cellSpan colSpan=\"1\" rowSpan=\"1\"/>` +\n `<hp:cellSz width=\"${cellW}\" height=\"0\"/>` +\n `<hp:cellMargin left=\"283\" right=\"283\" top=\"141\" bottom=\"141\"/>` +\n `</hp:tc></hp:tr></hp:tbl><hp:t xml:space=\"preserve\"> </hp:t></hp:run>` +\n linesegXml +\n `</hp:p>`;\n\n return { xml, nextVertPos: vertPos + totalHeight };\n}\n\nfunction encodeParaKids(kids: ParaNode[\"kids\"], ctx: HwpxCtx): string {\n let xml = \"\";\n let currentRunCharPrId: number | null = null;\n let currentRunContent = \"\";\n\n const flushRun = () => {\n if (currentRunCharPrId !== null) {\n // 내용이 없더라도 빈 hp:t를 생성하여 '텍스트 없음' 오류 방지\n const content = currentRunContent || `<hp:t xml:space=\"preserve\"> </hp:t>`;\n xml += `<hp:run charPrIDRef=\"${currentRunCharPrId}\" charTcId=\"0\">${content}</hp:run>`;\n }\n currentRunCharPrId = null;\n currentRunContent = \"\";\n };\n\n for (const kid of kids) {\n if (kid.tag === \"span\") {\n const span = kid as SpanNode;\n const charPrId = ctx.charPrMap.get(charPrKey(span.props)) ?? 0;\n \n if (currentRunCharPrId !== null && currentRunCharPrId !== charPrId) {\n flushRun();\n }\n \n currentRunCharPrId = charPrId;\n currentRunContent += encodeRunInner(span);\n } \n else if (kid.tag === \"link\") {\n const link = kid as LinkNode;\n // 링크의 첫 번째 span 스타일을 기준으로 함\n let charPrId = 0;\n if (link.kids.length > 0 && link.kids[0].tag === \"span\") {\n charPrId = ctx.charPrMap.get(charPrKey((link.kids[0] as SpanNode).props)) ?? 0;\n }\n\n if (currentRunCharPrId !== null && currentRunCharPrId !== charPrId) {\n flushRun();\n }\n\n currentRunCharPrId = charPrId;\n currentRunContent += encodeLinkInner(link, ctx);\n }\n else if (kid.tag === \"img\") {\n flushRun();\n xml += encodeImgWrapped(kid, ctx);\n }\n }\n\n flushRun();\n return xml;\n}\n\n/** hp:run 내부의 태그들만 생성 (span용) */\nfunction encodeRunInner(span: SpanNode): string {\n let xml = \"\";\n for (const kid of span.kids) {\n if (kid.tag === \"txt\") {\n const content = esc(kid.content);\n if (content) xml += `<hp:t xml:space=\"preserve\">${content}</hp:t>`;\n } else if (kid.tag === \"br\") {\n xml += `<hp:t xml:space=\"preserve\">\\n</hp:t>`;\n } else if (kid.tag === \"pagenum\") {\n const fmt = (kid as any).format === \"roman\" ? \"ROMAN_LOWER\" \n : (kid as any).format === \"romanCaps\" ? \"ROMAN_UPPER\" : \"DIGIT\";\n xml += `<hp:pageNum pageStartsOn=\"BOTH\" formatType=\"${fmt}\"/>`;\n }\n }\n return xml;\n}\n\n/** hp:run 내부의 태그들만 생성 (link용) */\nfunction encodeLinkInner(link: LinkNode, ctx: HwpxCtx): string {\n const fieldId = 600000000 + (ctx.nextElementId++ % 100000000);\n const instanceId = 2100000000 + (ctx.nextElementId++ % 100000000);\n const url = link.href;\n\n let xml = `<hp:ctrl>` +\n `<hp:fieldBegin id=\"${instanceId}\" type=\"HYPERLINK\" name=\"\" editable=\"0\" dirty=\"1\" zorder=\"-1\" fieldid=\"${fieldId}\">` +\n `<hp:parameters cnt=\"6\" name=\"\">` +\n `<hp:integerParam name=\"Prop\">0</hp:integerParam>` +\n `<hp:stringParam name=\"Command\">${esc(url.replace(/:/g, \"\\\\:\"))};1;5;-1;</hp:stringParam>` +\n `<hp:stringParam name=\"Path\">${esc(url)}</hp:stringParam>` +\n `<hp:stringParam name=\"Category\">HWPHYPERLINK_TYPE_URL</hp:stringParam>` +\n `<hp:stringParam name=\"TargetType\">HWPHYPERLINK_TARGET_HYPERLINK</hp:stringParam>` +\n `<hp:stringParam name=\"DocOpenType\">HWPHYPERLINK_JUMP_DONTCARE</hp:stringParam>` +\n `</hp:parameters>` +\n `</hp:fieldBegin>` +\n `</hp:ctrl>`;\n\n for (const kid of link.kids) {\n if (kid.tag === \"span\") {\n xml += encodeRunInner(kid as SpanNode);\n }\n }\n\n xml += `<hp:ctrl><hp:fieldEnd beginIDRef=\"${instanceId}\"/></hp:ctrl>`;\n return xml;\n}\n\n// ─── 이미지 인코딩 (ANYTOHWP 영감: 픽셀 치수 추출) ──────────\n\nconst WRAP_MAP: 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};\nconst FLOW_MAP: 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};\n\nfunction encodeImage(img: ImgNode, ctx: HwpxCtx): string {\n // 0. 플레이스홀더 처리 (차트 등 b64가 없는 경우)\n if (!img.b64) {\n return `<hp:t xml:space=\"preserve\">${esc(img.alt || \"[개체]\")}</hp:t>`;\n }\n\n const binId = ctx.imgMap.get(img);\n if (!binId) return \"\";\n\n // ANYTOHWP 영감: PNG/JPEG 바이너리 헤더에서 실제 픽셀 치수 추출\n // img.w / img.h는 pt 단위이지만, 이미지 실제 픽셀을 HWPUNIT으로 변환하면 더 정확\n const pixelDims = readPixelDims(img.b64, img.mime);\n let wHwp: number, hHwp: number;\n\n if (pixelDims && pixelDims.w > 0 && pixelDims.h > 0) {\n // 픽셀 → pt (96dpi 기준) → HWPUNIT\n wHwp = Metric.ptToHwp((pixelDims.w * 72) / 96);\n hHwp = Metric.ptToHwp((pixelDims.h * 72) / 96);\n } else {\n wHwp = Metric.ptToHwp(img.w);\n hHwp = Metric.ptToHwp(img.h);\n }\n\n // 가용 너비 초과 방지 (비율 유지)\n if (wHwp > ctx.availableWidth) {\n hHwp = Math.round((hHwp * ctx.availableWidth) / wHwp);\n wHwp = ctx.availableWidth;\n }\n\n // 회전 중심점 (rotation center) 계산: 이미지 중앙을 기준으로 회전\n const rotationCenterX = Math.round(wHwp / 2);\n const rotationCenterY = Math.round(hHwp / 2);\n\n const layout = img.layout;\n const isInline = !layout || layout.wrap === \"inline\";\n const textWrap = layout ? (WRAP_MAP[layout.wrap] ?? \"SQUARE\") : \"SQUARE\";\n const textFlow = layout\n ? (FLOW_MAP[layout.wrap] ?? \"BOTH_SIDES\")\n : \"BOTH_SIDES\";\n const zOrder = ctx.nextZOrder++;\n\n return (\n `<hp:pic id=\"${ctx.nextElementId++}\" zOrder=\"${zOrder}\" numberingType=\"PICTURE\" ` +\n `textWrap=\"${textWrap}\" textFlow=\"${textFlow}\" lock=\"0\" dropcapstyle=\"None\" href=\"\" groupLevel=\"0\" instid=\"0\" reverse=\"0\">` +\n `<hp:offset x=\"0\" y=\"0\"/>` +\n `<hp:orgSz width=\"${wHwp}\" height=\"${hHwp}\"/>` +\n `<hp:curSz width=\"${wHwp}\" height=\"${hHwp}\"/>` +\n `<hp:flip horizontal=\"0\" vertical=\"0\"/>` +\n `<hp:rotationInfo angle=\"0\" centerX=\"${rotationCenterX}\" centerY=\"${rotationCenterY}\" rotateimage=\"1\"/>` +\n `<hp:renderingInfo>` +\n `<hc:transMatrix e1=\"1\" e2=\"0\" e3=\"0\" e4=\"0\" e5=\"1\" e6=\"0\"/>` +\n `<hc:scaMatrix e1=\"1\" e2=\"0\" e3=\"0\" e4=\"0\" e5=\"1\" e6=\"0\"/>` +\n `<hc:rotMatrix e1=\"1\" e2=\"0\" e3=\"0\" e4=\"0\" e5=\"1\" e6=\"0\"/>` +\n `</hp:renderingInfo>` +\n `<hp:imgRect>` +\n `<hc:pt0 x=\"0\" y=\"0\"/><hc:pt1 x=\"${wHwp}\" y=\"0\"/>` +\n `<hc:pt2 x=\"${wHwp}\" y=\"${hHwp}\"/><hc:pt3 x=\"0\" y=\"${hHwp}\"/>` +\n `</hp:imgRect>` +\n `<hp:imgClip left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/>` +\n `<hp:inMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/>` +\n `<hp:imgDim dimwidth=\"${wHwp}\" dimheight=\"${hHwp}\"/>` +\n `<hc:img binaryItemIDRef=\"${binId}\" bright=\"0\" contrast=\"0\" effect=\"REAL_PIC\" alpha=\"0\"/>` +\n `<hp:effects/>` +\n `<hp:sz width=\"${wHwp}\" widthRelTo=\"ABSOLUTE\" height=\"${hHwp}\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/>` +\n `<hp:pos treatAsChar=\"${isInline ? 1 : 0}\" affectLSpacing=\"0\" flowWithText=\"1\" ` +\n `allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" ` +\n `vertAlign=\"TOP\" horzAlign=\"LEFT\" vertOffset=\"0\" horzOffset=\"0\"/>` +\n `<hp:outMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/>` +\n `</hp:pic>`\n );\n}\n\nfunction encodeImgWrapped(img: ImgNode, ctx: HwpxCtx): string {\n const content = encodeImage(img, ctx);\n if (!img.b64) {\n return `<hp:run charPrIDRef=\"0\" charTcId=\"0\">${content}</hp:run>`;\n }\n return `<hp:run charPrIDRef=\"0\" charTcId=\"0\">${content}<hp:t xml:space=\"preserve\"> </hp:t></hp:run>`;\n}\n\n// ─── 표(Grid) 인코딩 ─────────────────────────────────────────\n\nfunction encodeGridPositioned(\n grid: GridNode,\n ctx: HwpxCtx,\n vertPos: number,\n secPr = \"\",\n hfRun = \"\",\n): { xml: string; nextVertPos: number } {\n const { xml: gridXml, height: tblHeight } = buildGridXml(grid, ctx);\n const totalHeight = Math.max(1600, tblHeight);\n const fontSize = 1000;\n const baseline = Math.round(fontSize * 0.83);\n const spacing = Math.max(0, totalHeight - fontSize);\n\n const linesegXml =\n `<hp:linesegarray>` +\n `<hp:lineseg textpos=\"0\" vertpos=\"${vertPos}\" vertsize=\"${totalHeight}\" ` +\n `textheight=\"${fontSize}\" baseline=\"${baseline}\" spacing=\"${spacing}\" ` +\n `horzpos=\"0\" horzsize=\"${ctx.availableWidth}\" flags=\"${LINESEG_FLAGS_FIRST}\"/>` +\n `</hp:linesegarray>`;\n\n const xml =\n `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"0\" styleIDRef=\"0\" pageBreak=\"0\" columnBreak=\"0\" merged=\"0\" paraTcId=\"0\">` +\n secPr +\n hfRun +\n gridXml +\n linesegXml +\n `</hp:p>`;\n\n return { xml, nextVertPos: vertPos + totalHeight };\n}\nfunction buildGridXml(\n grid: GridNode,\n ctx: HwpxCtx,\n): { xml: string; height: number } {\n const rowCount = grid.kids.length;\n // ... (기존 tableMap 생성 로직 동일)\n\n // 가상 2D 맵 — 병합 셀 처리\n interface CellEntry {\n type: \"real\" | \"absorbed\";\n cell?: CellNode;\n }\n const tableMap: CellEntry[][] = Array.from({ length: rowCount }, () => []);\n\n for (let ri = 0; ri < rowCount; ri++) {\n let ci = 0;\n for (const cell of grid.kids[ri].kids) {\n while (tableMap[ri][ci]) ci++;\n tableMap[ri][ci] = { type: \"real\", cell };\n for (let rr = 0; rr < cell.rs; rr++) {\n const tri = ri + rr;\n if (tri >= rowCount) break;\n for (let cc = 0; cc < cell.cs; cc++) {\n if (rr === 0 && cc === 0) continue;\n tableMap[tri][ci + cc] = { type: \"absorbed\" };\n }\n }\n ci += cell.cs;\n }\n }\n\n let colCount = 0;\n for (let ri = 0; ri < rowCount; ri++)\n colCount = Math.max(colCount, tableMap[ri].length);\n if (colCount === 0) colCount = 1;\n\n // 컬럼 너비 계산 (Bug 6: 균등 배분 금지, 원본 보존)\n const totalW = ctx.availableWidth;\n const colWidths: number[] = [];\n\n if (grid.props.colWidths && grid.props.colWidths.length === colCount) {\n // pt -> HWPUNIT 변환하여 원본 값 보존\n for (const wPt of grid.props.colWidths) {\n colWidths.push(Metric.ptToHwp(wPt));\n }\n } else {\n // 너비 정보가 없을 때만 균등 배분\n const defW = Math.round(totalW / colCount);\n for (let c = 0; c < colCount; c++) colWidths.push(defW);\n }\n\n // 본문 너비 초과 시에만 비율 축소 보정\n const rawTotal = colWidths.reduce((s, w) => s + w, 0);\n if (rawTotal > totalW && rawTotal > 0) {\n const scale = totalW / rawTotal;\n for (let i = 0; i < colWidths.length; i++) {\n colWidths[i] = Math.max(100, Math.round(colWidths[i] * scale));\n }\n }\n const actualTotal = colWidths.reduce((s, w) => s + w, 0);\n\n // 행 높이 계산\n const rowHeights: number[] = [];\n for (let ri = 0; ri < rowCount; ri++) {\n if (\n grid.kids[ri].heightPt != null &&\n (grid.kids[ri].heightPt as number) > 0\n ) {\n rowHeights.push(Metric.ptToHwp(grid.kids[ri].heightPt as number));\n } else {\n let maxH = 0;\n for (let ci = 0; ci < colCount; ci++) {\n const entry = tableMap[ri][ci];\n if (entry?.type === \"real\") {\n const h = estimateCellHeight(entry.cell!, ctx);\n if (h > maxH) maxH = h;\n }\n }\n rowHeights.push(maxH || Math.round(1000 * 1.6));\n }\n }\n const totalH = rowHeights.reduce((s, h) => s + h, 0);\n\n const defStroke = grid.props.defaultStroke ?? DEFAULT_STROKE;\n // 표 기본 테두리 — BorderFillBank에서 실제 ID 조회\n const tblBfId = ctx.borderFillBank.addUniform(defStroke);\n\n let rowsXml = \"\";\n for (let ri = 0; ri < rowCount; ri++) {\n let cellsXml = \"\";\n for (let ci = 0; ci < colCount; ci++) {\n const entry = tableMap[ri][ci];\n if (!entry || entry.type === \"absorbed\") continue;\n const cell = entry.cell!;\n const cp = cell.props;\n\n // 셀 테두리 — BorderFillBank에서 실제 ID 조회 (하드코딩 제거)\n const cellBfId = ctx.borderFillBank.addFromCellProps(cp, defStroke);\n\n let cellW = 0;\n for (let sc = ci; sc < ci + cell.cs && sc < colWidths.length; sc++)\n cellW += colWidths[sc];\n if (!cellW) cellW = Math.round(totalW / colCount) * cell.cs;\n\n const subListId = ctx.nextElementId++;\n\n // 셀 여백 (기본 141)\n const padL = cp.padL !== undefined ? Metric.ptToHwp(cp.padL) : 141;\n const padR = cp.padR !== undefined ? Metric.ptToHwp(cp.padR) : 141;\n const padT = cp.padT !== undefined ? Metric.ptToHwp(cp.padT) : 141;\n const padB = cp.padB !== undefined ? Metric.ptToHwp(cp.padB) : 141;\n\n const innerW = Math.max(cellW - padL - padR, 100);\n let parasXml = '';\n if (cell.kids.length > 0) {\n for (const kid of cell.kids) {\n if (kid.tag === 'grid') {\n // 중첩 표: <hp:p><hp:run><hp:tbl>...</hp:tbl></hp:run></hp:p> 형식으로 감싸기\n const { xml: tblXml } = buildGridXml(kid, ctx);\n const pid = ctx.nextElementId++;\n const rid = ctx.nextElementId++;\n parasXml += `<hp:p id=\"${pid}\" paraPrIDRef=\"0\" styleIDRef=\"0\" paraTcId=\"0\"><hp:run id=\"${rid}\" charPrIDRef=\"0\" charTcId=\"0\">${tblXml}</hp:run></hp:p>`;\n } else {\n parasXml += encodeParaPositioned(kid, ctx, 0, '', innerW).xml;\n }\n }\n } else {\n parasXml = `<hp:p id=\"${ctx.nextElementId++}\" paraPrIDRef=\"0\" styleIDRef=\"0\" paraTcId=\"0\"><hp:run charPrIDRef=\"0\" charTcId=\"0\"><hp:t xml:space=\"preserve\"> </hp:t></hp:run></hp:p>`;\n }\n\n const vAlign =\n cp.va === \"mid\" ? \"CENTER\" : cp.va === \"bot\" ? \"BOTTOM\" : \"TOP\";\n\n cellsXml +=\n `<hp:tc name=\"\" header=\"0\" hasMargin=\"1\" protect=\"0\" editable=\"0\" dirty=\"0\" borderFillIDRef=\"${cellBfId}\">` +\n `<hp:cellAddr colAddr=\"${ci}\" rowAddr=\"${ri}\"/>` +\n `<hp:cellSpan colSpan=\"${cell.cs}\" rowSpan=\"${cell.rs}\"/>` +\n `<hp:cellSz width=\"${cellW}\" height=\"${rowHeights[ri]}\"/>` +\n `<hp:cellMargin left=\"${padL}\" right=\"${padR}\" top=\"${padT}\" bottom=\"${padB}\"/>` +\n `<hp:subList id=\"${subListId}\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"${vAlign}\" ` +\n `linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"${innerW}\" textHeight=\"${Math.max(100, rowHeights[ri] - padT - padB)}\" hasTextRef=\"0\" hasNumRef=\"0\">` +\n parasXml +\n `</hp:subList>` +\n `</hp:tc>`;\n }\n rowsXml += `<hp:tr>${cellsXml}</hp:tr>`;\n }\n\n // 표 정렬 처리\n const alignMap: Record<string, string> = {\n left: 'LEFT', right: 'RIGHT', center: 'CENTER', justify: 'JUSTIFY',\n };\n const horzAlign = alignMap[grid.props.align ?? 'left'] ?? 'LEFT';\n\n const headerRow = grid.props.headerRow ? ' repeatHeader=\"1\"' : \"\";\n const xml =\n `<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\">` +\n `<hp:sz width=\"${actualTotal}\" widthRelTo=\"ABSOLUTE\" height=\"${totalH}\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/>` +\n `<hp:pos treatAsChar=\"1\" affectLSpacing=\"0\" flowWithText=\"1\" allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" vertAlign=\"TOP\" horzAlign=\"${horzAlign}\" vertOffset=\"0\" horzOffset=\"0\"/>` +\n `<hp:outMargin left=\"138\" right=\"138\" top=\"138\" bottom=\"138\"/>` +\n `<hp:inMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/>` +\n rowsXml +\n `</hp:tbl>`;\n\n return { xml, height: totalH };\n}\n\nfunction estimateCellHeight(cell: CellNode, ctx: HwpxCtx): number {\n const topPad = 141;\n const botPad = 141;\n let h = 0;\n for (const kid of cell.kids) {\n if (kid.tag === 'grid') {\n // 중첩 표 높이는 최소값으로 처리\n h += 1600;\n continue;\n }\n const para = kid;\n const fs = fontSizeForPara(para, ctx);\n const ppId = ctx.paraPrMap.get(paraPrKey(para.props));\n const pp = ppId !== undefined ? ctx.paraPrs[ppId] : null;\n const ls = pp?.lineSpacing ?? 160;\n const before = pp?.prevHwp ?? 0;\n const after = pp?.nextHwp ?? 0;\n h += Math.round((fs * ls) / 100) + before + after;\n }\n if (!h) h = Math.round(1000 * 1.6);\n return h + topPad + botPad;\n}\n\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 .flatMap((k) =>\n k.tag === \"span\"\n ? k.kids.flatMap((c) => (c.tag === \"txt\" ? [c.content] : []))\n : [],\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 .flatMap((p) =>\n p.tag === 'para'\n ? p.kids.flatMap((k) =>\n k.tag === \"span\"\n ? k.kids.flatMap((c) => (c.tag === \"txt\" ? [c.content] : []))\n : [],\n )\n : [],\n )\n .join(\"\"),\n );\n lines.push(cells.join(\"\\t\"));\n }\n }\n }\n return lines.join(\"\\r\\n\");\n}\n\n// ─── XML 이스케이프 ──────────────────────────────────────────\n\nfunction esc(s: string): string {\n if (!s) return \"\";\n s = s.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n s = s.replace(/湰灧/g, \"\").replace(/\\uFEFF/g, \"\");\n // XML 1.0 비허용 제어문자 제거\n // eslint-disable-next-line no-control-regex\n s = s.replace(\n /[^\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\u{10000}-\\u{10FFFF}]/gu,\n \"\",\n );\n return TextKit.escapeXml(s);\n}\n\nregistry.registerEncoder(new HwpxEncoder());\n","import type {\n DocRoot,\n ParaNode,\n SpanNode,\n GridNode,\n ContentNode,\n ImgNode,\n SheetNode,\n} 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\";\nimport { BaseEncoder } from \"../../core/BaseEncoder\";\n\ninterface ImageEntry {\n rId: string;\n name: string;\n data: Uint8Array;\n ext: string;\n}\n\nexport class DocxEncoder extends BaseEncoder {\n protected getFormat(): string {\n return \"docx\";\n }\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n // 모든 섹션(SheetNode)을 처리 — 첫 번째 섹션에서 헤더/푸터/페이지 설정을 가져오고\n // 이후 섹션들의 콘텐츠는 sectPr로 구분하여 단일 body에 병합한다.\n const sheets = doc.kids.length > 0 ? doc.kids : [];\n const firstSheet = sheets[0];\n const dims = normalizeDims(firstSheet?.dims ?? A4);\n\n // 모든 섹션의 콘텐츠를 합산\n const allKids: ContentNode[] = sheets.flatMap((s) => s?.kids ?? []);\n\n const images: ImageEntry[] = [];\n const ctx: EncCtx = {\n images,\n nextId: 10,\n nextImgNum: 1,\n warns: [],\n imgMap: new WeakMap(),\n };\n\n // Collect images from all content\n collectImages(allKids, ctx);\n\n // Header / footer (첫 번째 섹션 기준)\n let headerParas = firstSheet?.headers?.default;\n let footerParas = firstSheet?.footers?.default;\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 from all sections\n const numInfo = collectNumbering(allKids);\n\n // kids 참조를 allKids로 통일 (후속 코드 호환)\n const kids = allKids;\n\n const entries: { name: string; data: Uint8Array }[] = [\n {\n name: \"[Content_Types].xml\",\n data: this.stringToBytes(contentTypes(images, hasHeader, hasFooter)),\n },\n { name: \"_rels/.rels\", data: this.stringToBytes(pkgRels()) },\n {\n name: \"word/document.xml\",\n data: this.stringToBytes(\n documentXml(kids, dims, ctx, headerRId, footerRId),\n ),\n },\n { name: \"word/styles.xml\", data: this.stringToBytes(stylesXml()) },\n { name: \"word/settings.xml\", data: this.stringToBytes(settingsXml()) },\n {\n name: \"word/_rels/document.xml.rels\",\n data: this.stringToBytes(\n docRels(images, headerRId, footerRId, numInfo.hasLists),\n ),\n },\n { name: \"docProps/app.xml\", data: this.stringToBytes(appXml()) },\n {\n name: \"docProps/core.xml\",\n data: this.stringToBytes(coreXml(doc.meta)),\n },\n ];\n\n // Add numbering.xml if needed\n if (numInfo.hasLists) {\n entries.push({\n name: \"word/numbering.xml\",\n data: this.stringToBytes(numberingXml(numInfo)),\n });\n }\n\n // Add header/footer files\n if (hasHeader) {\n entries.push({\n name: \"word/header1.xml\",\n data: this.stringToBytes(headerFooterXml(\"hdr\", headerParas!, ctx)),\n });\n }\n if (hasFooter) {\n entries.push({\n name: \"word/footer1.xml\",\n data: this.stringToBytes(headerFooterXml(\"ftr\", footerParas!, ctx)),\n });\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 this.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)\n if (p.tag === \"para\") collectImagesFromPara(p, ctx);\n else collectImages([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(\n images: ImageEntry[],\n hasHeader?: boolean,\n hasFooter?: boolean,\n): 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 =\n ext === \"png\"\n ? \"image/png\"\n : ext === \"jpeg\"\n ? \"image/jpeg\"\n : ext === \"gif\"\n ? \"image/gif\"\n : \"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)\n overrides += `\\n <Override PartName=\"/word/header1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml\"/>`;\n if (hasFooter)\n 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(\n images: ImageEntry[],\n headerRId?: string,\n footerRId?: string,\n hasLists?: boolean,\n): 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=\"240\" 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=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/><w:left w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/><w:bottom w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/><w:right w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/><w:insideH w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/><w:insideV w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/></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 =\n lvl % 3 === 0\n ? \"decimal\"\n : lvl % 3 === 1\n ? \"lowerLetter\"\n : \"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(\n type: \"hdr\" | \"ftr\",\n paras: ParaNode[],\n ctx: EncCtx,\n): 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(\n kids: ContentNode[],\n dims: PageDims,\n ctx: EncCtx,\n headerRId?: string,\n footerRId?: string,\n): string {\n const body = kids.map((k) => encodeContent(k, ctx, dims)).join(\"\\n\");\n\n let sectRefs = \"\";\n if (headerRId)\n sectRefs += `\\n <w:headerReference w:type=\"default\" r:id=\"${headerRId}\"/>`;\n if (footerRId)\n 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(\n node: ContentNode,\n ctx: EncCtx,\n dims?: PageDims,\n): string {\n return node.tag === \"grid\"\n ? encodeGrid(node, ctx, dims)\n : 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\n ? `<w:pStyle w:val=\"Heading${para.props.heading}\"/>`\n : \"\";\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) - ensure all values are non-negative\n // ECMA-376 §17.3.1.33 spacing: line은 1/240th of a line(auto) 또는 dxa(exact/atLeast)\n let spacingXml = \"\";\n const { spaceBefore, spaceAfter, lineHeight, lineHeightFixed } = para.props;\n if (\n spaceBefore !== undefined ||\n spaceAfter !== undefined ||\n lineHeight !== undefined ||\n lineHeightFixed !== undefined\n ) {\n const parts: string[] = [];\n if (spaceBefore !== undefined)\n parts.push(`w:before=\"${Math.max(0, Metric.ptToDxa(spaceBefore))}\"`);\n if (spaceAfter !== undefined)\n parts.push(`w:after=\"${Math.max(0, Metric.ptToDxa(spaceAfter))}\"`);\n if (lineHeightFixed !== undefined) {\n // FIXED: lineRule=\"exact\", line값은 dxa (1pt = 20dxa)\n parts.push(\n `w:line=\"${Math.max(1, Metric.ptToDxa(lineHeightFixed))}\" w:lineRule=\"exact\"`,\n );\n } else if (lineHeight !== undefined) {\n parts.push(`w:line=\"${Math.round(lineHeight * 240)}\" w:lineRule=\"auto\"`);\n }\n spacingXml = `<w:spacing ${parts.join(\" \")}/>`;\n }\n\n // Indentation — ECMA-376 §17.3.1.12 ind\n // w:left = 전체 왼쪽 여백(dxa), w:right = 전체 오른쪽 여백(dxa)\n // w:firstLine = 첫 줄 추가 들여쓰기(dxa, 양수), w:hanging = 내어쓰기(dxa, 양수값으로 표현)\n let indentXml = \"\";\n const leftDxa = Math.round(Metric.ptToDxa(para.props.indentPt ?? 0));\n const rightDxa = Math.round(Metric.ptToDxa(para.props.indentRightPt ?? 0));\n const firstPt = para.props.firstLineIndentPt ?? 0;\n\n const indParts: string[] = [];\n if (leftDxa > 0) indParts.push(`w:left=\"${leftDxa}\"`);\n if (rightDxa > 0) indParts.push(`w:right=\"${rightDxa}\"`);\n if (firstPt > 0)\n indParts.push(`w:firstLine=\"${Math.round(Metric.ptToDxa(firstPt))}\"`);\n if (firstPt < 0)\n indParts.push(`w:hanging=\"${Math.round(Metric.ptToDxa(-firstPt))}\"`);\n if (indParts.length > 0) indentXml = `<w:ind ${indParts.join(\" \")}/>`;\n\n const runs = para.kids\n .map((k) => {\n if (k.tag === \"span\") return encodeRun(k, ctx);\n if (k.tag === \"img\") return encodeImage(k, ctx);\n return \"\";\n })\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)\n rPr.push(\n `<w:sz w:val=\"${Metric.ptToHalfPt(p.pt)}\"/><w:szCs w:val=\"${Metric.ptToHalfPt(p.pt)}\"/>`,\n );\n if (p.color) rPr.push(`<w:color w:val=\"${p.color}\"/>`);\n if (p.font)\n rPr.push(\n `<w:rFonts w:ascii=\"${esc(p.font)}\" w:hAnsi=\"${esc(p.font)}\" w:eastAsia=\"${esc(p.font)}\"/>`,\n );\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 // __EXT_N__ or __EXT_N_W<w>_H<h>__ 자리표시자 제거\n const content = kid.content.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n if (content) {\n parts.push(\n `<w:r><w:rPr>${rPr.join(\"\")}</w:rPr><w:t xml:space=\"preserve\">${esc(content)}</w:t></w:r>`,\n );\n }\n } else if (kid.tag === \"pagenum\") {\n parts.push(\n `<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 );\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 // Fallback to 72pt (1 inch) when w/h are 0 to prevent invisible images\n const cx = Metric.ptToEmu(img.w > 0 ? img.w : 72);\n const cy = Metric.ptToEmu(img.h > 0 ? img.h : 72);\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\n const isInline = !layout || layout.wrap === \"inline\";\n // topAndBottom은 반드시 anchor (float)로 처리\n const forceAnchor =\n layout?.wrap === \"topAndBottom\" ||\n layout?.wrap === \"square\" ||\n layout?.wrap === \"tight\" ||\n layout?.wrap === \"behind\" ||\n layout?.wrap === \"front\";\n if (isInline && !forceAnchor) {\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 return `<w:r><w:drawing>${encodeAnchor(img, cx, cy, alt, docPrId, graphic, layout!)}</w:drawing></w:r>`;\n}\n\nfunction encodeAnchor(\n _img: ImgNode,\n cx: number,\n cy: number,\n alt: string,\n docPrId: number,\n graphic: string,\n 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 =\n 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 =\n 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\",\n column: \"column\",\n page: \"page\",\n para: \"paragraph\",\n};\nconst VERT_RELTO_DOCX: Record<string, string> = {\n margin: \"margin\",\n line: \"line\",\n page: \"page\",\n para: \"paragraph\",\n};\nconst HORZ_ALIGN_DOCX: Record<string, string> = {\n left: \"left\",\n center: \"center\",\n right: \"right\",\n};\nconst VERT_ALIGN_DOCX: Record<string, string> = {\n top: \"top\",\n center: \"center\",\n bottom: \"bottom\",\n};\n// ECMA-376 §20.4.2 wordprocessingDrawing wrapping elements\nconst WRAP_DOCX: Record<string, string> = {\n square: '<wp:wrapSquare wrapText=\"bothSides\"/>',\n tight:\n '<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:\n '<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 // ECMA-376 §20.4.2.15: wrapTopAndBottom — 텍스트가 이미지 위아래로만 흐름\n topAndBottom: \"<wp:wrapTopAndBottom/>\",\n none: \"<wp:wrapNone/>\",\n behind: \"<wp:wrapNone/>\",\n front: \"<wp:wrapNone/>\",\n};\n\nfunction encodeGrid(grid: GridNode, ctx: EncCtx, dims: PageDims = A4): 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 // 'real': 데이터 셀, 'continue': 세로 병합 지속 셀, 'absorbed': 가로/세로 병합으로 흡수된 자리, 'void': 빈 공간\n interface CellMap {\n type: \"real\" | \"continue\" | \"absorbed\" | \"void\";\n cell?: any;\n width?: number;\n }\n const tableMap: CellMap[][] = Array.from(\n { length: grid.kids.length },\n () => [],\n );\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 // 이미 이전 행의 rowspan이나 현재 행의 colspan으로 차지된 자리 건너뜀\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 const targetRi = ri + rr;\n if (targetRi >= grid.kids.length) break;\n if (!tableMap[targetRi]) tableMap[targetRi] = [];\n\n for (let cc = 0; cc < cell.cs; cc++) {\n if (rr === 0 && cc === 0) continue; // 시작 셀은 이미 'real'로 처리됨\n\n if (rr > 0 && cc === 0) {\n // 세로 병합이 시작된 이후 행의 첫 번째 칸\n tableMap[targetRi][c + cc] = { type: \"continue\", width: cell.cs };\n } else {\n // 가로 병합으로 흡수된 칸 또는 세로 병합 중 가로 병합된 칸\n tableMap[targetRi][c + cc] = { type: \"absorbed\" };\n }\n }\n }\n c += cell.cs;\n }\n }\n\n // 정확한 전체 열 개수(colCount) 계산 (모든 행 중 최대 길이)\n let colCount = 0;\n for (let ri = 0; ri < grid.kids.length; ri++) {\n colCount = Math.max(colCount, tableMap[ri].length);\n }\n if (colCount === 0) colCount = 1;\n\n // 빈 공간(void) 채우기 및 colCount에 맞춰 배열 길이 정규화\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: \"void\" };\n }\n }\n\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 const srcPt = [...grid.props.colWidths];\n while (srcPt.length < colCount) srcPt.push(0);\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 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 colWidthsDxa = srcPt.map((w) => Math.round(Metric.ptToDxa(w)));\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 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 = tableMap\n .map((rowMap, ri) => {\n const cellXmls: string[] = [];\n\n for (let c = 0; c < colCount; c++) {\n const mapEntry = rowMap[c];\n\n // 가로 병합으로 흡수된 칸은 렌더링하지 않음 (앞선 칸의 gridSpan이 차지)\n if (mapEntry.type === \"absorbed\") continue;\n\n // 세로 병합 지속(continue), 실제 셀(real), 또는 빈 공간(void) 처리\n const isContinue = mapEntry.type === \"continue\";\n const isReal = mapEntry.type === \"real\";\n const isVoid = mapEntry.type === \"void\";\n\n if (isContinue || isReal || isVoid) {\n let cw = 0;\n const cellWidth = mapEntry.width || 1;\n\n // 너비 계산: 현재 칸부터 colspan(width) 만큼의 컬럼 너비 합산\n // colWidthsDxa 가 colCount 보다 작은 경우를 대비하여 safe 하게 처리\n const safeColWidths =\n colWidthsDxa.length >= colCount\n ? colWidthsDxa\n : [\n ...colWidthsDxa,\n ...Array(colCount - colWidthsDxa.length).fill(defaultColDxa),\n ];\n for (\n let sc = c;\n sc < c + cellWidth && sc < safeColWidths.length;\n sc++\n ) {\n cw += safeColWidths[sc];\n }\n if (cw <= 0) cw = defaultColDxa * cellWidth;\n\n const tcPrParts: string[] = [];\n tcPrParts.push(`<w:tcW w:w=\"${Math.round(cw)}\" w:type=\"dxa\"/>`);\n\n if (cellWidth > 1) {\n tcPrParts.push(`<w:gridSpan w:val=\"${cellWidth}\"/>`);\n }\n\n if (isContinue) {\n tcPrParts.push(`<w:vMerge/>`);\n }\n\n let cellContent = \"\";\n if (isReal) {\n const cell = mapEntry.cell!;\n const cp = cell.props;\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)\n tcPrParts.push(\n `<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${cp.bg}\"/>`,\n );\n if (cp.va) {\n const vaMap: Record<string, string> = {\n top: \"top\",\n mid: \"center\",\n bot: \"bottom\",\n };\n tcPrParts.push(`<w:vAlign w:val=\"${vaMap[cp.va] ?? \"top\"}\"/>`);\n }\n // Per-cell margin override (only when explicitly set)\n const cPadT =\n cp.padT != null ? Math.round(Metric.ptToDxa(cp.padT)) : null;\n const cPadB =\n cp.padB != null ? Math.round(Metric.ptToDxa(cp.padB)) : null;\n const cPadL =\n cp.padL != null ? Math.round(Metric.ptToDxa(cp.padL)) : null;\n const cPadR =\n cp.padR != null ? Math.round(Metric.ptToDxa(cp.padR)) : null;\n if (\n cPadT != null ||\n cPadB != null ||\n cPadL != null ||\n cPadR != null\n ) {\n const t = cPadT ?? 28;\n const b = cPadB ?? 28;\n const l = cPadL ?? 72;\n const r = cPadR ?? 72;\n tcPrParts.push(\n `<w:tcMar><w:top w:w=\"${t}\" w:type=\"dxa\"/><w:left w:w=\"${l}\" w:type=\"dxa\"/><w:bottom w:w=\"${b}\" w:type=\"dxa\"/><w:right w:w=\"${r}\" w:type=\"dxa\"/></w:tcMar>`,\n );\n }\n // Encode cell content: paragraphs and nested grids (중첩 표)\n // DOCX cells must end with <w:p>; nested <w:tbl> goes between paras\n const parts: string[] = [];\n for (const kid of cell.kids) {\n if (kid.tag === \"grid\") {\n parts.push(encodeGrid(kid, ctx)); // dims 제거 — 중첩 표는 부모 dims 불필요\n } else if (kid.tag === \"para\") {\n parts.push(encodeParaInner(kid, ctx));\n }\n }\n // DOCX 셀은 반드시 <w:p>로 끝나야 함\n const lastKid = cell.kids[cell.kids.length - 1];\n if (cell.kids.length === 0 || lastKid?.tag === \"grid\") {\n parts.push('<w:p><w:pPr><w:spacing w:after=\"0\"/></w:pPr></w:p>');\n }\n cellContent = parts.join(\"\");\n } else {\n // continue 거나 void 인 경우 빈 단락 추가\n cellContent = `<w:p><w:pPr/></w:p>`;\n }\n\n const tcPr = `<w:tcPr>${tcPrParts.join(\"\")}</w:tcPr>`;\n cellXmls.push(` <w:tc>${tcPr}${cellContent}</w:tc>`);\n }\n }\n\n const trPrParts: string[] = [];\n if (ri === 0 && (gp.headerRow || look?.firstRow)) {\n trPrParts.push(\"<w:tblHeader/>\");\n }\n // 원본 행 정보에서 높이 가져오기 (tableMap 과 grid.kids 는 같은 인덱스)\n const originalRow = grid.kids[ri];\n if (originalRow?.heightPt != null && originalRow.heightPt > 0) {\n const hDxa = Math.round(Metric.ptToDxa(originalRow.heightPt));\n trPrParts.push(`<w:trHeight w:val=\"${hDxa}\" w:hRule=\"atLeast\"/>`);\n }\n const trPr =\n trPrParts.length > 0 ? `<w:trPr>${trPrParts.join(\"\")}</w:trPr>` : \"\";\n\n return ` <w:tr>${trPr}\\n${cellXmls.join(\"\\n\")}\\n </w:tr>`;\n })\n .join(\"\\n\");\n\n // 4단계: 테두리 및 최종 테이블 XML 조립\n let tblBorders = \"\";\n const strokeKindMap: Record<string, string> = {\n solid: \"single\",\n dash: \"dash\",\n dot: \"dot\",\n double: \"double\",\n none: \"none\",\n dotDash: \"dotDash\",\n dotDotDash: \"dotDotDash\",\n triple: \"triple\",\n thinThickSmallGap: \"thinThickSmallGap\",\n thickThinSmallGap: \"thickThinSmallGap\",\n thinThickThinSmallGap: \"thinThickThinSmallGap\",\n };\n\n if (gp.defaultStroke) {\n const s = gp.defaultStroke;\n const val = strokeKindMap[s.kind] ?? \"single\";\n\n if (val === \"none\" || s.pt <= 0) {\n tblBorders =\n '<w:tblBorders><w:top w:val=\"none\"/><w:left w:val=\"none\"/><w:bottom w:val=\"none\"/><w:right w:val=\"none\"/><w:insideH w:val=\"none\"/><w:insideV w:val=\"none\"/></w:tblBorders>';\n } else {\n // DOCX sz는 1/8pt 단위. 최소 굵기 2(0.25pt) 보장\n const sz = Math.max(2, Math.round(s.pt * 8));\n // 색상 '#' 제거 및 빈 값일 경우 auto 처리\n const clr = s.color ? s.color.replace(\"#\", \"\") : \"auto\";\n const bdr = `w:val=\"${val}\" w:sz=\"${sz}\" w:space=\"0\" w:color=\"${clr}\"`;\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\n // ECMA-376 §17.4.58: tblJc — 표 가로 정렬 (start/center/end)\n const tblAlignMap: Record<string, string> = {\n left: \"start\",\n center: \"center\",\n right: \"end\",\n justify: \"start\",\n };\n const tblJc = gp.align\n ? `<w:jc w:val=\"${tblAlignMap[gp.align] ?? \"start\"}\"/>`\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}${tblJc}<w:tblCellMar><w:top w:w=\"28\" w:type=\"dxa\"/><w:left w:w=\"72\" w:type=\"dxa\"/><w:bottom w:w=\"28\" w:type=\"dxa\"/><w:right w:w=\"72\" 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> = {\n solid: \"single\",\n dash: \"dash\",\n dot: \"dot\",\n double: \"double\",\n none: \"none\",\n dotDash: \"dotDash\",\n dotDotDash: \"dotDotDash\",\n triple: \"triple\",\n };\n\n const encode = (\n s?: { kind: string; pt: number; color: string },\n tag?: string,\n ) => {\n if (!s || !tag) return \"\";\n const val = strokeKindMap[s.kind] ?? \"single\";\n\n // 선이 없거나 굵기가 0 이하인 경우 확실하게 제거 처리\n if (val === \"none\" || s.pt <= 0) {\n return `<w:${tag} w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>`;\n }\n\n // 최소 굵기 sz=2 (0.25pt) 보장\n const sz = Math.max(2, Math.round(s.pt * 8));\n // 색상 '#' 제거 및 빈 값일 경우 auto 처리\n const clr = s.color ? s.color.replace(\"#\", \"\") : \"auto\";\n\n return `<w:${tag} w:val=\"${val}\" w:sz=\"${sz}\" w:space=\"0\" w:color=\"${clr}\"/>`;\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__ 또는 __EXT_0_W144_H108__ 등) 제거\n s = s.replace(/__EXT_\\d+(?:_W\\d+_H\\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 { DocRoot, ParaNode, SpanNode, GridNode, ContentNode, ImgNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { Stroke } from '../../model/doc-props';\nimport type { EncoderOptions } from '../../contract/encoder';\nimport { succeed, fail } from '../../contract/result';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { registry } from '../../pipeline/registry';\nimport { BaseEncoder } from '../../core/BaseEncoder';\n\nexport class MdEncoder extends BaseEncoder {\n protected getFormat(): string { return 'md'; }\n\n async encode(doc: DocRoot, options?: EncoderOptions): Promise<Outcome<Uint8Array>> {\n const includeImages = options?.includeImages !== false; // default: true\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.headers && sheet.headers.default && sheet.headers.default.length > 0) warns.push('[SHIELD] MD: 머리글(header) 표현 불가 — 손실됨');\n if (sheet.footers && sheet.footers.default && sheet.footers.default.length > 0) warns.push('[SHIELD] MD: 바닥글(footer) 표현 불가 — 손실됨');\n\n for (const kid of sheet.kids) parts.push(encodeContent(kid, warns, includeImages));\n }\n return succeed(this.stringToBytes(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[], includeImages: boolean): string {\n return node.tag === 'grid' ? encodeGrid(node, warns, includeImages) : encodePara(node, warns, includeImages);\n}\n\nfunction encodePara(para: ParaNode, warns: string[], includeImages: boolean): 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, includeImages);\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, includeImages: boolean): string {\n if (!includeImages) {\n return `![${img.alt ?? ''}]`; // alt text only, no data URI\n }\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[], includeImages: boolean): 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 => p.tag === 'para' ? encodePara(p, warns, includeImages) : encodeGrid(p, warns, includeImages)).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, 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';\nimport { BaseEncoder } from '../../core/BaseEncoder';\n\nexport class HtmlEncoder extends BaseEncoder {\n protected getFormat(): string { return '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.headers?.default && sheet.headers.default.length > 0) {\n const hText = sheet.headers.default.map((p: ParaNode) => 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.footers?.default && sheet.footers.default.length > 0) {\n const fText = sheet.footers.default.map((p: ParaNode) => encodePara(p, warns)).join('');\n bodyParts.push(`<div class=\"hwp-footer\">${fText}</div>`);\n }\n }\n\n const title = this.escapeXml(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(this.stringToBytes(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; }\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=\"${TextKit.escapeXml(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 // __EXT_N__ 또는 __EXT_N_W<w>_H<h>__ 자리표시자 제거\n const content = kid.content.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, '');\n if (content) parts.push(TextKit.escapeXml(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:${TextKit.escapeXml(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 = TextKit.escapeXml(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 => p.tag === 'para' ? encodePara(p, warns) : encodeGrid(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\nregistry.registerEncoder(new HtmlEncoder());\n","/**\n * HwpEncoder — DocRoot → HWP 5.0 바이너리 (OLE2/CFB 컨테이너)\n *\n * ANYTOHWP에서 영감받은 개선 사항:\n * 1. HwpStyleBank — 7개 언어 그룹 독립 폰트 레지스트리 (HANGUL/LATIN/HANJA/…)\n * 2. readPixelDims — PNG/JPEG 바이너리 헤더에서 픽셀 치수 추출 → 정확한 HWPUNIT 변환\n * 3. mkIdMappings — 언어별 폰트 카운트를 개별 기록\n * 4. mkCharShape — 언어별 faceId[7] 사용\n *\n * OLE2 레이아웃:\n * FileHeader (stream) — 256-byte HWP 시그니처 + 플래그\n * DocInfo (stream) — zlib 압축된 FACE_NAME / CHAR_SHAPE / PARA_SHAPE 레코드\n * BodyText (storage)\n * Section0 (stream) — zlib 압축된 PAGE_DEF + 문단/표 레코드\n */\n\nimport type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n LinkNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n TextProps,\n ParaProps,\n Stroke,\n PageDims,\n Align,\n} from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport { Metric, safeFontToKr } from \"../../safety/StyleBridge\";\nimport { registry } from \"../../pipeline/registry\";\nimport { A4 } from \"../../model/doc-props\";\nimport pako from \"pako\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { BaseEncoder } from \"../../core/BaseEncoder\";\n\n// ─── HWP 5.0 태그 ID ────────────────────────────────────────\nconst T = 16; // HWPTAG_BEGIN\n\n// DocInfo 태그\nconst TAG_DOCUMENT_PROPERTIES = T + 0; // 16\nconst TAG_ID_MAPPINGS = T + 1; // 17\nconst TAG_BIN_DATA = T + 2; // 18\nconst TAG_FACE_NAME = T + 3; // 19\nconst TAG_BORDER_FILL = T + 4; // 20\nconst TAG_CHAR_SHAPE = T + 5; // 21\nconst TAG_PARA_SHAPE = T + 9; // 25\nconst TAG_STYLE = T + 10; // 26\n\n// BodyText 태그\nconst TAG_PARA_HEADER = T + 50; // 66\nconst TAG_PARA_TEXT = T + 51; // 67\nconst TAG_PARA_CHAR_SHAPE = T + 52; // 68\nconst TAG_PARA_LINE_SEG = T + 53; // 69\nconst TAG_CTRL_HEADER = T + 55; // 71\nconst TAG_LIST_HEADER = T + 56; // 72\nconst TAG_PAGE_DEF = T + 57; // 73\nconst TAG_FOOTNOTE_SHAPE = T + 58; // 74\nconst TAG_TABLE = T + 61; // 77\nconst TAG_SHAPE_COMPONENT_PICTURE = T + 69; // 85\n\n// Control ID (LE UINT32)\nconst CTRL_TABLE = 0x74626c20; // 'tbl '\nconst CTRL_SECD = 0x73656364; // 'secd'\nconst CTRL_PIC = 0x24706963; // '$pic'\nconst CTRL_FIELD_BEGIN = 0x646c6625; // '%fld'\nconst CTRL_FIELD_END = 0x646c665c; // '\\fld'\n\n/** 테두리선 굵기 인덱스 테이블 (pt) */\nconst BORDER_W_PT = [\n 0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.7, 1.98, 2.84, 4.25, 5.67,\n 8.5, 11.34, 14.17,\n];\n\nconst BORDER_KIND_IDX: Record<string, number> = {\n solid: 0,\n dot: 1,\n dash: 2,\n double: 7,\n triple: 8,\n none: 0,\n};\n\nconst ALIGN_CODE: Record<string, number> = {\n justify: 0,\n left: 1,\n right: 2,\n center: 3,\n distribute: 4,\n};\n\n// ─── 바이너리 버퍼 라이터 ────────────────────────────────────\n\nclass BufWriter {\n private chunks: Uint8Array[] = [];\n private _sz = 0;\n get size() {\n return this._sz;\n }\n\n u8(v: number): this {\n this.chunks.push(new Uint8Array([v & 0xff]));\n this._sz++;\n return this;\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 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 i32(v: number): this {\n return this.u32(v < 0 ? v + 0x100000000 : v);\n }\n i16(v: number): this {\n return this.u16(v < 0 ? v + 0x10000 : v);\n }\n bytes(d: Uint8Array): this {\n this.chunks.push(d);\n this._sz += d.length;\n return this;\n }\n zeros(n: number): this {\n this.chunks.push(new Uint8Array(n));\n this._sz += n;\n return this;\n }\n utf16(s: string): this {\n for (let i = 0; i < s.length; i++) this.u16(s.charCodeAt(i));\n return this;\n }\n colorRef(hex: string): this {\n const h = (hex || \"000000\").replace(\"#\", \"\").padStart(6, \"0\");\n return this.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 build(): Uint8Array {\n const out = new Uint8Array(this._sz);\n let off = 0;\n for (const c of this.chunks) {\n out.set(c, off);\n off += c.length;\n }\n return out;\n }\n}\n\n// ─── HWP 레코드 빌더 ─────────────────────────────────────────\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// ─── ANYTOHWP 영감: PNG/JPEG 바이너리 헤더에서 픽셀 치수 추출\nfunction readPixelDims(\n data: Uint8Array,\n mime: string,\n): { w: number; h: number } | null {\n try {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n if (mime.includes(\"png\")) {\n if (\n data.length >= 24 &&\n view.getUint32(0) === 0x89504e47 &&\n view.getUint32(4) === 0x0d0a1a0a\n ) {\n return { w: view.getUint32(16), h: view.getUint32(20) };\n }\n } else if (mime.includes(\"jpeg\") || mime.includes(\"jpg\")) {\n let off = 2;\n while (off < data.length - 4) {\n const marker = view.getUint16(off);\n off += 2;\n if (marker === 0xffc0 || marker === 0xffc2) {\n return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) };\n }\n if ((marker & 0xff00) !== 0xff00) break;\n off += view.getUint16(off);\n }\n }\n } catch {\n /* 무시 */\n }\n return null;\n}\n\n// ─── ANYTOHWP 영감: HwpStyleBank — 7개 언어 그룹 독립 폰트 레지스트리\n// StyleCollector를 대체하는 새로운 스타일 수집기\n\nconst LANG_GROUPS = [\n \"HANGUL\",\n \"LATIN\",\n \"HANJA\",\n \"JAPANESE\",\n \"OTHER\",\n \"SYMBOL\",\n \"USER\",\n] as const;\ntype LangGroup = (typeof LANG_GROUPS)[number];\n\n/** 한글 폰트 여부 판별 */\nfunction isKoreanFont(face: string): boolean {\n return (\n /[\\uAC00-\\uD7A3\\u3131-\\u318E]/.test(face) ||\n [\"맑은\", \"나눔\", \"굴림\", \"돋움\", \"바탕\", \"함초롬\", \"한컴\", \"HY\"].some((k) =>\n face.includes(k),\n )\n );\n}\n\nclass HwpStyleBank {\n readonly DEF_STROKE: Stroke = { kind: \"solid\", pt: 0.5, color: \"000000\" };\n\n // 언어별 독립 폰트 목록 (ANYTOHWP langFontFaces)\n private langFonts = new Map<LangGroup, string[]>(\n LANG_GROUPS.map((g) => [g, []]),\n );\n private langFontIdx = new Map<LangGroup, Map<string, number>>(\n LANG_GROUPS.map((g) => [g, new Map()]),\n );\n\n // charShape, parShape, borderFill 레지스트리\n readonly csProps: TextProps[] = [{}];\n private csIdx = new Map<string, number>([[csKey({}), 0]]);\n\n readonly psProps: ParaProps[] = [{}];\n private psIdx = new Map<string, number>([[psKey({}), 0]]);\n\n readonly bfData: BfEntry[] = [];\n private bfIdx = new Map<string, number>();\n\n // charShape마다 언어별 fontId를 기록\n readonly csFontIds: number[][] = [[0, 0, 0, 0, 0, 0, 0]]; // id=0 → 모두 0\n\n constructor() {\n // 기본 폰트 등록 (ANYTOHWP: 함초롬바탕)\n for (const g of LANG_GROUPS) this._registerLangFont(g, \"함초롬바탕\");\n this.addBorderFill(this.DEF_STROKE); // bfId=1\n }\n\n private _registerLangFont(lang: LangGroup, face: string): number {\n const idx = this.langFontIdx.get(lang)!;\n if (idx.has(face)) return idx.get(face)!;\n const id = this.langFonts.get(lang)!.length;\n this.langFonts.get(lang)!.push(face);\n idx.set(face, id);\n return id;\n }\n\n /** 폰트 이름 → 언어별 7개 ID 반환 (ANYTOHWP 방식) */\n registerFontForLangs(rawFace: string): number[] {\n const face = safeFontToKr(rawFace) || \"함초롬바탕\";\n const isKor = isKoreanFont(face);\n const hangulFace = isKor ? face : \"함초롬바탕\";\n const latinFace = isKor ? \"함초롬바탕\" : face;\n\n const ids: number[] = [];\n for (const lang of LANG_GROUPS) {\n const f = lang === \"LATIN\" ? latinFace : hangulFace;\n ids.push(this._registerLangFont(lang, f));\n }\n return ids; // [hangulId, latinId, hanjaId, japaneseId, otherId, symbolId, userId]\n }\n\n /** 언어별 폰트 목록 반환 */\n getFontsForLang(lang: LangGroup): string[] {\n return [...(this.langFonts.get(lang) ?? [])];\n }\n\n /** 폰트 수 반환 (mkIdMappings용) */\n getFontCount(lang: LangGroup): number {\n return this.langFonts.get(lang)?.length ?? 0;\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 const fIds = p.font\n ? this.registerFontForLangs(p.font)\n : [0, 0, 0, 0, 0, 0, 0];\n this.csProps.push(p);\n this.csFontIds.push(fIds);\n this.csIdx.set(k, id);\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 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(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n ): 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\n// ─── 키 함수 ────────────────────────────────────────────────\n\nfunction csKey(p: TextProps): string {\n return [\n p.font ?? \"\",\n p.pt ?? 10,\n p.b ? 1 : 0,\n p.i ? 1 : 0,\n p.u ? 1 : 0,\n p.s ? 1 : 0,\n p.sup ? 1 : 0,\n p.sub ? 1 : 0,\n p.color ?? \"000000\",\n ].join(\"|\");\n}\n\nfunction psKey(p: ParaProps): string {\n return [\n p.align ?? \"left\",\n p.indentPt ?? 0,\n p.firstLineIndentPt ?? 0,\n p.spaceBefore ?? 0,\n p.spaceAfter ?? 0,\n p.lineHeight ?? 1,\n ].join(\"|\");\n}\n\nfunction bfKey(s: Stroke, bg?: string): string {\n return `${s.kind}|${s.pt}|${s.color}|${bg ?? \"\"}`;\n}\n\nfunction bfPerSideKey(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n): 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\n// ─── Pre-scan: 스타일 수집 ──────────────────────────────────\n\nfunction collectNode(node: ContentNode, bank: HwpStyleBank): void {\n if (node.tag === \"para\") {\n bank.addParaShape(node.props);\n for (const kid of node.kids) {\n if (kid.tag === \"span\") bank.addCharShape((kid as SpanNode).props);\n }\n } else if (node.tag === \"grid\") {\n if (node.props.defaultStroke) bank.addBorderFill(node.props.defaultStroke);\n for (const row of node.kids) {\n for (const cell of row.kids) {\n const defStroke = node.props.defaultStroke ?? bank.DEF_STROKE;\n const cp = cell.props;\n if (cp.top || cp.bot || cp.left || cp.right) {\n bank.addBorderFillPerSide(\n cp.left ?? defStroke,\n cp.right ?? defStroke,\n cp.top ?? defStroke,\n cp.bot ?? defStroke,\n cp.bg,\n );\n } else {\n bank.addBorderFill(defStroke, cp.bg);\n }\n for (const para of cell.kids) collectNode(para, bank);\n }\n }\n }\n}\n\n// ─── DocInfo 레코드 빌더 ─────────────────────────────────────\n\nfunction mkDocumentProperties(): Uint8Array {\n return new BufWriter()\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1) // 7× UINT16 카운터\n .u32(0)\n .u32(0)\n .u32(0) // 캐럿 위치\n .build(); // 26 bytes\n}\n\n/**\n * HWPTAG_ID_MAPPINGS (72 bytes = 18 × INT32)\n * [0]=binData, [1-7]=7개 언어별 글꼴 수 (ANYTOHWP 방식으로 언어별 독립),\n * [8]=테두리/배경, [9]=글자모양, [10]=탭, [11]=번호, [12]=글머리,\n * [13]=문단모양, [14]=스타일, [15-17]=메모/변경추적\n */\nfunction mkIdMappings(bank: HwpStyleBank, nBinData = 0): Uint8Array {\n const w = new BufWriter();\n w.u32(nBinData);\n // [1-7]: 언어별 폰트 수 (ANYTOHWP: langFontFaces별 크기)\n for (const lang of LANG_GROUPS) w.u32(bank.getFontCount(lang));\n w.u32(bank.bfData.length); // [8]\n w.u32(bank.csProps.length); // [9]\n w.u32(0); // [10] tabDef\n w.u32(0); // [11] numbering\n w.u32(0); // [12] bullet\n w.u32(bank.psProps.length); // [13]\n w.u32(1); // [14] style (바탕글 1개)\n w.u32(0); // [15]\n w.u32(0); // [16]\n w.u32(0); // [17]\n return w.build(); // 18 × 4 = 72 bytes\n}\n\nfunction mkStyle(\n name: string,\n engName: string,\n paraPrId: number,\n charPrId: number,\n): Uint8Array {\n return new BufWriter()\n .u16(name.length)\n .utf16(name)\n .u16(engName.length)\n .utf16(engName)\n .u16(paraPrId)\n .u16(charPrId)\n .u16(0)\n .u16(1042)\n .u16(0)\n .build();\n}\n\nfunction mkFaceName(name: string): Uint8Array {\n return new BufWriter()\n .u8(0)\n .u16(name.length)\n .utf16(name)\n .u8(0)\n .u16(0)\n .zeros(10)\n .u16(0)\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))\n best = i;\n }\n return best;\n}\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 w.u16(0);\n for (let i = 0; i < 4; i++) w.u8(t);\n for (let i = 0; i < 4; i++) w.u8(wi);\n for (let i = 0; i < 4; i++) w.colorRef(col);\n w.u8(0).u8(0).colorRef(\"000000\");\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\nfunction mkBorderFillPerSide(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n): Uint8Array {\n const w = new BufWriter();\n w.u16(0);\n w.u8(BORDER_KIND_IDX[l.kind] ?? 0)\n .u8(BORDER_KIND_IDX[r.kind] ?? 0)\n .u8(BORDER_KIND_IDX[t.kind] ?? 0)\n .u8(BORDER_KIND_IDX[b.kind] ?? 0);\n w.u8(borderWidthIdx(l.pt))\n .u8(borderWidthIdx(r.pt))\n .u8(borderWidthIdx(t.pt))\n .u8(borderWidthIdx(b.pt));\n w.colorRef(l.color || \"000000\")\n .colorRef(r.color || \"000000\")\n .colorRef(t.color || \"000000\")\n .colorRef(b.color || \"000000\");\n w.u8(0).u8(0).colorRef(\"000000\");\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 (74 bytes)\n * ANYTOHWP 개선: faceId[7]에 언어별 ID를 개별 기록\n */\nfunction mkCharShape(fontIds: number[], p: TextProps): Uint8Array {\n const height = Math.round((p.pt ?? 10) * 100);\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;\n if (p.s) attr |= 1 << 18;\n if (p.sup) attr |= 1 << 16;\n if (p.sub) attr |= 2 << 16;\n\n const w = new BufWriter();\n // faceId[7]: 언어별 독립 ID (ANYTOHWP 핵심 개선)\n for (const id of fontIds) w.u16(id);\n for (let i = 0; i < 7; i++) w.u8(100); // ratio\n for (let i = 0; i < 7; i++) w.u8(0); // spacing\n for (let i = 0; i < 7; i++) w.u8(100); // relSize\n for (let i = 0; i < 7; i++) w.u8(0); // offset\n w.i32(height).u32(attr).u8(0).u8(0);\n w.colorRef(p.color ?? \"000000\");\n w.colorRef(\"000000\"); // underlineColor\n w.colorRef(p.bg ?? \"FFFFFF\"); // shadeColor\n w.colorRef(\"000000\"); // shadowColor\n w.u16(0); // borderFillId\n w.colorRef(\"000000\"); // strikeColor\n return w.build(); // 74 bytes\n}\n\nfunction mkParaShape(p: ParaProps): Uint8Array {\n const alignVal = ALIGN_CODE[p.align ?? \"left\"] ?? 1;\n const attr1 = (alignVal & 0x7) << 2;\n const lineSpacePct = p.lineHeight ? Math.round(p.lineHeight * 100) : 160;\n return new BufWriter()\n .u32(attr1)\n .i32(Metric.ptToHwp(p.indentPt ?? 0))\n .i32(Metric.ptToHwp(p.indentRightPt ?? 0))\n .i32(Metric.ptToHwp(p.firstLineIndentPt ?? 0))\n .i32(Metric.ptToHwp(p.spaceBefore ?? 0))\n .i32(Metric.ptToHwp(p.spaceAfter ?? 0))\n .i32(lineSpacePct)\n .u16(0)\n .u16(0)\n .u16(0)\n .i16(0)\n .i16(0)\n .i16(0)\n .i16(0)\n .u32(0)\n .u32(4)\n .u32(lineSpacePct)\n .build(); // 54 bytes\n}\n\nfunction mkBinData(id: number, ext: string): Uint8Array {\n return new BufWriter().u16(0x0002).u16(id).u16(ext.length).utf16(ext).build();\n}\n\ninterface BinImage {\n id: number;\n ext: string;\n data: Uint8Array;\n}\n\n/**\n * DocInfo 스트림 빌더\n * ANYTOHWP 개선: 언어별 폰트 목록을 순서대로 독립 기록\n */\nfunction buildDocInfoStream(\n bank: HwpStyleBank,\n images: BinImage[] = [],\n): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n chunks.push(mkRec(TAG_DOCUMENT_PROPERTIES, 0, mkDocumentProperties()));\n chunks.push(mkRec(TAG_ID_MAPPINGS, 1, mkIdMappings(bank, images.length)));\n\n for (const img of images) {\n chunks.push(mkRec(TAG_BIN_DATA, 1, mkBinData(img.id, img.ext)));\n }\n\n // ANYTOHWP 방식: 언어 그룹별로 독립된 FACE_NAME 레코드 직렬화\n for (const lang of LANG_GROUPS) {\n for (const face of bank.getFontsForLang(lang)) {\n chunks.push(mkRec(TAG_FACE_NAME, 1, mkFaceName(face)));\n }\n }\n\n for (const entry of bank.bfData) {\n chunks.push(\n mkRec(\n TAG_BORDER_FILL,\n 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 }\n\n // charShape — 언어별 fontId 배열 사용\n for (let i = 0; i < bank.csProps.length; i++) {\n chunks.push(\n mkRec(TAG_CHAR_SHAPE, 1, mkCharShape(bank.csFontIds[i], bank.csProps[i])),\n );\n }\n\n for (const p of bank.psProps) {\n chunks.push(mkRec(TAG_PARA_SHAPE, 1, mkParaShape(p)));\n }\n\n chunks.push(mkRec(TAG_STYLE, 1, mkStyle(\"바탕글\", \"Normal\", 0, 0)));\n\n return concatU8(chunks);\n}\n\n// ─── BodyText 레코드 빌더 ────────────────────────────────────\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)\n .u32(dims.orient === \"landscape\" ? 1 : 0)\n .build(); // 40 bytes\n}\n\nfunction mkParaHeader(\n nchars: number,\n ctrlMask: number,\n psId: number,\n csCount: number,\n lineAlignCount = 0,\n instanceId = 0,\n): Uint8Array {\n return new BufWriter()\n .u32(nchars)\n .u32(ctrlMask)\n .u16(psId)\n .u8(0)\n .u8(0)\n .u16(csCount)\n .u16(0)\n .u16(lineAlignCount)\n .u32(instanceId)\n .u16(0)\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 // 0x09(탭), 0x0A(줄바꿈), 0x03(필드시작), 0x04(필드종료) 등 허용\n w.u16(c);\n }\n w.u16(13); // 문단 종결자\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 * 5가지 LineSpacing(줄 간격) 타입에 따른 height 계산 로직\n */\nfunction calcLineHeight(\n type: number,\n value: number,\n textHeight: number,\n): number {\n switch (type) {\n case 0:\n return Math.floor((textHeight * value) / 100);\n case 1:\n return value;\n case 2:\n return Math.max(textHeight, value);\n case 3:\n return textHeight + value;\n case 4:\n return Math.floor(textHeight * value);\n default:\n return Math.floor((textHeight * value) / 100);\n }\n}\n\n/**\n * LineSeg 36바이트 구조체 (HWP 5.0 공식 규격)\n */\nfunction mkLineSeg(\n textStartPos: number,\n vertPos: number,\n vertSize: number,\n textHeight: number,\n baseline: number,\n spacing: number,\n horzPos: number,\n horzSize: number,\n flags: number,\n): Uint8Array {\n return new BufWriter()\n .u32(textStartPos)\n .i32(vertPos)\n .i32(vertSize)\n .i32(textHeight)\n .i32(baseline)\n .i32(spacing)\n .i32(horzPos)\n .i32(horzSize)\n .u32(flags)\n .build(); // 36 bytes\n}\n\nfunction buildDefaultLineSeg(\n availWidthHwp: number,\n fontHwp: number,\n nchars: number,\n paraProps?: ParaProps,\n vertPos = 0,\n): Uint8Array {\n const ratio = paraProps?.lineHeight\n ? Math.round(paraProps.lineHeight * 100)\n : 160;\n const vertSize = calcLineHeight(0, ratio, fontHwp);\n const baseline = Math.round(fontHwp * 0.85);\n const spacing = vertSize - fontHwp;\n // flags: bit 0 (페이지 첫 줄), bit 1 (컬럼 첫 줄)\n const flags = 3;\n\n return mkLineSeg(\n 0,\n vertPos,\n vertSize,\n fontHwp,\n baseline,\n spacing,\n 0,\n availWidthHwp,\n flags,\n );\n}\n\nfunction mkSecdParaText(): Uint8Array {\n const lo = CTRL_SECD & 0xffff;\n const hi = (CTRL_SECD >>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x0002)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x0002)\n .u16(0x000d)\n .build();\n}\n\nfunction mkTableParaText(): Uint8Array {\n const lo = CTRL_TABLE & 0xffff;\n const hi = (CTRL_TABLE >>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x000b)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x000b)\n .u16(0x000d)\n .build();\n}\n\nfunction mkPicParaText(): Uint8Array {\n const lo = CTRL_PIC & 0xffff;\n const hi = (CTRL_PIC >>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x000b)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x000b)\n .u16(0x000d)\n .build();\n}\n\n// ─── 이미지 관련 레코드 (ANYTOHWP 영감: 픽셀 치수 우선 사용)\n\ninterface ImgLayout {\n wrap?: string;\n xPt?: number;\n yPt?: number;\n zOrder?: number;\n distL?: number;\n distR?: number;\n distT?: number;\n distB?: number;\n}\n\nfunction mkShapeComponentPicture(\n binDataId: number,\n wHwp: number,\n hHwp: number,\n): Uint8Array {\n const w = new BufWriter();\n w.u32(CTRL_PIC).zeros(15);\n w.u32(0).u32(0).u32(wHwp).u32(hHwp);\n w.u32(0).u32(0).u32(wHwp).u32(hHwp);\n w.zeros(36);\n w.u16(binDataId).u8(0).u8(0).u8(0).zeros(5);\n return w.build();\n}\n\nfunction mkObjectCtrl(\n ctrlId: number,\n wHwp: number,\n hHwp: number,\n instanceId: number,\n layout?: ImgLayout,\n): Uint8Array {\n let attr = 0x082a2210;\n if (layout?.wrap === \"inline\") attr |= 1 << 3;\n return new BufWriter()\n .u32(ctrlId)\n .u32(attr)\n .i32(layout?.yPt ? Metric.ptToHwp(layout.yPt) : 0)\n .i32(layout?.xPt ? Metric.ptToHwp(layout.xPt) : 0)\n .u32(wHwp)\n .u32(hHwp)\n .i32(layout?.zOrder ?? 0)\n .u16(layout?.distL ? Metric.ptToHwp(layout.distL) : 0)\n .u16(layout?.distR ? Metric.ptToHwp(layout.distR) : 0)\n .u16(layout?.distT ? Metric.ptToHwp(layout.distT) : 0)\n .u16(layout?.distB ? Metric.ptToHwp(layout.distB) : 0)\n .u32(instanceId)\n .i32(0)\n .u16(0)\n .build(); // 46 bytes\n}\n\nfunction mkFieldBeginCtrl(instanceId: number): Uint8Array {\n // 46-byte Object Control Header for Field\n return new BufWriter()\n .u32(CTRL_FIELD_BEGIN)\n .u32(0x00000002) // 필드 플래그\n .zeros(28) // xy/size 등 불필요 (필드는 비가시)\n .u32(instanceId)\n .zeros(6)\n .build();\n}\n\nfunction mkFieldEndCtrl(beginId: number): Uint8Array {\n return new BufWriter()\n .u32(CTRL_FIELD_END)\n .u32(0)\n .zeros(28)\n .u32(beginId)\n .zeros(6)\n .build();\n}\n\n/**\n * 이미지 단락 인코딩\n * ANYTOHWP 개선: PNG/JPEG 픽셀 치수에서 HWPUNIT 계산\n */\nfunction encodePicPara(\n imgNode: ImgNode,\n binDataId: number,\n bank: HwpStyleBank,\n lv: number,\n idGen: () => number,\n availWidthHwp: number,\n): Uint8Array[] {\n // ANYTOHWP 방식: 픽셀 치수 추출 시도 → 실패 시 pt 기반으로 폴백\n const rawData = TextKit.base64Decode(imgNode.b64);\n const pixDims = readPixelDims(rawData, imgNode.mime);\n\n let wHwp: number, hHwp: number;\n if (pixDims && pixDims.w > 0 && pixDims.h > 0) {\n wHwp = Metric.ptToHwp((pixDims.w * 72) / 96); // px → pt(96dpi) → hwpunit\n hHwp = Metric.ptToHwp((pixDims.h * 72) / 96);\n } else {\n wHwp = Metric.ptToHwp(imgNode.w);\n hHwp = Metric.ptToHwp(imgNode.h);\n }\n\n // 가용 너비 초과 방지\n if (wHwp > availWidthHwp) {\n hHwp = Math.round((hHwp * availWidthHwp) / wHwp);\n wHwp = availWidthHwp;\n }\n\n const CTRL_MASK = 1 << 11;\n const instanceId = idGen();\n const psId = bank.addParaShape({});\n\n return [\n mkRec(\n TAG_PARA_HEADER,\n lv,\n mkParaHeader(9, CTRL_MASK, psId, 1, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, lv + 1, mkPicParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape([[0, 0]])),\n mkRec(\n TAG_PARA_LINE_SEG,\n lv + 1,\n buildDefaultLineSeg(availWidthHwp, hHwp, 9),\n ),\n mkRec(\n TAG_CTRL_HEADER,\n lv + 1,\n mkObjectCtrl(CTRL_PIC, wHwp, hHwp, idGen(), imgNode.layout),\n ),\n mkRec(\n TAG_SHAPE_COMPONENT_PICTURE,\n lv + 2,\n mkShapeComponentPicture(binDataId, wHwp, hHwp),\n ),\n ];\n}\n\n// ─── 문단 인코딩 ─────────────────────────────────────────────\n\nfunction encodePara(\n para: ParaNode,\n bank: HwpStyleBank,\n lv: number,\n instanceId: number,\n availWidthHwp: number,\n mask = 0,\n vertPos = 0,\n): Uint8Array[] {\n let text = \"\";\n const csPairs: [number, number][] = [];\n let pos = 0;\n let fontHwp = 1000;\n const ctrlRecords: Uint8Array[] = [];\n\n for (const kid of para.kids) {\n if (\n kid.tag === \"span\" &&\n (kid as SpanNode).props.pt &&\n ((kid as SpanNode).props.pt as number) > 0\n ) {\n fontHwp = Metric.ptToHwp((kid as SpanNode).props.pt as number);\n break;\n }\n }\n\n // 내부적으로 사용되는 ID 생성기 (단락 내에서 로컬하게 사용)\n let localIdCounter = 10000;\n const localIdGen = () => localIdCounter++;\n\n function processKids(kids: any[]): void {\n for (const kid of kids) {\n if (kid.tag === \"span\") {\n const span = kid as SpanNode;\n const csId = bank.addCharShape(span.props);\n if (!csPairs.length || csPairs[csPairs.length - 1][1] !== csId) {\n csPairs.push([pos, csId]);\n }\n for (const t of span.kids) {\n if (t.tag === \"txt\") {\n text += t.content;\n pos += t.content.length;\n }\n }\n } else if (kid.tag === \"link\") {\n const link = kid as LinkNode;\n mask |= 1 << 11; // 하이퍼링크 마스크\n\n const fieldBeginId = localIdGen();\n // 1. 시작 제어 문자 (0x03)\n text += String.fromCharCode(3);\n pos += 1;\n ctrlRecords.push(\n mkRec(TAG_CTRL_HEADER, lv + 1, mkFieldBeginCtrl(fieldBeginId)),\n );\n\n // 2. 내용 처리\n processKids(link.kids);\n\n // 3. 종료 제어 문자 (0x04)\n text += String.fromCharCode(4);\n pos += 1;\n ctrlRecords.push(\n mkRec(TAG_CTRL_HEADER, lv + 1, mkFieldEndCtrl(fieldBeginId)),\n );\n }\n }\n }\n processKids(para.kids);\n if (!csPairs.length) csPairs.push([0, 0]);\n\n const psId = bank.addParaShape(para.props);\n const nchars = text.length + 1;\n\n return [\n mkRec(\n TAG_PARA_HEADER,\n lv,\n mkParaHeader(nchars, mask, psId, csPairs.length, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, lv + 1, mkParaText(text)),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape(csPairs)),\n mkRec(\n TAG_PARA_LINE_SEG,\n lv + 1,\n buildDefaultLineSeg(availWidthHwp, fontHwp, nchars, para.props, vertPos),\n ),\n ...ctrlRecords,\n ];\n}\n\n// ─── 표 인코딩 ───────────────────────────────────────────────\n\nfunction mkTableCtrl(\n wHwp: number,\n hHwp: number,\n instanceId: number,\n align: Align = \"left\",\n): Uint8Array {\n // 표 정렬 속성 플래그 (HWP 표 제어 문자)\n // offset 20-21: 속성 플래그 (align: left=0, center=1, right=2, justify=3)\n const alignFlags = { left: 0, center: 1, right: 2, justify: 3 }[align] ?? 0;\n return new BufWriter()\n .u32(CTRL_TABLE)\n .u32(0x082a2211)\n .i32(0)\n .i32(0)\n .u32(wHwp)\n .u32(hHwp)\n .i32(7)\n .u16(140)\n .u16(140)\n .u16(140)\n .u16(140)\n .u32(instanceId)\n .i32(alignFlags)\n .u16(0)\n .build(); // 46 bytes\n}\n\nfunction mkTableRecord(\n rowCnt: number,\n colCnt: number,\n rowHwp: number[],\n bfId: number,\n): Uint8Array {\n const w = new BufWriter();\n w.u32(0x04000006).u16(rowCnt).u16(colCnt).u16(0);\n w.u16(510).u16(510).u16(141).u16(141);\n for (const h of rowHwp) w.u16(Math.max(1, h & 0xffff));\n w.u16(bfId).u16(0);\n return w.build();\n}\n\nfunction mkCellListHeader(\n paraCount: number,\n row: number,\n col: number,\n rs: number,\n cs: number,\n wHwp: number,\n hHwp: number,\n bfId: number,\n padL = 141,\n padR = 141,\n padT = 141,\n padB = 141,\n): Uint8Array {\n return new BufWriter()\n .u16(paraCount)\n .u32(0)\n .u16(0)\n .u16(col)\n .u16(row)\n .u16(rs)\n .u16(cs)\n .u32(wHwp)\n .u32(hHwp)\n .u16(padL)\n .u16(padR)\n .u16(padT)\n .u16(padB)\n .u16(bfId)\n .zeros(13)\n .build(); // 47 bytes\n}\n\nconst DEFAULT_ROW_HEIGHT_PT = 14;\n\nfunction encodeGrid(\n grid: GridNode,\n bank: HwpStyleBank,\n lv: number,\n idGen: () => number,\n availWidthHwp: number,\n): 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 const defStroke = grid.props.defaultStroke ?? bank.DEF_STROKE;\n const defBfId = bank.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\n const tblWPt =\n cwPt.length > 0 ? cwPt.reduce((s: number, w: number) => s + w, 0) : totalPt;\n const tblHPt = grid.kids.reduce(\n (s: number, row: any) =>\n s +\n (row.heightPt != null && row.heightPt > 0\n ? row.heightPt\n : DEFAULT_ROW_HEIGHT_PT),\n 0,\n );\n const tblInstanceId = idGen();\n const tblAlign = grid.props.align ?? \"left\";\n\n records.push(\n mkRec(\n TAG_CTRL_HEADER,\n lv,\n mkTableCtrl(\n Metric.ptToHwp(tblWPt),\n Metric.ptToHwp(tblHPt),\n tblInstanceId,\n tblAlign,\n ),\n ),\n );\n records.push(\n mkRec(TAG_TABLE, lv + 1, mkTableRecord(rowCnt, colCnt, rowHwp, defBfId)),\n );\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 ? bank.addBorderFillPerSide(\n cp.left ?? defStroke,\n cp.right ?? defStroke,\n cp.top ?? defStroke,\n cp.bot ?? defStroke,\n cp.bg,\n )\n : bank.addBorderFill(defStroke, cp.bg);\n\n const paras =\n cell.kids.length > 0\n ? cell.kids\n : [{ tag: \"para\" as const, props: {}, kids: [] }];\n\n const padL = cp.padL !== undefined ? Metric.ptToHwp(cp.padL) : 510;\n const padR = cp.padR !== undefined ? Metric.ptToHwp(cp.padR) : 510;\n const padT = cp.padT !== undefined ? Metric.ptToHwp(cp.padT) : 141;\n const padB = cp.padB !== undefined ? Metric.ptToHwp(cp.padB) : 141;\n\n records.push(\n mkRec(\n TAG_LIST_HEADER,\n lv + 1,\n mkCellListHeader(\n paras.length,\n r,\n c,\n cell.rs,\n cell.cs,\n wHwp,\n hHwp,\n bfId,\n padL,\n padR,\n padT,\n padB,\n ),\n ),\n );\n\n const cellWidthHwp = Metric.ptToHwp(cwPt[c] ?? defColPt);\n for (const para of paras) {\n records.push(\n ...encodePara(para as ParaNode, bank, lv + 2, idGen(), cellWidthHwp),\n );\n }\n }\n }\n return records;\n}\n\nfunction mkSectionCtrl(): Uint8Array {\n return new BufWriter()\n .u32(CTRL_SECD)\n .u32(0)\n .u32(1134)\n .u16(0x4000)\n .u16(0x001f)\n .zeros(31)\n .build(); // 47 bytes\n}\n\nfunction buildSectionParagraph(\n dims: PageDims,\n instanceId: number,\n): Uint8Array[] {\n const SECD_CTRL_MASK = 1 << 2;\n const nchars = 9;\n const availWidthHwp = Math.max(\n 1000,\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(dims.ml) -\n Metric.ptToHwp(dims.mr),\n );\n return [\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(nchars, SECD_CTRL_MASK, 0, 1, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, 1, mkSecdParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])),\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, nchars),\n ),\n mkRec(TAG_CTRL_HEADER, 1, mkSectionCtrl()),\n mkRec(TAG_PAGE_DEF, 2, mkPageDef(dims)),\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)),\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)),\n ];\n}\n\n// ─── BodyText 스트림 빌더 ─────────────────────────────────────\n\nfunction flatImgNodes(kids: any[]): any[] {\n const result: any[] = [];\n for (const kid of kids) {\n if (kid.tag === \"img\") result.push(kid);\n else if (kid.tag === \"link\" && Array.isArray(kid.kids))\n result.push(...flatImgNodes(kid.kids));\n }\n return result;\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\nfunction buildBodyTextStream(\n doc: DocRoot,\n bank: HwpStyleBank,\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 const availWidthHwp = Math.max(\n 1000,\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(dims.ml) -\n Metric.ptToHwp(dims.mr),\n );\n\n for (const r of buildSectionParagraph(dims, idGen())) chunks.push(r);\n\n const TABLE_CTRL_MASK = 1 << 11;\n let vertPos = 0; // 단락 간격 추적\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\n const hasPageBreak = para.kids.some(\n (k) => k.tag === \"span\" && k.kids.some((c) => c.tag === \"pb\"),\n );\n let paraMask = hasPageBreak ? 1 << 2 : 0;\n\n // 코드 블록 감지 → 1×1 표로 감싸기\n const hasCourier = (kids: any[]): boolean =>\n kids.some(\n (k) =>\n (k.tag === \"span\" &&\n k.props.font?.toLowerCase().includes(\"courier\")) ||\n (k.tag === \"link\" && hasCourier(k.kids)),\n );\n const isCode =\n para.props.styleId?.toLowerCase().includes(\"code\") ||\n hasCourier(para.kids);\n\n if (isCode) {\n const gridNode: GridNode = {\n tag: \"grid\",\n props: {\n colWidths: [Metric.hwpToPt(availWidthHwp)],\n defaultStroke: { kind: \"solid\", pt: 0.5, color: \"aaaaaa\" },\n },\n kids: [\n {\n tag: \"row\",\n kids: [\n {\n tag: \"cell\",\n rs: 1,\n cs: 1,\n props: { bg: \"f4f4f4\" },\n kids: [para],\n },\n ],\n },\n ],\n };\n chunks.push(\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(9, TABLE_CTRL_MASK | paraMask, 0, 1, 1, idGen()),\n ),\n );\n chunks.push(mkRec(TAG_PARA_TEXT, 1, mkTableParaText()));\n chunks.push(mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])));\n chunks.push(\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, 9, undefined, vertPos),\n ),\n );\n vertPos += Metric.ptToHwp(20); // 코드 블록 후 간격\n for (const r of encodeGrid(gridNode, bank, 1, idGen, availWidthHwp))\n chunks.push(r);\n continue;\n }\n\n const imgNodes = flatImgNodes(para.kids);\n if (imgNodes.length > 0) {\n for (const img of imgNodes) {\n const binImg = images.find((b) => b64Matches(b, img.b64));\n if (binImg) {\n for (const r of encodePicPara(\n img,\n binImg.id,\n bank,\n 0,\n idGen,\n availWidthHwp,\n )) {\n // 첫 레코드가 PARA_HEADER인 경우 페이지 브레이크 마스크 적용\n chunks.push(r);\n }\n vertPos += Metric.ptToHwp(img.h ?? 100); // 이미지 높이 추가\n }\n }\n const textKids = para.kids.filter(\n (k: any) => k.tag !== \"img\" && k.tag !== \"link\",\n );\n if (textKids.length > 0) {\n const textPara: ParaNode = {\n tag: \"para\",\n props: para.props,\n kids: textKids as any,\n };\n for (const r of encodePara(\n textPara,\n bank,\n 0,\n idGen(),\n availWidthHwp,\n paraMask,\n vertPos,\n )) {\n // PARA_HEADER 레코드(목록의 첫 번째)에 마스크 적용\n if (r[0] === (TAG_PARA_HEADER & 0xff)) {\n // 레코드 헤더 수정은 복잡하므로 encodePara 내부에서 처리하는 것이 안전하지만\n // 여기서는 간단히 구현하기 위해 encodePara의 인자로 mask를 넘기도록 구조를 변경하는 것이 좋습니다.\n }\n chunks.push(r);\n }\n // 단락 높이 계산 및 vertPos 업데이트 (이미지/텍스트 혼합)\n const fontHwp_img = (\n textKids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n )?.props.pt\n ? Metric.ptToHwp(\n (\n textKids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n ).props.pt as number,\n )\n : 1000;\n const lineSpacePct_img = Math.round((para.props.lineHeight ?? 1.6) * 100);\n vertPos += Math.round((fontHwp_img * lineSpacePct_img) / 100);\n }\n } else {\n for (const r of encodePara(\n para,\n bank,\n 0,\n idGen(),\n availWidthHwp,\n paraMask,\n vertPos,\n ))\n chunks.push(r);\n // 단락 높이 계산 및 vertPos 업데이트 (일반 단락)\n const fontHwp_para = (\n para.kids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n )?.props.pt\n ? Metric.ptToHwp(\n (\n para.kids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n ).props.pt as number,\n )\n : 1000;\n const lineSpacePct_para = para.props.lineHeight\n ? Math.round(para.props.lineHeight * 100)\n : 160;\n vertPos += Math.round((fontHwp_para * lineSpacePct_para) / 100);\n }\n } else if (node.tag === \"grid\") {\n chunks.push(\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(9, TABLE_CTRL_MASK, 0, 1, 1, idGen()),\n ),\n );\n chunks.push(mkRec(TAG_PARA_TEXT, 1, mkTableParaText()));\n chunks.push(mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])));\n chunks.push(\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, 9, undefined, vertPos),\n ),\n );\n vertPos += Metric.ptToHwp(20); // 표 후 간격\n for (const r of encodeGrid(\n node as GridNode,\n bank,\n 1,\n idGen,\n availWidthHwp,\n ))\n chunks.push(r);\n }\n }\n }\n\n return concatU8(chunks);\n}\n\n// ─── HWP FileHeader ─────────────────────────────────────────\n/**\n * HWP 5.0 FileHeader 를 생성합니다.\n *\n * 구조:\n * 0-15: 시그니처 \"HWP Document File\" (16 바이트)\n * 16-31: reserved (16 바이트)\n * 32-35: version (4 바이트, Little-Endian) - 0x05000300 = 5.0.3.0\n * 36-39: flags (4 바이트, Little-Endian) - bit 0 = compressed, bit 1 = encrypted\n * 40-255: reserved (216 바이트)\n *\n * 총 256 바이트\n */\nfunction buildHwpFileHeader(): Uint8Array {\n const SIZE = 256;\n const buf = new Uint8Array(SIZE);\n const dv = new DataView(buf.buffer);\n\n // 0-15: 시그니처 \"HWP Document File\" (16 바이트)\n const sig = \"HWP Document File\";\n for (let i = 0; i < sig.length; i++) {\n buf[i] = sig.charCodeAt(i);\n }\n\n // 16-31: reserved (0 으로 초기화됨)\n\n // 32-35: version (4 바이트, Little-Endian) - 0x05000300 = 5.0.3.0\n dv.setUint32(32, 0x05000300, true);\n\n // 36-39: flags (4 바이트, Little-Endian)\n // bit 0 = 1: compressed (압축됨)\n // bit 1 = 0: not encrypted (암호화 안됨)\n dv.setUint32(36, 0x00000001, true);\n\n // 40-255: reserved (0 으로 초기화됨)\n\n // 검증\n if (buf.length !== SIZE) {\n throw new Error(`FileHeader 크기 오류: ${buf.length} (기대: ${SIZE})`);\n }\n if (new TextDecoder().decode(buf.subarray(0, sig.length)) !== sig) {\n throw new Error(\"FileHeader 시그니처 오류\");\n }\n if (dv.getUint32(32, true) !== 0x05000300) {\n throw new Error(\"FileHeader 버전 오류\");\n }\n\n return buf;\n}\n\n// ─── OLE2/CFB 컨테이너 빌더 ─────────────────────────────────\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 // FileHeader 크기 검증\n if (fileHeaderData.length < 256) {\n throw new Error(\n `FileHeader 크기 부족: ${fileHeaderData.length} (최소 256)`,\n );\n }\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 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 const numDirEntries = 5 + (binImages.length > 0 ? 1 + binImages.length : 0);\n const dirN = Math.max(2, Math.ceil(numDirEntries / 4));\n\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 = dir1Sec + dirN;\n const diSec = fhSec + fhN;\n const s0Sec = diSec + diN;\n\n const imgSecs: number[] = [];\n let curSec = s0Sec + s0N;\n for (const n of imgNs) {\n imgSecs.push(curSec);\n curSec += n;\n }\n const totalSec = curSec;\n\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++)\n setFat(dir1Sec + i, i + 1 < dirN ? dir1Sec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < fhN; i++)\n setFat(fhSec + i, i + 1 < fhN ? fhSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < diN; i++)\n setFat(diSec + i, i + 1 < diN ? diSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < s0N; i++)\n 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++)\n setFat(start + i, i + 1 < n ? start + i + 1 : ENDOFCHAIN);\n }\n\n const dirBuf = new Uint8Array(dirN * SS);\n const dv = new DataView(dirBuf.buffer);\n\n function writeDirEntry(\n idx: number,\n name: string,\n type: number,\n left: number,\n right: number,\n child: number,\n startSec: number,\n size: number,\n ): void {\n const base = idx * 128;\n const nl = name.length;\n // OLE2: 이름은 UTF-16LE, (글자수+1)*2 바이트가 길이 필드에 기록됨\n for (let i = 0; i < nl; i++)\n 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; // DE_NODE\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 // 초기값 -1 (NOSTREAM)\n for (let i = 0; i < dirN * 4; i++) {\n const base = i * 128;\n dv.setInt32(base + 68, -1, true);\n dv.setInt32(base + 72, -1, true);\n dv.setInt32(base + 76, -1, true);\n }\n\n /**\n * 트리 구조 설계:\n * 0: Root Entry (child -> 1)\n * 1: FileHeader (left -> -1, right -> 2)\n * 2: DocInfo (left -> -1, right -> 3)\n * 3: BodyText (left -> -1, right -> 5, child -> 4)\n * 4: Section0 (left -> -1, right -> -1)\n * 5: BinData (left -> -1, right -> -1, child -> 6...)\n */\n\n if (binImages.length > 0) {\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);\n writeDirEntry(4, \"Section0\", 2, -1, -1, -1, s0Sec, section0Data.length);\n writeDirEntry(5, \"BinData\", 1, -1, -1, 6, ENDOFCHAIN, 0);\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(\n 6 + ii,\n streamName,\n 2,\n -1,\n sibling,\n -1,\n imgSecs[ii],\n img.data.length,\n );\n }\n } else {\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 // HWP Root Entry CLSID\n const HWP_CLSID = [\n 0x20, 0xe9, 0xe3, 0xc0, 0x46, 0x35, 0xcf, 0x11, 0x8d, 0x81, 0x00, 0xaa,\n 0x00, 0x38, 0x9b, 0x71,\n ];\n for (let i = 0; i < 16; i++) dirBuf[80 + i] = HWP_CLSID[i];\n\n const hdr = new Uint8Array(SS);\n const hdv = new DataView(hdr.buffer);\n\n // OLE2/CFB 헤더 구조:\n // 0-7: Magic number (D0 CF 11 E0 A1 B1 1A E1)\n // 8-23: CLSID (16 bytes)\n // 24-25: Minor version (0x003E = 62)\n // 26-27: Major version (0x0003 = 3)\n // 28-29: Byte order (0x00FE = Little-Endian)\n // 30-31: Sector size exponent (0x0009 = 2^9 = 512)\n // 32-33: Mini sector size exponent (0x0006 = 2^6 = 64)\n // 34-39: Reserved (6 bytes)\n // 40-43: Number of FAT sectors\n // 44-47: Directory start sector location\n // 48-51: Transaction signature number\n // 52-55: Mini stream cutoff size (0x1000 = 4096)\n // 56-59: Mini FAT start sector location\n // 60-63: Number of mini FAT sectors\n // 64-67: FAT start sector location\n // 68-71: Number of backup FAT sectors\n // 72-75: Backup FAT start sector location\n // 76-511: Sector bitmap (109 sectors worth)\n\n // Magic number\n const MAGIC = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];\n MAGIC.forEach((b, i) => {\n hdr[i] = b;\n });\n\n // CLSID is already set in dirBuf[0][80:96] for Root Entry\n\n // Version\n hdv.setUint16(24, 0x003e, true); // Minor version\n hdv.setUint16(26, 0x0003, true); // Major version\n\n // Byte order\n hdv.setUint16(28, 0x00fe, true); // Little-Endian\n\n // Sector size exponent (2^9 = 512)\n hdv.setUint16(30, 0x0009, true);\n\n // Mini sector size exponent (2^6 = 64)\n hdv.setUint16(32, 0x0006, true);\n\n // Reserved (34-39, 6 bytes) - already zero\n\n // Number of FAT sectors\n hdv.setUint32(40, fatN, true);\n\n // Directory start sector location\n hdv.setUint32(44, dir1Sec, true);\n\n // Transaction signature number\n hdv.setUint32(48, 0, true);\n\n // Mini stream cutoff size\n hdv.setUint32(52, 0x1000, true);\n\n // Mini FAT start sector location\n hdv.setUint32(56, ENDOFCHAIN, true);\n\n // Number of mini FAT sectors\n hdv.setUint32(60, 0, true);\n\n // FAT start sector location\n hdv.setUint32(64, ENDOFCHAIN, true);\n\n // Number of backup FAT sectors\n hdv.setUint32(68, 0, true);\n\n // Backup FAT start sector location\n hdv.setUint32(72, 0, true);\n\n // Sector bitmap (76-511)\n for (let i = 0; i < 109; i++) {\n hdv.setUint32(76 + i * 4, i < fatN ? i : FREESECT, true);\n }\n\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 for (let i = 0; i < dirN; i++)\n out.set(dirBuf.subarray(i * SS, (i + 1) * SS), SS + (dir1Sec + i) * SS);\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 return out;\n}\n\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) {\n out.set(a, off);\n off += a.length;\n }\n return out;\n}\n\n// ─── OLE2 검증 ──────────────────────────────────────────────\n\nfunction validateOle2Magic(hwp: Uint8Array): boolean {\n const OLE_MAGIC = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];\n return OLE_MAGIC.every((b, i) => hwp[i] === b);\n}\n\n// ─── Encoder 진입점 ──────────────────────────────────────────\n\nexport class HwpEncoder extends BaseEncoder {\n protected getFormat(): string {\n return \"hwp\";\n }\n protected getAliases(): string[] {\n return [\"application/vnd.hancom.hwp\"];\n }\n\n async encode(doc: DocRoot): Promise<Outcome<Uint8Array>> {\n try {\n // 패스 1: 스타일 수집 (HwpStyleBank — ANYTOHWP 방식 언어별 폰트)\n const bank = new HwpStyleBank();\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectNode(node, bank);\n }\n\n // 이미지 수집 (ANYTOHWP 개선: 픽셀 치수는 encodePicPara에서 추출)\n const images: BinImage[] = [];\n const seenB64 = new Set<string>();\n let binIdCounter = 1;\n\n function registerImg(img: any): void {\n const key = img.b64.substring(0, 50);\n if (seenB64.has(key)) return;\n seenB64.add(key);\n const raw = TextKit.base64Decode(img.b64);\n const ext =\n img.mime === \"image/png\"\n ? \"png\"\n : img.mime === \"image/gif\"\n ? \"gif\"\n : img.mime === \"image/bmp\"\n ? \"bmp\"\n : \"jpg\";\n images.push({ id: binIdCounter++, ext, data: new Uint8Array(raw) });\n }\n\n function collectImages(node: any): void {\n if (node.tag === \"para\") {\n for (const img of flatImgNodes(node.kids)) registerImg(img);\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 for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectImages(node);\n }\n\n // 패스 2: 스트림 빌드\n const docInfoRaw = buildDocInfoStream(bank, images);\n const bodyRaw = buildBodyTextStream(doc, bank, images);\n\n // HWP 5.0: Zlib 헤더 없는 Raw Deflate\n const docInfoCmp = pako.deflateRaw(docInfoRaw);\n const bodyCmp = pako.deflateRaw(bodyRaw);\n\n const fileHdr = buildHwpFileHeader();\n\n // FileHeader 검증\n if (fileHdr.length !== 256) {\n return fail(\n `HwpEncoder: FileHeader 크기 오류 - ${fileHdr.length} bytes (기대: 256 bytes)`,\n );\n }\n\n const hwp = buildHwpOle2(fileHdr, docInfoCmp, bodyCmp, images);\n\n if (!validateOle2Magic(hwp)) {\n return fail(\"HwpEncoder: OLE2 매직 바이트 오류\");\n }\n\n // HWP 파일 크기 검증 (최소 512 바이트 - OLE2 헤더 1 섹터)\n if (hwp.length < 512) {\n return fail(\n `HwpEncoder: HWP 파일 크기 부족 - ${hwp.length} bytes (최소 512 bytes)`,\n );\n }\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 { DocRoot } from '../model/doc-tree';\nimport type { Outcome } from '../contract/result';\nimport type { EncoderOptions } from '../contract/encoder';\nimport { succeed, 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 '../decoders/html/HtmlDecoder';\nimport '../encoders/hwpx/HwpxEncoder';\nimport '../encoders/docx/DocxEncoder';\nimport '../encoders/md/MdEncoder';\nimport '../encoders/html/HtmlEncoder';\nimport '../encoders/hwp/HwpEncoder';\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, options?: EncoderOptions): 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, options);\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 { 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":["pako","i","r","data","coreXml","stylesXml","extractDims","decodeHeaderFooter","toArr","decodePara","decodeGrid","decodeGridSimple","decodeGridFlat","decodeGridText","cellText","tableText","end","t","paraKids","stylesXml","mimeToExt","registerImage","esc","encodeImage","encodeContent","encodeGrid","encodeImage","encodePara","encodeContent","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","readPixelDims","LANG_GROUPS","encodePara","encodeGrid","out","registerImg","collectImages","pako"]}
|