kordoc 4.16.0 → 4.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +344 -1135
  2. package/dist/{-VQNLLLPE.js → -4G6MA4X6.js} +11 -11
  3. package/dist/chunk-3IB7LBHC.js +57 -0
  4. package/dist/chunk-3IB7LBHC.js.map +1 -0
  5. package/dist/{chunk-6LMKQM7I.js → chunk-4VODJKFL.js} +3 -3
  6. package/dist/{chunk-UDX7TSOC.js → chunk-5KS5PWJR.js} +2 -2
  7. package/dist/chunk-62W7QCEX.cjs +57 -0
  8. package/dist/chunk-62W7QCEX.cjs.map +1 -0
  9. package/dist/{chunk-NNYF2AGC.js → chunk-7KNGSQU7.js} +4 -4
  10. package/dist/chunk-7KNGSQU7.js.map +1 -0
  11. package/dist/{chunk-DYENR3PX.js → chunk-AUWGDP4G.js} +2 -2
  12. package/dist/{chunk-H6KMTYYZ.cjs → chunk-CEIATRDW.cjs} +3 -3
  13. package/dist/{chunk-H6KMTYYZ.cjs.map → chunk-CEIATRDW.cjs.map} +1 -1
  14. package/dist/{chunk-N6TPODYL.js → chunk-DES2LGFZ.js} +2 -2
  15. package/dist/{chunk-PQRP4NSF.js → chunk-F4NRLLY4.js} +2 -2
  16. package/dist/{chunk-B5NEGP65.cjs → chunk-FKUDAIJI.cjs} +692 -33
  17. package/dist/chunk-FKUDAIJI.cjs.map +1 -0
  18. package/dist/{chunk-XWA625AN.js → chunk-FSDJLAOW.js} +3 -1
  19. package/dist/chunk-FSDJLAOW.js.map +1 -0
  20. package/dist/{chunk-PIMB2YNO.js → chunk-GO5IFOUF.js} +2 -2
  21. package/dist/{chunk-476OYHGZ.js → chunk-IQGIT2VX.js} +37 -7
  22. package/dist/chunk-IQGIT2VX.js.map +1 -0
  23. package/dist/chunk-J3IF6KGW.js +59 -0
  24. package/dist/chunk-J3IF6KGW.js.map +1 -0
  25. package/dist/{chunk-C75WE52C.js → chunk-JELRWAZC.js} +2 -2
  26. package/dist/{chunk-46DZF3RK.js → chunk-JFLAM3MM.js} +2 -2
  27. package/dist/{chunk-A3QDRMVD.js → chunk-KIOQ4N37.js} +2 -2
  28. package/dist/{chunk-TGD7UFHD.js → chunk-LEIAEWZ7.js} +4 -4
  29. package/dist/chunk-LEIAEWZ7.js.map +1 -0
  30. package/dist/{chunk-GOQBON77.js → chunk-MLIS253L.js} +2 -2
  31. package/dist/{chunk-JB5X5NNL.js → chunk-OXLPVQYK.js} +680 -21
  32. package/dist/chunk-OXLPVQYK.js.map +1 -0
  33. package/dist/{chunk-RC4C7Q33.js → chunk-P6ZDXTV6.js} +2 -2
  34. package/dist/{chunk-CB5XDCSL.js → chunk-QOCS7W7R.js} +5034 -4569
  35. package/dist/chunk-QOCS7W7R.js.map +1 -0
  36. package/dist/{chunk-3JWMDL3S.js → chunk-S2PL227Q.js} +2 -2
  37. package/dist/{chunk-HIVK5V27.js → chunk-SFEQYKYJ.js} +133 -110
  38. package/dist/chunk-SFEQYKYJ.js.map +1 -0
  39. package/dist/{chunk-NWODPYBD.cjs → chunk-STM3ORY7.cjs} +2 -2
  40. package/dist/{chunk-NWODPYBD.cjs.map → chunk-STM3ORY7.cjs.map} +1 -1
  41. package/dist/{chunk-43FKGDDO.js → chunk-TXUKTOG2.js} +213 -30
  42. package/dist/chunk-TXUKTOG2.js.map +1 -0
  43. package/dist/{chunk-XHOZB2WP.js → chunk-UTP2WCHS.js} +681 -22
  44. package/dist/chunk-UTP2WCHS.js.map +1 -0
  45. package/dist/{chunk-MH6MAL64.cjs → chunk-WDQTFAXY.cjs} +217 -114
  46. package/dist/chunk-WDQTFAXY.cjs.map +1 -0
  47. package/dist/{chunk-DRY3L5KQ.cjs → chunk-XTFN5WKS.cjs} +7 -7
  48. package/dist/chunk-XTFN5WKS.cjs.map +1 -0
  49. package/dist/chunks-NUNIKS2J.js +10 -0
  50. package/dist/cli.js +33 -30
  51. package/dist/cli.js.map +1 -1
  52. package/dist/{formula-FNQYHMIY.js → formula-EPKLPDU7.js} +3 -3
  53. package/dist/{formula-5775PTP2.js → formula-NARUOXRX.js} +4 -4
  54. package/dist/{formula-VEFKYXPB.cjs → formula-WIMV5TUX.cjs} +9 -9
  55. package/dist/{formula-VEFKYXPB.cjs.map → formula-WIMV5TUX.cjs.map} +1 -1
  56. package/dist/{image-ocr-PYZU4TO7.js → image-ocr-3WJ4QH3T.js} +8 -8
  57. package/dist/{image-ocr-YA2MQBRP.js → image-ocr-5BUJQ4TK.js} +6 -6
  58. package/dist/{image-ocr-6JZR734G.cjs → image-ocr-AXWXR6JV.cjs} +15 -15
  59. package/dist/{image-ocr-6JZR734G.cjs.map → image-ocr-AXWXR6JV.cjs.map} +1 -1
  60. package/dist/index.cjs +1900 -1406
  61. package/dist/index.cjs.map +1 -1
  62. package/dist/index.d.cts +24 -6
  63. package/dist/index.d.ts +24 -6
  64. package/dist/index.js +1282 -788
  65. package/dist/index.js.map +1 -1
  66. package/dist/mcp.js +34 -28
  67. package/dist/mcp.js.map +1 -1
  68. package/dist/{model-bundle-O6J7ORVC.js → model-bundle-IMBW7D2Z.js} +5 -5
  69. package/dist/{models-YMOKZGCI.js → models-SY75IBOE.js} +5 -5
  70. package/dist/{parser-YAQV7FBO.cjs → parser-2LU4EVU3.cjs} +360 -219
  71. package/dist/parser-2LU4EVU3.cjs.map +1 -0
  72. package/dist/{parser-3B6I2XL7.js → parser-N6476XAC.js} +225 -84
  73. package/dist/parser-N6476XAC.js.map +1 -0
  74. package/dist/{parser-PXATL5DM.js → parser-ZQM3664Z.js} +222 -81
  75. package/dist/parser-ZQM3664Z.js.map +1 -0
  76. package/dist/pdf-ocr-6DEE23IP.js +15 -0
  77. package/dist/pdf-ocr-GHEJVPX2.cjs +16 -0
  78. package/dist/{pdf-ocr-T2JXQATA.cjs.map → pdf-ocr-GHEJVPX2.cjs.map} +1 -1
  79. package/dist/pdf-ocr-MQTWODVU.js +18 -0
  80. package/dist/{profile-io-ZTV2MKRT.js → profile-io-GJPKCYPT.js} +3 -3
  81. package/dist/{rasterize-MMUZ537K.js → rasterize-UOALJQDS.js} +3 -3
  82. package/dist/{redact-doc-S42XGV5D.js → redact-doc-22SYW3KH.js} +11 -11
  83. package/dist/{render-WCWPZKJ7.js → render-MJ4H3R23.js} +7 -7
  84. package/dist/seal-XWMRUTI4.js +10 -0
  85. package/dist/{setup-D35LKZCH.js → setup-2URYVUEO.js} +3 -3
  86. package/dist/visual-USPS4QRC.js +20 -0
  87. package/dist/{watch-AX64CIMN.js → watch-ALXZGTOB.js} +12 -12
  88. package/package.json +1 -1
  89. package/dist/chunk-43FKGDDO.js.map +0 -1
  90. package/dist/chunk-476OYHGZ.js.map +0 -1
  91. package/dist/chunk-B5NEGP65.cjs.map +0 -1
  92. package/dist/chunk-CB5XDCSL.js.map +0 -1
  93. package/dist/chunk-DRY3L5KQ.cjs.map +0 -1
  94. package/dist/chunk-HIVK5V27.js.map +0 -1
  95. package/dist/chunk-JB5X5NNL.js.map +0 -1
  96. package/dist/chunk-MH6MAL64.cjs.map +0 -1
  97. package/dist/chunk-NNYF2AGC.js.map +0 -1
  98. package/dist/chunk-QJERJZJ6.js +0 -11
  99. package/dist/chunk-QJERJZJ6.js.map +0 -1
  100. package/dist/chunk-TGD7UFHD.js.map +0 -1
  101. package/dist/chunk-UQ6TZDW6.js +0 -13
  102. package/dist/chunk-UQ6TZDW6.js.map +0 -1
  103. package/dist/chunk-XHOZB2WP.js.map +0 -1
  104. package/dist/chunk-XWA625AN.js.map +0 -1
  105. package/dist/chunk-ZY5K3LPM.cjs +0 -11
  106. package/dist/chunk-ZY5K3LPM.cjs.map +0 -1
  107. package/dist/chunks-JD25E5PM.js +0 -10
  108. package/dist/parser-3B6I2XL7.js.map +0 -1
  109. package/dist/parser-PXATL5DM.js.map +0 -1
  110. package/dist/parser-YAQV7FBO.cjs.map +0 -1
  111. package/dist/pdf-ocr-2TTO5PX2.js +0 -15
  112. package/dist/pdf-ocr-T2JXQATA.cjs +0 -16
  113. package/dist/pdf-ocr-WF2NQA6X.js +0 -18
  114. package/dist/seal-WHK4GOHR.js +0 -10
  115. package/dist/visual-WL4TDE5B.js +0 -20
  116. /package/dist/{-VQNLLLPE.js.map → -4G6MA4X6.js.map} +0 -0
  117. /package/dist/{chunk-6LMKQM7I.js.map → chunk-4VODJKFL.js.map} +0 -0
  118. /package/dist/{chunk-UDX7TSOC.js.map → chunk-5KS5PWJR.js.map} +0 -0
  119. /package/dist/{chunk-DYENR3PX.js.map → chunk-AUWGDP4G.js.map} +0 -0
  120. /package/dist/{chunk-N6TPODYL.js.map → chunk-DES2LGFZ.js.map} +0 -0
  121. /package/dist/{chunk-PQRP4NSF.js.map → chunk-F4NRLLY4.js.map} +0 -0
  122. /package/dist/{chunk-PIMB2YNO.js.map → chunk-GO5IFOUF.js.map} +0 -0
  123. /package/dist/{chunk-C75WE52C.js.map → chunk-JELRWAZC.js.map} +0 -0
  124. /package/dist/{chunk-46DZF3RK.js.map → chunk-JFLAM3MM.js.map} +0 -0
  125. /package/dist/{chunk-A3QDRMVD.js.map → chunk-KIOQ4N37.js.map} +0 -0
  126. /package/dist/{chunk-GOQBON77.js.map → chunk-MLIS253L.js.map} +0 -0
  127. /package/dist/{chunk-RC4C7Q33.js.map → chunk-P6ZDXTV6.js.map} +0 -0
  128. /package/dist/{chunk-3JWMDL3S.js.map → chunk-S2PL227Q.js.map} +0 -0
  129. /package/dist/{chunks-JD25E5PM.js.map → chunks-NUNIKS2J.js.map} +0 -0
  130. /package/dist/{formula-FNQYHMIY.js.map → formula-EPKLPDU7.js.map} +0 -0
  131. /package/dist/{formula-5775PTP2.js.map → formula-NARUOXRX.js.map} +0 -0
  132. /package/dist/{image-ocr-PYZU4TO7.js.map → image-ocr-3WJ4QH3T.js.map} +0 -0
  133. /package/dist/{image-ocr-YA2MQBRP.js.map → image-ocr-5BUJQ4TK.js.map} +0 -0
  134. /package/dist/{model-bundle-O6J7ORVC.js.map → model-bundle-IMBW7D2Z.js.map} +0 -0
  135. /package/dist/{models-YMOKZGCI.js.map → models-SY75IBOE.js.map} +0 -0
  136. /package/dist/{pdf-ocr-2TTO5PX2.js.map → pdf-ocr-6DEE23IP.js.map} +0 -0
  137. /package/dist/{pdf-ocr-WF2NQA6X.js.map → pdf-ocr-MQTWODVU.js.map} +0 -0
  138. /package/dist/{profile-io-ZTV2MKRT.js.map → profile-io-GJPKCYPT.js.map} +0 -0
  139. /package/dist/{rasterize-MMUZ537K.js.map → rasterize-UOALJQDS.js.map} +0 -0
  140. /package/dist/{redact-doc-S42XGV5D.js.map → redact-doc-22SYW3KH.js.map} +0 -0
  141. /package/dist/{render-WCWPZKJ7.js.map → render-MJ4H3R23.js.map} +0 -0
  142. /package/dist/{seal-WHK4GOHR.js.map → seal-XWMRUTI4.js.map} +0 -0
  143. /package/dist/{setup-D35LKZCH.js.map → setup-2URYVUEO.js.map} +0 -0
  144. /package/dist/{visual-WL4TDE5B.js.map → visual-USPS4QRC.js.map} +0 -0
  145. /package/dist/{watch-AX64CIMN.js.map → watch-ALXZGTOB.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  blocksToPages,
5
5
  encodePng,
6
6
  escapeLiteralDollar
7
- } from "./chunk-NNYF2AGC.js";
7
+ } from "./chunk-7KNGSQU7.js";
8
8
  import {
9
9
  hasRequestedPagesAfter,
10
10
  parsePageRange
@@ -41,15 +41,18 @@ import {
41
41
  ocrModelsCached,
42
42
  refineDocumentStyleHeadings,
43
43
  removeHeaderFooterBlocks,
44
+ startsNewItem,
44
45
  trimTrailingEmptyTableCols,
45
46
  wrapJoiner
46
- } from "./chunk-HIVK5V27.js";
47
- import "./chunk-QJERJZJ6.js";
48
- import "./chunk-PQRP4NSF.js";
47
+ } from "./chunk-TXUKTOG2.js";
48
+ import {
49
+ stripScriptTags
50
+ } from "./chunk-3IB7LBHC.js";
51
+ import "./chunk-F4NRLLY4.js";
49
52
  import {
50
53
  KordocError,
51
54
  sanitizeHref
52
- } from "./chunk-GOQBON77.js";
55
+ } from "./chunk-MLIS253L.js";
53
56
 
