kordoc 4.15.6 → 4.15.7

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 (146) hide show
  1. package/README.md +33 -4
  2. package/dist/{-F73GANY7.js → -H6WNRHK6.js} +11 -11
  3. package/dist/{chunk-SOM7JIKG.cjs → chunk-4ANWGSUT.cjs} +227 -103
  4. package/dist/chunk-4ANWGSUT.cjs.map +1 -0
  5. package/dist/{chunk-ISJRNC2G.js → chunk-6ULM2YCN.js} +46 -8
  6. package/dist/{chunk-ISJRNC2G.js.map → chunk-6ULM2YCN.js.map} +1 -1
  7. package/dist/{chunk-2OKMF2KY.js → chunk-AWXXLLIG.js} +2 -2
  8. package/dist/{chunk-NK5XFKL4.js → chunk-C572DIHX.js} +17 -7
  9. package/dist/chunk-C572DIHX.js.map +1 -0
  10. package/dist/{chunk-JX7URXOL.js → chunk-F5FHYJKJ.js} +8 -2
  11. package/dist/{chunk-JX7URXOL.js.map → chunk-F5FHYJKJ.js.map} +1 -1
  12. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  13. package/dist/{chunk-U7J7BFV3.js → chunk-IHCQ4IE7.js} +2 -2
  14. package/dist/chunk-J55UQC5H.cjs.map +1 -1
  15. package/dist/{chunk-FBZCWSPN.cjs → chunk-J6ZU7AIR.cjs} +9 -3
  16. package/dist/chunk-J6ZU7AIR.cjs.map +1 -0
  17. package/dist/{chunk-DRQW5SYI.js → chunk-KJSD2WNF.js} +2 -2
  18. package/dist/{chunk-765SAMGS.js → chunk-L5MDTA6T.js} +2 -2
  19. package/dist/{chunk-3PDCVDSO.js → chunk-NVG2GQNA.js} +1 -1
  20. package/dist/chunk-NVG2GQNA.js.map +1 -0
  21. package/dist/{chunk-A63JPQEE.js → chunk-NZMPU24H.js} +42 -47
  22. package/dist/chunk-NZMPU24H.js.map +1 -0
  23. package/dist/{chunk-KJKMBV5K.js → chunk-O5SDUPB2.js} +5 -4
  24. package/dist/chunk-O5SDUPB2.js.map +1 -0
  25. package/dist/{chunk-2DLW4CMC.cjs → chunk-OE6XLTMC.cjs} +54 -59
  26. package/dist/chunk-OE6XLTMC.cjs.map +1 -0
  27. package/dist/{chunk-6OQTREJ5.js → chunk-ORMMGTNK.js} +2 -2
  28. package/dist/{chunk-QJX4IR77.cjs → chunk-R45AG5K6.cjs} +3 -3
  29. package/dist/chunk-R45AG5K6.cjs.map +1 -0
  30. package/dist/{chunk-FA5JIHUV.js → chunk-S7PEBTU3.js} +148 -38
  31. package/dist/chunk-S7PEBTU3.js.map +1 -0
  32. package/dist/{chunk-OQ3DY7RF.js → chunk-TRB6OYMU.js} +2 -2
  33. package/dist/{chunk-QC736WXT.js → chunk-UGSRP7E2.js} +3 -3
  34. package/dist/{chunk-U6SS43O6.js → chunk-W2UTB3RG.js} +1 -1
  35. package/dist/chunk-W2UTB3RG.js.map +1 -0
  36. package/dist/{chunk-O6A6SK55.js → chunk-WHZUJH2O.js} +42 -47
  37. package/dist/chunk-WHZUJH2O.js.map +1 -0
  38. package/dist/{chunk-FWT24USP.js → chunk-WMLGS5QL.js} +157 -33
  39. package/dist/chunk-WMLGS5QL.js.map +1 -0
  40. package/dist/{chunk-UGIESTA6.js → chunk-WQWXQVOQ.js} +8 -2
  41. package/dist/{chunk-UGIESTA6.js.map → chunk-WQWXQVOQ.js.map} +1 -1
  42. package/dist/{chunk-RSKR6A6S.js → chunk-X3PBLSV5.js} +157 -33
  43. package/dist/chunk-X3PBLSV5.js.map +1 -0
  44. package/dist/{chunk-UKD7C2WS.js → chunk-YFHV4QP3.js} +2 -2
  45. package/dist/{chunk-CND4NRNF.cjs → chunk-YNJLZVEO.cjs} +1 -1
  46. package/dist/chunk-YNJLZVEO.cjs.map +1 -0
  47. package/dist/{chunk-HT2TGO46.js → chunk-ZWPRA2SE.js} +2 -2
  48. package/dist/{chunk-SQJ7Q2Q5.cjs → chunk-ZXAH4AFS.cjs} +49 -11
  49. package/dist/chunk-ZXAH4AFS.cjs.map +1 -0
  50. package/dist/{chunk-WXEXWGPT.js → chunk-ZYJY44BT.js} +46 -8
  51. package/dist/{chunk-WXEXWGPT.js.map → chunk-ZYJY44BT.js.map} +1 -1
  52. package/dist/chunks-PPHEGDUD.js +10 -0
  53. package/dist/cli.js +54 -33
  54. package/dist/cli.js.map +1 -1
  55. package/dist/{formula-HU2APQRR.js → formula-CUSB5R3P.js} +4 -4
  56. package/dist/{formula-P54CLKTH.js → formula-UKLCJINT.js} +3 -3
  57. package/dist/{formula-LWU5I4NX.cjs → formula-YJIUNSWW.cjs} +9 -9
  58. package/dist/formula-YJIUNSWW.cjs.map +1 -0
  59. package/dist/{image-ocr-RCM3KL27.cjs → image-ocr-BMCOWLLB.cjs} +14 -14
  60. package/dist/image-ocr-BMCOWLLB.cjs.map +1 -0
  61. package/dist/{image-ocr-2UCO6DQD.js → image-ocr-OEEGTGDU.js} +6 -6
  62. package/dist/{image-ocr-I62V7QB2.js → image-ocr-S5OLK6WH.js} +8 -8
  63. package/dist/index.cjs +769 -649
  64. package/dist/index.cjs.map +1 -1
  65. package/dist/index.d.cts +9 -0
  66. package/dist/index.d.ts +9 -0
  67. package/dist/index.js +154 -34
  68. package/dist/index.js.map +1 -1
  69. package/dist/mcp.js +29 -23
  70. package/dist/mcp.js.map +1 -1
  71. package/dist/{model-bundle-MSYSZSDJ.js → model-bundle-A6QPDJZ3.js} +5 -5
  72. package/dist/{models-BCUGEIQX.js → models-GAP4U6WU.js} +5 -5
  73. package/dist/page-range-QHHFTL7X.cjs.map +1 -1
  74. package/dist/{parser-KZDC4LLY.js → parser-BCN3SZZC.js} +519 -25
  75. package/dist/parser-BCN3SZZC.js.map +1 -0
  76. package/dist/{parser-M26S76U2.cjs → parser-DZMXH4V5.cjs} +635 -141
  77. package/dist/parser-DZMXH4V5.cjs.map +1 -0
  78. package/dist/{parser-SI4DSZ6J.js → parser-MRTO7R2Y.js} +520 -26
  79. package/dist/parser-MRTO7R2Y.js.map +1 -0
  80. package/dist/pdf-ocr-4V7U52JI.js +18 -0
  81. package/dist/pdf-ocr-A3Q4YMCG.js +15 -0
  82. package/dist/pdf-ocr-CZDODSMI.cjs +16 -0
  83. package/dist/pdf-ocr-CZDODSMI.cjs.map +1 -0
  84. package/dist/{profile-io-QHKLJKAM.js → profile-io-XAZ2MDXD.js} +3 -3
  85. package/dist/{rasterize-JY72CIBX.js → rasterize-2YKKVEIR.js} +3 -3
  86. package/dist/{redact-doc-BWS4KRNH.js → redact-doc-XPV546P6.js} +11 -11
  87. package/dist/{render-53DA6GD5.js → render-ASDQSRPX.js} +7 -7
  88. package/dist/seal-3XWSKD6C.js +10 -0
  89. package/dist/{setup-GHLZX5VK.js → setup-M3MH2DHU.js} +3 -3
  90. package/dist/visual-Z6BCNJMU.js +20 -0
  91. package/dist/{watch-SYDX4ZLX.js → watch-3DB2LMAP.js} +12 -12
  92. package/package.json +1 -1
  93. package/dist/chunk-2DLW4CMC.cjs.map +0 -1
  94. package/dist/chunk-3PDCVDSO.js.map +0 -1
  95. package/dist/chunk-A63JPQEE.js.map +0 -1
  96. package/dist/chunk-CND4NRNF.cjs.map +0 -1
  97. package/dist/chunk-FA5JIHUV.js.map +0 -1
  98. package/dist/chunk-FBZCWSPN.cjs.map +0 -1
  99. package/dist/chunk-FWT24USP.js.map +0 -1
  100. package/dist/chunk-KJKMBV5K.js.map +0 -1
  101. package/dist/chunk-NK5XFKL4.js.map +0 -1
  102. package/dist/chunk-O6A6SK55.js.map +0 -1
  103. package/dist/chunk-QJX4IR77.cjs.map +0 -1
  104. package/dist/chunk-RSKR6A6S.js.map +0 -1
  105. package/dist/chunk-SOM7JIKG.cjs.map +0 -1
  106. package/dist/chunk-SQJ7Q2Q5.cjs.map +0 -1
  107. package/dist/chunk-U6SS43O6.js.map +0 -1
  108. package/dist/chunks-RJXLSR5O.js +0 -10
  109. package/dist/formula-LWU5I4NX.cjs.map +0 -1
  110. package/dist/image-ocr-RCM3KL27.cjs.map +0 -1
  111. package/dist/parser-KZDC4LLY.js.map +0 -1
  112. package/dist/parser-M26S76U2.cjs.map +0 -1
  113. package/dist/parser-SI4DSZ6J.js.map +0 -1
  114. package/dist/pdf-ocr-IOQA7ZQM.cjs +0 -16
  115. package/dist/pdf-ocr-IOQA7ZQM.cjs.map +0 -1
  116. package/dist/pdf-ocr-KA6BQTAB.js +0 -18
  117. package/dist/pdf-ocr-TPTWVV57.js +0 -15
  118. package/dist/seal-TJX6N5EE.js +0 -10
  119. package/dist/visual-JSTROEWO.js +0 -20
  120. /package/dist/{-F73GANY7.js.map → -H6WNRHK6.js.map} +0 -0
  121. /package/dist/{chunk-2OKMF2KY.js.map → chunk-AWXXLLIG.js.map} +0 -0
  122. /package/dist/{chunk-U7J7BFV3.js.map → chunk-IHCQ4IE7.js.map} +0 -0
  123. /package/dist/{chunk-DRQW5SYI.js.map → chunk-KJSD2WNF.js.map} +0 -0
  124. /package/dist/{chunk-765SAMGS.js.map → chunk-L5MDTA6T.js.map} +0 -0
  125. /package/dist/{chunk-6OQTREJ5.js.map → chunk-ORMMGTNK.js.map} +0 -0
  126. /package/dist/{chunk-OQ3DY7RF.js.map → chunk-TRB6OYMU.js.map} +0 -0
  127. /package/dist/{chunk-QC736WXT.js.map → chunk-UGSRP7E2.js.map} +0 -0
  128. /package/dist/{chunk-UKD7C2WS.js.map → chunk-YFHV4QP3.js.map} +0 -0
  129. /package/dist/{chunk-HT2TGO46.js.map → chunk-ZWPRA2SE.js.map} +0 -0
  130. /package/dist/{chunks-RJXLSR5O.js.map → chunks-PPHEGDUD.js.map} +0 -0
  131. /package/dist/{formula-HU2APQRR.js.map → formula-CUSB5R3P.js.map} +0 -0
  132. /package/dist/{formula-P54CLKTH.js.map → formula-UKLCJINT.js.map} +0 -0
  133. /package/dist/{image-ocr-2UCO6DQD.js.map → image-ocr-OEEGTGDU.js.map} +0 -0
  134. /package/dist/{image-ocr-I62V7QB2.js.map → image-ocr-S5OLK6WH.js.map} +0 -0
  135. /package/dist/{model-bundle-MSYSZSDJ.js.map → model-bundle-A6QPDJZ3.js.map} +0 -0
  136. /package/dist/{models-BCUGEIQX.js.map → models-GAP4U6WU.js.map} +0 -0
  137. /package/dist/{pdf-ocr-KA6BQTAB.js.map → pdf-ocr-4V7U52JI.js.map} +0 -0
  138. /package/dist/{pdf-ocr-TPTWVV57.js.map → pdf-ocr-A3Q4YMCG.js.map} +0 -0
  139. /package/dist/{profile-io-QHKLJKAM.js.map → profile-io-XAZ2MDXD.js.map} +0 -0
  140. /package/dist/{rasterize-JY72CIBX.js.map → rasterize-2YKKVEIR.js.map} +0 -0
  141. /package/dist/{redact-doc-BWS4KRNH.js.map → redact-doc-XPV546P6.js.map} +0 -0
  142. /package/dist/{render-53DA6GD5.js.map → render-ASDQSRPX.js.map} +0 -0
  143. /package/dist/{seal-TJX6N5EE.js.map → seal-3XWSKD6C.js.map} +0 -0
  144. /package/dist/{setup-GHLZX5VK.js.map → setup-M3MH2DHU.js.map} +0 -0
  145. /package/dist/{visual-JSTROEWO.js.map → visual-Z6BCNJMU.js.map} +0 -0
  146. /package/dist/{watch-SYDX4ZLX.js.map → watch-3DB2LMAP.js.map} +0 -0
@@ -2,11 +2,11 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkCND4NRNFcjs = require('./chunk-CND4NRNF.cjs');
5
+ var _chunkYNJLZVEOcjs = require('./chunk-YNJLZVEO.cjs');
6
6
 
