@embedpdf/engines 1.0.19 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{engine-DMU8HkGx.js → engine-D0zKoYug.js} +345 -10
  2. package/dist/engine-D0zKoYug.js.map +1 -0
  3. package/dist/engine-Dcn6oo4j.cjs +2 -0
  4. package/dist/engine-Dcn6oo4j.cjs.map +1 -0
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.js +14 -7
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/pdfium/engine.d.ts +51 -12
  10. package/dist/lib/pdfium/index.cjs +1 -1
  11. package/dist/lib/pdfium/index.js +2 -2
  12. package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
  13. package/dist/lib/pdfium/web/direct-engine.js +1 -1
  14. package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
  15. package/dist/lib/pdfium/web/worker-engine.js +1 -1
  16. package/dist/lib/webworker/engine.cjs +1 -1
  17. package/dist/lib/webworker/engine.cjs.map +1 -1
  18. package/dist/lib/webworker/engine.d.ts +13 -1
  19. package/dist/lib/webworker/engine.js +29 -0
  20. package/dist/lib/webworker/engine.js.map +1 -1
  21. package/dist/preact/index.cjs +1 -1
  22. package/dist/preact/index.js +1 -1
  23. package/dist/react/index.cjs +1 -1
  24. package/dist/react/index.js +1 -1
  25. package/dist/{runner-TzQFlVIQ.js → runner-CGyvdr9V.js} +8 -2
  26. package/dist/runner-CGyvdr9V.js.map +1 -0
  27. package/dist/runner-CHOggH0O.cjs +2 -0
  28. package/dist/runner-CHOggH0O.cjs.map +1 -0
  29. package/dist/vue/index.cjs +1 -1
  30. package/dist/vue/index.js +1 -1
  31. package/package.json +3 -3
  32. package/dist/engine-CkrTs7st.cjs +0 -2
  33. package/dist/engine-CkrTs7st.cjs.map +0 -1
  34. package/dist/engine-DMU8HkGx.js.map +0 -1
  35. package/dist/runner-BPhmukiN.cjs +0 -2
  36. package/dist/runner-BPhmukiN.cjs.map +0 -1
  37. package/dist/runner-TzQFlVIQ.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { NoopLogger, PdfTaskHelper, PdfErrorCode, Task, ignore, isUuidV4, uuidV4, PdfAnnotationSubtype, Rotation, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationIcon, PdfAnnotationBorderStyle, PdfAnnotationColorType, PdfAnnotationLineEnding, pdfColorToWebColor, webColorToPdfColor, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, pdfDateToDate, dateToPdfDate, quadToRect, rectToQuad, PdfStandardFont, PdfPageObjectType, flagsToNames, namesToFlags, PDF_FORM_FIELD_TYPE, AppearanceMode, toIntRect, transformRect, makeMatrix, toIntSize, transformSize, PdfActionType, PdfZoomMode, MatchFlag } from "@embedpdf/models";
