kordoc 4.24.13 → 4.24.15

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 +7 -7
  2. package/dist/{-NBCZTPBD.js → -CCZTES5C.js} +11 -11
  3. package/dist/{chunk-XWWQGSEP.js → chunk-4EVUCAW5.js} +2 -2
  4. package/dist/{chunk-VPKZB6Y7.cjs → chunk-4ZNM7XRW.cjs} +6 -6
  5. package/dist/{chunk-VPKZB6Y7.cjs.map → chunk-4ZNM7XRW.cjs.map} +1 -1
  6. package/dist/{chunk-XGESPSWE.cjs → chunk-6KQWC2KN.cjs} +3 -3
  7. package/dist/{chunk-XGESPSWE.cjs.map → chunk-6KQWC2KN.cjs.map} +1 -1
  8. package/dist/{chunk-QW2H2HHS.js → chunk-6WEHXC2D.js} +315 -6
  9. package/dist/chunk-6WEHXC2D.js.map +1 -0
  10. package/dist/{chunk-PUHBCAXI.js → chunk-7Y4MVNYA.js} +11 -11
  11. package/dist/{chunk-CKOCIQU6.js → chunk-7YCKDE5X.js} +2 -2
  12. package/dist/{chunk-FJ3IKKDV.js → chunk-DULJ7PPP.js} +315 -6
  13. package/dist/chunk-DULJ7PPP.js.map +1 -0
  14. package/dist/{chunk-KTXDK5A6.js → chunk-E5H5WHJH.js} +2 -2
  15. package/dist/{chunk-A232MW5F.js → chunk-EY3PT2X7.js} +2 -2
  16. package/dist/{chunk-W52B6GOE.cjs → chunk-GDE4YE2P.cjs} +3 -3
  17. package/dist/{chunk-W52B6GOE.cjs.map → chunk-GDE4YE2P.cjs.map} +1 -1
  18. package/dist/{chunk-UVQOPGOA.js → chunk-GZ3BY2LV.js} +14 -9
  19. package/dist/chunk-GZ3BY2LV.js.map +1 -0
  20. package/dist/{chunk-ZUMOEVMV.js → chunk-HZFYPOBJ.js} +3 -3
  21. package/dist/{chunk-OVQWOOS3.js → chunk-IGLRJCO6.js} +2 -2
  22. package/dist/{chunk-A4CYMI55.js → chunk-K37LMDT5.js} +2 -2
  23. package/dist/{chunk-X2E5QCKO.js → chunk-KMSLXG5F.js} +2 -2
  24. package/dist/{chunk-DMPX4KLC.js → chunk-KOHEEPQV.js} +2 -2
  25. package/dist/{chunk-37MTSMUF.js → chunk-MTAQVHCB.js} +2 -2
  26. package/dist/{chunk-2H2VYPM2.cjs → chunk-OICA67AT.cjs} +2 -2
  27. package/dist/{chunk-2H2VYPM2.cjs.map → chunk-OICA67AT.cjs.map} +1 -1
  28. package/dist/{chunk-QAGPSWGH.js → chunk-PCHGHLUP.js} +2 -2
  29. package/dist/{chunk-BC4LVU4D.js → chunk-SLHWOJNZ.js} +2 -2
  30. package/dist/{chunk-ZSCDH3NU.js → chunk-T7MDUY5X.js} +2 -2
  31. package/dist/{chunk-QVEAR6IR.js → chunk-UGO3UFXX.js} +48 -7
  32. package/dist/chunk-UGO3UFXX.js.map +1 -0
  33. package/dist/{chunk-WAWREGAC.js → chunk-UV2ZS65C.js} +2 -2
  34. package/dist/{chunk-4I2CKMKU.js → chunk-VNB2IKVA.js} +3 -3
  35. package/dist/{chunk-IQGXY63Y.js → chunk-VSYLST4K.js} +49 -8
  36. package/dist/chunk-VSYLST4K.js.map +1 -0
  37. package/dist/{chunk-QZ2H4ZTO.cjs → chunk-X2XZXDBZ.cjs} +390 -81
  38. package/dist/chunk-X2XZXDBZ.cjs.map +1 -0
  39. package/dist/{chunk-WOVJRXIA.js → chunk-XW7L76FE.js} +2 -2
  40. package/dist/{chunk-BJBPBU5B.js → chunk-Y3VNNGB2.js} +2 -2
  41. package/dist/{chunk-U2VAABMK.cjs → chunk-YAK4U7CC.cjs} +194 -153
  42. package/dist/chunk-YAK4U7CC.cjs.map +1 -0
  43. package/dist/chunks-74SE5QB2.js +10 -0
  44. package/dist/cli.js +30 -30
  45. package/dist/{formula-WFL6JRCR.js → formula-54IFKOYU.js} +3 -3
  46. package/dist/{formula-M4FM364X.js → formula-EW7XLBSA.js} +4 -4
  47. package/dist/{formula-ZKZGV6JV.cjs → formula-Q4MFVPEO.cjs} +9 -9
  48. package/dist/{formula-ZKZGV6JV.cjs.map → formula-Q4MFVPEO.cjs.map} +1 -1
  49. package/dist/{image-ocr-47CBNIS5.js → image-ocr-GWF2XELH.js} +9 -9
  50. package/dist/{image-ocr-YJISJPKE.js → image-ocr-I7UGQZF5.js} +6 -6
  51. package/dist/{image-ocr-2V3M3ZEA.cjs → image-ocr-OGJ6A3ML.cjs} +17 -17
  52. package/dist/{image-ocr-2V3M3ZEA.cjs.map → image-ocr-OGJ6A3ML.cjs.map} +1 -1
  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-43YHGZCC.js} +5 -5
  59. package/dist/{models-TBHMNI7M.js → models-O3NS6OPX.js} +5 -5
  60. package/dist/{parse-worker-v2-JUYUEXCY.js → parse-worker-v2-OXW3CQOW.js} +12 -12
  61. package/dist/{parser-RNJ4KSDF.js → parser-B3RVTCOY.js} +9 -9
  62. package/dist/{parser-R44KTBZX.cjs → parser-FMVOWRG4.cjs} +159 -159
  63. package/dist/{parser-R44KTBZX.cjs.map → parser-FMVOWRG4.cjs.map} +1 -1
  64. package/dist/{parser-EKQCZLML.js → parser-H6OY6UWW.js} +12 -12
  65. package/dist/pdf-ocr-5Z6GDYBQ.cjs +35 -0
  66. package/dist/{pdf-ocr-74BOCXAT.cjs.map → pdf-ocr-5Z6GDYBQ.cjs.map} +1 -1
  67. package/dist/{pdf-ocr-ZAF4P74R.js → pdf-ocr-NE6Y4I6O.js} +6 -6
  68. package/dist/{pdf-ocr-EE5KGFVX.js → pdf-ocr-QHW74LO6.js} +9 -9
  69. package/dist/{profile-io-RU3RVIYV.js → profile-io-2IOYOBGP.js} +3 -3
  70. package/dist/{rasterize-UNCPM26D.js → rasterize-ZLPDGEZY.js} +3 -3
  71. package/dist/{redact-doc-BFE4UZCY.js → redact-doc-CDFM5S7S.js} +11 -11
  72. package/dist/{render-3DXTLKIA.js → render-VXAEYSJA.js} +7 -7
  73. package/dist/seal-YSBFBEXC.js +10 -0
  74. package/dist/{setup-7POQAKDG.js → setup-CBWVQJID.js} +3 -3
  75. package/dist/visual-MJVIFZHH.js +21 -0
  76. package/dist/{watch-37YCXJWW.js → watch-2SA3CTRT.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 → -CCZTES5C.js.map} +0 -0
  90. /package/dist/{chunk-XWWQGSEP.js.map → chunk-4EVUCAW5.js.map} +0 -0
  91. /package/dist/{chunk-PUHBCAXI.js.map → chunk-7Y4MVNYA.js.map} +0 -0
  92. /package/dist/{chunk-CKOCIQU6.js.map → chunk-7YCKDE5X.js.map} +0 -0
  93. /package/dist/{chunk-KTXDK5A6.js.map → chunk-E5H5WHJH.js.map} +0 -0
  94. /package/dist/{chunk-A232MW5F.js.map → chunk-EY3PT2X7.js.map} +0 -0
  95. /package/dist/{chunk-ZUMOEVMV.js.map → chunk-HZFYPOBJ.js.map} +0 -0
  96. /package/dist/{chunk-OVQWOOS3.js.map → chunk-IGLRJCO6.js.map} +0 -0
  97. /package/dist/{chunk-A4CYMI55.js.map → chunk-K37LMDT5.js.map} +0 -0
  98. /package/dist/{chunk-X2E5QCKO.js.map → chunk-KMSLXG5F.js.map} +0 -0
  99. /package/dist/{chunk-DMPX4KLC.js.map → chunk-KOHEEPQV.js.map} +0 -0
  100. /package/dist/{chunk-37MTSMUF.js.map → chunk-MTAQVHCB.js.map} +0 -0
  101. /package/dist/{chunk-QAGPSWGH.js.map → chunk-PCHGHLUP.js.map} +0 -0
  102. /package/dist/{chunk-BC4LVU4D.js.map → chunk-SLHWOJNZ.js.map} +0 -0
  103. /package/dist/{chunk-ZSCDH3NU.js.map → chunk-T7MDUY5X.js.map} +0 -0
  104. /package/dist/{chunk-WAWREGAC.js.map → chunk-UV2ZS65C.js.map} +0 -0
  105. /package/dist/{chunk-4I2CKMKU.js.map → chunk-VNB2IKVA.js.map} +0 -0
  106. /package/dist/{chunk-WOVJRXIA.js.map → chunk-XW7L76FE.js.map} +0 -0
  107. /package/dist/{chunk-BJBPBU5B.js.map → chunk-Y3VNNGB2.js.map} +0 -0
  108. /package/dist/{chunks-IXFBIZPW.js.map → chunks-74SE5QB2.js.map} +0 -0
  109. /package/dist/{formula-WFL6JRCR.js.map → formula-54IFKOYU.js.map} +0 -0
  110. /package/dist/{formula-M4FM364X.js.map → formula-EW7XLBSA.js.map} +0 -0
  111. /package/dist/{image-ocr-47CBNIS5.js.map → image-ocr-GWF2XELH.js.map} +0 -0
  112. /package/dist/{image-ocr-YJISJPKE.js.map → image-ocr-I7UGQZF5.js.map} +0 -0
  113. /package/dist/{model-bundle-7W344HDI.js.map → model-bundle-43YHGZCC.js.map} +0 -0
  114. /package/dist/{models-TBHMNI7M.js.map → models-O3NS6OPX.js.map} +0 -0
  115. /package/dist/{parse-worker-v2-JUYUEXCY.js.map → parse-worker-v2-OXW3CQOW.js.map} +0 -0
  116. /package/dist/{parser-RNJ4KSDF.js.map → parser-B3RVTCOY.js.map} +0 -0
  117. /package/dist/{parser-EKQCZLML.js.map → parser-H6OY6UWW.js.map} +0 -0
  118. /package/dist/{pdf-ocr-EE5KGFVX.js.map → pdf-ocr-NE6Y4I6O.js.map} +0 -0
  119. /package/dist/{pdf-ocr-ZAF4P74R.js.map → pdf-ocr-QHW74LO6.js.map} +0 -0
  120. /package/dist/{profile-io-RU3RVIYV.js.map → profile-io-2IOYOBGP.js.map} +0 -0
  121. /package/dist/{rasterize-UNCPM26D.js.map → rasterize-ZLPDGEZY.js.map} +0 -0
  122. /package/dist/{redact-doc-BFE4UZCY.js.map → redact-doc-CDFM5S7S.js.map} +0 -0
  123. /package/dist/{render-3DXTLKIA.js.map → render-VXAEYSJA.js.map} +0 -0
  124. /package/dist/{seal-3LBTETDG.js.map → seal-YSBFBEXC.js.map} +0 -0
  125. /package/dist/{setup-7POQAKDG.js.map → setup-CBWVQJID.js.map} +0 -0
  126. /package/dist/{visual-7SVIGIJC.js.map → visual-MJVIFZHH.js.map} +0 -0
  127. /package/dist/{watch-37YCXJWW.js.map → watch-2SA3CTRT.js.map} +0 -0
