kordoc 4.14.3 → 4.14.4
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 +16 -4
- package/dist/{-7XBPXCXN.js → -Z4TJ3QGK.js} +11 -11
- package/dist/{chunk-EBZUZC6F.cjs → chunk-5LAZQCUJ.cjs} +4 -4
- package/dist/{chunk-EBZUZC6F.cjs.map → chunk-5LAZQCUJ.cjs.map} +1 -1
- package/dist/{chunk-NQCUAGLR.js → chunk-6BWU6SQX.js} +1 -1
- package/dist/{chunk-2LQGSDZ6.js.map → chunk-6BWU6SQX.js.map} +1 -1
- package/dist/{chunk-2LQGSDZ6.js → chunk-6CUIXJOC.js} +1 -1
- package/dist/{chunk-NQCUAGLR.js.map → chunk-6CUIXJOC.js.map} +1 -1
- package/dist/{chunk-D6KQKMU3.js → chunk-7SE4EZ45.js} +2 -2
- package/dist/{chunk-YGBZABI4.js → chunk-D4U2TXDC.js} +6 -6
- package/dist/chunk-DPWWXUOG.js +2222 -0
- package/dist/chunk-DPWWXUOG.js.map +1 -0
- package/dist/{chunk-FAZR34CA.js → chunk-GLSBEEZJ.js} +2 -2
- package/dist/{chunk-L5EH2NVO.js → chunk-GUJ4Q73I.js} +2 -2
- package/dist/{chunk-JCVIOLBF.js → chunk-HIJUKZHM.js} +3 -3
- package/dist/{chunk-IW2CB755.cjs → chunk-IMAAFSAX.cjs} +392 -42
- package/dist/chunk-IMAAFSAX.cjs.map +1 -0
- package/dist/{chunk-GTINVM5K.js → chunk-LCW7SEPG.js} +2 -2
- package/dist/{chunk-4R67INKT.js → chunk-LFSQAMSM.js} +389 -39
- package/dist/chunk-LFSQAMSM.js.map +1 -0
- package/dist/{chunk-VJHAUMCF.js → chunk-MG6DJEX4.js} +389 -39
- package/dist/chunk-MG6DJEX4.js.map +1 -0
- package/dist/{chunk-QGW7NMTX.js → chunk-NLU6LBLY.js} +2 -2
- package/dist/{chunk-5VVS2QIJ.cjs → chunk-QEJUY6SK.cjs} +3 -3
- package/dist/{chunk-5VVS2QIJ.cjs.map → chunk-QEJUY6SK.cjs.map} +1 -1
- package/dist/{chunk-VYOGXNQ3.js → chunk-QIF2VXBQ.js} +2 -2
- package/dist/{chunk-I4NNYWIR.js → chunk-TITDJWVZ.js} +2 -2
- package/dist/{chunk-NOAQRCV6.cjs → chunk-USHQCF5T.cjs} +676 -75
- package/dist/chunk-USHQCF5T.cjs.map +1 -0
- package/dist/{chunk-VNFJPTU4.js → chunk-V3DX4DUF.js} +2 -2
- package/dist/{chunk-WB5LW52Z.js → chunk-VDN7LMPL.js} +2 -2
- package/dist/{chunk-IHZEFW4L.js → chunk-VJIL6PIL.js} +2 -2
- package/dist/{chunk-HX4UUF7Y.cjs → chunk-VWUYVEFN.cjs} +1 -1
- package/dist/{chunk-HX4UUF7Y.cjs.map → chunk-VWUYVEFN.cjs.map} +1 -1
- package/dist/{chunk-EMGF6EEV.cjs → chunk-WJHAU73B.cjs} +2 -2
- package/dist/{chunk-EMGF6EEV.cjs.map → chunk-WJHAU73B.cjs.map} +1 -1
- package/dist/{chunk-O2PGQNYE.js → chunk-WJJGW5PL.js} +2 -2
- package/dist/{chunk-CVEERPMP.js → chunk-XVXHXQIO.js} +9 -9
- package/dist/{chunk-4RJ5D7MT.js → chunk-YAKC46HZ.js} +2 -2
- package/dist/{chunk-A275ZQLX.js → chunk-YAVHVFRY.js} +653 -52
- package/dist/chunk-YAVHVFRY.js.map +1 -0
- package/dist/{chunk-UVVEBI22.js → chunk-YT3GC62E.js} +653 -52
- package/dist/chunk-YT3GC62E.js.map +1 -0
- package/dist/chunks-CCMRL4MJ.js +10 -0
- package/dist/cli.js +28 -28
- package/dist/cli.js.map +1 -1
- package/dist/{formula-CPO2TZGB.cjs → formula-5LOVHAKE.cjs} +9 -9
- package/dist/{formula-CPO2TZGB.cjs.map → formula-5LOVHAKE.cjs.map} +1 -1
- package/dist/{formula-X44GV7TN.js → formula-7RANCW5L.js} +3 -3
- package/dist/{formula-NOIDZEBA.js → formula-7UYJOVTB.js} +4 -4
- package/dist/{image-ocr-72RAR4WR.js → image-ocr-I6JOCATS.js} +8 -8
- package/dist/{image-ocr-SUGT64ZM.cjs → image-ocr-NYBJEOH2.cjs} +13 -13
- package/dist/{image-ocr-SUGT64ZM.cjs.map → image-ocr-NYBJEOH2.cjs.map} +1 -1
- package/dist/{image-ocr-R6W6A75P.js → image-ocr-ZV6PDBUQ.js} +6 -6
- package/dist/index.cjs +2137 -537
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1851 -251
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +24 -24
- package/dist/mcp.js.map +1 -1
- package/dist/{model-bundle-57CLEBCO.js → model-bundle-2C5IYDLE.js} +5 -5
- package/dist/{models-7ELIFTD7.js → models-SEQZHZFT.js} +5 -5
- package/dist/{parser-4NKAYWAX.js → parser-3FNXEP6T.js} +485 -47
- package/dist/parser-3FNXEP6T.js.map +1 -0
- package/dist/{parser-HWFQRSUQ.js → parser-FJBJXRJK.js} +485 -47
- package/dist/parser-FJBJXRJK.js.map +1 -0
- package/dist/{parser-RANGXGBD.cjs → parser-HVEKF73B.cjs} +535 -97
- package/dist/parser-HVEKF73B.cjs.map +1 -0
- package/dist/pdf-ocr-JRDBJ6TA.cjs +14 -0
- package/dist/{pdf-ocr-VHSFACH7.cjs.map → pdf-ocr-JRDBJ6TA.cjs.map} +1 -1
- package/dist/pdf-ocr-UUBWBEHL.js +16 -0
- package/dist/pdf-ocr-VJSF2SQC.js +13 -0
- package/dist/{profile-io-V52PL5ZO.js → profile-io-RUFZOZO6.js} +3 -3
- package/dist/{rasterize-ZIGLJDOG.js → rasterize-IOYXR5SI.js} +3 -3
- package/dist/{redact-TIQEQI3M.js → redact-NMIKVHMP.js} +2 -2
- package/dist/{redact-doc-KXZ3TZAG.js → redact-doc-QBHNJ2BU.js} +98 -30
- package/dist/redact-doc-QBHNJ2BU.js.map +1 -0
- package/dist/{render-U5PE6V2E.js → render-YZ2TEC3N.js} +7 -7
- package/dist/seal-ECV44TUH.js +10 -0
- package/dist/{setup-YRDM4ODP.js → setup-MPIEP6XT.js} +3 -3
- package/dist/visual-ICMOWUCR.js +19 -0
- package/dist/{watch-5IOLBATT.js → watch-RYO7MN5B.js} +12 -12
- package/package.json +2 -2
- package/dist/chunk-4R67INKT.js.map +0 -1
- package/dist/chunk-A275ZQLX.js.map +0 -1
- package/dist/chunk-IH56ZISC.js +0 -620
- package/dist/chunk-IH56ZISC.js.map +0 -1
- package/dist/chunk-IW2CB755.cjs.map +0 -1
- package/dist/chunk-NOAQRCV6.cjs.map +0 -1
- package/dist/chunk-UVVEBI22.js.map +0 -1
- package/dist/chunk-VJHAUMCF.js.map +0 -1
- package/dist/chunks-I7TEMJXH.js +0 -10
- package/dist/parser-4NKAYWAX.js.map +0 -1
- package/dist/parser-HWFQRSUQ.js.map +0 -1
- package/dist/parser-RANGXGBD.cjs.map +0 -1
- package/dist/pdf-ocr-BNC34MNU.js +0 -13
- package/dist/pdf-ocr-QX2GB33Q.js +0 -16
- package/dist/pdf-ocr-VHSFACH7.cjs +0 -14
- package/dist/redact-doc-KXZ3TZAG.js.map +0 -1
- package/dist/seal-DNXJBILR.js +0 -10
- package/dist/visual-5XWMA4EV.js +0 -19
- /package/dist/{-7XBPXCXN.js.map → -Z4TJ3QGK.js.map} +0 -0
- /package/dist/{chunk-D6KQKMU3.js.map → chunk-7SE4EZ45.js.map} +0 -0
- /package/dist/{chunk-YGBZABI4.js.map → chunk-D4U2TXDC.js.map} +0 -0
- /package/dist/{chunk-FAZR34CA.js.map → chunk-GLSBEEZJ.js.map} +0 -0
- /package/dist/{chunk-L5EH2NVO.js.map → chunk-GUJ4Q73I.js.map} +0 -0
- /package/dist/{chunk-JCVIOLBF.js.map → chunk-HIJUKZHM.js.map} +0 -0
- /package/dist/{chunk-GTINVM5K.js.map → chunk-LCW7SEPG.js.map} +0 -0
- /package/dist/{chunk-QGW7NMTX.js.map → chunk-NLU6LBLY.js.map} +0 -0
- /package/dist/{chunk-VYOGXNQ3.js.map → chunk-QIF2VXBQ.js.map} +0 -0
- /package/dist/{chunk-I4NNYWIR.js.map → chunk-TITDJWVZ.js.map} +0 -0
- /package/dist/{chunk-VNFJPTU4.js.map → chunk-V3DX4DUF.js.map} +0 -0
- /package/dist/{chunk-WB5LW52Z.js.map → chunk-VDN7LMPL.js.map} +0 -0
- /package/dist/{chunk-IHZEFW4L.js.map → chunk-VJIL6PIL.js.map} +0 -0
- /package/dist/{chunk-O2PGQNYE.js.map → chunk-WJJGW5PL.js.map} +0 -0
- /package/dist/{chunk-CVEERPMP.js.map → chunk-XVXHXQIO.js.map} +0 -0
- /package/dist/{chunk-4RJ5D7MT.js.map → chunk-YAKC46HZ.js.map} +0 -0
- /package/dist/{chunks-I7TEMJXH.js.map → chunks-CCMRL4MJ.js.map} +0 -0
- /package/dist/{formula-X44GV7TN.js.map → formula-7RANCW5L.js.map} +0 -0
- /package/dist/{formula-NOIDZEBA.js.map → formula-7UYJOVTB.js.map} +0 -0
- /package/dist/{image-ocr-72RAR4WR.js.map → image-ocr-I6JOCATS.js.map} +0 -0
- /package/dist/{image-ocr-R6W6A75P.js.map → image-ocr-ZV6PDBUQ.js.map} +0 -0
- /package/dist/{model-bundle-57CLEBCO.js.map → model-bundle-2C5IYDLE.js.map} +0 -0
- /package/dist/{models-7ELIFTD7.js.map → models-SEQZHZFT.js.map} +0 -0
- /package/dist/{pdf-ocr-BNC34MNU.js.map → pdf-ocr-UUBWBEHL.js.map} +0 -0
- /package/dist/{pdf-ocr-QX2GB33Q.js.map → pdf-ocr-VJSF2SQC.js.map} +0 -0
- /package/dist/{profile-io-V52PL5ZO.js.map → profile-io-RUFZOZO6.js.map} +0 -0
- /package/dist/{rasterize-ZIGLJDOG.js.map → rasterize-IOYXR5SI.js.map} +0 -0
- /package/dist/{redact-TIQEQI3M.js.map → redact-NMIKVHMP.js.map} +0 -0
- /package/dist/{render-U5PE6V2E.js.map → render-YZ2TEC3N.js.map} +0 -0
- /package/dist/{seal-DNXJBILR.js.map → seal-ECV44TUH.js.map} +0 -0
- /package/dist/{setup-YRDM4ODP.js.map → setup-MPIEP6XT.js.map} +0 -0
- /package/dist/{visual-5XWMA4EV.js.map → visual-ICMOWUCR.js.map} +0 -0
- /package/dist/{watch-5IOLBATT.js.map → watch-RYO7MN5B.js.map} +0 -0
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
var _chunk5LAZQCUJcjs = require('./chunk-5LAZQCUJ.cjs');
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
var _chunkDCZVOIEOcjs = require('./chunk-DCZVOIEO.cjs');
|
|
@@ -25,12 +26,15 @@ var _chunkDCZVOIEOcjs = require('./chunk-DCZVOIEO.cjs');
|
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
var _chunkNOAQRCV6cjs = require('./chunk-NOAQRCV6.cjs');
|
|
29
|
-
require('./chunk-HX4UUF7Y.cjs');
|
|
30
29
|
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
var
|
|
32
|
+
var _chunkUSHQCF5Tcjs = require('./chunk-USHQCF5T.cjs');
|
|
33
|
+
require('./chunk-VWUYVEFN.cjs');
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
var _chunkWJHAU73Bcjs = require('./chunk-WJHAU73B.cjs');
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
var _chunkGS7T56RPcjs = require('./chunk-GS7T56RP.cjs');
|
|
@@ -160,7 +164,7 @@ async function extractPageImages(page, fnArray, argsArray, pageNumber, state, wa
|
|
|
160
164
|
const filename = `image_${String(state.imageIndex).padStart(3, "0")}.png`;
|
|
161
165
|
state.seen.set(hash, filename);
|
|
162
166
|
if (withBytes) {
|
|
163
|
-
const png =
|
|
167
|
+
const png = _chunk5LAZQCUJcjs.encodePng.call(void 0, w, h, rgba);
|
|
164
168
|
state.totalBytes += png.length;
|
|
165
169
|
images.push({ filename, data: png, mimeType: "image/png" });
|
|
166
170
|
}
|
|
@@ -208,7 +212,9 @@ var RARE_JONG = /* @__PURE__ */ new Set([3, 5, 6, 9, 10, 11, 12, 13, 14, 15, 18,
|
|
|
208
212
|
var MOJIBAKE_MIN_HANGUL = 30;
|
|
209
213
|
var MOJIBAKE_MAX_NOBATCHIM = 0.15;
|
|
210
214
|
var MOJIBAKE_MIN_RAREBATCHIM = 0.25;
|
|
211
|
-
|
|
215
|
+
var VECTOR_TEXT_MIN_GLYPHS = 40;
|
|
216
|
+
var VECTOR_TEXT_MIN_SHARE = 0.25;
|
|
217
|
+
function computePageQuality(page, text, vectorGlyphs = 0) {
|
|
212
218
|
let total = 0;
|
|
213
219
|
let hangul = 0;
|
|
214
220
|
let hangulNoBatchim = 0;
|
|
@@ -249,7 +255,10 @@ function computePageQuality(page, text) {
|
|
|
249
255
|
const garbledHangul = hangul >= MOJIBAKE_MIN_HANGUL && hangulNoBatchimRatio < MOJIBAKE_MAX_NOBATCHIM && hangulRareBatchimRatio >= MOJIBAKE_MIN_RAREBATCHIM;
|
|
250
256
|
let needsOcr = false;
|
|
251
257
|
let ocrReason;
|
|
252
|
-
if (total
|
|
258
|
+
if (vectorGlyphs >= VECTOR_TEXT_MIN_GLYPHS && vectorGlyphs >= (vectorGlyphs + total) * VECTOR_TEXT_MIN_SHARE) {
|
|
259
|
+
needsOcr = true;
|
|
260
|
+
ocrReason = "vector_text";
|
|
261
|
+
} else if (total < LOW_TEXT_THRESHOLD) {
|
|
253
262
|
needsOcr = true;
|
|
254
263
|
ocrReason = "low_text";
|
|
255
264
|
} else if (puaRatio >= HIGH_PUA_THRESHOLD) {
|
|
@@ -334,6 +343,221 @@ function summarizeDocumentQuality(pages) {
|
|
|
334
343
|
};
|
|
335
344
|
}
|
|
336
345
|
|
|
346
|
+
// src/pdf/vector-glyphs.ts
|
|
347
|
+
|
|
348
|
+
var GLYPH_MIN_H = 3;
|
|
349
|
+
var GLYPH_MAX_H = 40;
|
|
350
|
+
var GLYPH_MAX_ASPECT = 2;
|
|
351
|
+
var GLYPH_MIN_SEGS = 8;
|
|
352
|
+
var GLYPH_MIN_SUBS = 2;
|
|
353
|
+
var RUN_GAP_EM = 1.5;
|
|
354
|
+
var RUN_MIN = 3;
|
|
355
|
+
var RUN_ALIGN_EM = 0.05;
|
|
356
|
+
var RUN_MAX_OVERLAP = 0.2;
|
|
357
|
+
var RUN_MIN_COLOR = 0.9;
|
|
358
|
+
var RUN_MIN_SHAPES = 0.5;
|
|
359
|
+
var mul = (m, t) => [
|
|
360
|
+
m[0] * t[0] + m[2] * t[1],
|
|
361
|
+
m[1] * t[0] + m[3] * t[1],
|
|
362
|
+
m[0] * t[2] + m[2] * t[3],
|
|
363
|
+
m[1] * t[2] + m[3] * t[3],
|
|
364
|
+
m[0] * t[4] + m[2] * t[5] + m[4],
|
|
365
|
+
m[1] * t[4] + m[3] * t[5] + m[5]
|
|
366
|
+
];
|
|
367
|
+
function collectGlyphPaths(fnArray, argsArray) {
|
|
368
|
+
const out = [];
|
|
369
|
+
let ctm = [1, 0, 0, 1, 0, 0];
|
|
370
|
+
let color = 0;
|
|
371
|
+
const stack = [];
|
|
372
|
+
let x1 = Infinity, y1 = Infinity, x2 = -Infinity, y2 = -Infinity;
|
|
373
|
+
let segs = 0, subs = 0, rects = 0;
|
|
374
|
+
let ops = [];
|
|
375
|
+
const add = (x, y) => {
|
|
376
|
+
const tx = ctm[0] * x + ctm[2] * y + ctm[4], ty = ctm[1] * x + ctm[3] * y + ctm[5];
|
|
377
|
+
if (tx < x1) x1 = tx;
|
|
378
|
+
if (tx > x2) x2 = tx;
|
|
379
|
+
if (ty < y1) y1 = ty;
|
|
380
|
+
if (ty > y2) y2 = ty;
|
|
381
|
+
};
|
|
382
|
+
const reset = () => {
|
|
383
|
+
x1 = Infinity;
|
|
384
|
+
y1 = Infinity;
|
|
385
|
+
x2 = -Infinity;
|
|
386
|
+
y2 = -Infinity;
|
|
387
|
+
segs = 0;
|
|
388
|
+
subs = 0;
|
|
389
|
+
rects = 0;
|
|
390
|
+
ops = [];
|
|
391
|
+
};
|
|
392
|
+
for (let i = 0; i < fnArray.length; i++) {
|
|
393
|
+
const op = fnArray[i];
|
|
394
|
+
const args = argsArray[i];
|
|
395
|
+
switch (op) {
|
|
396
|
+
case _pdfmjs.OPS.save:
|
|
397
|
+
stack.push([ctm, color]);
|
|
398
|
+
break;
|
|
399
|
+
case _pdfmjs.OPS.restore:
|
|
400
|
+
[ctm, color] = _nullishCoalesce(stack.pop(), () => ( [[1, 0, 0, 1, 0, 0], 0]));
|
|
401
|
+
break;
|
|
402
|
+
case _pdfmjs.OPS.transform:
|
|
403
|
+
ctm = mul(ctm, args);
|
|
404
|
+
break;
|
|
405
|
+
case _pdfmjs.OPS.paintFormXObjectBegin: {
|
|
406
|
+
stack.push([ctm, color]);
|
|
407
|
+
const m = args[0];
|
|
408
|
+
if (Array.isArray(m) && m.length >= 6) ctm = mul(ctm, m);
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
case _pdfmjs.OPS.paintFormXObjectEnd:
|
|
412
|
+
[ctm, color] = _nullishCoalesce(stack.pop(), () => ( [[1, 0, 0, 1, 0, 0], 0]));
|
|
413
|
+
break;
|
|
414
|
+
case _pdfmjs.OPS.setFillRGBColor: {
|
|
415
|
+
const c = args;
|
|
416
|
+
color = c[0] << 16 | c[1] << 8 | c[2];
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
case _pdfmjs.OPS.constructPath: {
|
|
420
|
+
const [subOps, coords] = args;
|
|
421
|
+
if (!Array.isArray(subOps) || !Array.isArray(coords)) break;
|
|
422
|
+
ops.push(i);
|
|
423
|
+
let ci = 0;
|
|
424
|
+
for (const s of subOps) {
|
|
425
|
+
if (s === _pdfmjs.OPS.moveTo) {
|
|
426
|
+
add(coords[ci], coords[ci + 1]);
|
|
427
|
+
ci += 2;
|
|
428
|
+
subs++;
|
|
429
|
+
} else if (s === _pdfmjs.OPS.lineTo) {
|
|
430
|
+
add(coords[ci], coords[ci + 1]);
|
|
431
|
+
ci += 2;
|
|
432
|
+
segs++;
|
|
433
|
+
} else if (s === _pdfmjs.OPS.curveTo) {
|
|
434
|
+
add(coords[ci], coords[ci + 1]);
|
|
435
|
+
add(coords[ci + 2], coords[ci + 3]);
|
|
436
|
+
add(coords[ci + 4], coords[ci + 5]);
|
|
437
|
+
ci += 6;
|
|
438
|
+
segs++;
|
|
439
|
+
} else if (s === _pdfmjs.OPS.curveTo2 || s === _pdfmjs.OPS.curveTo3) {
|
|
440
|
+
add(coords[ci], coords[ci + 1]);
|
|
441
|
+
add(coords[ci + 2], coords[ci + 3]);
|
|
442
|
+
ci += 4;
|
|
443
|
+
segs++;
|
|
444
|
+
} else if (s === _pdfmjs.OPS.rectangle) {
|
|
445
|
+
const rx = coords[ci], ry = coords[ci + 1], rw = coords[ci + 2], rh = coords[ci + 3];
|
|
446
|
+
add(rx, ry);
|
|
447
|
+
add(rx + rw, ry + rh);
|
|
448
|
+
add(rx, ry + rh);
|
|
449
|
+
add(rx + rw, ry);
|
|
450
|
+
ci += 4;
|
|
451
|
+
rects++;
|
|
452
|
+
subs++;
|
|
453
|
+
segs += 4;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
case _pdfmjs.OPS.fill:
|
|
459
|
+
case _pdfmjs.OPS.eoFill:
|
|
460
|
+
case _pdfmjs.OPS.fillStroke:
|
|
461
|
+
case _pdfmjs.OPS.eoFillStroke:
|
|
462
|
+
case _pdfmjs.OPS.closeFillStroke:
|
|
463
|
+
case _pdfmjs.OPS.closeEOFillStroke: {
|
|
464
|
+
const w = x2 - x1, h = y2 - y1;
|
|
465
|
+
if (segs > rects * 4 && h >= GLYPH_MIN_H && h <= GLYPH_MAX_H && w <= h * GLYPH_MAX_ASPECT && segs >= GLYPH_MIN_SEGS && subs >= GLYPH_MIN_SUBS) {
|
|
466
|
+
out.push({ x1, y1, x2, y2, segs, subs, color, ops: [...ops, i] });
|
|
467
|
+
}
|
|
468
|
+
reset();
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
case _pdfmjs.OPS.stroke:
|
|
472
|
+
case _pdfmjs.OPS.closeStroke:
|
|
473
|
+
case _pdfmjs.OPS.endPath:
|
|
474
|
+
reset();
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return out;
|
|
479
|
+
}
|
|
480
|
+
function coveredByText(b, texts) {
|
|
481
|
+
const cx = (b.x1 + b.x2) / 2, cy = (b.y1 + b.y2) / 2;
|
|
482
|
+
for (const t of texts) {
|
|
483
|
+
if (cx >= t.x - 1 && cx <= t.x + t.w + 1 && cy >= t.y - t.h * 0.3 - 1 && cy <= t.y + t.h + 1 && t.text.trim()) return true;
|
|
484
|
+
}
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
var median = (a) => {
|
|
488
|
+
const s = a.slice().sort((x, y) => x - y);
|
|
489
|
+
return s[s.length >> 1];
|
|
490
|
+
};
|
|
491
|
+
var spread = (a) => {
|
|
492
|
+
const c = median(a);
|
|
493
|
+
return median(a.map((v) => Math.abs(v - c)));
|
|
494
|
+
};
|
|
495
|
+
function isTextRun(m, em) {
|
|
496
|
+
if (m.length < RUN_MIN) return false;
|
|
497
|
+
if (Math.min(spread(m.map((b) => b.y2)), spread(m.map((b) => b.y1))) > em * RUN_ALIGN_EM) return false;
|
|
498
|
+
let overlaps = 0;
|
|
499
|
+
for (let i = 1; i < m.length; i++) if (m[i].x1 < m[i - 1].x2 - em * 0.1) overlaps++;
|
|
500
|
+
if (overlaps > (m.length - 1) * RUN_MAX_OVERLAP) return false;
|
|
501
|
+
const colors = /* @__PURE__ */ new Map();
|
|
502
|
+
for (const b of m) colors.set(b.color, (_nullishCoalesce(colors.get(b.color), () => ( 0))) + 1);
|
|
503
|
+
if (Math.max(...colors.values()) < m.length * RUN_MIN_COLOR) return false;
|
|
504
|
+
const shapes = new Set(m.map((b) => `${Math.round((b.x2 - b.x1) * 2)}:${Math.round((b.y2 - b.y1) * 2)}:${b.segs}`));
|
|
505
|
+
return shapes.size >= m.length * RUN_MIN_SHAPES;
|
|
506
|
+
}
|
|
507
|
+
function scanVectorGlyphs(fnArray, argsArray, texts) {
|
|
508
|
+
const paths = collectGlyphPaths(fnArray, argsArray);
|
|
509
|
+
if (paths.length < RUN_MIN) return { glyphs: 0, paths };
|
|
510
|
+
const free = paths.filter((b) => !coveredByText(b, texts));
|
|
511
|
+
const sorted = free.slice().sort((a, b) => a.y1 + a.y2 - (b.y1 + b.y2));
|
|
512
|
+
let glyphs = 0;
|
|
513
|
+
let row = [];
|
|
514
|
+
let rowCy = 0, rowH = 0;
|
|
515
|
+
const flushRow = () => {
|
|
516
|
+
if (row.length < RUN_MIN) return;
|
|
517
|
+
row.sort((a, b) => a.x1 - b.x1);
|
|
518
|
+
const em = median(row.map((b) => b.y2 - b.y1));
|
|
519
|
+
let start = 0, maxX = row[0].x2;
|
|
520
|
+
for (let i = 1; i <= row.length; i++) {
|
|
521
|
+
if (i < row.length && row[i].x1 - maxX <= em * RUN_GAP_EM) {
|
|
522
|
+
if (row[i].x2 > maxX) maxX = row[i].x2;
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
const run = row.slice(start, i);
|
|
526
|
+
if (isTextRun(run, em)) glyphs += run.length;
|
|
527
|
+
if (i < row.length) {
|
|
528
|
+
start = i;
|
|
529
|
+
maxX = row[i].x2;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
for (const b of sorted) {
|
|
534
|
+
const cy = (b.y1 + b.y2) / 2, h = b.y2 - b.y1;
|
|
535
|
+
if (row.length && Math.abs(cy - rowCy) <= Math.max(h, rowH) * 0.5) {
|
|
536
|
+
row.push(b);
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
flushRow();
|
|
540
|
+
row = [b];
|
|
541
|
+
rowCy = cy;
|
|
542
|
+
rowH = h;
|
|
543
|
+
}
|
|
544
|
+
flushRow();
|
|
545
|
+
return { glyphs, paths };
|
|
546
|
+
}
|
|
547
|
+
function ocrVectorOps(opList, paths) {
|
|
548
|
+
const drop = /* @__PURE__ */ new Set();
|
|
549
|
+
for (const p of paths) for (const i of p.ops) drop.add(i);
|
|
550
|
+
const fnArray = [];
|
|
551
|
+
const argsArray = [];
|
|
552
|
+
for (let i = 0; i < opList.fnArray.length; i++) {
|
|
553
|
+
const op = opList.fnArray[i];
|
|
554
|
+
if (drop.has(i) || op === _pdfmjs.OPS.clip || op === _pdfmjs.OPS.eoClip) continue;
|
|
555
|
+
fnArray.push(op);
|
|
556
|
+
argsArray.push(opList.argsArray[i]);
|
|
557
|
+
}
|
|
558
|
+
return { fnArray, argsArray };
|
|
559
|
+
}
|
|
560
|
+
|
|
337
561
|
// src/pdf/table-parts.ts
|
|
338
562
|
var PART_COL_TOL = 1;
|
|
339
563
|
function anchorsOf(table) {
|
|
@@ -369,7 +593,8 @@ var indexOf = (coords, x) => {
|
|
|
369
593
|
return bestD <= PART_COL_TOL ? best : -1;
|
|
370
594
|
};
|
|
371
595
|
var rowText = (anchors, r) => anchors.filter((a) => a.r === r).map((a) => a.cell.text.replace(/\s+/g, "")).join("|");
|
|
372
|
-
|
|
596
|
+
var hasText = (t) => t.replace(/\|/g, "") !== "";
|
|
597
|
+
function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
|
|
373
598
|
if (pcx.length !== prev.cols + 1 || ccx.length !== curr.cols + 1) return null;
|
|
374
599
|
const U = unionCoords(pcx, ccx);
|
|
375
600
|
const cols = U.length - 1;
|
|
@@ -377,10 +602,13 @@ function joinSplitParts(prev, pcx, curr, ccx) {
|
|
|
377
602
|
const pa = anchorsOf(prev), ca = anchorsOf(curr);
|
|
378
603
|
let skip = 0;
|
|
379
604
|
while (skip < Math.min(3, curr.rows - 1, prev.rows) && rowText(ca, skip) !== "" && rowText(ca, skip) === rowText(pa, skip)) skip++;
|
|
605
|
+
for (let h = 1; h <= 2 && !skip; h++) {
|
|
606
|
+
while (skip < Math.min(3, curr.rows - 1, prev.rows - h) && hasText(rowText(ca, skip)) && rowText(ca, skip) === rowText(pa, h + skip)) skip++;
|
|
607
|
+
}
|
|
380
608
|
const rows = prev.rows + curr.rows - skip;
|
|
381
609
|
const grid = Array.from({ length: rows }, () => Array.from({ length: cols }, () => ({ text: "", colSpan: 1, rowSpan: 1 })));
|
|
382
610
|
const owner = Array.from({ length: rows }, () => new Array(cols).fill(null));
|
|
383
|
-
const place = (a, x, rowOff) => {
|
|
611
|
+
const place = (a, x, rowOff, shift = 0) => {
|
|
384
612
|
const c1 = indexOf(U, x[a.c]), c2 = indexOf(U, x[a.c + a.cs]);
|
|
385
613
|
if (c1 < 0 || c2 <= c1) return false;
|
|
386
614
|
const r = a.r + rowOff;
|
|
@@ -389,15 +617,15 @@ function joinSplitParts(prev, pcx, curr, ccx) {
|
|
|
389
617
|
if (r + dr < rows) owner[r + dr][dc] = placed;
|
|
390
618
|
}
|
|
391
619
|
grid[r][c1] = { ...a.cell, colSpan: c2 - c1, rowSpan: a.rs };
|
|
392
|
-
const lines =
|
|
393
|
-
if (lines)
|
|
394
|
-
if (
|
|
620
|
+
const lines = _chunkUSHQCF5Tcjs.CELL_LINES.get(a.cell);
|
|
621
|
+
if (lines) _chunkUSHQCF5Tcjs.CELL_LINES.set(grid[r][c1], shift ? lines.map((l) => ({ ...l, l: l.l + shift, r: l.r + shift })) : lines);
|
|
622
|
+
if (_chunkUSHQCF5Tcjs.IMAGE_CELLS.has(a.cell)) _chunkUSHQCF5Tcjs.IMAGE_CELLS.add(grid[r][c1]);
|
|
395
623
|
return true;
|
|
396
624
|
};
|
|
397
|
-
for (const a of pa) if (!
|
|
625
|
+
for (const a of pa) if (!_chunkUSHQCF5Tcjs.FILLER_CELLS.has(a.cell) && !place(a, pcx, 0)) return null;
|
|
398
626
|
for (const a of ca) {
|
|
399
|
-
if (a.r < skip ||
|
|
400
|
-
if (!place(a, ccx, prev.rows - skip)) return null;
|
|
627
|
+
if (a.r < skip || _chunkUSHQCF5Tcjs.FILLER_CELLS.has(a.cell)) continue;
|
|
628
|
+
if (!place(a, ccx, prev.rows - skip, dx)) return null;
|
|
401
629
|
}
|
|
402
630
|
const first = prev.rows;
|
|
403
631
|
for (let c = 0; c < cols; c++) {
|
|
@@ -420,19 +648,49 @@ function joinSplitParts(prev, pcx, curr, ccx) {
|
|
|
420
648
|
const grown = { ...above, rs: newRs };
|
|
421
649
|
for (let rr = above.r; rr < above.r + newRs; rr++) for (let dc = above.c; dc < above.c + above.cs; dc++) owner[rr][dc] = grown;
|
|
422
650
|
}
|
|
423
|
-
for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) if (owner[r][c] === null)
|
|
651
|
+
for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) if (owner[r][c] === null) _chunkUSHQCF5Tcjs.FILLER_CELLS.add(grid[r][c]);
|
|
424
652
|
const table = { rows, cols, cells: grid, hasHeader: prev.hasHeader, ...prev.caption ? { caption: prev.caption } : {} };
|
|
425
|
-
|
|
426
|
-
|
|
653
|
+
const split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
|
|
654
|
+
if (rows > prev.rows && !split && prevBottom !== void 0) mergeStraddlingCells(table, owner, prev.rows, prevBottom);
|
|
655
|
+
return { table, colXs: U, split, header: ca.filter((a) => a.r < skip && a.cell.text.trim()).length >= 2 };
|
|
656
|
+
}
|
|
657
|
+
function mergeStraddlingCells(table, owner, first, prevBottom) {
|
|
658
|
+
const last = first - 1;
|
|
659
|
+
if (!owner[first].some((o, c) => o !== null && o === owner[last][c])) return;
|
|
660
|
+
for (let c = 0; c < table.cols; ) {
|
|
661
|
+
const u = owner[last][c], d = owner[first][c];
|
|
662
|
+
if (!u) {
|
|
663
|
+
c++;
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
c = u.c + u.cs;
|
|
667
|
+
if (!d || d === u || u.r >= last || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
|
|
668
|
+
const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
|
|
669
|
+
const U = _chunkUSHQCF5Tcjs.CELL_LINES.get(a);
|
|
670
|
+
if (!_optionalChain([U, 'optionalAccess', _12 => _12.length]) || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
|
|
671
|
+
const lu = U[U.length - 1];
|
|
672
|
+
if (lu.y - prevBottom > STRADDLE_BOTTOM * (lu.h || 10)) continue;
|
|
673
|
+
appendCell(a, b);
|
|
674
|
+
a.rowSpan = first + d.rs - u.r;
|
|
675
|
+
table.cells[first][d.c] = { text: "", colSpan: 1, rowSpan: 1 };
|
|
676
|
+
const grown = { ...u, rs: a.rowSpan };
|
|
677
|
+
for (let rr = u.r; rr < u.r + grown.rs; rr++) for (let dc = u.c; dc < u.c + u.cs; dc++) owner[rr][dc] = grown;
|
|
678
|
+
}
|
|
427
679
|
}
|
|
428
680
|
var FULL_LINE_TOL = 1;
|
|
429
681
|
var FULL_LINE_MIN_FRAC = 0.5;
|
|
430
682
|
var FULL_LINE_EDGE_MIN = 12;
|
|
431
683
|
var SINGLE_LINE_WORD_GAP = 3.5;
|
|
432
684
|
var SHORT_LINE_GAP = 1.5;
|
|
685
|
+
var STRADDLE_MAX_LINES = 3;
|
|
686
|
+
var STRADDLE_BOTTOM = 1.2;
|
|
687
|
+
var CARRIED_MIN_COL_W = 4;
|
|
688
|
+
var LABEL_ROOM = 1.5;
|
|
689
|
+
var HANGING_MIN = 0.5;
|
|
690
|
+
var HANGING_TOL = 1;
|
|
433
691
|
function continuesAcross(u, d, x1, x2) {
|
|
434
|
-
const U =
|
|
435
|
-
if (!_optionalChain([U, 'optionalAccess',
|
|
692
|
+
const U = _chunkUSHQCF5Tcjs.CELL_LINES.get(u), D = _chunkUSHQCF5Tcjs.CELL_LINES.get(d);
|
|
693
|
+
if (!_optionalChain([U, 'optionalAccess', _13 => _13.length]) || !_optionalChain([D, 'optionalAccess', _14 => _14.length])) return false;
|
|
436
694
|
const last = U[U.length - 1];
|
|
437
695
|
const fs = last.h || 10;
|
|
438
696
|
let minL = Infinity, maxR = -Infinity;
|
|
@@ -444,70 +702,113 @@ function continuesAcross(u, d, x1, x2) {
|
|
|
444
702
|
minL = Math.min(minL, l.l);
|
|
445
703
|
maxR = Math.max(maxR, l.r);
|
|
446
704
|
}
|
|
705
|
+
maxR = Math.max(maxR, x2 - (minL - x1));
|
|
447
706
|
if (maxR - last.r > FULL_LINE_TOL * fs) return false;
|
|
448
707
|
if (U.length === 1 && x2 - last.r > Math.max(FULL_LINE_EDGE_MIN, SINGLE_LINE_WORD_GAP * fs)) return false;
|
|
449
708
|
if (last.r - last.l < FULL_LINE_MIN_FRAC * (x2 - x1)) return false;
|
|
450
709
|
const leftAligned = (l) => l.l - minL <= fs && maxR - l.r > SHORT_LINE_GAP * fs;
|
|
451
|
-
|
|
710
|
+
const hanging = U.length >= 2 && U.every((l) => maxR - l.r <= FULL_LINE_TOL * fs) && last.l - minL >= HANGING_MIN * fs && Math.abs(D[0].l - last.l) <= HANGING_TOL;
|
|
711
|
+
return U.some(leftAligned) || D.some(leftAligned) || hanging;
|
|
712
|
+
}
|
|
713
|
+
function lineEnded(c, x1, x2) {
|
|
714
|
+
const L = _chunkUSHQCF5Tcjs.CELL_LINES.get(c);
|
|
715
|
+
if (!L || L.length !== 1) return false;
|
|
716
|
+
const l = L[0];
|
|
717
|
+
return x2 - l.r - (l.l - x1) >= LABEL_ROOM * (l.h || 10);
|
|
452
718
|
}
|
|
719
|
+
function appendCell(a, b) {
|
|
720
|
+
if (_optionalChain([a, 'access', _15 => _15.blocks, 'optionalAccess', _16 => _16.length]) || _optionalChain([b, 'access', _17 => _17.blocks, 'optionalAccess', _18 => _18.length])) {
|
|
721
|
+
const asBlocks = (c) => _optionalChain([c, 'access', _19 => _19.blocks, 'optionalAccess', _20 => _20.length]) ? c.blocks : c.text.split("\n").map((l) => l.trim()).filter(Boolean).map((text) => ({ type: "paragraph", text }));
|
|
722
|
+
a.blocks = [...asBlocks(a), ...asBlocks(b)];
|
|
723
|
+
}
|
|
724
|
+
if (b.text.trim()) a.text = a.text.trim() ? a.text + "\n" + b.text : b.text;
|
|
725
|
+
}
|
|
726
|
+
var hasContent = (cell) => !!cell.text.trim() || !!_optionalChain([cell, 'access', _21 => _21.blocks, 'optionalAccess', _22 => _22.length]) || _chunkUSHQCF5Tcjs.IMAGE_CELLS.has(cell);
|
|
453
727
|
function mergeSplitRow(table, owner, first, colXs) {
|
|
454
728
|
const last = first - 1;
|
|
455
729
|
const pairs = [];
|
|
730
|
+
let carried = false;
|
|
456
731
|
for (let c = 0; c < table.cols; ) {
|
|
457
732
|
const a = owner[last][c], b = owner[first][c];
|
|
458
|
-
if (!a
|
|
733
|
+
if (!a && !b) {
|
|
734
|
+
if (colXs[c + 1] - colXs[c] >= CARRIED_MIN_COL_W) carried = true;
|
|
735
|
+
c++;
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
if (!a || !b) return false;
|
|
459
739
|
if (a !== b) {
|
|
460
|
-
if (a.c !== b.c || a.cs !== b.cs || a.r + a.rs - 1 !== last || b.r !== first || b.rs !== 1) return;
|
|
740
|
+
if (a.c !== b.c || a.cs !== b.cs || a.r + a.rs - 1 !== last || b.r !== first || b.rs !== 1) return false;
|
|
461
741
|
pairs.push([a, b]);
|
|
462
|
-
}
|
|
742
|
+
} else if (a.r === last && a.rs === 2) carried = true;
|
|
463
743
|
c = a.c + a.cs;
|
|
464
744
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
if (
|
|
745
|
+
const carriedSplit = carried && pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell)).length <= 1 && !pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
|
|
746
|
+
const cell = (a) => table.cells[a.r][a.c];
|
|
747
|
+
if (!carriedSplit) {
|
|
748
|
+
const norm = (c) => c.text.replace(/\s+/g, "");
|
|
749
|
+
if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs]))) return false;
|
|
750
|
+
if (!pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]))) return false;
|
|
470
751
|
}
|
|
752
|
+
for (const [u, d] of pairs) appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
|
|
471
753
|
for (let r = 0; r < first; r++) for (let c = 0; c < table.cols; c++) {
|
|
472
754
|
const o = owner[r][c];
|
|
473
755
|
if (o && o.r === r && o.c === c && r + table.cells[r][c].rowSpan > first) table.cells[r][c].rowSpan--;
|
|
474
756
|
}
|
|
475
757
|
table.cells.splice(first, 1);
|
|
476
758
|
table.rows--;
|
|
759
|
+
return true;
|
|
477
760
|
}
|
|
478
761
|
var NEIGHBOR_TABLE_EPSILON = 0.2;
|
|
479
|
-
function
|
|
480
|
-
if (
|
|
762
|
+
function besideOwn(b, p, c) {
|
|
763
|
+
if (!b.bbox) return false;
|
|
764
|
+
if (b.type === "table") return leftColumnOf(b, p);
|
|
765
|
+
const t = (b.pageNumber === p.pageNumber ? p : c).bbox;
|
|
481
766
|
const bx1 = b.bbox.x, bx2 = b.bbox.x + b.bbox.width;
|
|
482
|
-
return
|
|
767
|
+
return bx2 <= t.x + 1 || bx1 >= t.x + t.width - 1;
|
|
768
|
+
}
|
|
769
|
+
function leftColumnOf(b, t) {
|
|
770
|
+
return !!b.bbox && b.pageNumber === t.pageNumber && b.bbox.x + b.bbox.width <= t.bbox.x + 1;
|
|
771
|
+
}
|
|
772
|
+
function placeJoined(blocks, i, j, table) {
|
|
773
|
+
const prev = blocks[i];
|
|
774
|
+
blocks[i] = { ...prev, table };
|
|
775
|
+
blocks.splice(j, 1);
|
|
776
|
+
let k = j - 1;
|
|
777
|
+
while (k > i && !leftColumnOf(blocks[k], prev)) k--;
|
|
778
|
+
if (k > i) blocks.splice(k, 0, blocks.splice(i, 1)[0]);
|
|
779
|
+
}
|
|
780
|
+
function insideTable(b, t) {
|
|
781
|
+
if (!b.bbox || b.pageNumber !== t.pageNumber) return false;
|
|
782
|
+
const o = t.bbox;
|
|
783
|
+
return b.bbox.x >= o.x - 1 && b.bbox.x + b.bbox.width <= o.x + o.width + 1 && b.bbox.y >= o.y - 1 && b.bbox.y + b.bbox.height <= o.y + o.height + 1;
|
|
483
784
|
}
|
|
484
785
|
function mergeCrossPageTables(blocks, pageHeights) {
|
|
786
|
+
mergeColumnFlow(blocks, pageHeights);
|
|
485
787
|
for (let i = blocks.length - 2; i >= 0; i--) {
|
|
486
788
|
const prev = blocks[i];
|
|
487
789
|
if (prev.type !== "table" || !prev.table || !prev.bbox || !prev.pageNumber) continue;
|
|
488
790
|
let j = i + 1;
|
|
489
|
-
while (j < blocks.length && blocks[j].type !== "table" && (_nullishCoalesce(blocks[j].pageNumber, () => ( 0))) <= prev.pageNumber + 1) j++;
|
|
791
|
+
while (j < blocks.length && (blocks[j].type !== "table" || insideTable(blocks[j], prev) || leftColumnOf(blocks[j], prev)) && (_nullishCoalesce(blocks[j].pageNumber, () => ( 0))) <= prev.pageNumber + 1) j++;
|
|
490
792
|
const curr = blocks[j];
|
|
491
793
|
if (!curr || curr.type !== "table" || !curr.table || !curr.bbox || curr.pageNumber !== prev.pageNumber + 1) continue;
|
|
492
|
-
const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) =>
|
|
794
|
+
const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) => besideOwn(b, prev, curr) || insideTable(b, prev)) ? looksContinued(prev, curr, pageHeights) && !restartsTable(blocks, i, curr.table, pageHeights) ? _nullishCoalesce(joinClipParts(prev, curr, pageHeights), () => ( false)) : null : null;
|
|
493
795
|
if (joined) {
|
|
494
|
-
blocks
|
|
495
|
-
blocks.splice(j, 1);
|
|
796
|
+
placeJoined(blocks, i, j, joined);
|
|
496
797
|
continue;
|
|
497
798
|
}
|
|
498
|
-
if (
|
|
799
|
+
if (_chunkUSHQCF5Tcjs.EMPTY_PARTS.has(curr.table)) {
|
|
499
800
|
blocks.splice(j, 1);
|
|
500
801
|
i++;
|
|
501
802
|
continue;
|
|
502
803
|
}
|
|
503
804
|
if (joined === null) continue;
|
|
504
|
-
if (prev.table.cols !== curr.table.cols ||
|
|
805
|
+
if (prev.table.cols !== curr.table.cols || _chunkUSHQCF5Tcjs.EMPTY_PARTS.has(prev.table)) continue;
|
|
505
806
|
const width = Math.max(prev.bbox.width, curr.bbox.width, 1);
|
|
506
807
|
const leftDiff = Math.abs(prev.bbox.x - curr.bbox.x);
|
|
507
808
|
const rightDiff = Math.abs(prev.bbox.x + prev.bbox.width - (curr.bbox.x + curr.bbox.width));
|
|
508
809
|
if (leftDiff > width * NEIGHBOR_TABLE_EPSILON || rightDiff > width * NEIGHBOR_TABLE_EPSILON) continue;
|
|
509
|
-
const px =
|
|
510
|
-
if (px && cx && (px
|
|
810
|
+
const px = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(prev.table), cx = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(curr.table);
|
|
811
|
+
if (px && cx && !shiftedSame(px, cx, !_chunkUSHQCF5Tcjs.CLIP_TABLES.has(prev.table) && !_chunkUSHQCF5Tcjs.CLIP_TABLES.has(curr.table))) continue;
|
|
511
812
|
let currCells = curr.table.cells;
|
|
512
813
|
if (currCells.length > 1 && prev.table.cells.length > 0 && rowTextsEqual(prev.table.cells[0], currCells[0])) {
|
|
513
814
|
currCells = currCells.slice(1);
|
|
@@ -523,40 +824,119 @@ function mergeCrossPageTables(blocks, pageHeights) {
|
|
|
523
824
|
hasHeader: prev.table.hasHeader,
|
|
524
825
|
caption: prev.table.caption
|
|
525
826
|
};
|
|
526
|
-
if (_nullishCoalesce(px, () => ( cx)))
|
|
527
|
-
if (
|
|
528
|
-
blocks
|
|
529
|
-
blocks.splice(j, 1);
|
|
827
|
+
if (_nullishCoalesce(px, () => ( cx))) _chunkUSHQCF5Tcjs.TABLE_COLXS.set(merged, _nullishCoalesce(px, () => ( cx)));
|
|
828
|
+
if (_chunkUSHQCF5Tcjs.CLIP_TABLES.has(prev.table) || _chunkUSHQCF5Tcjs.CLIP_TABLES.has(curr.table)) _chunkUSHQCF5Tcjs.CLIP_TABLES.add(merged);
|
|
829
|
+
placeJoined(blocks, i, j, merged);
|
|
530
830
|
}
|
|
531
831
|
for (let i = blocks.length - 1; i >= 0; i--) {
|
|
532
832
|
const t = blocks[i].table;
|
|
533
|
-
if (blocks[i].type === "table" && t &&
|
|
833
|
+
if (blocks[i].type === "table" && t && _chunkUSHQCF5Tcjs.EMPTY_PARTS.has(t)) blocks.splice(i, 1);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
function mergeColumnFlow(blocks, pageHeights) {
|
|
837
|
+
if (!pageHeights) return;
|
|
838
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
839
|
+
const L = blocks[i];
|
|
840
|
+
if (L.type !== "table" || !L.table || !L.bbox || !L.pageNumber || !_chunkUSHQCF5Tcjs.CLIP_TABLES.has(L.table) || _chunkUSHQCF5Tcjs.EMPTY_PARTS.has(L.table)) continue;
|
|
841
|
+
const ph = pageHeights.get(L.pageNumber);
|
|
842
|
+
if (!ph || L.bbox.y > ph * PAGE_EDGE_BAND) continue;
|
|
843
|
+
let s0 = i, s1 = i;
|
|
844
|
+
while (s0 > 0 && blocks[s0 - 1].pageNumber === L.pageNumber) s0--;
|
|
845
|
+
while (s1 + 1 < blocks.length && blocks[s1 + 1].pageNumber === L.pageNumber) s1++;
|
|
846
|
+
let k = -1;
|
|
847
|
+
for (let q = s0; q <= s1; q++) {
|
|
848
|
+
const R2 = blocks[q];
|
|
849
|
+
if (q === i || R2.type !== "table" || !R2.table || !R2.bbox || !leftColumnOf(L, R2)) continue;
|
|
850
|
+
const top2 = R2.bbox.y + R2.bbox.height;
|
|
851
|
+
if (top2 < ph * (1 - PAGE_EDGE_BAND)) continue;
|
|
852
|
+
if (k < 0 || top2 > blocks[k].bbox.y + blocks[k].bbox.height) k = q;
|
|
853
|
+
}
|
|
854
|
+
if (k < 0) continue;
|
|
855
|
+
const R = blocks[k];
|
|
856
|
+
if (Math.abs(R.bbox.width - L.bbox.width) > Math.max(R.bbox.width, L.bbox.width) * NEIGHBOR_TABLE_EPSILON) continue;
|
|
857
|
+
if (!looksContinued(L, R) || restartsTable(blocks, i, R.table, pageHeights)) continue;
|
|
858
|
+
const joined = joinClipParts(L, R, pageHeights);
|
|
859
|
+
if (!joined) continue;
|
|
860
|
+
const top = L.bbox.y + L.bbox.height;
|
|
861
|
+
const at = Math.min(i, k);
|
|
862
|
+
blocks[at] = { ...L, table: joined, bbox: { ...L.bbox, y: R.bbox.y, height: Math.max(0, top - R.bbox.y) } };
|
|
863
|
+
blocks.splice(Math.max(i, k), 1);
|
|
864
|
+
i = at - 1;
|
|
534
865
|
}
|
|
535
866
|
}
|
|
536
867
|
function joinClipParts(prev, curr, pageHeights) {
|
|
537
868
|
const pt = prev.table, ct = curr.table;
|
|
538
|
-
if (!
|
|
539
|
-
const px =
|
|
869
|
+
if (!_chunkUSHQCF5Tcjs.CLIP_TABLES.has(pt) || !_chunkUSHQCF5Tcjs.CLIP_TABLES.has(ct)) return null;
|
|
870
|
+
const px = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(pt), cx = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(ct);
|
|
540
871
|
if (!px || !cx) return null;
|
|
541
|
-
|
|
542
|
-
if (!
|
|
543
|
-
if (!_optionalChain([pageHeights, 'optionalAccess',
|
|
544
|
-
|
|
545
|
-
if (
|
|
872
|
+
let xs = cx, shifted = false, dx = 0;
|
|
873
|
+
if (!shiftedSame(px, cx, false)) {
|
|
874
|
+
if (!_optionalChain([pageHeights, 'optionalAccess', _23 => _23.get, 'call', _24 => _24(prev.pageNumber)]) || !_optionalChain([pageHeights, 'optionalAccess', _25 => _25.get, 'call', _26 => _26(curr.pageNumber)])) return null;
|
|
875
|
+
dx = px[px.length - 1] - cx[cx.length - 1];
|
|
876
|
+
if (Math.abs(dx) > CONTINUATION_COL_TOL) {
|
|
877
|
+
xs = cx.map((x) => x + dx);
|
|
878
|
+
shifted = true;
|
|
879
|
+
} else dx = 0;
|
|
880
|
+
if (!px.some((x) => Math.abs(x - xs[0]) <= CONTINUATION_COL_TOL)) return null;
|
|
546
881
|
}
|
|
547
|
-
const res = joinSplitParts(pt, px, ct,
|
|
548
|
-
if (!res) return null;
|
|
549
|
-
|
|
550
|
-
|
|
882
|
+
const res = joinSplitParts(pt, px, ct, xs, dx, _optionalChain([prev, 'access', _27 => _27.bbox, 'optionalAccess', _28 => _28.y]));
|
|
883
|
+
if (!res || shifted && !res.split && !res.header) return null;
|
|
884
|
+
_chunkUSHQCF5Tcjs.TABLE_COLXS.set(res.table, res.colXs);
|
|
885
|
+
_chunkUSHQCF5Tcjs.CLIP_TABLES.add(res.table);
|
|
551
886
|
return res.table;
|
|
552
887
|
}
|
|
553
888
|
var ANNEX_HEAD_RE = /^\s*[<\[(【]?\s*(?:붙\s*임|참\s*고|별\s*첨|별\s*지|별\s*표|첨\s*부|부\s*록)(?:\s*\d|\s*$|\s*[>\])】])|^\s*■/;
|
|
554
889
|
function looksContinued(prev, curr, pageHeights) {
|
|
555
|
-
const ph = _optionalChain([pageHeights, 'optionalAccess',
|
|
890
|
+
const ph = _optionalChain([pageHeights, 'optionalAccess', _29 => _29.get, 'call', _30 => _30(prev.pageNumber)]), ch = _optionalChain([pageHeights, 'optionalAccess', _31 => _31.get, 'call', _32 => _32(curr.pageNumber)]);
|
|
556
891
|
if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
|
|
557
|
-
const firstText = _nullishCoalesce(_optionalChain([curr, 'access',
|
|
892
|
+
const firstText = _nullishCoalesce(_optionalChain([curr, 'access', _33 => _33.table, 'access', _34 => _34.cells, 'access', _35 => _35[0], 'optionalAccess', _36 => _36.find, 'call', _37 => _37((c) => c.text.trim()), 'optionalAccess', _38 => _38.text]), () => ( ""));
|
|
558
893
|
return !ANNEX_HEAD_RE.test(firstText);
|
|
559
894
|
}
|
|
895
|
+
function firstRowSig(t) {
|
|
896
|
+
const x = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(t);
|
|
897
|
+
if (!x || x.length !== t.cols + 1) return null;
|
|
898
|
+
return anchorsOf(t).filter((a) => a.r === 0).map((a) => ({ x1: x[a.c], x2: x[a.c + a.cs], t: a.cell.text.replace(/\s+/g, "") }));
|
|
899
|
+
}
|
|
900
|
+
function restartsTable(blocks, i, curr, pageHeights) {
|
|
901
|
+
const cs = firstRowSig(curr);
|
|
902
|
+
if (!cs || cs.length < RESTART_MIN_ANCHORS) return false;
|
|
903
|
+
const hs = firstRowSig(blocks[chainHead(blocks, i, pageHeights)].table);
|
|
904
|
+
if (!hs || hs.length !== cs.length) return false;
|
|
905
|
+
const dx = hs[hs.length - 1].x2 - cs[cs.length - 1].x2;
|
|
906
|
+
if (!hs.every((h, n) => Math.abs(h.x1 - cs[n].x1 - dx) <= CONTINUATION_COL_TOL && Math.abs(h.x2 - cs[n].x2 - dx) <= CONTINUATION_COL_TOL)) return false;
|
|
907
|
+
let same = 0, diff = 0;
|
|
908
|
+
for (let n = 0; n < hs.length; n++) {
|
|
909
|
+
if (!hs[n].t && !cs[n].t) continue;
|
|
910
|
+
if (hs[n].t === cs[n].t) same++;
|
|
911
|
+
else diff++;
|
|
912
|
+
}
|
|
913
|
+
return same >= 2 && diff >= 1;
|
|
914
|
+
}
|
|
915
|
+
function chainHead(blocks, i, pageHeights) {
|
|
916
|
+
let k = i;
|
|
917
|
+
for (let steps = 0; steps < RESTART_LOOKBACK_PAGES; steps++) {
|
|
918
|
+
const cur = blocks[k];
|
|
919
|
+
let p = k - 1;
|
|
920
|
+
while (p >= 0 && blocks[p].type !== "table" && (_nullishCoalesce(blocks[p].pageNumber, () => ( 0))) >= (_nullishCoalesce(cur.pageNumber, () => ( 0))) - 1) p--;
|
|
921
|
+
if (p < 0 || blocks[p].type !== "table" || !blocks[p].table || !blocks[p].bbox) break;
|
|
922
|
+
for (let q = p - 1; q >= 0 && blocks[q].pageNumber === blocks[p].pageNumber; q--) {
|
|
923
|
+
if (blocks[q].type === "table" && blocks[q].bbox && insideTable(blocks[p], blocks[q])) {
|
|
924
|
+
p = q;
|
|
925
|
+
break;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
const pb = blocks[p];
|
|
929
|
+
if (pb.pageNumber !== (_nullishCoalesce(cur.pageNumber, () => ( 0))) - 1) break;
|
|
930
|
+
if (!blocks.slice(p + 1, k).every((b) => besideOwn(b, pb, cur) || insideTable(b, pb))) break;
|
|
931
|
+
if (!looksContinued(pb, cur, pageHeights)) break;
|
|
932
|
+
const px = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(pb.table), cx = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(cur.table);
|
|
933
|
+
if (!px || !cx) break;
|
|
934
|
+
const dx = px[px.length - 1] - cx[cx.length - 1];
|
|
935
|
+
if (!shiftedSame(px, cx) && !px.some((x) => Math.abs(x - (cx[0] + dx)) <= CONTINUATION_COL_TOL)) break;
|
|
936
|
+
k = p;
|
|
937
|
+
}
|
|
938
|
+
return k;
|
|
939
|
+
}
|
|
560
940
|
function rowTextsEqual(a, b) {
|
|
561
941
|
if (a.length !== b.length) return false;
|
|
562
942
|
const norm = (t) => t.replace(/\s+/g, "");
|
|
@@ -566,7 +946,52 @@ function rowTextsEqual(a, b) {
|
|
|
566
946
|
return a.some((c) => c.text.trim() !== "");
|
|
567
947
|
}
|
|
568
948
|
var CONTINUATION_COL_TOL = 2;
|
|
949
|
+
function shiftedSame(px, cx, allowShift = true) {
|
|
950
|
+
if (px.length !== cx.length) return false;
|
|
951
|
+
const dx = allowShift ? px[px.length - 1] - cx[cx.length - 1] : 0;
|
|
952
|
+
return px.every((x, k) => Math.abs(x - cx[k] - dx) <= CONTINUATION_COL_TOL);
|
|
953
|
+
}
|
|
569
954
|
var PAGE_EDGE_BAND = 0.16;
|
|
955
|
+
var RESTART_MIN_ANCHORS = 3;
|
|
956
|
+
var RESTART_LOOKBACK_PAGES = 5;
|
|
957
|
+
|
|
958
|
+
// src/pdf/cell-continuation.ts
|
|
959
|
+
var COL_MATCH_TOL = 0.5;
|
|
960
|
+
function lastRowCell(t, x1, x2) {
|
|
961
|
+
const xs = _chunkUSHQCF5Tcjs.TABLE_COLXS.get(t);
|
|
962
|
+
const covered = /* @__PURE__ */ new Set();
|
|
963
|
+
for (let r = 0; r < t.rows; r++) {
|
|
964
|
+
for (let c = 0; c < t.cols; c++) {
|
|
965
|
+
if (covered.has(r * 1e5 + c)) continue;
|
|
966
|
+
const cell = _optionalChain([t, 'access', _39 => _39.cells, 'access', _40 => _40[r], 'optionalAccess', _41 => _41[c]]);
|
|
967
|
+
if (!cell) continue;
|
|
968
|
+
for (let dr = 0; dr < cell.rowSpan; dr++) for (let dc = 0; dc < cell.colSpan; dc++) covered.add((r + dr) * 1e5 + c + dc);
|
|
969
|
+
if (r + cell.rowSpan !== t.rows) continue;
|
|
970
|
+
if (xs ? Math.abs(xs[c] - x1) <= COL_MATCH_TOL && Math.abs(xs[c + cell.colSpan] - x2) <= COL_MATCH_TOL : t.cols === 1) return cell;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
return void 0;
|
|
974
|
+
}
|
|
975
|
+
var cellBlocks = (cell, pageNumber) => _nullishCoalesce(cell.blocks, () => ( cell.text.split("\n").map((t) => t.trim()).filter(Boolean).map((text) => ({ type: "paragraph", text, pageNumber }))));
|
|
976
|
+
function mergeContinuedCells(blocks, pageHeights) {
|
|
977
|
+
for (let j = blocks.length - 1; j > 0; j--) {
|
|
978
|
+
const part = blocks[j];
|
|
979
|
+
const from = part.table ? _chunkUSHQCF5Tcjs.CONT_PARTS.get(part.table) : void 0;
|
|
980
|
+
if (!from || !part.table) continue;
|
|
981
|
+
let i = j - 1;
|
|
982
|
+
while (i >= 0 && blocks[i].type !== "table") i--;
|
|
983
|
+
const prev = blocks[i];
|
|
984
|
+
if (i < 0 || !prev.table || prev.pageNumber !== (_nullishCoalesce(part.pageNumber, () => ( 0))) - 1) continue;
|
|
985
|
+
const cell = lastRowCell(prev.table, from.x1, from.x2);
|
|
986
|
+
const add = _optionalChain([part, 'access', _42 => _42.table, 'access', _43 => _43.cells, 'access', _44 => _44[0], 'optionalAccess', _45 => _45[0]]);
|
|
987
|
+
if (!cell || !add) continue;
|
|
988
|
+
if (cell.blocks || add.blocks) cell.blocks = [...cellBlocks(cell, prev.pageNumber), ...cellBlocks(add, part.pageNumber)];
|
|
989
|
+
cell.text = [cell.text, add.text].filter((s) => s.trim()).join("\n");
|
|
990
|
+
if (cell.text.trim() || _optionalChain([cell, 'access', _46 => _46.blocks, 'optionalAccess', _47 => _47.length])) _chunkUSHQCF5Tcjs.EMPTY_PARTS.delete(prev.table);
|
|
991
|
+
blocks.splice(j, 1);
|
|
992
|
+
if (cell.blocks) mergeCrossPageTables(cell.blocks, pageHeights);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
570
995
|
|
|
571
996
|
// src/pdf/symbol-fonts.ts
|
|
572
997
|
var WINANSI_REVERSE = {
|
|
@@ -600,7 +1025,7 @@ var WINANSI_REVERSE = {
|
|
|
600
1025
|
};
|
|
601
1026
|
function symbolFontTable(fontName) {
|
|
602
1027
|
if (!fontName) return void 0;
|
|
603
|
-
if (/wingdings(?![\s-]*[23])/i.test(fontName)) return
|
|
1028
|
+
if (/wingdings(?![\s-]*[23])/i.test(fontName)) return _chunk5LAZQCUJcjs.WINGDINGS;
|
|
604
1029
|
return void 0;
|
|
605
1030
|
}
|
|
606
1031
|
function remapSymbolText(text, table) {
|
|
@@ -661,8 +1086,8 @@ function splitSingleCellTables(blocks) {
|
|
|
661
1086
|
const out = [];
|
|
662
1087
|
for (const b of blocks) {
|
|
663
1088
|
const t = b.type === "table" ? b.table : void 0;
|
|
664
|
-
const cell = t && t.rows === 1 && t.cols === 1 ? _optionalChain([t, 'access',
|
|
665
|
-
if (!cell || _optionalChain([cell, 'access',
|
|
1089
|
+
const cell = t && t.rows === 1 && t.cols === 1 ? _optionalChain([t, 'access', _48 => _48.cells, 'access', _49 => _49[0], 'optionalAccess', _50 => _50[0]]) : void 0;
|
|
1090
|
+
if (!cell || _optionalChain([cell, 'access', _51 => _51.blocks, 'optionalAccess', _52 => _52.some, 'call', _53 => _53((x) => x.type === "table")])) {
|
|
666
1091
|
out.push(b);
|
|
667
1092
|
continue;
|
|
668
1093
|
}
|
|
@@ -677,7 +1102,8 @@ function cleanPdfText(text) {
|
|
|
677
1102
|
normalizeAraea(stripControlChars(text)).replace(/^\d{1,4}\n/, "").replace(/^[\s]*[-–—]\s*[-–—]?\d+[-–—]?[\s]*[-–—]?[\s]*$/gm, "").replace(/^\s*\d+\s*\/\s*\d+\s*$/gm, "").replace(/\n\d{1,4}\n/g, "\n").replace(/\n\d{1,4}$/, "").replace(/^#{1,6}\s*\d{1,4}\s*$/gm, "")
|
|
678
1103
|
).replace(/^(?!\| ---).*$/gm, (line) => {
|
|
679
1104
|
if (/^\s*\${1,2}.+\${1,2}\s*$/.test(line)) return line;
|
|
680
|
-
|
|
1105
|
+
const mark = _nullishCoalesce(_optionalChain([/^(?:#{1,6}|-) /, 'access', _54 => _54.exec, 'call', _55 => _55(line), 'optionalAccess', _56 => _56[0]]), () => ( ""));
|
|
1106
|
+
return mark + _chunkUSHQCF5Tcjs.collapseEvenSpacing.call(void 0, line.slice(mark.length));
|
|
681
1107
|
}).replace(/([□■◆○●▶ㅇ])\s+([가-힣])\s+([가-힣])/g, "$1 $2$3").replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
682
1108
|
}
|
|
683
1109
|
function startsWithMarker(line) {
|
|
@@ -725,7 +1151,7 @@ function applyLinkAnnotations(items, annots) {
|
|
|
725
1151
|
const wrapped = /* @__PURE__ */ new Set();
|
|
726
1152
|
for (const a of annots) {
|
|
727
1153
|
if (a.subtype !== "Link" || !a.url || !a.rect || a.rect.length < 4) continue;
|
|
728
|
-
const url =
|
|
1154
|
+
const url = _chunkWJHAU73Bcjs.sanitizeHref.call(void 0, a.url);
|
|
729
1155
|
if (!url) continue;
|
|
730
1156
|
const x1 = Math.min(a.rect[0], a.rect[2]), x2 = Math.max(a.rect[0], a.rect[2]);
|
|
731
1157
|
const y1 = Math.min(a.rect[1], a.rect[3]), y2 = Math.max(a.rect[1], a.rect[3]);
|
|
@@ -756,7 +1182,7 @@ function applyLinkAnnotations(items, annots) {
|
|
|
756
1182
|
|
|
757
1183
|
// src/pdf/formula-ocr.ts
|
|
758
1184
|
async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
|
|
759
|
-
const formulaMod = await Promise.resolve().then(() => _interopRequireWildcard(require("./formula-
|
|
1185
|
+
const formulaMod = await Promise.resolve().then(() => _interopRequireWildcard(require("./formula-5LOVHAKE.cjs")));
|
|
760
1186
|
const { FormulaPipeline, ensureFormulaModels } = formulaMod;
|
|
761
1187
|
await ensureFormulaModels((p) => {
|
|
762
1188
|
if (p.phase === "download" && p.total) {
|
|
@@ -924,7 +1350,7 @@ async function loadPdfWithTimeout(buffer) {
|
|
|
924
1350
|
new Promise((_, reject) => {
|
|
925
1351
|
timer = setTimeout(() => {
|
|
926
1352
|
loadingTask.destroy();
|
|
927
|
-
reject(new (0,
|
|
1353
|
+
reject(new (0, _chunkWJHAU73Bcjs.KordocError)("PDF \uB85C\uB529 \uD0C0\uC784\uC544\uC6C3 (30\uCD08 \uCD08\uACFC)"));
|
|
928
1354
|
}, PDF_LOAD_TIMEOUT_MS);
|
|
929
1355
|
})
|
|
930
1356
|
]);
|
|
@@ -933,12 +1359,12 @@ async function loadPdfWithTimeout(buffer) {
|
|
|
933
1359
|
}
|
|
934
1360
|
}
|
|
935
1361
|
async function parsePdfDocument(buffer, options) {
|
|
936
|
-
const formulaBuffer = _optionalChain([options, 'optionalAccess',
|
|
937
|
-
const ocrBuffer = _optionalChain([options, 'optionalAccess',
|
|
1362
|
+
const formulaBuffer = _optionalChain([options, 'optionalAccess', _57 => _57.formulaOcr]) ? buffer.slice(0) : null;
|
|
1363
|
+
const ocrBuffer = _optionalChain([options, 'optionalAccess', _58 => _58.ocr]) ? buffer.slice(0) : null;
|
|
938
1364
|
const doc = await loadPdfWithTimeout(buffer);
|
|
939
1365
|
try {
|
|
940
1366
|
const pageCount = doc.numPages;
|
|
941
|
-
if (pageCount === 0) throw new (0,
|
|
1367
|
+
if (pageCount === 0) throw new (0, _chunkWJHAU73Bcjs.KordocError)("PDF\uC5D0 \uD398\uC774\uC9C0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
942
1368
|
const metadata = { pageCount, pageMode: "layout" };
|
|
943
1369
|
await extractPdfMetadata(doc, metadata);
|
|
944
1370
|
const blocks = [];
|
|
@@ -947,7 +1373,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
947
1373
|
let totalChars = 0;
|
|
948
1374
|
let totalTextBytes = 0;
|
|
949
1375
|
const effectivePageCount = Math.min(pageCount, MAX_PAGES);
|
|
950
|
-
const pageFilter = _optionalChain([options, 'optionalAccess',
|
|
1376
|
+
const pageFilter = _optionalChain([options, 'optionalAccess', _59 => _59.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, effectivePageCount) : null;
|
|
951
1377
|
const totalTarget = pageFilter ? pageFilter.size : effectivePageCount;
|
|
952
1378
|
const fontSizeFreq = /* @__PURE__ */ new Map();
|
|
953
1379
|
const pageHeights = /* @__PURE__ */ new Map();
|
|
@@ -956,6 +1382,9 @@ async function parsePdfDocument(buffer, options) {
|
|
|
956
1382
|
const imageState = createPdfImageState();
|
|
957
1383
|
const extractedImages = [];
|
|
958
1384
|
const pageImageBlocks = /* @__PURE__ */ new Map();
|
|
1385
|
+
const carry = {};
|
|
1386
|
+
const vectorPageOps = /* @__PURE__ */ new Map();
|
|
1387
|
+
const wrapLexicon = new (0, _chunkUSHQCF5Tcjs.WrapLexicon)();
|
|
959
1388
|
let parsedPages = 0;
|
|
960
1389
|
for (let i = 1; i <= effectivePageCount; i++) {
|
|
961
1390
|
if (pageFilter && !pageFilter.has(i)) continue;
|
|
@@ -965,8 +1394,8 @@ async function parsePdfDocument(buffer, options) {
|
|
|
965
1394
|
const viewport = page.getViewport({ scale: 1 });
|
|
966
1395
|
pageHeights.set(i, viewport.height);
|
|
967
1396
|
const rawItems = tc.items;
|
|
968
|
-
const items =
|
|
969
|
-
const { visible, hiddenCount } =
|
|
1397
|
+
const items = _chunkUSHQCF5Tcjs.normalizeItems.call(void 0, rawItems);
|
|
1398
|
+
const { visible, hiddenCount } = _chunkUSHQCF5Tcjs.filterHiddenText.call(void 0, items, viewport.width, viewport.height);
|
|
970
1399
|
if (hiddenCount > 0) {
|
|
971
1400
|
warnings.push({ page: i, message: `${hiddenCount}\uAC1C \uC228\uACA8\uC9C4 \uD14D\uC2A4\uD2B8 \uC694\uC18C \uD544\uD130\uB9C1\uB428`, code: "HIDDEN_TEXT_FILTERED" });
|
|
972
1401
|
}
|
|
@@ -981,32 +1410,33 @@ async function parsePdfDocument(buffer, options) {
|
|
|
981
1410
|
const opList = await page.getOperatorList();
|
|
982
1411
|
remapSymbolFontItems(visible, (loadedName) => {
|
|
983
1412
|
try {
|
|
984
|
-
return page.commonObjs.has(loadedName) ? _optionalChain([page, 'access',
|
|
1413
|
+
return page.commonObjs.has(loadedName) ? _optionalChain([page, 'access', _60 => _60.commonObjs, 'access', _61 => _61.get, 'call', _62 => _62(loadedName), 'optionalAccess', _63 => _63.name]) : void 0;
|
|
985
1414
|
} catch (e5) {
|
|
986
1415
|
return void 0;
|
|
987
1416
|
}
|
|
988
1417
|
});
|
|
1418
|
+
for (const it of visible) if (it.text.includes("$")) it.text = _chunk5LAZQCUJcjs.escapeLiteralDollar.call(void 0, it.text);
|
|
989
1419
|
const pageArea = viewport.width * viewport.height;
|
|
990
1420
|
if (pageArea > 0) {
|
|
991
|
-
const imageRegions =
|
|
1421
|
+
const imageRegions = _chunkUSHQCF5Tcjs.extractImageRegions.call(void 0, opList.fnArray, opList.argsArray);
|
|
992
1422
|
let uncovered = 0;
|
|
993
1423
|
for (const r of imageRegions) {
|
|
994
1424
|
const area = (r.x2 - r.x1) * (r.y2 - r.y1);
|
|
995
1425
|
if (area < pageArea * 0.05) continue;
|
|
996
1426
|
pagesWithLargeImage.add(i);
|
|
997
|
-
const
|
|
1427
|
+
const hasText2 = visible.some((it) => {
|
|
998
1428
|
const cx = it.x + it.w / 2;
|
|
999
1429
|
const cy = it.y + (it.h || it.fontSize) / 2;
|
|
1000
1430
|
return cx >= r.x1 && cx <= r.x2 && cy >= r.y1 && cy <= r.y2;
|
|
1001
1431
|
});
|
|
1002
|
-
if (!
|
|
1432
|
+
if (!hasText2) uncovered++;
|
|
1003
1433
|
}
|
|
1004
1434
|
if (uncovered > 0) skippedImagePages.set(i, uncovered);
|
|
1005
1435
|
}
|
|
1006
|
-
const pageBlocks =
|
|
1436
|
+
const pageBlocks = _chunkUSHQCF5Tcjs.extractPageBlocksWithLines.call(void 0, visible, i, opList, viewport.width, viewport.height, void 0, _optionalChain([options, 'optionalAccess', _64 => _64.tables]) !== false, carry, wrapLexicon);
|
|
1007
1437
|
for (const b of pageBlocks) blocks.push(b);
|
|
1008
1438
|
try {
|
|
1009
|
-
const { blocks: imgBlocks, images: pageImages } = await extractPageImages(page, opList.fnArray, opList.argsArray, i, imageState, warnings, _optionalChain([options, 'optionalAccess',
|
|
1439
|
+
const { blocks: imgBlocks, images: pageImages } = await extractPageImages(page, opList.fnArray, opList.argsArray, i, imageState, warnings, _optionalChain([options, 'optionalAccess', _65 => _65.images]) !== false);
|
|
1010
1440
|
if (imgBlocks.length > 0) pageImageBlocks.set(i, imgBlocks);
|
|
1011
1441
|
extractedImages.push(...pageImages);
|
|
1012
1442
|
} catch (e6) {
|
|
@@ -1022,19 +1452,24 @@ async function parsePdfDocument(buffer, options) {
|
|
|
1022
1452
|
totalTextBytes += t.length * 2;
|
|
1023
1453
|
pageText += pageText ? "\n" + t : t;
|
|
1024
1454
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1455
|
+
const vector = scanVectorGlyphs(opList.fnArray, opList.argsArray, visible);
|
|
1456
|
+
const quality = computePageQuality(i, pageText, vector.glyphs);
|
|
1457
|
+
pageQuality.push(quality);
|
|
1458
|
+
if (_optionalChain([options, 'optionalAccess', _66 => _66.ocr]) && quality.ocrReason === "vector_text" && page.rotate % 360 === 0 && page.view[0] === 0 && page.view[1] === 0) {
|
|
1459
|
+
vectorPageOps.set(i, ocrVectorOps(opList, vector.paths));
|
|
1460
|
+
}
|
|
1461
|
+
if (totalTextBytes > MAX_TOTAL_TEXT) throw new (0, _chunkWJHAU73Bcjs.KordocError)("\uD14D\uC2A4\uD2B8 \uCD94\uCD9C \uD06C\uAE30 \uCD08\uACFC");
|
|
1027
1462
|
parsedPages++;
|
|
1028
|
-
_optionalChain([options, 'optionalAccess',
|
|
1463
|
+
_optionalChain([options, 'optionalAccess', _67 => _67.onProgress, 'optionalCall', _68 => _68(parsedPages, totalTarget)]);
|
|
1029
1464
|
} catch (pageErr) {
|
|
1030
|
-
if (pageErr instanceof
|
|
1465
|
+
if (pageErr instanceof _chunkWJHAU73Bcjs.KordocError) throw pageErr;
|
|
1031
1466
|
warnings.push({ page: i, message: `\uD398\uC774\uC9C0 ${i} \uD30C\uC2F1 \uC2E4\uD328: ${pageErr instanceof Error ? pageErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "PARTIAL_PARSE" });
|
|
1032
1467
|
}
|
|
1033
1468
|
}
|
|
1034
1469
|
const parsedPageCount = parsedPages || (pageFilter ? pageFilter.size : effectivePageCount);
|
|
1035
1470
|
const isImageBased = totalChars / Math.max(parsedPageCount, 1) < 10;
|
|
1036
1471
|
const ocrDone = /* @__PURE__ */ new Set();
|
|
1037
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
1472
|
+
if (_optionalChain([options, 'optionalAccess', _69 => _69.ocr]) && ocrBuffer) {
|
|
1038
1473
|
const inScope = (p) => !pageFilter || pageFilter.has(p);
|
|
1039
1474
|
const targets = /* @__PURE__ */ new Set();
|
|
1040
1475
|
if (options.ocr === "force" || isImageBased) {
|
|
@@ -1048,9 +1483,9 @@ async function parsePdfDocument(buffer, options) {
|
|
|
1048
1483
|
}
|
|
1049
1484
|
if (targets.size > 0) {
|
|
1050
1485
|
try {
|
|
1051
|
-
const { runPdfOcr } = await Promise.resolve().then(() => _interopRequireWildcard(require("./pdf-ocr-
|
|
1486
|
+
const { runPdfOcr } = await Promise.resolve().then(() => _interopRequireWildcard(require("./pdf-ocr-JRDBJ6TA.cjs")));
|
|
1052
1487
|
const mode = typeof options.ocr === "function" ? options.ocr : "builtin";
|
|
1053
|
-
const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options.onProgress, options.tables !== false);
|
|
1488
|
+
const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options.onProgress, options.tables !== false, vectorPageOps);
|
|
1054
1489
|
if (ocrPageBlocks.size > 0) {
|
|
1055
1490
|
for (const p of ocrPageBlocks.keys()) ocrDone.add(p);
|
|
1056
1491
|
const merged = blocks.filter((b) => !(b.pageNumber && ocrDone.has(b.pageNumber)));
|
|
@@ -1080,6 +1515,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
1080
1515
|
}
|
|
1081
1516
|
if (!isImageBased) {
|
|
1082
1517
|
const OCR_REASON_MESSAGES = {
|
|
1518
|
+
vector_text: "\uAE00\uC790\uB97C \uACE1\uC120(\uBCA1\uD130 \uACBD\uB85C)\uC73C\uB85C \uADF8\uB9B0 \uD398\uC774\uC9C0 (\uD14D\uC2A4\uD2B8\uCE35\uC5D0 \uAE00\uC790 \uC5C6\uC74C)",
|
|
1083
1519
|
low_text: "\uD14D\uC2A4\uD2B8\uAC00 \uAC70\uC758 \uC5C6\uB294 \uD398\uC774\uC9C0 (\uC2A4\uCE94/\uC774\uBBF8\uC9C0 \uCD94\uC815)",
|
|
1084
1520
|
high_pua: "\uAE00\uAF34 \uB9E4\uD551 \uC2E4\uD328 (PUA \uBE44\uC728 \uB192\uC74C) \u2014 \uCD94\uCD9C \uD14D\uC2A4\uD2B8 \uC2E0\uB8B0 \uBD88\uAC00",
|
|
1085
1521
|
high_control: "\uC81C\uC5B4\uBB38\uC790 \uBE44\uC728 \uB192\uC74C \u2014 \uCD94\uCD9C \uD14D\uC2A4\uD2B8 \uC2E0\uB8B0 \uBD88\uAC00",
|
|
@@ -1097,16 +1533,18 @@ async function parsePdfDocument(buffer, options) {
|
|
|
1097
1533
|
warnings.push({ page, message: `${count}\uAC1C \uC774\uBBF8\uC9C0 \uC601\uC5ED\uC5D0 \uCD94\uCD9C \uAC00\uB2A5\uD55C \uD14D\uC2A4\uD2B8 \uC5C6\uC74C (\uADF8\uB9BC/\uCC28\uD2B8/\uB3C4\uC7A5 \uB0B4\uC6A9 \uB204\uB77D \uAC00\uB2A5)`, code: "SKIPPED_IMAGE" });
|
|
1098
1534
|
}
|
|
1099
1535
|
}
|
|
1100
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
1101
|
-
const removed =
|
|
1536
|
+
if (_optionalChain([options, 'optionalAccess', _70 => _70.removeHeaderFooter]) !== false && parsedPageCount >= 3) {
|
|
1537
|
+
const removed = _chunkUSHQCF5Tcjs.removeHeaderFooterBlocks.call(void 0, blocks, pageHeights, warnings);
|
|
1102
1538
|
for (let ri = removed.length - 1; ri >= 0; ri--) {
|
|
1103
1539
|
blocks.splice(removed[ri], 1);
|
|
1104
1540
|
}
|
|
1105
1541
|
}
|
|
1542
|
+
mergeContinuedCells(blocks, pageHeights);
|
|
1106
1543
|
mergeCrossPageTables(blocks, pageHeights);
|
|
1107
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
1544
|
+
if (!_optionalChain([options, 'optionalAccess', _71 => _71.keepTrailingEmptyCols])) _chunkUSHQCF5Tcjs.trimTrailingEmptyTableCols.call(void 0, blocks);
|
|
1545
|
+
_chunkUSHQCF5Tcjs.joinPageBreakWraps.call(void 0, blocks, wrapLexicon);
|
|
1108
1546
|
injectPageImageBlocks(blocks, pageImageBlocks);
|
|
1109
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
1547
|
+
if (_optionalChain([options, 'optionalAccess', _72 => _72.formulaOcr]) && formulaBuffer) {
|
|
1110
1548
|
try {
|
|
1111
1549
|
await applyFormulaOcr(formulaBuffer, blocks, pageFilter, effectivePageCount, warnings, options.onProgress);
|
|
1112
1550
|
} catch (e) {
|
|
@@ -1116,17 +1554,17 @@ async function parsePdfDocument(buffer, options) {
|
|
|
1116
1554
|
});
|
|
1117
1555
|
}
|
|
1118
1556
|
}
|
|
1119
|
-
const medianFontSize =
|
|
1557
|
+
const medianFontSize = _chunkUSHQCF5Tcjs.computeMedianFontSizeFromFreq.call(void 0, fontSizeFreq);
|
|
1120
1558
|
if (medianFontSize > 0) {
|
|
1121
|
-
|
|
1559
|
+
_chunkUSHQCF5Tcjs.detectHeadings.call(void 0, blocks, medianFontSize);
|
|
1122
1560
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1561
|
+
_chunkUSHQCF5Tcjs.detectMarkerHeadings.call(void 0, blocks);
|
|
1562
|
+
_chunkUSHQCF5Tcjs.detectTableCaptions.call(void 0, blocks);
|
|
1563
|
+
_chunkUSHQCF5Tcjs.detectKoreanListBlocks.call(void 0, blocks);
|
|
1126
1564
|
const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
1127
1565
|
sanitizeBlockControlChars(blocks);
|
|
1128
1566
|
const outBlocks = splitSingleCellTables(blocks);
|
|
1129
|
-
let markdown = cleanPdfText(
|
|
1567
|
+
let markdown = cleanPdfText(_chunk5LAZQCUJcjs.blocksToMarkdown.call(void 0, outBlocks));
|
|
1130
1568
|
return {
|
|
1131
1569
|
markdown,
|
|
1132
1570
|
blocks,
|
|
@@ -1146,7 +1584,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
1146
1584
|
async function extractPdfMetadata(doc, metadata) {
|
|
1147
1585
|
try {
|
|
1148
1586
|
const result = await doc.getMetadata();
|
|
1149
|
-
if (!_optionalChain([result, 'optionalAccess',
|
|
1587
|
+
if (!_optionalChain([result, 'optionalAccess', _73 => _73.info])) return;
|
|
1150
1588
|
const info = result.info;
|
|
1151
1589
|
if (typeof info.Title === "string" && info.Title.trim()) metadata.title = info.Title.trim();
|
|
1152
1590
|
if (typeof info.Author === "string" && info.Author.trim()) metadata.author = info.Author.trim();
|
|
@@ -1185,5 +1623,5 @@ async function extractPdfMetadataOnly(buffer) {
|
|
|
1185
1623
|
|
|
1186
1624
|
|
|
1187
1625
|
|
|
1188
|
-
exports.cleanPdfText = cleanPdfText; exports.detectKoreanListBlocks =
|
|
1189
|
-
//# sourceMappingURL=parser-
|
|
1626
|
+
exports.cleanPdfText = cleanPdfText; exports.detectKoreanListBlocks = _chunkUSHQCF5Tcjs.detectKoreanListBlocks; exports.detectTableCaptions = _chunkUSHQCF5Tcjs.detectTableCaptions; exports.extractPdfMetadataOnly = extractPdfMetadataOnly; exports.mergeCrossPageTables = mergeCrossPageTables; exports.parsePdfDocument = parsePdfDocument; exports.removeHeaderFooterBlocks = _chunkUSHQCF5Tcjs.removeHeaderFooterBlocks;
|
|
1627
|
+
//# sourceMappingURL=parser-HVEKF73B.cjs.map
|