54
57
  // src/pdf/ocr-region-merge.ts
55
58
  function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
@@ -634,6 +637,40 @@ function ocrVectorOps(opList, paths) {
634
637
  return { fnArray, argsArray };
635
638
  }
636
639
 
640
+ // src/pdf/contact-table.ts
641
+ var CONTACT_HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
642
+ var CONTACT_ROLE = /^(?:책임자|담당자)$/;
643
+ var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
644
+ function splitContactTables(blocks) {
645
+ for (const b of blocks) {
646
+ const t = b.type === "table" ? b.table : void 0;
647
+ if (!t || t.cols !== 4 || t.rows < 2) continue;
648
+ const rows = t.cells;
649
+ if (!CONTACT_HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
650
+ const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
651
+ if (people.some((p) => !p) || rows.some((r) => !CONTACT_ROLE.test(r[2].text.replace(/\s+/g, "")) || r[2].rowSpan !== 1 || r[3].rowSpan !== 1)) continue;
652
+ const lead = [];
653
+ let ok = true;
654
+ for (const c of [0, 1]) {
655
+ const top = rows[0][c];
656
+ if (top.rowSpan === 1) {
657
+ lead.push(rows.map((r) => r[c].text));
658
+ continue;
659
+ }
660
+ const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
661
+ if (top.rowSpan !== t.rows || lines.length > t.rows) {
662
+ ok = false;
663
+ break;
664
+ }
665
+ lead.push(rows.map((_, r) => lines[r] ?? ""));
666
+ }
667
+ if (!ok) continue;
668
+ const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
669
+ t.cells = rows.map((r, i) => [one(lead[0][i]), one(lead[1][i]), one(r[2].text), one(people[i][1]), one(people[i][2]), one(people[i][3])]);
670
+ t.cols = 6;
671
+ }
672
+ }
673
+
637
674
  // src/pdf/table-parts.ts
638
675
  var PART_COL_TOL = 1;
639
676
  function anchorsOf(table) {
@@ -670,7 +707,7 @@ var indexOf = (coords, x) => {
670
707
  };
671
708
  var rowText = (anchors, r) => anchors.filter((a) => a.r === r).map((a) => a.cell.text.replace(/\s+/g, "")).join("|");
672
709
  var hasText = (t) => t.replace(/\|/g, "") !== "";
673
- function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
710
+ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
674
711
  if (pcx.length !== prev.cols + 1 || ccx.length !== curr.cols + 1) return null;
675
712
  const U = unionCoords(pcx, ccx);
676
713
  const cols = U.length - 1;
@@ -726,13 +763,35 @@ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
726
763
  }
727
764
  for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) if (owner[r][c] === null) FILLER_CELLS.add(grid[r][c]);
