kordoc 3.13.0 → 3.15.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.
Files changed (48) hide show
  1. package/README.md +14 -1
  2. package/dist/{-MRPDPE2X.js → -EYPKRLMN.js} +13 -7
  3. package/dist/{chunk-33CIKNL4.js → chunk-734GJLXH.js} +522 -135
  4. package/dist/chunk-734GJLXH.js.map +1 -0
  5. package/dist/chunk-DCZVOIEO.cjs.map +1 -1
  6. package/dist/{chunk-MEXUFQVC.cjs → chunk-DMBTOJK4.cjs} +5 -5
  7. package/dist/chunk-DMBTOJK4.cjs.map +1 -0
  8. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  9. package/dist/{chunk-TWACKS3K.js → chunk-Q3IHI3E6.js} +309 -29
  10. package/dist/chunk-Q3IHI3E6.js.map +1 -0
  11. package/dist/{chunk-YXOT7P5B.js → chunk-Q5ZPWQID.js} +5 -5
  12. package/dist/{chunk-YXOT7P5B.js.map → chunk-Q5ZPWQID.js.map} +1 -1
  13. package/dist/{chunk-Q6UXVJXI.js → chunk-SCFFABCT.js} +2 -2
  14. package/dist/{chunk-O4WFPOFN.js → chunk-ZRNYYEE6.js} +5 -5
  15. package/dist/{chunk-O4WFPOFN.js.map → chunk-ZRNYYEE6.js.map} +1 -1
  16. package/dist/cli.js +71 -10
  17. package/dist/cli.js.map +1 -1
  18. package/dist/formula-5NKVS2LR.cjs.map +1 -1
  19. package/dist/index.cjs +1002 -335
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +80 -6
  22. package/dist/index.d.ts +80 -6
  23. package/dist/index.js +881 -214
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp.js +33 -10
  26. package/dist/mcp.js.map +1 -1
  27. package/dist/page-range-P7SDW6LR.cjs.map +1 -1
  28. package/dist/{parser-XUNGOH76.js → parser-76JSTEP3.js} +55 -7
  29. package/dist/parser-76JSTEP3.js.map +1 -0
  30. package/dist/{parser-DZBI3EA2.cjs → parser-O2SD4DFR.cjs} +66 -18
  31. package/dist/parser-O2SD4DFR.cjs.map +1 -0
  32. package/dist/{parser-Z3IL2ESY.js → parser-SNBQZO5E.js} +54 -6
  33. package/dist/parser-SNBQZO5E.js.map +1 -0
  34. package/dist/provider-G4C2V2PD.cjs.map +1 -1
  35. package/dist/render-LDI3LO2P.js +9 -0
  36. package/dist/{watch-G5NFIT5L.js → watch-LEK5U5P6.js} +5 -5
  37. package/package.json +4 -3
  38. package/dist/chunk-33CIKNL4.js.map +0 -1
  39. package/dist/chunk-MEXUFQVC.cjs.map +0 -1
  40. package/dist/chunk-TWACKS3K.js.map +0 -1
  41. package/dist/parser-DZBI3EA2.cjs.map +0 -1
  42. package/dist/parser-XUNGOH76.js.map +0 -1
  43. package/dist/parser-Z3IL2ESY.js.map +0 -1
  44. package/dist/render-VZ4OGHZU.js +0 -9
  45. /package/dist/{-MRPDPE2X.js.map → -EYPKRLMN.js.map} +0 -0
  46. /package/dist/{chunk-Q6UXVJXI.js.map → chunk-SCFFABCT.js.map} +0 -0
  47. /package/dist/{render-VZ4OGHZU.js.map → render-LDI3LO2P.js.map} +0 -0
  48. /package/dist/{watch-G5NFIT5L.js.map → watch-LEK5U5P6.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -19,7 +19,7 @@
19
19
 
20
20
 
21
21
 
22
- var _chunkMEXUFQVCcjs = require('./chunk-MEXUFQVC.cjs');
22
+ var _chunkDMBTOJK4cjs = require('./chunk-DMBTOJK4.cjs');
23
23
 
24
24
 
25
25
  var _chunkDCZVOIEOcjs = require('./chunk-DCZVOIEO.cjs');
@@ -405,7 +405,7 @@ function createSectionShared() {
405
405
  function createXmlParser(warnings) {
406
406
  return new (0, _xmldom.DOMParser)({
407
407
  onError(level, msg2) {
408
- if (level === "fatalError") throw new (0, _chunkMEXUFQVCcjs.KordocError)(`XML \uD30C\uC2F1 \uC2E4\uD328: ${msg2}`);
408
+ if (level === "fatalError") throw new (0, _chunkDMBTOJK4cjs.KordocError)(`XML \uD30C\uC2F1 \uC2E4\uD328: ${msg2}`);
409
409
  _optionalChain([warnings, 'optionalAccess', _3 => _3.push, 'call', _4 => _4({ code: "MALFORMED_XML", message: `XML ${level === "warn" ? "\uACBD\uACE0" : "\uC624\uB958"}: ${msg2}` })]);
410
410
  }
411
411
  });
@@ -460,10 +460,10 @@ async function extractHwpxStyles(zip, decompressed) {
460
460
  const xml = await file.async("text");
461
461
  if (decompressed) {
462
462
  decompressed.total += xml.length * 2;
463
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
463
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
464
464
  }
465
465
  const parser = createXmlParser();
466
- const doc = parser.parseFromString(_chunkMEXUFQVCcjs.stripDtd.call(void 0, xml), "text/xml");
466
+ const doc = parser.parseFromString(_chunkDMBTOJK4cjs.stripDtd.call(void 0, xml), "text/xml");
467
467
  if (!doc.documentElement) continue;
468
468
  parseCharProperties(doc, result.charProperties);
469
469
  parseStyleElements(doc, result.styles);
@@ -481,9 +481,9 @@ async function extractHwpxStyles(zip, decompressed) {
481
481
  function parseCharProperties(doc, map) {
482
482
  const tagNames = ["hh:charPr", "charPr", "hp:charPr"];
483
483
  for (const tagName of tagNames) {
484
- const elements2 = doc.getElementsByTagName(tagName);
485
- for (let i = 0; i < elements2.length; i++) {
486
- const el = elements2[i];
484
+ const elements3 = doc.getElementsByTagName(tagName);
485
+ for (let i = 0; i < elements3.length; i++) {
486
+ const el = elements3[i];
487
487
  const id = el.getAttribute("id") || el.getAttribute("IDRef") || "";
488
488
  if (!id) continue;
489
489
  const prop = {};
@@ -517,9 +517,9 @@ function parseCharProperties(doc, map) {
517
517
  function parseStyleElements(doc, map) {
518
518
  const tagNames = ["hh:style", "style", "hp:style"];
519
519
  for (const tagName of tagNames) {
520
- const elements2 = doc.getElementsByTagName(tagName);
521
- for (let i = 0; i < elements2.length; i++) {
522
- const el = elements2[i];
520
+ const elements3 = doc.getElementsByTagName(tagName);
521
+ for (let i = 0; i < elements3.length; i++) {
522
+ const el = elements3[i];
523
523
  const id = el.getAttribute("id") || el.getAttribute("IDRef") || String(i);
524
524
  const name = el.getAttribute("name") || el.getAttribute("engName") || "";
525
525
  const charPrId = el.getAttribute("charPrIDRef") || void 0;
@@ -531,9 +531,9 @@ function parseStyleElements(doc, map) {
531
531
  function parseNumberings(doc, map) {
532
532
  const tagNames = ["hh:numbering", "numbering"];
533
533
  for (const tagName of tagNames) {
534
- const elements2 = doc.getElementsByTagName(tagName);
535
- for (let i = 0; i < elements2.length; i++) {
536
- const el = elements2[i];
534
+ const elements3 = doc.getElementsByTagName(tagName);
535
+ for (let i = 0; i < elements3.length; i++) {
536
+ const el = elements3[i];
537
537
  const id = el.getAttribute("id") || "";
538
538
  if (!id) continue;
539
539
  const def = { heads: /* @__PURE__ */ new Map() };
@@ -560,9 +560,9 @@ function parseNumberings(doc, map) {
560
560
  function parseBullets(doc, map) {
561
561
  const tagNames = ["hh:bullet", "bullet"];
562
562
  for (const tagName of tagNames) {
563
- const elements2 = doc.getElementsByTagName(tagName);
564
- for (let i = 0; i < elements2.length; i++) {
565
- const el = elements2[i];
563
+ const elements3 = doc.getElementsByTagName(tagName);
564
+ for (let i = 0; i < elements3.length; i++) {
565
+ const el = elements3[i];
566
566
  const id = el.getAttribute("id") || "";
567
567
  const char = el.getAttribute("char") || "";
568
568
  if (id && char) map.set(id, char);
@@ -573,9 +573,9 @@ function parseBullets(doc, map) {
573
573
  function parseParaHeadings(doc, map) {
574
574
  const tagNames = ["hh:paraPr", "paraPr"];
575
575
  for (const tagName of tagNames) {
576
- const elements2 = doc.getElementsByTagName(tagName);
577
- for (let i = 0; i < elements2.length; i++) {
578
- const el = elements2[i];
576
+ const elements3 = doc.getElementsByTagName(tagName);
577
+ for (let i = 0; i < elements3.length; i++) {
578
+ const el = elements3[i];
579
579
  const id = el.getAttribute("id") || "";
580
580
  if (!id) continue;
581
581
  const heading = findChildByLocalName(el, "heading");
@@ -615,9 +615,9 @@ function detectHwpxHeadings(blocks, styleMap) {
615
615
  let level = 0;
616
616
  if (baseFontSize > 0 && _optionalChain([block, 'access', _7 => _7.style, 'optionalAccess', _8 => _8.fontSize])) {
617
617
  const ratio = block.style.fontSize / baseFontSize;
618
- if (ratio >= _chunkMEXUFQVCcjs.HEADING_RATIO_H1) level = 1;
619
- else if (ratio >= _chunkMEXUFQVCcjs.HEADING_RATIO_H2) level = 2;
620
- else if (ratio >= _chunkMEXUFQVCcjs.HEADING_RATIO_H3) level = 3;
618
+ if (ratio >= _chunkDMBTOJK4cjs.HEADING_RATIO_H1) level = 1;
619
+ else if (ratio >= _chunkDMBTOJK4cjs.HEADING_RATIO_H2) level = 2;
620
+ else if (ratio >= _chunkDMBTOJK4cjs.HEADING_RATIO_H3) level = 3;
621
621
  }
622
622
  const compactText = text.replace(/\s+/g, "");
623
623
  if (/^제\d+[조장절편]/.test(compactText) && text.length <= 50) {
@@ -923,10 +923,22 @@ function findEnclosingBrackets(eqString, startIdx) {
923
923
  }
924
924
  return null;
925
925
  }
926
+ function maskLiteralSpans(eqString) {
927
+ return eqString.replace(/"[^"]*"/g, (m) => "\uFFFF".repeat(m.length)).replace(/\\text\{[^}]*\}/g, (m) => "\uFFFF".repeat(m.length));
928
+ }
929
+ function findKeywordToken(eqString, word, from = 0) {
930
+ const masked = maskLiteralSpans(eqString);
931
+ for (let i = masked.indexOf(word, from); i !== -1; i = masked.indexOf(word, i + 1)) {
932
+ const okL = i === 0 || masked[i - 1] === " ";
933
+ const okR = i + word.length === masked.length || masked[i + word.length] === " ";
934
+ if (okL && okR) return i;
935
+ }
936
+ return -1;
937
+ }
926
938
  function replaceFrac(eqString) {
927
939
  const hmlFrac = "over";
928
940
  while (true) {
929
- const cursor = eqString.indexOf(hmlFrac);
941
+ const cursor = findKeywordToken(eqString, hmlFrac);
930
942
  if (cursor === -1) break;
931
943
  try {
932
944
  const [numStart, numEnd] = findBrackets(eqString, cursor, 0);
@@ -942,12 +954,12 @@ function replaceFrac(eqString) {
942
954
  }
943
955
  function replaceRootOf(eqString) {
944
956
  while (true) {
945
- const rootCursor = eqString.indexOf("root");
957
+ const rootCursor = findKeywordToken(eqString, "root");
946
958
  if (rootCursor === -1) break;
947
959
  try {
948
- const ofCursor = eqString.indexOf("of");
949
- if (ofCursor === -1) return eqString;
950
960
  const elem1 = findBrackets(eqString, rootCursor, 1);
961
+ const ofCursor = findKeywordToken(eqString, "of", elem1[1]);
962
+ if (ofCursor === -1) return eqString;
951
963
  const elem2 = findBrackets(eqString, ofCursor, 1);
952
964
  const e1 = eqString.slice(elem1[0] + 1, elem1[1] - 1);
953
965
  const e2 = eqString.slice(elem2[0] + 1, elem2[1] - 1);
@@ -1171,7 +1183,7 @@ function resolveParaHeading(paraEl, ctx) {
1171
1183
 
1172
1184
  // src/hwpx/table-build.ts
1173
1185
  function buildTableWithCellMeta(state) {
1174
- const table = _chunkMEXUFQVCcjs.buildTable.call(void 0, state.rows);
1186
+ const table = _chunkDMBTOJK4cjs.buildTable.call(void 0, state.rows);
1175
1187
  if (state.caption) table.caption = state.caption;
1176
1188
  const anchors = [];
1177
1189
  {
@@ -1241,7 +1253,7 @@ function completeTable(newTable, tableStack, blocks, ctx) {
1241
1253
  const cell = parentTable.cell;
1242
1254
  (cell.blocks ??= []).push(block);
1243
1255
  cell.hasStructure = true;
1244
- let flat = _chunkMEXUFQVCcjs.convertTableToText.call(void 0, newTable.rows);
1256
+ let flat = _chunkDMBTOJK4cjs.convertTableToText.call(void 0, newTable.rows);
1245
1257
  if (newTable.caption) flat = newTable.caption + (flat ? "\n" + flat : "");
1246
1258
  if (flat) cell.text += (cell.text ? "\n" : "") + flat;
1247
1259
  } else {
@@ -1253,7 +1265,7 @@ function completeTable(newTable, tableStack, blocks, ctx) {
1253
1265
  // src/hwpx/section-walker.ts
1254
1266
  function parseSectionXml(xml, styleMap, warnings, sectionNum, shared) {
1255
1267
  const parser = createXmlParser(warnings);
1256
- const doc = parser.parseFromString(_chunkMEXUFQVCcjs.stripDtd.call(void 0, xml), "text/xml");
1268
+ const doc = parser.parseFromString(_chunkDMBTOJK4cjs.stripDtd.call(void 0, xml), "text/xml");
1257
1269
  if (!doc.documentElement) return [];
1258
1270
  const ctx = { styleMap, warnings, sectionNum, shared: _nullishCoalesce(shared, () => ( createSectionShared())) };
1259
1271
  ctx.shared.track.deleteDepth = 0;
@@ -1344,8 +1356,8 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1344
1356
  const cs = isNaN(rawCs) ? 1 : rawCs;
1345
1357
  const rawRs = parseInt(el.getAttribute("rowSpan") || "1", 10);
1346
1358
  const rs = isNaN(rawRs) ? 1 : rawRs;
1347
- tableCtx.cell.colSpan = clampSpan(cs, _chunkMEXUFQVCcjs.MAX_COLS);
1348
- tableCtx.cell.rowSpan = clampSpan(rs, _chunkMEXUFQVCcjs.MAX_ROWS);
1359
+ tableCtx.cell.colSpan = clampSpan(cs, _chunkDMBTOJK4cjs.MAX_COLS);
1360
+ tableCtx.cell.rowSpan = clampSpan(rs, _chunkDMBTOJK4cjs.MAX_ROWS);
1349
1361
  }
1350
1362
  break;
1351
1363
  case "p": {
@@ -1567,7 +1579,7 @@ function extractHyperlinkHref(fieldBegin) {
1567
1579
  let url = (ch.textContent || "").trim();
1568
1580
  if (!url) continue;
1569
1581
  url = url.replace(/^https?:\/\/(?=https?:\/\/)/i, "");
1570
- const safe = _chunkMEXUFQVCcjs.sanitizeHref.call(void 0, url);
1582
+ const safe = _chunkDMBTOJK4cjs.sanitizeHref.call(void 0, url);
1571
1583
  if (safe) return safe;
1572
1584
  }
1573
1585
  return void 0;
@@ -1702,7 +1714,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1702
1714
  case "hyperlink": {
1703
1715
  const url = child.getAttribute("url") || child.getAttribute("href") || "";
1704
1716
  if (url) {
1705
- const safe = _chunkMEXUFQVCcjs.sanitizeHref.call(void 0, url);
1717
+ const safe = _chunkDMBTOJK4cjs.sanitizeHref.call(void 0, url);
1706
1718
  if (safe) href = safe;
1707
1719
  }
1708
1720
  walk(child);
@@ -1888,13 +1900,13 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
1888
1900
  }
1889
1901
  const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates;
1890
1902
  for (const path of allCandidates) {
1891
- if (_chunkMEXUFQVCcjs.isPathTraversal.call(void 0, path)) continue;
1903
+ if (_chunkDMBTOJK4cjs.isPathTraversal.call(void 0, path)) continue;
1892
1904
  const file = zip.file(path);
1893
1905
  if (!file) continue;
1894
1906
  try {
1895
1907
  const data = await file.async("uint8array");
1896
1908
  decompressed.total += data.length;
1897
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1909
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1898
1910
  const ext = path.includes(".") ? path.split(".").pop() || "png" : "png";
1899
1911
  const mimeType = imageExtToMime(ext);
1900
1912
  imageIndex++;
@@ -1903,7 +1915,7 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
1903
1915
  images.push(img);
1904
1916
  break;
1905
1917
  } catch (err) {
1906
- if (err instanceof _chunkMEXUFQVCcjs.KordocError) throw err;
1918
+ if (err instanceof _chunkDMBTOJK4cjs.KordocError) throw err;
1907
1919
  }
1908
1920
  }
1909
1921
  if (!img) _optionalChain([warnings, 'optionalAccess', _38 => _38.push, 'call', _39 => _39({ page: block.pageNumber, message: `\uC774\uBBF8\uC9C0 \uD30C\uC77C \uC5C6\uC74C: ${ref}`, code: "SKIPPED_IMAGE" })]);
@@ -1965,7 +1977,7 @@ function extractFromBrokenZip(buffer) {
1965
1977
  }
1966
1978
  const nameBytes = data.slice(pos + 30, pos + 30 + nameLen);
1967
1979
  const name = new TextDecoder().decode(nameBytes);
1968
- if (_chunkMEXUFQVCcjs.isPathTraversal.call(void 0, name)) {
1980
+ if (_chunkDMBTOJK4cjs.isPathTraversal.call(void 0, name)) {
1969
1981
  pos = fileStart + compSize;
1970
1982
  continue;
1971
1983
  }
@@ -1983,16 +1995,16 @@ function extractFromBrokenZip(buffer) {
1983
1995
  continue;
1984
1996
  }
1985
1997
  totalDecompressed += content.length * 2;
1986
- if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC");
1998
+ if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC");
1987
1999
  sectionNum++;
1988
2000
  blocks.push(...parseSectionXml(content, void 0, warnings, sectionNum, shared));
1989
2001
  } catch (e13) {
1990
2002
  continue;
1991
2003
  }
1992
2004
  }
1993
- if (blocks.length === 0) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC190\uC0C1\uB41C HWPX\uC5D0\uC11C \uC139\uC158 \uB370\uC774\uD130\uB97C \uBCF5\uAD6C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
2005
+ if (blocks.length === 0) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC190\uC0C1\uB41C HWPX\uC5D0\uC11C \uC139\uC158 \uB370\uC774\uD130\uB97C \uBCF5\uAD6C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1994
2006
  applyPageText(blocks, shared);
1995
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, blocks);
2007
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, blocks);
1996
2008
  return { markdown, blocks, warnings: warnings.length > 0 ? warnings : void 0 };
1997
2009
  }
1998
2010
  async function resolveSectionPaths(zip) {
@@ -2006,18 +2018,18 @@ async function resolveSectionPaths(zip) {
2006
2018
  if (paths.length > 0) return paths;
2007
2019
  }
2008
2020
  const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/);
2009
- return sectionFiles.map((f) => f.name).sort(_chunkMEXUFQVCcjs.compareSectionPaths);
2021
+ return sectionFiles.map((f) => f.name).sort(_chunkDMBTOJK4cjs.compareSectionPaths);
2010
2022
  }
2011
2023
  function parseSectionPathsFromManifest(xml) {
2012
2024
  const parser = createXmlParser();
2013
- const doc = parser.parseFromString(_chunkMEXUFQVCcjs.stripDtd.call(void 0, xml), "text/xml");
2025
+ const doc = parser.parseFromString(_chunkDMBTOJK4cjs.stripDtd.call(void 0, xml), "text/xml");
2014
2026
  const items = doc.getElementsByTagName("opf:item");
2015
2027
  const spine = doc.getElementsByTagName("opf:itemref");
2016
2028
  const idToHref = /* @__PURE__ */ new Map();
2017
2029
  for (let i = 0; i < items.length; i++) {
2018
2030
  const item = items[i];
2019
2031
  const id = item.getAttribute("id") || "";
2020
- const href = _chunkMEXUFQVCcjs.normalizeSectionHref.call(void 0, item.getAttribute("href") || "");
2032
+ const href = _chunkDMBTOJK4cjs.normalizeSectionHref.call(void 0, item.getAttribute("href") || "");
2021
2033
  if (id && href) idToHref.set(id, href);
2022
2034
  }
2023
2035
  if (spine.length > 0) {
@@ -2028,7 +2040,7 @@ function parseSectionPathsFromManifest(xml) {
2028
2040
  }
2029
2041
  if (ordered.length > 0) return ordered;
2030
2042
  }
2031
- return Array.from(idToHref.values()).sort(_chunkMEXUFQVCcjs.compareSectionPaths);
2043
+ return Array.from(idToHref.values()).sort(_chunkDMBTOJK4cjs.compareSectionPaths);
2032
2044
  }
2033
2045
 
2034
2046
  // src/hwpx/metadata.ts
@@ -2041,7 +2053,7 @@ async function extractHwpxMetadata(zip, metadata, decompressed) {
2041
2053
  const xml = await file.async("text");
2042
2054
  if (decompressed) {
2043
2055
  decompressed.total += xml.length * 2;
2044
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2056
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2045
2057
  }
2046
2058
  parseDublinCoreMetadata(xml, metadata);
2047
2059
  if (metadata.title || metadata.author) return;
@@ -2051,7 +2063,7 @@ async function extractHwpxMetadata(zip, metadata, decompressed) {
2051
2063
  }
2052
2064
  function parseDublinCoreMetadata(xml, metadata) {
2053
2065
  const parser = createXmlParser();
2054
- const doc = parser.parseFromString(_chunkMEXUFQVCcjs.stripDtd.call(void 0, xml), "text/xml");
2066
+ const doc = parser.parseFromString(_chunkDMBTOJK4cjs.stripDtd.call(void 0, xml), "text/xml");
2055
2067
  if (!doc.documentElement) return;
2056
2068
  const getText = (tagNames) => {
2057
2069
  for (const tag of tagNames) {
@@ -2076,7 +2088,7 @@ function parseDublinCoreMetadata(xml, metadata) {
2076
2088
 
2077
2089
  // src/hwpx/parser.ts
2078
2090
  async function parseHwpxDocument(buffer, options) {
2079
- _chunkMEXUFQVCcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
2091
+ _chunkDMBTOJK4cjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
2080
2092
  let zip;
2081
2093
  try {
2082
2094
  zip = await _jszip2.default.loadAsync(buffer);
@@ -2085,7 +2097,7 @@ async function parseHwpxDocument(buffer, options) {
2085
2097
  }
2086
2098
  const actualEntryCount = Object.keys(zip.files).length;
2087
2099
  if (actualEntryCount > MAX_ZIP_ENTRIES) {
2088
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP \uC5D4\uD2B8\uB9AC \uC218 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2100
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP \uC5D4\uD2B8\uB9AC \uC218 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2089
2101
  }
2090
2102
  const manifestFile = zip.file("META-INF/manifest.xml");
2091
2103
  if (manifestFile) {
@@ -2097,7 +2109,7 @@ async function parseHwpxDocument(buffer, options) {
2097
2109
  return comResultToParseResult(pages, pageCount, warnings2);
2098
2110
  }
2099
2111
  }
2100
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("DRM \uC554\uD638\uD654\uB41C HWPX \uD30C\uC77C\uC785\uB2C8\uB2E4. Windows + \uD55C\uCEF4 \uC624\uD53C\uC2A4 \uC124\uCE58 \uC2DC \uC790\uB3D9 \uCD94\uCD9C\uB429\uB2C8\uB2E4.");
2112
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("DRM \uC554\uD638\uD654\uB41C HWPX \uD30C\uC77C\uC785\uB2C8\uB2E4. Windows + \uD55C\uCEF4 \uC624\uD53C\uC2A4 \uC124\uCE58 \uC2DC \uC790\uB3D9 \uCD94\uCD9C\uB429\uB2C8\uB2E4.");
2101
2113
  }
2102
2114
  }
2103
2115
  const decompressed = { total: 0 };
@@ -2106,7 +2118,7 @@ async function parseHwpxDocument(buffer, options) {
2106
2118
  const styleMap = await extractHwpxStyles(zip, decompressed);
2107
2119
  const warnings = [];
2108
2120
  const sectionPaths = await resolveSectionPaths(zip);
2109
- if (sectionPaths.length === 0) throw new (0, _chunkMEXUFQVCcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
2121
+ if (sectionPaths.length === 0) throw new (0, _chunkDMBTOJK4cjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
2110
2122
  metadata.pageCount = sectionPaths.length;
2111
2123
  const pageFilter = _optionalChain([options, 'optionalAccess', _45 => _45.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sectionPaths.length) : null;
2112
2124
  const totalTarget = pageFilter ? pageFilter.size : sectionPaths.length;
@@ -2120,12 +2132,12 @@ async function parseHwpxDocument(buffer, options) {
2120
2132
  try {
2121
2133
  const xml = await file.async("text");
2122
2134
  decompressed.total += xml.length * 2;
2123
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2135
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2124
2136
  blocks.push(...parseSectionXml(xml, styleMap, warnings, si + 1, shared));
2125
2137
  parsedSections++;
2126
2138
  _optionalChain([options, 'optionalAccess', _46 => _46.onProgress, 'optionalCall', _47 => _47(parsedSections, totalTarget)]);
2127
2139
  } catch (secErr) {
2128
- if (secErr instanceof _chunkMEXUFQVCcjs.KordocError) throw secErr;
2140
+ if (secErr instanceof _chunkDMBTOJK4cjs.KordocError) throw secErr;
2129
2141
  warnings.push({ page: si + 1, message: `\uC139\uC158 ${si + 1} \uD30C\uC2F1 \uC2E4\uD328: ${secErr instanceof Error ? secErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "PARTIAL_PARSE" });
2130
2142
  }
2131
2143
  }
@@ -2133,7 +2145,7 @@ async function parseHwpxDocument(buffer, options) {
2133
2145
  const images = await extractImagesFromZip(zip, blocks, decompressed, warnings);
2134
2146
  detectHwpxHeadings(blocks, styleMap);
2135
2147
  const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
2136
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, blocks);
2148
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, blocks);
2137
2149
  return { markdown, blocks, metadata, outline: outline.length > 0 ? outline : void 0, warnings: warnings.length > 0 ? warnings : void 0, images: images.length > 0 ? images : void 0 };
2138
2150
  }
2139
2151
 
@@ -2200,7 +2212,7 @@ function decompressStream(data) {
2200
2212
  return _zlib.inflateRawSync.call(void 0, data, opts);
2201
2213
  }
2202
2214
  function parseFileHeader(data) {
2203
- if (data.length < 40) throw new (0, _chunkMEXUFQVCcjs.KordocError)("FileHeader\uAC00 \uB108\uBB34 \uC9E7\uC2B5\uB2C8\uB2E4 (\uCD5C\uC18C 40\uBC14\uC774\uD2B8)");
2215
+ if (data.length < 40) throw new (0, _chunkDMBTOJK4cjs.KordocError)("FileHeader\uAC00 \uB108\uBB34 \uC9E7\uC2B5\uB2C8\uB2E4 (\uCD5C\uC18C 40\uBC14\uC774\uD2B8)");
2204
2216
  const sig = data.subarray(0, 32).toString("utf8").replace(/\0+$/, "");
2205
2217
  return {
2206
2218
  signature: sig,
@@ -2352,7 +2364,6 @@ function appendParaText(state, data, resolveControl) {
2352
2364
  break;
2353
2365
  }
2354
2366
  result += "\n";
2355
- if (i + 14 <= data.length) i += 14;
2356
2367
  break;
2357
2368
  }
2358
2369
  case CHAR_PARA:
@@ -2508,11 +2519,11 @@ function formatRoman(n, upper) {
2508
2519
  const values = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
2509
2520
  const symbols = upper ? ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] : ["m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i"];
2510
2521
  let result = "";
2511
- let num2 = n;
2522
+ let num3 = n;
2512
2523
  for (let i = 0; i < values.length; i++) {
2513
- while (num2 >= values[i]) {
2524
+ while (num3 >= values[i]) {
2514
2525
  result += symbols[i];
2515
- num2 -= values[i];
2526
+ num3 -= values[i];
2516
2527
  }
2517
2528
  }
2518
2529
  return result;
@@ -2520,11 +2531,11 @@ function formatRoman(n, upper) {
2520
2531
  function formatLatin(n, upper) {
2521
2532
  if (n <= 0) return "";
2522
2533
  let result = "";
2523
- let num2 = n;
2524
- while (num2 > 0) {
2525
- num2--;
2526
- result = String.fromCharCode((upper ? 65 : 97) + num2 % 26) + result;
2527
- num2 = Math.floor(num2 / 26);
2534
+ let num3 = n;
2535
+ while (num3 > 0) {
2536
+ num3--;
2537
+ result = String.fromCharCode((upper ? 65 : 97) + num3 % 26) + result;
2538
+ num3 = Math.floor(num3 / 26);
2528
2539
  }
2529
2540
  return result;
2530
2541
  }
@@ -2532,15 +2543,15 @@ function formatEastAsianNumber(n, digits, units, zero) {
2532
2543
  if (n === 0) return zero;
2533
2544
  if (n < 0 || n > 99999) return String(n);
2534
2545
  let result = "";
2535
- let num2 = n;
2546
+ let num3 = n;
2536
2547
  let unit = 0;
2537
- while (num2 > 0) {
2538
- const d = num2 % 10;
2548
+ while (num3 > 0) {
2549
+ const d = num3 % 10;
2539
2550
  if (d > 0) {
2540
2551
  const digitStr = d === 1 && unit > 0 ? "" : digits[d];
2541
2552
  result = digitStr + units[unit] + result;
2542
2553
  }
2543
- num2 = Math.floor(num2 / 10);
2554
+ num3 = Math.floor(num3 / 10);
2544
2555
  unit++;
2545
2556
  }
2546
2557
  return result;
@@ -2587,8 +2598,8 @@ function expandNumberingFormat(formatStr, counters, numbering) {
2587
2598
  const idx = levelRef - 1;
2588
2599
  const counterVal = _nullishCoalesce(counters[idx], () => ( 0));
2589
2600
  const start = _nullishCoalesce(numbering.startNumbers[idx], () => ( 1));
2590
- const num2 = counterVal > 0 ? start - 1 + counterVal : start;
2591
- result += formatNumber(num2, headFormatToNumFmt(_nullishCoalesce(numbering.numberFormats[idx], () => ( 0))));
2601
+ const num3 = counterVal > 0 ? start - 1 + counterVal : start;
2602
+ result += formatNumber(num3, headFormatToNumFmt(_nullishCoalesce(numbering.numberFormats[idx], () => ( 0))));
2592
2603
  i += 2;
2593
2604
  continue;
2594
2605
  }
@@ -3734,7 +3745,7 @@ function parseHwp5Document(buffer, options) {
3734
3745
  lenientCfb = parseLenientCfb(buffer);
3735
3746
  warnings.push({ message: "\uC190\uC0C1\uB41C CFB \uCEE8\uD14C\uC774\uB108 \u2014 lenient \uBAA8\uB4DC\uB85C \uBCF5\uAD6C", code: "LENIENT_CFB_RECOVERY" });
3736
3747
  } catch (e21) {
3737
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328 (strict \uBC0F lenient \uBAA8\uB450)");
3748
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328 (strict \uBC0F lenient \uBAA8\uB450)");
3738
3749
  }
3739
3750
  }
3740
3751
  const findStream = (path) => {
@@ -3745,11 +3756,11 @@ function parseHwp5Document(buffer, options) {
3745
3756
  return lenientCfb.findStream(path);
3746
3757
  };
3747
3758
  const headerData = findStream("/FileHeader");
3748
- if (!headerData) throw new (0, _chunkMEXUFQVCcjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
3759
+ if (!headerData) throw new (0, _chunkDMBTOJK4cjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
3749
3760
  const header = parseFileHeader(headerData);
3750
- if (header.signature !== "HWP Document File") throw new (0, _chunkMEXUFQVCcjs.KordocError)("HWP \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
3751
- if (header.flags & FLAG_ENCRYPTED) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC554\uD638\uD654\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3752
- if (header.flags & FLAG_DRM) throw new (0, _chunkMEXUFQVCcjs.KordocError)("DRM \uBCF4\uD638\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3761
+ if (header.signature !== "HWP Document File") throw new (0, _chunkDMBTOJK4cjs.KordocError)("HWP \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
3762
+ if (header.flags & FLAG_ENCRYPTED) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC554\uD638\uD654\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3763
+ if (header.flags & FLAG_DRM) throw new (0, _chunkDMBTOJK4cjs.KordocError)("DRM \uBCF4\uD638\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3753
3764
  const compressed = (header.flags & FLAG_COMPRESSED) !== 0;
3754
3765
  const distribution = (header.flags & FLAG_DISTRIBUTION) !== 0;
3755
3766
  const metadata = {
@@ -3758,7 +3769,7 @@ function parseHwp5Document(buffer, options) {
3758
3769
  if (cfb) extractHwp5Metadata(cfb, metadata);
3759
3770
  const docInfo = cfb ? parseDocInfoStream(cfb, compressed) : parseDocInfoFromStream(findStream("/DocInfo"), compressed);
3760
3771
  const sections = distribution ? cfb ? findViewTextSections(cfb, compressed) : findViewTextSectionsLenient(lenientCfb, compressed) : cfb ? findSections(cfb) : findSectionsLenient(lenientCfb, compressed);
3761
- if (sections.length === 0) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC139\uC158 \uC2A4\uD2B8\uB9BC\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3772
+ if (sections.length === 0) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC139\uC158 \uC2A4\uD2B8\uB9BC\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3762
3773
  metadata.pageCount = sections.length;
3763
3774
  const pageFilter = _optionalChain([options, 'optionalAccess', _51 => _51.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sections.length) : null;
3764
3775
  const totalTarget = pageFilter ? pageFilter.size : sections.length;
@@ -3772,25 +3783,25 @@ function parseHwp5Document(buffer, options) {
3772
3783
  const sectionData = sections[si];
3773
3784
  const data = !distribution && compressed ? decompressStream(Buffer.from(sectionData)) : Buffer.from(sectionData);
3774
3785
  totalDecompressed += data.length;
3775
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3786
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3776
3787
  const records = readRecords(data);
3777
3788
  const sectionBlocks = parseSection(records, docInfo, warnings, si + 1, doc);
3778
3789
  bodyBlocks.push(...sectionBlocks);
3779
3790
  parsedSections++;
3780
3791
  _optionalChain([options, 'optionalAccess', _52 => _52.onProgress, 'optionalCall', _53 => _53(parsedSections, totalTarget)]);
3781
3792
  } catch (secErr) {
3782
- if (secErr instanceof _chunkMEXUFQVCcjs.KordocError) throw secErr;
3793
+ if (secErr instanceof _chunkDMBTOJK4cjs.KordocError) throw secErr;
3783
3794
  warnings.push({ page: si + 1, message: `\uC139\uC158 ${si + 1} \uD30C\uC2F1 \uC2E4\uD328: ${secErr instanceof Error ? secErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "PARTIAL_PARSE" });
3784
3795
  }
3785
3796
  }
3786
3797
  const blocks = [...doc.headerBlocks, ...bodyBlocks, ...doc.footerBlocks];
3787
3798
  const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings);
3788
- const flatBlocks = _chunkMEXUFQVCcjs.flattenLayoutTables.call(void 0, blocks);
3799
+ const flatBlocks = _chunkDMBTOJK4cjs.flattenLayoutTables.call(void 0, blocks);
3789
3800
  if (docInfo) {
3790
3801
  detectHwp5Headings(flatBlocks, docInfo);
3791
3802
  }
3792
3803
  const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
3793
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, flatBlocks);
3804
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, flatBlocks);
3794
3805
  return { markdown, blocks: flatBlocks, metadata, outline: outline.length > 0 ? outline : void 0, warnings: warnings.length > 0 ? warnings : void 0, images: images.length > 0 ? images : void 0 };
3795
3806
  }
3796
3807
  function parseDocInfoStream(cfb, compressed) {
@@ -3850,9 +3861,9 @@ function detectHwp5Headings(blocks, docInfo) {
3850
3861
  let level = 0;
3851
3862
  if (_optionalChain([block, 'access', _58 => _58.style, 'optionalAccess', _59 => _59.fontSize]) && baseFontSize > 0) {
3852
3863
  const ratio = block.style.fontSize / baseFontSize;
3853
- if (ratio >= _chunkMEXUFQVCcjs.HEADING_RATIO_H1) level = 1;
3854
- else if (ratio >= _chunkMEXUFQVCcjs.HEADING_RATIO_H2) level = 2;
3855
- else if (ratio >= _chunkMEXUFQVCcjs.HEADING_RATIO_H3) level = 3;
3864
+ if (ratio >= _chunkDMBTOJK4cjs.HEADING_RATIO_H1) level = 1;
3865
+ else if (ratio >= _chunkDMBTOJK4cjs.HEADING_RATIO_H2) level = 2;
3866
+ else if (ratio >= _chunkDMBTOJK4cjs.HEADING_RATIO_H3) level = 3;
3856
3867
  }
3857
3868
  if (/^제\d+[장절편]\s/.test(text) && text.length <= 50) {
3858
3869
  if (level === 0) level = 2;
@@ -3937,7 +3948,7 @@ function findSectionsLenient(lcfb, compressed) {
3937
3948
  if (!raw) break;
3938
3949
  const content = compressed ? decompressStream(raw) : raw;
3939
3950
  totalDecompressed += content.length;
3940
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3951
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3941
3952
  sections.push({ idx: i, content });
3942
3953
  }
3943
3954
  if (sections.length === 0) {
@@ -3949,7 +3960,7 @@ function findSectionsLenient(lcfb, compressed) {
3949
3960
  if (raw) {
3950
3961
  const content = compressed ? decompressStream(raw) : raw;
3951
3962
  totalDecompressed += content.length;
3952
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3963
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3953
3964
  sections.push({ idx, content });
3954
3965
  }
3955
3966
  }
@@ -3966,7 +3977,7 @@ function findViewTextSectionsLenient(lcfb, compressed) {
3966
3977
  try {
3967
3978
  const content = decryptViewText(raw, compressed);
3968
3979
  totalDecompressed += content.length;
3969
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3980
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3970
3981
  sections.push({ idx: i, content });
3971
3982
  } catch (e26) {
3972
3983
  break;
@@ -4069,7 +4080,7 @@ function parseParagraph(records, start, end, ctx) {
4069
4080
  const ctrl = ctrls[r.ctrlIdx];
4070
4081
  if (!_optionalChain([ctrl, 'optionalAccess', _66 => _66.href]) || r.end <= r.start) continue;
4071
4082
  if (applied.some(([s, e]) => r.start < e && r.end > s)) continue;
4072
- const href = _chunkMEXUFQVCcjs.sanitizeHref.call(void 0, ctrl.href);
4083
+ const href = _chunkDMBTOJK4cjs.sanitizeHref.call(void 0, ctrl.href);
4073
4084
  if (!href) continue;
4074
4085
  const anchor = text.slice(r.start, r.end);
4075
4086
  if (!anchor.trim()) continue;
@@ -4156,11 +4167,11 @@ function applyCtrlEffect(ctrl, records, ctx) {
4156
4167
  const attr = ctrl.data.readUInt32LE(4);
4157
4168
  const type = attr & 15;
4158
4169
  const format = attr >>> 4 & 255;
4159
- const num2 = _nullishCoalesce(ctx.doc.autoCounters.get(type), () => ( 1));
4160
- ctx.doc.autoCounters.set(type, num2 + 1);
4170
+ const num3 = _nullishCoalesce(ctx.doc.autoCounters.get(type), () => ( 1));
4171
+ ctx.doc.autoCounters.set(type, num3 + 1);
4161
4172
  const prefix = ctrl.data.length >= 14 ? wcharAt(ctrl.data, 12) : "";
4162
4173
  const suffix = ctrl.data.length >= 16 ? wcharAt(ctrl.data, 14) : "";
4163
- ctrl.inlineText = `${prefix}${formatNumber(num2, shapeFormatToNumFmt(format))}${suffix}`;
4174
+ ctrl.inlineText = `${prefix}${formatNumber(num3, shapeFormatToNumFmt(format))}${suffix}`;
4164
4175
  }
4165
4176
  return;
4166
4177
  }
@@ -4168,8 +4179,8 @@ function applyCtrlEffect(ctrl, records, ctx) {
4168
4179
  if (ctrl.data.length >= 10) {
4169
4180
  const attr = ctrl.data.readUInt32LE(4);
4170
4181
  const type = attr & 15;
4171
- const num2 = ctrl.data.readUInt16LE(8);
4172
- if (num2 > 0) ctx.doc.autoCounters.set(type, num2);
4182
+ const num3 = ctrl.data.readUInt16LE(8);
4183
+ if (num3 > 0) ctx.doc.autoCounters.set(type, num3);
4173
4184
  }
4174
4185
  return;
4175
4186
  }
@@ -4231,7 +4242,7 @@ function blocksPlainText(blocks, sep) {
4231
4242
  return parts.join(sep).trim();
4232
4243
  }
4233
4244
  function applyNoteEffect(ctrl, records, ctx, autoType) {
4234
- const num2 = _nullishCoalesce(ctx.doc.autoCounters.get(autoType), () => ( 1));
4245
+ const num3 = _nullishCoalesce(ctx.doc.autoCounters.get(autoType), () => ( 1));
4235
4246
  let before = "";
4236
4247
  let after = "";
4237
4248
  let shape = 0;
@@ -4242,11 +4253,11 @@ function applyNoteEffect(ctrl, records, ctx, autoType) {
4242
4253
  if (ctrl.data.length >= 16) {
4243
4254
  shape = ctrl.data.readUInt32LE(12) & 255;
4244
4255
  }
4245
- const formatted = formatNumber(num2, shapeFormatToNumFmt(shape));
4256
+ const formatted = formatNumber(num3, shapeFormatToNumFmt(shape));
4246
4257
  const marker = before || after ? `${before}${formatted}${after}` : `${formatted})`;
4247
4258
  const content = blocksPlainText(parseListHeaderParagraphs(ctrl, records, ctx), " ");
4248
- if ((_nullishCoalesce(ctx.doc.autoCounters.get(autoType), () => ( 1))) <= num2) {
4249
- ctx.doc.autoCounters.set(autoType, num2 + 1);
4259
+ if ((_nullishCoalesce(ctx.doc.autoCounters.get(autoType), () => ( 1))) <= num3) {
4260
+ ctx.doc.autoCounters.set(autoType, num3 + 1);
4250
4261
  }
4251
4262
  ctrl.inlineText = marker;
4252
4263
  if (content) ctrl.footnote = content.startsWith(marker) ? content : `${marker} ${content}`;
@@ -4302,8 +4313,8 @@ function parseTableControl(ctrl, records, ctx) {
4302
4313
  let tableIdx = -1;
4303
4314
  for (let i2 = childStart; i2 < childEnd; i2++) {
4304
4315
  if (records[i2].tagId === TAG_TABLE && records[i2].data.length >= 8) {
4305
- rows = Math.min(records[i2].data.readUInt16LE(4), _chunkMEXUFQVCcjs.MAX_ROWS);
4306
- cols = Math.min(records[i2].data.readUInt16LE(6), _chunkMEXUFQVCcjs.MAX_COLS);
4316
+ rows = Math.min(records[i2].data.readUInt16LE(4), _chunkDMBTOJK4cjs.MAX_ROWS);
4317
+ cols = Math.min(records[i2].data.readUInt16LE(6), _chunkDMBTOJK4cjs.MAX_COLS);
4307
4318
  tableIdx = i2;
4308
4319
  break;
4309
4320
  }
@@ -4352,7 +4363,7 @@ function parseTableControl(ctrl, records, ctx) {
4352
4363
  return table2;
4353
4364
  }
4354
4365
  const cellRows = arrangeCells(rows, cols, cells);
4355
- const table = _chunkMEXUFQVCcjs.buildTable.call(void 0, cellRows);
4366
+ const table = _chunkDMBTOJK4cjs.buildTable.call(void 0, cellRows);
4356
4367
  if (caption && table.rows > 0) table.caption = caption;
4357
4368
  return table.rows > 0 ? table : null;
4358
4369
  }
@@ -4369,8 +4380,8 @@ function parseCell(records, lhIdx, end, ctx) {
4369
4380
  rowAddr = rec.data.readUInt16LE(10);
4370
4381
  const cs = rec.data.readUInt16LE(12);
4371
4382
  const rs = rec.data.readUInt16LE(14);
4372
- if (cs > 0) colSpan = Math.min(cs, _chunkMEXUFQVCcjs.MAX_COLS);
4373
- if (rs > 0) rowSpan = Math.min(rs, _chunkMEXUFQVCcjs.MAX_ROWS);
4383
+ if (cs > 0) colSpan = Math.min(cs, _chunkDMBTOJK4cjs.MAX_COLS);
4384
+ if (rs > 0) rowSpan = Math.min(rs, _chunkDMBTOJK4cjs.MAX_ROWS);
4374
4385
  }
4375
4386
  const blocks = ctx.depth < MAX_NEST_DEPTH ? parseParagraphList(records, lhIdx + 1, end, { ...ctx, depth: ctx.depth + 1 }) : [];
4376
4387
  const parts = [];
@@ -4380,7 +4391,7 @@ function parseCell(records, lhIdx, end, ctx) {
4380
4391
  parts.push(`![image](hwp5bin:${b.text})`);
4381
4392
  hasStructure = true;
4382
4393
  } else if (b.type === "table" && b.table) {
4383
- const flat = _chunkMEXUFQVCcjs.convertTableToText.call(void 0, b.table.cells);
4394
+ const flat = _chunkDMBTOJK4cjs.convertTableToText.call(void 0, b.table.cells);
4384
4395
  if (flat) parts.push(flat);
4385
4396
  hasStructure = true;
4386
4397
  } else if (b.text) {
@@ -16784,9 +16795,9 @@ var MAX_ROWS2 = 1e4;
16784
16795
  var MAX_COLS2 = 200;
16785
16796
  function cleanNumericValue(raw) {
16786
16797
  if (!/^-?\d+\.\d+$/.test(raw)) return raw;
16787
- const num2 = parseFloat(raw);
16788
- if (!isFinite(num2)) return raw;
16789
- const cleaned = parseFloat(num2.toPrecision(15)).toString();
16798
+ const num3 = parseFloat(raw);
16799
+ if (!isFinite(num3)) return raw;
16800
+ const cleaned = parseFloat(num3.toPrecision(15)).toString();
16790
16801
  return cleaned;
16791
16802
  }
16792
16803
  function parseCellRef(ref) {
@@ -16817,7 +16828,7 @@ function getTextContent(el) {
16817
16828
  return _nullishCoalesce(_optionalChain([el, 'access', _81 => _81.textContent, 'optionalAccess', _82 => _82.trim, 'call', _83 => _83()]), () => ( ""));
16818
16829
  }
16819
16830
  function parseXml(text) {
16820
- return new (0, _xmldom.DOMParser)().parseFromString(_chunkMEXUFQVCcjs.stripDtd.call(void 0, text), "text/xml");
16831
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunkDMBTOJK4cjs.stripDtd.call(void 0, text), "text/xml");
16821
16832
  }
16822
16833
  function parseSharedStrings(xml) {
16823
16834
  const doc = parseXml(xml);
@@ -16961,7 +16972,7 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
16961
16972
  cellRows.push(row);
16962
16973
  }
16963
16974
  if (cellRows.length > 0) {
16964
- const table = _chunkMEXUFQVCcjs.buildTable.call(void 0, cellRows);
16975
+ const table = _chunkDMBTOJK4cjs.buildTable.call(void 0, cellRows);
16965
16976
  if (table.rows > 0) {
16966
16977
  blocks.push({ type: "table", table, pageNumber: sheetIndex + 1 });
16967
16978
  }
@@ -16969,12 +16980,12 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
16969
16980
  return blocks;
16970
16981
  }
16971
16982
  async function parseXlsxDocument(buffer, options) {
16972
- _chunkMEXUFQVCcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE3);
16983
+ _chunkDMBTOJK4cjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE3);
16973
16984
  const zip = await _jszip2.default.loadAsync(buffer);
16974
16985
  const warnings = [];
16975
16986
  const workbookFile = zip.file("xl/workbook.xml");
16976
16987
  if (!workbookFile) {
16977
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 XLSX \uD30C\uC77C: xl/workbook.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
16988
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 XLSX \uD30C\uC77C: xl/workbook.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
16978
16989
  }
16979
16990
  let sharedStrings = [];
16980
16991
  const ssFile = zip.file("xl/sharedStrings.xml");
@@ -16983,7 +16994,7 @@ async function parseXlsxDocument(buffer, options) {
16983
16994
  }
16984
16995
  const sheets = parseWorkbook(await workbookFile.async("text"));
16985
16996
  if (sheets.length === 0) {
16986
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("XLSX \uD30C\uC77C\uC5D0 \uC2DC\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
16997
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("XLSX \uD30C\uC77C\uC5D0 \uC2DC\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
16987
16998
  }
16988
16999
  let relsMap = /* @__PURE__ */ new Map();
16989
17000
  const relsFile = zip.file("xl/_rels/workbook.xml.rels");
@@ -17055,7 +17066,7 @@ async function parseXlsxDocument(buffer, options) {
17055
17066
  } catch (e27) {
17056
17067
  }
17057
17068
  }
17058
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, blocks);
17069
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, blocks);
17059
17070
  return { markdown, blocks, metadata, warnings: warnings.length > 0 ? warnings : void 0 };
17060
17071
  }
17061
17072
 
@@ -17129,17 +17140,17 @@ function decodeRk(rk) {
17129
17140
  const fDiv100 = (rk & 1) !== 0;
17130
17141
  const fInt = (rk & 2) !== 0;
17131
17142
  const val30 = rk >> 2;
17132
- let num2;
17143
+ let num3;
17133
17144
  if (fInt) {
17134
- num2 = val30;
17145
+ num3 = val30;
17135
17146
  } else {
17136
17147
  const high32 = (rk & 4294967292) >>> 0;
17137
17148
  const buf = Buffer.alloc(8);
17138
17149
  buf.writeUInt32LE(0, 0);
17139
17150
  buf.writeUInt32LE(high32, 4);
17140
- num2 = buf.readDoubleLE(0);
17151
+ num3 = buf.readDoubleLE(0);
17141
17152
  }
17142
- return fDiv100 ? num2 / 100 : num2;
17153
+ return fDiv100 ? num3 / 100 : num3;
17143
17154
  }
17144
17155
  function decodeMulRk(data) {
17145
17156
  if (data.length < 6) return null;
@@ -17462,11 +17473,11 @@ function processGlobals(records) {
17462
17473
  let encrypted = false;
17463
17474
  const firstBof = records[0];
17464
17475
  if (!firstBof || firstBof.opcode !== OP_BOF) {
17465
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("XLS: \uCCAB \uB808\uCF54\uB4DC\uAC00 BOF\uAC00 \uC544\uB2D8");
17476
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("XLS: \uCCAB \uB808\uCF54\uB4DC\uAC00 BOF\uAC00 \uC544\uB2D8");
17466
17477
  }
17467
17478
  const bof = decodeBof(firstBof.data);
17468
17479
  if (!bof || bof.dt !== DT_GLOBALS) {
17469
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("XLS: Globals \uC11C\uBE0C\uC2A4\uD2B8\uB9BC BOF \uB204\uB77D");
17480
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("XLS: Globals \uC11C\uBE0C\uC2A4\uD2B8\uB9BC BOF \uB204\uB77D");
17470
17481
  }
17471
17482
  let i = 1;
17472
17483
  while (i < records.length) {
@@ -17581,7 +17592,7 @@ function sheetToBlocks2(sheetName, sheet, sheetIndex) {
17581
17592
  cellRows.push(row);
17582
17593
  }
17583
17594
  if (cellRows.length > 0) {
17584
- const table = _chunkMEXUFQVCcjs.buildTable.call(void 0, cellRows);
17595
+ const table = _chunkDMBTOJK4cjs.buildTable.call(void 0, cellRows);
17585
17596
  if (table.rows > 0) {
17586
17597
  blocks.push({ type: "table", table, pageNumber: sheetIndex + 1 });
17587
17598
  }
@@ -17594,21 +17605,21 @@ async function parseXlsDocument(buffer, options) {
17594
17605
  try {
17595
17606
  cfb = parseLenientCfb(buf);
17596
17607
  } catch (e) {
17597
- throw new (0, _chunkMEXUFQVCcjs.KordocError)(
17608
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)(
17598
17609
  `XLS: OLE2 \uC2DC\uADF8\uB2C8\uCC98 \uAC80\uC99D \uC2E4\uD328 \u2014 ${e instanceof Error ? e.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`
17599
17610
  );
17600
17611
  }
17601
17612
  const wb = _nullishCoalesce(cfb.findStream("/Workbook"), () => ( cfb.findStream("/Book")));
17602
17613
  if (!wb) {
17603
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("XLS: Workbook \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC74C (BIFF5 \uB610\uB294 \uBE44\uD45C\uC900 \uD30C\uC77C)");
17614
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("XLS: Workbook \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC74C (BIFF5 \uB610\uB294 \uBE44\uD45C\uC900 \uD30C\uC77C)");
17604
17615
  }
17605
17616
  const records = readRecords2(wb);
17606
17617
  if (records.length === 0) {
17607
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("XLS: \uC2DC\uADF8\uB2C8\uCC98 \uB808\uCF54\uB4DC\uAC00 \uC5C6\uC74C (Workbook \uC2A4\uD2B8\uB9BC \uC190\uC0C1)");
17618
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("XLS: \uC2DC\uADF8\uB2C8\uCC98 \uB808\uCF54\uB4DC\uAC00 \uC5C6\uC74C (Workbook \uC2A4\uD2B8\uB9BC \uC190\uC0C1)");
17608
17619
  }
17609
17620
  const firstBof = decodeBof(records[0].data);
17610
17621
  if (firstBof && firstBof.vers !== 1536) {
17611
- throw new (0, _chunkMEXUFQVCcjs.KordocError)(
17622
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)(
17612
17623
  `XLS: BIFF8(0x0600)\uB9CC \uC9C0\uC6D0 \u2014 \uBCF8 \uD30C\uC77C\uC740 0x${firstBof.vers.toString(16)}`
17613
17624
  );
17614
17625
  }
@@ -17668,7 +17679,7 @@ async function parseXlsDocument(buffer, options) {
17668
17679
  pageCount: totalSheets
17669
17680
  };
17670
17681
  return {
17671
- markdown: _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, allBlocks),
17682
+ markdown: _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, allBlocks),
17672
17683
  blocks: allBlocks,
17673
17684
  metadata,
17674
17685
  warnings: warnings.length > 0 ? warnings : void 0
@@ -17839,9 +17850,9 @@ function nodeToLatex(el) {
17839
17850
  case "f": {
17840
17851
  const n = firstKid(el, "num");
17841
17852
  const d = firstKid(el, "den");
17842
- const num2 = n ? childrenToLatex(n) : "";
17853
+ const num3 = n ? childrenToLatex(n) : "";
17843
17854
  const den = d ? childrenToLatex(d) : "";
17844
- return "\\frac" + grp(num2) + grp(den);
17855
+ return "\\frac" + grp(num3) + grp(den);
17845
17856
  }
17846
17857
  // 첨자
17847
17858
  case "sSup": {
@@ -18106,7 +18117,7 @@ function getAttr(el, localName2) {
18106
18117
  return null;
18107
18118
  }
18108
18119
  function parseXml2(text) {
18109
- return new (0, _xmldom.DOMParser)().parseFromString(_chunkMEXUFQVCcjs.stripDtd.call(void 0, text), "text/xml");
18120
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunkDMBTOJK4cjs.stripDtd.call(void 0, text), "text/xml");
18110
18121
  }
18111
18122
  function parseStyles(xml) {
18112
18123
  const doc = parseXml2(xml);
@@ -18211,6 +18222,7 @@ function collectOmmlRoots(p) {
18211
18222
  const tag = el.localName || _optionalChain([el, 'access', _103 => _103.tagName, 'optionalAccess', _104 => _104.replace, 'call', _105 => _105(/^[^:]+:/, "")]) || "";
18212
18223
  if (tag === "oMath" || tag === "oMathPara") {
18213
18224
  out.push(el);
18225
+ } else if (tag === "txbxContent" || tag === "Fallback") {
18214
18226
  } else {
18215
18227
  walk(el);
18216
18228
  }
@@ -18335,6 +18347,13 @@ function parseTable(tbl, styles, numbering, footnotes, rels) {
18335
18347
  for (const tr of trElements) {
18336
18348
  const row = [];
18337
18349
  let col = 0;
18350
+ const trPrEls = getChildElements(tr, "trPr");
18351
+ if (trPrEls.length > 0) {
18352
+ const gridBeforeEls = getChildElements(trPrEls[0], "gridBefore");
18353
+ if (gridBeforeEls.length > 0) {
18354
+ col = parseInt(_nullishCoalesce(getAttr(gridBeforeEls[0], "val"), () => ( "0")), 10) || 0;
18355
+ }
18356
+ }
18338
18357
  for (const tc of getChildElements(tr, "tc")) {
18339
18358
  let colSpan = 1;
18340
18359
  let vMerge = null;
@@ -18349,12 +18368,28 @@ function parseTable(tbl, styles, numbering, footnotes, rels) {
18349
18368
  vMerge = getAttr(vMergeEls[0], "val") === "restart" ? "restart" : "continue";
18350
18369
  }
18351
18370
  }
18352
- const text = vMerge === "continue" ? "" : collectCellText(tc, styles, numbering, footnotes, rels, 0).join("\n");
18371
+ const text = collectCellText(tc, styles, numbering, footnotes, rels, 0).join("\n");
18353
18372
  row.push({ col, colSpan, vMerge, text });
18354
18373
  col += colSpan;
18355
18374
  }
18356
18375
  rawRows.push(row);
18357
18376
  }
18377
+ for (let r = 0; r < rawRows.length; r++) {
18378
+ for (const cell of rawRows[r]) {
18379
+ if (cell.vMerge !== "continue" || !cell.text) continue;
18380
+ let start;
18381
+ for (let pr = r - 1; pr >= 0 && !start; pr--) {
18382
+ start = rawRows[pr].find((pc) => pc.col === cell.col && pc.vMerge !== "continue");
18383
+ }
18384
+ if (start) {
18385
+ start.text = start.text ? `${start.text}
18386
+ ${cell.text}` : cell.text;
18387
+ cell.text = "";
18388
+ } else {
18389
+ cell.vMerge = null;
18390
+ }
18391
+ }
18392
+ }
18358
18393
  const cellRows = rawRows.map(
18359
18394
  (row, r) => row.filter((cell) => cell.vMerge !== "continue").map((cell) => {
18360
18395
  let rowSpan = 1;
@@ -18367,7 +18402,7 @@ function parseTable(tbl, styles, numbering, footnotes, rels) {
18367
18402
  return { text: cell.text, colSpan: cell.colSpan, rowSpan, colAddr: cell.col, rowAddr: r };
18368
18403
  })
18369
18404
  );
18370
- const table = _chunkMEXUFQVCcjs.buildTable.call(void 0, cellRows);
18405
+ const table = _chunkDMBTOJK4cjs.buildTable.call(void 0, cellRows);
18371
18406
  if (table.rows === 0 || table.cols === 0) return null;
18372
18407
  return { type: "table", table };
18373
18408
  }
@@ -18434,12 +18469,12 @@ async function extractImages(zip, rels, doc, warnings) {
18434
18469
  return { blocks, images };
18435
18470
  }
18436
18471
  async function parseDocxDocument(buffer, options) {
18437
- _chunkMEXUFQVCcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
18472
+ _chunkDMBTOJK4cjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
18438
18473
  const zip = await _jszip2.default.loadAsync(buffer);
18439
18474
  const warnings = [];
18440
18475
  const docFile = zip.file("word/document.xml");
18441
18476
  if (!docFile) {
18442
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 DOCX \uD30C\uC77C: word/document.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
18477
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 DOCX \uD30C\uC77C: word/document.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
18443
18478
  }
18444
18479
  let rels = /* @__PURE__ */ new Map();
18445
18480
  const relsFile = zip.file("word/_rels/document.xml.rels");
@@ -18486,7 +18521,7 @@ async function parseDocxDocument(buffer, options) {
18486
18521
  const doc = parseXml2(docXml);
18487
18522
  const body = findElements(doc, "body");
18488
18523
  if (body.length === 0) {
18489
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("DOCX \uBCF8\uBB38(w:body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
18524
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("DOCX \uBCF8\uBB38(w:body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
18490
18525
  }
18491
18526
  const blocks = [];
18492
18527
  const bodyEl = body[0];
@@ -18531,7 +18566,7 @@ async function parseDocxDocument(buffer, options) {
18531
18566
  }
18532
18567
  }
18533
18568
  const outline = blocks.filter((b) => b.type === "heading").map((b) => ({ level: _nullishCoalesce(b.level, () => ( 2)), text: _nullishCoalesce(b.text, () => ( "")) }));
18534
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, blocks);
18569
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, blocks);
18535
18570
  return {
18536
18571
  markdown,
18537
18572
  blocks,
@@ -18554,7 +18589,7 @@ function parseHwpmlDocument(buffer, options) {
18554
18589
  }
18555
18590
  const text = new TextDecoder("utf-8").decode(buffer).replace(/^\uFEFF/, "");
18556
18591
  const normalized = text.replace(/&nbsp;/g, "&#160;");
18557
- const xml = _chunkMEXUFQVCcjs.stripDtd.call(void 0, normalized);
18592
+ const xml = _chunkDMBTOJK4cjs.stripDtd.call(void 0, normalized);
18558
18593
  const warnings = [];
18559
18594
  const parser = new (0, _xmldom.DOMParser)({
18560
18595
  onError: (_level, msg2) => {
@@ -18594,7 +18629,7 @@ function parseHwpmlDocument(buffer, options) {
18594
18629
  parseSection2(el, blocks, paraShapeMap, sectionIdx, warnings);
18595
18630
  }
18596
18631
  const outline = blocks.filter((b) => b.type === "heading" && b.text).map((b) => ({ level: _nullishCoalesce(b.level, () => ( 1)), text: b.text, pageNumber: b.pageNumber }));
18597
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, blocks);
18632
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, blocks);
18598
18633
  return {
18599
18634
  markdown,
18600
18635
  blocks,
@@ -18752,7 +18787,7 @@ function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings) {
18752
18787
  const cellRows = grid.map(
18753
18788
  (row) => row.map((cell) => _nullishCoalesce(cell, () => ( { text: "", colSpan: 1, rowSpan: 1 })))
18754
18789
  );
18755
- const table = _chunkMEXUFQVCcjs.buildTable.call(void 0, cellRows);
18790
+ const table = _chunkDMBTOJK4cjs.buildTable.call(void 0, cellRows);
18756
18791
  const caption = extractShapeCaption(el);
18757
18792
  if (caption.text && caption.before) {
18758
18793
  blocks.push({ type: "paragraph", text: caption.text, pageNumber: sectionNum });
@@ -18844,6 +18879,81 @@ function countSections(body) {
18844
18879
  }
18845
18880
 
18846
18881
  // src/form/match.ts
18882
+ function parseYMD(v) {
18883
+ const d = v.replace(/\D/g, "");
18884
+ let y, m, day;
18885
+ if (d.length >= 8) {
18886
+ y = d.slice(0, 4);
18887
+ m = d.slice(4, 6);
18888
+ day = d.slice(6, 8);
18889
+ } else if (d.length === 6) {
18890
+ const yy = +d.slice(0, 2);
18891
+ y = String(yy <= 29 ? 2e3 + yy : 1900 + yy);
18892
+ m = d.slice(2, 4);
18893
+ day = d.slice(4, 6);
18894
+ } else return null;
18895
+ return { y, yy: y.slice(2), m, d: day };
18896
+ }
18897
+ function fmtDate(v, style) {
18898
+ const p = parseYMD(v);
18899
+ if (!p) return v;
18900
+ return (style || "yyyy-mm-dd").replace(/yyyy/g, p.y).replace(/yy/g, p.yy).replace(/mm/g, p.m).replace(/dd/g, p.d).replace(/m/g, String(+p.m)).replace(/d/g, String(+p.d));
18901
+ }
18902
+ function maskDigits(v, pattern) {
18903
+ const ds = v.replace(/\D/g, "");
18904
+ let i = 0;
18905
+ return pattern.replace(/#/g, () => _nullishCoalesce(ds[i++], () => ( "")));
18906
+ }
18907
+ function fmtPhone(v, style) {
18908
+ const d = v.replace(/\D/g, "");
18909
+ if (d.length < 9) return v;
18910
+ const a = d.slice(0, 3), b = d.slice(3, -4), c = d.slice(-4);
18911
+ switch (style) {
18912
+ case "digits":
18913
+ return d;
18914
+ case "dot":
18915
+ return `${a}.${b}.${c}`;
18916
+ case "space":
18917
+ return `${a} ${b} ${c}`;
18918
+ case "intl":
18919
+ return `+82-${d.slice(1, 3)}-${b}-${c}`;
18920
+ case "intl-paren":
18921
+ return `82)${d.slice(1, 3)}-${b}-${c}`;
18922
+ default:
18923
+ return `${a}-${b}-${c}`;
18924
+ }
18925
+ }
18926
+ function fmtRRN(v, style) {
18927
+ const d = v.replace(/\D/g, "");
18928
+ if (d.length !== 13) return v;
18929
+ switch (style) {
18930
+ case "digits":
18931
+ return d;
18932
+ case "front":
18933
+ return d.slice(0, 6);
18934
+ case "masked":
18935
+ return `${d.slice(0, 6)}-${d[6]}******`;
18936
+ default:
18937
+ return `${d.slice(0, 6)}-${d.slice(6)}`;
18938
+ }
18939
+ }
18940
+ function formatFillValue(value, format) {
18941
+ if (!format) return value;
18942
+ const ci = format.indexOf(":");
18943
+ const kind = ci >= 0 ? format.slice(0, ci) : format;
18944
+ const style = ci >= 0 ? format.slice(ci + 1) : "";
18945
+ if (kind === "date") return fmtDate(value, style);
18946
+ if (kind === "phone") return fmtPhone(value, style);
18947
+ if (kind === "rrn") return fmtRRN(value, style);
18948
+ if (kind === "mask") return maskDigits(value, style);
18949
+ if (kind === "digits") return value.replace(/\D/g, "");
18950
+ if (kind === "upper") return value.toUpperCase();
18951
+ if (kind === "lower") return value.toLowerCase();
18952
+ if (kind === "nospace") return value.replace(/\s+/g, "");
18953
+ if (format.includes("#")) return maskDigits(value, format);
18954
+ if (/(yyyy|yy|mm|dd)/.test(format)) return fmtDate(value, format);
18955
+ return value;
18956
+ }
18847
18957
  var ValueCursor = (_class2 = class {
18848
18958
  constructor(values) {;_class2.prototype.__init4.call(this);
18849
18959
  this.values = values;
@@ -18995,11 +19105,32 @@ function padInsertion(text, pos, value) {
18995
19105
  }
18996
19106
  function normalizeValues(values) {
18997
19107
  const map = /* @__PURE__ */ new Map();
18998
- for (const [label, value] of Object.entries(values)) {
18999
- map.set(normalizeLabel(label), value);
19108
+ for (const [label, raw] of Object.entries(values)) {
19109
+ const { value, format } = typeof raw === "object" && !Array.isArray(raw) ? raw : { value: raw, format: void 0 };
19110
+ map.set(normalizeLabel(label), Array.isArray(value) ? value.map((v) => formatFillValue(v, format)) : formatFillValue(value, format));
19000
19111
  }
19001
19112
  return map;
19002
19113
  }
19114
+ async function fillWithUniqueGuard(values, run) {
19115
+ const first = await run(values);
19116
+ const counts = /* @__PURE__ */ new Map();
19117
+ for (const f of first.filled) {
19118
+ if (f.key) counts.set(f.key, (_nullishCoalesce(counts.get(f.key), () => ( 0))) + 1);
19119
+ }
19120
+ const isArrayValue = (normKey) => {
19121
+ for (const [label, raw] of Object.entries(values)) {
19122
+ if (normalizeLabel(label) !== normKey) continue;
19123
+ return Array.isArray(typeof raw === "object" && !Array.isArray(raw) ? raw.value : raw);
19124
+ }
19125
+ return false;
19126
+ };
19127
+ const dup = new Set([...counts].filter(([k, n]) => n >= 2 && !isArrayValue(k)).map(([k]) => k));
19128
+ if (dup.size === 0) return { ...first, rejected: [] };
19129
+ const filtered = Object.fromEntries(Object.entries(values).filter(([label]) => !dup.has(normalizeLabel(label))));
19130
+ const second = await run(filtered);
19131
+ const rejected = Object.keys(values).filter((label) => dup.has(normalizeLabel(label)));
19132
+ return { ...second, rejected };
19133
+ }
19003
19134
  function resolveUnmatched(normalizedValues, matchedLabels, originalValues) {
19004
19135
  return [...normalizedValues.keys()].filter((k) => !matchedLabels.has(k)).map((k) => {
19005
19136
  for (const orig of Object.keys(originalValues)) {
@@ -19269,7 +19400,7 @@ function fillFormFields(blocks, values) {
19269
19400
  cell.text = result.text;
19270
19401
  patternFilledCells.add(cell);
19271
19402
  for (const m of result.matches) {
19272
- filled.push({ label: m.label, value: m.value, row: r, col: c });
19403
+ filled.push({ label: m.label, value: m.value, row: r, col: c, key: m.key });
19273
19404
  }
19274
19405
  }
19275
19406
  }
@@ -19349,7 +19480,8 @@ function fillTable(table, values, filled, matchedLabels, patternFilledCells) {
19349
19480
  label: labelCell.text.trim().replace(/[::]\s*$/, ""),
19350
19481
  value: newValue,
19351
19482
  row: r,
19352
- col: c
19483
+ col: c,
19484
+ key: matchKey
19353
19485
  });
19354
19486
  }
19355
19487
  }
@@ -19378,7 +19510,8 @@ function fillTable(table, values, filled, matchedLabels, patternFilledCells) {
19378
19510
  label: headerCell.text.trim(),
19379
19511
  value: newValue,
19380
19512
  row: r,
19381
- col: c
19513
+ col: c,
19514
+ key: matchKey
19382
19515
  });
19383
19516
  }
19384
19517
  }
@@ -19395,7 +19528,7 @@ function fillInlineFields(text, values, filled, matchedLabels) {
19395
19528
  const newValue = values.consume(matchKey);
19396
19529
  if (newValue === void 0) continue;
19397
19530
  matchedLabels.add(matchKey);
19398
- filled.push({ label: seg.label.trim(), value: newValue, row: -1, col: -1 });
19531
+ filled.push({ label: seg.label.trim(), value: newValue, row: -1, col: -1, key: matchKey });
19399
19532
  out += text.slice(pos, seg.valueStart);
19400
19533
  out += seg.valueStart === seg.valueEnd ? padInsertion(text, seg.valueStart, newValue) : newValue;
19401
19534
  pos = seg.valueEnd;
@@ -19957,19 +20090,19 @@ function parseCentralDirectory(buf) {
19957
20090
  }
19958
20091
  }
19959
20092
  }
19960
- if (eocdOffset < 0) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP EOCD\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
20093
+ if (eocdOffset < 0) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP EOCD\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
19961
20094
  const totalEntries = view.getUint16(eocdOffset + 10, true);
19962
20095
  const cdSize = view.getUint32(eocdOffset + 12, true);
19963
20096
  const cdOffset = view.getUint32(eocdOffset + 16, true);
19964
- if (cdOffset === 4294967295 || totalEntries === 65535) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
20097
+ if (cdOffset === 4294967295 || totalEntries === 65535) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19965
20098
  if (eocdOffset >= 20 && view.getUint32(eocdOffset - 20, true) === ZIP64_EOCD_LOC_SIG) {
19966
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
20099
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19967
20100
  }
19968
20101
  const decoder = new TextDecoder("utf-8");
19969
20102
  const entries = [];
19970
20103
  let pos = cdOffset;
19971
20104
  for (let i = 0; i < totalEntries; i++) {
19972
- if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
20105
+ if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
19973
20106
  const flags = view.getUint16(pos + 8, true);
19974
20107
  const method = view.getUint16(pos + 10, true);
19975
20108
  const crc = view.getUint32(pos + 16, true);
@@ -19980,7 +20113,7 @@ function parseCentralDirectory(buf) {
19980
20113
  const commentLen = view.getUint16(pos + 32, true);
19981
20114
  const localOffset = view.getUint32(pos + 42, true);
19982
20115
  if (compSize === 4294967295 || uncompSize === 4294967295 || localOffset === 4294967295) {
19983
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
20116
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19984
20117
  }
19985
20118
  const name = decoder.decode(buf.subarray(pos + 46, pos + 46 + nameLen));
19986
20119
  const cdEnd = pos + 46 + nameLen + extraLen + commentLen;
@@ -20009,7 +20142,7 @@ function patchZipEntries(original, replacements) {
20009
20142
  const { entries, cdOffset, eocdOffset } = parseCentralDirectory(original);
20010
20143
  const view = new DataView(original.buffer, original.byteOffset, original.byteLength);
20011
20144
  for (const name of replacements.keys()) {
20012
- if (!entries.some((e) => e.name === name)) throw new (0, _chunkMEXUFQVCcjs.KordocError)(`ZIP\uC5D0 \uC5C6\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
20145
+ if (!entries.some((e) => e.name === name)) throw new (0, _chunkDMBTOJK4cjs.KordocError)(`ZIP\uC5D0 \uC5C6\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
20013
20146
  }
20014
20147
  const byLocal = [...entries].sort((a, b) => a.localOffset - b.localOffset);
20015
20148
  const segments = [];
@@ -20027,7 +20160,7 @@ function patchZipEntries(original, replacements) {
20027
20160
  offset += seg.length;
20028
20161
  continue;
20029
20162
  }
20030
- if (view.getUint32(e.localOffset, true) !== LOCAL_SIG) throw new (0, _chunkMEXUFQVCcjs.KordocError)("ZIP \uB85C\uCEEC \uD5E4\uB354 \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
20163
+ if (view.getUint32(e.localOffset, true) !== LOCAL_SIG) throw new (0, _chunkDMBTOJK4cjs.KordocError)("ZIP \uB85C\uCEEC \uD5E4\uB354 \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
20031
20164
  const nameLen = view.getUint16(e.localOffset + 26, true);
20032
20165
  const extraLen = view.getUint16(e.localOffset + 28, true);
20033
20166
  const headerLen = 30 + nameLen + extraLen;
@@ -20082,7 +20215,7 @@ async function fillHwpx(hwpxBuffer, values) {
20082
20215
  const zip = await _jszip2.default.loadAsync(hwpxBuffer);
20083
20216
  const sectionPaths = Object.keys(zip.files).filter((name) => /[Ss]ection\d+\.xml$/i.test(name)).sort();
20084
20217
  if (sectionPaths.length === 0) {
20085
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
20218
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
20086
20219
  }
20087
20220
  const normalizedValues = normalizeValues(values);
20088
20221
  const cursor = new ValueCursor(normalizedValues);
@@ -20232,7 +20365,8 @@ async function fillHwpx(hwpxBuffer, values) {
20232
20365
  label: cellLabelText(headerCells[colIdx]).trim(),
20233
20366
  value: newValue,
20234
20367
  row: rowIdx,
20235
- col: colIdx
20368
+ col: colIdx,
20369
+ key: matchKey
20236
20370
  });
20237
20371
  }
20238
20372
  }
@@ -21453,7 +21587,7 @@ function escapeGfm(text) {
21453
21587
  }
21454
21588
  var HWP_SHAPE_ALT_TEXT_RE = /(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|이등변 삼각형|직각 삼각형|선|직선|곡선|화살표|굵은 화살표|이중 화살표|오각형|육각형|팔각형|별|[4-8]점별|십자|십자형|구름|구름형|마름모|도넛|평행사변형|사다리꼴|부채꼴|호|반원|물결|번개|하트|빗금|블록 화살표|수식|표|그림|개체|그리기\s?개체|묶음\s?개체|글상자|수식\s?개체|OLE\s?개체)\s?입니다\.?/g;
21455
21589
  function sanitizeText(text) {
21456
- let result = _chunkMEXUFQVCcjs.mapPuaText.call(void 0, text).replace(/[\u{F0000}-\u{FFFFD}]/gu, "").replace(HWP_SHAPE_ALT_TEXT_RE, "").replace(/ +/g, " ").trim();
21590
+ let result = _chunkDMBTOJK4cjs.mapPuaText.call(void 0, text).replace(/[\u{F0000}-\u{FFFFD}]/gu, "").replace(HWP_SHAPE_ALT_TEXT_RE, "").replace(/ +/g, " ").trim();
21457
21591
  if (result.length <= 30 && result.includes(" ")) {
21458
21592
  const tokens = result.split(" ");
21459
21593
  const koreanSingleCharCount = tokens.filter((t) => t.length === 1 && /[가-힯ㄱ-ㆎ]/.test(t)).length;
@@ -21939,9 +22073,9 @@ function readCommand(input, idx, depth) {
21939
22073
  const command = name.value;
21940
22074
  if (command === "\\") return { value: "#", next: name.next };
21941
22075
  if (command === "frac") {
21942
- const num2 = readGroupOrToken(input, name.next, depth);
21943
- const den = readGroupOrToken(input, num2.next, depth);
21944
- return { value: `{${num2.value}} over {${den.value}}`, next: den.next };
22076
+ const num3 = readGroupOrToken(input, name.next, depth);
22077
+ const den = readGroupOrToken(input, num3.next, depth);
22078
+ return { value: `{${num3.value}} over {${den.value}}`, next: den.next };
21945
22079
  }
21946
22080
  if (command === "sqrt") {
21947
22081
  let cursor = skipSpaces(input, name.next);
@@ -21982,6 +22116,9 @@ function readCommand(input, idx, depth) {
21982
22116
  const body = readGroupOrToken(input, name.next, depth);
21983
22117
  return { value: `${ACCENT_COMMANDS[command]}{${body.value}}`, next: body.next };
21984
22118
  }
22119
+ if (command === ",") return { value: "`", next: name.next };
22120
+ if (command === ";" || command === ":") return { value: "~", next: name.next };
22121
+ if (command === "!") return { value: "", next: name.next };
21985
22122
  if (command === "mathrm" || command === "text") {
21986
22123
  const start = skipSpaces(input, name.next);
21987
22124
  if (input[start] === "{") {
@@ -22958,7 +23095,7 @@ async function resolveSectionEntryNames(zip) {
22958
23095
  const paths = sectionPathsFromManifest(xml).filter((p) => zip.file(p) !== null);
22959
23096
  if (paths.length > 0) return paths;
22960
23097
  }
22961
- return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunkMEXUFQVCcjs.compareSectionPaths);
23098
+ return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunkDMBTOJK4cjs.compareSectionPaths);
22962
23099
  }
22963
23100
  function sectionPathsFromManifest(xml) {
22964
23101
  const attr = (tag, name) => {
@@ -22968,7 +23105,7 @@ function sectionPathsFromManifest(xml) {
22968
23105
  const idToHref = /* @__PURE__ */ new Map();
22969
23106
  for (const m of xml.matchAll(/<opf:item(\s(?:"[^"]*"|'[^']*'|[^>"'])*?)\/?>/g)) {
22970
23107
  const id = attr(m[1], "id");
22971
- const href = _chunkMEXUFQVCcjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
23108
+ const href = _chunkDMBTOJK4cjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
22972
23109
  if (id && href) idToHref.set(id, href);
22973
23110
  }
22974
23111
  const ordered = [];
@@ -22977,7 +23114,7 @@ function sectionPathsFromManifest(xml) {
22977
23114
  if (href) ordered.push(href);
22978
23115
  }
22979
23116
  if (ordered.length > 0) return ordered;
22980
- return Array.from(idToHref.values()).sort(_chunkMEXUFQVCcjs.compareSectionPaths);
23117
+ return Array.from(idToHref.values()).sort(_chunkDMBTOJK4cjs.compareSectionPaths);
22981
23118
  }
22982
23119
 
22983
23120
  // src/roundtrip/patcher.ts
@@ -23088,9 +23225,9 @@ function buildOrigUnits(blocks) {
23088
23225
  if (block.type === "paragraph" && block.text && /^\[별표\s*\d+/.test(sanitizeText(block.text))) {
23089
23226
  const next = blocks[i + 1];
23090
23227
  if (_optionalChain([next, 'optionalAccess', _217 => _217.type]) === "paragraph" && next.text && /관련\)?$/.test(next.text)) consume = 2;
23091
- chunk = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
23228
+ chunk = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
23092
23229
  } else {
23093
- chunk = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, [block]);
23230
+ chunk = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, [block]);
23094
23231
  }
23095
23232
  if (chunk) {
23096
23233
  const subUnits = splitMarkdownUnits(chunk);
@@ -23984,10 +24121,11 @@ function handleModified(orig, edited, ctx) {
23984
24121
  function patchParagraph(block, orig, edited, ctx, skip) {
23985
24122
  const mapping = ctx.paraMap.get(orig.blockIdx);
23986
24123
  if (!_optionalChain([mapping, 'optionalAccess', _238 => _238.para])) return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED\uC774\uAC70\uB098 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)");
23987
- if (block.text && block.text.includes("\n")) {
23988
- return skip("\uBB38\uB2E8 \uB0B4 \uAC15\uC81C \uC904\uBC14\uAFC8 \uD3EC\uD568 \u2014 \uC218\uC815 \uC2DC \uC904\uBC14\uAFC8 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0 (v1)");
24124
+ const restoreBr = (s) => s.replace(/\s*<br\s*\/?\s*>\s*/gi, "\n");
24125
+ let newPlain = restoreBr(textUnitToPlain(edited.raw, block));
24126
+ if (block.text && block.text.includes("\n") && !newPlain.includes("\n")) {
24127
+ return skip("\uB2E4\uC911\uC904 \uBB38\uB2E8 \uC218\uC815\uC5D0 <br> \uC5C6\uC74C \u2014 \uC904\uBC14\uAFC8 \uC704\uCE58 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0 (\uC904\uBC14\uAFC8\uC740 <br>\uB85C \uD45C\uAE30)");
23989
24128
  }
23990
- let newPlain = textUnitToPlain(edited.raw, block);
23991
24129
  if (block.footnoteText) {
23992
24130
  const noteMatch = newPlain.match(/\s*\(주: ([\s\S]*)\)$/);
23993
24131
  if (noteMatch) {
@@ -24009,7 +24147,7 @@ function patchParagraph(block, orig, edited, ctx, skip) {
24009
24147
  ctx.skipped.push({ reason: "\uC790\uB3D9\uBC88\uD638 \uC811\uB450 \uC2DD\uBCC4 \uC2E4\uD328 \u2014 \uBC88\uD638 \uD3EC\uD568 \uD14D\uC2A4\uD2B8\uB85C \uC801\uC6A9 (\uBDF0\uC5B4\uC5D0\uC11C \uC911\uBCF5 \uD45C\uC2DC \uAC00\uB2A5)", after: summarize(newPlain) });
24010
24148
  }
24011
24149
  }
24012
- const origPlain = textUnitToPlain(orig.raw, block);
24150
+ const origPlain = restoreBr(textUnitToPlain(orig.raw, block));
24013
24151
  if (newPlain === origPlain) return skip("\uD14D\uC2A4\uD2B8 \uC678 \uBCC0\uACBD(\uD5E4\uB529 \uB808\uBCA8/\uC11C\uC2DD)\uB9CC \uAC10\uC9C0 \u2014 \uC2A4\uD0C0\uC77C \uBCC0\uACBD\uC740 \uBBF8\uC9C0\uC6D0");
24014
24152
  if (sanitizeText(newPlain) !== newPlain) {
24015
24153
  return skip("\uACF5\uBC31 \uC815\uADDC\uD654 \uBD88\uC548\uC815 \uD14D\uC2A4\uD2B8 \u2014 \uD328\uCE58 \uC2DC \uC6D0\uBB38 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0");
@@ -24037,6 +24175,28 @@ function patchGfmCells(scanTable, orig, edited, ctx, skip) {
24037
24175
  }
24038
24176
  const beforeParts = origRows[r][c].split(/<br\s*\/?>/i);
24039
24177
  const afterParts = editedRows[r][c].split(/<br\s*\/?>/i);
24178
+ if (cell.paras.length === 1) {
24179
+ const beforeEach = beforeParts.map(gfmCellToPlain);
24180
+ const afterEach = afterParts.map(gfmCellToPlain);
24181
+ if (beforeEach.some((p) => p === null) || afterEach.some((p) => p === null)) {
24182
+ cellSkip("\uC11C\uC2DD/\uB9C1\uD06C/\uC774\uBBF8\uC9C0 \uD3EC\uD568 \uC140 \uC218\uC815\uC740 \uBBF8\uC9C0\uC6D0 (v1)");
24183
+ continue;
24184
+ }
24185
+ const before = beforeEach.join("\n");
24186
+ const after = afterEach.join("\n");
24187
+ if (before === after) continue;
24188
+ const para = cell.paras[0];
24189
+ if (normForMatch(para.rawText) !== normForMatch(before)) {
24190
+ cellSkip("\uC140 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58 \u2014 \uC18C\uC2A4\uB9F5 \uC2E0\uB8B0 \uBD88\uAC00");
24191
+ continue;
24192
+ }
24193
+ if (afterEach.some((l) => sanitizeText(l) !== l)) {
24194
+ cellSkip("\uACF5\uBC31 \uC815\uADDC\uD654 \uBD88\uC548\uC815 \uD14D\uC2A4\uD2B8 \u2014 \uBBF8\uC9C0\uC6D0");
24195
+ continue;
24196
+ }
24197
+ applied += stageParaPatch(ctx.scans[para.sectionIndex], para, after, cellSkip);
24198
+ continue;
24199
+ }
24040
24200
  if (beforeParts.length !== cell.paras.length || afterParts.length !== cell.paras.length) {
24041
24201
  cellSkip("\uC140 \uBB38\uB2E8 \uC218 \uBCC0\uACBD \u2014 \uBBF8\uC9C0\uC6D0 (\uBB38\uB2E8 \uCD94\uAC00/\uC0AD\uC81C)");
24042
24202
  continue;
@@ -24181,13 +24341,13 @@ function applyCellEdit5(table, scanTable, gridR, gridC, newLines, ctx, before, a
24181
24341
  const assigned = [];
24182
24342
  for (let i = 0; i < targets.length; i++) {
24183
24343
  if (i < newLines.length) {
24184
- assigned.push(i === targets.length - 1 && newLines.length > targets.length ? newLines.slice(i).join(" ") : newLines[i]);
24344
+ assigned.push(i === targets.length - 1 && newLines.length > targets.length ? newLines.slice(i).join("\n") : newLines[i]);
24185
24345
  } else {
24186
24346
  assigned.push("");
24187
24347
  }
24188
24348
  }
24189
24349
  if (newLines.length > targets.length) {
24190
- ctx.skipped.push({ reason: "\uC140 \uB0B4 \uC904 \uCD94\uAC00\uB294 \uBB38\uB2E8 \uC0DD\uC131 \uBBF8\uC9C0\uC6D0 \u2014 \uB9C8\uC9C0\uB9C9 \uBB38\uB2E8\uC5D0 \uBCD1\uD569 \uC801\uC6A9", after: summarize(after), partial: true });
24350
+ ctx.skipped.push({ reason: "\uC140 \uB0B4 \uCD94\uAC00 \uC904\uC744 \uB9C8\uC9C0\uB9C9 \uBB38\uB2E8\uC5D0 \uAC15\uC81C \uC904\uBC14\uAFC8\uC73C\uB85C \uBCD1\uD569(\uBB38\uB2E8 \uC0DD\uC131 \uB300\uC2E0)", after: summarize(after), partial: true });
24191
24351
  } else if (newLines.length < nonEmpty.length && nonEmpty.length > 1) {
24192
24352
  ctx.skipped.push({ reason: "\uC140 \uB0B4 \uC904 \uC0AD\uC81C\uB294 \uBB38\uB2E8 \uC81C\uAC70 \uBBF8\uC9C0\uC6D0 \u2014 \uBE48 \uBB38\uB2E8 \uC794\uC874(\uBDF0\uC5B4\uC5D0 \uBE48 \uC904 \uD45C\uC2DC \uAC00\uB2A5)", before: summarize(before), after: summarize(after), partial: true });
24193
24353
  }
@@ -24245,8 +24405,7 @@ function splitParaText(data) {
24245
24405
  i += 16;
24246
24406
  toks.push({ start, end: i, units: 1, plain: false, visible: false });
24247
24407
  } else {
24248
- if (i + 14 <= data.length) i += 14;
24249
- toks.push({ start, end: i, units: 1, plain: false, visible: true });
24408
+ toks.push({ start, end: i, units: 1, plain: true, visible: true });
24250
24409
  }
24251
24410
  break;
24252
24411
  default: {
@@ -24309,13 +24468,31 @@ function rebuildCharShape(csData, coreStartUnit) {
24309
24468
  });
24310
24469
  return { buf, count: kept.length };
24311
24470
  }
24471
+ function synthesizeLineSegs(lineSegData, newRaw, startUnits) {
24472
+ if (lineSegData.length < 36) return null;
24473
+ const seg0 = lineSegData.subarray(0, 36);
24474
+ const vPos0 = seg0.readInt32LE(4);
24475
+ const pitch = seg0.readInt32LE(8) + seg0.readInt32LE(20);
24476
+ if (pitch <= 0) return null;
24477
+ const lines = newRaw.split("\n");
24478
+ const segs = [];
24479
+ let pos = startUnits;
24480
+ for (let k = 0; k < lines.length; k++) {
24481
+ const s = Buffer.from(seg0);
24482
+ s.writeUInt32LE((k === 0 ? 0 : pos) >>> 0, 0);
24483
+ s.writeInt32LE(vPos0 + k * pitch, 4);
24484
+ segs.push(s);
24485
+ pos += lines[k].length + 1;
24486
+ }
24487
+ return { buf: Buffer.concat(segs), count: lines.length };
24488
+ }
24312
24489
  function stageParaPatch(scan, para, newPlain, skip) {
24313
24490
  if (!scan.safe) return skip("\uC139\uC158 \uB808\uCF54\uB4DC \uC7AC\uC9C1\uB82C\uD654 \uBD88\uC77C\uCE58 \u2014 \uC548\uC804\uC744 \uC704\uD574 \uC774 \uC139\uC158\uC740 \uBBF8\uC9C0\uC6D0");
24314
24491
  if (para.textIdx === -2) return skip("\uBCF5\uC218 PARA_TEXT \uB808\uCF54\uB4DC \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)");
24315
24492
  if (para.rangeTagCount > 0) return skip("\uBC94\uC704 \uD0DC\uADF8(\uD615\uAD11\uD39C/\uAD50\uC815\uBD80\uD638) \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)");
24316
24493
  if (para.charShapeIdx < 0 || para.lineSegIdx < 0) return skip("\uBB38\uB2E8 \uB808\uCF54\uB4DC \uAD6C\uC131 \uBE44\uC815\uD615 \u2014 \uBBF8\uC9C0\uC6D0");
24317
24494
  if (scan.repl.has(para.headerIdx)) return skip("\uB3D9\uC77C \uBB38\uB2E8 \uC911\uBCF5 \uC218\uC815 \u2014 \uCCAB \uC218\uC815\uB9CC \uC801\uC6A9");
24318
- if (/[\u0000-\u001f]/.test(newPlain)) return skip("\uC0C8 \uD14D\uC2A4\uD2B8\uC5D0 \uC81C\uC5B4\uBB38\uC790 \uD3EC\uD568 \u2014 \uBBF8\uC9C0\uC6D0");
24495
+ if (/[\u0000-\u0009\u000b-\u001f]/.test(newPlain)) return skip("\uC0C8 \uD14D\uC2A4\uD2B8\uC5D0 \uC81C\uC5B4\uBB38\uC790 \uD3EC\uD568 \u2014 \uBBF8\uC9C0\uC6D0");
24319
24496
  const records = scan.records;
24320
24497
  const headerRec = records[para.headerIdx];
24321
24498
  const charShapeRec = records[para.charShapeIdx];
@@ -24335,6 +24512,13 @@ function stageParaPatch(scan, para, newPlain, skip) {
24335
24512
  const cs2 = rebuildCharShape(charShapeRec.data, 0);
24336
24513
  scan.repl.set(para.charShapeIdx, cs2.buf);
24337
24514
  newHeader2.writeUInt16LE(cs2.count, 12);
24515
+ if (newPlain.includes("\n")) {
24516
+ const synth = synthesizeLineSegs(records[para.lineSegIdx].data, newPlain, 0);
24517
+ if (synth) {
24518
+ scan.repl.set(para.lineSegIdx, synth.buf);
24519
+ newHeader2.writeUInt16LE(synth.count, 16);
24520
+ }
24521
+ }
24338
24522
  scan.repl.set(para.headerIdx, newHeader2);
24339
24523
  return 1;
24340
24524
  }
@@ -24355,10 +24539,103 @@ function stageParaPatch(scan, para, newPlain, skip) {
24355
24539
  const cs = rebuildCharShape(charShapeRec.data, seg.prefixUnits);
24356
24540
  scan.repl.set(para.charShapeIdx, cs.buf);
24357
24541
  newHeader.writeUInt16LE(cs.count, 12);
24542
+ if (newRaw.includes("\n")) {
24543
+ const synth = synthesizeLineSegs(records[para.lineSegIdx].data, newRaw, seg.prefixUnits);
24544
+ if (synth) {
24545
+ scan.repl.set(para.lineSegIdx, synth.buf);
24546
+ newHeader.writeUInt16LE(synth.count, 16);
24547
+ }
24548
+ }
24358
24549
  scan.repl.set(para.headerIdx, newHeader);
24359
24550
  return 1;
24360
24551
  }
24361
24552
 
24553
+ // src/validate.ts
24554
+
24555
+
24556
+ var REQUIRED_FILES = [
24557
+ "mimetype",
24558
+ "META-INF/container.xml",
24559
+ "Contents/content.hpf",
24560
+ "Contents/header.xml",
24561
+ "Contents/section0.xml"
24562
+ ];
24563
+ var EXPECTED_MIMETYPE = "application/hwp+zip";
24564
+ var XML_SUFFIXES = [".xml", ".hpf", ".rdf"];
24565
+ var SECTION_FILE_RE = /^Contents\/section\d+\.xml$/;
24566
+ var SECCNT_RE = /<(?:\w+:)?head\b[^>]*?\bsecCnt="(\d+)"/;
24567
+ var OPF_HREF_RE = /<opf:item\b[^>]*?\bhref="([^"]*)"/g;
24568
+ async function validateHwpx(buffer) {
24569
+ const issues = [];
24570
+ let zip;
24571
+ try {
24572
+ zip = await _jszip2.default.loadAsync(buffer);
24573
+ } catch (err) {
24574
+ return {
24575
+ ok: false,
24576
+ issues: [{ message: `\uC720\uD6A8\uD55C ZIP\uC774 \uC544\uB2D8: ${err instanceof Error ? err.message : String(err)}` }],
24577
+ entryCount: 0
24578
+ };
24579
+ }
24580
+ const rawNames = Object.keys(zip.files);
24581
+ const names = rawNames.filter((n) => !zip.files[n].dir);
24582
+ if (names.length === 0) return { ok: false, issues: [{ message: "\uBE48 ZIP" }], entryCount: 0 };
24583
+ if (rawNames[0] !== "mimetype") {
24584
+ issues.push({ message: `\uCCAB zip \uC5D4\uD2B8\uB9AC\uAC00 '${rawNames[0]}' \u2014 'mimetype'\uC774\uC5B4\uC57C \uD568` });
24585
+ }
24586
+ const nameset = new Set(names);
24587
+ if (nameset.has("mimetype")) {
24588
+ const mt = (await zip.files["mimetype"].async("string")).trim();
24589
+ if (mt !== EXPECTED_MIMETYPE) {
24590
+ issues.push({ path: "mimetype", message: `\uB0B4\uC6A9\uC774 '${mt}' \u2014 '${EXPECTED_MIMETYPE}'\uC774\uC5B4\uC57C \uD568` });
24591
+ }
24592
+ }
24593
+ for (const req of REQUIRED_FILES) {
24594
+ if (!nameset.has(req)) issues.push({ message: `\uD544\uC218 \uD30C\uC77C \uB204\uB77D: ${req}` });
24595
+ }
24596
+ for (const name of names) {
24597
+ if (!XML_SUFFIXES.some((s) => name.endsWith(s))) continue;
24598
+ const text = await zip.files[name].async("string");
24599
+ let firstError = null;
24600
+ try {
24601
+ new (0, _xmldom.DOMParser)({
24602
+ onError(level, msg2) {
24603
+ if (level !== "warning" && firstError === null) firstError = String(msg2);
24604
+ }
24605
+ }).parseFromString(text, "text/xml");
24606
+ } catch (err) {
24607
+ firstError ??= err instanceof Error ? err.message : String(err);
24608
+ }
24609
+ if (firstError !== null) {
24610
+ issues.push({ path: name, message: `XML \uC6F0\uD3FC\uB4DC \uC704\uBC18: ${firstError.split("\n")[0]}` });
24611
+ }
24612
+ }
24613
+ if (nameset.has("Contents/header.xml")) {
24614
+ const header = await zip.files["Contents/header.xml"].async("string");
24615
+ const m = SECCNT_RE.exec(header);
24616
+ if (m) {
24617
+ const declared = Number(m[1]);
24618
+ const actual = names.filter((n) => SECTION_FILE_RE.test(n)).length;
24619
+ if (declared !== actual) {
24620
+ issues.push({
24621
+ path: "Contents/header.xml",
24622
+ message: `secCnt=${declared}\uC778\uB370 \uC2E4\uC81C sectionN.xml\uC740 ${actual}\uAC1C \u2014 \uD55C\uCEF4\uB3C5\uC2A4\uAC00 \uC5F4\uAE30\uB97C \uAC70\uBD80\uD568`
24623
+ });
24624
+ }
24625
+ }
24626
+ }
24627
+ if (nameset.has("Contents/content.hpf")) {
24628
+ const hpf = await zip.files["Contents/content.hpf"].async("string");
24629
+ for (const m of hpf.matchAll(OPF_HREF_RE)) {
24630
+ const href = m[1];
24631
+ if (!nameset.has(href) && !nameset.has(`Contents/${href}`)) {
24632
+ issues.push({ path: "Contents/content.hpf", message: `manifest\uAC00 \uC5C6\uB294 \uD30C\uC77C\uC744 \uCC38\uC870: ${href}` });
24633
+ }
24634
+ }
24635
+ }
24636
+ return { ok: issues.length === 0, issues, entryCount: names.length };
24637
+ }
24638
+
24362
24639
  // src/roundtrip/session.ts
24363
24640
 
24364
24641
  async function buildState(bytes) {
@@ -24788,13 +25065,13 @@ async function htmlToPdf(html, options) {
24788
25065
  try {
24789
25066
  puppeteer = await Promise.resolve().then(() => _interopRequireWildcard(require("puppeteer-core")));
24790
25067
  } catch (e30) {
24791
- throw new (0, _chunkMEXUFQVCcjs.KordocError)(
25068
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)(
24792
25069
  "PDF \uC0DD\uC131\uC5D0 puppeteer-core\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC124\uCE58: npm install puppeteer-core"
24793
25070
  );
24794
25071
  }
24795
25072
  const executablePath = _nullishCoalesce(process.env.PUPPETEER_EXECUTABLE_PATH, () => ( findChromiumPath()));
24796
25073
  if (!executablePath) {
24797
- throw new (0, _chunkMEXUFQVCcjs.KordocError)(
25074
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)(
24798
25075
  "Chromium \uC2E4\uD589 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. PUPPETEER_EXECUTABLE_PATH \uD658\uACBD\uBCC0\uC218\uB97C \uC124\uC815\uD558\uC138\uC694."
24799
25076
  );
24800
25077
  }
@@ -24853,7 +25130,7 @@ async function markdownToPdf(markdown, options) {
24853
25130
  return htmlToPdf(html, options);
24854
25131
  }
24855
25132
  async function blocksToPdf(blocks, options) {
24856
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, blocks);
25133
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, blocks);
24857
25134
  return markdownToPdf(markdown, options);
24858
25135
  }
24859
25136
 
@@ -24935,6 +25212,15 @@ function solveRowHeights(cells, rowCount) {
24935
25212
  }
24936
25213
 
24937
25214
  // src/render/head-styles.ts
25215
+ var DEFAULT_PARA_GEOM = {
25216
+ lineSpacingType: "PERCENT",
25217
+ lineSpacingValue: 160,
25218
+ marginLeft: 0,
25219
+ marginRight: 0,
25220
+ marginIntent: 0,
25221
+ spaceBefore: 0,
25222
+ spaceAfter: 0
25223
+ };
24938
25224
  var DEFAULT_CHAR = { height: 1e3, bold: false, italic: false, underline: false, ratio: 100, spacing: 0 };
24939
25225
  function borderWidthPt(v) {
24940
25226
  const n = parseFloat(_nullishCoalesce(v, () => ( "")));
@@ -24947,8 +25233,43 @@ function parseEdge(el) {
24947
25233
  if (type === "NONE") return void 0;
24948
25234
  return { type, widthPt: borderWidthPt(el.getAttribute("width")), color: _nullishCoalesce(el.getAttribute("color"), () => ( "#000000")) };
24949
25235
  }
25236
+ function findDeep(el, name, depth = 0) {
25237
+ if (depth > 32) return null;
25238
+ const children = el.childNodes;
25239
+ if (!children) return null;
25240
+ for (let i = 0; i < children.length; i++) {
25241
+ const ch = children[i];
25242
+ if (ch.nodeType !== 1) continue;
25243
+ const e = ch;
25244
+ if ((e.tagName || "").replace(/^[^:]+:/, "") === name) return e;
25245
+ const found = findDeep(e, name, depth + 1);
25246
+ if (found) return found;
25247
+ }
25248
+ return null;
25249
+ }
25250
+ function parseParaGeom(el) {
25251
+ const g = { ...DEFAULT_PARA_GEOM };
25252
+ const ls = findDeep(el, "lineSpacing");
25253
+ if (ls) {
25254
+ g.lineSpacingType = _nullishCoalesce(ls.getAttribute("type"), () => ( "PERCENT"));
25255
+ g.lineSpacingValue = Number(ls.getAttribute("value")) || 160;
25256
+ }
25257
+ const margin = findDeep(el, "margin");
25258
+ if (margin) {
25259
+ const v = (n) => {
25260
+ const c = findDeep(margin, n);
25261
+ return c ? Number(c.getAttribute("value")) || 0 : 0;
25262
+ };
25263
+ g.marginLeft = v("left");
25264
+ g.marginRight = v("right");
25265
+ g.marginIntent = v("intent");
25266
+ g.spaceBefore = v("prev");
25267
+ g.spaceAfter = v("next");
25268
+ }
25269
+ return g;
25270
+ }
24950
25271
  function parseRenderStyles(headXml) {
24951
- const styles = { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
25272
+ const styles = { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), paraGeom: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
24952
25273
  const doc = createXmlParser().parseFromString(headXml, "text/xml");
24953
25274
  const root = doc.documentElement;
24954
25275
  if (!root) return styles;
@@ -24976,6 +25297,7 @@ function parseRenderStyles(headXml) {
24976
25297
  if (id != null) {
24977
25298
  const align = findChildByLocalName(el, "align");
24978
25299
  styles.paraAlign.set(id, _optionalChain([align, 'optionalAccess', _280 => _280.getAttribute, 'call', _281 => _281("horizontal")]) || "JUSTIFY");
25300
+ styles.paraGeom.set(id, parseParaGeom(el));
24979
25301
  }
24980
25302
  } else if (tag === "borderFill") {
24981
25303
  const id = el.getAttribute("id");
@@ -25003,11 +25325,162 @@ function parseRenderStyles(headXml) {
25003
25325
  return styles;
25004
25326
  }
25005
25327
 
25006
- // src/render/svg-render.ts
25328
+ // src/render/reflow.ts
25329
+ var LINESEG_FLAGS = "393216";
25330
+ var BASELINE_RATIO = 0.85;
25007
25331
  function ln(el) {
25008
25332
  return (el.tagName || "").replace(/^[^:]+:/, "");
25009
25333
  }
25010
25334
  function elements(el) {
25335
+ const out = [];
25336
+ const kids2 = el.childNodes;
25337
+ if (!kids2) return out;
25338
+ for (let i = 0; i < kids2.length; i++) if (kids2[i].nodeType === 1) out.push(kids2[i]);
25339
+ return out;
25340
+ }
25341
+ function num(el, attr, fallback = 0) {
25342
+ return el ? toInt32(_nullishCoalesce(el.getAttribute(attr), () => ( void 0)), fallback) : fallback;
25343
+ }
25344
+ function shiftParaVert(p, delta) {
25345
+ for (const lsa of elements(p)) {
25346
+ if (ln(lsa) !== "linesegarray") continue;
25347
+ for (const seg of elements(lsa)) {
25348
+ if (ln(seg) !== "lineseg") continue;
25349
+ seg.setAttribute("vertpos", String(num(seg, "vertpos") + delta));
25350
+ }
25351
+ }
25352
+ }
25353
+ function pitchFor(height, geom) {
25354
+ const v = geom.lineSpacingValue;
25355
+ switch (geom.lineSpacingType) {
25356
+ case "PERCENT":
25357
+ return Math.round(height * v / 100);
25358
+ case "FIXED":
25359
+ return v > 0 ? v : Math.round(height * 1.6);
25360
+ // 고정 줄높이(HWPUNIT)
25361
+ case "AT_LEAST":
25362
+ return Math.max(v, height);
25363
+ default:
25364
+ return Math.round(height * 1.6);
25365
+ }
25366
+ }
25367
+ function reflowPara(p, doc, styles, areaW, startV, mode) {
25368
+ const m = buildPara(p);
25369
+ if (m.segs.length > 0) return null;
25370
+ const realIdx = [];
25371
+ let text = "";
25372
+ for (let i = 0; i < m.chars.length; i++) {
25373
+ const ch = m.chars[i].ch;
25374
+ if (ch === "") continue;
25375
+ for (let u = 0; u < ch.length; u++) realIdx.push(i);
25376
+ text += ch;
25377
+ }
25378
+ const geom = _nullishCoalesce(styles.paraGeom.get(_nullishCoalesce(m.paraPrId, () => ( ""))), () => ( DEFAULT_PARA_GEOM));
25379
+ let domChar = DEFAULT_CHAR;
25380
+ for (const c of m.chars) {
25381
+ if (c.ch !== "" && c.prId != null) {
25382
+ const st = styles.charPr.get(c.prId);
25383
+ if (st) {
25384
+ domChar = st;
25385
+ break;
25386
+ }
25387
+ }
25388
+ }
25389
+ const height = domChar.height || 1e3;
25390
+ const ratio = domChar.ratio || 100;
25391
+ const spacingPct = domChar.spacing || 0;
25392
+ const marginL = geom.marginLeft;
25393
+ const avail = Math.max(1e3, areaW - marginL - geom.marginRight);
25394
+ const firstWidth = avail;
25395
+ const contWidth = Math.max(500, avail + Math.min(0, geom.marginIntent));
25396
+ const contHorz = marginL - Math.min(0, geom.marginIntent);
25397
+ const wrap = text.length === 0 ? { lines: 1, starts: [0], lastLineWidth: 0 } : simulateWrap(text, firstWidth, contWidth, height, ratio, mode, { spacingPct });
25398
+ const pitch = pitchFor(height, geom);
25399
+ const baseline = Math.round(height * BASELINE_RATIO);
25400
+ const spacing = Math.max(0, pitch - height);
25401
+ const lsa = doc.createElement("hp:linesegarray");
25402
+ for (let li = 0; li < wrap.starts.length; li++) {
25403
+ const startReal = wrap.starts[li];
25404
+ const textpos = startReal < realIdx.length ? realIdx[startReal] : m.chars.length;
25405
+ const vertpos = startV + li * pitch;
25406
+ const isFirst = li === 0;
25407
+ const seg = doc.createElement("hp:lineseg");
25408
+ seg.setAttribute("textpos", String(textpos));
25409
+ seg.setAttribute("vertpos", String(vertpos));
25410
+ seg.setAttribute("vertsize", String(height));
25411
+ seg.setAttribute("textheight", String(height));
25412
+ seg.setAttribute("baseline", String(baseline));
25413
+ seg.setAttribute("spacing", String(spacing));
25414
+ seg.setAttribute("horzpos", String(isFirst ? marginL : contHorz));
25415
+ seg.setAttribute("horzsize", String(isFirst ? firstWidth : contWidth));
25416
+ seg.setAttribute("flags", LINESEG_FLAGS);
25417
+ lsa.appendChild(seg);
25418
+ }
25419
+ p.appendChild(lsa);
25420
+ const textBottom = startV + wrap.starts.length * pitch;
25421
+ let objBottom = startV;
25422
+ for (const o of m.objs) {
25423
+ const h = o.tag === "tbl" ? Math.max(o.height, measureTableHeight(o.el)) : o.height;
25424
+ objBottom = Math.max(objBottom, startV + h);
25425
+ }
25426
+ return { paraBottom: Math.max(textBottom, objBottom), spaceAfter: geom.spaceAfter };
25427
+ }
25428
+ function reflowTablesIn(p, doc, styles, mode, counter) {
25429
+ for (const run of elements(p)) {
25430
+ if (ln(run) !== "run") continue;
25431
+ for (const obj of elements(run)) {
25432
+ if (ln(obj) !== "tbl") continue;
25433
+ for (const tr of elements(obj)) {
25434
+ if (ln(tr) !== "tr") continue;
25435
+ for (const tc of elements(tr)) {
25436
+ if (ln(tc) !== "tc") continue;
25437
+ const csz = findChildByLocalName(tc, "cellSz");
25438
+ const cm = findChildByLocalName(tc, "cellMargin");
25439
+ const cellW = num(csz, "width");
25440
+ const mL = cm ? num(cm, "left", 141) : 141;
25441
+ const mR = cm ? num(cm, "right", 141) : 141;
25442
+ const areaW = Math.max(500, cellW - mL - mR);
25443
+ const sub = findChildByLocalName(tc, "subList");
25444
+ if (sub) reflowBlockFlow(sub, doc, styles, areaW, mode, counter, 0);
25445
+ }
25446
+ }
25447
+ }
25448
+ }
25449
+ }
25450
+ function reflowBlockFlow(container, doc, styles, areaW, mode, counter, bodyH) {
25451
+ let cursorV = 0;
25452
+ let prevSpaceAfter = 0;
25453
+ for (const p of elements(container)) {
25454
+ if (ln(p) !== "p") continue;
25455
+ reflowTablesIn(p, doc, styles, mode, counter);
25456
+ const g = styles.paraGeom.get(_nullishCoalesce(p.getAttribute("paraPrIDRef"), () => ( "")));
25457
+ const startV = cursorV + prevSpaceAfter + (_nullishCoalesce(_optionalChain([g, 'optionalAccess', _284 => _284.spaceBefore]), () => ( 0)));
25458
+ const res = reflowPara(p, doc, styles, areaW, startV, mode);
25459
+ if (res) {
25460
+ const paraH = res.paraBottom - startV;
25461
+ if (bodyH > 0 && startV > 0 && res.paraBottom > bodyH && paraH <= bodyH) {
25462
+ shiftParaVert(p, -startV);
25463
+ cursorV = paraH;
25464
+ } else {
25465
+ cursorV = res.paraBottom;
25466
+ }
25467
+ prevSpaceAfter = res.spaceAfter;
25468
+ counter.n++;
25469
+ }
25470
+ }
25471
+ }
25472
+ function reflowSection(root, styles, geom, mode = "keep") {
25473
+ const doc = root.ownerDocument;
25474
+ const counter = { n: 0 };
25475
+ reflowBlockFlow(root, doc, styles, geom.BODY_W, mode, counter, geom.BODY_H);
25476
+ return counter.n;
25477
+ }
25478
+
25479
+ // src/render/svg-render.ts
25480
+ function ln2(el) {
25481
+ return (el.tagName || "").replace(/^[^:]+:/, "");
25482
+ }
25483
+ function elements2(el) {
25011
25484
  const out = [];
25012
25485
  const children = el.childNodes;
25013
25486
  if (!children) return out;
@@ -25016,13 +25489,13 @@ function elements(el) {
25016
25489
  }
25017
25490
  return out;
25018
25491
  }
25019
- function num(el, attr, fallback = 0) {
25492
+ function num2(el, attr, fallback = 0) {
25020
25493
  return el ? toInt32(_nullishCoalesce(el.getAttribute(attr), () => ( void 0)), fallback) : fallback;
25021
25494
  }
25022
25495
  function findFirst(el, name, depth = 0) {
25023
25496
  if (depth > 64) return null;
25024
- for (const ch of elements(el)) {
25025
- if (ln(ch) === name) return ch;
25497
+ for (const ch of elements2(el)) {
25498
+ if (ln2(ch) === name) return ch;
25026
25499
  const found = findFirst(ch, name, depth + 1);
25027
25500
  if (found) return found;
25028
25501
  }
@@ -25033,59 +25506,80 @@ function escapeXml3(s) {
25033
25506
  }
25034
25507
  var OBJ_TAGS = /* @__PURE__ */ new Set(["tbl", "pic", "container", "equation", "rect", "ellipse", "polygon", "curv", "line", "arc", "ole", "textart"]);
25035
25508
  var pt = (u) => String(Math.round(u) / 100);
25509
+ function emit(ctx, s) {
25510
+ ctx.pages[ctx.page].push(s);
25511
+ }
25036
25512
  function warnOnce(ctx, key, msg2) {
25037
25513
  if (ctx.warned.has(key)) return;
25038
25514
  ctx.warned.add(key);
25039
25515
  ctx.warnings.push(msg2);
25040
25516
  }
25041
- function textOfT(t) {
25042
- let s = "";
25043
- const walk = (n, d) => {
25044
- if (d > 32) return;
25045
- const kids2 = n.childNodes;
25046
- if (!kids2) return;
25047
- for (let i = 0; i < kids2.length; i++) {
25048
- const c = kids2[i];
25049
- if (c.nodeType === 3) s += _nullishCoalesce(c.textContent, () => ( ""));
25050
- else if (c.nodeType === 1) walk(c, d + 1);
25517
+ var CHAR_CTRL_1SLOT = /* @__PURE__ */ new Set(["lineBreak", "hyphen", "nbSpace", "fwSpace"]);
25518
+ function pushFillers(chars, n, prId) {
25519
+ for (let i = 0; i < n; i++) chars.push({ ch: "", prId });
25520
+ }
25521
+ function pushTextSlots(t, chars, prId, depth) {
25522
+ if (depth > 32) return;
25523
+ const kids2 = t.childNodes;
25524
+ if (!kids2) return;
25525
+ for (let i = 0; i < kids2.length; i++) {
25526
+ const c = kids2[i];
25527
+ if (c.nodeType === 3) {
25528
+ for (const cp of _nullishCoalesce(c.textContent, () => ( ""))) {
25529
+ chars.push({ ch: cp, prId });
25530
+ if (cp.length === 2) chars.push({ ch: "", prId });
25531
+ }
25532
+ } else if (c.nodeType === 1) {
25533
+ const el = c;
25534
+ const tag = ln2(el);
25535
+ if (tag === "tab") {
25536
+ pushFillers(chars, 8, prId);
25537
+ } else if (CHAR_CTRL_1SLOT.has(tag)) {
25538
+ chars.push({ ch: tag === "nbSpace" || tag === "fwSpace" ? " " : "", prId });
25539
+ } else {
25540
+ pushTextSlots(el, chars, prId, depth + 1);
25541
+ }
25051
25542
  }
25052
- };
25053
- walk(t, 0);
25054
- return s;
25543
+ }
25055
25544
  }
25056
25545
  function buildPara(p) {
25057
25546
  const chars = [];
25058
25547
  const objs = [];
25059
25548
  let segs = [];
25060
- for (const runEl of elements(p)) {
25061
- const tag = ln(runEl);
25549
+ for (const runEl of elements2(p)) {
25550
+ const tag = ln2(runEl);
25062
25551
  if (tag === "run") {
25063
25552
  const prId = runEl.getAttribute("charPrIDRef");
25064
- for (const ch of elements(runEl)) {
25065
- const cn = ln(ch);
25553
+ for (const ch of elements2(runEl)) {
25554
+ const cn = ln2(ch);
25066
25555
  if (cn === "t") {
25067
- for (const c of textOfT(ch)) chars.push({ ch: c, prId });
25556
+ pushTextSlots(ch, chars, prId, 0);
25068
25557
  } else if (OBJ_TAGS.has(cn)) {
25069
25558
  const sz = findChildByLocalName(ch, "sz");
25070
25559
  const pos = findChildByLocalName(ch, "pos");
25560
+ const w = num2(sz, "width") || num2(findChildByLocalName(ch, "curSz"), "width") || num2(findChildByLocalName(ch, "orgSz"), "width");
25561
+ const h = num2(sz, "height") || num2(findChildByLocalName(ch, "curSz"), "height") || num2(findChildByLocalName(ch, "orgSz"), "height");
25071
25562
  objs.push({
25072
25563
  el: ch,
25073
25564
  tag: cn,
25074
25565
  index: chars.length,
25075
- inline: _optionalChain([pos, 'optionalAccess', _284 => _284.getAttribute, 'call', _285 => _285("treatAsChar")]) === "1",
25076
- width: num(sz, "width"),
25077
- height: num(sz, "height")
25566
+ inline: _optionalChain([pos, 'optionalAccess', _285 => _285.getAttribute, 'call', _286 => _286("treatAsChar")]) === "1",
25567
+ width: w,
25568
+ height: h
25078
25569
  });
25570
+ pushFillers(chars, 8, prId);
25571
+ } else {
25572
+ pushFillers(chars, 8, prId);
25079
25573
  }
25080
25574
  }
25081
25575
  } else if (tag === "linesegarray") {
25082
- segs = elements(runEl).filter((s) => ln(s) === "lineseg").map((s) => ({
25083
- textpos: num(s, "textpos"),
25084
- vertpos: num(s, "vertpos"),
25085
- horzpos: num(s, "horzpos"),
25086
- horzsize: num(s, "horzsize"),
25087
- textheight: num(s, "textheight", 1e3),
25088
- baseline: num(s, "baseline", 850)
25576
+ segs = elements2(runEl).filter((s) => ln2(s) === "lineseg").map((s) => ({
25577
+ textpos: num2(s, "textpos"),
25578
+ vertpos: num2(s, "vertpos"),
25579
+ horzpos: num2(s, "horzpos"),
25580
+ horzsize: num2(s, "horzsize"),
25581
+ textheight: num2(s, "textheight", 1e3),
25582
+ baseline: num2(s, "baseline", 850)
25089
25583
  }));
25090
25584
  }
25091
25585
  }
@@ -25133,38 +25627,41 @@ function advanceTo(m, styles, plan, upto) {
25133
25627
  for (const o of m.objs) if (o.inline && o.index >= plan.start && o.index < upto) x += o.width;
25134
25628
  return x;
25135
25629
  }
25136
- function drawPara(p, ox, oy, areaW, ctx, depth) {
25630
+ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
25137
25631
  if (depth > 16) {
25138
25632
  warnOnce(ctx, "depth", "\uC911\uCCA9 \uAE4A\uC774 16 \uCD08\uACFC \u2014 \uC774\uD558 \uC0DD\uB7B5");
25139
25633
  return;
25140
25634
  }
25141
25635
  const m = buildPara(p);
25142
25636
  if (m.segs.length === 0) {
25637
+ if (m.chars.some((c) => c.ch !== "")) {
25638
+ warnOnce(ctx, "no-lineseg", "\uC870\uD310 \uCE90\uC2DC \uC5C6\uB294 \uBB38\uB2E8 \uD14D\uC2A4\uD2B8 \uC0DD\uB7B5 \u2014 reflow \uC635\uC158\uC73C\uB85C \uD569\uC131 \uAC00\uB2A5");
25639
+ }
25143
25640
  for (const o of m.objs) drawObject(o, ox, oy, 0, areaW, ctx, depth);
25144
25641
  return;
25145
25642
  }
25146
25643
  const plans = planLines(m, ctx.styles);
25147
25644
  const baseV = m.segs[0].vertpos;
25148
- for (const plan of plans) {
25645
+ for (let li = 0; li < plans.length; li++) {
25646
+ const plan = plans[li];
25647
+ if (segPages && segPages[li] !== void 0) ctx.page = segPages[li];
25149
25648
  const { seg } = plan;
25150
25649
  let i = plan.start;
25151
25650
  let cursor = ox + seg.horzpos + plan.xoff;
25152
25651
  const y = oy + seg.vertpos + seg.baseline;
25153
25652
  while (i < plan.end && i < m.chars.length) {
25653
+ if (m.chars[i].ch === "") {
25654
+ for (const o of m.objs) if (o.inline && o.index === i) cursor += o.width;
25655
+ i++;
25656
+ continue;
25657
+ }
25154
25658
  const prId = m.chars[i].prId;
25155
25659
  let j = i;
25156
25660
  let piece = "";
25157
- while (j < plan.end && j < m.chars.length && m.chars[j].prId === prId) {
25661
+ while (j < plan.end && j < m.chars.length && m.chars[j].prId === prId && m.chars[j].ch !== "") {
25158
25662
  piece += m.chars[j].ch;
25159
25663
  j++;
25160
25664
  }
25161
- for (const o of m.objs) {
25162
- if (o.inline && o.index > i && o.index < j) {
25163
- piece = piece.slice(0, o.index - i);
25164
- j = o.index;
25165
- break;
25166
- }
25167
- }
25168
25665
  {
25169
25666
  const cut = piece.search(/ {2,}/);
25170
25667
  if (cut > 0) {
@@ -25177,32 +25674,71 @@ function drawPara(p, ox, oy, areaW, ctx, depth) {
25177
25674
  }
25178
25675
  }
25179
25676
  const st = _nullishCoalesce((prId != null ? ctx.styles.charPr.get(prId) : void 0), () => ( DEFAULT_CHAR));
25180
- const w = measureTextWidth(piece, st.height, st.ratio, { spacingPct: st.spacing }) * plan.scale;
25181
- if (piece.trim().length > 0) {
25182
- const attrs = [`x="${pt(cursor)}"`, `y="${pt(y)}"`, `font-size="${pt(st.height)}"`];
25183
- if ([...piece].length > 1 && w > 50) {
25184
- attrs.push(`textLength="${pt(w)}"`, `lengthAdjust="${plan.scale < 1 ? "spacingAndGlyphs" : "spacing"}"`);
25677
+ const renderSeg = (text, cx, hit) => {
25678
+ const sw = measureTextWidth(text, st.height, st.ratio, { spacingPct: st.spacing }) * plan.scale;
25679
+ if (hit) {
25680
+ emit(ctx, `<rect x="${pt(cx)}" y="${pt(oy + seg.vertpos)}" width="${pt(sw)}" height="${pt(seg.textheight)}" fill="#ffd54f" fill-opacity="0.45"/>`);
25185
25681
  }
25186
- if (st.bold) attrs.push(`font-weight="bold"`);
25187
- if (st.italic) attrs.push(`font-style="italic"`);
25188
- if (st.underline) attrs.push(`text-decoration="underline"`);
25189
- if (st.color) attrs.push(`fill="${escapeXml3(st.color)}"`);
25190
- ctx.svg.push(`<text ${attrs.join(" ")}>${escapeXml3(piece)}</text>`);
25191
- ctx.stats.texts++;
25682
+ if (text.trim().length > 0) {
25683
+ const attrs = [`x="${pt(cx)}"`, `y="${pt(y)}"`, `font-size="${pt(st.height)}"`];
25684
+ if ([...text].length > 1 && sw > 50) {
25685
+ attrs.push(`textLength="${pt(sw)}"`, `lengthAdjust="${plan.scale < 1 ? "spacingAndGlyphs" : "spacing"}"`);
25686
+ }
25687
+ if (st.bold) attrs.push(`font-weight="bold"`);
25688
+ if (st.italic) attrs.push(`font-style="italic"`);
25689
+ if (st.underline) attrs.push(`text-decoration="underline"`);
25690
+ if (st.color) attrs.push(`fill="${escapeXml3(st.color)}"`);
25691
+ emit(ctx, `<text ${attrs.join(" ")}>${escapeXml3(text)}</text>`);
25692
+ ctx.stats.texts++;
25693
+ }
25694
+ return sw;
25695
+ };
25696
+ const merged = [];
25697
+ if (ctx.highlights.length > 0 && piece.trim().length > 0) {
25698
+ const found = [];
25699
+ const lower = piece.toLowerCase();
25700
+ for (const term of ctx.highlights) {
25701
+ for (let f = lower.indexOf(term); f !== -1; f = lower.indexOf(term, f + term.length)) {
25702
+ found.push([f, f + term.length]);
25703
+ }
25704
+ }
25705
+ found.sort((a, b) => a[0] - b[0]);
25706
+ for (const [s, e] of found) {
25707
+ const tail = merged[merged.length - 1];
25708
+ if (tail && s <= tail[1]) tail[1] = Math.max(tail[1], e);
25709
+ else merged.push([s, e]);
25710
+ }
25711
+ }
25712
+ if (merged.length === 0) {
25713
+ cursor += renderSeg(piece, cursor, false);
25714
+ } else {
25715
+ let segCur = cursor;
25716
+ let last = 0;
25717
+ for (const [s, e] of merged) {
25718
+ segCur += renderSeg(piece.slice(last, s), segCur, false);
25719
+ segCur += renderSeg(piece.slice(s, e), segCur, true);
25720
+ last = e;
25721
+ }
25722
+ segCur += renderSeg(piece.slice(last), segCur, false);
25723
+ cursor = segCur;
25192
25724
  }
25193
- cursor += w;
25194
- for (const o of m.objs) if (o.inline && o.index === j) cursor += o.width;
25195
25725
  i = j;
25196
25726
  }
25197
25727
  }
25198
25728
  for (const o of m.objs) {
25199
25729
  if (o.inline) {
25200
- let plan = plans[0];
25201
- for (const pl of plans) if (pl.start <= o.index && (o.index < pl.end || pl === plans[plans.length - 1])) plan = pl;
25730
+ let planIdx = 0;
25731
+ for (let k = 0; k < plans.length; k++) {
25732
+ const pl = plans[k];
25733
+ if (pl.start <= o.index && (o.index < pl.end || k === plans.length - 1)) planIdx = k;
25734
+ }
25735
+ const plan = plans[planIdx];
25736
+ if (segPages && segPages[planIdx] !== void 0) ctx.page = segPages[planIdx];
25202
25737
  const x = ox + plan.seg.horzpos + plan.xoff + advanceTo(m, ctx.styles, plan, o.index);
25203
25738
  const yTop = oy + plan.seg.vertpos + Math.max(0, plan.seg.baseline - o.height);
25204
25739
  drawObject(o, x, yTop, baseV, areaW, ctx, depth);
25205
25740
  } else {
25741
+ if (segPages && segPages[0] !== void 0) ctx.page = segPages[0];
25206
25742
  const { x, y } = anchorObject(o, ox, oy, baseV, areaW, ctx);
25207
25743
  drawObject(o, x, y, baseV, areaW, ctx, depth);
25208
25744
  }
@@ -25212,11 +25748,11 @@ function anchorObject(o, ox, oy, baseV, areaW, ctx) {
25212
25748
  const { PW, PH, ML, MT, BODY_W, BODY_H } = ctx.geom;
25213
25749
  const pos = findChildByLocalName(o.el, "pos");
25214
25750
  const om = findChildByLocalName(o.el, "outMargin");
25215
- const omT = num(om, "top"), omB = num(om, "bottom");
25751
+ const omT = num2(om, "top"), omB = num2(om, "bottom");
25216
25752
  const w = o.width, h = o.height;
25217
25753
  if (!pos) return { x: ox, y: oy + baseV };
25218
- const vo = num(pos, "vertOffset");
25219
- const ho = num(pos, "horzOffset");
25754
+ const vo = num2(pos, "vertOffset");
25755
+ const ho = num2(pos, "horzOffset");
25220
25756
  const vrel = _nullishCoalesce(pos.getAttribute("vertRelTo"), () => ( "PARA"));
25221
25757
  const hrel = _nullishCoalesce(pos.getAttribute("horzRelTo"), () => ( "PARA"));
25222
25758
  const va = _nullishCoalesce(pos.getAttribute("vertAlign"), () => ( "TOP"));
@@ -25248,36 +25784,85 @@ function drawObject(o, x, y, baseV, areaW, ctx, depth) {
25248
25784
  if (o.tag === "tbl") drawTable(o.el, x, y, ctx, depth + 1);
25249
25785
  else if (o.tag === "pic") drawPic(o.el, x, y, ctx);
25250
25786
  else if (o.tag === "container") {
25251
- for (const ch of elements(o.el)) {
25252
- const tag = ln(ch);
25787
+ for (const ch of elements2(o.el)) {
25788
+ const tag = ln2(ch);
25253
25789
  if (!OBJ_TAGS.has(tag)) continue;
25254
25790
  const sz = findChildByLocalName(ch, "sz");
25255
25791
  const off = findChildByLocalName(ch, "offset");
25256
- const sub = { el: ch, tag, index: 0, inline: true, width: num(sz, "width"), height: num(sz, "height") };
25257
- drawObject(sub, x + num(off, "x"), y + num(off, "y"), baseV, areaW, ctx, depth + 1);
25792
+ const sub = { el: ch, tag, index: 0, inline: true, width: num2(sz, "width"), height: num2(sz, "height") };
25793
+ drawObject(sub, x + num2(off, "x"), y + num2(off, "y"), baseV, areaW, ctx, depth + 1);
25258
25794
  }
25259
25795
  } else if (o.tag === "equation") {
25260
25796
  warnOnce(ctx, "equation", "\uC218\uC2DD \uAC1C\uCCB4\uB294 \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5");
25797
+ } else if (SHAPE_TAGS.has(o.tag)) {
25798
+ drawShape(o, x, y, ctx, depth);
25261
25799
  } else {
25262
- warnOnce(ctx, `shape:${o.tag}`, `\uB3C4\uD615 \uAC1C\uCCB4(${o.tag}) \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5`);
25263
- }
25264
- }
25265
- function cellContentExtent(cell, ctx) {
25800
+ warnOnce(ctx, `shape:${o.tag}`, `\uAC1C\uCCB4(${o.tag}) \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5`);
25801
+ }
25802
+ }
25803
+ var SHAPE_TAGS = /* @__PURE__ */ new Set(["rect", "ellipse", "line", "polygon", "curv", "arc"]);
25804
+ function shapeStrokePt(v) {
25805
+ return Math.max(0.2, v / 100 * 2.834645);
25806
+ }
25807
+ function drawShape(o, x, y, ctx, depth) {
25808
+ const el = o.el;
25809
+ const orgSz = findChildByLocalName(el, "orgSz");
25810
+ const curSz = findChildByLocalName(el, "curSz");
25811
+ const ow = num2(orgSz, "width"), oh = num2(orgSz, "height");
25812
+ const w = num2(curSz, "width") || ow || o.width;
25813
+ const h = num2(curSz, "height") || oh || o.height;
25814
+ const sx = ow > 0 ? w / ow : 1;
25815
+ const sy = oh > 0 ? h / oh : 1;
25816
+ const lineShape = findChildByLocalName(el, "lineShape");
25817
+ const lstyle = _nullishCoalesce(_optionalChain([lineShape, 'optionalAccess', _287 => _287.getAttribute, 'call', _288 => _288("style")]), () => ( "SOLID"));
25818
+ const strokeCol = _optionalChain([lineShape, 'optionalAccess', _289 => _289.getAttribute, 'call', _290 => _290("color")]) || "#000000";
25819
+ const hasStroke = lstyle !== "NONE";
25820
+ const strokeW = hasStroke ? shapeStrokePt(lineShape ? num2(lineShape, "width") : 33) : 0;
25821
+ const dash = /DASH|DOT/.test(lstyle) ? ` stroke-dasharray="${lstyle.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
25822
+ const strokeAttr = hasStroke ? ` stroke="${escapeXml3(strokeCol)}" stroke-width="${strokeW.toFixed(2)}"${dash}` : "";
25823
+ const fillBrush = findChildByLocalName(el, "fillBrush");
25824
+ const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
25825
+ const face = _optionalChain([winBrush, 'optionalAccess', _291 => _291.getAttribute, 'call', _292 => _292("faceColor")]);
25826
+ const fill = face && face.toLowerCase() !== "none" ? face : "none";
25827
+ const fillAttr = ` fill="${fill === "none" ? "none" : escapeXml3(fill)}"`;
25828
+ if (o.tag === "rect") {
25829
+ emit(ctx, `<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}"${fillAttr}${strokeAttr}/>`);
25830
+ } else if (o.tag === "ellipse") {
25831
+ emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}"${fillAttr}${strokeAttr}/>`);
25832
+ } else if (o.tag === "line") {
25833
+ const s = findChildByLocalName(el, "startPt"), e = findChildByLocalName(el, "endPt");
25834
+ const x1 = x + num2(s, "x") * sx, y1 = y + num2(s, "y") * sy;
25835
+ const x2 = x + num2(e, "x") * sx, y2 = y + num2(e, "y") * sy;
25836
+ emit(ctx, `<line x1="${pt(x1)}" y1="${pt(y1)}" x2="${pt(x2)}" y2="${pt(y2)}" stroke="${escapeXml3(strokeCol)}" stroke-width="${(strokeW || 0.3).toFixed(2)}"${dash}/>`);
25837
+ } else if (o.tag === "polygon" || o.tag === "curv") {
25838
+ const pts = [];
25839
+ for (const c of elements2(el)) if (ln2(c) === "pt") pts.push(`${pt(x + num2(c, "x") * sx)},${pt(y + num2(c, "y") * sy)}`);
25840
+ if (pts.length >= 2) emit(ctx, `<polygon points="${pts.join(" ")}"${fillAttr}${strokeAttr}/>`);
25841
+ } else if (o.tag === "arc") {
25842
+ emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}" fill="none"${strokeAttr || ` stroke="${escapeXml3(strokeCol)}" stroke-width="0.3"`}/>`);
25843
+ }
25844
+ const dt = findChildByLocalName(el, "drawText");
25845
+ const sub = dt ? findChildByLocalName(dt, "subList") : null;
25846
+ if (sub) {
25847
+ for (const p of elements2(sub)) if (ln2(p) === "p") drawPara(p, x, y, w, ctx, depth + 1);
25848
+ }
25849
+ }
25850
+ function cellContentExtent(cell) {
25266
25851
  if (!cell.sub) return 0;
25267
25852
  let ext = 0;
25268
- for (const p of elements(cell.sub)) {
25269
- if (ln(p) !== "p") continue;
25853
+ for (const p of elements2(cell.sub)) {
25854
+ if (ln2(p) !== "p") continue;
25270
25855
  const m = buildPara(p);
25271
25856
  for (const s of m.segs) ext = Math.max(ext, s.vertpos + s.textheight);
25272
- const baseV = _nullishCoalesce(_optionalChain([m, 'access', _286 => _286.segs, 'access', _287 => _287[0], 'optionalAccess', _288 => _288.vertpos]), () => ( 0));
25857
+ const baseV = _nullishCoalesce(_optionalChain([m, 'access', _293 => _293.segs, 'access', _294 => _294[0], 'optionalAccess', _295 => _295.vertpos]), () => ( 0));
25273
25858
  for (const o of m.objs) {
25274
25859
  if (o.inline) continue;
25275
25860
  const pos = findChildByLocalName(o.el, "pos");
25276
- if ((_nullishCoalesce(_optionalChain([pos, 'optionalAccess', _289 => _289.getAttribute, 'call', _290 => _290("vertRelTo")]), () => ( "PARA"))) !== "PARA") continue;
25861
+ if ((_nullishCoalesce(_optionalChain([pos, 'optionalAccess', _296 => _296.getAttribute, 'call', _297 => _297("vertRelTo")]), () => ( "PARA"))) !== "PARA") continue;
25277
25862
  const om = findChildByLocalName(o.el, "outMargin");
25278
- const pushed = baseV - (num(om, "top") + o.height + num(om, "bottom"));
25863
+ const pushed = baseV - (num2(om, "top") + o.height + num2(om, "bottom"));
25279
25864
  const anchor = pushed >= -100 ? pushed : baseV;
25280
- ext = Math.max(ext, anchor + num(om, "top") + num(pos, "vertOffset") + o.height);
25865
+ ext = Math.max(ext, anchor + num2(om, "top") + num2(pos, "vertOffset") + o.height);
25281
25866
  }
25282
25867
  }
25283
25868
  return ext;
@@ -25286,21 +25871,15 @@ function edgeLine(x1, y1, x2, y2, e) {
25286
25871
  const dash = /DASH|DOT/.test(e.type) ? ` stroke-dasharray="${e.type.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
25287
25872
  return `<line x1="${pt(x1)}" y1="${pt(y1)}" x2="${pt(x2)}" y2="${pt(y2)}" stroke="${escapeXml3(e.color)}" stroke-width="${e.widthPt.toFixed(2)}"${dash}/>`;
25288
25873
  }
25289
- function drawTable(tbl, tx, ty, ctx, depth) {
25290
- if (depth > 16) {
25291
- warnOnce(ctx, "depth", "\uC911\uCCA9 \uAE4A\uC774 16 \uCD08\uACFC \u2014 \uC774\uD558 \uC0DD\uB7B5");
25292
- return;
25293
- }
25294
- ctx.stats.tables++;
25295
- const tblSz = findChildByLocalName(tbl, "sz");
25874
+ function collectCells(tbl) {
25296
25875
  const inMargin = findChildByLocalName(tbl, "inMargin");
25297
- const defL = num(inMargin, "left", 141), defR = num(inMargin, "right", 141);
25298
- const defT = num(inMargin, "top", 141), defB = num(inMargin, "bottom", 141);
25876
+ const defL = num2(inMargin, "left", 141), defR = num2(inMargin, "right", 141);
25877
+ const defT = num2(inMargin, "top", 141), defB = num2(inMargin, "bottom", 141);
25299
25878
  const cells = [];
25300
- for (const tr of elements(tbl)) {
25301
- if (ln(tr) !== "tr") continue;
25302
- for (const tc of elements(tr)) {
25303
- if (ln(tc) !== "tc") continue;
25879
+ for (const tr of elements2(tbl)) {
25880
+ if (ln2(tr) !== "tr") continue;
25881
+ for (const tc of elements2(tr)) {
25882
+ if (ln2(tc) !== "tc") continue;
25304
25883
  const addr = findChildByLocalName(tc, "cellAddr");
25305
25884
  const span = findChildByLocalName(tc, "cellSpan");
25306
25885
  const csz = findChildByLocalName(tc, "cellSz");
@@ -25308,28 +25887,50 @@ function drawTable(tbl, tx, ty, ctx, depth) {
25308
25887
  if (!addr || !csz) continue;
25309
25888
  cells.push({
25310
25889
  el: tc,
25311
- ca: num(addr, "colAddr"),
25312
- ra: num(addr, "rowAddr"),
25313
- cs: Math.max(1, num(span, "colSpan", 1)),
25314
- rs: Math.max(1, num(span, "rowSpan", 1)),
25315
- w: num(csz, "width"),
25316
- h: num(csz, "height"),
25890
+ ca: num2(addr, "colAddr"),
25891
+ ra: num2(addr, "rowAddr"),
25892
+ cs: Math.max(1, num2(span, "colSpan", 1)),
25893
+ rs: Math.max(1, num2(span, "rowSpan", 1)),
25894
+ w: num2(csz, "width"),
25895
+ h: num2(csz, "height"),
25317
25896
  bfId: tc.getAttribute("borderFillIDRef"),
25318
25897
  sub: findChildByLocalName(tc, "subList"),
25319
- marginL: cm ? num(cm, "left", defL) : defL,
25320
- marginR: cm ? num(cm, "right", defR) : defR,
25321
- marginT: cm ? num(cm, "top", defT) : defT,
25322
- marginB: cm ? num(cm, "bottom", defB) : defB
25898
+ marginL: cm ? num2(cm, "left", defL) : defL,
25899
+ marginR: cm ? num2(cm, "right", defR) : defR,
25900
+ marginT: cm ? num2(cm, "top", defT) : defT,
25901
+ marginB: cm ? num2(cm, "bottom", defB) : defB
25323
25902
  });
25324
25903
  }
25325
25904
  }
25905
+ return cells;
25906
+ }
25907
+ function measureTableHeight(tbl) {
25908
+ const cells = collectCells(tbl);
25909
+ if (cells.length === 0 || cells.length > 4096) return 0;
25910
+ const nRows = Math.max(...cells.map((c) => c.ra + c.rs));
25911
+ const rowH = solveRowHeights(
25912
+ cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c) : void 0 })),
25913
+ nRows
25914
+ );
25915
+ let sum = 0;
25916
+ for (const h of rowH) sum += h;
25917
+ return sum;
25918
+ }
25919
+ function drawTable(tbl, tx, ty, ctx, depth) {
25920
+ if (depth > 16) {
25921
+ warnOnce(ctx, "depth", "\uC911\uCCA9 \uAE4A\uC774 16 \uCD08\uACFC \u2014 \uC774\uD558 \uC0DD\uB7B5");
25922
+ return;
25923
+ }
25924
+ ctx.stats.tables++;
25925
+ const tblSz = findChildByLocalName(tbl, "sz");
25926
+ const cells = collectCells(tbl);
25326
25927
  if (cells.length === 0 || cells.length > 4096) return;
25327
25928
  const nCols = Math.max(...cells.map((c) => c.ca + c.cs));
25328
25929
  const nRows = Math.max(...cells.map((c) => c.ra + c.rs));
25329
25930
  const colCons = cells.map((c) => ({ a: c.ca, b: c.ca + c.cs, size: c.w }));
25330
- const colX = solveBoundaries(colCons, nCols, num(tblSz, "width") || void 0);
25931
+ const colX = solveBoundaries(colCons, nCols, num2(tblSz, "width") || void 0);
25331
25932
  const rowH = solveRowHeights(
25332
- cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c, ctx) : void 0 })),
25933
+ cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c) : void 0 })),
25333
25934
  nRows
25334
25935
  );
25335
25936
  const rowY = [0];
@@ -25343,55 +25944,69 @@ function drawTable(tbl, tx, ty, ctx, depth) {
25343
25944
  }));
25344
25945
  for (const g of geom) {
25345
25946
  const bf = g.c.bfId != null ? ctx.styles.borderFill.get(g.c.bfId) : void 0;
25346
- if (_optionalChain([bf, 'optionalAccess', _291 => _291.fill])) ctx.svg.push(`<rect x="${pt(g.x)}" y="${pt(g.y)}" width="${pt(g.w)}" height="${pt(g.h)}" fill="${escapeXml3(bf.fill)}"/>`);
25947
+ if (_optionalChain([bf, 'optionalAccess', _298 => _298.fill])) emit(ctx, `<rect x="${pt(g.x)}" y="${pt(g.y)}" width="${pt(g.w)}" height="${pt(g.h)}" fill="${escapeXml3(bf.fill)}"/>`);
25347
25948
  }
25348
25949
  for (const g of geom) {
25349
25950
  const { c } = g;
25350
25951
  if (!c.sub) continue;
25351
25952
  const innerH = g.h - c.marginT - c.marginB;
25352
- const extent = cellContentExtent(c, ctx);
25953
+ const extent = cellContentExtent(c);
25353
25954
  const va = _nullishCoalesce(c.sub.getAttribute("vertAlign"), () => ( "TOP"));
25354
25955
  let yoff = 0;
25355
25956
  if (va === "CENTER") yoff = Math.max(0, (innerH - extent) / 2);
25356
25957
  else if (va === "BOTTOM") yoff = Math.max(0, innerH - extent);
25357
- for (const p of elements(c.sub)) {
25358
- if (ln(p) !== "p") continue;
25958
+ for (const p of elements2(c.sub)) {
25959
+ if (ln2(p) !== "p") continue;
25359
25960
  drawPara(p, g.x + c.marginL, g.y + c.marginT + yoff, g.w - c.marginL - c.marginR, ctx, depth + 1);
25360
25961
  }
25361
25962
  }
25362
25963
  for (const g of geom) {
25363
25964
  const bf = g.c.bfId != null ? ctx.styles.borderFill.get(g.c.bfId) : void 0;
25364
25965
  if (!bf) continue;
25365
- if (bf.top) ctx.svg.push(edgeLine(g.x, g.y, g.x + g.w, g.y, bf.top));
25366
- if (bf.bottom) ctx.svg.push(edgeLine(g.x, g.y + g.h, g.x + g.w, g.y + g.h, bf.bottom));
25367
- if (bf.left) ctx.svg.push(edgeLine(g.x, g.y, g.x, g.y + g.h, bf.left));
25368
- if (bf.right) ctx.svg.push(edgeLine(g.x + g.w, g.y, g.x + g.w, g.y + g.h, bf.right));
25966
+ if (bf.top) emit(ctx, edgeLine(g.x, g.y, g.x + g.w, g.y, bf.top));
25967
+ if (bf.bottom) emit(ctx, edgeLine(g.x, g.y + g.h, g.x + g.w, g.y + g.h, bf.bottom));
25968
+ if (bf.left) emit(ctx, edgeLine(g.x, g.y, g.x, g.y + g.h, bf.left));
25969
+ if (bf.right) emit(ctx, edgeLine(g.x + g.w, g.y, g.x + g.w, g.y + g.h, bf.right));
25369
25970
  }
25370
25971
  }
25972
+ function imageSymbol(loaded, ctx) {
25973
+ if (!loaded.symId) {
25974
+ loaded.symId = `bin${ctx.defs.length}`;
25975
+ ctx.defs.push(
25976
+ `<symbol id="${loaded.symId}" viewBox="0 0 100 100" preserveAspectRatio="none"><image width="100" height="100" preserveAspectRatio="none" href="${loaded.dataUri}"/></symbol>`
25977
+ );
25978
+ }
25979
+ return loaded.symId;
25980
+ }
25371
25981
  function drawPic(pic, x, y, ctx) {
25372
25982
  const sz = findChildByLocalName(pic, "sz");
25373
- const w = num(sz, "width", 5669), h = num(sz, "height", 5669);
25983
+ const w = num2(sz, "width", 5669), h = num2(sz, "height", 5669);
25374
25984
  const img = findFirst(pic, "img");
25375
- const ref = _optionalChain([img, 'optionalAccess', _292 => _292.getAttribute, 'call', _293 => _293("binaryItemIDRef")]);
25985
+ const ref = _optionalChain([img, 'optionalAccess', _299 => _299.getAttribute, 'call', _300 => _300("binaryItemIDRef")]);
25376
25986
  const loaded = ref != null ? ctx.images.get(ref) : void 0;
25377
25987
  if (!loaded) {
25378
- ctx.svg.push(`<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" fill="#eee" stroke="#c00" stroke-width="0.5"/>`);
25988
+ emit(ctx, `<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" fill="#eee" stroke="#c00" stroke-width="0.5"/>`);
25379
25989
  warnOnce(ctx, `img:${ref}`, `\uC774\uBBF8\uC9C0 \uBC14\uC774\uB108\uB9AC \uB204\uB77D: ${_nullishCoalesce(ref, () => ( "(ref \uC5C6\uC74C)"))}`);
25380
25990
  return;
25381
25991
  }
25382
25992
  ctx.stats.images++;
25383
- const orgSz = findChildByLocalName(pic, "orgSz");
25384
25993
  const clip = findChildByLocalName(pic, "imgClip");
25385
- const orgW = num(orgSz, "width"), orgH = num(orgSz, "height");
25386
- const cl = num(clip, "left"), ct = num(clip, "top");
25387
- const cr = num(clip, "right", orgW), cb = num(clip, "bottom", orgH);
25388
- const cropped = orgW > 0 && orgH > 0 && clip != null && (cl > 0 || ct > 0 || cr < orgW || cb < orgH) && cr > cl && cb > ct;
25994
+ const imgDim = findChildByLocalName(pic, "imgDim");
25995
+ const orgSz = findChildByLocalName(pic, "orgSz");
25996
+ const dimW = num2(imgDim, "dimwidth"), dimH = num2(imgDim, "dimheight");
25997
+ const refW = dimW > 0 ? dimW : num2(orgSz, "width");
25998
+ const refH = dimH > 0 ? dimH : num2(orgSz, "height");
25999
+ const cl = num2(clip, "left"), ct = num2(clip, "top");
26000
+ const cr = num2(clip, "right", refW), cb = num2(clip, "bottom", refH);
26001
+ const cropped = refW > 0 && refH > 0 && clip != null && (cl > 0 || ct > 0 || cr < refW || cb < refH) && cr > cl && cb > ct;
26002
+ const symId = imageSymbol(loaded, ctx);
25389
26003
  if (cropped) {
25390
- ctx.svg.push(
25391
- `<svg x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" viewBox="${pt(cl)} ${pt(ct)} ${pt(cr - cl)} ${pt(cb - ct)}" preserveAspectRatio="none"><image x="0" y="0" width="${pt(orgW)}" height="${pt(orgH)}" preserveAspectRatio="none" href="${loaded.dataUri}"/></svg>`
26004
+ emit(
26005
+ ctx,
26006
+ `<svg x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" viewBox="${pt(cl)} ${pt(ct)} ${pt(cr - cl)} ${pt(cb - ct)}" preserveAspectRatio="none"><use href="#${symId}" x="0" y="0" width="${pt(refW)}" height="${pt(refH)}"/></svg>`
25392
26007
  );
25393
26008
  } else {
25394
- ctx.svg.push(`<image x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" preserveAspectRatio="none" href="${loaded.dataUri}"/>`);
26009
+ emit(ctx, `<use href="#${symId}" x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}"/>`);
25395
26010
  }
25396
26011
  }
25397
26012
  function sniffMime(name, bytes) {
@@ -25403,23 +26018,24 @@ function sniffMime(name, bytes) {
25403
26018
  return "image/jpeg";
25404
26019
  }
25405
26020
  async function renderHwpxToSvg(input, options) {
25406
- const maxImg = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _294 => _294.maxImageBytes]), () => ( 40 * 1024 * 1024));
26021
+ const maxImg = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _301 => _301.maxImageBytes]), () => ( 40 * 1024 * 1024));
25407
26022
  let zip;
25408
26023
  try {
25409
26024
  zip = await _jszip2.default.loadAsync(input);
25410
26025
  } catch (e31) {
25411
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("HWPX(ZIP) \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB294 HWPX\uB9CC \uC9C0\uC6D0");
26026
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("HWPX(ZIP) \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB294 HWPX\uB9CC \uC9C0\uC6D0");
25412
26027
  }
25413
26028
  const secFile = _nullishCoalesce(zip.file("Contents/section0.xml"), () => ( zip.file(/Contents\/section\d+\.xml$/i).sort((a, b) => a.name.localeCompare(b.name))[0]));
25414
- if (!secFile) throw new (0, _chunkMEXUFQVCcjs.KordocError)("Contents/section0.xml \uC5C6\uC74C \u2014 HWPX\uAC00 \uC544\uB2C8\uAC70\uB098 \uC190\uC0C1\uB428");
26029
+ if (!secFile) throw new (0, _chunkDMBTOJK4cjs.KordocError)("Contents/section0.xml \uC5C6\uC74C \u2014 HWPX\uAC00 \uC544\uB2C8\uAC70\uB098 \uC190\uC0C1\uB428");
25415
26030
  const secXml = await secFile.async("string");
25416
- if (secXml.length > MAX_DECOMPRESS_SIZE) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
25417
- if (!secXml.includes("linesegarray")) {
25418
- throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC870\uD310 \uCE90\uC2DC(linesegarray) \uC5C6\uC74C \u2014 \uD55C\uCEF4\uC5D0\uC11C \uC800\uC7A5\uD55C HWPX\uB9CC \uB80C\uB354 \uAC00\uB2A5");
26031
+ if (secXml.length > MAX_DECOMPRESS_SIZE) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
26032
+ const hasCache = /<(?:[A-Za-z][\w.-]*:)?linesegarray[\s/>]/.test(secXml);
26033
+ if (!hasCache && !_optionalChain([options, 'optionalAccess', _302 => _302.reflow])) {
26034
+ throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC870\uD310 \uCE90\uC2DC(linesegarray) \uC5C6\uC74C \u2014 \uD55C\uCEF4\uC5D0\uC11C \uC800\uC7A5\uD55C HWPX\uB9CC \uB80C\uB354 \uAC00\uB2A5 (reflow \uC635\uC158\uC73C\uB85C \uD569\uC131 \uB80C\uB354 \uAC00\uB2A5)");
25419
26035
  }
25420
26036
  const warnings = [];
25421
26037
  const headFile = _nullishCoalesce(zip.file("Contents/header.xml"), () => ( zip.file("Contents/head.xml")));
25422
- const styles = headFile ? parseRenderStyles(await headFile.async("string")) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
26038
+ const styles = headFile ? parseRenderStyles(await headFile.async("string")) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), paraGeom: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
25423
26039
  if (!headFile) warnings.push("header.xml \uC5C6\uC74C \u2014 \uAE30\uBCF8 \uC2A4\uD0C0\uC77C\uB85C \uB80C\uB354");
25424
26040
  const binmap = /* @__PURE__ */ new Map();
25425
26041
  const hpf = zip.file(/content\.hpf$/i)[0];
@@ -25428,14 +26044,21 @@ async function renderHwpxToSvg(input, options) {
25428
26044
  for (const m of man.matchAll(/<[^>]*\bid="([^"]+)"[^>]*\bhref="(BinData\/[^"]+)"[^>]*>/g)) binmap.set(m[1], m[2]);
25429
26045
  for (const m of man.matchAll(/<[^>]*\bhref="(BinData\/[^"]+)"[^>]*\bid="([^"]+)"[^>]*>/g)) binmap.set(m[2], m[1]);
25430
26046
  }
26047
+ const MAX_IMAGE_REFS = 256;
26048
+ const MAX_TOTAL_IMAGE_BYTES = 128 * 1024 * 1024;
25431
26049
  const images = /* @__PURE__ */ new Map();
25432
26050
  const refs = /* @__PURE__ */ new Set();
25433
26051
  for (const m of secXml.matchAll(/binaryItemIDRef="([^"]+)"/g)) refs.add(m[1]);
26052
+ let totalImgBytes = 0;
25434
26053
  for (const ref of refs) {
26054
+ if (images.size >= MAX_IMAGE_REFS) {
26055
+ warnings.push(`\uC774\uBBF8\uC9C0 ${refs.size}\uC885 \uC911 ${MAX_IMAGE_REFS}\uC885\uB9CC \uB85C\uB529 \u2014 \uAC1C\uC218 \uD55C\uB3C4 \uCD08\uACFC\uBD84 \uC0DD\uB7B5`);
26056
+ break;
26057
+ }
25435
26058
  let href = binmap.get(ref);
25436
26059
  if (!href) {
25437
26060
  const cand = zip.file(new RegExp(`BinData/.*${ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i"))[0];
25438
- href = _optionalChain([cand, 'optionalAccess', _295 => _295.name]);
26061
+ href = _optionalChain([cand, 'optionalAccess', _303 => _303.name]);
25439
26062
  }
25440
26063
  if (!href) continue;
25441
26064
  const f = _nullishCoalesce(zip.file(href), () => ( zip.file("Contents/" + href)));
@@ -25445,55 +26068,96 @@ async function renderHwpxToSvg(input, options) {
25445
26068
  warnings.push(`\uC774\uBBF8\uC9C0 ${href} ${(bytes.length / 1048576).toFixed(1)}MB \u2014 \uD55C\uB3C4 \uCD08\uACFC\uB85C \uC0DD\uB7B5`);
25446
26069
  continue;
25447
26070
  }
26071
+ if (totalImgBytes + bytes.length > MAX_TOTAL_IMAGE_BYTES) {
26072
+ warnings.push(`\uC774\uBBF8\uC9C0 \uB204\uC801 ${Math.round(MAX_TOTAL_IMAGE_BYTES / 1048576)}MB \uD55C\uB3C4 \uCD08\uACFC \u2014 \uC774\uD6C4 \uC0DD\uB7B5`);
26073
+ break;
26074
+ }
26075
+ totalImgBytes += bytes.length;
25448
26076
  images.set(ref, { dataUri: `data:${sniffMime(href, bytes)};base64,${Buffer.from(bytes).toString("base64")}` });
25449
26077
  }
25450
26078
  const doc = createXmlParser().parseFromString(secXml, "text/xml");
25451
26079
  const root = doc.documentElement;
25452
- if (!root) throw new (0, _chunkMEXUFQVCcjs.KordocError)("\uC139\uC158 XML \uD30C\uC2F1 \uC2E4\uD328");
26080
+ if (!root) throw new (0, _chunkDMBTOJK4cjs.KordocError)("\uC139\uC158 XML \uD30C\uC2F1 \uC2E4\uD328");
25453
26081
  const pagePr = findFirst(root, "pagePr");
25454
26082
  const margin = pagePr ? findChildByLocalName(pagePr, "margin") : null;
25455
- const PW = num(pagePr, "width", 59528), PH = num(pagePr, "height", 84188);
25456
- const ML = num(margin, "left", 8504);
25457
- const MT = num(margin, "top", 5668) + num(margin, "header", 0);
25458
- const BODY_H = PH - MT - num(margin, "bottom", 4252) - num(margin, "footer", 0);
25459
- const BODY_W = PW - ML - num(margin, "right", 8504);
26083
+ const PW = num2(pagePr, "width", 59528), PH = num2(pagePr, "height", 84188);
26084
+ const ML = num2(margin, "left", 8504);
26085
+ const MT = num2(margin, "top", 5668) + num2(margin, "header", 0);
26086
+ const BODY_H = PH - MT - num2(margin, "bottom", 4252) - num2(margin, "footer", 0);
26087
+ const BODY_W = PW - ML - num2(margin, "right", 8504);
26088
+ if (!hasCache) reflowSection(root, styles, { BODY_W, BODY_H }, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _304 => _304.reflowMode]), () => ( "keep")));
26089
+ const colPr = findFirst(root, "colPr");
26090
+ const multiCol = num2(colPr, "colCount", 1) > 1;
26091
+ const paraSegPages = /* @__PURE__ */ new Map();
26092
+ let nPages = 1;
26093
+ let maxTopV = 0;
26094
+ {
26095
+ let prevV = Number.NEGATIVE_INFINITY;
26096
+ let prevH = Number.NEGATIVE_INFINITY;
26097
+ let cur = 0;
26098
+ for (const p of elements2(root)) {
26099
+ if (ln2(p) !== "p") continue;
26100
+ const lsa = findChildByLocalName(p, "linesegarray");
26101
+ const segEls = lsa ? elements2(lsa).filter((s) => ln2(s) === "lineseg") : [];
26102
+ const pagesOf = [];
26103
+ for (const s of segEls) {
26104
+ const v = num2(s, "vertpos");
26105
+ const h = num2(s, "horzpos");
26106
+ if (v < prevV && (!multiCol || h <= prevH)) cur++;
26107
+ pagesOf.push(cur);
26108
+ maxTopV = Math.max(maxTopV, v + num2(s, "textheight", 1e3));
26109
+ prevV = v;
26110
+ prevH = h;
26111
+ }
26112
+ paraSegPages.set(p, pagesOf);
26113
+ nPages = Math.max(nPages, cur + 1);
26114
+ }
26115
+ }
25460
26116
  const ctx = {
25461
- svg: [],
26117
+ pages: Array.from({ length: nPages }, () => []),
26118
+ page: 0,
25462
26119
  geom: { PW, PH, ML, MT, BODY_W, BODY_H },
25463
26120
  styles,
25464
26121
  images,
26122
+ defs: [],
26123
+ highlights: (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _305 => _305.highlights]), () => ( []))).map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0),
25465
26124
  warnings,
25466
26125
  warned: /* @__PURE__ */ new Set(),
25467
26126
  stats: { texts: 0, images: 0, tables: 0 }
25468
26127
  };
25469
- for (const p of elements(root)) {
25470
- if (ln(p) !== "p") continue;
25471
- const segs = findChildByLocalName(p, "linesegarray");
25472
- const first = segs ? elements(segs)[0] : null;
25473
- if (first && num(first, "vertpos") > BODY_H) continue;
25474
- drawPara(p, ML, MT, BODY_W, ctx, 0);
25475
- }
25476
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pt(PW)} ${pt(PH)}" width="${pt(PW)}pt" height="${pt(PH)}pt" font-family="'HCR Batang','\uD568\uCD08\uB86C\uBC14\uD0D5','Hancom Batang',AppleMyungjo,'Noto Serif CJK KR',serif" xml:space="preserve">
25477
- <rect width="100%" height="100%" fill="white"/>
25478
- ${ctx.svg.join("\n")}
26128
+ for (const p of elements2(root)) {
26129
+ if (ln2(p) !== "p") continue;
26130
+ drawPara(p, ML, MT, BODY_W, ctx, 0, paraSegPages.get(p));
26131
+ }
26132
+ const pageH = nPages === 1 ? Math.max(PH, MT + maxTopV + 2e3) : PH;
26133
+ const GAP = 2400;
26134
+ const totalH = nPages * pageH + (nPages - 1) * GAP;
26135
+ const pagesSvg = ctx.pages.map(
26136
+ (buf, k) => `<g data-page="${k + 1}" transform="translate(0 ${pt(k * (pageH + GAP))})"><rect width="${pt(PW)}" height="${pt(pageH)}" fill="white" stroke="#c9c7c4" stroke-width="0.75"/><g clip-path="url(#pgclip)">
26137
+ ${buf.join("\n")}
26138
+ </g></g>`
26139
+ ).join("\n");
26140
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pt(PW)} ${pt(totalH)}" width="${pt(PW)}pt" height="${pt(totalH)}pt" font-family="'HCR Batang','\uD568\uCD08\uB86C\uBC14\uD0D5','Hancom Batang',AppleMyungjo,'Noto Serif CJK KR',serif" xml:space="preserve">
26141
+ <defs><clipPath id="pgclip"><rect x="0" y="0" width="${pt(PW)}" height="${pt(pageH)}"/></clipPath>${ctx.defs.join("")}</defs>
26142
+ ${pagesSvg}
25479
26143
  </svg>`;
25480
- return { svg, width: Math.round(PW) / 100, height: Math.round(PH) / 100, warnings, stats: ctx.stats };
26144
+ return { svg, width: Math.round(PW) / 100, height: Math.round(totalH) / 100, pageCount: nPages, warnings, stats: ctx.stats };
25481
26145
  }
25482
26146
 
25483
26147
  // src/index.ts
25484
26148
  async function parse(input, options) {
25485
26149
  let buffer;
25486
- const opts = typeof input === "string" && !_optionalChain([options, 'optionalAccess', _296 => _296.filePath]) ? { ...options, filePath: input } : options;
26150
+ const opts = typeof input === "string" && !_optionalChain([options, 'optionalAccess', _306 => _306.filePath]) ? { ...options, filePath: input } : options;
25487
26151
  if (typeof input === "string") {
25488
26152
  try {
25489
26153
  const buf = await _promises.readFile.call(void 0, input);
25490
- buffer = _chunkMEXUFQVCcjs.toArrayBuffer.call(void 0, buf);
26154
+ buffer = _chunkDMBTOJK4cjs.toArrayBuffer.call(void 0, buf);
25491
26155
  } catch (err) {
25492
26156
  const msg2 = err instanceof Error && "code" in err && err.code === "ENOENT" ? `\uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input}` : `\uD30C\uC77C \uC77D\uAE30 \uC2E4\uD328: ${input}`;
25493
26157
  return { success: false, fileType: "unknown", error: msg2, code: "PARSE_ERROR" };
25494
26158
  }
25495
26159
  } else if (Buffer.isBuffer(input)) {
25496
- buffer = _chunkMEXUFQVCcjs.toArrayBuffer.call(void 0, input);
26160
+ buffer = _chunkDMBTOJK4cjs.toArrayBuffer.call(void 0, input);
25497
26161
  } else {
25498
26162
  buffer = input;
25499
26163
  }
@@ -25528,21 +26192,21 @@ async function parseHwp3(buffer, options) {
25528
26192
  const { markdown, blocks, metadata, outline, warnings } = parseHwp3Document(buffer, options);
25529
26193
  return { success: true, fileType: "hwp3", markdown, blocks, metadata, outline, warnings };
25530
26194
  } catch (err) {
25531
- return { success: false, fileType: "hwp3", error: err instanceof Error ? err.message : "HWP3 \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err) };
26195
+ return { success: false, fileType: "hwp3", error: err instanceof Error ? err.message : "HWP3 \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err) };
25532
26196
  }
25533
26197
  }
25534
26198
  async function parseHwpx(buffer, options) {
25535
26199
  try {
25536
26200
  const { markdown, blocks, metadata, outline, warnings, images } = await parseHwpxDocument(buffer, options);
25537
- return { success: true, fileType: "hwpx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _297 => _297.length]) ? images : void 0 };
26201
+ return { success: true, fileType: "hwpx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _307 => _307.length]) ? images : void 0 };
25538
26202
  } catch (err) {
25539
- return { success: false, fileType: "hwpx", error: err instanceof Error ? err.message : "HWPX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err) };
26203
+ return { success: false, fileType: "hwpx", error: err instanceof Error ? err.message : "HWPX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err) };
25540
26204
  }
25541
26205
  }
25542
26206
  async function parseHwp(buffer, options) {
25543
26207
  try {
25544
26208
  const { markdown, blocks, metadata, outline, warnings, images } = parseHwp5Document(Buffer.from(buffer), options);
25545
- if (isDistributionSentinel(markdown) && isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _298 => _298.filePath])) {
26209
+ if (isDistributionSentinel(markdown) && isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _308 => _308.filePath])) {
25546
26210
  try {
25547
26211
  const { pages, pageCount, warnings: comWarns } = extractTextViaCom(options.filePath);
25548
26212
  if (pages.some((p) => p && p.trim().length > 0)) {
@@ -25559,15 +26223,15 @@ async function parseHwp(buffer, options) {
25559
26223
  } catch (e32) {
25560
26224
  }
25561
26225
  }
25562
- return { success: true, fileType: "hwp", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _299 => _299.length]) ? images : void 0 };
26226
+ return { success: true, fileType: "hwp", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _309 => _309.length]) ? images : void 0 };
25563
26227
  } catch (err) {
25564
- return { success: false, fileType: "hwp", error: err instanceof Error ? err.message : "HWP \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err) };
26228
+ return { success: false, fileType: "hwp", error: err instanceof Error ? err.message : "HWP \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err) };
25565
26229
  }
25566
26230
  }
25567
26231
  async function parsePdf(buffer, options) {
25568
26232
  let parsePdfDocument;
25569
26233
  try {
25570
- const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-DZBI3EA2.cjs")));
26234
+ const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-O2SD4DFR.cjs")));
25571
26235
  parsePdfDocument = mod.parsePdfDocument;
25572
26236
  } catch (e33) {
25573
26237
  return {
@@ -25582,7 +26246,7 @@ async function parsePdf(buffer, options) {
25582
26246
  return { success: true, fileType: "pdf", markdown, blocks, metadata, outline, warnings, isImageBased, pageQuality, qualitySummary };
25583
26247
  } catch (err) {
25584
26248
  const isImageBased = err instanceof Error && "isImageBased" in err ? true : void 0;
25585
- return { success: false, fileType: "pdf", error: err instanceof Error ? err.message : "PDF \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err), isImageBased };
26249
+ return { success: false, fileType: "pdf", error: err instanceof Error ? err.message : "PDF \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err), isImageBased };
25586
26250
  }
25587
26251
  }
25588
26252
  async function parseXlsx(buffer, options) {
@@ -25590,7 +26254,7 @@ async function parseXlsx(buffer, options) {
25590
26254
  const { markdown, blocks, metadata, warnings } = await parseXlsxDocument(buffer, options);
25591
26255
  return { success: true, fileType: "xlsx", markdown, blocks, metadata, warnings };
25592
26256
  } catch (err) {
25593
- return { success: false, fileType: "xlsx", error: err instanceof Error ? err.message : "XLSX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err) };
26257
+ return { success: false, fileType: "xlsx", error: err instanceof Error ? err.message : "XLSX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err) };
25594
26258
  }
25595
26259
  }
25596
26260
  async function parseXls(buffer, options) {
@@ -25598,15 +26262,15 @@ async function parseXls(buffer, options) {
25598
26262
  const { markdown, blocks, metadata, warnings } = await parseXlsDocument(buffer, options);
25599
26263
  return { success: true, fileType: "xls", markdown, blocks, metadata, warnings };
25600
26264
  } catch (err) {
25601
- return { success: false, fileType: "xls", error: err instanceof Error ? err.message : "XLS \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err) };
26265
+ return { success: false, fileType: "xls", error: err instanceof Error ? err.message : "XLS \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err) };
25602
26266
  }
25603
26267
  }
25604
26268
  async function parseDocx(buffer, options) {
25605
26269
  try {
25606
26270
  const { markdown, blocks, metadata, outline, warnings, images } = await parseDocxDocument(buffer, options);
25607
- return { success: true, fileType: "docx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _300 => _300.length]) ? images : void 0 };
26271
+ return { success: true, fileType: "docx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _310 => _310.length]) ? images : void 0 };
25608
26272
  } catch (err) {
25609
- return { success: false, fileType: "docx", error: err instanceof Error ? err.message : "DOCX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err) };
26273
+ return { success: false, fileType: "docx", error: err instanceof Error ? err.message : "DOCX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err) };
25610
26274
  }
25611
26275
  }
25612
26276
  async function parseHwpml(buffer, options) {
@@ -25614,16 +26278,16 @@ async function parseHwpml(buffer, options) {
25614
26278
  const { markdown, blocks, metadata, outline, warnings } = parseHwpmlDocument(buffer, options);
25615
26279
  return { success: true, fileType: "hwpml", markdown, blocks, metadata, outline, warnings };
25616
26280
  } catch (err) {
25617
- return { success: false, fileType: "hwpml", error: err instanceof Error ? err.message : "HWPML \uD30C\uC2F1 \uC2E4\uD328", code: _chunkMEXUFQVCcjs.classifyError.call(void 0, err) };
26281
+ return { success: false, fileType: "hwpml", error: err instanceof Error ? err.message : "HWPML \uD30C\uC2F1 \uC2E4\uD328", code: _chunkDMBTOJK4cjs.classifyError.call(void 0, err) };
25618
26282
  }
25619
26283
  }
25620
26284
  async function fillForm(input, values, outputFormat = "markdown") {
25621
26285
  let buffer;
25622
26286
  if (typeof input === "string") {
25623
26287
  const buf = await _promises.readFile.call(void 0, input);
25624
- buffer = _chunkMEXUFQVCcjs.toArrayBuffer.call(void 0, buf);
26288
+ buffer = _chunkDMBTOJK4cjs.toArrayBuffer.call(void 0, buf);
25625
26289
  } else if (Buffer.isBuffer(input)) {
25626
- buffer = _chunkMEXUFQVCcjs.toArrayBuffer.call(void 0, input);
26290
+ buffer = _chunkDMBTOJK4cjs.toArrayBuffer.call(void 0, input);
25627
26291
  } else {
25628
26292
  buffer = input;
25629
26293
  }
@@ -25649,7 +26313,7 @@ async function fillForm(input, values, outputFormat = "markdown") {
25649
26313
  throw new Error(`\uC11C\uC2DD \uD30C\uC2F1 \uC2E4\uD328: ${parsed.error}`);
25650
26314
  }
25651
26315
  const fill = fillFormFields(parsed.blocks, values);
25652
- const markdown = _chunkMEXUFQVCcjs.blocksToMarkdown.call(void 0, fill.blocks);
26316
+ const markdown = _chunkDMBTOJK4cjs.blocksToMarkdown.call(void 0, fill.blocks);
25653
26317
  if (outputFormat === "hwpx") {
25654
26318
  const hwpxBuffer = await markdownToHwpx(markdown);
25655
26319
  return { output: hwpxBuffer, format: "hwpx", fill };
@@ -25708,5 +26372,8 @@ async function fillForm(input, values, outputFormat = "markdown") {
25708
26372
 
25709
26373
 
25710
26374
 
25711
- exports.HwpxSession = HwpxSession; exports.PRESET_ALIAS = PRESET_ALIAS; exports.SPACE_EM_FIXED = SPACE_EM_FIXED; exports.SPACE_EM_FONT = SPACE_EM_FONT; exports.VERSION = _chunkMEXUFQVCcjs.VERSION; exports.ValueCursor = ValueCursor; exports.applySplices = applySplices; exports.blocksToMarkdown = _chunkMEXUFQVCcjs.blocksToMarkdown; exports.blocksToPdf = blocksToPdf; exports.buildParagraphSplices = buildParagraphSplices; exports.buildRangeSplices = buildRangeSplices; exports.charWidthEm1000 = charWidthEm1000; exports.compare = compare; exports.detectFormat = detectFormat; exports.detectOle2Format = detectOle2Format; exports.detectZipFormat = detectZipFormat; exports.diffBlocks = diffBlocks; exports.extractFormFields = extractFormFields; exports.extractFormSchema = extractFormSchema; exports.fillForm = fillForm; exports.fillFormFields = fillFormFields; exports.fillHwpx = fillHwpx; exports.fitRatioForFewerLines = fitRatioForFewerLines; exports.inferFieldType = inferFieldType; exports.isHwpxFile = isHwpxFile; exports.isLabelCell = isLabelCell; exports.isOldHwpFile = isOldHwpFile; exports.isPdfFile = isPdfFile; exports.isZipFile = isZipFile; exports.markdownToHwpx = markdownToHwpx; exports.markdownToPdf = markdownToPdf; exports.measureTextWidth = measureTextWidth; exports.normalizeGongmunPreset = normalizeGongmunPreset; exports.openHwpxDocument = openHwpxDocument; exports.parse = parse; exports.parseDocx = parseDocx; exports.parseHwp = parseHwp; exports.parseHwp3 = parseHwp3; exports.parseHwpml = parseHwpml; exports.parseHwpx = parseHwpx; exports.parsePdf = parsePdf; exports.parseXls = parseXls; exports.parseXlsx = parseXlsx; exports.patchHwp = patchHwp; exports.patchHwpx = patchHwpx; exports.patchHwpxBlocks = patchHwpxBlocks; exports.renderHtml = renderHtml; exports.renderHwpxToSvg = renderHwpxToSvg; exports.scanSectionXml = scanSectionXml; exports.simulateWrap = simulateWrap; exports.simulateWrapKeepWord = simulateWrapKeepWord;
26375
+
26376
+
26377
+
26378
+ exports.HwpxSession = HwpxSession; exports.PRESET_ALIAS = PRESET_ALIAS; exports.SPACE_EM_FIXED = SPACE_EM_FIXED; exports.SPACE_EM_FONT = SPACE_EM_FONT; exports.VERSION = _chunkDMBTOJK4cjs.VERSION; exports.ValueCursor = ValueCursor; exports.applySplices = applySplices; exports.blocksToMarkdown = _chunkDMBTOJK4cjs.blocksToMarkdown; exports.blocksToPdf = blocksToPdf; exports.buildParagraphSplices = buildParagraphSplices; exports.buildRangeSplices = buildRangeSplices; exports.charWidthEm1000 = charWidthEm1000; exports.compare = compare; exports.detectFormat = detectFormat; exports.detectOle2Format = detectOle2Format; exports.detectZipFormat = detectZipFormat; exports.diffBlocks = diffBlocks; exports.extractFormFields = extractFormFields; exports.extractFormSchema = extractFormSchema; exports.fillForm = fillForm; exports.fillFormFields = fillFormFields; exports.fillHwpx = fillHwpx; exports.fillWithUniqueGuard = fillWithUniqueGuard; exports.fitRatioForFewerLines = fitRatioForFewerLines; exports.formatFillValue = formatFillValue; exports.inferFieldType = inferFieldType; exports.isHwpxFile = isHwpxFile; exports.isLabelCell = isLabelCell; exports.isOldHwpFile = isOldHwpFile; exports.isPdfFile = isPdfFile; exports.isZipFile = isZipFile; exports.markdownToHwpx = markdownToHwpx; exports.markdownToPdf = markdownToPdf; exports.measureTextWidth = measureTextWidth; exports.normalizeGongmunPreset = normalizeGongmunPreset; exports.openHwpxDocument = openHwpxDocument; exports.parse = parse; exports.parseDocx = parseDocx; exports.parseHwp = parseHwp; exports.parseHwp3 = parseHwp3; exports.parseHwpml = parseHwpml; exports.parseHwpx = parseHwpx; exports.parsePdf = parsePdf; exports.parseXls = parseXls; exports.parseXlsx = parseXlsx; exports.patchHwp = patchHwp; exports.patchHwpx = patchHwpx; exports.patchHwpxBlocks = patchHwpxBlocks; exports.renderHtml = renderHtml; exports.renderHwpxToSvg = renderHwpxToSvg; exports.scanSectionXml = scanSectionXml; exports.simulateWrap = simulateWrap; exports.simulateWrapKeepWord = simulateWrapKeepWord; exports.validateHwpx = validateHwpx;
25712
26379
  //# sourceMappingURL=index.cjs.map