@poe-platform/safe-bash 0.1.809 → 0.1.810

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 (109) hide show
  1. package/dist/audio-ast/index.d.ts +1 -1
  2. package/dist/audio-ast/index.js +6 -0
  3. package/dist/audio-ast/wav-source.d.ts +7 -1
  4. package/dist/image-ast/index.js +1 -1
  5. package/dist/pdf-ast/cos/mutable-object-store.d.ts +3 -0
  6. package/dist/pdf-ast/cos/qpdf-json-document.d.ts +42 -0
  7. package/dist/pdf-ast/cos/qpdf-json-values.d.ts +7 -0
  8. package/dist/pdf-ast/index.d.ts +1 -0
  9. package/dist/pdf-ast/index.js +508 -37
  10. package/dist/pdf-ast/retained-document.d.ts +3 -1
  11. package/dist/safe-bash/chunks/{chunk-RQCK77SC.js → chunk-65TFMAZU.js} +2 -2
  12. package/dist/safe-bash/chunks/{chunk-SOFBGDXG.js → chunk-HHSOUC3Z.js} +32 -0
  13. package/dist/safe-bash/chunks/{chunk-WAZEELYB.js → chunk-ZA5FQ34E.js} +10 -5
  14. package/dist/safe-bash/command-chunks/biff-ORSHM4YX-QYPGRDAZ.js +4937 -0
  15. package/dist/safe-bash/command-chunks/{chunk-62ZAHKFS.js → chunk-2VCKUNDZ.js} +130 -14
  16. package/dist/safe-bash/command-chunks/{chunk-GLVD3JJG.js → chunk-BYZUOF6X.js} +2858 -2816
  17. package/dist/safe-bash/command-chunks/{chunk-6OKH4X67.js → chunk-CAXJ4RLF.js} +264 -1
  18. package/dist/safe-bash/command-chunks/{chunk-YJJBGN7U.js → chunk-CHR2OD2U.js} +9 -9
  19. package/dist/safe-bash/command-chunks/{chunk-D7XBUF76.js → chunk-D2ASPM7R.js} +109 -23
  20. package/dist/safe-bash/command-chunks/chunk-D5AYP2UM.js +816 -0
  21. package/dist/safe-bash/command-chunks/{chunk-WFDG3N5R.js → chunk-ECDEPKKW.js} +1 -1
  22. package/dist/safe-bash/command-chunks/{chunk-OQCJGUI6.js → chunk-HARUYHH7.js} +10 -10
  23. package/dist/safe-bash/command-chunks/{chunk-NVBUC644.js → chunk-HKGNBH7Z.js} +2 -2
  24. package/dist/safe-bash/command-chunks/chunk-MGBHGZEX.js +12 -0
  25. package/dist/safe-bash/command-chunks/{chunk-4557HE3J.js → chunk-PMWW7KSB.js} +161 -42
  26. package/dist/safe-bash/command-chunks/{chunk-JW3KIZU6.js → chunk-RUXY7GN5.js} +1 -1
  27. package/dist/safe-bash/command-chunks/{chunk-KELMIFVV.js → chunk-TI52LKLL.js} +1 -1
  28. package/dist/safe-bash/command-chunks/{chunk-JJQ72P3V.js → chunk-VCML4T5D.js} +1 -1
  29. package/dist/safe-bash/command-chunks/{chunk-5HGEXQVD.js → chunk-WC2OCF4H.js} +1 -1
  30. package/dist/safe-bash/command-chunks/chunk-WH3TIOTS.js +326 -0
  31. package/dist/safe-bash/command-chunks/{chunk-45FI2IPY.js → chunk-WQ6ABTJU.js} +3 -6
  32. package/dist/safe-bash/command-chunks/{chunk-NB7JO7FE.js → chunk-YTFWPJ3F.js} +1 -1
  33. package/dist/safe-bash/command-chunks/{chunk-GKYCV6BU.js → chunk-ZEPDT6I5.js} +482 -168
  34. package/dist/safe-bash/command-chunks/{command-engine-P5DFM4OU.js → command-engine-BEWABZ75.js} +10 -3
  35. package/dist/safe-bash/command-chunks/{engine-RU4OFLPO-CPLFYD67.js → engine-MEPOXIXT-WZMRHACG.js} +1 -1
  36. package/dist/safe-bash/command-chunks/pdf-LOZAXXS6-ERI57IAV.js +557 -0
  37. package/dist/safe-bash/commands/audio/index.browser.js +2 -14
  38. package/dist/safe-bash/commands/diff-patch/index.js +0 -2
  39. package/dist/safe-bash/commands/ffprobe/index.browser.js +2 -5
  40. package/dist/safe-bash/commands/pandoc/index.browser.js +3 -1
  41. package/dist/safe-bash/commands/text.js +10 -1
  42. package/dist/safe-bash/core.d.ts +2 -2
  43. package/dist/safe-bash/core.js +2 -2
  44. package/dist/safe-bash/full-core.browser.js +18 -22
  45. package/dist/safe-bash/lazy-optional.d.ts +9 -0
  46. package/dist/safe-bash/lazy-optional.js +24 -0
  47. package/dist/safe-bash/plugins/index.browser.js +5 -3
  48. package/dist/safe-bash/registry-entry.browser.js +1 -1
  49. package/dist/safe-bash-command-apply-patch/apply.js +2 -2
  50. package/dist/safe-bash-command-apply-patch/index.js +2 -2
  51. package/dist/safe-bash-command-apply-patch/parser.d.ts +20 -1
  52. package/dist/safe-bash-command-apply-patch/parser.js +1 -1
  53. package/dist/safe-bash-command-ffprobe/index.js +2 -1
  54. package/dist/safe-bash-command-ffprobe/media.js +2 -1
  55. package/dist/safe-bash-command-ffprobe/options.d.ts +15 -0
  56. package/dist/safe-bash-command-ffprobe/options.js +7 -0
  57. package/dist/safe-bash-command-media/index.js +2 -2
  58. package/dist/safe-bash-command-media/plugin.js +1 -1
  59. package/dist/safe-bash-command-media/remote.js +2 -2
  60. package/dist/safe-bash-command-pandoc/command.js +6 -6
  61. package/dist/safe-bash-command-pandoc/index.js +31 -31
  62. package/dist/safe-bash-command-patch/index.js +2 -2
  63. package/dist/safe-bash-command-patch/patch-publication.d.ts +2 -2
  64. package/dist/safe-bash-command-patch/patch-publication.js +1 -1
  65. package/dist/safe-bash-command-patch/patch.js +2 -2
  66. package/dist/safe-bash-command-pptx/engine.js +1 -1
  67. package/dist/safe-bash-command-ssconvert/index.js +2 -2
  68. package/dist/safe-bash-command-xmllint/index.js +137 -30
  69. package/dist/safe-bash-compression-engine/bounded-codec.js +2 -2
  70. package/dist/safe-bash-compression-engine/codec-loader.js +1 -1
  71. package/dist/safe-bash-compression-engine/files.js +5 -5
  72. package/dist/safe-bash-compression-engine/index.js +4 -4
  73. package/dist/safe-bash-compression-engine/operand.js +5 -5
  74. package/dist/safe-bash-compression-engine/stream.js +4 -4
  75. package/dist/safe-bash-compression-engine/zstd-decode.js +3 -3
  76. package/dist/safe-bash-media-engine/imagemagick.d.ts +2 -0
  77. package/dist/safe-bash-media-engine/index.js +162 -72
  78. package/dist/safe-bash-network-engine/body.d.ts +1 -0
  79. package/dist/safe-bash-network-engine/body.js +1 -1
  80. package/dist/safe-bash-network-engine/transfer.js +11 -3
  81. package/dist/safe-bash-presentation-engine/command-placeholder.js +4 -3
  82. package/dist/safe-bash-presentation-engine/index.d.ts +1 -1
  83. package/dist/safe-bash-presentation-engine/index.js +9 -4
  84. package/dist/safe-bash-presentation-engine/presentation-model.js +3 -2
  85. package/dist/safe-bash-presentation-engine/retained-text.js +3 -3
  86. package/dist/safe-bash-presentation-engine/retained-xml-parts.d.ts +26 -0
  87. package/dist/safe-bash-presentation-engine/xml-parts.d.ts +1 -0
  88. package/dist/safe-bash-presentation-engine/xml-parts.js +7 -1
  89. package/dist/safe-bash-xml-engine/document.js +1 -1
  90. package/dist/safe-bash-xml-engine/index.js +1 -1
  91. package/dist/spreadsheet-engine/rendering/print/tab-layout.d.ts +11 -0
  92. package/dist/spreadsheet-engine/rendering/print/tab-layout.js +15 -0
  93. package/dist/spreadsheet-engine/rendering/print/text-lines.d.ts +2 -2
  94. package/dist/spreadsheet-engine/rendering/print/text-lines.js +3 -3
  95. package/dist/spreadsheet-format-xls/biff-encrypted-properties.d.ts +4 -0
  96. package/dist/spreadsheet-format-xls/biff-encrypted-properties.js +137 -56
  97. package/dist/spreadsheet-format-xls/biff-encryption.d.ts +1 -1
  98. package/dist/spreadsheet-format-xls/biff-encryption.js +8 -3
  99. package/dist/spreadsheet-format-xls/biff-property-bytes.d.ts +1 -1
  100. package/dist/spreadsheet-format-xls/biff-property-bytes.js +2 -2
  101. package/dist/spreadsheet-format-xls/biff.js +11 -3
  102. package/package.json +3 -2
  103. package/dist/safe-bash/chunks/chunk-I2A5ZCPD.js +0 -17
  104. package/dist/safe-bash/chunks/chunk-PQTT2EZP.js +0 -8
  105. package/dist/safe-bash/command-chunks/biff-DS263V2K-2GP4GZT7.js +0 -4868
  106. package/dist/safe-bash/command-chunks/chunk-6ZFYWT3U.js +0 -581
  107. package/dist/safe-bash/command-chunks/chunk-S244SWDH.js +0 -153
  108. package/dist/safe-bash/command-chunks/pdf-T7AWYZGQ-KNAYJ7YF.js +0 -552
  109. /package/dist/safe-bash/command-chunks/{chunk-EMMSXKEJ.js → chunk-4Q4R3VZU.js} +0 -0