728
765
  const table = { rows, cols, cells: grid, hasHeader: prev.hasHeader, ...prev.caption ? { caption: prev.caption } : {} };
729
- const split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
730
- if (rows > prev.rows && !split && prevBottom !== void 0) mergeStraddlingCells(table, owner, prev.rows, prevBottom);
766
+ let split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
767
+ if (rows > prev.rows && !split && prevBottom !== void 0 && mergeStraddlingCells(table, owner, prev.rows, prevBottom, lex)) split = mergeSplitRow(table, owner, prev.rows, U, true);
731
768
  return { table, colXs: U, split, header: ca.filter((a) => a.r < skip && a.cell.text.trim()).length >= 2 };
732
769
  }
733
- function mergeStraddlingCells(table, owner, first, prevBottom) {
770
+ function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
734
771
  const last = first - 1;
735
- if (!owner[first].some((o, c) => o !== null && o === owner[last][c])) return;
772
+ const straddles = owner[first].some((o, c) => o !== null && o === owner[last][c]);
773
+ let firstNew = table.cols;
774
+ for (let c = 0; c < table.cols; c++) {
775
+ const d = owner[first][c];
776
+ if (d && d.r === first && d !== owner[last][c] && hasContent(table.cells[d.r][d.c])) {
777
+ firstNew = c;
778
+ break;
779
+ }
780
+ }
781
+ let midWord = false;
782
+ if (lex) for (let c = 0; c < table.cols && !midWord; ) {
783
+ const u = owner[last][c], d = owner[first][c];
784
+ if (!u) {
785
+ c++;
786
+ continue;
787
+ }
788
+ c = u.c + u.cs;
789
+ if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
790
+ if (u.r !== last || d.rs < 2) continue;
791
+ const tail = table.cells[u.r][u.c].text.trim().split(/\s+/).pop() ?? "", head = table.cells[first][d.c].text.trim().split(/\s+/)[0] ?? "";
792
+ if (/^[가-힣]{2,}$/.test(tail) && /^[가-힣]{2,}/.test(head) && lex.evidence2(tail, head) === "") midWord = true;
793
+ }
794
+ let merged = false;
736
795
  for (let c = 0; c < table.cols; ) {
737
796
  const u = owner[last][c], d = owner[first][c];
738
797
  if (!u) {
@@ -740,18 +799,24 @@ function mergeStraddlingCells(table, owner, first, prevBottom) {
740
799
  continue;
741
800
  }
742
801
  c = u.c + u.cs;
743
- if (!d || d === u || u.r >= last && d.rs < 2 || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
802
+ if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
744
803
  const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
745
- const U = CELL_LINES.get(a);
746
- if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
747
- const lu = U[U.length - 1];
748
- if (lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
804
+ if (!(u.rs >= 2 && u.c + u.cs <= firstNew && hasContent(a) && !hasContent(b))) {
805
+ if (!straddles && !midWord) continue;
806
+ if (u.r >= last && d.rs < 2) continue;
807
+ const U = CELL_LINES.get(a);
808
+ if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
809
+ const lu = U[U.length - 1];
810
+ if (!midWord && lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
811
+ }
749
812
  appendCell(a, b);
750
813
  a.rowSpan = first + d.rs - u.r;
751
814
  table.cells[first][d.c] = { text: "", colSpan: 1, rowSpan: 1 };
752
815
  const grown = { ...u, rs: a.rowSpan };
753
816
  for (let rr = u.r; rr < u.r + grown.rs; rr++) for (let dc = u.c; dc < u.c + u.cs; dc++) owner[rr][dc] = grown;
817
+ merged = true;
754
818
  }
819
+ return merged;
755
820
  }
756
821
  var FULL_LINE_TOL = 1;
757
822
  var FULL_LINE_MIN_FRAC = 0.5;
@@ -787,11 +852,21 @@ function continuesAcross(u, d, x1, x2) {
787
852
  const hanging = U.length >= 2 && U.every((l) => maxR - l.r <= FULL_LINE_TOL * fs) && last.l - minL >= HANGING_MIN * fs && Math.abs(D[0].l - last.l) <= HANGING_TOL;
788
853
  return U.some(leftAligned) || D.some(leftAligned) || hanging;
789
854
  }
790
- function lineEnded(c, x1, x2) {
855
+ var OUTLINE_HEAD = /^[□■]\s*\S/;
856
+ var OUTLINE_ITEM = /^[ㅇ○◦\-‐–·․‧※*]\s*\S/;
857
+ function outlineContinues(u, d) {
858
+ const U = u.text.split("\n").map((l) => l.trim()).filter(Boolean);
859
+ const D = d.text.split("\n").map((l) => l.trim()).filter(Boolean);
860
+ return U.length >= 2 && D.length >= 1 && U.some((l) => OUTLINE_HEAD.test(l)) && OUTLINE_ITEM.test(D[0]);
861
+ }
862
+ function lineEnded(c, x1, x2, next = "") {
791
863
  const L = CELL_LINES.get(c);
792
864
  if (!L || L.length !== 1) return false;
793
- const l = L[0];
794
- return x2 - l.r - (l.l - x1) >= LABEL_ROOM * (l.h || 10);
865
+ const l = L[0], h = l.h || 10;
866
+ const word = next.trim().split(/\s+/)[0] ?? "";
867
+ let units = 0;
868
+ for (const ch of word) units += /[가-힣\u3400-\u9fff]/.test(ch) ? 1 : 0.55;
869
+ return x2 - l.r - (l.l - x1) >= Math.max(LABEL_ROOM, units) * h;
795
870
  }
796
871
  function appendCell(a, b) {
797
872
  if (a.blocks?.length || b.blocks?.length) {
@@ -801,7 +876,22 @@ function appendCell(a, b) {
801
876
  if (b.text.trim()) a.text = a.text.trim() ? a.text + "\n" + b.text : b.text;
802
877
  }
803
878
  var hasContent = (cell) => !!cell.text.trim() || !!cell.blocks?.length || IMAGE_CELLS.has(cell);
804
- function mergeSplitRow(table, owner, first, colXs) {
879
+ var CLAUSE_OPEN_ENDING = /(?:하는|되는|하고|하며|하여|되어|되고|되며|이며|으며|어야|아야|여야)$/;
880
+ var batchim = (ch) => {
881
+ const k = ch.charCodeAt(0) - 44032;
882
+ return k >= 0 && k < 11172 && k % 28 !== 0;
883
+ };
884
+ function clauseContinues(u, d) {
885
+ const tail = u.text.trim().split(/\s+/).pop() ?? "", head = d.text.trim();
886
+ if (!/^[가-힣]{2,}$/.test(tail) || !/^[가-힣]/.test(head) || startsNewItem(u.text, head)) return false;
887
+ const last = tail[tail.length - 1], before = tail[tail.length - 2];
888
+ return last === "\uC744" && batchim(before) || last === "\uB97C" && !batchim(before) || CLAUSE_OPEN_ENDING.test(tail);
889
+ }
890
+ function outlineOnly(pairs, cell) {
891
+ const filled = pairs.filter(([, d]) => hasContent(d.cell));
892
+ return filled.length === 1 && outlineContinues(cell(filled[0][0]), cell(filled[0][1]));
893
+ }
894
+ function mergeSplitRow(table, owner, first, colXs, textOnly = false) {
805
895
  const last = first - 1;
806
896
  const pairs = [];
807
897
  let carried = false;
@@ -819,12 +909,12 @@ function mergeSplitRow(table, owner, first, colXs) {
819
909
  } else if (a.r === last && a.rs === 2) carried = true;
820
910
  c = a.c + a.cs;
821
911
  }
822
- const carriedSplit = carried && pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell)).length <= 1 && !pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
912
+ const carriedSplit = !textOnly && carried && pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell)).length <= 1 && !pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
823
913
  const cell = (a) => table.cells[a.r][a.c];
824
914
  if (!carriedSplit) {
825
915
  const norm = (c) => c.text.replace(/\s+/g, "");
826
- if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs]))) return false;
827
- if (!pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]))) return false;
916
+ if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs], cell(d).text))) return false;
917
+ if (!outlineOnly(pairs, cell) && !pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs])) && !pairs.some(([u, d]) => clauseContinues(cell(u), cell(d)))) return false;
828
918
  }