7
7
 
8
8
 
9
- var _chunkFBZCWSPNcjs = require('./chunk-FBZCWSPN.cjs');
9
+ var _chunkJ6ZU7AIRcjs = require('./chunk-J6ZU7AIR.cjs');
10
10
 
11
11
  // src/pdf/image-regions.ts
12
12
  var _pdfmjs = require('pdfjs-dist/legacy/build/pdf.mjs');
@@ -790,6 +790,10 @@ var CUT_INTERIOR_MATCH_TOL = 8;
790
790
  var CUT_MAX_INTERIOR_OVERLAP = 0.5;
791
791
  var CUT_VCHAIN_X_TOL = 1.5;
792
792
  var CUT_VCHAIN_GAP = 1;
793
+ var NEST_STRICT_TOL = 0.5;
794
+ var NEST_MIN_GAP = 0.8;
795
+ var NEST_EDGE_COVER = 0.95;
796
+ var NEST_DOUBLE_RULE_GAP = 6;
793
797
  var VERTEX_BUCKET_CELL = 100;
794
798
  function lowerBound(sorted, key) {
795
799
  let lo = 0, hi = sorted.length;
@@ -893,9 +897,12 @@ function buildTableGrids(horizontals, verticals) {
893
897
  ...verticals.map((l, i) => ({ ...l, type: "v", id: i + horizontals.length }))
894
898
  ];
895
899
  const groups = [];
896
- for (const g of groupConnectedLines(allLines)) {
900
+ for (const g0 of groupConnectedLines(allLines)) {
901
+ const { outer: g, nested } = splitNestedBoxes(g0);
902
+ for (const n of nested) groups.push({ lines: n, fromSplit: true, nested: true });
903
+ if (g.length === 0) continue;
897
904
  const bands = splitStackedGroup(g);
898
- for (const b of bands) groups.push({ lines: b, fromSplit: bands.length > 1 });
905
+ for (const b of bands) groups.push({ lines: b, fromSplit: bands.length > 1 || nested.length > 0 });
899
906
  }
900
907
  const grids = [];
901
908
  const byY = [...vertices].sort((a, b) => a.y - b.y);
@@ -909,7 +916,7 @@ function buildTableGrids(horizontals, verticals) {
909
916
  }
910
917
  return lo;
911
918
  };
912
- for (const { lines: group, fromSplit } of groups) {
919
+ for (const { lines: group, fromSplit, nested } of groups) {
913
920
  const hLines = group.filter((l) => l.type === "h");
914
921
  const vLines = group.filter((l) => l.type === "v");
915
922
  if (hLines.length < 2 || vLines.length < 2) continue;
@@ -971,9 +978,9 @@ function buildTableGrids(horizontals, verticals) {
971
978
  x2: validColXs[validColXs.length - 1],
972
979
  y2: validRowYs[0]
973
980
  };
974
- grids.push({ rowYs: validRowYs, colXs: validColXs, bbox, vertexRadius: groupRadius });
981
+ grids.push({ rowYs: validRowYs, colXs: validColXs, bbox, vertexRadius: groupRadius, ...nested ? { lineNested: true } : {} });
975
982
  }
976
- return mergeAdjacentGrids(grids);
983
+ return [...mergeAdjacentGrids(grids.filter((g) => !g.lineNested)), ...grids.filter((g) => g.lineNested)];
977
984
  }
978
985
  var SHADE_CLIP_TOL = 1.5;
979
986
  var SHADE_CLIP_MAX_AREA = 0.5;
@@ -1152,8 +1159,52 @@ function splitStackedGroup(group) {
1152
1159
  }
1153
1160
  return bands.filter((b) => b.length > 0);
1154
1161
  }
1162
+ function splitNestedBoxes(group) {
1163
+ const comps = groupConnectedLines(group, NEST_STRICT_TOL);
1164
+ if (comps.length < 2) return { outer: group, nested: [] };
1165
+ const boxes = comps.map((c) => {
1166
+ const hs = c.filter((l) => l.type === "h"), vs = c.filter((l) => l.type === "v");
1167
+ if (hs.length < 2 || vs.length < 2) return null;
1168
+ const x1 = Math.min(...vs.map((v) => v.x1)), x2 = Math.max(...vs.map((v) => v.x1));
1169
+ const y1 = Math.min(...hs.map((h) => h.y1)), y2 = Math.max(...hs.map((h) => h.y1));
1170
+ if (x2 - x1 < 1 || y2 - y1 < 1) return null;
1171
+ const cover = (segs, a, b) => segs.reduce((s, [p, q]) => s + Math.max(0, Math.min(q, b) - Math.max(p, a)), 0) >= (b - a) * NEST_EDGE_COVER;
1172
+ const edgeH = (y) => cover(hs.filter((h) => Math.abs(h.y1 - y) <= NEST_STRICT_TOL).map((h) => [h.x1, h.x2]), x1, x2);
1173
+ const edgeV = (x) => cover(vs.filter((v) => Math.abs(v.x1 - x) <= NEST_STRICT_TOL).map((v) => [v.y1, v.y2]), y1, y2);
1174
+ return edgeH(y1) && edgeH(y2) && edgeV(x1) && edgeV(x2) ? { x1, y1, x2, y2 } : null;
1175
+ });
1176
+ const bboxOf = (c) => ({
1177
+ x1: Math.min(...c.map((l) => Math.min(l.x1, l.x2))),
1178
+ x2: Math.max(...c.map((l) => Math.max(l.x1, l.x2))),
1179
+ y1: Math.min(...c.map((l) => Math.min(l.y1, l.y2))),
1180
+ y2: Math.max(...c.map((l) => Math.max(l.y1, l.y2)))
1181
+ });
1182
+ const extents = comps.map(bboxOf);
1183
+ const nestedIdx = /* @__PURE__ */ new Set();
1184
+ comps.forEach((_, i) => {
1185
+ const b = boxes[i];
1186
+ if (!b) return;
1187
+ const e = extents[i];
1188
+ const uniq = (xs) => xs.filter((x, k) => xs.findIndex((y) => Math.abs(y - x) <= NEST_STRICT_TOL) === k).length;
1189
+ const bare = uniq(comps[i].filter((l) => l.type === "h").map((l) => l.y1)) === 2 && uniq(comps[i].filter((l) => l.type === "v").map((l) => l.x1)) === 2;
1190
+ const inside = comps.some((c, j) => {
1191
+ if (j === i || c.filter((l) => l.type === "v").length < 2 || !c.some((l) => l.type === "h")) return false;
1192
+ const p = extents[j];
1193
+ const gaps = [e.x1 - p.x1, p.x2 - e.x2, e.y1 - p.y1, p.y2 - e.y2];
1194
+ return gaps.every((g) => g >= NEST_MIN_GAP) && !(bare && gaps.every((g) => g <= NEST_DOUBLE_RULE_GAP));
1195
+ });
1196
+ if (!inside) return;
1197
+ const crossed = comps.some((c, j) => j !== i && c.some((l) => l.type === "h" ? l.y1 > e.y1 + NEST_MIN_GAP && l.y1 < e.y2 - NEST_MIN_GAP && Math.min(l.x2, e.x2) - Math.max(l.x1, e.x1) > NEST_MIN_GAP : l.x1 > e.x1 + NEST_MIN_GAP && l.x1 < e.x2 - NEST_MIN_GAP && Math.min(l.y2, e.y2) - Math.max(l.y1, e.y1) > NEST_MIN_GAP) && !(extents[j].x1 >= e.x1 && extents[j].x2 <= e.x2 && extents[j].y1 >= e.y1 && extents[j].y2 <= e.y2));
1198
+ if (!crossed) nestedIdx.add(i);
1199
+ });
1200
+ if (nestedIdx.size === 0) return { outer: group, nested: [] };
1201
+ return {
1202
+ outer: comps.filter((_, i) => !nestedIdx.has(i)).flat(),
1203
+ nested: comps.filter((_, i) => nestedIdx.has(i))
1204
+ };
1205
+ }
1155
1206
  var GROUP_BUCKET_CELL = 100;