1
+ import { NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, Task, ignore, isUuidV4, uuidV4, PdfAnnotationSubtype, Rotation, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationIcon, PdfAnnotationBorderStyle, PdfAnnotationColorType, PdfAnnotationLineEnding, pdfColorToWebColor, webColorToPdfColor, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, dateToPdfDate, quadToRect, rectToQuad, PdfStandardFont, PdfPageObjectType, flagsToNames, namesToFlags, PDF_FORM_FIELD_TYPE, AppearanceMode, toIntRect, transformRect, makeMatrix, toIntSize, transformSize, PdfActionType, PdfZoomMode, MatchFlag } from "@embedpdf/models";
2
2
  function readString(wasmModule, readChars, parseChars, defaultLength = 100) {
3
3
  let buffer = wasmModule.wasmExports.malloc(defaultLength);
4
4
  for (let i = 0; i < defaultLength; i++) {
@@ -367,6 +367,7 @@ class PdfiumEngine {
367
367
  const arrayBuf = await response.arrayBuffer();
368
368
  const pdfFile = {
369
369
  id: file.id,
370
+ name: file.name,
370
371
  content: arrayBuf
371
372
  };
372
373
  return this.openDocumentBuffer(pdfFile, { password });
@@ -483,6 +484,7 @@ class PdfiumEngine {
483
484
  this.free(sizePtr);
484
485
  const pdfDoc = {
485
486
  id: file.id,
487
+ name: file.name,
486
488
  pageCount,
487
489
  pages
488
490
  };
@@ -564,6 +566,7 @@ class PdfiumEngine {
564
566
  this.free(sizePtr);
565
567
  const pdfDoc = {
566
568
  id: file.id,
569
+ name: file.name,
567
570
  pageCount,
568
571
  pages
569
572
  };
@@ -587,6 +590,8 @@ class PdfiumEngine {
587
590
  message: "document does not open"
588
591
  });
589
592
  }
593
+ const creationRaw = this.readMetaText(ctx.docPtr, "CreationDate");
594
+ const modRaw = this.readMetaText(ctx.docPtr, "ModDate");
590
595
  const metadata = {
591
596
  title: this.readMetaText(ctx.docPtr, "Title"),
592
597
  author: this.readMetaText(ctx.docPtr, "Author"),
@@ -594,12 +599,62 @@ class PdfiumEngine {
594
599
  keywords: this.readMetaText(ctx.docPtr, "Keywords"),
595
600
  producer: this.readMetaText(ctx.docPtr, "Producer"),
596
601
  creator: this.readMetaText(ctx.docPtr, "Creator"),
597
- creationDate: this.readMetaText(ctx.docPtr, "CreationDate"),
598
- modificationDate: this.readMetaText(ctx.docPtr, "ModDate")
602
+ creationDate: creationRaw ? pdfDateToDate(creationRaw) ?? null : null,
603
+ modificationDate: modRaw ? pdfDateToDate(modRaw) ?? null : null
599
604
  };
600
605
  this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `GetMetadata`, "End", doc.id);
601
606
  return PdfTaskHelper.resolve(metadata);
602
607
  }
608
+ /**
609
+ * {@inheritDoc @embedpdf/models!PdfEngine.setMetadata}
610
+ *
611
+ * @public
612
+ */
613
+ setMetadata(doc, meta) {
614
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "setMetadata", doc, meta);
615
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SetMetadata", "Begin", doc.id);
616
+ const ctx = this.cache.getContext(doc.id);
617
+ if (!ctx) {
618
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SetMetadata", "End", doc.id);
619
+ return PdfTaskHelper.reject({
620
+ code: PdfErrorCode.DocNotOpen,
621
+ message: "document does not open"
622
+ });
623
+ }
624
+ const strMap = [
625
+ ["title", "Title"],
626
+ ["author", "Author"],
627
+ ["subject", "Subject"],
628
+ ["keywords", "Keywords"],
629
+ ["producer", "Producer"],
630
+ ["creator", "Creator"]
631
+ ];
632
+ let ok = true;
633
+ for (const [field, key] of strMap) {
634
+ const v = meta[field];
635
+ if (v === void 0) continue;
636
+ const s = v === null ? null : v;
637
+ if (!this.setMetaText(ctx.docPtr, key, s)) ok = false;
638
+ }
639
+ const writeDate = (field, key) => {
640
+ const v = meta[field];
641
+ if (v === void 0) return;
642
+ if (v === null) {
643
+ if (!this.setMetaText(ctx.docPtr, key, null)) ok = false;
644
+ return;
645
+ }
646
+ const d = v;
647
+ const raw = dateToPdfDate(d);
648
+ if (!this.setMetaText(ctx.docPtr, key, raw)) ok = false;
649
+ };
650
+ writeDate("creationDate", "CreationDate");
651
+ writeDate("modificationDate", "ModDate");
652
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SetMetadata", "End", doc.id);
653
+ return ok ? PdfTaskHelper.resolve(true) : PdfTaskHelper.reject({
654
+ code: PdfErrorCode.Unknown,
655
+ message: "one or more metadata fields could not be written"
656
+ });
657
+ }
603
658
  /**
604
659
  * {@inheritDoc @embedpdf/models!PdfEngine.getDocPermissions}
605
660
  *
@@ -1336,7 +1391,7 @@ class PdfiumEngine {
1336
1391
  });
1337
1392
  }
1338
1393
  const attachmentPtr = this.pdfiumModule.FPDFDoc_GetAttachment(ctx.docPtr, attachment.index);
1339
- const sizePtr = this.malloc(8);
1394
+ const sizePtr = this.malloc(4);
1340
1395
  if (!this.pdfiumModule.FPDFAttachment_GetFile(attachmentPtr, 0, 0, sizePtr)) {
1341
1396
  this.free(sizePtr);
1342
1397
  this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `ReadAttachmentContent`, "End", doc.id);
@@ -1345,7 +1400,7 @@ class PdfiumEngine {
1345
1400
  message: "can not read attachment size"
1346
1401
  });
1347
1402
  }
1348
- const size = this.pdfiumModule.pdfium.getValue(sizePtr, "i64");
1403
+ const size = this.pdfiumModule.pdfium.getValue(sizePtr, "i32") >>> 0;
1349
1404
  const contentPtr = this.malloc(size);
1350
1405
  if (!this.pdfiumModule.FPDFAttachment_GetFile(attachmentPtr, contentPtr, size, sizePtr)) {
1351
1406
  this.free(sizePtr);
@@ -1960,6 +2015,9 @@ class PdfiumEngine {
1960
2015
  if (annotation.created && !this.setAnnotationDate(annotationPtr, "CreationDate", annotation.created)) {
1961
2016
  return false;
1962
2017
  }
2018
+ if (annotation.flags && !this.setAnnotationFlags(annotationPtr, annotation.flags)) {
2019
+ return false;
2020
+ }
1963
2021
  if (annotation.modified && !this.setAnnotationDate(annotationPtr, "M", annotation.modified)) {
1964
2022
  return false;
1965
2023
  }
@@ -2022,6 +2080,9 @@ class PdfiumEngine {
2022
2080
  if (annotation.created && !this.setAnnotationDate(annotationPtr, "CreationDate", annotation.created)) {
2023
2081
  return false;
2024
2082
  }
2083
+ if (annotation.flags && !this.setAnnotationFlags(annotationPtr, annotation.flags)) {
2084
+ return false;
2085
+ }
2025
2086
  if (annotation.modified && !this.setAnnotationDate(annotationPtr, "M", annotation.modified)) {
2026
2087
  return false;
2027
2088
  }
@@ -2067,6 +2128,9 @@ class PdfiumEngine {
2067
2128
  if (annotation.created && !this.setAnnotationDate(annotationPtr, "CreationDate", annotation.created)) {
2068
2129
  return false;
2069
2130
  }
2131
+ if (annotation.flags && !this.setAnnotationFlags(annotationPtr, annotation.flags)) {
2132
+ return false;
2133
+ }
2070
2134
  if (annotation.modified && !this.setAnnotationDate(annotationPtr, "M", annotation.modified)) {
2071
2135
  return false;
2072
2136
  }
@@ -2144,6 +2208,9 @@ class PdfiumEngine {
2144
2208
  if (annotation.modified && !this.setAnnotationDate(annotationPtr, "M", annotation.modified)) {
2145
2209
  return false;
2146
2210
  }
2211
+ if (annotation.flags && !this.setAnnotationFlags(annotationPtr, annotation.flags)) {
2212
+ return false;
2213
+ }
2147
2214
  if (!this.setPageAnnoRect(page, pagePtr, annotationPtr, annotation.rect)) {
2148
2215
  return false;
2149
2216
  }
@@ -2266,6 +2333,9 @@ class PdfiumEngine {
2266
2333
  if (annotation.created && !this.setAnnotationDate(annotationPtr, "CreationDate", annotation.created)) {
2267
2334
  return false;
2268
2335
  }
2336
+ if (annotation.flags && !this.setAnnotationFlags(annotationPtr, annotation.flags)) {
2337
+ return false;
2338
+ }
2269
2339
  if (annotation.modified && !this.setAnnotationDate(annotationPtr, "M", annotation.modified)) {
2270
2340
  return false;
2271
2341
  }
@@ -2309,6 +2379,9 @@ class PdfiumEngine {
2309
2379
  if (annotation.created && !this.setAnnotationDate(annotationPtr, "CreationDate", annotation.created)) {
2310
2380
  return false;
2311
2381
  }
2382
+ if (annotation.flags && !this.setAnnotationFlags(annotationPtr, annotation.flags)) {
2383
+ return false;
2384
+ }
2312
2385
  if (annotation.modified && !this.setAnnotationDate(annotationPtr, "M", annotation.modified)) {
2313
2386
  return false;
2314
2387
  }
@@ -2445,14 +2518,42 @@ class PdfiumEngine {
2445
2518
  * @private
2446
2519
  */
2447
2520
  readMetaText(docPtr, key) {
2521
+ const exists = !!this.pdfiumModule.EPDF_HasMetaText(docPtr, key);
2522
+ if (!exists) return null;
2523
+ const len = this.pdfiumModule.FPDF_GetMetaText(docPtr, key, 0, 0);
2524
+ if (len === 2) return "";
2448
2525
  return readString(
2449
2526
  this.pdfiumModule.pdfium,
2450
- (buffer, bufferLength) => {
2451
- return this.pdfiumModule.FPDF_GetMetaText(docPtr, key, buffer, bufferLength);
2452
- },
2453
- this.pdfiumModule.pdfium.UTF16ToString
2527
+ (buffer, bufferLength) => this.pdfiumModule.FPDF_GetMetaText(docPtr, key, buffer, bufferLength),
2528
+ this.pdfiumModule.pdfium.UTF16ToString,
2529
+ len
2454
2530
  );
2455
2531
  }
2532
+ /**
2533
+ * Write metadata into the PDF's Info dictionary.
2534
+ * If `value` is null or empty string, the key is removed.
2535
+ * @param docPtr - pointer to pdf document
2536
+ * @param key - key of metadata field
2537
+ * @param value - value of metadata field
2538
+ * @returns whether metadata is written to the pdf document
2539
+ *
2540
+ * @private
2541
+ */
2542
+ setMetaText(docPtr, key, value) {
2543
+ if (value == null || value.length === 0) {
2544
+ const ok = this.pdfiumModule.EPDF_SetMetaText(docPtr, key, 0);
2545
+ return !!ok;
2546
+ }
2547
+ const bytes = 2 * (value.length + 1);
2548
+ const ptr = this.malloc(bytes);
2549
+ try {
2550
+ this.pdfiumModule.pdfium.stringToUTF16(value, ptr, bytes);
2551
+ const ok = this.pdfiumModule.EPDF_SetMetaText(docPtr, key, ptr);
2552
+ return !!ok;
2553
+ } finally {
2554
+ this.free(ptr);
2555
+ }
2556
+ }
2456
2557
  /**
2457
2558
  * Read bookmarks in the pdf document
2458
2559
  * @param docPtr - pointer to pdf document
@@ -5915,6 +6016,240 @@ class PdfiumEngine {
5915
6016
  return pageResults;
5916
6017
  });
5917
6018
  }
6019
+ /**
6020
+ * {@inheritDoc @embedpdf/models!PdfEngine.preparePrintDocument}
6021
+ *
6022
+ * Prepares a PDF document for printing with specified options.
6023
+ * Creates a new document with selected pages and optionally removes annotations
6024
+ * for optimal printing performance.
6025
+ *
6026
+ * @public
6027
+ */
6028
+ preparePrintDocument(doc, options) {
6029
+ const { includeAnnotations = true, pageRange = null } = options ?? {};
6030
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "preparePrintDocument", doc, options);
6031
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "Begin", doc.id);
6032
+ const ctx = this.cache.getContext(doc.id);
6033
+ if (!ctx) {
6034
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "End", doc.id);
6035
+ return PdfTaskHelper.reject({
6036
+ code: PdfErrorCode.DocNotOpen,
6037
+ message: "Document is not open"
6038
+ });
6039
+ }
6040
+ const printDocPtr = this.pdfiumModule.FPDF_CreateNewDocument();
6041
+ if (!printDocPtr) {
6042
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "End", doc.id);
6043
+ return PdfTaskHelper.reject({
6044
+ code: PdfErrorCode.CantCreateNewDoc,
6045
+ message: "Cannot create print document"
6046
+ });
6047
+ }
6048
+ try {
6049
+ const sanitizedPageRange = this.sanitizePageRange(pageRange, doc.pageCount);
6050
+ if (!this.pdfiumModule.FPDF_ImportPages(
6051
+ printDocPtr,
6052
+ ctx.docPtr,
6053
+ sanitizedPageRange ?? "",
6054
+ 0
6055
+ // Insert at beginning
6056
+ )) {
6057
+ this.pdfiumModule.FPDF_CloseDocument(printDocPtr);
6058
+ this.logger.error(LOG_SOURCE, LOG_CATEGORY, "Failed to import pages for printing");
6059
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "End", doc.id);
6060
+ return PdfTaskHelper.reject({
6061
+ code: PdfErrorCode.CantImportPages,
6062
+ message: "Failed to import pages for printing"
6063
+ });
6064
+ }
6065
+ if (!includeAnnotations) {
6066
+ const removalResult = this.removeAnnotationsFromPrintDocument(printDocPtr);
6067
+ if (!removalResult.success) {
6068
+ this.pdfiumModule.FPDF_CloseDocument(printDocPtr);
6069
+ this.logger.error(
6070
+ LOG_SOURCE,
6071
+ LOG_CATEGORY,
6072
+ `Failed to remove annotations: ${removalResult.error}`
6073
+ );
6074
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "End", doc.id);
6075
+ return PdfTaskHelper.reject({
6076
+ code: PdfErrorCode.Unknown,
6077
+ message: `Failed to prepare print document: ${removalResult.error}`
6078
+ });
6079
+ }
6080
+ this.logger.debug(
6081
+ LOG_SOURCE,
6082
+ LOG_CATEGORY,
6083
+ `Removed ${removalResult.annotationsRemoved} annotations from ${removalResult.pagesProcessed} pages`
6084
+ );
6085
+ }
6086
+ const buffer = this.saveDocument(printDocPtr);
6087
+ this.pdfiumModule.FPDF_CloseDocument(printDocPtr);
6088
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "End", doc.id);
6089
+ return PdfTaskHelper.resolve(buffer);
6090
+ } catch (error) {
6091
+ if (printDocPtr) {
6092
+ this.pdfiumModule.FPDF_CloseDocument(printDocPtr);
6093
+ }
6094
+ this.logger.error(LOG_SOURCE, LOG_CATEGORY, "preparePrintDocument failed", error);
6095
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "End", doc.id);
6096
+ return PdfTaskHelper.reject({
6097
+ code: PdfErrorCode.Unknown,
6098
+ message: error instanceof Error ? error.message : "Failed to prepare print document"
6099
+ });
6100
+ }
6101
+ }
6102
+ /**
6103
+ * Removes all annotations from a print document using fast raw annotation functions.
6104
+ * This method is optimized for performance by avoiding full page loading.
6105
+ *
6106
+ * @param printDocPtr - Pointer to the print document
6107
+ * @returns Result object with success status and statistics
6108
+ *
6109
+ * @private
6110
+ */
6111
+ removeAnnotationsFromPrintDocument(printDocPtr) {
6112
+ let totalAnnotationsRemoved = 0;
6113
+ let pagesProcessed = 0;
6114
+ try {
6115
+ const pageCount = this.pdfiumModule.FPDF_GetPageCount(printDocPtr);
6116
+ for (let pageIndex = 0; pageIndex < pageCount; pageIndex++) {
6117
+ const annotCount = this.pdfiumModule.EPDFPage_GetAnnotCountRaw(printDocPtr, pageIndex);
6118
+ if (annotCount <= 0) {
6119
+ pagesProcessed++;
6120
+ continue;
6121
+ }
6122
+ let annotationsRemovedFromPage = 0;
6123
+ for (let annotIndex = annotCount - 1; annotIndex >= 0; annotIndex--) {
6124
+ const removed = this.pdfiumModule.EPDFPage_RemoveAnnotRaw(
6125
+ printDocPtr,
6126
+ pageIndex,
6127
+ annotIndex
6128
+ );
6129
+ if (removed) {
6130
+ annotationsRemovedFromPage++;
6131
+ totalAnnotationsRemoved++;
6132
+ } else {
6133
+ this.logger.warn(
6134
+ LOG_SOURCE,
6135
+ LOG_CATEGORY,
6136
+ `Failed to remove annotation ${annotIndex} from page ${pageIndex}`
6137
+ );
6138
+ }
6139
+ }
6140
+ if (annotationsRemovedFromPage > 0) {
6141
+ const pagePtr = this.pdfiumModule.FPDF_LoadPage(printDocPtr, pageIndex);
6142
+ if (pagePtr) {
6143
+ this.pdfiumModule.FPDFPage_GenerateContent(pagePtr);
6144
+ this.pdfiumModule.FPDF_ClosePage(pagePtr);
6145
+ }
6146
+ }
6147
+ pagesProcessed++;
6148
+ }
6149
+ return {
6150
+ success: true,
6151
+ annotationsRemoved: totalAnnotationsRemoved,
6152
+ pagesProcessed
6153
+ };
6154
+ } catch (error) {
6155
+ return {
6156
+ success: false,
6157
+ annotationsRemoved: totalAnnotationsRemoved,
6158
+ pagesProcessed,
6159
+ error: error instanceof Error ? error.message : "Unknown error during annotation removal"
6160
+ };
6161
+ }
6162
+ }
6163
+ /**
6164
+ * Sanitizes and validates a page range string.
6165
+ * Ensures page numbers are within valid bounds and properly formatted.
6166
+ *
6167
+ * @param pageRange - Page range string (e.g., "1,3,5-7") or null for all pages
6168
+ * @param totalPages - Total number of pages in the document
6169
+ * @returns Sanitized page range string or null for all pages
6170
+ *
6171
+ * @private
6172
+ */
6173
+ sanitizePageRange(pageRange, totalPages) {
6174
+ if (!pageRange || pageRange.trim() === "") {
6175
+ return null;
6176
+ }
6177
+ try {
6178
+ const sanitized = [];
6179
+ const parts = pageRange.split(",");
6180
+ for (const part of parts) {
6181
+ const trimmed = part.trim();
6182
+ if (trimmed.includes("-")) {
6183
+ const [startStr, endStr] = trimmed.split("-").map((s) => s.trim());
6184
+ const start = parseInt(startStr, 10);
6185
+ const end = parseInt(endStr, 10);
6186
+ if (isNaN(start) || isNaN(end)) {
6187
+ this.logger.warn(LOG_SOURCE, LOG_CATEGORY, `Invalid range: ${trimmed}`);
6188
+ continue;
6189
+ }
6190
+ const validStart = Math.max(1, Math.min(start, totalPages));
6191
+ const validEnd = Math.max(1, Math.min(end, totalPages));
6192
+ for (let i = validStart; i <= validEnd; i++) {
6193
+ if (!sanitized.includes(i)) {
6194
+ sanitized.push(i);
6195
+ }
6196
+ }
6197
+ } else {
6198
+ const pageNum = parseInt(trimmed, 10);
6199
+ if (isNaN(pageNum)) {
6200
+ this.logger.warn(LOG_SOURCE, LOG_CATEGORY, `Invalid page number: ${trimmed}`);
6201
+ continue;
6202
+ }
6203
+ const validPageNum = Math.max(1, Math.min(pageNum, totalPages));
6204
+ if (!sanitized.includes(validPageNum)) {
6205
+ sanitized.push(validPageNum);
6206
+ }
6207
+ }
6208
+ }
6209
+ if (sanitized.length === 0) {
6210
+ this.logger.warn(LOG_SOURCE, LOG_CATEGORY, "No valid pages in range, using all pages");
6211
+ return null;
6212
+ }
6213
+ sanitized.sort((a, b) => a - b);
6214
+ const optimized = [];
6215
+ let rangeStart = sanitized[0];
6216
+ let rangeEnd = sanitized[0];
6217
+ for (let i = 1; i < sanitized.length; i++) {
6218
+ if (sanitized[i] === rangeEnd + 1) {
6219
+ rangeEnd = sanitized[i];
6220
+ } else {
6221
+ if (rangeStart === rangeEnd) {
6222
+ optimized.push(rangeStart.toString());
6223
+ } else if (rangeEnd - rangeStart === 1) {
6224
+ optimized.push(rangeStart.toString());
6225
+ optimized.push(rangeEnd.toString());
6226
+ } else {
6227
+ optimized.push(`${rangeStart}-${rangeEnd}`);
6228
+ }
6229
+ rangeStart = sanitized[i];
6230
+ rangeEnd = sanitized[i];
6231
+ }
6232
+ }
6233
+ if (rangeStart === rangeEnd) {
6234
+ optimized.push(rangeStart.toString());
6235
+ } else if (rangeEnd - rangeStart === 1) {
6236
+ optimized.push(rangeStart.toString());
6237
+ optimized.push(rangeEnd.toString());
6238
+ } else {
6239
+ optimized.push(`${rangeStart}-${rangeEnd}`);
6240
+ }
6241
+ const result = optimized.join(",");
6242
+ this.logger.debug(
6243
+ LOG_SOURCE,
6244
+ LOG_CATEGORY,
6245
+ `Sanitized page range: "${pageRange}" -> "${result}"`
6246
+ );
6247
+ return result;
6248
+ } catch (error) {
6249
+ this.logger.error(LOG_SOURCE, LOG_CATEGORY, `Error sanitizing page range: ${error}`);
6250
+ return null;
6251
+ }
6252
+ }
5918
6253
  }
5919
6254
  export {
5920
6255
  BitmapFormat as B,
@@ -5925,4 +6260,4 @@ export {
5925
6260
  readArrayBuffer as c,
5926
6261
  readString as r
5927
6262
  };
5928
- //# sourceMappingURL=engine-DMU8HkGx.js.map
6263
+ //# sourceMappingURL=engine-D0zKoYug.js.map