829
919
  for (const [u, d] of pairs) appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
830
920
  for (let r = 0; r < first; r++) for (let c = 0; c < table.cols; c++) {
@@ -871,8 +961,8 @@ function sameHeadShape(a, b) {
871
961
  }
872
962
  return tall;
873
963
  }
874
- function mergeCrossPageTables(blocks, pageHeights) {
875
- mergeColumnFlow(blocks, pageHeights);
964
+ function mergeCrossPageTables(blocks, pageHeights, lex) {
965
+ mergeColumnFlow(blocks, pageHeights, lex);
876
966
  for (let i = blocks.length - 2; i >= 0; i--) {
877
967
  const prev = blocks[i];
878
968
  if (prev.type !== "table" || !prev.table || !prev.bbox || !prev.pageNumber) continue;
@@ -881,7 +971,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
881
971
  const curr = blocks[j];
882
972
  if (!curr || curr.type !== "table" || !curr.table || !curr.bbox || curr.pageNumber !== prev.pageNumber + 1) continue;
883
973
  if (startsWithUnitRow(prev.table) && startsWithUnitRow(curr.table)) continue;
884
- const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) => besideOwn(b, prev, curr) || insideTable(b, prev)) ? looksContinued(prev, curr, pageHeights) && !restartsTable(blocks, i, curr.table, pageHeights) ? joinClipParts(prev, curr, pageHeights) ?? false : null : null;
974
+ const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) => besideOwn(b, prev, curr) || insideTable(b, prev)) ? looksContinued(prev, curr, pageHeights) && !restartsTable(blocks, i, curr.table, pageHeights) ? joinClipParts(prev, curr, pageHeights, lex) ?? false : null : null;
885
975
  if (joined) {
886
976
  placeJoined(blocks, i, j, joined);
887
977
  continue;
@@ -925,7 +1015,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
925
1015
  if (blocks[i].type === "table" && t && EMPTY_PARTS.has(t)) blocks.splice(i, 1);
926
1016
  }
