@stll/anonymize-pdf 2.9.0 → 2.9.1
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.mjs +15 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -142,13 +142,13 @@ const decodePdfRasterRewriteCertificate = (json) => {
|
|
|
142
142
|
//#endregion
|
|
143
143
|
//#region src/local-provider.ts
|
|
144
144
|
const LOCAL_PROVIDER_ID = "poppler-tesseract-local";
|
|
145
|
-
const PROCESS_OUTPUT_MAX_BYTES =
|
|
146
|
-
const PDF_DOCUMENT_MAX_BYTES$1 =
|
|
147
|
-
const PDF_RASTER_MAX_PAGE_BYTES$1 =
|
|
148
|
-
const PDF_RASTER_MAX_TOTAL_BYTES$1 =
|
|
145
|
+
const PROCESS_OUTPUT_MAX_BYTES = 67108864;
|
|
146
|
+
const PDF_DOCUMENT_MAX_BYTES$1 = 67108864;
|
|
147
|
+
const PDF_RASTER_MAX_PAGE_BYTES$1 = 134217728;
|
|
148
|
+
const PDF_RASTER_MAX_TOTAL_BYTES$1 = 536870912;
|
|
149
149
|
const PDF_MAX_PAGES$1 = 1e4;
|
|
150
150
|
const PDF_MAX_GLYPHS$1 = 5e6;
|
|
151
|
-
const PDF_MAX_OBSERVED_TEXT_UTF8_BYTES$1 =
|
|
151
|
+
const PDF_MAX_OBSERVED_TEXT_UTF8_BYTES$1 = 67108864;
|
|
152
152
|
const DEFAULT_DPI = 300;
|
|
153
153
|
const DEFAULT_TIMEOUT_MS = 12e4;
|
|
154
154
|
const MIN_DPI = 72;
|
|
@@ -462,21 +462,21 @@ const renderPdfWithPopplerTesseract = async (options) => {
|
|
|
462
462
|
//#region src/index.ts
|
|
463
463
|
const PDF_INSPECTION_CONTRACT_VERSION = 1;
|
|
464
464
|
const PDF_RASTER_CONTRACT_VERSION = 1;
|
|
465
|
-
const PDF_RASTER_MAX_PAGE_BYTES =
|
|
466
|
-
const PDF_RASTER_MAX_TOTAL_BYTES =
|
|
467
|
-
const PDF_RASTER_MAX_OUTPUT_BYTES =
|
|
468
|
-
const PDF_RASTER_REQUEST_JSON_MAX_BYTES =
|
|
469
|
-
const PDF_DOCUMENT_MAX_BYTES =
|
|
470
|
-
const PDF_STREAM_DECOMPRESSED_MAX_BYTES =
|
|
471
|
-
const PDF_LOADED_PAYLOAD_MAX_BYTES =
|
|
465
|
+
const PDF_RASTER_MAX_PAGE_BYTES = 134217728;
|
|
466
|
+
const PDF_RASTER_MAX_TOTAL_BYTES = 536870912;
|
|
467
|
+
const PDF_RASTER_MAX_OUTPUT_BYTES = 536870912;
|
|
468
|
+
const PDF_RASTER_REQUEST_JSON_MAX_BYTES = 67108864;
|
|
469
|
+
const PDF_DOCUMENT_MAX_BYTES = 67108864;
|
|
470
|
+
const PDF_STREAM_DECOMPRESSED_MAX_BYTES = 33554432;
|
|
471
|
+
const PDF_LOADED_PAYLOAD_MAX_BYTES = 134217728;
|
|
472
472
|
const PDF_MAX_OBJECTS = 2e5;
|
|
473
473
|
const PDF_MAX_OBJECT_NODES = 1e6;
|
|
474
474
|
const PDF_MAX_OBJECT_DEPTH = 128;
|
|
475
475
|
const PDF_MAX_PAGES = 1e4;
|
|
476
476
|
const PDF_MAX_GLYPHS = 5e6;
|
|
477
|
-
const PDF_MAX_PAGE_TEXT_UTF8_BYTES =
|
|
478
|
-
const PDF_MAX_OBSERVED_TEXT_UTF8_BYTES =
|
|
479
|
-
const PDF_OBSERVATIONS_JSON_MAX_BYTES =
|
|
477
|
+
const PDF_MAX_PAGE_TEXT_UTF8_BYTES = 16777216;
|
|
478
|
+
const PDF_MAX_OBSERVED_TEXT_UTF8_BYTES = 67108864;
|
|
479
|
+
const PDF_OBSERVATIONS_JSON_MAX_BYTES = 67108864;
|
|
480
480
|
/** Renderer dimensions may differ by this many points due to numeric rounding. */
|
|
481
481
|
const PDF_PAGE_DIMENSION_TOLERANCE_POINTS = .25;
|
|
482
482
|
var PdfInspectionError = class extends Error {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["PDF_DOCUMENT_MAX_BYTES","PDF_RASTER_MAX_PAGE_BYTES","PDF_RASTER_MAX_TOTAL_BYTES","PDF_MAX_PAGES","PDF_MAX_GLYPHS","PDF_MAX_OBSERVED_TEXT_UTF8_BYTES"],"sources":["../src/types.ts","../src/native-codec.ts","../src/local-provider.ts","../src/index.ts"],"sourcesContent":["export type PdfRect = {\n left: number;\n bottom: number;\n right: number;\n top: number;\n};\n\nexport type PdfGlyphObservation = {\n start: number;\n end: number;\n /** Bounds in normalized displayed-page PDF points, origin bottom-left. */\n bounds: PdfRect;\n source: \"embedded-text\" | \"ocr\";\n};\n\nexport type PdfPageObservation = {\n pageIndex: number;\n /** Effective visible width after page boxes, rotation, and UserUnit scaling. */\n widthPoints: number;\n /** Effective visible height after page boxes, rotation, and UserUnit scaling. */\n heightPoints: number;\n text: string;\n glyphs: readonly PdfGlyphObservation[];\n rendered: boolean;\n textLayer: \"absent\" | \"partial\" | \"complete\";\n ocr: \"not-run\" | \"partial\" | \"complete\";\n imageCount: number;\n};\n\nexport type PdfRiskInventory = {\n acroFormFieldCount: number;\n annotationCount: number;\n documentInfoEntryCount: number;\n embeddedFileCount: number;\n externalActionCount: number;\n formXObjectCount: number;\n imageObjectCount: number;\n incrementalRevisionCount: number;\n javascriptActionCount: number;\n metadataStreamCount: number;\n optionalContentGroupCount: number;\n signatureCount: number;\n trailingNonWhitespaceByteCount: number;\n unsupportedActionCount: number;\n xfaEntryCount: number;\n};\n\nexport type PdfInspectionGap =\n | \"encrypted-document\"\n | \"page-content-not-observed\"\n | \"page-not-rendered\"\n | \"partial-text-layer\"\n | \"retained-document-bytes\"\n | \"unobserved-visual-content\";\n\nexport type PdfPageInspection = {\n pageIndex: number;\n /** Effective visible width after page boxes, rotation, and UserUnit scaling. */\n widthPoints: number;\n /** Effective visible height after page boxes, rotation, and UserUnit scaling. */\n heightPoints: number;\n annotationCount: number;\n observation: PdfPageObservation | null;\n};\n\nexport type PdfInspection = {\n contractVersion: 1;\n pdfVersion: string;\n byteLength: number;\n objectCount: number;\n pageCount: number;\n encrypted: boolean;\n pages: readonly PdfPageInspection[];\n risks: PdfRiskInventory;\n coverage: {\n status: \"full\" | \"partial\";\n gaps: readonly PdfInspectionGap[];\n };\n};\n\nexport type PdfRasterProvider = {\n providerId: string;\n rendererName: string;\n rendererVersion: string;\n ocrName: string;\n ocrVersion: string;\n /** One explicit provider language pack; never an implicit mixed-language set. */\n ocrLanguage: string;\n};\n\nexport type PdfRasterPage = {\n observation: PdfPageObservation;\n widthPixels: number;\n heightPixels: number;\n /** Lowercase SHA-256 of this page's exact opaque, row-packed RGB8 bytes. */\n pixelSha256: string;\n /** Strictly ordered, non-overlapping UTF-16 spans. */\n detections: readonly PdfRasterDetection[];\n};\n\nexport type PdfRasterDetection = { start: number; end: number };\n\nexport type PdfRasterRewrite = {\n contractVersion: 1;\n /** Lowercase SHA-256 of the exact source PDF bytes supplied to the call. */\n sourceSha256: string;\n provider: PdfRasterProvider;\n fillRgb: readonly [number, number, number];\n pages: readonly PdfRasterPage[];\n};\n\nexport type PdfRasterRewriteCertificate = {\n contractVersion: 1;\n pageCount: number;\n sourceSha256: string;\n outputSha256: string;\n provider: PdfRasterProvider;\n detectionCount: number;\n mappedRegionCount: number;\n structurePixelRewriteVerified: true;\n providerAssertedCoverage: \"complete-rendering-and-ocr-observation\";\n piiCleanGuaranteed: false;\n limitation: string;\n};\n\nexport type PdfRasterRewriteResult = {\n document: Uint8Array;\n certificate: PdfRasterRewriteCertificate;\n};\n\nexport const PDF_INSPECTION_ERROR_CODES = {\n documentLimitExceeded: \"document-limit-exceeded\",\n invalidDocument: \"invalid-document\",\n invalidObservation: \"invalid-observation\",\n observationLimitExceeded: \"observation-limit-exceeded\",\n providerFailed: \"provider-failed\",\n} as const;\n\nexport type PdfInspectionErrorCode =\n (typeof PDF_INSPECTION_ERROR_CODES)[keyof typeof PDF_INSPECTION_ERROR_CODES];\n\nexport const PDF_RASTER_ERROR_CODES = {\n detectionFailed: \"detection-failed\",\n invalidContract: \"invalid-contract\",\n limitExceeded: \"limit-exceeded\",\n sourceRejected: \"source-rejected\",\n verificationFailed: \"verification-failed\",\n} as const;\n\nexport type PdfRasterErrorCode =\n (typeof PDF_RASTER_ERROR_CODES)[keyof typeof PDF_RASTER_ERROR_CODES];\n","import type {\n PdfGlyphObservation,\n PdfInspection,\n PdfInspectionGap,\n PdfPageInspection,\n PdfPageObservation,\n PdfRasterProvider,\n PdfRasterRewriteCertificate,\n PdfRect,\n PdfRiskInventory,\n} from \"./types\";\n\ntype RequiredFields<T> = { [Key in keyof T]-?: true };\n\nconst RECT_FIELDS = {\n left: true,\n bottom: true,\n right: true,\n top: true,\n} as const satisfies RequiredFields<PdfRect>;\n\nconst GLYPH_FIELDS = {\n start: true,\n end: true,\n bounds: true,\n source: true,\n} as const satisfies RequiredFields<PdfGlyphObservation>;\n\nconst OBSERVATION_FIELDS = {\n pageIndex: true,\n widthPoints: true,\n heightPoints: true,\n text: true,\n glyphs: true,\n rendered: true,\n textLayer: true,\n ocr: true,\n imageCount: true,\n} as const satisfies RequiredFields<PdfPageObservation>;\n\nconst PAGE_FIELDS = {\n pageIndex: true,\n widthPoints: true,\n heightPoints: true,\n annotationCount: true,\n observation: true,\n} as const satisfies RequiredFields<PdfPageInspection>;\n\nconst RISK_FIELDS = {\n acroFormFieldCount: true,\n annotationCount: true,\n documentInfoEntryCount: true,\n embeddedFileCount: true,\n externalActionCount: true,\n formXObjectCount: true,\n imageObjectCount: true,\n incrementalRevisionCount: true,\n javascriptActionCount: true,\n metadataStreamCount: true,\n optionalContentGroupCount: true,\n signatureCount: true,\n trailingNonWhitespaceByteCount: true,\n unsupportedActionCount: true,\n xfaEntryCount: true,\n} as const satisfies RequiredFields<PdfRiskInventory>;\n\nconst INSPECTION_FIELDS = {\n contractVersion: true,\n pdfVersion: true,\n byteLength: true,\n objectCount: true,\n pageCount: true,\n encrypted: true,\n pages: true,\n risks: true,\n coverage: true,\n} as const satisfies RequiredFields<PdfInspection>;\n\nconst PROVIDER_FIELDS = {\n providerId: true,\n rendererName: true,\n rendererVersion: true,\n ocrName: true,\n ocrVersion: true,\n ocrLanguage: true,\n} as const satisfies RequiredFields<PdfRasterProvider>;\n\nconst CERTIFICATE_FIELDS = {\n contractVersion: true,\n pageCount: true,\n sourceSha256: true,\n outputSha256: true,\n provider: true,\n detectionCount: true,\n mappedRegionCount: true,\n structurePixelRewriteVerified: true,\n providerAssertedCoverage: true,\n piiCleanGuaranteed: true,\n limitation: true,\n} as const satisfies RequiredFields<PdfRasterRewriteCertificate>;\n\nconst COVERAGE_FIELDS = {\n status: true,\n gaps: true,\n} as const satisfies RequiredFields<PdfInspection[\"coverage\"]>;\n\nconst INSPECTION_GAPS = {\n \"encrypted-document\": true,\n \"page-content-not-observed\": true,\n \"page-not-rendered\": true,\n \"partial-text-layer\": true,\n \"retained-document-bytes\": true,\n \"unobserved-visual-content\": true,\n} as const satisfies Record<PdfInspectionGap, true>;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst hasExactFields = (\n value: Record<string, unknown>,\n fields: Record<string, true>,\n): boolean => {\n const keys = Object.keys(value);\n return (\n keys.length === Object.keys(fields).length &&\n keys.every((key) => Object.hasOwn(fields, key))\n );\n};\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\n\nconst isNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n\nconst isRect = (value: unknown): value is PdfRect =>\n isRecord(value) &&\n hasExactFields(value, RECT_FIELDS) &&\n isFiniteNumber(value[\"left\"]) &&\n isFiniteNumber(value[\"bottom\"]) &&\n isFiniteNumber(value[\"right\"]) &&\n isFiniteNumber(value[\"top\"]);\n\nconst isGlyph = (value: unknown): value is PdfGlyphObservation =>\n isRecord(value) &&\n hasExactFields(value, GLYPH_FIELDS) &&\n isNonNegativeInteger(value[\"start\"]) &&\n isNonNegativeInteger(value[\"end\"]) &&\n value[\"end\"] >= value[\"start\"] &&\n isRect(value[\"bounds\"]) &&\n (value[\"source\"] === \"embedded-text\" || value[\"source\"] === \"ocr\");\n\nconst isObservation = (value: unknown): value is PdfPageObservation =>\n isRecord(value) &&\n hasExactFields(value, OBSERVATION_FIELDS) &&\n isNonNegativeInteger(value[\"pageIndex\"]) &&\n isFiniteNumber(value[\"widthPoints\"]) &&\n value[\"widthPoints\"] > 0 &&\n isFiniteNumber(value[\"heightPoints\"]) &&\n value[\"heightPoints\"] > 0 &&\n typeof value[\"text\"] === \"string\" &&\n Array.isArray(value[\"glyphs\"]) &&\n value[\"glyphs\"].every(isGlyph) &&\n typeof value[\"rendered\"] === \"boolean\" &&\n (value[\"textLayer\"] === \"absent\" ||\n value[\"textLayer\"] === \"partial\" ||\n value[\"textLayer\"] === \"complete\") &&\n (value[\"ocr\"] === \"not-run\" ||\n value[\"ocr\"] === \"partial\" ||\n value[\"ocr\"] === \"complete\") &&\n isNonNegativeInteger(value[\"imageCount\"]);\n\nconst isPage = (value: unknown): value is PdfPageInspection =>\n isRecord(value) &&\n hasExactFields(value, PAGE_FIELDS) &&\n isNonNegativeInteger(value[\"pageIndex\"]) &&\n isFiniteNumber(value[\"widthPoints\"]) &&\n value[\"widthPoints\"] > 0 &&\n isFiniteNumber(value[\"heightPoints\"]) &&\n value[\"heightPoints\"] > 0 &&\n isNonNegativeInteger(value[\"annotationCount\"]) &&\n (value[\"observation\"] === null || isObservation(value[\"observation\"]));\n\nconst isRiskInventory = (value: unknown): value is PdfRiskInventory =>\n isRecord(value) &&\n hasExactFields(value, RISK_FIELDS) &&\n Object.keys(RISK_FIELDS).every((field) => isNonNegativeInteger(value[field]));\n\nconst isInspectionGap = (value: unknown): value is PdfInspectionGap =>\n typeof value === \"string\" && Object.hasOwn(INSPECTION_GAPS, value);\n\nconst isInspection = (value: unknown): value is PdfInspection =>\n isRecord(value) &&\n hasExactFields(value, INSPECTION_FIELDS) &&\n value[\"contractVersion\"] === 1 &&\n typeof value[\"pdfVersion\"] === \"string\" &&\n isNonNegativeInteger(value[\"byteLength\"]) &&\n isNonNegativeInteger(value[\"objectCount\"]) &&\n isNonNegativeInteger(value[\"pageCount\"]) &&\n typeof value[\"encrypted\"] === \"boolean\" &&\n Array.isArray(value[\"pages\"]) &&\n value[\"pages\"].length === value[\"pageCount\"] &&\n value[\"pages\"].every(isPage) &&\n value[\"pages\"].every(({ pageIndex }, index) => pageIndex === index) &&\n isRiskInventory(value[\"risks\"]) &&\n isRecord(value[\"coverage\"]) &&\n hasExactFields(value[\"coverage\"], COVERAGE_FIELDS) &&\n (value[\"coverage\"][\"status\"] === \"full\" ||\n value[\"coverage\"][\"status\"] === \"partial\") &&\n Array.isArray(value[\"coverage\"][\"gaps\"]) &&\n value[\"coverage\"][\"gaps\"].every(isInspectionGap);\n\nconst isProvider = (value: unknown): value is PdfRasterProvider =>\n isRecord(value) &&\n hasExactFields(value, PROVIDER_FIELDS) &&\n typeof value[\"providerId\"] === \"string\" &&\n typeof value[\"rendererName\"] === \"string\" &&\n typeof value[\"rendererVersion\"] === \"string\" &&\n typeof value[\"ocrName\"] === \"string\" &&\n typeof value[\"ocrVersion\"] === \"string\" &&\n typeof value[\"ocrLanguage\"] === \"string\";\n\nconst isSha256 = (value: unknown): value is string =>\n typeof value === \"string\" && /^[a-f0-9]{64}$/u.test(value);\n\nconst isCertificate = (value: unknown): value is PdfRasterRewriteCertificate =>\n isRecord(value) &&\n hasExactFields(value, CERTIFICATE_FIELDS) &&\n value[\"contractVersion\"] === 1 &&\n isNonNegativeInteger(value[\"pageCount\"]) &&\n isSha256(value[\"sourceSha256\"]) &&\n isSha256(value[\"outputSha256\"]) &&\n isProvider(value[\"provider\"]) &&\n isNonNegativeInteger(value[\"detectionCount\"]) &&\n isNonNegativeInteger(value[\"mappedRegionCount\"]) &&\n value[\"structurePixelRewriteVerified\"] === true &&\n value[\"providerAssertedCoverage\"] ===\n \"complete-rendering-and-ocr-observation\" &&\n value[\"piiCleanGuaranteed\"] === false &&\n typeof value[\"limitation\"] === \"string\";\n\nexport const decodePdfInspection = (json: string): PdfInspection => {\n const value: unknown = JSON.parse(json);\n if (!isInspection(value)) {\n throw new Error(\"Native PDF inspection does not match contract version 1\");\n }\n return value;\n};\n\nexport const decodePdfRasterRewriteCertificate = (\n json: string,\n): PdfRasterRewriteCertificate => {\n const value: unknown = JSON.parse(json);\n if (!isCertificate(value)) {\n throw new Error(\n \"Native PDF raster certificate does not match contract version 1\",\n );\n }\n return value;\n};\n","import { execFile } from \"node:child_process\";\nimport {\n lstat,\n mkdtemp,\n readFile,\n rm,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, sep } from \"node:path\";\n\nimport { loadNativeAnonymizeBinding } from \"@stll/anonymize\";\n\nimport { decodePdfInspection } from \"./native-codec\";\nimport type {\n PdfGlyphObservation,\n PdfPageObservation,\n PdfRasterProvider,\n} from \"./types\";\n\nconst LOCAL_PROVIDER_ID = \"poppler-tesseract-local\";\nconst PROCESS_OUTPUT_MAX_BYTES = 64 * 1024 * 1024;\nconst PDF_DOCUMENT_MAX_BYTES = 64 * 1024 * 1024;\nconst PDF_RASTER_MAX_PAGE_BYTES = 128 * 1024 * 1024;\nconst PDF_RASTER_MAX_TOTAL_BYTES = 512 * 1024 * 1024;\nconst PDF_MAX_PAGES = 10_000;\nconst PDF_MAX_GLYPHS = 5_000_000;\nconst PDF_MAX_OBSERVED_TEXT_UTF8_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_DPI = 300;\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MIN_DPI = 72;\nconst MAX_DPI = 600;\nconst MIN_TIMEOUT_MS = 100;\nconst MAX_TIMEOUT_MS = 300_000;\nconst LANGUAGE_PACK_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/u;\nconst TEMP_PREFIX = \"stella-anonymize-pdf-\";\n\nexport const PDF_LOCAL_PROVIDER_ERROR_CODES = {\n cleanupFailed: \"cleanup-failed\",\n executableFailed: \"executable-failed\",\n invalidOptions: \"invalid-options\",\n invalidOutput: \"invalid-output\",\n limitExceeded: \"limit-exceeded\",\n sourceRejected: \"source-rejected\",\n} as const;\n\nexport type PdfLocalProviderErrorCode =\n (typeof PDF_LOCAL_PROVIDER_ERROR_CODES)[keyof typeof PDF_LOCAL_PROVIDER_ERROR_CODES];\n\nexport class PdfLocalProviderError extends Error {\n readonly code: PdfLocalProviderErrorCode;\n\n constructor(code: PdfLocalProviderErrorCode, message: string) {\n super(message);\n this.name = \"PdfLocalProviderError\";\n this.code = code;\n }\n}\n\nexport type RenderPdfWithPopplerTesseractOptions = {\n document: Uint8Array;\n /** One explicit installed Tesseract traineddata name, for example `eng`. */\n ocrLanguage: string;\n dpi?: number | undefined;\n pdftoppmPath?: string | undefined;\n tesseractPath?: string | undefined;\n timeoutMs?: number | undefined;\n};\n\nexport type LocalPdfRasterPage = {\n observation: PdfPageObservation;\n widthPixels: number;\n heightPixels: number;\n pixels: Uint8Array;\n};\n\nexport type LocalPdfRasterObservation = {\n provider: PdfRasterProvider;\n pages: readonly LocalPdfRasterPage[];\n};\n\ntype ResolvedLocalProviderOptions = {\n dpi: number;\n ocrLanguage: string;\n pdftoppmPath: string;\n tesseractPath: string;\n timeoutMs: number;\n};\n\ntype ProcessResult = { stdout: Buffer; stderr: Buffer };\n\nconst providerError = (\n code: PdfLocalProviderErrorCode,\n message: string,\n): PdfLocalProviderError =>\n new PdfLocalProviderError(code, `${code}: ${message}`);\n\nconst validateOptions = (\n options: RenderPdfWithPopplerTesseractOptions,\n): ResolvedLocalProviderOptions => {\n const dpi = options.dpi ?? DEFAULT_DPI;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const pdftoppmPath = options.pdftoppmPath ?? \"pdftoppm\";\n const tesseractPath = options.tesseractPath ?? \"tesseract\";\n if (\n !Number.isInteger(dpi) ||\n dpi < MIN_DPI ||\n dpi > MAX_DPI ||\n !Number.isInteger(timeoutMs) ||\n timeoutMs < MIN_TIMEOUT_MS ||\n timeoutMs > MAX_TIMEOUT_MS ||\n !LANGUAGE_PACK_PATTERN.test(options.ocrLanguage) ||\n !pdftoppmPath ||\n pdftoppmPath.includes(\"\\0\") ||\n !tesseractPath ||\n tesseractPath.includes(\"\\0\")\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOptions,\n \"local PDF provider options are invalid\",\n );\n }\n return {\n dpi,\n ocrLanguage: options.ocrLanguage,\n pdftoppmPath,\n tesseractPath,\n timeoutMs,\n };\n};\n\nconst runExecutable = (\n executable: string,\n args: readonly string[],\n timeoutMs: number,\n stage: \"OCR\" | \"renderer\" | \"version probe\",\n): Promise<ProcessResult> =>\n new Promise((resolve, reject) => {\n execFile(\n executable,\n args,\n {\n encoding: \"buffer\",\n maxBuffer: PROCESS_OUTPUT_MAX_BYTES,\n timeout: timeoutMs,\n windowsHide: true,\n },\n (error, stdout, stderr) => {\n if (error !== null) {\n reject(\n providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.executableFailed,\n `local PDF ${stage} failed`,\n ),\n );\n return;\n }\n resolve({ stdout: Buffer.from(stdout), stderr: Buffer.from(stderr) });\n },\n );\n });\n\nconst decodeUtf8 = (value: Uint8Array, context: string): string => {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(value);\n } catch {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n `local PDF ${context} is not valid UTF-8`,\n );\n }\n};\n\nconst versionFrom = (\n value: Uint8Array,\n prefix: string,\n context: string,\n): string => {\n const line = decodeUtf8(value, context).split(/\\r?\\n/u, 1)[0]?.trim();\n const version = line?.startsWith(prefix)\n ? line.slice(prefix.length).trim()\n : \"\";\n if (!version || version.length > 256 || /\\p{Cc}/u.test(version)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n `local PDF ${context} is invalid`,\n );\n }\n return version;\n};\n\ntype InspectedPageGeometry = {\n heightPoints: number;\n widthPoints: number;\n};\n\nconst inspectPageGeometry = (\n document: Uint8Array,\n): readonly InspectedPageGeometry[] => {\n if (document.byteLength > PDF_DOCUMENT_MAX_BYTES) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"PDF source exceeds its byte limit\",\n );\n }\n const inspect = loadNativeAnonymizeBinding().inspectPdfJson;\n if (inspect === undefined) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.sourceRejected,\n \"native PDF inspection is unavailable\",\n );\n }\n try {\n const inspection = decodePdfInspection(inspect(document));\n if (\n inspection.encrypted === true ||\n inspection.pageCount < 1 ||\n inspection.pageCount > PDF_MAX_PAGES\n ) {\n throw new Error(\"source rejected\");\n }\n return inspection.pages.map(({ heightPoints, widthPoints }) => ({\n heightPoints,\n widthPoints,\n }));\n } catch {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.sourceRejected,\n \"PDF source is unsupported by the local raster provider\",\n );\n }\n};\n\nconst assertProjectedRasterLimits = (\n pages: readonly InspectedPageGeometry[],\n dpi: number,\n): void => {\n let totalBytes = 0;\n for (const { heightPoints, widthPoints } of pages) {\n const widthPixels = Math.ceil((widthPoints * dpi) / 72);\n const heightPixels = Math.ceil((heightPoints * dpi) / 72);\n const pageBytes = widthPixels * heightPixels * 3;\n totalBytes += pageBytes;\n if (\n !Number.isSafeInteger(widthPixels) ||\n !Number.isSafeInteger(heightPixels) ||\n widthPixels <= 0 ||\n heightPixels <= 0 ||\n !Number.isSafeInteger(pageBytes) ||\n pageBytes > PDF_RASTER_MAX_PAGE_BYTES ||\n !Number.isSafeInteger(totalBytes) ||\n totalBytes > PDF_RASTER_MAX_TOTAL_BYTES\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"PDF page geometry exceeds the selected DPI raster limits\",\n );\n }\n }\n};\n\ntype PpmPage = {\n width: number;\n height: number;\n pixels: Uint8Array;\n};\n\nconst isWhitespace = (byte: number): boolean =>\n byte === 0x09 ||\n byte === 0x0a ||\n byte === 0x0b ||\n byte === 0x0c ||\n byte === 0x0d ||\n byte === 0x20;\n\nconst ppmToken = (bytes: Uint8Array, start: number): [string, number] => {\n let offset = start;\n while (offset < bytes.length) {\n if (isWhitespace(bytes[offset] ?? -1)) {\n offset += 1;\n continue;\n }\n if (bytes[offset] === 0x23) {\n while (offset < bytes.length && bytes[offset] !== 0x0a) offset += 1;\n continue;\n }\n break;\n }\n const tokenStart = offset;\n while (\n offset < bytes.length &&\n !isWhitespace(bytes[offset] ?? -1) &&\n bytes[offset] !== 0x23\n ) {\n offset += 1;\n }\n if (tokenStart === offset) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted an invalid PPM header\",\n );\n }\n const token = Buffer.from(bytes.subarray(tokenStart, offset)).toString(\n \"ascii\",\n );\n if (!/^[\\x21-\\x7e]+$/u.test(token)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted an invalid PPM header\",\n );\n }\n return [token, offset];\n};\n\nconst parsePositiveInteger = (value: string): number => {\n if (!/^[1-9][0-9]*$/u.test(value)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted invalid PPM dimensions\",\n );\n }\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler PPM dimensions exceed their limit\",\n );\n }\n return parsed;\n};\n\nconst parsePpm = (bytes: Uint8Array): PpmPage => {\n const [magic, afterMagic] = ppmToken(bytes, 0);\n const [widthValue, afterWidth] = ppmToken(bytes, afterMagic);\n const [heightValue, afterHeight] = ppmToken(bytes, afterWidth);\n const [maximumValue, afterMaximum] = ppmToken(bytes, afterHeight);\n if (magic !== \"P6\" || maximumValue !== \"255\") {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler must emit binary RGB8 PPM pages\",\n );\n }\n const width = parsePositiveInteger(widthValue);\n const height = parsePositiveInteger(heightValue);\n const expected = width * height * 3;\n if (!Number.isSafeInteger(expected) || expected > PDF_RASTER_MAX_PAGE_BYTES) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler page pixels exceed their byte limit\",\n );\n }\n let pixelOffset = afterMaximum;\n if (!isWhitespace(bytes[pixelOffset] ?? -1)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted an invalid PPM pixel separator\",\n );\n }\n const separator = bytes[pixelOffset];\n pixelOffset += 1;\n if (separator === 0x0d && bytes[pixelOffset] === 0x0a) pixelOffset += 1;\n if (bytes.length - pixelOffset !== expected) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted a truncated or trailing PPM page\",\n );\n }\n return { width, height, pixels: bytes.subarray(pixelOffset) };\n};\n\nconst boundedRenderedPage = async (path: string): Promise<PpmPage> => {\n const metadata = await lstat(path);\n if (!metadata.isFile() || metadata.isSymbolicLink()) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler page output must be a regular file\",\n );\n }\n if (metadata.size > PDF_RASTER_MAX_PAGE_BYTES + 1024 * 1024) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler page output exceeds its byte limit\",\n );\n }\n return parsePpm(await readFile(path));\n};\n\nconst integerTsvField = (value: string | undefined): number => {\n if (value === undefined || !/^(?:0|[1-9][0-9]*)$/u.test(value)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted invalid TSV geometry\",\n );\n }\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract TSV geometry exceeds its limit\",\n );\n }\n return parsed;\n};\n\nconst parseTesseractTsv = (\n bytes: Uint8Array,\n page: PpmPage,\n pageGeometry: InspectedPageGeometry,\n pageIndex: number,\n): PdfPageObservation => {\n const lines = decodeUtf8(bytes, \"Tesseract TSV\").split(/\\r?\\n/u);\n const header = lines.shift()?.split(\"\\t\");\n if (\n header?.slice(0, 12).join(\"\\t\") !==\n \"level\\tpage_num\\tblock_num\\tpar_num\\tline_num\\tword_num\\tleft\\ttop\\twidth\\theight\\tconf\\ttext\"\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted an unsupported TSV header\",\n );\n }\n const { heightPoints, widthPoints } = pageGeometry;\n const glyphs: PdfGlyphObservation[] = [];\n let text = \"\";\n let previousLine = \"\";\n for (const line of lines) {\n if (!line) continue;\n const fields = line.split(\"\\t\");\n if (fields[0] !== \"5\") continue;\n const word = fields.slice(11).join(\"\\t\").trim();\n if (!word) continue;\n if (/\\p{Cc}/u.test(word)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted control characters in OCR text\",\n );\n }\n const lineKey = `${fields[2] ?? \"\"}/${fields[3] ?? \"\"}/${fields[4] ?? \"\"}`;\n if (text) text += lineKey === previousLine ? \" \" : \"\\n\";\n previousLine = lineKey;\n const start = text.length;\n text += word;\n const end = text.length;\n const left = integerTsvField(fields[6]);\n const top = integerTsvField(fields[7]);\n const width = integerTsvField(fields[8]);\n const height = integerTsvField(fields[9]);\n const right = left + width;\n const bottom = top + height;\n if (\n width === 0 ||\n height === 0 ||\n !Number.isSafeInteger(right) ||\n !Number.isSafeInteger(bottom) ||\n right > page.width ||\n bottom > page.height\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted out-of-page OCR geometry\",\n );\n }\n glyphs.push({\n start,\n end,\n bounds: {\n left: (left * widthPoints) / page.width,\n bottom: heightPoints - (bottom * heightPoints) / page.height,\n right: (right * widthPoints) / page.width,\n top: heightPoints - (top * heightPoints) / page.height,\n },\n source: \"ocr\",\n });\n if (glyphs.length > PDF_MAX_GLYPHS) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract OCR glyph count exceeds its limit\",\n );\n }\n if (Buffer.byteLength(text, \"utf8\") > PDF_MAX_OBSERVED_TEXT_UTF8_BYTES) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract OCR text exceeds its byte limit\",\n );\n }\n }\n return {\n pageIndex,\n widthPoints,\n heightPoints,\n text,\n glyphs,\n rendered: true,\n textLayer: \"absent\",\n ocr: \"complete\",\n imageCount: 0,\n };\n};\n\nconst safeCleanup = async (directory: string): Promise<void> => {\n const expectedPrefix = `${tmpdir()}${sep}${TEMP_PREFIX}`;\n if (!directory.startsWith(expectedPrefix)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary directory could not be verified\",\n );\n }\n try {\n const metadata = await lstat(directory);\n if (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary directory could not be verified\",\n );\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n if (error instanceof PdfLocalProviderError) throw error;\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary directory could not be inspected\",\n );\n }\n try {\n await rm(directory, { force: true, recursive: true });\n } catch {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary files could not be removed\",\n );\n }\n};\n\nexport const renderPdfWithPopplerTesseract = async (\n options: RenderPdfWithPopplerTesseractOptions,\n): Promise<LocalPdfRasterObservation> => {\n const resolved = validateOptions(options);\n const pageGeometry = inspectPageGeometry(options.document);\n assertProjectedRasterLimits(pageGeometry, resolved.dpi);\n const pageCount = pageGeometry.length;\n const popplerVersionResult = await runExecutable(\n resolved.pdftoppmPath,\n [\"-v\"],\n resolved.timeoutMs,\n \"version probe\",\n );\n const tesseractVersionResult = await runExecutable(\n resolved.tesseractPath,\n [\"--version\"],\n resolved.timeoutMs,\n \"version probe\",\n );\n const rendererVersion = versionFrom(\n popplerVersionResult.stderr.length > 0\n ? popplerVersionResult.stderr\n : popplerVersionResult.stdout,\n \"pdftoppm version \",\n \"Poppler version\",\n );\n const ocrVersion = versionFrom(\n tesseractVersionResult.stdout.length > 0\n ? tesseractVersionResult.stdout\n : tesseractVersionResult.stderr,\n \"tesseract \",\n \"Tesseract version\",\n );\n const directory = await mkdtemp(join(tmpdir(), TEMP_PREFIX));\n try {\n const sourcePath = join(directory, \"source.pdf\");\n const outputPrefix = join(directory, \"page\");\n await writeFile(sourcePath, options.document, { flag: \"wx\", mode: 0o600 });\n const pages: LocalPdfRasterPage[] = [];\n let totalPixels = 0;\n let totalGlyphs = 0;\n let totalObservedTextUtf8Bytes = 0;\n for (let pageNumber = 1; pageNumber <= pageCount; pageNumber += 1) {\n const inspectedGeometry = pageGeometry.at(pageNumber - 1);\n if (inspectedGeometry === undefined) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.sourceRejected,\n \"PDF page geometry became unavailable\",\n );\n }\n const pageOutputPrefix = `${outputPrefix}-${pageNumber}`;\n const pagePath = `${pageOutputPrefix}.ppm`;\n await runExecutable(\n resolved.pdftoppmPath,\n [\n \"-cropbox\",\n \"-f\",\n String(pageNumber),\n \"-l\",\n String(pageNumber),\n \"-singlefile\",\n \"-r\",\n String(resolved.dpi),\n sourcePath,\n pageOutputPrefix,\n ],\n resolved.timeoutMs,\n \"renderer\",\n );\n try {\n const page = await boundedRenderedPage(pagePath);\n totalPixels += page.pixels.byteLength;\n if (\n !Number.isSafeInteger(totalPixels) ||\n totalPixels > PDF_RASTER_MAX_TOTAL_BYTES\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler page pixels exceed their aggregate limit\",\n );\n }\n const ocr = await runExecutable(\n resolved.tesseractPath,\n [pagePath, \"stdout\", \"-l\", resolved.ocrLanguage, \"tsv\"],\n resolved.timeoutMs,\n \"OCR\",\n );\n const observation = parseTesseractTsv(\n ocr.stdout,\n page,\n inspectedGeometry,\n pageNumber - 1,\n );\n totalGlyphs += observation.glyphs.length;\n totalObservedTextUtf8Bytes += Buffer.byteLength(\n observation.text,\n \"utf8\",\n );\n if (\n !Number.isSafeInteger(totalGlyphs) ||\n totalGlyphs > PDF_MAX_GLYPHS ||\n !Number.isSafeInteger(totalObservedTextUtf8Bytes) ||\n totalObservedTextUtf8Bytes > PDF_MAX_OBSERVED_TEXT_UTF8_BYTES\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract OCR document output exceeds its aggregate limit\",\n );\n }\n pages.push({\n observation,\n widthPixels: page.width,\n heightPixels: page.height,\n pixels: page.pixels,\n });\n } finally {\n await unlink(pagePath).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return;\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF page raster could not be removed\",\n );\n });\n }\n }\n return {\n provider: {\n providerId: LOCAL_PROVIDER_ID,\n rendererName: \"Poppler pdftoppm\",\n rendererVersion,\n ocrName: \"Tesseract OCR\",\n ocrVersion,\n ocrLanguage: resolved.ocrLanguage,\n },\n pages,\n };\n } finally {\n await safeCleanup(directory);\n }\n};\n","import { createHash } from \"node:crypto\";\n\nimport {\n convert_external_detection_batch,\n loadNativeAnonymizeBinding,\n type ExternalDetectionBatch,\n type PreparedNativePipeline,\n} from \"@stll/anonymize\";\n\nimport {\n PDF_INSPECTION_ERROR_CODES,\n PDF_RASTER_ERROR_CODES,\n type PdfInspection,\n type PdfInspectionErrorCode,\n type PdfPageObservation,\n type PdfRasterProvider,\n type PdfRasterErrorCode,\n type PdfRasterRewrite,\n type PdfRasterRewriteResult,\n} from \"./types\";\nimport {\n decodePdfInspection,\n decodePdfRasterRewriteCertificate,\n} from \"./native-codec\";\n\nexport const PDF_INSPECTION_CONTRACT_VERSION = 1 as const;\nexport const PDF_RASTER_CONTRACT_VERSION = 1 as const;\nexport const PDF_RASTER_MAX_PAGE_BYTES = 128 * 1024 * 1024;\nexport const PDF_RASTER_MAX_TOTAL_BYTES = 512 * 1024 * 1024;\nexport const PDF_RASTER_MAX_OUTPUT_BYTES = 512 * 1024 * 1024;\nexport const PDF_RASTER_REQUEST_JSON_MAX_BYTES = 64 * 1024 * 1024;\nexport const PDF_DOCUMENT_MAX_BYTES = 64 * 1024 * 1024;\nexport const PDF_STREAM_DECOMPRESSED_MAX_BYTES = 32 * 1024 * 1024;\nexport const PDF_LOADED_PAYLOAD_MAX_BYTES = 128 * 1024 * 1024;\nexport const PDF_MAX_OBJECTS = 200_000;\nexport const PDF_MAX_OBJECT_NODES = 1_000_000;\nexport const PDF_MAX_OBJECT_DEPTH = 128;\nexport const PDF_MAX_PAGES = 10_000;\nexport const PDF_MAX_GLYPHS = 5_000_000;\nexport const PDF_MAX_PAGE_TEXT_UTF8_BYTES = 16 * 1024 * 1024;\nexport const PDF_MAX_OBSERVED_TEXT_UTF8_BYTES = 64 * 1024 * 1024;\nexport const PDF_OBSERVATIONS_JSON_MAX_BYTES = 64 * 1024 * 1024;\n/** Renderer dimensions may differ by this many points due to numeric rounding. */\nexport const PDF_PAGE_DIMENSION_TOLERANCE_POINTS = 0.25;\n\nexport class PdfInspectionError extends Error {\n readonly code: PdfInspectionErrorCode;\n\n constructor(code: PdfInspectionErrorCode, message: string) {\n super(message);\n this.name = \"PdfInspectionError\";\n this.code = code;\n }\n}\n\nexport class PdfRasterError extends Error {\n readonly code: PdfRasterErrorCode;\n\n constructor(code: PdfRasterErrorCode, message: string) {\n super(message);\n this.name = \"PdfRasterError\";\n this.code = code;\n }\n}\n\nconst errorCode = (message: string): PdfInspectionErrorCode => {\n const code = Object.values(PDF_INSPECTION_ERROR_CODES).find((candidate) =>\n message.startsWith(`${candidate}:`),\n );\n return code ?? PDF_INSPECTION_ERROR_CODES.invalidDocument;\n};\n\nconst rasterErrorCode = (message: string): PdfRasterErrorCode => {\n const code = Object.values(PDF_RASTER_ERROR_CODES).find((candidate) =>\n message.startsWith(`${candidate}:`),\n );\n return code ?? PDF_RASTER_ERROR_CODES.verificationFailed;\n};\n\nexport type InspectPdfOptions = {\n pageObservations?: readonly PdfPageObservation[];\n};\n\nexport const inspectPdf = (\n document: Uint8Array,\n options: InspectPdfOptions = {},\n): PdfInspection => {\n const inspect = loadNativeAnonymizeBinding().inspectPdfJson;\n if (inspect === undefined) {\n throw new PdfInspectionError(\n PDF_INSPECTION_ERROR_CODES.invalidDocument,\n \"Native anonymize binding does not expose PDF inspection\",\n );\n }\n try {\n const observations = options.pageObservations;\n return decodePdfInspection(\n inspect(\n document,\n observations === undefined ? undefined : JSON.stringify(observations),\n ),\n );\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"PDF inspection failed\";\n throw new PdfInspectionError(errorCode(message), message);\n }\n};\n\nexport type RewritePdfRasterFromDetectionsOptions = {\n document: Uint8Array;\n request: PdfRasterRewrite;\n /** One opaque, row-packed RGB8 buffer per request page, in page order. */\n pagePixels: readonly Uint8Array[];\n};\n\n/**\n * Advanced rewrite-only surface. It verifies structure and destructive pixels but\n * does not run detection or certify that the result is PII-free.\n */\nexport const rewritePdfRasterFromDetections = ({\n document,\n request,\n pagePixels,\n}: RewritePdfRasterFromDetectionsOptions): PdfRasterRewriteResult => {\n const rewrite =\n loadNativeAnonymizeBinding().rewritePdfRasterFromDetectionsJson;\n if (rewrite === undefined) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.verificationFailed,\n \"Native anonymize binding does not expose PDF raster rewriting\",\n );\n }\n try {\n const result = rewrite(document, JSON.stringify(request), pagePixels);\n return {\n document: result.document,\n certificate: decodePdfRasterRewriteCertificate(result.certificateJson),\n };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"PDF raster rewrite failed\";\n throw new PdfRasterError(rasterErrorCode(message), message);\n }\n};\n\nexport type PdfRasterObservedPageInput = {\n observation: PdfPageObservation;\n widthPixels: number;\n heightPixels: number;\n pixels: Uint8Array;\n /** Optional digest-bound provider batch merged through stella caller semantics. */\n externalDetectionBatch?: ExternalDetectionBatch | string | undefined;\n};\n\nexport type AnonymizePdfRasterOptions = {\n document: Uint8Array;\n pipeline: Pick<\n PreparedNativePipeline,\n \"redactText\" | \"redactTextWithCallerDetections\"\n >;\n provider: PdfRasterProvider;\n pages: readonly PdfRasterObservedPageInput[];\n fillRgb?: readonly [number, number, number] | undefined;\n};\n\nconst sha256 = (value: Uint8Array): string =>\n createHash(\"sha256\").update(value).digest(\"hex\");\n\n/** Run stella detection, merge optional external detections, then rewrite pixels. */\nexport const anonymizePdfRaster = ({\n document,\n pipeline,\n provider,\n pages,\n fillRgb = [0, 0, 0],\n}: AnonymizePdfRasterOptions): PdfRasterRewriteResult => {\n if (document.byteLength > PDF_DOCUMENT_MAX_BYTES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF source exceeds its byte limit\",\n );\n }\n if (pages.length > PDF_MAX_PAGES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster page count exceeds its limit\",\n );\n }\n let totalPixelBytes = 0;\n let totalObservedTextBytes = 0;\n const textEncoder = new TextEncoder();\n for (const page of pages) {\n if (typeof page.observation?.text !== \"string\") {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.invalidContract,\n \"invalid-contract: PDF raster observed text is invalid\",\n );\n }\n const observedTextBytes = textEncoder.encode(\n page.observation.text,\n ).byteLength;\n if (observedTextBytes > PDF_MAX_PAGE_TEXT_UTF8_BYTES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster page text exceeds its byte limit\",\n );\n }\n totalObservedTextBytes += observedTextBytes;\n if (totalObservedTextBytes > PDF_MAX_OBSERVED_TEXT_UTF8_BYTES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster observed text exceeds its aggregate byte limit\",\n );\n }\n const { heightPixels, widthPixels } = page;\n if (\n !Number.isSafeInteger(widthPixels) ||\n !Number.isSafeInteger(heightPixels) ||\n widthPixels <= 0 ||\n heightPixels <= 0\n ) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.invalidContract,\n \"invalid-contract: PDF raster pixel dimensions are invalid\",\n );\n }\n const expected = widthPixels * heightPixels * 3;\n if (\n !Number.isSafeInteger(expected) ||\n expected > PDF_RASTER_MAX_PAGE_BYTES ||\n page.pixels.byteLength !== expected\n ) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster page pixels exceed limits or have an invalid RGB8 length\",\n );\n }\n totalPixelBytes += expected;\n if (\n !Number.isSafeInteger(totalPixelBytes) ||\n totalPixelBytes > PDF_RASTER_MAX_TOTAL_BYTES\n ) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster pixels exceed their aggregate limit\",\n );\n }\n }\n const binding = loadNativeAnonymizeBinding();\n let requestPages: PdfRasterRewrite[\"pages\"];\n try {\n requestPages = pages.map((page) => {\n const external =\n page.externalDetectionBatch === undefined\n ? undefined\n : convert_external_detection_batch(\n new TextEncoder().encode(page.observation.text),\n page.externalDetectionBatch,\n { binding },\n );\n const result =\n external === undefined\n ? pipeline.redactText(page.observation.text)\n : pipeline.redactTextWithCallerDetections(page.observation.text, {\n detections: external,\n });\n return {\n observation: page.observation,\n widthPixels: page.widthPixels,\n heightPixels: page.heightPixels,\n pixelSha256: sha256(page.pixels),\n detections: result.resolvedEntities.map(({ start, end }) => ({\n start,\n end,\n })),\n };\n });\n } catch {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.detectionFailed,\n \"detection-failed: PDF raster detection failed\",\n );\n }\n return rewritePdfRasterFromDetections({\n document,\n request: {\n contractVersion: PDF_RASTER_CONTRACT_VERSION,\n sourceSha256: sha256(document),\n provider,\n fillRgb,\n pages: requestPages,\n },\n pagePixels: pages.map(({ pixels }) => pixels),\n });\n};\n\nexport { PDF_INSPECTION_ERROR_CODES } from \"./types\";\nexport { PDF_RASTER_ERROR_CODES } from \"./types\";\nexport {\n PDF_LOCAL_PROVIDER_ERROR_CODES,\n PdfLocalProviderError,\n renderPdfWithPopplerTesseract,\n} from \"./local-provider\";\nexport type {\n LocalPdfRasterObservation,\n LocalPdfRasterPage,\n PdfLocalProviderErrorCode,\n RenderPdfWithPopplerTesseractOptions,\n} from \"./local-provider\";\nexport type {\n PdfGlyphObservation,\n PdfInspection,\n PdfInspectionErrorCode,\n PdfInspectionGap,\n PdfPageInspection,\n PdfPageObservation,\n PdfRect,\n PdfRiskInventory,\n PdfRasterDetection,\n PdfRasterErrorCode,\n PdfRasterPage,\n PdfRasterProvider,\n PdfRasterRewrite,\n PdfRasterRewriteCertificate,\n PdfRasterRewriteResult,\n} from \"./types\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["PDF_DOCUMENT_MAX_BYTES","PDF_RASTER_MAX_PAGE_BYTES","PDF_RASTER_MAX_TOTAL_BYTES","PDF_MAX_PAGES","PDF_MAX_GLYPHS","PDF_MAX_OBSERVED_TEXT_UTF8_BYTES"],"sources":["../src/types.ts","../src/native-codec.ts","../src/local-provider.ts","../src/index.ts"],"sourcesContent":["export type PdfRect = {\n left: number;\n bottom: number;\n right: number;\n top: number;\n};\n\nexport type PdfGlyphObservation = {\n start: number;\n end: number;\n /** Bounds in normalized displayed-page PDF points, origin bottom-left. */\n bounds: PdfRect;\n source: \"embedded-text\" | \"ocr\";\n};\n\nexport type PdfPageObservation = {\n pageIndex: number;\n /** Effective visible width after page boxes, rotation, and UserUnit scaling. */\n widthPoints: number;\n /** Effective visible height after page boxes, rotation, and UserUnit scaling. */\n heightPoints: number;\n text: string;\n glyphs: readonly PdfGlyphObservation[];\n rendered: boolean;\n textLayer: \"absent\" | \"partial\" | \"complete\";\n ocr: \"not-run\" | \"partial\" | \"complete\";\n imageCount: number;\n};\n\nexport type PdfRiskInventory = {\n acroFormFieldCount: number;\n annotationCount: number;\n documentInfoEntryCount: number;\n embeddedFileCount: number;\n externalActionCount: number;\n formXObjectCount: number;\n imageObjectCount: number;\n incrementalRevisionCount: number;\n javascriptActionCount: number;\n metadataStreamCount: number;\n optionalContentGroupCount: number;\n signatureCount: number;\n trailingNonWhitespaceByteCount: number;\n unsupportedActionCount: number;\n xfaEntryCount: number;\n};\n\nexport type PdfInspectionGap =\n | \"encrypted-document\"\n | \"page-content-not-observed\"\n | \"page-not-rendered\"\n | \"partial-text-layer\"\n | \"retained-document-bytes\"\n | \"unobserved-visual-content\";\n\nexport type PdfPageInspection = {\n pageIndex: number;\n /** Effective visible width after page boxes, rotation, and UserUnit scaling. */\n widthPoints: number;\n /** Effective visible height after page boxes, rotation, and UserUnit scaling. */\n heightPoints: number;\n annotationCount: number;\n observation: PdfPageObservation | null;\n};\n\nexport type PdfInspection = {\n contractVersion: 1;\n pdfVersion: string;\n byteLength: number;\n objectCount: number;\n pageCount: number;\n encrypted: boolean;\n pages: readonly PdfPageInspection[];\n risks: PdfRiskInventory;\n coverage: {\n status: \"full\" | \"partial\";\n gaps: readonly PdfInspectionGap[];\n };\n};\n\nexport type PdfRasterProvider = {\n providerId: string;\n rendererName: string;\n rendererVersion: string;\n ocrName: string;\n ocrVersion: string;\n /** One explicit provider language pack; never an implicit mixed-language set. */\n ocrLanguage: string;\n};\n\nexport type PdfRasterPage = {\n observation: PdfPageObservation;\n widthPixels: number;\n heightPixels: number;\n /** Lowercase SHA-256 of this page's exact opaque, row-packed RGB8 bytes. */\n pixelSha256: string;\n /** Strictly ordered, non-overlapping UTF-16 spans. */\n detections: readonly PdfRasterDetection[];\n};\n\nexport type PdfRasterDetection = { start: number; end: number };\n\nexport type PdfRasterRewrite = {\n contractVersion: 1;\n /** Lowercase SHA-256 of the exact source PDF bytes supplied to the call. */\n sourceSha256: string;\n provider: PdfRasterProvider;\n fillRgb: readonly [number, number, number];\n pages: readonly PdfRasterPage[];\n};\n\nexport type PdfRasterRewriteCertificate = {\n contractVersion: 1;\n pageCount: number;\n sourceSha256: string;\n outputSha256: string;\n provider: PdfRasterProvider;\n detectionCount: number;\n mappedRegionCount: number;\n structurePixelRewriteVerified: true;\n providerAssertedCoverage: \"complete-rendering-and-ocr-observation\";\n piiCleanGuaranteed: false;\n limitation: string;\n};\n\nexport type PdfRasterRewriteResult = {\n document: Uint8Array;\n certificate: PdfRasterRewriteCertificate;\n};\n\nexport const PDF_INSPECTION_ERROR_CODES = {\n documentLimitExceeded: \"document-limit-exceeded\",\n invalidDocument: \"invalid-document\",\n invalidObservation: \"invalid-observation\",\n observationLimitExceeded: \"observation-limit-exceeded\",\n providerFailed: \"provider-failed\",\n} as const;\n\nexport type PdfInspectionErrorCode =\n (typeof PDF_INSPECTION_ERROR_CODES)[keyof typeof PDF_INSPECTION_ERROR_CODES];\n\nexport const PDF_RASTER_ERROR_CODES = {\n detectionFailed: \"detection-failed\",\n invalidContract: \"invalid-contract\",\n limitExceeded: \"limit-exceeded\",\n sourceRejected: \"source-rejected\",\n verificationFailed: \"verification-failed\",\n} as const;\n\nexport type PdfRasterErrorCode =\n (typeof PDF_RASTER_ERROR_CODES)[keyof typeof PDF_RASTER_ERROR_CODES];\n","import type {\n PdfGlyphObservation,\n PdfInspection,\n PdfInspectionGap,\n PdfPageInspection,\n PdfPageObservation,\n PdfRasterProvider,\n PdfRasterRewriteCertificate,\n PdfRect,\n PdfRiskInventory,\n} from \"./types\";\n\ntype RequiredFields<T> = { [Key in keyof T]-?: true };\n\nconst RECT_FIELDS = {\n left: true,\n bottom: true,\n right: true,\n top: true,\n} as const satisfies RequiredFields<PdfRect>;\n\nconst GLYPH_FIELDS = {\n start: true,\n end: true,\n bounds: true,\n source: true,\n} as const satisfies RequiredFields<PdfGlyphObservation>;\n\nconst OBSERVATION_FIELDS = {\n pageIndex: true,\n widthPoints: true,\n heightPoints: true,\n text: true,\n glyphs: true,\n rendered: true,\n textLayer: true,\n ocr: true,\n imageCount: true,\n} as const satisfies RequiredFields<PdfPageObservation>;\n\nconst PAGE_FIELDS = {\n pageIndex: true,\n widthPoints: true,\n heightPoints: true,\n annotationCount: true,\n observation: true,\n} as const satisfies RequiredFields<PdfPageInspection>;\n\nconst RISK_FIELDS = {\n acroFormFieldCount: true,\n annotationCount: true,\n documentInfoEntryCount: true,\n embeddedFileCount: true,\n externalActionCount: true,\n formXObjectCount: true,\n imageObjectCount: true,\n incrementalRevisionCount: true,\n javascriptActionCount: true,\n metadataStreamCount: true,\n optionalContentGroupCount: true,\n signatureCount: true,\n trailingNonWhitespaceByteCount: true,\n unsupportedActionCount: true,\n xfaEntryCount: true,\n} as const satisfies RequiredFields<PdfRiskInventory>;\n\nconst INSPECTION_FIELDS = {\n contractVersion: true,\n pdfVersion: true,\n byteLength: true,\n objectCount: true,\n pageCount: true,\n encrypted: true,\n pages: true,\n risks: true,\n coverage: true,\n} as const satisfies RequiredFields<PdfInspection>;\n\nconst PROVIDER_FIELDS = {\n providerId: true,\n rendererName: true,\n rendererVersion: true,\n ocrName: true,\n ocrVersion: true,\n ocrLanguage: true,\n} as const satisfies RequiredFields<PdfRasterProvider>;\n\nconst CERTIFICATE_FIELDS = {\n contractVersion: true,\n pageCount: true,\n sourceSha256: true,\n outputSha256: true,\n provider: true,\n detectionCount: true,\n mappedRegionCount: true,\n structurePixelRewriteVerified: true,\n providerAssertedCoverage: true,\n piiCleanGuaranteed: true,\n limitation: true,\n} as const satisfies RequiredFields<PdfRasterRewriteCertificate>;\n\nconst COVERAGE_FIELDS = {\n status: true,\n gaps: true,\n} as const satisfies RequiredFields<PdfInspection[\"coverage\"]>;\n\nconst INSPECTION_GAPS = {\n \"encrypted-document\": true,\n \"page-content-not-observed\": true,\n \"page-not-rendered\": true,\n \"partial-text-layer\": true,\n \"retained-document-bytes\": true,\n \"unobserved-visual-content\": true,\n} as const satisfies Record<PdfInspectionGap, true>;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst hasExactFields = (\n value: Record<string, unknown>,\n fields: Record<string, true>,\n): boolean => {\n const keys = Object.keys(value);\n return (\n keys.length === Object.keys(fields).length &&\n keys.every((key) => Object.hasOwn(fields, key))\n );\n};\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\n\nconst isNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n\nconst isRect = (value: unknown): value is PdfRect =>\n isRecord(value) &&\n hasExactFields(value, RECT_FIELDS) &&\n isFiniteNumber(value[\"left\"]) &&\n isFiniteNumber(value[\"bottom\"]) &&\n isFiniteNumber(value[\"right\"]) &&\n isFiniteNumber(value[\"top\"]);\n\nconst isGlyph = (value: unknown): value is PdfGlyphObservation =>\n isRecord(value) &&\n hasExactFields(value, GLYPH_FIELDS) &&\n isNonNegativeInteger(value[\"start\"]) &&\n isNonNegativeInteger(value[\"end\"]) &&\n value[\"end\"] >= value[\"start\"] &&\n isRect(value[\"bounds\"]) &&\n (value[\"source\"] === \"embedded-text\" || value[\"source\"] === \"ocr\");\n\nconst isObservation = (value: unknown): value is PdfPageObservation =>\n isRecord(value) &&\n hasExactFields(value, OBSERVATION_FIELDS) &&\n isNonNegativeInteger(value[\"pageIndex\"]) &&\n isFiniteNumber(value[\"widthPoints\"]) &&\n value[\"widthPoints\"] > 0 &&\n isFiniteNumber(value[\"heightPoints\"]) &&\n value[\"heightPoints\"] > 0 &&\n typeof value[\"text\"] === \"string\" &&\n Array.isArray(value[\"glyphs\"]) &&\n value[\"glyphs\"].every(isGlyph) &&\n typeof value[\"rendered\"] === \"boolean\" &&\n (value[\"textLayer\"] === \"absent\" ||\n value[\"textLayer\"] === \"partial\" ||\n value[\"textLayer\"] === \"complete\") &&\n (value[\"ocr\"] === \"not-run\" ||\n value[\"ocr\"] === \"partial\" ||\n value[\"ocr\"] === \"complete\") &&\n isNonNegativeInteger(value[\"imageCount\"]);\n\nconst isPage = (value: unknown): value is PdfPageInspection =>\n isRecord(value) &&\n hasExactFields(value, PAGE_FIELDS) &&\n isNonNegativeInteger(value[\"pageIndex\"]) &&\n isFiniteNumber(value[\"widthPoints\"]) &&\n value[\"widthPoints\"] > 0 &&\n isFiniteNumber(value[\"heightPoints\"]) &&\n value[\"heightPoints\"] > 0 &&\n isNonNegativeInteger(value[\"annotationCount\"]) &&\n (value[\"observation\"] === null || isObservation(value[\"observation\"]));\n\nconst isRiskInventory = (value: unknown): value is PdfRiskInventory =>\n isRecord(value) &&\n hasExactFields(value, RISK_FIELDS) &&\n Object.keys(RISK_FIELDS).every((field) => isNonNegativeInteger(value[field]));\n\nconst isInspectionGap = (value: unknown): value is PdfInspectionGap =>\n typeof value === \"string\" && Object.hasOwn(INSPECTION_GAPS, value);\n\nconst isInspection = (value: unknown): value is PdfInspection =>\n isRecord(value) &&\n hasExactFields(value, INSPECTION_FIELDS) &&\n value[\"contractVersion\"] === 1 &&\n typeof value[\"pdfVersion\"] === \"string\" &&\n isNonNegativeInteger(value[\"byteLength\"]) &&\n isNonNegativeInteger(value[\"objectCount\"]) &&\n isNonNegativeInteger(value[\"pageCount\"]) &&\n typeof value[\"encrypted\"] === \"boolean\" &&\n Array.isArray(value[\"pages\"]) &&\n value[\"pages\"].length === value[\"pageCount\"] &&\n value[\"pages\"].every(isPage) &&\n value[\"pages\"].every(({ pageIndex }, index) => pageIndex === index) &&\n isRiskInventory(value[\"risks\"]) &&\n isRecord(value[\"coverage\"]) &&\n hasExactFields(value[\"coverage\"], COVERAGE_FIELDS) &&\n (value[\"coverage\"][\"status\"] === \"full\" ||\n value[\"coverage\"][\"status\"] === \"partial\") &&\n Array.isArray(value[\"coverage\"][\"gaps\"]) &&\n value[\"coverage\"][\"gaps\"].every(isInspectionGap);\n\nconst isProvider = (value: unknown): value is PdfRasterProvider =>\n isRecord(value) &&\n hasExactFields(value, PROVIDER_FIELDS) &&\n typeof value[\"providerId\"] === \"string\" &&\n typeof value[\"rendererName\"] === \"string\" &&\n typeof value[\"rendererVersion\"] === \"string\" &&\n typeof value[\"ocrName\"] === \"string\" &&\n typeof value[\"ocrVersion\"] === \"string\" &&\n typeof value[\"ocrLanguage\"] === \"string\";\n\nconst isSha256 = (value: unknown): value is string =>\n typeof value === \"string\" && /^[a-f0-9]{64}$/u.test(value);\n\nconst isCertificate = (value: unknown): value is PdfRasterRewriteCertificate =>\n isRecord(value) &&\n hasExactFields(value, CERTIFICATE_FIELDS) &&\n value[\"contractVersion\"] === 1 &&\n isNonNegativeInteger(value[\"pageCount\"]) &&\n isSha256(value[\"sourceSha256\"]) &&\n isSha256(value[\"outputSha256\"]) &&\n isProvider(value[\"provider\"]) &&\n isNonNegativeInteger(value[\"detectionCount\"]) &&\n isNonNegativeInteger(value[\"mappedRegionCount\"]) &&\n value[\"structurePixelRewriteVerified\"] === true &&\n value[\"providerAssertedCoverage\"] ===\n \"complete-rendering-and-ocr-observation\" &&\n value[\"piiCleanGuaranteed\"] === false &&\n typeof value[\"limitation\"] === \"string\";\n\nexport const decodePdfInspection = (json: string): PdfInspection => {\n const value: unknown = JSON.parse(json);\n if (!isInspection(value)) {\n throw new Error(\"Native PDF inspection does not match contract version 1\");\n }\n return value;\n};\n\nexport const decodePdfRasterRewriteCertificate = (\n json: string,\n): PdfRasterRewriteCertificate => {\n const value: unknown = JSON.parse(json);\n if (!isCertificate(value)) {\n throw new Error(\n \"Native PDF raster certificate does not match contract version 1\",\n );\n }\n return value;\n};\n","import { execFile } from \"node:child_process\";\nimport {\n lstat,\n mkdtemp,\n readFile,\n rm,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, sep } from \"node:path\";\n\nimport { loadNativeAnonymizeBinding } from \"@stll/anonymize\";\n\nimport { decodePdfInspection } from \"./native-codec\";\nimport type {\n PdfGlyphObservation,\n PdfPageObservation,\n PdfRasterProvider,\n} from \"./types\";\n\nconst LOCAL_PROVIDER_ID = \"poppler-tesseract-local\";\nconst PROCESS_OUTPUT_MAX_BYTES = 64 * 1024 * 1024;\nconst PDF_DOCUMENT_MAX_BYTES = 64 * 1024 * 1024;\nconst PDF_RASTER_MAX_PAGE_BYTES = 128 * 1024 * 1024;\nconst PDF_RASTER_MAX_TOTAL_BYTES = 512 * 1024 * 1024;\nconst PDF_MAX_PAGES = 10_000;\nconst PDF_MAX_GLYPHS = 5_000_000;\nconst PDF_MAX_OBSERVED_TEXT_UTF8_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_DPI = 300;\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MIN_DPI = 72;\nconst MAX_DPI = 600;\nconst MIN_TIMEOUT_MS = 100;\nconst MAX_TIMEOUT_MS = 300_000;\nconst LANGUAGE_PACK_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/u;\nconst TEMP_PREFIX = \"stella-anonymize-pdf-\";\n\nexport const PDF_LOCAL_PROVIDER_ERROR_CODES = {\n cleanupFailed: \"cleanup-failed\",\n executableFailed: \"executable-failed\",\n invalidOptions: \"invalid-options\",\n invalidOutput: \"invalid-output\",\n limitExceeded: \"limit-exceeded\",\n sourceRejected: \"source-rejected\",\n} as const;\n\nexport type PdfLocalProviderErrorCode =\n (typeof PDF_LOCAL_PROVIDER_ERROR_CODES)[keyof typeof PDF_LOCAL_PROVIDER_ERROR_CODES];\n\nexport class PdfLocalProviderError extends Error {\n readonly code: PdfLocalProviderErrorCode;\n\n constructor(code: PdfLocalProviderErrorCode, message: string) {\n super(message);\n this.name = \"PdfLocalProviderError\";\n this.code = code;\n }\n}\n\nexport type RenderPdfWithPopplerTesseractOptions = {\n document: Uint8Array;\n /** One explicit installed Tesseract traineddata name, for example `eng`. */\n ocrLanguage: string;\n dpi?: number | undefined;\n pdftoppmPath?: string | undefined;\n tesseractPath?: string | undefined;\n timeoutMs?: number | undefined;\n};\n\nexport type LocalPdfRasterPage = {\n observation: PdfPageObservation;\n widthPixels: number;\n heightPixels: number;\n pixels: Uint8Array;\n};\n\nexport type LocalPdfRasterObservation = {\n provider: PdfRasterProvider;\n pages: readonly LocalPdfRasterPage[];\n};\n\ntype ResolvedLocalProviderOptions = {\n dpi: number;\n ocrLanguage: string;\n pdftoppmPath: string;\n tesseractPath: string;\n timeoutMs: number;\n};\n\ntype ProcessResult = { stdout: Buffer; stderr: Buffer };\n\nconst providerError = (\n code: PdfLocalProviderErrorCode,\n message: string,\n): PdfLocalProviderError =>\n new PdfLocalProviderError(code, `${code}: ${message}`);\n\nconst validateOptions = (\n options: RenderPdfWithPopplerTesseractOptions,\n): ResolvedLocalProviderOptions => {\n const dpi = options.dpi ?? DEFAULT_DPI;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const pdftoppmPath = options.pdftoppmPath ?? \"pdftoppm\";\n const tesseractPath = options.tesseractPath ?? \"tesseract\";\n if (\n !Number.isInteger(dpi) ||\n dpi < MIN_DPI ||\n dpi > MAX_DPI ||\n !Number.isInteger(timeoutMs) ||\n timeoutMs < MIN_TIMEOUT_MS ||\n timeoutMs > MAX_TIMEOUT_MS ||\n !LANGUAGE_PACK_PATTERN.test(options.ocrLanguage) ||\n !pdftoppmPath ||\n pdftoppmPath.includes(\"\\0\") ||\n !tesseractPath ||\n tesseractPath.includes(\"\\0\")\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOptions,\n \"local PDF provider options are invalid\",\n );\n }\n return {\n dpi,\n ocrLanguage: options.ocrLanguage,\n pdftoppmPath,\n tesseractPath,\n timeoutMs,\n };\n};\n\nconst runExecutable = (\n executable: string,\n args: readonly string[],\n timeoutMs: number,\n stage: \"OCR\" | \"renderer\" | \"version probe\",\n): Promise<ProcessResult> =>\n new Promise((resolve, reject) => {\n execFile(\n executable,\n args,\n {\n encoding: \"buffer\",\n maxBuffer: PROCESS_OUTPUT_MAX_BYTES,\n timeout: timeoutMs,\n windowsHide: true,\n },\n (error, stdout, stderr) => {\n if (error !== null) {\n reject(\n providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.executableFailed,\n `local PDF ${stage} failed`,\n ),\n );\n return;\n }\n resolve({ stdout: Buffer.from(stdout), stderr: Buffer.from(stderr) });\n },\n );\n });\n\nconst decodeUtf8 = (value: Uint8Array, context: string): string => {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(value);\n } catch {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n `local PDF ${context} is not valid UTF-8`,\n );\n }\n};\n\nconst versionFrom = (\n value: Uint8Array,\n prefix: string,\n context: string,\n): string => {\n const line = decodeUtf8(value, context).split(/\\r?\\n/u, 1)[0]?.trim();\n const version = line?.startsWith(prefix)\n ? line.slice(prefix.length).trim()\n : \"\";\n if (!version || version.length > 256 || /\\p{Cc}/u.test(version)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n `local PDF ${context} is invalid`,\n );\n }\n return version;\n};\n\ntype InspectedPageGeometry = {\n heightPoints: number;\n widthPoints: number;\n};\n\nconst inspectPageGeometry = (\n document: Uint8Array,\n): readonly InspectedPageGeometry[] => {\n if (document.byteLength > PDF_DOCUMENT_MAX_BYTES) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"PDF source exceeds its byte limit\",\n );\n }\n const inspect = loadNativeAnonymizeBinding().inspectPdfJson;\n if (inspect === undefined) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.sourceRejected,\n \"native PDF inspection is unavailable\",\n );\n }\n try {\n const inspection = decodePdfInspection(inspect(document));\n if (\n inspection.encrypted === true ||\n inspection.pageCount < 1 ||\n inspection.pageCount > PDF_MAX_PAGES\n ) {\n throw new Error(\"source rejected\");\n }\n return inspection.pages.map(({ heightPoints, widthPoints }) => ({\n heightPoints,\n widthPoints,\n }));\n } catch {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.sourceRejected,\n \"PDF source is unsupported by the local raster provider\",\n );\n }\n};\n\nconst assertProjectedRasterLimits = (\n pages: readonly InspectedPageGeometry[],\n dpi: number,\n): void => {\n let totalBytes = 0;\n for (const { heightPoints, widthPoints } of pages) {\n const widthPixels = Math.ceil((widthPoints * dpi) / 72);\n const heightPixels = Math.ceil((heightPoints * dpi) / 72);\n const pageBytes = widthPixels * heightPixels * 3;\n totalBytes += pageBytes;\n if (\n !Number.isSafeInteger(widthPixels) ||\n !Number.isSafeInteger(heightPixels) ||\n widthPixels <= 0 ||\n heightPixels <= 0 ||\n !Number.isSafeInteger(pageBytes) ||\n pageBytes > PDF_RASTER_MAX_PAGE_BYTES ||\n !Number.isSafeInteger(totalBytes) ||\n totalBytes > PDF_RASTER_MAX_TOTAL_BYTES\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"PDF page geometry exceeds the selected DPI raster limits\",\n );\n }\n }\n};\n\ntype PpmPage = {\n width: number;\n height: number;\n pixels: Uint8Array;\n};\n\nconst isWhitespace = (byte: number): boolean =>\n byte === 0x09 ||\n byte === 0x0a ||\n byte === 0x0b ||\n byte === 0x0c ||\n byte === 0x0d ||\n byte === 0x20;\n\nconst ppmToken = (bytes: Uint8Array, start: number): [string, number] => {\n let offset = start;\n while (offset < bytes.length) {\n if (isWhitespace(bytes[offset] ?? -1)) {\n offset += 1;\n continue;\n }\n if (bytes[offset] === 0x23) {\n while (offset < bytes.length && bytes[offset] !== 0x0a) offset += 1;\n continue;\n }\n break;\n }\n const tokenStart = offset;\n while (\n offset < bytes.length &&\n !isWhitespace(bytes[offset] ?? -1) &&\n bytes[offset] !== 0x23\n ) {\n offset += 1;\n }\n if (tokenStart === offset) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted an invalid PPM header\",\n );\n }\n const token = Buffer.from(bytes.subarray(tokenStart, offset)).toString(\n \"ascii\",\n );\n if (!/^[\\x21-\\x7e]+$/u.test(token)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted an invalid PPM header\",\n );\n }\n return [token, offset];\n};\n\nconst parsePositiveInteger = (value: string): number => {\n if (!/^[1-9][0-9]*$/u.test(value)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted invalid PPM dimensions\",\n );\n }\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler PPM dimensions exceed their limit\",\n );\n }\n return parsed;\n};\n\nconst parsePpm = (bytes: Uint8Array): PpmPage => {\n const [magic, afterMagic] = ppmToken(bytes, 0);\n const [widthValue, afterWidth] = ppmToken(bytes, afterMagic);\n const [heightValue, afterHeight] = ppmToken(bytes, afterWidth);\n const [maximumValue, afterMaximum] = ppmToken(bytes, afterHeight);\n if (magic !== \"P6\" || maximumValue !== \"255\") {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler must emit binary RGB8 PPM pages\",\n );\n }\n const width = parsePositiveInteger(widthValue);\n const height = parsePositiveInteger(heightValue);\n const expected = width * height * 3;\n if (!Number.isSafeInteger(expected) || expected > PDF_RASTER_MAX_PAGE_BYTES) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler page pixels exceed their byte limit\",\n );\n }\n let pixelOffset = afterMaximum;\n if (!isWhitespace(bytes[pixelOffset] ?? -1)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted an invalid PPM pixel separator\",\n );\n }\n const separator = bytes[pixelOffset];\n pixelOffset += 1;\n if (separator === 0x0d && bytes[pixelOffset] === 0x0a) pixelOffset += 1;\n if (bytes.length - pixelOffset !== expected) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler emitted a truncated or trailing PPM page\",\n );\n }\n return { width, height, pixels: bytes.subarray(pixelOffset) };\n};\n\nconst boundedRenderedPage = async (path: string): Promise<PpmPage> => {\n const metadata = await lstat(path);\n if (!metadata.isFile() || metadata.isSymbolicLink()) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Poppler page output must be a regular file\",\n );\n }\n if (metadata.size > PDF_RASTER_MAX_PAGE_BYTES + 1024 * 1024) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler page output exceeds its byte limit\",\n );\n }\n return parsePpm(await readFile(path));\n};\n\nconst integerTsvField = (value: string | undefined): number => {\n if (value === undefined || !/^(?:0|[1-9][0-9]*)$/u.test(value)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted invalid TSV geometry\",\n );\n }\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract TSV geometry exceeds its limit\",\n );\n }\n return parsed;\n};\n\nconst parseTesseractTsv = (\n bytes: Uint8Array,\n page: PpmPage,\n pageGeometry: InspectedPageGeometry,\n pageIndex: number,\n): PdfPageObservation => {\n const lines = decodeUtf8(bytes, \"Tesseract TSV\").split(/\\r?\\n/u);\n const header = lines.shift()?.split(\"\\t\");\n if (\n header?.slice(0, 12).join(\"\\t\") !==\n \"level\\tpage_num\\tblock_num\\tpar_num\\tline_num\\tword_num\\tleft\\ttop\\twidth\\theight\\tconf\\ttext\"\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted an unsupported TSV header\",\n );\n }\n const { heightPoints, widthPoints } = pageGeometry;\n const glyphs: PdfGlyphObservation[] = [];\n let text = \"\";\n let previousLine = \"\";\n for (const line of lines) {\n if (!line) continue;\n const fields = line.split(\"\\t\");\n if (fields[0] !== \"5\") continue;\n const word = fields.slice(11).join(\"\\t\").trim();\n if (!word) continue;\n if (/\\p{Cc}/u.test(word)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted control characters in OCR text\",\n );\n }\n const lineKey = `${fields[2] ?? \"\"}/${fields[3] ?? \"\"}/${fields[4] ?? \"\"}`;\n if (text) text += lineKey === previousLine ? \" \" : \"\\n\";\n previousLine = lineKey;\n const start = text.length;\n text += word;\n const end = text.length;\n const left = integerTsvField(fields[6]);\n const top = integerTsvField(fields[7]);\n const width = integerTsvField(fields[8]);\n const height = integerTsvField(fields[9]);\n const right = left + width;\n const bottom = top + height;\n if (\n width === 0 ||\n height === 0 ||\n !Number.isSafeInteger(right) ||\n !Number.isSafeInteger(bottom) ||\n right > page.width ||\n bottom > page.height\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.invalidOutput,\n \"Tesseract emitted out-of-page OCR geometry\",\n );\n }\n glyphs.push({\n start,\n end,\n bounds: {\n left: (left * widthPoints) / page.width,\n bottom: heightPoints - (bottom * heightPoints) / page.height,\n right: (right * widthPoints) / page.width,\n top: heightPoints - (top * heightPoints) / page.height,\n },\n source: \"ocr\",\n });\n if (glyphs.length > PDF_MAX_GLYPHS) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract OCR glyph count exceeds its limit\",\n );\n }\n if (Buffer.byteLength(text, \"utf8\") > PDF_MAX_OBSERVED_TEXT_UTF8_BYTES) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract OCR text exceeds its byte limit\",\n );\n }\n }\n return {\n pageIndex,\n widthPoints,\n heightPoints,\n text,\n glyphs,\n rendered: true,\n textLayer: \"absent\",\n ocr: \"complete\",\n imageCount: 0,\n };\n};\n\nconst safeCleanup = async (directory: string): Promise<void> => {\n const expectedPrefix = `${tmpdir()}${sep}${TEMP_PREFIX}`;\n if (!directory.startsWith(expectedPrefix)) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary directory could not be verified\",\n );\n }\n try {\n const metadata = await lstat(directory);\n if (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary directory could not be verified\",\n );\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n if (error instanceof PdfLocalProviderError) throw error;\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary directory could not be inspected\",\n );\n }\n try {\n await rm(directory, { force: true, recursive: true });\n } catch {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF temporary files could not be removed\",\n );\n }\n};\n\nexport const renderPdfWithPopplerTesseract = async (\n options: RenderPdfWithPopplerTesseractOptions,\n): Promise<LocalPdfRasterObservation> => {\n const resolved = validateOptions(options);\n const pageGeometry = inspectPageGeometry(options.document);\n assertProjectedRasterLimits(pageGeometry, resolved.dpi);\n const pageCount = pageGeometry.length;\n const popplerVersionResult = await runExecutable(\n resolved.pdftoppmPath,\n [\"-v\"],\n resolved.timeoutMs,\n \"version probe\",\n );\n const tesseractVersionResult = await runExecutable(\n resolved.tesseractPath,\n [\"--version\"],\n resolved.timeoutMs,\n \"version probe\",\n );\n const rendererVersion = versionFrom(\n popplerVersionResult.stderr.length > 0\n ? popplerVersionResult.stderr\n : popplerVersionResult.stdout,\n \"pdftoppm version \",\n \"Poppler version\",\n );\n const ocrVersion = versionFrom(\n tesseractVersionResult.stdout.length > 0\n ? tesseractVersionResult.stdout\n : tesseractVersionResult.stderr,\n \"tesseract \",\n \"Tesseract version\",\n );\n const directory = await mkdtemp(join(tmpdir(), TEMP_PREFIX));\n try {\n const sourcePath = join(directory, \"source.pdf\");\n const outputPrefix = join(directory, \"page\");\n await writeFile(sourcePath, options.document, { flag: \"wx\", mode: 0o600 });\n const pages: LocalPdfRasterPage[] = [];\n let totalPixels = 0;\n let totalGlyphs = 0;\n let totalObservedTextUtf8Bytes = 0;\n for (let pageNumber = 1; pageNumber <= pageCount; pageNumber += 1) {\n const inspectedGeometry = pageGeometry.at(pageNumber - 1);\n if (inspectedGeometry === undefined) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.sourceRejected,\n \"PDF page geometry became unavailable\",\n );\n }\n const pageOutputPrefix = `${outputPrefix}-${pageNumber}`;\n const pagePath = `${pageOutputPrefix}.ppm`;\n await runExecutable(\n resolved.pdftoppmPath,\n [\n \"-cropbox\",\n \"-f\",\n String(pageNumber),\n \"-l\",\n String(pageNumber),\n \"-singlefile\",\n \"-r\",\n String(resolved.dpi),\n sourcePath,\n pageOutputPrefix,\n ],\n resolved.timeoutMs,\n \"renderer\",\n );\n try {\n const page = await boundedRenderedPage(pagePath);\n totalPixels += page.pixels.byteLength;\n if (\n !Number.isSafeInteger(totalPixels) ||\n totalPixels > PDF_RASTER_MAX_TOTAL_BYTES\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Poppler page pixels exceed their aggregate limit\",\n );\n }\n const ocr = await runExecutable(\n resolved.tesseractPath,\n [pagePath, \"stdout\", \"-l\", resolved.ocrLanguage, \"tsv\"],\n resolved.timeoutMs,\n \"OCR\",\n );\n const observation = parseTesseractTsv(\n ocr.stdout,\n page,\n inspectedGeometry,\n pageNumber - 1,\n );\n totalGlyphs += observation.glyphs.length;\n totalObservedTextUtf8Bytes += Buffer.byteLength(\n observation.text,\n \"utf8\",\n );\n if (\n !Number.isSafeInteger(totalGlyphs) ||\n totalGlyphs > PDF_MAX_GLYPHS ||\n !Number.isSafeInteger(totalObservedTextUtf8Bytes) ||\n totalObservedTextUtf8Bytes > PDF_MAX_OBSERVED_TEXT_UTF8_BYTES\n ) {\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.limitExceeded,\n \"Tesseract OCR document output exceeds its aggregate limit\",\n );\n }\n pages.push({\n observation,\n widthPixels: page.width,\n heightPixels: page.height,\n pixels: page.pixels,\n });\n } finally {\n await unlink(pagePath).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return;\n throw providerError(\n PDF_LOCAL_PROVIDER_ERROR_CODES.cleanupFailed,\n \"local PDF page raster could not be removed\",\n );\n });\n }\n }\n return {\n provider: {\n providerId: LOCAL_PROVIDER_ID,\n rendererName: \"Poppler pdftoppm\",\n rendererVersion,\n ocrName: \"Tesseract OCR\",\n ocrVersion,\n ocrLanguage: resolved.ocrLanguage,\n },\n pages,\n };\n } finally {\n await safeCleanup(directory);\n }\n};\n","import { createHash } from \"node:crypto\";\n\nimport {\n convert_external_detection_batch,\n loadNativeAnonymizeBinding,\n type ExternalDetectionBatch,\n type PreparedNativePipeline,\n} from \"@stll/anonymize\";\n\nimport {\n PDF_INSPECTION_ERROR_CODES,\n PDF_RASTER_ERROR_CODES,\n type PdfInspection,\n type PdfInspectionErrorCode,\n type PdfPageObservation,\n type PdfRasterProvider,\n type PdfRasterErrorCode,\n type PdfRasterRewrite,\n type PdfRasterRewriteResult,\n} from \"./types\";\nimport {\n decodePdfInspection,\n decodePdfRasterRewriteCertificate,\n} from \"./native-codec\";\n\nexport const PDF_INSPECTION_CONTRACT_VERSION = 1 as const;\nexport const PDF_RASTER_CONTRACT_VERSION = 1 as const;\nexport const PDF_RASTER_MAX_PAGE_BYTES = 128 * 1024 * 1024;\nexport const PDF_RASTER_MAX_TOTAL_BYTES = 512 * 1024 * 1024;\nexport const PDF_RASTER_MAX_OUTPUT_BYTES = 512 * 1024 * 1024;\nexport const PDF_RASTER_REQUEST_JSON_MAX_BYTES = 64 * 1024 * 1024;\nexport const PDF_DOCUMENT_MAX_BYTES = 64 * 1024 * 1024;\nexport const PDF_STREAM_DECOMPRESSED_MAX_BYTES = 32 * 1024 * 1024;\nexport const PDF_LOADED_PAYLOAD_MAX_BYTES = 128 * 1024 * 1024;\nexport const PDF_MAX_OBJECTS = 200_000;\nexport const PDF_MAX_OBJECT_NODES = 1_000_000;\nexport const PDF_MAX_OBJECT_DEPTH = 128;\nexport const PDF_MAX_PAGES = 10_000;\nexport const PDF_MAX_GLYPHS = 5_000_000;\nexport const PDF_MAX_PAGE_TEXT_UTF8_BYTES = 16 * 1024 * 1024;\nexport const PDF_MAX_OBSERVED_TEXT_UTF8_BYTES = 64 * 1024 * 1024;\nexport const PDF_OBSERVATIONS_JSON_MAX_BYTES = 64 * 1024 * 1024;\n/** Renderer dimensions may differ by this many points due to numeric rounding. */\nexport const PDF_PAGE_DIMENSION_TOLERANCE_POINTS = 0.25;\n\nexport class PdfInspectionError extends Error {\n readonly code: PdfInspectionErrorCode;\n\n constructor(code: PdfInspectionErrorCode, message: string) {\n super(message);\n this.name = \"PdfInspectionError\";\n this.code = code;\n }\n}\n\nexport class PdfRasterError extends Error {\n readonly code: PdfRasterErrorCode;\n\n constructor(code: PdfRasterErrorCode, message: string) {\n super(message);\n this.name = \"PdfRasterError\";\n this.code = code;\n }\n}\n\nconst errorCode = (message: string): PdfInspectionErrorCode => {\n const code = Object.values(PDF_INSPECTION_ERROR_CODES).find((candidate) =>\n message.startsWith(`${candidate}:`),\n );\n return code ?? PDF_INSPECTION_ERROR_CODES.invalidDocument;\n};\n\nconst rasterErrorCode = (message: string): PdfRasterErrorCode => {\n const code = Object.values(PDF_RASTER_ERROR_CODES).find((candidate) =>\n message.startsWith(`${candidate}:`),\n );\n return code ?? PDF_RASTER_ERROR_CODES.verificationFailed;\n};\n\nexport type InspectPdfOptions = {\n pageObservations?: readonly PdfPageObservation[];\n};\n\nexport const inspectPdf = (\n document: Uint8Array,\n options: InspectPdfOptions = {},\n): PdfInspection => {\n const inspect = loadNativeAnonymizeBinding().inspectPdfJson;\n if (inspect === undefined) {\n throw new PdfInspectionError(\n PDF_INSPECTION_ERROR_CODES.invalidDocument,\n \"Native anonymize binding does not expose PDF inspection\",\n );\n }\n try {\n const observations = options.pageObservations;\n return decodePdfInspection(\n inspect(\n document,\n observations === undefined ? undefined : JSON.stringify(observations),\n ),\n );\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"PDF inspection failed\";\n throw new PdfInspectionError(errorCode(message), message);\n }\n};\n\nexport type RewritePdfRasterFromDetectionsOptions = {\n document: Uint8Array;\n request: PdfRasterRewrite;\n /** One opaque, row-packed RGB8 buffer per request page, in page order. */\n pagePixels: readonly Uint8Array[];\n};\n\n/**\n * Advanced rewrite-only surface. It verifies structure and destructive pixels but\n * does not run detection or certify that the result is PII-free.\n */\nexport const rewritePdfRasterFromDetections = ({\n document,\n request,\n pagePixels,\n}: RewritePdfRasterFromDetectionsOptions): PdfRasterRewriteResult => {\n const rewrite =\n loadNativeAnonymizeBinding().rewritePdfRasterFromDetectionsJson;\n if (rewrite === undefined) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.verificationFailed,\n \"Native anonymize binding does not expose PDF raster rewriting\",\n );\n }\n try {\n const result = rewrite(document, JSON.stringify(request), pagePixels);\n return {\n document: result.document,\n certificate: decodePdfRasterRewriteCertificate(result.certificateJson),\n };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"PDF raster rewrite failed\";\n throw new PdfRasterError(rasterErrorCode(message), message);\n }\n};\n\nexport type PdfRasterObservedPageInput = {\n observation: PdfPageObservation;\n widthPixels: number;\n heightPixels: number;\n pixels: Uint8Array;\n /** Optional digest-bound provider batch merged through stella caller semantics. */\n externalDetectionBatch?: ExternalDetectionBatch | string | undefined;\n};\n\nexport type AnonymizePdfRasterOptions = {\n document: Uint8Array;\n pipeline: Pick<\n PreparedNativePipeline,\n \"redactText\" | \"redactTextWithCallerDetections\"\n >;\n provider: PdfRasterProvider;\n pages: readonly PdfRasterObservedPageInput[];\n fillRgb?: readonly [number, number, number] | undefined;\n};\n\nconst sha256 = (value: Uint8Array): string =>\n createHash(\"sha256\").update(value).digest(\"hex\");\n\n/** Run stella detection, merge optional external detections, then rewrite pixels. */\nexport const anonymizePdfRaster = ({\n document,\n pipeline,\n provider,\n pages,\n fillRgb = [0, 0, 0],\n}: AnonymizePdfRasterOptions): PdfRasterRewriteResult => {\n if (document.byteLength > PDF_DOCUMENT_MAX_BYTES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF source exceeds its byte limit\",\n );\n }\n if (pages.length > PDF_MAX_PAGES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster page count exceeds its limit\",\n );\n }\n let totalPixelBytes = 0;\n let totalObservedTextBytes = 0;\n const textEncoder = new TextEncoder();\n for (const page of pages) {\n if (typeof page.observation?.text !== \"string\") {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.invalidContract,\n \"invalid-contract: PDF raster observed text is invalid\",\n );\n }\n const observedTextBytes = textEncoder.encode(\n page.observation.text,\n ).byteLength;\n if (observedTextBytes > PDF_MAX_PAGE_TEXT_UTF8_BYTES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster page text exceeds its byte limit\",\n );\n }\n totalObservedTextBytes += observedTextBytes;\n if (totalObservedTextBytes > PDF_MAX_OBSERVED_TEXT_UTF8_BYTES) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster observed text exceeds its aggregate byte limit\",\n );\n }\n const { heightPixels, widthPixels } = page;\n if (\n !Number.isSafeInteger(widthPixels) ||\n !Number.isSafeInteger(heightPixels) ||\n widthPixels <= 0 ||\n heightPixels <= 0\n ) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.invalidContract,\n \"invalid-contract: PDF raster pixel dimensions are invalid\",\n );\n }\n const expected = widthPixels * heightPixels * 3;\n if (\n !Number.isSafeInteger(expected) ||\n expected > PDF_RASTER_MAX_PAGE_BYTES ||\n page.pixels.byteLength !== expected\n ) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster page pixels exceed limits or have an invalid RGB8 length\",\n );\n }\n totalPixelBytes += expected;\n if (\n !Number.isSafeInteger(totalPixelBytes) ||\n totalPixelBytes > PDF_RASTER_MAX_TOTAL_BYTES\n ) {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.limitExceeded,\n \"limit-exceeded: PDF raster pixels exceed their aggregate limit\",\n );\n }\n }\n const binding = loadNativeAnonymizeBinding();\n let requestPages: PdfRasterRewrite[\"pages\"];\n try {\n requestPages = pages.map((page) => {\n const external =\n page.externalDetectionBatch === undefined\n ? undefined\n : convert_external_detection_batch(\n new TextEncoder().encode(page.observation.text),\n page.externalDetectionBatch,\n { binding },\n );\n const result =\n external === undefined\n ? pipeline.redactText(page.observation.text)\n : pipeline.redactTextWithCallerDetections(page.observation.text, {\n detections: external,\n });\n return {\n observation: page.observation,\n widthPixels: page.widthPixels,\n heightPixels: page.heightPixels,\n pixelSha256: sha256(page.pixels),\n detections: result.resolvedEntities.map(({ start, end }) => ({\n start,\n end,\n })),\n };\n });\n } catch {\n throw new PdfRasterError(\n PDF_RASTER_ERROR_CODES.detectionFailed,\n \"detection-failed: PDF raster detection failed\",\n );\n }\n return rewritePdfRasterFromDetections({\n document,\n request: {\n contractVersion: PDF_RASTER_CONTRACT_VERSION,\n sourceSha256: sha256(document),\n provider,\n fillRgb,\n pages: requestPages,\n },\n pagePixels: pages.map(({ pixels }) => pixels),\n });\n};\n\nexport { PDF_INSPECTION_ERROR_CODES } from \"./types\";\nexport { PDF_RASTER_ERROR_CODES } from \"./types\";\nexport {\n PDF_LOCAL_PROVIDER_ERROR_CODES,\n PdfLocalProviderError,\n renderPdfWithPopplerTesseract,\n} from \"./local-provider\";\nexport type {\n LocalPdfRasterObservation,\n LocalPdfRasterPage,\n PdfLocalProviderErrorCode,\n RenderPdfWithPopplerTesseractOptions,\n} from \"./local-provider\";\nexport type {\n PdfGlyphObservation,\n PdfInspection,\n PdfInspectionErrorCode,\n PdfInspectionGap,\n PdfPageInspection,\n PdfPageObservation,\n PdfRect,\n PdfRiskInventory,\n PdfRasterDetection,\n PdfRasterErrorCode,\n PdfRasterPage,\n PdfRasterProvider,\n PdfRasterRewrite,\n PdfRasterRewriteCertificate,\n PdfRasterRewriteResult,\n} from \"./types\";\n"],"mappings":";;;;;;;AAkIA,MAAa,6BAA6B;CACxC,uBAAuB;CACvB,iBAAiB;CACjB,oBAAoB;CACpB,0BAA0B;CAC1B,gBAAgB;AAClB;AAKA,MAAa,yBAAyB;CACpC,iBAAiB;CACjB,iBAAiB;CACjB,eAAe;CACf,gBAAgB;CAChB,oBAAoB;AACtB;;;ACrIA,MAAM,cAAc;CAClB,MAAM;CACN,QAAQ;CACR,OAAO;CACP,KAAK;AACP;AAEA,MAAM,eAAe;CACnB,OAAO;CACP,KAAK;CACL,QAAQ;CACR,QAAQ;AACV;AAEA,MAAM,qBAAqB;CACzB,WAAW;CACX,aAAa;CACb,cAAc;CACd,MAAM;CACN,QAAQ;CACR,UAAU;CACV,WAAW;CACX,KAAK;CACL,YAAY;AACd;AAEA,MAAM,cAAc;CAClB,WAAW;CACX,aAAa;CACb,cAAc;CACd,iBAAiB;CACjB,aAAa;AACf;AAEA,MAAM,cAAc;CAClB,oBAAoB;CACpB,iBAAiB;CACjB,wBAAwB;CACxB,mBAAmB;CACnB,qBAAqB;CACrB,kBAAkB;CAClB,kBAAkB;CAClB,0BAA0B;CAC1B,uBAAuB;CACvB,qBAAqB;CACrB,2BAA2B;CAC3B,gBAAgB;CAChB,gCAAgC;CAChC,wBAAwB;CACxB,eAAe;AACjB;AAEA,MAAM,oBAAoB;CACxB,iBAAiB;CACjB,YAAY;CACZ,YAAY;CACZ,aAAa;CACb,WAAW;CACX,WAAW;CACX,OAAO;CACP,OAAO;CACP,UAAU;AACZ;AAEA,MAAM,kBAAkB;CACtB,YAAY;CACZ,cAAc;CACd,iBAAiB;CACjB,SAAS;CACT,YAAY;CACZ,aAAa;AACf;AAEA,MAAM,qBAAqB;CACzB,iBAAiB;CACjB,WAAW;CACX,cAAc;CACd,cAAc;CACd,UAAU;CACV,gBAAgB;CAChB,mBAAmB;CACnB,+BAA+B;CAC/B,0BAA0B;CAC1B,oBAAoB;CACpB,YAAY;AACd;AAEA,MAAM,kBAAkB;CACtB,QAAQ;CACR,MAAM;AACR;AAEA,MAAM,kBAAkB;CACtB,sBAAsB;CACtB,6BAA6B;CAC7B,qBAAqB;CACrB,sBAAsB;CACtB,2BAA2B;CAC3B,6BAA6B;AAC/B;AAEA,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAM,kBACJ,OACA,WACY;CACZ,MAAM,OAAO,OAAO,KAAK,KAAK;CAC9B,OACE,KAAK,WAAW,OAAO,KAAK,MAAM,CAAC,CAAC,UACpC,KAAK,OAAO,QAAQ,OAAO,OAAO,QAAQ,GAAG,CAAC;AAElD;AAEA,MAAM,kBAAkB,UACtB,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAEpD,MAAM,wBAAwB,UAC5B,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS;AAEvE,MAAM,UAAU,UACd,SAAS,KAAK,KACd,eAAe,OAAO,WAAW,KACjC,eAAe,MAAM,OAAO,KAC5B,eAAe,MAAM,SAAS,KAC9B,eAAe,MAAM,QAAQ,KAC7B,eAAe,MAAM,MAAM;AAE7B,MAAM,WAAW,UACf,SAAS,KAAK,KACd,eAAe,OAAO,YAAY,KAClC,qBAAqB,MAAM,QAAQ,KACnC,qBAAqB,MAAM,MAAM,KACjC,MAAM,UAAU,MAAM,YACtB,OAAO,MAAM,SAAS,MACrB,MAAM,cAAc,mBAAmB,MAAM,cAAc;AAE9D,MAAM,iBAAiB,UACrB,SAAS,KAAK,KACd,eAAe,OAAO,kBAAkB,KACxC,qBAAqB,MAAM,YAAY,KACvC,eAAe,MAAM,cAAc,KACnC,MAAM,iBAAiB,KACvB,eAAe,MAAM,eAAe,KACpC,MAAM,kBAAkB,KACxB,OAAO,MAAM,YAAY,YACzB,MAAM,QAAQ,MAAM,SAAS,KAC7B,MAAM,SAAS,CAAC,MAAM,OAAO,KAC7B,OAAO,MAAM,gBAAgB,cAC5B,MAAM,iBAAiB,YACtB,MAAM,iBAAiB,aACvB,MAAM,iBAAiB,gBACxB,MAAM,WAAW,aAChB,MAAM,WAAW,aACjB,MAAM,WAAW,eACnB,qBAAqB,MAAM,aAAa;AAE1C,MAAM,UAAU,UACd,SAAS,KAAK,KACd,eAAe,OAAO,WAAW,KACjC,qBAAqB,MAAM,YAAY,KACvC,eAAe,MAAM,cAAc,KACnC,MAAM,iBAAiB,KACvB,eAAe,MAAM,eAAe,KACpC,MAAM,kBAAkB,KACxB,qBAAqB,MAAM,kBAAkB,MAC5C,MAAM,mBAAmB,QAAQ,cAAc,MAAM,cAAc;AAEtE,MAAM,mBAAmB,UACvB,SAAS,KAAK,KACd,eAAe,OAAO,WAAW,KACjC,OAAO,KAAK,WAAW,CAAC,CAAC,OAAO,UAAU,qBAAqB,MAAM,MAAM,CAAC;AAE9E,MAAM,mBAAmB,UACvB,OAAO,UAAU,YAAY,OAAO,OAAO,iBAAiB,KAAK;AAEnE,MAAM,gBAAgB,UACpB,SAAS,KAAK,KACd,eAAe,OAAO,iBAAiB,KACvC,MAAM,uBAAuB,KAC7B,OAAO,MAAM,kBAAkB,YAC/B,qBAAqB,MAAM,aAAa,KACxC,qBAAqB,MAAM,cAAc,KACzC,qBAAqB,MAAM,YAAY,KACvC,OAAO,MAAM,iBAAiB,aAC9B,MAAM,QAAQ,MAAM,QAAQ,KAC5B,MAAM,QAAQ,CAAC,WAAW,MAAM,gBAChC,MAAM,QAAQ,CAAC,MAAM,MAAM,KAC3B,MAAM,QAAQ,CAAC,OAAO,EAAE,aAAa,UAAU,cAAc,KAAK,KAClE,gBAAgB,MAAM,QAAQ,KAC9B,SAAS,MAAM,WAAW,KAC1B,eAAe,MAAM,aAAa,eAAe,MAChD,MAAM,WAAW,CAAC,cAAc,UAC/B,MAAM,WAAW,CAAC,cAAc,cAClC,MAAM,QAAQ,MAAM,WAAW,CAAC,OAAO,KACvC,MAAM,WAAW,CAAC,OAAO,CAAC,MAAM,eAAe;AAEjD,MAAM,cAAc,UAClB,SAAS,KAAK,KACd,eAAe,OAAO,eAAe,KACrC,OAAO,MAAM,kBAAkB,YAC/B,OAAO,MAAM,oBAAoB,YACjC,OAAO,MAAM,uBAAuB,YACpC,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,kBAAkB,YAC/B,OAAO,MAAM,mBAAmB;AAElC,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,kBAAkB,KAAK,KAAK;AAE3D,MAAM,iBAAiB,UACrB,SAAS,KAAK,KACd,eAAe,OAAO,kBAAkB,KACxC,MAAM,uBAAuB,KAC7B,qBAAqB,MAAM,YAAY,KACvC,SAAS,MAAM,eAAe,KAC9B,SAAS,MAAM,eAAe,KAC9B,WAAW,MAAM,WAAW,KAC5B,qBAAqB,MAAM,iBAAiB,KAC5C,qBAAqB,MAAM,oBAAoB,KAC/C,MAAM,qCAAqC,QAC3C,MAAM,gCACJ,4CACF,MAAM,0BAA0B,SAChC,OAAO,MAAM,kBAAkB;AAEjC,MAAa,uBAAuB,SAAgC;CAClE,MAAM,QAAiB,KAAK,MAAM,IAAI;CACtC,IAAI,CAAC,aAAa,KAAK,GACrB,MAAM,IAAI,MAAM,yDAAyD;CAE3E,OAAO;AACT;AAEA,MAAa,qCACX,SACgC;CAChC,MAAM,QAAiB,KAAK,MAAM,IAAI;CACtC,IAAI,CAAC,cAAc,KAAK,GACtB,MAAM,IAAI,MACR,iEACF;CAEF,OAAO;AACT;;;AC9OA,MAAM,oBAAoB;AAC1B,MAAM,2BAA2B;AACjC,MAAMA,2BAAyB;AAC/B,MAAMC,8BAA4B;AAClC,MAAMC,+BAA6B;AACnC,MAAMC,kBAAgB;AACtB,MAAMC,mBAAiB;AACvB,MAAMC,qCAAmC;AACzC,MAAM,cAAc;AACpB,MAAM,qBAAqB;AAC3B,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AACvB,MAAM,wBAAwB;AAC9B,MAAM,cAAc;AAEpB,MAAa,iCAAiC;CAC5C,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,eAAe;CACf,eAAe;CACf,gBAAgB;AAClB;AAKA,IAAa,wBAAb,cAA2C,MAAM;CAC/C;CAEA,YAAY,MAAiC,SAAiB;EAC5D,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;AACF;AAkCA,MAAM,iBACJ,MACA,YAEA,IAAI,sBAAsB,MAAM,GAAG,KAAK,IAAI,SAAS;AAEvD,MAAM,mBACJ,YACiC;CACjC,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,IACE,CAAC,OAAO,UAAU,GAAG,KACrB,MAAM,WACN,MAAM,WACN,CAAC,OAAO,UAAU,SAAS,KAC3B,YAAY,kBACZ,YAAY,kBACZ,CAAC,sBAAsB,KAAK,QAAQ,WAAW,KAC/C,CAAC,gBACD,aAAa,SAAS,IAAI,KAC1B,CAAC,iBACD,cAAc,SAAS,IAAI,GAE3B,MAAM,cACJ,+BAA+B,gBAC/B,wCACF;CAEF,OAAO;EACL;EACA,aAAa,QAAQ;EACrB;EACA;EACA;CACF;AACF;AAEA,MAAM,iBACJ,YACA,MACA,WACA,UAEA,IAAI,SAAS,SAAS,WAAW;CAC/B,SACE,YACA,MACA;EACE,UAAU;EACV,WAAW;EACX,SAAS;EACT,aAAa;CACf,IACC,OAAO,QAAQ,WAAW;EACzB,IAAI,UAAU,MAAM;GAClB,OACE,cACE,+BAA+B,kBAC/B,aAAa,MAAM,QACrB,CACF;GACA;EACF;EACA,QAAQ;GAAE,QAAQ,OAAO,KAAK,MAAM;GAAG,QAAQ,OAAO,KAAK,MAAM;EAAE,CAAC;CACtE,CACF;AACF,CAAC;AAEH,MAAM,cAAc,OAAmB,YAA4B;CACjE,IAAI;EACF,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,KAAK;CAC/D,QAAQ;EACN,MAAM,cACJ,+BAA+B,eAC/B,aAAa,QAAQ,oBACvB;CACF;AACF;AAEA,MAAM,eACJ,OACA,QACA,YACW;CACX,MAAM,OAAO,WAAW,OAAO,OAAO,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK;CACpE,MAAM,UAAU,MAAM,WAAW,MAAM,IACnC,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,KAAK,IAC/B;CACJ,IAAI,CAAC,WAAW,QAAQ,SAAS,OAAO,UAAU,KAAK,OAAO,GAC5D,MAAM,cACJ,+BAA+B,eAC/B,aAAa,QAAQ,YACvB;CAEF,OAAO;AACT;AAOA,MAAM,uBACJ,aACqC;CACrC,IAAI,SAAS,aAAaL,0BACxB,MAAM,cACJ,+BAA+B,eAC/B,mCACF;CAEF,MAAM,UAAU,2BAA2B,CAAC,CAAC;CAC7C,IAAI,YAAY,KAAA,GACd,MAAM,cACJ,+BAA+B,gBAC/B,sCACF;CAEF,IAAI;EACF,MAAM,aAAa,oBAAoB,QAAQ,QAAQ,CAAC;EACxD,IACE,WAAW,cAAc,QACzB,WAAW,YAAY,KACvB,WAAW,YAAYG,iBAEvB,MAAM,IAAI,MAAM,iBAAiB;EAEnC,OAAO,WAAW,MAAM,KAAK,EAAE,cAAc,mBAAmB;GAC9D;GACA;EACF,EAAE;CACJ,QAAQ;EACN,MAAM,cACJ,+BAA+B,gBAC/B,wDACF;CACF;AACF;AAEA,MAAM,+BACJ,OACA,QACS;CACT,IAAI,aAAa;CACjB,KAAK,MAAM,EAAE,cAAc,iBAAiB,OAAO;EACjD,MAAM,cAAc,KAAK,KAAM,cAAc,MAAO,EAAE;EACtD,MAAM,eAAe,KAAK,KAAM,eAAe,MAAO,EAAE;EACxD,MAAM,YAAY,cAAc,eAAe;EAC/C,cAAc;EACd,IACE,CAAC,OAAO,cAAc,WAAW,KACjC,CAAC,OAAO,cAAc,YAAY,KAClC,eAAe,KACf,gBAAgB,KAChB,CAAC,OAAO,cAAc,SAAS,KAC/B,YAAYF,+BACZ,CAAC,OAAO,cAAc,UAAU,KAChC,aAAaC,8BAEb,MAAM,cACJ,+BAA+B,eAC/B,0DACF;CAEJ;AACF;AAQA,MAAM,gBAAgB,SACpB,SAAS,KACT,SAAS,MACT,SAAS,MACT,SAAS,MACT,SAAS,MACT,SAAS;AAEX,MAAM,YAAY,OAAmB,UAAoC;CACvE,IAAI,SAAS;CACb,OAAO,SAAS,MAAM,QAAQ;EAC5B,IAAI,aAAa,MAAM,WAAW,EAAE,GAAG;GACrC,UAAU;GACV;EACF;EACA,IAAI,MAAM,YAAY,IAAM;GAC1B,OAAO,SAAS,MAAM,UAAU,MAAM,YAAY,IAAM,UAAU;GAClE;EACF;EACA;CACF;CACA,MAAM,aAAa;CACnB,OACE,SAAS,MAAM,UACf,CAAC,aAAa,MAAM,WAAW,EAAE,KACjC,MAAM,YAAY,IAElB,UAAU;CAEZ,IAAI,eAAe,QACjB,MAAM,cACJ,+BAA+B,eAC/B,uCACF;CAEF,MAAM,QAAQ,OAAO,KAAK,MAAM,SAAS,YAAY,MAAM,CAAC,CAAC,CAAC,SAC5D,OACF;CACA,IAAI,CAAC,kBAAkB,KAAK,KAAK,GAC/B,MAAM,cACJ,+BAA+B,eAC/B,uCACF;CAEF,OAAO,CAAC,OAAO,MAAM;AACvB;AAEA,MAAM,wBAAwB,UAA0B;CACtD,IAAI,CAAC,iBAAiB,KAAK,KAAK,GAC9B,MAAM,cACJ,+BAA+B,eAC/B,wCACF;CAEF,MAAM,SAAS,OAAO,KAAK;CAC3B,IAAI,CAAC,OAAO,cAAc,MAAM,GAC9B,MAAM,cACJ,+BAA+B,eAC/B,2CACF;CAEF,OAAO;AACT;AAEA,MAAM,YAAY,UAA+B;CAC/C,MAAM,CAAC,OAAO,cAAc,SAAS,OAAO,CAAC;CAC7C,MAAM,CAAC,YAAY,cAAc,SAAS,OAAO,UAAU;CAC3D,MAAM,CAAC,aAAa,eAAe,SAAS,OAAO,UAAU;CAC7D,MAAM,CAAC,cAAc,gBAAgB,SAAS,OAAO,WAAW;CAChE,IAAI,UAAU,QAAQ,iBAAiB,OACrC,MAAM,cACJ,+BAA+B,eAC/B,yCACF;CAEF,MAAM,QAAQ,qBAAqB,UAAU;CAC7C,MAAM,SAAS,qBAAqB,WAAW;CAC/C,MAAM,WAAW,QAAQ,SAAS;CAClC,IAAI,CAAC,OAAO,cAAc,QAAQ,KAAK,WAAWD,6BAChD,MAAM,cACJ,+BAA+B,eAC/B,6CACF;CAEF,IAAI,cAAc;CAClB,IAAI,CAAC,aAAa,MAAM,gBAAgB,EAAE,GACxC,MAAM,cACJ,+BAA+B,eAC/B,gDACF;CAEF,MAAM,YAAY,MAAM;CACxB,eAAe;CACf,IAAI,cAAc,MAAQ,MAAM,iBAAiB,IAAM,eAAe;CACtE,IAAI,MAAM,SAAS,gBAAgB,UACjC,MAAM,cACJ,+BAA+B,eAC/B,kDACF;CAEF,OAAO;EAAE;EAAO;EAAQ,QAAQ,MAAM,SAAS,WAAW;CAAE;AAC9D;AAEA,MAAM,sBAAsB,OAAO,SAAmC;CACpE,MAAM,WAAW,MAAM,MAAM,IAAI;CACjC,IAAI,CAAC,SAAS,OAAO,KAAK,SAAS,eAAe,GAChD,MAAM,cACJ,+BAA+B,eAC/B,4CACF;CAEF,IAAI,SAAS,OAAO,WAClB,MAAM,cACJ,+BAA+B,eAC/B,4CACF;CAEF,OAAO,SAAS,MAAM,SAAS,IAAI,CAAC;AACtC;AAEA,MAAM,mBAAmB,UAAsC;CAC7D,IAAI,UAAU,KAAA,KAAa,CAAC,uBAAuB,KAAK,KAAK,GAC3D,MAAM,cACJ,+BAA+B,eAC/B,wCACF;CAEF,MAAM,SAAS,OAAO,KAAK;CAC3B,IAAI,CAAC,OAAO,cAAc,MAAM,GAC9B,MAAM,cACJ,+BAA+B,eAC/B,0CACF;CAEF,OAAO;AACT;AAEA,MAAM,qBACJ,OACA,MACA,cACA,cACuB;CACvB,MAAM,QAAQ,WAAW,OAAO,eAAe,CAAC,CAAC,MAAM,QAAQ;CAE/D,KADe,MAAM,MAAM,CAAC,EAAE,MAAM,GAAI,EAAA,EAE9B,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,GAAI,MAC9B,sFAEA,MAAM,cACJ,+BAA+B,eAC/B,6CACF;CAEF,MAAM,EAAE,cAAc,gBAAgB;CACtC,MAAM,SAAgC,CAAC;CACvC,IAAI,OAAO;CACX,IAAI,eAAe;CACnB,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,CAAC,MAAM;EACX,MAAM,SAAS,KAAK,MAAM,GAAI;EAC9B,IAAI,OAAO,OAAO,KAAK;EACvB,MAAM,OAAO,OAAO,MAAM,EAAE,CAAC,CAAC,KAAK,GAAI,CAAC,CAAC,KAAK;EAC9C,IAAI,CAAC,MAAM;EACX,IAAI,UAAU,KAAK,IAAI,GACrB,MAAM,cACJ,+BAA+B,eAC/B,kDACF;EAEF,MAAM,UAAU,GAAG,OAAO,MAAM,GAAG,GAAG,OAAO,MAAM,GAAG,GAAG,OAAO,MAAM;EACtE,IAAI,MAAM,QAAQ,YAAY,eAAe,MAAM;EACnD,eAAe;EACf,MAAM,QAAQ,KAAK;EACnB,QAAQ;EACR,MAAM,MAAM,KAAK;EACjB,MAAM,OAAO,gBAAgB,OAAO,EAAE;EACtC,MAAM,MAAM,gBAAgB,OAAO,EAAE;EACrC,MAAM,QAAQ,gBAAgB,OAAO,EAAE;EACvC,MAAM,SAAS,gBAAgB,OAAO,EAAE;EACxC,MAAM,QAAQ,OAAO;EACrB,MAAM,SAAS,MAAM;EACrB,IACE,UAAU,KACV,WAAW,KACX,CAAC,OAAO,cAAc,KAAK,KAC3B,CAAC,OAAO,cAAc,MAAM,KAC5B,QAAQ,KAAK,SACb,SAAS,KAAK,QAEd,MAAM,cACJ,+BAA+B,eAC/B,4CACF;EAEF,OAAO,KAAK;GACV;GACA;GACA,QAAQ;IACN,MAAO,OAAO,cAAe,KAAK;IAClC,QAAQ,eAAgB,SAAS,eAAgB,KAAK;IACtD,OAAQ,QAAQ,cAAe,KAAK;IACpC,KAAK,eAAgB,MAAM,eAAgB,KAAK;GAClD;GACA,QAAQ;EACV,CAAC;EACD,IAAI,OAAO,SAASG,kBAClB,MAAM,cACJ,+BAA+B,eAC/B,6CACF;EAEF,IAAI,OAAO,WAAW,MAAM,MAAM,IAAIC,oCACpC,MAAM,cACJ,+BAA+B,eAC/B,2CACF;CAEJ;CACA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA,UAAU;EACV,WAAW;EACX,KAAK;EACL,YAAY;CACd;AACF;AAEA,MAAM,cAAc,OAAO,cAAqC;CAC9D,MAAM,iBAAiB,GAAG,OAAO,IAAI,MAAM;CAC3C,IAAI,CAAC,UAAU,WAAW,cAAc,GACtC,MAAM,cACJ,+BAA+B,eAC/B,qDACF;CAEF,IAAI;EACF,MAAM,WAAW,MAAM,MAAM,SAAS;EACtC,IAAI,CAAC,SAAS,YAAY,KAAK,SAAS,eAAe,GACrD,MAAM,cACJ,+BAA+B,eAC/B,qDACF;CAEJ,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU;EACxD,IAAI,iBAAiB,uBAAuB,MAAM;EAClD,MAAM,cACJ,+BAA+B,eAC/B,sDACF;CACF;CACA,IAAI;EACF,MAAM,GAAG,WAAW;GAAE,OAAO;GAAM,WAAW;EAAK,CAAC;CACtD,QAAQ;EACN,MAAM,cACJ,+BAA+B,eAC/B,gDACF;CACF;AACF;AAEA,MAAa,gCAAgC,OAC3C,YACuC;CACvC,MAAM,WAAW,gBAAgB,OAAO;CACxC,MAAM,eAAe,oBAAoB,QAAQ,QAAQ;CACzD,4BAA4B,cAAc,SAAS,GAAG;CACtD,MAAM,YAAY,aAAa;CAC/B,MAAM,uBAAuB,MAAM,cACjC,SAAS,cACT,CAAC,IAAI,GACL,SAAS,WACT,eACF;CACA,MAAM,yBAAyB,MAAM,cACnC,SAAS,eACT,CAAC,WAAW,GACZ,SAAS,WACT,eACF;CACA,MAAM,kBAAkB,YACtB,qBAAqB,OAAO,SAAS,IACjC,qBAAqB,SACrB,qBAAqB,QACzB,qBACA,iBACF;CACA,MAAM,aAAa,YACjB,uBAAuB,OAAO,SAAS,IACnC,uBAAuB,SACvB,uBAAuB,QAC3B,cACA,mBACF;CACA,MAAM,YAAY,MAAM,QAAQ,KAAK,OAAO,GAAG,WAAW,CAAC;CAC3D,IAAI;EACF,MAAM,aAAa,KAAK,WAAW,YAAY;EAC/C,MAAM,eAAe,KAAK,WAAW,MAAM;EAC3C,MAAM,UAAU,YAAY,QAAQ,UAAU;GAAE,MAAM;GAAM,MAAM;EAAM,CAAC;EACzE,MAAM,QAA8B,CAAC;EACrC,IAAI,cAAc;EAClB,IAAI,cAAc;EAClB,IAAI,6BAA6B;EACjC,KAAK,IAAI,aAAa,GAAG,cAAc,WAAW,cAAc,GAAG;GACjE,MAAM,oBAAoB,aAAa,GAAG,aAAa,CAAC;GACxD,IAAI,sBAAsB,KAAA,GACxB,MAAM,cACJ,+BAA+B,gBAC/B,sCACF;GAEF,MAAM,mBAAmB,GAAG,aAAa,GAAG;GAC5C,MAAM,WAAW,GAAG,iBAAiB;GACrC,MAAM,cACJ,SAAS,cACT;IACE;IACA;IACA,OAAO,UAAU;IACjB;IACA,OAAO,UAAU;IACjB;IACA;IACA,OAAO,SAAS,GAAG;IACnB;IACA;GACF,GACA,SAAS,WACT,UACF;GACA,IAAI;IACF,MAAM,OAAO,MAAM,oBAAoB,QAAQ;IAC/C,eAAe,KAAK,OAAO;IAC3B,IACE,CAAC,OAAO,cAAc,WAAW,KACjC,cAAcH,8BAEd,MAAM,cACJ,+BAA+B,eAC/B,kDACF;IAEF,MAAM,MAAM,MAAM,cAChB,SAAS,eACT;KAAC;KAAU;KAAU;KAAM,SAAS;KAAa;IAAK,GACtD,SAAS,WACT,KACF;IACA,MAAM,cAAc,kBAClB,IAAI,QACJ,MACA,mBACA,aAAa,CACf;IACA,eAAe,YAAY,OAAO;IAClC,8BAA8B,OAAO,WACnC,YAAY,MACZ,MACF;IACA,IACE,CAAC,OAAO,cAAc,WAAW,KACjC,cAAcE,oBACd,CAAC,OAAO,cAAc,0BAA0B,KAChD,6BAA6BC,oCAE7B,MAAM,cACJ,+BAA+B,eAC/B,2DACF;IAEF,MAAM,KAAK;KACT;KACA,aAAa,KAAK;KAClB,cAAc,KAAK;KACnB,QAAQ,KAAK;IACf,CAAC;GACH,UAAU;IACR,MAAM,OAAO,QAAQ,CAAC,CAAC,OAAO,UAAiC;KAC7D,IAAI,MAAM,SAAS,UAAU;KAC7B,MAAM,cACJ,+BAA+B,eAC/B,4CACF;IACF,CAAC;GACH;EACF;EACA,OAAO;GACL,UAAU;IACR,YAAY;IACZ,cAAc;IACd;IACA,SAAS;IACT;IACA,aAAa,SAAS;GACxB;GACA;EACF;CACF,UAAU;EACR,MAAM,YAAY,SAAS;CAC7B;AACF;;;ACxoBA,MAAa,kCAAkC;AAC/C,MAAa,8BAA8B;AAC3C,MAAa,4BAA4B;AACzC,MAAa,6BAA6B;AAC1C,MAAa,8BAA8B;AAC3C,MAAa,oCAAoC;AACjD,MAAa,yBAAyB;AACtC,MAAa,oCAAoC;AACjD,MAAa,+BAA+B;AAC5C,MAAa,kBAAkB;AAC/B,MAAa,uBAAuB;AACpC,MAAa,uBAAuB;AACpC,MAAa,gBAAgB;AAC7B,MAAa,iBAAiB;AAC9B,MAAa,+BAA+B;AAC5C,MAAa,mCAAmC;AAChD,MAAa,kCAAkC;;AAE/C,MAAa,sCAAsC;AAEnD,IAAa,qBAAb,cAAwC,MAAM;CAC5C;CAEA,YAAY,MAA8B,SAAiB;EACzD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;AACF;AAEA,IAAa,iBAAb,cAAoC,MAAM;CACxC;CAEA,YAAY,MAA0B,SAAiB;EACrD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;AACF;AAEA,MAAM,aAAa,YAA4C;CAI7D,OAHa,OAAO,OAAO,0BAA0B,CAAC,CAAC,MAAM,cAC3D,QAAQ,WAAW,GAAG,UAAU,EAAE,CAE1B,KAAK,2BAA2B;AAC5C;AAEA,MAAM,mBAAmB,YAAwC;CAI/D,OAHa,OAAO,OAAO,sBAAsB,CAAC,CAAC,MAAM,cACvD,QAAQ,WAAW,GAAG,UAAU,EAAE,CAE1B,KAAK,uBAAuB;AACxC;AAMA,MAAa,cACX,UACA,UAA6B,CAAC,MACZ;CAClB,MAAM,UAAU,2BAA2B,CAAC,CAAC;CAC7C,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,mBACR,2BAA2B,iBAC3B,yDACF;CAEF,IAAI;EACF,MAAM,eAAe,QAAQ;EAC7B,OAAO,oBACL,QACE,UACA,iBAAiB,KAAA,IAAY,KAAA,IAAY,KAAK,UAAU,YAAY,CACtE,CACF;CACF,SAAS,OAAO;EACd,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;EAC3C,MAAM,IAAI,mBAAmB,UAAU,OAAO,GAAG,OAAO;CAC1D;AACF;;;;;AAaA,MAAa,kCAAkC,EAC7C,UACA,SACA,iBACmE;CACnE,MAAM,UACJ,2BAA2B,CAAC,CAAC;CAC/B,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,eACR,uBAAuB,oBACvB,+DACF;CAEF,IAAI;EACF,MAAM,SAAS,QAAQ,UAAU,KAAK,UAAU,OAAO,GAAG,UAAU;EACpE,OAAO;GACL,UAAU,OAAO;GACjB,aAAa,kCAAkC,OAAO,eAAe;EACvE;CACF,SAAS,OAAO;EACd,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;EAC3C,MAAM,IAAI,eAAe,gBAAgB,OAAO,GAAG,OAAO;CAC5D;AACF;AAsBA,MAAM,UAAU,UACd,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;;AAGjD,MAAa,sBAAsB,EACjC,UACA,UACA,UACA,OACA,UAAU;CAAC;CAAG;CAAG;AAAC,QACqC;CACvD,IAAI,SAAS,aAAA,UACX,MAAM,IAAI,eACR,uBAAuB,eACvB,mDACF;CAEF,IAAI,MAAM,SAAA,KACR,MAAM,IAAI,eACR,uBAAuB,eACvB,yDACF;CAEF,IAAI,kBAAkB;CACtB,IAAI,yBAAyB;CAC7B,MAAM,cAAc,IAAI,YAAY;CACpC,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,OAAO,KAAK,aAAa,SAAS,UACpC,MAAM,IAAI,eACR,uBAAuB,iBACvB,uDACF;EAEF,MAAM,oBAAoB,YAAY,OACpC,KAAK,YAAY,IACnB,CAAC,CAAC;EACF,IAAI,oBAAA,UACF,MAAM,IAAI,eACR,uBAAuB,eACvB,6DACF;EAEF,0BAA0B;EAC1B,IAAI,yBAAA,UACF,MAAM,IAAI,eACR,uBAAuB,eACvB,2EACF;EAEF,MAAM,EAAE,cAAc,gBAAgB;EACtC,IACE,CAAC,OAAO,cAAc,WAAW,KACjC,CAAC,OAAO,cAAc,YAAY,KAClC,eAAe,KACf,gBAAgB,GAEhB,MAAM,IAAI,eACR,uBAAuB,iBACvB,2DACF;EAEF,MAAM,WAAW,cAAc,eAAe;EAC9C,IACE,CAAC,OAAO,cAAc,QAAQ,KAC9B,WAAA,aACA,KAAK,OAAO,eAAe,UAE3B,MAAM,IAAI,eACR,uBAAuB,eACvB,qFACF;EAEF,mBAAmB;EACnB,IACE,CAAC,OAAO,cAAc,eAAe,KACrC,kBAAA,WAEA,MAAM,IAAI,eACR,uBAAuB,eACvB,gEACF;CAEJ;CACA,MAAM,UAAU,2BAA2B;CAC3C,IAAI;CACJ,IAAI;EACF,eAAe,MAAM,KAAK,SAAS;GACjC,MAAM,WACJ,KAAK,2BAA2B,KAAA,IAC5B,KAAA,IACA,iCACE,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,YAAY,IAAI,GAC9C,KAAK,wBACL,EAAE,QAAQ,CACZ;GACN,MAAM,SACJ,aAAa,KAAA,IACT,SAAS,WAAW,KAAK,YAAY,IAAI,IACzC,SAAS,+BAA+B,KAAK,YAAY,MAAM,EAC7D,YAAY,SACd,CAAC;GACP,OAAO;IACL,aAAa,KAAK;IAClB,aAAa,KAAK;IAClB,cAAc,KAAK;IACnB,aAAa,OAAO,KAAK,MAAM;IAC/B,YAAY,OAAO,iBAAiB,KAAK,EAAE,OAAO,WAAW;KAC3D;KACA;IACF,EAAE;GACJ;EACF,CAAC;CACH,QAAQ;EACN,MAAM,IAAI,eACR,uBAAuB,iBACvB,+CACF;CACF;CACA,OAAO,+BAA+B;EACpC;EACA,SAAS;GACP,iBAAA;GACA,cAAc,OAAO,QAAQ;GAC7B;GACA;GACA,OAAO;EACT;EACA,YAAY,MAAM,KAAK,EAAE,aAAa,MAAM;CAC9C,CAAC;AACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/anonymize-pdf",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.1",
|
|
4
4
|
"description": "Fail-closed PDF coverage and risk inspection contracts for stella anonymization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"format": "oxfmt ."
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@stll/anonymize": "2.9.
|
|
35
|
+
"@stll/anonymize": "2.9.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^26.2.0",
|