1156
- function groupConnectedLines(lines) {
1207
+ function groupConnectedLines(lines, tol = CONNECT_TOL) {
1157
1208
  const parent = lines.map((_, i) => i);
1158
1209
  function find(x) {
1159
1210
  while (parent[x] !== x) {
@@ -1195,7 +1246,7 @@ function groupConnectedLines(lines) {
1195
1246
  const key = i * lines.length + j;
1196
1247
  if (tested.has(key)) continue;
1197
1248
  tested.add(key);
1198
- if (linesIntersect(lines[i], lines[j])) {
1249
+ if (linesIntersect(lines[i], lines[j], tol)) {
1199
1250
  union(i, j);
1200
1251
  }
1201
1252
  }
@@ -1209,19 +1260,18 @@ function groupConnectedLines(lines) {
1209
1260
  }
1210
1261
  return [...groups.values()];
1211
1262
  }
1212
- function linesIntersect(a, b) {
1263
+ function linesIntersect(a, b, tol = CONNECT_TOL) {
1213
1264
  if (a.type === b.type) {
1214
1265
  if (a.type === "h") {
1215
- if (Math.abs(a.y1 - b.y1) > CONNECT_TOL) return false;
1216
- return Math.min(a.x2, b.x2) >= Math.max(a.x1, b.x1) - CONNECT_TOL;
1266
+ if (Math.abs(a.y1 - b.y1) > tol) return false;
1267
+ return Math.min(a.x2, b.x2) >= Math.max(a.x1, b.x1) - tol;
1217
1268
  } else {
1218
- if (Math.abs(a.x1 - b.x1) > CONNECT_TOL) return false;
1219
- return Math.min(a.y2, b.y2) >= Math.max(a.y1, b.y1) - CONNECT_TOL;
1269
+ if (Math.abs(a.x1 - b.x1) > tol) return false;
1270
+ return Math.min(a.y2, b.y2) >= Math.max(a.y1, b.y1) - tol;
1220
1271
  }
1221
1272
  }
1222
1273
  const h = a.type === "h" ? a : b;
1223
1274
  const v = a.type === "h" ? b : a;
1224
- const tol = CONNECT_TOL;
1225
1275
  return v.x1 >= h.x1 - tol && v.x1 <= h.x2 + tol && h.y1 >= v.y1 - tol && h.y1 <= v.y2 + tol;
1226
1276
  }
1227
1277
 
@@ -1265,6 +1315,13 @@ function clusterCoords(values) {
1265
1315
  if (run.length > 0) out.push(run.reduce((s, x) => s + x, 0) / run.length);
1266
1316
  return out;
1267
1317
  }
1318
+ function dropSliverGaps(coords) {
1319
+ const out = [...coords];
1320
+ if (out.length > 2 && out[1] - out[0] < 1) out.splice(0, 2, (out[0] + out[1]) / 2);
1321
+ const n = out.length;
1322
+ if (n > 2 && out[n - 1] - out[n - 2] < 1) out.splice(n - 2, 2, (out[n - 2] + out[n - 1]) / 2);
1323
+ return out;
1324
+ }
1268
1325
  var nearestIndex = (coords, v) => {
1269
1326
  let best = 0;
1270
1327
  for (let i = 1; i < coords.length; i++) if (Math.abs(coords[i] - v) < Math.abs(coords[best] - v)) best = i;
@@ -1462,7 +1519,7 @@ function buildClipCellGrids(rects, strokedH, strokedV, pageWidth, pageHeight, te
1462
1519
  if (!edgeStroked(strokedV, "v", r.x2, r.y1, r.y2)) invisible++;
1463
1520
  }
1464
1521
  if (invisible / edges < CLIP_MIN_INVISIBLE) continue;
1465
- const colXs = clusterCoords(members.flatMap((r) => [r.x1, r.x2]));
1522
+ const colXs = dropSliverGaps(clusterCoords(members.flatMap((r) => [r.x1, r.x2])));
1466
1523
  const rowYs = clusterCoords(members.flatMap((r) => [r.y1, r.y2])).reverse();
1467
1524
  const numRows = rowYs.length - 1, numCols = colXs.length - 1;
1468
1525
  if (numRows < 1 || numCols < 1) continue;
@@ -2224,7 +2281,7 @@ function mergeCellTextLines(textLines, wrap) {
2224
2281
  merged[merged.length - 1] = prev + curr.trim();
2225
2282
  } else if (!wrap && /[,(]$/.test(prev.trim()) && curr.trim().length <= 15) {
2226
2283
  merged[merged.length - 1] = prev + curr.trim();
2227
- } else if (/[\d,]$/.test(prev) && /^[\d,]+[)\]]?$/.test(curr.trim()) && curr.trim().length <= 10 && !(/\d,\d{3}$/.test(prev) && /^\d/.test(curr.trim())) && !(/(?:^|[^\d,])\d{1,3}$/.test(prev) && /^(\d{1,3}(,\d{3})+|\d{1,3})$/.test(curr.trim()))) {
2284
+ } else if (/[\d,]$/.test(prev) && /^[\d,]+[)\]]?$/.test(curr.trim()) && curr.trim().length <= 10 && !(/\d,\d{3}$/.test(prev) && /^\d/.test(curr.trim())) && !(/(?:^|[^\d,])\d{1,3}$/.test(prev) && /^(\d{1,3}(,\d{3})+|\d{1,3})$/.test(curr.trim()) && !_optionalChain([wrap, 'optionalAccess', _38 => _38.wraps, 'access', _39 => _39[i - 1]])) && !(/(?:^|\s)\d{1,7}$/.test(prev) && /^\d{1,7}$/.test(curr.trim()) && !_optionalChain([wrap, 'optionalAccess', _40 => _40.wraps, 'access', _41 => _41[i - 1]]))) {
2228
2285
  merged[merged.length - 1] = prev + curr.trim();
2229
2286
  } else {
2230
2287
  merged.push(curr);
@@ -2294,7 +2351,7 @@ function normalizeUndersegmentedTable(originalCells, colXs, items, rowYs) {
2294
2351
  if (numRows > MAX_UNDERSEGMENTED_ROWS || numCols < MIN_UNDERSEGMENTED_COLUMNS) return null;
2295
2352
  if (items.length === 0) return null;
2296
2353
  if (numRows >= 3) {
2297
- if (_optionalChain([rowYs, 'optionalAccess', _38 => _38.length]) !== numRows + 1) return null;
2354
+ if (_optionalChain([rowYs, 'optionalAccess', _42 => _42.length]) !== numRows + 1) return null;
2298
2355
  const rebuilt2 = [];
2299
2356
  let expanded = 0;
2300
2357
  for (let r = 0; r < numRows; r++) {
@@ -2435,7 +2492,7 @@ function dominantStyle(items) {
2435
2492
  let maxCount = 0, dominantSize = 0;
2436
2493
  for (const i of items) {
2437
2494
  if (i.fontSize <= 0) continue;
2438
- const count = (freq.get(i.fontSize) || 0) + Math.max(1, _nullishCoalesce(_optionalChain([i, 'access', _39 => _39.text, 'access', _40 => _40.match, 'call', _41 => _41(/[\p{L}\p{N}]/gu), 'optionalAccess', _42 => _42.length]), () => ( 0)));
2495
+ const count = (freq.get(i.fontSize) || 0) + Math.max(1, _nullishCoalesce(_optionalChain([i, 'access', _43 => _43.text, 'access', _44 => _44.match, 'call', _45 => _45(/[\p{L}\p{N}]/gu), 'optionalAccess', _46 => _46.length]), () => ( 0)));
2439
2496
  freq.set(i.fontSize, count);
2440
2497
  if (count > maxCount) {
2441
2498
  maxCount = count;
@@ -2443,7 +2500,7 @@ function dominantStyle(items) {
2443
2500
  }
2444
2501
  }
2445
2502
  if (dominantSize === 0) return void 0;
2446
- const fontName = _optionalChain([items, 'access', _43 => _43.find, 'call', _44 => _44((i) => i.fontSize === dominantSize), 'optionalAccess', _45 => _45.fontName]) || void 0;
2503
+ const fontName = _optionalChain([items, 'access', _47 => _47.find, 'call', _48 => _48((i) => i.fontSize === dominantSize), 'optionalAccess', _49 => _49.fontName]) || void 0;
2447
2504
  return fontName ? { fontSize: dominantSize, fontName } : { fontSize: dominantSize };
2448
2505
  }
2449
2506
  function normalizeItems(rawItems) {
@@ -2556,7 +2613,7 @@ function splitAroundOverlays(c, overlays) {
2556
2613
  const ov = overlays.filter((o) => {
2557
2614
  for (let at = c.text.indexOf(o.text); at >= 0; at = c.text.indexOf(o.text, at + 1)) {
2558
2615
  const prefix = c.text.slice(0, at);
2559
- const est = c.x + glyphUnits(prefix.replace(/\s+/g, "")) * a0 + (_nullishCoalesce(_optionalChain([prefix, 'access', _46 => _46.match, 'call', _47 => _47(/\s+/g), 'optionalAccess', _48 => _48.length]), () => ( 0))) * ws;
2616
+ const est = c.x + glyphUnits(prefix.replace(/\s+/g, "")) * a0 + (_nullishCoalesce(_optionalChain([prefix, 'access', _50 => _50.match, 'call', _51 => _51(/\s+/g), 'optionalAccess', _52 => _52.length]), () => ( 0))) * ws;
2560
2617
  if (Math.abs(est - o.x) <= OVERLAY_DUP_EM * fs) return false;
2561
2618
  }
2562
2619
  return true;
@@ -2669,7 +2726,7 @@ function mergeSuperscriptLines(lines) {
2669
2726
  return result;
2670
2727
  }
2671
2728
  function mergeLineSimple(items) {
2672
- if (items.length <= 1) return _optionalChain([items, 'access', _49 => _49[0], 'optionalAccess', _50 => _50.text]) || "";
2729
+ if (items.length <= 1) return _optionalChain([items, 'access', _53 => _53[0], 'optionalAccess', _54 => _54.text]) || "";
2673
2730
  const sorted = sortLineByX([...items]);
2674
2731
  const isEvenSpaced = detectEvenSpacedItems(sorted);
2675
2732
  let result = sorted[0].text;
@@ -2810,7 +2867,7 @@ function splitTrailingColumnRegion(items) {
2810
2867
  }
2811
2868
  function panelBlocks(items, panel, pageNum) {
2812
2869
  const lines = groupByY([...items].sort((a, b) => b.y - a.y || a.x - b.x));
2813
- const faceOf = (line) => _nullishCoalesce(_optionalChain([dominantStyle, 'call', _51 => _51(line), 'optionalAccess', _52 => _52.fontName]), () => ( ""));
2870
+ const faceOf = (line) => _nullishCoalesce(_optionalChain([dominantStyle, 'call', _55 => _55(line), 'optionalAccess', _56 => _56.fontName]), () => ( ""));
2814
2871
  const runs = [];
2815
2872
  for (const line of lines) {
2816
2873
  const last = runs[runs.length - 1];
@@ -2840,9 +2897,12 @@ function pushLineParagraphs(out, yLines, pageNum, lex) {
2840
2897
  const lines = attachDropCaps(yLines).map((items) => ({ items, text: mergeLineSimple(items) })).filter((l) => l.text.trim());
2841
2898
  const geo = lines.map((l) => {
2842
2899
  const b = computeBBox(l.items, pageNum);
2843
- return { text: l.text, left: b.x, right: b.x + b.width, y: l.items.reduce((s, i) => s + i.y, 0) / l.items.length, fontSize: _nullishCoalesce(_optionalChain([dominantStyle, 'call', _53 => _53(l.items), 'optionalAccess', _54 => _54.fontSize]), () => ( 0)) };
2900
+ return { text: l.text, left: b.x, right: b.x + b.width, y: l.items.reduce((s, i) => s + i.y, 0) / l.items.length, fontSize: _nullishCoalesce(_optionalChain([dominantStyle, 'call', _57 => _57(l.items), 'optionalAccess', _58 => _58.fontSize]), () => ( 0)) };
2844
2901
  });
2845
2902
  const joins = bodyLineJoins(geo, lex);
2903
+ for (let i = 0; i + 1 < geo.length; i++) {
2904
+ if (/^\d{1,2}$/.test(geo[i].text.trim()) && geo[i].fontSize >= geo[i + 1].fontSize * 1.2) joins[i] = "\n";
2905
+ }
2846
2906
  if (hasNumberedStyledTitle(lines.map((line) => line.items))) {
2847
2907
  joins[0] = "\n";
2848
2908
  joins[1] = "\n";
@@ -2879,16 +2939,17 @@ function computeMedianFontSizeFromFreq(freq) {
2879
2939
  return sorted[sorted.length - 1][0];
2880
2940
  }
2881
2941
  function detectHeadings(blocks, medianFontSize) {
2882
- for (const block of blocks) {
2883
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _55 => _55.style, 'optionalAccess', _56 => _56.fontSize])) continue;
2942
+ for (let bi = 0; bi < blocks.length; bi++) {
2943
+ const block = blocks[bi];
2944
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _59 => _59.style, 'optionalAccess', _60 => _60.fontSize])) continue;
2884
2945
  const text = block.text.trim();
2885
2946
  if (text.length === 0 || text.length > 200) continue;
2886
- if (/^\d+$/.test(text)) continue;
2947
+ if (/^\d+$/.test(text) && !isChapterNumber(block, blocks[bi + 1], medianFontSize)) continue;
2887
2948
  const ratio = block.style.fontSize / medianFontSize;
2888
2949
  let level = 0;
2889
- if (ratio >= _chunkCND4NRNFcjs.HEADING_RATIO_H1) level = 1;
2890
- else if (ratio >= _chunkCND4NRNFcjs.HEADING_RATIO_H2) level = 2;
2891
- else if (ratio >= _chunkCND4NRNFcjs.HEADING_RATIO_H3) level = 3;
2950
+ if (ratio >= _chunkYNJLZVEOcjs.HEADING_RATIO_H1) level = 1;
2951
+ else if (ratio >= _chunkYNJLZVEOcjs.HEADING_RATIO_H2) level = 2;
2952
+ else if (ratio >= _chunkYNJLZVEOcjs.HEADING_RATIO_H3) level = 3;
2892
2953
  if (level > 0) {
2893
2954
  block.type = "heading";
2894
2955
  block.level = level;
@@ -2896,17 +2957,24 @@ function detectHeadings(blocks, medianFontSize) {
2896
2957
  }
2897
2958
  }
2898
2959
  }
2960
+ function isChapterNumber(block, next, medianFontSize) {
2961
+ const size = _nullishCoalesce(_optionalChain([block, 'access', _61 => _61.style, 'optionalAccess', _62 => _62.fontSize]), () => ( 0));
2962
+ const nextSize = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _63 => _63.style, 'optionalAccess', _64 => _64.fontSize]), () => ( 0));
2963
+ const text = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _65 => _65.text, 'optionalAccess', _66 => _66.trim, 'call', _67 => _67()]), () => ( ""));
2964
+ const a = block.bbox, b = _optionalChain([next, 'optionalAccess', _68 => _68.bbox]);
2965
+ return /^\d{1,2}$/.test(_nullishCoalesce(_optionalChain([block, 'access', _69 => _69.text, 'optionalAccess', _70 => _70.trim, 'call', _71 => _71()]), () => ( ""))) && size >= medianFontSize * 2.5 && !!next && (next.type === "paragraph" || next.type === "heading") && next.pageNumber === block.pageNumber && nextSize >= medianFontSize * _chunkYNJLZVEOcjs.HEADING_RATIO_H1 && text.length > 0 && text.length <= 80 && !/^[\d\s.]+$/.test(text) && !!a && !!b && a.y > b.y && a.y - (b.y + b.height) <= size * 2;
2966
+ }
2899
2967
  function mergeStackedHeadingLines(blocks, medianFontSize) {
2900
2968
  for (let i = 0; i < blocks.length - 1; ) {
2901
2969
  const a = blocks[i], b = blocks[i + 1];
2902
2970
  const ab = a.bbox, bb = b.bbox;
2903
- const af = _nullishCoalesce(_optionalChain([a, 'access', _57 => _57.style, 'optionalAccess', _58 => _58.fontSize]), () => ( 0)), bf = _nullishCoalesce(_optionalChain([b, 'access', _59 => _59.style, 'optionalAccess', _60 => _60.fontSize]), () => ( 0));
2971
+ const af = _nullishCoalesce(_optionalChain([a, 'access', _72 => _72.style, 'optionalAccess', _73 => _73.fontSize]), () => ( 0)), bf = _nullishCoalesce(_optionalChain([b, 'access', _74 => _74.style, 'optionalAccess', _75 => _75.fontSize]), () => ( 0));
2904
2972
  const gap = ab && bb ? ab.y - (bb.y + bb.height) : Infinity;
2905
- const centered = ab && bb && _optionalChain([a, 'access', _61 => _61.style, 'optionalAccess', _62 => _62.fontName]) === _optionalChain([b, 'access', _63 => _63.style, 'optionalAccess', _64 => _64.fontName]) && Math.abs(ab.x + ab.width / 2 - (bb.x + bb.width / 2)) <= Math.max(5, af * 0.5);
2973
+ const centered = ab && bb && _optionalChain([a, 'access', _76 => _76.style, 'optionalAccess', _77 => _77.fontName]) === _optionalChain([b, 'access', _78 => _78.style, 'optionalAccess', _79 => _79.fontName]) && Math.abs(ab.x + ab.width / 2 - (bb.x + bb.width / 2)) <= Math.max(5, af * 0.5);
2906
2974
  const sameAnchor = ab && bb && Math.abs(ab.x - bb.x) <= 5;
2907
- const wrapped = sameAnchor && _optionalChain([a, 'access', _65 => _65.style, 'optionalAccess', _66 => _66.fontName]) === _optionalChain([b, 'access', _67 => _67.style, 'optionalAccess', _68 => _68.fontName]) && af === bf && ab.width >= bb.width * 0.95 && (_nullishCoalesce(_optionalChain([a, 'access', _69 => _69.text, 'optionalAccess', _70 => _70.trim, 'call', _71 => _71(), 'access', _72 => _72.split, 'call', _73 => _73(/\s+/), 'access', _74 => _74.length]), () => ( 0))) >= 3;
2975
+ const wrapped = sameAnchor && _optionalChain([a, 'access', _80 => _80.style, 'optionalAccess', _81 => _81.fontName]) === _optionalChain([b, 'access', _82 => _82.style, 'optionalAccess', _83 => _83.fontName]) && af === bf && ab.width >= bb.width * 0.95 && (_nullishCoalesce(_optionalChain([a, 'access', _84 => _84.text, 'optionalAccess', _85 => _85.trim, 'call', _86 => _86(), 'access', _87 => _87.split, 'call', _88 => _88(/\s+/), 'access', _89 => _89.length]), () => ( 0))) >= 3;
2908
2976
  const displayStack = centered && gap <= Math.min(af, bf) * 0.3 && Math.max(af, bf) <= Math.min(af, bf) * 1.45;
2909
- if (a.type !== "heading" || b.type !== "heading" || !a.text || !b.text || !ab || !bb || ab.page !== bb.page || !(sameAnchor && af >= medianFontSize * 2 && bf >= medianFontSize * 2) && !wrapped && !(centered && af >= medianFontSize * 1.25 && bf >= medianFontSize * 1.25) || Math.abs(af - bf) > Math.max(af, bf) * 0.15 && !displayStack || gap < -2 || gap > Math.max(af, bf) * 0.45 || a.text.length > (centered ? 120 : 50) || b.text.length > (centered ? 120 : 50)) {
2977
+ if (a.type !== "heading" || b.type !== "heading" || !a.text || !b.text || /^\d+$/.test(a.text.trim()) || !ab || !bb || ab.page !== bb.page || !(sameAnchor && af >= medianFontSize * 2 && bf >= medianFontSize * 2) && !wrapped && !(centered && af >= medianFontSize * 1.25 && bf >= medianFontSize * 1.25) || Math.abs(af - bf) > Math.max(af, bf) * 0.15 && !displayStack || gap < -2 || gap > Math.max(af, bf) * 0.45 || a.text.length > (centered ? 120 : 50) || b.text.length > (centered ? 120 : 50)) {
2910
2978
  i++;
2911
2979
  continue;
2912
2980
  }
@@ -2933,22 +3001,22 @@ function detectTypographyHeadings(blocks) {
2933
3001
  if (page.some((block) => block.type === "heading")) continue;
2934
3002
  const faceWeight = /* @__PURE__ */ new Map();
2935
3003
  for (const block of page) {
2936
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _75 => _75.style, 'optionalAccess', _76 => _76.fontName])) continue;
3004
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _90 => _90.style, 'optionalAccess', _91 => _91.fontName])) continue;
2937
3005
  const face = block.style.fontName;
2938
3006
  faceWeight.set(face, (_nullishCoalesce(faceWeight.get(face), () => ( 0))) + block.text.length);
2939
3007
  }
2940
- const bodyFace = _optionalChain([[...faceWeight], 'access', _77 => _77.sort, 'call', _78 => _78((a, b) => b[1] - a[1]), 'access', _79 => _79[0], 'optionalAccess', _80 => _80[0]]);
3008
+ const bodyFace = _optionalChain([[...faceWeight], 'access', _92 => _92.sort, 'call', _93 => _93((a, b) => b[1] - a[1]), 'access', _94 => _94[0], 'optionalAccess', _95 => _95[0]]);
2941
3009
  if (!bodyFace || (_nullishCoalesce(faceWeight.get(bodyFace), () => ( 0))) < 250) continue;
2942
3010
  const sizeWeight = /* @__PURE__ */ new Map();
2943
3011
  for (const block of page) {
2944
- if (block.type !== "paragraph" || _optionalChain([block, 'access', _81 => _81.style, 'optionalAccess', _82 => _82.fontName]) !== bodyFace || !block.style.fontSize) continue;
3012
+ if (block.type !== "paragraph" || _optionalChain([block, 'access', _96 => _96.style, 'optionalAccess', _97 => _97.fontName]) !== bodyFace || !block.style.fontSize) continue;
2945
3013
  sizeWeight.set(block.style.fontSize, (_nullishCoalesce(sizeWeight.get(block.style.fontSize), () => ( 0))) + block.text.length);
2946
3014
  }
2947
- const bodySize = _nullishCoalesce(_optionalChain([[...sizeWeight], 'access', _83 => _83.sort, 'call', _84 => _84((a, b) => b[1] - a[1]), 'access', _85 => _85[0], 'optionalAccess', _86 => _86[0]]), () => ( 0));
3015
+ const bodySize = _nullishCoalesce(_optionalChain([[...sizeWeight], 'access', _98 => _98.sort, 'call', _99 => _99((a, b) => b[1] - a[1]), 'access', _100 => _100[0], 'optionalAccess', _101 => _101[0]]), () => ( 0));
2948
3016
  for (let i = 0; i < page.length; i++) {
2949
3017
  const block = page[i];
2950
3018
  const { text, bbox, style } = block;
2951
- if (block.type !== "paragraph" || !text || !bbox || !_optionalChain([style, 'optionalAccess', _87 => _87.fontName]) || !style.fontSize) continue;
3019
+ if (block.type !== "paragraph" || !text || !bbox || !_optionalChain([style, 'optionalAccess', _102 => _102.fontName]) || !style.fontSize) continue;
2952
3020
  const title = text.trim();
2953
3021
  const numbered = /^\d+(?:\.\d+)*\.?\s+[A-Z가-힣]/.test(title);
2954
3022
  const faces = FACE_CHARS.get(block);
@@ -2978,16 +3046,16 @@ function detectDocumentStyleHeadings(blocks) {
2978
3046
  for (const page of byPage.values()) {
2979
3047
  const faceChars = /* @__PURE__ */ new Map();
2980
3048
  for (const block of page) {
2981
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _88 => _88.style, 'optionalAccess', _89 => _89.fontName])) continue;
3049
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _103 => _103.style, 'optionalAccess', _104 => _104.fontName])) continue;
2982
3050
  faceChars.set(block.style.fontName, (_nullishCoalesce(faceChars.get(block.style.fontName), () => ( 0))) + block.text.length);
2983
3051
  }
2984
- const bodyFace = _optionalChain([[...faceChars], 'access', _90 => _90.sort, 'call', _91 => _91((a, b) => b[1] - a[1]), 'access', _92 => _92[0], 'optionalAccess', _93 => _93[0]]);
3052
+ const bodyFace = _optionalChain([[...faceChars], 'access', _105 => _105.sort, 'call', _106 => _106((a, b) => b[1] - a[1]), 'access', _107 => _107[0], 'optionalAccess', _108 => _108[0]]);
2985
3053
  if (!bodyFace || (_nullishCoalesce(faceChars.get(bodyFace), () => ( 0))) < 100) continue;
2986
- const labels = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _94 => _94.style, 'optionalAccess', _95 => _95.fontName]) && b.style.fontName !== bodyFace && b.text.trim().length >= 3 && b.text.trim().length <= 40);
3054
+ const labels = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _109 => _109.style, 'optionalAccess', _110 => _110.fontName]) && b.style.fontName !== bodyFace && b.text.trim().length >= 3 && b.text.trim().length <= 40);
2987
3055
  for (const label of labels) {
2988
- const peers = labels.filter((b) => _optionalChain([b, 'access', _96 => _96.style, 'optionalAccess', _97 => _97.fontName]) === _optionalChain([label, 'access', _98 => _98.style, 'optionalAccess', _99 => _99.fontName]) && Math.abs(b.bbox.y - label.bbox.y) <= 3 && Math.abs(b.bbox.x - label.bbox.x) >= 60);
3056
+ const peers = labels.filter((b) => _optionalChain([b, 'access', _111 => _111.style, 'optionalAccess', _112 => _112.fontName]) === _optionalChain([label, 'access', _113 => _113.style, 'optionalAccess', _114 => _114.fontName]) && Math.abs(b.bbox.y - label.bbox.y) <= 3 && Math.abs(b.bbox.x - label.bbox.x) >= 60);
2989
3057
  if (peers.length < 2) continue;
2990
- const value = page.find((b) => b.type === "paragraph" && b.bbox && _optionalChain([b, 'access', _100 => _100.style, 'optionalAccess', _101 => _101.fontName]) !== _optionalChain([label, 'access', _102 => _102.style, 'optionalAccess', _103 => _103.fontName]) && b.bbox.x >= label.bbox.x - 5 && b.bbox.x <= label.bbox.x + 20 && b.bbox.y < label.bbox.y && label.bbox.y - (b.bbox.y + b.bbox.height) <= 60);
3058
+ const value = page.find((b) => b.type === "paragraph" && b.bbox && _optionalChain([b, 'access', _115 => _115.style, 'optionalAccess', _116 => _116.fontName]) !== _optionalChain([label, 'access', _117 => _117.style, 'optionalAccess', _118 => _118.fontName]) && b.bbox.x >= label.bbox.x - 5 && b.bbox.x <= label.bbox.x + 20 && b.bbox.y < label.bbox.y && label.bbox.y - (b.bbox.y + b.bbox.height) <= 60);
2991
3059
  if (value) {
2992
3060
  label.type = "heading";
2993
3061
  label.level = 2;
@@ -2996,7 +3064,7 @@ function detectDocumentStyleHeadings(blocks) {
2996
3064
  const first = page.find((b) => b.type !== "image" && b.type !== "separator");
2997
3065
  const second = page[page.indexOf(first) + 1];
2998
3066
  const third = page[page.indexOf(first) + 2];
2999
- if (!first || !second || !third || first.type !== "list" && first.type !== "paragraph" || second.type !== "paragraph" || !first.text || !second.text || !first.bbox || !second.bbox || !_optionalChain([first, 'access', _104 => _104.style, 'optionalAccess', _105 => _105.fontName]) || !_optionalChain([second, 'access', _106 => _106.style, 'optionalAccess', _107 => _107.fontName]) || !/^\d+(?:\.\d+)*\.\s+/.test(first.text.trim()) || first.style.fontName === bodyFace || second.style.fontName === bodyFace || first.text.length + second.text.length > 140 || Math.abs(first.bbox.x - second.bbox.x) > 30 || first.bbox.y - (second.bbox.y + second.bbox.height) > (_nullishCoalesce(first.style.fontSize, () => ( 0))) * 1.5 || _optionalChain([third, 'access', _108 => _108.style, 'optionalAccess', _109 => _109.fontName]) !== bodyFace) continue;
3067
+ if (!first || !second || !third || first.type !== "list" && first.type !== "paragraph" || second.type !== "paragraph" || !first.text || !second.text || !first.bbox || !second.bbox || !_optionalChain([first, 'access', _119 => _119.style, 'optionalAccess', _120 => _120.fontName]) || !_optionalChain([second, 'access', _121 => _121.style, 'optionalAccess', _122 => _122.fontName]) || !/^\d+(?:\.\d+)*\.\s+/.test(first.text.trim()) || first.style.fontName === bodyFace || second.style.fontName === bodyFace || first.text.length + second.text.length > 140 || Math.abs(first.bbox.x - second.bbox.x) > 30 || first.bbox.y - (second.bbox.y + second.bbox.height) > (_nullishCoalesce(first.style.fontSize, () => ( 0))) * 1.5 || _optionalChain([third, 'access', _123 => _123.style, 'optionalAccess', _124 => _124.fontName]) !== bodyFace) continue;
3000
3068
  first.type = "heading";
3001
3069
  first.level = 1;
3002
3070
  first.text = `${first.text.trim()} ${second.text.trim()}`;
@@ -3020,18 +3088,18 @@ function detectSiblingStyleHeadings(blocks) {
3020
3088
  for (const page of byPage.values()) {
3021
3089
  const bodyChars = /* @__PURE__ */ new Map();
3022
3090
  for (const block of page) {
3023
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _110 => _110.style, 'optionalAccess', _111 => _111.fontName])) continue;
3091
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _125 => _125.style, 'optionalAccess', _126 => _126.fontName])) continue;
3024
3092
  const face = block.style.fontName;
