kordoc 4.16.0 → 4.16.1

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 (138) hide show
  1. package/README.md +345 -1135
  2. package/dist/{-VQNLLLPE.js → -3DURLXSO.js} +11 -11
  3. package/dist/{chunk-3JWMDL3S.js → chunk-24N4IJ5I.js} +2 -2
  4. package/dist/{chunk-H6KMTYYZ.cjs → chunk-2BZFKIRB.cjs} +3 -3
  5. package/dist/{chunk-H6KMTYYZ.cjs.map → chunk-2BZFKIRB.cjs.map} +1 -1
  6. package/dist/{chunk-RC4C7Q33.js → chunk-3VLVNKJV.js} +2 -2
  7. package/dist/{chunk-XHOZB2WP.js → chunk-3WIQSM3Z.js} +681 -22
  8. package/dist/chunk-3WIQSM3Z.js.map +1 -0
  9. package/dist/{chunk-DYENR3PX.js → chunk-63YGGAQW.js} +2 -2
  10. package/dist/{chunk-43FKGDDO.js → chunk-7FKPPIDZ.js} +50 -19
  11. package/dist/chunk-7FKPPIDZ.js.map +1 -0
  12. package/dist/{chunk-MH6MAL64.cjs → chunk-7IRHSRPU.cjs} +136 -105
  13. package/dist/chunk-7IRHSRPU.cjs.map +1 -0
  14. package/dist/{chunk-A3QDRMVD.js → chunk-7XAGIPOX.js} +2 -2
  15. package/dist/{chunk-NNYF2AGC.js → chunk-ANZTLTKU.js} +2 -2
  16. package/dist/{chunk-N6TPODYL.js → chunk-BIHS4VWR.js} +2 -2
  17. package/dist/{chunk-476OYHGZ.js → chunk-BTO7ZEE4.js} +6 -6
  18. package/dist/{chunk-46DZF3RK.js → chunk-CXWWX6BQ.js} +2 -2
  19. package/dist/{chunk-DRY3L5KQ.cjs → chunk-D2QCXK2X.cjs} +6 -6
  20. package/dist/{chunk-DRY3L5KQ.cjs.map → chunk-D2QCXK2X.cjs.map} +1 -1
  21. package/dist/{chunk-JB5X5NNL.js → chunk-DJ2BBQ5P.js} +680 -21
  22. package/dist/chunk-DJ2BBQ5P.js.map +1 -0
  23. package/dist/{chunk-ZY5K3LPM.cjs → chunk-DO74GYSM.cjs} +1 -1
  24. package/dist/chunk-DO74GYSM.cjs.map +1 -0
  25. package/dist/{chunk-6LMKQM7I.js → chunk-EEVAPRPD.js} +3 -3
  26. package/dist/{chunk-XWA625AN.js → chunk-FSDJLAOW.js} +3 -1
  27. package/dist/chunk-FSDJLAOW.js.map +1 -0
  28. package/dist/{chunk-QJERJZJ6.js → chunk-KBAQLAEL.js} +1 -1
  29. package/dist/chunk-KBAQLAEL.js.map +1 -0
  30. package/dist/{chunk-PQRP4NSF.js → chunk-N65ZXWNQ.js} +2 -2
  31. package/dist/{chunk-UDX7TSOC.js → chunk-NCXRSQNE.js} +2 -2
  32. package/dist/{chunk-GOQBON77.js → chunk-NUPXPKIQ.js} +2 -2
  33. package/dist/{chunk-B5NEGP65.cjs → chunk-NV37CQFN.cjs} +692 -33
  34. package/dist/chunk-NV37CQFN.cjs.map +1 -0
  35. package/dist/{chunk-CB5XDCSL.js → chunk-OBRPYCIS.js} +1377 -947
  36. package/dist/chunk-OBRPYCIS.js.map +1 -0
  37. package/dist/{chunk-HIVK5V27.js → chunk-PVMROO3A.js} +51 -20
  38. package/dist/chunk-PVMROO3A.js.map +1 -0
  39. package/dist/{chunk-UQ6TZDW6.js → chunk-T77M2QP7.js} +1 -1
  40. package/dist/chunk-T77M2QP7.js.map +1 -0
  41. package/dist/{chunk-TGD7UFHD.js → chunk-UZHT3LBF.js} +2 -2
  42. package/dist/{chunk-PIMB2YNO.js → chunk-VCRBR72A.js} +2 -2
  43. package/dist/{chunk-C75WE52C.js → chunk-VNOQTDTE.js} +2 -2
  44. package/dist/{chunk-NWODPYBD.cjs → chunk-YRRBA4HW.cjs} +2 -2
  45. package/dist/{chunk-NWODPYBD.cjs.map → chunk-YRRBA4HW.cjs.map} +1 -1
  46. package/dist/chunks-PYYQURNO.js +10 -0
  47. package/dist/cli.js +31 -29
  48. package/dist/cli.js.map +1 -1
  49. package/dist/{formula-FNQYHMIY.js → formula-IPLFHEBD.js} +3 -3
  50. package/dist/{formula-VEFKYXPB.cjs → formula-TRTONZMA.cjs} +9 -9
  51. package/dist/{formula-VEFKYXPB.cjs.map → formula-TRTONZMA.cjs.map} +1 -1
  52. package/dist/{formula-5775PTP2.js → formula-U4BTEZ6I.js} +4 -4
  53. package/dist/{image-ocr-PYZU4TO7.js → image-ocr-3IJ25PS4.js} +8 -8
  54. package/dist/{image-ocr-YA2MQBRP.js → image-ocr-GTDG4SAJ.js} +6 -6
  55. package/dist/{image-ocr-6JZR734G.cjs → image-ocr-THFLQ3DC.cjs} +15 -15
  56. package/dist/{image-ocr-6JZR734G.cjs.map → image-ocr-THFLQ3DC.cjs.map} +1 -1
  57. package/dist/index.cjs +1555 -1125
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.d.cts +17 -5
  60. package/dist/index.d.ts +17 -5
  61. package/dist/index.js +1105 -675
  62. package/dist/index.js.map +1 -1
  63. package/dist/mcp.js +31 -27
  64. package/dist/mcp.js.map +1 -1
  65. package/dist/{model-bundle-O6J7ORVC.js → model-bundle-PVWIAVEX.js} +5 -5
  66. package/dist/{models-YMOKZGCI.js → models-VCRF3JMT.js} +5 -5
  67. package/dist/{parser-YAQV7FBO.cjs → parser-2CN2DIPV.cjs} +356 -218
  68. package/dist/parser-2CN2DIPV.cjs.map +1 -0
  69. package/dist/{parser-3B6I2XL7.js → parser-T4RITZDP.js} +221 -83
  70. package/dist/parser-T4RITZDP.js.map +1 -0
  71. package/dist/{parser-PXATL5DM.js → parser-UEROAPYZ.js} +218 -80
  72. package/dist/parser-UEROAPYZ.js.map +1 -0
  73. package/dist/pdf-ocr-NARV2AQI.cjs +16 -0
  74. package/dist/{pdf-ocr-T2JXQATA.cjs.map → pdf-ocr-NARV2AQI.cjs.map} +1 -1
  75. package/dist/pdf-ocr-SYLMM727.js +18 -0
  76. package/dist/pdf-ocr-YMQZDJBO.js +15 -0
  77. package/dist/{profile-io-ZTV2MKRT.js → profile-io-YD54CDXY.js} +3 -3
  78. package/dist/{rasterize-MMUZ537K.js → rasterize-3THYOOUN.js} +3 -3
  79. package/dist/{redact-doc-S42XGV5D.js → redact-doc-65L2YJN6.js} +11 -11
  80. package/dist/{render-WCWPZKJ7.js → render-YU7QJVZ7.js} +7 -7
  81. package/dist/seal-6CQGFTML.js +10 -0
  82. package/dist/{setup-D35LKZCH.js → setup-CFHKXDY4.js} +3 -3
  83. package/dist/visual-ED2H75Q5.js +20 -0
  84. package/dist/{watch-AX64CIMN.js → watch-D6FCAYKJ.js} +12 -12
  85. package/package.json +1 -1
  86. package/dist/chunk-43FKGDDO.js.map +0 -1
  87. package/dist/chunk-B5NEGP65.cjs.map +0 -1
  88. package/dist/chunk-CB5XDCSL.js.map +0 -1
  89. package/dist/chunk-HIVK5V27.js.map +0 -1
  90. package/dist/chunk-JB5X5NNL.js.map +0 -1
  91. package/dist/chunk-MH6MAL64.cjs.map +0 -1
  92. package/dist/chunk-QJERJZJ6.js.map +0 -1
  93. package/dist/chunk-UQ6TZDW6.js.map +0 -1
  94. package/dist/chunk-XHOZB2WP.js.map +0 -1
  95. package/dist/chunk-XWA625AN.js.map +0 -1
  96. package/dist/chunk-ZY5K3LPM.cjs.map +0 -1
  97. package/dist/chunks-JD25E5PM.js +0 -10
  98. package/dist/parser-3B6I2XL7.js.map +0 -1
  99. package/dist/parser-PXATL5DM.js.map +0 -1
  100. package/dist/parser-YAQV7FBO.cjs.map +0 -1
  101. package/dist/pdf-ocr-2TTO5PX2.js +0 -15
  102. package/dist/pdf-ocr-T2JXQATA.cjs +0 -16
  103. package/dist/pdf-ocr-WF2NQA6X.js +0 -18
  104. package/dist/seal-WHK4GOHR.js +0 -10
  105. package/dist/visual-WL4TDE5B.js +0 -20
  106. /package/dist/{-VQNLLLPE.js.map → -3DURLXSO.js.map} +0 -0
  107. /package/dist/{chunk-3JWMDL3S.js.map → chunk-24N4IJ5I.js.map} +0 -0
  108. /package/dist/{chunk-RC4C7Q33.js.map → chunk-3VLVNKJV.js.map} +0 -0
  109. /package/dist/{chunk-DYENR3PX.js.map → chunk-63YGGAQW.js.map} +0 -0
  110. /package/dist/{chunk-A3QDRMVD.js.map → chunk-7XAGIPOX.js.map} +0 -0
  111. /package/dist/{chunk-NNYF2AGC.js.map → chunk-ANZTLTKU.js.map} +0 -0
  112. /package/dist/{chunk-N6TPODYL.js.map → chunk-BIHS4VWR.js.map} +0 -0
  113. /package/dist/{chunk-476OYHGZ.js.map → chunk-BTO7ZEE4.js.map} +0 -0
  114. /package/dist/{chunk-46DZF3RK.js.map → chunk-CXWWX6BQ.js.map} +0 -0
  115. /package/dist/{chunk-6LMKQM7I.js.map → chunk-EEVAPRPD.js.map} +0 -0
  116. /package/dist/{chunk-PQRP4NSF.js.map → chunk-N65ZXWNQ.js.map} +0 -0
  117. /package/dist/{chunk-UDX7TSOC.js.map → chunk-NCXRSQNE.js.map} +0 -0
  118. /package/dist/{chunk-GOQBON77.js.map → chunk-NUPXPKIQ.js.map} +0 -0
  119. /package/dist/{chunk-TGD7UFHD.js.map → chunk-UZHT3LBF.js.map} +0 -0
  120. /package/dist/{chunk-PIMB2YNO.js.map → chunk-VCRBR72A.js.map} +0 -0
  121. /package/dist/{chunk-C75WE52C.js.map → chunk-VNOQTDTE.js.map} +0 -0
  122. /package/dist/{chunks-JD25E5PM.js.map → chunks-PYYQURNO.js.map} +0 -0
  123. /package/dist/{formula-FNQYHMIY.js.map → formula-IPLFHEBD.js.map} +0 -0
  124. /package/dist/{formula-5775PTP2.js.map → formula-U4BTEZ6I.js.map} +0 -0
  125. /package/dist/{image-ocr-PYZU4TO7.js.map → image-ocr-3IJ25PS4.js.map} +0 -0
  126. /package/dist/{image-ocr-YA2MQBRP.js.map → image-ocr-GTDG4SAJ.js.map} +0 -0
  127. /package/dist/{model-bundle-O6J7ORVC.js.map → model-bundle-PVWIAVEX.js.map} +0 -0
  128. /package/dist/{models-YMOKZGCI.js.map → models-VCRF3JMT.js.map} +0 -0
  129. /package/dist/{pdf-ocr-2TTO5PX2.js.map → pdf-ocr-SYLMM727.js.map} +0 -0
  130. /package/dist/{pdf-ocr-WF2NQA6X.js.map → pdf-ocr-YMQZDJBO.js.map} +0 -0
  131. /package/dist/{profile-io-ZTV2MKRT.js.map → profile-io-YD54CDXY.js.map} +0 -0
  132. /package/dist/{rasterize-MMUZ537K.js.map → rasterize-3THYOOUN.js.map} +0 -0
  133. /package/dist/{redact-doc-S42XGV5D.js.map → redact-doc-65L2YJN6.js.map} +0 -0
  134. /package/dist/{render-WCWPZKJ7.js.map → render-YU7QJVZ7.js.map} +0 -0
  135. /package/dist/{seal-WHK4GOHR.js.map → seal-6CQGFTML.js.map} +0 -0
  136. /package/dist/{setup-D35LKZCH.js.map → setup-CFHKXDY4.js.map} +0 -0
  137. /package/dist/{visual-WL4TDE5B.js.map → visual-ED2H75Q5.js.map} +0 -0
  138. /package/dist/{watch-AX64CIMN.js.map → watch-D6FCAYKJ.js.map} +0 -0
