modern-pdf-lib 0.13.0 → 0.14.0

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 CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as colorToComponents, $t as setTextMatrix, A as beginMarkedContent, At as fill, B as radians, Bt as setLineJoin, C as AnnotationFlags, Ct as closeFillEvenOddAndStroke, D as createAnnotation, Dt as curveToInitial, E as buildAnnotationDict, Et as curveToFinal, F as endMarkedContent, Ft as moveTo, G as saveState, Gt as endText, H as restoreState, Ht as setMiterLimit, I as wrapInMarkedContent, It as rectangle, J as skew, Jt as nextLine, K as scale, Kt as moveText, L as concatMatrix, Lt as setDashPattern, M as beginMarkedContentWithProperties, Mt as fillEvenOdd, N as createMarkedContentScope, Nt as fillEvenOddAndStroke, O as beginArtifact, Ot as ellipsePath, P as endArtifact, Pt as lineTo, Q as cmyk, Qt as setLeading, R as degrees, Rt as setFlatness, S as parseSvgTransform, St as closeFillAndStroke, T as annotationFromDict, Tt as curveTo, U as rotate, Ut as stroke, V as radiansToDegrees, Vt as setLineWidth, W as rotationMatrix, Wt as beginText, X as applyFillColor, Xt as setFont, Y as translate, Yt as setCharacterSpacing, Z as applyStrokeColor, Zt as setFontSize, _ as drawSvgOnPage, _t as drawXObject, a as buildGradientObjects, an as showTextHex, at as setFillColorCmyk, b as parseSvgColor, bt as clipEvenOdd, c as radialGradient, ct as setFillingColor, d as getRedactionMarks, dt as setStrokeColorGray, en as setTextRenderingMode, et as componentsToColor, f as markForRedaction, ft as setStrokeColorRgb, g as endLayerContent, gt as drawImageXObject, h as beginLayerContent, ht as drawImageWithMatrix, i as wrapText, in as showTextArray, it as setFillColor, j as beginMarkedContentSequence, jt as fillAndStroke, k as beginArtifactWithType, kt as endPath, l as tilingPattern, lt as setStrokeColor, m as PdfLayerManager, mt as setStrokingColor, n as PdfPage, nn as setWordSpacing, nt as rgb, o as buildPatternObjects, on as showTextNextLine, ot as setFillColorGray, p as PdfLayer, pt as setStrokeColorSpace, q as setGraphicsState, qt as moveTextSetLeading, rn as showText, rt as setColorSpace, s as linearGradient, sn as showTextWithSpacing, st as setFillColorRgb, t as PageSizes, tn as setTextRise, tt as grayscale, u as applyRedactions, ut as setStrokeColorCmyk, v as svgToPdfOperators, vt as circlePath, w as PdfAnnotation, wt as closePath, x as parseSvgPath, xt as closeAndStroke, y as parseSvg, yt as clip, z as degreesToRadians, zt as setLineCap } from "./pdfPage-B7vA518n.mjs";
2
- import { a as formatPdfDate, c as PdfBool, d as PdfNull, f as PdfNumber, g as PdfString, h as PdfStream, i as buildPageTree, l as PdfDict, m as PdfRef, n as buildDocumentStructure, p as PdfObjectRegistry, r as buildInfoDict, s as PdfArray, t as buildCatalog, u as PdfName } from "./pdfCatalog-CTfeeqtF.mjs";
1
+ import { $ as colorToComponents, $t as setTextMatrix, A as beginMarkedContent, At as fill, B as radians, Bt as setLineJoin, C as AnnotationFlags, Ct as closeFillEvenOddAndStroke, D as createAnnotation, Dt as curveToInitial, E as buildAnnotationDict, Et as curveToFinal, F as endMarkedContent, Ft as moveTo, G as saveState, Gt as endText, H as restoreState, Ht as setMiterLimit, I as wrapInMarkedContent, It as rectangle, J as skew, Jt as nextLine, K as scale, Kt as moveText, L as concatMatrix, Lt as setDashPattern, M as beginMarkedContentWithProperties, Mt as fillEvenOdd, N as createMarkedContentScope, Nt as fillEvenOddAndStroke, O as beginArtifact, Ot as ellipsePath, P as endArtifact, Pt as lineTo, Q as cmyk, Qt as setLeading, R as degrees, Rt as setFlatness, S as parseSvgTransform, St as closeFillAndStroke, T as annotationFromDict, Tt as curveTo, U as rotate, Ut as stroke, V as radiansToDegrees, Vt as setLineWidth, W as rotationMatrix, Wt as beginText, X as applyFillColor, Xt as setFont, Y as translate, Yt as setCharacterSpacing, Z as applyStrokeColor, Zt as setFontSize, _ as drawSvgOnPage, _t as drawXObject, a as buildGradientObjects, an as showTextHex, at as setFillColorCmyk, b as parseSvgColor, bt as clipEvenOdd, c as radialGradient, ct as setFillingColor, d as getRedactionMarks, dt as setStrokeColorGray, en as setTextRenderingMode, et as componentsToColor, f as markForRedaction, ft as setStrokeColorRgb, g as endLayerContent, gt as drawImageXObject, h as beginLayerContent, ht as drawImageWithMatrix, i as wrapText, in as showTextArray, it as setFillColor, j as beginMarkedContentSequence, jt as fillAndStroke, k as beginArtifactWithType, kt as endPath, l as tilingPattern, lt as setStrokeColor, m as PdfLayerManager, mt as setStrokingColor, n as PdfPage, nn as setWordSpacing, nt as rgb, o as buildPatternObjects, on as showTextNextLine, ot as setFillColorGray, p as PdfLayer, pt as setStrokeColorSpace, q as setGraphicsState, qt as moveTextSetLeading, rn as showText, rt as setColorSpace, s as linearGradient, sn as showTextWithSpacing, st as setFillColorRgb, t as PageSizes, tn as setTextRise, tt as grayscale, u as applyRedactions, ut as setStrokeColorCmyk, v as svgToPdfOperators, vt as circlePath, w as PdfAnnotation, wt as closePath, x as parseSvgPath, xt as closeAndStroke, y as parseSvg, yt as clip, z as degreesToRadians, zt as setLineCap } from "./pdfPage-N1K2U3jI.mjs";
2
+ import { a as formatPdfDate, c as PdfBool, d as PdfNull, f as PdfNumber, g as PdfString, h as PdfStream, i as buildPageTree, l as PdfDict, m as PdfRef, n as buildDocumentStructure, p as PdfObjectRegistry, r as buildInfoDict, s as PdfArray, t as buildCatalog, u as PdfName } from "./pdfCatalog-BB2Wnmud.mjs";
3
3
  import { n as isAvailable, t as deflateSync$1 } from "./libdeflateWasm-DlHgU5oy.mjs";
4
4
  import { i as subsetFont, n as computeSubsetTag, t as buildSubsetCmap } from "./fontSubset-ZpLoOZ2e.mjs";
5
5
  import { t as embedPng } from "./pngEmbed-DTOqgEUC.mjs";