3025
3093
  bodyChars.set(face, (_nullishCoalesce(bodyChars.get(face), () => ( 0))) + block.text.length);
3026
3094
  }
3027
- const bodyFace = _optionalChain([[...bodyChars], 'access', _112 => _112.sort, 'call', _113 => _113((a, b) => b[1] - a[1]), 'access', _114 => _114[0], 'optionalAccess', _115 => _115[0]]);
3028
- const anchors = page.filter((b) => b.type === "heading" && b.text && _optionalChain([b, 'access', _116 => _116.style, 'optionalAccess', _117 => _117.fontName]) && b.style.fontName !== bodyFace);
3095
+ const bodyFace = _optionalChain([[...bodyChars], 'access', _127 => _127.sort, 'call', _128 => _128((a, b) => b[1] - a[1]), 'access', _129 => _129[0], 'optionalAccess', _130 => _130[0]]);
3096
+ const anchors = page.filter((b) => b.type === "heading" && b.text && _optionalChain([b, 'access', _131 => _131.style, 'optionalAccess', _132 => _132.fontName]) && b.style.fontName !== bodyFace);
3029
3097
  for (const anchor of anchors) {
3030
3098
  const numbered = /^([A-Z])\.\d+\s+/.exec(anchor.text.trim());
3031
3099
  const lettered = /^([A-Z])\s+/.exec(anchor.text.trim());
3032
- const peers = anchors.filter((b) => _optionalChain([b, 'access', _118 => _118.style, 'optionalAccess', _119 => _119.fontName]) === _optionalChain([anchor, 'access', _120 => _120.style, 'optionalAccess', _121 => _121.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _122 => _122.style, 'optionalAccess', _123 => _123.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _124 => _124.style, 'optionalAccess', _125 => _125.fontSize]), () => ( 0)))) < 0.5);
3100
+ const peers = anchors.filter((b) => _optionalChain([b, 'access', _133 => _133.style, 'optionalAccess', _134 => _134.fontName]) === _optionalChain([anchor, 'access', _135 => _135.style, 'optionalAccess', _136 => _136.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _137 => _137.style, 'optionalAccess', _138 => _138.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _139 => _139.style, 'optionalAccess', _140 => _140.fontSize]), () => ( 0)))) < 0.5);
3033
3101
  if (peers.length < 2 && !numbered && !lettered) continue;
