renderpdf-js 0.0.0-stage → 0.2.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.js ADDED
@@ -0,0 +1,2388 @@
1
+ import e from "@pdf-lib/fontkit";
2
+ import { PDFArray as t, PDFDict as n, PDFDocument as r, PDFHexString as i, PDFName as a, TextRenderingMode as o, beginText as s, clip as c, concatTransformationMatrix as l, drawObject as u, endPath as d, endText as f, popGraphicsState as p, pushGraphicsState as m, rectangle as h, rgb as g, setFillingColor as _, setFontAndSize as v, setGraphicsState as y, setTextMatrix as b, setTextRenderingMode as x, showText as S } from "pdf-lib";
3
+ import { toPng as C } from "html-to-image";
4
+ // src/diagnostics.ts
5
+ var w = class extends Error {
6
+ code;
7
+ constructor(e, t, n) {
8
+ super(t, n), this.code = e, this.name = "RenderPDFError";
9
+ }
10
+ };
11
+ function T(e) {
12
+ if (e?.aborted) throw new DOMException("PDF rendering was cancelled.", "AbortError");
13
+ }
14
+ // src/breaks.ts
15
+ var E = /* @__PURE__ */ new Set([
16
+ "block",
17
+ "flow-root",
18
+ "flex",
19
+ "grid",
20
+ "table",
21
+ "table-caption",
22
+ "table-row",
23
+ "table-row-group",
24
+ "table-header-group",
25
+ "table-footer-group"
26
+ ]);
27
+ function D(e, t) {
28
+ let n = e.getPropertyValue(`break-${t}`).trim(), r = e.getPropertyValue(`page-break-${t}`).trim();
29
+ return n && n !== "auto" ? n : r || n || "auto";
30
+ }
31
+ function O(e, t) {
32
+ if (e !== "auto" && e !== "avoid" && e !== "avoid-page" && (t === "inside" || e !== "page" && e !== "always")) throw new w("UNSUPPORTED_CSS", `Unsupported CSS break-${t}: ${e}; only page/always boundaries and avoid/avoid-page preferences are supported.`);
33
+ }
34
+ function ee(e, t) {
35
+ let n = e.getBoundingClientRect();
36
+ return {
37
+ x: n.left - t.left,
38
+ y: n.top - t.top,
39
+ width: n.width,
40
+ height: n.height
41
+ };
42
+ }
43
+ function te(e) {
44
+ let t = getComputedStyle(e), n = e.getBoundingClientRect();
45
+ return t.visibility === "visible" && E.has(t.display) && n.width > 0 && n.height > 0;
46
+ }
47
+ function ne(e, t) {
48
+ let n = t === "previous" ? e.previousElementSibling : e.nextElementSibling;
49
+ for (; n;) {
50
+ if (!(n instanceof HTMLElement)) return;
51
+ let e = getComputedStyle(n);
52
+ if (e.display !== "none" && e.visibility === "visible") return te(n) ? n : void 0;
53
+ n = t === "previous" ? n.previousElementSibling : n.nextElementSibling;
54
+ }
55
+ }
56
+ function re(e, t) {
57
+ let n = Math.min(e.x, t.x), r = Math.min(e.y, t.y);
58
+ return {
59
+ x: n,
60
+ y: r,
61
+ width: Math.max(e.x + e.width, t.x + t.width) - n,
62
+ height: Math.max(e.y + e.height, t.y + t.height) - r
63
+ };
64
+ }
65
+ function ie(e, t) {
66
+ if (!e.isConnected || e.ownerDocument !== document) throw new w("INVALID_SOURCE", "CSS page-break collection requires a connected source in the current document.");
67
+ let n = e.getBoundingClientRect(), r = t.operations.filter((e) => e.kind === "raster"), i = /* @__PURE__ */ new Map(), a = [];
68
+ for (let t of [e, ...e.querySelectorAll("*")]) {
69
+ if (!(t instanceof HTMLElement)) continue;
70
+ let e = getComputedStyle(t);
71
+ if (e.display === "none" || e.visibility !== "visible") continue;
72
+ let o = t.getBoundingClientRect();
73
+ if (o.width === 0 && o.height === 0 && t.getClientRects().length === 0) continue;
74
+ let s = D(e, "before"), c = D(e, "after"), l = D(e, "inside");
75
+ O(s, "before"), O(c, "after"), O(l, "inside");
76
+ let u = r.find((e) => e.element.contains(t));
77
+ if (!u && E.has(e.display) && (e.widows && e.widows !== "2" || e.orphans && e.orphans !== "2")) throw new w("UNSUPPORTED_CSS", "Nondefault CSS widows/orphans are unsupported; this renderer preserves measured text lines without a line-count pagination policy.");
78
+ if (s === "auto" && c === "auto" && l === "auto") continue;
79
+ let d = s === "page" || s === "always", f = c === "page" || c === "always";
80
+ if (u && u.element !== t) {
81
+ if (d || f) throw new w("PAGINATION_FAILED", "A forced CSS page break lies inside an atomic raster region; move the break outside that region.");
82
+ continue;
83
+ }
84
+ if (!E.has(e.display)) throw new w("UNSUPPORTED_CSS", "Explicit CSS page breaks require a block, table group or table row; inline fragments and table cells are unsupported.");
85
+ let p = ee(t, n);
86
+ d && a.push(p.y), f && a.push(p.y + p.height), l !== "auto" && !u && i.set(`${p.x}:${p.y}:${p.width}:${p.height}`, p);
87
+ for (let e of ["previous", "next"]) {
88
+ let r = e === "previous" ? s : c;
89
+ if (r !== "avoid" && r !== "avoid-page") continue;
90
+ let a = ne(t, e);
91
+ if (!a) continue;
92
+ let o = re(p, ee(a, n));
93
+ i.set(`${o.x}:${o.y}:${o.width}:${o.height}`, o);
94
+ }
95
+ }
96
+ return {
97
+ forcedBreaks: a,
98
+ avoidBreakBounds: [...i.values()]
99
+ };
100
+ }
101
+ // src/export-options.ts
102
+ function ae(e) {
103
+ if (e === void 0) return;
104
+ if (!e || typeof e != "object" || Array.isArray(e)) throw new w("INVALID_OPTIONS", "PDF metadata must be an object.");
105
+ let { title: t, author: n, subject: r, keywords: i } = e;
106
+ if ([
107
+ t,
108
+ n,
109
+ r
110
+ ].some((e) => e !== void 0 && typeof e != "string") || i !== void 0 && (!Array.isArray(i) || Array.from(i).some((e) => typeof e != "string"))) throw new w("INVALID_OPTIONS", "PDF metadata title, author and subject must be strings; keywords must be an array of strings.");
111
+ return Object.freeze({
112
+ ...t === void 0 ? {} : { title: t },
113
+ ...n === void 0 ? {} : { author: n },
114
+ ...r === void 0 ? {} : { subject: r },
115
+ ...i === void 0 ? {} : { keywords: Object.freeze([...i]) }
116
+ });
117
+ }
118
+ function oe(e, t) {
119
+ e.setTitle(t?.title ?? "RenderPDF.js"), t?.author !== void 0 && e.setAuthor(t.author), t?.subject !== void 0 && e.setSubject(t.subject), t?.keywords !== void 0 && e.setKeywords([...t.keywords]);
120
+ }
121
+ // src/fonts.ts
122
+ var se = /* @__PURE__ */ new WeakMap(), ce = /* @__PURE__ */ new WeakMap(), le = /* @__PURE__ */ new Set([
123
+ "serif",
124
+ "sans-serif",
125
+ "monospace",
126
+ "cursive",
127
+ "fantasy",
128
+ "system-ui",
129
+ "ui-serif",
130
+ "ui-sans-serif",
131
+ "ui-monospace",
132
+ "ui-rounded",
133
+ "emoji",
134
+ "math",
135
+ "fangsong",
136
+ "inherit",
137
+ "initial",
138
+ "unset",
139
+ "revert",
140
+ "revert-layer"
141
+ ]);
142
+ function ue(e) {
143
+ if (e.byteLength < 12) throw new w("FONT_LOAD_FAILED", "Provide a complete static TTF/OTF font program.");
144
+ let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = t.getUint32(0);
145
+ if (n !== 65536 && n !== 1330926671) throw new w("FONT_LOAD_FAILED", "Only static TTF/OTF programs are supported; WOFF fonts and font collections are unsupported.");
146
+ let r = t.getUint16(4);
147
+ if (r === 0 || 12 + r * 16 > e.byteLength) throw new w("FONT_LOAD_FAILED", "The TTF/OTF font table directory is incomplete.");
148
+ for (let e = 0; e < r; e += 1) if (t.getUint32(12 + e * 16) === 1719034226) throw new w("FONT_LOAD_FAILED", "Variable fonts are unsupported. Provide an explicitly generated static TTF/OTF instance.");
149
+ }
150
+ function k(e, t, n, r, i) {
151
+ for (let a of e.fonts) {
152
+ if (a === i || a.family.replace(/^["']|["']$/g, "").toLowerCase() !== t.toLowerCase() || a.style !== r) continue;
153
+ let e = a.weight === "normal" ? [400] : a.weight === "bold" ? [700] : a.weight.split(/\s+/).map(Number);
154
+ if (e[0] === n || e.length === 2 && n >= e[0] && n <= e[1]) throw new w("INVALID_OPTIONS", `Font ${t} ${n} ${r} conflicts with an existing browser font face. Choose a family owned by this registration.`);
155
+ }
156
+ }
157
+ function A(e) {
158
+ for (let t of e) {
159
+ let e = t && typeof t == "object" ? ce.get(t) : void 0;
160
+ if (!e || typeof document > "u" || e.document !== document || !document.fonts.has(e.face)) throw new w("MISSING_FONT", "Provide font handles returned by registerFont() whose browser faces remain registered in the current document.");
161
+ k(document, t.family, t.weight, t.style, e.face);
162
+ }
163
+ }
164
+ async function de(e) {
165
+ if (!e || typeof e != "object" || typeof e.family != "string") throw new w("INVALID_OPTIONS", "Font registration requires a CSS family and font bytes.");
166
+ let t = e.family.trim(), n = e.weight ?? 400, r = e.style ?? "normal";
167
+ if (!t || !/^[\w -]+$/.test(t) || le.has(t.toLowerCase()) || !Number.isInteger(n) || n < 1 || n > 1e3 || r !== "normal" && r !== "italic" || !(e.data instanceof Uint8Array) && !(e.data instanceof ArrayBuffer) || e.data.byteLength === 0) throw new w("INVALID_OPTIONS", "Provide a plain custom CSS family (letters, digits, spaces, hyphens, or underscores), nonempty TTF/OTF bytes, integer weight from 1 to 1000, and normal or italic style.");
168
+ if (typeof document > "u" || typeof FontFace > "u" || !document.fonts) throw new w("FONT_LOAD_FAILED", "Font registration requires a browser document with FontFace support.");
169
+ let i = new Uint8Array(e.data instanceof Uint8Array ? e.data : new Uint8Array(e.data));
170
+ ue(i);
171
+ let a = `${t.toLowerCase()}:${n}:${r}`, o = document, s = se.get(o);
172
+ s || (s = /* @__PURE__ */ new Map(), se.set(o, s));
173
+ let c = s.get(a);
174
+ if (k(o, t, n, r, c?.face), c) {
175
+ if (c.bytes.length !== i.length || c.bytes.some((e, t) => e !== i[t])) throw new w("INVALID_OPTIONS", `Font ${t} ${n} ${r} is already registered with different bytes.`);
176
+ return c.promise;
177
+ }
178
+ async function l() {
179
+ try {
180
+ let e = new FontFace(t, i, {
181
+ weight: String(n),
182
+ style: r
183
+ });
184
+ await e.load(), k(o, t, n, r), o.fonts.add(e), d.face = e;
185
+ let a = Object.freeze({
186
+ family: t,
187
+ weight: n,
188
+ style: r,
189
+ get bytes() {
190
+ return i.slice();
191
+ }
192
+ });
193
+ return ce.set(a, {
194
+ document: o,
195
+ face: e
196
+ }), a;
197
+ } catch (e) {
198
+ throw s.delete(a), e instanceof w ? e : new w("FONT_LOAD_FAILED", `Could not load font ${t} ${n} ${r}.`, { cause: e });
199
+ }
200
+ }
201
+ let u = Promise.resolve().then(l), d = {
202
+ bytes: i,
203
+ promise: u
204
+ };
205
+ return s.set(a, d), u;
206
+ }
207
+ // src/planner.ts
208
+ var fe = /^data:image\/(?:png|jpeg|gif|webp|avif);base64,[a-z\d+/=\s]+$/i;
209
+ function pe(e) {
210
+ let t = 0, n = "", r = 0, i = [];
211
+ for (let a = 0; a < e.length; a += 1) {
212
+ let o = e[a];
213
+ o === "\\" ? a += 1 : n ? o === n && (n = "") : o === "\"" || o === "'" ? n = o : o === "(" ? t += 1 : o === ")" ? --t : o === "," && t === 0 && (i.push(e.slice(r, a).trim()), r = a + 1);
214
+ }
215
+ return i.push(e.slice(r).trim()), i;
216
+ }
217
+ function me(e) {
218
+ let t = [];
219
+ if (e.backgroundImage !== "none") {
220
+ for (let t of pe(e.backgroundImage)) {
221
+ if (/^(?:repeating-)?(?:linear|radial|conic)-gradient\(/i.test(t)) continue;
222
+ let e = t.match(/^url\(\s*(["']?)(.*?)\1\s*\)$/i)?.[2];
223
+ if (!e || !fe.test(e)) throw new w("UNSUPPORTED_CSS", "Unsupported CSS: automatic raster backgrounds require gradients or inline bitmap URLs.");
224
+ }
225
+ t.push("background-image");
226
+ }
227
+ if (e.borderRadius !== "0px" && t.push("border-radius"), e.boxShadow !== "none") {
228
+ if (pe(e.boxShadow).some((e) => !/\binset\b/.test(e))) throw new w("UNSUPPORTED_CSS", "Unsupported CSS: outer shadows require expanded capture bounds; only inset shadows can fall back automatically.");
229
+ t.push("inset box-shadow");
230
+ }
231
+ return e.opacity !== "1" && t.push("opacity"), t.length ? t.join(", ") : void 0;
232
+ }
233
+ function he(e, t) {
234
+ if (!(e instanceof HTMLImageElement) && ![
235
+ "block",
236
+ "flow-root",
237
+ "inline-block",
238
+ "flex",
239
+ "inline-flex",
240
+ "grid",
241
+ "inline-grid"
242
+ ].includes(t.display)) throw new w("UNSUPPORTED_CSS", "Automatic raster fallback requires a rectangular block, flex, grid, inline-block, or image boundary; wrap inline or table-internal effects in a supported block.");
243
+ if (Array.from(e.getClientRects()).filter((e) => e.width > 0 && e.height > 0).length !== 1) throw new w("UNSUPPORTED_CSS", "Automatic raster fallback cannot capture fragmented inline or multi-column regions.");
244
+ }
245
+ // src/table-borders.ts
246
+ var j = .001;
247
+ function M(e, t) {
248
+ let n = (e) => e.style === "hidden" ? 2 : +(e.style === "solid" && e.width > 0);
249
+ return n(e) - n(t) || e.width - t.width || Number(e.owner === "cell") - Number(t.owner === "cell") || (e.direction === t.direction ? e.direction === "vertical" ? t.column - e.column || t.row - e.row : t.row - e.row || t.column - e.column : Number(e.direction === "horizontal") - Number(t.direction === "horizontal"));
250
+ }
251
+ function ge(e) {
252
+ let t = /* @__PURE__ */ new Map();
253
+ for (let n of e) {
254
+ if (![
255
+ n.position,
256
+ n.start,
257
+ n.end,
258
+ n.width
259
+ ].every(Number.isFinite) || n.width < 0 || n.end <= n.start) throw new w("INVALID_SOURCE", "Collapsed border geometry must be finite and positive.");
260
+ let e = `${n.direction}:${n.position.toFixed(4)}`, r = t.get(e) ?? [];
261
+ r.push(n), t.set(e, r);
262
+ }
263
+ let n = [];
264
+ for (let e of t.values()) {
265
+ let t = /* @__PURE__ */ new Map();
266
+ for (let n of e) {
267
+ let e = t.get(n.start) ?? {
268
+ starts: [],
269
+ ends: []
270
+ };
271
+ e.starts.push(n), t.set(n.start, e);
272
+ let r = t.get(n.end) ?? {
273
+ starts: [],
274
+ ends: []
275
+ };
276
+ r.ends.push(n), t.set(n.end, r);
277
+ }
278
+ let r = [...t.keys()].sort((e, t) => e - t), i = /* @__PURE__ */ new Set();
279
+ for (let e = 0; e < r.length - 1; e += 1) {
280
+ let a = r[e], o = r[e + 1], s = t.get(a);
281
+ for (let e of s.ends) i.delete(e);
282
+ for (let e of s.starts) i.add(e);
283
+ if (o - a <= j) continue;
284
+ let c;
285
+ for (let e of i) (!c || M(e, c) > 0) && (c = e);
286
+ c?.style === "solid" && c.width > 0 && n.push({
287
+ ...c,
288
+ start: a,
289
+ end: o
290
+ });
291
+ }
292
+ }
293
+ return n;
294
+ }
295
+ function _e(e, t) {
296
+ let n = Math.max(e.x, t.x), r = Math.min(e.x + e.width, t.x + t.width), i = Math.max(e.y, t.y), a = Math.min(e.y + e.height, t.y + t.height);
297
+ return r <= n + j || a <= i + j ? [e] : [
298
+ {
299
+ x: e.x,
300
+ y: e.y,
301
+ width: e.width,
302
+ height: i - e.y
303
+ },
304
+ {
305
+ x: e.x,
306
+ y: a,
307
+ width: e.width,
308
+ height: e.y + e.height - a
309
+ },
310
+ {
311
+ x: e.x,
312
+ y: i,
313
+ width: n - e.x,
314
+ height: a - i
315
+ },
316
+ {
317
+ x: r,
318
+ y: i,
319
+ width: e.x + e.width - r,
320
+ height: a - i
321
+ }
322
+ ].filter((e) => e.width > j && e.height > j);
323
+ }
324
+ function ve(e) {
325
+ let t = [], n = /* @__PURE__ */ new Map();
326
+ for (let t of e) {
327
+ let e = `${t.direction}:${t.position.toFixed(4)}`, r = n.get(e) ?? [];
328
+ r.push(t), n.set(e, r);
329
+ }
330
+ for (let e of n.values()) e.sort((e, t) => e.start - t.start);
331
+ let r = /* @__PURE__ */ new Map(), i = (e) => {
332
+ let t = [];
333
+ for (let n = Math.floor(e.x / 64); n <= Math.floor((e.x + e.width) / 64); n += 1) for (let r = Math.floor(e.y / 64); r <= Math.floor((e.y + e.height) / 64); r += 1) t.push(`${n}:${r}`);
334
+ return t;
335
+ }, a = [...e].sort((e, t) => M(t, e));
336
+ for (let e of a) {
337
+ let a = (t) => {
338
+ let r = e.direction === "horizontal" ? "vertical" : "horizontal", i = n.get(`${r}:${t.toFixed(4)}`) ?? [], a = 0, o = i.length;
339
+ for (; a < o;) {
340
+ let t = a + o >>> 1;
341
+ i[t].start <= e.position + j ? a = t + 1 : o = t;
342
+ }
343
+ let s = 0;
344
+ for (let t = a - 1; t >= 0; --t) {
345
+ let n = i[t];
346
+ if (n.end < e.position - j) break;
347
+ s = Math.max(s, n.width / 2);
348
+ }
349
+ return s;
350
+ }, o = e.start - a(e.start), s = e.end + a(e.end), c = [e.direction === "horizontal" ? {
351
+ x: o,
352
+ y: e.position - e.width / 2,
353
+ width: s - o,
354
+ height: e.width
355
+ } : {
356
+ x: e.position - e.width / 2,
357
+ y: o,
358
+ width: e.width,
359
+ height: s - o
360
+ }], l = new Set(i(c[0]).flatMap((e) => r.get(e) ?? []));
361
+ for (let e of l) if (c = c.flatMap((t) => _e(t, e.bounds)), c.length === 0) break;
362
+ for (let n of c) {
363
+ let a = {
364
+ kind: "border",
365
+ bounds: n,
366
+ color: e.color,
367
+ width: e.width,
368
+ direction: e.direction
369
+ };
370
+ t.push(a);
371
+ for (let e of i(n)) {
372
+ let t = r.get(e) ?? [];
373
+ t.push(a), r.set(e, t);
374
+ }
375
+ }
376
+ }
377
+ return t;
378
+ }
379
+ function ye(e, t) {
380
+ if (![
381
+ "TABLE",
382
+ "THEAD",
383
+ "TBODY",
384
+ "TFOOT",
385
+ "TR",
386
+ "TD",
387
+ "TH",
388
+ "COL",
389
+ "COLGROUP"
390
+ ].includes(e.tagName)) return;
391
+ let n = e instanceof HTMLTableElement ? e : e.closest("table");
392
+ return n && (e === n ? t : getComputedStyle(n)).borderCollapse === "collapse" ? n : void 0;
393
+ }
394
+ function be(e, t) {
395
+ if (!{
396
+ TABLE: ["table", "inline-table"],
397
+ THEAD: ["table-header-group"],
398
+ TBODY: ["table-row-group"],
399
+ TFOOT: ["table-footer-group"],
400
+ TR: ["table-row"],
401
+ TD: ["table-cell"],
402
+ TH: ["table-cell"],
403
+ COL: ["table-column"],
404
+ COLGROUP: ["table-column-group"]
405
+ }[e.tagName]?.includes(t.display)) throw new w("UNSUPPORTED_CSS", "Collapsed table parts require their native table-cell, table-row and table-group display modes.");
406
+ for (let n of [
407
+ "Top",
408
+ "Right",
409
+ "Bottom",
410
+ "Left"
411
+ ]) {
412
+ let r = t[`border${n}Style`], i = Number.parseFloat(t[`border${n}Width`]);
413
+ if (![
414
+ "solid",
415
+ "none",
416
+ "hidden"
417
+ ].includes(r)) throw new w("UNSUPPORTED_CSS", "Collapsed tables support only solid, none and hidden border styles.");
418
+ if (![
419
+ "TABLE",
420
+ "TD",
421
+ "TH"
422
+ ].includes(e.tagName) && (r === "hidden" || i > 0)) throw new w("UNSUPPORTED_CSS", "Collapsed row, row-group, column and column-group border contributions are unsupported; put borders on cells or the table.");
423
+ }
424
+ }
425
+ function xe(e, t) {
426
+ if (e.parentElement?.closest("table") || e.querySelector("table") || e.caption || !["table", "inline-table"].includes(getComputedStyle(e).display)) throw new w("UNSUPPORTED_ELEMENT", "Native collapsed borders require a table without nested tables or captions.");
427
+ let n = [], r = Array.from(e.rows).flatMap((e) => Array.from(e.cells).filter((e) => {
428
+ let t = e.getBoundingClientRect();
429
+ return t.width > 0 && t.height > 0;
430
+ }));
431
+ if (r.length === 0) return {
432
+ operations: [],
433
+ repeatSafe: !0
434
+ };
435
+ let i = r.map((e) => e.getBoundingClientRect()), a = i.reduce((e, t) => ({
436
+ left: Math.min(e.left, t.left),
437
+ right: Math.max(e.right, t.right),
438
+ top: Math.min(e.top, t.top),
439
+ bottom: Math.max(e.bottom, t.bottom)
440
+ }), {
441
+ left: Infinity,
442
+ right: -Infinity,
443
+ top: Infinity,
444
+ bottom: -Infinity
445
+ }), o = (r, i) => {
446
+ let a = getComputedStyle(r), o = r === e ? "table" : "cell";
447
+ for (let e of [
448
+ "Top",
449
+ "Right",
450
+ "Bottom",
451
+ "Left"
452
+ ]) {
453
+ let r = e === "Top" || e === "Bottom";
454
+ n.push({
455
+ direction: r ? "horizontal" : "vertical",
456
+ position: (e === "Top" ? i.top : e === "Bottom" ? i.bottom : e === "Left" ? i.left : i.right) - (r ? t.top : t.left),
457
+ start: (r ? i.left : i.top) - (r ? t.left : t.top),
458
+ end: (r ? i.right : i.bottom) - (r ? t.left : t.top),
459
+ width: Number.parseFloat(a[`border${e}Width`]),
460
+ style: a[`border${e}Style`],
461
+ color: a[`border${e}Color`],
462
+ owner: o,
463
+ row: i.top,
464
+ column: i.left
465
+ });
466
+ }
467
+ };
468
+ o(e, a), r.forEach((e, t) => o(e, i[t]));
469
+ let s = ge(n), c = ve(s), l = e.tHead?.getBoundingClientRect();
470
+ if (!l || l.height <= 0) return {
471
+ operations: c,
472
+ repeatSafe: !0
473
+ };
474
+ let u = l.bottom - t.top, d = Array.from(e.tBodies).flatMap((e) => Array.from(e.rows)), f = d.at(-1)?.getBoundingClientRect().bottom ?? l.bottom, p = [.../* @__PURE__ */ new Set([u, ...d.map((e) => e.getBoundingClientRect().top - t.top).filter((e) => e < f - t.top - j)])], m = /* @__PURE__ */ new Map();
475
+ for (let e of s) {
476
+ if (e.direction !== "horizontal") continue;
477
+ let t = e.position.toFixed(4), n = m.get(t) ?? [];
478
+ n.push(e), m.set(t, n);
479
+ }
480
+ let h = (e) => JSON.stringify((m.get(e.toFixed(4)) ?? []).sort((e, t) => e.start - t.start).map(({ start: e, end: t, width: n, color: r }) => ({
481
+ start: e,
482
+ end: t,
483
+ width: n,
484
+ color: r
485
+ }))), g = h(u), _ = p.every((e) => h(e) === g), v = c.filter((e) => e.bounds.y < u + j && e.bounds.y + e.bounds.height > l.top - t.top - j).reduce((e, { bounds: t }) => ({
486
+ left: Math.min(e.left, t.x),
487
+ right: Math.max(e.right, t.x + t.width),
488
+ top: Math.min(e.top, t.y)
489
+ }), {
490
+ left: l.left - t.left,
491
+ right: l.right - t.left,
492
+ top: l.top - t.top
493
+ });
494
+ return {
495
+ operations: c,
496
+ repeatSafe: _,
497
+ headerBounds: {
498
+ x: v.left,
499
+ y: v.top,
500
+ width: v.right - v.left,
501
+ height: u - v.top
502
+ }
503
+ };
504
+ }
505
+ // src/layout.ts
506
+ var Se = new Intl.Segmenter("en", { granularity: "grapheme" });
507
+ function N(e, t) {
508
+ if (![
509
+ e.x,
510
+ e.y,
511
+ e.width,
512
+ e.height
513
+ ].every(Number.isFinite)) throw new w("INVALID_SOURCE", "Browser geometry must contain only finite CSS pixel values.");
514
+ return {
515
+ x: e.left - t.left,
516
+ y: e.top - t.top,
517
+ width: e.width,
518
+ height: e.height
519
+ };
520
+ }
521
+ function P(e) {
522
+ let t = e.getRootNode();
523
+ return e.parentElement ?? (t instanceof ShadowRoot && t.host instanceof HTMLElement ? t.host : null);
524
+ }
525
+ function F(e, t, n = !1, r = !1) {
526
+ let i = e instanceof HTMLImageElement, a = [
527
+ t.position !== "static" && `position: ${t.position}`,
528
+ t.zIndex !== "auto" && `z-index: ${t.zIndex}`,
529
+ t.transform !== "none" && "transform",
530
+ t.filter !== "none" && "filter",
531
+ t.backdropFilter !== "none" && "backdrop-filter",
532
+ t.mixBlendMode !== "normal" && "mix-blend-mode",
533
+ t.opacity !== "1" && !n && "opacity",
534
+ t.clipPath !== "none" && "clip-path",
535
+ t.maskImage !== "none" && "mask-image",
536
+ t.backgroundImage !== "none" && !n && "background-image",
537
+ t.boxShadow !== "none" && !n && "box-shadow",
538
+ t.borderRadius !== "0px" && !n && "border-radius",
539
+ t.overflowX !== "visible" && !(i && t.overflowX === "clip") && "overflow-x",
540
+ t.overflowY !== "visible" && !(i && t.overflowY === "clip") && "overflow-y",
541
+ t.cssFloat !== "none" && "float",
542
+ t.order !== "0" && "order",
543
+ t.direction !== "ltr" && "direction",
544
+ t.writingMode !== "horizontal-tb" && "writing-mode",
545
+ t.textShadow !== "none" && "text-shadow",
546
+ t.textDecorationLine !== "none" && "text-decoration",
547
+ t.textTransform !== "none" && "text-transform",
548
+ t.letterSpacing !== "normal" && t.letterSpacing !== "0px" && "letter-spacing",
549
+ t.wordSpacing !== "normal" && t.wordSpacing !== "0px" && "word-spacing",
550
+ t.whiteSpace !== "normal" && "white-space",
551
+ t.columnCount !== "auto" && t.columnCount !== "1" && "columns",
552
+ t.outlineStyle !== "none" && "outline",
553
+ t.borderImageSource !== "none" && "border-image",
554
+ t.boxDecorationBreak === "clone" && "box-decoration-break: clone",
555
+ t.zoom !== "1" && "zoom",
556
+ [
557
+ "marginTop",
558
+ "marginRight",
559
+ "marginBottom",
560
+ "marginLeft"
561
+ ].some((e) => Number.parseFloat(t.getPropertyValue(e.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`))) < 0) && "negative margins"
562
+ ].filter(Boolean);
563
+ for (let t of ["::before", "::after"]) {
564
+ let n = getComputedStyle(e, t).content;
565
+ n !== "none" && n !== "normal" && a.push(`generated content ${t}`);
566
+ }
567
+ if (a.length > 0) throw new w("UNSUPPORTED_CSS", `Unsupported CSS on ${e.tagName}: ${a.join(", ")}. Use a bounded data-raster subtree when safe.`);
568
+ if (e instanceof HTMLTableElement && !["separate", "collapse"].includes(t.borderCollapse)) throw new w("UNSUPPORTED_CSS", "Native table snapshots require separate or collapsed borders.");
569
+ if ([
570
+ "THEAD",
571
+ "TBODY",
572
+ "TFOOT",
573
+ "TR",
574
+ "COL",
575
+ "COLGROUP"
576
+ ].includes(e.tagName) && t.backgroundColor !== "rgba(0, 0, 0, 0)") throw new w("UNSUPPORTED_CSS", "Native table snapshots require transparent row-group, row, and column backgrounds.");
577
+ let o = [
578
+ "Top",
579
+ "Right",
580
+ "Bottom",
581
+ "Left"
582
+ ], s = o.map((e) => t[`border${e}Width`]), c = o.map((e) => t[`border${e}Color`]), l = o.map((e) => t[`border${e}Style`]);
583
+ if (r && be(e, t), !r && (s.some((e) => e !== s[0]) || s[0] !== "0px" && (c.some((e) => e !== c[0]) || l.some((e) => e !== "solid")))) throw new w("UNSUPPORTED_CSS", "Unsupported CSS: only uniform solid borders are supported.");
584
+ if (!n && (t.backgroundColor !== "rgba(0, 0, 0, 0)" || s[0] !== "0px") && Array.from(e.getClientRects()).filter((e) => e.width > 0 && e.height > 0).length > 1) throw new w("UNSUPPORTED_CSS", "Fragmented inline backgrounds and borders require an explicit containing raster region.");
585
+ }
586
+ function I(e, t) {
587
+ if (!(e instanceof HTMLImageElement) && ![
588
+ "block",
589
+ "flow-root",
590
+ "inline",
591
+ "inline-block",
592
+ "flex",
593
+ "inline-flex",
594
+ "grid",
595
+ "inline-grid",
596
+ "table",
597
+ "inline-table",
598
+ "table-caption",
599
+ "table-header-group",
600
+ "table-row-group",
601
+ "table-footer-group",
602
+ "table-row",
603
+ "table-cell",
604
+ "table-column-group",
605
+ "table-column"
606
+ ].includes(t.display)) throw new w("UNSUPPORTED_CSS", `Unsupported CSS display: ${t.display}.`);
607
+ }
608
+ function Ce(e, t, n, r, i) {
609
+ let a = e.parentElement;
610
+ if (!a || !e.data.replace(/[\t\n\r\f ]+/g, "")) return [];
611
+ let o = getComputedStyle(a), s = o.fontFamily.split(",")[0]?.trim().replace(/^['"]|['"]$/g, ""), c = Number(o.fontWeight), l = n.find((e) => e.family.toLowerCase() === s?.toLowerCase() && e.weight === c && e.style === o.fontStyle);
612
+ if (!l) throw new w("MISSING_FONT", `No exact registered font face for ${o.fontFamily} ${o.fontWeight} ${o.fontStyle}.`);
613
+ if (o.direction !== "ltr" || o.writingMode !== "horizontal-tb" || o.textTransform !== "none" || o.whiteSpace !== "normal" || e.data.includes("­") || o.hyphens === "auto" || o.letterSpacing !== "normal" && o.letterSpacing !== "0px" || o.wordSpacing !== "normal" && o.wordSpacing !== "0px" || o.fontVariantCaps !== "normal" || o.fontVariantAlternates !== "normal" || o.fontVariantLigatures !== "normal" || o.fontVariantNumeric !== "normal" || o.fontVariantEastAsian !== "normal" || o.fontVariantPosition !== "normal" || o.fontFeatureSettings !== "normal" || o.fontVariationSettings !== "normal" || o.fontStretch !== "100%" && o.fontStretch !== "normal" || o.fontSizeAdjust !== "none" && o.fontSizeAdjust !== void 0 || !["auto", "geometricPrecision"].includes(o.textRendering)) throw new w("UNSUPPORTED_CSS", "Unsupported CSS: text requires horizontal LTR layout with normal whitespace, spacing, font variants and OpenType features, without automatic hyphenation or soft hyphens.");
614
+ let u = Number.parseFloat(o.fontSize), d = `${l.style} ${l.weight} ${u}px "${l.family}"`, f = r.fonts.get(d);
615
+ if (!f) {
616
+ if (!Array.from(document.fonts).some((e) => {
617
+ let t = e.weight === "normal" ? 400 : e.weight === "bold" ? 700 : Number(e.weight);
618
+ return e.family.replace(/^['"]|['"]$/g, "").toLowerCase() === l.family.toLowerCase() && t === l.weight && e.style === l.style && e.status === "loaded";
619
+ }) || !document.fonts.check(d, e.data)) throw new w("MISSING_FONT", `Browser font is not loaded: ${d}.`);
620
+ r.context.font = d;
621
+ let t = r.context.measureText(e.data), n = t.fontBoundingBoxAscent, i = t.fontBoundingBoxDescent;
622
+ if (!Number.isFinite(n) || !Number.isFinite(i)) throw new w("UNSUPPORTED_CSS", "Font bounding metrics are unavailable in this browser.");
623
+ f = {
624
+ ascent: n,
625
+ descent: i
626
+ }, r.fonts.set(d, f);
627
+ }
628
+ let { ascent: p, descent: m } = f, h = Se.segment(e.data), g = document.createRange(), _ = [];
629
+ for (let t of h) {
630
+ g.setStart(e, t.index), g.setEnd(e, t.index + t.segment.length);
631
+ let n = Array.from(g.getClientRects()), r = n.find((e) => e.width > 0 && e.height > 0);
632
+ if (!r) {
633
+ if (/[^\t\n\r\f ]/.test(t.segment) && n.some((e) => e.height > 0 && e.width === 0)) throw new w("UNSUPPORTED_CSS", "Text shaping crosses an inline boundary or uses an unsupported zero-width glyph. Keep each shaped word in one text node.");
634
+ continue;
635
+ }
636
+ let i = _.at(-1);
637
+ i && Math.abs(i.top - r.top) < .5 ? i.end = t.index + t.segment.length : _.push({
638
+ start: t.index,
639
+ end: t.index + t.segment.length,
640
+ top: r.top
641
+ });
642
+ }
643
+ return _.flatMap((n) => {
644
+ let r = n.start, a = n.end;
645
+ for (; r < a && /[\t\n\r\f ]/.test(e.data[r]);) r += 1;
646
+ for (; a > r && /[\t\n\r\f ]/.test(e.data[a - 1]);) --a;
647
+ if (r === a) return [];
648
+ g.setStart(e, r), g.setEnd(e, a);
649
+ let s = e.data.slice(r, a), c = s.replace(/[\t\n\r\f ]+/g, " "), d = N(g.getBoundingClientRect(), t);
650
+ return [{
651
+ kind: "text",
652
+ bounds: d,
653
+ text: c,
654
+ runs: Array.from(s.matchAll(/[^\t\n\r\f ]+/g), (n) => {
655
+ g.setStart(e, r + n.index), g.setEnd(e, r + n.index + n[0].length);
656
+ let i = N(g.getBoundingClientRect(), t);
657
+ return {
658
+ text: n[0],
659
+ x: i.x,
660
+ width: i.width
661
+ };
662
+ }),
663
+ baseline: d.y + (d.height - p - m) / 2 + p,
664
+ fontSize: u,
665
+ family: l.family,
666
+ weight: l.weight,
667
+ style: l.style,
668
+ kerning: o.fontKerning !== "none",
669
+ color: o.color,
670
+ invisible: i
671
+ }];
672
+ });
673
+ }
674
+ function we(e, t, n, r = !1) {
675
+ if (n !== "auto" && n !== "strict") throw new w("INVALID_OPTIONS", "Raster fallback must be auto or strict.");
676
+ if (typeof r != "boolean") throw new w("INVALID_OPTIONS", "Table header repetition must be a boolean.");
677
+ if (!(e instanceof HTMLElement) || e.ownerDocument !== document || !e.isConnected || t.length === 0) throw new w("INVALID_SOURCE", "A connected source root and registered fonts are required.");
678
+ if (new Set(t.map((e) => `${e.family.toLowerCase()}:${e.weight}:${e.style}`)).size !== t.length) throw new w("INVALID_OPTIONS", "Registered fonts require unique family/weight/style descriptors.");
679
+ for (let t = P(e); t; t = P(t)) {
680
+ let e = getComputedStyle(t);
681
+ if (e.transform !== "none" || e.filter !== "none" || e.opacity !== "1" || e.clipPath !== "none" || e.maskImage !== "none" || e.mixBlendMode !== "normal" || e.zoom !== "1" || e.overflowX !== "visible" || e.overflowY !== "visible") throw new w("UNSUPPORTED_CSS", "Unsupported CSS: source ancestors must not transform, clip, blend, or fade the source.");
682
+ }
683
+ }
684
+ function Te(e, t, n, r, i, a) {
685
+ let o = Array.from(e.querySelectorAll("table"));
686
+ e instanceof HTMLTableElement && o.unshift(e);
687
+ let s = [];
688
+ for (let c of o) {
689
+ let o = c.tHead;
690
+ if (!o || getComputedStyle(o).display === "none") continue;
691
+ let l = a.get(c), u = l?.headerBounds ?? N(o.getBoundingClientRect(), t);
692
+ if (u.width <= 0 || u.height <= 0) continue;
693
+ let d = Array.from(c.tBodies).flatMap((e) => Array.from(e.rows).filter((e) => e.getBoundingClientRect().height > 0));
694
+ if (d.length === 0) continue;
695
+ if (l && !l.repeatSafe) throw new w("UNSUPPORTED_CSS", "Repeated collapsed headers require matching horizontal border winners at the header/body boundary and all body row boundaries.");
696
+ if (c.parentElement?.closest("table") || c.querySelector("table") || Array.from(c.children).filter((e) => e.tagName === "THEAD").length !== 1 || getComputedStyle(c).display !== "table" || getComputedStyle(o).display !== "table-header-group") throw new w("UNSUPPORTED_ELEMENT", "Repeated headers require a standalone native table with one THEAD and no nested tables.");
697
+ if (Array.from(o.rows).some((e) => Array.from(e.cells).some((e) => e.rowSpan !== 1)) || n.some((e) => e.kind === "raster" && (e.element.contains(o) || o.contains(e.element)))) throw new w("UNSUPPORTED_ELEMENT", "Repeated table headers do not support header rowspans or rasterized headers and ancestors.");
698
+ let f = N(d[0].getBoundingClientRect(), t).y, p = N(d.at(-1).getBoundingClientRect(), t), m = p.y + p.height, h = r.get(o);
699
+ if (!h || f < u.y + u.height - .1 || m <= f || h.some((e) => e.kind !== "border" && (e.bounds.y < u.y - .1 || e.bounds.y + e.bounds.height > u.y + u.height + .1 || e.bounds.x < u.x - .1 || e.bounds.x + e.bounds.width > u.x + u.width + .1)) || d.some((e) => Array.from(e.cells).some((e) => {
700
+ let n = N(e.getBoundingClientRect(), t);
701
+ return n.y < f - .1 || n.y + n.height > m + .1;
702
+ }))) throw new w("UNSUPPORTED_CSS", "Repeated table headers require a separate, ordered header band without overflowing paint or cells spanning header/body boundaries.");
703
+ if (s.some((e) => Math.min(e.bodyEnd, m) - Math.max(e.bounds.y, u.y) > .01)) throw new w("UNSUPPORTED_CSS", "Repeated headers do not support tables whose vertical continuation intervals overlap.");
704
+ let g = new Set(h);
705
+ for (let t = o.parentElement; t; t = t.parentElement) {
706
+ let n = i.get(t);
707
+ if (n && g.add(n), t === e) break;
708
+ }
709
+ s.push({
710
+ bounds: u,
711
+ bodyStart: f,
712
+ bodyEnd: m,
713
+ operations: n.filter((e) => g.has(e))
714
+ });
715
+ }
716
+ return s;
717
+ }
718
+ function Ee(e, t, n = {}) {
719
+ let r = n.fallback ?? "auto", i = n.repeatTableHeaders ?? !1;
720
+ we(e, t, r, i);
721
+ let a = e.getBoundingClientRect();
722
+ if (a.width <= 0 || a.height <= 0) throw new w("INVALID_SOURCE", "The source root must have positive visible dimensions.");
723
+ let o = document.createElement("canvas").getContext("2d");
724
+ if (!o) throw new w("INVALID_SOURCE", "Canvas font measurement is unavailable.");
725
+ let s = {
726
+ context: o,
727
+ fonts: /* @__PURE__ */ new Map()
728
+ }, c = [], l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = [], p = /* @__PURE__ */ new Map(), m = [{
729
+ code: "TEXT_METRICS_APPROXIMATED",
730
+ message: "Baselines are estimated from Canvas font metrics; browser and PDF shaping engines may still differ for unsupported scripts or font features."
731
+ }];
732
+ function h(e, n, o = !1) {
733
+ let g = c.length, _ = getComputedStyle(e);
734
+ if (_.display === "none") return;
735
+ let v = ye(e, _);
736
+ if (_.visibility !== "visible") {
737
+ if (!n || o) throw new w("UNSUPPORTED_CSS", "Unsupported CSS: visibility overrides are not supported.");
738
+ m.push({
739
+ code: "RASTER_TEXT_OMITTED",
740
+ message: `Raster text extraction omitted for visibility-controlled subtree ${e.tagName}.`
741
+ });
742
+ return;
743
+ }
744
+ if ((!n || o) && !(/* @__PURE__ */ "MAIN.SECTION.ARTICLE.DIV.SPAN.P.H1.H2.H3.H4.H5.H6.STRONG.EM.B.I.IMG.FONT.CENTER.BR.HR.TABLE.THEAD.TBODY.TFOOT.TR.TH.TD.CAPTION.COLGROUP.COL".split(".")).includes(e.tagName)) throw new w("UNSUPPORTED_ELEMENT", `Native snapshots do not support ${e.tagName}.`);
745
+ let y = !n && e.hasAttribute("data-raster"), b = !n && !y && r === "auto" ? me(_) : void 0, x = o || b !== void 0;
746
+ if (x && (o && me(_), F(e, _, !0, v !== void 0), I(e, _)), n && (_.transform !== "none" || _.writingMode !== "horizontal-tb" || _.direction !== "ltr" || _.opacity === "0" || _.clipPath !== "none" || _.maskImage !== "none" || _.overflowX !== "visible" || _.overflowY !== "visible")) {
747
+ m.push({
748
+ code: "RASTER_TEXT_OMITTED",
749
+ message: `Raster text extraction omitted for transformed, clipped, hidden, masked, or non-LTR subtree ${e.tagName}.`
750
+ });
751
+ return;
752
+ }
753
+ let S = N(e.getBoundingClientRect(), a);
754
+ if (!n && (S.x < -.1 || S.y < -.1 || S.x + S.width > a.width + .1 || S.y + S.height > a.height + .1)) throw new w("SOURCE_OVERFLOW", "Source content must fit within the root border box.");
755
+ let C = y || b !== void 0;
756
+ if (C && v && !(e instanceof HTMLTableElement)) throw new w("UNSUPPORTED_CSS", "Collapsed table cells and internal groups cannot be independently rasterized.");
757
+ if (C) {
758
+ if (_.position !== "static" || _.transform !== "none" || _.mixBlendMode !== "normal") throw new w("UNSUPPORTED_CSS", "A raster boundary must be static, untransformed, and independently compositable.");
759
+ if (b !== void 0 && he(e, _), c.push({
760
+ kind: "raster",
761
+ bounds: S,
762
+ element: e
763
+ }), m.push({
764
+ code: "RASTER_FALLBACK",
765
+ message: `${b === void 0 ? "An explicit raster subtree" : `Automatic raster fallback on ${e.tagName} for ${b}`} uses invisible PDF text for extraction where supported; generated content and clipped or transformed text are not represented.`
766
+ }), _.overflowX !== "visible" || _.overflowY !== "visible" || _.clipPath !== "none" || _.maskImage !== "none" || _.opacity === "0") {
767
+ m.push({
768
+ code: "RASTER_TEXT_OMITTED",
769
+ message: `Raster text extraction omitted for clipped, masked, or hidden boundary ${e.tagName}.`
770
+ });
771
+ return;
772
+ }
773
+ } else if (!n) {
774
+ if (F(e, _, !1, v !== void 0), I(e, _), e instanceof HTMLTableRowElement || e instanceof HTMLTableCellElement && e.rowSpan !== 1) {
775
+ let t = { ...S };
776
+ f.push(t), e instanceof HTMLTableRowElement && p.set(e, t);
777
+ }
778
+ if (e instanceof HTMLImageElement) {
779
+ if (_.objectFit !== "fill" || _.borderTopWidth !== "0px") throw new w("UNSUPPORTED_CSS", "Image boxes require object-fit: fill without borders.");
780
+ if ([
781
+ "paddingTop",
782
+ "paddingRight",
783
+ "paddingBottom",
784
+ "paddingLeft"
785
+ ].some((e) => Number.parseFloat(_.getPropertyValue(e.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`))) !== 0) || _.backgroundColor !== "rgba(0, 0, 0, 0)") throw new w("UNSUPPORTED_CSS", "Image boxes require zero padding and a transparent background.");
786
+ c.push({
787
+ kind: "image",
788
+ bounds: S,
789
+ element: e
790
+ });
791
+ } else if (![
792
+ "BR",
793
+ "COL",
794
+ "COLGROUP"
795
+ ].includes(e.tagName)) {
796
+ let t = {
797
+ kind: "box",
798
+ bounds: S,
799
+ background: _.backgroundColor,
800
+ borderColor: _.borderTopColor,
801
+ borderWidth: v ? 0 : Number.parseFloat(_.borderTopWidth)
802
+ };
803
+ c.push(t), i && u.set(e, t);
804
+ }
805
+ }
806
+ let T = n || C;
807
+ if (!T || x) {
808
+ let t = Array.from(e.children).filter((e) => e instanceof HTMLElement && !(v && ["COL", "COLGROUP"].includes(e.tagName)) && getComputedStyle(e).display !== "none" && getComputedStyle(e).visibility !== "hidden").map((e) => e.getBoundingClientRect());
809
+ for (let e = 0; e < t.length; e += 1) for (let n = e + 1; n < t.length; n += 1) {
810
+ let r = t[e], i = t[n];
811
+ if (Math.min(r.right, i.right) - Math.max(r.left, i.left) > .1 && Math.min(r.bottom, i.bottom) - Math.max(r.top, i.top) > .1) throw new w("UNSUPPORTED_CSS", "Overlapping sibling boxes are unsupported; isolate them in one raster subtree.");
812
+ }
813
+ }
814
+ for (let n of e.childNodes) if (n instanceof Text) c.push(...Ce(n, a, t, s, T));
815
+ else if (n instanceof HTMLElement) h(n, T, x);
816
+ else if (n instanceof Element) {
817
+ if (T) m.push({
818
+ code: "RASTER_TEXT_OMITTED",
819
+ message: `Raster text extraction omitted for ${n.tagName}.`
820
+ });
821
+ else throw new w("UNSUPPORTED_ELEMENT", `Cannot snapshot ${n.tagName}; use a raster subtree.`);
822
+ }
823
+ if (i && e instanceof HTMLTableSectionElement && e.tagName === "THEAD" && l.set(e, c.slice(g)), !T && e instanceof HTMLTableElement && v) {
824
+ let t = xe(e, a);
825
+ d.set(e, t);
826
+ for (let e of t.operations) c.push(e);
827
+ let n = Array.from(e.rows).filter((e) => p.has(e)), r = n[0] ? p.get(n[0]) : void 0, o = n.at(-1) ? p.get(n.at(-1)) : void 0, s = t.operations.reduce((e, { bounds: t }) => ({
828
+ top: Math.min(e.top, t.y),
829
+ bottom: Math.max(e.bottom, t.y + t.height)
830
+ }), {
831
+ top: r?.y ?? 0,
832
+ bottom: o ? o.y + o.height : 0
833
+ });
834
+ r && s.top < r.y && (r.height += r.y - s.top, r.y = s.top), o && (o.height = Math.max(o.height, s.bottom - o.y));
835
+ let u = e.tHead;
836
+ if (i && u && t.headerBounds) {
837
+ let e = t.headerBounds, n = t.operations.filter((t) => t.bounds.y < e.y + e.height + .001 && t.bounds.y + t.bounds.height > e.y - .001);
838
+ l.set(u, [...l.get(u) ?? [], ...n]);
839
+ }
840
+ }
841
+ }
842
+ h(e, !1);
843
+ let g = [];
844
+ for (let e of c) {
845
+ if (e.kind === "text") {
846
+ e.invisible || g.push(e);
847
+ continue;
848
+ }
849
+ if (e.kind === "box" && (e.background.startsWith("rgba(") ? Number(e.background.slice(e.background.lastIndexOf(",") + 1, -1)) : 1) === 0 && e.borderWidth === 0) continue;
850
+ let t = e.bounds;
851
+ if (g.some((e) => Math.min(e.bounds.x + e.bounds.width, t.x + t.width) - Math.max(e.bounds.x, t.x) > .1 && Math.min(e.bounds.y + e.bounds.height, t.y + t.height) - Math.max(e.bounds.y, t.y) > .1)) throw new w("UNSUPPORTED_CSS", "Text overlaps later visible paint whose CSS paint phases cannot be represented safely; use an explicit containing raster region.");
852
+ }
853
+ if (c.some((e) => {
854
+ if (e.kind === "text" && e.invisible) return !1;
855
+ let t = e.bounds;
856
+ return t.x < -.1 || t.y < -.1 || t.x + t.width > a.width + .1 || t.y + t.height > a.height + .1;
857
+ })) throw new w("SOURCE_OVERFLOW", "Visible source text or paint overflows the root border box.");
858
+ return {
859
+ width: a.width,
860
+ height: a.height,
861
+ operations: c,
862
+ warnings: m,
863
+ atomicBounds: f,
864
+ ...i ? { tableHeaders: Te(e, a, c, l, u, d) } : {}
865
+ };
866
+ }
867
+ // src/page.ts
868
+ function L(e) {
869
+ if (!e || typeof e != "object" || Array.isArray(e)) throw new w("INVALID_OPTIONS", "PDF page options must be an object.");
870
+ let t = {
871
+ A4: [595.28, 841.89],
872
+ A3: [841.89, 1190.55],
873
+ Letter: [612, 792]
874
+ }, n = e.format ?? "A4";
875
+ if (typeof n != "object" && !Object.hasOwn(t, n)) throw new w("INVALID_OPTIONS", `Unsupported page format: ${n}.`);
876
+ let r = e.orientation ?? "portrait";
877
+ if (r !== "portrait" && r !== "landscape") throw new w("INVALID_OPTIONS", `Unsupported page orientation: ${r}.`);
878
+ let i = e.margin ?? 24, a = typeof i == "number" ? {
879
+ top: i,
880
+ right: i,
881
+ bottom: i,
882
+ left: i
883
+ } : {
884
+ top: i?.top,
885
+ right: i?.right,
886
+ bottom: i?.bottom,
887
+ left: i?.left
888
+ };
889
+ if (Object.values(a).some((e) => !Number.isFinite(e) || e < 0)) throw new w("INVALID_OPTIONS", "Every page margin must be finite and nonnegative.");
890
+ let o = typeof n == "object" ? [n?.width, n?.height] : t[n].map((e) => e / .75);
891
+ if (o.some((e) => !Number.isFinite(e) || e <= 0)) throw new w("INVALID_OPTIONS", "Custom page width and height must be finite positive CSS pixel values.");
892
+ let s = o[r === "portrait" ? 0 : 1], c = o[+(r === "portrait")];
893
+ if (a.left + a.right >= s || a.top + a.bottom >= c) throw new w("INVALID_OPTIONS", "Page margins leave no positive content area.");
894
+ return {
895
+ width: s,
896
+ height: c,
897
+ margin: a
898
+ };
899
+ }
900
+ function De(e) {
901
+ if (!e || !Array.isArray(e.fonts) || e.fonts.length === 0) throw new w("INVALID_OPTIONS", "Provide at least one explicitly registered font.");
902
+ let t = L(e);
903
+ if (e.rasterScale !== void 0 && (!Number.isFinite(e.rasterScale) || e.rasterScale <= 0)) throw new w("INVALID_OPTIONS", "Raster scale must be a finite positive number.");
904
+ if (e.onWarning !== void 0 && typeof e.onWarning != "function") throw new w("INVALID_OPTIONS", "onWarning must be a function.");
905
+ if (e.onProgress !== void 0 && typeof e.onProgress != "function") throw new w("INVALID_OPTIONS", "onProgress must be a function.");
906
+ if (e.fallback !== void 0 && !["auto", "strict"].includes(e.fallback)) throw new w("INVALID_OPTIONS", "fallback must be auto or strict.");
907
+ if (e.pageBreak !== void 0 && !["auto", "css"].includes(e.pageBreak)) throw new w("INVALID_OPTIONS", "pageBreak must be auto or css.");
908
+ if (e.repeatTableHeaders !== void 0 && typeof e.repeatTableHeaders != "boolean") throw new w("INVALID_OPTIONS", "repeatTableHeaders must be a boolean.");
909
+ if (e.signal !== void 0 && !(e.signal instanceof AbortSignal)) throw new w("INVALID_OPTIONS", "signal must be an AbortSignal.");
910
+ return t;
911
+ }
912
+ // src/page-bands.ts
913
+ function R(e, t) {
914
+ if (e === void 0) return;
915
+ if (!e || typeof e != "object" || typeof e.text != "string" || !Number.isFinite(e.height) || e.height <= 0 || /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(e.text) || /[^\p{Script=Latin}\p{Script=Common}\p{Script=Inherited}]/u.test(e.text)) throw new w("INVALID_OPTIONS", "Page header/footer requires single-line Latin text and a finite positive reserved height.");
916
+ let n = e.font ?? t[0], r = e.fontSize ?? 12, i = e.align ?? "left";
917
+ if (!t.includes(n) || !Number.isFinite(r) || r <= 0 || ![
918
+ "left",
919
+ "center",
920
+ "right"
921
+ ].includes(i)) throw new w("INVALID_OPTIONS", "Page header/footer needs a font included in fonts, a positive fontSize and left/center/right alignment.");
922
+ return Object.freeze({
923
+ text: e.text,
924
+ height: e.height,
925
+ font: n,
926
+ fontSize: r,
927
+ align: i
928
+ });
929
+ }
930
+ function Oe(e, t) {
931
+ let n = R(t.header, t.fonts), r = R(t.footer, t.fonts), i = {
932
+ ...e,
933
+ margin: {
934
+ ...e.margin,
935
+ top: e.margin.top + (n?.height ?? 0),
936
+ bottom: e.margin.bottom + (r?.height ?? 0)
937
+ }
938
+ };
939
+ if (i.margin.top + i.margin.bottom >= i.height) throw new w("INVALID_OPTIONS", "Page header/footer heights and margins leave no positive source content area.");
940
+ return {
941
+ content: i,
942
+ header: n,
943
+ footer: r
944
+ };
945
+ }
946
+ // src/pagination.ts
947
+ var z = .01;
948
+ function B(e, t, n) {
949
+ if (![
950
+ e.x,
951
+ e.y,
952
+ e.width,
953
+ e.height
954
+ ].every(Number.isFinite) || e.width < 0 || e.height < 0 || e.y < -.01 || e.y + e.height > t + z) throw new w("PAGINATION_FAILED", `${n} geometry must be finite, nonnegative and within the source height.`);
955
+ }
956
+ function V(e, t) {
957
+ return e.y < t - z && e.y + e.height > t + z;
958
+ }
959
+ function ke(e, t, n) {
960
+ let r = e;
961
+ for (;;) {
962
+ let e = n.reduce((e, t) => V(t, r) ? Math.min(e, t.y) : e, r);
963
+ if (e === r) return r;
964
+ if (e <= t + z) throw new w("PAGINATION_FAILED", "Overlapping atomic items cannot fit on one page.");
965
+ r = e;
966
+ }
967
+ }
968
+ function Ae(e, t, n) {
969
+ if (!Number.isFinite(t) || t <= 0) throw new w("PAGINATION_FAILED", "Page content height must be finite and positive.");
970
+ if (!Number.isFinite(e.height) || e.height <= 0) throw new w("PAGINATION_FAILED", "Source height must be finite and positive.");
971
+ let r = [], i = [...e.operations.filter((e) => e.kind !== "box" && e.kind !== "border").map((e) => e.bounds), ...e.atomicBounds ?? []], a = e.tableHeaders ?? [];
972
+ for (let [n, r] of a.entries()) {
973
+ if (B(r.bounds, e.height, "Table header"), r.bounds.width <= 0 || r.bounds.height <= 0 || !Number.isFinite(r.bodyStart) || !Number.isFinite(r.bodyEnd) || r.bodyStart < r.bounds.y + r.bounds.height - z || r.bodyEnd <= r.bodyStart || r.bodyEnd > e.height + z) throw new w("PAGINATION_FAILED", "Repeated table headers require a positive header followed by finite body row bounds.");
974
+ if (a.slice(0, n).some((e) => Math.min(e.bodyEnd, r.bodyEnd) - Math.max(e.bounds.y, r.bounds.y) > z)) throw new w("PAGINATION_FAILED", "Repeated table header continuation intervals must not overlap.");
975
+ let o = r.bodyStart;
976
+ for (;;) {
977
+ let e = i.reduce((e, t) => t.y >= r.bodyStart - z && t.y < r.bodyEnd - z && (t.y <= r.bodyStart + z || t.y < o - z) ? Math.max(e, t.y + t.height) : e, o);
978
+ if (e === o) break;
979
+ o = e;
980
+ }
981
+ if (o <= r.bodyStart + z) throw new w("PAGINATION_FAILED", "Repeated table headers require a measured atomic first body row.");
982
+ if (o - r.bounds.y > t + z) throw new w("PAGINATION_FAILED", "A table header and its first atomic body row cannot fit on one page.");
983
+ i.push({
984
+ ...r.bounds,
985
+ height: o - r.bounds.y
986
+ });
987
+ }
988
+ for (let n of i) if (B(n, e.height, "Atomic"), n.height > t + z) throw new w("PAGINATION_FAILED", "An atomic item is taller than one page; this renderer cannot split it.");
989
+ let o = e.forcedBreaks ?? [];
990
+ for (let t of o) if (!Number.isFinite(t) || t < 0 || t > e.height) throw new w("PAGINATION_FAILED", "Forced page breaks must lie within the finite source height.");
991
+ let s = [...new Set(o)].filter((t) => t > z && t < e.height - z).sort((e, t) => e - t).filter((e, t, n) => t === 0 || e - n[t - 1] > z);
992
+ for (let e of s) if (i.some((t) => V(t, e))) throw new w("PAGINATION_FAILED", "A forced CSS page break crosses an atomic text, image, raster, table row or spanning cell.");
993
+ let c = !1;
994
+ function l() {
995
+ c || (c = !0, n?.({
996
+ code: "BREAK_AVOID_RELAXED",
997
+ message: "A CSS break-avoid preference could not fit on one page and was relaxed; native text, images and table rows remain indivisible."
998
+ }));
999
+ }
1000
+ let u = [];
1001
+ for (let n of e.avoidBreakBounds ?? []) B(n, e.height, "Preferred break-avoid"), !s.some((e) => V(n, e)) && (n.height > t + z ? l() : u.push(n));
1002
+ let d = [...i, ...u], f = 0, p = 0;
1003
+ for (; f < e.height;) {
1004
+ let n = a.find((e) => f >= e.bodyStart - z && f < e.bodyEnd - z), o = n ? (e.atomicBounds ?? []).reduce((e, t) => t.y >= f - z && t.y < n.bodyEnd - z ? Math.min(e, t.y) : e, Infinity) : f, c = Number.isFinite(o) ? Math.max(0, o - f) : 0, u = n ? Math.max(n.bounds.height, n.bodyStart - n.bounds.y - c) : 0, m = t - u;
1005
+ if (m <= z) throw new w("PAGINATION_FAILED", "A repeated table header leaves no space for its body rows.");
1006
+ for (; s[p] !== void 0 && s[p] <= f + z;) p += 1;
1007
+ let h = s[p] ?? e.height, g = Math.min(f + m, h, e.height);
1008
+ if (n && i.some((e) => e.y <= f + z && V(e, f + m))) throw new w("PAGINATION_FAILED", "A repeated table header and its atomic body row cannot fit on one page.");
1009
+ let _ = ke(g, f, i), v = _;
1010
+ if (Math.abs(g - h) > z) for (;;) {
1011
+ let e = d.reduce((e, t) => V(t, v) ? Math.min(e, t.y) : e, v);
1012
+ if (e === v) break;
1013
+ if (e <= f + z) {
1014
+ l(), v = _;
1015
+ break;
1016
+ }
1017
+ v = e;
1018
+ }
1019
+ if (v <= f + z) throw new w("PAGINATION_FAILED", "Page planning must advance through the source.");
1020
+ if (n && !(e.atomicBounds ?? []).some((e) => e.y >= f - z && e.y < n.bodyEnd - z && e.y + e.height <= v + z && e.y + e.height > f + z)) throw new w("PAGINATION_FAILED", "A repeated table header must share its page with a complete atomic body row.");
1021
+ r.push({
1022
+ start: f,
1023
+ end: v,
1024
+ ...n ? {
1025
+ header: n,
1026
+ headerHeight: u
1027
+ } : {}
1028
+ }), f = v;
1029
+ }
1030
+ return r;
1031
+ }
1032
+ // src/images.ts
1033
+ function H() {
1034
+ throw new w("RESOURCE_LOAD_FAILED", "JPEG EXIF orientation must be 1 with valid metadata; normalize the image pixels and remove orientation metadata before exporting.");
1035
+ }
1036
+ function je(e, t, n) {
1037
+ let r = new DataView(e.buffer, e.byteOffset + t, n - t);
1038
+ r.byteLength < 8 && H();
1039
+ let i = r.getUint16(0);
1040
+ i !== 18761 && i !== 19789 && H();
1041
+ let a = i === 18761;
1042
+ r.getUint16(2, a) !== 42 && H();
1043
+ let o = r.getUint32(4, a);
1044
+ (o < 8 || o + 2 > r.byteLength) && H();
1045
+ let s = r.getUint16(o, a), c = o + 2 + s * 12;
1046
+ c + 4 > r.byteLength && H();
1047
+ let l = !1;
1048
+ for (let e = 0; e < s; e += 1) {
1049
+ let t = o + 2 + e * 12;
1050
+ r.getUint16(t, a) === 274 && ((l || r.getUint16(t + 2, a) !== 3 || r.getUint32(t + 4, a) !== 1 || r.getUint16(t + 8, a) !== 1) && H(), l = !0);
1051
+ }
1052
+ let u = r.getUint32(c, a);
1053
+ u !== 0 && (u < 8 || u + 2 > r.byteLength) && H();
1054
+ }
1055
+ function Me(e) {
1056
+ if (e[0] === 137 && e[1] === 80 && e[2] === 78 && e[3] === 71 && e[4] === 13 && e[5] === 10 && e[6] === 26 && e[7] === 10) return "png";
1057
+ if (e[0] !== 255 || e[1] !== 216) throw new w("RESOURCE_LOAD_FAILED", "Native PDF images require PNG or JPEG bytes.");
1058
+ let t = 2;
1059
+ for (; t < e.length;) {
1060
+ for (e[t] !== 255 && H(); e[t] === 255;) t += 1;
1061
+ let n = e[t];
1062
+ if ((n === void 0 || n === 0) && H(), t += 1, n === 217) return "jpeg";
1063
+ if (n === 1 || n >= 208 && n <= 215) continue;
1064
+ t + 2 > e.length && H();
1065
+ let r = e[t] * 256 + e[t + 1], i = t + r;
1066
+ if ((r < 2 || i > e.length) && H(), n === 218) return "jpeg";
1067
+ let a = t + 2;
1068
+ n === 225 && i - a >= 4 && e[a] === 69 && e[a + 1] === 120 && e[a + 2] === 105 && e[a + 3] === 102 && ((i - a < 6 || e[a + 4] !== 0 || e[a + 5] !== 0) && H(), je(e, a + 6, i)), t = i;
1069
+ }
1070
+ H();
1071
+ }
1072
+ // src/raster.ts
1073
+ var Ne = 16777216, Pe = 8192, Fe = /^data:image\/(?:png|jpeg|gif|webp|avif);base64,[a-z\d+/=\s]+$/i;
1074
+ function Ie(e) {
1075
+ let t = e.bytes;
1076
+ if (!/^[\w -]+$/.test(e.family) || t.byteLength === 0) throw new w("RASTER_FAILED", "Raster capture requires nonempty registered fonts with plain CSS family names.");
1077
+ let n = "";
1078
+ for (let e = 0; e < t.length; e += 8192) n += String.fromCharCode(...t.subarray(e, e + 8192));
1079
+ let r = t[0] === 79 && t[1] === 84 && t[2] === 84 && t[3] === 79;
1080
+ return `@font-face { font-family: "${e.family}"; font-weight: ${e.weight}; font-style: ${e.style}; src: url("data:font/${r ? "otf" : "ttf"};base64,${btoa(n)}") format("${r ? "opentype" : "truetype"}"); }`;
1081
+ }
1082
+ function Le(e) {
1083
+ for (let t of e) {
1084
+ let n = e.getPropertyValue(t);
1085
+ for (let e of n.matchAll(/url\(\s*(["']?)(.*?)\1\s*\)/gi)) if (!Fe.test(e[2] ?? "")) throw new w("RASTER_FAILED", `Raster capture requires inline bitmap resources (${t}).`);
1086
+ }
1087
+ }
1088
+ function Re(e, t) {
1089
+ let n = e.getBoundingClientRect(), r = [e, ...e.querySelectorAll("*")];
1090
+ for (let i of r) {
1091
+ if (!(i instanceof HTMLElement)) throw new w("RASTER_FAILED", "Raster capture supports HTML subtrees only; inline SVG needs a separate experiment.");
1092
+ if (i.shadowRoot || i.tagName.includes("-") || i.tagName === "SLOT") throw new w("RASTER_FAILED", "Raster capture does not inspect shadow trees or distributed slot content in supported renderer.");
1093
+ if (/^(CANVAS|IFRAME|OBJECT|EMBED|VIDEO|AUDIO|INPUT|TEXTAREA|SELECT|SCRIPT|STYLE|LINK)$/.test(i.tagName)) throw new w("RASTER_FAILED", `Raster capture does not support ${i.tagName.toLowerCase()} elements.`);
1094
+ let r = getComputedStyle(i);
1095
+ if (Le(r), r.mixBlendMode !== "normal" || r.backdropFilter !== "none") throw new w("RASTER_FAILED", "Raster capture cannot reproduce blending with pixels outside its subtree.");
1096
+ if (r.position === "fixed" || r.position === "sticky") throw new w("RASTER_FAILED", "Raster capture does not reproduce viewport-dependent positioning.");
1097
+ if (i !== e && r.position === "absolute") throw new w("RASTER_FAILED", "Raster capture does not normalize external containing blocks for positioned descendants.");
1098
+ let a = r.boxShadow.split(/,(?![^(]*\))/);
1099
+ if (r.filter !== "none" || r.boxShadow !== "none" && a.some((e) => !e.includes("inset"))) throw new w("RASTER_FAILED", "Raster capture requires effects contained in the border box; outer shadows and filters need expanded bounds.");
1100
+ if (r.textShadow !== "none" || r.outlineStyle !== "none" && Number.parseFloat(r.outlineWidth) > 0) throw new w("RASTER_FAILED", "Raster capture requires expanded bounds before capturing text shadows or outlines.");
1101
+ if (r.backgroundAttachment.includes("fixed")) throw new w("RASTER_FAILED", "Raster capture does not preserve viewport-dependent background attachment.");
1102
+ if (i === e && r.transform !== "none") throw new w("RASTER_FAILED", "Raster capture does not normalize transformed region coordinates.");
1103
+ if (r.display === "list-item") throw new w("RASTER_FAILED", "Raster capture does not preserve generated list markers in supported renderer.");
1104
+ for (let e of ["::before", "::after"]) {
1105
+ let t = getComputedStyle(i, e).content;
1106
+ if (t !== "none" && t !== "normal") throw new w("RASTER_FAILED", "Raster capture does not support generated pseudo-element content in supported renderer.");
1107
+ }
1108
+ if (i instanceof HTMLImageElement) {
1109
+ if (i.srcset || !Fe.test(i.currentSrc || i.src)) throw new w("RASTER_FAILED", "Raster capture requires inline bitmap images without srcset.");
1110
+ if (!i.complete || i.naturalWidth === 0) throw new w("RASTER_FAILED", "Raster capture requires successfully decoded images.");
1111
+ }
1112
+ if ([...i.childNodes].some((e) => e.nodeType === Node.TEXT_NODE && !!e.textContent?.trim())) {
1113
+ if (!r.font) throw new w("RASTER_FAILED", "Raster capture requires a serializable computed font shorthand to preserve exact font sizes.");
1114
+ let e = r.fontFamily.split(",")[0]?.trim().replace(/^["']|["']$/g, "");
1115
+ if (!t.some((t) => t.family.toLowerCase() === e?.toLowerCase() && t.weight === Number(r.fontWeight) && t.style === r.fontStyle)) throw new w("RASTER_FAILED", "Raster capture text requires an explicitly registered matching font face.");
1116
+ }
1117
+ let o = i.getBoundingClientRect();
1118
+ if (o.width > 0 && o.height > 0 && (o.left < n.left - .5 || o.top < n.top - .5 || o.right > n.right + .5 || o.bottom > n.bottom + .5)) throw new w("RASTER_FAILED", "Raster capture descendants must stay inside the selected border box.");
1119
+ }
1120
+ }
1121
+ async function ze(e, t, n, r = {
1122
+ x: 0,
1123
+ y: 0
1124
+ }) {
1125
+ if (!e.isConnected || e.ownerDocument !== document) throw new w("RASTER_FAILED", "Raster capture requires a connected element in the current document.");
1126
+ if (!Number.isFinite(n) || n <= 0) throw new w("RASTER_FAILED", "Raster scale must be a finite positive number.");
1127
+ if (!r || ![r.x, r.y].every((e) => Number.isFinite(e) && e >= 0 && e < 1)) throw new w("RASTER_FAILED", "Raster offsets must be finite CSS pixel fractions from zero inclusive to one exclusive.");
1128
+ await document.fonts.ready;
1129
+ let { width: i, height: a } = e.getBoundingClientRect(), o = Math.ceil(i + r.x), s = Math.ceil(a + r.y), c = Math.ceil(o * n), l = Math.ceil(s * n);
1130
+ if (i <= 0 || a <= 0 || c < 1 || l < 1 || c > Pe || l > Pe || c * l > Ne) throw new w("RASTER_FAILED", "Raster region exceeds the supported renderer canvas budget or has empty bounds.");
1131
+ Re(e, t);
1132
+ let u = t.map(Ie).join("\n"), d = ["font", ...Array.from(getComputedStyle(e)).filter((e) => e !== "font-size")], f = (await C(e, {
1133
+ width: o,
1134
+ height: s,
1135
+ pixelRatio: n,
1136
+ skipAutoScale: !0,
1137
+ fontEmbedCSS: u,
1138
+ includeStyleProperties: d,
1139
+ style: {
1140
+ margin: "0",
1141
+ top: "0",
1142
+ left: "0",
1143
+ right: "auto",
1144
+ bottom: "auto",
1145
+ boxSizing: "border-box",
1146
+ width: `${i}px`,
1147
+ height: `${a}px`,
1148
+ transform: `translate(${r.x}px, ${r.y}px)`
1149
+ }
1150
+ })).match(/^data:image\/png;base64,(.+)$/)?.[1];
1151
+ if (!f) throw new w("RASTER_FAILED", "Raster capture produced an empty or invalid PNG.");
1152
+ let p = atob(f);
1153
+ return Uint8Array.from(p, (e) => e.charCodeAt(0));
1154
+ }
1155
+ // src/text.ts
1156
+ var Be = class {
1157
+ font;
1158
+ program;
1159
+ words = /* @__PURE__ */ new Map();
1160
+ unicode = /* @__PURE__ */ new Map();
1161
+ widths = /* @__PURE__ */ new Map();
1162
+ unitsPerEm;
1163
+ constructor(t, n) {
1164
+ this.font = t, this.program = e.create(n), this.unitsPerEm = this.program.unitsPerEm;
1165
+ }
1166
+ shape(e, t = !0) {
1167
+ let n = `${t ? "1" : "0"}:${e}`, r = this.words.get(n);
1168
+ if (r) return r;
1169
+ let a = this.program.layout(e, { kern: t }), o = this.font.encodeText(e).asString();
1170
+ if (o.length !== a.glyphs.length * 4) throw new w("PDF_WRITE_FAILED", "PDF font encoding disagrees with font shaping.");
1171
+ let s = 0, c = 0, l = a.glyphs.map((e, t) => {
1172
+ let n = o.slice(t * 4, t * 4 + 4);
1173
+ if (Number.parseInt(n, 16) !== e.id) throw new w("PDF_WRITE_FAILED", "PDF glyph identifiers disagree with shaping.");
1174
+ if (e.codePoints.length === 0) throw new w("PDF_WRITE_FAILED", "The font produced a shaped glyph without a Unicode source mapping.");
1175
+ let r = a.positions[t];
1176
+ this.unicode.has(n) || this.unicode.set(n, [...e.codePoints]), this.widths.set(n, e.advanceWidth * 1e3 / this.unitsPerEm);
1177
+ let l = {
1178
+ encoded: i.of(n),
1179
+ x: s + r.xOffset,
1180
+ y: c + r.yOffset
1181
+ };
1182
+ return s += r.xAdvance, c += r.yAdvance, l;
1183
+ });
1184
+ return this.words.set(n, l), l;
1185
+ }
1186
+ measure(e) {
1187
+ let t = this.program.layout(e), n = 0, r = 0, i = 0, a = 0, o = this.program.ascent, s = -this.program.descent;
1188
+ for (let e = 0; e < t.glyphs.length; e += 1) {
1189
+ let c = t.glyphs[e], l = t.positions[e];
1190
+ i = Math.min(i, n + l.xOffset + c.bbox.minX), a = Math.max(a, n + l.xOffset + c.bbox.maxX), o = Math.max(o, r + l.yOffset + c.bbox.maxY), s = Math.max(s, -(r + l.yOffset + c.bbox.minY)), n += l.xAdvance, r += l.yAdvance;
1191
+ }
1192
+ return {
1193
+ left: i,
1194
+ right: Math.max(a, n),
1195
+ ascent: o,
1196
+ descent: s
1197
+ };
1198
+ }
1199
+ async embedUnicode(e) {
1200
+ if (await this.font.embed(), this.unicode.size === 0) return;
1201
+ let r = [...this.unicode].map(([e, t]) => {
1202
+ let n = String.fromCodePoint(...t), r = "";
1203
+ for (let e = 0; e < n.length; e += 1) r += n.charCodeAt(e).toString(16).padStart(4, "0");
1204
+ return `<${e}> <${r}>`;
1205
+ }), i = [];
1206
+ for (let e = 0; e < r.length; e += 100) {
1207
+ let t = r.slice(e, e + 100);
1208
+ i.push(`${t.length} beginbfchar\n${t.join("\n")}\nendbfchar`);
1209
+ }
1210
+ let o = [
1211
+ "/CIDInit /ProcSet findresource begin",
1212
+ "12 dict begin",
1213
+ "begincmap",
1214
+ "/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def",
1215
+ "/CMapName /RenderPDFUnicode def",
1216
+ "/CMapType 2 def",
1217
+ "1 begincodespacerange",
1218
+ "<0000> <ffff>",
1219
+ "endcodespacerange",
1220
+ ...i,
1221
+ "endcmap",
1222
+ "CMapName currentdict /CMap defineresource pop",
1223
+ "end",
1224
+ "end"
1225
+ ].join("\n"), s = e.context.lookup(this.font.ref, n);
1226
+ s.set(a.of("ToUnicode"), e.context.register(e.context.flateStream(o)));
1227
+ let c = s.lookup(a.of("DescendantFonts"), t).lookup(0, n), l = [...this.widths].sort(([e], [t]) => Number.parseInt(e, 16) - Number.parseInt(t, 16)).flatMap(([e, t]) => [Number.parseInt(e, 16), [t]]);
1228
+ c.set(a.of("W"), e.context.obj(l));
1229
+ }
1230
+ }, U = .75;
1231
+ function W(e) {
1232
+ let t = e.match(/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/);
1233
+ if (!t) throw new w("UNSUPPORTED_CSS", `Unsupported computed color: ${e}`);
1234
+ return {
1235
+ color: g(Number(t[1]) / 255, Number(t[2]) / 255, Number(t[3]) / 255),
1236
+ opacity: Number(t[4] ?? 1)
1237
+ };
1238
+ }
1239
+ function G(e, t) {
1240
+ let n = t.find(({ definition: t }) => t.family.toLowerCase() === e.family.toLowerCase() && t.weight === e.weight && t.style === e.style);
1241
+ if (!n) throw new w("MISSING_FONT", `Unregistered font face: ${e.family} ${e.weight} ${e.style}`);
1242
+ for (let t of e.text) if (!n.characters.has(t.codePointAt(0))) throw new w("MISSING_GLYPH", `Missing glyph: ${t} (${e.family} ${e.weight} ${e.style})`);
1243
+ return n;
1244
+ }
1245
+ function K(e, t, n, r, i, a) {
1246
+ let c = W(t.color), l = a.fonts.get(n.font);
1247
+ if (l || (l = e.node.newFontDictionary(n.font.name, n.font.ref), a.fonts.set(n.font, l)), e.pushOperators(m(), _(c.color)), c.opacity !== 1) {
1248
+ let t = a.opacity.get(c.opacity);
1249
+ t || (t = e.node.newExtGState("TextOpacity", e.doc.context.obj({
1250
+ Type: "ExtGState",
1251
+ ca: c.opacity
1252
+ })), a.opacity.set(c.opacity, t)), e.pushOperators(y(t));
1253
+ }
1254
+ e.pushOperators(s(), v(l, t.fontSize * U), x(t.invisible ? o.Invisible : o.Fill));
1255
+ let u = t.fontSize * U / n.positioned.unitsPerEm, d = (i.height - i.margin.top - (t.baseline - r)) * U;
1256
+ for (let r of t.runs) {
1257
+ let a = (i.margin.left + r.x) * U;
1258
+ for (let i of n.positioned.shape(r.text, t.kerning ?? !0)) e.pushOperators(b(1, 0, 0, 1, a + i.x * u, d + i.y * u), S(i.encoded));
1259
+ }
1260
+ e.pushOperators(f(), p());
1261
+ }
1262
+ function Ve(e, t, n, r, i, a) {
1263
+ let o = e.text.replaceAll("{pageNumber}", String(t)).replaceAll("{pageCount}", String(n)), s = a.find((t) => t.definition === e.font), c = e.fontSize / s.positioned.unitsPerEm, l = s.positioned.measure(o), u = (l.right - l.left) * c, d = (l.ascent + l.descent) * c, f = i.width - i.margin.left - i.margin.right;
1264
+ if (u > f + .01 || d > e.height + .01) throw new w("SOURCE_OVERFLOW", "Page header/footer text does not fit its reserved height or page content width; increase its area or reduce fontSize.");
1265
+ let p = e.align === "right" ? f - u : e.align === "center" ? (f - u) / 2 : 0, m = p - l.left * c, h = r - i.margin.top + (e.height - d) / 2;
1266
+ return {
1267
+ kind: "text",
1268
+ bounds: {
1269
+ x: p,
1270
+ y: h,
1271
+ width: u,
1272
+ height: d
1273
+ },
1274
+ text: o,
1275
+ runs: [{
1276
+ text: o,
1277
+ x: m,
1278
+ width: u
1279
+ }],
1280
+ baseline: h + l.ascent * c,
1281
+ fontSize: e.fontSize,
1282
+ family: e.font.family,
1283
+ weight: e.font.weight,
1284
+ style: e.font.style,
1285
+ color: "rgb(0, 0, 0)",
1286
+ invisible: !1
1287
+ };
1288
+ }
1289
+ function He(e) {
1290
+ let t = Math.floor(e.x), n = Math.floor(e.y);
1291
+ return {
1292
+ x: t,
1293
+ y: n,
1294
+ width: Math.ceil(e.x + e.width) - t,
1295
+ height: Math.ceil(e.y + e.height) - n
1296
+ };
1297
+ }
1298
+ async function Ue(e, t, n) {
1299
+ let r = t.currentSrc || t.src;
1300
+ try {
1301
+ T(n);
1302
+ let t = await fetch(r, {
1303
+ mode: "cors",
1304
+ credentials: "same-origin",
1305
+ ...n ? { signal: n } : {}
1306
+ });
1307
+ if (!t.ok) throw Error(`Image request returned HTTP ${t.status}.`);
1308
+ let i = new Uint8Array(await t.arrayBuffer());
1309
+ return T(n), Me(i) === "png" ? await e.embedPng(i) : await e.embedJpg(i);
1310
+ } catch (e) {
1311
+ throw T(n), e instanceof w ? e : new w("RESOURCE_LOAD_FAILED", "The source image could not be embedded; provide a readable PNG/JPEG with same-origin or CORS access.", { cause: e });
1312
+ }
1313
+ }
1314
+ async function We(t, n, i, a, o = {}) {
1315
+ try {
1316
+ if (T(o.signal), t.width > i.width - i.margin.left - i.margin.right) throw new w("SOURCE_OVERFLOW", "Source is wider than the PDF content area.");
1317
+ let s = await r.create();
1318
+ T(o.signal), s.registerFontkit(e), oe(s, o.metadata);
1319
+ let l = o.reportProgress ? n.length + t.operations.filter((e) => e.kind === "image" || e.kind === "raster").length : 0, u = 0;
1320
+ o.reportProgress && await o.reportProgress({
1321
+ stage: "resources",
1322
+ completed: 0,
1323
+ total: l
1324
+ });
1325
+ let f = [];
1326
+ for (let e of n) {
1327
+ T(o.signal);
1328
+ let t = await s.embedFont(e.bytes);
1329
+ f.push({
1330
+ definition: e,
1331
+ font: t,
1332
+ characters: new Set(t.getCharacterSet()),
1333
+ positioned: new Be(t, e.bytes)
1334
+ }), u += 1, o.reportProgress && await o.reportProgress({
1335
+ stage: "resources",
1336
+ completed: u,
1337
+ total: l
1338
+ });
1339
+ }
1340
+ for (let e of t.operations) e.kind !== "text" || e.invisible && o.includeRasterText === !1 || G(e, f);
1341
+ let g = a.map((e, t) => {
1342
+ let n = [];
1343
+ o.header && n.push(Ve(o.header, t + 1, a.length, i.margin.top, i, f)), o.footer && n.push(Ve(o.footer, t + 1, a.length, i.height - i.margin.bottom - o.footer.height, i, f));
1344
+ for (let e of n) G(e, f);
1345
+ return n;
1346
+ }), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map();
1347
+ for (let e of t.operations) {
1348
+ if (T(o.signal), e.kind === "raster") {
1349
+ let t = He(e.bounds);
1350
+ try {
1351
+ let r = await ze(e.element, n, o.rasterScale ?? 2, {
1352
+ x: e.bounds.x - t.x,
1353
+ y: e.bounds.y - t.y
1354
+ });
1355
+ T(o.signal), _.set(e, await s.embedPng(r));
1356
+ } catch (e) {
1357
+ throw T(o.signal), e instanceof w ? e : new w("RASTER_FAILED", "The selected local raster region could not be captured.", { cause: e });
1358
+ }
1359
+ }
1360
+ if (e.kind === "image") {
1361
+ let t = e.element.currentSrc || e.element.src, n = v.get(t);
1362
+ n || (n = await Ue(s, e.element, o.signal), v.set(t, n)), _.set(e, n);
1363
+ }
1364
+ (e.kind === "image" || e.kind === "raster") && (u += 1, o.reportProgress && await o.reportProgress({
1365
+ stage: "resources",
1366
+ completed: u,
1367
+ total: l
1368
+ }));
1369
+ }
1370
+ o.reportProgress && await o.reportProgress({
1371
+ stage: "pages",
1372
+ completed: 0,
1373
+ total: a.length
1374
+ });
1375
+ for (let [e, n] of a.entries()) {
1376
+ T(o.signal);
1377
+ let r = s.addPage([i.width * U, i.height * U]), l = {
1378
+ fonts: /* @__PURE__ */ new Map(),
1379
+ opacity: /* @__PURE__ */ new Map()
1380
+ };
1381
+ function u(e, t, n) {
1382
+ let a = {
1383
+ ...i,
1384
+ margin: {
1385
+ ...i.margin,
1386
+ top: n.y
1387
+ }
1388
+ };
1389
+ r.pushOperators(m(), h(n.x * U, (i.height - n.y - n.height) * U, n.width * U, n.height * U), c(), d());
1390
+ for (let s of e) {
1391
+ let e = s.bounds;
1392
+ if (e.y >= t + n.height - .01 || e.y + e.height <= t + .01) continue;
1393
+ if (s.kind === "text") {
1394
+ s.invisible && o.includeRasterText === !1 || K(r, s, G(s, f), t, a, l);
1395
+ continue;
1396
+ }
1397
+ let c = s.kind === "raster" ? He(e) : e, u = {
1398
+ x: (i.margin.left + c.x) * U,
1399
+ y: (i.height - n.y - (c.y - t) - c.height) * U,
1400
+ width: c.width * U,
1401
+ height: c.height * U
1402
+ };
1403
+ if (s.kind === "box") {
1404
+ let e = W(s.background), t = W(s.borderColor);
1405
+ if (r.drawRectangle({
1406
+ ...u,
1407
+ color: e.color,
1408
+ opacity: e.opacity
1409
+ }), s.borderWidth > 0) {
1410
+ let e = s.borderWidth * U / 2;
1411
+ r.drawRectangle({
1412
+ x: u.x + e,
1413
+ y: u.y + e,
1414
+ width: u.width - e * 2,
1415
+ height: u.height - e * 2,
1416
+ borderWidth: s.borderWidth * U,
1417
+ borderColor: t.color,
1418
+ borderOpacity: t.opacity
1419
+ });
1420
+ }
1421
+ } else if (s.kind === "border") {
1422
+ let e = W(s.color);
1423
+ r.drawRectangle({
1424
+ ...u,
1425
+ color: e.color,
1426
+ opacity: e.opacity
1427
+ });
1428
+ } else r.drawImage(_.get(s), u);
1429
+ }
1430
+ r.pushOperators(p());
1431
+ }
1432
+ let v = i.margin.top + (o.header?.height ?? 0), y = n.headerHeight ?? (n.header ? n.header.bodyStart - n.header.bounds.y : 0);
1433
+ if (o.header) {
1434
+ let t = g[e][0];
1435
+ K(r, t, G(t, f), 0, i, l);
1436
+ }
1437
+ if (n.header && u(n.header.operations, n.header.bounds.y, {
1438
+ x: i.margin.left + n.header.bounds.x,
1439
+ y: v,
1440
+ width: n.header.bounds.width,
1441
+ height: y
1442
+ }), u(t.operations, n.start, {
1443
+ x: i.margin.left,
1444
+ y: v + y,
1445
+ width: i.width - i.margin.left - i.margin.right,
1446
+ height: n.end - n.start
1447
+ }), o.footer) {
1448
+ let t = g[e].at(-1);
1449
+ K(r, t, G(t, f), 0, i, l);
1450
+ }
1451
+ o.reportProgress && await o.reportProgress({
1452
+ stage: "pages",
1453
+ completed: e + 1,
1454
+ total: a.length
1455
+ });
1456
+ }
1457
+ T(o.signal), o.reportProgress && await o.reportProgress({
1458
+ stage: "saving",
1459
+ completed: 0,
1460
+ total: 1
1461
+ });
1462
+ for (let e of f) await e.positioned.embedUnicode(s), T(o.signal);
1463
+ let y = Uint8Array.from(await s.save());
1464
+ return T(o.signal), o.reportProgress && await o.reportProgress({
1465
+ stage: "saving",
1466
+ completed: 1,
1467
+ total: 1
1468
+ }), {
1469
+ bytes: y,
1470
+ slices: a
1471
+ };
1472
+ } catch (e) {
1473
+ throw T(o.signal), e instanceof w ? e : new w("PDF_WRITE_FAILED", "The measured content could not be serialized as a PDF.", { cause: e });
1474
+ }
1475
+ }
1476
+ // src/prepare.ts
1477
+ async function q(e, t) {
1478
+ return T(t), t ? new Promise((n, r) => {
1479
+ let i = () => r(new DOMException("PDF rendering was cancelled.", "AbortError"));
1480
+ t.addEventListener("abort", i, { once: !0 }), e.then(n, r).finally(() => t.removeEventListener("abort", i));
1481
+ }) : e;
1482
+ }
1483
+ function Ge(e, t) {
1484
+ if (T(t), typeof document > "u" || !(e instanceof HTMLElement) || !e.isConnected || e.ownerDocument !== document) throw new w("INVALID_SOURCE", "Provide a connected HTMLElement in the current document.");
1485
+ let n = !1, r, i = /* @__PURE__ */ new Map(), a = new MutationObserver(() => {
1486
+ n = !0;
1487
+ }), o = [];
1488
+ a.observe(e, {
1489
+ subtree: !0,
1490
+ attributes: !0,
1491
+ childList: !0,
1492
+ characterData: !0
1493
+ });
1494
+ let s = e.parentElement, c = e.getRootNode();
1495
+ for (c instanceof ShadowRoot && (a.observe(c, {
1496
+ subtree: !0,
1497
+ attributes: !0,
1498
+ childList: !0,
1499
+ characterData: !0
1500
+ }), s ??= c.host); s;) o.push(s), a.observe(s, { attributes: !0 }), s = s.parentElement ?? (s.getRootNode() instanceof ShadowRoot ? s.getRootNode().host : null);
1501
+ a.observe(document.head, {
1502
+ subtree: !0,
1503
+ attributes: !0,
1504
+ childList: !0,
1505
+ characterData: !0
1506
+ });
1507
+ let l = Array.from(getComputedStyle(document.documentElement)).filter((e) => !e.startsWith("--"));
1508
+ function u() {
1509
+ let t = 2166136261, n = 5381;
1510
+ function r(e) {
1511
+ let r = i.get(e);
1512
+ r === void 0 && (r = i.size + 1, i.set(e, r)), t = Math.imul(t ^ r, 16777619), n = Math.imul(n, 33) ^ r;
1513
+ }
1514
+ function a(e, t) {
1515
+ let n = getComputedStyle(e, t);
1516
+ if (r(t ?? "element"), t && (r(n.content), n.content === "none" || n.content === "normal")) return;
1517
+ let i = n.length, a = i >= l.length ? l : [];
1518
+ r(String(i));
1519
+ for (let e = 0; e < i; e += 1) {
1520
+ let t = a[e] ?? n[e];
1521
+ e >= a.length && r(t), r(n.getPropertyValue(t));
1522
+ }
1523
+ }
1524
+ let s = e.getBoundingClientRect();
1525
+ for (let e of o) a(e);
1526
+ for (let t of [e, ...e.querySelectorAll("*")]) {
1527
+ a(t), a(t, "::before"), a(t, "::after");
1528
+ let e = t.getBoundingClientRect();
1529
+ r(`${e.x - s.x},${e.y - s.y},${e.width},${e.height}`);
1530
+ }
1531
+ return `${t >>> 0}:${n >>> 0}`;
1532
+ }
1533
+ function d() {
1534
+ if (T(t), a.takeRecords().length && (n = !0), !e.isConnected || n || r !== void 0 && u() !== r) throw new w("SOURCE_CHANGED", "The source or its styles changed during PDF rendering. Retry with a stable source.");
1535
+ }
1536
+ function f() {
1537
+ if (d(), [...e.getAnimations({ subtree: !0 }), ...o.flatMap((e) => e.getAnimations())].some((e) => e.playState === "running")) throw new w("UNSUPPORTED_CSS", "Pause source animations before rendering a PDF.");
1538
+ r = u();
1539
+ }
1540
+ async function p() {
1541
+ await q(document.fonts.ready, t);
1542
+ try {
1543
+ await q(Promise.all([...e.querySelectorAll("img"), ...e instanceof HTMLImageElement ? [e] : []].map((e) => e.decode())), t);
1544
+ } catch (e) {
1545
+ throw T(t), new w("RESOURCE_LOAD_FAILED", "A source image could not be decoded.", { cause: e });
1546
+ }
1547
+ d();
1548
+ }
1549
+ return {
1550
+ ready: p,
1551
+ captureBaseline: f,
1552
+ assertUnchanged: d,
1553
+ dispose: () => a.disconnect()
1554
+ };
1555
+ }
1556
+ // src/progress.ts
1557
+ function Ke(e, t) {
1558
+ let n, r = 0;
1559
+ return {
1560
+ report: e ? async (i) => {
1561
+ T(t);
1562
+ try {
1563
+ e(Object.freeze({ ...i }));
1564
+ } catch (e) {
1565
+ throw n = { error: e }, e;
1566
+ }
1567
+ T(t), i.stage !== "complete" && (i.completed === 0 || i.completed === i.total || performance.now() - r >= 32) && (await new Promise((e) => setTimeout(e, 0)), r = performance.now(), T(t));
1568
+ } : void 0,
1569
+ rethrow(e) {
1570
+ throw n ? n.error : (T(t), e);
1571
+ }
1572
+ };
1573
+ }
1574
+ // src/result.ts
1575
+ function qe(e, t, n) {
1576
+ let r = Uint8Array.from(e), i = Object.freeze(n.map((e) => Object.freeze({ ...e })));
1577
+ return Object.freeze({
1578
+ pageCount: t,
1579
+ warnings: i,
1580
+ async toUint8Array() {
1581
+ return Uint8Array.from(r);
1582
+ },
1583
+ async toBlob() {
1584
+ return new Blob([r], { type: "application/pdf" });
1585
+ },
1586
+ async download(e = "document.pdf") {
1587
+ if (typeof e != "string" || !e.trim() || /[/\\]/.test(e) || [...e].some((e) => e.codePointAt(0) < 32)) throw new w("INVALID_OPTIONS", "Provide a nonempty PDF filename without path separators or control characters.");
1588
+ let t = URL.createObjectURL(new Blob([r], { type: "application/pdf" }));
1589
+ try {
1590
+ let n = document.createElement("a");
1591
+ n.href = t, n.download = e, n.click();
1592
+ } finally {
1593
+ window.setTimeout(() => URL.revokeObjectURL(t), 1e3);
1594
+ }
1595
+ }
1596
+ });
1597
+ }
1598
+ // src/render-pdf.ts
1599
+ async function Je(e, t, n = !0) {
1600
+ let r = De(t), i = Oe(r, t), a = ae(t.metadata), o = [...t.fonts];
1601
+ A(o);
1602
+ let { signal: s, onWarning: c, onProgress: l, rasterScale: u = 2, fallback: d = "auto", pageBreak: f = "css", repeatTableHeaders: p = !1 } = t, m = Ge(e, s), h = Ke(l, s), g = h.report;
1603
+ try {
1604
+ g && await g({
1605
+ stage: "preparing",
1606
+ completed: 0,
1607
+ total: 1
1608
+ }), await m.ready(), g && m.captureBaseline(), g && await g({
1609
+ stage: "preparing",
1610
+ completed: 1,
1611
+ total: 1
1612
+ }), g && await g({
1613
+ stage: "layout",
1614
+ completed: 0,
1615
+ total: 1
1616
+ }), m.assertUnchanged();
1617
+ let t = Ee(e, o, {
1618
+ fallback: d,
1619
+ repeatTableHeaders: p
1620
+ });
1621
+ if (g || m.captureBaseline(), g && await g({
1622
+ stage: "layout",
1623
+ completed: 1,
1624
+ total: 1
1625
+ }), g && await g({
1626
+ stage: "pagination",
1627
+ completed: 0,
1628
+ total: 1
1629
+ }), g && m.assertUnchanged(), t.width > r.width - r.margin.left - r.margin.right) throw new w("SOURCE_OVERFLOW", "Source is wider than the configured page content area. Set the source width explicitly; no implicit scaling is applied.");
1630
+ f === "css" && Object.assign(t, ie(e, t));
1631
+ let l = [], h = Ae(t, i.content.height - i.content.margin.top - i.content.margin.bottom, (e) => l.push(e));
1632
+ g && await g({
1633
+ stage: "pagination",
1634
+ completed: 1,
1635
+ total: 1
1636
+ });
1637
+ let _ = [...t.warnings, ...l];
1638
+ t.operations.some((e) => e.kind === "text") && !_.some((e) => e.code === "TEXT_METRICS_APPROXIMATED") && _.unshift({
1639
+ code: "TEXT_METRICS_APPROXIMATED",
1640
+ message: "PDF text uses browser word origins and approximate baseline/kerning metrics; full glyph shaping fidelity is not guaranteed."
1641
+ });
1642
+ for (let e of _) c?.(Object.freeze(e));
1643
+ (c || g) && m.assertUnchanged();
1644
+ let v = await q(We(t, o, r, h, {
1645
+ rasterScale: u,
1646
+ includeRasterText: n,
1647
+ ...i.header ? { header: i.header } : {},
1648
+ ...i.footer ? { footer: i.footer } : {},
1649
+ ...a ? { metadata: a } : {},
1650
+ ...g ? { reportProgress: g } : {},
1651
+ ...s ? { signal: s } : {}
1652
+ }), s);
1653
+ return m.assertUnchanged(), A(o), T(s), g && (await g({
1654
+ stage: "complete",
1655
+ completed: 1,
1656
+ total: 1
1657
+ }), m.assertUnchanged(), A(o)), {
1658
+ ...v,
1659
+ snapshot: t,
1660
+ warnings: _
1661
+ };
1662
+ } catch (e) {
1663
+ return h.rethrow(e);
1664
+ } finally {
1665
+ m.dispose();
1666
+ }
1667
+ }
1668
+ async function Ye(e, t) {
1669
+ let n = await Je(e, t);
1670
+ return qe(n.bytes, n.slices.length, n.warnings);
1671
+ }
1672
+ // src/image-geometry.ts
1673
+ var Xe = 4e7;
1674
+ function J(e, t) {
1675
+ if (!Number.isSafeInteger(e) || !Number.isSafeInteger(t) || e <= 0 || t <= 0) throw new w("INVALID_SOURCE", "Image dimensions must be positive safe integers.");
1676
+ if (e > 4e7 / t) throw new w("UNSUPPORTED_IMAGE", `Each image frame must contain at most ${Xe} pixels.`);
1677
+ }
1678
+ function Ze(e, t, n, r) {
1679
+ if (J(e, t), !Number.isInteger(n) || n < 1 || n > 8) throw new w("INVALID_SOURCE", "Image orientation must be an integer from 1 through 8.");
1680
+ let i = n >= 5 ? t : e, a = n >= 5 ? e : t, o = r.width - r.margin.left - r.margin.right, s = r.height - r.margin.top - r.margin.bottom, c = Math.min(o / i, s / a), l = i * c, u = a * c, d = r.margin.left + (o - l) / 2, f = r.margin.bottom + (s - u) / 2, [p, m, h, g, _, v] = [
1681
+ [
1682
+ 1,
1683
+ 0,
1684
+ 0,
1685
+ 1,
1686
+ 0,
1687
+ 0
1688
+ ],
1689
+ [
1690
+ -1,
1691
+ 0,
1692
+ 0,
1693
+ 1,
1694
+ 1,
1695
+ 0
1696
+ ],
1697
+ [
1698
+ -1,
1699
+ 0,
1700
+ 0,
1701
+ -1,
1702
+ 1,
1703
+ 1
1704
+ ],
1705
+ [
1706
+ 1,
1707
+ 0,
1708
+ 0,
1709
+ -1,
1710
+ 0,
1711
+ 1
1712
+ ],
1713
+ [
1714
+ 0,
1715
+ -1,
1716
+ -1,
1717
+ 0,
1718
+ 1,
1719
+ 1
1720
+ ],
1721
+ [
1722
+ 0,
1723
+ -1,
1724
+ 1,
1725
+ 0,
1726
+ 0,
1727
+ 1
1728
+ ],
1729
+ [
1730
+ 0,
1731
+ 1,
1732
+ 1,
1733
+ 0,
1734
+ 0,
1735
+ 0
1736
+ ],
1737
+ [
1738
+ 0,
1739
+ 1,
1740
+ -1,
1741
+ 0,
1742
+ 1,
1743
+ 0
1744
+ ]
1745
+ ][n - 1];
1746
+ return [
1747
+ p * l,
1748
+ m * u,
1749
+ h * l,
1750
+ g * u,
1751
+ d + _ * l,
1752
+ f + v * u
1753
+ ];
1754
+ }
1755
+ // src/image-input.ts
1756
+ function Y(e) {
1757
+ throw new w("INVALID_SOURCE", e);
1758
+ }
1759
+ var Qe = Uint32Array.from({ length: 256 }, (e, t) => {
1760
+ let n = t;
1761
+ for (let e = 0; e < 8; e += 1) n = n >>> 1 ^ (n & 1 ? 3988292384 : 0);
1762
+ return n >>> 0;
1763
+ });
1764
+ function $e(e, t, n) {
1765
+ let r = 4294967295;
1766
+ for (let i = t; i < n; i += 1) r = Qe[(r ^ e[i]) & 255] ^ r >>> 8;
1767
+ return (r ^ 4294967295) >>> 0;
1768
+ }
1769
+ function et(e) {
1770
+ let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = 8, r = 0, i = 0, a = -1, o = 0, s = 0, c = !1, l = !1, u = 1, d = !1, f = !1, p = 0;
1771
+ for (; n < e.length;) {
1772
+ n + 12 > e.length && Y("PNG contains a truncated chunk header.");
1773
+ let m = t.getUint32(n), h = n + 12 + m;
1774
+ h > e.length && Y("PNG chunk data extends beyond the input.");
1775
+ let g = e.subarray(n + 4, n + 8);
1776
+ g.some((e) => !(e >= 65 && e <= 90 || e >= 97 && e <= 122)) && Y("PNG chunk names must contain four ASCII letters.");
1777
+ let _ = String.fromCharCode(...g);
1778
+ $e(e, n + 4, h - 4) !== t.getUint32(h - 4) && Y(`PNG ${_} chunk checksum is invalid.`), n === 8 && _ !== "IHDR" && Y("PNG must begin with its IHDR chunk.");
1779
+ let v = n + 8;
1780
+ if (_ === "IHDR") (n !== 8 || m !== 13) && Y("PNG requires exactly one 13-byte IHDR chunk."), r = t.getUint32(v), i = t.getUint32(v + 4), J(r, i), o = e[v + 8], a = e[v + 9], {
1781
+ 0: [
1782
+ 1,
1783
+ 2,
1784
+ 4,
1785
+ 8,
1786
+ 16
1787
+ ],
1788
+ 2: [8, 16],
1789
+ 3: [
1790
+ 1,
1791
+ 2,
1792
+ 4,
1793
+ 8
1794
+ ],
1795
+ 4: [8, 16],
1796
+ 6: [8, 16]
1797
+ }[a]?.includes(o) || Y("PNG bit depth and color type are incompatible."), (e[v + 10] !== 0 || e[v + 11] !== 0 || e[v + 12] > 1) && Y("PNG compression, filtering or interlace settings are invalid.");
1798
+ else if (_ === "acTL" || _ === "fcTL" || _ === "fdAT") throw new w("UNSUPPORTED_IMAGE", "Animated PNG is unsupported; provide a static PNG or a multipage TIFF.");
1799
+ else if (_ === "PLTE") (s || d || m === 0 || m % 3 != 0 || m > 768 || a === 0 || a === 4) && Y("PNG palette is invalid or appears after image data."), s = m / 3, a === 3 && s > 2 ** o && Y("PNG palette exceeds its indexed bit depth.");
1800
+ else if (_ === "tRNS") (c || d || !(a === 0 && m === 2 || a === 2 && m === 6 || a === 3 && m > 0 && m <= s)) && Y("PNG transparency is incompatible with its color type or palette."), c = !0;
1801
+ else if (_ === "eXIf") l && Y("PNG requires at most one eXIf chunk."), u = X(e, v, h - 4), l = !0;
1802
+ else if (_ === "IDAT") (f || a === 3 && s === 0) && Y("PNG image data must be contiguous and follow its palette."), d = !0, p += m;
1803
+ else if (_ === "IEND") return m === 0 && d && p !== 0 && h === e.length || Y("PNG must end with IEND after nonempty image data."), {
1804
+ format: "png",
1805
+ width: r,
1806
+ height: i,
1807
+ orientation: u
1808
+ };
1809
+ else if (g[0] < 97) throw new w("UNSUPPORTED_IMAGE", `Unsupported critical PNG chunk: ${_}.`);
1810
+ d && _ !== "IDAT" && (f = !0), n = h;
1811
+ }
1812
+ Y("PNG is missing its final IEND chunk.");
1813
+ }
1814
+ function X(e, t, n) {
1815
+ let r = new DataView(e.buffer, e.byteOffset + t, n - t);
1816
+ r.byteLength < 8 && Y("Image EXIF TIFF header is truncated.");
1817
+ let i = r.getUint16(0);
1818
+ i !== 18761 && i !== 19789 && Y("Image EXIF byte order is invalid.");
1819
+ let a = i === 18761;
1820
+ r.getUint16(2, a) !== 42 && Y("Image EXIF requires a classic TIFF header.");
1821
+ let o = r.getUint32(4, a);
1822
+ (o < 8 || o + 2 > r.byteLength) && Y("Image EXIF IFD0 offset is outside its metadata segment.");
1823
+ let s = r.getUint16(o, a), c = o + 2 + s * 12;
1824
+ c + 4 > r.byteLength && Y("Image EXIF directory extends beyond its metadata segment.");
1825
+ let l = 1, u = !1;
1826
+ for (let e = 0; e < s; e += 1) {
1827
+ let t = o + 2 + e * 12;
1828
+ if (r.getUint16(t, a) !== 274) continue;
1829
+ let n = r.getUint16(t + 8, a);
1830
+ (u || r.getUint16(t + 2, a) !== 3 || r.getUint32(t + 4, a) !== 1 || n < 1 || n > 8) && Y("Image EXIF orientation must be one unambiguous SHORT value from 1 to 8."), l = n, u = !0;
1831
+ }
1832
+ let d = r.getUint32(c, a);
1833
+ return d !== 0 && (d < 8 || d + 2 > r.byteLength) && Y("Image EXIF thumbnail directory is outside its metadata segment."), l;
1834
+ }
1835
+ function tt(e) {
1836
+ let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = 2, r = 0, i = 0, a = 1, o = !1, s = 0, c = !1, l = /* @__PURE__ */ new Set();
1837
+ for (; n < e.length;) {
1838
+ for (e[n] !== 255 && Y("JPEG marker structure is invalid."), n += 1; e[n] === 255;) n += 1;
1839
+ let u = e[n++];
1840
+ if ((u === void 0 || u === 0 || u === 216) && Y("JPEG contains an invalid or truncated marker."), u === 217) return s && c && n === e.length || Y("JPEG must end after a complete frame and scan."), {
1841
+ format: "jpeg",
1842
+ width: r,
1843
+ height: i,
1844
+ orientation: a
1845
+ };
1846
+ (u === 1 || u >= 208 && u <= 215) && Y("JPEG standalone markers are only supported inside scan data."), n + 2 > e.length && Y("JPEG segment length is truncated.");
1847
+ let d = t.getUint16(n), f = n + d;
1848
+ (d < 2 || f > e.length) && Y("JPEG segment extends beyond the input.");
1849
+ let p = n + 2;
1850
+ if (u >= 192 && u <= 207 && ![
1851
+ 196,
1852
+ 200,
1853
+ 204
1854
+ ].includes(u)) {
1855
+ if (![
1856
+ 192,
1857
+ 193,
1858
+ 194
1859
+ ].includes(u)) throw new w("UNSUPPORTED_IMAGE", "JPEG requires baseline, extended sequential or progressive Huffman encoding.");
1860
+ (s || d < 8) && Y("JPEG contains an invalid or duplicate frame header.");
1861
+ let n = e[p + 5];
1862
+ if (d !== 8 + n * 3 && Y("JPEG frame components are truncated."), e[p] !== 8 || ![
1863
+ 1,
1864
+ 3,
1865
+ 4
1866
+ ].includes(n)) throw new w("UNSUPPORTED_IMAGE", "JPEG requires 8-bit grayscale, RGB or CMYK pixels.");
1867
+ i = t.getUint16(p + 1), r = t.getUint16(p + 3), J(r, i);
1868
+ for (let t = 0; t < n; t += 1) {
1869
+ let n = p + 6 + t * 3, r = e[n], i = e[n + 1];
1870
+ (l.has(r) || !(i >> 4) || i >> 4 > 4 || !(i & 15) || (i & 15) > 4 || e[n + 2] > 3) && Y("JPEG frame component identifiers or sampling settings are invalid."), l.add(r);
1871
+ }
1872
+ s = u;
1873
+ } else if (u === 225 && d >= 6 && e[p] === 69 && e[p + 1] === 120 && e[p + 2] === 105 && e[p + 3] === 102) (o || d < 8 || e[p + 4] !== 0 || e[p + 5] !== 0) && Y("JPEG contains ambiguous or malformed EXIF APP1 metadata."), a = X(e, p + 6, f), o = !0;
1874
+ else if (u === 218) {
1875
+ let t = e[p];
1876
+ (!s || t === void 0 || t < 1 || t > l.size || d !== 6 + t * 2) && Y("JPEG scan header must follow a complete frame and select its components.");
1877
+ let r = /* @__PURE__ */ new Set();
1878
+ for (let n = 0; n < t; n += 1) {
1879
+ let t = e[p + 1 + n * 2], i = e[p + 2 + n * 2];
1880
+ (!l.has(t) || r.has(t) || i >> 4 > 3 || (i & 15) > 3) && Y("JPEG scan components or Huffman table selectors are invalid."), r.add(t);
1881
+ }
1882
+ let i = p + 1 + t * 2;
1883
+ (e[i] > e[i + 1] || e[i + 1] > 63 || e[i + 2] >> 4 > 13 || (e[i + 2] & 15) > 13 || s !== 194 && (e[i] !== 0 || e[i + 1] !== 63 || e[i + 2] !== 0)) && Y("JPEG scan spectral settings are invalid."), c = !0, n = f;
1884
+ let a = 0;
1885
+ for (; n < e.length;) {
1886
+ if (e[n] !== 255) {
1887
+ a += 1, n += 1;
1888
+ continue;
1889
+ }
1890
+ let t = n;
1891
+ for (n += 1; e[n] === 255;) n += 1;
1892
+ let r = e[n];
1893
+ if (r === 0 || r !== void 0 && r >= 208 && r <= 215) r === 0 && (a += 1), n += 1;
1894
+ else {
1895
+ n = t;
1896
+ break;
1897
+ }
1898
+ }
1899
+ a === 0 && Y("JPEG scan data is empty or truncated.");
1900
+ continue;
1901
+ } else if ([
1902
+ 220,
1903
+ 222,
1904
+ 223
1905
+ ].includes(u)) throw new w("UNSUPPORTED_IMAGE", "JPEG deferred-height and hierarchical frames are unsupported.");
1906
+ n = f;
1907
+ }
1908
+ Y("JPEG is missing its final EOI marker.");
1909
+ }
1910
+ function nt(e) {
1911
+ if (e.length >= 8 && [
1912
+ 137,
1913
+ 80,
1914
+ 78,
1915
+ 71,
1916
+ 13,
1917
+ 10,
1918
+ 26,
1919
+ 10
1920
+ ].every((t, n) => e[n] === t)) return et(e);
1921
+ if (e[0] === 255 && e[1] === 216) return tt(e);
1922
+ throw new w("UNSUPPORTED_IMAGE", "Provide PNG, JPEG or classic TIFF image bytes.");
1923
+ }
1924
+ async function rt(e, t) {
1925
+ T(t);
1926
+ let n = e.buffer instanceof ArrayBuffer ? new Uint8Array(e.buffer, e.byteOffset, e.byteLength) : Uint8Array.from(e), r = nt(n);
1927
+ if (r.format !== "png" && Y("PNG data validation requires PNG bytes."), typeof DecompressionStream != "function") throw new w("UNSUPPORTED_IMAGE", "PNG validation requires DecompressionStream support.");
1928
+ let i = {
1929
+ 0: 1,
1930
+ 2: 3,
1931
+ 3: 1,
1932
+ 4: 2,
1933
+ 6: 4
1934
+ }[n[25]] * n[24], a = (n[28] === 0 ? [[
1935
+ 0,
1936
+ 0,
1937
+ 1,
1938
+ 1
1939
+ ]] : [
1940
+ [
1941
+ 0,
1942
+ 0,
1943
+ 8,
1944
+ 8
1945
+ ],
1946
+ [
1947
+ 4,
1948
+ 0,
1949
+ 8,
1950
+ 8
1951
+ ],
1952
+ [
1953
+ 0,
1954
+ 4,
1955
+ 4,
1956
+ 8
1957
+ ],
1958
+ [
1959
+ 2,
1960
+ 0,
1961
+ 4,
1962
+ 4
1963
+ ],
1964
+ [
1965
+ 0,
1966
+ 2,
1967
+ 2,
1968
+ 4
1969
+ ],
1970
+ [
1971
+ 1,
1972
+ 0,
1973
+ 2,
1974
+ 2
1975
+ ],
1976
+ [
1977
+ 0,
1978
+ 1,
1979
+ 1,
1980
+ 2
1981
+ ]
1982
+ ]).flatMap(([e = 0, t = 0, n = 1, a = 1]) => {
1983
+ let o = Math.max(0, Math.ceil((r.width - e) / n)), s = Math.max(0, Math.ceil((r.height - t) / a));
1984
+ return o && s ? [{
1985
+ rows: s,
1986
+ stride: Math.ceil(o * i / 8) + 1
1987
+ }] : [];
1988
+ }), o = a.reduce((e, t) => e + t.rows * t.stride, 0), s = new DataView(n.buffer, n.byteOffset, n.byteLength), c = 8, l = 0, u = 0, d = new ReadableStream({ pull(e) {
1989
+ for (; l === u && c < n.length;) {
1990
+ let e = s.getUint32(c), t = c + 8, r = n[c + 4] === 73 && n[c + 5] === 68 && n[c + 6] === 65 && n[c + 7] === 84;
1991
+ c += e + 12, r && e > 0 && (l = t, u = t + e);
1992
+ }
1993
+ if (l === u) {
1994
+ e.close();
1995
+ return;
1996
+ }
1997
+ let t = Math.min(l + 8192, u);
1998
+ e.enqueue(n.subarray(l, t)), l = t;
1999
+ } }).pipeThrough(new DecompressionStream("deflate")).getReader(), f = () => {
2000
+ d.cancel().catch(() => {});
2001
+ };
2002
+ t?.addEventListener("abort", f, { once: !0 });
2003
+ let p = !1, m = 0, h = 0, g = a[0]?.rows ?? 0, _ = 0;
2004
+ try {
2005
+ for (;;) {
2006
+ T(t);
2007
+ let e = await d.read();
2008
+ if (T(t), e.done) break;
2009
+ m += e.value.length, m > o && Y("PNG decompressed data exceeds its declared scanline dimensions.");
2010
+ let n = 0;
2011
+ for (; n < e.value.length;) {
2012
+ let t = a[h];
2013
+ t || Y("PNG decompressed data contains unexpected image rows."), _ === 0 && (e.value[n] > 4 && Y("PNG scanline filter must be between zero and four."), n += 1, _ = 1);
2014
+ let r = Math.min(e.value.length - n, t.stride - _);
2015
+ n += r, _ += r, _ === t.stride && (_ = 0, --g, g === 0 && (h += 1, g = a[h]?.rows ?? 0));
2016
+ }
2017
+ }
2018
+ (m !== o || h !== a.length || _ !== 0) && Y("PNG decompressed data is shorter than its declared scanline dimensions."), p = !0;
2019
+ } catch (e) {
2020
+ throw T(t), e instanceof w ? e : new w("INVALID_SOURCE", "PNG compressed data or zlib checksum is invalid.", { cause: e });
2021
+ } finally {
2022
+ t?.removeEventListener("abort", f), p || await d.cancel().catch(() => {}), d.releaseLock();
2023
+ }
2024
+ }
2025
+ // src/tiff.ts
2026
+ var it = 1e3, at = [
2027
+ 0,
2028
+ 1,
2029
+ 1,
2030
+ 2,
2031
+ 4,
2032
+ 8,
2033
+ 1,
2034
+ 1,
2035
+ 2,
2036
+ 4,
2037
+ 8,
2038
+ 4,
2039
+ 8,
2040
+ 4
2041
+ ], ot = /* @__PURE__ */ new Set([
2042
+ 256,
2043
+ 257,
2044
+ 258,
2045
+ 259,
2046
+ 262,
2047
+ 266,
2048
+ 273,
2049
+ 274,
2050
+ 277,
2051
+ 278,
2052
+ 279,
2053
+ 284,
2054
+ 292,
2055
+ 293,
2056
+ 317,
2057
+ 320,
2058
+ 322,
2059
+ 323,
2060
+ 324,
2061
+ 325,
2062
+ 330,
2063
+ 338,
2064
+ 339
2065
+ ]);
2066
+ function Z(e) {
2067
+ throw new w("INVALID_SOURCE", `Invalid TIFF: ${e}`);
2068
+ }
2069
+ function Q(e) {
2070
+ throw new w("UNSUPPORTED_IMAGE", `Unsupported TIFF: ${e}`);
2071
+ }
2072
+ function $(e, t, n) {
2073
+ let r = e[`t${t}`];
2074
+ return !r && n !== void 0 ? n : (r && r.length === 1 && Number.isSafeInteger(r[0]) || Z(`tag ${t} requires one integer value.`), r[0]);
2075
+ }
2076
+ function st(e, t) {
2077
+ let n = $(e, 256), r = $(e, 257);
2078
+ J(n, r);
2079
+ let i = $(e, 274, 1);
2080
+ (i < 1 || i > 8) && Z("orientation must be between 1 and 8.");
2081
+ let a = $(e, 259, 1);
2082
+ [
2083
+ 1,
2084
+ 2,
2085
+ 3,
2086
+ 4,
2087
+ 5,
2088
+ 8,
2089
+ 32946,
2090
+ 32773
2091
+ ].includes(a) || Q(`compression ${a}; use uncompressed, CCITT, LZW, Deflate or PackBits strips.`), [
2092
+ 322,
2093
+ 323,
2094
+ 324,
2095
+ 325,
2096
+ 330
2097
+ ].some((t) => e[`t${t}`]) && Q("tiled images and SubIFDs are not supported."), $(e, 284, 1) !== 1 && Q("separate planar samples are not supported.");
2098
+ let o = $(e, 277, 1), s = e.t258 ?? [1], c = s[0], l = e.t339 ?? [1];
2099
+ (![1, o].includes(s.length) || s.some((e) => e !== c) || ![1, o].includes(l.length) || l.some((e) => e !== 1)) && Q("sample depths must match and samples must be unsigned integers.");
2100
+ let u = $(e, 262), d = o === 1 && (u === 0 && [
2101
+ 1,
2102
+ 4,
2103
+ 8
2104
+ ].includes(c) || u === 1 && [
2105
+ 1,
2106
+ 2,
2107
+ 8
2108
+ ].includes(c)), f = u === 2 && c === 8 && [3, 4].includes(o), p = u === 3 && o === 1 && [
2109
+ 1,
2110
+ 2,
2111
+ 4,
2112
+ 8
2113
+ ].includes(c);
2114
+ d || f || p || Q("photometric interpretation, channels or bit depth.");
2115
+ let m = e.t338 ?? [];
2116
+ o !== 4 || m.length === 1 && [1, 2].includes(m[0]) || Q("four-channel RGB requires an explicit associated or unassociated alpha sample."), o !== 4 && m.length > 0 && Q("extra samples are unsupported in this pixel mode."), p && e.t320?.length !== 3 * (1 << c) && Z("the palette has an invalid size."), p && e.t320.some((e) => e > 65535) && Z("palette entries must be sixteen-bit values.");
2117
+ let h = $(e, 266, 1), g = [
2118
+ 2,
2119
+ 3,
2120
+ 4
2121
+ ].includes(a);
2122
+ [1, 2].includes(h) || Z("fill order must be 1 or 2."), h === 2 && !g && Q("reversed fill order is supported only for CCITT scans."), g && (!d || c !== 1 || o !== 1) && Q("CCITT compression requires bilevel grayscale."), a === 3 && ![0, 1].includes($(e, 292, 0)) && Q("unsupported Group 3 options."), a === 4 && $(e, 293, 0) !== 0 && Q("uncompressed Group 4 extension mode.");
2123
+ let _ = $(e, 317, 1);
2124
+ _ !== 1 && !(_ === 2 && c === 8 && [
2125
+ 1,
2126
+ 5,
2127
+ 8,
2128
+ 32946,
2129
+ 32773
2130
+ ].includes(a)) && Q("only normal and eight-bit horizontal differencing predictors are supported.");
2131
+ let v = Math.min($(e, 278, r), r);
2132
+ v <= 0 && Z("RowsPerStrip must be positive.");
2133
+ let y = e.t273, b = e.t279;
2134
+ y && b && y.length === b.length && y.length === Math.ceil(r / v) || Z("strip offsets and byte counts must cover exactly the declared rows.");
2135
+ for (let e = 0; e < y.length; e += 1) {
2136
+ let n = y[e], r = b[e];
2137
+ (n < 8 || r <= 0 || n > t - r) && Z("a strip extends outside the input.");
2138
+ }
2139
+ return {
2140
+ tags: e,
2141
+ width: n,
2142
+ height: r,
2143
+ orientation: i,
2144
+ bits: c,
2145
+ samples: o,
2146
+ compression: a,
2147
+ rowsPerStrip: v,
2148
+ offsets: y,
2149
+ counts: b,
2150
+ associatedAlpha: o === 4 && m[0] === 1
2151
+ };
2152
+ }
2153
+ function ct(e) {
2154
+ e.byteLength < 8 && Z("the header is truncated.");
2155
+ let t = e[0] === 73 && e[1] === 73;
2156
+ t || e[0] === 77 && e[1] === 77 || Z("byte order must be II or MM.");
2157
+ let n = new DataView(e.buffer, e.byteOffset, e.byteLength), r = n.getUint16(2, t);
2158
+ r === 43 && Q("BigTIFF is not supported."), r !== 42 && Z("the classic TIFF signature is missing.");
2159
+ let i = n.getUint32(4, t), a = /* @__PURE__ */ new Set(), o = [];
2160
+ for (; i !== 0;) {
2161
+ a.has(i) && Z("the main IFD chain contains a cycle."), o.length >= it && Q("the file exceeds the 1000 frame limit."), a.add(i), (i < 8 || i > e.length - 2) && Z("an IFD offset is outside the input.");
2162
+ let r = n.getUint16(i, t), s = i + 2 + r * 12;
2163
+ s > e.length - 4 && Z("an IFD directory is truncated.");
2164
+ let c = {};
2165
+ for (let a = 0; a < r; a += 1) {
2166
+ let r = i + 2 + a * 12, o = n.getUint16(r, t), s = n.getUint16(r + 2, t), l = n.getUint32(r + 4, t), u = at[s];
2167
+ u && l !== 0 || Z("an IFD field has an invalid type or count.");
2168
+ let d = u * l, f = d <= 4 ? r + 8 : n.getUint32(r + 8, t);
2169
+ if (f > e.length - d && Z("an IFD value extends outside the input."), !ot.has(o)) continue;
2170
+ [3, 4].includes(s) || Q(`rendering tag ${o} must use SHORT or LONG values.`), c[`t${o}`] && Z(`rendering tag ${o} occurs more than once.`), l > 1e6 && Q("a rendering tag contains too many values.");
2171
+ let p = [];
2172
+ for (let e = 0; e < l; e += 1) p.push(s === 3 ? n.getUint16(f + e * 2, t) : n.getUint32(f + e * 4, t));
2173
+ c[`t${o}`] = p;
2174
+ }
2175
+ o.push(st(c, e.length)), i = n.getUint32(s, t);
2176
+ }
2177
+ return o.length === 0 && Z("no main image IFD exists."), o;
2178
+ }
2179
+ function lt(e, t) {
2180
+ let n = 0, r = 0;
2181
+ for (; n < e.length;) {
2182
+ let i = e[n++];
2183
+ if (i <= 127) {
2184
+ let t = i + 1;
2185
+ n + t > e.length && Z("a PackBits literal is truncated."), n += t, r += t;
2186
+ } else i !== 128 && (n >= e.length && Z("a PackBits repeat is truncated."), n += 1, r += 257 - i);
2187
+ r > t && Z("PackBits output exceeds the declared strip size.");
2188
+ }
2189
+ r !== t && Z("PackBits output does not cover the declared strip.");
2190
+ }
2191
+ function ut(e, t) {
2192
+ let n = /* @__PURE__ */ new Uint32Array(4096);
2193
+ for (let e = 0; e < 256; e += 1) n[e] = 1;
2194
+ let r = 0, i = 9, a = 258, o = 0, s = 0, c = !1;
2195
+ for (; r + i <= e.length * 8;) {
2196
+ let l = 0;
2197
+ for (let t = 0; t < i; t += 1) l = l << 1 | e[r >>> 3] >>> 7 - (r & 7) & 1, r += 1;
2198
+ if (l === 256) {
2199
+ i = 9, a = 258, o = 0, c = !0;
2200
+ continue;
2201
+ }
2202
+ if (c || Z("an LZW strip must start with its clear code."), l === 257) {
2203
+ s !== t && Z("LZW output does not cover the declared strip.");
2204
+ return;
2205
+ }
2206
+ let u = l < a ? n[l] : l === a && o > 0 ? o + 1 : 0;
2207
+ u || Z("an LZW strip contains an invalid dictionary reference."), s += u, s > t && Z("LZW output exceeds the declared strip size."), o > 0 && a < 4096 && (n[a++] = o + 1, i < 12 && a === (1 << i) - 1 && (i += 1)), o = u;
2208
+ }
2209
+ Z("an LZW strip is missing its end code.");
2210
+ }
2211
+ async function dt(e, t, n) {
2212
+ typeof DecompressionStream != "function" && Q("Deflate requires DecompressionStream support.");
2213
+ let r = new Blob([Uint8Array.from(e)]).stream().pipeThrough(new DecompressionStream("deflate")).getReader(), i = 0;
2214
+ try {
2215
+ for (;;) {
2216
+ T(n);
2217
+ let { value: e, done: a } = await r.read();
2218
+ if (a) break;
2219
+ i += e.byteLength, i > t && Z("Deflate output exceeds the declared strip size.");
2220
+ }
2221
+ i !== t && Z("Deflate output does not cover the declared strip.");
2222
+ } catch (e) {
2223
+ throw await r.cancel().catch(() => void 0), T(n), e instanceof w ? e : new w("INVALID_SOURCE", "Invalid TIFF: a Deflate strip is corrupt or truncated.", { cause: e });
2224
+ } finally {
2225
+ r.releaseLock();
2226
+ }
2227
+ }
2228
+ async function ft(e, t) {
2229
+ T(t);
2230
+ let n = Uint8Array.from(e), r = ct(n);
2231
+ return T(t), {
2232
+ pageCount: r.length,
2233
+ async decodeFrame(e) {
2234
+ T(t), (!Number.isSafeInteger(e) || e < 0 || e >= r.length) && Z("frame index is outside the document.");
2235
+ let i = r[e], a = Math.ceil(i.width * i.samples * i.bits / 8);
2236
+ for (let e = 0; e < i.offsets.length; e += 1) {
2237
+ let r = Math.min(i.rowsPerStrip, i.height - e * i.rowsPerStrip) * a, o = i.offsets[e], s = i.counts[e];
2238
+ i.compression === 1 && s !== r && Z("an uncompressed strip has the wrong byte length."), i.compression === 5 && ut(n.subarray(o, o + s), r), i.compression === 32773 && lt(n.subarray(o, o + s), r), [8, 32946].includes(i.compression) && await dt(n.subarray(o, o + s), r, t);
2239
+ }
2240
+ let o = Object.fromEntries(Object.entries(i.tags).map(([e, t]) => [e, [...t]])), s;
2241
+ try {
2242
+ let e = (await import("utif2")).default;
2243
+ T(t), e.decodeImage(n.buffer, o), o.data instanceof Uint8Array && o.data.length === a * i.height || Z("the decoder returned an incomplete raster."), s = e.toRGBA8(o);
2244
+ } catch (e) {
2245
+ throw T(t), e instanceof w ? e : new w("RESOURCE_LOAD_FAILED", "The TIFF frame could not be decoded.", { cause: e });
2246
+ }
2247
+ if (s.length !== i.width * i.height * 4 && Z("the decoder returned an invalid RGBA raster."), i.associatedAlpha) for (let e = 0; e < s.length; e += 4) {
2248
+ let t = s[e + 3];
2249
+ for (let n = 0; n < 3; n += 1) s[e + n] = t === 0 ? 0 : Math.min(255, Math.round(s[e + n] * 255 / t));
2250
+ }
2251
+ return T(t), {
2252
+ width: i.width,
2253
+ height: i.height,
2254
+ rgba: s,
2255
+ orientation: i.orientation
2256
+ };
2257
+ }
2258
+ };
2259
+ }
2260
+ // src/image-pdf.ts
2261
+ function pt(e, t) {
2262
+ let { width: n, height: r, rgba: i, orientation: a } = t;
2263
+ J(n, r);
2264
+ let o = n * r;
2265
+ if (i.length !== o * 4) throw new w("RESOURCE_LOAD_FAILED", "Decoded TIFF pixels do not match the frame dimensions.");
2266
+ let s = new Uint8Array(o * 3), c;
2267
+ for (let e = 0; e < o; e += 1) {
2268
+ s[e * 3] = i[e * 4], s[e * 3 + 1] = i[e * 4 + 1], s[e * 3 + 2] = i[e * 4 + 2];
2269
+ let t = i[e * 4 + 3];
2270
+ t !== 255 && !c && (c = new Uint8Array(o).fill(255)), c && (c[e] = t);
2271
+ }
2272
+ let l = c ? e.context.register(e.context.flateStream(c, {
2273
+ Type: "XObject",
2274
+ Subtype: "Image",
2275
+ Width: n,
2276
+ Height: r,
2277
+ ColorSpace: "DeviceGray",
2278
+ BitsPerComponent: 8
2279
+ })) : void 0;
2280
+ return {
2281
+ ref: e.context.register(e.context.flateStream(s, {
2282
+ Type: "XObject",
2283
+ Subtype: "Image",
2284
+ Width: n,
2285
+ Height: r,
2286
+ ColorSpace: "DeviceRGB",
2287
+ BitsPerComponent: 8,
2288
+ ...l ? { SMask: l } : {}
2289
+ })),
2290
+ width: n,
2291
+ height: r,
2292
+ orientation: a
2293
+ };
2294
+ }
2295
+ async function mt(e, t) {
2296
+ try {
2297
+ return new Uint8Array(await q(e.arrayBuffer(), t));
2298
+ } catch (e) {
2299
+ throw T(t), new w("RESOURCE_LOAD_FAILED", "The source image file could not be read.", { cause: e });
2300
+ }
2301
+ }
2302
+ async function ht(e, t = {}) {
2303
+ let n = L(t), i = ae(t.metadata), { signal: a, onProgress: o } = t;
2304
+ if (o !== void 0 && typeof o != "function") throw new w("INVALID_OPTIONS", "onProgress must be a function.");
2305
+ if (a !== void 0 && !(a instanceof AbortSignal)) throw new w("INVALID_OPTIONS", "signal must be an AbortSignal.");
2306
+ T(a);
2307
+ let s = e instanceof Uint8Array ? Uint8Array.from(e) : e instanceof ArrayBuffer ? new Uint8Array(e.slice(0)) : void 0, c = typeof Blob < "u" && e instanceof Blob ? e : void 0;
2308
+ if (!s && !c) throw new w("INVALID_SOURCE", "Provide image bytes, an ArrayBuffer, or a File/Blob.");
2309
+ let d = Ke(o, a), f = d.report;
2310
+ try {
2311
+ f && await f({
2312
+ stage: "preparing",
2313
+ completed: 0,
2314
+ total: 1
2315
+ });
2316
+ let e = s ?? await mt(c, a);
2317
+ if (e.length === 0) throw new w("INVALID_SOURCE", "The source image is empty.");
2318
+ let t = e.length >= 4 && (e[0] === 73 && e[1] === 73 && (e[2] === 42 || e[2] === 43) && e[3] === 0 || e[0] === 77 && e[1] === 77 && e[2] === 0 && (e[3] === 42 || e[3] === 43)) ? await q(ft(e, a), a) : void 0, o = t ? void 0 : nt(e), d = t?.pageCount ?? 1;
2319
+ f && await f({
2320
+ stage: "preparing",
2321
+ completed: 1,
2322
+ total: 1
2323
+ });
2324
+ let h = await r.create();
2325
+ oe(h, i);
2326
+ let g = [];
2327
+ f && await f({
2328
+ stage: "resources",
2329
+ completed: 0,
2330
+ total: d
2331
+ });
2332
+ for (let n = 0; n < d; n += 1) {
2333
+ if (T(a), t) {
2334
+ let e = await q(t.decodeFrame(n), a);
2335
+ g.push(pt(h, e));
2336
+ } else try {
2337
+ o.format === "png" && await rt(e, a);
2338
+ let t = o.format === "png" ? await h.embedPng(e) : await h.embedJpg(e);
2339
+ if (t.width !== o.width || t.height !== o.height) throw new w("INVALID_SOURCE", "Decoded image dimensions disagree with its header.");
2340
+ g.push({
2341
+ ref: t.ref,
2342
+ width: t.width,
2343
+ height: t.height,
2344
+ orientation: o.orientation
2345
+ });
2346
+ } catch (e) {
2347
+ throw e instanceof w ? e : new w("RESOURCE_LOAD_FAILED", "The PNG/JPEG image could not be embedded.", { cause: e });
2348
+ }
2349
+ f && await f({
2350
+ stage: "resources",
2351
+ completed: n + 1,
2352
+ total: d
2353
+ });
2354
+ }
2355
+ f && await f({
2356
+ stage: "pages",
2357
+ completed: 0,
2358
+ total: d
2359
+ });
2360
+ for (let [e, t] of g.entries()) {
2361
+ T(a);
2362
+ let r = h.addPage([n.width * .75, n.height * .75]), i = Ze(t.width, t.height, t.orientation, n), o = r.node.newXObject("Image", t.ref);
2363
+ r.pushOperators(m(), l(i[0] * .75, i[1] * .75, i[2] * .75, i[3] * .75, i[4] * .75, i[5] * .75), u(o), p()), f && await f({
2364
+ stage: "pages",
2365
+ completed: e + 1,
2366
+ total: d
2367
+ });
2368
+ }
2369
+ f && await f({
2370
+ stage: "saving",
2371
+ completed: 0,
2372
+ total: 1
2373
+ });
2374
+ let _ = await q(h.save(), a);
2375
+ return T(a), f && await f({
2376
+ stage: "saving",
2377
+ completed: 1,
2378
+ total: 1
2379
+ }), f && await f({
2380
+ stage: "complete",
2381
+ completed: 1,
2382
+ total: 1
2383
+ }), T(a), qe(_, d, []);
2384
+ } catch (e) {
2385
+ return d.rethrow(e instanceof w ? e : new w("PDF_WRITE_FAILED", "The standalone image could not be written as PDF.", { cause: e }));
2386
+ }
2387
+ }
2388
+ export { w as RenderPDFError, ht as imageToPDF, de as registerFont, Ye as renderPDF };