@@ -199,20 +199,19 @@ var PdfWriter = class {
199
199
  */
200
200
  writeObjectStream(entries, xrefEntries) {
201
201
  const serializedObjects = [];
202
- new StringByteWriter();
203
202
  for (const entry of entries) {
204
203
  const objWriter = new StringByteWriter();
205
204
  entry.object.serialize(objWriter);
206
205
  serializedObjects.push(objWriter.toUint8Array());
207
206
  }
208
- let headerStr = "";
207
+ const headerParts = [];
209
208
  let dataOffset = 0;
210
209
  for (let i = 0; i < entries.length; i++) {
211
- if (i > 0) headerStr += " ";
212
- headerStr += `${entries[i].ref.objectNumber} ${dataOffset}`;
210
+ headerParts.push(`${entries[i].ref.objectNumber} ${dataOffset}`);
213
211
  dataOffset += serializedObjects[i].length;
214
212
  if (i < entries.length - 1) dataOffset += 1;
215
213
  }
214
+ const headerStr = headerParts.join(" ");
216
215
  const headerBytes = encoder$5.encode(headerStr + " ");
217
216
  const firstOffset = headerBytes.length;
218
217
  let totalDataLen = firstOffset;
@@ -3754,7 +3753,7 @@ const isDelimiter = /* @__PURE__ */ (() => {
3754
3753
  * `hexVal[b]` is the numeric value (0-15) of a hex character, or -1 if
3755
3754
  * the byte is not a valid hex digit.
3756
3755
  */
3757
- const hexVal = /* @__PURE__ */ (() => {
3756
+ const hexVal$1 = /* @__PURE__ */ (() => {
3758
3757
  const t = new Int8Array(256).fill(-1);
3759
3758
  for (let i = 0; i <= 9; i++) t[CH_0 + i] = i;
3760
3759
  for (let i = 0; i < 6; i++) {
@@ -4051,7 +4050,7 @@ var PdfLexer = class {
4051
4050
  const d = this._data;
4052
4051
  let pos = startPos + 1;
4053
4052
  let depth = 1;
4054
- let result = "";
4053
+ const parts = [];
4055
4054
  while (pos < this.len && depth > 0) {
4056
4055
  const c = d[pos];
4057
4056
  if (c === CH_BACKSLASH) {
@@ -4060,35 +4059,35 @@ var PdfLexer = class {
4060
4059
  const esc = d[pos];
4061
4060
  switch (esc) {
4062
4061
  case 110:
4063
- result += "\n";
4062
+ parts.push("\n");
4064
4063
  pos++;
4065
4064
  break;
4066
4065
  case 114:
4067
- result += "\r";
4066
+ parts.push("\r");
4068
4067
  pos++;
4069
4068
  break;
4070
4069
  case 116:
4071
- result += " ";
4070
+ parts.push(" ");
4072
4071
  pos++;
4073
4072
  break;
4074
4073
  case 98:
4075
- result += "\b";
4074
+ parts.push("\b");
4076
4075
  pos++;
4077
4076
  break;
4078
4077
  case 102:
4079
- result += "\f";
4078
+ parts.push("\f");
4080
4079
  pos++;
4081
4080
  break;
4082
4081
  case CH_LPAREN:
4083
- result += "(";
4082
+ parts.push("(");
4084
4083
  pos++;
4085
4084
  break;
4086
4085
  case CH_RPAREN:
4087
- result += ")";
4086
+ parts.push(")");
4088
4087
  pos++;
4089
4088
  break;
4090
4089
  case CH_BACKSLASH:
4091
- result += "\\";
4090
+ parts.push("\\");
4092
4091
  pos++;
4093
4092
  break;
4094
4093
  case WS_LF:
@@ -4110,9 +4109,9 @@ var PdfLexer = class {
4110
4109
  pos++;
4111
4110
  }
4112
4111
  }
4113
- result += String.fromCharCode(octal & 255);
4112
+ parts.push(String.fromCharCode(octal & 255));
4114
4113
  } else {
4115
- result += String.fromCharCode(esc);
4114
+ parts.push(String.fromCharCode(esc));
4116
4115
  pos++;
4117
4116
  }
4118
4117
  break;
@@ -4121,23 +4120,23 @@ var PdfLexer = class {
4121
4120
  }
4122
4121
  if (c === CH_LPAREN) {
4123
4122
  depth++;
4124
- result += "(";
4123
+ parts.push("(");
4125
4124
  pos++;
4126
4125
  continue;
4127
4126
  }
4128
4127
  if (c === CH_RPAREN) {
4129
4128
  depth--;
4130
- if (depth > 0) result += ")";
4129
+ if (depth > 0) parts.push(")");
4131
4130
  pos++;
4132
4131
  continue;
4133
4132
  }
4134
4133
  if (c === WS_CR) {
4135
- result += "\n";
4134
+ parts.push("\n");
4136
4135
  pos++;
4137
4136
  if (pos < this.len && d[pos] === WS_LF) pos++;
4138
4137
  continue;
4139
4138
  }
4140
- result += String.fromCharCode(c);
4139
+ parts.push(String.fromCharCode(c));
4141
4140
  pos++;
4142
4141
  }
4143
4142
  if (depth !== 0) throw new PdfParseError({
@@ -4150,7 +4149,7 @@ var PdfLexer = class {
4150
4149
  this.position = pos;
4151
4150
  return {
4152
4151
  type: TokenType$1.LiteralString,
4153
- value: result,
4152
+ value: parts.join(""),
4154
4153
  offset: startPos
4155
4154
  };
4156
4155
  }
@@ -4163,7 +4162,8 @@ var PdfLexer = class {
4163
4162
  readHexString(startPos) {
4164
4163
  const d = this._data;
4165
4164
  let pos = startPos + 1;
4166
- let hex = "";
4165
+ const bytes = [];
4166
+ let hi = -1;
4167
4167
  while (pos < this.len) {
4168
4168
  const c = d[pos];
4169
4169
  if (c === CH_GT) {
@@ -4174,27 +4174,26 @@ var PdfLexer = class {
4174
4174
  pos++;
4175
4175
  continue;
4176
4176
  }
4177
- if (hexVal[c] === -1) throw new PdfParseError({
4177
+ const v = hexVal$1[c];
4178
+ if (v === -1) throw new PdfParseError({
4178
4179
  message: `PdfLexer: invalid hex digit 0x${c.toString(16).padStart(2, "0")} at offset ${pos} in hex string starting at ${startPos}`,
4179
4180
  offset: pos,
4180
4181
  expected: "hex digit (0-9, a-f, A-F)",
4181
4182
  actual: `0x${c.toString(16).padStart(2, "0")}`,
4182
4183
  data: this._data
4183
4184
  });
4184
- hex += String.fromCharCode(c);
4185
+ if (hi === -1) hi = v;
4186
+ else {
4187
+ bytes.push(hi << 4 | v);
4188
+ hi = -1;
4189
+ }
4185
4190
  pos++;
4186
4191
  }
4187
- if (hex.length % 2 !== 0) hex += "0";
4188
- let result = "";
4189
- for (let i = 0; i < hex.length; i += 2) {
4190
- const hi = hexVal[hex.charCodeAt(i)];
4191
- const lo = hexVal[hex.charCodeAt(i + 1)];
4192
- result += String.fromCharCode(hi << 4 | lo);
4193
- }
4192
+ if (hi !== -1) bytes.push(hi << 4);
4194
4193
  this.position = pos;
4195
4194
  return {
4196
4195
  type: TokenType$1.HexString,
4197
- value: result,
4196
+ value: String.fromCharCode.apply(null, bytes),
4198
4197
  offset: startPos
4199
4198
  };
4200
4199
  }
@@ -4207,7 +4206,7 @@ var PdfLexer = class {
4207
4206
  readName(startPos) {
4208
4207
  const d = this._data;
4209
4208
  let pos = startPos + 1;
4210
- let name = "/";
4209
+ const parts = ["/"];
4211
4210
  while (pos < this.len) {
4212
4211
  const c = d[pos];
4213
4212
  if (isWhitespace[c] || isDelimiter[c]) break;
@@ -4219,8 +4218,8 @@ var PdfLexer = class {
4219
4218
  actual: "end of input",
4220
4219
  data: this._data
4221
4220
  });
4222
- const hi = hexVal[d[pos + 1]];
4223
- const lo = hexVal[d[pos + 2]];
4221
+ const hi = hexVal$1[d[pos + 1]];
4222
+ const lo = hexVal$1[d[pos + 2]];
4224
4223
  if (hi === -1 || lo === -1) throw new PdfParseError({
4225
4224
  message: `PdfLexer: invalid #XX escape in name at offset ${pos}`,
4226
4225
  offset: pos,
@@ -4228,17 +4227,17 @@ var PdfLexer = class {
4228
4227
  actual: `#${String.fromCharCode(d[pos + 1])}${String.fromCharCode(d[pos + 2])}`,
4229
4228
  data: this._data
4230
4229
  });
4231
- name += String.fromCharCode(hi << 4 | lo);
4230
+ parts.push(String.fromCharCode(hi << 4 | lo));
4232
4231
  pos += 3;
4233
4232
  continue;
4234
4233
  }
4235
- name += String.fromCharCode(c);
4234
+ parts.push(String.fromCharCode(c));
4236
4235
  pos++;
4237
4236
  }
4238
4237
  this.position = pos;
4239
4238
  return {
4240
4239
  type: TokenType$1.Name,
4241
- value: name,
4240
+ value: parts.join(""),
4242
4241
  offset: startPos
4243
4242
  };
4244
4243
  }
@@ -4353,10 +4352,7 @@ var PdfLexer = class {
4353
4352
  * because it avoids the per-call overhead of the streaming decoder.
4354
4353
  */
4355
4354
  bytesToAscii(from, to) {
4356
- const d = this._data;
4357
- let s = "";
4358
- for (let i = from; i < to; i++) s += String.fromCharCode(d[i]);
4359
- return s;
4355
+ return String.fromCharCode.apply(null, this._data.subarray(from, to));
4360
4356
  }
4361
4357
  };
4362
4358
 
@@ -5250,18 +5246,20 @@ var XrefParser = class {
5250
5246
  parseTraditionalXref(offset) {
5251
5247
  const entries = [];
5252
5248
  let pos = offset;
5253
- const xrefTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 4));
5254
- if (xrefTag !== "xref") throw new PdfParseError({
5255
- message: `Invalid PDF: expected "xref" keyword at offset ${offset}, found "${xrefTag}".`,
5256
- offset,
5257
- expected: "\"xref\" keyword",
5258
- actual: `"${xrefTag}"`,
5259
- data: this.data
5260
- });
5249
+ if (!this.isTraditionalXref(pos)) {
5250
+ const xrefTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 4));
5251
+ throw new PdfParseError({
5252
+ message: `Invalid PDF: expected "xref" keyword at offset ${offset}, found "${xrefTag}".`,
5253
+ offset,
5254
+ expected: "\"xref\" keyword",
5255
+ actual: `"${xrefTag}"`,
5256
+ data: this.data
5257
+ });
5258
+ }
5261
5259
  pos += 4;
5262
5260
  pos = this.skipWhitespaceAt(pos);
5263
5261
  while (pos < this.data.length) {
5264
- if (TEXT_DECODER$1.decode(this.data.subarray(pos, Math.min(pos + 7, this.data.length))).startsWith("trailer")) break;
5262
+ if (this.matchesBytes(pos, 116, 114, 97, 105, 108, 101, 114)) break;
5265
5263
  const headerLine = this.readLineAt(pos);
5266
5264
  const headerMatch = headerLine.text.trim().match(/^(\d+)\s+(\d+)/);
5267
5265
  if (!headerMatch) throw new PdfParseError({
@@ -5276,35 +5274,45 @@ var XrefParser = class {
5276
5274
  pos = headerLine.nextPos;
5277
5275
  for (let i = 0; i < count; i++) {
5278
5276
  const objectNumber = firstObjNum + i;
5279
- const entryText = this.readXrefEntryAt(pos);
5280
- const entryMatch = entryText.text.trim().match(/^(\d{10})\s+(\d{5})\s+([fn])/);
5281
- if (!entryMatch) throw new PdfParseError({
5282
- message: `Invalid PDF: malformed xref entry at offset ${pos} for object ${objectNumber}: "${entryText.text.trim()}"`,
5283
- offset: pos,
5284
- expected: "xref entry \"OOOOOOOOOO GGGGG f/n\"",
5285
- actual: `"${entryText.text.trim()}"`,
5286
- data: this.data
5287
- });
5288
- const entryOffset = parseInt(entryMatch[1], 10);
5289
- const gen = parseInt(entryMatch[2], 10);
5290
- const marker = entryMatch[3];
5291
- entries.push({
5292
- objectNumber,
5293
- generationNumber: gen,
5294
- offset: entryOffset,
5295
- type: marker === "n" ? "in-use" : "free"
5296
- });
5297
- pos = entryText.nextPos;
5277
+ const parsed = this.parseXrefEntryDirect(pos);
5278
+ if (parsed) {
5279
+ entries.push({
5280
+ objectNumber,
5281
+ generationNumber: parsed.gen,
5282
+ offset: parsed.offset,
5283
+ type: parsed.type
5284
+ });
5285
+ pos = parsed.nextPos;
5286
+ } else {
5287
+ const entryText = this.readXrefEntryAt(pos);
5288
+ const entryMatch = entryText.text.trim().match(/^(\d{10})\s+(\d{5})\s+([fn])/);
5289
+ if (!entryMatch) throw new PdfParseError({
5290
+ message: `Invalid PDF: malformed xref entry at offset ${pos} for object ${objectNumber}: "${entryText.text.trim()}"`,
5291
+ offset: pos,
5292
+ expected: "xref entry \"OOOOOOOOOO GGGGG f/n\"",
5293
+ actual: `"${entryText.text.trim()}"`,
5294
+ data: this.data
5295
+ });
5296
+ entries.push({
5297
+ objectNumber,
5298
+ generationNumber: parseInt(entryMatch[2], 10),
5299
+ offset: parseInt(entryMatch[1], 10),
5300
+ type: entryMatch[3] === "n" ? "in-use" : "free"
5301
+ });
5302
+ pos = entryText.nextPos;
5303
+ }
5298
5304
  }
5299
5305
  }
5300
- const trailerTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 7));
5301
- if (trailerTag !== "trailer") throw new PdfParseError({
5302
- message: `Invalid PDF: expected "trailer" keyword at offset ${pos}, found "${trailerTag}".`,
5303
- offset: pos,
5304
- expected: "\"trailer\" keyword",
5305
- actual: `"${trailerTag}"`,
5306
- data: this.data
5307
- });
5306
+ if (!this.matchesBytes(pos, 116, 114, 97, 105, 108, 101, 114)) {
5307
+ const trailerTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 7));
5308
+ throw new PdfParseError({
5309
+ message: `Invalid PDF: expected "trailer" keyword at offset ${pos}, found "${trailerTag}".`,
5310
+ offset: pos,
5311
+ expected: "\"trailer\" keyword",
5312
+ actual: `"${trailerTag}"`,
5313
+ data: this.data
5314
+ });
5315
+ }
5308
5316
  pos += 7;
5309
5317
  const trailerObj = this.objectParser.parseObjectAt(pos);
5310
5318
  if (trailerObj.kind !== "dict") throw new PdfParseError({
@@ -5459,17 +5467,33 @@ var XrefParser = class {
5459
5467
  */
5460
5468
  rebuildXrefFromScan() {
5461
5469
  const entries = /* @__PURE__ */ new Map();
5462
- const fileText = TEXT_DECODER$1.decode(this.data);
5463
- const objPattern = /(\d+)\s+(\d+)\s+obj\b/g;
5464
- let match;
5465
- while ((match = objPattern.exec(fileText)) !== null) {
5466
- const objectNumber = parseInt(match[1], 10);
5467
- const gen = parseInt(match[2], 10);
5468
- const offset = match.index;
5470
+ const d = this.data;
5471
+ const len = d.length;
5472
+ for (let i = 0; i < len - 2; i++) {
5473
+ if (d[i] !== 111 || d[i + 1] !== 98 || d[i + 2] !== 106) continue;
5474
+ if (i + 3 < len) {
5475
+ const after = d[i + 3];
5476
+ if (after > 32 && after !== 37 && after !== 40 && after !== 41 && after !== 47 && after !== 60 && after !== 62 && after !== 91 && after !== 93 && after !== 123 && after !== 125) continue;
5477
+ }
5478
+ let j = i - 1;
5479
+ while (j >= 0 && (d[j] === 32 || d[j] === 10 || d[j] === 13 || d[j] === 9 || d[j] === 0)) j--;
5480
+ const genEnd = j + 1;
5481
+ while (j >= 0 && d[j] >= 48 && d[j] <= 57) j--;
5482
+ const genStart = j + 1;
5483
+ if (genStart >= genEnd) continue;
5484
+ while (j >= 0 && (d[j] === 32 || d[j] === 10 || d[j] === 13 || d[j] === 9 || d[j] === 0)) j--;
5485
+ const objEnd = j + 1;
5486
+ while (j >= 0 && d[j] >= 48 && d[j] <= 57) j--;
5487
+ const objStart = j + 1;
5488
+ if (objStart >= objEnd) continue;
5489
+ let objectNumber = 0;
5490
+ for (let k = objStart; k < objEnd; k++) objectNumber = objectNumber * 10 + (d[k] - 48);
5491
+ let gen = 0;
5492
+ for (let k = genStart; k < genEnd; k++) gen = gen * 10 + (d[k] - 48);
5469
5493
  entries.set(objectNumber, {
5470
5494
  objectNumber,
5471
5495
  generationNumber: gen,
5472
- offset,
5496
+ offset: objStart,
5473
5497
  type: "in-use"
5474
5498
  });
5475
5499
  }
@@ -5482,7 +5506,11 @@ var XrefParser = class {
5482
5506
  });
5483
5507
  let rootRef;
5484
5508
  let infoRef;
5485
- const trailerIdx = fileText.lastIndexOf("trailer");
5509
+ let trailerIdx = -1;
5510
+ for (let i = len - 7; i >= 0; i--) if (d[i] === 116 && d[i + 1] === 114 && d[i + 2] === 97 && d[i + 3] === 105 && d[i + 4] === 108 && d[i + 5] === 101 && d[i + 6] === 114) {
5511
+ trailerIdx = i;
5512
+ break;
5513
+ }
5486
5514
  if (trailerIdx !== -1) try {
5487
5515
  const trailerObj = this.objectParser.parseObjectAt(trailerIdx + 7);
5488
5516
  if (trailerObj.kind === "dict") {
@@ -5523,6 +5551,48 @@ var XrefParser = class {
5523
5551
  * Determine whether the data at the given offset starts with the
5524
5552
  * "xref" keyword (indicating a traditional xref table).
5525
5553
  */
5554
+ /**
5555
+ * Check if the bytes at `pos` match the given byte values.
5556
+ */
5557
+ matchesBytes(pos, ...bytes) {
5558
+ if (pos + bytes.length > this.data.length) return false;
5559
+ for (let i = 0; i < bytes.length; i++) if (this.data[pos + i] !== bytes[i]) return false;
5560
+ return true;
5561
+ }
5562
+ /**
5563
+ * Parse a standard xref entry directly from bytes, avoiding TextDecoder
5564
+ * and regex. Returns null if the bytes don't form a valid entry.
5565
+ *
5566
+ * Standard format: `OOOOOOOOOO GGGGG f/n` (18 significant bytes)
5567
+ */
5568
+ parseXrefEntryDirect(pos) {
5569
+ const d = this.data;
5570
+ if (pos + 18 > d.length) return null;
5571
+ let offset = 0;
5572
+ for (let k = 0; k < 10; k++) {
5573
+ const b = d[pos + k];
5574
+ if (b < 48 || b > 57) return null;
5575
+ offset = offset * 10 + (b - 48);
5576
+ }
5577
+ if (d[pos + 10] !== 32) return null;
5578
+ let gen = 0;
5579
+ for (let k = 0; k < 5; k++) {
5580
+ const b = d[pos + 11 + k];
5581
+ if (b < 48 || b > 57) return null;
5582
+ gen = gen * 10 + (b - 48);
5583
+ }
5584
+ if (d[pos + 16] !== 32) return null;
5585
+ const marker = d[pos + 17];
5586
+ if (marker !== 110 && marker !== 102) return null;
5587
+ let nextPos = pos + 18;
5588
+ while (nextPos < d.length && (d[nextPos] === 32 || d[nextPos] === 13 || d[nextPos] === 10)) nextPos++;
5589
+ return {
5590
+ offset,
5591
+ gen,
5592
+ type: marker === 110 ? "in-use" : "free",
5593
+ nextPos
5594
+ };
5595
+ }
5526
5596
  isTraditionalXref(offset) {
5527
5597
  if (offset + 4 > this.data.length) return false;
5528
5598
  return this.data[offset] === 120 && this.data[offset + 1] === 114 && this.data[offset + 2] === 101 && this.data[offset + 3] === 102;
@@ -6320,10 +6390,12 @@ function computeOwnerPasswordValue(ownerPassword, userPassword, revision, keyLen
6320
6390
  if (revision >= 3) for (let i = 0; i < 50; i++) hash = md5(hash.subarray(0, keyByteLength));
6321
6391
  const rc4Key = hash.subarray(0, keyByteLength);
6322
6392
  let encrypted = rc4(rc4Key, padPassword(userPassword));
6323
- if (revision >= 3) for (let i = 1; i <= 19; i++) {
6393
+ if (revision >= 3) {
6324
6394
  const modKey = new Uint8Array(rc4Key.length);
6325
- for (let j = 0; j < rc4Key.length; j++) modKey[j] = (rc4Key[j] ^ i) & 255;
6326
- encrypted = rc4(modKey, encrypted);
6395
+ for (let i = 1; i <= 19; i++) {
6396
+ for (let j = 0; j < rc4Key.length; j++) modKey[j] = (rc4Key[j] ^ i) & 255;
6397
+ encrypted = rc4(modKey, encrypted);
6398
+ }
6327
6399
  }
6328
6400
  return encrypted;
6329
6401
  }
@@ -6353,10 +6425,12 @@ function computeUserPasswordR2(fileKey) {
6353
6425
  */
6354
6426
  function computeUserPasswordR3R4(fileKey, fileId) {
6355
6427
  let encrypted = rc4(fileKey, md5(concat$1(PASSWORD_PADDING, fileId)));
6356
- for (let i = 1; i <= 19; i++) {
6428
+ {
6357
6429
  const modKey = new Uint8Array(fileKey.length);
6358
- for (let j = 0; j < fileKey.length; j++) modKey[j] = (fileKey[j] ^ i) & 255;
6359
- encrypted = rc4(modKey, encrypted);
6430
+ for (let i = 1; i <= 19; i++) {
6431
+ for (let j = 0; j < fileKey.length; j++) modKey[j] = (fileKey[j] ^ i) & 255;
6432
+ encrypted = rc4(modKey, encrypted);
6433
+ }
6360
6434
  }
6361
6435
  const result = new Uint8Array(32);
6362
6436
  result.set(encrypted.subarray(0, 16));
@@ -6422,9 +6496,17 @@ async function algorithm2B(password, salt, uKey) {
6422
6496
  let K = await sha256(uKey ? concat$1(password, salt, uKey) : concat$1(password, salt));
6423
6497
  let round = 0;
6424
6498
  while (true) {
6425
- const K1block = uKey ? concat$1(password, K, uKey) : concat$1(password, K);
6426
- const K1 = new Uint8Array(K1block.length * 64);
6427
- for (let i = 0; i < 64; i++) K1.set(K1block, i * K1block.length);
6499
+ const pLen = password.length;
6500
+ const kLen = K.length;
6501
+ const uLen = uKey ? uKey.length : 0;
6502
+ const blockLen = pLen + kLen + uLen;
6503
+ const K1 = new Uint8Array(blockLen * 64);
6504
+ for (let i = 0; i < 64; i++) {
6505
+ const base = i * blockLen;
6506
+ K1.set(password, base);
6507
+ K1.set(K, base + pLen);
6508
+ if (uKey) K1.set(uKey, base + pLen + kLen);
6509
+ }
6428
6510
  const E = await aesEncryptCBCNoPad(K.subarray(0, 16), K.subarray(16, 32), K1);
6429
6511
  let bigModVal = 0;
6430
6512
  for (let i = 0; i < 16; i++) bigModVal = (bigModVal * 256 + E[i]) % 3;
@@ -8576,7 +8658,17 @@ const NS_PDFAID = "http://www.aiim.org/pdfa/ns/id/";
8576
8658
  * @internal
8577
8659
  */
8578
8660
  function escapeXml(str) {
8579
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
8661
+ const parts = [];
8662
+ for (let i = 0; i < str.length; i++) {
8663
+ const c = str.charCodeAt(i);
8664
+ if (c === 38) parts.push("&amp;");
8665
+ else if (c === 60) parts.push("&lt;");
8666
+ else if (c === 62) parts.push("&gt;");
8667
+ else if (c === 34) parts.push("&quot;");
8668
+ else if (c === 39) parts.push("&apos;");
8669
+ else parts.push(str[i]);
8670
+ }
8671
+ return parts.join("");
8580
8672
  }
8581
8673
  /**
8582
8674
  * Format a Date as an ISO 8601 string for XMP.
@@ -9879,9 +9971,10 @@ function remapRef$1(sourceRef, context) {
9879
9971
  context.refMap.set(sourceRef.objectNumber, placeholderRef);
9880
9972
  return placeholderRef;
9881
9973
  }
9974
+ let streamHash;
9882
9975
  if (sourceObj.kind === "stream") {
9883
- const hash = hashBytes(sourceObj.data);
9884
- const dedup = context.hashMap.get(hash);
9976
+ streamHash = hashBytes(sourceObj.data);
9977
+ const dedup = context.hashMap.get(streamHash);
9885
9978
  if (dedup) {
9886
9979
  context.refMap.set(sourceRef.objectNumber, dedup);
9887
9980
  return dedup;
@@ -9891,10 +9984,7 @@ function remapRef$1(sourceRef, context) {
9891
9984
  context.refMap.set(sourceRef.objectNumber, targetRef);
9892
9985
  const clonedObj = deepClone$1(sourceObj, context);
9893
9986
  context.targetRegistry.assign(targetRef, clonedObj);
9894
- if (sourceObj.kind === "stream") {
9895
- const hash = hashBytes(sourceObj.data);
9896
- context.hashMap.set(hash, targetRef);
9897
- }
9987
+ if (streamHash !== void 0) context.hashMap.set(streamHash, targetRef);
9898
9988
  return targetRef;
9899
9989
  }
9900
9990
  /**
@@ -14473,7 +14563,6 @@ function read2DMode(reader) {
14473
14563
  if (bit === 1) {
14474
14564
  bit = reader.readBit();
14475
14565
  if (bit < 0) return Mode2D.EOL;
14476
- if (bit === 1) return Mode2D.HORIZONTAL;
14477
14566
  if (bit === 0) return Mode2D.VERTICAL_MINUS_1;
14478
14567
  return Mode2D.VERTICAL_PLUS_1;
14479
14568
  }
@@ -17604,9 +17693,28 @@ function hexValue(ch) {
17604
17693
  * `~>` marks end-of-data.
17605
17694
  */
17606
17695
  function decodeASCII85(data) {
17607
- const result = [];
17608
- const group = [];
17696
+ let out = new Uint8Array(Math.max(data.length * 4 / 5 | 0, 256));
17697
+ let outPos = 0;
17698
+ const group = new Uint8Array(5);
17699
+ let groupLen = 0;
17609
17700
  let i = 0;
17701
+ function ensureOut(needed) {
17702
+ if (outPos + needed > out.length) {
17703
+ const newBuf = new Uint8Array(Math.max(out.length * 2, outPos + needed));
17704
+ newBuf.set(out.subarray(0, outPos));
17705
+ out = newBuf;
17706
+ }
17707
+ }
17708
+ function decodeGroup(count) {
17709
+ for (let k = count; k < 5; k++) group[k] = 84;
17710
+ const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
17711
+ const numBytes = count === 5 ? 4 : count - 1;
17712
+ ensureOut(numBytes);
17713
+ if (numBytes >= 1) out[outPos++] = val >>> 24 & 255;
17714
+ if (numBytes >= 2) out[outPos++] = val >>> 16 & 255;
17715
+ if (numBytes >= 3) out[outPos++] = val >>> 8 & 255;
17716
+ if (numBytes >= 4) out[outPos++] = val & 255;
17717
+ }
17610
17718
  while (i < data.length) {
17611
17719
  const ch = data[i];
17612
17720
  if (ch === 126) break;
@@ -17615,8 +17723,12 @@ function decodeASCII85(data) {
17615
17723
  continue;
17616
17724
  }
17617
17725
  if (ch === 122) {
17618
- if (group.length > 0) throw new Error("ASCII85Decode: \"z\" inside a group");
17619
- result.push(0, 0, 0, 0);
17726
+ if (groupLen > 0) throw new Error("ASCII85Decode: \"z\" inside a group");
17727
+ ensureOut(4);
17728
+ out[outPos++] = 0;
17729
+ out[outPos++] = 0;
17730
+ out[outPos++] = 0;
17731
+ out[outPos++] = 0;
17620
17732
  i++;
17621
17733
  continue;
17622
17734
  }
@@ -17624,24 +17736,15 @@ function decodeASCII85(data) {
17624
17736
  i++;
17625
17737
  continue;
17626
17738
  }
17627
- group.push(ch - 33);
17628
- if (group.length === 5) {
17629
- const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
17630
- result.push(val >>> 24 & 255, val >>> 16 & 255, val >>> 8 & 255, val & 255);
17631
- group.length = 0;
17739
+ group[groupLen++] = ch - 33;
17740
+ if (groupLen === 5) {
17741
+ decodeGroup(5);
17742
+ groupLen = 0;
17632
17743
  }
17633
17744
  i++;
17634
17745
  }
17635
- if (group.length >= 2) {
17636
- const origLen = group.length;
17637
- while (group.length < 5) group.push(84);
17638
- const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
17639
- const numBytes = origLen - 1;
17640
- if (numBytes >= 1) result.push(val >>> 24 & 255);
17641
- if (numBytes >= 2) result.push(val >>> 16 & 255);
17642
- if (numBytes >= 3) result.push(val >>> 8 & 255);
17643
- }
17644
- return new Uint8Array(result);
17746
+ if (groupLen >= 2) decodeGroup(groupLen);
17747
+ return out.subarray(0, outPos);
17645
17748
  }
17646
17749
  /**
17647
17750
  * Decode an LZWDecode stream.
@@ -17661,6 +17764,10 @@ function decodeLZW(data, parms) {
17661
17764
  }
17662
17765
  /**
17663
17766
  * Core LZW decompression.
17767
+ *
17768
+ * Uses a flat pooled buffer for the code table instead of per-entry
17769
+ * Uint8Array allocations, and a pre-allocated output buffer with
17770
+ * manual growth instead of `number[]` + push.
17664
17771
  */
17665
17772
  function lzwDecompress(data, earlyChange) {
17666
17773
  const CLEAR_TABLE = 256;
@@ -17685,71 +17792,88 @@ function lzwDecompress(data, earlyChange) {
17685
17792
  }
17686
17793
  return result;
17687
17794
  }
17688
- let table = [];
17795
+ let tableBuf = new Uint8Array(65536);
17796
+ const tableOff = new Int32Array(4096);
17797
+ const tableLen = new Int32Array(4096);
17798
+ let tableBufUsed = 256;
17689
17799
  let codeSize = 9;
17690
17800
  let nextCode = 258;
17801
+ for (let i = 0; i < 256; i++) {
17802
+ tableBuf[i] = i;
17803
+ tableOff[i] = i;
17804
+ tableLen[i] = 1;
17805
+ }
17691
17806
  function resetTable() {
17692
- table = [];
17693
- for (let i = 0; i < 256; i++) table[i] = new Uint8Array([i]);
17694
- table[256] = new Uint8Array(0);
17695
- table[257] = new Uint8Array(0);
17807
+ tableBufUsed = 256;
17696
17808
  nextCode = 258;
17697
17809
  codeSize = 9;
17698
17810
  }
17699
- resetTable();
17700
- const output = [];
17701
- let prevEntry = null;
17811
+ let out = new Uint8Array(Math.max(data.length * 3, 4096));
17812
+ let outPos = 0;
17813
+ function ensureOut(needed) {
17814
+ if (outPos + needed > out.length) {
17815
+ const newBuf = new Uint8Array(Math.max(out.length * 2, outPos + needed));
17816
+ newBuf.set(out.subarray(0, outPos));
17817
+ out = newBuf;
17818
+ }
17819
+ }
17820
+ function ensureTable(needed) {
17821
+ if (tableBufUsed + needed > tableBuf.length) {
17822
+ const newBuf = new Uint8Array(Math.max(tableBuf.length * 2, tableBufUsed + needed));
17823
+ newBuf.set(tableBuf.subarray(0, tableBufUsed));
17824
+ tableBuf = newBuf;
17825
+ }
17826
+ }
17827
+ function writeEntry(code) {
17828
+ const off = tableOff[code];
17829
+ const len = tableLen[code];
17830
+ ensureOut(len);
17831
+ out.set(tableBuf.subarray(off, off + len), outPos);
17832
+ outPos += len;
17833
+ }
17834
+ function addEntry(prevCode, firstByte) {
17835
+ const prevOff = tableOff[prevCode];
17836
+ const prevLen = tableLen[prevCode];
17837
+ const newLen = prevLen + 1;
17838
+ ensureTable(newLen);
17839
+ tableBuf.set(tableBuf.subarray(prevOff, prevOff + prevLen), tableBufUsed);
17840
+ tableBuf[tableBufUsed + prevLen] = firstByte;
17841
+ tableOff[nextCode] = tableBufUsed;
17842
+ tableLen[nextCode] = newLen;
17843
+ tableBufUsed += newLen;
17844
+ nextCode++;
17845
+ }
17702
17846
  let code = readBits(codeSize);
17703
17847
  if (code === CLEAR_TABLE) {
17704
17848
  resetTable();
17705
17849
  code = readBits(codeSize);
17706
17850
  }
17707
- if (code === EOD) return new Uint8Array(output);
17708
- let entry = table[code];
17709
- if (entry) {
17710
- for (const b of entry) output.push(b);
17711
- prevEntry = entry;
17712
- }
17851
+ if (code === EOD) return new Uint8Array(0);
17852
+ writeEntry(code);
17853
+ let prevCode = code;
17713
17854
  while (true) {
17714
17855
  code = readBits(codeSize);
17715
17856
  if (code === EOD) break;
17716
17857
  if (code === CLEAR_TABLE) {
17717
17858
  resetTable();
17718
- prevEntry = null;
17719
17859
  code = readBits(codeSize);
17720
17860
  if (code === EOD) break;
17721
- entry = table[code];
17722
- if (entry) {
17723
- for (const b of entry) output.push(b);
17724
- prevEntry = entry;
17725
- }
17861
+ writeEntry(code);
17862
+ prevCode = code;
17726
17863
  continue;
17727
17864
  }
17728
- if (code < nextCode && table[code]) {
17729
- entry = table[code];
17730
- for (const b of entry) output.push(b);
17731
- if (prevEntry) {
17732
- const newEntry = new Uint8Array(prevEntry.length + 1);
17733
- newEntry.set(prevEntry);
17734
- newEntry[prevEntry.length] = entry[0];
17735
- table[nextCode] = newEntry;
17736
- nextCode++;
17737
- }
17865
+ if (code < nextCode) {
17866
+ writeEntry(code);
17867
+ addEntry(prevCode, tableBuf[tableOff[code]]);
17738
17868
  } else {
17739
- if (!prevEntry) throw new Error("LZWDecode: invalid code sequence");
17740
- const newEntry = new Uint8Array(prevEntry.length + 1);
17741
- newEntry.set(prevEntry);
17742
- newEntry[prevEntry.length] = prevEntry[0];
17743
- for (const b of newEntry) output.push(b);
17744
- table[nextCode] = newEntry;
17745
- nextCode++;
17746
- entry = newEntry;
17747
- }
17748
- prevEntry = entry;
17869
+ addEntry(prevCode, tableBuf[tableOff[prevCode]]);
17870
+ writeEntry(nextCode - 1);
17871
+ }
17872
+ prevCode = code;
17749
17873
  const threshold = (1 << codeSize) - earlyChange;
17750
17874
  if (nextCode >= threshold && codeSize < 12) codeSize++;
17751
17875
  }
17752
- return new Uint8Array(output);
17876
+ return out.subarray(0, outPos);
17753
17877
  }
17754
17878
  /**
17755
17879
  * Decode a RunLengthDecode stream.
@@ -17881,7 +18005,6 @@ function embedPageAsFormXObject(page, sourceRegistry, targetRegistry, xObjectNam
17881
18005
  const pageWidth = page.width;
17882
18006
  const pageHeight = page.height;
17883
18007
  const contentChunks = [];
17884
- new TextDecoder();
17885
18008
  const originalRefs = page.getOriginalContentRefs();
17886
18009
  for (const ref of originalRefs) {
17887
18010
  const obj = sourceRegistry.resolve(ref);
@@ -18399,7 +18522,7 @@ var PdfDocument = class PdfDocument {
18399
18522
  async embedTrueTypeFont(fontData, options) {
18400
18523
  const embeddedFont = await embedFont(fontData);
18401
18524
  const metrics = embeddedFont.metrics;
18402
- const psName = options?.customName || metrics.postScriptName || metrics.familyName || "CustomFont";
18525
+ const psName = options?.customName ?? metrics.postScriptName ?? metrics.familyName ?? "CustomFont";
18403
18526
  const existing = this.embeddedFonts.get(`__ttf__${psName}`);
18404
18527
  if (existing) return existing;
18405
18528
  this.fontCounter++;
@@ -18514,7 +18637,7 @@ var PdfDocument = class PdfDocument {
18514
18637
  async embedCffFont(fontData, options) {
18515
18638
  const embeddedFont = await embedFont(fontData);
18516
18639
  const metrics = embeddedFont.metrics;
18517
- const psName = options?.customName || metrics.postScriptName || metrics.familyName || "CFFFont";
18640
+ const psName = options?.customName ?? metrics.postScriptName ?? metrics.familyName ?? "CFFFont";
18518
18641
  const existing = this.embeddedFonts.get(`__cff__${psName}`);
18519
18642
  if (existing) return existing;
18520
18643
  this.fontCounter++;
@@ -18804,7 +18927,7 @@ var PdfDocument = class PdfDocument {
18804
18927
  * @param pages Array of PdfPage instances to embed.
18805
18928
  * @returns Array of {@link EmbeddedPdfPage} handles, one per input page.
18806
18929
  */
18807
- async embedPages(pages) {
18930
+ embedPages(pages) {
18808
18931
  return pages.map((page) => this.embedPage(page));
18809
18932
  }
18810
18933
  /** Set the document title. */
@@ -20336,8 +20459,8 @@ function compressStream(stream, level) {
20336
20459
  * @returns The incremental save result.
20337
20460
  */
20338
20461
  async function saveDocumentIncremental(originalBytes, doc, options) {
20339
- const { buildDocumentStructure } = await import("./pdfCatalog-CTfeeqtF.mjs").then((n) => n.o);
20340
- const { PdfPage: _PdfPage } = await import("./pdfPage-B7vA518n.mjs").then((n) => n.r);
20462
+ const { buildDocumentStructure } = await import("./pdfCatalog-BB2Wnmud.mjs").then((n) => n.o);
20463
+ const { PdfPage: _PdfPage } = await import("./pdfPage-N1K2U3jI.mjs").then((n) => n.r);
20341
20464
  const registry = doc.getRegistry();
20342
20465
  const structure = buildDocumentStructure(doc.getInternalPages().map((p) => p.finalize()), {
20343
20466
  producer: doc.getProducer(),
@@ -22444,6 +22567,19 @@ var TokenType = /* @__PURE__ */ function(TokenType) {
22444
22567
  return TokenType;
22445
22568
  }(TokenType || {});
22446
22569
  /**
22570
+ * `hexVal[b]` is the numeric value (0-15) of a hex character, or -1 if
22571
+ * the byte is not a valid hex digit.
22572
+ */
22573
+ const hexVal = /* @__PURE__ */ (() => {
22574
+ const t = new Int8Array(256).fill(-1);
22575
+ for (let i = 0; i <= 9; i++) t[48 + i] = i;
22576
+ for (let i = 0; i < 6; i++) {
22577
+ t[65 + i] = 10 + i;
22578
+ t[97 + i] = 10 + i;
22579
+ }
22580
+ return t;
22581
+ })();
22582
+ /**
22447
22583
  * Combined lexer + parser for PDF content streams.
22448
22584
  *
22449
22585
  * Content streams are simpler than full PDF object syntax — there are no
@@ -22562,20 +22698,22 @@ var ContentStreamLexer = class {
22562
22698
  }
22563
22699
  const dataStart = this.pos;
22564
22700
  let dataEnd = this.pos;
22565
- while (this.pos < this.data.length) {
22566
- if (this.isWhitespace(this.data[this.pos])) {
22567
- const wsPos = this.pos;
22568
- let probe = wsPos + 1;
22569
- if (probe + 1 < this.data.length && this.data[probe] === 69 && this.data[probe + 1] === 73) {
22570
- const afterEI = probe + 2;
22571
- if (afterEI >= this.data.length || this.isWhitespace(this.data[afterEI])) {
22572
- dataEnd = wsPos;
22573
- this.pos = afterEI;
22574
- break;
22575
- }
22701
+ let searchFrom = this.pos;
22702
+ while (searchFrom < this.data.length) {
22703
+ const eIdx = this.data.indexOf(69, searchFrom);
22704
+ if (eIdx === -1 || eIdx + 1 >= this.data.length) {
22705
+ this.pos = this.data.length;
22706
+ break;
22707
+ }
22708
+ if (eIdx > dataStart && this.isWhitespace(this.data[eIdx - 1]) && this.data[eIdx + 1] === 73) {
22709
+ const afterEI = eIdx + 2;
22710
+ if (afterEI >= this.data.length || this.isWhitespace(this.data[afterEI])) {
22711
+ dataEnd = eIdx - 1;
22712
+ this.pos = afterEI;
22713
+ break;
22576
22714
  }
22577
22715
  }
22578
- this.pos++;
22716
+ searchFrom = eIdx + 1;
22579
22717
  }
22580
22718
  return {
22581
22719
  dict,
@@ -22643,7 +22781,7 @@ var ContentStreamLexer = class {
22643
22781
  */
22644
22782
  readLiteralString() {
22645
22783
  this.pos++;
22646
- let result = "";
22784
+ const parts = [];
22647
22785
  let depth = 1;
22648
22786
  while (this.pos < this.data.length && depth > 0) {
22649
22787
  const ch = this.data[this.pos];
@@ -22653,35 +22791,35 @@ var ContentStreamLexer = class {
22653
22791
  const esc = this.data[this.pos];
22654
22792
  switch (esc) {
22655
22793
  case 110:
22656
- result += "\n";
22794
+ parts.push("\n");
22657
22795
  this.pos++;
22658
22796
  break;
22659
22797
  case 114:
22660
- result += "\r";
22798
+ parts.push("\r");
22661
22799
  this.pos++;
22662
22800
  break;
22663
22801
  case 116:
22664
- result += " ";
22802
+ parts.push(" ");
22665
22803
  this.pos++;
22666
22804
  break;
22667
22805
  case 98:
22668
- result += "\b";
22806
+ parts.push("\b");
22669
22807
  this.pos++;
22670
22808
  break;
22671
22809
  case 102:
22672
- result += "\f";
22810
+ parts.push("\f");
22673
22811
  this.pos++;
22674
22812
  break;
22675
22813
  case 40:
22676
- result += "(";
22814
+ parts.push("(");
22677
22815
  this.pos++;
22678
22816
  break;
22679
22817
  case 41:
22680
- result += ")";
22818
+ parts.push(")");
22681
22819
  this.pos++;
22682
22820
  break;
22683
22821
  case 92:
22684
- result += "\\";
22822
+ parts.push("\\");
22685
22823
  this.pos++;
22686
22824
  break;
22687
22825
  case 10:
@@ -22709,29 +22847,29 @@ var ContentStreamLexer = class {
22709
22847
  }
22710
22848
  }
22711
22849
  }
22712
- result += String.fromCharCode(octal & 255);
22850
+ parts.push(String.fromCharCode(octal & 255));
22713
22851
  } else {
22714
- result += String.fromCharCode(esc);
22852
+ parts.push(String.fromCharCode(esc));
22715
22853
  this.pos++;
22716
22854
  }
22717
22855
  break;
22718
22856
  }
22719
22857
  } else if (ch === 40) {
22720
22858
  depth++;
22721
- result += "(";
22859
+ parts.push("(");
22722
22860
  this.pos++;
22723
22861
  } else if (ch === 41) {
22724
22862
  depth--;
22725
- if (depth > 0) result += ")";
22863
+ if (depth > 0) parts.push(")");
22726
22864
  this.pos++;
22727
22865
  } else {
22728
- result += String.fromCharCode(ch);
22866
+ parts.push(String.fromCharCode(ch));
22729
22867
  this.pos++;
22730
22868
  }
22731
22869
  }
22732
22870
  return {
22733
22871
  type: TokenType.String,
22734
- value: result
22872
+ value: parts.join("")
22735
22873
  };
22736
22874
  }
22737
22875
  /**
@@ -22739,7 +22877,8 @@ var ContentStreamLexer = class {
22739
22877
  */
22740
22878
  readHexString() {
22741
22879
  this.pos++;
22742
- let hex = "";
22880
+ const bytes = [];
22881
+ let hi = -1;
22743
22882
  while (this.pos < this.data.length) {
22744
22883
  const ch = this.data[this.pos];
22745
22884
  if (ch === 62) {
@@ -22750,18 +22889,22 @@ var ContentStreamLexer = class {
22750
22889
  this.pos++;
22751
22890
  continue;
22752
22891
  }
22753
- hex += String.fromCharCode(ch);
22892
+ const v = hexVal[ch];
22893
+ if (v === -1) {
22894
+ this.pos++;
22895
+ continue;
22896
+ }
22897
+ if (hi === -1) hi = v;
22898
+ else {
22899
+ bytes.push(hi << 4 | v);
22900
+ hi = -1;
22901
+ }
22754
22902
  this.pos++;
22755
22903
  }
22756
- if (hex.length % 2 !== 0) hex += "0";
22757
- let result = "";
22758
- for (let i = 0; i < hex.length; i += 2) {
22759
- const byte = parseInt(hex.substring(i, i + 2), 16);
22760
- if (!isNaN(byte)) result += String.fromCharCode(byte);
22761
- }
22904
+ if (hi !== -1) bytes.push(hi << 4);
22762
22905
  return {
22763
22906
  type: TokenType.HexString,
22764
- value: result
22907
+ value: String.fromCharCode.apply(null, bytes)
22765
22908
  };
22766
22909
  }
22767
22910
  /**
@@ -22769,27 +22912,25 @@ var ContentStreamLexer = class {
22769
22912
  */
22770
22913
  readName() {
22771
22914
  this.pos++;
22772
- let name = "/";
22915
+ const parts = ["/"];
22773
22916
  while (this.pos < this.data.length) {
22774
22917
  const ch = this.data[this.pos];
22775
22918
  if (this.isWhitespace(ch) || this.isDelimiter(ch)) break;
22776
22919
  if (ch === 35 && this.pos + 2 < this.data.length) {
22777
- const hi = this.data[this.pos + 1];
22778
- const lo = this.data[this.pos + 2];
22779
- const hex = String.fromCharCode(hi) + String.fromCharCode(lo);
22780
- const code = parseInt(hex, 16);
22781
- if (!isNaN(code)) {
22782
- name += String.fromCharCode(code);
22920
+ const hi = hexVal[this.data[this.pos + 1]];
22921
+ const lo = hexVal[this.data[this.pos + 2]];
22922
+ if (hi !== -1 && lo !== -1) {
22923
+ parts.push(String.fromCharCode(hi << 4 | lo));
22783
22924
  this.pos += 3;
22784
22925
  continue;
22785
22926
  }
22786
22927
  }
22787
- name += String.fromCharCode(ch);
22928
+ parts.push(String.fromCharCode(ch));
22788
22929
  this.pos++;
22789
22930
  }
22790
22931
  return {
22791
22932
  type: TokenType.Name,
22792
- value: PdfName.of(name)
22933
+ value: PdfName.of(parts.join(""))
22793
22934
  };
22794
22935
  }
22795
22936
  /**
@@ -22883,9 +23024,7 @@ var ContentStreamLexer = class {
22883
23024
  * Decode a slice of the data as ASCII text.
22884
23025
  */
22885
23026
  decodeAscii(start, end) {
22886
- let s = "";
22887
- for (let i = start; i < end; i++) s += String.fromCharCode(this.data[i]);
22888
- return s;
23027
+ return String.fromCharCode.apply(null, this.data.subarray(start, end));
22889
23028
  }
22890
23029
  };
22891
23030