3034
- const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _126 => _126.style, 'optionalAccess', _127 => _127.fontName]) === _optionalChain([anchor, 'access', _128 => _128.style, 'optionalAccess', _129 => _129.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _130 => _130.style, 'optionalAccess', _131 => _131.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _132 => _132.style, 'optionalAccess', _133 => _133.fontSize]), () => ( 0)))) < 0.5 && b.text.trim().length >= 3 && b.text.trim().length <= 80 && b.bbox.height <= (_nullishCoalesce(_optionalChain([b, 'access', _134 => _134.style, 'optionalAccess', _135 => _135.fontSize]), () => ( 0))) * 1.6 && /^[A-Z]/.test(b.text.trim()) && !/[.!?:;,]$/.test(b.text.trim()) && !/^(?:Table|Figure|Fig\.?|Appendix)\s+\d/i.test(b.text.trim()));
3102
+ const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _141 => _141.style, 'optionalAccess', _142 => _142.fontName]) === _optionalChain([anchor, 'access', _143 => _143.style, 'optionalAccess', _144 => _144.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _145 => _145.style, 'optionalAccess', _146 => _146.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _147 => _147.style, 'optionalAccess', _148 => _148.fontSize]), () => ( 0)))) < 0.5 && b.text.trim().length >= 3 && b.text.trim().length <= 80 && b.bbox.height <= (_nullishCoalesce(_optionalChain([b, 'access', _149 => _149.style, 'optionalAccess', _150 => _150.fontSize]), () => ( 0))) * 1.6 && /^[A-Z]/.test(b.text.trim()) && !/[.!?:;,]$/.test(b.text.trim()) && !/^(?:Table|Figure|Fig\.?|Appendix)\s+\d/i.test(b.text.trim()));
3035
3103
  const siblings = candidates.filter((b) => numbered ? new RegExp(`^${numbered[1]}\\.\\d+\\s+`).test(b.text.trim()) : lettered ? /^[A-Z]\s+/.test(b.text.trim()) && Math.abs(anchor.bbox.x - b.bbox.x) < 8 : peers.some((h) => h.bbox && Math.abs(h.bbox.x - b.bbox.x) < 8));
3036
3104
  if (siblings.length < (numbered || lettered ? 1 : 2)) continue;
3037
3105
  for (const sibling of siblings) {
@@ -3050,11 +3118,11 @@ function detectRepeatedPageLabels(blocks) {
3050
3118
  }
3051
3119
  for (const page of byPage.values()) {
3052
3120
  const bodyChars = /* @__PURE__ */ new Map();
3053
- for (const b of page) if (b.type === "paragraph" && b.text && _optionalChain([b, 'access', _136 => _136.style, 'optionalAccess', _137 => _137.fontName])) {
3121
+ for (const b of page) if (b.type === "paragraph" && b.text && _optionalChain([b, 'access', _151 => _151.style, 'optionalAccess', _152 => _152.fontName])) {
3054
3122
  bodyChars.set(b.style.fontName, (_nullishCoalesce(bodyChars.get(b.style.fontName), () => ( 0))) + b.text.length);
3055
3123
  }
3056
- const bodyFace = _optionalChain([[...bodyChars], 'access', _138 => _138.sort, 'call', _139 => _139((a, b) => b[1] - a[1]), 'access', _140 => _140[0], 'optionalAccess', _141 => _141[0]]);
3057
- const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _142 => _142.style, 'optionalAccess', _143 => _143.fontName]) && b.style.fontName !== bodyFace && b.bbox.height <= (_nullishCoalesce(b.style.fontSize, () => ( 0))) * 1.6 && b.text.trim().length >= 5 && b.text.trim().length <= 80);
3124
+ const bodyFace = _optionalChain([[...bodyChars], 'access', _153 => _153.sort, 'call', _154 => _154((a, b) => b[1] - a[1]), 'access', _155 => _155[0], 'optionalAccess', _156 => _156[0]]);
3125
+ const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _157 => _157.style, 'optionalAccess', _158 => _158.fontName]) && b.style.fontName !== bodyFace && b.bbox.height <= (_nullishCoalesce(b.style.fontSize, () => ( 0))) * 1.6 && b.text.trim().length >= 5 && b.text.trim().length <= 80);
3058
3126
  const groups = /* @__PURE__ */ new Map();
3059
3127
  for (const b of candidates) {
3060
3128
  const key = `${b.style.fontName}:${b.style.fontSize}`;
@@ -3088,21 +3156,21 @@ function detectPageLeadHeadings(blocks) {
3088
3156
  byPage.set(_nullishCoalesce(b.pageNumber, () => ( 0)), page);
3089
3157
  }
3090
3158
  for (const page of byPage.values()) {
3091
- const content = page.filter((b) => b.type !== "image" && b.type !== "separator");
3159
+ const content = page.filter((b) => b.type !== "image" && b.type !== "separator" && !(b.type === "paragraph" && !b.style));
3092
3160
  const [first, second, third] = content;
3093
- if (!_optionalChain([first, 'optionalAccess', _144 => _144.bbox]) || !first.text || !_optionalChain([first, 'access', _145 => _145.style, 'optionalAccess', _146 => _146.fontSize]) || !second) continue;
3161
+ if (!_optionalChain([first, 'optionalAccess', _159 => _159.bbox]) || !first.text || !_optionalChain([first, 'access', _160 => _160.style, 'optionalAccess', _161 => _161.fontSize]) || !second) continue;
3094
3162
  const firstText = first.text.trim();
3095
3163
  const captionLike = /^(?:Figure|Fig\.?|Table|표|그림)\s*\d/i;
3096
3164
  const hasImage = page.some((b) => b.type === "image");
3097
- const firstIsTitle = first.type === "paragraph" && firstText.length >= 5 && firstText.length <= 80 && first.bbox.height <= first.style.fontSize * 1.6 && (/^(?:CONTENTS|Table of Contents)$/i.test(firstText) || hasImage && /^[A-Z]/.test(firstText) && !captionLike.test(firstText) && second.type === "paragraph" && /^[A-Z]/.test(_nullishCoalesce(_optionalChain([second, 'access', _147 => _147.text, 'optionalAccess', _148 => _148.trim, 'call', _149 => _149()]), () => ( ""))) && (_nullishCoalesce(_optionalChain([second, 'access', _150 => _150.text, 'optionalAccess', _151 => _151.length]), () => ( 0))) >= 100 && second.bbox && first.bbox.y - (second.bbox.y + second.bbox.height) >= first.style.fontSize);
3165
+ const firstIsTitle = first.type === "paragraph" && firstText.length >= 5 && firstText.length <= 80 && first.bbox.height <= first.style.fontSize * 1.6 && (/^(?:CONTENTS|Table of Contents)$/i.test(firstText) || hasImage && /^[A-Z]/.test(firstText) && !captionLike.test(firstText) && second.type === "paragraph" && /^[A-Z]/.test(_nullishCoalesce(_optionalChain([second, 'access', _162 => _162.text, 'optionalAccess', _163 => _163.trim, 'call', _164 => _164()]), () => ( ""))) && (_nullishCoalesce(_optionalChain([second, 'access', _165 => _165.text, 'optionalAccess', _166 => _166.length]), () => ( 0))) >= 100 && second.bbox && first.bbox.y - (second.bbox.y + second.bbox.height) >= first.style.fontSize);
3098
3166
  const firstAboveProse = first.type === "paragraph" && firstText.length >= 5 && firstText.length <= 80 && first.bbox.height <= first.style.fontSize * 2 && second.type === "paragraph" && second.bbox && second.bbox.height >= first.style.fontSize * 4 && Math.abs(first.bbox.x - second.bbox.x) <= first.style.fontSize * 2 && first.bbox.y - (second.bbox.y + second.bbox.height) >= first.style.fontSize * 2 && !captionLike.test(firstText) && !/^(?:doi:|https?:|www\.)/i.test(firstText);
3099
- const firstIsSection = first.type === "list" && /^\d+\.\s+[A-Z][A-Z\s]{12,}$/.test(firstText) && second.type === "paragraph" && (_nullishCoalesce(_optionalChain([second, 'access', _152 => _152.text, 'optionalAccess', _153 => _153.length]), () => ( 0))) >= 100;
3167
+ const firstIsSection = first.type === "list" && /^\d+\.\s+[A-Z][A-Z\s]{12,}$/.test(firstText) && second.type === "paragraph" && (_nullishCoalesce(_optionalChain([second, 'access', _167 => _167.text, 'optionalAccess', _168 => _168.length]), () => ( 0))) >= 100;
3100
3168
  if (firstIsTitle || firstAboveProse || firstIsSection) {
3101
3169
  first.type = "heading";
3102
3170
  first.level = 1;
3103
3171
  }
3104
- if (first.type !== "heading" || captionLike.test(firstText) || second.type !== "paragraph" || !second.text || !second.bbox || !_optionalChain([second, 'access', _154 => _154.style, 'optionalAccess', _155 => _155.fontName]) || !second.style.fontSize || !_optionalChain([third, 'optionalAccess', _156 => _156.text]) || !third.bbox || second.text.trim().length < 5 || second.text.trim().length > 80 || captionLike.test(second.text.trim()) || /^(?:doi:|https?:)/i.test(second.text.trim()) || second.bbox.height > second.style.fontSize * 1.6 || Math.abs(second.bbox.x - third.bbox.x) > 30) continue;
3105
- const distinctFace = _optionalChain([third, 'access', _157 => _157.style, 'optionalAccess', _158 => _158.fontName]) !== second.style.fontName;
3172
+ if (first.type !== "heading" || captionLike.test(firstText) || second.type !== "paragraph" || !second.text || !second.bbox || !_optionalChain([second, 'access', _169 => _169.style, 'optionalAccess', _170 => _170.fontName]) || !second.style.fontSize || !_optionalChain([third, 'optionalAccess', _171 => _171.text]) || !third.bbox || second.text.trim().length < 5 || second.text.trim().length > 80 || captionLike.test(second.text.trim()) || /^(?:doi:|https?:)/i.test(second.text.trim()) || second.bbox.height > second.style.fontSize * 1.6 || Math.abs(second.bbox.x - third.bbox.x) > 30) continue;
3173
+ const distinctFace = _optionalChain([third, 'access', _172 => _172.style, 'optionalAccess', _173 => _173.fontName]) !== second.style.fontName;
3106
3174
  const namedContents = /^Table of Contents$/i.test(second.text.trim());
3107
3175
  if (distinctFace && third.text.length >= 60 || namedContents) {
3108
3176
  second.type = "heading";
@@ -3113,24 +3181,24 @@ function detectPageLeadHeadings(blocks) {
3113
3181
  function refineDocumentStyleHeadings(blocks) {
3114
3182
  const faceChars = /* @__PURE__ */ new Map();
3115
3183
  for (const block of blocks) {
3116
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _159 => _159.style, 'optionalAccess', _160 => _160.fontName])) continue;
3184
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _174 => _174.style, 'optionalAccess', _175 => _175.fontName])) continue;
3117
3185
  faceChars.set(block.style.fontName, (_nullishCoalesce(faceChars.get(block.style.fontName), () => ( 0))) + block.text.length);
3118
3186
  }
3119
3187
  const [bodyFace, bodyChars] = _nullishCoalesce([...faceChars].sort((a, b) => b[1] - a[1])[0], () => ( []));
3120
3188
  if (!bodyFace || !bodyChars || bodyChars < 300) return;
3121
3189
  for (let i = 0; i < blocks.length; i++) {
3122
3190
  const block = blocks[i];
3123
- const text = _nullishCoalesce(_optionalChain([block, 'access', _161 => _161.text, 'optionalAccess', _162 => _162.trim, 'call', _163 => _163()]), () => ( ""));
3191
+ const text = _nullishCoalesce(_optionalChain([block, 'access', _176 => _176.text, 'optionalAccess', _177 => _177.trim, 'call', _178 => _178()]), () => ( ""));
3124
3192
  if (block.type === "heading" && /(?:https?:\/\/|www\.|^arxiv:|^doi:)/i.test(text)) {
3125
3193
  block.type = "paragraph";
3126
3194
  block.level = void 0;
3127
3195
  continue;
3128
3196
  }
3129
3197
  const box = block.bbox, style = block.style;
3130
- if (block.type !== "paragraph" || !box || !_optionalChain([style, 'optionalAccess', _164 => _164.fontName]) || !style.fontSize || style.fontName === bodyFace || (_nullishCoalesce(faceChars.get(style.fontName), () => ( 0))) > bodyChars * 0.25 || text.length < 3 || text.length > 70 || text.includes("\n") || box.height > style.fontSize * 1.6 || /^(?:table|figure|fig\.?|source|doi:|arxiv:|https?:|www\.|[•●○▪▫⮚*∗†])/i.test(text) || /(?:https?:\/\/|www\.|@|[=¼≪þ])/i.test(text) || /^definition\s+\d+[.:]?\s+.*\b(?:is|are|means)\b/i.test(text) || /^[\d\s.,:%+\-–]+$/.test(text)) continue;
3198
+ if (block.type !== "paragraph" || !box || !_optionalChain([style, 'optionalAccess', _179 => _179.fontName]) || !style.fontSize || style.fontName === bodyFace || (_nullishCoalesce(faceChars.get(style.fontName), () => ( 0))) > bodyChars * 0.25 || text.length < 3 || text.length > 70 || text.includes("\n") || box.height > style.fontSize * 1.6 || /^(?:table|figure|fig\.?|source|doi:|arxiv:|https?:|www\.|[•●○▪▫⮚*∗†])/i.test(text) || /(?:https?:\/\/|www\.|@|[=¼≪þ])/i.test(text) || /^definition\s+\d+[.:]?\s+.*\b(?:is|are|means)\b/i.test(text) || /^[\d\s.,:%+\-–]+$/.test(text)) continue;
3131
3199
  const previous = blocks[i - 1], next = blocks[i + 1];
3132
- const pb = _optionalChain([previous, 'optionalAccess', _165 => _165.bbox]), nb = _optionalChain([next, 'optionalAccess', _166 => _166.bbox]);
3133
- if (!pb || !nb || previous.pageNumber !== block.pageNumber || next.pageNumber !== block.pageNumber || previous.type !== "paragraph" && previous.type !== "heading" || next.type !== "paragraph" || _optionalChain([next, 'access', _167 => _167.style, 'optionalAccess', _168 => _168.fontName]) !== bodyFace || !next.text || next.text.length < 40 || style.fontSize < (_nullishCoalesce(next.style.fontSize, () => ( 0))) * 0.95 || pb.y - (box.y + box.height) < style.fontSize * 0.5 || box.y - (nb.y + nb.height) < 0 || box.y - (nb.y + nb.height) > style.fontSize * 2 || box.x + box.width / 2 < nb.x - 10 || box.x + box.width / 2 > nb.x + nb.width + 10) continue;
3200
+ const pb = _optionalChain([previous, 'optionalAccess', _180 => _180.bbox]), nb = _optionalChain([next, 'optionalAccess', _181 => _181.bbox]);
3201
+ if (!pb || !nb || previous.pageNumber !== block.pageNumber || next.pageNumber !== block.pageNumber || previous.type !== "paragraph" && previous.type !== "heading" || next.type !== "paragraph" || _optionalChain([next, 'access', _182 => _182.style, 'optionalAccess', _183 => _183.fontName]) !== bodyFace || !next.text || next.text.length < 40 || style.fontSize < (_nullishCoalesce(next.style.fontSize, () => ( 0))) * 0.95 || pb.y - (box.y + box.height) < style.fontSize * 0.5 || box.y - (nb.y + nb.height) < 0 || box.y - (nb.y + nb.height) > style.fontSize * 2 || box.x + box.width / 2 < nb.x - 10 || box.x + box.width / 2 > nb.x + nb.width + 10) continue;
3134
3202
  block.type = "heading";
3135
3203
  block.level = 2;
3136
3204
  }