927
1017
  }
928
- function mergeColumnFlow(blocks, pageHeights) {
1018
+ function mergeColumnFlow(blocks, pageHeights, lex) {
929
1019
  if (!pageHeights) return;
930
1020
  for (let i = 0; i < blocks.length; i++) {
931
1021
  const L = blocks[i];
@@ -947,7 +1037,7 @@ function mergeColumnFlow(blocks, pageHeights) {
947
1037
  const R = blocks[k];
948
1038
  if (Math.abs(R.bbox.width - L.bbox.width) > Math.max(R.bbox.width, L.bbox.width) * NEIGHBOR_TABLE_EPSILON) continue;
949
1039
  if (!looksContinued(L, R) || restartsTable(blocks, i, R.table, pageHeights)) continue;
950
- const joined = joinClipParts(L, R, pageHeights);
1040
+ const joined = joinClipParts(L, R, pageHeights, lex);
951
1041
  if (!joined) continue;
952
1042
  const top = L.bbox.y + L.bbox.height;
953
1043
  const at = Math.min(i, k);
@@ -956,12 +1046,12 @@ function mergeColumnFlow(blocks, pageHeights) {
956
1046
  i = at - 1;
957
1047
  }
958
1048
  }
959
- function joinClipParts(prev, curr, pageHeights) {
1049
+ function joinClipParts(prev, curr, pageHeights, lex) {
960
1050
  const pt = prev.table, ct = curr.table;
961
1051
  if (!CLIP_TABLES.has(pt) || !CLIP_TABLES.has(ct)) return null;
962
1052
  const px = TABLE_COLXS.get(pt), cx = TABLE_COLXS.get(ct);
963
1053
  if (!px || !cx) return null;
964
- let xs = cx, shifted = false, dx = 0;
1054
+ let xs = cx, shifted = false, dx = 0, foreign = false;
965
1055
  if (!shiftedSame(px, cx, false)) {
966
1056
  if (!pageHeights?.get(prev.pageNumber) || !pageHeights?.get(curr.pageNumber)) return null;
967
1057
  dx = px[px.length - 1] - cx[cx.length - 1];
@@ -970,19 +1060,29 @@ function joinClipParts(prev, curr, pageHeights) {
970
1060
  shifted = true;
971
1061
  } else dx = 0;
972
1062
  if (!px.some((x) => Math.abs(x - xs[0]) <= CONTINUATION_COL_TOL)) return null;
1063
+ const inner = xs.slice(1, -1);
1064
+ foreign = inner.length > 0 && !inner.some((x) => px.some((p) => Math.abs(p - x) <= CONTINUATION_COL_TOL)) && headingRow(ct.cells[0] ?? []);
973
1065
  }
974
- const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y);
975
- if (!res || shifted && !res.split && !res.header) return null;
1066
+ const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y, lex);
1067
+ if (!res || (shifted || foreign) && !res.split && !res.header) return null;
976
1068
  TABLE_COLXS.set(res.table, res.colXs);
977
1069
  CLIP_TABLES.add(res.table);
978
1070
  return res.table;
979
1071
  }
1072
+ function headingRow(row) {
1073
+ const heads = row.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1074
+ if (heads.length === 1) return heads[0].length <= 8 || /^[①-⑳❶-❿]/.test(heads[0]);
1075
+ return heads.length === 2 && /^(?:\d{1,2}|[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ]+|[①-⑳❶-❿])$/.test(heads[0]);
1076
+ }
980
1077
  var ANNEX_HEAD_RE = /^\s*[<\[(【]?\s*(?:붙\s*임|참\s*고|별\s*첨|별\s*지|별\s*표|첨\s*부|부\s*록)(?:\s*\d|\s*$|\s*[>\])】])|^\s*■/;
981
1078
  function looksContinued(prev, curr, pageHeights) {
982
1079
  const ph = pageHeights?.get(prev.pageNumber), ch = pageHeights?.get(curr.pageNumber);
983
1080
  if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
984
- const firstText = curr.table.cells[0]?.find((c) => c.text.trim())?.text ?? "";
985
- return !ANNEX_HEAD_RE.test(firstText);
1081
+ const firstRow = curr.table.cells[0] ?? [];
1082
+ const firstText = firstRow.find((c) => c.text.trim())?.text ?? "";
1083
+ if (!ANNEX_HEAD_RE.test(firstText)) return true;
1084
+ const filled = firstRow.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1085
+ return filled.length >= 2 && filled.every((t) => t === filled[0]);
986
1086
  }
987
1087
  function firstRowSig(t) {
988
1088
  const x = TABLE_COLXS.get(t);
@@ -995,6 +1095,7 @@ function restartsTable(blocks, i, curr, pageHeights) {
995
1095
  const head = blocks[chainHead(blocks, i, pageHeights)].table;
996
1096
  if (cs.length === 1 && restartsTitledForm(head, curr)) return true;
997
1097
  if (cs.length < RESTART_MIN_ANCHORS) return false;
1098
+ if (CONTACT_HEAD.test(cs[0].t) && cs.some((c) => CONTACT_ROLE.test(c.t))) return false;
998
1099
  const hs = firstRowSig(head);
999
1100
  if (!hs || hs.length !== cs.length) return false;
1000
1101
  const dx = hs[hs.length - 1].x2 - cs[cs.length - 1].x2;
@@ -1841,6 +1942,52 @@ function restoreTrackedSpacing(items, fnArray, argsArray) {
1841
1942
  }
1842
1943
  return changed;
1843
1944
  }
1945
+ function markSyntheticSpaces(items, fnArray, argsArray) {
1946
+ if (!items.some((it) => typeof it.str === "string" && it.str.length > 0 && !it.str.trim())) return;
1947
+ const streams = /* @__PURE__ */ new Map();
1948
+ const saved = [];
1949
+ let font = "";
1950
+ for (let i = 0; i < fnArray.length; i++) {
1951
+ const fn = fnArray[i];
1952
+ const args = argsArray[i];
1953
+ if (fn === OPS5.setFont) font = String(args[0]);
1954
+ else if (fn === OPS5.save || fn === OPS5.paintFormXObjectBegin) saved.push(font);
1955
+ else if (fn === OPS5.restore || fn === OPS5.paintFormXObjectEnd) font = saved.pop() ?? font;
1956
+ else if (fn === OPS5.showText) {
1957
+ let list = streams.get(font);
1958
+ if (!list) streams.set(font, list = []);
1959
+ for (const g2 of args[0]) {
1960
+ if (g2 && typeof g2 === "object" && typeof g2.unicode === "string") list.push(normalizeUnicode3(g2.unicode));
1961
+ }
1962
+ }
1963
+ }
1964
+ const cursor = /* @__PURE__ */ new Map();
1965
+ const failed = /* @__PURE__ */ new Set();
1966
+ const marks = [];
1967
+ for (const it of items) {
1968
+ const f = it.fontName ?? "";
1969
+ const glyphs = streams.get(f);
1970
+ if (!glyphs || failed.has(f) || typeof it.str !== "string" || !it.str) continue;
1971
+ let gi = cursor.get(f) ?? 0;
1972
+ if (!it.str.trim()) {
1973
+ if (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) {
1974
+ while (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) gi++;
1975
+ cursor.set(f, gi);
1976
+ } else marks.push(it);
1977
+ continue;
1978
+ }
1979
+ const want = it.str.replace(/\s+/g, "");
1980
+ while (gi < glyphs.length && /^\s*$/.test(glyphs[gi])) gi++;
1981
+ let got = "";
1982
+ while (gi < glyphs.length && got.length < want.length) got += glyphs[gi++].replace(/\s+/g, "");
1983
+ if (got !== want) {
1984
+ failed.add(f);
1985
+ continue;
1986
+ }
1987
+ cursor.set(f, gi);
1988
+ }
1989
+ for (const it of marks) if (!failed.has(it.fontName ?? "")) it.synthetic = true;
1990
+ }
1844
1991
 
1845
1992
  // src/pdf/endnotes.ts
1846
1993
  var NOTE_MARK = /^\s*(문\d{1,5}[))]|\d{1,5}\)|\(\d{1,5}\))/;
