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.
- package/README.md +7 -7
- package/dist/{-NBCZTPBD.js → -CCZTES5C.js} +11 -11
- package/dist/{chunk-XWWQGSEP.js → chunk-4EVUCAW5.js} +2 -2
- package/dist/{chunk-VPKZB6Y7.cjs → chunk-4ZNM7XRW.cjs} +6 -6
- package/dist/{chunk-VPKZB6Y7.cjs.map → chunk-4ZNM7XRW.cjs.map} +1 -1
- package/dist/{chunk-XGESPSWE.cjs → chunk-6KQWC2KN.cjs} +3 -3
- package/dist/{chunk-XGESPSWE.cjs.map → chunk-6KQWC2KN.cjs.map} +1 -1
- package/dist/{chunk-QW2H2HHS.js → chunk-6WEHXC2D.js} +315 -6
- package/dist/chunk-6WEHXC2D.js.map +1 -0
- package/dist/{chunk-PUHBCAXI.js → chunk-7Y4MVNYA.js} +11 -11
- package/dist/{chunk-CKOCIQU6.js → chunk-7YCKDE5X.js} +2 -2
- package/dist/{chunk-FJ3IKKDV.js → chunk-DULJ7PPP.js} +315 -6
- package/dist/chunk-DULJ7PPP.js.map +1 -0
- package/dist/{chunk-KTXDK5A6.js → chunk-E5H5WHJH.js} +2 -2
- package/dist/{chunk-A232MW5F.js → chunk-EY3PT2X7.js} +2 -2
- package/dist/{chunk-W52B6GOE.cjs → chunk-GDE4YE2P.cjs} +3 -3
- package/dist/{chunk-W52B6GOE.cjs.map → chunk-GDE4YE2P.cjs.map} +1 -1
- package/dist/{chunk-UVQOPGOA.js → chunk-GZ3BY2LV.js} +14 -9
- package/dist/chunk-GZ3BY2LV.js.map +1 -0
- package/dist/{chunk-ZUMOEVMV.js → chunk-HZFYPOBJ.js} +3 -3
- package/dist/{chunk-OVQWOOS3.js → chunk-IGLRJCO6.js} +2 -2
- package/dist/{chunk-A4CYMI55.js → chunk-K37LMDT5.js} +2 -2
- package/dist/{chunk-X2E5QCKO.js → chunk-KMSLXG5F.js} +2 -2
- package/dist/{chunk-DMPX4KLC.js → chunk-KOHEEPQV.js} +2 -2
- package/dist/{chunk-37MTSMUF.js → chunk-MTAQVHCB.js} +2 -2
- package/dist/{chunk-2H2VYPM2.cjs → chunk-OICA67AT.cjs} +2 -2
- package/dist/{chunk-2H2VYPM2.cjs.map → chunk-OICA67AT.cjs.map} +1 -1
- package/dist/{chunk-QAGPSWGH.js → chunk-PCHGHLUP.js} +2 -2
- package/dist/{chunk-BC4LVU4D.js → chunk-SLHWOJNZ.js} +2 -2
- package/dist/{chunk-ZSCDH3NU.js → chunk-T7MDUY5X.js} +2 -2
- package/dist/{chunk-QVEAR6IR.js → chunk-UGO3UFXX.js} +48 -7
- package/dist/chunk-UGO3UFXX.js.map +1 -0
- package/dist/{chunk-WAWREGAC.js → chunk-UV2ZS65C.js} +2 -2
- package/dist/{chunk-4I2CKMKU.js → chunk-VNB2IKVA.js} +3 -3
- package/dist/{chunk-IQGXY63Y.js → chunk-VSYLST4K.js} +49 -8
- package/dist/chunk-VSYLST4K.js.map +1 -0
- package/dist/{chunk-QZ2H4ZTO.cjs → chunk-X2XZXDBZ.cjs} +390 -81
- package/dist/chunk-X2XZXDBZ.cjs.map +1 -0
- package/dist/{chunk-WOVJRXIA.js → chunk-XW7L76FE.js} +2 -2
- package/dist/{chunk-BJBPBU5B.js → chunk-Y3VNNGB2.js} +2 -2
- package/dist/{chunk-U2VAABMK.cjs → chunk-YAK4U7CC.cjs} +194 -153
- package/dist/chunk-YAK4U7CC.cjs.map +1 -0
- package/dist/chunks-74SE5QB2.js +10 -0
- package/dist/cli.js +30 -30
- package/dist/{formula-WFL6JRCR.js → formula-54IFKOYU.js} +3 -3
- package/dist/{formula-M4FM364X.js → formula-EW7XLBSA.js} +4 -4
- package/dist/{formula-ZKZGV6JV.cjs → formula-Q4MFVPEO.cjs} +9 -9
- package/dist/{formula-ZKZGV6JV.cjs.map → formula-Q4MFVPEO.cjs.map} +1 -1
- package/dist/{image-ocr-47CBNIS5.js → image-ocr-GWF2XELH.js} +9 -9
- package/dist/{image-ocr-YJISJPKE.js → image-ocr-I7UGQZF5.js} +6 -6
- package/dist/{image-ocr-2V3M3ZEA.cjs → image-ocr-OGJ6A3ML.cjs} +17 -17
- package/dist/{image-ocr-2V3M3ZEA.cjs.map → image-ocr-OGJ6A3ML.cjs.map} +1 -1
- package/dist/index.cjs +368 -363
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -9
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +23 -23
- package/dist/{model-bundle-7W344HDI.js → model-bundle-43YHGZCC.js} +5 -5
- package/dist/{models-TBHMNI7M.js → models-O3NS6OPX.js} +5 -5
- package/dist/{parse-worker-v2-JUYUEXCY.js → parse-worker-v2-OXW3CQOW.js} +12 -12
- package/dist/{parser-RNJ4KSDF.js → parser-B3RVTCOY.js} +9 -9
- package/dist/{parser-R44KTBZX.cjs → parser-FMVOWRG4.cjs} +159 -159
- package/dist/{parser-R44KTBZX.cjs.map → parser-FMVOWRG4.cjs.map} +1 -1
- package/dist/{parser-EKQCZLML.js → parser-H6OY6UWW.js} +12 -12
- package/dist/pdf-ocr-5Z6GDYBQ.cjs +35 -0
- package/dist/{pdf-ocr-74BOCXAT.cjs.map → pdf-ocr-5Z6GDYBQ.cjs.map} +1 -1
- package/dist/{pdf-ocr-ZAF4P74R.js → pdf-ocr-NE6Y4I6O.js} +6 -6
- package/dist/{pdf-ocr-EE5KGFVX.js → pdf-ocr-QHW74LO6.js} +9 -9
- package/dist/{profile-io-RU3RVIYV.js → profile-io-2IOYOBGP.js} +3 -3
- package/dist/{rasterize-UNCPM26D.js → rasterize-ZLPDGEZY.js} +3 -3
- package/dist/{redact-doc-BFE4UZCY.js → redact-doc-CDFM5S7S.js} +11 -11
- package/dist/{render-3DXTLKIA.js → render-VXAEYSJA.js} +7 -7
- package/dist/seal-YSBFBEXC.js +10 -0
- package/dist/{setup-7POQAKDG.js → setup-CBWVQJID.js} +3 -3
- package/dist/visual-MJVIFZHH.js +21 -0
- package/dist/{watch-37YCXJWW.js → watch-2SA3CTRT.js} +12 -12
- package/package.json +1 -1
- package/dist/chunk-FJ3IKKDV.js.map +0 -1
- package/dist/chunk-IQGXY63Y.js.map +0 -1
- package/dist/chunk-QVEAR6IR.js.map +0 -1
- package/dist/chunk-QW2H2HHS.js.map +0 -1
- package/dist/chunk-QZ2H4ZTO.cjs.map +0 -1
- package/dist/chunk-U2VAABMK.cjs.map +0 -1
- package/dist/chunk-UVQOPGOA.js.map +0 -1
- package/dist/chunks-IXFBIZPW.js +0 -10
- package/dist/pdf-ocr-74BOCXAT.cjs +0 -35
- package/dist/seal-3LBTETDG.js +0 -10
- package/dist/visual-7SVIGIJC.js +0 -21
- /package/dist/{-NBCZTPBD.js.map → -CCZTES5C.js.map} +0 -0
- /package/dist/{chunk-XWWQGSEP.js.map → chunk-4EVUCAW5.js.map} +0 -0
- /package/dist/{chunk-PUHBCAXI.js.map → chunk-7Y4MVNYA.js.map} +0 -0
- /package/dist/{chunk-CKOCIQU6.js.map → chunk-7YCKDE5X.js.map} +0 -0
- /package/dist/{chunk-KTXDK5A6.js.map → chunk-E5H5WHJH.js.map} +0 -0
- /package/dist/{chunk-A232MW5F.js.map → chunk-EY3PT2X7.js.map} +0 -0
- /package/dist/{chunk-ZUMOEVMV.js.map → chunk-HZFYPOBJ.js.map} +0 -0
- /package/dist/{chunk-OVQWOOS3.js.map → chunk-IGLRJCO6.js.map} +0 -0
- /package/dist/{chunk-A4CYMI55.js.map → chunk-K37LMDT5.js.map} +0 -0
- /package/dist/{chunk-X2E5QCKO.js.map → chunk-KMSLXG5F.js.map} +0 -0
- /package/dist/{chunk-DMPX4KLC.js.map → chunk-KOHEEPQV.js.map} +0 -0
- /package/dist/{chunk-37MTSMUF.js.map → chunk-MTAQVHCB.js.map} +0 -0
- /package/dist/{chunk-QAGPSWGH.js.map → chunk-PCHGHLUP.js.map} +0 -0
- /package/dist/{chunk-BC4LVU4D.js.map → chunk-SLHWOJNZ.js.map} +0 -0
- /package/dist/{chunk-ZSCDH3NU.js.map → chunk-T7MDUY5X.js.map} +0 -0
- /package/dist/{chunk-WAWREGAC.js.map → chunk-UV2ZS65C.js.map} +0 -0
- /package/dist/{chunk-4I2CKMKU.js.map → chunk-VNB2IKVA.js.map} +0 -0
- /package/dist/{chunk-WOVJRXIA.js.map → chunk-XW7L76FE.js.map} +0 -0
- /package/dist/{chunk-BJBPBU5B.js.map → chunk-Y3VNNGB2.js.map} +0 -0
- /package/dist/{chunks-IXFBIZPW.js.map → chunks-74SE5QB2.js.map} +0 -0
- /package/dist/{formula-WFL6JRCR.js.map → formula-54IFKOYU.js.map} +0 -0
- /package/dist/{formula-M4FM364X.js.map → formula-EW7XLBSA.js.map} +0 -0
- /package/dist/{image-ocr-47CBNIS5.js.map → image-ocr-GWF2XELH.js.map} +0 -0
- /package/dist/{image-ocr-YJISJPKE.js.map → image-ocr-I7UGQZF5.js.map} +0 -0
- /package/dist/{model-bundle-7W344HDI.js.map → model-bundle-43YHGZCC.js.map} +0 -0
- /package/dist/{models-TBHMNI7M.js.map → models-O3NS6OPX.js.map} +0 -0
- /package/dist/{parse-worker-v2-JUYUEXCY.js.map → parse-worker-v2-OXW3CQOW.js.map} +0 -0
- /package/dist/{parser-RNJ4KSDF.js.map → parser-B3RVTCOY.js.map} +0 -0
- /package/dist/{parser-EKQCZLML.js.map → parser-H6OY6UWW.js.map} +0 -0
- /package/dist/{pdf-ocr-EE5KGFVX.js.map → pdf-ocr-NE6Y4I6O.js.map} +0 -0
- /package/dist/{pdf-ocr-ZAF4P74R.js.map → pdf-ocr-QHW74LO6.js.map} +0 -0
- /package/dist/{profile-io-RU3RVIYV.js.map → profile-io-2IOYOBGP.js.map} +0 -0
- /package/dist/{rasterize-UNCPM26D.js.map → rasterize-ZLPDGEZY.js.map} +0 -0
- /package/dist/{redact-doc-BFE4UZCY.js.map → redact-doc-CDFM5S7S.js.map} +0 -0
- /package/dist/{render-3DXTLKIA.js.map → render-VXAEYSJA.js.map} +0 -0
- /package/dist/{seal-3LBTETDG.js.map → seal-YSBFBEXC.js.map} +0 -0
- /package/dist/{setup-7POQAKDG.js.map → setup-CBWVQJID.js.map} +0 -0
- /package/dist/{visual-7SVIGIJC.js.map → visual-MJVIFZHH.js.map} +0 -0
- /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
|
|
38
|
+
var _chunkYAK4U7CCcjs = require('./chunk-YAK4U7CC.cjs');
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
var
|
|
41
|
+
var _chunk4ZNM7XRWcjs = require('./chunk-4ZNM7XRW.cjs');
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
var
|
|
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 =
|
|
393
|
-
const c = { chars, cx: (i) => (steps[i] + 0.5) * stepPx, gray, w: box.w, h: box.h, ink:
|
|
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 =
|
|
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 =
|
|
441
|
-
if (f &&
|
|
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 =
|
|
452
|
-
const shape = f &&
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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]) &&
|
|
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 } =
|
|
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\
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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',
|
|
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',
|
|
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 =
|
|
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,
|
|
906
|
-
}) : ortMod.InferenceSession.create(
|
|
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,
|
|
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 =
|
|
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,
|
|
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 =
|
|
947
|
-
const b =
|
|
948
|
-
if (_optionalChain([b, 'optionalAccess',
|
|
949
|
-
const ink =
|
|
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 =
|
|
966
|
-
const ink =
|
|
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 =
|
|
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 ?
|
|
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 ?
|
|
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 &&
|
|
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 &&
|
|
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 =
|
|
1025
|
-
const b =
|
|
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',
|
|
1029
|
-
else if (_optionalChain([b, 'optionalAccess',
|
|
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',
|
|
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',
|
|
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]) &&
|
|
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 =
|
|
1041
|
-
const tri =
|
|
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 =
|
|
1046
|
-
text = _nullishCoalesce(
|
|
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',
|
|
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)
|
|
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 =
|
|
1094
|
-
const t =
|
|
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,
|
|
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 =
|
|
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 ?
|
|
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.${
|
|
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,
|
|
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,
|
|
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 =
|
|
1323
|
-
const key =
|
|
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:
|
|
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 =
|
|
1430
|
-
if (bad) throw new (0,
|
|
1738
|
+
const bad = _chunk4ZNM7XRWcjs.validateOcrOptions.call(void 0, o);
|
|
1739
|
+
if (bad) throw new (0, _chunkOICA67ATcjs.KordocError)(bad);
|
|
1431
1740
|
return {
|
|
1432
|
-
models:
|
|
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
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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")
|
|
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
|
-
|
|
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',
|
|
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
|
-
|
|
2006
|
+
_chunkYAK4U7CCcjs.copyOcrTextGaps.call(void 0, it, normalized, 1 / scale);
|
|
1698
2007
|
return normalized;
|
|
1699
2008
|
});
|
|
1700
|
-
return
|
|
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.${
|
|
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-
|
|
2064
|
+
//# sourceMappingURL=chunk-X2XZXDBZ.cjs.map
|