@@ -3180,7 +3248,7 @@ function detectMarkerHeadings(blocks) {
3180
3248
  block.level = 4;
3181
3249
  continue;
3182
3250
  }
3183
- if (/^[가-힣]{2,6}$/.test(text) && _optionalChain([block, 'access', _169 => _169.style, 'optionalAccess', _170 => _170.fontSize])) {
3251
+ if (/^[가-힣]{2,6}$/.test(text) && _optionalChain([block, 'access', _184 => _184.style, 'optionalAccess', _185 => _185.fontSize])) {
3184
3252
  const prev = blocks[i - 1];
3185
3253
  const next = blocks[i + 1];
3186
3254
  const prevIsStructural = !prev || prev.type === "table" || prev.type === "heading" || prev.type === "separator";
@@ -3221,7 +3289,7 @@ function detectTableCaptions(blocks) {
3221
3289
  block.table.caption = blocks[i - 1].text.trim();
3222
3290
  blocks.splice(i - 1, 1);
3223
3291
  i--;
3224
- } else if (isCaptionCandidate(blocks[i + 1], block) && _optionalChain([blocks, 'access', _171 => _171[i + 2], 'optionalAccess', _172 => _172.type]) !== "table") {
3292
+ } else if (isCaptionCandidate(blocks[i + 1], block) && _optionalChain([blocks, 'access', _186 => _186[i + 2], 'optionalAccess', _187 => _187.type]) !== "table") {
3225
3293
  block.table.caption = blocks[i + 1].text.trim();
3226
3294
  blocks.splice(i + 1, 1);
3227
3295
  }
@@ -3435,7 +3503,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
3435
3503
  const bottomEntries = [];
3436
3504
  for (let bi = 0; bi < blocks.length; bi++) {
3437
3505
  const b = blocks[bi];
3438
- if (!b.bbox || !b.pageNumber || !_optionalChain([b, 'access', _173 => _173.text, 'optionalAccess', _174 => _174.trim, 'call', _175 => _175()])) continue;
3506
+ if (!b.bbox || !b.pageNumber || !_optionalChain([b, 'access', _188 => _188.text, 'optionalAccess', _189 => _189.trim, 'call', _190 => _190()])) continue;
3439
3507
  const ph = pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber);
3440
3508
  if (!ph) continue;
3441
3509
  const blockTop = ph - (b.bbox.y + b.bbox.height);
@@ -3458,7 +3526,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
3458
3526
  }
3459
3527
  const repeatedPatterns = /* @__PURE__ */ new Set();
3460
3528
  for (const [p, count] of patternCount) {
3461
- if (count >= MIN_REPEAT && (_nullishCoalesce(_optionalChain([patternPages, 'access', _176 => _176.get, 'call', _177 => _177(p), 'optionalAccess', _178 => _178.size]), () => ( 0))) >= MIN_REPEAT) {
3529
+ if (count >= MIN_REPEAT && (_nullishCoalesce(_optionalChain([patternPages, 'access', _191 => _191.get, 'call', _192 => _192(p), 'optionalAccess', _193 => _193.size]), () => ( 0))) >= MIN_REPEAT) {
3462
3530
  repeatedPatterns.add(p);
3463
3531
  }
3464
3532
  }
@@ -3478,7 +3546,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
3478
3546
  if (bi === e.blockIdx) continue;
3479
3547
  const o = blocks[bi];
3480
3548
  if (!o.bbox || o.bbox.page !== cb.page) continue;
3481
- const oNorm = _optionalChain([o, 'access', _179 => _179.text, 'optionalAccess', _180 => _180.trim, 'call', _181 => _181(), 'access', _182 => _182.replace, 'call', _183 => _183(/\d+/g, "#")]);
3549
+ const oNorm = _optionalChain([o, 'access', _194 => _194.text, 'optionalAccess', _195 => _195.trim, 'call', _196 => _196(), 'access', _197 => _197.replace, 'call', _198 => _198(/\d+/g, "#")]);
3482
3550
  if (oNorm && repeatedPatterns.has(oNorm)) continue;
3483
3551
  const overlap2 = Math.min(cb.y + cb.height, o.bbox.y + o.bbox.height) - Math.max(cb.y, o.bbox.y);
3484
3552
  if (overlap2 >= cb.height * 0.5) {
@@ -3521,7 +3589,7 @@ function recordCellLines(cell, items) {
3521
3589
  function markImageCell(cell) {
3522
3590
  IMAGE_CELLS.add(cell);
3523
3591
  }
3524
- var emptyCell = (cell) => !cell || !_optionalChain([cell, 'access', _184 => _184.text, 'optionalAccess', _185 => _185.trim, 'call', _186 => _186()]) && !_optionalChain([cell, 'access', _187 => _187.blocks, 'optionalAccess', _188 => _188.length]) && !IMAGE_CELLS.has(cell);
3592
+ var emptyCell = (cell) => !cell || !_optionalChain([cell, 'access', _199 => _199.text, 'optionalAccess', _200 => _200.trim, 'call', _201 => _201()]) && !_optionalChain([cell, 'access', _202 => _202.blocks, 'optionalAccess', _203 => _203.length]) && !IMAGE_CELLS.has(cell);
3525
3593
  function trimTable(table) {
3526
3594
  let cols = table.cols;
3527
3595
  while (cols > 0 && table.cells.every((row) => emptyCell(row[cols - 1]))) cols--;
@@ -3537,7 +3605,7 @@ function trimTable(table) {
3537
3605
  function trimTrailingEmptyTableCols(blocks) {
3538
3606
  for (const b of blocks) {
3539
3607
  if (b.type !== "table" || !b.table) continue;
3540
- for (const row of b.table.cells) for (const cell of row) if (_optionalChain([cell, 'access', _189 => _189.blocks, 'optionalAccess', _190 => _190.length])) trimTrailingEmptyTableCols(cell.blocks);
3608
+ for (const row of b.table.cells) for (const cell of row) if (_optionalChain([cell, 'access', _204 => _204.blocks, 'optionalAccess', _205 => _205.length])) trimTrailingEmptyTableCols(cell.blocks);
3541
3609
  trimTable(b.table);
3542
3610
  }
3543
3611
  }
@@ -3557,7 +3625,7 @@ function mergeSliverColumns(grid, colXs, maxWidth) {
3557
3625
  }
3558
3626
  const ok = owner.every((row) => {
3559
3627
  const o = row[c];
3560
- return !!o && (o.colSpan > 1 || !o.text.trim() && !_optionalChain([o, 'access', _191 => _191.blocks, 'optionalAccess', _192 => _192.length]));
3628
+ return !!o && (o.colSpan > 1 || !o.text.trim() && !_optionalChain([o, 'access', _206 => _206.blocks, 'optionalAccess', _207 => _207.length]));
3561
3629
  });
3562
3630
  if (!ok) continue;
3563
3631
  const spanning = /* @__PURE__ */ new Set();
@@ -3623,7 +3691,7 @@ function isProseTable(table) {
3623
3691
  if (!(long > 0 && long >= total * 0.5 && longRows >= rows * 0.4)) return false;
3624
3692
  for (let c = 0; c < table.cols; c++) {
3625
3693
  const filled = table.cells.map((row) => row[c]).filter((cell) => cell && cell.colSpan < table.cols && cell.text.trim()).map((cell) => cell.text.trim());
3626
- if (filled.length >= 3 && filled.length >= rows * 0.6 && filled.every((text) => text.length <= 30 && (_nullishCoalesce(_optionalChain([text, 'access', _193 => _193.match, 'call', _194 => _194(/\p{L}/gu), 'optionalAccess', _195 => _195.length]), () => ( 0))) >= 2)) return false;
3694
+ if (filled.length >= 3 && filled.length >= rows * 0.6 && filled.every((text) => text.length <= 30 && (_nullishCoalesce(_optionalChain([text, 'access', _208 => _208.match, 'call', _209 => _209(/\p{L}/gu), 'optionalAccess', _210 => _210.length]), () => ( 0))) >= 2)) return false;
3627
3695
  }
3628
3696
  return true;
3629
3697
  }
@@ -3650,7 +3718,7 @@ function isChartTable(table) {
3650
3718
  const numeric = texts.filter((text) => NUMERIC_CELL.test(text)).length;
3651
3719
  if (numeric < texts.length * 0.5) return false;
3652
3720
  for (let c = 0; c < table.cols; c++) {
3653
- const ticks = table.cells.flatMap((row) => (_nullishCoalesce(_optionalChain([row, 'access', _196 => _196[c], 'optionalAccess', _197 => _197.text]), () => ( ""))).split(/\s+/)).filter((token) => /^-?[\d,]+(?:\.\d+)?%?$/.test(token)).map((token) => Number(token.replace(/[,%]/g, "")));
3721
+ const ticks = table.cells.flatMap((row) => (_nullishCoalesce(_optionalChain([row, 'access', _211 => _211[c], 'optionalAccess', _212 => _212.text]), () => ( ""))).split(/\s+/)).filter((token) => /^-?[\d,]+(?:\.\d+)?%?$/.test(token)).map((token) => Number(token.replace(/[,%]/g, "")));
3654
3722
  if (hasValueAxis(ticks)) return true;
3655
3723
  }
3656
3724
  const values = texts.filter((text) => text.split(/\s+/).every((token) => /^[-−–]?[\d,]*\.?\d+%?$/.test(token))).length;
@@ -3798,7 +3866,7 @@ function detectAlignedTwoColumnTables(rows, pageNum) {
3798
3866
  continue;
3799
3867
  }
3800
3868
  const top = rows[i - 1];
3801
- const title = _optionalChain([top, 'optionalAccess', _198 => _198.items, 'access', _199 => _199.length]) === 1 && Math.abs(top.items[0].x - first[0].x) <= 5 && top.items[0].text.length <= 65 && top.y - first[0].y <= Math.max(24, first[0].fontSize * 2.8) ? top : void 0;
3869
+ const title = _optionalChain([top, 'optionalAccess', _213 => _213.items, 'access', _214 => _214.length]) === 1 && Math.abs(top.items[0].x - first[0].x) <= 5 && top.items[0].text.length <= 65 && top.y - first[0].y <= Math.max(24, first[0].fontSize * 2.8) ? top : void 0;
3802
3870
  const tableRows = title ? [title, ...body] : body;
3803
3871
  const cells = tableRows.map((row, idx) => {
3804
3872
  if (title && idx === 0) return [{ text: row.items[0].text, colSpan: 2, rowSpan: 1 }, { text: "", colSpan: 1, rowSpan: 1 }];
@@ -3854,12 +3922,12 @@ function isTwoColumnProse(r) {
3854
3922
  if (t.rows < 8) return false;
3855
3923
  const dense = [];
3856
3924
  for (let c = 0; c < t.cols; c++) {
3857
- const filled = t.cells.filter((row) => _optionalChain([row, 'access', _200 => _200[c], 'optionalAccess', _201 => _201.text, 'access', _202 => _202.trim, 'call', _203 => _203()])).length;
3925
+ const filled = t.cells.filter((row) => _optionalChain([row, 'access', _215 => _215[c], 'optionalAccess', _216 => _216.text, 'access', _217 => _217.trim, 'call', _218 => _218()])).length;
3858
3926
  if (filled / t.rows >= 0.3) dense.push(c);
3859
3927
  }
3860
3928
  if (dense.length !== 2) return false;
3861
3929
  for (const c of dense) {
3862
- const lens = t.cells.map((row) => _nullishCoalesce(_optionalChain([row, 'access', _204 => _204[c], 'optionalAccess', _205 => _205.text, 'access', _206 => _206.replace, 'call', _207 => _207(/\s+/g, ""), 'access', _208 => _208.length]), () => ( 0))).filter((n) => n > 0);
3930
+ const lens = t.cells.map((row) => _nullishCoalesce(_optionalChain([row, 'access', _219 => _219[c], 'optionalAccess', _220 => _220.text, 'access', _221 => _221.replace, 'call', _222 => _222(/\s+/g, ""), 'access', _223 => _223.length]), () => ( 0))).filter((n) => n > 0);
3863
3931
  const avg = lens.reduce((s, v) => s + v, 0) / (lens.length || 1);
3864
3932
  if (avg < 12) return false;
3865
3933
  }
@@ -4255,7 +4323,7 @@ function assignRowItems(items, columns, numCols, headerFace) {
4255
4323
  const runs = [];
4256
4324
  for (const it of sorted) {
4257
4325
  const last = runs[runs.length - 1];
4258
- const prev = _optionalChain([last, 'optionalAccess', _209 => _209[last.length - 1]]);
4326
+ const prev = _optionalChain([last, 'optionalAccess', _224 => _224[last.length - 1]]);
4259
4327
  if (prev && it.x - (prev.x + prev.w) <= Math.max(0.5, it.fontSize * 0.05) && !it.hasSpaceBefore) last.push(it);
4260
4328
  else runs.push([it]);
4261
4329
  }
@@ -4329,7 +4397,7 @@ function buildClusterTable(rows, columns, pageNum) {
4329
4397
  () => Array.from({ length: numCols }, () => ({ text: "", colSpan: 1, rowSpan: 1 }))
4330
4398
  );
4331
4399
  const usedItems = /* @__PURE__ */ new Set();
4332
- const headFaces = new Set(_optionalChain([rows, 'access', _210 => _210[0], 'optionalAccess', _211 => _211.items, 'access', _212 => _212.map, 'call', _213 => _213((i) => i.fontName)]));
4400
+ const headFaces = new Set(_optionalChain([rows, 'access', _225 => _225[0], 'optionalAccess', _226 => _226.items, 'access', _227 => _227.map, 'call', _228 => _228((i) => i.fontName)]));
4333
4401
  const headerFace = headFaces.size === 1 && rows.slice(1).every((row) => row.items.every((i) => !headFaces.has(i.fontName))) ? [...headFaces][0] : void 0;
4334
4402
  for (let r = 0; r < numRows; r++) {
4335
4403
  const row = rows[r];
@@ -4359,7 +4427,7 @@ function buildClusterTable(rows, columns, pageNum) {
4359
4427
  const nonEmptyCols = cells[r].filter((c) => c.text.trim()).length;
4360
4428
  if (nonEmptyCols !== 1) continue;
4361
4429
  if (cells[r][0].text.trim() !== "") continue;
4362
- const contentText = _optionalChain([cells, 'access', _214 => _214[r], 'access', _215 => _215.find, 'call', _216 => _216((c) => c.text.trim()), 'optionalAccess', _217 => _217.text, 'access', _218 => _218.trim, 'call', _219 => _219()]) || "";
4430
+ const contentText = _optionalChain([cells, 'access', _229 => _229[r], 'access', _230 => _230.find, 'call', _231 => _231((c) => c.text.trim()), 'optionalAccess', _232 => _232.text, 'access', _233 => _233.trim, 'call', _234 => _234()]) || "";
4363
4431
  if (/^[○●▶\-·]/.test(contentText)) continue;
4364
4432
  for (let pr = r - 1; pr >= 0; pr--) {
4365
4433
  if (cells[pr].some((c) => c.text.trim())) {
@@ -4485,9 +4553,9 @@ function xyCutOrder(items, gapThreshold, depth = 0) {
4485
4553
  const hCut = findHorizontalCut(items);
4486
4554
  const vCut = findVerticalCutWithOutlierFilter(items, minGap);
4487
4555
  const hValid = hCut.gap >= minGap;
4488
- const vValid = vCut.gap >= minGap || vCut.gap >= PROSE_GUTTER_MIN_GAP && isProseGutter(items, vCut.position);
4556
+ const vValid = (vCut.gap >= minGap || vCut.gap >= PROSE_GUTTER_MIN_GAP && isProseGutter(items, vCut.position)) && !splitsSpacedLabel(items, vCut.position);
4489
4557
  let useHorizontal;
4490
- if (hValid && vValid) useHorizontal = vCut.gap <= hCut.gap * 1.5;
4558
+ if (hValid && vValid) useHorizontal = vCut.gap <= hCut.gap * 1.5 || staggeredSides(items, vCut.position);
4491
4559
  else if (hValid) useHorizontal = true;
4492
4560
  else if (vValid) useHorizontal = false;
4493
4561
  else return _nullishCoalesce(splitEdgeSpannedColumns(items, gapThreshold, depth), () => ( [items]));
@@ -4506,6 +4574,33 @@ function xyCutOrder(items, gapThreshold, depth = 0) {
4506
4574
  }
4507
4575
  return [items];
4508
4576
  }
4577
+ function splitsSpacedLabel(items, cutX) {
4578
+ const lone = (i) => /^[가-힣]$/.test(i.text.trim());
4579
+ const sameRow = (a, b) => Math.min(a.y, b.y) > Math.max(a.y - a.h, b.y - b.h);
4580
+ const left = items.filter((i) => i.x + i.w / 2 < cutX);
4581
+ const right = items.filter((i) => i.x + i.w / 2 >= cutX);
4582
+ let spaced = 0;
4583
+ for (const r of right) {
4584
+ if (right.some((o) => o !== r && o.x < r.x && sameRow(o, r))) continue;
4585
+ const row = left.filter((l2) => sameRow(l2, r));
4586
+ if (row.length === 0) continue;
4587
+ const l = row.reduce((a, b) => b.x + b.w > a.x + a.w ? b : a);
4588
+ if (!lone(l) || !lone(r)) return false;
4589
+ spaced++;
4590
+ }
4591
+ return spaced > 0;
4592
+ }
4593
+ function staggeredSides(items, cutX) {
4594
+ const left = items.filter((i) => i.x + i.w / 2 < cutX);
4595
+ const right = items.filter((i) => i.x + i.w / 2 >= cutX);
4596
+ if (left.length * right.length > 2e5) return false;
4597
+ const shareRow = (a, b) => Math.min(a.y, b.y) > Math.max(a.y - a.h, b.y - b.h);
4598
+ if (left.some((a) => right.some((b) => shareRow(a, b)))) return false;
4599
+ const sides = [...items].sort((a, b) => b.y - a.y).map((i) => i.x + i.w / 2 < cutX);
4600
+ let switches = 0;
4601
+ for (let k = 1; k < sides.length; k++) if (sides[k] !== sides[k - 1]) switches++;
4602
+ return switches >= 3;
4603
+ }
4509
4604
  function identifyCrossLayoutItems(items) {
4510
4605
  const cross = /* @__PURE__ */ new Set();
4511
4606
  if (items.length < 3) return cross;
@@ -4910,16 +5005,16 @@ function isProseSpread(items) {
4910
5005
  for (let i = 1; i < sorted.length; i++) {
4911
5006
  gaps.push(sorted[i].x - (sorted[i - 1].x + sorted[i - 1].w));
4912
5007
  }
4913
- const maxGap = _chunkFBZCWSPNcjs.safeMax.call(void 0, gaps);
5008
+ const maxGap = _chunkJ6ZU7AIRcjs.safeMax.call(void 0, gaps);
4914
5009
  const avgLen = items.reduce((s, i) => s + i.text.length, 0) / items.length;
4915
5010
  if (items.length >= 4 && maxGap < 40 && avgLen < 5) return true;
4916
- const minGap = _chunkFBZCWSPNcjs.safeMin.call(void 0, gaps);
5011
+ const minGap = _chunkJ6ZU7AIRcjs.safeMin.call(void 0, gaps);
4917
5012
  return minGap > 0 && maxGap - minGap <= Math.max(2, maxGap * 0.15) && items.filter((i) => /^\P{L}*\p{Ll}/u.test(i.text)).length * 2 >= items.length;
4918
5013
  }
4919
5014
  function detectColumns(yLines) {
4920
5015
  const allItems = yLines.flat();
4921
5016
  if (allItems.length === 0) return null;
4922
- const pageWidth = _chunkFBZCWSPNcjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunkFBZCWSPNcjs.safeMin.call(void 0, allItems.map((i) => i.x));
5017
+ const pageWidth = _chunkJ6ZU7AIRcjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunkJ6ZU7AIRcjs.safeMin.call(void 0, allItems.map((i) => i.x));
4923
5018
  if (pageWidth < 100) return null;
4924
5019
  let bigoLineIdx = -1;
4925
5020
  for (let i = 0; i < yLines.length; i++) {
@@ -5305,6 +5400,19 @@ function commonEnd(ends) {
5305
5400
  }
5306
5401
  return bestN >= MIN_REACHING ? best : null;
5307
5402
  }
5403
+ function splitBodies(g, chained) {
5404
+ if (g.length < MIN_RULES * 2) return [g];
5405
+ const x1 = Math.min(...g.map((r) => r.x1)), x2 = Math.max(...g.map((r) => r.x2));
5406
+ const sorted = [...g].sort((a, b) => b.y1 - a.y1);
5407
+ const parts = [[sorted[0]]];
5408
+ for (let i = 1; i < sorted.length; i++) {
5409
+ const upper = sorted[i - 1].y1, lower = sorted[i].y1;
5410
+ const joined = chained.some((v) => v.x1 >= x1 - ALIGN_TOL && v.x1 <= x2 + ALIGN_TOL && v.y2 >= upper - TOUCH_TOL && v.y1 <= lower + TOUCH_TOL);
5411
+ if (joined) parts[parts.length - 1].push(sorted[i]);
5412
+ else parts.push([sorted[i]]);
5413
+ }
5414
+ return parts.filter((p) => p.length >= MIN_RULES).length >= 2 ? parts : [g];
5415
+ }
5308
5416
  function closeOpenTableEnds(horizontals, verticals, textLayer = false) {
5309
5417
  if (horizontals.length < MIN_RULES || verticals.length < MIN_REACHING) return horizontals;
5310
5418
  const groups = [];
@@ -5315,7 +5423,7 @@ function closeOpenTableEnds(horizontals, verticals, textLayer = false) {
5315
5423
  }
5316
5424
  const chained = chainVerticals2(verticals);
5317
5425
  const added = [];
5318
- for (const g of groups) {
5426
+ for (const g of groups.flatMap((gr) => splitBodies(gr, chained))) {
5319
5427
  if (g.length < MIN_RULES) continue;
5320
5428
  const x1 = Math.min(...g.map((r) => r.x1)), x2 = Math.max(...g.map((r) => r.x2));
5321
5429
  const yLo = Math.min(...g.map((r) => r.y1)), yHi = Math.max(...g.map((r) => r.y1));
@@ -5763,7 +5871,7 @@ function stackedTableBands(items) {
5763
5871
  const caption = (start, end) => lines.slice(start, end).some((line) => /^Table\s+\d+\s*[:.]/i.test(mergeLineSimple(line).trim()));
5764
5872
  while (runs.length > 0 && !caption(runs[runs.length - 1].end, lines.length)) runs.pop();
5765
5873
  if (runs.length < 2) return null;
5766
- if (runs.some((run, i) => !caption(run.end, _nullishCoalesce(_optionalChain([runs, 'access', _220 => _220[i + 1], 'optionalAccess', _221 => _221.start]), () => ( lines.length))))) return null;
5874
+ if (runs.some((run, i) => !caption(run.end, _nullishCoalesce(_optionalChain([runs, 'access', _235 => _235[i + 1], 'optionalAccess', _236 => _236.start]), () => ( lines.length))))) return null;
5767
5875
  const tables = runs.map((run) => lines.slice(run.start, run.end).flat());
5768
5876
  const between = runs.slice(0, -1).map((run, i) => lines.slice(run.end, runs[i + 1].start).flat());
5769
5877
  const tail = lines.slice(runs[runs.length - 1].end);
@@ -5923,7 +6031,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
5923
6031
  for (const line of streamLines(items)) lex.addLine(mergeLineSimple(line));
5924
6032
  const extracted = extractLines(opList.fnArray, opList.argsArray);
5925
6033
  let { horizontals, verticals } = extracted;
5926
- const prevPage = _optionalChain([carry, 'optionalAccess', _222 => _222.page]) === pageNum - 1 ? carry.clip : void 0;
6034
+ const prevPage = _optionalChain([carry, 'optionalAccess', _237 => _237.page]) === pageNum - 1 ? carry.clip : void 0;
5927
6035
  const clipResult = detectTables ? buildClipCellGrids(extracted.clipRects, horizontals, verticals, pageWidth, pageHeight, items.map((it) => ({ x: it.x + it.w / 2, y: it.y + it.h / 2 })), extracted.fillRects, prevPage) : { grids: [], containers: [], page: void 0 };
5928
6036
  if (carry) {
5929
6037
  carry.page = pageNum;
@@ -5988,6 +6096,7 @@ function markStrikethroughItems(items, horizontals) {
5988
6096
  if (line.lineWidth > STRIKE_MAX_THICKNESS) continue;
5989
6097
  const matches = [];
5990
6098
  for (const item of items) {
6099
+ if (item.fontName === "ocr") continue;
5991
6100
  const h = item.h > 0 ? item.h : item.fontSize;
5992
6101
  if (h <= 0 || item.w <= 0) continue;
5993
6102
  if (line.lineWidth > h * STRIKE_MAX_THICKNESS_RATIO) continue;
@@ -6068,16 +6177,25 @@ function isProseBoxGrid(grid, verticals, table) {
6068
6177
  if (longCells < PROSEBOX_LONG_CELL_MIN || longCells < texts.length * PROSEBOX_LONG_CELL_RATIO) return false;
6069
6178
  return true;
6070
6179
  }
6180
+ function isSparseProseGrid(table) {
6181
+ if (table.rows < 4) return false;
6182
+ const texts = table.cells.flat().map((c) => c.text.trim());
6183
+ const filled = texts.filter(Boolean);
6184
+ if (filled.length === 0 || filled.length > texts.length * 0.25) return false;
6185
+ const chars = filled.reduce((n, t) => n + t.length, 0);
6186
+ const prose = filled.filter((t) => t.length >= 60 && /[.!?。]/.test(t)).reduce((n, t) => n + t.length, 0);
6187
+ return prose >= chars * 0.6;
6188
+ }
6071
6189
  function cleanCellText(text) {
6072
6190
  const stripped = text.replace(/^[\s]*[-–—]\s*\d+\s*[-–—][\s]*$/gm, "").trim();
6073
6191
  return stripped.split("\n").map((line) => collapseEvenSpacing(line)).join("\n");
6074
6192
  }
6075
6193
  var FRAME_RECT_TOL = 1.5;
6076
- function takePendingNested(pending, cellBox) {
6194
+ function takePendingNested(pending, cellBox, clipCell) {
6077
6195
  const out = [];
6078
6196
  for (let i = pending.length - 1; i >= 0; i--) {
6079
6197
  const p = pending[i].parent;
6080
- if (Math.abs(p.x1 - cellBox.x1) <= FRAME_RECT_TOL && Math.abs(p.x2 - cellBox.x2) <= FRAME_RECT_TOL && Math.abs(p.y1 - cellBox.y1) <= FRAME_RECT_TOL && Math.abs(p.y2 - cellBox.y2) <= FRAME_RECT_TOL) {
6198
+ if (pending[i].contained ? p.x1 >= cellBox.x1 - FRAME_RECT_TOL && p.x2 <= cellBox.x2 + FRAME_RECT_TOL && p.y1 >= cellBox.y1 - FRAME_RECT_TOL && p.y2 <= cellBox.y2 + FRAME_RECT_TOL : clipCell && Math.abs(p.x1 - cellBox.x1) <= FRAME_RECT_TOL && Math.abs(p.x2 - cellBox.x2) <= FRAME_RECT_TOL && Math.abs(p.y1 - cellBox.y1) <= FRAME_RECT_TOL && Math.abs(p.y2 - cellBox.y2) <= FRAME_RECT_TOL) {
6081
6199
  out.push(pending[i].block);
6082
6200
  pending.splice(i, 1);
6083
6201
  }
@@ -6106,6 +6224,7 @@ function buildFrameCellBlocks(cellItems, nested, pageNum, wrap) {
6106
6224
  return { blocks, text };
6107
6225
  }
6108
6226
  function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions = [], lex, ruled = []) {
6227
+ const ocrPage = items.length > 0 && items.every((i) => i.fontName === "ocr");
6109
6228
  const blocks = [];
6110
6229
  const usedItems = /* @__PURE__ */ new Set();
6111
6230
  for (const r of ruled) {
@@ -6115,13 +6234,14 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6115
6234
  const proseSidebars = /* @__PURE__ */ new Set();
6116
6235
  const pendingNested = [];
6117
6236
  const gridArea = (g) => (g.bbox.x2 - g.bbox.x1) * (g.bbox.y2 - g.bbox.y1);
6118
- const sortedGrids = [...grids].sort((a, b) => (b.cells ? 1 : 0) - (a.cells ? 1 : 0) || (a.cells && b.cells ? gridArea(a) - gridArea(b) : 0) || b.bbox.y2 - a.bbox.y2);
6237
+ const sortedGrids = [...grids].sort((a, b) => (b.cells ? 1 : 0) - (a.cells ? 1 : 0) || (a.cells && b.cells ? gridArea(a) - gridArea(b) : 0) || (b.lineNested ? 1 : 0) - (a.lineNested ? 1 : 0) || (a.lineNested && b.lineNested ? gridArea(a) - gridArea(b) : 0) || b.bbox.y2 - a.bbox.y2);
6119
6238
  for (const grid of sortedGrids) {
6120
6239
  const numGridRows = grid.rowYs.length - 1;
6121
6240
  const numGridCols = grid.colXs.length - 1;
6122
6241
  const gridW = grid.bbox.x2 - grid.bbox.x1;
6123
- if (!grid.cells && numGridRows === 1 && numGridCols >= 2) continue;
6124
- if (!grid.cells && numGridCols === 1 && numGridRows >= 2 && (numGridRows < 5 || gridW > pageWidth * 0.7)) continue;
6242
+ const holdsNested = !grid.cells && pendingNested.some((p) => p.contained && p.parent.x1 >= grid.bbox.x1 - FRAME_RECT_TOL && p.parent.x2 <= grid.bbox.x2 + FRAME_RECT_TOL && p.parent.y1 >= grid.bbox.y1 - FRAME_RECT_TOL && p.parent.y2 <= grid.bbox.y2 + FRAME_RECT_TOL);
6243
+ if (!grid.cells && !holdsNested && numGridRows === 1 && numGridCols >= 2) continue;
6244
+ if (!grid.cells && !holdsNested && numGridCols === 1 && numGridRows >= 2 && (numGridRows < 5 || gridW > pageWidth * 0.7)) continue;
6125
6245
  const tableItems = [];
6126
6246
  const pad = 3;
6127
6247
  for (const item of items) {
@@ -6157,7 +6277,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6157
6277
  let nestedAttached = false;
6158
6278
  for (const cell of cells) {
6159
6279
  const cellItems = cellTextMap.get(cell) || [];
6160
- const nested = grid.cells ? takePendingNested(pendingNested, cell.bbox) : [];
6280
+ const nested = pendingNested.length ? takePendingNested(pendingNested, cell.bbox, !!grid.cells) : [];
6161
6281
  if (nested.length > 0) {
6162
6282
  nestedAttached = true;
6163
6283
  const built = buildFrameCellBlocks(cellItems, nested, pageNum, { box: cell.bbox, lex });
@@ -6210,14 +6330,14 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6210
6330
  if (!assignedItems.has(textItems[ti])) usedItems.delete(tableItems[ti]);
6211
6331
  }
6212
6332
  }
6213
- if (unitLine.length > 0 && rebuiltUsed && !/^\s*\(\s*단위\s*[::]/.test(_nullishCoalesce(_optionalChain([finalGrid, 'access', _223 => _223[0], 'optionalAccess', _224 => _224[0], 'optionalAccess', _225 => _225.text]), () => ( "")))) {
6333
+ if (unitLine.length > 0 && rebuiltUsed && !/^\s*\(\s*단위\s*[::]/.test(_nullishCoalesce(_optionalChain([finalGrid, 'access', _238 => _238[0], 'optionalAccess', _239 => _239[0], 'optionalAccess', _240 => _240.text]), () => ( "")))) {
6214
6334
  finalGrid.unshift(Array.from({ length: numCols }, (_, c) => ({ text: c === 0 ? cleanCellText(unitText) : "", colSpan: c === 0 ? numCols : 1, rowSpan: 1 })));
6215
6335
  finalRows++;
6216
6336
  for (const item of unitLine) usedItems.add(item);
6217
6337
  }
6218
6338
  let semanticOneColumn = false;
6219
6339
  if (!grid.cells && numCols === 1 && numGridRows >= 2) {
6220
- const populatedRows = finalGrid.filter((row) => _optionalChain([row, 'access', _226 => _226[0], 'optionalAccess', _227 => _227.text, 'access', _228 => _228.trim, 'call', _229 => _229()]));
6340
+ const populatedRows = finalGrid.filter((row) => _optionalChain([row, 'access', _241 => _241[0], 'optionalAccess', _242 => _242.text, 'access', _243 => _243.trim, 'call', _244 => _244()]));
6221
6341
  if (populatedRows.length >= 4) {
6222
6342
  const fontSizes = tableItems.map((item) => item.fontSize).filter((size) => size > 0).sort((a, b) => a - b);
6223
6343
  const medianFont = _nullishCoalesce(fontSizes[Math.floor(fontSizes.length / 2)], () => ( 0));
@@ -6275,11 +6395,11 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6275
6395
  pendingNested.push({ parent: grid.clipParent, block: { type: "table", table: irTable, pageNumber: pageNum, bbox: nb } });
6276
6396
  continue;
6277
6397
  }
6278
- if (!grid.cells && isProseBoxGrid(grid, verticals, irTable)) {
6398
+ if (!grid.cells && !nestedAttached && (isProseBoxGrid(grid, verticals, irTable) || ocrPage && isSparseProseGrid(irTable))) {
6279
6399
  for (const it of tableItems) usedItems.delete(it);
6280
6400
  continue;
6281
6401
  }
6282
- if (!grid.cells && isChartTable(irTable)) {
6402
+ if (!grid.cells && !nestedAttached && isChartTable(irTable)) {
6283
6403
  blocks.push(chartBlock(tableItems, pageNum, { page: pageNum, x: grid.bbox.x1, y: grid.bbox.y1, width: gridW, height: grid.bbox.y2 - grid.bbox.y1 }));
6284
6404
  continue;
6285
6405
  }
@@ -6291,7 +6411,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6291
6411
  height: grid.bbox.y2 - grid.bbox.y1
6292
6412
  };
6293
6413
  if (numRows === 1 && numCols === 1 && gridW < pageWidth * 0.35) {
6294
- const prose = _nullishCoalesce(_optionalChain([finalGrid, 'access', _230 => _230[0], 'optionalAccess', _231 => _231[0], 'optionalAccess', _232 => _232.text]), () => ( ""));
6414
+ const prose = _nullishCoalesce(_optionalChain([finalGrid, 'access', _245 => _245[0], 'optionalAccess', _246 => _246[0], 'optionalAccess', _247 => _247.text]), () => ( ""));
6295
6415
  const besideLines = (side) => new Set(side.map((it) => Math.round(it.y / 3))).size;
6296
6416
  const rightLines = items.filter((it) => it.x >= grid.bbox.x2 + 3 && it.y >= grid.bbox.y1 && it.y <= grid.bbox.y2);
6297
6417
  const leftLines = items.filter((it) => it.x + it.w <= grid.bbox.x1 - 3 && it.y >= grid.bbox.y1 && it.y <= grid.bbox.y2);
@@ -6317,6 +6437,10 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6317
6437
  }
6318
6438
  continue;
6319
6439
  }
6440
+ if (grid.lineNested) {
6441
+ pendingNested.push({ parent: grid.bbox, block: { type: "table", table: irTable, pageNumber: pageNum, bbox: tableBbox }, contained: true });
6442
+ continue;
6443
+ }
6320
6444
  blocks.push({ type: "table", table: irTable, pageNumber: pageNum, bbox: tableBbox });
6321
6445
  }
6322
6446
  for (const p of pendingNested) blocks.push(p.block);
@@ -6371,7 +6495,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6371
6495
  if (gutterX !== null) {
6372
6496
  const gx = gutterX;
6373
6497
  const allY = remaining.map((i) => i.y);
6374
- const pageH = _chunkFBZCWSPNcjs.safeMax.call(void 0, allY) - _chunkFBZCWSPNcjs.safeMin.call(void 0, allY);
6498
+ const pageH = _chunkJ6ZU7AIRcjs.safeMax.call(void 0, allY) - _chunkJ6ZU7AIRcjs.safeMin.call(void 0, allY);
6375
6499
  const gapThreshold = Math.max(15, pageH * 0.03);
6376
6500
  const sides = [
6377
6501
  remaining.filter((i) => i.x + i.w <= gx),
@@ -6391,7 +6515,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6391
6515
  finalTextBlocks = detectListBlocks(textBlocks);
6392
6516
  } else {
6393
6517
  const allY = remaining.map((i) => i.y);
6394
- const pageH = _chunkFBZCWSPNcjs.safeMax.call(void 0, allY) - _chunkFBZCWSPNcjs.safeMin.call(void 0, allY);
6518
+ const pageH = _chunkJ6ZU7AIRcjs.safeMax.call(void 0, allY) - _chunkJ6ZU7AIRcjs.safeMin.call(void 0, allY);
6395
6519
  const groups = xyCutOrder(remaining, Math.max(15, pageH * 0.03));
6396
6520
  const textBlocks = [];
6397
6521
  for (const group of groups) {
@@ -6703,7 +6827,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
6703
6827
  blocks.push(...columnTextToBlocks(tableText, pageNum, bbox, dominantStyle(items)));
6704
6828
  } else {
6705
6829
  const allY = items.map((i) => i.y);
6706
- const pageHeight = _chunkFBZCWSPNcjs.safeMax.call(void 0, allY) - _chunkFBZCWSPNcjs.safeMin.call(void 0, allY);
6830
+ const pageHeight = _chunkJ6ZU7AIRcjs.safeMax.call(void 0, allY) - _chunkJ6ZU7AIRcjs.safeMin.call(void 0, allY);
6707
6831
  const gapThreshold = Math.max(15, pageHeight * 0.03);
6708
6832
  const orderedGroups = proseCutX !== null ? splitTwoColumnProse(items, proseCutX) : xyCutOrder(items, gapThreshold);
6709
6833
  for (const group of orderedGroups) {
@@ -6756,4 +6880,4 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
6756
6880
 
6757
6881
 
6758
6882
  exports.extractImageRegions = extractImageRegions; exports.filterHiddenText = filterHiddenText; exports.collapseEvenSpacing = collapseEvenSpacing; exports.normalizeItems = normalizeItems; exports.WrapLexicon = WrapLexicon; exports.wrapJoiner = wrapJoiner; exports.joinPageBreakWraps = joinPageBreakWraps; exports.latinSoftWrap = latinSoftWrap; exports.TOC_BLOCKS = TOC_BLOCKS; exports.computeMedianFontSizeFromFreq = computeMedianFontSizeFromFreq; exports.detectHeadings = detectHeadings; exports.mergeStackedHeadingLines = mergeStackedHeadingLines; exports.detectTypographyHeadings = detectTypographyHeadings; exports.detectDocumentStyleHeadings = detectDocumentStyleHeadings; exports.detectSiblingStyleHeadings = detectSiblingStyleHeadings; exports.detectRepeatedPageLabels = detectRepeatedPageLabels; exports.detectPageLeadHeadings = detectPageLeadHeadings; exports.refineDocumentStyleHeadings = refineDocumentStyleHeadings; exports.detectMarkerHeadings = detectMarkerHeadings; exports.detectTableCaptions = detectTableCaptions; exports.detectKoreanListBlocks = detectKoreanListBlocks; exports.removeHeaderFooterBlocks = removeHeaderFooterBlocks; exports.CLIP_TABLES = CLIP_TABLES; exports.TABLE_COLXS = TABLE_COLXS; exports.EMPTY_PARTS = EMPTY_PARTS; exports.IMAGE_CELLS = IMAGE_CELLS; exports.FILLER_CELLS = FILLER_CELLS; exports.CONT_PARTS = CONT_PARTS; exports.CELL_LINES = CELL_LINES; exports.trimTrailingEmptyTableCols = trimTrailingEmptyTableCols; exports.extractPageBlocksWithLines = extractPageBlocksWithLines;
6759
- //# sourceMappingURL=chunk-SOM7JIKG.cjs.map
6883
+ //# sourceMappingURL=chunk-4ANWGSUT.cjs.map