@@ -30,21 +30,22 @@ import {
30
30
  normalizeItems,
31
31
  refineDocumentStyleHeadings,
32
32
  removeHeaderFooterBlocks,
33
+ startsNewItem,
33
34
  trimTrailingEmptyTableCols,
34
35
  wrapJoiner
35
- } from "./chunk-43FKGDDO.js";
36
+ } from "./chunk-7FKPPIDZ.js";
36
37
  import {
37
38
  ocrModelsCached
38
- } from "./chunk-N6TPODYL.js";
39
- import "./chunk-A3QDRMVD.js";
40
- import "./chunk-C75WE52C.js";
39
+ } from "./chunk-BIHS4VWR.js";
40
+ import "./chunk-7XAGIPOX.js";
41
+ import "./chunk-VNOQTDTE.js";
41
42
  import {
42
43
  blocksToPages
43
- } from "./chunk-DYENR3PX.js";
44
+ } from "./chunk-63YGGAQW.js";
44
45
  import {
45
46
  encodePng
46
47
  } from "./chunk-7FCNOKOR.js";
47
- import "./chunk-UQ6TZDW6.js";
48
+ import "./chunk-T77M2QP7.js";
48
49
  import {
49
50
  hasRequestedPagesAfter,
50
51
  parsePageRange
@@ -53,11 +54,11 @@ import {
53
54
  WINGDINGS,
54
55
  blocksToMarkdown,
55
56
  escapeLiteralDollar
56
- } from "./chunk-TGD7UFHD.js";
57
+ } from "./chunk-UZHT3LBF.js";
57
58
  import {
58
59
  KordocError,
59
60
  sanitizeHref
60
- } from "./chunk-RC4C7Q33.js";
61
+ } from "./chunk-3VLVNKJV.js";
61
62
 
