hwpx-js 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/codecs/hwpx/zip.ts","../src/codecs/hwpx/xml/index.ts","../src/codecs/hwpx/ns.ts","../src/codecs/hwpx/xml/version.ts","../src/codecs/hwpx/xml/container.ts","../src/codecs/hwpx/xml/manifest.ts","../src/codecs/hwpx/xml/settings.ts","../src/codecs/hwpx/xml/content-hpf.ts","../src/codecs/hwpx/xml/header.ts","../src/codecs/hwpx/xml/section.ts","../src/codecs/hwpx/writer.ts","../src/codecs/hwpx/xml/parser.ts","../src/codecs/hwpx/xml/parse-header.ts","../src/codecs/hwpx/xml/parse-section.ts","../src/codecs/hwpx/xml/parse-content-hpf.ts","../src/errors.ts","../src/codecs/hwpx/reader.ts","../src/codecs/hwp5/reader.ts","../src/codecs/hwp5/ole.ts","../src/codecs/hwp5/records.ts","../src/utils/units.ts","../src/utils/color.ts","../src/defaults.ts","../src/utils/detect.ts","../src/utils/id.ts","../src/builder.ts","../src/utils/index.ts","../src/index.ts"],"sourcesContent":["import { zipSync, unzipSync, type Zippable } from 'fflate';\n\nexport interface ZipEntry {\n path: string;\n data: Uint8Array;\n /** true → store (no compression), default: deflate */\n store?: boolean;\n}\n\n/** 엔트리 배열로부터 ZIP 바이너리를 생성 */\nexport function createZip(entries: ZipEntry[]): Uint8Array {\n const data: Zippable = {};\n\n for (const entry of entries) {\n data[entry.path] = entry.store\n ? [entry.data, { level: 0 }]\n : entry.data;\n }\n\n return zipSync(data);\n}\n\n/** ZIP 바이너리를 엔트리 맵으로 추출 */\nexport function extractZip(data: Uint8Array): Record<string, Uint8Array> {\n return unzipSync(data);\n}\n\n/** 문자열을 UTF-8 Uint8Array로 인코딩 */\nexport function encodeUtf8(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/** Uint8Array를 UTF-8 문자열로 디코딩 */\nexport function decodeUtf8(data: Uint8Array): string {\n return new TextDecoder().decode(data);\n}\n","/** XML 문자열 이스케이프 */\nexport function escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\n/** XML attribute 맵을 문자열로 변환 */\nexport function attrs(map: Record<string, string | number | boolean | undefined>): string {\n const parts: string[] = [];\n for (const [key, val] of Object.entries(map)) {\n if (val === undefined) continue;\n parts.push(`${key}=\"${escapeXml(String(val))}\"`);\n }\n return parts.length > 0 ? ' ' + parts.join(' ') : '';\n}\n\n/** XML 요소 생성 헬퍼 */\nexport function el(\n tag: string,\n attributes: Record<string, string | number | boolean | undefined>,\n children?: string,\n): string {\n const a = attrs(attributes);\n if (children === undefined || children === '') {\n return `<${tag}${a}/>`;\n }\n return `<${tag}${a}>${children}</${tag}>`;\n}\n\n/** XML 선언 */\nexport function xmlDecl(): string {\n return '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>';\n}\n","// OWPML Namespace constants\nexport const NS = {\n // 한/글 문서 네임스페이스\n hh: 'http://www.hancom.co.kr/hwpml/2011/head',\n hp: 'http://www.hancom.co.kr/hwpml/2011/paragraph',\n hs: 'http://www.hancom.co.kr/hwpml/2011/section',\n hc: 'http://www.hancom.co.kr/hwpml/2011/core',\n ha: 'http://www.hancom.co.kr/hwpml/2011/app',\n // OPF / ODF\n opf: 'http://www.idpf.org/2007/opf',\n odf: 'urn:oasis:names:tc:opendocument:xmlns:container',\n // 미디어 타입\n mimeHwpx: 'application/hwp+zip',\n} as const;\n","import { xmlDecl, el } from './index.js';\nimport { NS } from '../ns.js';\nimport type { DocumentMeta } from '../../../types.js';\n\nexport function generateVersionXml(meta: DocumentMeta): string {\n return (\n xmlDecl() +\n '\\n' +\n el('hc:version', {\n 'xmlns:hc': NS.hc,\n 'xmlns:ha': NS.ha,\n tagtypes: '1',\n },\n '\\n' +\n el('ha:app', {}, 'hwpx-js') +\n '\\n' +\n el('ha:appversion', {}, meta.hwpVersion) +\n '\\n' +\n el('hc:version', { tagtypes: '0' },\n el('ha:major', {}, '1') +\n el('ha:minor', {}, '4'),\n ) +\n '\\n',\n )\n );\n}\n","import { xmlDecl, el } from './index.js';\nimport { NS } from '../ns.js';\n\nexport function generateContainerXml(): string {\n return (\n xmlDecl() +\n '\\n' +\n el(\n 'container',\n { xmlns: NS.odf, version: '1.0' },\n '\\n' +\n el(\n 'rootfiles',\n {},\n '\\n' +\n el('rootfile', {\n 'full-path': 'Contents/content.hpf',\n 'media-type': NS.mimeHwpx,\n }) +\n '\\n',\n ) +\n '\\n',\n )\n );\n}\n","import { xmlDecl, el } from './index.js';\n\ninterface ManifestEntry {\n fullPath: string;\n mediaType: string;\n}\n\nexport function generateManifestXml(entries: ManifestEntry[]): string {\n const items = entries\n .map(\n (e) =>\n '\\n' +\n el('manifest:file-entry', {\n 'manifest:full-path': e.fullPath,\n 'manifest:media-type': e.mediaType,\n }),\n )\n .join('');\n\n return (\n xmlDecl() +\n '\\n' +\n el(\n 'manifest:manifest',\n { 'xmlns:manifest': 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0' },\n items + '\\n',\n )\n );\n}\n\nexport function buildManifestEntries(sectionCount: number, binData: { name: string; format: string }[]): ManifestEntry[] {\n const entries: ManifestEntry[] = [\n { fullPath: '/', mediaType: 'application/hwp+zip' },\n { fullPath: 'version.xml', mediaType: 'application/xml' },\n { fullPath: 'Contents/content.hpf', mediaType: 'application/xml' },\n { fullPath: 'Contents/header.xml', mediaType: 'application/xml' },\n { fullPath: 'settings.xml', mediaType: 'application/xml' },\n ];\n\n for (let i = 0; i < sectionCount; i++) {\n entries.push({\n fullPath: `Contents/section${i}.xml`,\n mediaType: 'application/xml',\n });\n }\n\n for (const bin of binData) {\n const mimeMap: Record<string, string> = {\n jpg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n bmp: 'image/bmp',\n tiff: 'image/tiff',\n wmf: 'image/x-wmf',\n emf: 'image/x-emf',\n };\n entries.push({\n fullPath: `BinData/${bin.name}`,\n mediaType: mimeMap[bin.format] || 'application/octet-stream',\n });\n }\n\n return entries;\n}\n","import { xmlDecl, el } from './index.js';\nimport { NS } from '../ns.js';\n\nexport function generateSettingsXml(): string {\n return (\n xmlDecl() +\n '\\n' +\n el(\n 'ha:HWPApplicationSetting',\n { 'xmlns:ha': NS.ha },\n '\\n' +\n el('ha:CaretPosition', { list: '0', para: '0', pos: '0' }) +\n '\\n',\n )\n );\n}\n","import { xmlDecl, el } from './index.js';\nimport { NS } from '../ns.js';\nimport type { HWPXDocument } from '../../../types.js';\n\nexport function generateContentHpfXml(doc: HWPXDocument): string {\n const sectionItems = doc.sections\n .map(\n (_, i) =>\n el('opf:item', {\n id: `section${i}`,\n href: `section${i}.xml`,\n 'media-type': 'application/xml',\n }),\n )\n .join('\\n');\n\n const sectionRefs = doc.sections\n .map((_, i) => el('opf:itemref', { idref: `section${i}` }))\n .join('\\n');\n\n const binItems = doc.binData\n .map(\n (b) =>\n el('opf:item', {\n id: `bindata${b.id}`,\n href: `../BinData/${b.name}`,\n 'media-type': getMimeType(b.format),\n }),\n )\n .join('\\n');\n\n return (\n xmlDecl() +\n '\\n' +\n el(\n 'opf:package',\n {\n 'xmlns:opf': NS.opf,\n version: '1.0',\n 'unique-identifier': 'bookid',\n },\n '\\n' +\n el(\n 'opf:metadata',\n {},\n '\\n' + el('opf:title', {}, doc.meta.title || '') + '\\n',\n ) +\n '\\n' +\n el(\n 'opf:manifest',\n {},\n '\\n' +\n el('opf:item', { id: 'header', href: 'header.xml', 'media-type': 'application/xml' }) +\n '\\n' +\n sectionItems +\n '\\n' +\n binItems +\n (binItems ? '\\n' : ''),\n ) +\n '\\n' +\n el(\n 'opf:spine',\n {},\n '\\n' + sectionRefs + '\\n',\n ) +\n '\\n',\n )\n );\n}\n\nfunction getMimeType(format: string): string {\n const map: Record<string, string> = {\n jpg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n bmp: 'image/bmp',\n tiff: 'image/tiff',\n wmf: 'image/x-wmf',\n emf: 'image/x-emf',\n };\n return map[format] || 'application/octet-stream';\n}\n","import { xmlDecl, el, attrs } from './index.js';\nimport { NS } from '../ns.js';\nimport type {\n DocumentHead,\n CharProperty,\n ParaProperty,\n FontFace,\n Style,\n BorderFill,\n BorderLine,\n BulletProperty,\n NumberingProperty,\n} from '../../../types.js';\n\nexport function generateHeaderXml(head: DocumentHead): string {\n return (\n xmlDecl() +\n '\\n' +\n el(\n 'hh:head',\n {\n 'xmlns:hh': NS.hh,\n 'xmlns:hc': NS.hc,\n version: '1.4',\n secCnt: '1',\n },\n '\\n' +\n generateFontFaces(head.fontFaces) +\n generateBorderFills(head.borderFills) +\n generateCharProperties(head.charProperties) +\n generateParaProperties(head.paraProperties) +\n generateStyles(head.styles) +\n generateNumberings(head.numberingProperties) +\n generateBullets(head.bulletProperties) +\n generateCompatibleDoc(head.compatibleDoc) +\n '',\n )\n );\n}\n\nfunction generateFontFaces(faces: FontFace[]): string {\n if (faces.length === 0) return '';\n\n const byLang = new Map<string, FontFace[]>();\n for (const f of faces) {\n const arr = byLang.get(f.lang) || [];\n arr.push(f);\n byLang.set(f.lang, arr);\n }\n\n let xml = '';\n xml += el(\n 'hh:fontfaces',\n {},\n '\\n' +\n Array.from(byLang.entries())\n .map(([lang, items]) =>\n el(\n 'hh:fontface',\n { lang },\n '\\n' +\n items\n .map((f, i) =>\n el('hh:font', { id: String(i), face: f.fontName, type: f.fontType || 'ttf' }),\n )\n .join('\\n') +\n '\\n',\n ),\n )\n .join('\\n') +\n '\\n',\n );\n xml += '\\n';\n return xml;\n}\n\nfunction generateBorderFills(fills: BorderFill[]): string {\n if (fills.length === 0) return '';\n\n const items = fills.map((bf) => {\n const borderElements = (['left', 'right', 'top', 'bottom'] as const)\n .map((side) => generateBorderLine(side, bf.borders[side]))\n .join('\\n');\n\n let fillContent = '';\n if (bf.fillBrush) {\n if (bf.fillBrush.type === 'SOLID' && bf.fillBrush.faceColor !== undefined) {\n fillContent = el(\n 'hc:fillBrush',\n {},\n '\\n' +\n el('hc:winBrush', {\n faceColor: colorToString(bf.fillBrush.faceColor),\n hatchColor: bf.fillBrush.patternColor !== undefined ? colorToString(bf.fillBrush.patternColor) : undefined,\n }) +\n '\\n',\n );\n }\n }\n\n return el(\n 'hh:borderFill',\n {\n id: String(bf.id),\n threeD: bf.threeD ? '1' : '0',\n shadow: bf.shadow ? '1' : '0',\n slash: bf.slash || 'NONE',\n backSlash: bf.backSlash || 'NONE',\n },\n '\\n' + borderElements + '\\n' + fillContent,\n );\n });\n\n return el('hh:borderFills', {}, '\\n' + items.join('\\n') + '\\n') + '\\n';\n}\n\nfunction generateBorderLine(side: string, line: BorderLine): string {\n return el(`hc:${side}Border`, {\n type: line.type,\n width: line.width,\n color: colorToString(line.color),\n });\n}\n\nfunction generateCharProperties(props: CharProperty[]): string {\n if (props.length === 0) return '';\n\n const items = props.map((cp) => {\n const fontRefs =\n el('hh:fontRef', {\n hangul: String(cp.fontRef.hangul),\n latin: String(cp.fontRef.latin),\n hanja: String(cp.fontRef.hanja),\n japanese: String(cp.fontRef.japanese),\n other: String(cp.fontRef.other),\n symbol: String(cp.fontRef.symbol),\n user: String(cp.fontRef.user),\n });\n\n return el(\n 'hh:charPr',\n {\n id: String(cp.id),\n height: String(cp.height),\n textColor: colorToString(cp.textColor),\n shadeColor: cp.shadeColor !== undefined ? colorToString(cp.shadeColor) : undefined,\n useFontSpace: cp.useFontSpace ? '1' : undefined,\n useKerning: cp.useKerning ? '1' : undefined,\n spacing: cp.spacing !== undefined ? String(cp.spacing) : undefined,\n relSz: cp.relSize !== undefined ? String(cp.relSize) : undefined,\n offset: cp.charOffset !== undefined ? String(cp.charOffset) : undefined,\n bold: cp.bold ? '1' : '0',\n italic: cp.italic ? '1' : '0',\n underline: cp.underline || 'NONE',\n strikeout: cp.strikeout || 'NONE',\n },\n '\\n' + fontRefs + '\\n',\n );\n });\n\n return el('hh:charProperties', {}, '\\n' + items.join('\\n') + '\\n') + '\\n';\n}\n\nfunction generateParaProperties(props: ParaProperty[]): string {\n if (props.length === 0) return '';\n\n const items = props.map((pp) => {\n const marginEl = el('hh:parMargin', {\n left: String(pp.paraMargin.left),\n right: String(pp.paraMargin.right),\n indent: String(pp.paraMargin.indent),\n prev: String(pp.paraMargin.prevSpacing),\n next: String(pp.paraMargin.nextSpacing),\n });\n\n const lineSpacingEl = el('hh:lineSpacing', {\n type: pp.lineSpacing.type,\n value: String(pp.lineSpacing.value),\n });\n\n return el(\n 'hh:paraPr',\n {\n id: String(pp.id),\n align: pp.alignment || 'JUSTIFY',\n heading: pp.heading,\n breakBefore: pp.breakBefore,\n },\n '\\n' + marginEl + '\\n' + lineSpacingEl + '\\n',\n );\n });\n\n return el('hh:paraProperties', {}, '\\n' + items.join('\\n') + '\\n') + '\\n';\n}\n\nfunction generateStyles(styles: Style[]): string {\n if (styles.length === 0) return '';\n\n const items = styles.map((s) =>\n el('hh:style', {\n id: String(s.id),\n type: s.type,\n name: s.name,\n engName: s.engName,\n paraPrIDRef: s.paraPrIDRef !== undefined ? String(s.paraPrIDRef) : undefined,\n charPrIDRef: s.charPrIDRef !== undefined ? String(s.charPrIDRef) : undefined,\n nextStyleIDRef: s.nextStyleIDRef !== undefined ? String(s.nextStyleIDRef) : undefined,\n }),\n );\n\n return el('hh:styles', {}, '\\n' + items.join('\\n') + '\\n') + '\\n';\n}\n\nfunction generateNumberings(numberings: NumberingProperty[]): string {\n if (numberings.length === 0) return '';\n\n const items = numberings.map((n) => {\n const levels = n.levels\n .map((lvl, i) =>\n el('hh:paraHead', {\n level: String(i + 1),\n numFormat: lvl.format,\n start: lvl.start !== undefined ? String(lvl.start) : '1',\n prefix: lvl.prefix || '',\n suffix: lvl.suffix || '.',\n }),\n )\n .join('\\n');\n\n return el('hh:numbering', { id: String(n.id) }, '\\n' + levels + '\\n');\n });\n\n return el('hh:numberings', {}, '\\n' + items.join('\\n') + '\\n') + '\\n';\n}\n\nfunction generateBullets(bullets: BulletProperty[]): string {\n if (bullets.length === 0) return '';\n\n const items = bullets.map((b) =>\n el('hh:bullet', {\n id: String(b.id),\n char: b.bulletChar,\n bulletSz: b.bulletSize !== undefined ? String(b.bulletSize) : undefined,\n }),\n );\n\n return el('hh:bullets', {}, '\\n' + items.join('\\n') + '\\n') + '\\n';\n}\n\nfunction generateCompatibleDoc(compat?: string): string {\n if (!compat) return '';\n return el('hh:compatibleDocument', { targetProgram: compat }) + '\\n';\n}\n\nfunction colorToString(color: number): string {\n return '#' + color.toString(16).padStart(6, '0');\n}\n","import { xmlDecl, el, escapeXml } from './index.js';\nimport { NS } from '../ns.js';\nimport type {\n Section,\n Paragraph,\n Run,\n TextRun,\n TableRun,\n PictureRun,\n SectionDef,\n Table,\n TableRow,\n TableCell,\n Picture,\n ColumnDef,\n HeaderFooterDef,\n SubDocument,\n} from '../../../types.js';\n\nexport function generateSectionXml(section: Section, sectionIndex: number): string {\n return (\n xmlDecl() +\n '\\n' +\n el(\n 'hs:sec',\n {\n 'xmlns:hs': NS.hs,\n 'xmlns:hp': NS.hp,\n 'xmlns:hc': NS.hc,\n },\n '\\n' +\n generateSectionDef(section.def) +\n section.paragraphs.map((p) => generateParagraph(p)).join('\\n') +\n '\\n',\n )\n );\n}\n\nfunction generateSectionDef(def: SectionDef): string {\n const pagePr = el('hs:pagePr', {\n landscape: def.landscape ? 'LANDSCAPE' : 'PORTRAIT',\n width: String(def.pageWidth),\n height: String(def.pageHeight),\n gutterType: def.gutterType || 'LEFT_ONLY',\n });\n\n const pageMargin = el('hs:pageMargin', {\n left: String(def.pageMargin.left),\n right: String(def.pageMargin.right),\n top: String(def.pageMargin.top),\n bottom: String(def.pageMargin.bottom),\n header: String(def.pageMargin.header),\n footer: String(def.pageMargin.footer),\n gutter: String(def.pageMargin.gutter),\n });\n\n let extra = '';\n\n // 다단\n if (def.columns && def.columns.count > 1) {\n extra += generateColumns(def.columns) + '\\n';\n }\n\n // 머리글/바닥글\n if (def.headerFooter) {\n if (def.headerFooter.header) {\n extra += generateHeaderFooter('hs:header', def.headerFooter.header) + '\\n';\n }\n if (def.headerFooter.footer) {\n extra += generateHeaderFooter('hs:footer', def.headerFooter.footer) + '\\n';\n }\n }\n\n return el(\n 'hs:secPr',\n {},\n '\\n' + pagePr + '\\n' + pageMargin + '\\n' + extra,\n ) + '\\n';\n}\n\nfunction generateColumns(cols: ColumnDef): string {\n return el('hs:colPr', {\n type: cols.type || 'NORMAL',\n count: String(cols.count),\n gap: String(cols.gap || 0),\n sameSz: cols.sameSizes ? '1' : '0',\n });\n}\n\nfunction generateHeaderFooter(tag: string, subDoc: SubDocument): string {\n const paragraphs = subDoc.paragraphs.map((p) => generateParagraph(p)).join('\\n');\n return el(tag, {}, '\\n' + paragraphs + '\\n');\n}\n\nfunction generateParagraph(para: Paragraph): string {\n const runs = para.runs.map((run) => generateRun(run)).join('');\n\n return el(\n 'hp:p',\n {\n paraPrIDRef: String(para.paraPrIDRef),\n styleIDRef: String(para.styleIDRef),\n },\n '\\n' + runs,\n );\n}\n\nfunction generateRun(run: Run): string {\n switch (run.t) {\n case 'text':\n return generateTextRun(run);\n case 'table':\n return generateTableRun(run);\n case 'picture':\n return generatePictureRun(run);\n case 'break':\n return generateBreakRun(run);\n default:\n return '';\n }\n}\n\nfunction generateTextRun(run: TextRun): string {\n return el(\n 'hp:run',\n { charPrIDRef: String(run.charPrIDRef) },\n '\\n' +\n el('hp:runText', {}, escapeXml(run.text)) +\n '\\n',\n );\n}\n\nfunction generateTableRun(run: TableRun): string {\n return el(\n 'hp:run',\n { charPrIDRef: String(run.charPrIDRef) },\n '\\n' + generateTable(run.table) + '\\n',\n );\n}\n\nfunction generatePictureRun(run: PictureRun): string {\n return el(\n 'hp:run',\n { charPrIDRef: String(run.charPrIDRef) },\n '\\n' + generatePicture(run.picture) + '\\n',\n );\n}\n\nfunction generateBreakRun(run: Run & { t: 'break' }): string {\n const tagMap: Record<string, string> = {\n LINE: 'hp:lineBreak',\n PAGE: 'hp:pageBreak',\n COLUMN: 'hp:colBreak',\n };\n const tag = tagMap[run.breakType] || 'hp:lineBreak';\n return el(\n 'hp:run',\n { charPrIDRef: String(run.charPrIDRef) },\n '\\n' + `<${tag}/>` + '\\n',\n );\n}\n\n// ─── Table Generation ───\n\nfunction generateTable(table: Table): string {\n const colWidths = table.colWidths.map((w) => el('hp:colSz', { width: String(w) })).join('\\n');\n\n const rows = table.rows.map((row, ri) => generateTableRow(row, ri)).join('\\n');\n\n return el(\n 'hp:tbl',\n {\n rowCnt: String(table.rowCount),\n colCnt: String(table.colCount),\n cellSpacing: table.cellSpacing !== undefined ? String(table.cellSpacing) : '0',\n borderFillIDRef: String(table.borderFillIDRef),\n width: String(table.width),\n },\n '\\n' + colWidths + '\\n' + rows + '\\n',\n );\n}\n\nfunction generateTableRow(row: TableRow, rowIndex: number): string {\n const cells = row.cells.map((cell) => generateTableCell(cell)).join('\\n');\n\n return el(\n 'hp:tr',\n { height: String(row.height) },\n '\\n' + cells + '\\n',\n );\n}\n\nfunction generateTableCell(cell: TableCell): string {\n const paddingAttrs: Record<string, string | undefined> = {};\n if (cell.padding) {\n paddingAttrs['paddingLeft'] = String(cell.padding.left);\n paddingAttrs['paddingRight'] = String(cell.padding.right);\n paddingAttrs['paddingTop'] = String(cell.padding.top);\n paddingAttrs['paddingBottom'] = String(cell.padding.bottom);\n }\n\n const paragraphs = cell.paragraphs.map((p) => generateParagraph(p)).join('\\n');\n\n return el(\n 'hp:tc',\n {\n colSpan: String(cell.colSpan),\n rowSpan: String(cell.rowSpan),\n width: String(cell.width),\n height: String(cell.height),\n borderFillIDRef: String(cell.borderFillIDRef),\n ...paddingAttrs,\n },\n '\\n' +\n el('hp:subList', {}, '\\n' + paragraphs + '\\n') +\n '\\n',\n );\n}\n\n// ─── Picture Generation ───\n\nfunction generatePicture(pic: Picture): string {\n return el(\n 'hp:pic',\n {\n binDataIDRef: String(pic.binDataIDRef),\n width: String(pic.width),\n height: String(pic.height),\n offsetX: pic.offsetX !== undefined ? String(pic.offsetX) : undefined,\n offsetY: pic.offsetY !== undefined ? String(pic.offsetY) : undefined,\n },\n );\n}\n","import type { HWPXDocument, WriteOptions } from '../../types.js';\nimport { createZip, encodeUtf8, type ZipEntry } from './zip.js';\nimport { generateVersionXml } from './xml/version.js';\nimport { generateContainerXml } from './xml/container.js';\nimport { generateManifestXml, buildManifestEntries } from './xml/manifest.js';\nimport { generateSettingsXml } from './xml/settings.js';\nimport { generateContentHpfXml } from './xml/content-hpf.js';\nimport { generateHeaderXml } from './xml/header.js';\nimport { generateSectionXml } from './xml/section.js';\nimport { NS } from './ns.js';\n\nexport function writeHwpx(doc: HWPXDocument, _opts?: WriteOptions): Uint8Array {\n const entries: ZipEntry[] = [];\n\n // mimetype — 반드시 첫 번째, 비압축\n entries.push({\n path: 'mimetype',\n data: encodeUtf8(NS.mimeHwpx),\n store: true,\n });\n\n // META-INF/container.xml\n entries.push({\n path: 'META-INF/container.xml',\n data: encodeUtf8(generateContainerXml()),\n });\n\n // META-INF/manifest.xml\n const manifestEntries = buildManifestEntries(\n doc.sections.length,\n doc.binData.map((b) => ({ name: b.name, format: b.format })),\n );\n entries.push({\n path: 'META-INF/manifest.xml',\n data: encodeUtf8(generateManifestXml(manifestEntries)),\n });\n\n // version.xml\n entries.push({\n path: 'version.xml',\n data: encodeUtf8(generateVersionXml(doc.meta)),\n });\n\n // settings.xml\n entries.push({\n path: 'settings.xml',\n data: encodeUtf8(generateSettingsXml()),\n });\n\n // Contents/content.hpf\n entries.push({\n path: 'Contents/content.hpf',\n data: encodeUtf8(generateContentHpfXml(doc)),\n });\n\n // Contents/header.xml\n entries.push({\n path: 'Contents/header.xml',\n data: encodeUtf8(generateHeaderXml(doc.head)),\n });\n\n // Contents/section*.xml\n for (let i = 0; i < doc.sections.length; i++) {\n entries.push({\n path: `Contents/section${i}.xml`,\n data: encodeUtf8(generateSectionXml(doc.sections[i], i)),\n });\n }\n\n // BinData/*\n for (const bin of doc.binData) {\n entries.push({\n path: `BinData/${bin.name}`,\n data: bin.data,\n });\n }\n\n return createZip(entries);\n}\n","// 경량 XML 파서 — 외부 의존성 없이 HWPX XML을 파싱\n// DOMParser 없는 환경(Node.js)에서도 동작\n\nexport interface XmlNode {\n tag: string;\n attrs: Record<string, string>;\n children: XmlNode[];\n text: string;\n}\n\n/** XML 문자열을 XmlNode 트리로 파싱 */\nexport function parseXml(xml: string): XmlNode {\n const parser = new XmlParser(xml);\n return parser.parse();\n}\n\n/** 특정 태그명의 자식 노드 찾기 (네임스페이스 접두사 무시 가능) */\nexport function findChild(node: XmlNode, tag: string): XmlNode | undefined {\n return node.children.find((c) => c.tag === tag || stripNs(c.tag) === tag);\n}\n\n/** 특정 태그명의 모든 자식 노드 찾기 */\nexport function findChildren(node: XmlNode, tag: string): XmlNode[] {\n return node.children.filter((c) => c.tag === tag || stripNs(c.tag) === tag);\n}\n\n/** 네임스페이스 접두사 제거 (hh:head → head) */\nexport function stripNs(tag: string): string {\n const idx = tag.indexOf(':');\n return idx >= 0 ? tag.substring(idx + 1) : tag;\n}\n\n/** 속성값을 숫자로 파싱 (없으면 기본값) */\nexport function attrInt(node: XmlNode, name: string, defaultValue = 0): number {\n const v = node.attrs[name];\n if (v === undefined) return defaultValue;\n const n = parseInt(v, 10);\n return isNaN(n) ? defaultValue : n;\n}\n\n/** 속성값을 문자열로 (없으면 기본값) */\nexport function attrStr(node: XmlNode, name: string, defaultValue = ''): string {\n return node.attrs[name] ?? defaultValue;\n}\n\n/** 속성값을 boolean으로 ('1', 'true' → true) */\nexport function attrBool(node: XmlNode, name: string, defaultValue = false): boolean {\n const v = node.attrs[name];\n if (v === undefined) return defaultValue;\n return v === '1' || v === 'true';\n}\n\n// ─── XML Parser Implementation ───\n\nclass XmlParser {\n private xml: string;\n private pos: number;\n\n constructor(xml: string) {\n this.xml = xml;\n this.pos = 0;\n }\n\n parse(): XmlNode {\n this.skipWhitespace();\n // XML declaration 건너뛰기\n if (this.xml.startsWith('<?', this.pos)) {\n const end = this.xml.indexOf('?>', this.pos);\n if (end >= 0) this.pos = end + 2;\n }\n this.skipWhitespace();\n return this.parseElement();\n }\n\n private parseElement(): XmlNode {\n this.expect('<');\n const tag = this.readTagName();\n const attrs = this.readAttributes();\n\n this.skipWhitespace();\n\n // Self-closing tag\n if (this.xml.startsWith('/>', this.pos)) {\n this.pos += 2;\n return { tag, attrs, children: [], text: '' };\n }\n\n this.expect('>');\n\n // Children and text content\n const children: XmlNode[] = [];\n let text = '';\n let hasChildElements = false;\n\n while (this.pos < this.xml.length) {\n if (this.xml.startsWith('</', this.pos)) {\n // Closing tag\n this.pos += 2;\n const closingTag = this.readTagName();\n this.skipWhitespace();\n this.expect('>');\n // 자식 요소가 있으면 formatting 공백 trim, 텍스트 전용이면 보존\n const finalText = hasChildElements ? text.trim() : text;\n return { tag, attrs, children, text: finalText };\n }\n\n if (this.xml.startsWith('<!--', this.pos)) {\n // Comment — skip\n const end = this.xml.indexOf('-->', this.pos);\n if (end >= 0) this.pos = end + 3;\n continue;\n }\n\n if (this.xml.startsWith('<![CDATA[', this.pos)) {\n const end = this.xml.indexOf(']]>', this.pos);\n if (end >= 0) {\n text += this.xml.substring(this.pos + 9, end);\n this.pos = end + 3;\n }\n continue;\n }\n\n if (this.xml[this.pos] === '<') {\n hasChildElements = true;\n children.push(this.parseElement());\n } else {\n // Text content\n const nextTag = this.xml.indexOf('<', this.pos);\n if (nextTag >= 0) {\n text += this.xml.substring(this.pos, nextTag);\n this.pos = nextTag;\n } else {\n text += this.xml.substring(this.pos);\n this.pos = this.xml.length;\n }\n }\n }\n\n const finalText = hasChildElements ? text.trim() : text;\n return { tag, attrs, children, text: finalText };\n }\n\n private readTagName(): string {\n const start = this.pos;\n while (this.pos < this.xml.length) {\n const ch = this.xml[this.pos];\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r' || ch === '>' || ch === '/') break;\n this.pos++;\n }\n return this.xml.substring(start, this.pos);\n }\n\n private readAttributes(): Record<string, string> {\n const attrs: Record<string, string> = {};\n\n while (this.pos < this.xml.length) {\n this.skipWhitespace();\n const ch = this.xml[this.pos];\n if (ch === '>' || ch === '/') break;\n\n const name = this.readAttrName();\n this.skipWhitespace();\n this.expect('=');\n this.skipWhitespace();\n const value = this.readAttrValue();\n attrs[name] = this.unescapeXml(value);\n }\n\n return attrs;\n }\n\n private readAttrName(): string {\n const start = this.pos;\n while (this.pos < this.xml.length) {\n const ch = this.xml[this.pos];\n if (ch === '=' || ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '>' || ch === '/') break;\n this.pos++;\n }\n return this.xml.substring(start, this.pos);\n }\n\n private readAttrValue(): string {\n const quote = this.xml[this.pos];\n if (quote !== '\"' && quote !== \"'\") {\n throw new Error(`Expected quote at pos ${this.pos}`);\n }\n this.pos++;\n const start = this.pos;\n const end = this.xml.indexOf(quote, this.pos);\n if (end < 0) throw new Error(`Unterminated attribute value at pos ${start}`);\n this.pos = end + 1;\n return this.xml.substring(start, end);\n }\n\n private skipWhitespace(): void {\n while (this.pos < this.xml.length) {\n const ch = this.xml[this.pos];\n if (ch !== ' ' && ch !== '\\t' && ch !== '\\n' && ch !== '\\r') break;\n this.pos++;\n }\n }\n\n private expect(ch: string): void {\n if (!this.xml.startsWith(ch, this.pos)) {\n throw new Error(\n `Expected \"${ch}\" at pos ${this.pos}, got \"${this.xml.substring(this.pos, this.pos + 10)}\"`,\n );\n }\n this.pos += ch.length;\n }\n\n private unescapeXml(str: string): string {\n return str\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\");\n }\n}\n","import type {\n DocumentHead,\n CharProperty,\n ParaProperty,\n FontFace,\n FontLang,\n Style,\n BorderFill,\n BorderLine,\n BorderLineType,\n BorderWidth,\n UnderlineType,\n StrikeoutType,\n Alignment,\n SlashType,\n FillBrush,\n BulletProperty,\n NumberingProperty,\n NumberingLevel,\n NumberFormat,\n} from '../../../types.js';\nimport {\n parseXml,\n findChild,\n findChildren,\n stripNs,\n attrInt,\n attrStr,\n attrBool,\n type XmlNode,\n} from './parser.js';\n\nexport function parseHeaderXml(xml: string): DocumentHead {\n const root = parseXml(xml);\n\n return {\n fontFaces: parseFontFaces(root),\n borderFills: parseBorderFills(root),\n charProperties: parseCharProperties(root),\n paraProperties: parseParaProperties(root),\n styles: parseStyles(root),\n bulletProperties: parseBullets(root),\n numberingProperties: parseNumberings(root),\n compatibleDoc: parseCompatibleDoc(root),\n };\n}\n\nfunction parseFontFaces(root: XmlNode): FontFace[] {\n const faces: FontFace[] = [];\n const fontfacesNode = findChild(root, 'hh:fontfaces');\n if (!fontfacesNode) return faces;\n\n for (const faceNode of findChildren(fontfacesNode, 'hh:fontface')) {\n const lang = attrStr(faceNode, 'lang', 'HANGUL') as FontLang;\n for (const fontNode of findChildren(faceNode, 'hh:font')) {\n faces.push({\n lang,\n fontName: attrStr(fontNode, 'face'),\n fontType: (attrStr(fontNode, 'type', 'ttf') as 'ttf' | 'hps' | 'unknown'),\n });\n }\n }\n\n return faces;\n}\n\nfunction parseBorderFills(root: XmlNode): BorderFill[] {\n const fills: BorderFill[] = [];\n const fillsNode = findChild(root, 'hh:borderFills');\n if (!fillsNode) return fills;\n\n for (const bfNode of findChildren(fillsNode, 'hh:borderFill')) {\n const leftBorder = findChild(bfNode, 'hc:leftBorder');\n const rightBorder = findChild(bfNode, 'hc:rightBorder');\n const topBorder = findChild(bfNode, 'hc:topBorder');\n const bottomBorder = findChild(bfNode, 'hc:bottomBorder');\n\n let fillBrush: FillBrush | undefined;\n const fillBrushNode = findChild(bfNode, 'hc:fillBrush');\n if (fillBrushNode) {\n const winBrush = findChild(fillBrushNode, 'hc:winBrush');\n if (winBrush) {\n fillBrush = {\n type: 'SOLID',\n faceColor: parseColor(attrStr(winBrush, 'faceColor', '#000000')),\n patternColor: winBrush.attrs['hatchColor']\n ? parseColor(attrStr(winBrush, 'hatchColor'))\n : undefined,\n };\n }\n }\n\n fills.push({\n id: attrInt(bfNode, 'id'),\n threeD: attrBool(bfNode, 'threeD'),\n shadow: attrBool(bfNode, 'shadow'),\n slash: attrStr(bfNode, 'slash', 'NONE') as SlashType,\n backSlash: attrStr(bfNode, 'backSlash', 'NONE') as SlashType,\n borders: {\n left: parseBorderLine(leftBorder),\n right: parseBorderLine(rightBorder),\n top: parseBorderLine(topBorder),\n bottom: parseBorderLine(bottomBorder),\n },\n fillBrush,\n });\n }\n\n return fills;\n}\n\nfunction parseBorderLine(node: XmlNode | undefined): BorderLine {\n if (!node) {\n return { type: 'NONE', width: '0.1mm', color: 0 };\n }\n return {\n type: attrStr(node, 'type', 'NONE') as BorderLineType,\n width: attrStr(node, 'width', '0.1mm') as BorderWidth,\n color: parseColor(attrStr(node, 'color', '#000000')),\n };\n}\n\nfunction parseCharProperties(root: XmlNode): CharProperty[] {\n const props: CharProperty[] = [];\n const propsNode = findChild(root, 'hh:charProperties');\n if (!propsNode) return props;\n\n for (const cpNode of findChildren(propsNode, 'hh:charPr')) {\n const fontRefNode = findChild(cpNode, 'hh:fontRef');\n\n props.push({\n id: attrInt(cpNode, 'id'),\n height: attrInt(cpNode, 'height', 1000),\n textColor: parseColor(attrStr(cpNode, 'textColor', '#000000')),\n shadeColor: cpNode.attrs['shadeColor']\n ? parseColor(attrStr(cpNode, 'shadeColor'))\n : undefined,\n bold: attrBool(cpNode, 'bold'),\n italic: attrBool(cpNode, 'italic'),\n underline: attrStr(cpNode, 'underline', 'NONE') as UnderlineType,\n strikeout: attrStr(cpNode, 'strikeout', 'NONE') as StrikeoutType,\n useFontSpace: attrBool(cpNode, 'useFontSpace'),\n useKerning: attrBool(cpNode, 'useKerning'),\n spacing: cpNode.attrs['spacing'] !== undefined ? attrInt(cpNode, 'spacing') : undefined,\n relSize: cpNode.attrs['relSz'] !== undefined ? attrInt(cpNode, 'relSz') : undefined,\n charOffset: cpNode.attrs['offset'] !== undefined ? attrInt(cpNode, 'offset') : undefined,\n fontRef: fontRefNode\n ? {\n hangul: attrInt(fontRefNode, 'hangul'),\n latin: attrInt(fontRefNode, 'latin'),\n hanja: attrInt(fontRefNode, 'hanja'),\n japanese: attrInt(fontRefNode, 'japanese'),\n other: attrInt(fontRefNode, 'other'),\n symbol: attrInt(fontRefNode, 'symbol'),\n user: attrInt(fontRefNode, 'user'),\n }\n : { hangul: 0, latin: 0, hanja: 0, japanese: 0, other: 0, symbol: 0, user: 0 },\n });\n }\n\n return props;\n}\n\nfunction parseParaProperties(root: XmlNode): ParaProperty[] {\n const props: ParaProperty[] = [];\n const propsNode = findChild(root, 'hh:paraProperties');\n if (!propsNode) return props;\n\n for (const ppNode of findChildren(propsNode, 'hh:paraPr')) {\n const marginNode = findChild(ppNode, 'hh:parMargin');\n const lineSpacingNode = findChild(ppNode, 'hh:lineSpacing');\n\n props.push({\n id: attrInt(ppNode, 'id'),\n alignment: (attrStr(ppNode, 'align', 'JUSTIFY') as Alignment),\n heading: ppNode.attrs['heading'] ? (ppNode.attrs['heading'] as any) : undefined,\n breakBefore: ppNode.attrs['breakBefore'] ? (ppNode.attrs['breakBefore'] as any) : undefined,\n lineSpacing: lineSpacingNode\n ? {\n type: attrStr(lineSpacingNode, 'type', 'PERCENT') as any,\n value: attrInt(lineSpacingNode, 'value', 160),\n }\n : { type: 'PERCENT', value: 160 },\n paraMargin: marginNode\n ? {\n left: attrInt(marginNode, 'left'),\n right: attrInt(marginNode, 'right'),\n indent: attrInt(marginNode, 'indent'),\n prevSpacing: attrInt(marginNode, 'prev'),\n nextSpacing: attrInt(marginNode, 'next'),\n }\n : { left: 0, right: 0, indent: 0, prevSpacing: 0, nextSpacing: 0 },\n });\n }\n\n return props;\n}\n\nfunction parseStyles(root: XmlNode): Style[] {\n const styles: Style[] = [];\n const stylesNode = findChild(root, 'hh:styles');\n if (!stylesNode) return styles;\n\n for (const sNode of findChildren(stylesNode, 'hh:style')) {\n styles.push({\n id: attrInt(sNode, 'id'),\n type: attrStr(sNode, 'type', 'PARA') as 'PARA' | 'CHAR',\n name: attrStr(sNode, 'name'),\n engName: sNode.attrs['engName'] || undefined,\n paraPrIDRef: sNode.attrs['paraPrIDRef'] !== undefined\n ? attrInt(sNode, 'paraPrIDRef')\n : undefined,\n charPrIDRef: sNode.attrs['charPrIDRef'] !== undefined\n ? attrInt(sNode, 'charPrIDRef')\n : undefined,\n nextStyleIDRef: sNode.attrs['nextStyleIDRef'] !== undefined\n ? attrInt(sNode, 'nextStyleIDRef')\n : undefined,\n });\n }\n\n return styles;\n}\n\nfunction parseNumberings(root: XmlNode): NumberingProperty[] {\n const result: NumberingProperty[] = [];\n const node = findChild(root, 'hh:numberings');\n if (!node) return result;\n\n for (const nNode of findChildren(node, 'hh:numbering')) {\n const levels: NumberingLevel[] = [];\n for (const lNode of findChildren(nNode, 'hh:paraHead')) {\n levels.push({\n format: attrStr(lNode, 'numFormat', 'DIGIT') as NumberFormat,\n start: attrInt(lNode, 'start', 1),\n prefix: lNode.attrs['prefix'] || undefined,\n suffix: lNode.attrs['suffix'] || undefined,\n });\n }\n result.push({ id: attrInt(nNode, 'id'), levels });\n }\n\n return result;\n}\n\nfunction parseBullets(root: XmlNode): BulletProperty[] {\n const result: BulletProperty[] = [];\n const node = findChild(root, 'hh:bullets');\n if (!node) return result;\n\n for (const bNode of findChildren(node, 'hh:bullet')) {\n result.push({\n id: attrInt(bNode, 'id'),\n bulletChar: attrStr(bNode, 'char', '●'),\n bulletSize: bNode.attrs['bulletSz'] !== undefined ? attrInt(bNode, 'bulletSz') : undefined,\n });\n }\n\n return result;\n}\n\nfunction parseCompatibleDoc(root: XmlNode): string | undefined {\n const node = findChild(root, 'hh:compatibleDocument');\n if (!node) return undefined;\n return attrStr(node, 'targetProgram') || undefined;\n}\n\nfunction parseColor(hex: string): number {\n const h = hex.replace('#', '');\n return parseInt(h, 16);\n}\n","import type {\n Section,\n SectionDef,\n Paragraph,\n Run,\n Table,\n TableRow,\n TableCell,\n Picture,\n CellPadding,\n PageMargin,\n ColumnDef,\n HeaderFooterDef,\n SubDocument,\n} from '../../../types.js';\nimport {\n parseXml,\n findChild,\n findChildren,\n attrInt,\n attrStr,\n type XmlNode,\n} from './parser.js';\n\nexport function parseSectionXml(xml: string): Section {\n const root = parseXml(xml);\n\n return {\n def: parseSectionDef(root),\n paragraphs: parseParagraphs(root),\n };\n}\n\nfunction parseSectionDef(root: XmlNode): SectionDef {\n const secPr = findChild(root, 'hs:secPr');\n\n if (!secPr) {\n return defaultSectionDef();\n }\n\n const pagePr = findChild(secPr, 'hs:pagePr');\n const pageMarginNode = findChild(secPr, 'hs:pageMargin');\n\n // 다단\n const colPr = findChild(secPr, 'hs:colPr');\n let columns: ColumnDef | undefined;\n if (colPr && attrInt(colPr, 'count', 1) > 1) {\n columns = {\n type: attrStr(colPr, 'type', 'NORMAL') as ColumnDef['type'],\n count: attrInt(colPr, 'count', 1),\n gap: attrInt(colPr, 'gap', 0),\n sameSizes: attrStr(colPr, 'sameSz') === '1',\n };\n }\n\n // 머리글/바닥글\n let headerFooter: HeaderFooterDef | undefined;\n const headerNode = findChild(secPr, 'hs:header');\n const footerNode = findChild(secPr, 'hs:footer');\n if (headerNode || footerNode) {\n headerFooter = {};\n if (headerNode) {\n headerFooter.header = { paragraphs: parseParagraphs(headerNode) };\n }\n if (footerNode) {\n headerFooter.footer = { paragraphs: parseParagraphs(footerNode) };\n }\n }\n\n return {\n pageWidth: pagePr ? attrInt(pagePr, 'width', 59528) : 59528,\n pageHeight: pagePr ? attrInt(pagePr, 'height', 84188) : 84188,\n landscape: pagePr ? attrStr(pagePr, 'landscape') === 'LANDSCAPE' : false,\n gutterType: pagePr\n ? (attrStr(pagePr, 'gutterType', 'LEFT_ONLY') as any)\n : 'LEFT_ONLY',\n pageMargin: pageMarginNode\n ? parsePageMargin(pageMarginNode)\n : defaultPageMargin(),\n columns,\n headerFooter,\n };\n}\n\nfunction parsePageMargin(node: XmlNode): PageMargin {\n return {\n left: attrInt(node, 'left'),\n right: attrInt(node, 'right'),\n top: attrInt(node, 'top'),\n bottom: attrInt(node, 'bottom'),\n header: attrInt(node, 'header'),\n footer: attrInt(node, 'footer'),\n gutter: attrInt(node, 'gutter'),\n };\n}\n\nfunction parseParagraphs(parent: XmlNode): Paragraph[] {\n const paragraphs: Paragraph[] = [];\n\n for (const pNode of findChildren(parent, 'hp:p')) {\n paragraphs.push(parseParagraph(pNode));\n }\n\n return paragraphs;\n}\n\nfunction parseParagraph(pNode: XmlNode): Paragraph {\n const runs: Run[] = [];\n\n for (const runNode of findChildren(pNode, 'hp:run')) {\n const charPrIDRef = attrInt(runNode, 'charPrIDRef');\n\n // Break elements\n const lineBreak = findChild(runNode, 'hp:lineBreak');\n const pageBreak = findChild(runNode, 'hp:pageBreak');\n const colBreak = findChild(runNode, 'hp:colBreak');\n\n if (lineBreak) {\n runs.push({ t: 'break', breakType: 'LINE', charPrIDRef });\n } else if (pageBreak) {\n runs.push({ t: 'break', breakType: 'PAGE', charPrIDRef });\n } else if (colBreak) {\n runs.push({ t: 'break', breakType: 'COLUMN', charPrIDRef });\n } else {\n // Table\n const tblNode = findChild(runNode, 'hp:tbl');\n if (tblNode) {\n runs.push({ t: 'table', table: parseTable(tblNode), charPrIDRef });\n continue;\n }\n\n // Picture\n const picNode = findChild(runNode, 'hp:pic');\n if (picNode) {\n runs.push({ t: 'picture', picture: parsePicture(picNode), charPrIDRef });\n continue;\n }\n\n // Text run\n const runTextNode = findChild(runNode, 'hp:runText');\n const text = runTextNode ? getTextContent(runTextNode) : '';\n runs.push({ t: 'text', text, charPrIDRef });\n }\n }\n\n return {\n paraPrIDRef: attrInt(pNode, 'paraPrIDRef'),\n styleIDRef: attrInt(pNode, 'styleIDRef'),\n runs,\n };\n}\n\n// ─── Table Parsing ───\n\nfunction parseTable(tblNode: XmlNode): Table {\n const rowCount = attrInt(tblNode, 'rowCnt', 1);\n const colCount = attrInt(tblNode, 'colCnt', 1);\n const width = attrInt(tblNode, 'width', 0);\n const borderFillIDRef = attrInt(tblNode, 'borderFillIDRef', 1);\n const cellSpacing = attrInt(tblNode, 'cellSpacing', 0);\n\n // colWidths\n const colSzNodes = findChildren(tblNode, 'hp:colSz');\n const colWidths = colSzNodes.map((n) => attrInt(n, 'width', 0));\n\n // rows\n const rows: TableRow[] = [];\n for (const trNode of findChildren(tblNode, 'hp:tr')) {\n rows.push(parseTableRow(trNode));\n }\n\n return {\n rowCount,\n colCount,\n width,\n borderFillIDRef,\n cellSpacing: cellSpacing || undefined,\n colWidths,\n rows,\n };\n}\n\nfunction parseTableRow(trNode: XmlNode): TableRow {\n const height = attrInt(trNode, 'height', 0);\n const cells: TableCell[] = [];\n\n for (const tcNode of findChildren(trNode, 'hp:tc')) {\n cells.push(parseTableCell(tcNode));\n }\n\n return { height, cells };\n}\n\nfunction parseTableCell(tcNode: XmlNode): TableCell {\n const colSpan = attrInt(tcNode, 'colSpan', 1);\n const rowSpan = attrInt(tcNode, 'rowSpan', 1);\n const width = attrInt(tcNode, 'width', 0);\n const height = attrInt(tcNode, 'height', 0);\n const borderFillIDRef = attrInt(tcNode, 'borderFillIDRef', 1);\n\n let padding: CellPadding | undefined;\n if (tcNode.attrs['paddingLeft'] !== undefined) {\n padding = {\n left: attrInt(tcNode, 'paddingLeft'),\n right: attrInt(tcNode, 'paddingRight'),\n top: attrInt(tcNode, 'paddingTop'),\n bottom: attrInt(tcNode, 'paddingBottom'),\n };\n }\n\n // subList 안의 paragraphs\n const subList = findChild(tcNode, 'hp:subList');\n const paragraphs = subList ? parseParagraphs(subList) : [];\n\n return { paragraphs, colSpan, rowSpan, width, height, borderFillIDRef, padding };\n}\n\n// ─── Picture Parsing ───\n\nfunction parsePicture(picNode: XmlNode): Picture {\n return {\n binDataIDRef: attrInt(picNode, 'binDataIDRef', 0),\n width: attrInt(picNode, 'width', 0),\n height: attrInt(picNode, 'height', 0),\n offsetX: picNode.attrs['offsetX'] !== undefined ? attrInt(picNode, 'offsetX') : undefined,\n offsetY: picNode.attrs['offsetY'] !== undefined ? attrInt(picNode, 'offsetY') : undefined,\n };\n}\n\n// ─── Helpers ───\n\nfunction getTextContent(node: XmlNode): string {\n let text = node.text;\n for (const child of node.children) {\n text += getTextContent(child);\n }\n return unescapeXml(text);\n}\n\nfunction unescapeXml(str: string): string {\n return str\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\");\n}\n\nfunction defaultSectionDef(): SectionDef {\n return {\n pageWidth: 59528,\n pageHeight: 84188,\n pageMargin: defaultPageMargin(),\n landscape: false,\n };\n}\n\nfunction defaultPageMargin(): PageMargin {\n return {\n left: 8504,\n right: 8504,\n top: 7087,\n bottom: 7087,\n header: 4252,\n footer: 4252,\n gutter: 0,\n };\n}\n","import { parseXml, findChild, findChildren, attrStr, type XmlNode } from './parser.js';\n\nexport interface ContentHpfInfo {\n title: string;\n sectionFiles: string[];\n binDataFiles: { id: string; href: string; mediaType: string }[];\n}\n\nexport function parseContentHpfXml(xml: string): ContentHpfInfo {\n const root = parseXml(xml);\n\n // metadata\n const metadata = findChild(root, 'opf:metadata');\n const titleNode = metadata ? findChild(metadata, 'opf:title') : undefined;\n const title = titleNode ? titleNode.text : '';\n\n // manifest → section files\n const manifest = findChild(root, 'opf:manifest');\n const items = manifest ? findChildren(manifest, 'opf:item') : [];\n\n const sectionFiles: string[] = [];\n const binDataFiles: { id: string; href: string; mediaType: string }[] = [];\n\n for (const item of items) {\n const id = attrStr(item, 'id');\n const href = attrStr(item, 'href');\n const mediaType = attrStr(item, 'media-type');\n\n if (id.startsWith('section')) {\n sectionFiles.push(href);\n } else if (id.startsWith('bindata')) {\n binDataFiles.push({ id, href, mediaType });\n }\n }\n\n // spine에서 순서 가져오기 (fallback)\n if (sectionFiles.length === 0) {\n const spine = findChild(root, 'opf:spine');\n if (spine) {\n for (const itemref of findChildren(spine, 'opf:itemref')) {\n const idref = attrStr(itemref, 'idref');\n if (idref.startsWith('section')) {\n sectionFiles.push(`${idref}.xml`);\n }\n }\n }\n }\n\n return { title, sectionFiles, binDataFiles };\n}\n","export class HWPXError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'HWPXError';\n }\n}\n\nexport class HWPXValidationError extends HWPXError {\n public readonly field: string;\n\n constructor(field: string, message: string) {\n super(`Validation error on \"${field}\": ${message}`);\n this.name = 'HWPXValidationError';\n this.field = field;\n }\n}\n","import type { HWPXDocument, ReadOptions, DocumentMeta, BinDataItem } from '../../types.js';\nimport { extractZip, decodeUtf8 } from './zip.js';\nimport { parseHeaderXml } from './xml/parse-header.js';\nimport { parseSectionXml } from './xml/parse-section.js';\nimport { parseContentHpfXml } from './xml/parse-content-hpf.js';\nimport { HWPXError } from '../../errors.js';\n\nexport function readHwpx(data: Uint8Array, _opts?: ReadOptions): HWPXDocument {\n const files = extractZip(data);\n\n // mimetype 검증\n const mimetype = files['mimetype'];\n if (mimetype) {\n const mt = decodeUtf8(mimetype);\n if (!mt.includes('hwp')) {\n throw new HWPXError(`Invalid mimetype: \"${mt}\"`);\n }\n }\n\n // content.hpf 파싱 → 섹션 파일 목록\n const contentHpf = getFile(files, 'Contents/content.hpf');\n const hpfInfo = parseContentHpfXml(decodeUtf8(contentHpf));\n\n // header.xml 파싱\n const headerXml = getFile(files, 'Contents/header.xml');\n const head = parseHeaderXml(decodeUtf8(headerXml));\n\n // sections 파싱\n const sections = hpfInfo.sectionFiles.map((file) => {\n const path = file.startsWith('Contents/') ? file : `Contents/${file}`;\n const sectionData = getFile(files, path);\n return parseSectionXml(decodeUtf8(sectionData));\n });\n\n // meta 구성\n const meta = parseMeta(files, hpfInfo.title);\n\n // binData 구성\n const binData = parseBinData(files, hpfInfo.binDataFiles);\n\n return { meta, head, sections, binData };\n}\n\nfunction getFile(files: Record<string, Uint8Array>, path: string): Uint8Array {\n const data = files[path];\n if (!data) {\n throw new HWPXError(`Required file not found in HWPX archive: ${path}`);\n }\n return data;\n}\n\nfunction parseMeta(\n files: Record<string, Uint8Array>,\n title: string,\n): DocumentMeta {\n const meta: DocumentMeta = {\n hwpVersion: '5.1.0.1',\n title: title || undefined,\n };\n\n // version.xml에서 버전 정보 추출\n const versionData = files['version.xml'];\n if (versionData) {\n const versionXml = decodeUtf8(versionData);\n const versionMatch = versionXml.match(/<ha:appversion[^>]*>([^<]+)/);\n if (versionMatch) {\n meta.hwpVersion = versionMatch[1];\n }\n }\n\n return meta;\n}\n\nfunction parseBinData(\n files: Record<string, Uint8Array>,\n binDataFiles: { id: string; href: string; mediaType: string }[],\n): BinDataItem[] {\n const items: BinDataItem[] = [];\n\n for (let i = 0; i < binDataFiles.length; i++) {\n const { href, mediaType } = binDataFiles[i];\n // href는 상대경로(../BinData/xxx) 또는 절대경로\n const cleanPath = href.replace(/^\\.\\.\\//, '');\n const path = cleanPath.startsWith('BinData/') ? cleanPath : `BinData/${cleanPath}`;\n const data = files[path];\n if (!data) continue;\n\n const name = path.replace('BinData/', '');\n const format = mediaTypeToFormat(mediaType);\n\n items.push({\n id: i + 1,\n format,\n name,\n data,\n });\n }\n\n return items;\n}\n\nfunction mediaTypeToFormat(mediaType: string): BinDataItem['format'] {\n const map: Record<string, BinDataItem['format']> = {\n 'image/jpeg': 'jpg',\n 'image/png': 'png',\n 'image/gif': 'gif',\n 'image/bmp': 'bmp',\n 'image/tiff': 'tiff',\n 'image/x-wmf': 'wmf',\n 'image/x-emf': 'emf',\n };\n return map[mediaType] || 'png';\n}\n","// HWP 5.0 바이너리 파일 → HWPXDocument 변환\n// DocInfo + BodyText 스트림을 파싱하여 CDF IR로 변환\n\nimport { inflateSync } from 'fflate';\nimport { parseOle, type OleFile } from './ole.js';\nimport {\n parseRecords,\n TAG,\n readUtf16,\n readU16,\n readU32,\n readI32,\n type HwpRecord,\n} from './records.js';\nimport type {\n HWPXDocument,\n DocumentHead,\n DocumentMeta,\n Section,\n Paragraph,\n Run,\n TextRun,\n CharProperty,\n ParaProperty,\n FontFace,\n FontLang,\n Style,\n BorderFill,\n BorderLine,\n BorderLineType,\n BorderWidth,\n} from '../../types.js';\nimport {\n createDefaultHead,\n createDefaultMeta,\n createDefaultSectionDef,\n createDefaultBorderFill,\n} from '../../defaults.js';\nimport { HWPXError } from '../../errors.js';\n\nexport function readHwp5(data: Uint8Array): HWPXDocument {\n const ole = parseOle(data);\n\n // FileHeader에서 문서 속성 읽기\n const fileHeader = ole.getStream('FileHeader');\n const compressed = isCompressed(fileHeader);\n const hwpVersion = readHwpVersion(fileHeader);\n\n // DocInfo 파싱\n const docInfoRaw = ole.getStream('DocInfo');\n const docInfoData = compressed ? tryDecompress(docInfoRaw) : docInfoRaw;\n const docInfoRecords = parseRecords(docInfoData);\n const head = parseDocInfo(docInfoRecords);\n\n // BodyText 섹션 파싱\n const sections = parseBodyText(ole, compressed);\n\n const meta: DocumentMeta = {\n ...createDefaultMeta(),\n hwpVersion,\n };\n\n return { meta, head, sections, binData: [] };\n}\n\nfunction isCompressed(fileHeader: Uint8Array): boolean {\n if (fileHeader.length < 40) return false;\n const flags = readU32(fileHeader, 36);\n return (flags & 0x01) !== 0;\n}\n\nfunction readHwpVersion(fileHeader: Uint8Array): string {\n if (fileHeader.length < 36) return '5.0.0.0';\n const major = fileHeader[35];\n const minor = fileHeader[34];\n const build = fileHeader[33];\n const revision = fileHeader[32];\n return `${major}.${minor}.${build}.${revision}`;\n}\n\nfunction tryDecompress(data: Uint8Array): Uint8Array {\n try {\n return inflateSync(data);\n } catch {\n return data;\n }\n}\n\n// ─── DocInfo 파싱 ───\n\nfunction parseDocInfo(records: HwpRecord[]): DocumentHead {\n const head = createDefaultHead();\n head.fontFaces = [];\n head.charProperties = [];\n head.paraProperties = [];\n head.styles = [];\n head.borderFills = [];\n\n let fontId = 0;\n let charPrId = 0;\n let paraPrId = 0;\n let styleId = 0;\n let borderFillId = 1;\n\n for (const rec of records) {\n switch (rec.tagId) {\n case TAG.FACE_NAME: {\n const face = parseFaceName(rec.data, fontId);\n if (face) {\n head.fontFaces.push(face);\n fontId++;\n }\n break;\n }\n case TAG.CHAR_SHAPE: {\n const cp = parseCharShape(rec.data, charPrId);\n if (cp) {\n head.charProperties.push(cp);\n charPrId++;\n }\n break;\n }\n case TAG.PARA_SHAPE: {\n const pp = parseParaShape(rec.data, paraPrId);\n if (pp) {\n head.paraProperties.push(pp);\n paraPrId++;\n }\n break;\n }\n case TAG.STYLE: {\n const style = parseStyle(rec.data, styleId);\n if (style) {\n head.styles.push(style);\n styleId++;\n }\n break;\n }\n case TAG.BORDER_FILL: {\n const bf = parseBorderFillRecord(rec.data, borderFillId);\n if (bf) {\n head.borderFills.push(bf);\n borderFillId++;\n }\n break;\n }\n }\n }\n\n // 최소 기본값 보장\n if (head.fontFaces.length === 0) head.fontFaces = [{ lang: 'HANGUL', fontName: '함초롬돋움', fontType: 'ttf' }];\n if (head.charProperties.length === 0) head.charProperties = [{ id: 0, height: 1000, textColor: 0, fontRef: { hangul: 0, latin: 0, hanja: 0, japanese: 0, other: 0, symbol: 0, user: 0 } }];\n if (head.paraProperties.length === 0) head.paraProperties = [{ id: 0, alignment: 'JUSTIFY', lineSpacing: { type: 'PERCENT', value: 160 }, paraMargin: { left: 0, right: 0, indent: 0, prevSpacing: 0, nextSpacing: 0 } }];\n if (head.styles.length === 0) head.styles = [{ id: 0, type: 'PARA', name: '바탕글', engName: 'Normal', paraPrIDRef: 0, charPrIDRef: 0 }];\n if (head.borderFills.length === 0) head.borderFills = [createDefaultBorderFill(1)];\n\n return head;\n}\n\nfunction parseFaceName(data: Uint8Array, id: number): FontFace | null {\n if (data.length < 6) return null;\n\n const nameLen = readU16(data, 2);\n if (data.length < 4 + nameLen * 2) return null;\n\n const fontName = readUtf16(data, 4, nameLen);\n const langMap: FontLang[] = ['HANGUL', 'LATIN', 'HANJA', 'JAPANESE', 'OTHER', 'SYMBOL', 'USER'];\n const lang = langMap[id % 7] || 'HANGUL';\n\n return { lang, fontName, fontType: 'ttf' };\n}\n\nfunction parseCharShape(data: Uint8Array, id: number): CharProperty | null {\n if (data.length < 72) return null;\n\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n // 언어별 폰트 참조 (각 2바이트 × 7)\n const fontRef = {\n hangul: readU16(data, 0),\n latin: readU16(data, 2),\n hanja: readU16(data, 4),\n japanese: readU16(data, 6),\n other: readU16(data, 8),\n symbol: readU16(data, 10),\n user: readU16(data, 12),\n };\n\n // 언어별 글자 크기 (ratio): 14 ~ 27\n // 언어별 자간: 28 ~ 41\n // 언어별 상대크기: 42 ~ 55\n // 언어별 글자위치: 56 ~ 69\n\n const height = readI32(data, 70); // baseSize (1/100 pt 단위로 인코딩됨 — 실제로 height 값)\n\n let textColor = 0;\n if (data.length >= 78) {\n textColor = readU32(data, 74);\n }\n\n let bold = false;\n let italic = false;\n if (data.length >= 74) {\n const attr = readU32(data, 70);\n // 간략하게 bold/italic 추출은 어려움 — HWP5에서는 속성 비트 필드로 관리\n }\n\n return {\n id,\n height: height > 0 ? height : 1000,\n textColor: textColor & 0xffffff,\n fontRef,\n bold,\n italic,\n };\n}\n\nfunction parseParaShape(data: Uint8Array, id: number): ParaProperty | null {\n if (data.length < 8) return null;\n\n const attr = readU32(data, 0);\n const alignment = ['JUSTIFY', 'LEFT', 'RIGHT', 'CENTER', 'DISTRIBUTE', 'DISTRIBUTE_SPACE'][attr & 0x07] || 'JUSTIFY';\n\n let leftMargin = 0, rightMargin = 0, indent = 0;\n if (data.length >= 20) {\n leftMargin = readI32(data, 4);\n rightMargin = readI32(data, 8);\n indent = readI32(data, 12);\n }\n\n let prevSpacing = 0, nextSpacing = 0;\n if (data.length >= 28) {\n prevSpacing = readI32(data, 16);\n nextSpacing = readI32(data, 20);\n }\n\n let lineSpacingValue = 160;\n if (data.length >= 32) {\n lineSpacingValue = readI32(data, 24);\n }\n\n return {\n id,\n alignment: alignment as any,\n lineSpacing: { type: 'PERCENT', value: lineSpacingValue > 0 ? lineSpacingValue : 160 },\n paraMargin: {\n left: Math.max(0, leftMargin),\n right: Math.max(0, rightMargin),\n indent,\n prevSpacing: Math.max(0, prevSpacing),\n nextSpacing: Math.max(0, nextSpacing),\n },\n };\n}\n\nfunction parseStyle(data: Uint8Array, id: number): Style | null {\n if (data.length < 8) return null;\n\n // 스타일 이름 (UTF-16LE, 첫 2바이트가 길이)\n const nameLen = readU16(data, 0);\n let offset = 2;\n const name = readUtf16(data, offset, nameLen);\n offset += nameLen * 2;\n\n // 영문 이름\n let engName = '';\n if (offset + 2 <= data.length) {\n const engNameLen = readU16(data, offset);\n offset += 2;\n if (offset + engNameLen * 2 <= data.length) {\n engName = readUtf16(data, offset, engNameLen);\n offset += engNameLen * 2;\n }\n }\n\n // 속성\n let type: 'PARA' | 'CHAR' = 'PARA';\n let paraPrIDRef = 0;\n let charPrIDRef = 0;\n if (offset + 4 <= data.length) {\n const styleType = data[offset];\n type = styleType === 1 ? 'CHAR' : 'PARA';\n offset += 1;\n }\n\n return {\n id,\n type,\n name: name || `Style${id}`,\n engName: engName || undefined,\n paraPrIDRef,\n charPrIDRef,\n };\n}\n\nfunction parseBorderFillRecord(data: Uint8Array, id: number): BorderFill | null {\n if (data.length < 2) return null;\n // 간략화: 기본 borderFill 반환\n return createDefaultBorderFill(id);\n}\n\n// ─── BodyText 파싱 ───\n\nfunction parseBodyText(ole: OleFile, compressed: boolean): Section[] {\n const sections: Section[] = [];\n const streams = ole.listStreams();\n\n // Section0, Section1, ... 스트림 찾기\n const sectionStreams = streams\n .filter((name) => /^Section\\d+$/.test(name))\n .sort((a, b) => {\n const numA = parseInt(a.replace('Section', ''), 10);\n const numB = parseInt(b.replace('Section', ''), 10);\n return numA - numB;\n });\n\n // BodyText 하위 스트림으로도 시도\n if (sectionStreams.length === 0) {\n // OLE 엔트리에서 직접 탐색\n for (const entry of ole.entries) {\n if (/^Section\\d+$/.test(entry.name) && entry.type === 2) {\n sectionStreams.push(entry.name);\n }\n }\n sectionStreams.sort();\n }\n\n for (const streamName of sectionStreams) {\n try {\n const raw = ole.getStream(streamName);\n const sectionData = compressed ? tryDecompress(raw) : raw;\n const records = parseRecords(sectionData);\n sections.push(parseSectionRecords(records));\n } catch {\n // 섹션 파싱 실패 시 빈 섹션\n sections.push({ def: createDefaultSectionDef(), paragraphs: [] });\n }\n }\n\n if (sections.length === 0) {\n sections.push({ def: createDefaultSectionDef(), paragraphs: [] });\n }\n\n return sections;\n}\n\nfunction parseSectionRecords(records: HwpRecord[]): Section {\n const paragraphs: Paragraph[] = [];\n let currentParaCharShapeRef = 0;\n let currentParaStyleRef = 0;\n\n for (let i = 0; i < records.length; i++) {\n const rec = records[i];\n\n if (rec.tagId === TAG.PARA_HEADER) {\n if (rec.data.length >= 4) {\n // 문단 속성\n const nCharShapeRef = readU32(rec.data, 0);\n }\n\n // 다음 PARA_TEXT 레코드 찾기\n let textRec: HwpRecord | null = null;\n let charShapeRec: HwpRecord | null = null;\n for (let j = i + 1; j < records.length && records[j].level > rec.level; j++) {\n if (records[j].tagId === TAG.PARA_TEXT && !textRec) {\n textRec = records[j];\n }\n if (records[j].tagId === TAG.PARA_CHAR_SHAPE && !charShapeRec) {\n charShapeRec = records[j];\n }\n }\n\n const text = textRec ? parseParaText(textRec.data) : '';\n const charPrIDRef = charShapeRec ? readU32(charShapeRec.data, 4) : 0;\n const paraPrIDRef = rec.data.length >= 6 ? readU16(rec.data, 4) : 0;\n const styleIDRef = rec.data.length >= 8 ? readU16(rec.data, 6) : 0;\n\n paragraphs.push({\n paraPrIDRef,\n styleIDRef,\n runs: [{ t: 'text', text, charPrIDRef }],\n });\n }\n\n if (rec.tagId === TAG.PAGE_DEF) {\n // 첫 번째 PageDef만 사용\n }\n }\n\n return {\n def: createDefaultSectionDef(),\n paragraphs,\n };\n}\n\nfunction parseParaText(data: Uint8Array): string {\n let text = '';\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n for (let offset = 0; offset + 1 < data.length; offset += 2) {\n const ch = view.getUint16(offset, true);\n\n // 제어 문자 처리\n if (ch < 0x20) {\n switch (ch) {\n case 0x0d: // paragraph break\n case 0x0a: // line break\n break;\n case 0x09: // tab\n text += '\\t';\n break;\n case 1: // reserved\n case 2: // section/column control\n case 3: // field start\n // 확장 제어 문자: 추가 데이터 건너뛰기 (8바이트)\n offset += 14;\n break;\n case 4: // field end\n case 11: // control char (inline)\n case 12: // control char (extended)\n case 15: // hyphen\n case 16: // reserved\n case 17: // reserved\n case 18: // reserved\n case 23: // reserved\n case 24: // inline object\n break;\n default:\n break;\n }\n } else {\n text += String.fromCharCode(ch);\n }\n }\n\n return text;\n}\n","// OLE2 Compound File Binary Format (MS-CFB) 파서\n// HWP 5.0 파일은 이 포맷 위에 구축됨\n\nimport { HWPXError } from '../../errors.js';\n\nconst HEADER_SIZE = 512;\nconst DIR_ENTRY_SIZE = 128;\nconst ENDOFCHAIN = 0xfffffffe;\nconst FREESECT = 0xffffffff;\nconst DIFSECT = 0xfffffffc;\nconst FATSECT = 0xfffffffd;\n\nexport interface OleEntry {\n name: string;\n type: number; // 1=storage, 2=stream, 5=root\n size: number;\n startSector: number;\n childId: number;\n leftSiblingId: number;\n rightSiblingId: number;\n}\n\nexport interface OleFile {\n entries: OleEntry[];\n getStream(name: string): Uint8Array;\n getStreamByEntry(entry: OleEntry): Uint8Array;\n listStreams(): string[];\n}\n\nexport function parseOle(data: Uint8Array): OleFile {\n if (data.length < HEADER_SIZE) {\n throw new HWPXError('File too small for OLE format');\n }\n\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n // Magic number 검증\n if (view.getUint32(0, true) !== 0xe011cfd0 || view.getUint32(4, true) !== 0xa1b11ae1) {\n throw new HWPXError('Invalid OLE magic number');\n }\n\n const sectorSize = 1 << view.getUint16(30, true); // 보통 512\n const miniSectorSize = 1 << view.getUint16(32, true); // 보통 64\n const fatSectors = view.getInt32(44, true);\n const firstDirSector = view.getInt32(48, true);\n const miniStreamCutoff = view.getUint32(56, true); // 보통 4096\n const firstMiniFatSector = view.getInt32(60, true);\n const miniSectorCount = view.getInt32(64, true);\n const firstDifatSector = view.getInt32(68, true);\n const difatCount = view.getInt32(72, true);\n\n // DIFAT (헤더에 109개 + 추가 DIFAT 섹터)\n const difat: number[] = [];\n for (let i = 0; i < 109 && i < fatSectors; i++) {\n difat.push(view.getInt32(76 + i * 4, true));\n }\n\n // 추가 DIFAT 섹터 읽기\n let difatSector = firstDifatSector;\n while (difatSector >= 0 && difatSector !== ENDOFCHAIN && difat.length < fatSectors) {\n const offset = sectorOffset(difatSector, sectorSize);\n const entriesPerSector = sectorSize / 4 - 1;\n for (let i = 0; i < entriesPerSector && difat.length < fatSectors; i++) {\n difat.push(view.getInt32(offset + i * 4, true));\n }\n difatSector = view.getInt32(offset + entriesPerSector * 4, true);\n }\n\n // FAT 구축\n const fat: number[] = [];\n for (const fatSectorIdx of difat) {\n if (fatSectorIdx < 0) break;\n const offset = sectorOffset(fatSectorIdx, sectorSize);\n for (let i = 0; i < sectorSize / 4; i++) {\n fat.push(view.getInt32(offset + i * 4, true));\n }\n }\n\n // 디렉토리 엔트리 읽기\n const dirData = readSectorChain(data, fat, firstDirSector, sectorSize);\n const entries = parseDirectoryEntries(dirData);\n\n // Mini FAT 구축\n let miniFat: number[] = [];\n if (firstMiniFatSector >= 0 && firstMiniFatSector !== ENDOFCHAIN) {\n const miniFatData = readSectorChain(data, fat, firstMiniFatSector, sectorSize);\n const miniFatView = new DataView(miniFatData.buffer, miniFatData.byteOffset, miniFatData.byteLength);\n for (let i = 0; i < miniFatData.length / 4; i++) {\n miniFat.push(miniFatView.getInt32(i * 4, true));\n }\n }\n\n // Mini stream (root entry의 데이터)\n let miniStream: Uint8Array = new Uint8Array(0);\n if (entries.length > 0 && entries[0].startSector >= 0) {\n miniStream = readSectorChain(data, fat, entries[0].startSector, sectorSize);\n }\n\n function getStreamByEntry(entry: OleEntry): Uint8Array {\n if (entry.size === 0) return new Uint8Array(0);\n\n if (entry.size < miniStreamCutoff) {\n // mini stream에서 읽기\n return readMiniSectorChain(miniStream, miniFat, entry.startSector, miniSectorSize, entry.size);\n } else {\n // 일반 섹터 체인에서 읽기\n const raw = readSectorChain(data, fat, entry.startSector, sectorSize);\n return raw.slice(0, entry.size);\n }\n }\n\n function getStream(name: string): Uint8Array {\n const entry = entries.find((e) => e.name === name && e.type === 2);\n if (!entry) {\n throw new HWPXError(`OLE stream not found: ${name}`);\n }\n return getStreamByEntry(entry);\n }\n\n function listStreams(): string[] {\n return entries.filter((e) => e.type === 2).map((e) => e.name);\n }\n\n return { entries, getStream, getStreamByEntry, listStreams };\n}\n\nfunction sectorOffset(sector: number, sectorSize: number): number {\n return HEADER_SIZE + sector * sectorSize;\n}\n\nfunction readSectorChain(\n data: Uint8Array,\n fat: number[],\n startSector: number,\n sectorSize: number,\n): Uint8Array {\n const sectors: number[] = [];\n let sector = startSector;\n const maxSectors = fat.length; // 무한루프 방지\n\n while (sector >= 0 && sector !== ENDOFCHAIN && sectors.length < maxSectors) {\n sectors.push(sector);\n sector = fat[sector] ?? ENDOFCHAIN;\n }\n\n const result = new Uint8Array(sectors.length * sectorSize);\n for (let i = 0; i < sectors.length; i++) {\n const offset = sectorOffset(sectors[i], sectorSize);\n const chunk = data.subarray(offset, offset + sectorSize);\n result.set(chunk, i * sectorSize);\n }\n\n return result;\n}\n\nfunction readMiniSectorChain(\n miniStream: Uint8Array,\n miniFat: number[],\n startSector: number,\n miniSectorSize: number,\n size: number,\n): Uint8Array {\n const sectors: number[] = [];\n let sector = startSector;\n const maxSectors = miniFat.length;\n\n while (sector >= 0 && sector !== ENDOFCHAIN && sectors.length < maxSectors) {\n sectors.push(sector);\n sector = miniFat[sector] ?? ENDOFCHAIN;\n }\n\n const result = new Uint8Array(sectors.length * miniSectorSize);\n for (let i = 0; i < sectors.length; i++) {\n const offset = sectors[i] * miniSectorSize;\n const chunk = miniStream.subarray(offset, offset + miniSectorSize);\n result.set(chunk, i * miniSectorSize);\n }\n\n return result.slice(0, size);\n}\n\nfunction parseDirectoryEntries(data: Uint8Array): OleEntry[] {\n const entries: OleEntry[] = [];\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n for (let offset = 0; offset + DIR_ENTRY_SIZE <= data.length; offset += DIR_ENTRY_SIZE) {\n const nameLen = view.getUint16(offset + 64, true);\n if (nameLen === 0) continue;\n\n // UTF-16LE 이름 디코딩\n const nameBytes = data.subarray(offset, offset + nameLen - 2); // -2: null terminator 제외\n let name = '';\n for (let i = 0; i < nameBytes.length; i += 2) {\n const code = nameBytes[i] | (nameBytes[i + 1] << 8);\n if (code === 0) break;\n name += String.fromCharCode(code);\n }\n\n const type = data[offset + 66];\n const startSector = view.getInt32(offset + 116, true);\n const size = view.getUint32(offset + 120, true);\n const leftSiblingId = view.getInt32(offset + 68, true);\n const rightSiblingId = view.getInt32(offset + 72, true);\n const childId = view.getInt32(offset + 76, true);\n\n entries.push({\n name,\n type,\n size,\n startSector,\n childId,\n leftSiblingId,\n rightSiblingId,\n });\n }\n\n return entries;\n}\n","// HWP 5.0 Record 기반 바이너리 스트림 파서\n// 각 레코드: TagID(10bit) + Level(10bit) + Size(12bit) + Data\n\nexport interface HwpRecord {\n tagId: number;\n level: number;\n size: number;\n data: Uint8Array;\n}\n\n// 주요 Tag IDs (DocInfo)\nexport const TAG = {\n DOCUMENT_PROPERTIES: 16,\n ID_MAPPINGS: 17,\n BIN_DATA: 18,\n FACE_NAME: 19,\n BORDER_FILL: 20,\n CHAR_SHAPE: 21,\n TAB_DEF: 22,\n NUMBERING: 23,\n BULLET: 24,\n PARA_SHAPE: 25,\n STYLE: 26,\n // BodyText\n PARA_HEADER: 66,\n PARA_TEXT: 67,\n PARA_CHAR_SHAPE: 68,\n PARA_LINE_SEG: 69,\n CTRL_HEADER: 71,\n PAGE_DEF: 72,\n FOOTNOTE_SHAPE: 73,\n PAGE_BORDER_FILL: 74,\n LIST_HEADER: 75,\n TABLE: 79,\n CTRL_DATA: 80,\n SHAPE_COMPONENT: 82,\n} as const;\n\n/** 바이너리 데이터에서 HWP 레코드 스트림 파싱 */\nexport function parseRecords(data: Uint8Array): HwpRecord[] {\n const records: HwpRecord[] = [];\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n let offset = 0;\n\n while (offset + 4 <= data.length) {\n const header = view.getUint32(offset, true);\n const tagId = header & 0x3ff;\n const level = (header >> 10) & 0x3ff;\n let size = (header >> 20) & 0xfff;\n\n offset += 4;\n\n // 확장 크기 (size가 0xFFF이면 다음 4바이트가 실제 크기)\n if (size === 0xfff) {\n if (offset + 4 > data.length) break;\n size = view.getUint32(offset, true);\n offset += 4;\n }\n\n if (offset + size > data.length) break;\n\n records.push({\n tagId,\n level,\n size,\n data: data.subarray(offset, offset + size),\n });\n\n offset += size;\n }\n\n return records;\n}\n\n/** 레코드 데이터에서 UTF-16LE 문자열 읽기 */\nexport function readUtf16(data: Uint8Array, offset: number, charCount: number): string {\n let str = '';\n for (let i = 0; i < charCount; i++) {\n const code = data[offset + i * 2] | (data[offset + i * 2 + 1] << 8);\n if (code === 0) break;\n str += String.fromCharCode(code);\n }\n return str;\n}\n\n/** 레코드 데이터에서 uint16 읽기 */\nexport function readU16(data: Uint8Array, offset: number): number {\n return data[offset] | (data[offset + 1] << 8);\n}\n\n/** 레코드 데이터에서 uint32 읽기 */\nexport function readU32(data: Uint8Array, offset: number): number {\n return (\n data[offset] |\n (data[offset + 1] << 8) |\n (data[offset + 2] << 16) |\n (data[offset + 3] << 24)\n ) >>> 0;\n}\n\n/** 레코드 데이터에서 int32 읽기 */\nexport function readI32(data: Uint8Array, offset: number): number {\n return data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24);\n}\n","// HWPUNIT = 1/7200 inch\nconst HWPUNIT_PER_INCH = 7200;\nconst MM_PER_INCH = 25.4;\nconst PT_PER_INCH = 72;\n\nexport function mmToHwpunit(mm: number): number {\n return Math.round((mm / MM_PER_INCH) * HWPUNIT_PER_INCH);\n}\n\nexport function hwpunitToMm(hu: number): number {\n return (hu / HWPUNIT_PER_INCH) * MM_PER_INCH;\n}\n\nexport function ptToHwpunit(pt: number): number {\n return Math.round((pt / PT_PER_INCH) * HWPUNIT_PER_INCH);\n}\n\nexport function hwpunitToPt(hu: number): number {\n return (hu / HWPUNIT_PER_INCH) * PT_PER_INCH;\n}\n\nexport function pxToHwpunit(px: number, dpi = 96): number {\n return Math.round((px / dpi) * HWPUNIT_PER_INCH);\n}\n\nexport function hwpunitToPx(hu: number, dpi = 96): number {\n return (hu / HWPUNIT_PER_INCH) * dpi;\n}\n\n/** 한글 글자 크기 단위: 1pt = 100 unit */\nexport function ptToCharHeight(pt: number): number {\n return Math.round(pt * 100);\n}\n\nexport function charHeightToPt(height: number): number {\n return height / 100;\n}\n","// COLORREF format: 0x00BBGGRR (little-endian BGR)\n\nexport function hexToColorref(hex: string): number {\n const h = hex.replace('#', '');\n const r = parseInt(h.substring(0, 2), 16);\n const g = parseInt(h.substring(2, 4), 16);\n const b = parseInt(h.substring(4, 6), 16);\n return (b << 16) | (g << 8) | r;\n}\n\nexport function colorrefToHex(colorref: number): string {\n const r = colorref & 0xff;\n const g = (colorref >> 8) & 0xff;\n const b = (colorref >> 16) & 0xff;\n return '#' + [r, g, b].map((c) => c.toString(16).padStart(2, '0')).join('');\n}\n\n/** COLORREF를 \"R, G, B\" 형식 문자열로 */\nexport function colorrefToRgbString(colorref: number): string {\n const r = colorref & 0xff;\n const g = (colorref >> 8) & 0xff;\n const b = (colorref >> 16) & 0xff;\n return `${r}, ${g}, ${b}`;\n}\n\n/** 0x00RRGGBB (일반 RGB 정수)를 COLORREF로 변환 */\nexport function rgbToColorref(rgb: number): number {\n const r = (rgb >> 16) & 0xff;\n const g = (rgb >> 8) & 0xff;\n const b = rgb & 0xff;\n return (b << 16) | (g << 8) | r;\n}\n","import type {\n HWPXDocument,\n DocumentMeta,\n DocumentHead,\n Section,\n SectionDef,\n CharProperty,\n ParaProperty,\n FontFace,\n Style,\n BorderFill,\n FontRef,\n PageMargin,\n} from './types.js';\nimport { mmToHwpunit, ptToCharHeight } from './utils/units.js';\nimport { hexToColorref } from './utils/color.js';\n\n// ─── 기본 폰트 참조 (모든 언어에 index 0) ───\n\nfunction defaultFontRef(): FontRef {\n return { hangul: 0, latin: 0, hanja: 0, japanese: 0, other: 0, symbol: 0, user: 0 };\n}\n\n// ─── 기본 폰트 페이스 ───\n\nexport function createDefaultFontFaces(): FontFace[] {\n return [\n { lang: 'HANGUL', fontName: '함초롬돋움', fontType: 'ttf' },\n { lang: 'LATIN', fontName: '함초롬돋움', fontType: 'ttf' },\n { lang: 'HANJA', fontName: '함초롬돋움', fontType: 'ttf' },\n { lang: 'JAPANESE', fontName: '함초롬돋움', fontType: 'ttf' },\n { lang: 'OTHER', fontName: '함초롬돋움', fontType: 'ttf' },\n { lang: 'SYMBOL', fontName: '함초롬돋움', fontType: 'ttf' },\n { lang: 'USER', fontName: '함초롬돋움', fontType: 'ttf' },\n ];\n}\n\n// ─── 기본 글자 속성 ───\n\nexport function createDefaultCharProperty(id = 0): CharProperty {\n return {\n id,\n height: ptToCharHeight(10), // 10pt\n textColor: hexToColorref('#000000'),\n bold: false,\n italic: false,\n underline: 'NONE',\n strikeout: 'NONE',\n fontRef: defaultFontRef(),\n useFontSpace: false,\n useKerning: true,\n relSize: 100,\n spacing: 0,\n charOffset: 0,\n };\n}\n\n// ─── 기본 문단 속성 ───\n\nexport function createDefaultParaProperty(id = 0): ParaProperty {\n return {\n id,\n alignment: 'JUSTIFY',\n lineSpacing: { type: 'PERCENT', value: 160 },\n paraMargin: {\n left: 0,\n right: 0,\n indent: 0,\n prevSpacing: 0,\n nextSpacing: 0,\n },\n };\n}\n\n// ─── 기본 테두리/배경 ───\n\nexport function createDefaultBorderFill(id = 1): BorderFill {\n const noBorder = {\n type: 'NONE' as const,\n width: '0.1mm' as const,\n color: hexToColorref('#000000'),\n };\n return {\n id,\n borders: {\n left: { ...noBorder },\n right: { ...noBorder },\n top: { ...noBorder },\n bottom: { ...noBorder },\n },\n };\n}\n\n// ─── 기본 스타일 ───\n\nexport function createDefaultStyles(): Style[] {\n return [\n {\n id: 0,\n type: 'PARA',\n name: '바탕글',\n engName: 'Normal',\n paraPrIDRef: 0,\n charPrIDRef: 0,\n nextStyleIDRef: 0,\n },\n ];\n}\n\n// ─── 기본 페이지 설정 (A4) ───\n\nexport function createDefaultSectionDef(): SectionDef {\n return {\n pageWidth: mmToHwpunit(210),\n pageHeight: mmToHwpunit(297),\n pageMargin: createDefaultPageMargin(),\n landscape: false,\n gutterType: 'LEFT_ONLY',\n };\n}\n\nexport function createDefaultPageMargin(): PageMargin {\n return {\n left: mmToHwpunit(30),\n right: mmToHwpunit(30),\n top: mmToHwpunit(25),\n bottom: mmToHwpunit(25),\n header: mmToHwpunit(15),\n footer: mmToHwpunit(15),\n gutter: 0,\n };\n}\n\n// ─── 기본 문서 Head ───\n\nexport function createDefaultHead(): DocumentHead {\n return {\n fontFaces: createDefaultFontFaces(),\n charProperties: [createDefaultCharProperty(0)],\n paraProperties: [createDefaultParaProperty(0)],\n styles: createDefaultStyles(),\n borderFills: [createDefaultBorderFill(1)],\n bulletProperties: [],\n numberingProperties: [],\n compatibleDoc: 'HWP',\n };\n}\n\n// ─── 기본 문서 Meta ───\n\nexport function createDefaultMeta(): DocumentMeta {\n return {\n hwpVersion: '5.1.0.1',\n };\n}\n\n// ─── 기본 빈 문서 ───\n\nexport function createDefaultDocument(): HWPXDocument {\n return {\n meta: createDefaultMeta(),\n head: createDefaultHead(),\n sections: [\n {\n def: createDefaultSectionDef(),\n paragraphs: [],\n },\n ],\n binData: [],\n };\n}\n","export type DocumentFormat = 'hwpx' | 'hwp5' | 'unknown';\n\n/** 바이트 데이터의 magic bytes로 문서 포맷 감지 */\nexport function detectFormat(data: Uint8Array): DocumentFormat {\n if (data.length < 4) return 'unknown';\n\n // ZIP (PK\\x03\\x04) → HWPX\n if (data[0] === 0x50 && data[1] === 0x4b && data[2] === 0x03 && data[3] === 0x04) {\n return 'hwpx';\n }\n\n // OLE Compound File (D0 CF 11 E0) → HWP5\n if (data[0] === 0xd0 && data[1] === 0xcf && data[2] === 0x11 && data[3] === 0xe0) {\n return 'hwp5';\n }\n\n return 'unknown';\n}\n","export class IdCounter {\n private value: number;\n\n constructor(start = 0) {\n this.value = start;\n }\n\n next(): number {\n return this.value++;\n }\n\n current(): number {\n return this.value;\n }\n\n reset(start = 0): void {\n this.value = start;\n }\n}\n","import type {\n HWPXDocument,\n CharProperty,\n ParaProperty,\n Paragraph,\n TextRun,\n TableRun,\n Table,\n TableRow,\n TableCell,\n Picture,\n PictureRun,\n BinDataItem,\n FontRef,\n Section,\n BorderFill,\n BorderLine,\n BorderLineType,\n} from './types.js';\nimport {\n createDefaultDocument,\n createDefaultCharProperty,\n createDefaultParaProperty,\n createDefaultSectionDef,\n createDefaultBorderFill,\n} from './defaults.js';\nimport { ptToCharHeight, mmToHwpunit } from './utils/units.js';\nimport { hexToColorref } from './utils/color.js';\nimport { IdCounter } from './utils/id.js';\n\nexport interface TextStyleOptions {\n fontSize?: number; // pt\n bold?: boolean;\n italic?: boolean;\n color?: string; // hex (#RRGGBB)\n underline?: boolean;\n strikeout?: boolean;\n fontName?: string;\n}\n\nexport interface StyledSegment {\n text: string;\n style?: TextStyleOptions;\n}\n\nexport interface PageSettings {\n width?: number; // mm\n height?: number; // mm\n landscape?: boolean;\n marginLeft?: number; // mm\n marginRight?: number; // mm\n marginTop?: number; // mm\n marginBottom?: number; // mm\n}\n\nexport interface TableOptions {\n headerRow?: boolean;\n borderStyle?: BorderLineType;\n colWidths?: number[]; // mm 단위 (미지정시 균등 분배)\n cellPadding?: number; // mm\n width?: number; // mm (미지정시 본문 폭)\n}\n\nexport interface ImageOptions {\n width: number; // mm\n height: number; // mm\n}\n\nexport interface CellMerge {\n row: number;\n col: number;\n rowSpan: number;\n colSpan: number;\n}\n\nexport interface ColumnSettings {\n count: number;\n gap?: number; // mm (기본 10mm)\n type?: 'NORMAL' | 'DISTRIBUTE' | 'PARALLEL';\n}\n\nexport interface HeaderFooterOptions {\n header?: string;\n footer?: string;\n}\n\nexport class HWPXBuilder {\n private doc: HWPXDocument;\n private charPrIdCounter: IdCounter;\n private paraPrIdCounter: IdCounter;\n private borderFillIdCounter: IdCounter;\n private binDataIdCounter: IdCounter;\n private charPrCache = new Map<string, number>();\n\n constructor() {\n this.doc = createDefaultDocument();\n // 기본 charPr(id=0), paraPr(id=0)가 이미 있으므로 1부터 시작\n this.charPrIdCounter = new IdCounter(1);\n this.paraPrIdCounter = new IdCounter(1);\n this.borderFillIdCounter = new IdCounter(2); // 기본 borderFill(id=1) 이미 있음\n this.binDataIdCounter = new IdCounter(1);\n }\n\n /** 단일 스타일 문단 추가 */\n addParagraph(text: string, style?: TextStyleOptions): this {\n const charPrId = this.getOrCreateCharPr(style);\n const para: Paragraph = {\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs: [\n {\n t: 'text',\n text,\n charPrIDRef: charPrId,\n },\n ],\n };\n this.currentSection().paragraphs.push(para);\n return this;\n }\n\n /** 복수 스타일 세그먼트로 구성된 문단 추가 */\n addStyledText(segments: StyledSegment[]): this {\n const runs: TextRun[] = segments.map((seg) => ({\n t: 'text' as const,\n text: seg.text,\n charPrIDRef: this.getOrCreateCharPr(seg.style),\n }));\n\n const para: Paragraph = {\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs,\n };\n this.currentSection().paragraphs.push(para);\n return this;\n }\n\n /** 빈 문단(빈 줄) 추가 */\n addEmptyParagraph(): this {\n const para: Paragraph = {\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs: [\n {\n t: 'text',\n text: '',\n charPrIDRef: 0,\n },\n ],\n };\n this.currentSection().paragraphs.push(para);\n return this;\n }\n\n /** 페이지 설정 변경 */\n setPageSettings(opts: PageSettings): this {\n const def = this.currentSection().def;\n if (opts.width !== undefined) def.pageWidth = mmToHwpunit(opts.width);\n if (opts.height !== undefined) def.pageHeight = mmToHwpunit(opts.height);\n if (opts.landscape !== undefined) def.landscape = opts.landscape;\n if (opts.marginLeft !== undefined) def.pageMargin.left = mmToHwpunit(opts.marginLeft);\n if (opts.marginRight !== undefined) def.pageMargin.right = mmToHwpunit(opts.marginRight);\n if (opts.marginTop !== undefined) def.pageMargin.top = mmToHwpunit(opts.marginTop);\n if (opts.marginBottom !== undefined) def.pageMargin.bottom = mmToHwpunit(opts.marginBottom);\n return this;\n }\n\n /** 테이블 추가 (string[][] 데이터, 셀 병합은 merges 옵션) */\n addTable(data: string[][], opts?: TableOptions & { merges?: CellMerge[] }): this {\n const rowCount = data.length;\n const colCount = data.length > 0 ? data[0].length : 0;\n if (rowCount === 0 || colCount === 0) return this;\n\n const secDef = this.currentSection().def;\n const bodyWidth = opts?.width\n ? mmToHwpunit(opts.width)\n : secDef.pageWidth - secDef.pageMargin.left - secDef.pageMargin.right;\n\n const colWidths = opts?.colWidths\n ? opts.colWidths.map((w) => mmToHwpunit(w))\n : Array(colCount).fill(Math.floor(bodyWidth / colCount));\n\n const borderFillId = this.getOrCreateTableBorderFill(opts?.borderStyle || 'SOLID');\n\n const cellPadding = opts?.cellPadding\n ? mmToHwpunit(opts.cellPadding)\n : mmToHwpunit(1.5);\n\n const rowHeight = mmToHwpunit(10);\n\n // 병합 맵 구축: mergedCells[row][col] = { rowSpan, colSpan } or 'hidden'\n const mergeMap = new Map<string, { rowSpan: number; colSpan: number } | 'hidden'>();\n if (opts?.merges) {\n for (const m of opts.merges) {\n mergeMap.set(`${m.row},${m.col}`, { rowSpan: m.rowSpan, colSpan: m.colSpan });\n for (let r = m.row; r < m.row + m.rowSpan; r++) {\n for (let c = m.col; c < m.col + m.colSpan; c++) {\n if (r !== m.row || c !== m.col) {\n mergeMap.set(`${r},${c}`, 'hidden');\n }\n }\n }\n }\n }\n\n const rows: TableRow[] = data.map((rowData, ri) => ({\n height: rowHeight,\n cells: rowData\n .map((cellText, ci) => {\n const key = `${ri},${ci}`;\n const mergeInfo = mergeMap.get(key);\n if (mergeInfo === 'hidden') return null; // 병합으로 숨겨진 셀\n\n const span = mergeInfo\n ? mergeInfo\n : { rowSpan: 1, colSpan: 1 };\n\n let cellWidth = 0;\n for (let c = ci; c < ci + span.colSpan && c < colWidths.length; c++) {\n cellWidth += colWidths[c];\n }\n\n return {\n paragraphs: [{\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs: [{ t: 'text' as const, text: cellText, charPrIDRef: 0 }],\n }],\n colSpan: span.colSpan,\n rowSpan: span.rowSpan,\n width: cellWidth || colWidths[ci] || colWidths[0],\n height: rowHeight * span.rowSpan,\n borderFillIDRef: borderFillId,\n padding: {\n left: cellPadding,\n right: cellPadding,\n top: cellPadding,\n bottom: cellPadding,\n },\n } as TableCell;\n })\n .filter((c): c is TableCell => c !== null),\n }));\n\n const table: Table = {\n rows,\n borderFillIDRef: borderFillId,\n width: bodyWidth,\n rowCount,\n colCount,\n colWidths,\n };\n\n const para: Paragraph = {\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs: [{ t: 'table', table, charPrIDRef: 0 }],\n };\n this.currentSection().paragraphs.push(para);\n return this;\n }\n\n /** 이미지 추가 */\n addImage(data: Uint8Array, format: BinDataItem['format'], opts: ImageOptions): this {\n const id = this.binDataIdCounter.next();\n const name = `image${id}.${format}`;\n this.doc.binData.push({ id, format, name, data });\n\n const pic: Picture = {\n binDataIDRef: id,\n width: mmToHwpunit(opts.width),\n height: mmToHwpunit(opts.height),\n };\n\n const para: Paragraph = {\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs: [{ t: 'picture', picture: pic, charPrIDRef: 0 }],\n };\n this.currentSection().paragraphs.push(para);\n return this;\n }\n\n /** 머리글/바닥글 설정 */\n setHeaderFooter(opts: HeaderFooterOptions): this {\n const def = this.currentSection().def;\n if (!def.headerFooter) def.headerFooter = {};\n\n if (opts.header !== undefined) {\n def.headerFooter.header = {\n paragraphs: [{\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs: [{ t: 'text' as const, text: opts.header, charPrIDRef: 0 }],\n }],\n };\n }\n\n if (opts.footer !== undefined) {\n def.headerFooter.footer = {\n paragraphs: [{\n paraPrIDRef: 0,\n styleIDRef: 0,\n runs: [{ t: 'text' as const, text: opts.footer, charPrIDRef: 0 }],\n }],\n };\n }\n\n return this;\n }\n\n /** 다단 설정 */\n setColumns(opts: ColumnSettings): this {\n const def = this.currentSection().def;\n def.columns = {\n type: opts.type || 'NORMAL',\n count: opts.count,\n gap: mmToHwpunit(opts.gap ?? 10),\n sameSizes: true,\n };\n return this;\n }\n\n /** 새 섹션 시작 */\n addSection(): this {\n this.doc.sections.push({\n def: createDefaultSectionDef(),\n paragraphs: [],\n });\n return this;\n }\n\n /** 문서 빌드 */\n build(): HWPXDocument {\n return this.doc;\n }\n\n // ─── Internal ───\n\n private currentSection(): Section {\n return this.doc.sections[this.doc.sections.length - 1];\n }\n\n private getOrCreateCharPr(style?: TextStyleOptions): number {\n if (!style) return 0; // 기본 charPr\n\n const key = this.styleKey(style);\n const cached = this.charPrCache.get(key);\n if (cached !== undefined) return cached;\n\n const id = this.charPrIdCounter.next();\n const base = createDefaultCharProperty(id);\n\n if (style.fontSize !== undefined) base.height = ptToCharHeight(style.fontSize);\n if (style.bold !== undefined) base.bold = style.bold;\n if (style.italic !== undefined) base.italic = style.italic;\n if (style.color !== undefined) base.textColor = hexToColorref(style.color);\n if (style.underline) base.underline = 'BOTTOM';\n if (style.strikeout) base.strikeout = 'CONTINUOUS';\n\n if (style.fontName) {\n const fontIdx = this.ensureFont(style.fontName);\n base.fontRef = {\n hangul: fontIdx,\n latin: fontIdx,\n hanja: fontIdx,\n japanese: fontIdx,\n other: fontIdx,\n symbol: fontIdx,\n user: fontIdx,\n };\n }\n\n this.doc.head.charProperties.push(base);\n this.charPrCache.set(key, id);\n return id;\n }\n\n private ensureFont(fontName: string): number {\n const faces = this.doc.head.fontFaces;\n // 같은 fontName이 이미 있는지 확인 (HANGUL 기준)\n const hangulFaces = faces.filter((f) => f.lang === 'HANGUL');\n const existing = hangulFaces.findIndex((f) => f.fontName === fontName);\n if (existing !== -1) return existing;\n\n // 새 폰트 추가 — 모든 lang에 추가\n const newIdx = hangulFaces.length;\n const langs: Array<FontRef[keyof FontRef] extends number ? never : string> = [];\n const allLangs = ['HANGUL', 'LATIN', 'HANJA', 'JAPANESE', 'OTHER', 'SYMBOL', 'USER'] as const;\n for (const lang of allLangs) {\n faces.push({ lang, fontName, fontType: 'ttf' });\n }\n return newIdx;\n }\n\n private getOrCreateTableBorderFill(lineType: BorderLineType): number {\n const line: BorderLine = {\n type: lineType,\n width: '0.12mm',\n color: hexToColorref('#000000'),\n };\n const bf: BorderFill = {\n id: this.borderFillIdCounter.next(),\n borders: {\n left: { ...line },\n right: { ...line },\n top: { ...line },\n bottom: { ...line },\n },\n };\n this.doc.head.borderFills.push(bf);\n return bf.id;\n }\n\n private styleKey(style: TextStyleOptions): string {\n return JSON.stringify({\n fs: style.fontSize,\n b: style.bold,\n i: style.italic,\n c: style.color,\n u: style.underline,\n s: style.strikeout,\n f: style.fontName,\n });\n }\n}\n","export {\n mmToHwpunit,\n hwpunitToMm,\n ptToHwpunit,\n hwpunitToPt,\n pxToHwpunit,\n hwpunitToPx,\n ptToCharHeight,\n charHeightToPt,\n} from './units.js';\n\nexport {\n hexToColorref,\n colorrefToHex,\n colorrefToRgbString,\n rgbToColorref,\n} from './color.js';\n\nexport { IdCounter } from './id.js';\nexport { detectFormat } from './detect.js';\nexport type { DocumentFormat } from './detect.js';\n","import type { HWPXDocument, WriteOptions, ReadOptions } from './types.js';\nimport { writeHwpx, readHwpx } from './codecs/hwpx/index.js';\nimport { readHwp5 } from './codecs/hwp5/index.js';\nimport { detectFormat } from './utils/detect.js';\nimport { HWPXError } from './errors.js';\n\n/**\n * HWPXDocument를 .hwpx 바이너리(Uint8Array)로 직렬화\n */\nexport function write(doc: HWPXDocument, opts?: WriteOptions): Uint8Array {\n return writeHwpx(doc, opts);\n}\n\n/**\n * .hwpx 또는 .hwp 바이너리(Uint8Array)를 HWPXDocument로 파싱\n * 포맷 자동 감지 (HWPX ZIP / HWP5 OLE)\n */\nexport function read(data: Uint8Array, opts?: ReadOptions): HWPXDocument {\n const format = detectFormat(data);\n if (format === 'hwp5') {\n return readHwp5(data);\n }\n if (format === 'unknown') {\n throw new HWPXError('Unknown file format. Expected HWPX or HWP5 file.');\n }\n return readHwpx(data, opts);\n}\n\n// ─── Re-exports ───\n\nexport { HWPXBuilder } from './builder.js';\nexport type {\n TextStyleOptions,\n StyledSegment,\n PageSettings,\n TableOptions,\n ImageOptions,\n CellMerge,\n ColumnSettings,\n HeaderFooterOptions,\n} from './builder.js';\n\nexport {\n createDefaultDocument,\n createDefaultHead,\n createDefaultMeta,\n createDefaultCharProperty,\n createDefaultParaProperty,\n createDefaultSectionDef,\n createDefaultBorderFill,\n createDefaultFontFaces,\n createDefaultStyles,\n} from './defaults.js';\n\nexport * as utils from './utils/index.js';\n\nexport { HWPXError, HWPXValidationError } from './errors.js';\n\nexport type {\n HWPXDocument,\n DocumentMeta,\n DocumentHead,\n Section,\n SectionDef,\n Paragraph,\n Run,\n TextRun,\n TableRun,\n PictureRun,\n DrawingRun,\n BreakRun,\n CharProperty,\n ParaProperty,\n FontFace,\n Style,\n BorderFill,\n BorderLine,\n FillBrush,\n Table,\n TableRow,\n TableCell,\n Picture,\n DrawingObject,\n BinDataItem,\n WriteOptions,\n ReadOptions,\n PageMargin,\n ColumnDef,\n HeaderFooterDef,\n SubDocument,\n BulletProperty,\n NumberingProperty,\n NumberingLevel,\n CellPadding,\n} from './types.js';\n"],"mappings":"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","names":["attrs","finalText"]}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "hwpx-js",
3
+ "version": "0.1.0",
4
+ "description": "Read and write HWPX/HWP documents — the Korean word processor format by Hancom",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "LICENSE",
24
+ "README.md"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "test": "vitest run",
29
+ "test:watch": "vitest",
30
+ "typecheck": "tsc --noEmit",
31
+ "lint": "eslint src/",
32
+ "prepublishOnly": "npm run build"
33
+ },
34
+ "keywords": [
35
+ "hwpx",
36
+ "hwp",
37
+ "hancom",
38
+ "hangul",
39
+ "한글",
40
+ "owpml",
41
+ "document",
42
+ "word-processor"
43
+ ],
44
+ "author": "babpulss",
45
+ "license": "Apache-2.0",
46
+ "dependencies": {
47
+ "fflate": "^0.8.2"
48
+ },
49
+ "devDependencies": {
50
+ "tsup": "^8.4.0",
51
+ "typescript": "^5.7.0",
52
+ "vitest": "^3.0.0"
53
+ }
54
+ }