kordoc 4.24.13 → 4.24.14

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 (127) hide show
  1. package/README.md +5 -5
  2. package/dist/{-NBCZTPBD.js → -MG25ST6Y.js} +11 -11
  3. package/dist/{chunk-UVQOPGOA.js → chunk-3LFNTOL7.js} +14 -9
  4. package/dist/chunk-3LFNTOL7.js.map +1 -0
  5. package/dist/{chunk-BC4LVU4D.js → chunk-7VNYQHJV.js} +2 -2
  6. package/dist/{chunk-CKOCIQU6.js → chunk-AM6TECXD.js} +2 -2
  7. package/dist/{chunk-X2E5QCKO.js → chunk-AULD3QAB.js} +2 -2
  8. package/dist/{chunk-XGESPSWE.cjs → chunk-BUGXM2H5.cjs} +3 -3
  9. package/dist/{chunk-XGESPSWE.cjs.map → chunk-BUGXM2H5.cjs.map} +1 -1
  10. package/dist/{chunk-ZUMOEVMV.js → chunk-DIFJPJGN.js} +3 -3
  11. package/dist/{chunk-XWWQGSEP.js → chunk-ERYRF3EA.js} +2 -2
  12. package/dist/{chunk-QAGPSWGH.js → chunk-FGERVDQZ.js} +2 -2
  13. package/dist/{chunk-ZSCDH3NU.js → chunk-FUC3V2FR.js} +2 -2
  14. package/dist/{chunk-U2VAABMK.cjs → chunk-GV7ECKOK.cjs} +44 -27
  15. package/dist/chunk-GV7ECKOK.cjs.map +1 -0
  16. package/dist/{chunk-2H2VYPM2.cjs → chunk-HVILFVAT.cjs} +2 -2
  17. package/dist/{chunk-2H2VYPM2.cjs.map → chunk-HVILFVAT.cjs.map} +1 -1
  18. package/dist/{chunk-OVQWOOS3.js → chunk-J3OJWUON.js} +2 -2
  19. package/dist/{chunk-QVEAR6IR.js → chunk-LMQT2JFS.js} +22 -5
  20. package/dist/chunk-LMQT2JFS.js.map +1 -0
  21. package/dist/{chunk-37MTSMUF.js → chunk-LSFVBS2I.js} +2 -2
  22. package/dist/{chunk-IQGXY63Y.js → chunk-MACV3MZF.js} +23 -6
  23. package/dist/chunk-MACV3MZF.js.map +1 -0
  24. package/dist/{chunk-QW2H2HHS.js → chunk-MIJYCKJA.js} +115 -6
  25. package/dist/chunk-MIJYCKJA.js.map +1 -0
  26. package/dist/{chunk-DMPX4KLC.js → chunk-NIPFEMJJ.js} +2 -2
  27. package/dist/{chunk-WOVJRXIA.js → chunk-NVD24SLL.js} +2 -2
  28. package/dist/{chunk-A232MW5F.js → chunk-PVAJ4DBW.js} +2 -2
  29. package/dist/{chunk-BJBPBU5B.js → chunk-SSDHVKLM.js} +2 -2
  30. package/dist/{chunk-4I2CKMKU.js → chunk-TPZPICDM.js} +3 -3
  31. package/dist/{chunk-KTXDK5A6.js → chunk-UTLHDVC5.js} +2 -2
  32. package/dist/{chunk-PUHBCAXI.js → chunk-UUNCLJB7.js} +11 -11
  33. package/dist/{chunk-W52B6GOE.cjs → chunk-V26UPU2L.cjs} +3 -3
  34. package/dist/{chunk-W52B6GOE.cjs.map → chunk-V26UPU2L.cjs.map} +1 -1
  35. package/dist/{chunk-A4CYMI55.js → chunk-VBOFP27O.js} +2 -2
  36. package/dist/{chunk-FJ3IKKDV.js → chunk-WFOPOJHN.js} +115 -6
  37. package/dist/chunk-WFOPOJHN.js.map +1 -0
  38. package/dist/{chunk-VPKZB6Y7.cjs → chunk-ZBHS7KLW.cjs} +6 -6
  39. package/dist/{chunk-VPKZB6Y7.cjs.map → chunk-ZBHS7KLW.cjs.map} +1 -1
  40. package/dist/{chunk-WAWREGAC.js → chunk-ZIGWQ3IS.js} +2 -2
  41. package/dist/{chunk-QZ2H4ZTO.cjs → chunk-ZX66BXB5.cjs} +190 -81
  42. package/dist/chunk-ZX66BXB5.cjs.map +1 -0
  43. package/dist/chunks-JGSWNVLF.js +10 -0
  44. package/dist/cli.js +30 -30
  45. package/dist/{formula-M4FM364X.js → formula-4KFXQSEG.js} +4 -4
  46. package/dist/{formula-ZKZGV6JV.cjs → formula-N6GWFPHK.cjs} +9 -9
  47. package/dist/{formula-ZKZGV6JV.cjs.map → formula-N6GWFPHK.cjs.map} +1 -1
  48. package/dist/{formula-WFL6JRCR.js → formula-WAYIKS54.js} +3 -3
  49. package/dist/{image-ocr-2V3M3ZEA.cjs → image-ocr-GY7SZAHN.cjs} +17 -17
  50. package/dist/{image-ocr-2V3M3ZEA.cjs.map → image-ocr-GY7SZAHN.cjs.map} +1 -1
  51. package/dist/{image-ocr-YJISJPKE.js → image-ocr-P5S2QDKW.js} +6 -6
  52. package/dist/{image-ocr-47CBNIS5.js → image-ocr-QBCR7ZD6.js} +9 -9
  53. package/dist/index.cjs +368 -363
  54. package/dist/index.cjs.map +1 -1
  55. package/dist/index.js +14 -9
  56. package/dist/index.js.map +1 -1
  57. package/dist/mcp.js +23 -23
  58. package/dist/{model-bundle-7W344HDI.js → model-bundle-QAM24SYG.js} +5 -5
  59. package/dist/{models-TBHMNI7M.js → models-YHC236MP.js} +5 -5
  60. package/dist/{parse-worker-v2-JUYUEXCY.js → parse-worker-v2-LP7NKQBP.js} +12 -12
  61. package/dist/{parser-EKQCZLML.js → parser-26YUZU55.js} +12 -12
  62. package/dist/{parser-RNJ4KSDF.js → parser-DFJZ3CCE.js} +9 -9
  63. package/dist/{parser-R44KTBZX.cjs → parser-JWU6HYZZ.cjs} +159 -159
  64. package/dist/{parser-R44KTBZX.cjs.map → parser-JWU6HYZZ.cjs.map} +1 -1
  65. package/dist/{pdf-ocr-EE5KGFVX.js → pdf-ocr-BO6ACAGL.js} +9 -9
  66. package/dist/{pdf-ocr-ZAF4P74R.js → pdf-ocr-EEWQFS7P.js} +6 -6
  67. package/dist/pdf-ocr-Z4PBLB75.cjs +35 -0
  68. package/dist/{pdf-ocr-74BOCXAT.cjs.map → pdf-ocr-Z4PBLB75.cjs.map} +1 -1
  69. package/dist/{profile-io-RU3RVIYV.js → profile-io-PQXYWUBL.js} +3 -3
  70. package/dist/{rasterize-UNCPM26D.js → rasterize-CS7WZUGF.js} +3 -3
  71. package/dist/{redact-doc-BFE4UZCY.js → redact-doc-PI4JNHV6.js} +11 -11
  72. package/dist/{render-3DXTLKIA.js → render-M2CIEOF4.js} +7 -7
  73. package/dist/seal-4755WLFB.js +10 -0
  74. package/dist/{setup-7POQAKDG.js → setup-HGPUR27M.js} +3 -3
  75. package/dist/visual-JWWGGTKQ.js +21 -0
  76. package/dist/{watch-37YCXJWW.js → watch-B5ISBY3N.js} +12 -12
  77. package/package.json +1 -1
  78. package/dist/chunk-FJ3IKKDV.js.map +0 -1
  79. package/dist/chunk-IQGXY63Y.js.map +0 -1
  80. package/dist/chunk-QVEAR6IR.js.map +0 -1
  81. package/dist/chunk-QW2H2HHS.js.map +0 -1
  82. package/dist/chunk-QZ2H4ZTO.cjs.map +0 -1
  83. package/dist/chunk-U2VAABMK.cjs.map +0 -1
  84. package/dist/chunk-UVQOPGOA.js.map +0 -1
  85. package/dist/chunks-IXFBIZPW.js +0 -10
  86. package/dist/pdf-ocr-74BOCXAT.cjs +0 -35
  87. package/dist/seal-3LBTETDG.js +0 -10
  88. package/dist/visual-7SVIGIJC.js +0 -21
  89. /package/dist/{-NBCZTPBD.js.map → -MG25ST6Y.js.map} +0 -0
  90. /package/dist/{chunk-BC4LVU4D.js.map → chunk-7VNYQHJV.js.map} +0 -0
  91. /package/dist/{chunk-CKOCIQU6.js.map → chunk-AM6TECXD.js.map} +0 -0
  92. /package/dist/{chunk-X2E5QCKO.js.map → chunk-AULD3QAB.js.map} +0 -0
  93. /package/dist/{chunk-ZUMOEVMV.js.map → chunk-DIFJPJGN.js.map} +0 -0
  94. /package/dist/{chunk-XWWQGSEP.js.map → chunk-ERYRF3EA.js.map} +0 -0
  95. /package/dist/{chunk-QAGPSWGH.js.map → chunk-FGERVDQZ.js.map} +0 -0
  96. /package/dist/{chunk-ZSCDH3NU.js.map → chunk-FUC3V2FR.js.map} +0 -0
  97. /package/dist/{chunk-OVQWOOS3.js.map → chunk-J3OJWUON.js.map} +0 -0
  98. /package/dist/{chunk-37MTSMUF.js.map → chunk-LSFVBS2I.js.map} +0 -0
  99. /package/dist/{chunk-DMPX4KLC.js.map → chunk-NIPFEMJJ.js.map} +0 -0
  100. /package/dist/{chunk-WOVJRXIA.js.map → chunk-NVD24SLL.js.map} +0 -0
  101. /package/dist/{chunk-A232MW5F.js.map → chunk-PVAJ4DBW.js.map} +0 -0
  102. /package/dist/{chunk-BJBPBU5B.js.map → chunk-SSDHVKLM.js.map} +0 -0
  103. /package/dist/{chunk-4I2CKMKU.js.map → chunk-TPZPICDM.js.map} +0 -0
  104. /package/dist/{chunk-KTXDK5A6.js.map → chunk-UTLHDVC5.js.map} +0 -0
  105. /package/dist/{chunk-PUHBCAXI.js.map → chunk-UUNCLJB7.js.map} +0 -0
  106. /package/dist/{chunk-A4CYMI55.js.map → chunk-VBOFP27O.js.map} +0 -0
  107. /package/dist/{chunk-WAWREGAC.js.map → chunk-ZIGWQ3IS.js.map} +0 -0
  108. /package/dist/{chunks-IXFBIZPW.js.map → chunks-JGSWNVLF.js.map} +0 -0
  109. /package/dist/{formula-M4FM364X.js.map → formula-4KFXQSEG.js.map} +0 -0
  110. /package/dist/{formula-WFL6JRCR.js.map → formula-WAYIKS54.js.map} +0 -0
  111. /package/dist/{image-ocr-YJISJPKE.js.map → image-ocr-P5S2QDKW.js.map} +0 -0
  112. /package/dist/{image-ocr-47CBNIS5.js.map → image-ocr-QBCR7ZD6.js.map} +0 -0
  113. /package/dist/{model-bundle-7W344HDI.js.map → model-bundle-QAM24SYG.js.map} +0 -0
  114. /package/dist/{models-TBHMNI7M.js.map → models-YHC236MP.js.map} +0 -0
  115. /package/dist/{parse-worker-v2-JUYUEXCY.js.map → parse-worker-v2-LP7NKQBP.js.map} +0 -0
  116. /package/dist/{parser-EKQCZLML.js.map → parser-26YUZU55.js.map} +0 -0
  117. /package/dist/{parser-RNJ4KSDF.js.map → parser-DFJZ3CCE.js.map} +0 -0
  118. /package/dist/{pdf-ocr-EE5KGFVX.js.map → pdf-ocr-BO6ACAGL.js.map} +0 -0
  119. /package/dist/{pdf-ocr-ZAF4P74R.js.map → pdf-ocr-EEWQFS7P.js.map} +0 -0
  120. /package/dist/{profile-io-RU3RVIYV.js.map → profile-io-PQXYWUBL.js.map} +0 -0
  121. /package/dist/{rasterize-UNCPM26D.js.map → rasterize-CS7WZUGF.js.map} +0 -0
  122. /package/dist/{redact-doc-BFE4UZCY.js.map → redact-doc-PI4JNHV6.js.map} +0 -0
  123. /package/dist/{render-3DXTLKIA.js.map → render-M2CIEOF4.js.map} +0 -0
  124. /package/dist/{seal-3LBTETDG.js.map → seal-4755WLFB.js.map} +0 -0
  125. /package/dist/{setup-7POQAKDG.js.map → setup-HGPUR27M.js.map} +0 -0
  126. /package/dist/{visual-7SVIGIJC.js.map → visual-JWWGGTKQ.js.map} +0 -0
  127. /package/dist/{watch-37YCXJWW.js.map → watch-B5ISBY3N.js.map} +0 -0