62
63
  // src/pdf/ocr-region-merge.ts
63
64
  function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
@@ -642,6 +643,40 @@ function ocrVectorOps(opList, paths) {
642
643
  return { fnArray, argsArray };
643
644
  }
644
645
 
646
+ // src/pdf/contact-table.ts
647
+ var CONTACT_HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
648
+ var CONTACT_ROLE = /^(?:책임자|담당자)$/;
649
+ var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
650
+ function splitContactTables(blocks) {
651
+ for (const b of blocks) {
652
+ const t = b.type === "table" ? b.table : void 0;
653
+ if (!t || t.cols !== 4 || t.rows < 2) continue;
654
+ const rows = t.cells;
655
+ if (!CONTACT_HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
656
+ const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
657
+ 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;
658
+ const lead = [];
659
+ let ok = true;
660
+ for (const c of [0, 1]) {
661
+ const top = rows[0][c];
662
+ if (top.rowSpan === 1) {
663
+ lead.push(rows.map((r) => r[c].text));
664
+ continue;
665
+ }
666
+ const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
667
+ if (top.rowSpan !== t.rows || lines.length > t.rows) {
668
+ ok = false;
669
+ break;
670
+ }
671
+ lead.push(rows.map((_, r) => lines[r] ?? ""));
672
+ }
673
+ if (!ok) continue;
674
+ const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
675
+ 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])]);
676
+ t.cols = 6;
677
+ }
678
+ }
679
+
645
680
  // src/pdf/table-parts.ts
646
681
  var PART_COL_TOL = 1;
647
682
  function anchorsOf(table) {
@@ -678,7 +713,7 @@ var indexOf = (coords, x) => {
678
713
  };
679
714
  var rowText = (anchors, r) => anchors.filter((a) => a.r === r).map((a) => a.cell.text.replace(/\s+/g, "")).join("|");
680
715
  var hasText = (t) => t.replace(/\|/g, "") !== "";
681
- function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
716
+ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
682
717
  if (pcx.length !== prev.cols + 1 || ccx.length !== curr.cols + 1) return null;
683
718
  const U = unionCoords(pcx, ccx);
684
719
  const cols = U.length - 1;
@@ -734,13 +769,35 @@ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
734
769
  }
