kordoc 4.0.8 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +25 -11
  2. package/dist/{-LE4RLXVA.js → -AS4IABL2.js} +23 -10
  3. package/dist/{chunk-2DZQF6YJ.js → chunk-37HJHCPA.js} +24 -15
  4. package/dist/chunk-37HJHCPA.js.map +1 -0
  5. package/dist/{chunk-6XAAYAWL.cjs → chunk-37VKMUST.cjs} +47 -37
  6. package/dist/chunk-37VKMUST.cjs.map +1 -0
  7. package/dist/{chunk-OQPILS7B.js → chunk-4KI23VHA.js} +33 -23
  8. package/dist/chunk-4KI23VHA.js.map +1 -0
  9. package/dist/{chunk-D35VBACN.js → chunk-AX2R5Q2N.js} +7 -4
  10. package/dist/chunk-AX2R5Q2N.js.map +1 -0
  11. package/dist/chunk-DZIXKL7E.js +145 -0
  12. package/dist/chunk-DZIXKL7E.js.map +1 -0
  13. package/dist/chunk-F2ZU3IZG.js +82 -0
  14. package/dist/chunk-F2ZU3IZG.js.map +1 -0
  15. package/dist/{chunk-BNU5QGIZ.js → chunk-GQVSHGG4.js} +12 -4
  16. package/dist/chunk-GQVSHGG4.js.map +1 -0
  17. package/dist/{chunk-7S3M4N4E.js → chunk-L2XQQTOY.js} +566 -189
  18. package/dist/chunk-L2XQQTOY.js.map +1 -0
  19. package/dist/{chunk-HMUEU7D7.js → chunk-O5VS7RIR.js} +2 -2
  20. package/dist/{chunk-UEIYETCQ.js → chunk-SSTK6IKK.js} +18 -160
  21. package/dist/chunk-SSTK6IKK.js.map +1 -0
  22. package/dist/chunk-UOO7LSDG.js +152 -0
  23. package/dist/chunk-UOO7LSDG.js.map +1 -0
  24. package/dist/{chunk-RROH5WHO.js → chunk-WO52HVQJ.js} +2 -2
  25. package/dist/{chunk-MEPHGCPQ.js → chunk-YOO6ET6M.js} +7 -3
  26. package/dist/chunk-YOO6ET6M.js.map +1 -0
  27. package/dist/chunks-WVMGF7JL.js +10 -0
  28. package/dist/cli.js +170 -35
  29. package/dist/cli.js.map +1 -1
  30. package/dist/{detect-RI2MQ33K.js → detect-YEZX2XCF.js} +2 -2
  31. package/dist/index.cjs +1142 -531
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +105 -1
  34. package/dist/index.d.ts +105 -1
  35. package/dist/index.js +802 -191
  36. package/dist/index.js.map +1 -1
  37. package/dist/mcp.js +273 -65
  38. package/dist/mcp.js.map +1 -1
  39. package/dist/{parser-ITMU2WN5.cjs → parser-N4A7UGDK.cjs} +127 -45
  40. package/dist/parser-N4A7UGDK.cjs.map +1 -0
  41. package/dist/{parser-TCTCSBYZ.js → parser-PEOYBXBO.js} +118 -34
  42. package/dist/parser-PEOYBXBO.js.map +1 -0
  43. package/dist/{parser-KMMUS73Q.js → parser-XX4QTDFQ.js} +114 -32
  44. package/dist/parser-XX4QTDFQ.js.map +1 -0
  45. package/dist/{profile-io-SLN4P76T.js → profile-io-PLDQFPJA.js} +3 -3
  46. package/dist/{provider-G4C2V2PD.cjs → provider-4FAYHJ6N.cjs} +3 -3
  47. package/dist/provider-4FAYHJ6N.cjs.map +1 -0
  48. package/dist/{provider-4ZJKV3DC.js → provider-C6IOGIS5.js} +3 -3
  49. package/dist/provider-C6IOGIS5.js.map +1 -0
  50. package/dist/{provider-AKROB7WQ.js → provider-UIBW2MIH.js} +3 -3
  51. package/dist/provider-UIBW2MIH.js.map +1 -0
  52. package/dist/rasterize-WWNQLKYW.js +40 -0
  53. package/dist/rasterize-WWNQLKYW.js.map +1 -0
  54. package/dist/redact-7ILEAUTS.js +12 -0
  55. package/dist/render-T7S6H6AN.js +10 -0
  56. package/dist/render-T7S6H6AN.js.map +1 -0
  57. package/dist/seal-7PTL6MXH.js +10 -0
  58. package/dist/seal-7PTL6MXH.js.map +1 -0
  59. package/dist/{setup-57FB3LSP.js → setup-Q2PRE7UA.js} +5 -3
  60. package/dist/setup-Q2PRE7UA.js.map +1 -0
  61. package/dist/{watch-OHQWSVPE.js → watch-SFHXZALC.js} +77 -23
  62. package/dist/watch-SFHXZALC.js.map +1 -0
  63. package/package.json +1 -1
  64. package/dist/chunk-2DZQF6YJ.js.map +0 -1
  65. package/dist/chunk-6XAAYAWL.cjs.map +0 -1
  66. package/dist/chunk-7S3M4N4E.js.map +0 -1
  67. package/dist/chunk-BNU5QGIZ.js.map +0 -1
  68. package/dist/chunk-D35VBACN.js.map +0 -1
  69. package/dist/chunk-MEPHGCPQ.js.map +0 -1
  70. package/dist/chunk-OQPILS7B.js.map +0 -1
  71. package/dist/chunk-UEIYETCQ.js.map +0 -1
  72. package/dist/parser-ITMU2WN5.cjs.map +0 -1
  73. package/dist/parser-KMMUS73Q.js.map +0 -1
  74. package/dist/parser-TCTCSBYZ.js.map +0 -1
  75. package/dist/provider-4ZJKV3DC.js.map +0 -1
  76. package/dist/provider-AKROB7WQ.js.map +0 -1
  77. package/dist/provider-G4C2V2PD.cjs.map +0 -1
  78. package/dist/render-25BT623I.js +0 -10
  79. package/dist/seal-R4TETA4C.js +0 -10
  80. package/dist/setup-57FB3LSP.js.map +0 -1
  81. package/dist/watch-OHQWSVPE.js.map +0 -1
  82. /package/dist/{-LE4RLXVA.js.map → -AS4IABL2.js.map} +0 -0
  83. /package/dist/{chunk-HMUEU7D7.js.map → chunk-O5VS7RIR.js.map} +0 -0
  84. /package/dist/{chunk-RROH5WHO.js.map → chunk-WO52HVQJ.js.map} +0 -0
  85. /package/dist/{detect-RI2MQ33K.js.map → chunks-WVMGF7JL.js.map} +0 -0
  86. /package/dist/{profile-io-SLN4P76T.js.map → detect-YEZX2XCF.js.map} +0 -0
  87. /package/dist/{render-25BT623I.js.map → profile-io-PLDQFPJA.js.map} +0 -0
  88. /package/dist/{seal-R4TETA4C.js.map → redact-7ILEAUTS.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -21,7 +21,8 @@
21
21
 
22
22
 
23
23
 
24
- var _chunk6XAAYAWLcjs = require('./chunk-6XAAYAWL.cjs');
24
+
25
+ var _chunk37VKMUSTcjs = require('./chunk-37VKMUST.cjs');
25
26
 
26
27
 
27
28
  var _chunkDCZVOIEOcjs = require('./chunk-DCZVOIEO.cjs');
@@ -51,8 +52,11 @@ function parseLenientCfb(data) {
51
52
  const miniSectorSizeShift = data.readUInt16LE(32);
52
53
  if (miniSectorSizeShift > 16) throw new Error("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBBF8\uB2C8 \uC139\uD130 \uD06C\uAE30 \uC2DC\uD504\uD2B8: " + miniSectorSizeShift);
53
54
  const miniSectorSize = 1 << miniSectorSizeShift;
54
- const fatSectorCount = data.readUInt32LE(44);
55
- if (fatSectorCount > 1e4) throw new Error("FAT \uC139\uD130 \uC218\uAC00 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4: " + fatSectorCount);
55
+ const headerFatSectorCount = data.readUInt32LE(44);
56
+ if (headerFatSectorCount > 1e4) throw new Error("FAT \uC139\uD130 \uC218\uAC00 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4: " + headerFatSectorCount);
57
+ const maxRealSectors = Math.ceil(Math.max(0, data.length - 512) / sectorSize);
58
+ const maxFatSectors = Math.max(1, Math.ceil(maxRealSectors / (sectorSize / 4)));
59
+ const fatSectorCount = Math.min(headerFatSectorCount, maxFatSectors);
56
60
  const firstDirSector = data.readUInt32LE(48);
57
61
  const miniStreamCutoff = data.readUInt32LE(56);
58
62
  const firstMiniFatSector = data.readUInt32LE(60);
@@ -79,6 +83,7 @@ function parseLenientCfb(data) {
79
83
  if (visitedDifat.has(difatSector)) break;
80
84
  visitedDifat.add(difatSector);
81
85
  const buf = readSectorData(difatSector);
86
+ if (buf.length < sectorSize) break;
82
87
  const entriesPerSector = sectorSize / 4 - 1;
83
88
  for (let i = 0; i < entriesPerSector && fatSectors.length < fatSectorCount; i++) {
84
89
  const sid = buf.readUInt32LE(i * 4);
@@ -397,6 +402,12 @@ function comResultToParseResult(pages, pageCount, warnings) {
397
402
  var _xmldom = require('@xmldom/xmldom');
398
403
  var MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024;
399
404
  var MAX_ZIP_ENTRIES = 500;
405
+ var ZipBombError = class extends _chunk37VKMUSTcjs.KordocError {
406
+ constructor(message) {
407
+ super(message);
408
+ this.name = "ZipBombError";
409
+ }
410
+ };
400
411
  function clampSpan(val, max) {
401
412
  return Math.max(1, Math.min(val, max));
402
413
  }
@@ -407,7 +418,7 @@ function createSectionShared() {
407
418
  function createXmlParser(warnings) {
408
419
  return new (0, _xmldom.DOMParser)({
409
420
  onError(level, msg2) {
410
- if (level === "fatalError") throw new (0, _chunk6XAAYAWLcjs.KordocError)(`XML \uD30C\uC2F1 \uC2E4\uD328: ${msg2}`);
421
+ if (level === "fatalError") throw new (0, _chunk37VKMUSTcjs.KordocError)(`XML \uD30C\uC2F1 \uC2E4\uD328: ${msg2}`);
411
422
  _optionalChain([warnings, 'optionalAccess', _3 => _3.push, 'call', _4 => _4({ code: "MALFORMED_XML", message: `XML ${level === "warning" ? "\uACBD\uACE0" : "\uC624\uB958"}: ${msg2}` })]);
412
423
  }
413
424
  });
@@ -432,14 +443,15 @@ function findChildByLocalName(parent, name) {
432
443
  }
433
444
  return null;
434
445
  }
435
- function extractTextFromNode(node) {
446
+ function extractTextFromNode(node, depth = 0) {
436
447
  let result = "";
448
+ if (depth > MAX_XML_DEPTH) return result;
437
449
  const children = node.childNodes;
438
450
  if (!children) return result;
439
451
  for (let i = 0; i < children.length; i++) {
440
452
  const child = children[i];
441
453
  if (child.nodeType === 3) result += child.textContent || "";
442
- else if (child.nodeType === 1) result += extractTextFromNode(child);
454
+ else if (child.nodeType === 1) result += extractTextFromNode(child, depth + 1);
443
455
  }
444
456
  return result.trim();
445
457
  }
@@ -463,10 +475,10 @@ async function extractHwpxStyles(zip, decompressed) {
463
475
  const xml = await file.async("text");
464
476
  if (decompressed) {
465
477
  decompressed.total += xml.length * 2;
466
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
478
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
467
479
  }
468
480
  const parser = createXmlParser();
469
- const doc = parser.parseFromString(_chunk6XAAYAWLcjs.stripDtd.call(void 0, xml), "text/xml");
481
+ const doc = parser.parseFromString(_chunk37VKMUSTcjs.stripDtd.call(void 0, xml), "text/xml");
470
482
  if (!doc.documentElement) continue;
471
483
  const domDoc = doc;
472
484
  parseCharProperties(domDoc, result.charProperties);
@@ -649,9 +661,9 @@ function detectHwpxHeadings(blocks, styleMap) {
649
661
  let level = 0;
650
662
  if (baseFontSize > 0 && _optionalChain([block, 'access', _11 => _11.style, 'optionalAccess', _12 => _12.fontSize])) {
651
663
  const ratio = block.style.fontSize / baseFontSize;
652
- if (ratio >= _chunk6XAAYAWLcjs.HEADING_RATIO_H1) level = 1;
653
- else if (ratio >= _chunk6XAAYAWLcjs.HEADING_RATIO_H2) level = 2;
654
- else if (ratio >= _chunk6XAAYAWLcjs.HEADING_RATIO_H3) level = 3;
664
+ if (ratio >= _chunk37VKMUSTcjs.HEADING_RATIO_H1) level = 1;
665
+ else if (ratio >= _chunk37VKMUSTcjs.HEADING_RATIO_H2) level = 2;
666
+ else if (ratio >= _chunk37VKMUSTcjs.HEADING_RATIO_H3) level = 3;
655
667
  }
656
668
  const compactText = text.replace(/\s+/g, "");
657
669
  if (/^제\d+[조장절편]/.test(compactText) && text.length <= 50) {
@@ -1323,7 +1335,7 @@ function simulateWrap(text, firstWidth, contWidth, height, ratioPct, mode = "kee
1323
1335
  for (const ch of text.slice(from, to)) w += charW2(ch);
1324
1336
  return w;
1325
1337
  };
1326
- const units = _nullishCoalesce(text.match(mode === "keep" ? / +|[^ ]+/g : / +|[^ ]/g), () => ( []));
1338
+ const units = _nullishCoalesce(text.match(mode === "keep" ? / +|[^ ]+/gu : / +|[^ ]/gu), () => ( []));
1327
1339
  const starts = [0];
1328
1340
  let lineW = 0;
1329
1341
  let avail = firstWidth;
@@ -1576,7 +1588,7 @@ function needsGaejosikAssets(gongmun) {
1576
1588
  }
1577
1589
  function assertFiniteRange(name, value, min, max) {
1578
1590
  if (!Number.isFinite(value) || value < min || value > max) {
1579
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(`${name} must be a finite number between ${min} and ${max}`);
1591
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(`${name} must be a finite number between ${min} and ${max}`);
1580
1592
  }
1581
1593
  }
1582
1594
  function validateGongmunOptions(opts) {
@@ -1591,10 +1603,10 @@ function validateGongmunOptions(opts) {
1591
1603
  assertFiniteRange(`margins.${side}`, value, 0, 200);
1592
1604
  }
1593
1605
  if (opts.margins.left + opts.margins.right >= 210) {
1594
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("margins.left + margins.right must be less than 210");
1606
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("margins.left + margins.right must be less than 210");
1595
1607
  }
1596
1608
  if (opts.margins.top + opts.margins.bottom >= 297) {
1597
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("margins.top + margins.bottom must be less than 297");
1609
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("margins.top + margins.bottom must be less than 297");
1598
1610
  }
1599
1611
  }
1600
1612
  if (opts.sizes) {
@@ -1603,7 +1615,7 @@ function validateGongmunOptions(opts) {
1603
1615
  }
1604
1616
  }
1605
1617
  if (opts.approval && opts.approval.length > 6) {
1606
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("approval must contain at most 6 labels");
1618
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("approval must contain at most 6 labels");
1607
1619
  }
1608
1620
  }
1609
1621
  function incompatibleGongmunWarnings(opts) {
@@ -1792,6 +1804,7 @@ function toRoman(n) {
1792
1804
  return out;
1793
1805
  }
1794
1806
  function formatHeadNumber(n, numFormat) {
1807
+ if (n === 0 && numFormat === "DIGIT") return "0";
1795
1808
  if (n <= 0) n = 1;
1796
1809
  switch (numFormat) {
1797
1810
  case "DIGIT":
@@ -1849,25 +1862,25 @@ function resolveParaHeading(paraEl, ctx) {
1849
1862
  if (!numDef) return headingLevel ? { headingLevel } : null;
1850
1863
  let counters = ctx.shared.numState.get(numId);
1851
1864
  if (!counters) {
1852
- counters = new Array(11).fill(0);
1865
+ counters = new Array(11).fill(-1);
1853
1866
  ctx.shared.numState.set(numId, counters);
1854
1867
  }
1855
1868
  const head = numDef.heads.get(level);
1856
- counters[level] = counters[level] === 0 ? _nullishCoalesce(_optionalChain([head, 'optionalAccess', _22 => _22.start]), () => ( 1)) : counters[level] + 1;
1857
- for (let l = level + 1; l <= 10; l++) counters[l] = 0;
1869
+ counters[level] = counters[level] < 0 ? _nullishCoalesce(_optionalChain([head, 'optionalAccess', _22 => _22.start]), () => ( 1)) : counters[level] + 1;
1870
+ for (let l = level + 1; l <= 10; l++) counters[l] = -1;
1858
1871
  const fmtText = head ? head.text.trim() : `^${level}.`;
1859
1872
  const prefix = fmtText.replace(/\^(10|[1-9])/g, (_, d) => {
1860
1873
  const lv = parseInt(d, 10);
1861
1874
  const refHead = numDef.heads.get(lv);
1862
- const n = counters[lv] || _optionalChain([refHead, 'optionalAccess', _23 => _23.start]) || 1;
1875
+ const n = counters[lv] >= 0 ? counters[lv] : _nullishCoalesce(_optionalChain([refHead, 'optionalAccess', _23 => _23.start]), () => ( 1));
1863
1876
  return formatHeadNumber(n, _optionalChain([refHead, 'optionalAccess', _24 => _24.numFormat]) || "DIGIT");
1864
1877
  });
1865
1878
  return { prefix: prefix || void 0, headingLevel };
1866
1879
  }
1867
1880
 
1868
1881
  // src/hwpx/table-build.ts
1869
- function buildTableWithCellMeta(state) {
1870
- const table2 = _chunk6XAAYAWLcjs.buildTable.call(void 0, state.rows);
1882
+ function buildTableWithCellMeta(state, keepAnchoredEmptyCols) {
1883
+ const table2 = _chunk37VKMUSTcjs.buildTable.call(void 0, state.rows, { keepAnchoredEmptyCols });
1871
1884
  if (state.caption) table2.caption = state.caption;
1872
1885
  const anchors = [];
1873
1886
  {
@@ -1931,13 +1944,13 @@ function completeTable(newTable, tableStack, blocks, ctx) {
1931
1944
  if (newTable.caption) blocks.push({ type: "paragraph", text: newTable.caption, pageNumber: ctx.sectionNum });
1932
1945
  return parentTable;
1933
1946
  }
1934
- const ir = buildTableWithCellMeta(newTable);
1947
+ const ir = buildTableWithCellMeta(newTable, ctx.shared.keepTrailingEmptyCols);
1935
1948
  const block = { type: "table", table: ir, pageNumber: ctx.sectionNum };
1936
1949
  if (_optionalChain([parentTable, 'optionalAccess', _31 => _31.cell])) {
1937
1950
  const cell2 = parentTable.cell;
1938
1951
  (cell2.blocks ??= []).push(block);
1939
1952
  cell2.hasStructure = true;
1940
- let flat = _chunk6XAAYAWLcjs.convertTableToText.call(void 0, newTable.rows);
1953
+ let flat = _chunk37VKMUSTcjs.convertTableToText.call(void 0, newTable.rows);
1941
1954
  if (newTable.caption) flat = newTable.caption + (flat ? "\n" + flat : "");
1942
1955
  if (flat) cell2.text += (cell2.text ? "\n" : "") + flat;
1943
1956
  } else {
@@ -1949,7 +1962,7 @@ function completeTable(newTable, tableStack, blocks, ctx) {
1949
1962
  // src/hwpx/section-walker.ts
1950
1963
  function parseSectionXml(xml, styleMap, warnings, sectionNum, shared) {
1951
1964
  const parser = createXmlParser(warnings);
1952
- const doc = parser.parseFromString(_chunk6XAAYAWLcjs.stripDtd.call(void 0, xml), "text/xml");
1965
+ const doc = parser.parseFromString(_chunk37VKMUSTcjs.stripDtd.call(void 0, xml), "text/xml");
1953
1966
  if (!doc.documentElement) return [];
1954
1967
  const ctx = { styleMap, warnings, sectionNum, shared: _nullishCoalesce(shared, () => ( createSectionShared())) };
1955
1968
  ctx.shared.track.deleteDepth = 0;
@@ -1965,7 +1978,8 @@ function parseSectionXml(xml, styleMap, warnings, sectionNum, shared) {
1965
1978
  walkSection(doc.documentElement, blocks, null, [], ctx);
1966
1979
  return blocks;
1967
1980
  }
1968
- function extractImageRef(el) {
1981
+ function extractImageRef(el, depth = 0) {
1982
+ if (depth > MAX_XML_DEPTH) return null;
1969
1983
  const children = el.childNodes;
1970
1984
  if (!children) return null;
1971
1985
  for (let i = 0; i < children.length; i++) {
@@ -1976,7 +1990,7 @@ function extractImageRef(el) {
1976
1990
  const ref = child.getAttribute("binaryItemIDRef") || child.getAttribute("href") || "";
1977
1991
  if (ref) return ref;
1978
1992
  }
1979
- const nested = extractImageRef(child);
1993
+ const nested = extractImageRef(child, depth + 1);
1980
1994
  if (nested) return nested;
1981
1995
  }
1982
1996
  const directRef = el.getAttribute("binaryItemIDRef") || "";
@@ -2054,8 +2068,8 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
2054
2068
  const cs = isNaN(rawCs) ? 1 : rawCs;
2055
2069
  const rawRs = parseInt(el.getAttribute("rowSpan") || "1", 10);
2056
2070
  const rs = isNaN(rawRs) ? 1 : rawRs;
2057
- tableCtx.cell.colSpan = clampSpan(cs, _chunk6XAAYAWLcjs.MAX_COLS);
2058
- tableCtx.cell.rowSpan = clampSpan(rs, _chunk6XAAYAWLcjs.MAX_ROWS);
2071
+ tableCtx.cell.colSpan = clampSpan(cs, _chunk37VKMUSTcjs.MAX_COLS);
2072
+ tableCtx.cell.rowSpan = clampSpan(rs, _chunk37VKMUSTcjs.MAX_ROWS);
2059
2073
  }
2060
2074
  break;
2061
2075
  case "p": {
@@ -2083,7 +2097,7 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
2083
2097
  ;
2084
2098
  (cell2.blocks ??= []).push(cellBlock);
2085
2099
  } else if (!tableCtx) {
2086
- if (/^─{10,}$/.test(text)) {
2100
+ if (ctx.shared.kordocLayout && /^─{10,}$/.test(text)) {
2087
2101
  blocks.push({ type: "separator", pageNumber: ctx.sectionNum });
2088
2102
  tableCtx = walkParagraphChildren(el, blocks, tableCtx, tableStack, ctx, depth + 1);
2089
2103
  break;
@@ -2253,7 +2267,7 @@ function flattenSubListTable(el, ctx, depth) {
2253
2267
  const sink = [];
2254
2268
  const st = { rows: [], currentRow: [], cell: null };
2255
2269
  walkSection(el, sink, st, [], ctx, depth + 1);
2256
- let flat = _chunk6XAAYAWLcjs.convertTableToText.call(void 0, st.rows);
2270
+ let flat = _chunk37VKMUSTcjs.convertTableToText.call(void 0, st.rows);
2257
2271
  if (st.caption) flat = st.caption + (flat ? "\n" + flat : "");
2258
2272
  return flat;
2259
2273
  }
@@ -2359,8 +2373,8 @@ function extractDrawTextBlocks(drawTextNode, blocks, ctx) {
2359
2373
  } else {
2360
2374
  const info = extractParagraphInfo(child, ctx.styleMap, ctx);
2361
2375
  let text = info.text.trim();
2376
+ const ph = resolveParaHeading(child, ctx);
2362
2377
  if (text) {
2363
- const ph = resolveParaHeading(child, ctx);
2364
2378
  if (_optionalChain([ph, 'optionalAccess', _47 => _47.prefix])) text = ph.prefix + " " + text;
2365
2379
  const block = { type: "paragraph", text, style: _nullishCoalesce(info.style, () => ( void 0)), pageNumber: ctx.sectionNum };
2366
2380
  if (info.href) block.href = info.href;
@@ -2386,7 +2400,7 @@ function extractHyperlinkHref(fieldBegin) {
2386
2400
  let url = (ch.textContent || "").trim();
2387
2401
  if (!url) continue;
2388
2402
  url = url.replace(/^https?:\/\/(?=https?:\/\/)/i, "");
2389
- const safe = _chunk6XAAYAWLcjs.sanitizeHref.call(void 0, url);
2403
+ const safe = _chunk37VKMUSTcjs.sanitizeHref.call(void 0, url);
2390
2404
  if (safe) return safe;
2391
2405
  }
2392
2406
  return void 0;
@@ -2473,7 +2487,8 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2473
2487
  }
2474
2488
  }
2475
2489
  };
2476
- const walk = (node) => {
2490
+ const walk = (node, depth = 0) => {
2491
+ if (depth > MAX_XML_DEPTH) return;
2477
2492
  const children = node.childNodes;
2478
2493
  if (!children) return;
2479
2494
  for (let i = 0; i < children.length; i++) {
@@ -2494,7 +2509,7 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2494
2509
  const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
2495
2510
  switch (tag) {
2496
2511
  case "t":
2497
- walk(child);
2512
+ walk(child, depth + 1);
2498
2513
  break;
2499
2514
  // 자식 순회 (tab 등 하위 요소 처리)
2500
2515
  case "tab": {
@@ -2524,10 +2539,10 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2524
2539
  case "hyperlink": {
2525
2540
  const url = child.getAttribute("url") || child.getAttribute("href") || "";
2526
2541
  if (url) {
2527
- const safe = _chunk6XAAYAWLcjs.sanitizeHref.call(void 0, url);
2542
+ const safe = _chunk37VKMUSTcjs.sanitizeHref.call(void 0, url);
2528
2543
  if (safe) href = safe;
2529
2544
  }
2530
- walk(child);
2545
+ walk(child, depth + 1);
2531
2546
  break;
2532
2547
  }
2533
2548
  // 각주/미주
@@ -2598,11 +2613,11 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2598
2613
  case "r": {
2599
2614
  const runCharPr = child.getAttribute("charPrIDRef");
2600
2615
  if (runCharPr && !charPrId) charPrId = runCharPr;
2601
- walk(child);
2616
+ walk(child, depth + 1);
2602
2617
  break;
2603
2618
  }
2604
2619
  default:
2605
- walk(child);
2620
+ walk(child, depth + 1);
2606
2621
  break;
2607
2622
  }
2608
2623
  }
@@ -2613,7 +2628,7 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2613
2628
  let cleanText = text.replace(/[ \t]+/g, " ").trim();
2614
2629
  if (/^그림입니다\.?\s*원본\s*그림의\s*(이름|크기)/.test(cleanText)) cleanText = "";
2615
2630
  cleanText = cleanText.replace(/그림입니다\.?\s*원본\s*그림의\s*(이름|크기)[^\n]*(\n[^\n]*원본\s*그림의\s*(이름|크기)[^\n]*)*/g, "").trim();
2616
- cleanText = cleanText.replace(/(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|선|직선|곡선|화살표|오각형|육각형|팔각형|별|십자|구름|마름모|도넛|평행사변형|사다리꼴|개체|그리기\s?개체|묶음\s?개체|글상자|표|그림|OLE\s?개체)\s?입니다\.?/g, "").trim();
2631
+ cleanText = cleanText.replace(/^(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|선|직선|곡선|화살표|오각형|육각형|팔각형|별|십자|구름|마름모|도넛|평행사변형|사다리꼴|개체|그리기\s?개체|묶음\s?개체|글상자|표|그림|OLE\s?개체)\s?입니다\.?$/gm, "").trim();
2617
2632
  let style;
2618
2633
  if (styleMap && charPrId) {
2619
2634
  const charProp = styleMap.charProperties.get(charPrId);
@@ -2737,10 +2752,9 @@ var CHAR_LINE = 0;
2737
2752
  var CHAR_SECTION_BREAK = 10;
2738
2753
  var CHAR_PARA = 13;
2739
2754
  var CHAR_TAB = 9;
2740
- var CHAR_HYPHEN = 30;
2741
- var CHAR_NBSP = 31;
2742
- var CHAR_FIXED_NBSP = 24;
2743
- var CHAR_FIXED_WIDTH = 25;
2755
+ var CHAR_HYPHEN = 24;
2756
+ var CHAR_NBSP = 30;
2757
+ var CHAR_FIXED_WIDTH = 31;
2744
2758
  var FLAG_COMPRESSED = 1 << 0;
2745
2759
  var FLAG_ENCRYPTED = 1 << 1;
2746
2760
  var FLAG_DISTRIBUTION = 1 << 2;
@@ -2778,7 +2792,7 @@ function decompressStream(data) {
2778
2792
  return _zlib.inflateRawSync.call(void 0, data, opts);
2779
2793
  }
2780
2794
  function parseFileHeader(data) {
2781
- if (data.length < 40) throw new (0, _chunk6XAAYAWLcjs.KordocError)("FileHeader\uAC00 \uB108\uBB34 \uC9E7\uC2B5\uB2C8\uB2E4 (\uCD5C\uC18C 40\uBC14\uC774\uD2B8)");
2795
+ if (data.length < 40) throw new (0, _chunk37VKMUSTcjs.KordocError)("FileHeader\uAC00 \uB108\uBB34 \uC9E7\uC2B5\uB2C8\uB2E4 (\uCD5C\uC18C 40\uBC14\uC774\uD2B8)");
2782
2796
  const sig = data.subarray(0, 32).toString("utf8").replace(/\0+$/, "");
2783
2797
  return {
2784
2798
  signature: sig,
@@ -2939,9 +2953,6 @@ function appendParaText(state, data, resolveControl) {
2939
2953
  result += "-";
2940
2954
  break;
2941
2955
  case CHAR_NBSP:
2942
- result += " ";
2943
- break;
2944
- case CHAR_FIXED_NBSP:
2945
2956
  result += "\xA0";
2946
2957
  break;
2947
2958
  // 진짜 NBSP
@@ -3230,23 +3241,23 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUn
3230
3241
  }
3231
3242
  const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates;
3232
3243
  for (const path of allCandidates) {
3233
- if (_chunk6XAAYAWLcjs.isPathTraversal.call(void 0, path)) continue;
3244
+ if (_chunk37VKMUSTcjs.isPathTraversal.call(void 0, path)) continue;
3234
3245
  const file = zip.file(path);
3235
3246
  if (!file) continue;
3236
3247
  try {
3237
3248
  const data = await file.async("uint8array");
3238
3249
  decompressed.total += data.length;
3239
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3250
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3240
3251
  const ext = path.includes(".") ? path.split(".").pop() || "png" : "png";
3241
3252
  const mimeType = imageExtToMime(ext);
3242
3253
  imageIndex++;
3243
- const filename = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
3244
- img = { filename, data, mimeType };
3254
+ const filename2 = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
3255
+ img = { filename: filename2, data, mimeType };
3245
3256
  images.push(img);
3246
3257
  usedPaths.add(path);
3247
3258
  break;
3248
3259
  } catch (err) {
3249
- if (err instanceof _chunk6XAAYAWLcjs.KordocError) throw err;
3260
+ if (err instanceof _chunk37VKMUSTcjs.KordocError) throw err;
3250
3261
  }
3251
3262
  }
3252
3263
  if (!img) _optionalChain([warnings, 'optionalAccess', _69 => _69.push, 'call', _70 => _70({ page: block.pageNumber, message: `\uC774\uBBF8\uC9C0 \uD30C\uC77C \uC5C6\uC74C: ${ref}`, code: "SKIPPED_IMAGE" })]);
@@ -3255,21 +3266,22 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUn
3255
3266
  if (!img) {
3256
3267
  block.type = "paragraph";
3257
3268
  block.text = `[\uC774\uBBF8\uC9C0: ${ref}]`;
3258
- if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `[\uC774\uBBF8\uC9C0: ${ref}]`);
3269
+ if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, () => `[\uC774\uBBF8\uC9C0: ${ref}]`);
3259
3270
  continue;
3260
3271
  }
3261
- block.text = img.filename;
3272
+ const filename = img.filename;
3273
+ block.text = filename;
3262
3274
  block.imageData = { data: img.data, mimeType: img.mimeType, filename: ref };
3263
- if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `![image](${img.filename})`);
3275
+ if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, () => `![image](${filename})`);
3264
3276
  }
3265
3277
  if (sweepUnreferenced) {
3266
3278
  const binEntries = zip.file(/(?:^|\/)BinData\//i);
3267
3279
  for (const file of binEntries) {
3268
- if (file.dir || usedPaths.has(file.name) || _chunk6XAAYAWLcjs.isPathTraversal.call(void 0, file.name)) continue;
3280
+ if (file.dir || usedPaths.has(file.name) || _chunk37VKMUSTcjs.isPathTraversal.call(void 0, file.name)) continue;
3269
3281
  try {
3270
3282
  const data = await file.async("uint8array");
3271
3283
  decompressed.total += data.length;
3272
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3284
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3273
3285
  const ext = file.name.includes(".") ? file.name.split(".").pop() || "" : "";
3274
3286
  let mimeType = imageExtToMime(ext);
3275
3287
  if (mimeType === "application/octet-stream") {
@@ -3283,7 +3295,7 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUn
3283
3295
  images.push(img);
3284
3296
  blocks.push({ type: "image", text: filename, imageData: { data, mimeType, filename: file.name } });
3285
3297
  } catch (err) {
3286
- if (err instanceof _chunk6XAAYAWLcjs.KordocError) throw err;
3298
+ if (err instanceof _chunk37VKMUSTcjs.KordocError) throw err;
3287
3299
  _optionalChain([warnings, 'optionalAccess', _71 => _71.push, 'call', _72 => _72({ message: `\uC774\uBBF8\uC9C0 \uCD94\uCD9C \uC2E4\uD328: ${file.name}`, code: "SKIPPED_IMAGE" })]);
3288
3300
  }
3289
3301
  }
@@ -3334,7 +3346,7 @@ function extractFromBrokenZip(buffer) {
3334
3346
  }
3335
3347
  const nameBytes = data.slice(pos + 30, pos + 30 + nameLen);
3336
3348
  const name = new TextDecoder().decode(nameBytes);
3337
- if (_chunk6XAAYAWLcjs.isPathTraversal.call(void 0, name)) {
3349
+ if (_chunk37VKMUSTcjs.isPathTraversal.call(void 0, name)) {
3338
3350
  pos = fileStart + compSize;
3339
3351
  continue;
3340
3352
  }
@@ -3352,16 +3364,16 @@ function extractFromBrokenZip(buffer) {
3352
3364
  continue;
3353
3365
  }
3354
3366
  totalDecompressed += content.length * 2;
3355
- if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC");
3367
+ if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC");
3356
3368
  sectionNum++;
3357
3369
  blocks.push(...parseSectionXml(content, void 0, warnings, sectionNum, shared));
3358
3370
  } catch (e16) {
3359
3371
  continue;
3360
3372
  }
3361
3373
  }
3362
- if (blocks.length === 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uC190\uC0C1\uB41C HWPX\uC5D0\uC11C \uC139\uC158 \uB370\uC774\uD130\uB97C \uBCF5\uAD6C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3374
+ if (blocks.length === 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uC190\uC0C1\uB41C HWPX\uC5D0\uC11C \uC139\uC158 \uB370\uC774\uD130\uB97C \uBCF5\uAD6C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3363
3375
  applyPageText(blocks, shared);
3364
- const markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, blocks);
3376
+ const markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, blocks);
3365
3377
  return { markdown, blocks, warnings: warnings.length > 0 ? warnings : void 0 };
3366
3378
  }
3367
3379
  async function readKordocLayout(zip) {
@@ -3386,18 +3398,18 @@ async function resolveSectionPaths(zip) {
3386
3398
  if (paths.length > 0) return paths;
3387
3399
  }
3388
3400
  const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/);
3389
- return sectionFiles.map((f) => f.name).sort(_chunk6XAAYAWLcjs.compareSectionPaths);
3401
+ return sectionFiles.map((f) => f.name).sort(_chunk37VKMUSTcjs.compareSectionPaths);
3390
3402
  }
3391
3403
  function parseSectionPathsFromManifest(xml) {
3392
3404
  const parser = createXmlParser();
3393
- const doc = parser.parseFromString(_chunk6XAAYAWLcjs.stripDtd.call(void 0, xml), "text/xml");
3405
+ const doc = parser.parseFromString(_chunk37VKMUSTcjs.stripDtd.call(void 0, xml), "text/xml");
3394
3406
  const items = doc.getElementsByTagName("opf:item");
3395
3407
  const spine = doc.getElementsByTagName("opf:itemref");
3396
3408
  const idToHref = /* @__PURE__ */ new Map();
3397
3409
  for (let i = 0; i < items.length; i++) {
3398
3410
  const item = items[i];
3399
3411
  const id = item.getAttribute("id") || "";
3400
- const href = _chunk6XAAYAWLcjs.normalizeSectionHref.call(void 0, item.getAttribute("href") || "");
3412
+ const href = _chunk37VKMUSTcjs.normalizeSectionHref.call(void 0, item.getAttribute("href") || "");
3401
3413
  if (id && href) idToHref.set(id, href);
3402
3414
  }
3403
3415
  if (spine.length > 0) {
@@ -3408,7 +3420,7 @@ function parseSectionPathsFromManifest(xml) {
3408
3420
  }
3409
3421
  if (ordered.length > 0) return ordered;
3410
3422
  }
3411
- return Array.from(idToHref.values()).sort(_chunk6XAAYAWLcjs.compareSectionPaths);
3423
+ return Array.from(idToHref.values()).sort(_chunk37VKMUSTcjs.compareSectionPaths);
3412
3424
  }
3413
3425
 
3414
3426
  // src/hwpx/metadata.ts
@@ -3421,7 +3433,7 @@ async function extractHwpxMetadata(zip, metadata, decompressed) {
3421
3433
  const xml = await file.async("text");
3422
3434
  if (decompressed) {
3423
3435
  decompressed.total += xml.length * 2;
3424
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3436
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3425
3437
  }
3426
3438
  parseDublinCoreMetadata(xml, metadata);
3427
3439
  if (metadata.title || metadata.author) return;
@@ -3431,7 +3443,7 @@ async function extractHwpxMetadata(zip, metadata, decompressed) {
3431
3443
  }
3432
3444
  function parseDublinCoreMetadata(xml, metadata) {
3433
3445
  const parser = createXmlParser();
3434
- const doc = parser.parseFromString(_chunk6XAAYAWLcjs.stripDtd.call(void 0, xml), "text/xml");
3446
+ const doc = parser.parseFromString(_chunk37VKMUSTcjs.stripDtd.call(void 0, xml), "text/xml");
3435
3447
  if (!doc.documentElement) return;
3436
3448
  const getText = (tagNames) => {
3437
3449
  for (const tag of tagNames) {
@@ -3456,7 +3468,7 @@ function parseDublinCoreMetadata(xml, metadata) {
3456
3468
 
3457
3469
  // src/hwpx/parser.ts
3458
3470
  async function parseHwpxDocument(buffer, options) {
3459
- _chunk6XAAYAWLcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
3471
+ _chunk37VKMUSTcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
3460
3472
  let zip;
3461
3473
  try {
3462
3474
  zip = await _jszip2.default.loadAsync(buffer);
@@ -3465,7 +3477,7 @@ async function parseHwpxDocument(buffer, options) {
3465
3477
  }
3466
3478
  const actualEntryCount = Object.keys(zip.files).length;
3467
3479
  if (actualEntryCount > MAX_ZIP_ENTRIES) {
3468
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP \uC5D4\uD2B8\uB9AC \uC218 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3480
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP \uC5D4\uD2B8\uB9AC \uC218 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3469
3481
  }
3470
3482
  const manifestFile = zip.file("META-INF/manifest.xml");
3471
3483
  if (manifestFile) {
@@ -3477,7 +3489,7 @@ async function parseHwpxDocument(buffer, options) {
3477
3489
  return comResultToParseResult(pages, pageCount, warnings2);
3478
3490
  }
3479
3491
  }
3480
- throw new (0, _chunk6XAAYAWLcjs.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.");
3492
+ throw new (0, _chunk37VKMUSTcjs.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.");
3481
3493
  }
3482
3494
  }
3483
3495
  const decompressed = { total: 0 };
@@ -3486,13 +3498,14 @@ async function parseHwpxDocument(buffer, options) {
3486
3498
  const styleMap = await extractHwpxStyles(zip, decompressed);
3487
3499
  const warnings = [];
3488
3500
  const sectionPaths = await resolveSectionPaths(zip);
3489
- if (sectionPaths.length === 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3501
+ if (sectionPaths.length === 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3490
3502
  metadata.pageCount = sectionPaths.length;
3491
3503
  const pageFilter = _optionalChain([options, 'optionalAccess', _81 => _81.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sectionPaths.length) : null;
3492
3504
  const totalTarget = pageFilter ? pageFilter.size : sectionPaths.length;
3493
3505
  const blocks = [];
3494
3506
  const shared = createSectionShared();
3495
3507
  shared.kordocLayout = await readKordocLayout(zip);
3508
+ shared.keepTrailingEmptyCols = _optionalChain([options, 'optionalAccess', _82 => _82.keepTrailingEmptyCols]);
3496
3509
  let parsedSections = 0;
3497
3510
  for (let si = 0; si < sectionPaths.length; si++) {
3498
3511
  if (pageFilter && !pageFilter.has(si + 1)) continue;
@@ -3501,12 +3514,12 @@ async function parseHwpxDocument(buffer, options) {
3501
3514
  try {
3502
3515
  const xml = await file.async("text");
3503
3516
  decompressed.total += xml.length * 2;
3504
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3517
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new ZipBombError("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
3505
3518
  blocks.push(...parseSectionXml(xml, styleMap, warnings, si + 1, shared));
3506
3519
  parsedSections++;
3507
- _optionalChain([options, 'optionalAccess', _82 => _82.onProgress, 'optionalCall', _83 => _83(parsedSections, totalTarget)]);
3520
+ _optionalChain([options, 'optionalAccess', _83 => _83.onProgress, 'optionalCall', _84 => _84(parsedSections, totalTarget)]);
3508
3521
  } catch (secErr) {
3509
- if (secErr instanceof _chunk6XAAYAWLcjs.KordocError) throw secErr;
3522
+ if (secErr instanceof ZipBombError) throw secErr;
3510
3523
  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" });
3511
3524
  }
3512
3525
  }
@@ -3514,7 +3527,7 @@ async function parseHwpxDocument(buffer, options) {
3514
3527
  const images = await extractImagesFromZip(zip, blocks, decompressed, warnings, !pageFilter);
3515
3528
  detectHwpxHeadings(blocks, styleMap);
3516
3529
  const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
3517
- const markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, blocks);
3530
+ const markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, blocks);
3518
3531
  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 };
3519
3532
  }
3520
3533
 
@@ -4693,22 +4706,22 @@ function parseHwp5Document(buffer, options) {
4693
4706
  lenientCfb = parseLenientCfb(buffer);
4694
4707
  warnings.push({ message: "\uC190\uC0C1\uB41C CFB \uCEE8\uD14C\uC774\uB108 \u2014 lenient \uBAA8\uB4DC\uB85C \uBCF5\uAD6C", code: "LENIENT_CFB_RECOVERY" });
4695
4708
  } catch (e22) {
4696
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328 (strict \uBC0F lenient \uBAA8\uB450)");
4709
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328 (strict \uBC0F lenient \uBAA8\uB450)");
4697
4710
  }
4698
4711
  }
4699
4712
  const findStream = (path) => {
4700
4713
  if (cfb) {
4701
4714
  const entry = CFB.find(cfb, path);
4702
- return _optionalChain([entry, 'optionalAccess', _84 => _84.content]) ? Buffer.from(entry.content) : null;
4715
+ return _optionalChain([entry, 'optionalAccess', _85 => _85.content]) ? Buffer.from(entry.content) : null;
4703
4716
  }
4704
4717
  return lenientCfb.findStream(path);
4705
4718
  };
4706
4719
  const headerData = findStream("/FileHeader");
4707
- if (!headerData) throw new (0, _chunk6XAAYAWLcjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
4720
+ if (!headerData) throw new (0, _chunk37VKMUSTcjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
4708
4721
  const header = parseFileHeader(headerData);
4709
- if (header.signature !== "HWP Document File") throw new (0, _chunk6XAAYAWLcjs.KordocError)("HWP \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
4710
- if (header.flags & FLAG_ENCRYPTED) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uC554\uD638\uD654\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
4711
- if (header.flags & FLAG_DRM) throw new (0, _chunk6XAAYAWLcjs.KordocError)("DRM \uBCF4\uD638\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
4722
+ if (header.signature !== "HWP Document File") throw new (0, _chunk37VKMUSTcjs.KordocError)("HWP \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
4723
+ if (header.flags & FLAG_ENCRYPTED) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uC554\uD638\uD654\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
4724
+ if (header.flags & FLAG_DRM) throw new (0, _chunk37VKMUSTcjs.KordocError)("DRM \uBCF4\uD638\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
4712
4725
  const compressed = (header.flags & FLAG_COMPRESSED) !== 0;
4713
4726
  const distribution = (header.flags & FLAG_DISTRIBUTION) !== 0;
4714
4727
  const metadata = {
@@ -4717,12 +4730,13 @@ function parseHwp5Document(buffer, options) {
4717
4730
  if (cfb) extractHwp5Metadata(cfb, metadata);
4718
4731
  const docInfo = cfb ? parseDocInfoStream(cfb, compressed) : parseDocInfoFromStream(findStream("/DocInfo"), compressed);
4719
4732
  const sections = distribution ? cfb ? findViewTextSections(cfb, compressed) : findViewTextSectionsLenient(lenientCfb, compressed) : cfb ? findSections(cfb) : findSectionsLenient(lenientCfb, compressed);
4720
- if (sections.length === 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uC139\uC158 \uC2A4\uD2B8\uB9BC\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
4733
+ if (sections.length === 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uC139\uC158 \uC2A4\uD2B8\uB9BC\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
4721
4734
  metadata.pageCount = sections.length;
4722
- const pageFilter = _optionalChain([options, 'optionalAccess', _85 => _85.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sections.length) : null;
4735
+ const pageFilter = _optionalChain([options, 'optionalAccess', _86 => _86.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sections.length) : null;
4723
4736
  const totalTarget = pageFilter ? pageFilter.size : sections.length;
4724
4737
  const bodyBlocks = [];
4725
4738
  const doc = createHwp5DocState();
4739
+ doc.keepTrailingEmptyCols = _optionalChain([options, 'optionalAccess', _87 => _87.keepTrailingEmptyCols]);
4726
4740
  let totalDecompressed = 0;
4727
4741
  let parsedSections = 0;
4728
4742
  for (let si = 0; si < sections.length; si++) {
@@ -4731,22 +4745,22 @@ function parseHwp5Document(buffer, options) {
4731
4745
  const sectionData = sections[si];
4732
4746
  const data = !distribution && compressed ? decompressStream(Buffer.from(sectionData)) : Buffer.from(sectionData);
4733
4747
  totalDecompressed += data.length;
4734
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4748
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4735
4749
  const records = readRecords(data);
4736
4750
  const sectionBlocks = parseSection(records, docInfo, warnings, si + 1, doc);
4737
4751
  bodyBlocks.push(...sectionBlocks);
4738
4752
  parsedSections++;
4739
- _optionalChain([options, 'optionalAccess', _86 => _86.onProgress, 'optionalCall', _87 => _87(parsedSections, totalTarget)]);
4753
+ _optionalChain([options, 'optionalAccess', _88 => _88.onProgress, 'optionalCall', _89 => _89(parsedSections, totalTarget)]);
4740
4754
  } catch (secErr) {
4741
- if (secErr instanceof _chunk6XAAYAWLcjs.KordocError) throw secErr;
4755
+ if (secErr instanceof _chunk37VKMUSTcjs.KordocError) throw secErr;
4742
4756
  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" });
4743
4757
  }
4744
4758
  }
4745
4759
  const blocks = [...doc.headerBlocks, ...bodyBlocks, ...doc.footerBlocks];
4746
4760
  const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings, !pageFilter) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings, !pageFilter);
4747
- let flatBlocks = _chunk6XAAYAWLcjs.flattenLayoutTables.call(void 0, blocks);
4748
- if (_optionalChain([options, 'optionalAccess', _88 => _88.dedupeRunningHeaders])) {
4749
- const deduped = _chunk6XAAYAWLcjs.dedupeRunningHeaders.call(void 0, flatBlocks);
4761
+ let flatBlocks = _chunk37VKMUSTcjs.flattenLayoutTables.call(void 0, blocks);
4762
+ if (_optionalChain([options, 'optionalAccess', _90 => _90.dedupeRunningHeaders])) {
4763
+ const deduped = _chunk37VKMUSTcjs.dedupeRunningHeaders.call(void 0, flatBlocks);
4750
4764
  const removed = flatBlocks.length - deduped.length;
4751
4765
  if (removed > 0) warnings.push({ message: `\uBC18\uBCF5 \uB7EC\uB2DD \uD5E4\uB354 ${removed}\uAC1C \uC81C\uAC70`, code: "HIDDEN_TEXT_FILTERED" });
4752
4766
  flatBlocks = deduped;
@@ -4755,10 +4769,10 @@ function parseHwp5Document(buffer, options) {
4755
4769
  detectHwp5Headings(flatBlocks, docInfo);
4756
4770
  }
4757
4771
  const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
4758
- let markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, flatBlocks);
4759
- if (_optionalChain([options, 'optionalAccess', _89 => _89.inlineImages]) && images.length > 0) {
4772
+ let markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, flatBlocks);
4773
+ if (_optionalChain([options, 'optionalAccess', _91 => _91.inlineImages]) && images.length > 0) {
4760
4774
  try {
4761
- markdown = _chunk6XAAYAWLcjs.inlineImagesIntoMarkdown.call(void 0, markdown, images, { compress: true });
4775
+ markdown = _chunk37VKMUSTcjs.inlineImagesIntoMarkdown.call(void 0, markdown, images, { compress: true });
4762
4776
  } catch (inlineErr) {
4763
4777
  warnings.push({ message: `\uC774\uBBF8\uC9C0 \uC778\uB77C\uC778 \uC2E4\uD328 \u2014 \uC6D0\uBCF8 \uD30C\uC77C \uCC38\uC870\uB85C \uD3F4\uBC31: ${inlineErr instanceof Error ? inlineErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "SKIPPED_IMAGE" });
4764
4778
  }
@@ -4768,7 +4782,7 @@ function parseHwp5Document(buffer, options) {
4768
4782
  function parseDocInfoStream(cfb, compressed) {
4769
4783
  try {
4770
4784
  const entry = CFB.find(cfb, "/DocInfo");
4771
- if (!_optionalChain([entry, 'optionalAccess', _90 => _90.content])) return null;
4785
+ if (!_optionalChain([entry, 'optionalAccess', _92 => _92.content])) return null;
4772
4786
  const data = compressed ? decompressStream(Buffer.from(entry.content)) : Buffer.from(entry.content);
4773
4787
  const records = readRecords(data);
4774
4788
  return parseDocInfo(records);
@@ -4789,7 +4803,7 @@ function detectHwp5Headings(blocks, docInfo) {
4789
4803
  let baseFontSize = 0;
4790
4804
  const sizeFreq = /* @__PURE__ */ new Map();
4791
4805
  for (const b of blocks) {
4792
- if (_optionalChain([b, 'access', _91 => _91.style, 'optionalAccess', _92 => _92.fontSize]) && b.text) {
4806
+ if (_optionalChain([b, 'access', _93 => _93.style, 'optionalAccess', _94 => _94.fontSize]) && b.text) {
4793
4807
  sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + b.text.length);
4794
4808
  }
4795
4809
  }
@@ -4805,7 +4819,7 @@ function detectHwp5Headings(blocks, docInfo) {
4805
4819
  const name = (style.nameKo || style.name).toLowerCase();
4806
4820
  if (name.includes("\uBC14\uD0D5") || name.includes("\uBCF8\uBB38") || name === "normal" || name === "body") {
4807
4821
  const cs = docInfo.charShapes[style.charShapeId];
4808
- if (_optionalChain([cs, 'optionalAccess', _93 => _93.fontSize]) > 0) {
4822
+ if (_optionalChain([cs, 'optionalAccess', _95 => _95.fontSize]) > 0) {
4809
4823
  baseFontSize = cs.fontSize / 10;
4810
4824
  break;
4811
4825
  }
@@ -4820,11 +4834,11 @@ function detectHwp5Headings(blocks, docInfo) {
4820
4834
  if (text.length === 0 || text.length > 200) continue;
4821
4835
  if (/^\d+$/.test(text)) continue;
4822
4836
  let level = 0;
4823
- if (_optionalChain([block, 'access', _94 => _94.style, 'optionalAccess', _95 => _95.fontSize]) && baseFontSize > 0) {
4837
+ if (_optionalChain([block, 'access', _96 => _96.style, 'optionalAccess', _97 => _97.fontSize]) && baseFontSize > 0) {
4824
4838
  const ratio = block.style.fontSize / baseFontSize;
4825
- if (ratio >= _chunk6XAAYAWLcjs.HEADING_RATIO_H1) level = 1;
4826
- else if (ratio >= _chunk6XAAYAWLcjs.HEADING_RATIO_H2) level = 2;
4827
- else if (ratio >= _chunk6XAAYAWLcjs.HEADING_RATIO_H3) level = 3;
4839
+ if (ratio >= _chunk37VKMUSTcjs.HEADING_RATIO_H1) level = 1;
4840
+ else if (ratio >= _chunk37VKMUSTcjs.HEADING_RATIO_H2) level = 2;
4841
+ else if (ratio >= _chunk37VKMUSTcjs.HEADING_RATIO_H3) level = 3;
4828
4842
  }
4829
4843
  if (/^제\d+[장절편]\s/.test(text) && text.length <= 50) {
4830
4844
  if (level === 0) level = 2;
@@ -4840,7 +4854,7 @@ function detectHwp5Headings(blocks, docInfo) {
4840
4854
  function extractHwp5Metadata(cfb, metadata) {
4841
4855
  try {
4842
4856
  const summaryEntry = CFB.find(cfb, "/HwpSummaryInformation") || CFB.find(cfb, "/SummaryInformation");
4843
- if (!_optionalChain([summaryEntry, 'optionalAccess', _96 => _96.content])) return;
4857
+ if (!_optionalChain([summaryEntry, 'optionalAccess', _98 => _98.content])) return;
4844
4858
  const data = Buffer.from(summaryEntry.content);
4845
4859
  if (data.length < 48) return;
4846
4860
  const numSets = data.readUInt32LE(24);
@@ -4873,7 +4887,7 @@ function findViewTextSections(cfb, compressed) {
4873
4887
  const sections = [];
4874
4888
  for (let i = 0; i < MAX_SECTIONS; i++) {
4875
4889
  const entry = CFB.find(cfb, `/ViewText/Section${i}`);
4876
- if (!_optionalChain([entry, 'optionalAccess', _97 => _97.content])) break;
4890
+ if (!_optionalChain([entry, 'optionalAccess', _99 => _99.content])) break;
4877
4891
  try {
4878
4892
  const decrypted = decryptViewText(Buffer.from(entry.content), compressed);
4879
4893
  sections.push({ idx: i, content: decrypted });
@@ -4887,13 +4901,13 @@ function findSections(cfb) {
4887
4901
  const sections = [];
4888
4902
  for (let i = 0; i < MAX_SECTIONS; i++) {
4889
4903
  const entry = CFB.find(cfb, `/BodyText/Section${i}`);
4890
- if (!_optionalChain([entry, 'optionalAccess', _98 => _98.content])) break;
4904
+ if (!_optionalChain([entry, 'optionalAccess', _100 => _100.content])) break;
4891
4905
  sections.push({ idx: i, content: Buffer.from(entry.content) });
4892
4906
  }
4893
4907
  if (sections.length === 0 && cfb.FileIndex) {
4894
4908
  for (const entry of cfb.FileIndex) {
4895
4909
  if (sections.length >= MAX_SECTIONS) break;
4896
- if (_optionalChain([entry, 'access', _99 => _99.name, 'optionalAccess', _100 => _100.startsWith, 'call', _101 => _101("Section")]) && entry.content) {
4910
+ if (_optionalChain([entry, 'access', _101 => _101.name, 'optionalAccess', _102 => _102.startsWith, 'call', _103 => _103("Section")]) && entry.content) {
4897
4911
  const idx = parseInt(entry.name.replace("Section", ""), 10) || 0;
4898
4912
  sections.push({ idx, content: Buffer.from(entry.content) });
4899
4913
  }
@@ -4909,7 +4923,7 @@ function findSectionsLenient(lcfb, compressed) {
4909
4923
  if (!raw) break;
4910
4924
  const content = compressed ? decompressStream(raw) : raw;
4911
4925
  totalDecompressed += content.length;
4912
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4926
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4913
4927
  sections.push({ idx: i, content });
4914
4928
  }
4915
4929
  if (sections.length === 0) {
@@ -4921,7 +4935,7 @@ function findSectionsLenient(lcfb, compressed) {
4921
4935
  if (raw) {
4922
4936
  const content = compressed ? decompressStream(raw) : raw;
4923
4937
  totalDecompressed += content.length;
4924
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4938
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4925
4939
  sections.push({ idx, content });
4926
4940
  }
4927
4941
  }
@@ -4938,7 +4952,7 @@ function findViewTextSectionsLenient(lcfb, compressed) {
4938
4952
  try {
4939
4953
  const content = decryptViewText(raw, compressed);
4940
4954
  totalDecompressed += content.length;
4941
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4955
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
4942
4956
  sections.push({ idx: i, content });
4943
4957
  } catch (e27) {
4944
4958
  break;
@@ -5039,9 +5053,9 @@ function parseParagraph(records, start, end, ctx) {
5039
5053
  const applied = [];
5040
5054
  for (const r of ranges) {
5041
5055
  const ctrl = ctrls[r.ctrlIdx];
5042
- if (!_optionalChain([ctrl, 'optionalAccess', _102 => _102.href]) || r.end <= r.start) continue;
5056
+ if (!_optionalChain([ctrl, 'optionalAccess', _104 => _104.href]) || r.end <= r.start) continue;
5043
5057
  if (applied.some(([s, e]) => r.start < e && r.end > s)) continue;
5044
- const href = _chunk6XAAYAWLcjs.sanitizeHref.call(void 0, ctrl.href);
5058
+ const href = _chunk37VKMUSTcjs.sanitizeHref.call(void 0, ctrl.href);
5045
5059
  if (!href) continue;
5046
5060
  const anchor = text.slice(r.start, r.end);
5047
5061
  if (!anchor.trim()) continue;
@@ -5059,7 +5073,7 @@ function parseParagraph(records, start, end, ctx) {
5059
5073
  }
5060
5074
  if (ps.headType === 1 || ps.headType === 2) {
5061
5075
  const nid = ps.numberingId || (ps.headType === 1 ? ctx.doc.outlineNumberingId : 0);
5062
- const numbering = nid >= 1 ? _optionalChain([ctx, 'access', _103 => _103.docInfo, 'optionalAccess', _104 => _104.numberings, 'access', _105 => _105[nid - 1]]) : void 0;
5076
+ const numbering = nid >= 1 ? _optionalChain([ctx, 'access', _105 => _105.docInfo, 'optionalAccess', _106 => _106.numberings, 'access', _107 => _107[nid - 1]]) : void 0;
5063
5077
  if (numbering) {
5064
5078
  const counters = ctx.doc.numbering.advance(nid, ps.paraLevel);
5065
5079
  const fmt = numbering.levelFormats[Math.min(ps.paraLevel, 6)];
@@ -5069,7 +5083,7 @@ function parseParagraph(records, start, end, ctx) {
5069
5083
  }
5070
5084
  }
5071
5085
  } else if (ps.headType === 3) {
5072
- const bullet = ps.numberingId >= 1 ? _optionalChain([ctx, 'access', _106 => _106.docInfo, 'optionalAccess', _107 => _107.bullets, 'access', _108 => _108[ps.numberingId - 1]]) : void 0;
5086
+ const bullet = ps.numberingId >= 1 ? _optionalChain([ctx, 'access', _108 => _108.docInfo, 'optionalAccess', _109 => _109.bullets, 'access', _110 => _110[ps.numberingId - 1]]) : void 0;
5073
5087
  if (bullet && bullet.char !== "\uFFFF") headMarker = bullet.char;
5074
5088
  }
5075
5089
  }
@@ -5274,8 +5288,8 @@ function parseTableControl(ctrl, records, ctx) {
5274
5288
  let tableIdx = -1;
5275
5289
  for (let i2 = childStart; i2 < childEnd; i2++) {
5276
5290
  if (records[i2].tagId === TAG_TABLE && records[i2].data.length >= 8) {
5277
- rows = Math.min(records[i2].data.readUInt16LE(4), _chunk6XAAYAWLcjs.MAX_ROWS);
5278
- cols = Math.min(records[i2].data.readUInt16LE(6), _chunk6XAAYAWLcjs.MAX_COLS);
5291
+ rows = Math.min(records[i2].data.readUInt16LE(4), _chunk37VKMUSTcjs.MAX_ROWS);
5292
+ cols = Math.min(records[i2].data.readUInt16LE(6), _chunk37VKMUSTcjs.MAX_COLS);
5279
5293
  tableIdx = i2;
5280
5294
  break;
5281
5295
  }
@@ -5315,7 +5329,7 @@ function parseTableControl(ctrl, records, ctx) {
5315
5329
  const cellRows2 = arrangeCells(rows, cols, cells);
5316
5330
  const irCells = cellRows2.map((row) => row.map((c) => {
5317
5331
  const ir = { text: c.text.trim(), colSpan: c.colSpan, rowSpan: c.rowSpan };
5318
- if (_optionalChain([c, 'access', _109 => _109.blocks, 'optionalAccess', _110 => _110.length])) ir.blocks = c.blocks;
5332
+ if (_optionalChain([c, 'access', _111 => _111.blocks, 'optionalAccess', _112 => _112.length])) ir.blocks = c.blocks;
5319
5333
  if (c.isHeader) ir.isHeader = true;
5320
5334
  return ir;
5321
5335
  }));
@@ -5324,7 +5338,7 @@ function parseTableControl(ctrl, records, ctx) {
5324
5338
  return table3;
5325
5339
  }
5326
5340
  const cellRows = arrangeCells(rows, cols, cells);
5327
- const table2 = _chunk6XAAYAWLcjs.buildTable.call(void 0, cellRows);
5341
+ const table2 = _chunk37VKMUSTcjs.buildTable.call(void 0, cellRows, { keepAnchoredEmptyCols: ctx.doc.keepTrailingEmptyCols });
5328
5342
  if (caption && table2.rows > 0) table2.caption = caption;
5329
5343
  return table2.rows > 0 ? table2 : null;
5330
5344
  }
@@ -5341,8 +5355,8 @@ function parseCell(records, lhIdx, end, ctx) {
5341
5355
  rowAddr = rec.data.readUInt16LE(10);
5342
5356
  const cs = rec.data.readUInt16LE(12);
5343
5357
  const rs = rec.data.readUInt16LE(14);
5344
- if (cs > 0) colSpan = Math.min(cs, _chunk6XAAYAWLcjs.MAX_COLS);
5345
- if (rs > 0) rowSpan = Math.min(rs, _chunk6XAAYAWLcjs.MAX_ROWS);
5358
+ if (cs > 0) colSpan = Math.min(cs, _chunk37VKMUSTcjs.MAX_COLS);
5359
+ if (rs > 0) rowSpan = Math.min(rs, _chunk37VKMUSTcjs.MAX_ROWS);
5346
5360
  }
5347
5361
  const blocks = ctx.depth < MAX_NEST_DEPTH ? parseParagraphList(records, lhIdx + 1, end, { ...ctx, depth: ctx.depth + 1 }) : [];
5348
5362
  const parts = [];
@@ -5352,7 +5366,7 @@ function parseCell(records, lhIdx, end, ctx) {
5352
5366
  parts.push(`![image](hwp5bin:${b.text})`);
5353
5367
  hasStructure = true;
5354
5368
  } else if (b.type === "table" && b.table) {
5355
- const flat = _chunk6XAAYAWLcjs.convertTableToText.call(void 0, b.table.cells);
5369
+ const flat = _chunk37VKMUSTcjs.convertTableToText.call(void 0, b.table.cells);
5356
5370
  if (flat) parts.push(flat);
5357
5371
  hasStructure = true;
5358
5372
  } else if (b.text) {
@@ -5449,8 +5463,8 @@ function pictureToImageBlock(data, ctx) {
5449
5463
  if (data.length < 73) return null;
5450
5464
  const binDataId = data.readUInt16LE(71);
5451
5465
  if (binDataId === 0) return null;
5452
- const item = _optionalChain([ctx, 'access', _111 => _111.docInfo, 'optionalAccess', _112 => _112.binData, 'access', _113 => _113[binDataId - 1]]);
5453
- if (_optionalChain([item, 'optionalAccess', _114 => _114.kind]) === "link") {
5466
+ const item = _optionalChain([ctx, 'access', _113 => _113.docInfo, 'optionalAccess', _114 => _114.binData, 'access', _115 => _115[binDataId - 1]]);
5467
+ if (_optionalChain([item, 'optionalAccess', _116 => _116.kind]) === "link") {
5454
5468
  ctx.warnings.push({ page: ctx.sectionNum, message: `\uC678\uBD80 \uC5F0\uACB0 \uC774\uBBF8\uC9C0 (binDataId ${binDataId})`, code: "SKIPPED_IMAGE" });
5455
5469
  return null;
5456
5470
  }
@@ -17518,6 +17532,7 @@ function readHeader(reader) {
17518
17532
  }
17519
17533
 
17520
17534
  // src/hwp3/parser.ts
17535
+ var MAX_DECOMPRESS_SIZE3 = 100 * 1024 * 1024;
17521
17536
  var PARA_SHAPE_SIZE = 187;
17522
17537
  var LINE_INFO_SIZE = 14;
17523
17538
  var INLINE_CHAR_SHAPE_SIZE = 31;
@@ -17553,8 +17568,11 @@ function parseHwp3Document(buffer, _options) {
17553
17568
  const warnings = [];
17554
17569
  if (header.compressed !== 0) {
17555
17570
  try {
17556
- body = _zlib.inflateRawSync.call(void 0, tail);
17571
+ body = _zlib.inflateRawSync.call(void 0, tail, { maxOutputLength: MAX_DECOMPRESS_SIZE3 });
17557
17572
  } catch (err) {
17573
+ if (_optionalChain([err, 'optionalAccess', _117 => _117.code]) === "ERR_BUFFER_TOO_LARGE") {
17574
+ throw new Error(`HWP3 \uC555\uCD95 \uD574\uC81C \uACB0\uACFC\uAC00 \uCD5C\uB300 \uD5C8\uC6A9 \uD06C\uAE30(${MAX_DECOMPRESS_SIZE3 / 1024 / 1024}MB)\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4`);
17575
+ }
17558
17576
  const msg2 = err instanceof Error ? err.message : String(err);
17559
17577
  throw new Error(`HWP3 \uC555\uCD95 \uD574\uC81C \uC2E4\uD328: ${msg2}`);
17560
17578
  }
@@ -17751,7 +17769,7 @@ function isDistributionSentinel(markdown) {
17751
17769
 
17752
17770
 
17753
17771
  var MAX_SHEETS = 100;
17754
- var MAX_DECOMPRESS_SIZE3 = 100 * 1024 * 1024;
17772
+ var MAX_DECOMPRESS_SIZE4 = 100 * 1024 * 1024;
17755
17773
  var MAX_ROWS2 = 1e4;
17756
17774
  var MAX_COLS2 = 200;
17757
17775
  function cleanNumericValue(raw) {
@@ -17781,26 +17799,97 @@ function getElements(parent, tagName) {
17781
17799
  const result = [];
17782
17800
  for (let i = 0; i < nodes.length; i++) result.push(nodes[i]);
17783
17801
  if (result.length > 0) return result;
17784
- const nsNodes = _optionalChain([parent, 'access', _115 => _115.getElementsByTagNameNS, 'optionalCall', _116 => _116("*", tagName)]);
17802
+ const nsNodes = _optionalChain([parent, 'access', _118 => _118.getElementsByTagNameNS, 'optionalCall', _119 => _119("*", tagName)]);
17785
17803
  if (nsNodes) for (let i = 0; i < nsNodes.length; i++) result.push(nsNodes[i]);
17786
17804
  return result;
17787
17805
  }
17788
17806
  function getTextContent(el) {
17789
- return _nullishCoalesce(_optionalChain([el, 'access', _117 => _117.textContent, 'optionalAccess', _118 => _118.trim, 'call', _119 => _119()]), () => ( ""));
17807
+ return _nullishCoalesce(_optionalChain([el, 'access', _120 => _120.textContent, 'optionalAccess', _121 => _121.trim, 'call', _122 => _122()]), () => ( ""));
17790
17808
  }
17791
17809
  function parseXml(text) {
17792
- return new (0, _xmldom.DOMParser)().parseFromString(_chunk6XAAYAWLcjs.stripDtd.call(void 0, text), "text/xml");
17810
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunk37VKMUSTcjs.stripDtd.call(void 0, text), "text/xml");
17811
+ }
17812
+ function collectRichText(root) {
17813
+ let out = "";
17814
+ const walk = (node) => {
17815
+ const children = node.childNodes;
17816
+ for (let i = 0; i < children.length; i++) {
17817
+ if (children[i].nodeType !== 1) continue;
17818
+ const el = children[i];
17819
+ const local = el.localName || _optionalChain([el, 'access', _123 => _123.tagName, 'optionalAccess', _124 => _124.replace, 'call', _125 => _125(/^[^:]+:/, "")]) || "";
17820
+ if (local === "rPh") continue;
17821
+ if (local === "t") out += _nullishCoalesce(el.textContent, () => ( ""));
17822
+ else walk(el);
17823
+ }
17824
+ };
17825
+ walk(root);
17826
+ return out;
17793
17827
  }
17794
17828
  function parseSharedStrings(xml) {
17795
17829
  const doc = parseXml(xml);
17796
17830
  const strings = [];
17797
17831
  const siList = getElements(doc.documentElement, "si");
17798
17832
  for (const si of siList) {
17799
- const tElements = getElements(si, "t");
17800
- strings.push(tElements.map((t) => _nullishCoalesce(t.textContent, () => ( ""))).join(""));
17833
+ strings.push(collectRichText(si));
17801
17834
  }
17802
17835
  return strings;
17803
17836
  }
17837
+ var BUILTIN_DATE_FMT = /* @__PURE__ */ new Map([
17838
+ [14, "date"],
17839
+ [15, "date"],
17840
+ [16, "date"],
17841
+ [17, "date"],
17842
+ [18, "datetime"],
17843
+ [19, "datetime"],
17844
+ [20, "datetime"],
17845
+ [21, "datetime"],
17846
+ [22, "datetime"],
17847
+ [45, "datetime"],
17848
+ [46, "datetime"],
17849
+ [47, "datetime"]
17850
+ ]);
17851
+ function classifyDateFormat(code) {
17852
+ const stripped = code.replace(/"[^"]*"/g, "").replace(/\[[^\]]*\]/g, "").replace(/\\./g, "");
17853
+ if (!/[ymdh]/i.test(stripped)) return null;
17854
+ return /[hs]/i.test(stripped) ? "datetime" : "date";
17855
+ }
17856
+ function dateKindOfFmt(fmtId, customFormats) {
17857
+ const builtin = BUILTIN_DATE_FMT.get(fmtId);
17858
+ if (builtin) return builtin;
17859
+ const code = customFormats.get(fmtId);
17860
+ return code !== void 0 ? classifyDateFormat(code) : null;
17861
+ }
17862
+ function dateSerialToIso(serial, date1904, kind) {
17863
+ if (!isFinite(serial) || serial < 0) return null;
17864
+ let days = serial;
17865
+ if (date1904) days += 1462;
17866
+ else if (days < 60) days += 1;
17867
+ const ms = Math.round((days - 25569) * 864e5);
17868
+ const d = new Date(ms);
17869
+ if (isNaN(d.getTime()) || d.getUTCFullYear() > 9999) return null;
17870
+ const iso = d.toISOString();
17871
+ return kind === "datetime" ? iso.slice(0, 19) : iso.slice(0, 10);
17872
+ }
17873
+ function parseStyleDateXfs(xml) {
17874
+ const doc = parseXml(xml);
17875
+ const customFormats = /* @__PURE__ */ new Map();
17876
+ for (const el of getElements(doc.documentElement, "numFmt")) {
17877
+ const id = parseInt(_nullishCoalesce(el.getAttribute("numFmtId"), () => ( "")), 10);
17878
+ if (isNaN(id)) continue;
17879
+ customFormats.set(id, _nullishCoalesce(el.getAttribute("formatCode"), () => ( "")));
17880
+ }
17881
+ const dateXfs = /* @__PURE__ */ new Map();
17882
+ const cellXfsEls = getElements(doc.documentElement, "cellXfs");
17883
+ if (cellXfsEls.length === 0) return dateXfs;
17884
+ const xfs = getElements(cellXfsEls[0], "xf");
17885
+ for (let i = 0; i < xfs.length; i++) {
17886
+ const fmtId = parseInt(_nullishCoalesce(xfs[i].getAttribute("numFmtId"), () => ( "")), 10);
17887
+ if (isNaN(fmtId)) continue;
17888
+ const kind = dateKindOfFmt(fmtId, customFormats);
17889
+ if (kind) dateXfs.set(i, kind);
17890
+ }
17891
+ return dateXfs;
17892
+ }
17804
17893
  function parseWorkbook(xml) {
17805
17894
  const doc = parseXml(xml);
17806
17895
  const sheets = [];
@@ -17812,7 +17901,9 @@ function parseWorkbook(xml) {
17812
17901
  rId: _nullishCoalesce(el.getAttribute("r:id"), () => ( ""))
17813
17902
  });
17814
17903
  }
17815
- return sheets;
17904
+ const prEls = getElements(doc.documentElement, "workbookPr");
17905
+ const d1904 = prEls.length > 0 ? prEls[0].getAttribute("date1904") : null;
17906
+ return { sheets, date1904: d1904 === "1" || d1904 === "true" };
17816
17907
  }
17817
17908
  function parseRels(xml) {
17818
17909
  const doc = parseXml(xml);
@@ -17825,21 +17916,25 @@ function parseRels(xml) {
17825
17916
  }
17826
17917
  return map;
17827
17918
  }
17828
- function parseWorksheet(xml, sharedStrings) {
17919
+ function parseWorksheet(xml, sharedStrings, dateXfs, date1904) {
17829
17920
  const doc = parseXml(xml);
17830
17921
  const grid = [];
17831
17922
  let maxRow = 0;
17832
17923
  let maxCol = 0;
17833
17924
  const rows = getElements(doc.documentElement, "row");
17925
+ let prevRow = -1;
17834
17926
  for (const rowEl of rows) {
17835
- const rowNum = parseInt(_nullishCoalesce(rowEl.getAttribute("r"), () => ( "0")), 10) - 1;
17927
+ const rAttr = rowEl.getAttribute("r");
17928
+ const rowNum = rAttr !== null ? parseInt(rAttr, 10) - 1 : prevRow + 1;
17836
17929
  if (rowNum < 0 || rowNum >= MAX_ROWS2) continue;
17930
+ if (Number.isFinite(rowNum)) prevRow = rowNum;
17837
17931
  const cells = getElements(rowEl, "c");
17932
+ let prevCol = -1;
17838
17933
  for (const cellEl of cells) {
17839
17934
  const ref = cellEl.getAttribute("r");
17840
- if (!ref) continue;
17841
- const pos = parseCellRef(ref);
17842
- if (!pos || pos.col >= MAX_COLS2) continue;
17935
+ const pos = ref !== null ? parseCellRef(ref) : { col: prevCol + 1, row: rowNum };
17936
+ if (!pos || !Number.isFinite(pos.row) || pos.row < 0 || pos.row >= MAX_ROWS2 || pos.col >= MAX_COLS2) continue;
17937
+ prevCol = pos.col;
17843
17938
  const type = cellEl.getAttribute("t");
17844
17939
  const vElements = getElements(cellEl, "v");
17845
17940
  const fElements = getElements(cellEl, "f");
@@ -17853,12 +17948,19 @@ function parseWorksheet(xml, sharedStrings) {
17853
17948
  value = raw === "1" ? "TRUE" : "FALSE";
17854
17949
  } else {
17855
17950
  value = cleanNumericValue(raw);
17951
+ if (type === null || type === "n") {
17952
+ const sAttr = cellEl.getAttribute("s");
17953
+ const kind = sAttr !== null ? dateXfs.get(parseInt(sAttr, 10)) : void 0;
17954
+ if (kind) {
17955
+ const iso = dateSerialToIso(parseFloat(raw), date1904, kind);
17956
+ if (iso) value = iso;
17957
+ }
17958
+ }
17856
17959
  }
17857
17960
  } else if (type === "inlineStr") {
17858
17961
  const isEl = getElements(cellEl, "is");
17859
17962
  if (isEl.length > 0) {
17860
- const tElements = getElements(isEl[0], "t");
17861
- value = tElements.map((t) => _nullishCoalesce(t.textContent, () => ( ""))).join("");
17963
+ value = collectRichText(isEl[0]);
17862
17964
  }
17863
17965
  }
17864
17966
  if (!value && fElements.length > 0) {
@@ -17877,7 +17979,14 @@ function parseWorksheet(xml, sharedStrings) {
17877
17979
  const ref = el.getAttribute("ref");
17878
17980
  if (!ref) continue;
17879
17981
  const m = parseMergeRef(ref);
17880
- if (m) merges.push(m);
17982
+ if (m) {
17983
+ merges.push({
17984
+ startCol: Math.min(m.startCol, MAX_COLS2 - 1),
17985
+ startRow: Math.min(m.startRow, MAX_ROWS2 - 1),
17986
+ endCol: Math.min(m.endCol, MAX_COLS2 - 1),
17987
+ endRow: Math.min(m.endRow, MAX_ROWS2 - 1)
17988
+ });
17989
+ }
17881
17990
  }
17882
17991
  return { grid, merges, maxRow, maxCol };
17883
17992
  }
@@ -17926,14 +18035,14 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
17926
18035
  const merge = mergeMap.get(key);
17927
18036
  row.push({
17928
18037
  text,
17929
- colSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _120 => _120.colSpan]), () => ( 1)),
17930
- rowSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _121 => _121.rowSpan]), () => ( 1))
18038
+ colSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _126 => _126.colSpan]), () => ( 1)),
18039
+ rowSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _127 => _127.rowSpan]), () => ( 1))
17931
18040
  });
17932
18041
  }
17933
18042
  cellRows.push(row);
17934
18043
  }
17935
18044
  if (cellRows.length > 0) {
17936
- const table2 = _chunk6XAAYAWLcjs.buildTable.call(void 0, cellRows);
18045
+ const table2 = _chunk37VKMUSTcjs.buildTable.call(void 0, cellRows);
17937
18046
  if (table2.rows > 0) {
17938
18047
  blocks.push({ type: "table", table: table2, pageNumber: sheetIndex + 1 });
17939
18048
  }
@@ -17941,21 +18050,29 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
17941
18050
  return blocks;
17942
18051
  }
17943
18052
  async function parseXlsxDocument(buffer, options) {
17944
- _chunk6XAAYAWLcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE3);
18053
+ _chunk37VKMUSTcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
17945
18054
  const zip = await _jszip2.default.loadAsync(buffer);
17946
18055
  const warnings = [];
17947
18056
  const workbookFile = zip.file("xl/workbook.xml");
17948
18057
  if (!workbookFile) {
17949
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 XLSX \uD30C\uC77C: xl/workbook.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
18058
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 XLSX \uD30C\uC77C: xl/workbook.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
17950
18059
  }
17951
18060
  let sharedStrings = [];
17952
18061
  const ssFile = zip.file("xl/sharedStrings.xml");
17953
18062
  if (ssFile) {
17954
18063
  sharedStrings = parseSharedStrings(await ssFile.async("text"));
17955
18064
  }
17956
- const sheets = parseWorkbook(await workbookFile.async("text"));
18065
+ const { sheets, date1904 } = parseWorkbook(await workbookFile.async("text"));
17957
18066
  if (sheets.length === 0) {
17958
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("XLSX \uD30C\uC77C\uC5D0 \uC2DC\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
18067
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("XLSX \uD30C\uC77C\uC5D0 \uC2DC\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
18068
+ }
18069
+ let dateXfs = /* @__PURE__ */ new Map();
18070
+ const stylesFile = zip.file("xl/styles.xml");
18071
+ if (stylesFile) {
18072
+ try {
18073
+ dateXfs = parseStyleDateXfs(await stylesFile.async("text"));
18074
+ } catch (e28) {
18075
+ }
17959
18076
  }
17960
18077
  let relsMap = /* @__PURE__ */ new Map();
17961
18078
  const relsFile = zip.file("xl/_rels/workbook.xml.rels");
@@ -17963,7 +18080,7 @@ async function parseXlsxDocument(buffer, options) {
17963
18080
  relsMap = parseRels(await relsFile.async("text"));
17964
18081
  }
17965
18082
  let pageFilter = null;
17966
- if (_optionalChain([options, 'optionalAccess', _122 => _122.pages])) {
18083
+ if (_optionalChain([options, 'optionalAccess', _128 => _128.pages])) {
17967
18084
  const { parsePageRange: parsePageRange2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./page-range-P7SDW6LR.cjs")));
17968
18085
  pageFilter = parsePageRange2(options.pages, sheets.length);
17969
18086
  }
@@ -17972,7 +18089,7 @@ async function parseXlsxDocument(buffer, options) {
17972
18089
  for (let i = 0; i < processedSheets; i++) {
17973
18090
  if (pageFilter && !pageFilter.has(i + 1)) continue;
17974
18091
  const sheet = sheets[i];
17975
- _optionalChain([options, 'optionalAccess', _123 => _123.onProgress, 'optionalCall', _124 => _124(i + 1, processedSheets)]);
18092
+ _optionalChain([options, 'optionalAccess', _129 => _129.onProgress, 'optionalCall', _130 => _130(i + 1, processedSheets)]);
17976
18093
  let sheetPath = relsMap.get(sheet.rId);
17977
18094
  if (sheetPath) {
17978
18095
  if (!sheetPath.startsWith("xl/") && !sheetPath.startsWith("/")) {
@@ -17994,7 +18111,7 @@ async function parseXlsxDocument(buffer, options) {
17994
18111
  }
17995
18112
  try {
17996
18113
  const sheetXml = await sheetFile.async("text");
17997
- const { grid, merges, maxRow, maxCol } = parseWorksheet(sheetXml, sharedStrings);
18114
+ const { grid, merges, maxRow, maxCol } = parseWorksheet(sheetXml, sharedStrings, dateXfs, date1904);
17998
18115
  const sheetBlocks = sheetToBlocks(sheet.name, grid, merges, maxRow, maxCol, i);
17999
18116
  blocks.push(...sheetBlocks);
18000
18117
  } catch (err) {
@@ -18024,10 +18141,10 @@ async function parseXlsxDocument(buffer, options) {
18024
18141
  if (created) metadata.createdAt = created;
18025
18142
  const modified = getFirst("dcterms:modified");
18026
18143
  if (modified) metadata.modifiedAt = modified;
18027
- } catch (e28) {
18144
+ } catch (e29) {
18028
18145
  }
18029
18146
  }
18030
- const markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, blocks);
18147
+ const markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, blocks);
18031
18148
  return { markdown, blocks, metadata, warnings: warnings.length > 0 ? warnings : void 0 };
18032
18149
  }
18033
18150
 
@@ -18038,7 +18155,10 @@ var OP_CONTINUE = 60;
18038
18155
  var OP_BOUNDSHEET8 = 133;
18039
18156
  var OP_SST = 252;
18040
18157
  var OP_CODEPAGE = 66;
18158
+ var OP_DATE1904 = 34;
18041
18159
  var OP_FILEPASS = 47;
18160
+ var OP_FORMAT = 1054;
18161
+ var OP_XF = 224;
18042
18162
  var OP_NUMBER = 515;
18043
18163
  var OP_RK = 638;
18044
18164
  var OP_MULRK = 189;
@@ -18050,6 +18170,8 @@ var OP_BOOLERR = 517;
18050
18170
  var OP_BLANK = 513;
18051
18171
  var OP_MULBLANK = 190;
18052
18172
  var OP_MERGECELLS = 229;
18173
+ var OP_SHRFMLA = 1212;
18174
+ var OP_ARRAY = 545;
18053
18175
  var DT_GLOBALS = 5;
18054
18176
  var DT_WORKSHEET = 16;
18055
18177
  var MAX_RECORDS2 = 1e6;
@@ -18145,7 +18267,7 @@ function decodeUtf16Le(buf) {
18145
18267
  }
18146
18268
 
18147
18269
  // src/xls/sst.ts
18148
- function parseString(buf, offset, segments) {
18270
+ function parseString(buf, offset, segments, segCursor) {
18149
18271
  if (offset + 3 > buf.length) return null;
18150
18272
  const cch = buf.readUInt16LE(offset);
18151
18273
  let flags = buf.readUInt8(offset + 2);
@@ -18168,7 +18290,15 @@ function parseString(buf, offset, segments) {
18168
18290
  const charBytes = [];
18169
18291
  let charsRead = 0;
18170
18292
  while (charsRead < cch) {
18171
- const nextBoundary = _nullishCoalesce(segments.find((s) => s > off), () => ( buf.length));
18293
+ while (segCursor.idx < segments.length && segments[segCursor.idx] < off) segCursor.idx++;
18294
+ if (segCursor.idx < segments.length && segments[segCursor.idx] === off) {
18295
+ if (off >= buf.length) return null;
18296
+ flags = buf.readUInt8(off);
18297
+ highByte = (flags & 1) !== 0;
18298
+ off += 1;
18299
+ segCursor.idx++;
18300
+ }
18301
+ const nextBoundary = segCursor.idx < segments.length ? segments[segCursor.idx] : buf.length;
18172
18302
  const remainChars = cch - charsRead;
18173
18303
  const bytesPerChar = highByte ? 2 : 1;
18174
18304
  const bytesAvail = nextBoundary - off;
@@ -18179,12 +18309,10 @@ function parseString(buf, offset, segments) {
18179
18309
  charBytes.push(highByte ? slice : padToUtf16(slice));
18180
18310
  off += bytesToRead;
18181
18311
  charsRead += charsInThisRun;
18182
- }
18183
- if (charsRead < cch) {
18184
- if (off >= buf.length) return null;
18185
- flags = buf.readUInt8(off);
18186
- highByte = (flags & 1) !== 0;
18187
- off += 1;
18312
+ } else if (nextBoundary < buf.length) {
18313
+ off = nextBoundary;
18314
+ } else {
18315
+ return null;
18188
18316
  }
18189
18317
  }
18190
18318
  const text = decodeUtf16Le(Buffer.concat(charBytes));
@@ -18209,8 +18337,9 @@ function decodeSST(records) {
18209
18337
  const cstUnique = combined.readUInt32LE(4);
18210
18338
  const strings = [];
18211
18339
  let off = 8;
18340
+ const segCursor = { idx: 0 };
18212
18341
  for (let i = 0; i < cstUnique && off < combined.length; i++) {
18213
- const r = parseString(combined, off, segments);
18342
+ const r = parseString(combined, off, segments, segCursor);
18214
18343
  if (!r) break;
18215
18344
  strings.push(r.text);
18216
18345
  off += r.consumed;
@@ -18285,7 +18414,7 @@ function decodeFormulaStringRecord(data) {
18285
18414
  return decodeUtf16Le(padded);
18286
18415
  }
18287
18416
  }
18288
- function extractSheetCells(records, bofIndex, sst) {
18417
+ function extractSheetCells(records, bofIndex, sst, convertNum) {
18289
18418
  const cells = [];
18290
18419
  const merges = [];
18291
18420
  const bofOffset = records[bofIndex].offset;
@@ -18303,14 +18432,16 @@ function extractSheetCells(records, bofIndex, sst) {
18303
18432
  case OP_NUMBER: {
18304
18433
  const h = readCellHeader(rec.data);
18305
18434
  if (h && rec.data.length >= 14) {
18306
- cells.push({ row: h.row, col: h.col, value: rec.data.readDoubleLE(6) });
18435
+ const n = rec.data.readDoubleLE(6);
18436
+ cells.push({ row: h.row, col: h.col, value: convertNum ? convertNum(n, h.ixfe) : n });
18307
18437
  }
18308
18438
  break;
18309
18439
  }
18310
18440
  case OP_RK: {
18311
18441
  const h = readCellHeader(rec.data);
18312
18442
  if (h && rec.data.length >= 10) {
18313
- cells.push({ row: h.row, col: h.col, value: decodeRk(rec.data.readInt32LE(6)) });
18443
+ const n = decodeRk(rec.data.readInt32LE(6));
18444
+ cells.push({ row: h.row, col: h.col, value: convertNum ? convertNum(n, h.ixfe) : n });
18314
18445
  }
18315
18446
  break;
18316
18447
  }
@@ -18318,7 +18449,7 @@ function extractSheetCells(records, bofIndex, sst) {
18318
18449
  const m = decodeMulRk(rec.data);
18319
18450
  if (m) {
18320
18451
  for (const c of m.cells) {
18321
- cells.push({ row: m.row, col: c.col, value: c.value });
18452
+ cells.push({ row: m.row, col: c.col, value: convertNum ? convertNum(c.value, c.ixfe) : c.value });
18322
18453
  }
18323
18454
  }
18324
18455
  break;
@@ -18343,19 +18474,26 @@ function extractSheetCells(records, bofIndex, sst) {
18343
18474
  if (h && rec.data.length >= 14) {
18344
18475
  const result = decodeFormulaResult(rec.data.subarray(6, 14));
18345
18476
  if (result.kind === "stringRef") {
18346
- const next = records[i + 1];
18477
+ let j = i + 1;
18478
+ while (j < records.length && (records[j].opcode === OP_SHRFMLA || records[j].opcode === OP_ARRAY)) j++;
18479
+ const next = records[j];
18347
18480
  if (next && next.opcode === OP_STRING) {
18348
18481
  cells.push({
18349
18482
  row: h.row,
18350
18483
  col: h.col,
18351
18484
  value: decodeFormulaStringRecord(next.data)
18352
18485
  });
18353
- i++;
18486
+ i = j;
18354
18487
  } else {
18355
18488
  cells.push({ row: h.row, col: h.col, value: "" });
18356
18489
  }
18357
18490
  } else {
18358
- cells.push({ row: h.row, col: h.col, value: result.value });
18491
+ const v = result.value;
18492
+ cells.push({
18493
+ row: h.row,
18494
+ col: h.col,
18495
+ value: convertNum && typeof v === "number" ? convertNum(v, h.ixfe) : v
18496
+ });
18359
18497
  }
18360
18498
  }
18361
18499
  break;
@@ -18405,7 +18543,7 @@ function extractSheetCells(records, bofIndex, sst) {
18405
18543
 
18406
18544
  // src/xls/parser.ts
18407
18545
  var MAX_SHEETS2 = 100;
18408
- var MAX_ROWS3 = 1e5;
18546
+ var MAX_ROWS3 = 65536;
18409
18547
  var MAX_COLS3 = 1e3;
18410
18548
  function decodeBoundSheet(data) {
18411
18549
  if (data.length < 8) return null;
@@ -18428,17 +18566,40 @@ function decodeBoundSheet(data) {
18428
18566
  }
18429
18567
  return { name, lbPlyPos, dt };
18430
18568
  }
18569
+ function decodeFormatRecord(data) {
18570
+ if (data.length < 5) return null;
18571
+ const ifmt = data.readUInt16LE(0);
18572
+ const cch = data.readUInt16LE(2);
18573
+ const flags = data.readUInt8(4);
18574
+ const highByte = (flags & 1) !== 0;
18575
+ const start = 5;
18576
+ let code;
18577
+ if (highByte) {
18578
+ const end = Math.min(start + cch * 2, data.length);
18579
+ code = decodeUtf16Le(data.subarray(start, end));
18580
+ } else {
18581
+ const end = Math.min(start + cch, data.length);
18582
+ const slice = data.subarray(start, end);
18583
+ const padded = Buffer.alloc(slice.length * 2);
18584
+ for (let i = 0; i < slice.length; i++) padded[i * 2] = slice[i];
18585
+ code = decodeUtf16Le(padded);
18586
+ }
18587
+ return { ifmt, code };
18588
+ }
18431
18589
  function processGlobals(records) {
18432
18590
  const sheets = [];
18433
18591
  let codePage = 1200;
18434
18592
  let encrypted = false;
18593
+ let date1904 = false;
18594
+ const customFormats = /* @__PURE__ */ new Map();
18595
+ const xfFmtIds = [];
18435
18596
  const firstBof = records[0];
18436
18597
  if (!firstBof || firstBof.opcode !== OP_BOF) {
18437
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("XLS: \uCCAB \uB808\uCF54\uB4DC\uAC00 BOF\uAC00 \uC544\uB2D8");
18598
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("XLS: \uCCAB \uB808\uCF54\uB4DC\uAC00 BOF\uAC00 \uC544\uB2D8");
18438
18599
  }
18439
18600
  const bof = decodeBof(firstBof.data);
18440
18601
  if (!bof || bof.dt !== DT_GLOBALS) {
18441
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("XLS: Globals \uC11C\uBE0C\uC2A4\uD2B8\uB9BC BOF \uB204\uB77D");
18602
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("XLS: Globals \uC11C\uBE0C\uC2A4\uD2B8\uB9BC BOF \uB204\uB77D");
18442
18603
  }
18443
18604
  let i = 1;
18444
18605
  while (i < records.length) {
@@ -18454,21 +18615,41 @@ function processGlobals(records) {
18454
18615
  codePage = r.data.readUInt16LE(0);
18455
18616
  } else if (r.opcode === OP_FILEPASS) {
18456
18617
  encrypted = true;
18618
+ } else if (r.opcode === OP_DATE1904 && r.data.length >= 2) {
18619
+ date1904 = r.data.readUInt16LE(0) === 1;
18620
+ } else if (r.opcode === OP_FORMAT) {
18621
+ const f = decodeFormatRecord(r.data);
18622
+ if (f) customFormats.set(f.ifmt, f.code);
18623
+ } else if (r.opcode === OP_XF && r.data.length >= 4) {
18624
+ xfFmtIds.push(r.data.readUInt16LE(2));
18457
18625
  }
18458
18626
  i++;
18459
18627
  }
18628
+ const dateXfs = /* @__PURE__ */ new Map();
18629
+ for (let k = 0; k < xfFmtIds.length; k++) {
18630
+ const kind = dateKindOfFmt(xfFmtIds[k], customFormats);
18631
+ if (kind) dateXfs.set(k, kind);
18632
+ }
18460
18633
  const globalsRecords = records.slice(0, i);
18461
18634
  const sst = decodeSST(globalsRecords);
18462
- return { sheets, sst, codePage, encrypted, endIndex: i };
18635
+ return { sheets, sst, codePage, encrypted, dateXfs, date1904, endIndex: i };
18463
18636
  }
18464
18637
  function findSheetBofIndex(records, lbPlyPos) {
18465
18638
  const exact = records.findIndex(
18466
18639
  (r) => r.opcode === OP_BOF && r.offset === lbPlyPos
18467
18640
  );
18468
18641
  if (exact >= 0) return exact;
18469
- const bofIndices = records.map((r, idx) => r.opcode === OP_BOF ? idx : -1).filter((idx) => idx >= 0);
18470
- if (bofIndices.length === 0) return -1;
18471
- return bofIndices.length > 1 ? bofIndices[1] : -1;
18642
+ let best = -1;
18643
+ let bestOffset = Infinity;
18644
+ for (let idx = 1; idx < records.length; idx++) {
18645
+ const r = records[idx];
18646
+ if (r.opcode !== OP_BOF) continue;
18647
+ if (r.offset >= lbPlyPos && r.offset < bestOffset) {
18648
+ best = idx;
18649
+ bestOffset = r.offset;
18650
+ }
18651
+ }
18652
+ return best;
18472
18653
  }
18473
18654
  function cellValueToText(v) {
18474
18655
  if (v === null || v === void 0) return "";
@@ -18546,14 +18727,14 @@ function sheetToBlocks2(sheetName, sheet, sheetIndex) {
18546
18727
  const merge = mergeMap.get(key);
18547
18728
  row.push({
18548
18729
  text: grid[r][c],
18549
- colSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _125 => _125.colSpan]), () => ( 1)),
18550
- rowSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _126 => _126.rowSpan]), () => ( 1))
18730
+ colSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _131 => _131.colSpan]), () => ( 1)),
18731
+ rowSpan: _nullishCoalesce(_optionalChain([merge, 'optionalAccess', _132 => _132.rowSpan]), () => ( 1))
18551
18732
  });
18552
18733
  }
18553
18734
  cellRows.push(row);
18554
18735
  }
18555
18736
  if (cellRows.length > 0) {
18556
- const table2 = _chunk6XAAYAWLcjs.buildTable.call(void 0, cellRows);
18737
+ const table2 = _chunk37VKMUSTcjs.buildTable.call(void 0, cellRows);
18557
18738
  if (table2.rows > 0) {
18558
18739
  blocks.push({ type: "table", table: table2, pageNumber: sheetIndex + 1 });
18559
18740
  }
@@ -18566,21 +18747,21 @@ async function parseXlsDocument(buffer, options) {
18566
18747
  try {
18567
18748
  cfb = parseLenientCfb(buf);
18568
18749
  } catch (e) {
18569
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(
18750
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(
18570
18751
  `XLS: OLE2 \uC2DC\uADF8\uB2C8\uCC98 \uAC80\uC99D \uC2E4\uD328 \u2014 ${e instanceof Error ? e.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`
18571
18752
  );
18572
18753
  }
18573
18754
  const wb = _nullishCoalesce(cfb.findStream("/Workbook"), () => ( cfb.findStream("/Book")));
18574
18755
  if (!wb) {
18575
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("XLS: Workbook \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC74C (BIFF5 \uB610\uB294 \uBE44\uD45C\uC900 \uD30C\uC77C)");
18756
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("XLS: Workbook \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC74C (BIFF5 \uB610\uB294 \uBE44\uD45C\uC900 \uD30C\uC77C)");
18576
18757
  }
18577
18758
  const records = readRecords2(wb);
18578
18759
  if (records.length === 0) {
18579
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("XLS: \uC2DC\uADF8\uB2C8\uCC98 \uB808\uCF54\uB4DC\uAC00 \uC5C6\uC74C (Workbook \uC2A4\uD2B8\uB9BC \uC190\uC0C1)");
18760
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("XLS: \uC2DC\uADF8\uB2C8\uCC98 \uB808\uCF54\uB4DC\uAC00 \uC5C6\uC74C (Workbook \uC2A4\uD2B8\uB9BC \uC190\uC0C1)");
18580
18761
  }
18581
18762
  const firstBof = decodeBof(records[0].data);
18582
18763
  if (firstBof && firstBof.vers !== 1536) {
18583
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(
18764
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(
18584
18765
  `XLS: BIFF8(0x0600)\uB9CC \uC9C0\uC6D0 \u2014 \uBCF8 \uD30C\uC77C\uC740 0x${firstBof.vers.toString(16)}`
18585
18766
  );
18586
18767
  }
@@ -18599,9 +18780,17 @@ async function parseXlsDocument(buffer, options) {
18599
18780
  ]
18600
18781
  };
18601
18782
  }
18783
+ const convertNum = globals.dateXfs.size > 0 ? (n, ixfe) => {
18784
+ const kind = globals.dateXfs.get(ixfe);
18785
+ if (kind) {
18786
+ const iso = dateSerialToIso(n, globals.date1904, kind);
18787
+ if (iso) return iso;
18788
+ }
18789
+ return n;
18790
+ } : void 0;
18602
18791
  const totalSheets = Math.min(globals.sheets.length, MAX_SHEETS2);
18603
18792
  let pageFilter = null;
18604
- if (_optionalChain([options, 'optionalAccess', _127 => _127.pages])) {
18793
+ if (_optionalChain([options, 'optionalAccess', _133 => _133.pages])) {
18605
18794
  const { parsePageRange: parsePageRange2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./page-range-P7SDW6LR.cjs")));
18606
18795
  pageFilter = parsePageRange2(options.pages, totalSheets);
18607
18796
  }
@@ -18610,7 +18799,7 @@ async function parseXlsDocument(buffer, options) {
18610
18799
  if (pageFilter && !pageFilter.has(i + 1)) continue;
18611
18800
  const meta = globals.sheets[i];
18612
18801
  if (meta.dt !== 0) continue;
18613
- _optionalChain([options, 'optionalAccess', _128 => _128.onProgress, 'optionalCall', _129 => _129(i + 1, totalSheets)]);
18802
+ _optionalChain([options, 'optionalAccess', _134 => _134.onProgress, 'optionalCall', _135 => _135(i + 1, totalSheets)]);
18614
18803
  const bofIdx = findSheetBofIndex(records, meta.lbPlyPos);
18615
18804
  if (bofIdx < 0) {
18616
18805
  warnings.push({
@@ -18625,7 +18814,7 @@ async function parseXlsDocument(buffer, options) {
18625
18814
  continue;
18626
18815
  }
18627
18816
  try {
18628
- const { sheet } = extractSheetCells(records, bofIdx, globals.sst);
18817
+ const { sheet } = extractSheetCells(records, bofIdx, globals.sst, convertNum);
18629
18818
  const blocks = sheetToBlocks2(meta.name, sheet, i);
18630
18819
  allBlocks.push(...blocks);
18631
18820
  } catch (e) {
@@ -18640,7 +18829,7 @@ async function parseXlsDocument(buffer, options) {
18640
18829
  pageCount: totalSheets
18641
18830
  };
18642
18831
  return {
18643
- markdown: _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, allBlocks),
18832
+ markdown: _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, allBlocks),
18644
18833
  blocks: allBlocks,
18645
18834
  metadata,
18646
18835
  warnings: warnings.length > 0 ? warnings : void 0
@@ -18653,7 +18842,7 @@ async function parseXlsDocument(buffer, options) {
18653
18842
 
18654
18843
  // src/docx/equation.ts
18655
18844
  function lname(el) {
18656
- return el.localName || _optionalChain([el, 'access', _130 => _130.tagName, 'optionalAccess', _131 => _131.replace, 'call', _132 => _132(/^[^:]+:/, "")]) || "";
18845
+ return el.localName || _optionalChain([el, 'access', _136 => _136.tagName, 'optionalAccess', _137 => _137.replace, 'call', _138 => _138(/^[^:]+:/, "")]) || "";
18657
18846
  }
18658
18847
  function kids(parent, name) {
18659
18848
  const out = [];
@@ -18753,6 +18942,9 @@ var NARY_MAP = {
18753
18942
  "\u2A02": "\\bigotimes",
18754
18943
  "\u2A00": "\\bigodot"
18755
18944
  };
18945
+ function onOffVal(v) {
18946
+ return v !== "0" && v !== "false" && v !== "off";
18947
+ }
18756
18948
  function mapDelim(ch, isLeft) {
18757
18949
  const l = {
18758
18950
  "(": "(",
@@ -18779,10 +18971,23 @@ function mapDelim(ch, isLeft) {
18779
18971
  const map = isLeft ? l : r;
18780
18972
  return _nullishCoalesce(map[ch], () => ( ch));
18781
18973
  }
18974
+ function isBalancedWrap(s) {
18975
+ let depth = 0;
18976
+ for (let i = 0; i < s.length; i++) {
18977
+ const ch = s[i];
18978
+ if (ch === "{" && s[i - 1] !== "\\") depth++;
18979
+ else if (ch === "}" && s[i - 1] !== "\\") {
18980
+ depth--;
18981
+ if (depth === 0) return i === s.length - 1;
18982
+ if (depth < 0) return false;
18983
+ }
18984
+ }
18985
+ return false;
18986
+ }
18782
18987
  function grp(body) {
18783
18988
  const s = body.trim();
18784
18989
  if (s.length === 0) return "{}";
18785
- if (s.startsWith("{") && s.endsWith("}")) return s;
18990
+ if (s.startsWith("{") && s.endsWith("}") && isBalancedWrap(s)) return s;
18786
18991
  return "{" + s + "}";
18787
18992
  }
18788
18993
  function childrenToLatex(parent) {
@@ -18876,8 +19081,8 @@ function nodeToLatex(el) {
18876
19081
  }
18877
19082
  const sh = firstKid(naryPr, "subHide");
18878
19083
  const ph = firstKid(naryPr, "supHide");
18879
- if (sh) subHide = (_nullishCoalesce(sh.getAttribute("m:val"), () => ( sh.getAttribute("val")))) !== "0";
18880
- if (ph) supHide = (_nullishCoalesce(ph.getAttribute("m:val"), () => ( ph.getAttribute("val")))) !== "0";
19084
+ if (sh) subHide = onOffVal(_nullishCoalesce(sh.getAttribute("m:val"), () => ( sh.getAttribute("val"))));
19085
+ if (ph) supHide = onOffVal(_nullishCoalesce(ph.getAttribute("m:val"), () => ( ph.getAttribute("val"))));
18881
19086
  const ll = firstKid(naryPr, "limLoc");
18882
19087
  if (ll) limLoc = _nullishCoalesce(_nullishCoalesce(ll.getAttribute("m:val"), () => ( ll.getAttribute("val"))), () => ( ""));
18883
19088
  }
@@ -19024,9 +19229,9 @@ function isDisplayMath(el) {
19024
19229
  }
19025
19230
 
19026
19231
  // src/docx/parser.ts
19027
- var MAX_DECOMPRESS_SIZE4 = 100 * 1024 * 1024;
19232
+ var MAX_DECOMPRESS_SIZE5 = 100 * 1024 * 1024;
19028
19233
  function matchesLocal(el, localName2) {
19029
- return el.localName === localName2 || (_nullishCoalesce(_optionalChain([el, 'access', _133 => _133.tagName, 'optionalAccess', _134 => _134.endsWith, 'call', _135 => _135(`:${localName2}`)]), () => ( false)));
19234
+ return el.localName === localName2 || (_nullishCoalesce(_optionalChain([el, 'access', _139 => _139.tagName, 'optionalAccess', _140 => _140.endsWith, 'call', _141 => _141(`:${localName2}`)]), () => ( false)));
19030
19235
  }
19031
19236
  function effectiveChildElements(parent) {
19032
19237
  const result = [];
@@ -19042,6 +19247,8 @@ function effectiveChildElements(parent) {
19042
19247
  result.push(...effectiveChildElements(c));
19043
19248
  }
19044
19249
  }
19250
+ } else if (matchesLocal(el, "ins") || matchesLocal(el, "smartTag")) {
19251
+ result.push(...effectiveChildElements(el));
19045
19252
  } else {
19046
19253
  result.push(el);
19047
19254
  }
@@ -19059,7 +19266,7 @@ function findElements(parent, localName2) {
19059
19266
  const child = children[i];
19060
19267
  if (child.nodeType === 1) {
19061
19268
  const el = child;
19062
- if (el.localName === localName2 || _optionalChain([el, 'access', _136 => _136.tagName, 'optionalAccess', _137 => _137.endsWith, 'call', _138 => _138(`:${localName2}`)])) {
19269
+ if (el.localName === localName2 || _optionalChain([el, 'access', _142 => _142.tagName, 'optionalAccess', _143 => _143.endsWith, 'call', _144 => _144(`:${localName2}`)])) {
19063
19270
  result.push(el);
19064
19271
  }
19065
19272
  walk(el);
@@ -19078,7 +19285,7 @@ function getAttr(el, localName2) {
19078
19285
  return null;
19079
19286
  }
19080
19287
  function parseXml2(text) {
19081
- return new (0, _xmldom.DOMParser)().parseFromString(_chunk6XAAYAWLcjs.stripDtd.call(void 0, text), "text/xml");
19288
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunk37VKMUSTcjs.stripDtd.call(void 0, text), "text/xml");
19082
19289
  }
19083
19290
  function parseStyles(xml) {
19084
19291
  const doc = parseXml2(xml);
@@ -19106,6 +19313,21 @@ function parseStyles(xml) {
19106
19313
  }
19107
19314
  styles.set(styleId, { name, basedOn, outlineLevel });
19108
19315
  }
19316
+ for (const [styleId, info] of styles) {
19317
+ if (info.outlineLevel !== void 0) continue;
19318
+ const seen = /* @__PURE__ */ new Set([styleId]);
19319
+ let cur = info.basedOn;
19320
+ while (cur && !seen.has(cur)) {
19321
+ seen.add(cur);
19322
+ const parent = styles.get(cur);
19323
+ if (!parent) break;
19324
+ if (parent.outlineLevel !== void 0) {
19325
+ info.outlineLevel = parent.outlineLevel;
19326
+ break;
19327
+ }
19328
+ cur = parent.basedOn;
19329
+ }
19330
+ }
19109
19331
  return styles;
19110
19332
  }
19111
19333
  function parseNumbering(xml) {
@@ -19180,7 +19402,7 @@ function collectOmmlRoots(p) {
19180
19402
  const child = children[i];
19181
19403
  if (child.nodeType !== 1) continue;
19182
19404
  const el = child;
19183
- const tag = el.localName || _optionalChain([el, 'access', _139 => _139.tagName, 'optionalAccess', _140 => _140.replace, 'call', _141 => _141(/^[^:]+:/, "")]) || "";
19405
+ const tag = el.localName || _optionalChain([el, 'access', _145 => _145.tagName, 'optionalAccess', _146 => _146.replace, 'call', _147 => _147(/^[^:]+:/, "")]) || "";
19184
19406
  if (tag === "oMath" || tag === "oMathPara") {
19185
19407
  out.push(el);
19186
19408
  } else if (tag === "txbxContent" || tag === "Fallback") {
@@ -19193,8 +19415,12 @@ function collectOmmlRoots(p) {
19193
19415
  return out;
19194
19416
  }
19195
19417
  function extractRun(r) {
19196
- const tElements = getChildElements(r, "t");
19197
- const text = tElements.map((t) => _nullishCoalesce(t.textContent, () => ( ""))).join("");
19418
+ let text = "";
19419
+ for (const el of effectiveChildElements(r)) {
19420
+ if (matchesLocal(el, "t")) text += _nullishCoalesce(el.textContent, () => ( ""));
19421
+ else if (matchesLocal(el, "br") || matchesLocal(el, "cr")) text += "\n";
19422
+ else if (matchesLocal(el, "tab")) text += " ";
19423
+ }
19198
19424
  let bold = false;
19199
19425
  let italic = false;
19200
19426
  const rPrEls = getChildElements(r, "rPr");
@@ -19217,7 +19443,7 @@ function fieldUrlFromInstr(instr) {
19217
19443
  function makeLink(text, rawHref) {
19218
19444
  if (!text) return "";
19219
19445
  if (!rawHref) return text;
19220
- const href = _chunk6XAAYAWLcjs.sanitizeHref.call(void 0, rawHref);
19446
+ const href = _chunk37VKMUSTcjs.sanitizeHref.call(void 0, rawHref);
19221
19447
  return href ? `[${text}](${href})` : text;
19222
19448
  }
19223
19449
  function collectInline(p, footnotes, rels) {
@@ -19319,7 +19545,7 @@ function parseParagraph2(p, styles, numbering, footnotes, rels) {
19319
19545
  const { text, bold: hasBold, italic: hasItalic, footnoteText } = collectInline(p, footnotes, rels);
19320
19546
  if (!text) return null;
19321
19547
  const style = styles.get(styleId);
19322
- if (_optionalChain([style, 'optionalAccess', _142 => _142.outlineLevel]) !== void 0 && style.outlineLevel >= 0 && style.outlineLevel <= 5) {
19548
+ if (_optionalChain([style, 'optionalAccess', _148 => _148.outlineLevel]) !== void 0 && style.outlineLevel >= 0 && style.outlineLevel <= 5) {
19323
19549
  return {
19324
19550
  type: "heading",
19325
19551
  text,
@@ -19328,8 +19554,8 @@ function parseParagraph2(p, styles, numbering, footnotes, rels) {
19328
19554
  }
19329
19555
  if (numId && numId !== "0") {
19330
19556
  const numDef = numbering.get(numId);
19331
- const levelInfo = _optionalChain([numDef, 'optionalAccess', _143 => _143.get, 'call', _144 => _144(ilvl)]);
19332
- const listType = _optionalChain([levelInfo, 'optionalAccess', _145 => _145.numFmt]) === "bullet" ? "unordered" : "ordered";
19557
+ const levelInfo = _optionalChain([numDef, 'optionalAccess', _149 => _149.get, 'call', _150 => _150(ilvl)]);
19558
+ const listType = _optionalChain([levelInfo, 'optionalAccess', _151 => _151.numFmt]) === "bullet" ? "unordered" : "ordered";
19333
19559
  return { type: "list", text, listType };
19334
19560
  }
19335
19561
  const block = { type: "paragraph", text };
@@ -19349,7 +19575,7 @@ function collectTextboxParagraphs(node, inTxbx = false, out = [], depth = 0) {
19349
19575
  }
19350
19576
  return out;
19351
19577
  }
19352
- function parseTable(tbl2, styles, numbering, footnotes, rels) {
19578
+ function parseTable(tbl2, styles, numbering, footnotes, rels, keepEmptyCols) {
19353
19579
  const trElements = getChildElements(tbl2, "tr");
19354
19580
  if (trElements.length === 0) return null;
19355
19581
  const rawRows = [];
@@ -19411,7 +19637,7 @@ ${cell2.text}` : cell2.text;
19411
19637
  return { text: cell2.text, colSpan: cell2.colSpan, rowSpan, colAddr: cell2.col, rowAddr: r };
19412
19638
  })
19413
19639
  );
19414
- const table2 = _chunk6XAAYAWLcjs.buildTable.call(void 0, cellRows);
19640
+ const table2 = _chunk37VKMUSTcjs.buildTable.call(void 0, cellRows, { keepAnchoredEmptyCols: keepEmptyCols });
19415
19641
  if (table2.rows === 0 || table2.cols === 0) return null;
19416
19642
  return { type: "table", table: table2 };
19417
19643
  }
@@ -19421,10 +19647,10 @@ function collectCellText(tc2, styles, numbering, footnotes, rels, depth) {
19421
19647
  for (const el of effectiveChildElements(tc2)) {
19422
19648
  if (matchesLocal(el, "p")) {
19423
19649
  const block = parseParagraph2(el, styles, numbering, footnotes, rels);
19424
- if (_optionalChain([block, 'optionalAccess', _146 => _146.text])) parts.push(block.text);
19650
+ if (_optionalChain([block, 'optionalAccess', _152 => _152.text])) parts.push(block.text);
19425
19651
  for (const tp of collectTextboxParagraphs(el)) {
19426
19652
  const tb = parseParagraph2(tp, styles, numbering, footnotes, rels);
19427
- if (_optionalChain([tb, 'optionalAccess', _147 => _147.text])) parts.push(tb.text);
19653
+ if (_optionalChain([tb, 'optionalAccess', _153 => _153.text])) parts.push(tb.text);
19428
19654
  }
19429
19655
  } else if (matchesLocal(el, "tbl")) {
19430
19656
  for (const tr of getChildElements(el, "tr")) {
@@ -19459,7 +19685,7 @@ async function buildImageMap(zip, rels, doc, warnings) {
19459
19685
  try {
19460
19686
  const data = await imgFile.async("uint8array");
19461
19687
  imgIdx++;
19462
- const ext = _nullishCoalesce(_optionalChain([imgPath, 'access', _148 => _148.split, 'call', _149 => _149("."), 'access', _150 => _150.pop, 'call', _151 => _151(), 'optionalAccess', _152 => _152.toLowerCase, 'call', _153 => _153()]), () => ( "png"));
19688
+ const ext = _nullishCoalesce(_optionalChain([imgPath, 'access', _154 => _154.split, 'call', _155 => _155("."), 'access', _156 => _156.pop, 'call', _157 => _157(), 'optionalAccess', _158 => _158.toLowerCase, 'call', _159 => _159()]), () => ( "png"));
19463
19689
  const mimeMap = {
19464
19690
  png: "image/png",
19465
19691
  jpg: "image/jpeg",
@@ -19513,12 +19739,12 @@ function emitParagraphImages(p, imageMap, linked, out) {
19513
19739
  }
19514
19740
  }
19515
19741
  async function parseDocxDocument(buffer, options) {
19516
- _chunk6XAAYAWLcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
19742
+ _chunk37VKMUSTcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE5);
19517
19743
  const zip = await _jszip2.default.loadAsync(buffer);
19518
19744
  const warnings = [];
19519
19745
  const docFile = zip.file("word/document.xml");
19520
19746
  if (!docFile) {
19521
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 DOCX \uD30C\uC77C: word/document.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
19747
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 DOCX \uD30C\uC77C: word/document.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
19522
19748
  }
19523
19749
  let rels = /* @__PURE__ */ new Map();
19524
19750
  const relsFile = zip.file("word/_rels/document.xml.rels");
@@ -19565,7 +19791,7 @@ async function parseDocxDocument(buffer, options) {
19565
19791
  const doc = parseXml2(docXml);
19566
19792
  const body = findElements(doc, "body");
19567
19793
  if (body.length === 0) {
19568
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("DOCX \uBCF8\uBB38(w:body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
19794
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("DOCX \uBCF8\uBB38(w:body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
19569
19795
  }
19570
19796
  const { imageMap, images } = await buildImageMap(zip, rels, doc, warnings);
19571
19797
  const linkedImages = /* @__PURE__ */ new Set();
@@ -19573,7 +19799,7 @@ async function parseDocxDocument(buffer, options) {
19573
19799
  const bodyEl = body[0];
19574
19800
  const topLevel = effectiveChildElements(bodyEl);
19575
19801
  for (const el of topLevel) {
19576
- const localName2 = _nullishCoalesce(el.localName, () => ( _optionalChain([el, 'access', _154 => _154.tagName, 'optionalAccess', _155 => _155.split, 'call', _156 => _156(":"), 'access', _157 => _157.pop, 'call', _158 => _158()])));
19802
+ const localName2 = _nullishCoalesce(el.localName, () => ( _optionalChain([el, 'access', _160 => _160.tagName, 'optionalAccess', _161 => _161.split, 'call', _162 => _162(":"), 'access', _163 => _163.pop, 'call', _164 => _164()])));
19577
19803
  if (localName2 === "p") {
19578
19804
  const block = parseParagraph2(el, styles, numbering, footnotes, rels);
19579
19805
  if (block) blocks.push(block);
@@ -19584,7 +19810,7 @@ async function parseDocxDocument(buffer, options) {
19584
19810
  if (imageMap.size > 0) emitParagraphImages(tp, imageMap, linkedImages, blocks);
19585
19811
  }
19586
19812
  } else if (localName2 === "tbl") {
19587
- const block = parseTable(el, styles, numbering, footnotes, rels);
19813
+ const block = parseTable(el, styles, numbering, footnotes, rels, _optionalChain([options, 'optionalAccess', _165 => _165.keepTrailingEmptyCols]));
19588
19814
  if (block) blocks.push(block);
19589
19815
  }
19590
19816
  }
@@ -19616,7 +19842,7 @@ async function parseDocxDocument(buffer, options) {
19616
19842
  }
19617
19843
  }
19618
19844
  const outline = blocks.filter((b) => b.type === "heading").map((b) => ({ level: _nullishCoalesce(b.level, () => ( 2)), text: _nullishCoalesce(b.text, () => ( "")) }));
19619
- const markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, blocks);
19845
+ const markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, blocks);
19620
19846
  return {
19621
19847
  markdown,
19622
19848
  blocks,
@@ -19639,7 +19865,7 @@ function parseHwpmlDocument(buffer, options) {
19639
19865
  }
19640
19866
  const text = new TextDecoder("utf-8").decode(buffer).replace(/^\uFEFF/, "");
19641
19867
  const normalized = text.replace(/&nbsp;/g, "&#160;");
19642
- const xml = _chunk6XAAYAWLcjs.stripDtd.call(void 0, normalized);
19868
+ const xml = _chunk37VKMUSTcjs.stripDtd.call(void 0, normalized);
19643
19869
  const warnings = [];
19644
19870
  const parser = new (0, _xmldom.DOMParser)({
19645
19871
  onError: (_level, msg2) => {
@@ -19667,7 +19893,7 @@ function parseHwpmlDocument(buffer, options) {
19667
19893
  return { markdown: "", blocks: [], metadata, warnings };
19668
19894
  }
19669
19895
  const blocks = [];
19670
- const pageFilter = _optionalChain([options, 'optionalAccess', _159 => _159.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, countSections(body)) : null;
19896
+ const pageFilter = _optionalChain([options, 'optionalAccess', _166 => _166.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, countSections(body)) : null;
19671
19897
  let sectionIdx = 0;
19672
19898
  const children = body.childNodes;
19673
19899
  for (let i = 0; i < children.length; i++) {
@@ -19676,10 +19902,10 @@ function parseHwpmlDocument(buffer, options) {
19676
19902
  if (localName(el) !== "SECTION") continue;
19677
19903
  sectionIdx++;
19678
19904
  if (pageFilter && !pageFilter.has(sectionIdx)) continue;
19679
- parseSection2(el, blocks, paraShapeMap, sectionIdx, warnings);
19905
+ parseSection2(el, blocks, paraShapeMap, sectionIdx, warnings, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _167 => _167.keepTrailingEmptyCols]), () => ( false)));
19680
19906
  }
19681
19907
  const outline = blocks.filter((b) => b.type === "heading" && b.text).map((b) => ({ level: _nullishCoalesce(b.level, () => ( 1)), text: b.text, pageNumber: b.pageNumber }));
19682
- const markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, blocks);
19908
+ const markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, blocks);
19683
19909
  return {
19684
19910
  markdown,
19685
19911
  blocks,
@@ -19712,10 +19938,10 @@ function buildParaShapeMap(root) {
19712
19938
  }
19713
19939
  return map;
19714
19940
  }
19715
- function parseSection2(section, blocks, paraShapeMap, sectionNum, warnings) {
19716
- walkContent(section, blocks, paraShapeMap, sectionNum, warnings, false);
19941
+ function parseSection2(section, blocks, paraShapeMap, sectionNum, warnings, keep) {
19942
+ walkContent(section, blocks, paraShapeMap, sectionNum, warnings, false, keep);
19717
19943
  }
19718
- function walkContent(node, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, depth = 0) {
19944
+ function walkContent(node, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, keep, depth = 0) {
19719
19945
  if (depth > MAX_XML_DEPTH2) return;
19720
19946
  const children = node.childNodes;
19721
19947
  for (let i = 0; i < children.length; i++) {
@@ -19728,24 +19954,24 @@ function walkContent(node, blocks, paraShapeMap, sectionNum, warnings, inHeaderF
19728
19954
  if (tag === "P") {
19729
19955
  if (!inHeaderFooter) {
19730
19956
  parseParagraph3(el, blocks, paraShapeMap, sectionNum);
19731
- walkTablesInP(el, blocks, paraShapeMap, sectionNum, warnings);
19957
+ walkTablesInP(el, blocks, paraShapeMap, sectionNum, warnings, keep);
19732
19958
  }
19733
19959
  continue;
19734
19960
  }
19735
19961
  if (tag === "TABLE") {
19736
19962
  if (!inHeaderFooter) {
19737
- parseTable2(el, blocks, paraShapeMap, sectionNum, warnings);
19963
+ parseTable2(el, blocks, paraShapeMap, sectionNum, warnings, keep);
19738
19964
  }
19739
19965
  continue;
19740
19966
  }
19741
19967
  if (tag === "PARALIST" || tag === "SECTION" || tag === "COLDEF") {
19742
- walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, depth + 1);
19968
+ walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, keep, depth + 1);
19743
19969
  continue;
19744
19970
  }
19745
- walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, depth + 1);
19971
+ walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, keep, depth + 1);
19746
19972
  }
19747
19973
  }
19748
- function walkTablesInP(node, blocks, paraShapeMap, sectionNum, warnings, depth = 0) {
19974
+ function walkTablesInP(node, blocks, paraShapeMap, sectionNum, warnings, keep, depth = 0) {
19749
19975
  if (depth > MAX_XML_DEPTH2) return;
19750
19976
  const children = node.childNodes;
19751
19977
  for (let i = 0; i < children.length; i++) {
@@ -19753,11 +19979,11 @@ function walkTablesInP(node, blocks, paraShapeMap, sectionNum, warnings, depth =
19753
19979
  if (el.nodeType !== 1) continue;
19754
19980
  const tag = localName(el);
19755
19981
  if (tag === "TABLE") {
19756
- parseTable2(el, blocks, paraShapeMap, sectionNum, warnings);
19982
+ parseTable2(el, blocks, paraShapeMap, sectionNum, warnings, keep);
19757
19983
  continue;
19758
19984
  }
19759
19985
  if (tag === "FOOTNOTE" || tag === "ENDNOTE" || tag === "HEADER" || tag === "FOOTER") continue;
19760
- walkTablesInP(el, blocks, paraShapeMap, sectionNum, warnings, depth + 1);
19986
+ walkTablesInP(el, blocks, paraShapeMap, sectionNum, warnings, keep, depth + 1);
19761
19987
  }
19762
19988
  }
19763
19989
  function parseParagraph3(el, blocks, paraShapeMap, sectionNum) {
@@ -19765,7 +19991,7 @@ function parseParagraph3(el, blocks, paraShapeMap, sectionNum) {
19765
19991
  const shapeInfo = paraShapeMap.get(paraShapeId);
19766
19992
  const text = extractParagraphText(el);
19767
19993
  if (!text) return;
19768
- if (_optionalChain([shapeInfo, 'optionalAccess', _160 => _160.headingLevel]) != null) {
19994
+ if (_optionalChain([shapeInfo, 'optionalAccess', _168 => _168.headingLevel]) != null) {
19769
19995
  blocks.push({ type: "heading", text, level: shapeInfo.headingLevel, pageNumber: sectionNum });
19770
19996
  } else {
19771
19997
  blocks.push({ type: "paragraph", text, pageNumber: sectionNum });
@@ -19793,7 +20019,7 @@ function collectCharText(node, parts, depth = 0) {
19793
20019
  }
19794
20020
  }
19795
20021
  }
19796
- function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings) {
20022
+ function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings, keep) {
19797
20023
  const cells = [];
19798
20024
  const rowCount = parseInt(_nullishCoalesce(el.getAttribute("RowCount"), () => ( "0")), 10);
19799
20025
  const colCount = parseInt(_nullishCoalesce(el.getAttribute("ColCount"), () => ( "0")), 10);
@@ -19837,7 +20063,7 @@ function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings) {
19837
20063
  const cellRows = grid.map(
19838
20064
  (row) => row.map((cell2) => _nullishCoalesce(cell2, () => ( { text: "", colSpan: 1, rowSpan: 1 })))
19839
20065
  );
19840
- const table2 = _chunk6XAAYAWLcjs.buildTable.call(void 0, cellRows);
20066
+ const table2 = _chunk37VKMUSTcjs.buildTable.call(void 0, cellRows, { keepAnchoredEmptyCols: keep });
19841
20067
  const caption = extractShapeCaption(el);
19842
20068
  if (caption.text && caption.before) {
19843
20069
  blocks.push({ type: "paragraph", text: caption.text, pageNumber: sectionNum });
@@ -20073,7 +20299,7 @@ function findMatchingKey(cellLabel, values) {
20073
20299
  bestKey = key;
20074
20300
  }
20075
20301
  } else if (key.startsWith(cellLabel)) {
20076
- if (cellLabel.length >= key.length * 0.6 && cellLabel.length > bestLen) {
20302
+ if (cellLabel.length >= key.length * 0.75 && cellLabel.length > bestLen) {
20077
20303
  bestLen = cellLabel.length;
20078
20304
  bestKey = key;
20079
20305
  }
@@ -20097,7 +20323,7 @@ function fillInCellPatterns(cellText, values, matchedLabels, blockedLabels) {
20097
20323
  (match, prefix, suffix) => {
20098
20324
  const label = prefix + suffix;
20099
20325
  const normalizedLabel = normalizeLabel(label);
20100
- if (_optionalChain([blockedLabels, 'optionalAccess', _161 => _161.has, 'call', _162 => _162(normalizedLabel)])) return match;
20326
+ if (_optionalChain([blockedLabels, 'optionalAccess', _169 => _169.has, 'call', _170 => _170(normalizedLabel)])) return match;
20101
20327
  const matchKey = values.available(normalizedLabel) ? normalizedLabel : values.available(normalizeLabel(prefix)) ? normalizeLabel(prefix) : void 0;
20102
20328
  if (matchKey === void 0) return match;
20103
20329
  const newValue = values.consume(matchKey);
@@ -20113,7 +20339,7 @@ function fillInCellPatterns(cellText, values, matchedLabels, blockedLabels) {
20113
20339
  const matchKey = values.available(normalizedKw) ? normalizedKw : void 0;
20114
20340
  if (matchKey === void 0) return match;
20115
20341
  const val = values.peek(matchKey);
20116
- const isTruthy = ["\u2611", "\u2713", "\u2714", "v", "V", "true", "1", "yes", "o", "O"].includes(val.trim()) || val.trim() === "";
20342
+ const isTruthy = ["\u2611", "\u2713", "\u2714", "v", "V", "true", "1", "yes", "o", "O"].includes(val.trim());
20117
20343
  if (!isTruthy) return match;
20118
20344
  values.consume(matchKey);
20119
20345
  matchedLabels.add(matchKey);
@@ -20135,14 +20361,20 @@ function fillInCellPatterns(cellText, values, matchedLabels, blockedLabels) {
20135
20361
  );
20136
20362
  return matches.length > 0 ? { text, matches } : null;
20137
20363
  }
20138
- var INLINE_LABEL_RE = /([가-힣A-Za-z]{2,10})\s*[::]/g;
20364
+ var INLINE_LABEL_RE = /((?:[가-힣A-Za-z]{1,10} )?)([가-힣A-Za-z]{2,10})\s*[::]/g;
20139
20365
  function scanInlineSegments(text) {
20140
20366
  const labels = [];
20141
20367
  INLINE_LABEL_RE.lastIndex = 0;
20142
20368
  let m;
20143
20369
  while ((m = INLINE_LABEL_RE.exec(text)) !== null) {
20144
20370
  if (text[INLINE_LABEL_RE.lastIndex] === "/") continue;
20145
- labels.push({ label: m[1], start: m.index, end: INLINE_LABEL_RE.lastIndex });
20371
+ labels.push({
20372
+ label: m[2],
20373
+ ext: m[1] ? m[1] + m[2] : void 0,
20374
+ extStart: m[1] ? m.index : void 0,
20375
+ start: m.index + m[1].length,
20376
+ end: INLINE_LABEL_RE.lastIndex
20377
+ });
20146
20378
  }
20147
20379
  const segments = [];
20148
20380
  for (let i = 0; i < labels.length; i++) {
@@ -20160,21 +20392,44 @@ function scanInlineSegments(text) {
20160
20392
  labelStart: cur.start,
20161
20393
  valueStart: vs,
20162
20394
  valueEnd: ve,
20163
- value: text.slice(vs, ve)
20395
+ value: text.slice(vs, ve),
20396
+ ...cur.ext !== void 0 ? { extLabel: cur.ext, extStart: cur.extStart } : {}
20164
20397
  });
20165
20398
  }
20166
20399
  return segments;
20167
20400
  }
20401
+ function matchInlineSegment(seg, values, blockedLabels) {
20402
+ const nlabel = normalizeLabel(seg.label);
20403
+ if (seg.extLabel !== void 0) {
20404
+ const nExt = normalizeLabel(seg.extLabel);
20405
+ if (nExt !== nlabel && !_optionalChain([blockedLabels, 'optionalAccess', _171 => _171.has, 'call', _172 => _172(nExt)]) && values.has(nExt)) {
20406
+ return { key: nExt, label: seg.extLabel, viaExt: true };
20407
+ }
20408
+ }
20409
+ if (_optionalChain([blockedLabels, 'optionalAccess', _173 => _173.has, 'call', _174 => _174(nlabel)])) return void 0;
20410
+ const key = findMatchingKey(nlabel, values);
20411
+ return key !== void 0 ? { key, label: seg.label, viaExt: false } : void 0;
20412
+ }
20413
+ function clampSegmentEnd(text, seg, next, nextViaExt) {
20414
+ let ve = seg.valueEnd;
20415
+ if (nextViaExt && _optionalChain([next, 'optionalAccess', _175 => _175.extStart]) !== void 0 && next.extStart < ve) ve = next.extStart;
20416
+ while (ve > seg.valueStart && /\s/.test(text[ve - 1])) ve--;
20417
+ return ve;
20418
+ }
20168
20419
  function padInsertion(text, pos, value) {
20169
20420
  const lead = pos > 0 && !/\s/.test(text[pos - 1]) ? " " : "";
20170
20421
  const trail = pos < text.length && !/\s/.test(text[pos]) ? " " : "";
20171
20422
  return lead + value + trail;
20172
20423
  }
20173
- function normalizeValues(values) {
20424
+ function normalizeValues(values, warnings) {
20174
20425
  const map = /* @__PURE__ */ new Map();
20175
20426
  for (const [label, raw] of Object.entries(values)) {
20176
20427
  const { value, format } = typeof raw === "object" && !Array.isArray(raw) ? raw : { value: raw, format: void 0 };
20177
- map.set(normalizeLabel(label), Array.isArray(value) ? value.map((v) => formatFillValue(v, format)) : formatFillValue(value, format));
20428
+ const key = normalizeLabel(label);
20429
+ if (map.has(key)) {
20430
+ _optionalChain([warnings, 'optionalAccess', _176 => _176.push, 'call', _177 => _177(`\uC785\uB825 \uB77C\uBCA8 "${label}"\uC774 \uC815\uADDC\uD654 \uD0A4 "${key}"\uC5D0\uC11C \uB2E4\uB978 \uB77C\uBCA8\uACFC \uCDA9\uB3CC \u2014 \uB4A4 \uAC12\uC73C\uB85C \uB36E\uC5B4\uC500`)]);
20431
+ }
20432
+ map.set(key, Array.isArray(value) ? value.map((v) => formatFillValue(v, format)) : formatFillValue(value, format));
20178
20433
  }
20179
20434
  return map;
20180
20435
  }
@@ -20347,8 +20602,8 @@ function extractFromTable(table2) {
20347
20602
  if (table2.cols >= 2) {
20348
20603
  for (let r = 0; r < table2.rows; r++) {
20349
20604
  for (let c = 0; c < table2.cols - 1; c++) {
20350
- const labelCell = _optionalChain([table2, 'access', _163 => _163.cells, 'access', _164 => _164[r], 'optionalAccess', _165 => _165[c]]);
20351
- const valueCell = _optionalChain([table2, 'access', _166 => _166.cells, 'access', _167 => _167[r], 'optionalAccess', _168 => _168[c + 1]]);
20605
+ const labelCell = _optionalChain([table2, 'access', _178 => _178.cells, 'access', _179 => _179[r], 'optionalAccess', _180 => _180[c]]);
20606
+ const valueCell = _optionalChain([table2, 'access', _181 => _181.cells, 'access', _182 => _182[r], 'optionalAccess', _183 => _183[c + 1]]);
20352
20607
  if (!labelCell || !valueCell) continue;
20353
20608
  if (isLabelCell(labelCell.text)) {
20354
20609
  fields.push({
@@ -20363,15 +20618,15 @@ function extractFromTable(table2) {
20363
20618
  }
20364
20619
  if (fields.length === 0 && table2.rows >= 2 && table2.cols >= 2) {
20365
20620
  const headerRow = table2.cells[0];
20366
- const allLabels = headerRow.every((cell2) => {
20367
- const t = cell2.text.trim();
20621
+ const allLabels = _nullishCoalesce(_optionalChain([headerRow, 'optionalAccess', _184 => _184.every, 'call', _185 => _185((cell2) => {
20622
+ const t = _nullishCoalesce(_optionalChain([cell2, 'optionalAccess', _186 => _186.text, 'access', _187 => _187.trim, 'call', _188 => _188()]), () => ( ""));
20368
20623
  return t.length > 0 && t.length <= 20;
20369
- });
20624
+ })]), () => ( false));
20370
20625
  if (allLabels) {
20371
20626
  for (let r = 1; r < table2.rows; r++) {
20372
20627
  for (let c = 0; c < table2.cols; c++) {
20373
- const label = _nullishCoalesce(_optionalChain([headerRow, 'access', _169 => _169[c], 'optionalAccess', _170 => _170.text, 'access', _171 => _171.trim, 'call', _172 => _172()]), () => ( ""));
20374
- const value = _nullishCoalesce(_optionalChain([table2, 'access', _173 => _173.cells, 'access', _174 => _174[r], 'optionalAccess', _175 => _175[c], 'optionalAccess', _176 => _176.text, 'access', _177 => _177.trim, 'call', _178 => _178()]), () => ( ""));
20628
+ const label = _nullishCoalesce(_optionalChain([headerRow, 'access', _189 => _189[c], 'optionalAccess', _190 => _190.text, 'access', _191 => _191.trim, 'call', _192 => _192()]), () => ( ""));
20629
+ const value = _nullishCoalesce(_optionalChain([table2, 'access', _193 => _193.cells, 'access', _194 => _194[r], 'optionalAccess', _195 => _195[c], 'optionalAccess', _196 => _196.text, 'access', _197 => _197.trim, 'call', _198 => _198()]), () => ( ""));
20375
20630
  if (label && value) {
20376
20631
  fields.push({ label, value, row: r, col: c });
20377
20632
  }
@@ -20457,14 +20712,15 @@ function fillFormFields(blocks, values, blockedLabels) {
20457
20712
  const cloned = structuredClone(blocks);
20458
20713
  const filled = [];
20459
20714
  const matchedLabels = /* @__PURE__ */ new Set();
20460
- const normalizedValues = normalizeValues(values);
20715
+ const warnings = [];
20716
+ const normalizedValues = normalizeValues(values, warnings);
20461
20717
  const cursor = new ValueCursor(normalizedValues);
20462
20718
  const allTables = collectIRTables(cloned, 0);
20463
20719
  const patternFilledCells = /* @__PURE__ */ new Set();
20464
20720
  for (const table2 of allTables) {
20465
20721
  for (let r = 0; r < table2.rows; r++) {
20466
20722
  for (let c = 0; c < table2.cols; c++) {
20467
- const cell2 = _optionalChain([table2, 'access', _179 => _179.cells, 'access', _180 => _180[r], 'optionalAccess', _181 => _181[c]]);
20723
+ const cell2 = _optionalChain([table2, 'access', _199 => _199.cells, 'access', _200 => _200[r], 'optionalAccess', _201 => _201[c]]);
20468
20724
  if (!cell2) continue;
20469
20725
  const result = fillInCellPatterns(cell2.text, cursor, matchedLabels, blockedLabels);
20470
20726
  if (result) {
@@ -20486,7 +20742,7 @@ function fillFormFields(blocks, values, blockedLabels) {
20486
20742
  if (newText !== block.text) block.text = newText;
20487
20743
  }
20488
20744
  const unmatched = resolveUnmatched(normalizedValues, matchedLabels, values);
20489
- return { blocks: cloned, filled, unmatched };
20745
+ return { blocks: cloned, filled, unmatched, ...warnings.length > 0 ? { warnings } : {} };
20490
20746
  }
20491
20747
  function collectIRTables(blocks, depth) {
20492
20748
  if (depth > 16) return [];
@@ -20496,7 +20752,7 @@ function collectIRTables(blocks, depth) {
20496
20752
  out.push(block.table);
20497
20753
  for (const row of block.table.cells) {
20498
20754
  for (const cell2 of row) {
20499
- if (_optionalChain([cell2, 'optionalAccess', _182 => _182.blocks, 'optionalAccess', _183 => _183.length])) out.push(...collectIRTables(cell2.blocks, depth + 1));
20755
+ if (_optionalChain([cell2, 'optionalAccess', _202 => _202.blocks, 'optionalAccess', _203 => _203.length])) out.push(...collectIRTables(cell2.blocks, depth + 1));
20500
20756
  }
20501
20757
  }
20502
20758
  }
@@ -20507,7 +20763,7 @@ function coveredPositions(table2) {
20507
20763
  for (let r = 0; r < table2.rows; r++) {
20508
20764
  for (let c = 0; c < table2.cols; c++) {
20509
20765
  if (covered.has(`${r},${c}`)) continue;
20510
- const cell2 = _optionalChain([table2, 'access', _184 => _184.cells, 'access', _185 => _185[r], 'optionalAccess', _186 => _186[c]]);
20766
+ const cell2 = _optionalChain([table2, 'access', _204 => _204.cells, 'access', _205 => _205[r], 'optionalAccess', _206 => _206[c]]);
20511
20767
  if (!cell2) continue;
20512
20768
  for (let dr = 0; dr < cell2.rowSpan; dr++) {
20513
20769
  for (let dc = 0; dc < cell2.colSpan; dc++) {
@@ -20520,13 +20776,31 @@ function coveredPositions(table2) {
20520
20776
  }
20521
20777
  return covered;
20522
20778
  }
20779
+ function isHeaderDataTable(table2, covered) {
20780
+ if (table2.rows < 2) return false;
20781
+ const headerRow = table2.cells[0];
20782
+ if (!_optionalChain([headerRow, 'optionalAccess', _207 => _207.length])) return false;
20783
+ const allLabels = headerRow.every((cell2) => {
20784
+ const t = _nullishCoalesce(_optionalChain([cell2, 'optionalAccess', _208 => _208.text, 'access', _209 => _209.trim, 'call', _210 => _210()]), () => ( ""));
20785
+ return t.length > 0 && t.length <= 20 && isLabelCell(t);
20786
+ });
20787
+ if (!allLabels) return false;
20788
+ for (let c = 0; c < table2.cols; c++) {
20789
+ if (covered.has(`1,${c}`)) continue;
20790
+ const cell2 = _optionalChain([table2, 'access', _211 => _211.cells, 'access', _212 => _212[1], 'optionalAccess', _213 => _213[c]]);
20791
+ if (!cell2) break;
20792
+ return !isLabelCell(cell2.text);
20793
+ }
20794
+ return true;
20795
+ }
20523
20796
  function fillTable(table2, values, filled, matchedLabels, patternFilledCells, blockedLabels) {
20524
20797
  if (table2.cols < 2) return;
20525
20798
  const covered = coveredPositions(table2);
20526
- for (let r = 0; r < table2.rows; r++) {
20799
+ const skipHeaderRow = isHeaderDataTable(table2, covered);
20800
+ for (let r = skipHeaderRow ? 1 : 0; r < table2.rows; r++) {
20527
20801
  for (let c = 0; c < table2.cols; c++) {
20528
20802
  if (covered.has(`${r},${c}`)) continue;
20529
- const labelCell = table2.cells[r][c];
20803
+ const labelCell = _optionalChain([table2, 'access', _214 => _214.cells, 'access', _215 => _215[r], 'optionalAccess', _216 => _216[c]]);
20530
20804
  if (!labelCell) continue;
20531
20805
  if (!isLabelCell(labelCell.text)) continue;
20532
20806
  let vc = c + labelCell.colSpan;
@@ -20537,12 +20811,12 @@ function fillTable(table2, values, filled, matchedLabels, patternFilledCells, bl
20537
20811
  if (isKeywordLabel(valueCell.text)) continue;
20538
20812
  const normalizedCellLabel = normalizeLabel(labelCell.text);
20539
20813
  if (!normalizedCellLabel) continue;
20540
- if (_optionalChain([blockedLabels, 'optionalAccess', _187 => _187.has, 'call', _188 => _188(normalizedCellLabel)])) continue;
20814
+ if (_optionalChain([blockedLabels, 'optionalAccess', _217 => _217.has, 'call', _218 => _218(normalizedCellLabel)])) continue;
20541
20815
  const matchKey = findMatchingKey(normalizedCellLabel, values);
20542
20816
  if (matchKey === void 0) continue;
20543
20817
  const newValue = values.consume(matchKey);
20544
20818
  if (newValue === void 0) continue;
20545
- if (_optionalChain([patternFilledCells, 'optionalAccess', _189 => _189.has, 'call', _190 => _190(valueCell)])) {
20819
+ if (_optionalChain([patternFilledCells, 'optionalAccess', _219 => _219.has, 'call', _220 => _220(valueCell)])) {
20546
20820
  valueCell.text = newValue + " " + valueCell.text;
20547
20821
  } else {
20548
20822
  valueCell.text = newValue;
@@ -20559,25 +20833,29 @@ function fillTable(table2, values, filled, matchedLabels, patternFilledCells, bl
20559
20833
  }
20560
20834
  if (table2.rows >= 2 && table2.cols >= 2) {
20561
20835
  const headerRow = table2.cells[0];
20562
- const allLabels = headerRow.every((cell2) => {
20563
- const t = cell2.text.trim();
20836
+ const allLabels = _nullishCoalesce(_optionalChain([headerRow, 'optionalAccess', _221 => _221.every, 'call', _222 => _222((cell2) => {
20837
+ const t = _nullishCoalesce(_optionalChain([cell2, 'optionalAccess', _223 => _223.text, 'access', _224 => _224.trim, 'call', _225 => _225()]), () => ( ""));
20564
20838
  return t.length > 0 && t.length <= 20 && isLabelCell(t);
20565
- });
20839
+ })]), () => ( false));
20566
20840
  if (!allLabels) return;
20567
20841
  for (let r = 1; r < table2.rows; r++) {
20568
20842
  for (let c = 0; c < table2.cols; c++) {
20569
20843
  if (covered.has(`${r},${c}`)) continue;
20570
20844
  const headerCell = headerRow[c];
20571
- const valueCell = _optionalChain([table2, 'access', _191 => _191.cells, 'access', _192 => _192[r], 'optionalAccess', _193 => _193[c]]);
20845
+ const valueCell = _optionalChain([table2, 'access', _226 => _226.cells, 'access', _227 => _227[r], 'optionalAccess', _228 => _228[c]]);
20572
20846
  if (!headerCell || !valueCell) continue;
20573
20847
  const headerLabel = normalizeLabel(headerCell.text);
20574
- if (_optionalChain([blockedLabels, 'optionalAccess', _194 => _194.has, 'call', _195 => _195(headerLabel)])) continue;
20848
+ if (_optionalChain([blockedLabels, 'optionalAccess', _229 => _229.has, 'call', _230 => _230(headerLabel)])) continue;
20575
20849
  const matchKey = findMatchingKey(headerLabel, values);
20576
20850
  if (matchKey === void 0) continue;
20577
20851
  if (!values.isArray(matchKey) && matchedLabels.has(matchKey)) continue;
20578
20852
  const newValue = values.consume(matchKey);
20579
20853
  if (newValue === void 0) continue;
20580
- valueCell.text = newValue;
20854
+ if (_optionalChain([patternFilledCells, 'optionalAccess', _231 => _231.has, 'call', _232 => _232(valueCell)])) {
20855
+ valueCell.text = newValue + " " + valueCell.text;
20856
+ } else {
20857
+ valueCell.text = newValue;
20858
+ }
20581
20859
  matchedLabels.add(matchKey);
20582
20860
  filled.push({
20583
20861
  label: headerCell.text.trim(),
@@ -20593,20 +20871,22 @@ function fillTable(table2, values, filled, matchedLabels, patternFilledCells, bl
20593
20871
  function fillInlineFields(text, values, filled, matchedLabels, blockedLabels) {
20594
20872
  const segments = scanInlineSegments(text);
20595
20873
  if (segments.length === 0) return text;
20874
+ const matches = segments.map((seg) => matchInlineSegment(seg, values, blockedLabels));
20596
20875
  let out = "";
20597
20876
  let pos = 0;
20598
- for (const seg of segments) {
20599
- const nlabel = normalizeLabel(seg.label);
20600
- if (_optionalChain([blockedLabels, 'optionalAccess', _196 => _196.has, 'call', _197 => _197(nlabel)])) continue;
20601
- const matchKey = findMatchingKey(nlabel, values);
20602
- if (matchKey === void 0) continue;
20877
+ for (let i = 0; i < segments.length; i++) {
20878
+ const seg = segments[i];
20879
+ const matched = matches[i];
20880
+ if (matched === void 0) continue;
20881
+ const matchKey = matched.key;
20603
20882
  const newValue = values.consume(matchKey);
20604
20883
  if (newValue === void 0) continue;
20605
20884
  matchedLabels.add(matchKey);
20606
- filled.push({ label: seg.label.trim(), value: newValue, row: -1, col: -1, key: matchKey });
20885
+ filled.push({ label: matched.label.trim(), value: newValue, row: -1, col: -1, key: matchKey });
20886
+ const ve = clampSegmentEnd(text, seg, segments[i + 1], _nullishCoalesce(_optionalChain([matches, 'access', _233 => _233[i + 1], 'optionalAccess', _234 => _234.viaExt]), () => ( false)));
20607
20887
  out += text.slice(pos, seg.valueStart);
20608
- out += seg.valueStart === seg.valueEnd ? padInsertion(text, seg.valueStart, newValue) : newValue;
20609
- pos = seg.valueEnd;
20888
+ out += seg.valueStart === ve ? padInsertion(text, seg.valueStart, newValue) : newValue;
20889
+ pos = ve;
20610
20890
  }
20611
20891
  out += text.slice(pos);
20612
20892
  return out;
@@ -20617,7 +20897,7 @@ function fillInlineFields(text, values, filled, matchedLabels, blockedLabels) {
20617
20897
 
20618
20898
  // src/roundtrip/source-map.ts
20619
20899
  function escapeXmlText(text) {
20620
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
20900
+ return text.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
20621
20901
  }
20622
20902
  function decodeXmlEntities(text) {
20623
20903
  return text.replace(/&(lt|gt|amp|quot|apos|#x?[0-9a-fA-F]+);/g, (m, ent) => {
@@ -20636,7 +20916,7 @@ function decodeXmlEntities(text) {
20636
20916
  try {
20637
20917
  const code = ent[1] === "x" || ent[1] === "X" ? parseInt(ent.slice(2), 16) : parseInt(ent.slice(1), 10);
20638
20918
  if (!isNaN(code) && code >= 0 && code <= 1114111) return String.fromCodePoint(code);
20639
- } catch (e29) {
20919
+ } catch (e30) {
20640
20920
  }
20641
20921
  return m;
20642
20922
  });
@@ -21165,19 +21445,19 @@ function parseCentralDirectory(buf) {
21165
21445
  }
21166
21446
  }
21167
21447
  }
21168
- if (eocdOffset < 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP EOCD\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
21448
+ if (eocdOffset < 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP EOCD\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
21169
21449
  const totalEntries = view.getUint16(eocdOffset + 10, true);
21170
21450
  const cdSize = view.getUint32(eocdOffset + 12, true);
21171
21451
  const cdOffset = view.getUint32(eocdOffset + 16, true);
21172
- if (cdOffset === 4294967295 || totalEntries === 65535) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
21452
+ if (cdOffset === 4294967295 || totalEntries === 65535) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
21173
21453
  if (eocdOffset >= 20 && view.getUint32(eocdOffset - 20, true) === ZIP64_EOCD_LOC_SIG) {
21174
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
21454
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
21175
21455
  }
21176
21456
  const decoder = new TextDecoder("utf-8");
21177
21457
  const entries = [];
21178
21458
  let pos = cdOffset;
21179
21459
  for (let i = 0; i < totalEntries; i++) {
21180
- if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
21460
+ if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
21181
21461
  const flags = view.getUint16(pos + 8, true);
21182
21462
  const method = view.getUint16(pos + 10, true);
21183
21463
  const crc = view.getUint32(pos + 16, true);
@@ -21188,7 +21468,7 @@ function parseCentralDirectory(buf) {
21188
21468
  const commentLen = view.getUint16(pos + 32, true);
21189
21469
  const localOffset = view.getUint32(pos + 42, true);
21190
21470
  if (compSize === 4294967295 || uncompSize === 4294967295 || localOffset === 4294967295) {
21191
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
21471
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
21192
21472
  }
21193
21473
  const name = decoder.decode(buf.subarray(pos + 46, pos + 46 + nameLen));
21194
21474
  const cdEnd = pos + 46 + nameLen + extraLen + commentLen;
@@ -21217,11 +21497,11 @@ function patchZipEntries(original, replacements, additions) {
21217
21497
  const { entries, cdOffset, eocdOffset } = parseCentralDirectory(original);
21218
21498
  const view = new DataView(original.buffer, original.byteOffset, original.byteLength);
21219
21499
  for (const name of replacements.keys()) {
21220
- if (!entries.some((e) => e.name === name)) throw new (0, _chunk6XAAYAWLcjs.KordocError)(`ZIP\uC5D0 \uC5C6\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
21500
+ if (!entries.some((e) => e.name === name)) throw new (0, _chunk37VKMUSTcjs.KordocError)(`ZIP\uC5D0 \uC5C6\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
21221
21501
  }
21222
21502
  if (additions) {
21223
21503
  for (const name of additions.keys()) {
21224
- if (entries.some((e) => e.name === name)) throw new (0, _chunk6XAAYAWLcjs.KordocError)(`ZIP\uC5D0 \uC774\uBBF8 \uC788\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
21504
+ if (entries.some((e) => e.name === name)) throw new (0, _chunk37VKMUSTcjs.KordocError)(`ZIP\uC5D0 \uC774\uBBF8 \uC788\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
21225
21505
  }
21226
21506
  }
21227
21507
  const byLocal = [...entries].sort((a, b) => a.localOffset - b.localOffset);
@@ -21240,13 +21520,16 @@ function patchZipEntries(original, replacements, additions) {
21240
21520
  offset += seg.length;
21241
21521
  continue;
21242
21522
  }
21243
- if (view.getUint32(e.localOffset, true) !== LOCAL_SIG) throw new (0, _chunk6XAAYAWLcjs.KordocError)("ZIP \uB85C\uCEEC \uD5E4\uB354 \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
21523
+ if (view.getUint32(e.localOffset, true) !== LOCAL_SIG) throw new (0, _chunk37VKMUSTcjs.KordocError)("ZIP \uB85C\uCEEC \uD5E4\uB354 \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
21244
21524
  const nameLen = view.getUint16(e.localOffset + 26, true);
21245
21525
  const extraLen = view.getUint16(e.localOffset + 28, true);
21246
21526
  const headerLen = 30 + nameLen + extraLen;
21247
21527
  const header = copyBytes(original, e.localOffset, e.localOffset + headerLen);
21248
21528
  const hview = new DataView(header.buffer, header.byteOffset, header.byteLength);
21249
21529
  const method = e.method;
21530
+ if (method !== 0 && method !== 8) {
21531
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 ZIP \uC555\uCD95 \uBC29\uC2DD(method=${method}): ${e.name} \u2014 STORE(0)/DEFLATE(8)\uB9CC \uAD50\uCCB4 \uAC00\uB2A5`);
21532
+ }
21250
21533
  const compData = method === 0 ? newData : new Uint8Array(_zlib.deflateRawSync.call(void 0, newData));
21251
21534
  const crc = crc32(newData);
21252
21535
  const flags = e.flags & ~8;
@@ -21346,9 +21629,10 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
21346
21629
  const zip = await _jszip2.default.loadAsync(hwpxBuffer);
21347
21630
  const sectionPaths = Object.keys(zip.files).filter((name) => /[Ss]ection\d+\.xml$/i.test(name)).sort();
21348
21631
  if (sectionPaths.length === 0) {
21349
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
21632
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
21350
21633
  }
21351
- const normalizedValues = normalizeValues(values);
21634
+ const warnings = [];
21635
+ const normalizedValues = normalizeValues(values, warnings);
21352
21636
  const cursor = new ValueCursor(normalizedValues);
21353
21637
  const matchedLabels = /* @__PURE__ */ new Set();
21354
21638
  const filled = [];
@@ -21410,7 +21694,17 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
21410
21694
  }
21411
21695
  }
21412
21696
  for (const table2 of allTables) {
21413
- for (let rowIdx = 0; rowIdx < table2.rows.length; rowIdx++) {
21697
+ const skipHeaderRow = table2.rows.length >= 2 && (() => {
21698
+ const first = table2.rows[0];
21699
+ const allLabels = first.length > 0 && first.every((cell2) => {
21700
+ const t = cellLabelText(cell2).trim();
21701
+ return t.length > 0 && t.length <= 20 && isLabelCell(t);
21702
+ });
21703
+ if (!allLabels) return false;
21704
+ const d0 = table2.rows[1][0];
21705
+ return d0 === void 0 || !isLabelCell(cellLabelText(d0));
21706
+ })();
21707
+ for (let rowIdx = skipHeaderRow ? 1 : 0; rowIdx < table2.rows.length; rowIdx++) {
21414
21708
  const cells = table2.rows[rowIdx];
21415
21709
  for (let colIdx = 0; colIdx < cells.length - 1; colIdx++) {
21416
21710
  const labelText = cellLabelText(cells[colIdx]);
@@ -21419,7 +21713,7 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
21419
21713
  if (isKeywordLabel(cellLabelText(valueCell))) continue;
21420
21714
  const normalizedCellLabel = normalizeLabel(labelText);
21421
21715
  if (!normalizedCellLabel) continue;
21422
- if (_optionalChain([blockedLabels, 'optionalAccess', _198 => _198.has, 'call', _199 => _199(normalizedCellLabel)])) continue;
21716
+ if (_optionalChain([blockedLabels, 'optionalAccess', _235 => _235.has, 'call', _236 => _236(normalizedCellLabel)])) continue;
21423
21717
  const matchKey = findMatchingKey(normalizedCellLabel, cursor);
21424
21718
  if (matchKey === void 0) continue;
21425
21719
  if (patternApplied.has(valueCell)) {
@@ -21477,13 +21771,34 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
21477
21771
  const dataCells = table2.rows[rowIdx];
21478
21772
  for (let colIdx = 0; colIdx < Math.min(headerCells.length, dataCells.length); colIdx++) {
21479
21773
  const headerLabel = normalizeLabel(cellLabelText(headerCells[colIdx]));
21480
- if (_optionalChain([blockedLabels, 'optionalAccess', _200 => _200.has, 'call', _201 => _201(headerLabel)])) continue;
21774
+ if (_optionalChain([blockedLabels, 'optionalAccess', _237 => _237.has, 'call', _238 => _238(headerLabel)])) continue;
21481
21775
  const matchKey = findMatchingKey(headerLabel, cursor);
21482
21776
  if (matchKey === void 0) continue;
21483
21777
  if (!cursor.isArray(matchKey) && matchedLabels.has(matchKey)) continue;
21778
+ const dataCell = dataCells[colIdx];
21779
+ if (patternApplied.has(dataCell)) {
21780
+ const target = _nullishCoalesce(dataCell.paragraphs.find((p) => p.tRanges.length > 0), () => ( dataCell.paragraphs[0]));
21781
+ if (!target) continue;
21782
+ const l = led(target);
21783
+ if (l.fullText !== void 0) continue;
21784
+ const newValue2 = cursor.consume(matchKey);
21785
+ if (newValue2 === void 0) continue;
21786
+ l.ranges.push({ start: 0, end: 0, replacement: newValue2 + " " });
21787
+ l.filledIdx.push(filled.length);
21788
+ l.matchKeys.push(matchKey);
21789
+ matchedLabels.add(matchKey);
21790
+ filled.push({
21791
+ label: cellLabelText(headerCells[colIdx]).trim(),
21792
+ value: newValue2,
21793
+ row: rowIdx,
21794
+ col: colIdx,
21795
+ key: matchKey
21796
+ });
21797
+ continue;
21798
+ }
21484
21799
  const newValue = cursor.consume(matchKey);
21485
21800
  if (newValue === void 0) continue;
21486
- const paras = dataCells[colIdx].paragraphs;
21801
+ const paras = dataCell.paragraphs;
21487
21802
  if (paras.length === 0) continue;
21488
21803
  const l0 = led(paras[0]);
21489
21804
  l0.fullText = newValue;
@@ -21510,22 +21825,25 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
21510
21825
  }
21511
21826
  for (const para2 of [...scan.bodyParagraphs, ...scan.excludedParagraphs]) {
21512
21827
  const existing = ledger.get(para2);
21513
- if (_optionalChain([existing, 'optionalAccess', _202 => _202.fullText]) !== void 0) continue;
21828
+ if (_optionalChain([existing, 'optionalAccess', _239 => _239.fullText]) !== void 0) continue;
21514
21829
  const text = matchText(para2);
21515
- for (const seg of scanInlineSegments(text)) {
21516
- const nlabel = normalizeLabel(seg.label);
21517
- if (_optionalChain([blockedLabels, 'optionalAccess', _203 => _203.has, 'call', _204 => _204(nlabel)])) continue;
21518
- const matchKey = findMatchingKey(nlabel, cursor);
21519
- if (matchKey === void 0) continue;
21830
+ const segments = scanInlineSegments(text);
21831
+ const matches = segments.map((seg) => matchInlineSegment(seg, cursor, blockedLabels));
21832
+ for (let i = 0; i < segments.length; i++) {
21833
+ const seg = segments[i];
21834
+ const matched = matches[i];
21835
+ if (matched === void 0) continue;
21836
+ const matchKey = matched.key;
21520
21837
  const newValue = cursor.consume(matchKey);
21521
21838
  if (newValue === void 0) continue;
21522
- const replacement = seg.valueStart === seg.valueEnd ? padInsertion(text, seg.valueStart, newValue) : newValue;
21839
+ const ve = clampSegmentEnd(text, seg, segments[i + 1], _nullishCoalesce(_optionalChain([matches, 'access', _240 => _240[i + 1], 'optionalAccess', _241 => _241.viaExt]), () => ( false)));
21840
+ const replacement = seg.valueStart === ve ? padInsertion(text, seg.valueStart, newValue) : newValue;
21523
21841
  const l = led(para2);
21524
- l.ranges.push({ start: seg.valueStart, end: seg.valueEnd, replacement });
21842
+ l.ranges.push({ start: seg.valueStart, end: ve, replacement });
21525
21843
  matchedLabels.add(matchKey);
21526
21844
  l.filledIdx.push(filled.length);
21527
21845
  l.matchKeys.push(matchKey);
21528
- filled.push({ label: seg.label.trim(), value: newValue, row: -1, col: -1, key: matchKey });
21846
+ filled.push({ label: matched.label.trim(), value: newValue, row: -1, col: -1, key: matchKey });
21529
21847
  }
21530
21848
  }
21531
21849
  const splices = [];
@@ -21578,7 +21896,7 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
21578
21896
  }
21579
21897
  }
21580
21898
  for (const k of failedKeys) {
21581
- if (!succeededKeys.has(k)) matchedLabels.delete(k);
21899
+ if (!succeededKeys.has(k) || cursor.isArray(k)) matchedLabels.delete(k);
21582
21900
  }
21583
21901
  const cleanFilled = filled.filter((f) => f !== null);
21584
21902
  const unmatched = resolveUnmatched(normalizedValues, matchedLabels, values);
@@ -21586,7 +21904,8 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
21586
21904
  return {
21587
21905
  buffer: out.buffer.slice(out.byteOffset, out.byteOffset + out.byteLength),
21588
21906
  filled: cleanFilled,
21589
- unmatched
21907
+ unmatched,
21908
+ ...warnings.length > 0 ? { warnings } : {}
21590
21909
  };
21591
21910
  }
21592
21911
 
@@ -21623,16 +21942,16 @@ var PARA_LIST = 7;
21623
21942
  var DEFAULT_TEXT_COLOR = "#000000";
21624
21943
  function resolveTheme(theme) {
21625
21944
  return {
21626
- h1: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _205 => _205.headingColors, 'optionalAccess', _206 => _206[1]]), () => ( DEFAULT_TEXT_COLOR)),
21627
- h2: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _207 => _207.headingColors, 'optionalAccess', _208 => _208[2]]), () => ( DEFAULT_TEXT_COLOR)),
21628
- h3: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _209 => _209.headingColors, 'optionalAccess', _210 => _210[3]]), () => ( DEFAULT_TEXT_COLOR)),
21629
- h4: _nullishCoalesce(_nullishCoalesce(_optionalChain([theme, 'optionalAccess', _211 => _211.headingColors, 'optionalAccess', _212 => _212[4]]), () => ( _optionalChain([theme, 'optionalAccess', _213 => _213.headingColors, 'optionalAccess', _214 => _214[3]]))), () => ( DEFAULT_TEXT_COLOR)),
21630
- body: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _215 => _215.bodyColor]), () => ( DEFAULT_TEXT_COLOR)),
21631
- quote: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _216 => _216.quoteColor]), () => ( DEFAULT_TEXT_COLOR)),
21945
+ h1: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _242 => _242.headingColors, 'optionalAccess', _243 => _243[1]]), () => ( DEFAULT_TEXT_COLOR)),
21946
+ h2: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _244 => _244.headingColors, 'optionalAccess', _245 => _245[2]]), () => ( DEFAULT_TEXT_COLOR)),
21947
+ h3: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _246 => _246.headingColors, 'optionalAccess', _247 => _247[3]]), () => ( DEFAULT_TEXT_COLOR)),
21948
+ h4: _nullishCoalesce(_nullishCoalesce(_optionalChain([theme, 'optionalAccess', _248 => _248.headingColors, 'optionalAccess', _249 => _249[4]]), () => ( _optionalChain([theme, 'optionalAccess', _250 => _250.headingColors, 'optionalAccess', _251 => _251[3]]))), () => ( DEFAULT_TEXT_COLOR)),
21949
+ body: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _252 => _252.bodyColor]), () => ( DEFAULT_TEXT_COLOR)),
21950
+ quote: _nullishCoalesce(_optionalChain([theme, 'optionalAccess', _253 => _253.quoteColor]), () => ( DEFAULT_TEXT_COLOR)),
21632
21951
  /** quoteColor가 명시되었는지 — blockquote charPr 분기에 사용 (baseline 호환) */
21633
- hasQuoteOption: _optionalChain([theme, 'optionalAccess', _217 => _217.quoteColor]) !== void 0,
21634
- tableHeader: _nullishCoalesce(_nullishCoalesce(_optionalChain([theme, 'optionalAccess', _218 => _218.tableHeaderColor]), () => ( _optionalChain([theme, 'optionalAccess', _219 => _219.bodyColor]))), () => ( DEFAULT_TEXT_COLOR)),
21635
- tableHeaderBold: !!_optionalChain([theme, 'optionalAccess', _220 => _220.tableHeaderBold])
21952
+ hasQuoteOption: _optionalChain([theme, 'optionalAccess', _254 => _254.quoteColor]) !== void 0,
21953
+ tableHeader: _nullishCoalesce(_nullishCoalesce(_optionalChain([theme, 'optionalAccess', _255 => _255.tableHeaderColor]), () => ( _optionalChain([theme, 'optionalAccess', _256 => _256.bodyColor]))), () => ( DEFAULT_TEXT_COLOR)),
21954
+ tableHeaderBold: !!_optionalChain([theme, 'optionalAccess', _257 => _257.tableHeaderBold])
21636
21955
  };
21637
21956
  }
21638
21957
  function escapeXml(text) {
@@ -21863,27 +22182,39 @@ function parseMarkdownToBlocks(md2) {
21863
22182
  if (/^<table[\s>]/i.test(line.trimStart())) {
21864
22183
  const htmlLines = [];
21865
22184
  let depth = 0;
21866
- while (i < lines.length) {
21867
- const l = lines[i];
22185
+ let closed = false;
22186
+ let j = i;
22187
+ while (j < lines.length) {
22188
+ const l = lines[j];
21868
22189
  htmlLines.push(l);
21869
22190
  depth += (_nullishCoalesce(l.match(/<table[\s>]/gi), () => ( []))).length;
21870
22191
  depth -= (_nullishCoalesce(l.match(/<\/table>/gi), () => ( []))).length;
21871
- i++;
21872
- if (depth <= 0) break;
22192
+ j++;
22193
+ if (depth <= 0) {
22194
+ closed = true;
22195
+ break;
22196
+ }
22197
+ }
22198
+ if (closed) {
22199
+ blocks.push({ type: "html_table", text: htmlLines.join("\n") });
22200
+ i = j;
22201
+ continue;
21873
22202
  }
21874
- blocks.push({ type: "html_table", text: htmlLines.join("\n") });
21875
- continue;
21876
22203
  }
21877
22204
  if (line.trimStart().startsWith("|")) {
21878
22205
  const tableRows = [];
22206
+ let sepSeen = false;
21879
22207
  while (i < lines.length && lines[i].trimStart().startsWith("|")) {
21880
22208
  const row = lines[i];
21881
- const sepCells = row.trim().replace(/^\|/, "").replace(/\|$/, "").split("|");
21882
- if (sepCells.every((c) => /^\s*:?-+:?\s*$/.test(c))) {
21883
- i++;
21884
- continue;
22209
+ if (tableRows.length === 1 && !sepSeen) {
22210
+ const sepCells = row.trim().replace(/^\|/, "").replace(/\|$/, "").split("|");
22211
+ if (sepCells.every((c) => /^\s*:?-+:?\s*$/.test(c))) {
22212
+ sepSeen = true;
22213
+ i++;
22214
+ continue;
22215
+ }
21885
22216
  }
21886
- const cells = row.split("|").slice(1, -1).map((c) => c.trim());
22217
+ const cells = row.split(/(?<!\\)\|/).slice(1, -1).map((c) => c.trim().replace(/\\\|/g, "|"));
21887
22218
  if (cells.length > 0) tableRows.push(cells);
21888
22219
  i++;
21889
22220
  }
@@ -22035,7 +22366,7 @@ function assertSequentialIds(rows, label, startId) {
22035
22366
  const m = rows[i].match(/\bid="(\d+)"/);
22036
22367
  const got = m ? Number(m[1]) : NaN;
22037
22368
  if (got !== startId + i) {
22038
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(
22369
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(
22039
22370
  `\uB0B4\uBD80 \uC624\uB958: ${label} id \uD30C\uD2F0\uC158 \uB4DC\uB9AC\uD504\uD2B8 \u2014 ${startId + i} \uC704\uCE58\uC5D0 id=${m ? m[1] : "?"} \uBC29\uCD9C. id \uC0C1\uC218(gen-ids)\uC640 \uC2E4\uC81C \uBC29\uCD9C \uC218\uAC00 \uC5B4\uAE0B\uB0AC\uB2E4 (GJ_CHAR_COUNT\uB958 \uCE74\uC6B4\uD2B8\xB7base \uC0B0\uC220 \uD655\uC778)`
22040
22371
  );
22041
22372
  }
@@ -22119,7 +22450,7 @@ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls
22119
22450
  }
22120
22451
  const expectedBase = charVariantBase(richAssets, !!gongmun);
22121
22452
  if (rows.length !== expectedBase) {
22122
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(
22453
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(
22123
22454
  `\uB0B4\uBD80 \uC624\uB958: charPr \uAE30\uBCF8 \uBE14\uB85D \uBC29\uCD9C \uC218(${rows.length}) \u2260 charVariantBase(${expectedBase}) \u2014 gen-header \uBC29\uCD9C \uD589\uACFC gen-ids \uCE74\uC6B4\uD2B8 \uC0C1\uC218\uAC00 \uC5B4\uAE0B\uB0AC\uB2E4`
22124
22455
  );
22125
22456
  }
@@ -22346,7 +22677,7 @@ function buildStyles(gongmun) {
22346
22677
  </hh:styles>`;
22347
22678
  }
22348
22679
  function generateHeaderXml(theme, gongmun, ratioVariants = [], extraBorderFills = [], extraCharPrXmls = [], listIndentVariants = [], extraFonts = []) {
22349
- const bodyFace = _nullishCoalesce(_optionalChain([gongmun, 'optionalAccess', _221 => _221.fonts, 'access', _222 => _222.body]), () => ( (_optionalChain([gongmun, 'optionalAccess', _223 => _223.bodyFont]) === "gothic" ? "\uB9D1\uC740 \uACE0\uB515" : "\uD568\uCD08\uB86C\uBC14\uD0D5")));
22680
+ const bodyFace = _nullishCoalesce(_optionalChain([gongmun, 'optionalAccess', _258 => _258.fonts, 'access', _259 => _259.body]), () => ( (_optionalChain([gongmun, 'optionalAccess', _260 => _260.bodyFont]) === "gothic" ? "\uB9D1\uC740 \uACE0\uB515" : "\uD568\uCD08\uB86C\uBC14\uD0D5")));
22350
22681
  const charPropsXml = buildCharProperties(theme, gongmun, ratioVariants, extraCharPrXmls);
22351
22682
  const paraPropsXml = buildParaProperties(gongmun, gongmun ? listIndentVariants : []);
22352
22683
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
@@ -22475,8 +22806,8 @@ function parseChartFence(text) {
22475
22806
  const spec = chartSpec(type);
22476
22807
  let finalSeries = spec.pie ? [series[0]] : series;
22477
22808
  finalSeries = finalSeries.map((s) => ({ ...s }));
22478
- const ptLen = Math.max(_nullishCoalesce(_optionalChain([cat, 'optionalAccess', _224 => _224.length]), () => ( 0)), ...finalSeries.map((s) => s.values.length));
22479
- const catFinal = Array.from({ length: ptLen }, (_, i) => _nullishCoalesce(_optionalChain([cat, 'optionalAccess', _225 => _225[i]]), () => ( `\uD56D\uBAA9 ${i + 1}`)));
22809
+ const ptLen = Math.max(_nullishCoalesce(_optionalChain([cat, 'optionalAccess', _261 => _261.length]), () => ( 0)), ...finalSeries.map((s) => s.values.length));
22810
+ const catFinal = Array.from({ length: ptLen }, (_, i) => _nullishCoalesce(_optionalChain([cat, 'optionalAccess', _262 => _262[i]]), () => ( `\uD56D\uBAA9 ${i + 1}`)));
22480
22811
  if (!spec.scatter) {
22481
22812
  finalSeries = finalSeries.map((s) => ({ ...s, values: catFinal.map((_, i) => _nullishCoalesce(s.values[i], () => ( 0))) }));
22482
22813
  }
@@ -22518,7 +22849,7 @@ function serSpPr(color, stroke) {
22518
22849
  return stroke ? `<c:spPr><a:ln w="28575" cap="flat" cmpd="sng" algn="ctr">${f}<a:prstDash val="solid"/><a:round/></a:ln></c:spPr>` : `<c:spPr>${f}</c:spPr>`;
22519
22850
  }
22520
22851
  function dPtXml(pointColors, pie) {
22521
- if (!_optionalChain([pointColors, 'optionalAccess', _226 => _226.length])) return "";
22852
+ if (!_optionalChain([pointColors, 'optionalAccess', _263 => _263.length])) return "";
22522
22853
  return pointColors.map((col, i) => {
22523
22854
  const f = chartColorFill(col);
22524
22855
  if (!f) return "";
@@ -22757,8 +23088,8 @@ function buildGaejosikCover(title, gongmun, bodyWidth = GAEJOSIK_BASE_WIDTH) {
22757
23088
  const botRow = cell({ bf: GJ_BF_BAR_DARK, col: 0, row: 2, w: g.botDarkW, h: g.botBarH, paras: barEmpty }) + cell({ bf: GJ_BF_BAR_LIGHT, col: 1, colSpan: 2, row: 2, w: g.botLightW, h: g.botBarH, paras: barEmpty });
22758
23089
  const tbl2 = table([topRow, titleRow, botRow], g.totalW, g.barH + g.titleH + g.botBarH, 3, 1, bodyWidth);
22759
23090
  const host = `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${tbl2}</hp:run></hp:p>`;
22760
- const date = _nullishCoalesce(_optionalChain([gongmun, 'access', _227 => _227.cover, 'optionalAccess', _228 => _228.date]), () => ( formatGaejosikDate(/* @__PURE__ */ new Date())));
22761
- const org = _nullishCoalesce(_optionalChain([gongmun, 'access', _229 => _229.cover, 'optionalAccess', _230 => _230.org]), () => ( ""));
23091
+ const date = _nullishCoalesce(_optionalChain([gongmun, 'access', _264 => _264.cover, 'optionalAccess', _265 => _265.date]), () => ( formatGaejosikDate(/* @__PURE__ */ new Date())));
23092
+ const org = _nullishCoalesce(_optionalChain([gongmun, 'access', _266 => _266.cover, 'optionalAccess', _267 => _267.org]), () => ( ""));
22762
23093
  const sub = (t) => `<hp:p paraPrIDRef="${GJ_PARA_COVER}" styleIDRef="0"><hp:run charPrIDRef="${GJ_CHAR_COVER_SUB}"><hp:t>${escapeXml(t)}</hp:t></hp:run></hp:p>`;
22763
23094
  const subEmpty = emptyPara(GJ_PARA_COVER, false, GJ_CHAR_COVER_SUB);
22764
23095
  return [
@@ -22832,13 +23163,26 @@ function normalize(s) {
22832
23163
  return s.replace(/\s+/g, " ").trim();
22833
23164
  }
22834
23165
  var MAX_LEVENSHTEIN_LEN = 1e4;
23166
+ function approxDistance(a, b) {
23167
+ const bigramCounts = (s) => {
23168
+ const m = /* @__PURE__ */ new Map();
23169
+ for (let i = 0; i < s.length - 1; i++) {
23170
+ const g = s.slice(i, i + 2);
23171
+ m.set(g, (_nullishCoalesce(m.get(g), () => ( 0))) + 1);
23172
+ }
23173
+ return m;
23174
+ };
23175
+ const ca = bigramCounts(a);
23176
+ const cb = bigramCounts(b);
23177
+ let inter = 0;
23178
+ for (const [g, n] of ca) inter += Math.min(n, _nullishCoalesce(cb.get(g), () => ( 0)));
23179
+ const total = Math.max(a.length - 1, 0) + Math.max(b.length - 1, 0);
23180
+ const dice = total > 0 ? 2 * inter / total : 1;
23181
+ return Math.round(Math.max(a.length, b.length) * (1 - dice));
23182
+ }
22835
23183
  function levenshtein(a, b) {
22836
23184
  if (a.length + b.length > MAX_LEVENSHTEIN_LEN) {
22837
- const sampleLen = Math.min(500, a.length, b.length);
22838
- let diffs = 0;
22839
- for (let i = 0; i < sampleLen; i++) if (a[i] !== b[i]) diffs++;
22840
- const sampleRate = sampleLen > 0 ? diffs / sampleLen : 1;
22841
- return Math.abs(a.length - b.length) + Math.round(Math.min(a.length, b.length) * sampleRate);
23185
+ return approxDistance(a, b);
22842
23186
  }
22843
23187
  if (a.length > b.length) [a, b] = [b, a];
22844
23188
  const m = a.length;
@@ -22990,11 +23334,18 @@ function bestSimInRange(arr, from, to, target) {
22990
23334
  return best;
22991
23335
  }
22992
23336
  function escapeGfm(text) {
22993
- return text.replace(/([~*])/g, "\\$1");
23337
+ const NUL = String.fromCharCode(0);
23338
+ const spans = [];
23339
+ const masked = text.replace(/!\[[^\]]*\]\([^)\n]*\)|\]\((?:https?:|mailto:|tel:|#)[^)\n]*\)/gi, (m) => {
23340
+ spans.push(m);
23341
+ return NUL + (spans.length - 1) + NUL;
23342
+ });
23343
+ const escaped = masked.replace(/([~*_`])/g, "\\$1");
23344
+ return escaped.replace(new RegExp(NUL + "(\\d+)" + NUL, "g"), (_, n) => spans[Number(n)]);
22994
23345
  }
22995
- var HWP_SHAPE_ALT_TEXT_RE = /(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|이등변 삼각형|직각 삼각형|선|직선|곡선|화살표|굵은 화살표|이중 화살표|오각형|육각형|팔각형|별|[4-8]점별|십자|십자형|구름|구름형|마름모|도넛|평행사변형|사다리꼴|부채꼴|호|반원|물결|번개|하트|빗금|블록 화살표|수식|표|그림|개체|그리기\s?개체|묶음\s?개체|글상자|수식\s?개체|OLE\s?개체)\s?입니다\.?/g;
23346
+ var HWP_SHAPE_ALT_TEXT_RE = /^(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|이등변 삼각형|직각 삼각형|선|직선|곡선|화살표|굵은 화살표|이중 화살표|오각형|육각형|팔각형|별|[4-8]점별|십자|십자형|구름|구름형|마름모|도넛|평행사변형|사다리꼴|부채꼴|호|반원|물결|번개|하트|빗금|블록 화살표|수식|표|그림|개체|그리기\s?개체|묶음\s?개체|글상자|수식\s?개체|OLE\s?개체)\s?입니다\.?$/gm;
22996
23347
  function sanitizeText(text) {
22997
- let result = _chunk6XAAYAWLcjs.mapPuaText.call(void 0, text).replace(/[\u{F0000}-\u{FFFFD}]/gu, "").replace(HWP_SHAPE_ALT_TEXT_RE, "").replace(/ +/g, " ").trim();
23348
+ let result = _chunk37VKMUSTcjs.mapPuaText.call(void 0, text).replace(/[\u{F0000}-\u{FFFFD}]/gu, "").replace(HWP_SHAPE_ALT_TEXT_RE, "").replace(/ +/g, " ").trim();
22998
23349
  if (result.length <= 30 && result.includes(" ")) {
22999
23350
  const tokens = result.split(" ");
23000
23351
  const koreanSingleCharCount = tokens.filter((t) => t.length === 1 && /[가-힯ㄱ-ㆎ]/.test(t)).length;
@@ -23008,7 +23359,7 @@ function normForMatch(text) {
23008
23359
  return sanitizeText(text).replace(/\s+/g, " ").trim();
23009
23360
  }
23010
23361
  function unescapeGfm(text) {
23011
- return text.replace(/\\([~*])/g, "$1");
23362
+ return text.replace(/\\([~*_`])/g, "$1");
23012
23363
  }
23013
23364
  function summarize(text) {
23014
23365
  const t = text.replace(/\s+/g, " ").trim();
@@ -23024,7 +23375,7 @@ function replicateGfmTable(table2) {
23024
23375
  for (let r = 0; r < numRows; r++) {
23025
23376
  for (let c = 0; c < numCols; c++) {
23026
23377
  if (skip.has(`${r},${c}`)) continue;
23027
- const cell2 = _optionalChain([cells, 'access', _231 => _231[r], 'optionalAccess', _232 => _232[c]]);
23378
+ const cell2 = _optionalChain([cells, 'access', _268 => _268[r], 'optionalAccess', _269 => _269[c]]);
23028
23379
  if (!cell2) continue;
23029
23380
  display[r][c] = {
23030
23381
  text: escapeGfm(sanitizeText(cell2.text)).replace(/\|/g, "\\|").replace(/\n/g, "<br>"),
@@ -23075,10 +23426,10 @@ function parseGfmTable(lines) {
23075
23426
  return rows;
23076
23427
  }
23077
23428
  function unescapeGfmCell(text) {
23078
- return text.replace(/<br\s*\/?>/gi, "\n").replace(/\\\|/g, "|").replace(/\\([~*])/g, "$1");
23429
+ return text.replace(/<br\s*\/?>/gi, "\n").replace(/\\\|/g, "|").replace(/\\([~*_`])/g, "$1");
23079
23430
  }
23080
23431
  function replicateCellInnerHtml(cell2) {
23081
- if (_optionalChain([cell2, 'access', _233 => _233.blocks, 'optionalAccess', _234 => _234.length])) {
23432
+ if (_optionalChain([cell2, 'access', _270 => _270.blocks, 'optionalAccess', _271 => _271.length])) {
23082
23433
  return cell2.blocks.map((b) => {
23083
23434
  if (b.type === "table" && b.table) {
23084
23435
  const cap = b.table.caption ? sanitizeText(b.table.caption) : "";
@@ -23117,7 +23468,7 @@ function replicateHtmlTable(table2) {
23117
23468
  const rowCells = [];
23118
23469
  for (let c = 0; c < numCols; c++) {
23119
23470
  if (skip.has(`${r},${c}`)) continue;
23120
- const cell2 = _optionalChain([cells, 'access', _235 => _235[r], 'optionalAccess', _236 => _236[c]]);
23471
+ const cell2 = _optionalChain([cells, 'access', _272 => _272[r], 'optionalAccess', _273 => _273[c]]);
23121
23472
  if (!cell2) continue;
23122
23473
  for (let dr = 0; dr < cell2.rowSpan; dr++) {
23123
23474
  for (let dc = 0; dc < cell2.colSpan; dc++) {
@@ -23163,10 +23514,10 @@ function parseHtmlTable(raw) {
23163
23514
  }
23164
23515
  } else {
23165
23516
  if (!isClose) {
23166
- const cs = parseInt(_optionalChain([attrs, 'access', _237 => _237.match, 'call', _238 => _238(/colspan\s*=\s*"(\d+)"/i), 'optionalAccess', _239 => _239[1]]) || "1", 10);
23167
- const rs = parseInt(_optionalChain([attrs, 'access', _240 => _240.match, 'call', _241 => _241(/rowspan\s*=\s*"(\d+)"/i), 'optionalAccess', _242 => _242[1]]) || "1", 10);
23517
+ const cs = parseInt(_optionalChain([attrs, 'access', _274 => _274.match, 'call', _275 => _275(/colspan\s*=\s*["']?(\d+)/i), 'optionalAccess', _276 => _276[1]]) || "1", 10);
23518
+ const rs = parseInt(_optionalChain([attrs, 'access', _277 => _277.match, 'call', _278 => _278(/rowspan\s*=\s*["']?(\d+)/i), 'optionalAccess', _279 => _279[1]]) || "1", 10);
23168
23519
  cellStart = m.index + m[0].length;
23169
- cellInfo = { colSpan: isNaN(cs) ? 1 : cs, rowSpan: isNaN(rs) ? 1 : rs };
23520
+ cellInfo = { colSpan: clampSpan(isNaN(cs) ? 1 : cs, _chunk37VKMUSTcjs.MAX_COLS), rowSpan: clampSpan(isNaN(rs) ? 1 : rs, _chunk37VKMUSTcjs.MAX_ROWS) };
23170
23521
  } else if (cellStart >= 0 && cellInfo && currentRow) {
23171
23522
  currentRow.push({ inner: raw.slice(cellStart, m.index), colSpan: cellInfo.colSpan, rowSpan: cellInfo.rowSpan });
23172
23523
  cellStart = -1;
@@ -23190,7 +23541,7 @@ function htmlCellInnerToLines(inner) {
23190
23541
  hadNonText = true;
23191
23542
  work = work.replace(/<img\s(?:"[^"]*"|'[^']*'|[^>"'])*?>/gi, (tag) => {
23192
23543
  const m = /\bsrc\s*=\s*(?:"([^"]*)"|'([^']*)')/i.exec(tag);
23193
- const src = _nullishCoalesce(_optionalChain([m, 'optionalAccess', _243 => _243[1]]), () => ( _optionalChain([m, 'optionalAccess', _244 => _244[2]])));
23544
+ const src = _nullishCoalesce(_optionalChain([m, 'optionalAccess', _280 => _280[1]]), () => ( _optionalChain([m, 'optionalAccess', _281 => _281[2]])));
23194
23545
  if (src) imgSrcs.push(src);
23195
23546
  return "";
23196
23547
  });
@@ -23321,7 +23672,7 @@ function edgeXml(tag, d) {
23321
23672
  return d ? `<hh:${tag} type="${escapeXml(d.type)}" width="${escapeXml(d.width)}" color="${escapeXml(d.color)}"/>` : `<hh:${tag} type="NONE" width="0.1 mm" color="#000000"/>`;
23322
23673
  }
23323
23674
  function borderFillDefToXml(id, def) {
23324
- const fill = _optionalChain([def, 'access', _245 => _245.fill, 'optionalAccess', _246 => _246.faceColor]) ? `<hh:fillBrush><hh:winBrush faceColor="${escapeXml(def.fill.faceColor)}" hatchColor="#000000" alpha="0"/></hh:fillBrush>` : "";
23675
+ const fill = _optionalChain([def, 'access', _282 => _282.fill, 'optionalAccess', _283 => _283.faceColor]) ? `<hh:fillBrush><hh:winBrush faceColor="${escapeXml(def.fill.faceColor)}" hatchColor="#000000" alpha="0"/></hh:fillBrush>` : "";
23325
23676
  return ` <hh:borderFill id="${id}" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
23326
23677
  <hh:slash type="NONE" Crooked="0" isCounter="0"/>
23327
23678
  <hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
@@ -23726,11 +24077,11 @@ function estimateRowHeight(cells, widths, charHeight) {
23726
24077
  function generateTable(rows, theme, style = null, remap = null, seq = 0, images = null) {
23727
24078
  const rowCnt = rows.length;
23728
24079
  const colCnt = Math.max(...rows.map((r) => r.length), 1);
23729
- const reg = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _247 => _247.bfRegistry]), () => ( null));
24080
+ const reg = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _284 => _284.bfRegistry]), () => ( null));
23730
24081
  const totalW = style ? reg ? style.totalWidth - DATA_TABLE_INSET : style.totalWidth : 44e3;
23731
- const measureH = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _248 => _248.charHeight]), () => ( 1e3));
24082
+ const measureH = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _285 => _285.charHeight]), () => ( 1e3));
23732
24083
  const rowAnchor = normalizeRowAnchor((_nullishCoalesce(rows[0], () => ( []))).map((c) => c.replace(/!\[[^\]]*\]\([^)]*\)/g, "")));
23733
- const prof = takeProfile(remap, rowCnt, colCnt, anchorOfMarkdownCell(_nullishCoalesce(_optionalChain([rows, 'access', _249 => _249[0], 'optionalAccess', _250 => _250[0]]), () => ( ""))), seq, rowAnchor);
24084
+ const prof = takeProfile(remap, rowCnt, colCnt, anchorOfMarkdownCell(_nullishCoalesce(_optionalChain([rows, 'access', _286 => _286[0], 'optionalAccess', _287 => _287[0]]), () => ( ""))), seq, rowAnchor);
23734
24085
  const colMax = Array(colCnt).fill(0);
23735
24086
  const colMaxBody = Array(colCnt).fill(0);
23736
24087
  const colMinWord = Array(colCnt).fill(0);
@@ -23758,7 +24109,7 @@ function generateTable(rows, theme, style = null, remap = null, seq = 0, images
23758
24109
  const k = `${rowIdx},${colIdx}`;
23759
24110
  const isLabelCell2 = labelCol0 && colIdx === 0;
23760
24111
  const defaultCharPr = style ? reg && (isHeaderRow || isLabelCell2) ? style.boldCharPr : style.charPr : isHeaderRow ? headerCharPr : baseCharPr;
23761
- const cellCharPr = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _251 => _251.cellChar, 'access', _252 => _252.get, 'call', _253 => _253(k)]), () => ( defaultCharPr));
24112
+ const cellCharPr = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _288 => _288.cellChar, 'access', _289 => _289.get, 'call', _290 => _290(k)]), () => ( defaultCharPr));
23762
24113
  const centered = isHeaderRow || colCentered[colIdx];
23763
24114
  const paraPrId = style ? centered ? _nullishCoalesce(style.tblCenterParaPr, () => ( style.centerParaPr)) : reg ? _nullishCoalesce(style.tblLeftParaPr, () => ( PARA_NORMAL)) : PARA_NORMAL : PARA_NORMAL;
23764
24115
  const p = cell2.split(/<br\s*\/?>/i).map((seg) => {
@@ -23776,11 +24127,11 @@ function generateTable(rows, theme, style = null, remap = null, seq = 0, images
23776
24127
  }
23777
24128
  }
23778
24129
  }
23779
- const runs = generateRuns(seg, cellCharPr, _optionalChain([prof, 'optionalAccess', _254 => _254.cellChar, 'access', _255 => _255.has, 'call', _256 => _256(k)]) ? void 0 : mapId);
24130
+ const runs = generateRuns(seg, cellCharPr, _optionalChain([prof, 'optionalAccess', _291 => _291.cellChar, 'access', _292 => _292.has, 'call', _293 => _293(k)]) ? void 0 : mapId);
23780
24131
  const body = (runs || (picRuns ? "" : `<hp:run charPrIDRef="${cellCharPr}"><hp:t></hp:t></hp:run>`)) + picRuns;
23781
24132
  return `<hp:p paraPrIDRef="${paraPrId}" styleIDRef="0">${body}</hp:p>`;
23782
24133
  }).join("");
23783
- const bf = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _257 => _257.cellBf, 'access', _258 => _258.get, 'call', _259 => _259(k)]), () => ( (reg ? reg.get(dataCellSpec({
24134
+ const bf = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _294 => _294.cellBf, 'access', _295 => _295.get, 'call', _296 => _296(k)]), () => ( (reg ? reg.get(dataCellSpec({
23784
24135
  row: rowIdx,
23785
24136
  rowEnd: rowIdx,
23786
24137
  col: colIdx,
@@ -23790,7 +24141,7 @@ function generateTable(rows, theme, style = null, remap = null, seq = 0, images
23790
24141
  headerRows: 1,
23791
24142
  fill: isHeaderRow ? _nullishCoalesce(style.headerFill, () => ( "#E6E6E6")) : isLabelCell2 ? _nullishCoalesce(style.labelFill, () => ( "#E7E7E7")) : void 0
23792
24143
  })) : style && isHeaderRow ? style.headerBf : 2)));
23793
- const h = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _260 => _260.cellH, 'access', _261 => _261.get, 'call', _262 => _262(k)]), () => ( cellH));
24144
+ const h = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _297 => _297.cellH, 'access', _298 => _298.get, 'call', _299 => _299(k)]), () => ( cellH));
23794
24145
  return `<hp:tc name="" header="${isHeaderRow ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="${bf}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="${style ? "CENTER" : "TOP"}" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${p}</hp:subList><hp:cellAddr colAddr="${colIdx}" rowAddr="${rowIdx}"/><hp:cellSpan colSpan="1" rowSpan="1"/><hp:cellSz width="${colWidths[colIdx]}" height="${h}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
23795
24146
  }).join("");
23796
24147
  return `<hp:tr>${tdElements}</hp:tr>`;
@@ -23799,7 +24150,7 @@ function generateTable(rows, theme, style = null, remap = null, seq = 0, images
23799
24150
  const tblH = rowHeights.reduce((a, b) => a + b, 0);
23800
24151
  const tblInner = `<hp:sz width="${tblW}" widthRelTo="ABSOLUTE" height="${tblH}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="0" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="0" right="0" top="0" bottom="0"/><hp:inMargin left="510" right="510" top="141" bottom="141"/>` + trElements;
23801
24152
  const tbl2 = `<hp:tbl id="${tblId}" zOrder="0" numberingType="TABLE" pageBreak="CELL" repeatHeader="${style ? 1 : 0}" rowCnt="${rowCnt}" colCnt="${colCnt}" cellSpacing="0" borderFillIDRef="2" noShading="0">${tblInner}</hp:tbl>`;
23802
- const hostPr = reg && _optionalChain([style, 'optionalAccess', _263 => _263.rightParaPr]) !== void 0 ? style.rightParaPr : 0;
24153
+ const hostPr = reg && _optionalChain([style, 'optionalAccess', _300 => _300.rightParaPr]) !== void 0 ? style.rightParaPr : 0;
23803
24154
  return `<hp:p paraPrIDRef="${hostPr}" styleIDRef="0"><hp:run charPrIDRef="0">${tbl2}</hp:run></hp:p>`;
23804
24155
  }
23805
24156
  function layoutHtmlRows(rows) {
@@ -23810,8 +24161,8 @@ function layoutHtmlRows(rows) {
23810
24161
  let c = 0;
23811
24162
  for (const cell2 of rows[r].cells) {
23812
24163
  while (occupied.has(`${r},${c}`)) c++;
23813
- const colSpan = Math.max(1, cell2.colSpan);
23814
- const rowSpan = Math.max(1, cell2.rowSpan);
24164
+ const colSpan = clampSpan(cell2.colSpan, _chunk37VKMUSTcjs.MAX_COLS);
24165
+ const rowSpan = clampSpan(cell2.rowSpan, _chunk37VKMUSTcjs.MAX_ROWS);
23815
24166
  placed.push({ r, c, colSpan, rowSpan, inner: cell2.inner, isHeader: rows[r].tag === "th" });
23816
24167
  for (let dr = 0; dr < rowSpan; dr++) {
23817
24168
  for (let dc = 0; dc < colSpan; dc++) occupied.add(`${r + dr},${c + dc}`);
@@ -23839,7 +24190,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
23839
24190
  if (!rows || rows.length === 0) return null;
23840
24191
  const { placed, rowCnt, colCnt } = layoutHtmlRows(rows);
23841
24192
  if (rowCnt === 0 || colCnt === 0) return null;
23842
- const measureH = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _264 => _264.charHeight]), () => ( 1e3));
24193
+ const measureH = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _301 => _301.charHeight]), () => ( 1e3));
23843
24194
  const first = _nullishCoalesce(placed.find((p) => p.r === 0 && p.c === 0), () => ( placed[0]));
23844
24195
  const row0 = Array.from({ length: colCnt }, () => "");
23845
24196
  for (const cell2 of placed) {
@@ -23868,7 +24219,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
23868
24219
  const tblId = nextTableId();
23869
24220
  const useHeaderStyle = !style && (theme.tableHeader !== theme.body || theme.tableHeaderBold);
23870
24221
  const spanW = (cell2) => colWidths.slice(cell2.c, cell2.c + cell2.colSpan).reduce((a, b) => a + b, 0);
23871
- const reg = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _265 => _265.bfRegistry]), () => ( null));
24222
+ const reg = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _302 => _302.bfRegistry]), () => ( null));
23872
24223
  let htmlHeaderRows = 0;
23873
24224
  while (htmlHeaderRows < rows.length && rows[htmlHeaderRows].tag === "th") htmlHeaderRows++;
23874
24225
  const tableRowHeights = Array(rowCnt).fill(cellH);
@@ -23883,7 +24234,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
23883
24234
  const nestedXml = generateHtmlTableXml(nested, theme, nestedW, style ? { ...style, totalWidth: nestedW } : null);
23884
24235
  if (nestedXml) {
23885
24236
  nestedXmls.push(nestedXml);
23886
- const szH = _optionalChain([nestedXml, 'access', _266 => _266.match, 'call', _267 => _267(/<hp:sz [^>]*height="(\d+)"/), 'optionalAccess', _268 => _268[1]]);
24237
+ const szH = _optionalChain([nestedXml, 'access', _303 => _303.match, 'call', _304 => _304(/<hp:sz [^>]*height="(\d+)"/), 'optionalAccess', _305 => _305[1]]);
23887
24238
  nestedH += (szH ? Number(szH) : (_nullishCoalesce(nested.match(/<tr[\s>]/gi), () => ( []))).length * cellH) + 300;
23888
24239
  }
23889
24240
  }
@@ -23892,7 +24243,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
23892
24243
  for (const line of lines) wrapLines += Math.max(1, Math.ceil(measureTextWidth(unescapeHtml(line).trim(), measureH, 100) / usable));
23893
24244
  const lineH = style ? Math.round(measureH * 1.6) : 800;
23894
24245
  const contentH = Math.max(cellH * rowSpan, Math.max(wrapLines, 1) * lineH + nestedH);
23895
- const cellHeight = Math.max(_nullishCoalesce(_optionalChain([prof, 'optionalAccess', _269 => _269.cellH, 'access', _270 => _270.get, 'call', _271 => _271(`${cell2.r},${cell2.c}`)]), () => ( 0)), contentH);
24246
+ const cellHeight = Math.max(_nullishCoalesce(_optionalChain([prof, 'optionalAccess', _306 => _306.cellH, 'access', _307 => _307.get, 'call', _308 => _308(`${cell2.r},${cell2.c}`)]), () => ( 0)), contentH);
23896
24247
  const perRow = Math.ceil(cellHeight / rowSpan);
23897
24248
  for (let r = cell2.r; r < cell2.r + rowSpan; r++) tableRowHeights[r] = Math.max(tableRowHeights[r], perRow);
23898
24249
  return { cell: cell2, rowSpan, lines, nestedXmls, imgSrcs: cellParsed[i].imgSrcs };
@@ -23903,7 +24254,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
23903
24254
  const baseCharPr = style ? style.charPr : CHAR_NORMAL;
23904
24255
  const headerCharPr = isHeader && useHeaderStyle ? CHAR_TABLE_HEADER : baseCharPr;
23905
24256
  const defaultCharPr = style && reg && isHeader ? style.boldCharPr : isHeader ? headerCharPr : baseCharPr;
23906
- const charPrId = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _272 => _272.cellChar, 'access', _273 => _273.get, 'call', _274 => _274(k)]), () => ( defaultCharPr));
24257
+ const charPrId = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _309 => _309.cellChar, 'access', _310 => _310.get, 'call', _311 => _311(k)]), () => ( defaultCharPr));
23907
24258
  const centered = isHeader || colCentered[cell2.c];
23908
24259
  const paraPrId = style ? centered ? reg ? _nullishCoalesce(style.tblCenterParaPr, () => ( style.centerParaPr)) : style.centerParaPr : reg ? _nullishCoalesce(style.tblLeftParaPr, () => ( PARA_NORMAL)) : PARA_NORMAL : PARA_NORMAL;
23909
24260
  const picUrls = images ? [...imgSrcs] : [];
@@ -23939,7 +24290,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
23939
24290
  let cellHeight = 0;
23940
24291
  for (let r = cell2.r; r < cell2.r + rowSpan; r++) cellHeight += tableRowHeights[r];
23941
24292
  const rowEnd = cell2.r + rowSpan - 1;
23942
- const bf = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _275 => _275.cellBf, 'access', _276 => _276.get, 'call', _277 => _277(k)]), () => ( (reg ? reg.get(dataCellSpec({
24293
+ const bf = _nullishCoalesce(_optionalChain([prof, 'optionalAccess', _312 => _312.cellBf, 'access', _313 => _313.get, 'call', _314 => _314(k)]), () => ( (reg ? reg.get(dataCellSpec({
23943
24294
  row: cell2.r,
23944
24295
  rowEnd,
23945
24296
  col: cell2.c,
@@ -24109,7 +24460,7 @@ function buildPressHead(g, ids, bodyWidth, reg) {
24109
24460
  return [`<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${table2}</hp:run></hp:p>`, blank()];
24110
24461
  }
24111
24462
  function buildPressContact(g, ids, bodyWidth, reg) {
24112
- const c = _optionalChain([g, 'access', _278 => _278.press, 'optionalAccess', _279 => _279.contact]);
24463
+ const c = _optionalChain([g, 'access', _315 => _315.press, 'optionalAccess', _316 => _316.contact]);
24113
24464
  if (!c || !c.dept && !c.manager && !c.phone) return [];
24114
24465
  const w = bodyWidth - 280;
24115
24466
  const cells = [["\uB2F4\uB2F9 \uBD80\uC11C", _nullishCoalesce(c.dept, () => ( ""))], ["\uB2F4\uB2F9\uC790", _nullishCoalesce(c.manager, () => ( ""))], ["\uC5F0\uB77D\uCC98", _nullishCoalesce(c.phone, () => ( ""))]];
@@ -24490,7 +24841,7 @@ function generateSecPr(gongmun) {
24490
24841
  }
24491
24842
  const secPr = `<hp:secPr textDirection="HORIZONTAL" spaceColumns="1134" tabStop="8000" outlineShapeIDRef="1" memoShapeIDRef="0" textVerticalWidthHead="0" masterPageCnt="0"><hp:grid lineGrid="0" charGrid="0" wonggojiFormat="0"/><hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/><hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/><hp:pagePr landscape="WIDELY" width="${A4_W_HU}" height="${A4_H_HU}" gutterType="LEFT_ONLY"><hp:margin header="${m.header}" footer="${m.footer}" gutter="0" left="${m.left}" right="${m.right}" top="${m.top}" bottom="${m.bottom}"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="EACH_COLUMN" beneathText="0"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="END_OF_DOCUMENT" beneathText="0"/></hp:endNotePr></hp:secPr>`;
24492
24843
  const colPr = `<hp:ctrl><hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="1" sameSz="1" sameGap="0"/></hp:ctrl>`;
24493
- return secPr + colPr + (_optionalChain([gongmun, 'optionalAccess', _280 => _280.pageNumbers]) ? pageNumCtrl() : "");
24844
+ return secPr + colPr + (_optionalChain([gongmun, 'optionalAccess', _317 => _317.pageNumbers]) ? pageNumCtrl() : "");
24494
24845
  }
24495
24846
  var SectionOpener = (_class6 = class {
24496
24847
  constructor(gongmun) {;_class6.prototype.__init12.call(this);
@@ -24529,19 +24880,19 @@ function buildPreamble(blocks, ctx) {
24529
24880
  const { gongmun, dfIds, bfReg, tableStyle, richAssets, gjBodyW } = ctx;
24530
24881
  const preamble = [];
24531
24882
  let hasFrontPages = false;
24532
- if (_optionalChain([gongmun, 'optionalAccess', _281 => _281.reportInfo]) && dfIds) {
24883
+ if (_optionalChain([gongmun, 'optionalAccess', _318 => _318.reportInfo]) && dfIds) {
24533
24884
  preamble.push(buildReportInfo(gongmun, dfIds));
24534
24885
  }
24535
- if (_optionalChain([gongmun, 'optionalAccess', _282 => _282.approval]) && bfReg) {
24886
+ if (_optionalChain([gongmun, 'optionalAccess', _319 => _319.approval]) && bfReg) {
24536
24887
  preamble.push(buildApprovalTable(gongmun.approval, bfReg, richAssets ? GJ_CHAR_APPROVAL : GONGMUN_APPROVAL_CHAR));
24537
24888
  }
24538
- if (_optionalChain([gongmun, 'optionalAccess', _283 => _283.docHead]) && dfIds) {
24889
+ if (_optionalChain([gongmun, 'optionalAccess', _320 => _320.docHead]) && dfIds) {
24539
24890
  preamble.push(...buildDocHead(gongmun, dfIds));
24540
24891
  }
24541
- if (_optionalChain([gongmun, 'optionalAccess', _284 => _284.noticeHead]) && dfIds) {
24892
+ if (_optionalChain([gongmun, 'optionalAccess', _321 => _321.noticeHead]) && dfIds) {
24542
24893
  preamble.push(...buildNoticeHead(gongmun));
24543
24894
  }
24544
- if (_optionalChain([gongmun, 'optionalAccess', _285 => _285.press]) && dfIds && bfReg && tableStyle) {
24895
+ if (_optionalChain([gongmun, 'optionalAccess', _322 => _322.press]) && dfIds && bfReg && tableStyle) {
24545
24896
  preamble.push(...buildPressHead(gongmun, dfIds, tableStyle.totalWidth, bfReg));
24546
24897
  }
24547
24898
  if (gongmun && (gongmun.cover || gongmun.toc)) {
@@ -24570,7 +24921,7 @@ function buildPreamble(blocks, ctx) {
24570
24921
  }
24571
24922
  if (gongmun && !ctx.gaejosik && ctx.coverH1Idx < 0 && bfReg && (gongmun.preset === "report" || gongmun.preset === "plan" || gongmun.preset === "notice")) {
24572
24923
  ctx.titleBoxH1Idx = blocks.findIndex((b) => b.type === "heading" && (_nullishCoalesce(b.level, () => ( 1))) === 1);
24573
- } else if (_optionalChain([gongmun, 'optionalAccess', _286 => _286.press]) && ctx.coverH1Idx < 0 && dfIds) {
24924
+ } else if (_optionalChain([gongmun, 'optionalAccess', _323 => _323.press]) && ctx.coverH1Idx < 0 && dfIds) {
24574
24925
  ctx.pressH1Idx = blocks.findIndex((b) => b.type === "heading" && (_nullishCoalesce(b.level, () => ( 1))) === 1);
24575
24926
  }
24576
24927
  if (preamble.length > 0) {
@@ -24585,7 +24936,7 @@ function renderHeading(block, blockIdx, ctx) {
24585
24936
  if (gongmun && blockIdx === ctx.coverH1Idx) return "";
24586
24937
  if (gongmun && blockIdx === ctx.pressH1Idx && dfIds) {
24587
24938
  const parts = [generateParagraph((block.text || "").trim(), GONGMUN_CENTER, dfIds.pressTitle)];
24588
- for (const s of _nullishCoalesce(_optionalChain([gongmun, 'access', _287 => _287.press, 'optionalAccess', _288 => _288.sub]), () => ( []))) {
24939
+ for (const s of _nullishCoalesce(_optionalChain([gongmun, 'access', _324 => _324.press, 'optionalAccess', _325 => _325.sub]), () => ( []))) {
24589
24940
  parts.push(generateParagraph(`- ${s} -`, GONGMUN_CENTER, dfIds.pressSub));
24590
24941
  }
24591
24942
  return parts.join("\n ");
@@ -24679,8 +25030,8 @@ function renderListItem(block, blockIdx, ctx) {
24679
25030
  const { gongmun, gongmunList, measured, fit, vBase, dfIds } = ctx;
24680
25031
  if (gongmun && gongmunList) {
24681
25032
  const info = gongmunList.items.get(blockIdx);
24682
- const depth = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _289 => _289.depth]), () => ( 0));
24683
- const marker2 = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _290 => _290.marker]), () => ( ""));
25033
+ const depth = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _326 => _326.depth]), () => ( 0));
25034
+ const marker2 = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _327 => _327.marker]), () => ( ""));
24684
25035
  const content = block.text || "";
24685
25036
  if (measured && content.trimStart().startsWith("\u203B")) {
24686
25037
  return generateParagraph(content.trim(), GJ_PARA_CHAM, GJ_CHAR_CHAM, ctx.chamMap);
@@ -24689,7 +25040,7 @@ function renderListItem(block, blockIdx, ctx) {
24689
25040
  return generateParagraph(`* ${content.trim()}`, GJ_PARA_CHAM, GJ_CHAR_CHAM, ctx.chamMap);
24690
25041
  }
24691
25042
  const text = marker2 ? `${marker2} ${content}` : content;
24692
- const listParaPr = marker2 ? _optionalChain([info, 'optionalAccess', _291 => _291.indentVariant]) !== void 0 ? GONGMUN_LIST_VARIANT_BASE + info.indentVariant : GONGMUN_LIST_BASE + depth : GONGMUN_LIST_PLAIN_BASE + depth;
25043
+ const listParaPr = marker2 ? _optionalChain([info, 'optionalAccess', _328 => _328.indentVariant]) !== void 0 ? GONGMUN_LIST_VARIANT_BASE + info.indentVariant : GONGMUN_LIST_BASE + depth : GONGMUN_LIST_PLAIN_BASE + depth;
24693
25044
  let listCharPr = gongmun.numbering === "report" && depth === 0 ? CHAR_BOLD : CHAR_NORMAL;
24694
25045
  let mapId = fit ? variantMapper(fit, blockIdx, vBase) : void 0;
24695
25046
  if (measured && depth === 0 && gongmun.numbering !== "standard") {
@@ -24748,18 +25099,18 @@ function renderHtmlTable(block, ctx) {
24748
25099
  }
24749
25100
  function appendPostamble(blocks, ctx) {
24750
25101
  const { gongmun, dfIds, bfReg, tableStyle, paraXmls } = ctx;
24751
- if (_optionalChain([gongmun, 'optionalAccess', _292 => _292.noticeHead]) && dfIds) {
25102
+ if (_optionalChain([gongmun, 'optionalAccess', _329 => _329.noticeHead]) && dfIds) {
24752
25103
  paraXmls.push(...buildNoticeFoot(gongmun));
24753
25104
  }
24754
- if (_optionalChain([gongmun, 'optionalAccess', _293 => _293.endMark]) && paraXmls.length > 0) {
24755
- const lastBlock = [...blocks].reverse().find((b) => (b.text || "").trim() || b.type === "table" && _optionalChain([b, 'access', _294 => _294.rows, 'optionalAccess', _295 => _295.length]));
25105
+ if (_optionalChain([gongmun, 'optionalAccess', _330 => _330.endMark]) && paraXmls.length > 0) {
25106
+ const lastBlock = [...blocks].reverse().find((b) => (b.text || "").trim() || b.type === "table" && _optionalChain([b, 'access', _331 => _331.rows, 'optionalAccess', _332 => _332.length]));
24756
25107
  const lastText = lastBlock && (lastBlock.type === "paragraph" || lastBlock.type === "list_item") ? lastBlock.text || "" : "";
24757
25108
  if (!hasEndMark(lastText)) paraXmls.push(buildEndMark());
24758
25109
  }
24759
- if (_optionalChain([gongmun, 'optionalAccess', _296 => _296.docFoot]) && dfIds) {
25110
+ if (_optionalChain([gongmun, 'optionalAccess', _333 => _333.docFoot]) && dfIds) {
24760
25111
  paraXmls.push(...buildDocFoot(gongmun, dfIds));
24761
25112
  }
24762
- if (_optionalChain([gongmun, 'optionalAccess', _297 => _297.press]) && dfIds && bfReg && tableStyle) {
25113
+ if (_optionalChain([gongmun, 'optionalAccess', _334 => _334.press]) && dfIds && bfReg && tableStyle) {
24763
25114
  paraXmls.push(...buildPressContact(gongmun, dfIds, tableStyle.totalWidth, bfReg));
24764
25115
  }
24765
25116
  }
@@ -24779,7 +25130,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
24779
25130
  remap,
24780
25131
  dfIds,
24781
25132
  images,
24782
- gaejosik: _optionalChain([gongmun, 'optionalAccess', _298 => _298.preset]) === "gaejosik",
25133
+ gaejosik: _optionalChain([gongmun, 'optionalAccess', _335 => _335.preset]) === "gaejosik",
24783
25134
  measured,
24784
25135
  richAssets,
24785
25136
  vBase: charVariantBase(richAssets, !!gongmun),
@@ -24885,18 +25236,18 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
24885
25236
 
24886
25237
  // src/hwpx/generator.ts
24887
25238
  async function markdownToHwpx(markdown, options) {
24888
- const theme = resolveTheme(_optionalChain([options, 'optionalAccess', _299 => _299.theme]));
24889
- const gongmun = _optionalChain([options, 'optionalAccess', _300 => _300.gongmun]) ? resolveGongmun(options.gongmun) : null;
25239
+ const theme = resolveTheme(_optionalChain([options, 'optionalAccess', _336 => _336.theme]));
25240
+ const gongmun = _optionalChain([options, 'optionalAccess', _337 => _337.gongmun]) ? resolveGongmun(options.gongmun) : null;
24890
25241
  const measured = !!gongmun && usesReportFonts(gongmun.preset);
24891
25242
  const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
24892
25243
  const blocks = parseMarkdownToBlocks(markdown);
24893
25244
  const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
24894
25245
  const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
24895
25246
  const staticBfEnd = staticBorderFillNext(gongmun);
24896
- const remap = _optionalChain([options, 'optionalAccess', _301 => _301.profile]) ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (_nullishCoalesce(_optionalChain([fit, 'optionalAccess', _302 => _302.variants, 'optionalAccess', _303 => _303.length]), () => ( 0))) * 4, staticBfEnd, staticFontNext(gongmun)) : null;
24897
- const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (_nullishCoalesce(_optionalChain([remap, 'optionalAccess', _304 => _304.borderFillXmls, 'access', _305 => _305.length]), () => ( 0)))) : null;
25247
+ const remap = _optionalChain([options, 'optionalAccess', _338 => _338.profile]) ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (_nullishCoalesce(_optionalChain([fit, 'optionalAccess', _339 => _339.variants, 'optionalAccess', _340 => _340.length]), () => ( 0))) * 4, staticBfEnd, staticFontNext(gongmun)) : null;
25248
+ const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (_nullishCoalesce(_optionalChain([remap, 'optionalAccess', _341 => _341.borderFillXmls, 'access', _342 => _342.length]), () => ( 0)))) : null;
24898
25249
  const dfActive = !!gongmun && docframeActive(gongmun);
24899
- const dfBase = charVariantBase(richAssets, !!gongmun) + (_nullishCoalesce(_optionalChain([fit, 'optionalAccess', _306 => _306.variants, 'optionalAccess', _307 => _307.length]), () => ( 0))) * 4 + (_nullishCoalesce(_optionalChain([remap, 'optionalAccess', _308 => _308.charPrXmls, 'access', _309 => _309.length]), () => ( 0)));
25250
+ const dfBase = charVariantBase(richAssets, !!gongmun) + (_nullishCoalesce(_optionalChain([fit, 'optionalAccess', _343 => _343.variants, 'optionalAccess', _344 => _344.length]), () => ( 0))) * 4 + (_nullishCoalesce(_optionalChain([remap, 'optionalAccess', _345 => _345.charPrXmls, 'access', _346 => _346.length]), () => ( 0)));
24900
25251
  const dfIds = dfActive ? docframeIds(dfBase) : null;
24901
25252
  const chartParts = [];
24902
25253
  const images = new ImageRegistry();
@@ -24907,7 +25258,7 @@ async function markdownToHwpx(markdown, options) {
24907
25258
  console.warn(`[kordoc] format profile: \uD504\uB85C\uD544 \uD45C ${unused}\uAC1C\uAC00 \uBB38\uC11C \uD45C\uC640 \uB9E4\uCE6D\uB418\uC9C0 \uC54A\uC544 \uBBF8\uC801\uC6A9 (\uD589\xB7\uC5F4/\uCCAB \uC140 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)`);
24908
25259
  }
24909
25260
  }
24910
- const extraBorderFills = [..._nullishCoalesce(_optionalChain([remap, 'optionalAccess', _310 => _310.borderFillXmls]), () => ( [])), ..._nullishCoalesce(_optionalChain([bfReg, 'optionalAccess', _311 => _311.emit, 'call', _312 => _312()]), () => ( []))];
25261
+ const extraBorderFills = [..._nullishCoalesce(_optionalChain([remap, 'optionalAccess', _347 => _347.borderFillXmls]), () => ( [])), ..._nullishCoalesce(_optionalChain([bfReg, 'optionalAccess', _348 => _348.emit, 'call', _349 => _349()]), () => ( []))];
24911
25262
  const zip = new (0, _jszip2.default)();
24912
25263
  zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
24913
25264
  zip.file("META-INF/container.xml", generateContainerXml());
@@ -24916,11 +25267,11 @@ async function markdownToHwpx(markdown, options) {
24916
25267
  zip.file("Contents/header.xml", generateHeaderXml(
24917
25268
  theme,
24918
25269
  gongmun,
24919
- _nullishCoalesce(_optionalChain([fit, 'optionalAccess', _313 => _313.variants]), () => ( [])),
25270
+ _nullishCoalesce(_optionalChain([fit, 'optionalAccess', _350 => _350.variants]), () => ( [])),
24920
25271
  extraBorderFills,
24921
- [..._nullishCoalesce(_optionalChain([remap, 'optionalAccess', _314 => _314.charPrXmls]), () => ( [])), ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []],
24922
- _nullishCoalesce(_optionalChain([gongmunList, 'optionalAccess', _315 => _315.indentVariants]), () => ( [])),
24923
- _nullishCoalesce(_optionalChain([remap, 'optionalAccess', _316 => _316.fontFaces]), () => ( []))
25272
+ [..._nullishCoalesce(_optionalChain([remap, 'optionalAccess', _351 => _351.charPrXmls]), () => ( [])), ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []],
25273
+ _nullishCoalesce(_optionalChain([gongmunList, 'optionalAccess', _352 => _352.indentVariants]), () => ( [])),
25274
+ _nullishCoalesce(_optionalChain([remap, 'optionalAccess', _353 => _353.fontFaces]), () => ( []))
24924
25275
  ));
24925
25276
  zip.file("Contents/section0.xml", sectionXml);
24926
25277
  for (const part of chartParts) zip.file(part.name, part.xml);
@@ -24970,12 +25321,20 @@ function diffBlocks(blocksA, blocksB) {
24970
25321
  function alignBlocks(a, b) {
24971
25322
  const m = a.length, n = b.length;
24972
25323
  if (m * n > 1e7) return fallbackAlign(a, b);
25324
+ const lenOf = (blk) => {
25325
+ const t = blk.text !== void 0 ? blk.text : blk.type === "table" && blk.table ? blk.table.cells.flat().map((c) => _nullishCoalesce(_optionalChain([c, 'optionalAccess', _354 => _354.text]), () => ( ""))).join(" ") : "";
25326
+ return t.replace(/\s+/g, " ").trim().length;
25327
+ };
25328
+ const aLen = a.map(lenOf);
25329
+ const bLen = b.map(lenOf);
24973
25330
  const simCache = /* @__PURE__ */ new Map();
24974
25331
  const getSim = (i2, j2) => {
24975
25332
  const key = `${i2},${j2}`;
24976
25333
  let v = simCache.get(key);
24977
25334
  if (v === void 0) {
24978
- v = blockSimilarity(a[i2], b[j2]);
25335
+ const mx = Math.max(aLen[i2], bLen[j2]);
25336
+ const cut = a[i2].type === "table" || b[j2].type === "table" ? 6 / 7 : 1 - SIMILARITY_THRESHOLD;
25337
+ v = mx > 0 && (mx - Math.min(aLen[i2], bLen[j2])) / mx > cut ? 0 : blockSimilarity(a[i2], b[j2]);
24979
25338
  simCache.set(key, v);
24980
25339
  }
24981
25340
  return v;
@@ -25036,8 +25395,8 @@ function blockSimilarity(a, b) {
25036
25395
  }
25037
25396
  function tableSimilarity(a, b) {
25038
25397
  const dimSim = 1 - Math.abs(a.rows * a.cols - b.rows * b.cols) / Math.max(a.rows * a.cols, b.rows * b.cols, 1);
25039
- const textsA = a.cells.flat().map((c) => c.text).join(" ");
25040
- const textsB = b.cells.flat().map((c) => c.text).join(" ");
25398
+ const textsA = a.cells.flat().map((c) => _nullishCoalesce(_optionalChain([c, 'optionalAccess', _355 => _355.text]), () => ( ""))).join(" ");
25399
+ const textsB = b.cells.flat().map((c) => _nullishCoalesce(_optionalChain([c, 'optionalAccess', _356 => _356.text]), () => ( ""))).join(" ");
25041
25400
  const contentSim = normalizedSimilarity(textsA, textsB);
25042
25401
  return dimSim * 0.3 + contentSim * 0.7;
25043
25402
  }
@@ -25048,8 +25407,8 @@ function diffTableCells(a, b) {
25048
25407
  for (let r = 0; r < maxRows; r++) {
25049
25408
  const row = [];
25050
25409
  for (let c = 0; c < maxCols; c++) {
25051
- const cellA = r < a.rows && c < a.cols ? a.cells[r][c].text : void 0;
25052
- const cellB = r < b.rows && c < b.cols ? b.cells[r][c].text : void 0;
25410
+ const cellA = r < a.rows && c < a.cols ? _optionalChain([a, 'access', _357 => _357.cells, 'access', _358 => _358[r], 'optionalAccess', _359 => _359[c], 'optionalAccess', _360 => _360.text]) : void 0;
25411
+ const cellB = r < b.rows && c < b.cols ? _optionalChain([b, 'access', _361 => _361.cells, 'access', _362 => _362[r], 'optionalAccess', _363 => _363[c], 'optionalAccess', _364 => _364.text]) : void 0;
25053
25412
  let type;
25054
25413
  if (cellA === void 0) type = "added";
25055
25414
  else if (cellB === void 0) type = "removed";
@@ -25215,7 +25574,7 @@ function parseRenderStyles(headXml) {
25215
25574
  const underlineEl = findChildByLocalName(el, "underline");
25216
25575
  const textColor = el.getAttribute("textColor");
25217
25576
  const fontRef = findChildByLocalName(el, "fontRef");
25218
- const fontId = _nullishCoalesce(_optionalChain([fontRef, 'optionalAccess', _317 => _317.getAttribute, 'call', _318 => _318("hangul")]), () => ( _optionalChain([fontRef, 'optionalAccess', _319 => _319.getAttribute, 'call', _320 => _320("latin")])));
25577
+ const fontId = _nullishCoalesce(_optionalChain([fontRef, 'optionalAccess', _365 => _365.getAttribute, 'call', _366 => _366("hangul")]), () => ( _optionalChain([fontRef, 'optionalAccess', _367 => _367.getAttribute, 'call', _368 => _368("latin")])));
25219
25578
  const face = fontId != null ? hangulFonts.get(fontId) : void 0;
25220
25579
  styles.charPr.set(id, {
25221
25580
  height: Number(el.getAttribute("height")) || 1e3,
@@ -25223,8 +25582,8 @@ function parseRenderStyles(headXml) {
25223
25582
  italic: findChildByLocalName(el, "italic") != null,
25224
25583
  underline: underlineEl != null && (_nullishCoalesce(underlineEl.getAttribute("type"), () => ( "NONE"))) !== "NONE",
25225
25584
  color: textColor && textColor !== "#000000" && textColor.toLowerCase() !== "none" ? textColor : void 0,
25226
- ratio: Number(_optionalChain([ratioEl, 'optionalAccess', _321 => _321.getAttribute, 'call', _322 => _322("hangul")])) || 100,
25227
- spacing: Number(_optionalChain([spacingEl, 'optionalAccess', _323 => _323.getAttribute, 'call', _324 => _324("hangul")])) || 0,
25585
+ ratio: Number(_optionalChain([ratioEl, 'optionalAccess', _369 => _369.getAttribute, 'call', _370 => _370("hangul")])) || 100,
25586
+ spacing: Number(_optionalChain([spacingEl, 'optionalAccess', _371 => _371.getAttribute, 'call', _372 => _372("hangul")])) || 0,
25228
25587
  fontFamily: face ? hwpFaceToCssStack(face) : void 0,
25229
25588
  face
25230
25589
  });
@@ -25233,7 +25592,7 @@ function parseRenderStyles(headXml) {
25233
25592
  const id = el.getAttribute("id");
25234
25593
  if (id != null) {
25235
25594
  const align = findChildByLocalName(el, "align");
25236
- styles.paraAlign.set(id, _optionalChain([align, 'optionalAccess', _325 => _325.getAttribute, 'call', _326 => _326("horizontal")]) || "JUSTIFY");
25595
+ styles.paraAlign.set(id, _optionalChain([align, 'optionalAccess', _373 => _373.getAttribute, 'call', _374 => _374("horizontal")]) || "JUSTIFY");
25237
25596
  styles.paraGeom.set(id, parseParaGeom(el));
25238
25597
  }
25239
25598
  } else if (tag === "borderFill") {
@@ -25247,7 +25606,7 @@ function parseRenderStyles(headXml) {
25247
25606
  };
25248
25607
  const fillBrush = findChildByLocalName(el, "fillBrush");
25249
25608
  const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
25250
- const face = _optionalChain([winBrush, 'optionalAccess', _327 => _327.getAttribute, 'call', _328 => _328("faceColor")]);
25609
+ const face = _optionalChain([winBrush, 'optionalAccess', _375 => _375.getAttribute, 'call', _376 => _376("faceColor")]);
25251
25610
  if (face && face.toLowerCase() !== "none") bf.fill = face;
25252
25611
  styles.borderFill.set(id, bf);
25253
25612
  }
@@ -25319,7 +25678,7 @@ function collectSites(scan) {
25319
25678
  }
25320
25679
  function attrOf(openTag, name) {
25321
25680
  const m = openTag.match(new RegExp(`\\b${name}="([^"]*)"`));
25322
- return _optionalChain([m, 'optionalAccess', _329 => _329[1]]);
25681
+ return _optionalChain([m, 'optionalAccess', _377 => _377[1]]);
25323
25682
  }
25324
25683
  function paraOpenTag(xml, para2) {
25325
25684
  const end = xml.indexOf(">", para2.start);
@@ -25334,7 +25693,7 @@ function anchorRunInfo(xml, para2, anchor) {
25334
25693
  if (!tr) return null;
25335
25694
  const before = xml.slice(Math.max(0, para2.start), tr.contentStart);
25336
25695
  const runOpen = [...before.matchAll(/<([A-Za-z0-9]+):run\b[^>]*>/g)].pop();
25337
- const prefix = _nullishCoalesce(_nullishCoalesce(_optionalChain([runOpen, 'optionalAccess', _330 => _330[1]]), () => ( tr.prefix)), () => ( "hp"));
25696
+ const prefix = _nullishCoalesce(_nullishCoalesce(_optionalChain([runOpen, 'optionalAccess', _378 => _378[1]]), () => ( tr.prefix)), () => ( "hp"));
25338
25697
  const charPr2 = runOpen && attrOf(runOpen[0], "charPrIDRef") || "0";
25339
25698
  const close = xml.indexOf(`</${prefix}:run>`, tr.contentEnd);
25340
25699
  if (close === -1) return null;
@@ -25361,7 +25720,7 @@ function cellContentWidthMm(xml, cell2) {
25361
25720
  if (width === null) return null;
25362
25721
  let content = width;
25363
25722
  const win = cellAddrWindow(xml, cell2);
25364
- const mg = _optionalChain([win, 'optionalAccess', _331 => _331.match, 'call', _332 => _332(/<[A-Za-z0-9]+:cellMargin\b[^>]*>/)]);
25723
+ const mg = _optionalChain([win, 'optionalAccess', _379 => _379.match, 'call', _380 => _380(/<[A-Za-z0-9]+:cellMargin\b[^>]*>/)]);
25365
25724
  if (mg) {
25366
25725
  content -= Number(_nullishCoalesce(attrOf(mg[0], "left"), () => ( 0))) + Number(_nullishCoalesce(attrOf(mg[0], "right"), () => ( 0)));
25367
25726
  }
@@ -25395,11 +25754,11 @@ function buildFloatPicXml(itemId, sizeHu, posXHu, posYHu, ids) {
25395
25754
  return `<hp:pic xmlns:hc="http://www.hancom.co.kr/hwpml/2011/core" id="${ids.id}" zOrder="0" numberingType="PICTURE" textWrap="IN_FRONT_OF_TEXT" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" href="" groupLevel="0" instid="${ids.instid}" reverse="0"><hp:offset x="0" y="0"/><hp:orgSz width="${w}" height="${h}"/><hp:curSz width="${w}" height="${h}"/><hp:flip horizontal="0" vertical="0"/><hp:rotationInfo angle="0" centerX="${Math.round(w / 2)}" centerY="${Math.round(h / 2)}" rotateimage="1"/><hp:renderingInfo><hc:transMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:scaMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:rotMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/></hp:renderingInfo><hp:imgRect><hc:pt0 x="0" y="0"/><hc:pt1 x="${w}" y="0"/><hc:pt2 x="${w}" y="${h}"/><hc:pt3 x="0" y="${h}"/></hp:imgRect><hp:imgClip left="0" right="${w}" top="0" bottom="${h}"/><hp:inMargin left="0" right="0" top="0" bottom="0"/><hp:imgDim dimwidth="${w}" dimheight="${h}"/><hc:img binaryItemIDRef="${itemId}" bright="0" contrast="0" effect="REAL_PIC" alpha="0"/><hp:effects/><hp:sz width="${w}" widthRelTo="ABSOLUTE" height="${h}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="0" affectLSpacing="0" flowWithText="0" allowOverlap="1" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="COLUMN" vertAlign="TOP" horzAlign="LEFT" vertOffset="${posYHu}" horzOffset="${posXHu}"/><hp:outMargin left="0" right="0" top="0" bottom="0"/><hp:shapeComment>kordoc seal</hp:shapeComment></hp:pic>`;
25396
25755
  }
25397
25756
  async function placeSealHwpx(hwpxBuffer, ops) {
25398
- if (ops.length === 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("place_seal: \uBC30\uCE58\uD560 \uB3C4\uC7A5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
25757
+ if (ops.length === 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("place_seal: \uBC30\uCE58\uD560 \uB3C4\uC7A5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
25399
25758
  const u8 = new Uint8Array(hwpxBuffer);
25400
25759
  const zip = await _jszip2.default.loadAsync(hwpxBuffer);
25401
- const sectionPaths = Object.keys(zip.files).filter((name) => /[Ss]ection\d+\.xml$/i.test(name)).sort((a, b) => Number(_nullishCoalesce(_optionalChain([a, 'access', _333 => _333.match, 'call', _334 => _334(/(\d+)\.xml$/i), 'optionalAccess', _335 => _335[1]]), () => ( 0))) - Number(_nullishCoalesce(_optionalChain([b, 'access', _336 => _336.match, 'call', _337 => _337(/(\d+)\.xml$/i), 'optionalAccess', _338 => _338[1]]), () => ( 0))));
25402
- if (sectionPaths.length === 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
25760
+ const sectionPaths = Object.keys(zip.files).filter((name) => /[Ss]ection\d+\.xml$/i.test(name)).sort((a, b) => Number(_nullishCoalesce(_optionalChain([a, 'access', _381 => _381.match, 'call', _382 => _382(/(\d+)\.xml$/i), 'optionalAccess', _383 => _383[1]]), () => ( 0))) - Number(_nullishCoalesce(_optionalChain([b, 'access', _384 => _384.match, 'call', _385 => _385(/(\d+)\.xml$/i), 'optionalAccess', _386 => _386[1]]), () => ( 0))));
25761
+ if (sectionPaths.length === 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
25403
25762
  const manifestPath = Object.keys(zip.files).find((name) => /\.hpf$/i.test(name));
25404
25763
  const headerPath = Object.keys(zip.files).find((name) => /(^|\/)header\.xml$/i.test(name));
25405
25764
  const styles = headerPath ? parseRenderStyles(await zip.file(headerPath).async("text")) : null;
@@ -25440,11 +25799,11 @@ async function placeSealHwpx(hwpxBuffer, ops) {
25440
25799
  const manifestItems = [];
25441
25800
  const placed = [];
25442
25801
  for (const op of ops) {
25443
- if (!op.anchor) throw new (0, _chunk6XAAYAWLcjs.KordocError)("place_seal: anchor \uBB38\uAD6C\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4");
25444
- if (!op.image || op.image.length === 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("place_seal: \uB3C4\uC7A5 \uC774\uBBF8\uC9C0\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4");
25802
+ if (!op.anchor) throw new (0, _chunk37VKMUSTcjs.KordocError)("place_seal: anchor \uBB38\uAD6C\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4");
25803
+ if (!op.image || op.image.length === 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("place_seal: \uB3C4\uC7A5 \uC774\uBBF8\uC9C0\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4");
25445
25804
  const ext = (_nullishCoalesce(op.ext, () => ( "png"))).toLowerCase();
25446
- if (!MIME[ext]) throw new (0, _chunk6XAAYAWLcjs.KordocError)(`place_seal: \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC774\uBBF8\uC9C0 \uD655\uC7A5\uC790 .${ext} (png/jpg/bmp/gif)`);
25447
- if (!imageMagicMatches(op.image, ext)) throw new (0, _chunk6XAAYAWLcjs.KordocError)(`place_seal: \uC774\uBBF8\uC9C0 \uB0B4\uC6A9\uC774 .${ext} \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 (\uB9E4\uC9C1\uBC14\uC774\uD2B8 \uBD88\uC77C\uCE58)`);
25805
+ if (!MIME[ext]) throw new (0, _chunk37VKMUSTcjs.KordocError)(`place_seal: \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC774\uBBF8\uC9C0 \uD655\uC7A5\uC790 .${ext} (png/jpg/bmp/gif)`);
25806
+ if (!imageMagicMatches(op.image, ext)) throw new (0, _chunk37VKMUSTcjs.KordocError)(`place_seal: \uC774\uBBF8\uC9C0 \uB0B4\uC6A9\uC774 .${ext} \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 (\uB9E4\uC9C1\uBC14\uC774\uD2B8 \uBD88\uC77C\uCE58)`);
25448
25807
  const wantOcc = _nullishCoalesce(op.occurrence, () => ( 0));
25449
25808
  let found = null;
25450
25809
  let total = 0;
@@ -25477,7 +25836,7 @@ async function placeSealHwpx(hwpxBuffer, ops) {
25477
25836
  }
25478
25837
  }
25479
25838
  }
25480
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(
25839
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(
25481
25840
  `place_seal: \uC575\uCEE4 "${op.anchor}" ${wantOcc}\uBC88\uC9F8 \uB4F1\uC7A5\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4 (\uBCF8\uBB38 \uB0B4 ${total}\uD68C \uB4F1\uC7A5 \u2014 occurrence 0..${Math.max(0, total - 1)})`
25482
25841
  );
25483
25842
  }
@@ -25485,9 +25844,9 @@ async function placeSealHwpx(hwpxBuffer, ops) {
25485
25844
  const xml = sectionXmls[si];
25486
25845
  const run = anchorRunInfo(xml, site.para, op.anchor);
25487
25846
  if (!run) {
25488
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(`place_seal: \uC575\uCEE4 "${op.anchor}" \uBB38\uB2E8\uC5D0\uC11C run\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`);
25847
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(`place_seal: \uC575\uCEE4 "${op.anchor}" \uBB38\uB2E8\uC5D0\uC11C run\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`);
25489
25848
  }
25490
- const charPrHeight = _nullishCoalesce(_optionalChain([styles, 'optionalAccess', _339 => _339.charPr, 'access', _340 => _340.get, 'call', _341 => _341(run.charPr), 'optionalAccess', _342 => _342.height]), () => ( 1e3));
25849
+ const charPrHeight = _nullishCoalesce(_optionalChain([styles, 'optionalAccess', _387 => _387.charPr, 'access', _388 => _388.get, 'call', _389 => _389(run.charPr), 'optionalAccess', _390 => _390.height]), () => ( 1e3));
25491
25850
  const fontPt = charPrHeight / 100;
25492
25851
  const emMm = fontPt * 25.4 / 72;
25493
25852
  const lineHMm = emMm;
@@ -25496,7 +25855,7 @@ async function placeSealHwpx(hwpxBuffer, ops) {
25496
25855
  const sizeMm = op.sizeMm != null && Number.isFinite(op.sizeMm) && op.sizeMm > 0 ? op.sizeMm : Math.max(7, Math.min(18, lineHMm * 1.6));
25497
25856
  const availMm = _nullishCoalesce((site.cell ? cellContentWidthMm(xml, site.cell) : null), () => ( bodyColumnWidthMm(xml)));
25498
25857
  const paraPrId = _nullishCoalesce(attrOf(paraOpenTag(xml, site.para), "paraPrIDRef"), () => ( "0"));
25499
- const align = _optionalChain([styles, 'optionalAccess', _343 => _343.paraAlign, 'access', _344 => _344.get, 'call', _345 => _345(paraPrId)]);
25858
+ const align = _optionalChain([styles, 'optionalAccess', _391 => _391.paraAlign, 'access', _392 => _392.get, 'call', _393 => _393(paraPrId)]);
25500
25859
  let alignShiftMm = 0;
25501
25860
  if (align === "CENTER" || align === "RIGHT") {
25502
25861
  const paraWMm = measureMm(site.para.text, emMm);
@@ -25592,7 +25951,7 @@ function parseBorderFills(headerDoc) {
25592
25951
  };
25593
25952
  const fillBrush = findChildByLocalName(bf, "fillBrush");
25594
25953
  const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
25595
- const face = _optionalChain([winBrush, 'optionalAccess', _346 => _346.getAttribute, 'call', _347 => _347("faceColor")]);
25954
+ const face = _optionalChain([winBrush, 'optionalAccess', _394 => _394.getAttribute, 'call', _395 => _395("faceColor")]);
25596
25955
  if (face && face !== "none") def.fill = { faceColor: face };
25597
25956
  map.set(id, def);
25598
25957
  }
@@ -25624,7 +25983,7 @@ function parseCharPrs(headerDoc, hangulFonts) {
25624
25983
  if (cp.getAttribute("italic") === "1") def.italic = true;
25625
25984
  if (findChildByLocalName(cp, "underline")) def.underline = true;
25626
25985
  const fontRef = findChildByLocalName(cp, "fontRef");
25627
- const hangul = _optionalChain([fontRef, 'optionalAccess', _348 => _348.getAttribute, 'call', _349 => _349("hangul")]);
25986
+ const hangul = _optionalChain([fontRef, 'optionalAccess', _396 => _396.getAttribute, 'call', _397 => _397("hangul")]);
25628
25987
  if (hangul) {
25629
25988
  def.fontRef_hangul = hangul;
25630
25989
  const face = hangulFonts.get(hangul);
@@ -25652,7 +26011,7 @@ function parseTable3(tbl2, tableIndex, borderFills, charPrs) {
25652
26011
  const rows = _nullishCoalesce(num(tbl2.getAttribute("rowCnt")), () => ( 0));
25653
26012
  const cols = _nullishCoalesce(num(tbl2.getAttribute("colCnt")), () => ( 0));
25654
26013
  const sz = findChildByLocalName(tbl2, "sz");
25655
- const width = _optionalChain([sz, 'optionalAccess', _350 => _350.getAttribute, 'call', _351 => _351("width")]) || void 0;
26014
+ const width = _optionalChain([sz, 'optionalAccess', _398 => _398.getAttribute, 'call', _399 => _399("width")]) || void 0;
25656
26015
  const cells = [];
25657
26016
  const usedBf = /* @__PURE__ */ new Set();
25658
26017
  const usedCp = /* @__PURE__ */ new Set();
@@ -25665,17 +26024,17 @@ function parseTable3(tbl2, tableIndex, borderFills, charPrs) {
25665
26024
  const addr = findChildByLocalName(tc2, "cellAddr");
25666
26025
  const span = findChildByLocalName(tc2, "cellSpan");
25667
26026
  const csz = findChildByLocalName(tc2, "cellSz");
25668
- const row = _nullishCoalesce(num(_optionalChain([addr, 'optionalAccess', _352 => _352.getAttribute, 'call', _353 => _353("rowAddr")])), () => ( 0));
25669
- const col = _nullishCoalesce(num(_optionalChain([addr, 'optionalAccess', _354 => _354.getAttribute, 'call', _355 => _355("colAddr")])), () => ( 0));
26027
+ const row = _nullishCoalesce(num(_optionalChain([addr, 'optionalAccess', _400 => _400.getAttribute, 'call', _401 => _401("rowAddr")])), () => ( 0));
26028
+ const col = _nullishCoalesce(num(_optionalChain([addr, 'optionalAccess', _402 => _402.getAttribute, 'call', _403 => _403("colAddr")])), () => ( 0));
25670
26029
  if (row === 0 && col === 0 && !anchorText) anchorText = directCellText(tc2);
25671
26030
  if (row === 0) row0Texts.set(col, directCellText(tc2));
25672
- const colSpan = _nullishCoalesce(num(_optionalChain([span, 'optionalAccess', _356 => _356.getAttribute, 'call', _357 => _357("colSpan")])), () => ( 1));
25673
- const rowSpan = _nullishCoalesce(num(_optionalChain([span, 'optionalAccess', _358 => _358.getAttribute, 'call', _359 => _359("rowSpan")])), () => ( 1));
26031
+ const colSpan = _nullishCoalesce(num(_optionalChain([span, 'optionalAccess', _404 => _404.getAttribute, 'call', _405 => _405("colSpan")])), () => ( 1));
26032
+ const rowSpan = _nullishCoalesce(num(_optionalChain([span, 'optionalAccess', _406 => _406.getAttribute, 'call', _407 => _407("rowSpan")])), () => ( 1));
25674
26033
  const bfId = tc2.getAttribute("borderFillIDRef") || void 0;
25675
26034
  const cpId = firstRunCharPr(tc2);
25676
26035
  const cell2 = { row, col, rowSpan, colSpan };
25677
- const w = _optionalChain([csz, 'optionalAccess', _360 => _360.getAttribute, 'call', _361 => _361("width")]);
25678
- const hh = _optionalChain([csz, 'optionalAccess', _362 => _362.getAttribute, 'call', _363 => _363("height")]);
26036
+ const w = _optionalChain([csz, 'optionalAccess', _408 => _408.getAttribute, 'call', _409 => _409("width")]);
26037
+ const hh = _optionalChain([csz, 'optionalAccess', _410 => _410.getAttribute, 'call', _411 => _411("height")]);
25679
26038
  if (w) cell2.width_hwpunit = w;
25680
26039
  if (hh) cell2.height_hwpunit = hh;
25681
26040
  if (bfId) {
@@ -25763,16 +26122,16 @@ function pick(map, keys) {
25763
26122
  return out;
25764
26123
  }
25765
26124
  async function hwpxToProfile(input) {
25766
- const buf = input instanceof ArrayBuffer ? input : _chunk6XAAYAWLcjs.toArrayBuffer.call(void 0, input);
26125
+ const buf = input instanceof ArrayBuffer ? input : _chunk37VKMUSTcjs.toArrayBuffer.call(void 0, input);
25767
26126
  const zip = await _jszip2.default.loadAsync(buf);
25768
26127
  const parser = createXmlParser();
25769
- const headerFile = _nullishCoalesce(zip.file("Contents/header.xml"), () => ( _optionalChain([zip, 'access', _364 => _364.file, 'call', _365 => _365(/[Hh]eader\.xml$/), 'optionalAccess', _366 => _366[0]])));
26128
+ const headerFile = _nullishCoalesce(zip.file("Contents/header.xml"), () => ( _optionalChain([zip, 'access', _412 => _412.file, 'call', _413 => _413(/[Hh]eader\.xml$/), 'optionalAccess', _414 => _414[0]])));
25770
26129
  let headerXml = "<root/>";
25771
26130
  if (headerFile) headerXml = await headerFile.async("text");
25772
26131
  const headerDoc = parser.parseFromString(headerXml, "text/xml");
25773
26132
  const borderFills = parseBorderFills(headerDoc);
25774
26133
  const charPrs = parseCharPrs(headerDoc, parseHangulFonts(headerDoc));
25775
- const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/).sort((a, b) => (_nullishCoalesce(num(_nullishCoalesce(_optionalChain([a, 'access', _367 => _367.name, 'access', _368 => _368.match, 'call', _369 => _369(/(\d+)\.xml$/), 'optionalAccess', _370 => _370[1]]), () => ( null))), () => ( 0))) - (_nullishCoalesce(num(_nullishCoalesce(_optionalChain([b, 'access', _371 => _371.name, 'access', _372 => _372.match, 'call', _373 => _373(/(\d+)\.xml$/), 'optionalAccess', _374 => _374[1]]), () => ( null))), () => ( 0))));
26134
+ const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/).sort((a, b) => (_nullishCoalesce(num(_nullishCoalesce(_optionalChain([a, 'access', _415 => _415.name, 'access', _416 => _416.match, 'call', _417 => _417(/(\d+)\.xml$/), 'optionalAccess', _418 => _418[1]]), () => ( null))), () => ( 0))) - (_nullishCoalesce(num(_nullishCoalesce(_optionalChain([b, 'access', _419 => _419.name, 'access', _420 => _420.match, 'call', _421 => _421(/(\d+)\.xml$/), 'optionalAccess', _422 => _422[1]]), () => ( null))), () => ( 0))));
25776
26135
  const tables = [];
25777
26136
  let tableIndex = 0;
25778
26137
  for (const f of sectionFiles) {
@@ -26086,7 +26445,7 @@ var ROW_OBJECT_RE = /<(?:[A-Za-z0-9_]+:)?(?:tbl|pic|equation|ole|container|shape
26086
26445
  var TAG_AT_RE = /<[A-Za-z0-9_:]+(?:"[^"]*"|'[^']*'|[^>"'])*>/y;
26087
26446
  function patchTableRows(input) {
26088
26447
  const { table: table2, scanTable, ctx, skip, origKeys, editedKeys } = input;
26089
- const xml = _optionalChain([ctx, 'access', _375 => _375.scans, 'access', _376 => _376[scanTable.sectionIndex], 'optionalAccess', _377 => _377.xml]);
26448
+ const xml = _optionalChain([ctx, 'access', _423 => _423.scans, 'access', _424 => _424[scanTable.sectionIndex], 'optionalAccess', _425 => _425.xml]);
26090
26449
  if (!xml) return skip("\uC139\uC158 XML \uB9E4\uD551 \uC2E4\uD328");
26091
26450
  const numRows = table2.rows;
26092
26451
  if (origKeys.length !== numRows) return skip("\uD45C \uD589 \uC88C\uD45C \uBD88\uC77C\uCE58 \u2014 \uD589 \uCD94\uAC00/\uC0AD\uC81C \uBBF8\uC9C0\uC6D0");
@@ -26253,7 +26612,7 @@ function buildRowFragment(xml, scanTable, template, cells, finalRow, hasExplicit
26253
26612
  const rr = scanTable.rowRanges[template];
26254
26613
  const wrapped = FRAG_OPEN + xml.slice(rr.start, rr.end) + FRAG_CLOSE;
26255
26614
  const scan = scanSectionXml(wrapped, 0);
26256
- const row = _optionalChain([scan, 'access', _378 => _378.tables, 'access', _379 => _379[0], 'optionalAccess', _380 => _380.rows, 'access', _381 => _381[0]]);
26615
+ const row = _optionalChain([scan, 'access', _426 => _426.tables, 'access', _427 => _427[0], 'optionalAccess', _428 => _428.rows, 'access', _429 => _429[0]]);
26257
26616
  if (!row || row.length !== cells.length) return null;
26258
26617
  const splices = allLinesegRemovalSplices(wrapped);
26259
26618
  for (let i = 0; i < cells.length; i++) {
@@ -26296,7 +26655,7 @@ function rowHeightOf(fragment) {
26296
26655
  }
26297
26656
  function tableSzHeightSplice(xml, scanTable, tblOpenLen, delta) {
26298
26657
  const from = scanTable.start + tblOpenLen;
26299
- const to = _nullishCoalesce(_optionalChain([scanTable, 'access', _382 => _382.rowRanges, 'access', _383 => _383[0], 'optionalAccess', _384 => _384.start]), () => ( from));
26658
+ const to = _nullishCoalesce(_optionalChain([scanTable, 'access', _430 => _430.rowRanges, 'access', _431 => _431[0], 'optionalAccess', _432 => _432.start]), () => ( from));
26300
26659
  const slice = xml.slice(from, to);
26301
26660
  const szM = slice.match(/<(?:[A-Za-z0-9_]+:)?sz\b(?:"[^"]*"|'[^']*'|[^>"'])*>/);
26302
26661
  if (!szM || szM.index === void 0) return null;
@@ -26485,9 +26844,9 @@ function patchHtmlTableRows(table2, scanTable, replica, editedRows, ctx, skip, d
26485
26844
  });
26486
26845
  }
26487
26846
  function patchNestedTables(table2, scanTable, oc, origTables, editedTables, ctx, skip, depth) {
26488
- const irCell = _optionalChain([table2, 'access', _385 => _385.cells, 'access', _386 => _386[oc.gridR], 'optionalAccess', _387 => _387[oc.gridC]]);
26847
+ const irCell = _optionalChain([table2, 'access', _433 => _433.cells, 'access', _434 => _434[oc.gridR], 'optionalAccess', _435 => _435[oc.gridC]]);
26489
26848
  const scanCell = scanTable.cellByAnchor.get(`${oc.gridR},${oc.gridC}`);
26490
- const nestedIRs = (_nullishCoalesce(_optionalChain([irCell, 'optionalAccess', _388 => _388.blocks]), () => ( []))).filter((b) => b.type === "table" && b.table).map((b) => b.table);
26849
+ const nestedIRs = (_nullishCoalesce(_optionalChain([irCell, 'optionalAccess', _436 => _436.blocks]), () => ( []))).filter((b) => b.type === "table" && b.table).map((b) => b.table);
26491
26850
  if (!scanCell || nestedIRs.length !== origTables.length || scanCell.tables.length !== origTables.length) {
26492
26851
  return skip("\uC911\uCCA9\uD45C \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328");
26493
26852
  }
@@ -26555,7 +26914,7 @@ function applyCellEdit(table2, scanTable, gridR, gridC, newLines, ctx, before, a
26555
26914
  };
26556
26915
  const cell2 = scanTable.cellByAnchor.get(`${gridR},${gridC}`);
26557
26916
  if (!cell2) return skip("\uC140 \uC88C\uD45C \uB9E4\uD551 \uC2E4\uD328 (\uBCD1\uD569 \uC601\uC5ED\uC758 \uBE48 \uCE78\uC774\uAC70\uB098 \uC88C\uD45C \uBD88\uC77C\uCE58)");
26558
- const irCell = _optionalChain([table2, 'access', _389 => _389.cells, 'access', _390 => _390[gridR], 'optionalAccess', _391 => _391[gridC]]);
26917
+ const irCell = _optionalChain([table2, 'access', _437 => _437.cells, 'access', _438 => _438[gridR], 'optionalAccess', _439 => _439[gridC]]);
26559
26918
  const scanJoined = cell2.paragraphs.map((p) => p.text).filter((t) => normForMatch(t)).join("\n");
26560
26919
  if (irCell && normForMatch(scanJoined) !== normForMatch(stripCellTokens(irCell.text))) {
26561
26920
  if (normForMatch(irCell.text) !== "" || normForMatch(scanJoined) !== "") {
@@ -26578,7 +26937,7 @@ function applyCellEdit(table2, scanTable, gridR, gridC, newLines, ctx, before, a
26578
26937
  if (newLines.length === 0) return 0;
26579
26938
  const target = cell2.paragraphs[0];
26580
26939
  if (!target) return skip("\uBE48 \uC140\uC5D0 \uBB38\uB2E8\uC774 \uC5C6\uC5B4 \uD14D\uC2A4\uD2B8 \uC0BD\uC785 \uBD88\uAC00");
26581
- const sp = buildParagraphSplices(target, newLines.join(" "), _optionalChain([ctx, 'access', _392 => _392.scans, 'access', _393 => _393[target.sectionIndex], 'optionalAccess', _394 => _394.xml]));
26940
+ const sp = buildParagraphSplices(target, newLines.join(" "), _optionalChain([ctx, 'access', _440 => _440.scans, 'access', _441 => _441[target.sectionIndex], 'optionalAccess', _442 => _442.xml]));
26582
26941
  if (sp === null) return skip("\uC140 \uBB38\uB2E8\uC5D0 \uD14D\uC2A4\uD2B8 \uB178\uB4DC\uB97C \uB9CC\uB4E4 \uC218 \uC5C6\uC74C");
26583
26942
  splices.push(...sp);
26584
26943
  sectionIndex = target.sectionIndex;
@@ -26601,7 +26960,7 @@ function applyCellEdit(table2, scanTable, gridR, gridC, newLines, ctx, before, a
26601
26960
  }
26602
26961
  for (let i = 0; i < nonEmpty.length; i++) {
26603
26962
  if (assigned[i] === nonEmpty[i].text || normForMatch(assigned[i]) === normForMatch(nonEmpty[i].text)) continue;
26604
- const sp = buildParagraphSplices(nonEmpty[i], assigned[i], _optionalChain([ctx, 'access', _395 => _395.scans, 'access', _396 => _396[nonEmpty[i].sectionIndex], 'optionalAccess', _397 => _397.xml]));
26963
+ const sp = buildParagraphSplices(nonEmpty[i], assigned[i], _optionalChain([ctx, 'access', _443 => _443.scans, 'access', _444 => _444[nonEmpty[i].sectionIndex], 'optionalAccess', _445 => _445.xml]));
26605
26964
  if (sp === null) return skip("\uC140 \uBB38\uB2E8\uC5D0 \uD14D\uC2A4\uD2B8 \uB178\uB4DC\uB97C \uB9CC\uB4E4 \uC218 \uC5C6\uC74C");
26606
26965
  splices.push(...sp);
26607
26966
  sectionIndex = nonEmpty[i].sectionIndex;
@@ -26682,7 +27041,7 @@ async function resolveSectionEntryNames(zip) {
26682
27041
  const paths = sectionPathsFromManifest(xml).filter((p) => zip.file(p) !== null);
26683
27042
  if (paths.length > 0) return paths;
26684
27043
  }
26685
- return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunk6XAAYAWLcjs.compareSectionPaths);
27044
+ return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunk37VKMUSTcjs.compareSectionPaths);
26686
27045
  }
26687
27046
  function sectionPathsFromManifest(xml) {
26688
27047
  const attr = (tag, name) => {
@@ -26692,7 +27051,7 @@ function sectionPathsFromManifest(xml) {
26692
27051
  const idToHref = /* @__PURE__ */ new Map();
26693
27052
  for (const m of xml.matchAll(/<opf:item(\s(?:"[^"]*"|'[^']*'|[^>"'])*?)\/?>/g)) {
26694
27053
  const id = attr(m[1], "id");
26695
- const href = _chunk6XAAYAWLcjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
27054
+ const href = _chunk37VKMUSTcjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
26696
27055
  if (id && href) idToHref.set(id, href);
26697
27056
  }
26698
27057
  const ordered = [];
@@ -26701,7 +27060,7 @@ function sectionPathsFromManifest(xml) {
26701
27060
  if (href) ordered.push(href);
26702
27061
  }
26703
27062
  if (ordered.length > 0) return ordered;
26704
- return Array.from(idToHref.values()).sort(_chunk6XAAYAWLcjs.compareSectionPaths);
27063
+ return Array.from(idToHref.values()).sort(_chunk37VKMUSTcjs.compareSectionPaths);
26705
27064
  }
26706
27065
 
26707
27066
  // src/roundtrip/patcher.ts
@@ -26718,7 +27077,7 @@ async function patchHwpx(original, editedMarkdown, options) {
26718
27077
  let zip;
26719
27078
  try {
26720
27079
  zip = await _jszip2.default.loadAsync(original);
26721
- } catch (e30) {
27080
+ } catch (e31) {
26722
27081
  return { success: false, applied: 0, skipped, error: "ZIP \uB85C\uB4DC \uC2E4\uD328" };
26723
27082
  }
26724
27083
  const sectionPaths = await resolveSectionEntryNames(zip);
@@ -26793,7 +27152,7 @@ async function patchHwpx(original, editedMarkdown, options) {
26793
27152
  }
26794
27153
  }
26795
27154
  let verification;
26796
- if (_optionalChain([options, 'optionalAccess', _398 => _398.verify]) !== false) {
27155
+ if (_optionalChain([options, 'optionalAccess', _446 => _446.verify]) !== false) {
26797
27156
  try {
26798
27157
  const reparsed = await parseHwpxDocument(u8ToArrayBuffer(data));
26799
27158
  verification = diffUnitLists(splitMarkdownUnits(reparsed.markdown), editedUnits);
@@ -26811,17 +27170,17 @@ function buildOrigUnits(blocks) {
26811
27170
  let chunk;
26812
27171
  if (block.type === "paragraph" && block.text && /^\[별표\s*\d+/.test(sanitizeText(block.text))) {
26813
27172
  const next = blocks[i + 1];
26814
- if (_optionalChain([next, 'optionalAccess', _399 => _399.type]) === "paragraph" && next.text && /관련\)?$/.test(next.text)) consume = 2;
26815
- chunk = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
27173
+ if (_optionalChain([next, 'optionalAccess', _447 => _447.type]) === "paragraph" && next.text && /관련\)?$/.test(next.text)) consume = 2;
27174
+ chunk = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
26816
27175
  } else {
26817
- chunk = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, [block]);
27176
+ chunk = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, [block]);
26818
27177
  }
26819
27178
  if (chunk) {
26820
27179
  const subUnits = splitMarkdownUnits(chunk);
26821
27180
  const isFragment = consume === 2 || (block.type === "paragraph" || block.type === "heading") && subUnits.length > 1;
26822
27181
  for (let s = 0; s < subUnits.length; s++) {
26823
27182
  const u = { ...subUnits[s], blockIdx: i, fragment: isFragment || void 0 };
26824
- if (block.type === "table" && _optionalChain([block, 'access', _400 => _400.table, 'optionalAccess', _401 => _401.caption]) && s === 0 && subUnits.length > 1 && u.kind === "text" && u.raw.startsWith("**")) {
27183
+ if (block.type === "table" && _optionalChain([block, 'access', _448 => _448.table, 'optionalAccess', _449 => _449.caption]) && s === 0 && subUnits.length > 1 && u.kind === "text" && u.raw.startsWith("**")) {
26825
27184
  u.role = "caption";
26826
27185
  }
26827
27186
  units.push(u);
@@ -26932,7 +27291,7 @@ function convertParagraphToTable(block, orig, edited, ctx, skip) {
26932
27291
  const ti = ctx.tableInsert;
26933
27292
  if (!ti) return skip("\uBB38\uB2E8\u2192\uD45C \uBCC0\uD658 \uBD88\uAC00 \u2014 header \uC5D4\uD2B8\uB9AC(borderFills) \uD574\uC11D \uC2E4\uD328");
26934
27293
  const mapping = ctx.paraMap.get(orig.blockIdx);
26935
- if (!_optionalChain([mapping, 'optionalAccess', _402 => _402.para])) return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED) \u2014 \uD45C \uBCC0\uD658 \uBD88\uAC00");
27294
+ if (!_optionalChain([mapping, 'optionalAccess', _450 => _450.para])) return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED) \u2014 \uD45C \uBCC0\uD658 \uBD88\uAC00");
26936
27295
  const para2 = mapping.para;
26937
27296
  if (para2.kind !== "body") return skip("\uBCF8\uBB38 \uC678 \uC601\uC5ED(\uD45C \uC140/\uAE00\uC0C1\uC790) \uBB38\uB2E8\uC758 \uD45C \uBCC0\uD658\uC740 \uBBF8\uC9C0\uC6D0");
26938
27297
  const scan = ctx.scans[para2.sectionIndex];
@@ -26960,7 +27319,7 @@ function convertParagraphToTable(block, orig, edited, ctx, skip) {
26960
27319
  }
26961
27320
  function patchParagraphUnit(block, orig, edited, ctx, skip) {
26962
27321
  const mapping = ctx.paraMap.get(orig.blockIdx);
26963
- if (!_optionalChain([mapping, 'optionalAccess', _403 => _403.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)");
27322
+ if (!_optionalChain([mapping, 'optionalAccess', _451 => _451.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)");
26964
27323
  if (block.text && block.text.includes("\n")) {
26965
27324
  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)");
26966
27325
  }
@@ -26991,7 +27350,7 @@ function patchParagraphUnit(block, orig, edited, ctx, skip) {
26991
27350
  if (sanitizeText(newPlain) !== newPlain) {
26992
27351
  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");
26993
27352
  }
26994
- const splices = buildParagraphSplices(mapping.para, newPlain, _optionalChain([ctx, 'access', _404 => _404.scans, 'access', _405 => _405[mapping.para.sectionIndex], 'optionalAccess', _406 => _406.xml]));
27353
+ const splices = buildParagraphSplices(mapping.para, newPlain, _optionalChain([ctx, 'access', _452 => _452.scans, 'access', _453 => _453[mapping.para.sectionIndex], 'optionalAccess', _454 => _454.xml]));
26995
27354
  if (splices === null) return skip("\uBB38\uB2E8\uC5D0 \uD14D\uC2A4\uD2B8 \uB178\uB4DC\uB97C \uB9CC\uB4E4 \uC218 \uC5C6\uC74C");
26996
27355
  ctx.sectionSplices[mapping.para.sectionIndex].push(...splices);
26997
27356
  return 1;
@@ -27084,7 +27443,10 @@ var Surgeon = (_class7 = class {
27084
27443
  __init16() {this.miniFatSectors = []}
27085
27444
  __init17() {this.dirSectors = []}
27086
27445
  __init18() {this.entries = []}
27087
- constructor(file) {;_class7.prototype.__init13.call(this);_class7.prototype.__init14.call(this);_class7.prototype.__init15.call(this);_class7.prototype.__init16.call(this);_class7.prototype.__init17.call(this);_class7.prototype.__init18.call(this);
27446
+ /** replace() FREESECT로 해제한 섹터 — finish()에서 재할당 안 된 것만 0으로 지움 (데이터 잔존 방지) */
27447
+ __init19() {this.freedSectors = []}
27448
+ __init20() {this.freedMiniSectors = []}
27449
+ constructor(file) {;_class7.prototype.__init13.call(this);_class7.prototype.__init14.call(this);_class7.prototype.__init15.call(this);_class7.prototype.__init16.call(this);_class7.prototype.__init17.call(this);_class7.prototype.__init18.call(this);_class7.prototype.__init19.call(this);_class7.prototype.__init20.call(this);
27088
27450
  if (file.length < SECTOR || file.readUInt32LE(0) !== 3759263696) {
27089
27451
  throw new OleSurgeonError("OLE \uC2DC\uADF8\uB2C8\uCC98\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
27090
27452
  }
@@ -27177,7 +27539,7 @@ var Surgeon = (_class7 = class {
27177
27539
  /** 디렉토리 트리에서 경로 해석 (형제 = L/R 이진 트리, 자식 = child) */
27178
27540
  findEntry(path) {
27179
27541
  const parts = path.replace(/^\//, "").split("/");
27180
- let scope = _nullishCoalesce(_optionalChain([this, 'access', _407 => _407.entries, 'access', _408 => _408[0], 'optionalAccess', _409 => _409.child]), () => ( -1));
27542
+ let scope = _nullishCoalesce(_optionalChain([this, 'access', _455 => _455.entries, 'access', _456 => _456[0], 'optionalAccess', _457 => _457.child]), () => ( -1));
27181
27543
  let current;
27182
27544
  for (const part of parts) {
27183
27545
  const search = (idx) => {
@@ -27207,6 +27569,8 @@ var Surgeon = (_class7 = class {
27207
27569
  if (this.fat[i] !== FREESECT) continue;
27208
27570
  if (SECTOR + (i + 1) * SECTOR > this.buf.length) continue;
27209
27571
  this.fat[i] = ENDOFCHAIN;
27572
+ const off = this.sectorOffset(i);
27573
+ this.buf.fill(0, off, off + SECTOR);
27210
27574
  out.push(i);
27211
27575
  }
27212
27576
  while (out.length < n) {
@@ -27306,9 +27670,15 @@ var Surgeon = (_class7 = class {
27306
27670
  const entry = this.findEntry(path);
27307
27671
  if (entry.size > 0 && entry.start !== ENDOFCHAIN) {
27308
27672
  if (entry.size < MINI_CUTOFF) {
27309
- for (const s of this.miniChain(entry.start)) this.miniFat[s] = FREESECT;
27673
+ for (const s of this.miniChain(entry.start)) {
27674
+ this.miniFat[s] = FREESECT;
27675
+ this.freedMiniSectors.push(s);
27676
+ }
27310
27677
  } else {
27311
- for (const s of this.chain(entry.start)) this.fat[s] = FREESECT;
27678
+ for (const s of this.chain(entry.start)) {
27679
+ this.fat[s] = FREESECT;
27680
+ this.freedSectors.push(s);
27681
+ }
27312
27682
  }
27313
27683
  }
27314
27684
  if (newData.length < MINI_CUTOFF) {
@@ -27337,9 +27707,27 @@ var Surgeon = (_class7 = class {
27337
27707
  this.writeDirEntry(entry);
27338
27708
  }
27339
27709
  finish() {
27710
+ this.wipeFreedSectors();
27340
27711
  this.flushFat();
27341
27712
  return this.buf;
27342
27713
  }
27714
+ /** 해제 후 재할당되지 않고 남은 FREESECT 섹터의 바이트를 0으로 채움 (데이터 remanence 제거) */
27715
+ wipeFreedSectors() {
27716
+ for (const s of this.freedSectors) {
27717
+ if (this.fat[s] !== FREESECT) continue;
27718
+ const off = this.sectorOffset(s);
27719
+ this.buf.fill(0, off, off + SECTOR);
27720
+ }
27721
+ if (this.freedMiniSectors.length > 0) {
27722
+ const root = this.rootEntry();
27723
+ const rootChain = root.start === ENDOFCHAIN || root.size === 0 ? [] : this.chain(root.start);
27724
+ for (const s of this.freedMiniSectors) {
27725
+ if (this.miniFat[s] !== FREESECT) continue;
27726
+ const off = this.miniOffset(s, rootChain);
27727
+ this.buf.fill(0, off, off + MINI_SECTOR);
27728
+ }
27729
+ }
27730
+ }
27343
27731
  }, _class7);
27344
27732
 
27345
27733
  // src/roundtrip/hwp5-patch.ts
@@ -27390,8 +27778,8 @@ function serializeRecords(recs, repl, inserts) {
27390
27778
  parts.push(header, data);
27391
27779
  };
27392
27780
  for (let i = 0; i < recs.length; i++) {
27393
- for (const ins of _nullishCoalesce(_optionalChain([inserts, 'optionalAccess', _410 => _410.get, 'call', _411 => _411(i)]), () => ( []))) push(ins.tagId, ins.level, ins.data);
27394
- push(recs[i].tagId, recs[i].level, _nullishCoalesce(_optionalChain([repl, 'optionalAccess', _412 => _412.get, 'call', _413 => _413(i)]), () => ( recs[i].data)));
27781
+ for (const ins of _nullishCoalesce(_optionalChain([inserts, 'optionalAccess', _458 => _458.get, 'call', _459 => _459(i)]), () => ( []))) push(ins.tagId, ins.level, ins.data);
27782
+ push(recs[i].tagId, recs[i].level, _nullishCoalesce(_optionalChain([repl, 'optionalAccess', _460 => _460.get, 'call', _461 => _461(i)]), () => ( recs[i].data)));
27395
27783
  }
27396
27784
  return Buffer.concat(parts);
27397
27785
  }
@@ -27509,7 +27897,7 @@ async function patchHwp(original, editedMarkdown, options) {
27509
27897
  return fail(`CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328: ${msg(err)}`);
27510
27898
  }
27511
27899
  const fhEntry = CFB2.find(cfb, "/FileHeader");
27512
- if (!_optionalChain([fhEntry, 'optionalAccess', _414 => _414.content])) return fail("FileHeader \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 HWP 5.x \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4");
27900
+ if (!_optionalChain([fhEntry, 'optionalAccess', _462 => _462.content])) return fail("FileHeader \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 HWP 5.x \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4");
27513
27901
  let flags;
27514
27902
  try {
27515
27903
  flags = parseFileHeader(Buffer.from(fhEntry.content)).flags;
@@ -27531,7 +27919,7 @@ async function patchHwp(original, editedMarkdown, options) {
27531
27919
  const scans = [];
27532
27920
  for (let i = 0; i < sectionPaths.length; i++) {
27533
27921
  const entry = CFB2.find(cfb, sectionPaths[i]);
27534
- if (!_optionalChain([entry, 'optionalAccess', _415 => _415.content])) return fail(`\uC139\uC158 \uC2A4\uD2B8\uB9BC \uC77D\uAE30 \uC2E4\uD328: ${sectionPaths[i]}`);
27922
+ if (!_optionalChain([entry, 'optionalAccess', _463 => _463.content])) return fail(`\uC139\uC158 \uC2A4\uD2B8\uB9BC \uC77D\uAE30 \uC2E4\uD328: ${sectionPaths[i]}`);
27535
27923
  let stream;
27536
27924
  try {
27537
27925
  stream = compressed ? decompressStream(Buffer.from(entry.content)) : Buffer.from(entry.content);
@@ -27582,7 +27970,7 @@ async function patchHwp(original, editedMarkdown, options) {
27582
27970
  }
27583
27971
  }
27584
27972
  let verification;
27585
- if (_optionalChain([options, 'optionalAccess', _416 => _416.verify]) !== false) {
27973
+ if (_optionalChain([options, 'optionalAccess', _464 => _464.verify]) !== false) {
27586
27974
  try {
27587
27975
  const reparsed = parseHwp5Document(Buffer.from(data));
27588
27976
  const normBr = (u) => ({ ...u, raw: u.raw.replace(/<br\s*\/?\s*>/gi, "\n") });
@@ -27672,7 +28060,7 @@ function tableContentScore(irTable, scanTable) {
27672
28060
  for (const [key, scanCell] of scanTable.cells) {
27673
28061
  const comma = key.indexOf(",");
27674
28062
  const r = Number(key.slice(0, comma)), c = Number(key.slice(comma + 1));
27675
- const irCell = _optionalChain([irTable, 'access', _417 => _417.cells, 'access', _418 => _418[r], 'optionalAccess', _419 => _419[c]]);
28063
+ const irCell = _optionalChain([irTable, 'access', _465 => _465.cells, 'access', _466 => _466[r], 'optionalAccess', _467 => _467[c]]);
27676
28064
  if (!irCell) continue;
27677
28065
  const a = normForMatch(scanCell.paras.map((p) => p.rawText).join(" "));
27678
28066
  const b = normForMatch(stripCellTokens(irCell.text));
@@ -27708,7 +28096,7 @@ function handleModified(orig, edited, ctx) {
27708
28096
  }
27709
28097
  function patchParagraph(block, orig, edited, ctx, skip) {
27710
28098
  const mapping = ctx.paraMap.get(orig.blockIdx);
27711
- if (!_optionalChain([mapping, 'optionalAccess', _420 => _420.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)");
28099
+ if (!_optionalChain([mapping, 'optionalAccess', _468 => _468.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)");
27712
28100
  const restoreBr = (s) => s.replace(/(?:\s*<br\s*\/?\s*>\s*)+/gi, "\n");
27713
28101
  let newPlain = restoreBr(textUnitToPlain(edited.raw, block));
27714
28102
  if (block.text && block.text.includes("\n") && !newPlain.includes("\n")) {
@@ -27907,7 +28295,7 @@ function applyCellEdit5(table2, scanTable, gridR, gridC, newLines, ctx, before,
27907
28295
  };
27908
28296
  const cell2 = scanTable.cells.get(`${gridR},${gridC}`);
27909
28297
  if (!cell2) return skip("\uC140 \uC88C\uD45C \uB9E4\uD551 \uC2E4\uD328 (\uBCD1\uD569 \uC601\uC5ED\uC758 \uBE48 \uCE78\uC774\uAC70\uB098 \uC88C\uD45C \uBD88\uC77C\uCE58)");
27910
- const irCell = _optionalChain([table2, 'access', _421 => _421.cells, 'access', _422 => _422[gridR], 'optionalAccess', _423 => _423[gridC]]);
28298
+ const irCell = _optionalChain([table2, 'access', _469 => _469.cells, 'access', _470 => _470[gridR], 'optionalAccess', _471 => _471[gridC]]);
27911
28299
  const scanJoined = cell2.paras.map((p) => p.rawText).filter((t) => normForMatch(t)).join("\n");
27912
28300
  if (irCell && normForMatch(scanJoined) !== normForMatch(stripCellTokens(irCell.text))) {
27913
28301
  if (normForMatch(irCell.text) !== "" || normForMatch(scanJoined) !== "") {
@@ -28224,6 +28612,216 @@ async function validateHwpx(buffer) {
28224
28612
  return { ok: issues.length === 0, issues, entryCount: names.length };
28225
28613
  }
28226
28614
 
28615
+ // src/redact.ts
28616
+ var DEFAULT_REDACT_RULES = [
28617
+ "rrn",
28618
+ "phone",
28619
+ "email",
28620
+ "card",
28621
+ "account"
28622
+ ];
28623
+ var RULE_PRIORITY = [
28624
+ "rrn",
28625
+ "email",
28626
+ "card",
28627
+ "phone",
28628
+ "driver",
28629
+ "account",
28630
+ "passport"
28631
+ ];
28632
+ function luhnValid(digits) {
28633
+ let sum = 0;
28634
+ for (let i = 0; i < digits.length; i++) {
28635
+ let d = digits.charCodeAt(digits.length - 1 - i) - 48;
28636
+ if (i % 2 === 1) {
28637
+ d *= 2;
28638
+ if (d > 9) d -= 9;
28639
+ }
28640
+ sum += d;
28641
+ }
28642
+ return sum % 10 === 0;
28643
+ }
28644
+ function birthdateValid(front6) {
28645
+ const mm = Number(front6.slice(2, 4));
28646
+ const dd = Number(front6.slice(4, 6));
28647
+ return mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31;
28648
+ }
28649
+ var RULES2 = {
28650
+ // 주민/외국인등록번호 — 뒷자리 첫 숫자 1-8 + 생년월일 유효성으로 오탐 축소.
28651
+ // 유니코드 대시 변형(‐ ‑ – —)은 rrn만 허용. 앞 6자리 유지, 뒤 7자리 전부 마스크.
28652
+ rrn: {
28653
+ pattern: /(?<!\d)(\d{6})([-‐‑–—])([1-8]\d{6})(?!\d)/g,
28654
+ validate: (m) => birthdateValid(m[1]),
28655
+ mask: (m, mc) => m[1] + m[2] + mc.repeat(7)
28656
+ },
28657
+ // 이메일 — 로컬파트 첫 글자만 남기고 마스크, 도메인 유지
28658
+ email: {
28659
+ pattern: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,
28660
+ mask: (m, mc) => {
28661
+ const at = m[0].indexOf("@");
28662
+ return m[0][0] + mc.repeat(at - 1) + m[0].slice(at);
28663
+ }
28664
+ },
28665
+ // 카드번호 — 구분자 필수(무구분 16자리는 오탐 높아 제외), 동일 구분자 강제(\2),
28666
+ // Luhn 체크. 가운데 8자리 마스크.
28667
+ card: {
28668
+ pattern: /(?<!\d)(\d{4})([- ])(\d{4})\2(\d{4})\2(\d{4})(?!\d)/g,
28669
+ validate: (m) => luhnValid(m[1] + m[3] + m[4] + m[5]),
28670
+ mask: (m, mc) => m[1] + m[2] + mc.repeat(4) + m[2] + mc.repeat(4) + m[2] + m[5]
28671
+ },
28672
+ // 전화번호 — 휴대폰(01[016789])·서울(02)·지역(0[3-6]\d)·인터넷(070)은 구분자
28673
+ // -·.·공백 또는 무구분(동일 구분자 강제), 대표번호(15xx/16xx/18xx)는 구분자 필수.
28674
+ // 가운데 자리만 마스크 (대표번호는 뒤 4자리). 선행 [\d-] 금지 — 계좌 부분매치 방지.
28675
+ phone: {
28676
+ pattern: /(?<![\d-])(?:(01[016789]|070|02|0[3-6]\d)([-. ]?)(\d{3,4})\2(\d{4})|(1[568]\d{2})([-. ])(\d{4}))(?!\d)/g,
28677
+ mask: (m, mc) => m[1] !== void 0 ? m[1] + m[2] + mc.repeat(m[3].length) + m[2] + m[4] : m[5] + m[6] + mc.repeat(4)
28678
+ },
28679
+ // 운전면허 (기본 OFF) — 신형 12자리만 (지역명 2글자 선행 구버전은 스킵). 뒷 8자리 마스크.
28680
+ driver: {
28681
+ pattern: /(?<![\d-])(\d{2})-(\d{2})-\d{6}-\d{2}(?!-?\d)/g,
28682
+ mask: (m, mc) => m[1] + "-" + m[2] + "-" + mc.repeat(6) + "-" + mc.repeat(2)
28683
+ },
28684
+ // 계좌번호 — 3~4그룹 + 총 자릿수 10~16. rrn·card·phone과 겹치면 그쪽 우선.
28685
+ // 마지막 그룹 빼고 전부 마스크. 사업자등록번호(3-2-5, 10자리)도 걸린다 — 계약상 의도
28686
+ // (테스트로 명시). 날짜(2026-07-16)는 8자리라 총자릿수 검증에서 탈락.
28687
+ account: {
28688
+ pattern: /(?<!\d)(?<!\d-)\d{2,6}(?:-\d{2,6}){1,2}-\d{2,8}(?!-?\d)/g,
28689
+ validate: (m) => {
28690
+ const digits = m[0].replace(/-/g, "").length;
28691
+ return digits >= 10 && digits <= 16;
28692
+ },
28693
+ mask: (m, mc) => {
28694
+ const parts = m[0].split("-");
28695
+ return parts.map((p, i) => i === parts.length - 1 ? p : mc.repeat(p.length)).join("-");
28696
+ }
28697
+ },
28698
+ // 여권번호 (기본 OFF) — 단어 경계, 첫 글자만 남기고 전부 마스크
28699
+ passport: {
28700
+ pattern: /\b([MSRODG])\d{8}(?![0-9A-Za-z])/g,
28701
+ mask: (m, mc) => m[1] + mc.repeat(8)
28702
+ }
28703
+ };
28704
+ function redactText(text, options) {
28705
+ const maskChar = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _472 => _472.maskChar]), () => ( "\u25CF"));
28706
+ if (maskChar.length !== 1 || /[0-9A-Za-z]/.test(maskChar)) {
28707
+ throw new Error(`maskChar\uB294 \uC601\uC22B\uC790\uAC00 \uC544\uB2CC 1\uAE00\uC790\uC5EC\uC57C \uD568: ${JSON.stringify(maskChar)}`);
28708
+ }
28709
+ const enabled = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _473 => _473.rules]), () => ( DEFAULT_REDACT_RULES));
28710
+ const hits = [];
28711
+ if (text === "" || enabled.length === 0) return { text, hits };
28712
+ const occupied = [];
28713
+ for (const rule of RULE_PRIORITY) {
28714
+ if (!enabled.includes(rule)) continue;
28715
+ const def = RULES2[rule];
28716
+ for (const m of text.matchAll(def.pattern)) {
28717
+ if (def.validate && !def.validate(m)) continue;
28718
+ const start = m.index;
28719
+ const end = start + m[0].length;
28720
+ if (occupied.some((o) => start < o.end && end > o.start)) continue;
28721
+ occupied.push({ start, end });
28722
+ hits.push({ rule, masked: def.mask(m, maskChar), index: start, length: m[0].length });
28723
+ }
28724
+ }
28725
+ hits.sort((a, b) => a.index - b.index);
28726
+ let out = "";
28727
+ let cursor = 0;
28728
+ for (const h of hits) {
28729
+ out += text.slice(cursor, h.index) + h.masked;
28730
+ cursor = h.index + h.length;
28731
+ }
28732
+ out += text.slice(cursor);
28733
+ return { text: out, hits };
28734
+ }
28735
+ function redactMarkdown(markdown, options) {
28736
+ const lines = markdown.split("\n");
28737
+ const hits = [];
28738
+ let offset = 0;
28739
+ const outLines = lines.map((line) => {
28740
+ if (line.includes("data:image/")) {
28741
+ offset += line.length + 1;
28742
+ return line;
28743
+ }
28744
+ const r = redactText(line, options);
28745
+ for (const h of r.hits) hits.push({ ...h, index: h.index + offset });
28746
+ offset += line.length + 1;
28747
+ return r.text;
28748
+ });
28749
+ return { text: outLines.join("\n"), hits };
28750
+ }
28751
+
28752
+ // src/chunks.ts
28753
+ var LIST_MARKER_RE = /^(?:[□■◇◆○◎●◦ㅇ•▪▸▶※-]|\d{1,3}[.)]|[가나다라마바사아자차카타파하][.)]|\([가나다라마바사아자차카타파하0-9]{1,3}\)|[①-⑳㉮-㉻㈎-㈛])\s/;
28754
+ function listDepthOf(block) {
28755
+ if (block.listDepth !== void 0) return block.listDepth;
28756
+ if (block.type === "list") return 0;
28757
+ if (block.type === "paragraph" && block.text && LIST_MARKER_RE.test(block.text.trim())) return 0;
28758
+ return void 0;
28759
+ }
28760
+ function sameBreadcrumb(a, b) {
28761
+ return a.length === b.length && a.every((v, i) => v === b[i]);
28762
+ }
28763
+ function blocksToChunks(blocks, options) {
28764
+ const granularity = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _474 => _474.granularity]), () => ( "section"));
28765
+ const includeCells = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _475 => _475.includeTableCells]), () => ( false));
28766
+ const chunks = [];
28767
+ const headingStack = [];
28768
+ const listStack = [];
28769
+ const crumb = () => [...headingStack.map((h) => h.text), ...listStack.map((l) => l.text)];
28770
+ const push = (type, breadcrumb, text, blockRange, page, table2) => {
28771
+ const chunk = { id: "c" + String(chunks.length + 1).padStart(4, "0"), type, breadcrumb, text, blockRange };
28772
+ if (page !== void 0) chunk.page = page;
28773
+ if (table2) chunk.table = table2;
28774
+ chunks.push(chunk);
28775
+ };
28776
+ let run = null;
28777
+ const flushRun = () => {
28778
+ if (!run) return;
28779
+ push("text", run.breadcrumb, _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, run.blocks), [run.start, run.end], run.page);
28780
+ run = null;
28781
+ };
28782
+ for (let i = 0; i < blocks.length; i++) {
28783
+ const block = blocks[i];
28784
+ const md2 = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, [block]);
28785
+ if (!md2) continue;
28786
+ if (block.type === "heading") {
28787
+ flushRun();
28788
+ const level = Math.min(block.level || 2, 6);
28789
+ while (headingStack.length && headingStack[headingStack.length - 1].level >= level) headingStack.pop();
28790
+ listStack.length = 0;
28791
+ push("heading", crumb(), md2, [i, i], block.pageNumber);
28792
+ headingStack.push({ level, text: (_nullishCoalesce(block.text, () => ( ""))).trim() });
28793
+ continue;
28794
+ }
28795
+ if (block.type === "table" && block.table) {
28796
+ flushRun();
28797
+ const summary = { rows: block.table.rows, cols: block.table.cols };
28798
+ if (includeCells) summary.cells = block.table.cells.map((row) => row.map((c) => c.text));
28799
+ push("table", crumb(), md2, [i, i], block.pageNumber, summary);
28800
+ continue;
28801
+ }
28802
+ const depth = listDepthOf(block);
28803
+ if (depth !== void 0) {
28804
+ while (listStack.length && listStack[listStack.length - 1].depth >= depth) listStack.pop();
28805
+ }
28806
+ const breadcrumb = crumb();
28807
+ if (depth !== void 0) listStack.push({ depth, text: (_nullishCoalesce(block.text, () => ( ""))).trim() });
28808
+ if (granularity === "block") {
28809
+ push("text", breadcrumb, md2, [i, i], block.pageNumber);
28810
+ continue;
28811
+ }
28812
+ if (run && sameBreadcrumb(run.breadcrumb, breadcrumb)) {
28813
+ run.blocks.push(block);
28814
+ run.end = i;
28815
+ if (run.page === void 0) run.page = block.pageNumber;
28816
+ } else {
28817
+ flushRun();
28818
+ run = { breadcrumb, blocks: [block], start: i, end: i, page: block.pageNumber };
28819
+ }
28820
+ }
28821
+ flushRun();
28822
+ return chunks;
28823
+ }
28824
+
28227
28825
  // src/roundtrip/session.ts
28228
28826
 
28229
28827
  async function buildState(bytes) {
@@ -28273,7 +28871,7 @@ function irCellLines(text) {
28273
28871
  }
28274
28872
  var HwpxSession = (_class8 = class _HwpxSession {
28275
28873
 
28276
- constructor(state) {;_class8.prototype.__init19.call(this);
28874
+ constructor(state) {;_class8.prototype.__init21.call(this);
28277
28875
  this.state = state;
28278
28876
  }
28279
28877
  /** HWPX 바이트로 세션을 연다 (입력은 복사되어 외부 변이와 격리) */
@@ -28299,7 +28897,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28299
28897
  const block = st.blocks[blockIndex];
28300
28898
  if (!block) return void 0;
28301
28899
  if (block.type === "paragraph" || block.type === "heading") {
28302
- const para2 = _optionalChain([st, 'access', _424 => _424.paraMap, 'access', _425 => _425.get, 'call', _426 => _426(blockIndex), 'optionalAccess', _427 => _427.para]);
28900
+ const para2 = _optionalChain([st, 'access', _476 => _476.paraMap, 'access', _477 => _477.get, 'call', _478 => _478(blockIndex), 'optionalAccess', _479 => _479.para]);
28303
28901
  if (!para2) return void 0;
28304
28902
  return { kind: "paragraph", sectionIndex: para2.sectionIndex, xmlStart: para2.start };
28305
28903
  }
@@ -28324,7 +28922,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28324
28922
  if (block.text && block.text.includes("\n")) {
28325
28923
  return { capability: "locked", reason: "\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)" };
28326
28924
  }
28327
- if (!_optionalChain([st, 'access', _428 => _428.paraMap, 'access', _429 => _429.get, 'call', _430 => _430(blockIndex), 'optionalAccess', _431 => _431.para])) {
28925
+ if (!_optionalChain([st, 'access', _480 => _480.paraMap, 'access', _481 => _481.get, 'call', _482 => _482(blockIndex), 'optionalAccess', _483 => _483.para])) {
28328
28926
  return { capability: "locked", reason: "\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)" };
28329
28927
  }
28330
28928
  return { capability: "text" };
@@ -28373,7 +28971,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28373
28971
  this.opQueue = run.then(() => void 0, () => void 0);
28374
28972
  return run;
28375
28973
  }
28376
- __init19() {this.opQueue = Promise.resolve()}
28974
+ __init21() {this.opQueue = Promise.resolve()}
28377
28975
  async patchBlocksInner(edits, options) {
28378
28976
  const st = this.state;
28379
28977
  const skipped = [];
@@ -28390,7 +28988,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28390
28988
  continue;
28391
28989
  }
28392
28990
  if (block.type === "table" && block.table) {
28393
- if (!_optionalChain([edit, 'access', _432 => _432.cells, 'optionalAccess', _433 => _433.length])) {
28991
+ if (!_optionalChain([edit, 'access', _484 => _484.cells, 'optionalAccess', _485 => _485.length])) {
28394
28992
  skipped.push({ reason: "\uD45C \uBE14\uB85D\uC5D0\uB294 cells \uD3B8\uC9D1\uB9CC \uC9C0\uC6D0", before: summarize(_nullishCoalesce(block.table.caption, () => ( "(\uD45C)"))) });
28395
28993
  continue;
28396
28994
  }
@@ -28410,7 +29008,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28410
29008
  skipped.push({ reason: "\uAC19\uC740 \uC140\uC5D0 \uC911\uBCF5 \uD3B8\uC9D1 \u2014 \uBA3C\uC800 \uC801\uC6A9\uB41C \uD3B8\uC9D1 \uC720\uC9C0", after: summarize(cellEdit.text) });
28411
29009
  continue;
28412
29010
  }
28413
- const irCell = _optionalChain([block, 'access', _434 => _434.table, 'access', _435 => _435.cells, 'access', _436 => _436[cellEdit.row], 'optionalAccess', _437 => _437[cellEdit.col]]);
29011
+ const irCell = _optionalChain([block, 'access', _486 => _486.table, 'access', _487 => _487.cells, 'access', _488 => _488[cellEdit.row], 'optionalAccess', _489 => _489[cellEdit.col]]);
28414
29012
  if (!irCell) {
28415
29013
  skipped.push({ reason: `\uC140 \uC88C\uD45C \uBC94\uC704 \uBC16: ${cellEdit.row},${cellEdit.col}`, after: summarize(cellEdit.text) });
28416
29014
  continue;
@@ -28466,7 +29064,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28466
29064
  }
28467
29065
  if (replacements.size === 0) {
28468
29066
  let changes2;
28469
- if (_optionalChain([options, 'optionalAccess', _438 => _438.verify]) !== false) {
29067
+ if (_optionalChain([options, 'optionalAccess', _490 => _490.verify]) !== false) {
28470
29068
  const units = splitMarkdownUnits(st.markdown);
28471
29069
  changes2 = diffUnitLists(units, units);
28472
29070
  }
@@ -28487,7 +29085,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28487
29085
  }
28488
29086
  this.state = newState;
28489
29087
  let changes;
28490
- if (_optionalChain([options, 'optionalAccess', _439 => _439.verify]) !== false) {
29088
+ if (_optionalChain([options, 'optionalAccess', _491 => _491.verify]) !== false) {
28491
29089
  changes = diffUnitLists(splitMarkdownUnits(beforeMarkdown), splitMarkdownUnits(newState.markdown));
28492
29090
  }
28493
29091
  return { success: true, data: new Uint8Array(data), applied, skipped, changes };
@@ -28507,7 +29105,7 @@ var HwpxSession = (_class8 = class _HwpxSession {
28507
29105
  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)");
28508
29106
  }
28509
29107
  const mapping = st.paraMap.get(blockIndex);
28510
- if (!_optionalChain([mapping, 'optionalAccess', _440 => _440.para])) {
29108
+ if (!_optionalChain([mapping, 'optionalAccess', _492 => _492.para])) {
28511
29109
  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)");
28512
29110
  }
28513
29111
  let newPlain = newTextRaw.split("\n").map((l) => l.trim()).filter(Boolean).join(" ");
@@ -28527,14 +29125,14 @@ var HwpxSession = (_class8 = class _HwpxSession {
28527
29125
  if (sanitizeText(newPlain) !== newPlain) {
28528
29126
  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");
28529
29127
  }
28530
- const splices = buildParagraphSplices(mapping.para, newPlain, _optionalChain([st, 'access', _441 => _441.scans, 'access', _442 => _442[mapping.para.sectionIndex], 'optionalAccess', _443 => _443.xml]));
29128
+ const splices = buildParagraphSplices(mapping.para, newPlain, _optionalChain([st, 'access', _493 => _493.scans, 'access', _494 => _494[mapping.para.sectionIndex], 'optionalAccess', _495 => _495.xml]));
28531
29129
  if (splices === null) return skip("\uBB38\uB2E8\uC5D0 \uD14D\uC2A4\uD2B8 \uB178\uB4DC\uB97C \uB9CC\uB4E4 \uC218 \uC5C6\uC74C");
28532
29130
  sectionSplices[mapping.para.sectionIndex].push(...splices);
28533
29131
  return 1;
28534
29132
  }
28535
29133
  }, _class8);
28536
29134
  function cellStaticCheck(table2, scanTable, r, c) {
28537
- const irCell = _optionalChain([table2, 'access', _444 => _444.cells, 'access', _445 => _445[r], 'optionalAccess', _446 => _446[c]]);
29135
+ const irCell = _optionalChain([table2, 'access', _496 => _496.cells, 'access', _497 => _497[r], 'optionalAccess', _498 => _498[c]]);
28538
29136
  if (!irCell) return { editable: false, reason: "\uC140 \uC88C\uD45C \uBC94\uC704 \uBC16" };
28539
29137
  const cell2 = scanTable.cellByAnchor.get(`${r},${c}`);
28540
29138
  if (!cell2) return { editable: false, reason: "\uBCD1\uD569 \uC601\uC5ED\uC758 \uBE48 \uCE78\uC774\uAC70\uB098 \uC88C\uD45C \uBD88\uC77C\uCE58" };
@@ -28618,11 +29216,11 @@ var md = new (0, _markdownit2.default)({
28618
29216
  breaks: false
28619
29217
  });
28620
29218
  function renderHtml(markdown, options) {
28621
- const preset = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _447 => _447.preset]), () => ( "default"));
28622
- const css = PRESETS[preset] + (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _448 => _448.extraCss]), () => ( "")));
29219
+ const preset = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _499 => _499.preset]), () => ( "default"));
29220
+ const css = PRESETS[preset] + (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _500 => _500.extraCss]), () => ( "")));
28623
29221
  const body = md.render(markdown);
28624
- const watermark = _optionalChain([options, 'optionalAccess', _449 => _449.watermark]) ? `<div class="watermark">${escapeHtml(options.watermark)}</div>` : "";
28625
- const watermarkCss = _optionalChain([options, 'optionalAccess', _450 => _450.watermark]) ? `
29222
+ const watermark = _optionalChain([options, 'optionalAccess', _501 => _501.watermark]) ? `<div class="watermark">${escapeHtml(options.watermark)}</div>` : "";
29223
+ const watermarkCss = _optionalChain([options, 'optionalAccess', _502 => _502.watermark]) ? `
28626
29224
  .watermark {
28627
29225
  position: fixed;
28628
29226
  top: 50%; left: 50%;
@@ -28652,14 +29250,14 @@ async function htmlToPdf(html, options) {
28652
29250
  let puppeteer;
28653
29251
  try {
28654
29252
  puppeteer = await Promise.resolve().then(() => _interopRequireWildcard(require("puppeteer-core")));
28655
- } catch (e31) {
28656
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(
29253
+ } catch (e32) {
29254
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(
28657
29255
  "PDF \uC0DD\uC131\uC5D0 puppeteer-core\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC124\uCE58: npm install puppeteer-core"
28658
29256
  );
28659
29257
  }
28660
29258
  const executablePath = _nullishCoalesce(process.env.PUPPETEER_EXECUTABLE_PATH, () => ( findChromiumPath()));
28661
29259
  if (!executablePath) {
28662
- throw new (0, _chunk6XAAYAWLcjs.KordocError)(
29260
+ throw new (0, _chunk37VKMUSTcjs.KordocError)(
28663
29261
  "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."
28664
29262
  );
28665
29263
  }
@@ -28671,10 +29269,10 @@ async function htmlToPdf(html, options) {
28671
29269
  try {
28672
29270
  const page = await browser.newPage();
28673
29271
  await page.setContent(html, { waitUntil: "networkidle0" });
28674
- const margin = _optionalChain([options, 'optionalAccess', _451 => _451.margin]);
29272
+ const margin = _optionalChain([options, 'optionalAccess', _503 => _503.margin]);
28675
29273
  const pdf = await page.pdf({
28676
- format: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _452 => _452.pageSize]), () => ( "A4")),
28677
- landscape: _optionalChain([options, 'optionalAccess', _453 => _453.orientation]) === "landscape",
29274
+ format: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _504 => _504.pageSize]), () => ( "A4")),
29275
+ landscape: _optionalChain([options, 'optionalAccess', _505 => _505.orientation]) === "landscape",
28678
29276
  printBackground: true,
28679
29277
  margin: margin ? {
28680
29278
  top: toCss(margin.top),
@@ -28682,9 +29280,9 @@ async function htmlToPdf(html, options) {
28682
29280
  bottom: toCss(margin.bottom),
28683
29281
  left: toCss(margin.left)
28684
29282
  } : void 0,
28685
- displayHeaderFooter: !!(_optionalChain([options, 'optionalAccess', _454 => _454.header]) || _optionalChain([options, 'optionalAccess', _455 => _455.footer])),
28686
- headerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _456 => _456.header]), () => ( "<div></div>")),
28687
- footerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _457 => _457.footer]), () => ( '<div style="font-size:8pt;width:100%;text-align:center;color:#777;"><span class="pageNumber"></span>/<span class="totalPages"></span></div>'))
29283
+ displayHeaderFooter: !!(_optionalChain([options, 'optionalAccess', _506 => _506.header]) || _optionalChain([options, 'optionalAccess', _507 => _507.footer])),
29284
+ headerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _508 => _508.header]), () => ( "<div></div>")),
29285
+ footerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _509 => _509.footer]), () => ( '<div style="font-size:8pt;width:100%;text-align:center;color:#777;"><span class="pageNumber"></span>/<span class="totalPages"></span></div>'))
28688
29286
  });
28689
29287
  return Buffer.from(pdf);
28690
29288
  } finally {
@@ -28718,7 +29316,7 @@ async function markdownToPdf(markdown, options) {
28718
29316
  return htmlToPdf(html, options);
28719
29317
  }
28720
29318
  async function blocksToPdf(blocks, options) {
28721
- const markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, blocks);
29319
+ const markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, blocks);
28722
29320
  return markdownToPdf(markdown, options);
28723
29321
  }
28724
29322
 
@@ -28897,7 +29495,7 @@ function reflowPara(p, doc, styles, areaW, startV, mode) {
28897
29495
  }
28898
29496
  const wrapAttr = _nullishCoalesce(o.el.getAttribute("textWrap"), () => ( ""));
28899
29497
  if (wrapAttr === "BEHIND_TEXT" || wrapAttr === "IN_FRONT_OF_TEXT") continue;
28900
- const vertRel = _nullishCoalesce(_optionalChain([pos, 'optionalAccess', _458 => _458.getAttribute, 'call', _459 => _459("vertRelTo")]), () => ( "PARA"));
29498
+ const vertRel = _nullishCoalesce(_optionalChain([pos, 'optionalAccess', _510 => _510.getAttribute, 'call', _511 => _511("vertRelTo")]), () => ( "PARA"));
28901
29499
  if (vertRel === "PAGE" || vertRel === "PAPER") continue;
28902
29500
  const vo = Math.max(0, num2(pos, "vertOffset"));
28903
29501
  if (wrapAttr === "TOP_AND_BOTTOM") {
@@ -28958,7 +29556,7 @@ function reflowBlockFlow(container, doc, styles, areaW, mode, counter, bodyH) {
28958
29556
  if (ln(p) !== "p") continue;
28959
29557
  reflowTablesIn(p, doc, styles, mode, counter);
28960
29558
  const g = styles.paraGeom.get(_nullishCoalesce(p.getAttribute("paraPrIDRef"), () => ( "")));
28961
- const startV = cursorV + prevSpaceAfter + (_nullishCoalesce(_optionalChain([g, 'optionalAccess', _460 => _460.spaceBefore]), () => ( 0)));
29559
+ const startV = cursorV + prevSpaceAfter + (_nullishCoalesce(_optionalChain([g, 'optionalAccess', _512 => _512.spaceBefore]), () => ( 0)));
28962
29560
  const res = reflowPara(p, doc, styles, areaW, startV, mode);
28963
29561
  if (!res) {
28964
29562
  const lsa = findChildByLocalName(p, "linesegarray");
@@ -28971,7 +29569,7 @@ function reflowBlockFlow(container, doc, styles, areaW, mode, counter, bodyH) {
28971
29569
  }
28972
29570
  if (Number.isFinite(bottom)) {
28973
29571
  cursorV = bottom;
28974
- prevSpaceAfter = _nullishCoalesce(_optionalChain([g, 'optionalAccess', _461 => _461.spaceAfter]), () => ( 0));
29572
+ prevSpaceAfter = _nullishCoalesce(_optionalChain([g, 'optionalAccess', _513 => _513.spaceAfter]), () => ( 0));
28975
29573
  }
28976
29574
  }
28977
29575
  continue;
@@ -29081,7 +29679,7 @@ function buildPara(p) {
29081
29679
  el: ch,
29082
29680
  tag: cn,
29083
29681
  index: chars.length,
29084
- inline: _optionalChain([pos, 'optionalAccess', _462 => _462.getAttribute, 'call', _463 => _463("treatAsChar")]) === "1",
29682
+ inline: _optionalChain([pos, 'optionalAccess', _514 => _514.getAttribute, 'call', _515 => _515("treatAsChar")]) === "1",
29085
29683
  width: w,
29086
29684
  height: h
29087
29685
  });
@@ -29199,7 +29797,7 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
29199
29797
  }
29200
29798
  if (text.trim().length > 0) {
29201
29799
  const attrs = [`x="${pt(cx)}"`, `y="${pt(y)}"`, `font-size="${pt(st.height)}"`];
29202
- if (st.fontFamily) attrs.push(`font-family="${st.fontFamily}"`);
29800
+ if (st.fontFamily) attrs.push(`font-family="${escapeXml3(st.fontFamily)}"`);
29203
29801
  if ([...text].length > 1 && sw > 50) {
29204
29802
  attrs.push(`textLength="${pt(sw)}"`, `lengthAdjust="${plan.scale < 1 ? "spacingAndGlyphs" : "spacing"}"`);
29205
29803
  }
@@ -29333,15 +29931,15 @@ function drawShape(o, x, y, ctx, depth) {
29333
29931
  const sx = ow > 0 ? w / ow : 1;
29334
29932
  const sy = oh > 0 ? h / oh : 1;
29335
29933
  const lineShape = findChildByLocalName(el, "lineShape");
29336
- const lstyle = _nullishCoalesce(_optionalChain([lineShape, 'optionalAccess', _464 => _464.getAttribute, 'call', _465 => _465("style")]), () => ( "SOLID"));
29337
- const strokeCol = _optionalChain([lineShape, 'optionalAccess', _466 => _466.getAttribute, 'call', _467 => _467("color")]) || "#000000";
29934
+ const lstyle = _nullishCoalesce(_optionalChain([lineShape, 'optionalAccess', _516 => _516.getAttribute, 'call', _517 => _517("style")]), () => ( "SOLID"));
29935
+ const strokeCol = _optionalChain([lineShape, 'optionalAccess', _518 => _518.getAttribute, 'call', _519 => _519("color")]) || "#000000";
29338
29936
  const hasStroke = lstyle !== "NONE";
29339
29937
  const strokeW = hasStroke ? shapeStrokePt(lineShape ? num3(lineShape, "width") : 33) : 0;
29340
29938
  const dash = /DASH|DOT/.test(lstyle) ? ` stroke-dasharray="${lstyle.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
29341
29939
  const strokeAttr = hasStroke ? ` stroke="${escapeXml3(strokeCol)}" stroke-width="${strokeW.toFixed(2)}"${dash}` : "";
29342
29940
  const fillBrush = findChildByLocalName(el, "fillBrush");
29343
29941
  const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
29344
- const face = _optionalChain([winBrush, 'optionalAccess', _468 => _468.getAttribute, 'call', _469 => _469("faceColor")]);
29942
+ const face = _optionalChain([winBrush, 'optionalAccess', _520 => _520.getAttribute, 'call', _521 => _521("faceColor")]);
29345
29943
  const fill = face && face.toLowerCase() !== "none" ? face : "none";
29346
29944
  const fillAttr = ` fill="${fill === "none" ? "none" : escapeXml3(fill)}"`;
29347
29945
  if (o.tag === "rect") {
@@ -29366,28 +29964,31 @@ function drawShape(o, x, y, ctx, depth) {
29366
29964
  for (const p of elements2(sub)) if (ln2(p) === "p") drawPara(p, x, y, w, ctx, depth + 1);
29367
29965
  }
29368
29966
  }
29369
- function cellContentExtent(cell2) {
29967
+ function cellContentExtent(cell2, memo) {
29370
29968
  if (!cell2.sub) return 0;
29969
+ const hit = _optionalChain([memo, 'optionalAccess', _522 => _522.cell, 'access', _523 => _523.get, 'call', _524 => _524(cell2.el)]);
29970
+ if (hit !== void 0) return hit;
29371
29971
  let ext = 0;
29372
29972
  for (const p of elements2(cell2.sub)) {
29373
29973
  if (ln2(p) !== "p") continue;
29374
29974
  const m = buildPara(p);
29375
29975
  for (const s of m.segs) ext = Math.max(ext, s.vertpos + s.textheight);
29376
- const baseV = _nullishCoalesce(_optionalChain([m, 'access', _470 => _470.segs, 'access', _471 => _471[0], 'optionalAccess', _472 => _472.vertpos]), () => ( 0));
29976
+ const baseV = _nullishCoalesce(_optionalChain([m, 'access', _525 => _525.segs, 'access', _526 => _526[0], 'optionalAccess', _527 => _527.vertpos]), () => ( 0));
29377
29977
  for (const o of m.objs) {
29378
29978
  if (o.inline) {
29379
- const h = o.tag === "tbl" ? Math.max(o.height, measureTableHeight(o.el)) : o.height;
29979
+ const h = o.tag === "tbl" ? Math.max(o.height, measureTableHeight(o.el, memo)) : o.height;
29380
29980
  ext = Math.max(ext, baseV + h);
29381
29981
  continue;
29382
29982
  }
29383
29983
  const pos = findChildByLocalName(o.el, "pos");
29384
- if ((_nullishCoalesce(_optionalChain([pos, 'optionalAccess', _473 => _473.getAttribute, 'call', _474 => _474("vertRelTo")]), () => ( "PARA"))) !== "PARA") continue;
29984
+ if ((_nullishCoalesce(_optionalChain([pos, 'optionalAccess', _528 => _528.getAttribute, 'call', _529 => _529("vertRelTo")]), () => ( "PARA"))) !== "PARA") continue;
29385
29985
  const om = findChildByLocalName(o.el, "outMargin");
29386
29986
  const pushed = baseV - (num3(om, "top") + o.height + num3(om, "bottom"));
29387
29987
  const anchor = pushed >= -100 ? pushed : baseV;
29388
29988
  ext = Math.max(ext, anchor + num3(om, "top") + num3(pos, "vertOffset") + o.height);
29389
29989
  }
29390
29990
  }
29991
+ _optionalChain([memo, 'optionalAccess', _530 => _530.cell, 'access', _531 => _531.set, 'call', _532 => _532(cell2.el, ext)]);
29391
29992
  return ext;
29392
29993
  }
29393
29994
  function edgeLine(x1, y1, x2, y2, e) {
@@ -29410,8 +30011,9 @@ function collectCells(tbl2) {
29410
30011
  if (!addr || !csz) continue;
29411
30012
  cells.push({
29412
30013
  el: tc2,
29413
- ca: num3(addr, "colAddr"),
29414
- ra: num3(addr, "rowAddr"),
30014
+ // 음수 주소(uint32 역변환·손상 입력) 방어 — colX/rowY 인덱스 이탈로 NaN 좌표 방지
30015
+ ca: Math.max(0, num3(addr, "colAddr")),
30016
+ ra: Math.max(0, num3(addr, "rowAddr")),
29415
30017
  cs: Math.max(1, num3(span, "colSpan", 1)),
29416
30018
  rs: Math.max(1, num3(span, "rowSpan", 1)),
29417
30019
  w: num3(csz, "width"),
@@ -29427,16 +30029,19 @@ function collectCells(tbl2) {
29427
30029
  }
29428
30030
  return cells;
29429
30031
  }
29430
- function measureTableHeight(tbl2) {
30032
+ function measureTableHeight(tbl2, memo) {
30033
+ const hit = _optionalChain([memo, 'optionalAccess', _533 => _533.table, 'access', _534 => _534.get, 'call', _535 => _535(tbl2)]);
30034
+ if (hit !== void 0) return hit;
29431
30035
  const cells = collectCells(tbl2);
29432
30036
  if (cells.length === 0 || cells.length > 4096) return 0;
29433
30037
  const nRows = Math.max(...cells.map((c) => c.ra + c.rs));
29434
30038
  const rowH = solveRowHeights(
29435
- cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c) : void 0 })),
30039
+ cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c, memo) : void 0 })),
29436
30040
  nRows
29437
30041
  );
29438
30042
  let sum = 0;
29439
30043
  for (const h of rowH) sum += h;
30044
+ _optionalChain([memo, 'optionalAccess', _536 => _536.table, 'access', _537 => _537.set, 'call', _538 => _538(tbl2, sum)]);
29440
30045
  return sum;
29441
30046
  }
29442
30047
  function drawTable(tbl2, tx, ty, ctx, depth) {
@@ -29453,7 +30058,7 @@ function drawTable(tbl2, tx, ty, ctx, depth) {
29453
30058
  const colCons = cells.map((c) => ({ a: c.ca, b: c.ca + c.cs, size: c.w }));
29454
30059
  const colX = solveBoundaries(colCons, nCols, num3(tblSz, "width") || void 0);
29455
30060
  const rowH = solveRowHeights(
29456
- cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c) : void 0 })),
30061
+ cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c, ctx.extentMemo) : void 0 })),
29457
30062
  nRows
29458
30063
  );
29459
30064
  const rowY = [0];
@@ -29467,13 +30072,13 @@ function drawTable(tbl2, tx, ty, ctx, depth) {
29467
30072
  }));
29468
30073
  for (const g of geom) {
29469
30074
  const bf = g.c.bfId != null ? ctx.styles.borderFill.get(g.c.bfId) : void 0;
29470
- if (_optionalChain([bf, 'optionalAccess', _475 => _475.fill])) emit(ctx, `<rect x="${pt(g.x)}" y="${pt(g.y)}" width="${pt(g.w)}" height="${pt(g.h)}" fill="${escapeXml3(bf.fill)}"/>`);
30075
+ if (_optionalChain([bf, 'optionalAccess', _539 => _539.fill])) emit(ctx, `<rect x="${pt(g.x)}" y="${pt(g.y)}" width="${pt(g.w)}" height="${pt(g.h)}" fill="${escapeXml3(bf.fill)}"/>`);
29471
30076
  }
29472
30077
  for (const g of geom) {
29473
30078
  const { c } = g;
29474
30079
  if (!c.sub) continue;
29475
30080
  const innerH = g.h - c.marginT - c.marginB;
29476
- const extent = cellContentExtent(c);
30081
+ const extent = cellContentExtent(c, ctx.extentMemo);
29477
30082
  const va = _nullishCoalesce(c.sub.getAttribute("vertAlign"), () => ( "TOP"));
29478
30083
  let yoff = 0;
29479
30084
  if (va === "CENTER") yoff = Math.max(0, (innerH - extent) / 2);
@@ -29505,7 +30110,7 @@ function drawPic(pic, x, y, ctx) {
29505
30110
  const sz = findChildByLocalName(pic, "sz");
29506
30111
  const w = num3(sz, "width", 5669), h = num3(sz, "height", 5669);
29507
30112
  const img = findFirst(pic, "img");
29508
- const ref = _optionalChain([img, 'optionalAccess', _476 => _476.getAttribute, 'call', _477 => _477("binaryItemIDRef")]);
30113
+ const ref = _optionalChain([img, 'optionalAccess', _540 => _540.getAttribute, 'call', _541 => _541("binaryItemIDRef")]);
29509
30114
  const loaded = ref != null ? ctx.images.get(ref) : void 0;
29510
30115
  if (!loaded) {
29511
30116
  emit(ctx, `<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" fill="#eee" stroke="#c00" stroke-width="0.5"/>`);
@@ -29536,15 +30141,16 @@ function sniffMime(name, bytes) {
29536
30141
  const lower = name.toLowerCase();
29537
30142
  if (lower.endsWith(".png") || bytes.length > 4 && bytes[0] === 137 && bytes[1] === 80) return "image/png";
29538
30143
  if (lower.endsWith(".bmp") || bytes.length > 2 && bytes[0] === 66 && bytes[1] === 77) return "image/bmp";
29539
- if (lower.endsWith(".gif")) return "image/gif";
30144
+ if (lower.endsWith(".gif") || bytes.length > 3 && bytes[0] === 71 && bytes[1] === 73 && bytes[2] === 70) return "image/gif";
29540
30145
  if (lower.endsWith(".svg")) return "image/svg+xml";
30146
+ if (bytes.length > 3 && bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return "image/jpeg";
29541
30147
  return "image/jpeg";
29542
30148
  }
29543
30149
  function readSectionGeom(root) {
29544
30150
  const pagePr = findFirst(root, "pagePr");
29545
30151
  const margin = pagePr ? findChildByLocalName(pagePr, "margin") : null;
29546
30152
  let PW = num3(pagePr, "width", 59528), PH = num3(pagePr, "height", 84188);
29547
- if (_optionalChain([pagePr, 'optionalAccess', _478 => _478.getAttribute, 'call', _479 => _479("landscape")]) === "NARROWLY" && PW < PH) {
30153
+ if (_optionalChain([pagePr, 'optionalAccess', _542 => _542.getAttribute, 'call', _543 => _543("landscape")]) === "NARROWLY" && PW < PH) {
29548
30154
  const t = PW;
29549
30155
  PW = PH;
29550
30156
  PH = t;
@@ -29602,17 +30208,17 @@ function renderSectionToPages(root, geom, ctxBase, doReflow, reflowMode) {
29602
30208
  return { pages: ctx.pages, pageH };
29603
30209
  }
29604
30210
  async function renderHwpxToSvg(input, options) {
29605
- const maxImg = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _480 => _480.maxImageBytes]), () => ( 40 * 1024 * 1024));
30211
+ const maxImg = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _544 => _544.maxImageBytes]), () => ( 40 * 1024 * 1024));
29606
30212
  const ab = input instanceof Uint8Array ? input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength) : input;
29607
- _chunk6XAAYAWLcjs.precheckZipSize.call(void 0, ab, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
30213
+ _chunk37VKMUSTcjs.precheckZipSize.call(void 0, ab, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
29608
30214
  let zip;
29609
30215
  try {
29610
30216
  zip = await _jszip2.default.loadAsync(input);
29611
- } catch (e32) {
29612
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("HWPX(ZIP) \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB294 HWPX\uB9CC \uC9C0\uC6D0");
30217
+ } catch (e33) {
30218
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("HWPX(ZIP) \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB294 HWPX\uB9CC \uC9C0\uC6D0");
29613
30219
  }
29614
30220
  const secFiles = zip.file(/Contents\/section\d+\.xml$/i).sort((a, b) => a.name.localeCompare(b.name));
29615
- if (secFiles.length === 0) throw new (0, _chunk6XAAYAWLcjs.KordocError)("Contents/section0.xml \uC5C6\uC74C \u2014 HWPX\uAC00 \uC544\uB2C8\uAC70\uB098 \uC190\uC0C1\uB428");
30221
+ if (secFiles.length === 0) throw new (0, _chunk37VKMUSTcjs.KordocError)("Contents/section0.xml \uC5C6\uC74C \u2014 HWPX\uAC00 \uC544\uB2C8\uAC70\uB098 \uC190\uC0C1\uB428");
29616
30222
  const warnings = [];
29617
30223
  const headFile = _nullishCoalesce(zip.file("Contents/header.xml"), () => ( zip.file("Contents/head.xml")));
29618
30224
  const styles = headFile ? parseRenderStyles(await headFile.async("string")) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), paraGeom: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
@@ -29620,7 +30226,7 @@ async function renderHwpxToSvg(input, options) {
29620
30226
  const secXmls = [];
29621
30227
  for (const f of secFiles) {
29622
30228
  const xml = await f.async("string");
29623
- if (xml.length > MAX_DECOMPRESS_SIZE) throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
30229
+ if (xml.length > MAX_DECOMPRESS_SIZE) throw new (0, _chunk37VKMUSTcjs.KordocError)("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
29624
30230
  secXmls.push(xml);
29625
30231
  }
29626
30232
  const binmap = /* @__PURE__ */ new Map();
@@ -29644,7 +30250,7 @@ async function renderHwpxToSvg(input, options) {
29644
30250
  let href = binmap.get(ref);
29645
30251
  if (!href) {
29646
30252
  const cand = zip.file(new RegExp(`BinData/.*${ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i"))[0];
29647
- href = _optionalChain([cand, 'optionalAccess', _481 => _481.name]);
30253
+ href = _optionalChain([cand, 'optionalAccess', _545 => _545.name]);
29648
30254
  }
29649
30255
  if (!href) continue;
29650
30256
  const f = _nullishCoalesce(zip.file(href), () => ( zip.file("Contents/" + href)));
@@ -29665,17 +30271,18 @@ async function renderHwpxToSvg(input, options) {
29665
30271
  styles,
29666
30272
  images,
29667
30273
  defs: [],
29668
- highlights: (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _482 => _482.highlights]), () => ( []))).map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0),
30274
+ highlights: (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _546 => _546.highlights]), () => ( []))).map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0),
29669
30275
  warnings,
29670
30276
  warned: /* @__PURE__ */ new Set(),
29671
- stats: { texts: 0, images: 0, tables: 0 }
30277
+ stats: { texts: 0, images: 0, tables: 0 },
30278
+ extentMemo: { cell: /* @__PURE__ */ new WeakMap(), table: /* @__PURE__ */ new WeakMap() }
29672
30279
  };
29673
30280
  const rendered = [];
29674
30281
  let noCacheSkipped = false;
29675
30282
  for (let si = 0; si < secXmls.length; si++) {
29676
30283
  const secXml = secXmls[si];
29677
30284
  const hasCache = /<(?:[A-Za-z][\w.-]*:)?linesegarray[\s/>]/.test(secXml);
29678
- if (!hasCache && !_optionalChain([options, 'optionalAccess', _483 => _483.reflow])) {
30285
+ if (!hasCache && !_optionalChain([options, 'optionalAccess', _547 => _547.reflow])) {
29679
30286
  noCacheSkipped = true;
29680
30287
  warnings.push(`\uAD6C\uC5ED ${si}: \uC870\uD310 \uCE90\uC2DC \uC5C6\uC74C \u2014 reflow \uC635\uC158 \uD544\uC694, \uC0DD\uB7B5`);
29681
30288
  continue;
@@ -29687,14 +30294,14 @@ async function renderHwpxToSvg(input, options) {
29687
30294
  continue;
29688
30295
  }
29689
30296
  const geom = readSectionGeom(root);
29690
- const { pages, pageH } = renderSectionToPages(root, geom, ctxBase, !!_optionalChain([options, 'optionalAccess', _484 => _484.reflow]), _nullishCoalesce(_optionalChain([options, 'optionalAccess', _485 => _485.reflowMode]), () => ( "keep")));
30297
+ const { pages, pageH } = renderSectionToPages(root, geom, ctxBase, !!_optionalChain([options, 'optionalAccess', _548 => _548.reflow]), _nullishCoalesce(_optionalChain([options, 'optionalAccess', _549 => _549.reflowMode]), () => ( "keep")));
29691
30298
  rendered.push({ pages, PW: geom.PW, pageH, clipId: `pgclip${si}` });
29692
30299
  }
29693
30300
  if (rendered.length === 0) {
29694
30301
  if (noCacheSkipped) {
29695
- throw new (0, _chunk6XAAYAWLcjs.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)");
30302
+ throw new (0, _chunk37VKMUSTcjs.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)");
29696
30303
  }
29697
- throw new (0, _chunk6XAAYAWLcjs.KordocError)("\uB80C\uB354\uD560 \uAD6C\uC5ED\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 HWPX\uAC00 \uC190\uC0C1\uB418\uC5C8\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
30304
+ throw new (0, _chunk37VKMUSTcjs.KordocError)("\uB80C\uB354\uD560 \uAD6C\uC5ED\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 HWPX\uAC00 \uC190\uC0C1\uB418\uC5C8\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
29698
30305
  }
29699
30306
  const GAP = 2400;
29700
30307
  const clipDefs = [];
@@ -29726,17 +30333,17 @@ ${groups.join("\n")}
29726
30333
  // src/index.ts
29727
30334
  async function parse(input, options) {
29728
30335
  let buffer;
29729
- const opts = typeof input === "string" && !_optionalChain([options, 'optionalAccess', _486 => _486.filePath]) ? { ...options, filePath: input } : options;
30336
+ const opts = typeof input === "string" && !_optionalChain([options, 'optionalAccess', _550 => _550.filePath]) ? { ...options, filePath: input } : options;
29730
30337
  if (typeof input === "string") {
29731
30338
  try {
29732
30339
  const buf = await _promises.readFile.call(void 0, input);
29733
- buffer = _chunk6XAAYAWLcjs.toArrayBuffer.call(void 0, buf);
30340
+ buffer = _chunk37VKMUSTcjs.toArrayBuffer.call(void 0, buf);
29734
30341
  } catch (err) {
29735
30342
  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}`;
29736
30343
  return { success: false, fileType: "unknown", error: msg2, code: "PARSE_ERROR" };
29737
30344
  }
29738
30345
  } else if (Buffer.isBuffer(input)) {
29739
- buffer = _chunk6XAAYAWLcjs.toArrayBuffer.call(void 0, input);
30346
+ buffer = _chunk37VKMUSTcjs.toArrayBuffer.call(void 0, input);
29740
30347
  } else {
29741
30348
  buffer = input;
29742
30349
  }
@@ -29771,21 +30378,21 @@ async function parseHwp3(buffer, options) {
29771
30378
  const { markdown, blocks, metadata, outline, warnings } = parseHwp3Document(buffer, options);
29772
30379
  return { success: true, fileType: "hwp3", markdown, blocks, metadata, outline, warnings };
29773
30380
  } catch (err) {
29774
- return { success: false, fileType: "hwp3", error: err instanceof Error ? err.message : "HWP3 \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err) };
30381
+ return { success: false, fileType: "hwp3", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err) };
29775
30382
  }
29776
30383
  }
29777
30384
  async function parseHwpx(buffer, options) {
29778
30385
  try {
29779
30386
  const { markdown, blocks, metadata, outline, warnings, images } = await parseHwpxDocument(buffer, options);
29780
- return { success: true, fileType: "hwpx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _487 => _487.length]) ? images : void 0 };
30387
+ return { success: true, fileType: "hwpx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _551 => _551.length]) ? images : void 0 };
29781
30388
  } catch (err) {
29782
- return { success: false, fileType: "hwpx", error: err instanceof Error ? err.message : "HWPX \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err) };
30389
+ return { success: false, fileType: "hwpx", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err) };
29783
30390
  }
29784
30391
  }
29785
30392
  async function parseHwp(buffer, options) {
29786
30393
  try {
29787
30394
  const { markdown, blocks, metadata, outline, warnings, images } = parseHwp5Document(Buffer.from(buffer), options);
29788
- if (isDistributionSentinel(markdown) && isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _488 => _488.filePath])) {
30395
+ if (isDistributionSentinel(markdown) && isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _552 => _552.filePath])) {
29789
30396
  try {
29790
30397
  const { pages, pageCount, warnings: comWarns } = extractTextViaCom(options.filePath);
29791
30398
  if (pages.some((p) => p && p.trim().length > 0)) {
@@ -29799,20 +30406,20 @@ async function parseHwp(buffer, options) {
29799
30406
  warnings: com.warnings
29800
30407
  };
29801
30408
  }
29802
- } catch (e33) {
30409
+ } catch (e34) {
29803
30410
  }
29804
30411
  }
29805
- return { success: true, fileType: "hwp", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _489 => _489.length]) ? images : void 0 };
30412
+ return { success: true, fileType: "hwp", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _553 => _553.length]) ? images : void 0 };
29806
30413
  } catch (err) {
29807
- return { success: false, fileType: "hwp", error: err instanceof Error ? err.message : "HWP \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err) };
30414
+ return { success: false, fileType: "hwp", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err) };
29808
30415
  }
29809
30416
  }
29810
30417
  async function parsePdf(buffer, options) {
29811
30418
  let parsePdfDocument;
29812
30419
  try {
29813
- const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-ITMU2WN5.cjs")));
30420
+ const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-N4A7UGDK.cjs")));
29814
30421
  parsePdfDocument = mod.parsePdfDocument;
29815
- } catch (e34) {
30422
+ } catch (e35) {
29816
30423
  return {
29817
30424
  success: false,
29818
30425
  fileType: "pdf",
@@ -29825,7 +30432,7 @@ async function parsePdf(buffer, options) {
29825
30432
  return { success: true, fileType: "pdf", markdown, blocks, metadata, outline, warnings, isImageBased, pageQuality, qualitySummary, images };
29826
30433
  } catch (err) {
29827
30434
  const isImageBased = err instanceof Error && "isImageBased" in err ? true : void 0;
29828
- return { success: false, fileType: "pdf", error: err instanceof Error ? err.message : "PDF \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err), isImageBased };
30435
+ return { success: false, fileType: "pdf", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err), isImageBased };
29829
30436
  }
29830
30437
  }
29831
30438
  async function parseXlsx(buffer, options) {
@@ -29833,7 +30440,7 @@ async function parseXlsx(buffer, options) {
29833
30440
  const { markdown, blocks, metadata, warnings } = await parseXlsxDocument(buffer, options);
29834
30441
  return { success: true, fileType: "xlsx", markdown, blocks, metadata, warnings };
29835
30442
  } catch (err) {
29836
- return { success: false, fileType: "xlsx", error: err instanceof Error ? err.message : "XLSX \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err) };
30443
+ return { success: false, fileType: "xlsx", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err) };
29837
30444
  }
29838
30445
  }
29839
30446
  async function parseXls(buffer, options) {
@@ -29841,15 +30448,15 @@ async function parseXls(buffer, options) {
29841
30448
  const { markdown, blocks, metadata, warnings } = await parseXlsDocument(buffer, options);
29842
30449
  return { success: true, fileType: "xls", markdown, blocks, metadata, warnings };
29843
30450
  } catch (err) {
29844
- return { success: false, fileType: "xls", error: err instanceof Error ? err.message : "XLS \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err) };
30451
+ return { success: false, fileType: "xls", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err) };
29845
30452
  }
29846
30453
  }
29847
30454
  async function parseDocx(buffer, options) {
29848
30455
  try {
29849
30456
  const { markdown, blocks, metadata, outline, warnings, images } = await parseDocxDocument(buffer, options);
29850
- return { success: true, fileType: "docx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _490 => _490.length]) ? images : void 0 };
30457
+ return { success: true, fileType: "docx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _554 => _554.length]) ? images : void 0 };
29851
30458
  } catch (err) {
29852
- return { success: false, fileType: "docx", error: err instanceof Error ? err.message : "DOCX \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err) };
30459
+ return { success: false, fileType: "docx", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err) };
29853
30460
  }
29854
30461
  }
29855
30462
  async function parseHwpml(buffer, options) {
@@ -29857,16 +30464,16 @@ async function parseHwpml(buffer, options) {
29857
30464
  const { markdown, blocks, metadata, outline, warnings } = parseHwpmlDocument(buffer, options);
29858
30465
  return { success: true, fileType: "hwpml", markdown, blocks, metadata, outline, warnings };
29859
30466
  } catch (err) {
29860
- return { success: false, fileType: "hwpml", error: err instanceof Error ? err.message : "HWPML \uD30C\uC2F1 \uC2E4\uD328", code: _chunk6XAAYAWLcjs.classifyError.call(void 0, err) };
30467
+ return { success: false, fileType: "hwpml", error: _chunk37VKMUSTcjs.sanitizeError.call(void 0, err), code: _chunk37VKMUSTcjs.classifyError.call(void 0, err) };
29861
30468
  }
29862
30469
  }
29863
30470
  async function fillForm(input, values, outputFormat = "markdown") {
29864
30471
  let buffer;
29865
30472
  if (typeof input === "string") {
29866
30473
  const buf = await _promises.readFile.call(void 0, input);
29867
- buffer = _chunk6XAAYAWLcjs.toArrayBuffer.call(void 0, buf);
30474
+ buffer = _chunk37VKMUSTcjs.toArrayBuffer.call(void 0, buf);
29868
30475
  } else if (Buffer.isBuffer(input)) {
29869
- buffer = _chunk6XAAYAWLcjs.toArrayBuffer.call(void 0, input);
30476
+ buffer = _chunk37VKMUSTcjs.toArrayBuffer.call(void 0, input);
29870
30477
  } else {
29871
30478
  buffer = input;
29872
30479
  }
@@ -29892,7 +30499,7 @@ async function fillForm(input, values, outputFormat = "markdown") {
29892
30499
  throw new Error(`\uC11C\uC2DD \uD30C\uC2F1 \uC2E4\uD328: ${parsed.error}`);
29893
30500
  }
29894
30501
  const fill = fillFormFields(parsed.blocks, values);
29895
- const markdown = _chunk6XAAYAWLcjs.blocksToMarkdown.call(void 0, fill.blocks);
30502
+ const markdown = _chunk37VKMUSTcjs.blocksToMarkdown.call(void 0, fill.blocks);
29896
30503
  if (outputFormat === "hwpx") {
29897
30504
  const hwpxBuffer = await markdownToHwpx(markdown);
29898
30505
  return { output: hwpxBuffer, format: "hwpx", fill };
@@ -29961,5 +30568,9 @@ async function fillForm(input, values, outputFormat = "markdown") {
29961
30568
 
29962
30569
 
29963
30570
 
29964
- exports.HwpxSession = HwpxSession; exports.PRESET_ALIAS = PRESET_ALIAS; exports.SPACE_EM_FIXED = SPACE_EM_FIXED; exports.SPACE_EM_FONT = SPACE_EM_FONT; exports.VERSION = _chunk6XAAYAWLcjs.VERSION; exports.ValueCursor = ValueCursor; exports.applySplices = applySplices; exports.blocksToMarkdown = _chunk6XAAYAWLcjs.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.gongmunLintWarnings = gongmunLintWarnings; exports.hwpxToProfile = hwpxToProfile; exports.incompatibleGongmunWarnings = incompatibleGongmunWarnings; exports.inferFieldType = inferFieldType; exports.isHwpxFile = isHwpxFile; exports.isKnownFont = isKnownFont; exports.isLabelCell = isLabelCell; exports.isOldHwpFile = isOldHwpFile; exports.isPdfFile = isPdfFile; exports.isZipFile = isZipFile; exports.lintGongmunText = lintGongmunText; 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.placeSealHwpx = placeSealHwpx; exports.renderHtml = renderHtml; exports.renderHwpxToSvg = renderHwpxToSvg; exports.scanSectionXml = scanSectionXml; exports.simulateWrap = simulateWrap; exports.simulateWrapKeepWord = simulateWrapKeepWord; exports.unknownFontWarnings = unknownFontWarnings; exports.validateHwpx = validateHwpx;
30571
+
30572
+
30573
+
30574
+
30575
+ exports.DEFAULT_REDACT_RULES = DEFAULT_REDACT_RULES; exports.HwpxSession = HwpxSession; exports.PRESET_ALIAS = PRESET_ALIAS; exports.SPACE_EM_FIXED = SPACE_EM_FIXED; exports.SPACE_EM_FONT = SPACE_EM_FONT; exports.VERSION = _chunk37VKMUSTcjs.VERSION; exports.ValueCursor = ValueCursor; exports.applySplices = applySplices; exports.blocksToChunks = blocksToChunks; exports.blocksToMarkdown = _chunk37VKMUSTcjs.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.gongmunLintWarnings = gongmunLintWarnings; exports.hwpxToProfile = hwpxToProfile; exports.incompatibleGongmunWarnings = incompatibleGongmunWarnings; exports.inferFieldType = inferFieldType; exports.isHwpxFile = isHwpxFile; exports.isKnownFont = isKnownFont; exports.isLabelCell = isLabelCell; exports.isOldHwpFile = isOldHwpFile; exports.isPdfFile = isPdfFile; exports.isZipFile = isZipFile; exports.lintGongmunText = lintGongmunText; 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.placeSealHwpx = placeSealHwpx; exports.redactMarkdown = redactMarkdown; exports.redactText = redactText; exports.renderHtml = renderHtml; exports.renderHwpxToSvg = renderHwpxToSvg; exports.scanSectionXml = scanSectionXml; exports.simulateWrap = simulateWrap; exports.simulateWrapKeepWord = simulateWrapKeepWord; exports.unknownFontWarnings = unknownFontWarnings; exports.validateHwpx = validateHwpx;
29965
30576
  //# sourceMappingURL=index.cjs.map