@@ -35,14 +35,14 @@ var _chunkTK3FDAEEcjs = require('./chunk-TK3FDAEE.cjs');
35
35
 
36
36
 
37
37
 
38
- var _chunkU2VAABMKcjs = require('./chunk-U2VAABMK.cjs');
38
+ var _chunkYAK4U7CCcjs = require('./chunk-YAK4U7CC.cjs');
39
39
 
40
40
 
41
- var _chunkVPKZB6Y7cjs = require('./chunk-VPKZB6Y7.cjs');
41
+ var _chunk4ZNM7XRWcjs = require('./chunk-4ZNM7XRW.cjs');
42
42
 
43
43
 
44
44
 
45
- var _chunk2H2VYPM2cjs = require('./chunk-2H2VYPM2.cjs');
45
+ var _chunkOICA67ATcjs = require('./chunk-OICA67AT.cjs');
46
46
 
47
47
  // src/ocr/ruling-lines.ts
48
48
  var INK_LUMA_MAX = 205;
@@ -389,9 +389,10 @@ var INKLESS_DELTA = 32;
389
389
  function restoreGlyphs(rgba, pageW, box, text, steps, stepPx, note = {}) {
390
390
  const chars = [...text];
391
391
  if (chars.length !== steps.length) return text;
392
- const gray = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, pageW, box);
393
- const c = { chars, cx: (i) => (steps[i] + 0.5) * stepPx, gray, w: box.w, h: box.h, ink: _chunkU2VAABMKcjs.inkStats.call(void 0, gray) };
392
+ const gray = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, pageW, box);
393
+ const c = { chars, cx: (i) => (steps[i] + 0.5) * stepPx, gray, w: box.w, h: box.h, ink: _chunkYAK4U7CCcjs.inkStats.call(void 0, gray) };
394
394
  if (/[[\]]/.test(text)) brackets(c);