@@ -1978,6 +2125,7 @@ function orderTwoUpPage(blocks, pageWidth, pageHeight) {
1978
2125
  var BAND = 0.12;
1979
2126
  var MAX_CHARS = 10;
1980
2127
  var MIN_REPEAT = 3;
2128
+ var RUN_GAP = 5;
1981
2129
  function removeSideTabs(blocks, pageWidths) {
1982
2130
  const edges = /* @__PURE__ */ new Map();
1983
2131
  for (const b of blocks) {
@@ -2010,13 +2158,21 @@ function removeSideTabs(blocks, pageWidths) {
2010
2158
  }
2011
2159
  const running = /* @__PURE__ */ new Set();
2012
2160
  for (const [k, ps] of pages) {
2013
- const list = [...ps];
2014
- const span = Math.max(...list) - Math.min(...list) + 1;
2015
- if (list.length >= MIN_REPEAT && list.length >= span * 0.4) running.add(k);
2161
+ const list = [...ps].sort((a, b) => a - b);
2162
+ let run = [];
2163
+ const flush = () => {
2164
+ if (run.length >= MIN_REPEAT && run.length >= (run[run.length - 1] - run[0] + 1) * 0.4) for (const p of run) running.add(`${p}\0${k}`);
2165
+ run = [];
2166
+ };
2167
+ for (const p of list) {
2168
+ if (run.length && p - run[run.length - 1] > RUN_GAP) flush();
2169
+ run.push(p);
2170
+ }
2171
+ flush();
2016
2172
  }
2017
2173
  return running.size ? blocks.filter((b) => {
2018
2174
  const k = key(b);
2019
- return !k || !running.has(k);
2175
+ return !k || !running.has(`${b.pageNumber}\0${k}`);
2020
2176
  }) : blocks;
2021
2177
  }
2022
2178
 
@@ -2184,7 +2340,9 @@ function normalizeAraea(text) {
2184
2340
  return text.replace(/(?<![\u1100-\u115F])\u119E/g, "\u318D");
2185
2341
  }
2186
2342
  var stripNoUnicodeGlyph = (text) => text.includes("\uF000") ? text.replace(/\uF000/g, "") : text;
2187
- var cleanChars = (text) => normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text)));
2343
+ var CHOSEONG_COMPAT = "\u3131\u3132\u3134\u3137\u3138\u3139\u3141\u3142\u3143\u3145\u3146\u3147\u3148\u3149\u314A\u314B\u314C\u314D\u314E";
2344
+ var normalizeLoneChoseong = (text) => /[\u1100-\u1112]/.test(text) ? text.replace(/[\u1100-\u1112](?![\u1160-\u11A7\uD7B0-\uD7C6])/g, (c) => CHOSEONG_COMPAT[c.charCodeAt(0) - 4352]) : text;
2345
+ var cleanChars = (text) => normalizeLoneChoseong(normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text))));
2188
2346
  function sanitizeBlockControlChars(blocks) {
2189
2347
  for (const b of blocks) {
2190
2348
  if (b.text) b.text = cleanChars(b.text);
@@ -2261,7 +2419,7 @@ function cleanPdfText(text, opts) {
2261
2419
  }
2262
2420
  const mark = /^(?:#{1,6}|-) /.exec(line)?.[0] ?? "";
2263
2421
  return mark + collapseEvenSpacing(line.slice(mark.length), false);
2264
- }).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/\n{3,}/g, "\n\n").trim();
2422
+ }).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/<(sup|sub)>\s*<\/\1>/g, "").replace(/\n{3,}/g, "\n\n").trim();
2265
2423
  }