735
770
  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]);
736
771
  const table = { rows, cols, cells: grid, hasHeader: prev.hasHeader, ...prev.caption ? { caption: prev.caption } : {} };
737
- const split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
738
- if (rows > prev.rows && !split && prevBottom !== void 0) mergeStraddlingCells(table, owner, prev.rows, prevBottom);
772
+ let split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
773
+ if (rows > prev.rows && !split && prevBottom !== void 0 && mergeStraddlingCells(table, owner, prev.rows, prevBottom, lex)) split = mergeSplitRow(table, owner, prev.rows, U, true);
739
774
  return { table, colXs: U, split, header: ca.filter((a) => a.r < skip && a.cell.text.trim()).length >= 2 };
740
775
  }
741
- function mergeStraddlingCells(table, owner, first, prevBottom) {
776
+ function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
742
777
  const last = first - 1;
743
- if (!owner[first].some((o, c) => o !== null && o === owner[last][c])) return;
778
+ const straddles = owner[first].some((o, c) => o !== null && o === owner[last][c]);
779
+ let firstNew = table.cols;
780
+ for (let c = 0; c < table.cols; c++) {
781
+ const d = owner[first][c];
782
+ if (d && d.r === first && d !== owner[last][c] && hasContent(table.cells[d.r][d.c])) {
783
+ firstNew = c;
784
+ break;
785
+ }
786
+ }
787
+ let midWord = false;
788
+ if (lex) for (let c = 0; c < table.cols && !midWord; ) {
789
+ const u = owner[last][c], d = owner[first][c];
790
+ if (!u) {
791
+ c++;
792
+ continue;
793
+ }
794
+ c = u.c + u.cs;
795
+ if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
796
+ if (u.r !== last || d.rs < 2) continue;
797
+ const tail = table.cells[u.r][u.c].text.trim().split(/\s+/).pop() ?? "", head = table.cells[first][d.c].text.trim().split(/\s+/)[0] ?? "";
798
+ if (/^[가-힣]{2,}$/.test(tail) && /^[가-힣]{2,}/.test(head) && lex.evidence2(tail, head) === "") midWord = true;
799
+ }
800
+ let merged = false;
744
801
  for (let c = 0; c < table.cols; ) {
745
802
  const u = owner[last][c], d = owner[first][c];
746
803
  if (!u) {
@@ -748,18 +805,24 @@ function mergeStraddlingCells(table, owner, first, prevBottom) {
748
805
  continue;
749
806
  }
750
807
  c = u.c + u.cs;
751
- 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;
808
+ if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
752
809
  const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
753
- const U = CELL_LINES.get(a);
754
- if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
755
- const lu = U[U.length - 1];
756
- if (lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
810
+ if (!(u.rs >= 2 && u.c + u.cs <= firstNew && hasContent(a) && !hasContent(b))) {
811
+ if (!straddles && !midWord) continue;
812
+ if (u.r >= last && d.rs < 2) continue;
813
+ const U = CELL_LINES.get(a);
814
+ if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
815
+ const lu = U[U.length - 1];
816
+ if (!midWord && lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
817
+ }
757
818
  appendCell(a, b);
758
819
  a.rowSpan = first + d.rs - u.r;
759
820
  table.cells[first][d.c] = { text: "", colSpan: 1, rowSpan: 1 };
760
821
  const grown = { ...u, rs: a.rowSpan };
761
822
  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;
823
+ merged = true;
762
824
  }
825
+ return merged;
763
826
  }
764
827
  var FULL_LINE_TOL = 1;
765
828
  var FULL_LINE_MIN_FRAC = 0.5;
@@ -795,11 +858,21 @@ function continuesAcross(u, d, x1, x2) {
795
858
  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;
796
859
  return U.some(leftAligned) || D.some(leftAligned) || hanging;
797
860
  }
798
- function lineEnded(c, x1, x2) {
861
+ var OUTLINE_HEAD = /^[□■]\s*\S/;
862
+ var OUTLINE_ITEM = /^[ㅇ○◦\-‐–·․‧※*]\s*\S/;
863
+ function outlineContinues(u, d) {
864
+ const U = u.text.split("\n").map((l) => l.trim()).filter(Boolean);
865
+ const D = d.text.split("\n").map((l) => l.trim()).filter(Boolean);
866
+ return U.length >= 2 && D.length >= 1 && U.some((l) => OUTLINE_HEAD.test(l)) && OUTLINE_ITEM.test(D[0]);
867
+ }
868
+ function lineEnded(c, x1, x2, next = "") {
799
869
  const L = CELL_LINES.get(c);
800
870
  if (!L || L.length !== 1) return false;
801
- const l = L[0];
802
- return x2 - l.r - (l.l - x1) >= LABEL_ROOM * (l.h || 10);
871
+ const l = L[0], h = l.h || 10;
872
+ const word = next.trim().split(/\s+/)[0] ?? "";
873
+ let units = 0;
874
+ for (const ch of word) units += /[가-힣\u3400-\u9fff]/.test(ch) ? 1 : 0.55;
875
+ return x2 - l.r - (l.l - x1) >= Math.max(LABEL_ROOM, units) * h;
803
876
  }
804
877
  function appendCell(a, b) {
805
878
  if (a.blocks?.length || b.blocks?.length) {
@@ -809,7 +882,22 @@ function appendCell(a, b) {
809
882
  if (b.text.trim()) a.text = a.text.trim() ? a.text + "\n" + b.text : b.text;
810
883
  }
811
884
  var hasContent = (cell) => !!cell.text.trim() || !!cell.blocks?.length || IMAGE_CELLS.has(cell);
812
- function mergeSplitRow(table, owner, first, colXs) {
885
+ var CLAUSE_OPEN_ENDING = /(?:하는|되는|하고|하며|하여|되어|되고|되며|이며|으며|어야|아야|여야)$/;
886
+ var batchim = (ch) => {
887
+ const k = ch.charCodeAt(0) - 44032;
888
+ return k >= 0 && k < 11172 && k % 28 !== 0;
889
+ };
890
+ function clauseContinues(u, d) {
891
+ const tail = u.text.trim().split(/\s+/).pop() ?? "", head = d.text.trim();
892
+ if (!/^[가-힣]{2,}$/.test(tail) || !/^[가-힣]/.test(head) || startsNewItem(u.text, head)) return false;
893
+ const last = tail[tail.length - 1], before = tail[tail.length - 2];
894
+ return last === "\uC744" && batchim(before) || last === "\uB97C" && !batchim(before) || CLAUSE_OPEN_ENDING.test(tail);
895
+ }
896
+ function outlineOnly(pairs, cell) {
897
+ const filled = pairs.filter(([, d]) => hasContent(d.cell));
898
+ return filled.length === 1 && outlineContinues(cell(filled[0][0]), cell(filled[0][1]));
899
+ }
900
+ function mergeSplitRow(table, owner, first, colXs, textOnly = false) {
813
901
  const last = first - 1;
814
902
  const pairs = [];
815
903
  let carried = false;
@@ -827,12 +915,12 @@ function mergeSplitRow(table, owner, first, colXs) {
827
915
  } else if (a.r === last && a.rs === 2) carried = true;
828
916
  c = a.c + a.cs;
829
917
  }
830
- 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));
918
+ 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));
831
919
  const cell = (a) => table.cells[a.r][a.c];
832
920
  if (!carriedSplit) {
833
921
  const norm = (c) => c.text.replace(/\s+/g, "");
834
- 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;
835
- if (!pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]))) return false;
922
+ 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;
923
+ 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;
836
924
  }