@@ -30,7 +30,7 @@ import {
30
30
  splitRowBands,
31
31
  starRun,
32
32
  tallInkCount
33
- } from "./chunk-QVEAR6IR.js";
33
+ } from "./chunk-LMQT2JFS.js";
34
34
  import {
35
35
  validateOcrOptions
36
36
  } from "./chunk-BYMPPVT3.js";
@@ -41,11 +41,11 @@ import {
41
41
  ocrSourcePath,
42
42
  parseCharacterDict,
43
43
  resolveOcrModels
44
- } from "./chunk-A4CYMI55.js";
44
+ } from "./chunk-VBOFP27O.js";
45
45
  import {
46
46
  KordocError,
47
47
  OPTIONAL_DEP_INSTALL_HINT
48
- } from "./chunk-WAWREGAC.js";
48
+ } from "./chunk-ZIGWQ3IS.js";
49
49
 
50
50
  // src/ocr/ruling-lines.ts
51
51
  var INK_LUMA_MAX = 205;
@@ -395,6 +395,7 @@ function restoreGlyphs(rgba, pageW, box, text, steps, stepPx, note = {}) {
395
395
  const gray = grayCrop(rgba, pageW, box);
396
396
  const c = { chars, cx: (i) => (steps[i] + 0.5) * stepPx, gray, w: box.w, h: box.h, ink: inkStats(gray) };
397
397
  if (/[[\]]/.test(text)) brackets(c);
398
+ if (text.includes("'")) cornerQuotes(c);
398
399
  if (/['"]/.test(text)) quotes(c);
399
400
  if (/(^|\D)[1-9](\D|$)/.test(text)) circled(c);
400
401
  if (text.includes("*")) stars(c);
@@ -448,6 +449,19 @@ function cornerCommas({ chars, cx, gray, w, h, ink }) {
448
449
  }
449
450
  }
450
451
  }
452
+ function cornerQuotes({ chars, cx, gray, w, h, ink }) {
453
+ for (let i = 0; i < chars.length; i++) {
454
+ if (chars[i] !== "'" || !/^[가-힣]/.test(chars[i + 1] ?? "")) continue;
455
+ const f = bracketFeatures(gray, w, h, ink, cx(i));
456
+ if (!f || f.ch < f.charH * 0.45 || bracketShape(f, false) !== "\u300C") continue;
457
+ const rest = chars.slice(i + 1), end = rest.findIndex((c) => c === "'" || c === "\u300D" || c === ",");
458
+ const pair = end >= 0 && rest[end] !== "'" && (rest[end] === "\u300D" || (() => {
459
+ const g = bracketFeatures(gray, w, h, ink, cx(i + 1 + end));
460
+ return !!g && bracketShape(g, true) === "\u300D";
461
+ })());
462
+ if (pair) chars[i] = "\u300C";
463
+ }
464
+ }
451
465
  function brackets({ chars, cx, gray, w, h, ink }) {
452
466
  for (let i = 0; i < chars.length; i++) {
453
467
  if (chars[i] !== "[" && chars[i] !== "]") continue;
@@ -549,6 +563,14 @@ function gaps({ chars, cx, gray, w, h, ink }) {
549
563
  if (loose.some((o) => o !== g && Math.abs((o.x0 + o.x1) / 2 - mid) <= pitch * 1.5)) continue;
550
564
  if (/[\u2026.\u00b7]$/.test(prev) || /^[\u2026.\u00b7]/.test(next)) continue;
551
565
  }
566
+ if (g.mark === "\u300C") {
567
+ let sp = chars.findIndex((c, i) => c === " " && near(i));
568
+ if (sp >= 0) while (chars[sp + 1] === " ") sp++;
569
+ if (sp >= 0) {
570
+ chars[sp] = g.mark;
571
+ continue;
572
+ }
573
+ }
552
574
  if (g.mark === "\xB7") {
553
575
  if (/^\d/.test(next)) continue;
554
576
  const sp = chars.findIndex((c, i) => c === " " && near(i));
@@ -562,10 +584,23 @@ function gaps({ chars, cx, gray, w, h, ink }) {
562
584
  }
563
585
  function ring({ chars, cx, gray, w, h, ink }) {
564
586
  const k = chars.findIndex((c) => c.trim());
565
- if (k < 0 || !/^[\u3147Oo0\u25cb]$/.test(chars[k])) return false;
587
+ if (k < 0 || !/^[\u3147Oo0\u25cbCc]$/.test(chars[k])) return false;
566
588
  const rest = chars.slice(k + 1).join("").trimStart();
589
+ const live = chars.map((c, i) => i).filter((i) => chars[i].trim());
590
+ if (live.length <= 3 && live.every((i) => /^[Oo]$/.test(chars[i]))) {
591
+ if (leadingBullet(gray, w, h, ink, cx(live[0]))?.mark === "\u25CE") return false;
592
+ if (!live.every((i) => ringBullet(gray, w, h, ink, cx(i)) === "\u25CB")) return false;
593
+ for (const i of live) chars[i] = "\u25CB";
594
+ return true;
595
+ }
596
+ if (/^[A-Z]{2,}/.test(rest) && /^[Oo0]$/.test(chars[k])) {
597
+ if (ringBullet(gray, w, h, ink, cx(k)) !== "\u25CB") return false;
598
+ chars[k] = chars[k + 1] === " " ? "\u25CB" : "\u25CB ";
599
+ return true;
600
+ }
567
601
  if (!/^[(\[「【<]?\d*[가-힣]/.test(rest)) return false;
568
602
  const r = ringBullet(gray, w, h, ink, cx(k));
603
+ if (/^[Cc]$/.test(chars[k]) && r !== "\u25CB") return false;
569
604
  if (r) chars[k] = r;
570
605
  return r !== null;
571
606
  }
@@ -872,6 +907,71 @@ var MIN_INK_RATIO = 0.01;
872
907
  var MAX_LOCAL_MODEL_BYTES = 1024 * 1024 * 1024;
873
908
  var DET_MEAN = [0.485, 0.456, 0.406];
874
909
  var DET_STD = [0.229, 0.224, 0.225];
910
+ function footerInkBox(rgba, width, height, boxes) {
911
+ const y0 = Math.floor(height * 0.88), x0 = Math.floor(width * 0.3), x1 = Math.ceil(width * 0.7);
912
+ let minX = Infinity, maxX = -1, minY = Infinity, maxY = -1;
913
+ for (let y = y0; y < height; y++) for (let x = x0; x < x1; x++) {
914
+ const p = (y * width + x) * 4;
915
+ if (rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29 >> 8 >= 128) continue;
916
+ if (boxes.some((b) => x >= b.x && x < b.x + b.w && y >= b.y && y < b.y + b.h)) continue;
917
+ if (x < minX) minX = x;
918
+ if (x > maxX) maxX = x;
919
+ if (y < minY) minY = y;
920
+ if (y > maxY) maxY = y;
921
+ }
922
+ if (maxX < 0) return null;
923
+ const bh = maxY - minY + 1;
924
+ if (bh < height * 5e-3 || bh > height * 0.025 || maxX - minX + 1 > width * 0.2) return null;
925
+ const pad = 4, bx = Math.max(0, minX - pad), by = Math.max(0, minY - pad);
926
+ return { x: bx, y: by, w: Math.min(width, maxX + pad + 1) - bx, h: Math.min(height, maxY + pad + 1) - by };
927
+ }
928
+ function closingParens(rgba, width, items) {
929
+ const out = [];
930
+ const dark = (x, y) => {
931
+ const p = (y * width + x) * 4;
932
+ return rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29 >> 8 < 128;
933
+ };
934
+ for (const it of items) {
935
+ const t = it.text.replace(/\s+$/, "");
936
+ if ((t.match(/\(/g)?.length ?? 0) <= (t.match(/\)/g)?.length ?? 0) || !/\([^()]*$/.test(t)) continue;
937
+ const x0 = it.x + it.w + 2;
938
+ const next = items.filter((o) => o !== it && o.x >= x0 && o.y < it.y + it.h && o.y + o.h > it.y).reduce((m, o) => Math.min(m, o.x), Infinity);
939
+ const x1 = Math.min(width, next, x0 + it.h * 8);
940
+ let minX = Infinity, maxX = -1, minY = Infinity, maxY = -1, cols = 0, prevOn = false, runs = 0;
941
+ for (let x = x0; x < x1; x++) {
942
+ let on = false;
943
+ for (let y = it.y; y < it.y + it.h; y++) if (dark(x, y)) {
944
+ on = true;
945
+ if (y < minY) minY = y;
946
+ if (y > maxY) maxY = y;
947
+ }
948
+ if (on) {
949
+ cols++;
950
+ if (!prevOn) runs++;
951
+ if (x < minX) minX = x;
952
+ maxX = x;
953
+ }
954
+ prevOn = on;
955
+ }
956
+ if (runs !== 1 || maxX - minX + 1 > it.h * 0.5 || maxY - minY + 1 < it.h * 0.6) continue;
957
+ let rule = false;
958
+ for (let x = minX; x <= maxX && !rule; x++) rule = minY > 1 && dark(x, minY - 2) || dark(x, Math.min(maxY + 2, Math.floor(rgba.length / 4 / width) - 1));
959
+ if (rule) continue;
960
+ const meanX = (ya, yb) => {
961
+ let sx = 0, k = 0;
962
+ for (let y = ya; y < yb; y++) for (let x = minX; x <= maxX; x++) if (dark(x, y)) {
963
+ sx += x;
964
+ k++;
965
+ }
966
+ return k ? sx / k : NaN;
967
+ };
968
+ const ch = maxY - minY + 1, band = Math.max(1, Math.round(ch * 0.2));
969
+ const ends = (meanX(minY, minY + band) + meanX(maxY + 1 - band, maxY + 1)) / 2, mid = meanX(minY + Math.floor(ch * 0.4), minY + Math.ceil(ch * 0.6));
970
+ if (!(mid - ends >= 0.8)) continue;
971
+ out.push({ text: ")", x: minX, y: minY, w: maxX - minX + 1, h: maxY - minY + 1, confidence: it.confidence });
972
+ }
973
+ return out;
974
+ }
875
975
  var OcrEngine = class _OcrEngine {
876
976
  det;
877
977
  rec;
@@ -961,6 +1061,7 @@ var OcrEngine = class _OcrEngine {
961
1061
  const detected = await this.detect(rgba, width, height, tuning, stats);
962
1062
  const rows = rowRules.length ? detected.flatMap((b) => splitBoxAtRowRules(b, rowRules)) : detected;
963
1063
  const boxes = cellRules.length ? rows.flatMap((b) => splitBoxAtCellRules(b, cellRules)) : rows;
1064
+ const footer = tuning.postprocess ? footerInkBox(rgba, width, height, boxes) : null;
964
1065
  const jobs = [];
965
1066
  const joins = [];
966
1067
  let group = 0;
@@ -1004,6 +1105,7 @@ var OcrEngine = class _OcrEngine {
1004
1105
  if (keep) jobs.push({ box: b, rot: 0, group, keep });
1005
1106
  jobs.push({ box: b, rot: 0, group: group++ });
1006
1107
  }
1108
+ if (footer) jobs.push({ box: footer, rot: 0, group: group++, footer: true });
1007
1109
  const results = await this.recognizeJobs(rgba, width, jobs, tuning.recBatch);
1008
1110
  const best = /* @__PURE__ */ new Map();
1009
1111
  const score = (job, confidence) => confidence - (job.keep ? KEEP_MARGIN : 0);
@@ -1021,7 +1123,7 @@ var OcrEngine = class _OcrEngine {
1021
1123
  const raw = tuning.postprocess && job.rot === 0 ? restoreGlyphs(rgba, width, job.box, read, steps, stepPx, note) : read;
1022
1124
  let text = tuning.postprocess ? restoreSymbols(raw.trim(), note.ringLead) : raw;
1023
1125
  if (!text.trim()) continue;
1024
- if (tuning.postprocess && job.rot === 0 && !/^[◎●▪□■▣❐❏○ㅇ]/.test(text)) {
1126
+ if (tuning.postprocess && job.rot === 0 && !/^[◎●▪□■▣❐❏○ㅇ◆◇◈]/.test(text)) {
1025
1127
  const chars = [...read], k = chars.findIndex((c) => c.trim());
1026
1128
  if (k >= 0 && steps.length === chars.length) {
1027
1129
  const g = grayCrop(rgba, width, job.box);
@@ -1031,6 +1133,8 @@ var OcrEngine = class _OcrEngine {
1031
1133
  if (b?.mark === "\u25CE" && b.covers && /^[Oo0○]/.test(text)) text = b.mark + " " + text.slice(1).trimStart();
1032
1134
  else if (b?.mark === "\u25A1" || b?.mark === "\u25A3") {
1033
1135
  if (!b.covers && body) text = b.mark + " " + text;
1136
+ } else if (b?.mark === "\u25C6" || b?.mark === "\u25C7" || b?.mark === "\u25C8") {
1137
+ if (b.covers ? /^[\p{S}\p{P}]/u.test(text) : body) text = b.covers ? b.mark + " " + text.slice(1).trimStart() : b.mark + " " + text;
1034
1138
  } else if (b?.mark === "\u2023") {
1035
1139
  if (b.covers ? text.startsWith("\u2192") : body) text = b.covers ? b.mark + " " + text.slice(1).trimStart() : b.mark + " " + text;
1036
1140
  } else if (b?.mark === "\u2750" || b?.mark === "\u274F") {
@@ -1048,6 +1152,10 @@ var OcrEngine = class _OcrEngine {
1048
1152
  const g = grayCrop(rgba, width, job.box);
1049
1153
  text = arrowGlyph(g, job.box.w, job.box.h, inkStats(g)) ?? text;
1050
1154
  }
1155
+ if (job.footer) {
1156
+ if (!/^[-\u2013\u2014]?\s*(?:\d{1,4}|[ivxIVXⅰ-ⅹⅠ-Ⅹ]{1,4})\s*[-\u2013\u2014]?$/.test(text.trim())) continue;
1157
+ text = text.replace(/[\u2013\u2014]/g, "-");
1158
+ }
1051
1159
  if (tuning.postprocess && isDotFragment(text)) continue;
1052
1160
  if (confidence < tuning.textScore) {
1053
1161
  if (stats) {
@@ -1086,6 +1194,7 @@ var OcrEngine = class _OcrEngine {
1086
1194
  if (leaderEnds.size) items = joinLeaderItems(items, leaderEnds);
1087
1195
  if (tuning.postprocess) items = dropNestedFragments(items);
1088
1196
  if (tuning.postprocess) for (const it of items) this.outerSquare(rgba, width, it, items);
1197
+ if (tuning.postprocess) items.push(...closingParens(rgba, width, items));
1089
1198
  if (tuning.postprocess) restoreBulletItems(items);
1090
1199
  items.sort((a, b) => a.y - b.y || a.x - b.x);
1091
1200
  return items;
@@ -1755,4 +1864,4 @@ export {
1755
1864
  groupOcrLines,
1756
1865
  ocrItemsToBlocks
1757
1866
  };
1758
- //# sourceMappingURL=chunk-QW2H2HHS.js.map
1867
+ //# sourceMappingURL=chunk-MIJYCKJA.js.map