2266
2424
  function startsWithMarker(line) {
2267
2425
  const t = line.trimStart();
@@ -2349,7 +2507,7 @@ function mergeLinkRuns(markdown) {
2349
2507
 
2350
2508
  // src/pdf/formula-ocr.ts
2351
2509
  async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
2352
- const formulaMod = await import("./formula-FNQYHMIY.js");
2510
+ const formulaMod = await import("./formula-EPKLPDU7.js");
2353
2511
  const { FormulaPipeline, ensureFormulaModels } = formulaMod;
2354
2512
  await ensureFormulaModels((p) => {
2355
2513
  if (p.phase === "download" && p.total) {
@@ -2489,42 +2647,15 @@ g.pdfjsWorker = pdfjsWorker;
2489
2647
  import { getDocument, GlobalWorkerOptions, OPS as OPS6 } from "pdfjs-dist/legacy/build/pdf.mjs";
2490
2648
  import { createRequire } from "module";
2491
2649
  import { dirname, join } from "path";
2492
-
2493
- // src/pdf/contact-table.ts
2494
- var HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
2495
- var ROLE = /^(?:책임자|담당자)$/;
2496
- var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
2497
- function splitContactTables(blocks) {
2498
- for (const b of blocks) {
2499
- const t = b.type === "table" ? b.table : void 0;
2500
- if (!t || t.cols !== 4 || t.rows < 2) continue;
2501
- const rows = t.cells;
2502
- if (!HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
2503
- const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
2504
- if (people.some((p) => !p) || rows.some((r) => !ROLE.test(r[2].text.replace(/\s+/g, "")) || r[2].rowSpan !== 1 || r[3].rowSpan !== 1)) continue;
2505
- const lead = [];
2506
- let ok = true;
2507
- for (const c of [0, 1]) {
2508
- const top = rows[0][c];
2509
- if (top.rowSpan === 1) {
2510
- lead.push(rows.map((r) => r[c].text));
2511
- continue;
2512
- }
2513
- const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
2514
- if (top.rowSpan !== t.rows || lines.length > t.rows) {
2515
- ok = false;
2516
- break;
2517
- }
2518
- lead.push(rows.map((_, r) => lines[r] ?? ""));
2519
- }
2520
- if (!ok) continue;
2521
- const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
2522
- t.cells = rows.map((r, i) => [one(lead[0][i]), one(lead[1][i]), one(r[2].text), one(people[i][1]), one(people[i][2]), one(people[i][3])]);
2523
- t.cols = 6;
2650
+ function ocrImageRegions(regions, large, all) {
2651
+ if (all) return regions;
2652
+ const out = /* @__PURE__ */ new Map();
2653
+ for (const [p, rs] of regions) {
2654
+ const big = rs.filter((r) => large.has(r));
2655
+ if (big.length) out.set(p, big);
2524
2656
  }
2657
+ return out;
2525
2658
  }
2526
-
2527
- // src/pdf/parser.ts
2528
2659
  GlobalWorkerOptions.workerSrc = "";
2529
2660
  var MAX_PAGES = 5e3;
2530
2661
  var MAX_TOTAL_TEXT = 100 * 1024 * 1024;
@@ -2597,6 +2728,7 @@ async function parsePdfDocument(buffer, options) {
2597
2728
  const pagesWithLargeImage = /* @__PURE__ */ new Set();
2598
2729
  const skippedImagePages = /* @__PURE__ */ new Map();
2599
2730
  const uncoveredImageRegions = /* @__PURE__ */ new Map();
2731
+ const largeImageRegions = /* @__PURE__ */ new Set();
2600
2732
  const imageState = createPdfImageState();
2601
2733
  const extractedImages = [];
2602
2734
  const pageImageBlocks = /* @__PURE__ */ new Map();
@@ -2628,6 +2760,7 @@ async function parsePdfDocument(buffer, options) {
2628
2760
  const differencesOf = (loadedName) => fontObj(loadedName)?.differences;
2629
2761
  restoreNamedGlyphs(rawItems, rawOps.fnArray, rawOps.argsArray, differencesOf, (n) => fontObj(n)?.name);
2630
2762
  restoreTrackedSpacing(rawItems, rawOps.fnArray, rawOps.argsArray);
2763
+ markSyntheticSpaces(rawItems, rawOps.fnArray, rawOps.argsArray);
2631
2764
  const occluded = occludedTextItems(rawItems, rawOps.fnArray, rawOps.argsArray);
2632
2765
  const items = normalizeItems(occluded.size ? rawItems.filter((it) => !occluded.has(it)) : rawItems);
2633
2766
  const filtered = filterHiddenText(items, pageW, pageH, viewX1, viewY1);
@@ -2691,6 +2824,7 @@ async function parsePdfDocument(buffer, options) {
2691
2824
  const regions = uncoveredImageRegions.get(i) ?? [];
2692
2825
  regions.push(r);
2693
2826
  uncoveredImageRegions.set(i, regions);
2827
+ if (large) largeImageRegions.add(r);
2694
2828
  }
2695
2829
  }
2696
2830
  }
@@ -2739,6 +2873,7 @@ async function parsePdfDocument(buffer, options) {
2739
2873
  const parsedPageCount = parsedPages || (pageFilter ? pageFilter.size : effectivePageCount);
2740
2874
  const isImageBased = pageFilter?.size !== 0 && totalChars / Math.max(parsedPageCount, 1) < 10;
2741
2875
  const ocrDone = /* @__PURE__ */ new Set();
2876
+ const ocrRegions = options?.ocr === true || autoOcr ? ocrImageRegions(uncoveredImageRegions, largeImageRegions, options?.ocr === true) : /* @__PURE__ */ new Map();
2742
2877
  if (ocrBuffer) {
2743
2878
  const inScope = (p) => !pageFilter || pageFilter.has(p);
2744
2879
  const targets = /* @__PURE__ */ new Set();
@@ -2751,14 +2886,15 @@ async function parsePdfDocument(buffer, options) {
2751
2886
  if (autoOcr && pq.ocrReason !== "low_text" && pq.ocrReason !== "vector_text") continue;
2752
2887
  targets.add(pq.page);
2753
2888
  }
2754
- if (options?.ocr === true) for (const p of uncoveredImageRegions.keys()) targets.add(p);
2889
+ for (const p of ocrRegions.keys()) targets.add(p);
2755
2890
  }
2756
2891
  if (targets.size > 0) {
2757
2892
  try {
2758
- const { runPdfOcr } = await import("./pdf-ocr-2TTO5PX2.js");
2893
+ const { runPdfOcr } = await import("./pdf-ocr-6DEE23IP.js");
2759
2894
  const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
2760
- const regionPages = new Map([...uncoveredImageRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
2895
+ const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
2761
2896
  const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
2897
+ for (const obs of ocrPageBlocks.values()) stripScriptTags({ blocks: obs });
2762
2898
  if (ocrPageBlocks.size > 0) {
2763
2899
  const replacePages = /* @__PURE__ */ new Set();
2764
2900
  for (const [p, obs] of ocrPageBlocks) {
@@ -2768,7 +2904,7 @@ async function parsePdfDocument(buffer, options) {
2768
2904
  ocrDone.add(p);
2769
2905
  continue;
2770
2906
  }
2771
- const regions = uncoveredImageRegions.get(p);
2907
+ const regions = ocrRegions.get(p);
2772
2908
  if (!regions || mergeOcrImageRegions(blocks, p, regions, obs) === 0) continue;
2773
2909
  ocrDone.add(p);
2774
2910
  if (pageImageBlocks.get(p)?.length === 1) pageImageBlocks.delete(p);
@@ -2822,7 +2958,7 @@ async function parsePdfDocument(buffer, options) {
2822
2958
  }
2823
2959
  }
2824
2960
  if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
2825
- const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings);
2961
+ const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks);
2826
2962
  for (let ri = removed.length - 1; ri >= 0; ri--) {
2827
2963
  blocks.splice(removed[ri], 1);
2828
2964
  }
@@ -2833,7 +2969,11 @@ async function parsePdfDocument(buffer, options) {
2833
2969
  }
2834
2970
  }
2835
2971
  mergeContinuedCells(blocks, pageHeights);
2836
- mergeCrossPageTables(blocks, pageHeights);
2972
+ mergeCrossPageTables(blocks, pageHeights, wrapLexicon);
2973
+ if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
2974
+ const boxes = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks, true);
2975
+ for (let ri = boxes.length - 1; ri >= 0; ri--) blocks.splice(boxes[ri], 1);
2976
+ }
2837
2977
  splitContactTables(blocks);
2838
2978
  if (!options?.keepTrailingEmptyCols) trimTrailingEmptyTableCols(blocks);
2839
2979
  joinPageBreakWraps(blocks, wrapLexicon);
@@ -2946,7 +3086,8 @@ export {
2946
3086
  detectTableCaptions,
2947
3087
  extractPdfMetadataOnly,
2948
3088
  mergeCrossPageTables,
3089
+ ocrImageRegions,
2949
3090
  parsePdfDocument,
2950
3091
  removeHeaderFooterBlocks
2951
3092
  };
2952
- //# sourceMappingURL=parser-PXATL5DM.js.map
3093
+ //# sourceMappingURL=parser-ZQM3664Z.js.map