@@ -5,7 +5,9 @@ import {
5
5
  transformBytes
6
6
  } from "../safe-bash/command-chunks/chunk-E6SK3OU2.js";
7
7
  import {
8
+ BackedJson,
8
9
  indexJsonObjects,
10
+ parseBackedJson,
9
11
  readJsonNumber
10
12
  } from "../safe-bash/command-chunks/chunk-LWZVDDJA.js";
11
13
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
@@ -31439,6 +31441,35 @@ function parseCosDocument(bytes, options = {}) {
31439
31441
  return drainWork(parseCosDocumentSteps(bytes, options));
31440
31442
  }
31441
31443
 
31444
+ // packages/pdf-ast/src/content/array-cursor.ts
31445
+ var PdfArrayCursor = class {
31446
+ constructor(array) {
31447
+ this.array = array;
31448
+ this.length = array.storedItems?.length ?? array.items.length;
31449
+ if (!Number.isSafeInteger(this.length) || this.length < 0) throw new RangeError("Invalid stored array length");
31450
+ this.position = array.storedItems?.position ?? -1;
31451
+ }
31452
+ array;
31453
+ index = 0;
31454
+ position;
31455
+ length;
31456
+ *next() {
31457
+ if (this.index === this.length) {
31458
+ if (this.array.storedItems && this.position !== -1) throw new Error("Invalid stored array terminator");
31459
+ return { done: true, value: void 0 };
31460
+ }
31461
+ let node = this.array.items[this.index];
31462
+ if (this.array.storedItems) {
31463
+ const reply = yield { kind: "array-item", items: this.array.storedItems, position: this.position };
31464
+ if (!reply || typeof reply !== "object" || reply.kind !== "array" || reply.items[0]?.kind !== "number" || !reply.items[1]) throw new TypeError("Expected a PDF array record");
31465
+ this.position = reply.items[0].value;
31466
+ node = reply.items[1];
31467
+ }
31468
+ this.index++;
31469
+ return { done: false, value: node };
31470
+ }
31471
+ };
31472
+
31442
31473
  // packages/pdf-ast/src/content/sampled-vertices.ts