837
925
  for (const [u, d] of pairs) appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
838
926
  for (let r = 0; r < first; r++) for (let c = 0; c < table.cols; c++) {
@@ -879,8 +967,8 @@ function sameHeadShape(a, b) {
879
967
  }
880
968
  return tall;
881
969
  }
882
- function mergeCrossPageTables(blocks, pageHeights) {
883
- mergeColumnFlow(blocks, pageHeights);
970
+ function mergeCrossPageTables(blocks, pageHeights, lex) {
971
+ mergeColumnFlow(blocks, pageHeights, lex);
884
972
  for (let i = blocks.length - 2; i >= 0; i--) {
885
973
  const prev = blocks[i];
886
974
  if (prev.type !== "table" || !prev.table || !prev.bbox || !prev.pageNumber) continue;
@@ -889,7 +977,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
889
977
  const curr = blocks[j];
890
978
  if (!curr || curr.type !== "table" || !curr.table || !curr.bbox || curr.pageNumber !== prev.pageNumber + 1) continue;
891
979
  if (startsWithUnitRow(prev.table) && startsWithUnitRow(curr.table)) continue;
892
- 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;
980
+ 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;
893
981
  if (joined) {
894
982
  placeJoined(blocks, i, j, joined);
895
983
  continue;
@@ -933,7 +1021,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
933
1021
  if (blocks[i].type === "table" && t && EMPTY_PARTS.has(t)) blocks.splice(i, 1);
934
1022
  }
935
1023
  }
936
- function mergeColumnFlow(blocks, pageHeights) {
1024
+ function mergeColumnFlow(blocks, pageHeights, lex) {
937
1025
  if (!pageHeights) return;
938
1026
  for (let i = 0; i < blocks.length; i++) {
939
1027
  const L = blocks[i];
@@ -955,7 +1043,7 @@ function mergeColumnFlow(blocks, pageHeights) {
955
1043
  const R = blocks[k];
956
1044
  if (Math.abs(R.bbox.width - L.bbox.width) > Math.max(R.bbox.width, L.bbox.width) * NEIGHBOR_TABLE_EPSILON) continue;
957
1045
  if (!looksContinued(L, R) || restartsTable(blocks, i, R.table, pageHeights)) continue;
958
- const joined = joinClipParts(L, R, pageHeights);
1046
+ const joined = joinClipParts(L, R, pageHeights, lex);
959
1047
  if (!joined) continue;
960
1048
  const top = L.bbox.y + L.bbox.height;
961
1049
  const at = Math.min(i, k);
@@ -964,12 +1052,12 @@ function mergeColumnFlow(blocks, pageHeights) {
964
1052
  i = at - 1;
965
1053
  }
966
1054
  }
967
- function joinClipParts(prev, curr, pageHeights) {
1055
+ function joinClipParts(prev, curr, pageHeights, lex) {
968
1056
  const pt = prev.table, ct = curr.table;
969
1057
  if (!CLIP_TABLES.has(pt) || !CLIP_TABLES.has(ct)) return null;
970
1058
  const px = TABLE_COLXS.get(pt), cx = TABLE_COLXS.get(ct);
971
1059
  if (!px || !cx) return null;
972
- let xs = cx, shifted = false, dx = 0;
1060
+ let xs = cx, shifted = false, dx = 0, foreign = false;
973
1061
  if (!shiftedSame(px, cx, false)) {
974
1062
  if (!pageHeights?.get(prev.pageNumber) || !pageHeights?.get(curr.pageNumber)) return null;
975
1063
  dx = px[px.length - 1] - cx[cx.length - 1];
@@ -978,19 +1066,29 @@ function joinClipParts(prev, curr, pageHeights) {
978
1066
  shifted = true;
979
1067
  } else dx = 0;
980
1068
  if (!px.some((x) => Math.abs(x - xs[0]) <= CONTINUATION_COL_TOL)) return null;
1069
+ const inner = xs.slice(1, -1);
1070
+ foreign = inner.length > 0 && !inner.some((x) => px.some((p) => Math.abs(p - x) <= CONTINUATION_COL_TOL)) && headingRow(ct.cells[0] ?? []);
981
1071
  }
982
- const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y);
983
- if (!res || shifted && !res.split && !res.header) return null;
1072
+ const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y, lex);
1073
+ if (!res || (shifted || foreign) && !res.split && !res.header) return null;
984
1074
  TABLE_COLXS.set(res.table, res.colXs);
985
1075
  CLIP_TABLES.add(res.table);
986
1076
  return res.table;
987
1077
  }
1078
+ function headingRow(row) {
1079
+ const heads = row.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1080
+ if (heads.length === 1) return heads[0].length <= 8 || /^[①-⑳❶-❿]/.test(heads[0]);
1081
+ return heads.length === 2 && /^(?:\d{1,2}|[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ]+|[①-⑳❶-❿])$/.test(heads[0]);
1082
+ }
988
1083
  var ANNEX_HEAD_RE = /^\s*[<\[(【]?\s*(?:붙\s*임|참\s*고|별\s*첨|별\s*지|별\s*표|첨\s*부|부\s*록)(?:\s*\d|\s*$|\s*[>\])】])|^\s*■/;
989
1084
  function looksContinued(prev, curr, pageHeights) {
990
1085
  const ph = pageHeights?.get(prev.pageNumber), ch = pageHeights?.get(curr.pageNumber);
991
1086
  if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
992
- const firstText = curr.table.cells[0]?.find((c) => c.text.trim())?.text ?? "";
993
- return !ANNEX_HEAD_RE.test(firstText);
1087
+ const firstRow = curr.table.cells[0] ?? [];
1088
+ const firstText = firstRow.find((c) => c.text.trim())?.text ?? "";
1089
+ if (!ANNEX_HEAD_RE.test(firstText)) return true;
1090
+ const filled = firstRow.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1091
+ return filled.length >= 2 && filled.every((t) => t === filled[0]);
994
1092
  }
995
1093
  function firstRowSig(t) {
996
1094
  const x = TABLE_COLXS.get(t);
@@ -1003,6 +1101,7 @@ function restartsTable(blocks, i, curr, pageHeights) {
1003
1101
  const head = blocks[chainHead(blocks, i, pageHeights)].table;
1004
1102
  if (cs.length === 1 && restartsTitledForm(head, curr)) return true;
1005
1103
  if (cs.length < RESTART_MIN_ANCHORS) return false;
1104
+ if (CONTACT_HEAD.test(cs[0].t) && cs.some((c) => CONTACT_ROLE.test(c.t))) return false;
1006
1105
  const hs = firstRowSig(head);
1007
1106
  if (!hs || hs.length !== cs.length) return false;
1008
1107
  const dx = hs[hs.length - 1].x2 - cs[cs.length - 1].x2;
@@ -1849,6 +1948,52 @@ function restoreTrackedSpacing(items, fnArray, argsArray) {
1849
1948
  }
1850
1949
  return changed;
1851
1950
  }
1951
+ function markSyntheticSpaces(items, fnArray, argsArray) {
1952
+ if (!items.some((it) => typeof it.str === "string" && it.str.length > 0 && !it.str.trim())) return;
1953
+ const streams = /* @__PURE__ */ new Map();
1954
+ const saved = [];
1955
+ let font = "";
1956
+ for (let i = 0; i < fnArray.length; i++) {
1957
+ const fn = fnArray[i];
1958
+ const args = argsArray[i];
1959
+ if (fn === OPS5.setFont) font = String(args[0]);
1960
+ else if (fn === OPS5.save || fn === OPS5.paintFormXObjectBegin) saved.push(font);
1961
+ else if (fn === OPS5.restore || fn === OPS5.paintFormXObjectEnd) font = saved.pop() ?? font;
1962
+ else if (fn === OPS5.showText) {
1963
+ let list = streams.get(font);
1964
+ if (!list) streams.set(font, list = []);
1965
+ for (const g2 of args[0]) {
1966
+ if (g2 && typeof g2 === "object" && typeof g2.unicode === "string") list.push(normalizeUnicode3(g2.unicode));
1967
+ }
1968
+ }
1969
+ }
1970
+ const cursor = /* @__PURE__ */ new Map();
1971
+ const failed = /* @__PURE__ */ new Set();
1972
+ const marks = [];
1973
+ for (const it of items) {
1974
+ const f = it.fontName ?? "";
1975
+ const glyphs = streams.get(f);
1976
+ if (!glyphs || failed.has(f) || typeof it.str !== "string" || !it.str) continue;
1977
+ let gi = cursor.get(f) ?? 0;
1978
+ if (!it.str.trim()) {
1979
+ if (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) {
1980
+ while (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) gi++;
1981
+ cursor.set(f, gi);
1982
+ } else marks.push(it);
1983
+ continue;
1984
+ }
1985
+ const want = it.str.replace(/\s+/g, "");
1986
+ while (gi < glyphs.length && /^\s*$/.test(glyphs[gi])) gi++;
1987
+ let got = "";
1988
+ while (gi < glyphs.length && got.length < want.length) got += glyphs[gi++].replace(/\s+/g, "");
1989
+ if (got !== want) {
1990
+ failed.add(f);
1991
+ continue;
1992
+ }
1993
+ cursor.set(f, gi);
1994
+ }
1995
+ for (const it of marks) if (!failed.has(it.fontName ?? "")) it.synthetic = true;
1996
+ }
1852
1997
 
1853
1998
  // src/pdf/endnotes.ts
1854
1999
  var NOTE_MARK = /^\s*(문\d{1,5}[))]|\d{1,5}\)|\(\d{1,5}\))/;
@@ -1986,6 +2131,7 @@ function orderTwoUpPage(blocks, pageWidth, pageHeight) {
1986
2131
  var BAND = 0.12;
1987
2132
  var MAX_CHARS = 10;
1988
2133
  var MIN_REPEAT = 3;
2134
+ var RUN_GAP = 5;
1989
2135
  function removeSideTabs(blocks, pageWidths) {
1990
2136
  const edges = /* @__PURE__ */ new Map();
1991
2137
  for (const b of blocks) {
@@ -2018,13 +2164,21 @@ function removeSideTabs(blocks, pageWidths) {
2018
2164
  }
2019
2165
  const running = /* @__PURE__ */ new Set();
2020
2166
  for (const [k, ps] of pages) {
2021
- const list = [...ps];
2022
- const span = Math.max(...list) - Math.min(...list) + 1;
2023
- if (list.length >= MIN_REPEAT && list.length >= span * 0.4) running.add(k);
2167
+ const list = [...ps].sort((a, b) => a - b);
2168
+ let run = [];
2169
+ const flush = () => {
2170
+ 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}`);
2171
+ run = [];
2172
+ };
2173
+ for (const p of list) {
2174
+ if (run.length && p - run[run.length - 1] > RUN_GAP) flush();
2175
+ run.push(p);
2176
+ }
2177
+ flush();
2024
2178
  }
2025
2179
  return running.size ? blocks.filter((b) => {
2026
2180
  const k = key(b);
2027
- return !k || !running.has(k);
2181
+ return !k || !running.has(`${b.pageNumber}\0${k}`);
2028
2182
  }) : blocks;
2029
2183
  }
2030
2184
 
@@ -2192,7 +2346,9 @@ function normalizeAraea(text) {
2192
2346
  return text.replace(/(?<![\u1100-\u115F])\u119E/g, "\u318D");
2193
2347
  }
2194
2348
  var stripNoUnicodeGlyph = (text) => text.includes("\uF000") ? text.replace(/\uF000/g, "") : text;
2195
- var cleanChars = (text) => normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text)));
2349
+ var CHOSEONG_COMPAT = "\u3131\u3132\u3134\u3137\u3138\u3139\u3141\u3142\u3143\u3145\u3146\u3147\u3148\u3149\u314A\u314B\u314C\u314D\u314E";
2350
+ var normalizeLoneChoseong = (text) => /[\u1100-\u1112]/.test(text) ? text.replace(/[\u1100-\u1112](?![\u1160-\u11A7\uD7B0-\uD7C6])/g, (c) => CHOSEONG_COMPAT[c.charCodeAt(0) - 4352]) : text;
2351
+ var cleanChars = (text) => normalizeLoneChoseong(normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text))));
2196
2352
  function sanitizeBlockControlChars(blocks) {
2197
2353
  for (const b of blocks) {
2198
2354
  if (b.text) b.text = cleanChars(b.text);
@@ -2357,7 +2513,7 @@ function mergeLinkRuns(markdown) {
2357
2513
 
2358
2514
  // src/pdf/formula-ocr.ts
2359
2515
  async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
2360
- const formulaMod = await import("./formula-5775PTP2.js");
2516
+ const formulaMod = await import("./formula-U4BTEZ6I.js");
2361
2517
  const { FormulaPipeline, ensureFormulaModels } = formulaMod;
2362
2518
  await ensureFormulaModels((p) => {
2363
2519
  if (p.phase === "download" && p.total) {
@@ -2497,42 +2653,15 @@ g.pdfjsWorker = pdfjsWorker;
2497
2653
  import { getDocument, GlobalWorkerOptions, OPS as OPS6 } from "pdfjs-dist/legacy/build/pdf.mjs";
2498
2654
  import { createRequire } from "module";
2499
2655
  import { dirname, join } from "path";
2500
-
2501
- // src/pdf/contact-table.ts
2502
- var HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
2503
- var ROLE = /^(?:책임자|담당자)$/;
2504
- var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
2505
- function splitContactTables(blocks) {
2506
- for (const b of blocks) {
2507
- const t = b.type === "table" ? b.table : void 0;
2508
- if (!t || t.cols !== 4 || t.rows < 2) continue;
2509
- const rows = t.cells;
2510
- if (!HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
2511
- const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
2512
- 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;
2513
- const lead = [];
2514
- let ok = true;
2515
- for (const c of [0, 1]) {
2516
- const top = rows[0][c];
2517
- if (top.rowSpan === 1) {
2518
- lead.push(rows.map((r) => r[c].text));
2519
- continue;
2520
- }
2521
- const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
2522
- if (top.rowSpan !== t.rows || lines.length > t.rows) {
2523
- ok = false;
2524
- break;
2525
- }
2526
- lead.push(rows.map((_, r) => lines[r] ?? ""));
2527
- }
2528
- if (!ok) continue;
2529
- const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
2530
- 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])]);
2531
- t.cols = 6;
2656
+ function ocrImageRegions(regions, large, all) {
2657
+ if (all) return regions;
2658
+ const out = /* @__PURE__ */ new Map();
2659
+ for (const [p, rs] of regions) {
2660
+ const big = rs.filter((r) => large.has(r));
2661
+ if (big.length) out.set(p, big);
2532
2662
  }
2663
+ return out;
2533
2664
  }
2534
-
2535
- // src/pdf/parser.ts
2536
2665
  GlobalWorkerOptions.workerSrc = "";
2537
2666
  var MAX_PAGES = 5e3;
2538
2667
  var MAX_TOTAL_TEXT = 100 * 1024 * 1024;
@@ -2605,6 +2734,7 @@ async function parsePdfDocument(buffer, options) {
2605
2734
  const pagesWithLargeImage = /* @__PURE__ */ new Set();
2606
2735
  const skippedImagePages = /* @__PURE__ */ new Map();
2607
2736
  const uncoveredImageRegions = /* @__PURE__ */ new Map();
2737
+ const largeImageRegions = /* @__PURE__ */ new Set();
2608
2738
  const imageState = createPdfImageState();
2609
2739
  const extractedImages = [];
2610
2740
  const pageImageBlocks = /* @__PURE__ */ new Map();
@@ -2636,6 +2766,7 @@ async function parsePdfDocument(buffer, options) {
2636
2766
  const differencesOf = (loadedName) => fontObj(loadedName)?.differences;
2637
2767
  restoreNamedGlyphs(rawItems, rawOps.fnArray, rawOps.argsArray, differencesOf, (n) => fontObj(n)?.name);
2638
2768
  restoreTrackedSpacing(rawItems, rawOps.fnArray, rawOps.argsArray);
2769
+ markSyntheticSpaces(rawItems, rawOps.fnArray, rawOps.argsArray);
2639
2770
  const occluded = occludedTextItems(rawItems, rawOps.fnArray, rawOps.argsArray);
2640
2771
  const items = normalizeItems(occluded.size ? rawItems.filter((it) => !occluded.has(it)) : rawItems);
2641
2772
  const filtered = filterHiddenText(items, pageW, pageH, viewX1, viewY1);
@@ -2699,6 +2830,7 @@ async function parsePdfDocument(buffer, options) {
2699
2830
  const regions = uncoveredImageRegions.get(i) ?? [];
2700
2831
  regions.push(r);
2701
2832
  uncoveredImageRegions.set(i, regions);
2833
+ if (large) largeImageRegions.add(r);
2702
2834
  }
2703
2835
  }
2704
2836
  }
@@ -2747,6 +2879,7 @@ async function parsePdfDocument(buffer, options) {
2747
2879
  const parsedPageCount = parsedPages || (pageFilter ? pageFilter.size : effectivePageCount);
2748
2880
  const isImageBased = pageFilter?.size !== 0 && totalChars / Math.max(parsedPageCount, 1) < 10;
2749
2881
  const ocrDone = /* @__PURE__ */ new Set();
2882
+ const ocrRegions = options?.ocr === true || autoOcr ? ocrImageRegions(uncoveredImageRegions, largeImageRegions, options?.ocr === true) : /* @__PURE__ */ new Map();
2750
2883
  if (ocrBuffer) {
2751
2884
  const inScope = (p) => !pageFilter || pageFilter.has(p);
2752
2885
  const targets = /* @__PURE__ */ new Set();
@@ -2759,13 +2892,13 @@ async function parsePdfDocument(buffer, options) {
2759
2892
  if (autoOcr && pq.ocrReason !== "low_text" && pq.ocrReason !== "vector_text") continue;
2760
2893
  targets.add(pq.page);
2761
2894
  }
2762
- if (options?.ocr === true) for (const p of uncoveredImageRegions.keys()) targets.add(p);
2895
+ for (const p of ocrRegions.keys()) targets.add(p);
2763
2896
  }
2764
2897
  if (targets.size > 0) {
2765
2898
  try {
2766
- const { runPdfOcr } = await import("./pdf-ocr-WF2NQA6X.js");
2899
+ const { runPdfOcr } = await import("./pdf-ocr-SYLMM727.js");
2767
2900
  const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
2768
- const regionPages = new Map([...uncoveredImageRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
2901
+ const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
2769
2902
  const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
2770
2903
  if (ocrPageBlocks.size > 0) {
2771
2904
  const replacePages = /* @__PURE__ */ new Set();
@@ -2776,7 +2909,7 @@ async function parsePdfDocument(buffer, options) {
2776
2909
  ocrDone.add(p);
2777
2910
  continue;
2778
2911
  }
2779
- const regions = uncoveredImageRegions.get(p);
2912
+ const regions = ocrRegions.get(p);
2780
2913
  if (!regions || mergeOcrImageRegions(blocks, p, regions, obs) === 0) continue;
2781
2914
  ocrDone.add(p);
2782
2915
  if (pageImageBlocks.get(p)?.length === 1) pageImageBlocks.delete(p);
@@ -2830,7 +2963,7 @@ async function parsePdfDocument(buffer, options) {
2830
2963
  }
2831
2964
  }
2832
2965
  if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
2833
- const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings);
2966
+ const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks);
2834
2967
  for (let ri = removed.length - 1; ri >= 0; ri--) {
2835
2968
  blocks.splice(removed[ri], 1);
2836
2969
  }
@@ -2841,7 +2974,11 @@ async function parsePdfDocument(buffer, options) {
2841
2974
  }
2842
2975
  }
2843
2976
  mergeContinuedCells(blocks, pageHeights);
2844
- mergeCrossPageTables(blocks, pageHeights);
2977
+ mergeCrossPageTables(blocks, pageHeights, wrapLexicon);
2978
+ if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
2979
+ const boxes = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks, true);
2980
+ for (let ri = boxes.length - 1; ri >= 0; ri--) blocks.splice(boxes[ri], 1);
2981
+ }
2845
2982
  splitContactTables(blocks);
2846
2983
  if (!options?.keepTrailingEmptyCols) trimTrailingEmptyTableCols(blocks);
2847
2984
  joinPageBreakWraps(blocks, wrapLexicon);
@@ -2954,7 +3091,8 @@ export {
2954
3091
  detectTableCaptions,
2955
3092
  extractPdfMetadataOnly,
2956
3093
  mergeCrossPageTables,
3094
+ ocrImageRegions,
2957
3095
  parsePdfDocument,
2958
3096
  removeHeaderFooterBlocks
2959
3097
  };
2960
- //# sourceMappingURL=parser-3B6I2XL7.js.map
3098
+ //# sourceMappingURL=parser-T4RITZDP.js.map