formatferry 1.0.24 → 1.0.25
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/dist/index.js +305 -49
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,9 +5,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __commonJS = (cb, mod) => function __require() {
|
|
9
12
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
13
|
};
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
11
18
|
var __copyProps = (to, from, except, desc) => {
|
|
12
19
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
20
|
for (let key of __getOwnPropNames(from))
|
|
@@ -2795,12 +2802,12 @@ var require_ChildNode = __commonJS({
|
|
|
2795
2802
|
"use strict";
|
|
2796
2803
|
var Node2 = require_Node();
|
|
2797
2804
|
var LinkedList = require_LinkedList();
|
|
2798
|
-
var createDocumentFragmentFromArguments = function(
|
|
2799
|
-
var docFrag =
|
|
2805
|
+
var createDocumentFragmentFromArguments = function(document3, args) {
|
|
2806
|
+
var docFrag = document3.createDocumentFragment();
|
|
2800
2807
|
for (var i = 0; i < args.length; i++) {
|
|
2801
2808
|
var argItem = args[i];
|
|
2802
2809
|
var isNode = argItem instanceof Node2;
|
|
2803
|
-
docFrag.appendChild(isNode ? argItem :
|
|
2810
|
+
docFrag.appendChild(isNode ? argItem : document3.createTextNode(String(argItem)));
|
|
2804
2811
|
}
|
|
2805
2812
|
return docFrag;
|
|
2806
2813
|
};
|
|
@@ -3068,7 +3075,7 @@ var require_Element = __commonJS({
|
|
|
3068
3075
|
return NodeUtils.serializeOne(this, { nodeType: 0 });
|
|
3069
3076
|
},
|
|
3070
3077
|
set: function(v) {
|
|
3071
|
-
var
|
|
3078
|
+
var document3 = this.ownerDocument;
|
|
3072
3079
|
var parent = this.parentNode;
|
|
3073
3080
|
if (parent === null) {
|
|
3074
3081
|
return;
|
|
@@ -3079,8 +3086,8 @@ var require_Element = __commonJS({
|
|
|
3079
3086
|
if (parent.nodeType === Node2.DOCUMENT_FRAGMENT_NODE) {
|
|
3080
3087
|
parent = parent.ownerDocument.createElement("body");
|
|
3081
3088
|
}
|
|
3082
|
-
var parser =
|
|
3083
|
-
|
|
3089
|
+
var parser = document3.implementation.mozHTMLParser(
|
|
3090
|
+
document3._address,
|
|
3084
3091
|
parent
|
|
3085
3092
|
);
|
|
3086
3093
|
parser.parse(v === null ? "" : String(v), true);
|
|
@@ -5665,9 +5672,9 @@ var require_defineElement = __commonJS({
|
|
|
5665
5672
|
});
|
|
5666
5673
|
return c;
|
|
5667
5674
|
};
|
|
5668
|
-
function EventHandlerBuilder(body,
|
|
5675
|
+
function EventHandlerBuilder(body, document3, form, element) {
|
|
5669
5676
|
this.body = body;
|
|
5670
|
-
this.document =
|
|
5677
|
+
this.document = document3;
|
|
5671
5678
|
this.form = form;
|
|
5672
5679
|
this.element = element;
|
|
5673
5680
|
}
|
|
@@ -16542,8 +16549,8 @@ var require_Window = __commonJS({
|
|
|
16542
16549
|
var Location = require_Location();
|
|
16543
16550
|
var utils = require_utils();
|
|
16544
16551
|
module.exports = Window;
|
|
16545
|
-
function Window(
|
|
16546
|
-
this.document =
|
|
16552
|
+
function Window(document3) {
|
|
16553
|
+
this.document = document3 || new DOMImplementation(null).createHTMLDocument("");
|
|
16547
16554
|
this.document._scripting_enabled = true;
|
|
16548
16555
|
this.document.defaultView = this;
|
|
16549
16556
|
this.location = new Location(this, this.document._address || "about:blank");
|
|
@@ -16674,11 +16681,11 @@ var require_lib = __commonJS({
|
|
|
16674
16681
|
};
|
|
16675
16682
|
};
|
|
16676
16683
|
exports.createWindow = function(html, address) {
|
|
16677
|
-
var
|
|
16684
|
+
var document3 = exports.createDocument(html);
|
|
16678
16685
|
if (address !== void 0) {
|
|
16679
|
-
|
|
16686
|
+
document3._address = address;
|
|
16680
16687
|
}
|
|
16681
|
-
return new impl.Window(
|
|
16688
|
+
return new impl.Window(document3);
|
|
16682
16689
|
};
|
|
16683
16690
|
exports.impl = impl;
|
|
16684
16691
|
}
|
|
@@ -17409,6 +17416,137 @@ var require_turndown_cjs = __commonJS({
|
|
|
17409
17416
|
}
|
|
17410
17417
|
});
|
|
17411
17418
|
|
|
17419
|
+
// ../../src/shared/feature-flags.ts
|
|
17420
|
+
function getFeatureFlags() {
|
|
17421
|
+
return { ..._flags };
|
|
17422
|
+
}
|
|
17423
|
+
var _flags;
|
|
17424
|
+
var init_feature_flags = __esm({
|
|
17425
|
+
"../../src/shared/feature-flags.ts"() {
|
|
17426
|
+
_flags = {
|
|
17427
|
+
enableDocx: true,
|
|
17428
|
+
enableXlsx: true,
|
|
17429
|
+
enablePdf: true,
|
|
17430
|
+
enableHtml: true,
|
|
17431
|
+
enablePdfTableDetection: true,
|
|
17432
|
+
enableData: true,
|
|
17433
|
+
enablePptx: true,
|
|
17434
|
+
enablePdfEnhanced: true,
|
|
17435
|
+
enablePdfMultiColumn: true,
|
|
17436
|
+
enablePdfOcr: false
|
|
17437
|
+
};
|
|
17438
|
+
}
|
|
17439
|
+
});
|
|
17440
|
+
|
|
17441
|
+
// ../../src/shared/adapters/pdf-ocr-adapter.ts
|
|
17442
|
+
var pdf_ocr_adapter_exports = {};
|
|
17443
|
+
__export(pdf_ocr_adapter_exports, {
|
|
17444
|
+
isOcrAvailable: () => isOcrAvailable,
|
|
17445
|
+
runOcr: () => runOcr
|
|
17446
|
+
});
|
|
17447
|
+
async function loadTesseract() {
|
|
17448
|
+
try {
|
|
17449
|
+
const mod = await import("tesseract.js");
|
|
17450
|
+
if (mod && typeof mod.createWorker === "function") {
|
|
17451
|
+
return mod;
|
|
17452
|
+
}
|
|
17453
|
+
return null;
|
|
17454
|
+
} catch {
|
|
17455
|
+
return null;
|
|
17456
|
+
}
|
|
17457
|
+
}
|
|
17458
|
+
function preScaleCanvas(canvas) {
|
|
17459
|
+
if (canvas.width <= MAX_IMAGE_WIDTH) return canvas;
|
|
17460
|
+
const scale = MAX_IMAGE_WIDTH / canvas.width;
|
|
17461
|
+
const scaled = document.createElement("canvas");
|
|
17462
|
+
scaled.width = MAX_IMAGE_WIDTH;
|
|
17463
|
+
scaled.height = Math.round(canvas.height * scale);
|
|
17464
|
+
const ctx = scaled.getContext("2d");
|
|
17465
|
+
if (ctx) {
|
|
17466
|
+
ctx.drawImage(canvas, 0, 0, scaled.width, scaled.height);
|
|
17467
|
+
}
|
|
17468
|
+
return scaled;
|
|
17469
|
+
}
|
|
17470
|
+
function canvasToBlob(canvas) {
|
|
17471
|
+
return new Promise((resolve2, reject) => {
|
|
17472
|
+
canvas.toBlob(
|
|
17473
|
+
(blob) => {
|
|
17474
|
+
if (blob) resolve2(blob);
|
|
17475
|
+
else reject(new Error("canvas.toBlob returned null"));
|
|
17476
|
+
},
|
|
17477
|
+
"image/png"
|
|
17478
|
+
);
|
|
17479
|
+
});
|
|
17480
|
+
}
|
|
17481
|
+
async function isOcrAvailable() {
|
|
17482
|
+
if (!getFeatureFlags().enablePdfOcr) return false;
|
|
17483
|
+
const lib = await loadTesseract();
|
|
17484
|
+
return lib !== null;
|
|
17485
|
+
}
|
|
17486
|
+
async function runOcr(pageCanvases, options) {
|
|
17487
|
+
const lib = await loadTesseract();
|
|
17488
|
+
if (!lib) {
|
|
17489
|
+
throw new Error(
|
|
17490
|
+
"OCR is not available: tesseract.js could not be loaded. Ensure the tesseract.js package is installed."
|
|
17491
|
+
);
|
|
17492
|
+
}
|
|
17493
|
+
const warnings = [];
|
|
17494
|
+
const pages = [];
|
|
17495
|
+
const worker = await lib.createWorker("eng", 1, {
|
|
17496
|
+
logger: (m) => {
|
|
17497
|
+
if (options?.onProgress) {
|
|
17498
|
+
options.onProgress({
|
|
17499
|
+
progress: m.progress,
|
|
17500
|
+
status: m.status
|
|
17501
|
+
});
|
|
17502
|
+
}
|
|
17503
|
+
}
|
|
17504
|
+
});
|
|
17505
|
+
try {
|
|
17506
|
+
for (let i = 0; i < pageCanvases.length; i++) {
|
|
17507
|
+
const { pageNumber, canvas } = pageCanvases[i];
|
|
17508
|
+
const scaled = preScaleCanvas(canvas);
|
|
17509
|
+
const blob = await canvasToBlob(scaled);
|
|
17510
|
+
try {
|
|
17511
|
+
const { data } = await worker.recognize(blob);
|
|
17512
|
+
const text = data.text.trim();
|
|
17513
|
+
if (data.confidence < MIN_CONFIDENCE) {
|
|
17514
|
+
warnings.push(
|
|
17515
|
+
`Page ${pageNumber}: low OCR confidence (${Math.round(data.confidence)}%). Text quality may be poor.`
|
|
17516
|
+
);
|
|
17517
|
+
}
|
|
17518
|
+
pages.push({
|
|
17519
|
+
pageNumber,
|
|
17520
|
+
text: text || "",
|
|
17521
|
+
confidence: data.confidence
|
|
17522
|
+
});
|
|
17523
|
+
} catch (err) {
|
|
17524
|
+
warnings.push(
|
|
17525
|
+
`Page ${pageNumber}: OCR failed \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
17526
|
+
);
|
|
17527
|
+
pages.push({ pageNumber, text: "", confidence: 0 });
|
|
17528
|
+
}
|
|
17529
|
+
if (options?.onProgress) {
|
|
17530
|
+
options.onProgress({
|
|
17531
|
+
progress: (i + 1) / pageCanvases.length,
|
|
17532
|
+
status: `OCR page ${i + 1}/${pageCanvases.length}`
|
|
17533
|
+
});
|
|
17534
|
+
}
|
|
17535
|
+
}
|
|
17536
|
+
} finally {
|
|
17537
|
+
await worker.terminate();
|
|
17538
|
+
}
|
|
17539
|
+
return { pages, warnings };
|
|
17540
|
+
}
|
|
17541
|
+
var MAX_IMAGE_WIDTH, MIN_CONFIDENCE;
|
|
17542
|
+
var init_pdf_ocr_adapter = __esm({
|
|
17543
|
+
"../../src/shared/adapters/pdf-ocr-adapter.ts"() {
|
|
17544
|
+
init_feature_flags();
|
|
17545
|
+
MAX_IMAGE_WIDTH = 2e3;
|
|
17546
|
+
MIN_CONFIDENCE = 40;
|
|
17547
|
+
}
|
|
17548
|
+
});
|
|
17549
|
+
|
|
17412
17550
|
// ../../node_modules/@mozilla/readability/Readability.js
|
|
17413
17551
|
var require_Readability = __commonJS({
|
|
17414
17552
|
"../../node_modules/@mozilla/readability/Readability.js"(exports, module) {
|
|
@@ -19471,9 +19609,9 @@ var require_readability = __commonJS({
|
|
|
19471
19609
|
// src/shim.ts
|
|
19472
19610
|
import { parseHTML } from "linkedom";
|
|
19473
19611
|
import createDOMPurify from "dompurify";
|
|
19474
|
-
var { document, window: window2 } = parseHTML("<!DOCTYPE html><html><body></body></html>");
|
|
19612
|
+
var { document: document2, window: window2 } = parseHTML("<!DOCTYPE html><html><body></body></html>");
|
|
19475
19613
|
globalThis.window = window2;
|
|
19476
|
-
globalThis.document =
|
|
19614
|
+
globalThis.document = document2;
|
|
19477
19615
|
globalThis.DOMParser = window2.DOMParser;
|
|
19478
19616
|
globalThis.Node = window2.Node;
|
|
19479
19617
|
globalThis.HTMLElement = window2.HTMLElement;
|
|
@@ -21449,21 +21587,8 @@ var DocxAdapter = class {
|
|
|
21449
21587
|
};
|
|
21450
21588
|
var docxAdapter = new DocxAdapter();
|
|
21451
21589
|
|
|
21452
|
-
// ../../src/shared/
|
|
21453
|
-
|
|
21454
|
-
enableDocx: true,
|
|
21455
|
-
enableXlsx: true,
|
|
21456
|
-
enablePdf: true,
|
|
21457
|
-
enableHtml: true,
|
|
21458
|
-
enablePdfTableDetection: true,
|
|
21459
|
-
enableData: true,
|
|
21460
|
-
enablePptx: true,
|
|
21461
|
-
enablePdfEnhanced: true,
|
|
21462
|
-
enablePdfMultiColumn: true
|
|
21463
|
-
};
|
|
21464
|
-
function getFeatureFlags() {
|
|
21465
|
-
return { ..._flags };
|
|
21466
|
-
}
|
|
21590
|
+
// ../../src/shared/adapters/pdf-adapter.ts
|
|
21591
|
+
init_feature_flags();
|
|
21467
21592
|
|
|
21468
21593
|
// ../../src/shared/adapters/pdf-table-detector.ts
|
|
21469
21594
|
var CJK_REGEX = /[\u3400-\u9FFF\uF900-\uFAFF\u3040-\u30FF\uAC00-\uD7AF]/;
|
|
@@ -23044,8 +23169,9 @@ var PdfAdapter = class {
|
|
|
23044
23169
|
onProgress?.(pageNum / numPages);
|
|
23045
23170
|
const page = await pdf.getPage(pageNum);
|
|
23046
23171
|
const viewport = page.getViewport({ scale: 1 });
|
|
23172
|
+
const useMarkedContent = getFeatureFlags().enablePdfEnhanced && isTaggedPdf;
|
|
23047
23173
|
const [textContent, annotations] = await Promise.all([
|
|
23048
|
-
page.getTextContent(),
|
|
23174
|
+
page.getTextContent(useMarkedContent ? { includeMarkedContent: true } : void 0),
|
|
23049
23175
|
page.getAnnotations().catch((err) => {
|
|
23050
23176
|
console.warn(`[PdfAdapter] getAnnotations failed for page ${pageNum}:`, err);
|
|
23051
23177
|
return [];
|
|
@@ -23053,10 +23179,23 @@ var PdfAdapter = class {
|
|
|
23053
23179
|
]);
|
|
23054
23180
|
const positionedText = [];
|
|
23055
23181
|
const xPositions = [];
|
|
23182
|
+
let currentMcid;
|
|
23056
23183
|
for (const item of textContent.items) {
|
|
23184
|
+
const itemType = "type" in item ? item.type : void 0;
|
|
23185
|
+
if (itemType === "beginMarkedContentProps") {
|
|
23186
|
+
currentMcid = item.id?.toString();
|
|
23187
|
+
continue;
|
|
23188
|
+
}
|
|
23189
|
+
if (itemType === "endMarkedContent") {
|
|
23190
|
+
currentMcid = void 0;
|
|
23191
|
+
continue;
|
|
23192
|
+
}
|
|
23057
23193
|
if (!("str" in item) || typeof item.str !== "string") continue;
|
|
23058
23194
|
const positioned = textItemToPositioned(item);
|
|
23059
23195
|
if (!positioned) continue;
|
|
23196
|
+
if (currentMcid !== void 0) {
|
|
23197
|
+
positioned.mcid = currentMcid;
|
|
23198
|
+
}
|
|
23060
23199
|
positionedText.push(positioned);
|
|
23061
23200
|
xPositions.push(positioned.x);
|
|
23062
23201
|
}
|
|
@@ -23071,38 +23210,90 @@ var PdfAdapter = class {
|
|
|
23071
23210
|
const renderItems = getFeatureFlags().enablePdfEnhanced && hfSuppressSet.size > 0 ? items.filter((it) => !isHeaderFooterItem(it, hfSuppressSet)) : items;
|
|
23072
23211
|
if (getFeatureFlags().enablePdfEnhanced && isTaggedPdf) {
|
|
23073
23212
|
let structHtml = null;
|
|
23213
|
+
let claimedMcids = null;
|
|
23074
23214
|
try {
|
|
23075
23215
|
if (hasStructTree(page)) {
|
|
23076
23216
|
const structResult = await structTreeToHtml(page);
|
|
23077
23217
|
if (structResult !== null) {
|
|
23078
23218
|
structHtml = structResult.html;
|
|
23219
|
+
claimedMcids = structResult.claimedMcids;
|
|
23079
23220
|
}
|
|
23080
23221
|
}
|
|
23081
23222
|
} catch {
|
|
23082
23223
|
}
|
|
23083
|
-
|
|
23084
|
-
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
|
|
23224
|
+
let fusionStructHtml = null;
|
|
23225
|
+
let fusionClaimedMcids = null;
|
|
23226
|
+
if (structHtml !== null && claimedMcids !== null) {
|
|
23227
|
+
const textItems = renderItems.filter((it) => it.source !== "acroform");
|
|
23228
|
+
const covered = textItems.filter((it) => it.mcid != null && claimedMcids.has(it.mcid)).length;
|
|
23229
|
+
const coverage = covered / Math.max(textItems.length, 1);
|
|
23230
|
+
if (coverage >= 0.7) {
|
|
23231
|
+
const plainText = structHtml.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
23232
|
+
totalTextLength += plainText.length;
|
|
23233
|
+
let hasImages2 = false;
|
|
23234
|
+
try {
|
|
23235
|
+
const opList = await page.getOperatorList();
|
|
23236
|
+
hasImages2 = opList.fnArray.some((op) => op === 85 || op === 86);
|
|
23237
|
+
} catch {
|
|
23238
|
+
}
|
|
23239
|
+
pages.push({
|
|
23240
|
+
pageNumber: pageNum,
|
|
23241
|
+
textContent: plainText,
|
|
23242
|
+
hasImages: hasImages2,
|
|
23243
|
+
viewportWidth: viewport.width,
|
|
23244
|
+
htmlBlocks: [structHtml],
|
|
23245
|
+
tablesDetected: 0
|
|
23246
|
+
});
|
|
23247
|
+
continue;
|
|
23248
|
+
} else if (coverage > 0) {
|
|
23249
|
+
fusionStructHtml = structHtml;
|
|
23250
|
+
fusionClaimedMcids = claimedMcids;
|
|
23088
23251
|
}
|
|
23089
23252
|
}
|
|
23090
|
-
if (
|
|
23091
|
-
const
|
|
23092
|
-
|
|
23093
|
-
|
|
23253
|
+
if (fusionStructHtml !== null && fusionClaimedMcids !== null) {
|
|
23254
|
+
const unclaimedItems = renderItems.filter(
|
|
23255
|
+
(it) => !it.mcid || !fusionClaimedMcids.has(it.mcid)
|
|
23256
|
+
);
|
|
23257
|
+
const fsSamples = unclaimedItems.map((it) => it.fontSize ?? 0).filter((f) => f > 0);
|
|
23258
|
+
const medianFontSize = fsSamples.length > 0 ? [...fsSamples].sort((a, b) => a - b)[Math.floor(fsSamples.length / 2)] : 12;
|
|
23259
|
+
const fusionEnhancedOpts = getFeatureFlags().enablePdfEnhanced ? { medianFontSize, outlineTitles } : void 0;
|
|
23260
|
+
const pageBottomY2 = Array.isArray(page.view) && page.view.length >= 2 ? page.view[1] : 0;
|
|
23261
|
+
let pageOpList2;
|
|
23262
|
+
let ruleSeparators2;
|
|
23094
23263
|
try {
|
|
23095
|
-
|
|
23096
|
-
|
|
23264
|
+
pageOpList2 = await page.getOperatorList();
|
|
23265
|
+
if (getFeatureFlags().enablePdfEnhanced && tableDetectionEnabled) {
|
|
23266
|
+
ruleSeparators2 = extractVectorLines(
|
|
23267
|
+
pageOpList2.fnArray,
|
|
23268
|
+
pageOpList2.argsArray ?? [],
|
|
23269
|
+
viewport.width,
|
|
23270
|
+
viewport.height
|
|
23271
|
+
);
|
|
23272
|
+
}
|
|
23097
23273
|
} catch {
|
|
23098
23274
|
}
|
|
23275
|
+
const rendered2 = renderPage(
|
|
23276
|
+
unclaimedItems,
|
|
23277
|
+
pageNum,
|
|
23278
|
+
pageNum < numPages ? pageNum + 1 : void 0,
|
|
23279
|
+
tableDetectionEnabled,
|
|
23280
|
+
translate,
|
|
23281
|
+
pageBottomY2,
|
|
23282
|
+
fusionEnhancedOpts,
|
|
23283
|
+
ruleSeparators2
|
|
23284
|
+
);
|
|
23285
|
+
for (const w of rendered2.warnings) warnings.push(w);
|
|
23286
|
+
const structPlainText = fusionStructHtml.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
23287
|
+
totalTextLength += structPlainText.length + rendered2.textContent.length;
|
|
23288
|
+
const hasImages2 = pageOpList2?.fnArray.some((op) => op === 85 || op === 86) ?? false;
|
|
23289
|
+
const mergedHtmlBlocks = [fusionStructHtml, ...rendered2.htmlBlocks];
|
|
23099
23290
|
pages.push({
|
|
23100
23291
|
pageNumber: pageNum,
|
|
23101
|
-
textContent:
|
|
23292
|
+
textContent: structPlainText + "\n" + rendered2.textContent,
|
|
23102
23293
|
hasImages: hasImages2,
|
|
23103
23294
|
viewportWidth: viewport.width,
|
|
23104
|
-
htmlBlocks:
|
|
23105
|
-
tablesDetected:
|
|
23295
|
+
htmlBlocks: mergedHtmlBlocks,
|
|
23296
|
+
tablesDetected: rendered2.tablesDetected
|
|
23106
23297
|
});
|
|
23107
23298
|
continue;
|
|
23108
23299
|
}
|
|
@@ -23174,6 +23365,12 @@ var PdfAdapter = class {
|
|
|
23174
23365
|
const hasNoText = totalTextLength === 0;
|
|
23175
23366
|
const hasMinimalTextWithImages = totalTextLength < MIN_TEXT_CHARS_THRESHOLD && hasAnyImages;
|
|
23176
23367
|
if (hasNoText || hasMinimalTextWithImages) {
|
|
23368
|
+
if (getFeatureFlags().enablePdfOcr) {
|
|
23369
|
+
const ocrResult = await this.runOcrOnPages(pdf, numPages);
|
|
23370
|
+
if (ocrResult !== null) {
|
|
23371
|
+
return ocrResult;
|
|
23372
|
+
}
|
|
23373
|
+
}
|
|
23177
23374
|
throw new PdfParseError(
|
|
23178
23375
|
"PDF contains only images \u2014 no text layer available.",
|
|
23179
23376
|
"IMAGE_ONLY"
|
|
@@ -23279,6 +23476,65 @@ var PdfAdapter = class {
|
|
|
23279
23476
|
}
|
|
23280
23477
|
}
|
|
23281
23478
|
}
|
|
23479
|
+
/**
|
|
23480
|
+
* Attempt OCR extraction on all pages of an image-only PDF.
|
|
23481
|
+
*
|
|
23482
|
+
* Renders each page to a canvas, passes them to Tesseract.js (lazy-loaded),
|
|
23483
|
+
* and returns a standard PdfParseResult if text is found.
|
|
23484
|
+
*
|
|
23485
|
+
* Returns null if:
|
|
23486
|
+
* - Tesseract.js cannot be loaded
|
|
23487
|
+
* - OCR produces no usable text across all pages
|
|
23488
|
+
*/
|
|
23489
|
+
async runOcrOnPages(pdf, numPages) {
|
|
23490
|
+
const { isOcrAvailable: isOcrAvailable2, runOcr: runOcr2 } = await Promise.resolve().then(() => (init_pdf_ocr_adapter(), pdf_ocr_adapter_exports));
|
|
23491
|
+
if (!await isOcrAvailable2()) {
|
|
23492
|
+
return null;
|
|
23493
|
+
}
|
|
23494
|
+
const SCALE = 2;
|
|
23495
|
+
const pageCanvases = [];
|
|
23496
|
+
const viewportWidths = /* @__PURE__ */ new Map();
|
|
23497
|
+
for (let pageNum = 1; pageNum <= numPages; pageNum++) {
|
|
23498
|
+
const page = await pdf.getPage(pageNum);
|
|
23499
|
+
const viewport = page.getViewport({ scale: 1 });
|
|
23500
|
+
viewportWidths.set(pageNum, viewport.width);
|
|
23501
|
+
const renderViewport = page.getViewport({ scale: SCALE });
|
|
23502
|
+
const canvas = document.createElement("canvas");
|
|
23503
|
+
canvas.width = renderViewport.width;
|
|
23504
|
+
canvas.height = renderViewport.height;
|
|
23505
|
+
const ctx = canvas.getContext("2d");
|
|
23506
|
+
if (!ctx) continue;
|
|
23507
|
+
await page.render({ canvasContext: ctx, viewport: renderViewport }).promise;
|
|
23508
|
+
pageCanvases.push({ pageNumber: pageNum, canvas });
|
|
23509
|
+
}
|
|
23510
|
+
if (pageCanvases.length === 0) return null;
|
|
23511
|
+
const ocrResult = await runOcr2(pageCanvases);
|
|
23512
|
+
const pagesWithText = ocrResult.pages.filter((p) => p.text.length > 0);
|
|
23513
|
+
if (pagesWithText.length === 0) return null;
|
|
23514
|
+
const ocrPages = ocrResult.pages.map((p) => ({
|
|
23515
|
+
pageNumber: p.pageNumber,
|
|
23516
|
+
textContent: p.text,
|
|
23517
|
+
hasImages: true,
|
|
23518
|
+
viewportWidth: viewportWidths.get(p.pageNumber),
|
|
23519
|
+
tablesDetected: 0
|
|
23520
|
+
}));
|
|
23521
|
+
const html = this.pagesToHtml(ocrPages);
|
|
23522
|
+
const allWarnings = [
|
|
23523
|
+
"OCR was used to extract text from this image-only PDF. Quality may vary.",
|
|
23524
|
+
...ocrResult.warnings
|
|
23525
|
+
];
|
|
23526
|
+
return {
|
|
23527
|
+
html,
|
|
23528
|
+
pages: ocrPages,
|
|
23529
|
+
metadata: {
|
|
23530
|
+
isTextBased: false,
|
|
23531
|
+
isOcrBased: true,
|
|
23532
|
+
pageCount: numPages
|
|
23533
|
+
},
|
|
23534
|
+
isTextBased: false,
|
|
23535
|
+
warnings: allWarnings
|
|
23536
|
+
};
|
|
23537
|
+
}
|
|
23282
23538
|
};
|
|
23283
23539
|
var pdfAdapter = new PdfAdapter();
|
|
23284
23540
|
|
|
@@ -24682,12 +24938,12 @@ var ToonifyService = class {
|
|
|
24682
24938
|
};
|
|
24683
24939
|
}
|
|
24684
24940
|
const blocks = this.parseMarkdown(markdown, opts);
|
|
24685
|
-
const
|
|
24941
|
+
const document3 = { t: "md", blocks };
|
|
24686
24942
|
const encodeOptions = {
|
|
24687
24943
|
keyFolding: opts.keyFolding,
|
|
24688
24944
|
tableFormat: opts.tableFormat
|
|
24689
24945
|
};
|
|
24690
|
-
const compressed = ToonEncoder.encode(
|
|
24946
|
+
const compressed = ToonEncoder.encode(document3, encodeOptions);
|
|
24691
24947
|
const compressedTokenEstimate = estimateTokens(compressed);
|
|
24692
24948
|
const reductionPercent = originalTokenEstimate > 0 ? Math.max(0, Math.min(100, Math.round(
|
|
24693
24949
|
(originalTokenEstimate - compressedTokenEstimate) / originalTokenEstimate * 100
|
|
@@ -25505,8 +25761,8 @@ import { readFileSync as readFileSync4 } from "fs";
|
|
|
25505
25761
|
import { resolve, dirname as dirname3 } from "path";
|
|
25506
25762
|
import { fileURLToPath } from "url";
|
|
25507
25763
|
var getVersion = () => {
|
|
25508
|
-
if ("1.0.
|
|
25509
|
-
return "1.0.
|
|
25764
|
+
if ("1.0.25") {
|
|
25765
|
+
return "1.0.25";
|
|
25510
25766
|
}
|
|
25511
25767
|
try {
|
|
25512
25768
|
const __dirname = dirname3(fileURLToPath(import.meta.url));
|