31443
31474
  function* sampledVertices(size, domain, encode3, inputs, sampleCount) {
31444
31475
  const dimensions = Math.max(1, size.length), axes = [];
@@ -31476,9 +31507,9 @@ function* sampledVertices(size, domain, encode3, inputs, sampleCount) {
31476
31507
  }
31477
31508
 
31478
31509
  // packages/pdf-ast/src/content/annotations.ts
31479
- function* resolveNode(node) {
31510
+ function* resolveNode(node, arrayKey) {
31480
31511
  if (!node) return void 0;
31481
- const result = yield { kind: "resolve", node };
31512
+ const result = yield { kind: "resolve", node, ...arrayKey ? { arrayKey } : {} };
31482
31513
  if (typeof result === "number" || typeof result === "boolean") throw new TypeError("Expected a PDF annotation object");
31483
31514
  return result;
31484
31515
  }
@@ -31486,12 +31517,20 @@ function* resolveDict(node) {
31486
31517
  const result = yield* resolveNode(node);
31487
31518
  return result?.kind === "dict" ? result : void 0;
31488
31519
  }
31489
- function* resolveArray(node) {
31490
- const result = yield* resolveNode(node);
31520
+ function* resolveArray(node, arrayKey) {
31521
+ const result = yield* resolveNode(node, arrayKey);
31491
31522
  return result?.kind === "array" ? result : void 0;
31492
31523
  }
31524
+ function* visitChildren(array, visit) {
31525
+ const cursor = new PdfArrayCursor(array);
31526
+ for (let step = yield* cursor.next(); !step.done; step = yield* cursor.next()) {
31527
+ const found = yield* visit(step.value);
31528
+ if (found !== void 0) return found;
31529
+ }
31530
+ return void 0;
31531
+ }
31493
31532
  function* extractPageAnnotationSteps(pageDict, root, maxDepth = Infinity) {
31494
- const annotsArr = yield* resolveArray(dictGet(pageDict, "Annots"));
31533
+ const annotsArr = yield* resolveArray(dictGet(pageDict, "Annots"), "Annots");
31495
31534
  if (!annotsArr) return;
31496
31535
  function* resolveDestToPageNum(destNode, depth = 0) {
31497
31536
  if (!destNode || depth > 4) return void 0;
@@ -31540,12 +31579,10 @@ function* extractPageAnnotationSteps(pageDict, root, maxDepth = Infinity) {
31540
31579
  if (kStr === destName) return namesArr.items[i + 1];
31541
31580
  }
31542
31581
  }
31543
- const kidsArr = yield* resolveArray(dictGet(treeDict, "Kids"));
31582
+ const kidsArr = yield* resolveArray(dictGet(treeDict, "Kids"), "Kids");
31544
31583
  if (kidsArr) {
31545
- for (const kid of kidsArr.items) {
31546
- const res = yield* searchNameTree(kid, depth2 + 1);
31547
- if (res) return res;
31548
- }
31584
+ const found = yield* visitChildren(kidsArr, (kid) => searchNameTree(kid, depth2 + 1));
31585
+ if (found) return found;
31549
31586
  }
31550
31587
  return void 0;
31551
31588
  } finally {
@@ -31558,7 +31595,9 @@ function* extractPageAnnotationSteps(pageDict, root, maxDepth = Infinity) {
31558
31595
  }
31559
31596
  return void 0;
31560
31597
  }
31561
- for (const item of annotsArr.items) {
31598
+ const annotations = new PdfArrayCursor(annotsArr);
31599
+ for (let step = yield* annotations.next(); !step.done; step = yield* annotations.next()) {
31600
+ const item = step.value;
31562
31601
  const dict = yield* resolveDict(item);
31563
31602
  if (!dict) continue;
31564
31603
  const rectArr = yield* resolveArray(dictGet(dict, "Rect"));
@@ -31604,12 +31643,10 @@ function* annotationPageNumberSteps(root, reference, maxDepth = Infinity) {
31604
31643
  const dict = yield* resolveDict(node);
31605
31644
  if (!dict) return void 0;
31606
31645
  const type = yield* resolveNode(dictGet(dict, "Type"));
31607
- const kids = yield* resolveArray(dictGet(dict, "Kids"));
31646
+ const kids = yield* resolveArray(dictGet(dict, "Kids"), "Kids");
31608
31647
  if (kids && (type?.kind !== "name" || type.decoded !== "Page")) {
31609
- for (const child of kids.items) {
31610
- const found = yield* walk(child, depth + 1);
31611
- if (found !== void 0) return found;
31612
- }
31648
+ const found = yield* visitChildren(kids, (child) => walk(child, depth + 1));
31649
+ if (found !== void 0) return found;
31613
31650
  } else {
31614
31651
  index2++;
31615
31652
  if (node.kind === "ref" && node.objectNumber === reference.objectNumber) return index2;
@@ -43916,8 +43953,8 @@ function* resolveDict3(node, arrayPathPrefix) {
43916
43953
  const value = yield* resolveNode2(node, arrayPathPrefix);
43917
43954
  return value?.kind === "dict" ? value : void 0;
43918
43955
  }
43919
- function* resolveArray3(node) {
43920
- const value = yield* resolveNode2(node);
43956
+ function* resolveArray3(node, arrayPathPrefix) {
43957
+ const value = yield* resolveNode2(node, arrayPathPrefix);
43921
43958
  return value?.kind === "array" ? value : void 0;
43922
43959
  }
43923
43960
  function* visible(node) {
@@ -43948,9 +43985,11 @@ function* preparePageAppearanceSteps(pageDict, pageRes, evalResourcesDict, hideA
43948
43985
  dictSet(evalResourcesDict, entry.key.decoded, entry.value);
43949
43986
  }
43950
43987
  }
43951
- const annotsArr = yield* resolveArray3(dictGet(pageDict, "Annots"));
43952
- if (!hideAnnotations && annotsArr && annotsArr.items.length > 0) {
43953
- for (const item of annotsArr.items) {
43988
+ const annotsArr = yield* resolveArray3(dictGet(pageDict, "Annots"), ["Annots"]);
43989
+ if (!hideAnnotations && annotsArr) {
43990
+ const annotations = new PdfArrayCursor(annotsArr);
43991
+ for (let step = yield* annotations.next(); !step.done; step = yield* annotations.next()) {
43992
+ const item = step.value;
43954
43993
  const annotDict = yield* resolveDict3(item);
43955
43994
  if (!annotDict) continue;
43956
43995
  const fNode = yield* resolveNode2(dictGet(annotDict, "F"));
@@ -57444,7 +57483,22 @@ var PdfMutableObjectStore = class {
57444
57483
  const parsed = await parseCosRangeValue(source, 0, { ...this.options, signal });
57445
57484
  if (!parsed.value) throw new PdfError("E_PARSE", "Missing mutable PDF value");
57446
57485
  const object = { objectNumber: number, generationNumber: generation, value: restoreStringFormats(parsed.value) };
57447
- if (!hasStream) return object;
57486
+ const stream = hasStream ? this.streamSnapshot(at, streamAt, length, hasStream) : void 0;
57487
+ return stream ? { ...object, stream } : object;
57488
+ }
57489
+ /** Borrow encoded stream bytes without parsing the object's dictionary. */
57490
+ getStream(number) {
57491
+ return this.operation(async () => {
57492
+ if (!Number.isSafeInteger(number) || number < 1) throw new RangeError("Invalid PDF object number");
57493
+ const at = await this.index.get(BigInt(number));
57494
+ if (at === void 0 || at === DELETED_OBJECT) return void 0;
57495
+ const bytes = await this.backing.read(Number(at), 64), record = new DataView(bytes.buffer, bytes.byteOffset, bytes.length);
57496
+ const flag = record.getFloat64(40);
57497
+ return flag ? this.streamSnapshot(Number(at), record.getFloat64(24), record.getFloat64(32), flag) : void 0;
57498
+ });
57499
+ }
57500
+ streamSnapshot(at, streamAt, length, flag) {
57501
+ const backing = this.backing, signal = this.signal;
57448
57502
  async function* chunks() {
57449
57503
  for (let offset = 0; offset < length; offset += 16384) {
57450
57504
  if (offset > 0 && offset % (16384 * 64) === 0) await new Promise((resolve2) => setTimeout(resolve2, 0));
@@ -57452,9 +57506,9 @@ var PdfMutableObjectStore = class {
57452
57506
  yield await backing.read(streamAt + offset, Math.min(16384, length - offset));
57453
57507
  }
57454
57508
  }
57455
- const stream = { length, chunks: { [Symbol.asyncIterator]: chunks }, decoded: hasStream === 2 };
57509
+ const stream = { length, chunks: { [Symbol.asyncIterator]: chunks }, decoded: flag === 2 };
57456
57510
  this.receipts.set(stream, at);
57457
- return { ...object, stream };
57511
+ return stream;
57458
57512
  }
57459
57513
  /** Remember successful decoding only while this stream snapshot is current. */
57460
57514
  markDecoded(object) {
@@ -59871,6 +59925,13 @@ var PdfRetainedDocument = class _PdfRetainedDocument {
59871
59925
  }
59872
59926
  return node ? { value: node, ...reference ? { reference } : {} } : void 0;
59873
59927
  }
59928
+ /** Read one caller-backed array record with document cancellation and ownership. */
59929
+ async readArrayItem(items, position) {
59930
+ this.assertOpen();
59931
+ const record = await readStoredRecord(items.storage, position, this.options.signal);
59932
+ this.assertOpen();
59933
+ return cosArray([cosNumber(record.next), record.value]);
59934
+ }
59874
59935
  async info() {
59875
59936
  const node = (await this.lookup(this.crossReference.infoRef))?.value;
59876
59937
  const result = /* @__PURE__ */ Object.create(null);
@@ -59888,13 +59949,16 @@ var PdfRetainedDocument = class _PdfRetainedDocument {
59888
59949
  const work = annotationPageNumberSteps(this.crossReference.rootRef, reference, this.depthLimit);
59889
59950
  let failed = false;
59890
59951
  try {
59891
- let step = work.next();
59952
+ let step = work.next(), turns = 0;
59892
59953
  while (!step.done) {
59954
+ if (++turns % 256 === 0) await new Promise((resolve2) => setTimeout(resolve2, 0));
59893
59955
  this.assertOpen();
59894
59956
  const request = step.value;
59895
59957
  if (request.kind === "resolve") {
59896
- const resolved = await this.lookup(request.node);
59958
+ const resolved = await this.lookup(request.node, void 0, request.arrayKey ? [request.arrayKey] : void 0);
59897
59959
  step = work.next(resolved?.stream && resolved.value.kind === "dict" ? { kind: "stream", dict: resolved.value, rawBytes: new Uint8Array() } : resolved?.value);
59960
+ } else if (request.kind === "array-item") {
59961
+ step = work.next(await this.readArrayItem(request.items, request.position));
59898
59962
  } else if (request.kind === "visit-page") step = work.next(await visited.add(request.reference.objectNumber));
59899
59963
  else throw new TypeError("Unexpected annotation page lookup request");
59900
59964
  }
@@ -59925,9 +59989,9 @@ var PdfRetainedDocument = class _PdfRetainedDocument {
59925
59989
  if (resolved?.value.kind !== "dict") return;
59926
59990
  const dict = resolved.value;
59927
59991
  const type = (await doc.lookup(dictGet(dict, "Type")))?.value;
59928
- const kids = (await doc.lookup(dictGet(dict, "Kids")))?.value;
59992
+ const kids = (await doc.lookup(dictGet(dict, "Kids"), void 0, ["Kids"]))?.value;
59929
59993
  if (type?.kind === "name" && type.decoded === "Pages" || kids?.kind === "array") {
59930
- if (kids?.kind === "array") for (const kid of kids.items) yield* walk(kid, depth + 1);
59994
+ if (kids?.kind === "array") for await (const kid of kids.storedItems ? readStoredItems(kids.storedItems, doc.options.signal) : kids.items) yield* walk(kid, depth + 1);
59931
59995
  } else if (type?.kind === "name" && type.decoded === "Page" || dictGet(dict, "MediaBox") || dictGet(dict, "Contents")) {
59932
59996
  if (count >= Math.min(doc.options.maxPages, Number.MAX_SAFE_INTEGER)) throw new PdfError("E_LIMIT", "PDF page count limit exceeded");
59933
59997
  yield new PdfRetainedPage(doc, count++, dict, node.kind === "ref" ? node : void 0);
@@ -60301,14 +60365,17 @@ var PdfRetainedPage = class {
60301
60365
  async *annotations() {
60302
60366
  const work = extractPageAnnotationSteps(this.dict, this.document.crossReference.rootRef, this.document.depthLimit);
60303
60367
  try {
60304
- let step = work.next();
60368
+ let step = work.next(), turns = 0;
60305
60369
  while (!step.done) {
60370
+ if (++turns % 256 === 0) await new Promise((resolve2) => setTimeout(resolve2, 0));
60306
60371
  const request = step.value;
60307
60372
  let result;
60308
60373
  if (request.kind === "annotation") yield request.annotation;
60309
60374
  else if (request.kind === "resolve") {
60310
- const resolved = await this.document.lookup(request.node);
60375
+ const resolved = await this.document.lookup(request.node, void 0, request.arrayKey ? [request.arrayKey] : void 0);
60311
60376
  result = resolved?.stream && resolved.value.kind === "dict" ? { kind: "stream", dict: resolved.value, rawBytes: new Uint8Array() } : resolved?.value;
60377
+ } else if (request.kind === "array-item") {
60378
+ result = await this.document.readArrayItem(request.items, request.position);
60312
60379
  } else if (request.kind === "page-number") result = await this.document.annotationPageNumber(request.reference);
60313
60380
  else throw new TypeError("Unexpected annotation request");
60314
60381
  step = work.next(result);
@@ -60319,13 +60386,22 @@ var PdfRetainedPage = class {
60319
60386
  }
60320
60387
  /** Preserve the buffered page API's newline after each content-array stream. */
60321
60388
  async *streamContents() {
60322
- const content = await this.document.lookup(dictGet(this.dict, "Contents"));
60389
+ const content = await this.document.lookup(dictGet(this.dict, "Contents"), void 0, ["Contents"]);
60323
60390
  if (content?.stream && content.reference) yield* this.document.objects.decodeStream(content.reference.objectNumber, content.reference.generationNumber);
60324
- else if (content?.value.kind === "array") for (const item of content.value.items) {
60325
- const stream = await this.document.lookup(item);
60326
- if (!stream?.stream || !stream.reference) continue;
60327
- yield* this.document.objects.decodeStream(stream.reference.objectNumber, stream.reference.generationNumber);
60328
- yield new Uint8Array([10]);
60391
+ else if (content?.value.kind === "array") {
60392
+ const cursor = new PdfArrayCursor(content.value);
60393
+ let turns = 0;
60394
+ while (true) {
60395
+ if (++turns % 256 === 0) await new Promise((resolve2) => setTimeout(resolve2, 0));
60396
+ const work = cursor.next();
60397
+ let step = work.next();
60398
+ while (!step.done) step = work.next(await this.document.readArrayItem(step.value.items, step.value.position));
60399
+ if (step.value.done) break;
60400
+ const stream = await this.document.lookup(step.value.value);
60401
+ if (!stream?.stream || !stream.reference) continue;
60402
+ yield* this.document.objects.decodeStream(stream.reference.objectNumber, stream.reference.generationNumber);
60403
+ yield new Uint8Array([10]);
60404
+ }
60329
60405
  }
60330
60406
  }
60331
60407
  };
@@ -63291,6 +63367,7 @@ var QpdfJsonValues = class _QpdfJsonValues {
63291
63367
  scratch;
63292
63368
  first;
63293
63369
  next;
63370
+ sourceOrder;
63294
63371
  closed = false;
63295
63372
  work = 0;
63296
63373
  async cooperate(units = 1) {
@@ -63366,7 +63443,7 @@ var QpdfJsonValues = class _QpdfJsonValues {
63366
63443
  }
63367
63444
  }
63368
63445
  async index() {
63369
- const order = await indexJsonObjects(this.tree, this.scratch, (units) => this.cooperate(units));
63446
+ const order = this.sourceOrder = await indexJsonObjects(this.tree, this.scratch, (units) => this.cooperate(units));
63370
63447
  const pointer = async (at) => {
63371
63448
  const bytes = await this.scratch.read(at, 8);
63372
63449
  return new DataView(bytes.buffer, bytes.byteOffset, bytes.length).getFloat64(0, true);
@@ -63541,7 +63618,102 @@ var QpdfJsonValues = class _QpdfJsonValues {
63541
63618
  }
63542
63619
  yield encoder.encode(utf16 ? ">" : ")");
63543
63620
  }
63621
+ // JSON.parse removes duplicate JSON names before conversion, but decoded PDF
63622
+ // name collisions happen after each value is converted. Validate the former
63623
+ // view before emitting the latter so overwritten invalid numbers still fail.
63624
+ async validate(root) {
63625
+ let position = root;
63626
+ for (; ; ) {
63627
+ await this.cooperate();
63628
+ let header2 = await this.tree.describe(position);
63629
+ if (header2.kind === "object" || header2.kind === "array") {
63630
+ const child = header2.kind === "object" ? await this.sourceOrder.first(position) : header2.children ? position + 32 : 0;
63631
+ if (child) {
63632
+ position = child;
63633
+ continue;
63634
+ }
63635
+ } else if (header2.kind === "literal") {
63636
+ const token2 = await this.tree.smallText(position, 5);
63637
+ if (token2 !== "null" && token2 !== "true" && token2 !== "false") cosNumber(await readJsonNumber(this.text(position), (units) => this.cooperate(units), false));
63638
+ }
63639
+ for (; ; ) {
63640
+ if (position === root) return;
63641
+ await this.cooperate();
63642
+ const parent = await this.tree.describe(header2.parent);
63643
+ const next = parent.kind === "object" && header2.kind !== "key" ? await this.sourceOrder.next(position, header2.parent) : header2.end < parent.end ? header2.end : 0;
63644
+ if (next) {
63645
+ position = next;
63646
+ break;
63647
+ }
63648
+ position = header2.parent;
63649
+ header2 = parent;
63650
+ }
63651
+ }
63652
+ }
63653
+ /** Look up a converted PDF dictionary name, after prefix decoding/collisions. */
63654
+ async property(root, name) {
63655
+ if ((await this.tree.describe(root)).kind !== "object") return void 0;
63656
+ for (let key = Number(await this.first.get(BigInt(root)) ?? 0n); key; ) {
63657
+ await this.cooperate();
63658
+ const value = (await this.tree.describe(key)).end;
63659
+ if (await this.keyEquals(key, name)) return value;
63660
+ key = Number(await this.next.get(BigInt(value)) ?? 0n);
63661
+ }
63662
+ return void 0;
63663
+ }
63664
+ async keyEquals(key, name) {
63665
+ const text = await this.tree.smallText(key, name.length + 3);
63666
+ return text !== void 0 && text.slice(text.startsWith("n:/") ? 3 : text.startsWith("/") ? 1 : 0) === name;
63667
+ }
63668
+ /** Stream an imported stream dictionary with legacy filter/length handling. */
63669
+ async *streamDictionary(root, length) {
63670
+ if (!Number.isSafeInteger(length) || length < 0) throw new RangeError("Invalid PDF stream length");
63671
+ if (root !== void 0) await this.validate(root);
63672
+ const encoder = new TextEncoder();
63673
+ const object = root !== void 0 && (await this.tree.describe(root)).kind === "object";
63674
+ let strip = false;
63675
+ if (object) {
63676
+ const filter = await this.property(root, "Filter");
63677
+ const recognized = async (position) => {
63678
+ if ((await this.tree.describe(position)).kind !== "string") return false;
63679
+ const text = await this.tree.smallText(position, 32);
63680
+ if (text === void 0) return false;
63681
+ const skip = text.startsWith("n:/") ? 3 : text.startsWith("n:") ? 2 : text.startsWith("/") ? 1 : 0;
63682
+ return skip > 0 && ["FlateDecode", "ASCIIHexDecode", "ASCII85Decode", "LZWDecode", "RunLengthDecode"].includes(text.slice(skip));
63683
+ };
63684
+ if (filter !== void 0) {
63685
+ strip = await recognized(filter);
63686
+ if ((await this.tree.describe(filter)).kind === "array") {
63687
+ strip = true;
63688
+ for await (const child of this.tree.children(filter)) if (!await recognized(child)) {
63689
+ strip = false;
63690
+ break;
63691
+ }
63692
+ }
63693
+ }
63694
+ }
63695
+ yield encoder.encode("<<\n");
63696
+ let hasLength = false;
63697
+ for (let key = object ? Number(await this.first.get(BigInt(root)) ?? 0n) : 0; key; ) {
63698
+ await this.cooperate();
63699
+ const value = (await this.tree.describe(key)).end;
63700
+ if (!strip || !await this.keyEquals(key, "Filter") && !await this.keyEquals(key, "DecodeParms")) {
63701
+ yield* this.scalar(key, true);
63702
+ yield encoder.encode(" ");
63703
+ if (await this.keyEquals(key, "Length")) {
63704
+ hasLength = true;
63705
+ yield serializeCosNodeBytes(cosNumber(length));
63706
+ } else yield* this.chunks(value);
63707
+ yield encoder.encode("\n");
63708
+ }
63709
+ key = Number(await this.next.get(BigInt(value)) ?? 0n);
63710
+ }
63711
+ if (!hasLength) yield encoder.encode(`/Length ${length}
63712
+ `);
63713
+ yield encoder.encode(">>");
63714
+ }
63544
63715
  async *chunks(root) {
63716
+ await this.validate(root);
63545
63717
  const encoder = new TextEncoder();
63546
63718
  let position = root, closing = false;
63547
63719
  while (position) {
@@ -63577,6 +63749,304 @@ var QpdfJsonValues = class _QpdfJsonValues {
63577
63749
  await this.scratch.close();
63578
63750
  }
63579
63751
  };
63752
+
63753
+ // packages/pdf-ast/src/cos/qpdf-json-document.ts
63754
+ import { IntegerTable as IntegerTable15, PagedStorage as PagedStorage25 } from "@poe-platform/safe-fs/storage";
63755
+ var QpdfJsonDocument = class _QpdfJsonDocument {
63756
+ constructor(storage, options = {}) {
63757
+ this.storage = storage;
63758
+ this.signal = options.signal ? AbortSignal.any([options.signal, this.controller.signal]) : this.controller.signal;
63759
+ this.store = new PdfMutableObjectStore(storage, { signal: this.signal });
63760
+ this.backing = new PagedStorage25(
63761
+ { fs: storage.fs, cwd: storage.directory, env: {}, signal: this.signal },
63762
+ 4
63763
+ );
63764
+ this.positions = new IntegerTable15(this.backing, 64);
63765
+ this.order = new IntegerTable15(this.backing, 64);
63766
+ this.catalogs = new IntegerTable15(this.backing, 64);
63767
+ }
63768
+ storage;
63769
+ rootRef;
63770
+ infoRef;
63771
+ store;
63772
+ backing;
63773
+ positions;
63774
+ order;
63775
+ catalogs;
63776
+ ordinal = 0;
63777
+ controller = new AbortController();
63778
+ signal;
63779
+ pending = Promise.resolve();
63780
+ closing;
63781
+ async remember(number) {
63782
+ if (!await this.positions.get(BigInt(number))) {
63783
+ const ordinal = ++this.ordinal;
63784
+ await this.positions.set(BigInt(number), BigInt(ordinal));
63785
+ await this.order.set(BigInt(ordinal), BigInt(number));
63786
+ }
63787
+ }
63788
+ static async fromDocument(document2, source, storage, options = {}) {
63789
+ const owner = new _QpdfJsonDocument(storage, options);
63790
+ try {
63791
+ owner.rootRef = document2.crossReference.rootRef;
63792
+ owner.infoRef = document2.crossReference.infoRef;
63793
+ for await (const object of retainedCosObjects(document2, storage, { signal: owner.signal })) {
63794
+ await owner.store.set(object);
63795
+ const type = object.value.kind === "dict" && !object.stream ? dictGet(object.value, "Type") : void 0;
63796
+ await owner.catalogs.set(
63797
+ BigInt(object.objectNumber),
63798
+ type?.kind === "name" && type.decoded === "Catalog" ? BigInt(object.generationNumber + 1) : 0n
63799
+ );
63800
+ }
63801
+ for await (const number of retainedObjectOrder(document2, source, storage, owner.signal))
63802
+ await owner.remember(number);
63803
+ return owner;
63804
+ } catch (error) {
63805
+ try {
63806
+ await owner.close();
63807
+ } catch {
63808
+ }
63809
+ throw error;
63810
+ }
63811
+ }
63812
+ apply(input, options = {}) {
63813
+ const task = this.pending.then(() => this.update(input, options));
63814
+ this.pending = task.catch(() => {
63815
+ });
63816
+ return task;
63817
+ }
63818
+ async update(input, options) {
63819
+ this.signal.throwIfAborted();
63820
+ const maximum10 = options.maxInputBytes ?? Infinity;
63821
+ if (maximum10 !== Infinity && (!Number.isSafeInteger(maximum10) || maximum10 < 0))
63822
+ throw new RangeError("Invalid QPDF JSON input limit");
63823
+ const context = {
63824
+ fs: this.storage.fs,
63825
+ cwd: this.storage.directory,
63826
+ env: {},
63827
+ signal: this.signal
63828
+ };
63829
+ const tape = new PagedStorage25(context, 4), scratch = new PagedStorage25(context, 4);
63830
+ let values, failed = false, work = 0;
63831
+ const cooperate = async (units = 1) => {
63832
+ this.signal.throwIfAborted();
63833
+ work += units;
63834
+ if (work >= 4096) {
63835
+ work = 0;
63836
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
63837
+ this.signal.throwIfAborted();
63838
+ }
63839
+ };
63840
+ const tree = new BackedJson(tape, cooperate);
63841
+ async function* text() {
63842
+ const decoder = new TextDecoder();
63843
+ let total = 0;
63844
+ for await (const bytes of input) {
63845
+ if (bytes.length > maximum10 - total)
63846
+ throw new PdfError("E_LIMIT", "QPDF JSON input byte limit exceeded");
63847
+ total += bytes.length;
63848
+ for (let at = 0; at < bytes.length; at += 16384) {
63849
+ await cooperate(16384);
63850
+ yield decoder.decode(bytes.subarray(at, at + 16384), { stream: true });
63851
+ }
63852
+ }
63853
+ yield decoder.decode();
63854
+ }
63855
+ const isNull = async (position) => position !== void 0 && (await tree.describe(position)).kind === "literal" && await tree.smallText(position, 4) === "null";
63856
+ try {
63857
+ await parseBackedJson(
63858
+ text(),
63859
+ tree,
63860
+ scratch,
63861
+ cooperate,
63862
+ options.syntaxError ?? ((offset, message) => {
63863
+ throw new SyntaxError(`${message} at offset ${offset}`);
63864
+ }),
63865
+ void 0,
63866
+ true
63867
+ );
63868
+ const order = await indexJsonObjects(tree, scratch, cooperate);
63869
+ const property = async (position, name) => position !== void 0 && (await tree.describe(position)).kind === "object" ? order.property(position, name) : void 0;
63870
+ const objectLike = async (position) => position !== void 0 && ["object", "array"].includes((await tree.describe(position)).kind);
63871
+ const root = tree.rootPosition;
63872
+ if (!await objectLike(root)) throw new Error("Invalid QPDF JSON root");
63873
+ let section;
63874
+ const qpdf = await property(root, "qpdf");
63875
+ let selected = false;
63876
+ if (qpdf !== void 0 && (await tree.describe(qpdf)).kind === "array") {
63877
+ let index2 = 0;
63878
+ for await (const child of tree.children(qpdf)) {
63879
+ if (index2++ === 1) {
63880
+ if (await objectLike(child) || await isNull(child)) {
63881
+ section = child;
63882
+ selected = true;
63883
+ }
63884
+ break;
63885
+ }
63886
+ }
63887
+ }
63888
+ if (!selected) {
63889
+ const objects = await property(root, "objects");
63890
+ if (await objectLike(objects)) section = objects;
63891
+ }
63892
+ if (section === void 0 || await isNull(section))
63893
+ throw new Error("Missing QPDF JSON objects section");
63894
+ values = await QpdfJsonValues.open(tree, this.storage, { signal: this.signal });
63895
+ let rootRef, infoRef;
63896
+ if ((await tree.describe(section)).kind === "object")
63897
+ for await (const { key, value: entry } of order.entries(section)) {
63898
+ await cooperate();
63899
+ if (!await objectLike(entry)) continue;
63900
+ const value = await property(entry, "value");
63901
+ if (await tree.smallText(key, 7) === "trailer") {
63902
+ if (value !== void 0) {
63903
+ for await (const bytes of values.chunks(value)) void bytes;
63904
+ const root2 = await values.property(value, "Root"), info3 = await values.property(value, "Info");
63905
+ if (root2 !== void 0) rootRef = await values.reference(root2) ?? rootRef;
63906
+ if (info3 !== void 0) infoRef = await values.reference(info3) ?? infoRef;
63907
+ }
63908
+ continue;
63909
+ }
63910
+ const ref = await values.reference(key);
63911
+ if (!ref) continue;
63912
+ const stream = await property(entry, "stream");
63913
+ if (await objectLike(stream)) {
63914
+ const dict = await property(stream, "dict"), data = await property(stream, "data"), datafile = await property(stream, "datafile");
63915
+ if (dict !== void 0) await values.validate(dict);
63916
+ let staged;
63917
+ let streamFailed = false;
63918
+ try {
63919
+ let raw;
63920
+ if (data !== void 0 && (await tree.describe(data)).kind === "string") {
63921
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
63922
+ async function* decoded() {
63923
+ let accumulator = 0, bits = 0, used = 0, buffer = new Uint8Array(8192);
63924
+ for await (const text2 of tree.scalarChunks(data)) {
63925
+ await cooperate(text2.length);
63926
+ for (const char of text2) {
63927
+ const code = alphabet.indexOf(char);
63928
+ if (code < 0) continue;
63929
+ accumulator = accumulator << 6 | code;
63930
+ bits += 6;
63931
+ if (bits >= 8) {
63932
+ bits -= 8;
63933
+ buffer[used++] = accumulator >>> bits & 255;
63934
+ accumulator &= (1 << bits) - 1;
63935
+ if (used === buffer.length) {
63936
+ yield buffer;
63937
+ buffer = new Uint8Array(8192);
63938
+ used = 0;
63939
+ }
63940
+ }
63941
+ }
63942
+ }
63943
+ if (used) yield buffer.subarray(0, used);
63944
+ }
63945
+ staged = await PdfFileSource.fromStream(
63946
+ this.storage.fs,
63947
+ this.storage.directory,
63948
+ decoded(),
63949
+ { signal: this.signal }
63950
+ );
63951
+ raw = { length: staged.size, chunks: staged.stream(0, staged.size, this.signal) };
63952
+ } else if (datafile !== void 0 && (await tree.describe(datafile)).kind === "string") {
63953
+ let path = "";
63954
+ for await (const part of tree.scalarChunks(datafile)) {
63955
+ await cooperate(part.length);
63956
+ path += part;
63957
+ }
63958
+ const file = await options.dataFile?.(path);
63959
+ if (!file) throw new Error(`cannot open stream datafile ${path}`);
63960
+ raw = { length: file.size, chunks: file.stream(0, file.size, this.signal) };
63961
+ } else
63962
+ raw = await this.store.getStream(ref.objectNumber) ?? { length: 0, chunks: [] };
63963
+ const dictionary = await isNull(dict) ? void 0 : dict;
63964
+ let length = 0;
63965
+ for await (const bytes of values.streamDictionary(dictionary, raw.length))
63966
+ length += bytes.length;
63967
+ await this.store.setSerializedValue({
63968
+ ...ref,
63969
+ body: { length, chunks: values.streamDictionary(dictionary, raw.length) },
63970
+ stream: raw
63971
+ });
63972
+ await this.remember(ref.objectNumber);
63973
+ await this.catalogs.set(BigInt(ref.objectNumber), 0n);
63974
+ } catch (error) {
63975
+ streamFailed = true;
63976
+ throw error;
63977
+ } finally {
63978
+ await staged?.close().catch((error) => {
63979
+ if (!streamFailed) throw error;
63980
+ });
63981
+ }
63982
+ } else if (value !== void 0) {
63983
+ if (await isNull(value)) {
63984
+ await this.store.delete(ref.objectNumber);
63985
+ await this.positions.set(BigInt(ref.objectNumber), 0n);
63986
+ await this.catalogs.set(BigInt(ref.objectNumber), 0n);
63987
+ } else {
63988
+ let length = 0;
63989
+ for await (const bytes of values.chunks(value)) length += bytes.length;
63990
+ await this.store.setSerializedValue({
63991
+ ...ref,
63992
+ body: { length, chunks: values.chunks(value) }
63993
+ });
63994
+ await this.remember(ref.objectNumber);
63995
+ const type = await values.property(value, "Type"), token2 = type === void 0 ? void 0 : await tree.smallText(type, 11);
63996
+ await this.catalogs.set(
63997
+ BigInt(ref.objectNumber),
63998
+ token2 === "/Catalog" || token2 === "n:/Catalog" || token2 === "n:Catalog" ? BigInt(ref.generationNumber + 1) : 0n
63999
+ );
64000
+ }
64001
+ }
64002
+ }
64003
+ if (!rootRef)
64004
+ for await (const [ordinal, number] of this.order.entries()) {
64005
+ await cooperate();
64006
+ if (await this.positions.get(number) !== ordinal) continue;
64007
+ const generation = await this.catalogs.get(number);
64008
+ if (generation) {
64009
+ rootRef = cosRef(Number(number), Number(generation) - 1);
64010
+ break;
64011
+ }
64012
+ }
64013
+ if (rootRef) this.rootRef = rootRef;
64014
+ if (infoRef) this.infoRef = infoRef;
64015
+ } catch (error) {
64016
+ failed = true;
64017
+ throw error;
64018
+ } finally {
64019
+ const results = await Promise.allSettled([values?.close(), tape.close(), scratch.close()]);
64020
+ if (!failed) {
64021
+ for (const result of results)
64022
+ if (result.status === "rejected") await Promise.reject(result.reason);
64023
+ }
64024
+ }
64025
+ }
64026
+ async *chunks(options = {}) {
64027
+ await this.pending;
64028
+ this.signal.throwIfAborted();
64029
+ if (!this.rootRef) throw new Error("missing trailer /Root");
64030
+ yield* serializeRetainedCosDocumentChunks(
64031
+ {
64032
+ ...options,
64033
+ objects: this.store.outputObjects(),
64034
+ rootRef: this.rootRef,
64035
+ infoRef: this.infoRef,
64036
+ signal: this.signal
64037
+ },
64038
+ this.storage
64039
+ );
64040
+ }
64041
+ close() {
64042
+ this.controller.abort(new PdfError("E_CANCELLED", "QPDF JSON document closed"));
64043
+ return this.closing ??= (async () => {
64044
+ await this.pending;
64045
+ const results = await Promise.allSettled([this.store.close(), this.backing.close()]);
64046
+ for (const result of results) if (result.status === "rejected") throw result.reason;
64047
+ })();
64048
+ }
64049
+ };
63580
64050
  export {
63581
64051
  CosByteLexer,
63582
64052
  CosRangeLexer,
@@ -63600,6 +64070,7 @@ export {
63600
64070
  PdfRetainedPage,
63601
64071
  PdfStagedOutputs,
63602
64072
  PdfStagingStorage,
64073
+ QpdfJsonDocument,
63603
64074
  QpdfJsonValues,
63604
64075
  STANDARD_14_FONTS,
63605
64076
  appendIncrementalRevision,