@darialan/web-printer 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1174 @@
1
+ import lt from "html2canvas";
2
+ const dt = 72 / 25.4, v = 25.4 / 96, k = 96 / 25.4, R = (t) => Number((t * v).toFixed(4)), U = {
3
+ "card-3x4": { widthPx: 1242, heightPx: 1656, marginPx: 60 },
4
+ "square-1x1": { widthPx: 1080, heightPx: 1080, marginPx: 54 },
5
+ "card-4x5": { widthPx: 1080, heightPx: 1350, marginPx: 54 },
6
+ "story-9x16": { widthPx: 1080, heightPx: 1920, marginPx: 54 },
7
+ "ecom-750x1000": { widthPx: 750, heightPx: 1e3, marginPx: 0 }
8
+ }, Vt = Object.keys(U);
9
+ function pt(t) {
10
+ return t in U;
11
+ }
12
+ function Yt(t) {
13
+ return pt(t) ? "px" : "mm";
14
+ }
15
+ const J = {
16
+ a4: [210, 297],
17
+ a3: [297, 420],
18
+ a5: [148, 210],
19
+ letter: [215.9, 279.4],
20
+ ...Object.fromEntries(
21
+ Object.entries(U).map(([t, e]) => [
22
+ t,
23
+ [R(e.widthPx), R(e.heightPx)]
24
+ ])
25
+ )
26
+ }, X = {
27
+ a4: {
28
+ widthMm: 210,
29
+ heightMm: 297,
30
+ marginTopMm: 10,
31
+ marginRightMm: 10,
32
+ marginBottomMm: 10,
33
+ marginLeftMm: 10
34
+ },
35
+ a3: {
36
+ widthMm: 297,
37
+ heightMm: 420,
38
+ marginTopMm: 10,
39
+ marginRightMm: 10,
40
+ marginBottomMm: 10,
41
+ marginLeftMm: 10
42
+ },
43
+ a5: {
44
+ widthMm: 148,
45
+ heightMm: 210,
46
+ marginTopMm: 10,
47
+ marginRightMm: 10,
48
+ marginBottomMm: 10,
49
+ marginLeftMm: 10
50
+ },
51
+ letter: {
52
+ widthMm: 215.9,
53
+ heightMm: 279.4,
54
+ marginTopMm: 10,
55
+ marginRightMm: 10,
56
+ marginBottomMm: 10,
57
+ marginLeftMm: 10
58
+ },
59
+ custom: {
60
+ widthMm: 210,
61
+ heightMm: Number((200 * v).toFixed(2)),
62
+ marginTopMm: Number((2 * v).toFixed(2)),
63
+ marginRightMm: Number((2 * v).toFixed(2)),
64
+ marginBottomMm: Number((2 * v).toFixed(2)),
65
+ marginLeftMm: Number((2 * v).toFixed(2))
66
+ },
67
+ ...Object.fromEntries(
68
+ Object.entries(U).map(([t, e]) => [
69
+ t,
70
+ {
71
+ widthMm: R(e.widthPx),
72
+ heightMm: R(e.heightPx),
73
+ marginTopMm: R(e.marginPx),
74
+ marginRightMm: R(e.marginPx),
75
+ marginBottomMm: R(e.marginPx),
76
+ marginLeftMm: R(e.marginPx)
77
+ }
78
+ ])
79
+ )
80
+ }, ut = {
81
+ unit: "mm",
82
+ paper: "a4",
83
+ widthMm: 210,
84
+ heightMm: 297,
85
+ orientation: "portrait",
86
+ marginTopMm: 10,
87
+ marginRightMm: 10,
88
+ marginBottomMm: 10,
89
+ marginLeftMm: 10,
90
+ pageNumber: {
91
+ enabled: !0,
92
+ position: "bottom-right",
93
+ format: "slash"
94
+ }
95
+ };
96
+ function Kt(t, e = "portrait", o = "mm") {
97
+ const r = X[t] || X.a4;
98
+ let n, i;
99
+ if (t === "custom")
100
+ n = r.widthMm, i = r.heightMm;
101
+ else {
102
+ const [p, d] = J[t];
103
+ n = e === "landscape" ? d : p, i = e === "landscape" ? p : d;
104
+ }
105
+ const { marginTopMm: a, marginRightMm: s, marginBottomMm: l, marginLeftMm: c } = r;
106
+ return o === "px" ? t === "custom" ? {
107
+ width: Number((n * k).toFixed(1)),
108
+ height: 200,
109
+ marginTop: 2,
110
+ marginRight: 2,
111
+ marginBottom: 2,
112
+ marginLeft: 2
113
+ } : {
114
+ width: Number((n * k).toFixed(1)),
115
+ height: Number((i * k).toFixed(1)),
116
+ marginTop: Number((a * k).toFixed(1)),
117
+ marginRight: Number((s * k).toFixed(1)),
118
+ marginBottom: Number((l * k).toFixed(1)),
119
+ marginLeft: Number((c * k).toFixed(1))
120
+ } : {
121
+ width: n,
122
+ height: i,
123
+ marginTop: a,
124
+ marginRight: s,
125
+ marginBottom: l,
126
+ marginLeft: c
127
+ };
128
+ }
129
+ function P(t) {
130
+ return t * dt;
131
+ }
132
+ function mt(t) {
133
+ const e = t.paper === "custom" ? [t.widthMm, t.heightMm] : J[t.paper];
134
+ if (!e || e.some((s) => !Number.isFinite(s) || s <= 0))
135
+ throw new Error("页面宽高必须是大于零的数值");
136
+ if (!["portrait", "landscape"].includes(t.orientation))
137
+ throw new Error("纸张方向无效");
138
+ const o = [t.marginTopMm, t.marginRightMm, t.marginBottomMm, t.marginLeftMm];
139
+ if (o.some((s) => !Number.isFinite(s) || s < 0))
140
+ throw new Error("页边距必须为非负数");
141
+ const [r, n] = [...e].sort((s, l) => s - l), [i, a] = t.paper === "custom" ? e : t.orientation === "portrait" ? [r, n] : [n, r];
142
+ if (i - o[1] - o[3] <= 0 || a - o[0] - o[2] <= 0)
143
+ throw new Error("页边距占满了页面,请减小边距");
144
+ return {
145
+ pageWidth: P(i),
146
+ pageHeight: P(a),
147
+ left: P(o[3]),
148
+ right: P(o[1]),
149
+ top: P(o[0]),
150
+ bottom: P(o[2]),
151
+ widthMm: i,
152
+ heightMm: a
153
+ };
154
+ }
155
+ const ht = ["widthMm", "heightMm", "marginTopMm", "marginRightMm", "marginBottomMm", "marginLeftMm"];
156
+ function qt(t, e) {
157
+ const o = { ...t };
158
+ return ht.forEach((r) => {
159
+ typeof t[r] == "number" && (o[r] = t[r] * e);
160
+ }), o;
161
+ }
162
+ function ft(t, e, o, r, n = !0) {
163
+ var x;
164
+ const { pageWidth: i, pageHeight: a } = t;
165
+ if (!Number.isFinite(e) || e <= 0 || [o, r].some((y) => y !== void 0 && (!Number.isFinite(y) || y < 0)))
166
+ throw new Error("打印区域或页眉页脚尺寸无效");
167
+ const s = typeof n == "boolean" ? n : n.enabled, l = typeof n == "object" && ((x = n.position) == null ? void 0 : x.startsWith("top")), c = s && l ? 14 : 0, p = s && !l ? 14 : 0, d = i - t.left - t.right, u = d / e, m = (o || 0) * u, h = (r || 0) * u, f = t.top + m + (o !== void 0 ? 6 : 0) + c, w = a - t.bottom - p - h, g = (w - (r !== void 0 ? 6 : 0) - f) / u;
168
+ if (g <= 0)
169
+ throw new Error("页眉页脚过高,没有剩余正文空间");
170
+ return {
171
+ pageWidth: i,
172
+ pageHeight: a,
173
+ contentWidth: d,
174
+ ratio: u,
175
+ headerHeight: m,
176
+ footerHeight: h,
177
+ bodyTop: f,
178
+ left: t.left,
179
+ headerY: t.top,
180
+ footerY: w,
181
+ pageNumberY: l ? f - 5 : a - Math.max(6, t.bottom / 2),
182
+ capacity: g
183
+ };
184
+ }
185
+ function gt(t, e, o, r = 100) {
186
+ if (![t, e].every(Number.isFinite) || t <= 0 || e <= 0 || !Number.isSafeInteger(r) || r < 1)
187
+ throw new Error("打印区域或纸张尺寸无效");
188
+ const n = [], i = o.map((c) => {
189
+ if (!Number.isFinite(c.top) || !Number.isFinite(c.bottom) || c.bottom < c.top)
190
+ throw new Error("分页测量结果无效");
191
+ return { top: Math.max(0, c.top), bottom: Math.min(t, c.bottom) };
192
+ }).filter((c) => c.bottom > c.top).sort((c, p) => c.top - p.top);
193
+ for (const c of i) {
194
+ if (c.bottom - c.top > e)
195
+ throw new Error("存在超过单页高度且不可拆分的内容,请缩小图片或调整布局");
196
+ const p = n[n.length - 1];
197
+ p && c.top < p.bottom ? p.bottom = Math.max(p.bottom, c.bottom) : n.push({ ...c });
198
+ }
199
+ if (n.some((c) => c.bottom - c.top > e))
200
+ throw new Error("重叠的不可拆分内容超过单页高度,无法安全分页");
201
+ const a = [];
202
+ let s = 0, l = 0;
203
+ for (; s < t; ) {
204
+ if (a.length >= r)
205
+ throw new Error(`文档超过 ${r} 页限制,请拆分导出或增大页面高度`);
206
+ let c = Math.min(s + e, t);
207
+ if (c < t) {
208
+ for (; l < n.length && n[l].bottom <= c; )
209
+ l++;
210
+ l < n.length && n[l].top < c && (c = n[l].top);
211
+ }
212
+ if (c <= s)
213
+ throw new Error("页面高度不足,无法安全分页,请增大页面高度");
214
+ a.push({ start: s, end: c }), s = c;
215
+ }
216
+ return a;
217
+ }
218
+ function bt(t, e, o = 0.25) {
219
+ const r = t.slice(1).filter((n) => e.some((i) => i.top + o < n.start && i.bottom - o > n.start));
220
+ if (r.length)
221
+ throw new Error(`分页预览与原页面布局不一致:${r.length} 个断点穿过受保护内容,首个位置 ${r[0].start.toFixed(1)}px`);
222
+ }
223
+ const wt = 3, yt = 1, Xt = {
224
+ /** 不可分割:最小原子化单元,严禁跨页切断,当前页放不下整块换到下一页 */
225
+ ATOMIC: 'data-print-atomic="true"',
226
+ /** 可分割:声明为流式内容,允许分页线直接穿透内部 */
227
+ SPLITTABLE: 'data-print-splittable="true"',
228
+ /** 打印忽略:不参与测量、快照与打印渲染 */
229
+ IGNORE: 'data-print-ignore="true"',
230
+ // 兼容别名
231
+ KEEP_TOGETHER: 'data-print-keep-together="true"',
232
+ KEEP_OR_SPLIT: 'data-print-keep-together="split"',
233
+ FORCE_SPLIT: 'data-print-break="split"'
234
+ }, Zt = {
235
+ ATOMIC: "print-atomic",
236
+ SPLITTABLE: "print-splittable",
237
+ IGNORE: "print-ignore",
238
+ // 兼容别名
239
+ KEEP_TOGETHER: "print-keep-together",
240
+ KEEP_OR_SPLIT: "print-keep-or-split",
241
+ FORCE_SPLIT: "print-force-split"
242
+ }, Qt = {
243
+ ATOMIC: 'data-pdf-atomic="true"',
244
+ SPLITTABLE: 'data-pdf-splittable="true"',
245
+ IGNORE: 'data-pdf-ignore="true"',
246
+ KEEP_TOGETHER: 'data-pdf-keep-together="true"',
247
+ KEEP_OR_SPLIT: 'data-pdf-keep-together="split"',
248
+ FORCE_SPLIT: 'data-pdf-break="split"'
249
+ }, Jt = {
250
+ ATOMIC: "pdf-atomic",
251
+ SPLITTABLE: "pdf-splittable",
252
+ IGNORE: "pdf-ignore",
253
+ KEEP_TOGETHER: "pdf-keep-together",
254
+ KEEP_OR_SPLIT: "pdf-keep-or-split",
255
+ FORCE_SPLIT: "pdf-force-split"
256
+ }, D = [
257
+ // 1. 忽略规则(不打印:标准不可见标签与协议标记)
258
+ {
259
+ selector: 'script, style, template, [hidden], [data-print-debug], [data-print-ignore="true"], .print-ignore, [data-pdf-debug], [data-pdf-ignore="true"], .pdf-ignore',
260
+ result: { kind: "ignore" }
261
+ },
262
+ // 2. 自由可分割规则(流式容器与段落流,允许分页线穿透)
263
+ {
264
+ selector: '[data-print-splittable="true"], .print-splittable, [data-print-break="split"], .print-force-split, [data-pdf-splittable="true"], .pdf-splittable, [data-pdf-break="split"], .pdf-force-split',
265
+ result: { kind: "container" }
266
+ },
267
+ // 3. 不可分割规则(显式声明的原子保护块:严禁拆分,超高报错)
268
+ {
269
+ selector: '[data-print-atomic="true"], .print-atomic, [data-print-keep-together="true"], .print-keep-together, [data-pdf-atomic="true"], .pdf-atomic, [data-pdf-keep-together="true"], .pdf-keep-together',
270
+ result: { kind: "atomic", label: "不可分割区域", overflow: "error" }
271
+ },
272
+ // 4. 不可分割规则(表格行与复合原子项:放不下整块换页,超高深入拆分)
273
+ {
274
+ selector: '[data-print-keep-together="split"], .print-keep-or-split, [data-pdf-keep-together="split"], .pdf-keep-or-split, tr',
275
+ result: { kind: "atomic", label: "表格行与复合块", overflow: "split" }
276
+ },
277
+ // 5. 原生不可切图片媒体与标题
278
+ {
279
+ selector: "img, canvas, svg",
280
+ result: { kind: "atomic", label: "图片媒体", overflow: "error" }
281
+ },
282
+ {
283
+ selector: "h1, h2, h3, h4, h5, h6",
284
+ result: { kind: "atomic", label: "标题", overflow: "error" }
285
+ }
286
+ ], xt = D;
287
+ function I(t) {
288
+ var n, i, a;
289
+ if (!t)
290
+ return [...D];
291
+ const e = [];
292
+ (n = t.customRules) != null && n.length && e.push(...t.customRules), (i = t.ignore) != null && i.length && e.push({
293
+ selector: t.ignore.join(", "),
294
+ result: { kind: "ignore" }
295
+ });
296
+ const o = [
297
+ ...t.splittable || [],
298
+ ...t.forceSplit || []
299
+ ];
300
+ o.length && e.push({
301
+ selector: o.join(", "),
302
+ result: { kind: "container" }
303
+ });
304
+ const r = [
305
+ ...t.atomic || [],
306
+ ...t.keepTogether || []
307
+ ];
308
+ return r.length && e.push({
309
+ selector: r.join(", "),
310
+ result: { kind: "atomic", label: "自定义原子项", overflow: "error" }
311
+ }), (a = t.keepOrSplit) != null && a.length && e.push({
312
+ selector: t.keepOrSplit.join(", "),
313
+ result: { kind: "atomic", label: "可降级拆分区域", overflow: "split" }
314
+ }), [...e, ...D];
315
+ }
316
+ let j = I();
317
+ function te(t) {
318
+ j = I(t);
319
+ }
320
+ function S() {
321
+ return j;
322
+ }
323
+ function ee() {
324
+ j = I();
325
+ }
326
+ function L(t, e = S()) {
327
+ var o, r;
328
+ return t.nodeType === wt ? (o = t.textContent) != null && o.trim() ? { kind: "text" } : { kind: "ignore" } : t.nodeType !== yt || typeof t.matches != "function" ? { kind: "ignore" } : ((r = e.find((n) => t.matches(n.selector))) == null ? void 0 : r.result) || { kind: "container" };
329
+ }
330
+ function Z(t, e, o, r) {
331
+ if (e <= o)
332
+ return "protect";
333
+ if (t.overflow === "split")
334
+ return "descend";
335
+ const n = r || t.label;
336
+ throw new Error(
337
+ `不可拆分区域「${n}」高 ${Math.ceil(e)}px,超过正文可用高度 ${Math.floor(o)}px,请缩小该区域或增大页面高度`
338
+ );
339
+ }
340
+ function V(t, e) {
341
+ const o = [], r = (n) => {
342
+ for (let i = n.childNodes.length - 1; i >= 0; i--)
343
+ o.push(n.childNodes[i]);
344
+ };
345
+ for (r(t); o.length; ) {
346
+ const n = o.pop();
347
+ e(n) === "descend" && r(n);
348
+ }
349
+ }
350
+ function tt(t, e = (o) => o) {
351
+ const o = /* @__PURE__ */ new WeakMap(), r = document.createRange();
352
+ let n = 0;
353
+ return (i) => {
354
+ var c, p;
355
+ if (n += ((c = i.textContent) == null ? void 0 : c.length) || 0, n > 2e5)
356
+ throw new Error("文本超过 200,000 字符限制,请拆分导出");
357
+ const a = i.parentElement;
358
+ if (a && !o.has(a)) {
359
+ const d = ((p = a.ownerDocument) == null ? void 0 : p.defaultView) || window, u = d.getComputedStyle ? d.getComputedStyle(a).lineHeight : window.getComputedStyle(a).lineHeight;
360
+ o.set(a, parseFloat(u));
361
+ }
362
+ const s = a ? o.get(a) : NaN;
363
+ return r.selectNodeContents(i), (r.getClientRects ? Array.from(r.getClientRects()) : []).filter((d) => d.width > 0 && d.height > 0).map((d) => {
364
+ const u = Number.isFinite(s) ? Math.max(0, s - d.height) / 2 : 0;
365
+ return { top: e(d.top - t - u), bottom: e(d.bottom - t + u) };
366
+ });
367
+ };
368
+ }
369
+ function re(t) {
370
+ const e = tt(t.getBoundingClientRect().top), o = [];
371
+ return V(t, (r) => {
372
+ const n = L(r);
373
+ return n.kind === "ignore" ? "skip" : n.kind === "text" ? (o.push(...e(r)), "skip") : "descend";
374
+ }), o;
375
+ }
376
+ function Et(t) {
377
+ const e = Math.max(t.getBoundingClientRect().height, t.scrollHeight);
378
+ if (e <= 0 || e > 2e5)
379
+ throw new Error("打印区域为空或超过 200,000px 高度限制");
380
+ return e;
381
+ }
382
+ function et(t, e, o = xt) {
383
+ const r = t.getBoundingClientRect(), n = Et(t), i = [], a = tt(r.top), s = { visitedNodes: 0, atomicElements: 0, textNodes: 0, textFragments: 0 }, l = L(t, o);
384
+ if (l.kind === "ignore")
385
+ throw new Error("打印区域已被 ignore 规则排除,请选择其他区域");
386
+ if (l.kind === "atomic" && Z(
387
+ l,
388
+ n,
389
+ e,
390
+ t.getAttribute("data-print-label") || t.getAttribute("data-pdf-label") || t.getAttribute("alt")
391
+ ) === "protect")
392
+ return { height: n, ranges: [{ top: 0, bottom: n }], stats: { ...s, visitedNodes: 1, atomicElements: 1 } };
393
+ const c = (p) => {
394
+ const d = Math.max(0, p.top), u = Math.min(n, p.bottom);
395
+ u > d && i.push({ top: d, bottom: u });
396
+ };
397
+ return V(t, (p) => {
398
+ s.visitedNodes++;
399
+ const d = L(p, o);
400
+ if (d.kind === "ignore")
401
+ return "skip";
402
+ if (d.kind === "container")
403
+ return "descend";
404
+ if (d.kind === "text") {
405
+ const f = a(p);
406
+ return s.textNodes++, s.textFragments += f.length, f.forEach(c), "skip";
407
+ }
408
+ const u = p, m = u.getBoundingClientRect();
409
+ if (m.width <= 0 || m.height <= 0)
410
+ return "skip";
411
+ const h = u.getAttribute("data-print-label") || u.getAttribute("data-pdf-label") || u.getAttribute("alt");
412
+ return Z(d, m.height, e, h) === "descend" ? "descend" : (s.atomicElements++, c({ top: m.top - r.top, bottom: m.bottom - r.top }), "skip");
413
+ }), { height: n, ranges: i, stats: s };
414
+ }
415
+ function M(t) {
416
+ if (t != null && t.aborted)
417
+ throw new Error("导出已取消");
418
+ }
419
+ async function Mt(t) {
420
+ for (let e = 0; e < 2; e++)
421
+ M(t), await new Promise((o) => setTimeout(o, 16));
422
+ M(t);
423
+ }
424
+ async function rt(t, e, o = S()) {
425
+ M(e);
426
+ let r, n = () => {
427
+ };
428
+ const i = new Promise((a, s) => {
429
+ r = setTimeout(() => s(new Error("字体或图片加载超时,请稍后重试")), 15e3), n = () => s(new Error("导出已取消")), e == null || e.addEventListener("abort", n, { once: !0 });
430
+ });
431
+ try {
432
+ await Promise.race([i, (async () => {
433
+ var a;
434
+ await Promise.all([
435
+ (a = t.ownerDocument.fonts) == null ? void 0 : a.ready,
436
+ ...[...t.tagName === "IMG" ? [t] : [], ...Array.from(t.querySelectorAll("img"))].filter((s) => {
437
+ for (let l = s; l; l = l.parentElement) {
438
+ if (L(l, o).kind === "ignore")
439
+ return !1;
440
+ if (l === t)
441
+ break;
442
+ }
443
+ return !0;
444
+ }).map(async (s) => {
445
+ try {
446
+ await s.decode();
447
+ } catch {
448
+ throw new Error(`图片加载失败:${s.alt || "未命名图片"}`);
449
+ }
450
+ if (!s.naturalWidth)
451
+ throw new Error(`图片内容为空:${s.alt || "未命名图片"}`);
452
+ })
453
+ ]), await Mt(e);
454
+ })()]), M(e);
455
+ } finally {
456
+ clearTimeout(r), e == null || e.removeEventListener("abort", n);
457
+ }
458
+ }
459
+ function Pt(t, e) {
460
+ var n;
461
+ const o = ((n = t.ownerDocument) == null ? void 0 : n.defaultView) || (typeof window < "u" ? window : null), r = o != null && o.getComputedStyle ? o.getComputedStyle(t) : null;
462
+ if (r) {
463
+ for (let i = 0; i < r.length; i++) {
464
+ const a = r.item(i);
465
+ /^(width|height|block-size|inline-size)$/.test(a) && !/^(IMG|CANVAS|SVG|TABLE|COL|COLGROUP)$/.test(t.tagName.toUpperCase()) || e.style.setProperty(a, r.getPropertyValue(a), r.getPropertyPriority(a));
466
+ }
467
+ e.style.animation = "none", e.style.transition = "none";
468
+ }
469
+ }
470
+ function Tt(t, e = S()) {
471
+ const o = typeof document < "u" ? document : t.ownerDocument, r = o != null && o.importNode ? o.importNode(t, !0) : t.cloneNode(!0), n = [t, ...Array.from(t.querySelectorAll("*"))], i = [r, ...Array.from(r.querySelectorAll("*"))];
472
+ n.forEach((s, l) => {
473
+ const c = i[l];
474
+ if (!c || c.nodeType !== 1)
475
+ return;
476
+ if (s !== t && L(s, e).kind === "ignore") {
477
+ c.remove();
478
+ return;
479
+ }
480
+ for (const d of Array.from(c.attributes))
481
+ (/^on/i.test(d.name) || d.name === "autofocus") && c.removeAttribute(d.name);
482
+ const p = (s.tagName || "").toLowerCase();
483
+ if (p === "input") {
484
+ const d = s, u = c;
485
+ u.value = d.value, u.checked = d.checked;
486
+ } else if (p === "textarea")
487
+ c.value = s.value;
488
+ else if (p === "select")
489
+ c.selectedIndex = s.selectedIndex;
490
+ else if (p === "canvas") {
491
+ const d = s, u = c;
492
+ u.width = d.width, u.height = d.height;
493
+ try {
494
+ d.toDataURL();
495
+ const m = u.getContext("2d");
496
+ if (!m)
497
+ throw new Error("canvas context unavailable");
498
+ m.drawImage(d, 0, 0);
499
+ } catch {
500
+ throw new Error("画布内容无法读取,请检查跨域图片或浏览器的画布支持");
501
+ }
502
+ } else if (p === "img") {
503
+ const d = c;
504
+ if (d.loading = "eager", d.src = s.currentSrc || s.src, d.removeAttribute("srcset"), d.removeAttribute("sizes"), /^https?:/.test(d.src) && typeof window < "u")
505
+ try {
506
+ new URL(d.src).origin !== window.location.origin && (d.crossOrigin = "anonymous");
507
+ } catch {
508
+ }
509
+ }
510
+ c.style && Pt(s, c);
511
+ }), r.querySelectorAll('[data-print-debug], [data-print-ignore="true"], [data-pdf-debug], [data-pdf-ignore="true"]').forEach((s) => s.remove()), r.style.margin = "0", r.style.setProperty("margin-inline", "0"), r.style.setProperty("margin-block", "0");
512
+ const a = t.getBoundingClientRect().width;
513
+ return a > 0 && (r.style.width = `${a}px`, r.style.maxWidth = "none", r.style.boxSizing = "border-box"), r;
514
+ }
515
+ function Rt(t, e = S()) {
516
+ const o = document.createElement("div");
517
+ return o.setAttribute("data-print-snapshot", "true"), o.setAttribute("aria-hidden", "true"), o.setAttribute("inert", ""), o.style.cssText = `position:absolute;left:-100000px;top:0;width:${t}px;pointer-events:none;background:white;`, {
518
+ clone: (n) => {
519
+ const i = Tt(n, e);
520
+ return i.style.width = `${t}px`, i.style.maxWidth = "none", i.style.boxSizing = "border-box", o.appendChild(i), i;
521
+ },
522
+ mount: () => document.body.appendChild(o),
523
+ ready: (n) => rt(o, n),
524
+ dispose: () => o.remove()
525
+ };
526
+ }
527
+ function ne(t) {
528
+ const e = t.cloneNode(!0);
529
+ let o = e;
530
+ const r = [t, ...Array.from(t.querySelectorAll("*"))], n = [e, ...Array.from(e.querySelectorAll("*"))];
531
+ return r.forEach((i, a) => {
532
+ const s = n[a];
533
+ for (const l of Array.from(s.attributes))
534
+ /^on/i.test(l.name) && s.removeAttribute(l.name);
535
+ if (i instanceof HTMLCanvasElement) {
536
+ const l = document.createElement("img");
537
+ l.src = i.toDataURL("image/png"), l.style.cssText = s.style.cssText, l.width = i.width, l.height = i.height, s === e ? o = l : s.replaceWith(l);
538
+ } else
539
+ i instanceof HTMLInputElement ? (s.setAttribute("value", i.type === "password" ? "" : i.value), s.toggleAttribute("checked", i.checked)) : i instanceof HTMLTextAreaElement ? s.textContent = i.value : i instanceof HTMLOptionElement && s.toggleAttribute("selected", i.selected);
540
+ s.matches("a, button, input, textarea, select, [tabindex]") && s.setAttribute("tabindex", "-1");
541
+ }), o.outerHTML;
542
+ }
543
+ function oe(t, e) {
544
+ const o = /* @__PURE__ */ new Map();
545
+ return t.replace(/\sid="([^"]+)"/g, (r, n) => (o.set(n, `${e}-${n}`), r)), t.replace(
546
+ /(\s(?:id|for|href|xlink:href|aria-labelledby|aria-describedby)="|url\(#)([^")]+)("|\))/g,
547
+ (r, n, i, a) => {
548
+ const s = i.startsWith("#"), l = (s ? i.slice(1) : i).split(" ").map((c) => o.get(c) || c).join(" ");
549
+ return `${n}${s ? "#" : ""}${l}${a}`;
550
+ }
551
+ );
552
+ }
553
+ const St = 8e6;
554
+ function At(t, e) {
555
+ const o = /* @__PURE__ */ new Set(), r = (n) => {
556
+ n.width = 0, n.height = 0, o.delete(n);
557
+ };
558
+ return {
559
+ async capture(n, i, a) {
560
+ if (e != null && e.aborted)
561
+ throw new Error("导出已取消");
562
+ const s = Math.min(2, Math.sqrt(St / (Math.ceil(t) * Math.ceil(a))), 8192 / t, 8192 / a);
563
+ if (!Number.isFinite(s) || s < 0.5)
564
+ throw new Error("页面像素超限,请缩小打印区域宽度");
565
+ const l = await lt(n, {
566
+ x: 0,
567
+ y: i,
568
+ width: t,
569
+ height: a,
570
+ scale: s,
571
+ useCORS: !0,
572
+ allowTaint: !1,
573
+ backgroundColor: "#ffffff",
574
+ logging: !1,
575
+ imageTimeout: 15e3,
576
+ ignoreElements: (c) => c.hasAttribute("data-print-debug") || c.getAttribute("data-print-ignore") === "true" ? !0 : c.tagName === "HEAD" || c.closest("head") ? !1 : c !== n && !c.contains(n) && !n.contains(c)
577
+ });
578
+ if (o.add(l), e != null && e.aborted)
579
+ throw new Error("导出已取消");
580
+ if (!l.width || !l.height)
581
+ throw new Error("截图为空,请检查打印区域");
582
+ return l;
583
+ },
584
+ release: r,
585
+ dispose: () => o.forEach(r)
586
+ };
587
+ }
588
+ function nt(t, e, o) {
589
+ const r = t + 1;
590
+ switch (o) {
591
+ case "chinese":
592
+ return `第 ${r} 页 / 共 ${e} 页`;
593
+ case "hyphen":
594
+ return `- ${r} -`;
595
+ case "slash":
596
+ default:
597
+ return `${r} / ${e}`;
598
+ }
599
+ }
600
+ async function kt({
601
+ geometry: t,
602
+ settings: e,
603
+ headerCanvas: o,
604
+ footerCanvas: r,
605
+ totalPages: n
606
+ }) {
607
+ const { jsPDF: i } = await import("jspdf"), { pageWidth: a, pageHeight: s, contentWidth: l, headerHeight: c, footerHeight: p, left: d, bodyTop: u, headerY: m, footerY: h, pageNumberY: f } = t, w = a > s ? "landscape" : "portrait", g = new i({ unit: "pt", format: [a, s], orientation: w }), x = (e == null ? void 0 : e.marginRightMm) !== void 0 ? P(e.marginRightMm) : P(10);
608
+ return {
609
+ addPageSlice(y, T, E) {
610
+ y > 0 && g.addPage(), g.addImage(T, "PNG", d, u, l, E, void 0, "FAST"), o && g.addImage(o, "PNG", d, m, l, c, "print-header", "FAST"), r && g.addImage(r, "PNG", d, h, l, p, "print-footer", "FAST");
611
+ const b = e == null ? void 0 : e.pageNumber;
612
+ if (b ? b.enabled : !0) {
613
+ g.setFontSize(9), g.setTextColor(120, 120, 120);
614
+ const C = (b == null ? void 0 : b.position) || "bottom-right", A = nt(y, n, b == null ? void 0 : b.format);
615
+ let _, $;
616
+ C === "bottom-center" || C === "top-center" ? (_ = a / 2, $ = "center") : (_ = a - x, $ = "right");
617
+ const K = f;
618
+ if ((b == null ? void 0 : b.format) === "chinese") {
619
+ const N = document.createElement("canvas");
620
+ N.width = 640, N.height = 48;
621
+ const F = N.getContext("2d");
622
+ if (!F)
623
+ throw new Error("浏览器无法渲染中文页码");
624
+ F.font = "24px sans-serif";
625
+ const st = Math.ceil(F.measureText(A).width);
626
+ F.fillStyle = "#787878", F.fillText(A, 0, 34);
627
+ const q = st * 9 / 24, ct = $ === "center" ? q / 2 : q;
628
+ g.addImage(N, "PNG", _ - ct, K - 12.75, 240, 18), N.width = 0, N.height = 0;
629
+ } else
630
+ g.text(A, _, K, { align: $ });
631
+ }
632
+ },
633
+ async finalize(y, T = !0) {
634
+ const E = g.output("blob");
635
+ return T && await g.save(`${y.replace(/\.pdf$/i, "") || "document"}.pdf`, { returnPromise: !0 }), E;
636
+ }
637
+ };
638
+ }
639
+ function Q(t, e, o) {
640
+ const r = document.createElement("div");
641
+ return r.className = `print-declarative-${e}`, r.style.width = `${o}px`, r.style.boxSizing = "border-box", r.style.padding = e === "header" ? "8px 0 6px 0" : "6px 0 8px 0", r.style.textAlign = t.align || "center", r.style.fontSize = e === "header" ? "12px" : "11px", r.style.color = e === "header" ? "#334155" : "#64748b", r.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif', r.style.lineHeight = "1.4", t.showDivider && (e === "header" ? r.style.borderBottom = "1px solid #cbd5e1" : r.style.borderTop = "1px solid #cbd5e1"), r.textContent = t.text || "", r;
642
+ }
643
+ const H = /* @__PURE__ */ new WeakSet();
644
+ function Ct({ root: t, capacity: e, maxPages: o, rules: r, ruleConfig: n }) {
645
+ const i = performance.now(), a = r || (n ? I(n) : S()), s = et(t, e, a), l = performance.now();
646
+ return {
647
+ pages: gt(s.height, e, s.ranges, o),
648
+ stats: s.stats,
649
+ timing: {
650
+ measurementMs: l - i,
651
+ paginationMs: performance.now() - l
652
+ }
653
+ };
654
+ }
655
+ function O(t) {
656
+ var n, i, a;
657
+ if (!t || typeof t != "object")
658
+ return !1;
659
+ const e = t;
660
+ if (e.nodeType !== 1)
661
+ return !1;
662
+ const o = (n = e.ownerDocument) == null ? void 0 : n.defaultView;
663
+ return o && typeof o.HTMLElement == "function" && e instanceof o.HTMLElement || typeof HTMLElement < "u" && e instanceof HTMLElement || typeof e.getBoundingClientRect == "function" && typeof e.cloneNode == "function" ? !!(e.isConnected ?? ((a = (i = e.ownerDocument) == null ? void 0 : i.contains) == null ? void 0 : a.call(i, e))) : !1;
664
+ }
665
+ function ot(t) {
666
+ var e, o, r;
667
+ if (!O(t))
668
+ return null;
669
+ if (((e = t.tagName) == null ? void 0 : e.toLowerCase()) === "iframe") {
670
+ const n = t;
671
+ let i;
672
+ try {
673
+ i = n.contentDocument || ((o = n.contentWindow) == null ? void 0 : o.document);
674
+ } catch {
675
+ throw new Error("无法读取跨域 iframe,请在嵌入系统内接入打印工具或使用其导出接口");
676
+ }
677
+ if (!(i != null && i.body) || i.readyState === "loading" || i.URL === "about:blank" && n.getAttribute("src"))
678
+ throw new Error("iframe 内容尚未就绪,请等待加载完成后重试");
679
+ const a = i.getElementById("iframe-report-content") || i.body;
680
+ if (!O(a) || !a.childElementCount && !((r = a.textContent) != null && r.trim()))
681
+ throw new Error("iframe 中没有可打印的业务内容");
682
+ return a;
683
+ }
684
+ return t;
685
+ }
686
+ async function it(t) {
687
+ var u, m, h, f, w;
688
+ const { header: e, footer: o, signal: r, orientation: n = "portrait" } = t, i = t.maxPages ?? 100, a = ot(t.element);
689
+ if (!a)
690
+ throw new Error("找不到有效的打印区域");
691
+ if (!["portrait", "landscape"].includes(n))
692
+ throw new Error("纸张方向必须为 portrait 或 landscape");
693
+ const s = mt({ ...ut, orientation: n, ...t.settings || {} });
694
+ if (H.has(a))
695
+ throw new Error("该区域正在导出,请勿重复提交");
696
+ let l = a.getBoundingClientRect().width;
697
+ if (!Number.isFinite(l) || l <= 0)
698
+ throw new Error("打印区域宽度为零,请先显示内容");
699
+ M(r), H.add(a);
700
+ const c = t.rules || (t.ruleConfig ? I(t.ruleConfig) : S());
701
+ let p;
702
+ const d = () => {
703
+ p == null || p.dispose(), H.delete(a);
704
+ };
705
+ try {
706
+ if (await rt(a, r, c), l = a.getBoundingClientRect().width, !Number.isFinite(l) || l <= 0)
707
+ throw new Error("打印区域宽度为零,请先显示内容");
708
+ p = Rt(l, c);
709
+ const g = p.clone(a);
710
+ let x;
711
+ if (e && O(e))
712
+ x = p.clone(e);
713
+ else if ((m = (u = t.settings) == null ? void 0 : u.header) != null && m.enabled && t.settings.header.text) {
714
+ const A = Q(t.settings.header, "header", l);
715
+ x = p.clone(A);
716
+ }
717
+ let y;
718
+ if (o && O(o))
719
+ y = p.clone(o);
720
+ else if ((f = (h = t.settings) == null ? void 0 : h.footer) != null && f.enabled && t.settings.footer.text) {
721
+ const A = Q(t.settings.footer, "footer", l);
722
+ y = p.clone(A);
723
+ }
724
+ p.mount(), await p.ready(r), M(r);
725
+ const T = ((w = t.settings) == null ? void 0 : w.pageNumber) ?? !0, E = ft(
726
+ s,
727
+ l,
728
+ x == null ? void 0 : x.getBoundingClientRect().height,
729
+ y == null ? void 0 : y.getBoundingClientRect().height,
730
+ T
731
+ ), { pages: b, stats: B, timing: C } = Ct({
732
+ root: g,
733
+ capacity: E.capacity,
734
+ maxPages: i,
735
+ rules: c
736
+ });
737
+ return {
738
+ ...E,
739
+ root: g,
740
+ header: x,
741
+ footer: y,
742
+ width: l,
743
+ pages: b,
744
+ stats: B,
745
+ timing: C,
746
+ cleanup: d
747
+ };
748
+ } catch (g) {
749
+ throw d(), g;
750
+ }
751
+ }
752
+ const Nt = Array.from({ length: 256 }, (t, e) => {
753
+ let o = e;
754
+ for (let r = 0; r < 8; r++)
755
+ o = o >>> 1 ^ 3988292384 & -(o & 1);
756
+ return o >>> 0;
757
+ });
758
+ function vt(t) {
759
+ if (t.length > 65535)
760
+ throw new Error("图片页数超出 ZIP 限制");
761
+ const e = [], o = [];
762
+ let r = 0, n = 0;
763
+ for (const { name: s, data: l } of t) {
764
+ const c = Uint8Array.from(s, (f) => f.charCodeAt(0));
765
+ let p = 4294967295;
766
+ for (let f = 0; f < l.length; f++)
767
+ p = p >>> 8 ^ Nt[(p ^ l[f]) & 255];
768
+ if (p = (p ^ 4294967295) >>> 0, r + l.length + c.length + 30 > 4294967295)
769
+ throw new Error("图片包超过 4GB,请分批导出");
770
+ const d = new Uint8Array(30 + c.length), u = new DataView(d.buffer);
771
+ u.setUint32(0, 67324752, !0), u.setUint16(4, 20, !0), u.setUint16(12, 33, !0), u.setUint32(14, p, !0), u.setUint32(18, l.length, !0), u.setUint32(22, l.length, !0), u.setUint16(26, c.length, !0), d.set(c, 30);
772
+ const m = new Uint8Array(46 + c.length), h = new DataView(m.buffer);
773
+ h.setUint32(0, 33639248, !0), h.setUint16(4, 20, !0), h.setUint16(6, 20, !0), h.setUint16(14, 33, !0), h.setUint32(16, p, !0), h.setUint32(20, l.length, !0), h.setUint32(24, l.length, !0), h.setUint16(28, c.length, !0), h.setUint32(42, r, !0), m.set(c, 46), e.push(d, l), o.push(m), r += d.length + l.length, n += m.length;
774
+ }
775
+ if (r + n + 22 > 4294967295)
776
+ throw new Error("图片包超过 4GB,请分批导出");
777
+ const i = new Uint8Array(22), a = new DataView(i.buffer);
778
+ return a.setUint32(0, 101010256, !0), a.setUint16(8, t.length, !0), a.setUint16(10, t.length, !0), a.setUint32(12, n, !0), a.setUint32(16, r, !0), new Blob([...e, ...o, i], { type: "application/zip" });
779
+ }
780
+ function Lt(t) {
781
+ return new Promise((e, o) => t.toBlob((r) => r ? e(r) : o(new Error("图片编码失败,请重试导出")), "image/png"));
782
+ }
783
+ function It(t) {
784
+ return new Promise((e, o) => {
785
+ const r = new FileReader();
786
+ r.onload = () => e(new Uint8Array(r.result)), r.onerror = () => o(new Error("图片读取失败,请重试导出")), r.readAsArrayBuffer(t);
787
+ });
788
+ }
789
+ function Bt(t, e, o, { geometry: r, settings: n, headerCanvas: i, footerCanvas: a, totalPages: s }) {
790
+ var d, u, m, h;
791
+ const l = document.createElement("canvas"), c = Math.min(t.width / r.contentWidth, Math.sqrt(8e6 / (r.pageWidth * r.pageHeight)), 8192 / r.pageWidth, 8192 / r.pageHeight);
792
+ l.width = Math.ceil(r.pageWidth * c), l.height = Math.ceil(r.pageHeight * c);
793
+ const p = l.getContext("2d");
794
+ if (!p)
795
+ throw new Error("浏览器无法生成分页图片");
796
+ if (p.scale(c, c), p.fillStyle = "#fff", p.fillRect(0, 0, r.pageWidth, r.pageHeight), p.drawImage(t, r.left, r.bodyTop, r.contentWidth, e), i && p.drawImage(i, r.left, r.headerY, r.contentWidth, r.headerHeight), a && p.drawImage(a, r.left, r.footerY, r.contentWidth, r.footerHeight), ((d = n == null ? void 0 : n.pageNumber) == null ? void 0 : d.enabled) !== !1) {
797
+ const f = (m = (u = n == null ? void 0 : n.pageNumber) == null ? void 0 : u.position) == null ? void 0 : m.endsWith("center");
798
+ p.font = "9px sans-serif", p.fillStyle = "#787878", p.textAlign = f ? "center" : "right", p.fillText(nt(o, s, (h = n == null ? void 0 : n.pageNumber) == null ? void 0 : h.format), f ? r.pageWidth / 2 : r.pageWidth - P((n == null ? void 0 : n.marginRightMm) ?? 10), r.pageNumberY);
799
+ }
800
+ return l;
801
+ }
802
+ function Ft({ geometry: t, settings: e, headerCanvas: o, footerCanvas: r, totalPages: n, signal: i }) {
803
+ const a = [];
804
+ return {
805
+ async addPageSlice(s, l, c) {
806
+ M(i);
807
+ const p = Bt(l, c, s, { geometry: t, settings: e, headerCanvas: o, footerCanvas: r, totalPages: n, signal: i });
808
+ try {
809
+ const d = await It(await Lt(p));
810
+ M(i), a.push({ name: `page-${String(s + 1).padStart(Math.max(3, String(n).length), "0")}.png`, data: d });
811
+ } finally {
812
+ p.width = 0, p.height = 0;
813
+ }
814
+ },
815
+ async finalize(s, l = !0) {
816
+ M(i);
817
+ const c = vt(a);
818
+ if (M(i), l) {
819
+ const p = URL.createObjectURL(c), d = document.createElement("a");
820
+ d.href = p, d.download = `${s.replace(/\.(pdf|zip|png)$/i, "") || "document"}-pages.zip`, document.body.appendChild(d);
821
+ try {
822
+ d.click();
823
+ } finally {
824
+ d.remove(), setTimeout(() => URL.revokeObjectURL(p), 6e4);
825
+ }
826
+ }
827
+ return c;
828
+ },
829
+ dispose() {
830
+ a.length = 0;
831
+ }
832
+ };
833
+ }
834
+ const at = {
835
+ pdf: kt,
836
+ png: Ft
837
+ };
838
+ function Y(t) {
839
+ if (!Object.prototype.hasOwnProperty.call(at, t))
840
+ throw new Error(`不支持的输出格式:${t}`);
841
+ }
842
+ function _t(t, e) {
843
+ return Y(t), at[t](e);
844
+ }
845
+ async function $t({ format: t = "pdf", filename: e, download: o = !0, onProgress: r, ...n }) {
846
+ Y(t);
847
+ const i = performance.now(), a = await it(n);
848
+ try {
849
+ return await Ot(a, { format: t, filename: e, download: o, onProgress: r, settings: n.settings, signal: n.signal }, performance.now() - i);
850
+ } finally {
851
+ a.cleanup();
852
+ }
853
+ }
854
+ async function Ot(t, e, o = 0) {
855
+ var f;
856
+ const { format: r = "pdf", filename: n, download: i = !0, onProgress: a } = e;
857
+ Y(r);
858
+ const s = performance.now(), { root: l, headerHeight: c, footerHeight: p, ratio: d, pages: u } = t;
859
+ let m, h;
860
+ try {
861
+ m = At(t.width, e.signal);
862
+ const { capture: w, release: g } = m, x = t.header ? await w(t.header, 0, c / d) : void 0, y = t.footer ? await w(t.footer, 0, p / d) : void 0;
863
+ h = await _t(r, {
864
+ signal: e.signal,
865
+ geometry: t,
866
+ settings: e.settings,
867
+ headerCanvas: x,
868
+ footerCanvas: y,
869
+ totalPages: u.length
870
+ }), a == null || a(0, u.length);
871
+ for (let E = 0; E < u.length; E++) {
872
+ M(e.signal);
873
+ const b = u[E], B = await w(l, b.start, b.end - b.start);
874
+ try {
875
+ await h.addPageSlice(E, B, (b.end - b.start) * d);
876
+ } finally {
877
+ g(B);
878
+ }
879
+ a == null || a(E + 1, u.length), await new Promise((C) => setTimeout(C, 0));
880
+ }
881
+ M(e.signal);
882
+ const T = await h.finalize(n, i);
883
+ return {
884
+ blob: T,
885
+ pages: u.length,
886
+ layoutMs: o,
887
+ totalMs: performance.now() - s,
888
+ bytes: T.size
889
+ };
890
+ } finally {
891
+ (f = h == null ? void 0 : h.dispose) == null || f.call(h), m == null || m.dispose();
892
+ }
893
+ }
894
+ function ie(t) {
895
+ return $t({ ...t, format: "pdf" });
896
+ }
897
+ async function Ut({
898
+ contentElement: t,
899
+ ...e
900
+ }) {
901
+ var i, a;
902
+ const o = performance.now(), r = ot(t), n = await it({ element: r, ...e });
903
+ try {
904
+ const s = n.pages.map((d) => d.start), l = e.rules || (e.ruleConfig ? I(e.ruleConfig) : S()), c = et(n.root, n.capacity, l);
905
+ bt(n.pages, c.ranges);
906
+ const p = {
907
+ pageBreaks: s,
908
+ pages: n.pages,
909
+ totalHeight: c.height,
910
+ capacity: n.capacity,
911
+ protectedRanges: c.ranges,
912
+ stats: n.stats,
913
+ timing: {
914
+ measurementMs: ((i = n.timing) == null ? void 0 : i.measurementMs) ?? 0,
915
+ paginationMs: ((a = n.timing) == null ? void 0 : a.paginationMs) ?? 0,
916
+ totalMs: performance.now() - o
917
+ }
918
+ };
919
+ return window.dispatchEvent(new CustomEvent("print-inspection", { detail: p })), window.dispatchEvent(new CustomEvent("pdf-print-inspection", { detail: p })), p;
920
+ } finally {
921
+ n.cleanup();
922
+ }
923
+ }
924
+ async function ae(t) {
925
+ return (await Ut(t)).pageBreaks;
926
+ }
927
+ const z = /* @__PURE__ */ new Map();
928
+ function Ht(t) {
929
+ (t || document).querySelectorAll("[data-print-debug]").forEach((o) => o.remove());
930
+ for (const [o, r] of Array.from(z))
931
+ (!t || t === o || t.nodeType === 9 && o.ownerDocument === t) && (r(), z.delete(o));
932
+ }
933
+ function se(t, e, o = S()) {
934
+ var c;
935
+ Ht(e);
936
+ const r = {
937
+ atomic: 0,
938
+ splittable: 0,
939
+ ignore: 0
940
+ }, n = ((c = e.ownerDocument) == null ? void 0 : c.defaultView) || (typeof window < "u" ? window : null), i = n != null && n.getComputedStyle ? n.getComputedStyle(e) : null;
941
+ if (i && i.position === "static") {
942
+ const p = e.style.getPropertyValue("position"), d = e.style.getPropertyPriority("position");
943
+ e.style.position = "relative", z.set(e, () => {
944
+ p ? e.style.setProperty("position", p, d) : e.style.removeProperty("position");
945
+ });
946
+ }
947
+ const a = e.getBoundingClientRect(), s = i && parseFloat(i.borderTopWidth) || 0, l = i && parseFloat(i.borderLeftWidth) || 0;
948
+ return V(e, (p) => {
949
+ if (p.nodeType !== 1)
950
+ return "skip";
951
+ const d = p;
952
+ if (d.hasAttribute("data-print-debug"))
953
+ return "skip";
954
+ const u = L(d, o);
955
+ if (u.kind === "ignore") {
956
+ r.ignore++;
957
+ const w = d.getBoundingClientRect();
958
+ return w.width > 0 && w.height > 0 && e.appendChild(
959
+ W({
960
+ left: w.left - a.left - l,
961
+ top: w.top - a.top - s,
962
+ width: w.width,
963
+ height: w.height,
964
+ borderColor: "#94a3b8",
965
+ borderStyle: "dashed",
966
+ backgroundColor: "rgba(148, 163, 184, 0.08)",
967
+ badgeText: "ignore",
968
+ badgeBg: "#64748b",
969
+ badgePosition: "left"
970
+ })
971
+ ), "skip";
972
+ }
973
+ const m = d.getBoundingClientRect();
974
+ if (m.width <= 0 || m.height <= 0)
975
+ return "skip";
976
+ if (u.kind === "atomic")
977
+ return r.atomic++, e.appendChild(
978
+ W({
979
+ left: m.left - a.left - l,
980
+ top: m.top - a.top - s,
981
+ width: m.width,
982
+ height: m.height,
983
+ borderColor: "#ef4444",
984
+ borderStyle: "solid",
985
+ backgroundColor: "rgba(239, 68, 68, 0.05)",
986
+ badgeText: "atomic",
987
+ badgeBg: "#ef4444",
988
+ badgePosition: "right"
989
+ })
990
+ ), "skip";
991
+ if (Gt(d, n))
992
+ return "skip";
993
+ const h = d.matches(Wt), f = zt(d);
994
+ return h || f ? (r.splittable++, e.appendChild(
995
+ W({
996
+ left: m.left - a.left - l,
997
+ top: m.top - a.top - s,
998
+ width: m.width,
999
+ height: m.height,
1000
+ borderColor: "#3b82f6",
1001
+ borderStyle: "dashed",
1002
+ backgroundColor: "rgba(59, 130, 246, 0.04)",
1003
+ badgeText: "splittable",
1004
+ badgeBg: "#3b82f6",
1005
+ badgePosition: "right"
1006
+ })
1007
+ ), h ? "descend" : "skip") : "descend";
1008
+ }), t.slice(1).forEach((p, d) => {
1009
+ const u = p - s, m = e.ownerDocument.createElement("div");
1010
+ m.setAttribute("data-print-debug", "true"), m.style.cssText = `
1011
+ position: absolute;
1012
+ left: 0;
1013
+ top: ${u}px;
1014
+ width: 100%;
1015
+ height: 0;
1016
+ border-top: 2px dashed #7c3aed;
1017
+ z-index: ${G.line};
1018
+ pointer-events: none;
1019
+ box-sizing: border-box;
1020
+ `;
1021
+ const h = e.ownerDocument.createElement("span");
1022
+ h.textContent = `✂️ page-break: ${Math.round(p)}px (p.${d + 1} ➔ p.${d + 2})`, h.style.cssText = `
1023
+ position: absolute;
1024
+ right: 16px;
1025
+ top: -11px;
1026
+ background: #7c3aed;
1027
+ color: #fff;
1028
+ font-size: 11px;
1029
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1030
+ line-height: 1;
1031
+ padding: 3px 8px;
1032
+ border-radius: 10px;
1033
+ font-weight: 600;
1034
+ letter-spacing: 0.2px;
1035
+ box-shadow: 0 1px 4px rgba(124, 58, 237, 0.35);
1036
+ white-space: nowrap;
1037
+ `, m.appendChild(h), e.appendChild(m);
1038
+ }), r;
1039
+ }
1040
+ const Wt = '[data-print-splittable="true"], .print-splittable, [data-print-break="split"], .print-force-split, [data-pdf-splittable="true"], .pdf-splittable, [data-pdf-break="split"], .pdf-force-split', G = { box: 2, badge: 3, line: 4 }, Dt = /* @__PURE__ */ new Set([
1041
+ "SPAN",
1042
+ "B",
1043
+ "STRONG",
1044
+ "EM",
1045
+ "I",
1046
+ "CODE",
1047
+ "A",
1048
+ "SMALL",
1049
+ "SUP",
1050
+ "SUB",
1051
+ "MARK",
1052
+ "ABBR",
1053
+ "CITE",
1054
+ "Q",
1055
+ "TIME",
1056
+ "U",
1057
+ "S",
1058
+ "KBD",
1059
+ "SAMP",
1060
+ "VAR",
1061
+ "BR"
1062
+ ]);
1063
+ function zt(t) {
1064
+ var e;
1065
+ for (let o = 0; o < t.childNodes.length; o++) {
1066
+ const r = t.childNodes[o];
1067
+ if (r.nodeType === 3 && ((e = r.textContent) != null && e.trim()))
1068
+ return !0;
1069
+ }
1070
+ return !1;
1071
+ }
1072
+ function Gt(t, e) {
1073
+ return Dt.has(t.tagName) ? !0 : e != null && e.getComputedStyle ? e.getComputedStyle(t).display.startsWith("inline") : !1;
1074
+ }
1075
+ function W(t) {
1076
+ const e = document.createElement("div");
1077
+ e.setAttribute("data-print-debug", "true"), e.style.cssText = `
1078
+ position: absolute;
1079
+ left: ${t.left}px;
1080
+ top: ${t.top}px;
1081
+ width: ${t.width}px;
1082
+ height: ${t.height}px;
1083
+ border: 1.5px ${t.borderStyle} ${t.borderColor};
1084
+ background: ${t.backgroundColor};
1085
+ box-sizing: border-box;
1086
+ z-index: ${G.box};
1087
+ pointer-events: none;
1088
+ border-radius: 2px;
1089
+ `;
1090
+ const o = document.createElement("span");
1091
+ o.textContent = t.badgeText;
1092
+ const r = t.badgePosition === "right", n = "2px", i = r ? "right: 4px;" : "left: 4px;";
1093
+ return o.style.cssText = `
1094
+ position: absolute;
1095
+ ${i}
1096
+ top: ${n};
1097
+ background: ${t.badgeBg};
1098
+ color: #ffffff;
1099
+ font-size: 9px;
1100
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1101
+ font-weight: 600;
1102
+ line-height: 1;
1103
+ padding: 1.5px 5px;
1104
+ border-radius: 3px;
1105
+ white-space: nowrap;
1106
+ box-shadow: 0 1px 2px rgba(0,0,0,0.18);
1107
+ z-index: ${G.badge};
1108
+ opacity: 0.95;
1109
+ letter-spacing: 0.2px;
1110
+ `, e.appendChild(o), e;
1111
+ }
1112
+ export {
1113
+ ot as $,
1114
+ te as A,
1115
+ D as B,
1116
+ S as C,
1117
+ ut as D,
1118
+ ee as E,
1119
+ L as F,
1120
+ Z as G,
1121
+ V as H,
1122
+ U as I,
1123
+ tt as J,
1124
+ re as K,
1125
+ Et as L,
1126
+ v as M,
1127
+ et as N,
1128
+ Pt as O,
1129
+ dt as P,
1130
+ Tt as Q,
1131
+ Rt as R,
1132
+ ne as S,
1133
+ oe as T,
1134
+ ht as U,
1135
+ rt as V,
1136
+ kt as W,
1137
+ nt as X,
1138
+ Q as Y,
1139
+ Ct as Z,
1140
+ O as _,
1141
+ Bt as a,
1142
+ $t as a0,
1143
+ ie as a1,
1144
+ Ut as a2,
1145
+ ae as a3,
1146
+ Y as a4,
1147
+ _t as a5,
1148
+ M as b,
1149
+ At as c,
1150
+ Ht as d,
1151
+ Ot as e,
1152
+ k as f,
1153
+ Vt as g,
1154
+ Yt as h,
1155
+ pt as i,
1156
+ J as j,
1157
+ X as k,
1158
+ Kt as l,
1159
+ P as m,
1160
+ qt as n,
1161
+ ft as o,
1162
+ it as p,
1163
+ gt as q,
1164
+ mt as r,
1165
+ bt as s,
1166
+ Xt as t,
1167
+ Zt as u,
1168
+ se as v,
1169
+ Qt as w,
1170
+ Jt as x,
1171
+ xt as y,
1172
+ I as z
1173
+ };
1174
+ //# sourceMappingURL=page-break-overlay-e5f1b145.mjs.map