395
+ if (text.includes("'")) cornerQuotes(c);
395
396
  if (/['"]/.test(text)) quotes(c);
396
397
  if (/(^|\D)[1-9](\D|$)/.test(text)) circled(c);
397
398
  if (text.includes("*")) stars(c);
@@ -406,7 +407,7 @@ function restoreGlyphs(rgba, pageW, box, text, steps, stepPx, note = {}) {
406
407
  function trimInklessEnds(rgba, pageW, box, text, steps, stepPx) {
407
408
  const chars = [...text], { w, h } = box;
408
409
  if (chars.length !== steps.length || steps.some((s) => (s + 0.5) * stepPx > w + stepPx)) return { text, steps };
409
- const gray = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, pageW, box);
410
+ const gray = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, pageW, box);
410
411
  const hist = new Uint32Array(256);
411
412
  for (const v of gray) hist[v]++;
412
413
  let bg = 0;
@@ -437,19 +438,32 @@ function cornerCommas({ chars, cx, gray, w, h, ink }) {
437
438
  continue;
438
439
  }
439
440
  if (open > 0) {
440
- const f = _chunkU2VAABMKcjs.bracketFeatures.call(void 0, gray, w, h, ink, cx(i));
441
- if (f && _chunkU2VAABMKcjs.bracketShape.call(void 0, f, true) === "\u300D") {
441
+ const f = _chunkYAK4U7CCcjs.bracketFeatures.call(void 0, gray, w, h, ink, cx(i));
442
+ if (f && _chunkYAK4U7CCcjs.bracketShape.call(void 0, f, true) === "\u300D") {
442
443
  chars[i] = "\u300D";
443
444
  open--;
444
445
  }
445
446
  }
446
447
  }
447
448
  }
449
+ function cornerQuotes({ chars, cx, gray, w, h, ink }) {
450
+ for (let i = 0; i < chars.length; i++) {
451
+ if (chars[i] !== "'" || !/^[가-힣]/.test(_nullishCoalesce(chars[i + 1], () => ( "")))) continue;
452
+ const f = _chunkYAK4U7CCcjs.bracketFeatures.call(void 0, gray, w, h, ink, cx(i));
453
+ if (!f || f.ch < f.charH * 0.45 || _chunkYAK4U7CCcjs.bracketShape.call(void 0, f, false) !== "\u300C") continue;
454
+ const rest = chars.slice(i + 1), end = rest.findIndex((c) => c === "'" || c === "\u300D" || c === ",");
455
+ const pair = end >= 0 && rest[end] !== "'" && (rest[end] === "\u300D" || (() => {
456
+ const g = _chunkYAK4U7CCcjs.bracketFeatures.call(void 0, gray, w, h, ink, cx(i + 1 + end));
457
+ return !!g && _chunkYAK4U7CCcjs.bracketShape.call(void 0, g, true) === "\u300D";
458
+ })());
459
+ if (pair) chars[i] = "\u300C";
460
+ }
461
+ }
448
462
  function brackets({ chars, cx, gray, w, h, ink }) {
449
463
  for (let i = 0; i < chars.length; i++) {
450
464
  if (chars[i] !== "[" && chars[i] !== "]") continue;
451
- const f = _chunkU2VAABMKcjs.bracketFeatures.call(void 0, gray, w, h, ink, cx(i));
452
- const shape = f && _chunkU2VAABMKcjs.bracketShape.call(void 0, f, chars[i] === "]");
465
+ const f = _chunkYAK4U7CCcjs.bracketFeatures.call(void 0, gray, w, h, ink, cx(i));
466
+ const shape = f && _chunkYAK4U7CCcjs.bracketShape.call(void 0, f, chars[i] === "]");
453
467
  if (shape) chars[i] = shape;
454
468
  }
455
469
  }
@@ -470,7 +484,7 @@ function quotes({ chars, cx, gray, w, h, ink }) {
470
484
  continue;
471
485
  }
472
486
  if (!year(i) && !single[kind]) continue;
473
- const r = _chunkU2VAABMKcjs.quoteHead.call(void 0, gray, w, h, ink, cx(i));
487
+ const r = _chunkYAK4U7CCcjs.quoteHead.call(void 0, gray, w, h, ink, cx(i));
474
488
  if (r !== null && r >= 0.47) {
475
489
  chars[i] = kind === "'" ? "\u2018" : "\u201C";
476
490
  open[kind] = true;
@@ -481,7 +495,7 @@ function dashes({ chars, cx, gray, w, h, ink }) {
481
495
  const head = chars.findIndex((c) => c.trim()), letters = chars.some((c) => /[가-힣A-Za-z]/.test(c));
482
496
  for (let i = 0; i < chars.length; i++) {
483
497
  if (!/^[-\u2013\u2014]$/.test(chars[i])) continue;
484
- const r = _chunkU2VAABMKcjs.dashRatio.call(void 0, gray, w, h, ink, cx(i));
498
+ const r = _chunkYAK4U7CCcjs.dashRatio.call(void 0, gray, w, h, ink, cx(i));
485
499
  if (r === null) continue;
486
500
  if (r < 0.65) chars[i] = "-";
487
501
  else if (r > 0.75 && i === head && letters) chars[i] = "\u2014";
@@ -490,7 +504,7 @@ function dashes({ chars, cx, gray, w, h, ink }) {
490
504
  function circled({ chars, cx, gray, w, h, ink }) {
491
505
  const at = chars.flatMap((c, i) => /^[1-9]$/.test(c) && !/\d/.test(_nullishCoalesce(chars[i - 1], () => ( ""))) && !/\d/.test(_nullishCoalesce(chars[i + 1], () => ( ""))) ? [i] : []);
492
506
  if (!at.length) return;
493
- const hit = _chunkU2VAABMKcjs.circledAt.call(void 0, gray, w, h, ink, at.map(cx));
507
+ const hit = _chunkYAK4U7CCcjs.circledAt.call(void 0, gray, w, h, ink, at.map(cx));
494
508
  at.forEach((i, k) => {
495
509
  if (hit[k]) chars[i] = String.fromCharCode(9311 + Number(chars[i]));
496
510
  });
@@ -500,16 +514,16 @@ function stars({ chars, cx, gray, w, h, ink }) {
500
514
  if (chars[i] !== "*" || chars[i - 1] === "*") continue;
501
515
  let e = i;
502
516
  while (chars[e + 1] === "*") e++;
503
- const n = _chunkU2VAABMKcjs.starRun.call(void 0, gray, w, h, ink, cx(i));
517
+ const n = _chunkYAK4U7CCcjs.starRun.call(void 0, gray, w, h, ink, cx(i));
504
518
  if (n > e - i + 1 && n <= 4) chars[e] += "*".repeat(n - (e - i + 1));
505
519
  i = e;
506
520
  }
507
521
  }
508
522
  function discs({ chars, cx, gray, w, h, ink }) {
509
- for (let i = 0; i < chars.length; i++) if (/^[\u00b7\u2022]$/.test(chars[i]) && _chunkU2VAABMKcjs.discAt.call(void 0, gray, w, h, ink, cx(i))) chars[i] = "\u25CF";
523
+ for (let i = 0; i < chars.length; i++) if (/^[\u00b7\u2022]$/.test(chars[i]) && _chunkYAK4U7CCcjs.discAt.call(void 0, gray, w, h, ink, cx(i))) chars[i] = "\u25CF";
510
524
  }
511
525
  function gaps({ chars, cx, gray, w, h, ink }) {
512
- const { glyphs, bandH } = _chunkU2VAABMKcjs.gapGlyphs.call(void 0, gray, w, h, ink);
526
+ const { glyphs, bandH } = _chunkYAK4U7CCcjs.gapGlyphs.call(void 0, gray, w, h, ink);
513
527
  if (!glyphs.length) return;
514
528
  const live = chars.map((c, i) => i).filter((i) => chars[i].trim());
515
529
  if (!live.length) return;
@@ -530,6 +544,7 @@ function gaps({ chars, cx, gray, w, h, ink }) {
530
544
  }
531
545
  if (cover.length) {
532
546
  if (g.mark.startsWith("\u25A1") && cover.length === 1 && /^[0Oo\u25cb]$/.test(chars[cover[0]])) chars[cover[0]] = "\u25A1";
547
+ if (g.mark === "\u3002" && cover.length === 1 && /^[\u00b7\u2022\u318d]$/.test(chars[cover[0]])) chars[cover[0]] = "\u3002";
533
548
  continue;
534
549
  }
535
550
  if (g.mark === "\u25A1\0") continue;
@@ -546,6 +561,14 @@ function gaps({ chars, cx, gray, w, h, ink }) {
546
561
  if (loose.some((o) => o !== g && Math.abs((o.x0 + o.x1) / 2 - mid) <= pitch * 1.5)) continue;
547
562
  if (/[\u2026.\u00b7]$/.test(prev) || /^[\u2026.\u00b7]/.test(next)) continue;
548
563
  }
564
+ if (g.mark === "\u300C") {
565
+ let sp = chars.findIndex((c, i) => c === " " && near(i));
566
+ if (sp >= 0) while (chars[sp + 1] === " ") sp++;
567
+ if (sp >= 0) {
568
+ chars[sp] = g.mark;
569
+ continue;
570
+ }
571
+ }
549
572
  if (g.mark === "\xB7") {
550
573
  if (/^\d/.test(next)) continue;
551
574
  const sp = chars.findIndex((c, i) => c === " " && near(i));
@@ -559,10 +582,23 @@ function gaps({ chars, cx, gray, w, h, ink }) {
559
582
  }
560
583
  function ring({ chars, cx, gray, w, h, ink }) {
561
584
  const k = chars.findIndex((c) => c.trim());
562
- if (k < 0 || !/^[\u3147Oo0\u25cb]$/.test(chars[k])) return false;
585
+ if (k < 0 || !/^[\u3147Oo0\u25cbCc]$/.test(chars[k])) return false;
563
586
  const rest = chars.slice(k + 1).join("").trimStart();
587
+ const live = chars.map((c, i) => i).filter((i) => chars[i].trim());
588
+ if (live.length <= 3 && live.every((i) => /^[Oo]$/.test(chars[i]))) {
589
+ if (_optionalChain([_chunkYAK4U7CCcjs.leadingBullet.call(void 0, gray, w, h, ink, cx(live[0])), 'optionalAccess', _2 => _2.mark]) === "\u25CE") return false;
590
+ if (!live.every((i) => _chunkYAK4U7CCcjs.ringBullet.call(void 0, gray, w, h, ink, cx(i)) === "\u25CB")) return false;
591
+ for (const i of live) chars[i] = "\u25CB";
592
+ return true;
593
+ }
594
+ if (/^[A-Z]{2,}/.test(rest) && /^[Oo0]$/.test(chars[k])) {
595
+ if (_chunkYAK4U7CCcjs.ringBullet.call(void 0, gray, w, h, ink, cx(k)) !== "\u25CB") return false;
596
+ chars[k] = chars[k + 1] === " " ? "\u25CB" : "\u25CB ";
597
+ return true;
598
+ }
564
599
  if (!/^[(\[「【<]?\d*[가-힣]/.test(rest)) return false;
565
- const r = _chunkU2VAABMKcjs.ringBullet.call(void 0, gray, w, h, ink, cx(k));
600
+ const r = _chunkYAK4U7CCcjs.ringBullet.call(void 0, gray, w, h, ink, cx(k));
601
+ if (/^[Cc]$/.test(chars[k]) && r !== "\u25CB") return false;
566
602
  if (r) chars[k] = r;
567
603
  return r !== null;
568
604
  }
@@ -570,7 +606,7 @@ function roman({ chars, cx, gray, w, h, ink }) {
570
606
  const ROMAN = /^[IⅠ-Ⅲ]$/, LATIN = /[A-Za-z]$/;
571
607
  for (let i = 0; i < chars.length; i++) {
572
608
  if (chars[i] !== "1" || /[\dA-Za-z]$/.test(_nullishCoalesce(chars[i - 1], () => ( ""))) || /^[\dA-Za-z,]/.test(_nullishCoalesce(chars[i + 1], () => ( "")))) continue;
573
- if (_chunkU2VAABMKcjs.serifOne.call(void 0, gray, w, h, ink, cx(i))) chars[i] = "\u2160";
609
+ if (_chunkYAK4U7CCcjs.serifOne.call(void 0, gray, w, h, ink, cx(i))) chars[i] = "\u2160";
574
610
  }
575
611
  for (let i = 0; i < chars.length; i++) {
576
612
  if (chars[i] !== "|" || chars[i - 1] === "|" || chars[i + 1] === "|") continue;
@@ -579,13 +615,13 @@ function roman({ chars, cx, gray, w, h, ink }) {
579
615
  while (q < chars.length && !chars[q].trim()) q++;
580
616
  const glued = /[가-힣]$/.test(_nullishCoalesce(chars[i - 1], () => ( ""))) || (_nullishCoalesce(chars[i + 1], () => ( ""))) === "." || chars[p] === "-" && chars[q] === "-";
581
617
  if (!glued) continue;
582
- const n = _chunkU2VAABMKcjs.romanStems.call(void 0, gray, w, h, ink, p >= 0 ? cx(p) : -Infinity, q < chars.length ? cx(q) : Infinity);
618
+ const n = _chunkYAK4U7CCcjs.romanStems.call(void 0, gray, w, h, ink, p >= 0 ? cx(p) : -Infinity, q < chars.length ? cx(q) : Infinity);
583
619
  if (n) chars[i] = String.fromCharCode(8543 + n);
584
620
  }
585
621
  const inRoman = (i) => ROMAN.test(chars[i]) || chars[i] === "1" && (ROMAN.test(_nullishCoalesce(chars[i - 1], () => ( ""))) || ROMAN.test(_nullishCoalesce(chars[i + 1], () => ( ""))));
586
622
  const k = chars.findIndex((c) => c.trim());
587
623
  if (chars[k] === "." && chars.slice(k + 1).some((c) => /[가-힣A-Za-z0-9]/.test(c))) {
588
- const n = _chunkU2VAABMKcjs.romanStems.call(void 0, gray, w, h, ink, -Infinity, cx(k));
624
+ const n = _chunkYAK4U7CCcjs.romanStems.call(void 0, gray, w, h, ink, -Infinity, cx(k));
589
625
  if (n) chars[k] = String.fromCharCode(8543 + n) + chars[k];
590
626
  }
591
627
  for (let s = 0; s < chars.length; ) {
@@ -603,7 +639,7 @@ function roman({ chars, cx, gray, w, h, ink }) {
603
639
  let p = s - 1, q = e;
604
640
  while (p >= 0 && !chars[p].trim()) p--;
605
641
  while (q < chars.length && !chars[q].trim()) q++;
606
- const n = _chunkU2VAABMKcjs.romanStems.call(void 0, gray, w, h, ink, p >= 0 ? cx(p) : -Infinity, q < chars.length ? cx(q) : Infinity);
642
+ const n = _chunkYAK4U7CCcjs.romanStems.call(void 0, gray, w, h, ink, p >= 0 ? cx(p) : -Infinity, q < chars.length ? cx(q) : Infinity);
607
643
  const canon = n ? [["\u2160", "I"], ["\u2161", "II"], ["\u2162", "III"]][n - 1] : null;
608
644
  if (canon && !canon.includes(tok)) {
609
645
  chars[s] = canon[0];
@@ -622,6 +658,7 @@ function restoreSymbols(text, ringDecided = false) {
622
658
  s = s.replace(/[\u2206\u0394]/g, "\u25B3");
623
659
  s = s.replace(/\(cid:\d*\)/g, "");
624
660
  s = s.replace(/(^|[^\uac00-\ud7a3])(전|현)\(\s?\)(?=\S)/g, (_, a, b) => `${a}${b}(${b === "\uC804" ? "\u524D" : "\u73FE"})`);
661
+ if (/[가-힣]/.test(s)) s = s.replace(/(\d)l(?![A-Za-z])/g, "$1\u2113");
625
662
  s = s.replace(/([((])\s?[A-Za-z@&]\s?(?=(?:0\d{1,2}-)?\d{3,4}-\d{4}\b)/g, "$1\u260E");
626
663
  return smartQuotes(dateDots(dateCommas(joinDigitGroups(s))));
627
664
  }
@@ -696,7 +733,7 @@ function joinLeaderItems(items, ends) {
696
733
  for (const o of items) if (!gone.has(o) && junk(o) && sameLine(o, left) && o.x + o.w / 2 >= left.x + left.w - left.h && o.x + o.w / 2 <= right.x + right.h) gone.add(o);
697
734
  };
698
735
  for (const it of [...items].sort((a, b) => b.x - a.x)) {
699
- if (gone.has(it) || !_optionalChain([ends, 'access', _2 => _2.get, 'call', _3 => _3(it), 'optionalAccess', _4 => _4.lead])) continue;
736
+ if (gone.has(it) || !_optionalChain([ends, 'access', _3 => _3.get, 'call', _4 => _4(it), 'optionalAccess', _5 => _5.lead])) continue;
700
737
  const left = neighbor(it, true);
701
738
  if (left) {
702
739
  dropJunkBetween(left, it);
@@ -704,7 +741,7 @@ function joinLeaderItems(items, ends) {
704
741
  }
705
742
  }
706
743
  for (const it of [...items].sort((a, b) => a.x - b.x)) {
707
- if (gone.has(it) || !_optionalChain([ends, 'access', _5 => _5.get, 'call', _6 => _6(it), 'optionalAccess', _7 => _7.trail])) continue;
744
+ if (gone.has(it) || !_optionalChain([ends, 'access', _6 => _6.get, 'call', _7 => _7(it), 'optionalAccess', _8 => _8.trail])) continue;
708
745
  const right = neighbor(it, false);
709
746
  if (right) {
710
747
  dropJunkBetween(it, right);
@@ -869,6 +906,247 @@ var MIN_INK_RATIO = 0.01;
869
906
  var MAX_LOCAL_MODEL_BYTES = 1024 * 1024 * 1024;
870
907
  var DET_MEAN = [0.485, 0.456, 0.406];
871
908
  var DET_STD = [0.229, 0.224, 0.225];
909
+ function rowHeadDashes(rgba, width, items) {
910
+ const out = [];
911
+ const dark = (x, y) => {
912
+ const p = (y * width + x) * 4;
913
+ return rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29 >> 8 < 160;
914
+ };
915
+ const inBox = (x, y) => items.some((b) => x >= b.x && x < b.x + b.w && y >= b.y && y < b.y + b.h);
916
+ const done = /* @__PURE__ */ new Set();
917
+ for (const it of [...items]) {
918
+ if (done.has(it) || it.h < 12) continue;
919
+ const row = items.filter((o) => Math.min(o.y + o.h, it.y + it.h) - Math.max(o.y, it.y) >= Math.min(o.h, it.h) * 0.6);
920
+ for (const o of row) done.add(o);
921
+ if (row.reduce((k, o) => k + (_nullishCoalesce(_optionalChain([o, 'access', _9 => _9.text, 'access', _10 => _10.match, 'call', _11 => _11(/[가-힣]/g), 'optionalAccess', _12 => _12.length]), () => ( 0))), 0) < 2) continue;
922
+ const first = row.reduce((m, o) => o.x < m.x ? o : m);
923
+ if (!/^[가-힣]/.test(first.text)) continue;
924
+ if (row.filter((o) => /\d/.test(o.text)).length >= 2) continue;
925
+ const y0 = Math.min(...row.map((o) => o.y)), y1 = Math.max(...row.map((o) => o.y + o.h)), h = y1 - y0;
926
+ const x0 = Math.max(0, Math.round(first.x - 2.5 * h)), x1 = first.x - 2;
927
+ let minX = -1, maxX = -1, minY = Infinity, maxY = -1, groups = 0;
928
+ for (let x = x0; x < x1; x++) {
929
+ let on = false;
930
+ for (let y = y0; y < y1; y++) if (dark(x, y) && !inBox(x, y)) {
931
+ on = true;
932
+ if (y < minY) minY = y;
933
+ if (y > maxY) maxY = y;
934
+ }
935
+ if (!on) continue;
936
+ if (maxX < 0 || x - maxX > 2) {
937
+ groups++;
938
+ if (groups === 1) minX = x;
939
+ }
940
+ maxX = x;
941
+ }
942
+ const bw = maxX - minX + 1, bh = maxY - minY + 1, cy = ((minY + maxY) / 2 - y0) / h;
943
+ if (groups !== 1 || bh > h * 0.2 || bw < h * 0.3 || bw > h * 1.2 || cy < 0.3 || cy > 0.7) continue;
944
+ const faint = (x, y) => {
945
+ const p = (y * width + x) * 4;
946
+ return rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29 >> 8 < 230;
947
+ };
948
+ let touch = minX <= x0;
949
+ for (let y = minY; y <= maxY && !touch; y++) for (let d = 2; d <= 4 && !touch; d++) touch = minX - d >= 0 && faint(minX - d, y) || faint(maxX + d, y);
950
+ if (touch) continue;
951
+ out.push({ text: "-", x: minX, y: y0, w: bw, h, confidence: first.confidence });
952
+ }
953
+ return out;
954
+ }
955
+ function rowTailBoxes(rgba, width, items) {
956
+ const out = [];
957
+ const dark = (x, y) => {
958
+ const p = (y * width + x) * 4;
959
+ return rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29 >> 8 < 160;
960
+ };
961
+ const done = /* @__PURE__ */ new Set();
962
+ for (const it of items) {
963
+ if (done.has(it) || it.h < 12) continue;
964
+ const row = items.filter((o) => Math.min(o.y + o.h, it.y + it.h) - Math.max(o.y, it.y) >= Math.min(o.h, it.h) * 0.6);
965
+ for (const o of row) done.add(o);
966
+ if (row.reduce((k, o) => k + (_nullishCoalesce(_optionalChain([o, 'access', _13 => _13.text, 'access', _14 => _14.match, 'call', _15 => _15(/[가-힣]/g), 'optionalAccess', _16 => _16.length]), () => ( 0))), 0) < 2) continue;
967
+ const last = row.reduce((m, o) => o.x + o.w > m.x + m.w ? o : m);
968
+ if (/\d$/.test(last.text.trim())) continue;
969
+ const y0 = Math.min(...row.map((o) => o.y)), y1 = Math.max(...row.map((o) => o.y + o.h)), h = y1 - y0;
970
+ const x0 = last.x + last.w + 4, x1 = Math.floor(width * 0.95);
971
+ if (x1 - x0 < h) continue;
972
+ let groups = 0, minX = -1, maxX = -1, minY = Infinity, maxY = -1;
973
+ for (let x = x0; x < x1; x++) {
974
+ let on = false;
975
+ for (let y = y0; y < y1; y++) if (dark(x, y)) {
976
+ on = true;
977
+ if (y < minY) minY = y;
978
+ if (y > maxY) maxY = y;
979
+ }
980
+ if (!on) continue;
981
+ if (maxX < 0 || x - maxX > h) {
982
+ groups++;
983
+ if (groups === 1) minX = x;
984
+ }
985
+ maxX = x;
986
+ }
987
+ if (groups !== 1 || maxY - minY + 1 < h * 0.5 || maxX - minX + 1 > h * 4) continue;
988
+ const height = Math.floor(rgba.length / 4 / width);
989
+ let rule = false;
990
+ for (let x = minX; x <= maxX && !rule; x++) rule = minY > 1 && dark(x, minY - 2) || maxY + 2 < height && dark(x, maxY + 2);
991
+ if (rule) continue;
992
+ const pad = 4;
993
+ out.push({ x: Math.max(0, minX - pad), y: Math.max(0, minY - pad), w: maxX - minX + 1 + 2 * pad, h: maxY - minY + 1 + 2 * pad });
994
+ }
995
+ return out;
996
+ }
997
+ function placeholderSquares(rgba, width, height, items) {
998
+ const dark = new Uint8Array(width * height);
999
+ for (let p = 0, i = 0; p < dark.length; p++, i += 4) dark[p] = rgba[i] * 77 + rgba[i + 1] * 150 + rgba[i + 2] * 29 >> 8 < 128 ? 1 : 0;
1000
+ const covered = (x, y) => items.some((b) => x >= b.x - 2 && x < b.x + b.w + 2 && y >= b.y - 2 && y < b.y + b.h + 2);
1001
+ const seen = new Uint8Array(width * height);
1002
+ const squares = [], bars = [];
1003
+ const stack = [];
1004
+ for (let start = 0; start < dark.length; start++) {
1005
+ if (!dark[start] || seen[start]) continue;
1006
+ const c = { x0: width, y0: height, x1: -1, y1: -1, n: 0, px: [] };
1007
+ stack.push(start);
1008
+ seen[start] = 1;
1009
+ while (stack.length) {
1010
+ const p = stack.pop(), x = p % width, y = (p - x) / width;
1011
+ c.n++;
1012
+ if (c.px.length < 4e3) c.px.push(p);
1013
+ if (x < c.x0) c.x0 = x;
1014
+ if (x > c.x1) c.x1 = x;
1015
+ if (y < c.y0) c.y0 = y;
1016
+ if (y > c.y1) c.y1 = y;
1017
+ for (const q of [p - 1, p + 1, p - width, p + width]) if (q >= 0 && q < dark.length && !seen[q] && dark[q] && Math.abs(q % width - x) <= 1) {
1018
+ seen[q] = 1;
1019
+ stack.push(q);
1020
+ }
1021
+ if (c.n > 4e3) break;
1022
+ }
1023
+ while (stack.length) {
1024
+ const p = stack.pop();
1025
+ seen[p] = 1;
1026
+ }
1027
+ const w = c.x1 - c.x0 + 1, h = c.y1 - c.y0 + 1;
1028
+ if (c.n > 4e3 || covered(c.x0 + c.x1 >> 1, c.y0 + c.y1 >> 1)) continue;
1029
+ if (h >= 2 && h <= 6 && w >= 4 && w <= 30 && c.n >= w * h * 0.7) {
1030
+ bars.push(c);
1031
+ continue;
1032
+ }
1033
+ if (w < 12 || h < 12 || w > 60 || h > 60 || w > h * 1.33 || h > w * 1.33) continue;
1034
+ const at = (x, y) => dark[y * width + x] === 1;
1035
+ const row = (y) => {
1036
+ let k = 0;
1037
+ for (let x = c.x0; x <= c.x1; x++) if (at(x, y)) k++;
1038
+ return k / w;
1039
+ };
1040
+ const col = (x) => {
1041
+ let k = 0;
1042
+ for (let y = c.y0; y <= c.y1; y++) if (at(x, y)) k++;
1043
+ return k / h;
1044
+ };
1045
+ const edge = (vals) => Math.max(...vals) >= 0.8;
1046
+ const top = edge([row(c.y0), row(c.y0 + 1)]), bottom = edge([row(c.y1), row(c.y1 - 1)]), left = edge([col(c.x0), col(c.x0 + 1)]), right = edge([col(c.x1), col(c.x1 - 1)]);
1047
+ let inner = 0;
1048
+ for (let y = c.y0 + Math.ceil(h * 0.25); y <= c.y1 - Math.ceil(h * 0.25); y++) for (let x = c.x0 + Math.ceil(w * 0.25); x <= c.x1 - Math.ceil(w * 0.25); x++) if (at(x, y)) inner++;
1049
+ if (top && bottom && left && right && inner === 0) squares.push(c);
1050
+ }
1051
+ squares.sort((a, b) => a.y0 - b.y0 || a.x0 - b.x0);
1052
+ const out = [];
1053
+ const used = /* @__PURE__ */ new Set();
1054
+ for (const s0 of squares) {
1055
+ if (used.has(s0)) continue;
1056
+ const run = [s0];
1057
+ used.add(s0);
1058
+ const side = s0.y1 - s0.y0 + 1, cy = (s0.y0 + s0.y1) / 2;
1059
+ let text = "\u25A1";
1060
+ for (; ; ) {
1061
+ const last = run[run.length - 1];
1062
+ const next = squares.find((q) => !used.has(q) && Math.abs((q.y0 + q.y1) / 2 - cy) <= side * 0.3 && q.x0 > last.x1 && q.x0 - last.x1 <= side * 2);
1063
+ if (!next) break;
1064
+ const gap = next.x0 - last.x1;
1065
+ const bar = bars.find((b) => b.x0 > last.x1 && b.x1 < next.x0 && Math.abs((b.y0 + b.y1) / 2 - cy) <= side * 0.3);
1066
+ let stroke = 0;
1067
+ if (!bar) for (let y = Math.round(cy - side * 0.15); y <= Math.round(cy + side * 0.15); y++) {
1068
+ let k = 0;
1069
+ for (let x = last.x1 + 1; x < next.x0; x++) {
1070
+ k = dark[y * width + x] ? k + 1 : 0;
1071
+ if (k > stroke) stroke = k;
1072
+ }
1073
+ }
1074
+ if (bar || stroke >= Math.max(4, side * 0.25)) text += "-";
1075
+ else if (gap > side) break;
1076
+ text += "\u25A1";
1077
+ used.add(next);
1078
+ run.push(next);
1079
+ }
1080
+ const x0 = run[0].x0, x1 = run[run.length - 1].x1;
1081
+ out.push({ text, x: x0, y: s0.y0, w: x1 - x0 + 1, h: side, confidence: 0.9 });
1082
+ }
1083
+ return out;
1084
+ }
1085
+ function footerInkBox(rgba, width, height, boxes) {
1086
+ const y0 = Math.floor(height * 0.88), x0 = Math.floor(width * 0.3), x1 = Math.ceil(width * 0.7);
1087
+ let minX = Infinity, maxX = -1, minY = Infinity, maxY = -1;
1088
+ for (let y = y0; y < height; y++) for (let x = x0; x < x1; x++) {
1089
+ const p = (y * width + x) * 4;
1090
+ if (rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29 >> 8 >= 128) continue;
1091
+ if (boxes.some((b) => x >= b.x && x < b.x + b.w && y >= b.y && y < b.y + b.h)) continue;
1092
+ if (x < minX) minX = x;
1093
+ if (x > maxX) maxX = x;
1094
+ if (y < minY) minY = y;
1095
+ if (y > maxY) maxY = y;
1096
+ }
1097
+ if (maxX < 0) return null;
1098
+ const bh = maxY - minY + 1;
1099
+ if (bh < height * 5e-3 || bh > height * 0.025 || maxX - minX + 1 > width * 0.2) return null;
1100
+ const pad = 4, bx = Math.max(0, minX - pad), by = Math.max(0, minY - pad);
1101
+ return { x: bx, y: by, w: Math.min(width, maxX + pad + 1) - bx, h: Math.min(height, maxY + pad + 1) - by };
1102
+ }
1103
+ function closingParens(rgba, width, items) {
1104
+ const out = [];
1105
+ const dark = (x, y) => {
1106
+ const p = (y * width + x) * 4;
1107
+ return rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29 >> 8 < 128;
1108
+ };
1109
+ for (const it of items) {
1110
+ const t = it.text.replace(/\s+$/, "");
1111
+ if ((_nullishCoalesce(_optionalChain([t, 'access', _17 => _17.match, 'call', _18 => _18(/\(/g), 'optionalAccess', _19 => _19.length]), () => ( 0))) <= (_nullishCoalesce(_optionalChain([t, 'access', _20 => _20.match, 'call', _21 => _21(/\)/g), 'optionalAccess', _22 => _22.length]), () => ( 0))) || !/\([^()]*$/.test(t)) continue;
1112
+ const x0 = it.x + it.w + 2;
1113
+ 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);
1114
+ const x1 = Math.min(width, next, x0 + it.h * 8);
1115
+ let minX = Infinity, maxX = -1, minY = Infinity, maxY = -1, cols = 0, prevOn = false, runs = 0;
1116
+ for (let x = x0; x < x1; x++) {
1117
+ let on = false;
1118
+ for (let y = it.y; y < it.y + it.h; y++) if (dark(x, y)) {
1119
+ on = true;
1120
+ if (y < minY) minY = y;
1121
+ if (y > maxY) maxY = y;
1122
+ }
1123
+ if (on) {
1124
+ cols++;
1125
+ if (!prevOn) runs++;
1126
+ if (x < minX) minX = x;
1127
+ maxX = x;
1128
+ }
1129
+ prevOn = on;
1130
+ }
1131
+ if (runs !== 1 || maxX - minX + 1 > it.h * 0.5 || maxY - minY + 1 < it.h * 0.6) continue;
1132
+ let rule = false;
1133
+ 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));
1134
+ if (rule) continue;
1135
+ const meanX = (ya, yb) => {
1136
+ let sx = 0, k = 0;
1137
+ for (let y = ya; y < yb; y++) for (let x = minX; x <= maxX; x++) if (dark(x, y)) {
1138
+ sx += x;
1139
+ k++;
1140
+ }
1141
+ return k ? sx / k : NaN;
1142
+ };
1143
+ const ch = maxY - minY + 1, band = Math.max(1, Math.round(ch * 0.2));
1144
+ 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));
1145
+ if (!(mid - ends >= 0.8)) continue;
1146
+ out.push({ text: ")", x: minX, y: minY, w: maxX - minX + 1, h: maxY - minY + 1, confidence: it.confidence });
1147
+ }
1148
+ return out;
1149
+ }
872
1150
  var OcrEngine = class _OcrEngine {
873
1151
 
874
1152
 
@@ -882,7 +1160,7 @@ var OcrEngine = class _OcrEngine {
882
1160
  this.ort = parts.ort;
883
1161
  this.sharp = parts.sharp;
884
1162
  }
885
- static async create(models = _chunkU2VAABMKcjs.DEFAULT_OCR_MODELS) {
1163
+ static async create(models = _chunkYAK4U7CCcjs.DEFAULT_OCR_MODELS) {
886
1164
  _chunkTK3FDAEEcjs.disableOrtTelemetry.call(void 0, );
887
1165
  const [ortMod, sharpModRaw] = await Promise.all([
888
1166
  tryImport("onnxruntime-node", () => Promise.resolve().then(() => _interopRequireWildcard(require("onnxruntime-node")))),
@@ -902,16 +1180,16 @@ var OcrEngine = class _OcrEngine {
902
1180
  const local = (s) => "spec" in s ? Promise.resolve(null) : verifiedBytes(s);
903
1181
  const [detBytes, recBytes, dictBytes] = await Promise.all([local(models.det), local(models.rec), local(models.dict)]);
904
1182
  const session = (s, bytes) => bytes ? ortMod.InferenceSession.create(bytes, sessionOpts).catch(() => {
905
- throw new (0, _chunk2H2VYPM2cjs.KordocError)(`OCR \uBAA8\uB378\uC744 \uC5F4\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${_path.basename.call(void 0, _chunkU2VAABMKcjs.ocrSourcePath.call(void 0, s))} \u2014 ONNX \uBAA8\uB378\uC774 \uC544\uB2C8\uAC70\uB098 \uC190\uC0C1\uB410\uC2B5\uB2C8\uB2E4`);
906
- }) : ortMod.InferenceSession.create(_chunkU2VAABMKcjs.ocrSourcePath.call(void 0, s), sessionOpts);
1183
+ throw new (0, _chunkOICA67ATcjs.KordocError)(`OCR \uBAA8\uB378\uC744 \uC5F4\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${_path.basename.call(void 0, _chunkYAK4U7CCcjs.ocrSourcePath.call(void 0, s))} \u2014 ONNX \uBAA8\uB378\uC774 \uC544\uB2C8\uAC70\uB098 \uC190\uC0C1\uB410\uC2B5\uB2C8\uB2E4`);
1184
+ }) : ortMod.InferenceSession.create(_chunkYAK4U7CCcjs.ocrSourcePath.call(void 0, s), sessionOpts);
907
1185
  const [det, rec, dictYml] = await Promise.all([
908
1186
  session(models.det, detBytes),
909
1187
  session(models.rec, recBytes),
910
- dictBytes ? new TextDecoder().decode(dictBytes) : _promises.readFile.call(void 0, _chunkU2VAABMKcjs.ocrSourcePath.call(void 0, models.dict), "utf-8")
1188
+ dictBytes ? new TextDecoder().decode(dictBytes) : _promises.readFile.call(void 0, _chunkYAK4U7CCcjs.ocrSourcePath.call(void 0, models.dict), "utf-8")
911
1189
  ]);
912
- const dict = _chunkU2VAABMKcjs.parseCharacterDict.call(void 0, dictYml);
1190
+ const dict = _chunkYAK4U7CCcjs.parseCharacterDict.call(void 0, dictYml);
913
1191
  if (dict.length === 0) {
914
- throw "spec" in models.dict ? new Error("OCR \uC0AC\uC804 \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uBAA8\uB378 \uCE90\uC2DC\uB97C \uC0AD\uC81C \uD6C4 \uC7AC\uB2E4\uC6B4\uB85C\uB4DC\uD558\uC138\uC694") : new (0, _chunk2H2VYPM2cjs.KordocError)(`OCR \uC0AC\uC804 \uD30C\uC2F1 \uC2E4\uD328 \u2014 ${_path.basename.call(void 0, models.dict.file.path)} \uC5D0 PostProcess.character_dict \uBAA9\uB85D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4`);
1192
+ throw "spec" in models.dict ? new Error("OCR \uC0AC\uC804 \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uBAA8\uB378 \uCE90\uC2DC\uB97C \uC0AD\uC81C \uD6C4 \uC7AC\uB2E4\uC6B4\uB85C\uB4DC\uD558\uC138\uC694") : new (0, _chunkOICA67ATcjs.KordocError)(`OCR \uC0AC\uC804 \uD30C\uC2F1 \uC2E4\uD328 \u2014 ${_path.basename.call(void 0, models.dict.file.path)} \uC5D0 PostProcess.character_dict \uBAA9\uB85D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4`);
915
1193
  }
916
1194
  return new _OcrEngine({ det, rec, dict, ort: ortMod, sharp: sharpMod });
917
1195
  }
@@ -943,10 +1221,10 @@ var OcrEngine = class _OcrEngine {
943
1221
  if (it.x - x < it.h * 0.8) return;
944
1222
  if (items.some((o) => o !== it && o.x < it.x && o.x + o.w > x && o.y < it.y + it.h && o.y + o.h > it.y)) return;
945
1223
  const box = { x, y: it.y, w: it.x + it.w - x, h: it.h };
946
- const g = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, width, box);
947
- const b = _chunkU2VAABMKcjs.leadingBullet.call(void 0, g, box.w, box.h, _chunkU2VAABMKcjs.inkStats.call(void 0, g), it.x - x, 1.05);
948
- if (_optionalChain([b, 'optionalAccess', _8 => _8.mark]) !== "\u25A1" || b.covers) return;
949
- const ink = _chunkU2VAABMKcjs.inkStats.call(void 0, g), on = (v) => ink.darkInk ? v <= ink.threshold : v > ink.threshold;
1224
+ const g = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, box);
1225
+ const b = _chunkYAK4U7CCcjs.leadingBullet.call(void 0, g, box.w, box.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, g), it.x - x, 1.05);
1226
+ if (_optionalChain([b, 'optionalAccess', _23 => _23.mark]) !== "\u25A1" || b.covers) return;
1227
+ const ink = _chunkYAK4U7CCcjs.inkStats.call(void 0, g), on = (v) => ink.darkInk ? v <= ink.threshold : v > ink.threshold;
950
1228
  let left = 0;
951
1229
  while (left < it.x - x && !Array.from({ length: box.h }, (_, y) => g[y * box.w + left]).some(on)) left++;
952
1230
  it.text = "\u25A1 " + it.text;
@@ -958,16 +1236,17 @@ var OcrEngine = class _OcrEngine {
958
1236
  const detected = await this.detect(rgba, width, height, tuning, stats);
959
1237
  const rows = rowRules.length ? detected.flatMap((b) => splitBoxAtRowRules(b, rowRules)) : detected;
960
1238
  const boxes = cellRules.length ? rows.flatMap((b) => splitBoxAtCellRules(b, cellRules)) : rows;
1239
+ const footer = tuning.postprocess ? footerInkBox(rgba, width, height, boxes) : null;
961
1240
  const jobs = [];
962
1241
  const joins = [];
963
1242
  let group = 0;
964
1243
  for (const b of boxes) {
965
- const gray = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, width, b);
966
- const ink = _chunkU2VAABMKcjs.inkStats.call(void 0, gray);
1244
+ const gray = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, b);
1245
+ const ink = _chunkYAK4U7CCcjs.inkStats.call(void 0, gray);
967
1246
  if (tuning.minInkContrast > 0 && ink.contrast < tuning.minInkContrast) continue;
968
1247
  if (tuning.minInkContrast > 0 && ink.inkRatio < MIN_INK_RATIO) continue;
969
1248
  if (tuning.splitTall && b.h >= b.w * TALL_RATIO) {
970
- const bands = _chunkU2VAABMKcjs.splitRowBands.call(void 0, gray, b.w, b.h, ink, 0.45);
1249
+ const bands = _chunkYAK4U7CCcjs.splitRowBands.call(void 0, gray, b.w, b.h, ink, 0.45);
971
1250
  if (bands.length >= 2) {
972
1251
  for (const sub of bandBoxes(b, bands, height)) jobs.push({ box: sub, rot: 0, group: group++ });
973
1252
  continue;
@@ -978,9 +1257,9 @@ var OcrEngine = class _OcrEngine {
978
1257
  continue;
979
1258
  }
980
1259
  }
981
- const trim = tuning.trimEdges ? _chunkU2VAABMKcjs.edgeTrim.call(void 0, gray, b.w, b.h, ink) : null;
1260
+ const trim = tuning.trimEdges ? _chunkYAK4U7CCcjs.edgeTrim.call(void 0, gray, b.w, b.h, ink) : null;
982
1261
  const keep = trim ? { ...trim, bg: median(gray) } : void 0;
983
- const leaders = tuning.splitLeaders ? _chunkU2VAABMKcjs.leaderRuns.call(void 0, gray, b.w, b.h, ink, LEADER_MIN_DOTS) : [];
1262
+ const leaders = tuning.splitLeaders ? _chunkYAK4U7CCcjs.leaderRuns.call(void 0, gray, b.w, b.h, ink, LEADER_MIN_DOTS) : [];
984
1263
  if (leaders.length) {
985
1264
  const join = joins.length;
986
1265
  joins.push({ box: b, parts: [], trailDots: false });
@@ -989,7 +1268,7 @@ var OcrEngine = class _OcrEngine {
989
1268
  const bare = { x: b.x + x0, y: b.y, w: a - x0, h: b.h };
990
1269
  const end = c > a ? Math.min(c, a + Math.round(b.h * LEADER_CONTEXT)) : a;
991
1270
  x0 = c;
992
- if (bare.w >= DET_MIN_SIZE && _chunkU2VAABMKcjs.inkStats.call(void 0, _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, width, bare)).contrast >= Math.max(1, tuning.minInkContrast)) {
1271
+ if (bare.w >= DET_MIN_SIZE && _chunkYAK4U7CCcjs.inkStats.call(void 0, _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, bare)).contrast >= Math.max(1, tuning.minInkContrast)) {
993
1272
  jobs.push({ box: { ...bare, w: end - (bare.x - b.x) }, rot: 0, group: group++, join, dotsBefore: dots, trimDots: end > a });
994
1273
  dots = false;
995
1274
  }
@@ -1001,6 +1280,7 @@ var OcrEngine = class _OcrEngine {
1001
1280
  if (keep) jobs.push({ box: b, rot: 0, group, keep });
1002
1281
  jobs.push({ box: b, rot: 0, group: group++ });
1003
1282
  }
1283
+ if (footer) jobs.push({ box: footer, rot: 0, group: group++, footer: true });
1004
1284
  const results = await this.recognizeJobs(rgba, width, jobs, tuning.recBatch);
1005
1285
  const best = /* @__PURE__ */ new Map();
1006
1286
  const score = (job, confidence) => confidence - (job.keep ? KEEP_MARGIN : 0);
@@ -1010,6 +1290,12 @@ var OcrEngine = class _OcrEngine {
1010
1290
  const cur = best.get(job.group);
1011
1291
  if (!cur || score(job, r.confidence) > score(cur.job, cur.confidence)) best.set(job.group, { job, ...r });
1012
1292
  });
1293
+ jobs.forEach((job, i) => {
1294
+ const r = results[i], cur = best.get(job.group);
1295
+ if (!job.keep || !r || !cur || cur.job === job) return;
1296
+ const b = cur.text.replace(/\s/g, "");
1297
+ if (r.text.replace(/\s/g, "") === "\xB7" + b && /^[가-힣]/.test(b)) best.set(job.group, { ...cur, text: "\xB7" + cur.text, steps: [r.steps[0], ...cur.steps] });
1298
+ });
1013
1299
  let items = [];
1014
1300
  for (const r of best.values()) {
1015
1301
  const { job, confidence, stepPx } = r;
@@ -1018,38 +1304,48 @@ var OcrEngine = class _OcrEngine {
1018
1304
  const raw = tuning.postprocess && job.rot === 0 ? restoreGlyphs(rgba, width, job.box, read, steps, stepPx, note) : read;
1019
1305
  let text = tuning.postprocess ? restoreSymbols(raw.trim(), note.ringLead) : raw;
1020
1306
  if (!text.trim()) continue;
1021
- if (tuning.postprocess && job.rot === 0 && !/^[◎●▪□■▣❐❏○ㅇ]/.test(text)) {
1307
+ if (tuning.postprocess && job.rot === 0 && text !== "/" && /^[(:;/)]+$/.test(text) && text.includes("/")) {
1308
+ const g = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, job.box);
1309
+ if (_chunkYAK4U7CCcjs.tallInkCount.call(void 0, g, job.box.w, job.box.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, g)) === 1) text = "/";
1310
+ }
1311
+ if (tuning.postprocess && job.rot === 0 && !/^[◎●▪□■▣❐❏○ㅇ◆◇◈]/.test(text)) {
1022
1312
  const chars = [...read], k = chars.findIndex((c) => c.trim());
1023
1313
  if (k >= 0 && steps.length === chars.length) {
1024
- const g = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, width, job.box);
1025
- const b = _chunkU2VAABMKcjs.leadingBullet.call(void 0, g, job.box.w, job.box.h, _chunkU2VAABMKcjs.inkStats.call(void 0, g), (steps[k] + 0.5) * stepPx);
1314
+ const g = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, job.box);
1315
+ const b = _chunkYAK4U7CCcjs.leadingBullet.call(void 0, g, job.box.w, job.box.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, g), (steps[k] + 0.5) * stepPx);
1026
1316
  const body = (_nullishCoalesce(text.match(/[가-힣]/g), () => ( []))).length >= 4;
1027
1317
  const miss = /^[Oo0•·ㆍ∙‧○]/.test(text);
1028
- if (_optionalChain([b, 'optionalAccess', _9 => _9.mark]) === "\u25CE" && b.covers && /^[Oo0○]/.test(text)) text = b.mark + " " + text.slice(1).trimStart();
1029
- else if (_optionalChain([b, 'optionalAccess', _10 => _10.mark]) === "\u25A1" || _optionalChain([b, 'optionalAccess', _11 => _11.mark]) === "\u25A3") {
1318
+ if (_optionalChain([b, 'optionalAccess', _24 => _24.mark]) === "\u25CE" && b.covers && /^[Oo0○]/.test(text)) text = b.mark + " " + text.slice(1).trimStart();
1319
+ else if (_optionalChain([b, 'optionalAccess', _25 => _25.mark]) === "\u25A1" || _optionalChain([b, 'optionalAccess', _26 => _26.mark]) === "\u25A3") {
1030
1320
  if (!b.covers && body) text = b.mark + " " + text;
1031
- } else if (_optionalChain([b, 'optionalAccess', _12 => _12.mark]) === "\u2023") {
1321
+ } else if (_optionalChain([b, 'optionalAccess', _27 => _27.mark]) === "\u25C6" || _optionalChain([b, 'optionalAccess', _28 => _28.mark]) === "\u25C7" || _optionalChain([b, 'optionalAccess', _29 => _29.mark]) === "\u25C8") {
1322
+ if (b.covers ? /^[\p{S}\p{P}]/u.test(text) : body) text = b.covers ? b.mark + " " + text.slice(1).trimStart() : b.mark + " " + text;
1323
+ } else if (_optionalChain([b, 'optionalAccess', _30 => _30.mark]) === "\u2023") {
1032
1324
  if (b.covers ? text.startsWith("\u2192") : body) text = b.covers ? b.mark + " " + text.slice(1).trimStart() : b.mark + " " + text;
1033
- } else if (_optionalChain([b, 'optionalAccess', _13 => _13.mark]) === "\u2750" || _optionalChain([b, 'optionalAccess', _14 => _14.mark]) === "\u274F") {
1325
+ } else if (_optionalChain([b, 'optionalAccess', _31 => _31.mark]) === "\u2750" || _optionalChain([b, 'optionalAccess', _32 => _32.mark]) === "\u274F") {
1034
1326
  if (b.covers ? /^[ㅁ口]/.test(text) : body) text = b.covers ? b.mark + text.slice(1) : b.mark + " " + text;
1035
1327
  } else if (b && b.mark !== "\u25CE" && body) text = b.covers ? miss ? b.mark + " " + text.slice(1).trimStart() : text : b.mark + " " + text;
1036
- else if (!b && body && /^[가-힣]/.test(chars[k]) && _chunkU2VAABMKcjs.leadingRing.call(void 0, g, job.box.w, job.box.h, _chunkU2VAABMKcjs.inkStats.call(void 0, g), (steps[k] + 0.5) * stepPx)) text = "\u25CB " + text;
1328
+ else if (!b && body && /^[가-힣]/.test(chars[k]) && _chunkYAK4U7CCcjs.leadingRing.call(void 0, g, job.box.w, job.box.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, g), (steps[k] + 0.5) * stepPx)) text = "\u25CB " + text;
1037
1329
  }
1038
1330
  }
1039
1331
  if (tuning.postprocess && /^\d/.test(text) && job.rot === 0) {
1040
- const g = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, width, job.box);
1041
- const tri = _chunkU2VAABMKcjs.leadingTriangle.call(void 0, g, job.box.w, job.box.h, _chunkU2VAABMKcjs.inkStats.call(void 0, g));
1332
+ const g = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, job.box);
1333
+ const tri = _chunkYAK4U7CCcjs.leadingTriangle.call(void 0, g, job.box.w, job.box.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, g));
1042
1334
  if (tri) text = tri + text;
1043
1335
  }
1044
1336
  if (tuning.postprocess && text === "\u2192" && job.rot === 0 && job.join === void 0) {
1045
- const g = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, width, job.box);
1046
- text = _nullishCoalesce(_chunkU2VAABMKcjs.arrowGlyph.call(void 0, g, job.box.w, job.box.h, _chunkU2VAABMKcjs.inkStats.call(void 0, g)), () => ( text));
1337
+ const g = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, job.box);
1338
+ text = _nullishCoalesce(_chunkYAK4U7CCcjs.arrowGlyph.call(void 0, g, job.box.w, job.box.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, g)), () => ( text));
1339
+ }
1340
+ if (job.footer) {
1341
+ if (!/^[-\u2013\u2014]?\s*(?:\d{1,4}|[ivxIVXⅰ-ⅹⅠ-Ⅹ]{1,4})\s*[-\u2013\u2014]?$/.test(text.trim())) continue;
1342
+ text = text.replace(/[\u2013\u2014]/g, "-");
1047
1343
  }
1048
1344
  if (tuning.postprocess && isDotFragment(text)) continue;
1049
1345
  if (confidence < tuning.textScore) {
1050
1346
  if (stats) {
1051
1347
  stats.droppedLowConf++;
1052
- _optionalChain([stats, 'access', _15 => _15.dropped, 'optionalAccess', _16 => _16.push, 'call', _17 => _17({ text, ...this.itemBox(rgba, width, job.box, tuning), confidence })]);
1348
+ _optionalChain([stats, 'access', _33 => _33.dropped, 'optionalAccess', _34 => _34.push, 'call', _35 => _35({ text, ...this.itemBox(rgba, width, job.box, tuning), confidence })]);
1053
1349
  }
1054
1350
  continue;
1055
1351
  }
@@ -1059,7 +1355,7 @@ var OcrEngine = class _OcrEngine {
1059
1355
  continue;
1060
1356
  }
1061
1357
  const item = { text, ...this.itemBox(rgba, width, job.box, tuning), confidence };
1062
- if (job.rot === 0) _chunkU2VAABMKcjs.rememberOcrTextGaps.call(void 0, item, _chunkU2VAABMKcjs.findOcrTextGaps.call(void 0, rgba, width, job.box, read, text, steps, stepPx));
1358
+ if (job.rot === 0) _chunkYAK4U7CCcjs.rememberOcrTextGaps.call(void 0, item, _chunkYAK4U7CCcjs.findOcrTextGaps.call(void 0, rgba, width, job.box, read, text, steps, stepPx));
1063
1359
  items.push(item);
1064
1360
  }
1065
1361
  const leaderEnds = /* @__PURE__ */ new Map();
@@ -1083,6 +1379,19 @@ var OcrEngine = class _OcrEngine {
1083
1379
  if (leaderEnds.size) items = joinLeaderItems(items, leaderEnds);
1084
1380
  if (tuning.postprocess) items = dropNestedFragments(items);
1085
1381
  if (tuning.postprocess) for (const it of items) this.outerSquare(rgba, width, it, items);
1382
+ if (tuning.postprocess) items.push(...closingParens(rgba, width, items));
1383
+ if (tuning.postprocess) items.push(...placeholderSquares(rgba, width, height, items));
1384
+ if (tuning.postprocess) items.push(...rowHeadDashes(rgba, width, items));
1385
+ if (tuning.postprocess) {
1386
+ const tails = rowTailBoxes(rgba, width, items);
1387
+ if (tails.length) {
1388
+ const res = await this.recognizeJobs(rgba, width, tails.map((box, k) => ({ box, rot: 0, group: k })), tuning.recBatch);
1389
+ tails.forEach((box, k) => {
1390
+ const t = _nullishCoalesce(_optionalChain([res, 'access', _36 => _36[k], 'optionalAccess', _37 => _37.text, 'access', _38 => _38.trim, 'call', _39 => _39()]), () => ( ""));
1391
+ if (/^\d{1,4}$/.test(t) && (_nullishCoalesce(_optionalChain([res, 'access', _40 => _40[k], 'optionalAccess', _41 => _41.confidence]), () => ( 0))) >= tuning.textScore) items.push({ text: t, ...this.itemBox(rgba, width, box, tuning), confidence: res[k].confidence });
1392
+ });
1393
+ }
1394
+ }
1086
1395
  if (tuning.postprocess) restoreBulletItems(items);
1087
1396
  items.sort((a, b) => a.y - b.y || a.x - b.x);
1088
1397
  return items;
@@ -1090,8 +1399,8 @@ var OcrEngine = class _OcrEngine {
1090
1399
  /** 결과 좌표 — det 박스 그대로 또는 박스 안 잉크 외곽 (tightBoxes) */
1091
1400
  itemBox(rgba, width, b, tuning) {
1092
1401
  if (!tuning.tightBoxes) return b;
1093
- const gray = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, width, b);
1094
- const t = _chunkU2VAABMKcjs.inkBounds.call(void 0, gray, b.w, b.h, _chunkU2VAABMKcjs.inkStats.call(void 0, gray));
1402
+ const gray = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, width, b);
1403
+ const t = _chunkYAK4U7CCcjs.inkBounds.call(void 0, gray, b.w, b.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, gray));
1095
1404
  return { x: b.x + t.x0, y: b.y + t.y0, w: t.x1 - t.x0, h: t.y1 - t.y0 };
1096
1405
  }
1097
1406
  // ─── det ─────────────────────────────────────────────
@@ -1164,7 +1473,7 @@ var OcrEngine = class _OcrEngine {
1164
1473
  const out = await this.rec.run({ [this.rec.inputNames[0]]: tensor });
1165
1474
  const logits = out[this.rec.outputNames[0]];
1166
1475
  const [, T, C] = logits.dims;
1167
- if (C !== this.dict.length + 2) throw new (0, _chunk2H2VYPM2cjs.KordocError)(`OCR rec \uCD9C\uB825 \uD074\uB798\uC2A4 ${C}\uAC1C\uAC00 \uC0AC\uC804 ${this.dict.length}\uC790 + 2 \uC640 \uB2E4\uB985\uB2C8\uB2E4 \u2014 \uBAA8\uB378\uC5D0 \uB9DE\uB294 \uC0AC\uC804(ocrRecDict)\uC744 \uC9C0\uC815\uD558\uC138\uC694`);
1476
+ if (C !== this.dict.length + 2) throw new (0, _chunkOICA67ATcjs.KordocError)(`OCR rec \uCD9C\uB825 \uD074\uB798\uC2A4 ${C}\uAC1C\uAC00 \uC0AC\uC804 ${this.dict.length}\uC790 + 2 \uC640 \uB2E4\uB985\uB2C8\uB2E4 \u2014 \uBAA8\uB378\uC5D0 \uB9DE\uB294 \uC0AC\uC804(ocrRecDict)\uC744 \uC9C0\uC815\uD558\uC138\uC694`);
1168
1477
  const data = logits.data;
1169
1478
  idx.forEach((ci, k) => {
1170
1479
  const r = ctcDecode(data.subarray(k * T * C, (k + 1) * T * C), T, C, this.dict);
@@ -1174,9 +1483,9 @@ var OcrEngine = class _OcrEngine {
1174
1483
  const chars = r ? [...r.text] : [];
1175
1484
  if (r && job.rot === 0 && chars.length === r.steps.length && r.steps.some((t) => t > last) && !r.text.includes("(cid:")) {
1176
1485
  const tallCh = (c) => !/[\s.,:;\u00b7\u2026'"\u2018-\u201d`\-_~]/.test(c);
1177
- const g = _chunkU2VAABMKcjs.grayCrop.call(void 0, rgba, pageW, job.box);
1486
+ const g = _chunkYAK4U7CCcjs.grayCrop.call(void 0, rgba, pageW, job.box);
1178
1487
  const inside = chars.filter((c, i) => r.steps[i] <= last && tallCh(c)).length;
1179
- let budget = inside <= 2 ? _chunkU2VAABMKcjs.tallInkCount.call(void 0, g, job.box.w, job.box.h, _chunkU2VAABMKcjs.inkStats.call(void 0, g)) - inside : Infinity;
1488
+ let budget = inside <= 2 ? _chunkYAK4U7CCcjs.tallInkCount.call(void 0, g, job.box.w, job.box.h, _chunkYAK4U7CCcjs.inkStats.call(void 0, g)) - inside : Infinity;
1180
1489
  const keep = chars.map((c, i) => r.steps[i] <= last || !tallCh(c) || budget-- > 0);
1181
1490
  if (!keep.every(Boolean)) kept = { ...r, text: chars.filter((_, i) => keep[i]).join(""), steps: r.steps.filter((_, i) => keep[i]) };
1182
1491
  }
@@ -1287,13 +1596,13 @@ async function tryImport(name, loader) {
1287
1596
  return await loader();
1288
1597
  } catch (e) {
1289
1598
  throw new Error(
1290
- `\uB0B4\uC7A5 OCR \uC744 \uC0AC\uC6A9\uD558\uB824\uBA74 optional dependency '${name}' \uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \`npm install ${name}\` \uD6C4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.${_chunk2H2VYPM2cjs.OPTIONAL_DEP_INSTALL_HINT} \uC6D0\uC778: ${e.message}`
1599
+ `\uB0B4\uC7A5 OCR \uC744 \uC0AC\uC6A9\uD558\uB824\uBA74 optional dependency '${name}' \uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \`npm install ${name}\` \uD6C4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.${_chunkOICA67ATcjs.OPTIONAL_DEP_INSTALL_HINT} \uC6D0\uC778: ${e.message}`
1291
1600
  );
1292
1601
  }
1293
1602
  }
1294
1603
  async function verifiedBytes(s) {
1295
1604
  const name = _path.basename.call(void 0, s.file.path);
1296
- const fail = (why2) => new (0, _chunk2H2VYPM2cjs.KordocError)(`OCR \uBAA8\uB378 \uD30C\uC77C\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${name} (${why2})`);
1605
+ const fail = (why2) => new (0, _chunkOICA67ATcjs.KordocError)(`OCR \uBAA8\uB378 \uD30C\uC77C\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${name} (${why2})`);
1297
1606
  const why = (e) => {
1298
1607
  const code = e.code;
1299
1608
  return code === "ENOENT" ? "\uD30C\uC77C\uC774 \uC5C6\uC74C" : code === "EACCES" || code === "EPERM" ? "\uAD8C\uD55C \uC5C6\uC74C" : "\uC77D\uAE30 \uC2E4\uD328";
@@ -1314,13 +1623,13 @@ async function verifiedBytes(s) {
1314
1623
  }
1315
1624
  const actual = _crypto.createHash.call(void 0, "sha256").update(bytes).digest("hex");
1316
1625
  if (actual !== s.file.sha256) {
1317
- throw new (0, _chunk2H2VYPM2cjs.KordocError)(`OCR \uBAA8\uB378 SHA256 mismatch: ${_path.basename.call(void 0, s.file.path)} \u2014 expected ${s.file.sha256}, got ${actual} (\uB85C\uB4DC \uAC70\uBD80)`);
1626
+ throw new (0, _chunkOICA67ATcjs.KordocError)(`OCR \uBAA8\uB378 SHA256 mismatch: ${_path.basename.call(void 0, s.file.path)} \u2014 expected ${s.file.sha256}, got ${actual} (\uB85C\uB4DC \uAC70\uBD80)`);
1318
1627
  }
1319
1628
  return bytes;
1320
1629
  }
1321
1630
  var engines = /* @__PURE__ */ new Map();
1322
- function getOcrEngine(models = _chunkU2VAABMKcjs.DEFAULT_OCR_MODELS) {
1323
- const key = _chunkU2VAABMKcjs.ocrSelectionKey.call(void 0, models);
1631
+ function getOcrEngine(models = _chunkYAK4U7CCcjs.DEFAULT_OCR_MODELS) {
1632
+ const key = _chunkYAK4U7CCcjs.ocrSelectionKey.call(void 0, models);
1324
1633
  let p = engines.get(key);
1325
1634
  if (!p) {
1326
1635
  p = OcrEngine.create(models).catch((err) => {
@@ -1423,13 +1732,13 @@ function rotateRgba(rgba, width, height, deg) {
1423
1732
  var OCR_RENDER_SCALE = 3;
1424
1733
  var MAX_OCR_PIXELS = 24e6;
1425
1734
  var PAGE_TIMEOUT_MS = 12e4;
1426
- var DEFAULT_BUILTIN_OCR = Object.freeze({ models: _chunkU2VAABMKcjs.DEFAULT_OCR_MODELS, tuning: DEFAULT_OCR_TUNING });
1735
+ var DEFAULT_BUILTIN_OCR = Object.freeze({ models: _chunkYAK4U7CCcjs.DEFAULT_OCR_MODELS, tuning: DEFAULT_OCR_TUNING });
1427
1736
  function builtinOcrConfig(o) {
1428
1737
  if (!o || o.ocrDet === void 0 && o.ocrDetLongSide === void 0 && o.ocrRec === void 0 && o.ocrRecDict === void 0 && !o.ocrLines) return DEFAULT_BUILTIN_OCR;
1429
- const bad = _chunkVPKZB6Y7cjs.validateOcrOptions.call(void 0, o);
1430
- if (bad) throw new (0, _chunk2H2VYPM2cjs.KordocError)(bad);
1738
+ const bad = _chunk4ZNM7XRWcjs.validateOcrOptions.call(void 0, o);
1739
+ if (bad) throw new (0, _chunkOICA67ATcjs.KordocError)(bad);
1431
1740
  return {
1432
- models: _chunkU2VAABMKcjs.resolveOcrModels.call(void 0, o),
1741
+ models: _chunkYAK4U7CCcjs.resolveOcrModels.call(void 0, o),
1433
1742
  tuning: o.ocrDetLongSide === void 0 ? DEFAULT_OCR_TUNING : { ...DEFAULT_OCR_TUNING, detLongSide: o.ocrDetLongSide },
1434
1743
  lines: o.ocrLines === "all" ? "all" : o.ocrLines ? "kept" : void 0
1435
1744
  };
@@ -1463,7 +1772,7 @@ async function runPdfOcr(buffer, targets, mode, warnings, onProgress, detectTabl
1463
1772
  "@hyzyla/pdfium",
1464
1773
  () => Promise.resolve().then(() => _interopRequireWildcard(require("@hyzyla/pdfium")))
1465
1774
  );
1466
- if (mode === "builtin") await _chunkU2VAABMKcjs.ensureOcrModelsFor.call(void 0, config.models, reportModelDownload);
1775
+ if (mode === "builtin") await _chunkYAK4U7CCcjs.ensureOcrModelsFor.call(void 0, config.models, reportModelDownload);
1467
1776
  const engine = mode === "builtin" ? await getOcrEngine(config.models) : null;
1468
1777
  const pdfium = await pdfiumMod.PDFiumLibrary.init();
1469
1778
  const doc = await pdfium.loadDocument(new Uint8Array(buffer));
@@ -1472,15 +1781,15 @@ async function runPdfOcr(buffer, targets, mode, warnings, onProgress, detectTabl
1472
1781
  const count = doc.getPageCount();
1473
1782
  for (const pageNo of [...targets].filter((p) => p >= 1 && p <= count).sort((a, b) => a - b)) {
1474
1783
  const page = doc.getPage(pageNo - 1);
1475
- _optionalChain([onProgress, 'optionalCall', _18 => _18(++done, targets.size)]);
1784
+ _optionalChain([onProgress, 'optionalCall', _42 => _42(++done, targets.size)]);
1476
1785
  try {
1477
1786
  const { blocks, lines } = await withTimeout(
1478
- ocrOnePage(page, pageNo, mode, engine, warnings, detectTables, _optionalChain([vectorOps, 'optionalAccess', _19 => _19.get, 'call', _20 => _20(pageNo)]), _optionalChain([imageRegions, 'optionalAccess', _21 => _21.get, 'call', _22 => _22(pageNo)]), config),
1787
+ ocrOnePage(page, pageNo, mode, engine, warnings, detectTables, _optionalChain([vectorOps, 'optionalAccess', _43 => _43.get, 'call', _44 => _44(pageNo)]), _optionalChain([imageRegions, 'optionalAccess', _45 => _45.get, 'call', _46 => _46(pageNo)]), config),
1479
1788
  PAGE_TIMEOUT_MS,
1480
1789
  `OCR \uD398\uC774\uC9C0 ${pageNo} \uD0C0\uC784\uC544\uC6C3 (${PAGE_TIMEOUT_MS / 1e3}\uCD08)`
1481
1790
  );
1482
1791
  result.set(pageNo, blocks);
1483
- if (lines) _optionalChain([linesOut, 'optionalAccess', _23 => _23.set, 'call', _24 => _24(pageNo, lines)]);
1792
+ if (lines) _optionalChain([linesOut, 'optionalAccess', _47 => _47.set, 'call', _48 => _48(pageNo, lines)]);
1484
1793
  } catch (e) {
1485
1794
  warnings.push({
1486
1795
  page: pageNo,
@@ -1545,7 +1854,7 @@ async function ocrOnePage(page, pageNo, mode, engine, warnings, detectTables, ve
1545
1854
  const regionBlocks = regions.flatMap((r, k) => {
1546
1855
  let own = items.filter((it) => inside(it, r));
1547
1856
  const near = reads[k];
1548
- if (_optionalChain([near, 'optionalAccess', _25 => _25.length]) && meanConfidence(near) > meanConfidence(own)) {
1857
+ if (_optionalChain([near, 'optionalAccess', _49 => _49.length]) && meanConfidence(near) > meanConfidence(own)) {
1549
1858
  own = near;
1550
1859
  reread.add(k);
1551
1860
  }
@@ -1553,9 +1862,9 @@ async function ocrOnePage(page, pageNo, mode, engine, warnings, detectTables, ve
1553
1862
  for (const it of own) used.add(it);
1554
1863
  const blocks = ocrItemsToBlocks(own, pageNo, pdfW, pdfH, scale, ruling && rulingToPdfLines(ruling, scale, pdfH), detectTables, void 0, true);
1555
1864
  const x1 = r.x1 * scale - 2, x2 = r.x2 * scale + 2, y1 = (pdfH - r.y2) * scale - 2, y2 = (pdfH - r.y1) * scale + 2;
1556
- const columnRules = _nullishCoalesce(_optionalChain([ruling, 'optionalAccess', _26 => _26.verticals, 'access', _27 => _27.filter, 'call', _28 => _28((s) => Math.min(s.x1, s.x2) >= x1 && Math.max(s.x1, s.x2) <= x2 && Math.min(s.y1, s.y2) >= y1 && Math.max(s.y1, s.y2) <= y2), 'access', _29 => _29.length]), () => ( 0));
1865
+ const columnRules = _nullishCoalesce(_optionalChain([ruling, 'optionalAccess', _50 => _50.verticals, 'access', _51 => _51.filter, 'call', _52 => _52((s) => Math.min(s.x1, s.x2) >= x1 && Math.max(s.x1, s.x2) <= x2 && Math.min(s.y1, s.y2) >= y1 && Math.max(s.y1, s.y2) <= y2), 'access', _53 => _53.length]), () => ( 0));
1557
1866
  if (columnRules < 2) {
1558
- for (const b of blocks) if (b.type === "table") _chunkU2VAABMKcjs.UNRULED_REGION_TABLES.add(b);
1867
+ for (const b of blocks) if (b.type === "table") _chunkYAK4U7CCcjs.UNRULED_REGION_TABLES.add(b);
1559
1868
  }
1560
1869
  return blocks;
1561
1870
  });
@@ -1614,7 +1923,7 @@ async function closerReads(rgba, rw, rh, pdfH, hi, regions, engine, tuning = REG
1614
1923
  const items = await engine.recognizePage(crop, cw, ch, void 0, tuning);
1615
1924
  out.push(items.map((it) => {
1616
1925
  const placed = { ...it, x: (it.x + x0) / 2, y: (it.y + y0) / 2, w: it.w / 2, h: it.h / 2 };
1617
- _chunkU2VAABMKcjs.copyOcrTextGaps.call(void 0, it, placed, 0.5, x0 / 2);
1926
+ _chunkYAK4U7CCcjs.copyOcrTextGaps.call(void 0, it, placed, 0.5, x0 / 2);
1618
1927
  return placed;
1619
1928
  }));
1620
1929
  }
@@ -1622,7 +1931,7 @@ async function closerReads(rgba, rw, rh, pdfH, hi, regions, engine, tuning = REG
1622
1931
  }
1623
1932
  var proseBox = (b) => {
1624
1933
  const t = b.text.replace(/\s/g, "");
1625
- return b.w >= b.h * 7 && (_nullishCoalesce(_optionalChain([t, 'access', _30 => _30.match, 'call', _31 => _31(/\d/g), 'optionalAccess', _32 => _32.length]), () => ( 0))) < t.length * 0.3;
1934
+ return b.w >= b.h * 7 && (_nullishCoalesce(_optionalChain([t, 'access', _54 => _54.match, 'call', _55 => _55(/\d/g), 'optionalAccess', _56 => _56.length]), () => ( 0))) < t.length * 0.3;
1626
1935
  };
1627
1936
  function groupOcrLines(items, figureRegion = false) {
1628
1937
  const order = items.map((_, i) => i).sort((a, b) => items[a].y + items[a].h / 2 - (items[b].y + items[b].h / 2));
@@ -1694,17 +2003,17 @@ function ocrItemsToBlocks(items, pageNumber, pdfW, pdfH, scale, extraLines, dete
1694
2003
  isHidden: false,
1695
2004
  ...xs[i].space ? { hasSpaceBefore: true } : {}
1696
2005
  };
1697
- _chunkU2VAABMKcjs.copyOcrTextGaps.call(void 0, it, normalized, 1 / scale);
2006
+ _chunkYAK4U7CCcjs.copyOcrTextGaps.call(void 0, it, normalized, 1 / scale);
1698
2007
  return normalized;
1699
2008
  });
1700
- return _chunkU2VAABMKcjs.extractPageBlocksWithLines.call(void 0, norm, pageNumber, opList, pdfW, pdfH, extraLines, detectTables);
2009
+ return _chunkYAK4U7CCcjs.extractPageBlocksWithLines.call(void 0, norm, pageNumber, opList, pdfW, pdfH, extraLines, detectTables);
1701
2010
  }
1702
2011
  async function tryImport2(name, loader) {
1703
2012
  try {
1704
2013
  return await loader();
1705
2014
  } catch (e) {
1706
2015
  throw new Error(
1707
- `OCR \uC744 \uC0AC\uC6A9\uD558\uB824\uBA74 optional dependency '${name}' \uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \`npm install ${name}\` \uD6C4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.${_chunk2H2VYPM2cjs.OPTIONAL_DEP_INSTALL_HINT} \uC6D0\uC778: ${e.message}`
2016
+ `OCR \uC744 \uC0AC\uC6A9\uD558\uB824\uBA74 optional dependency '${name}' \uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \`npm install ${name}\` \uD6C4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.${_chunkOICA67ATcjs.OPTIONAL_DEP_INSTALL_HINT} \uC6D0\uC778: ${e.message}`
1708
2017
  );
1709
2018
  }
1710
2019
  }
@@ -1752,4 +2061,4 @@ function bgraToRgba(bgra) {
1752
2061
 
1753
2062
 
1754
2063
  exports.getOcrEngine = getOcrEngine; exports.detectRulingLines = detectRulingLines; exports.rulingToPdfLines = rulingToPdfLines; exports.deskewPage = deskewPage; exports.MAX_OCR_PIXELS = MAX_OCR_PIXELS; exports.DEFAULT_BUILTIN_OCR = DEFAULT_BUILTIN_OCR; exports.builtinOcrConfig = builtinOcrConfig; exports.reportModelDownload = reportModelDownload; exports.toOcrLine = toOcrLine; exports.pageLines = pageLines; exports.cellEdgeVerticals = cellEdgeVerticals; exports.cellEdgeHorizontals = cellEdgeHorizontals; exports.runPdfOcr = runPdfOcr; exports.ocrOnePage = ocrOnePage; exports.groupOcrLines = groupOcrLines; exports.ocrItemsToBlocks = ocrItemsToBlocks;
1755
- //# sourceMappingURL=chunk-QZ2H4ZTO.cjs.map
2064
+ //# sourceMappingURL=chunk-X2XZXDBZ.cjs.map