@darialan/web-printer 0.0.0-stage → 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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -2
  3. package/dist/index.cjs +2 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.mjs +131 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/page-break-overlay-50796a2a.js +56 -0
  9. package/dist/page-break-overlay-50796a2a.js.map +1 -0
  10. package/dist/page-break-overlay-e5f1b145.mjs +1174 -0
  11. package/dist/page-break-overlay-e5f1b145.mjs.map +1 -0
  12. package/dist/react.cjs +2 -0
  13. package/dist/react.cjs.map +1 -0
  14. package/dist/react.mjs +60 -0
  15. package/dist/react.mjs.map +1 -0
  16. package/dist/types/adapters/canvas/index.d.ts +1 -0
  17. package/dist/types/adapters/canvas/page-capture.d.ts +6 -0
  18. package/dist/types/adapters/dom/index.d.ts +4 -0
  19. package/dist/types/adapters/dom/measurement.d.ts +4 -0
  20. package/dist/types/adapters/dom/snapshot.d.ts +20 -0
  21. package/dist/types/adapters/dom/text-range.d.ts +4 -0
  22. package/dist/types/adapters/dom/traversal.d.ts +3 -0
  23. package/dist/types/adapters/index.d.ts +4 -0
  24. package/dist/types/adapters/pdf/index.d.ts +1 -0
  25. package/dist/types/adapters/pdf/jspdf-writer.d.ts +15 -0
  26. package/dist/types/adapters/resources/index.d.ts +1 -0
  27. package/dist/types/adapters/resources/resource-loader.d.ts +2 -0
  28. package/dist/types/application/cancellation.d.ts +1 -0
  29. package/dist/types/application/index.d.ts +4 -0
  30. package/dist/types/application/print-pipeline.d.ts +53 -0
  31. package/dist/types/application/print-service.d.ts +55 -0
  32. package/dist/types/application/print-session.d.ts +17 -0
  33. package/dist/types/core/geometry/index.d.ts +2 -0
  34. package/dist/types/core/geometry/page-geometry.d.ts +18 -0
  35. package/dist/types/core/geometry/paper.d.ts +83 -0
  36. package/dist/types/core/index.d.ts +4 -0
  37. package/dist/types/core/pagination/index.d.ts +1 -0
  38. package/dist/types/core/pagination/paginator.d.ts +6 -0
  39. package/dist/types/core/rules/index.d.ts +1 -0
  40. package/dist/types/core/rules/print-rules.d.ts +80 -0
  41. package/dist/types/core/types.d.ts +77 -0
  42. package/dist/types/hooks/index.d.ts +3 -0
  43. package/dist/types/hooks/use-pdf-print.d.ts +6 -0
  44. package/dist/types/hooks/use-web-printer.d.ts +46 -0
  45. package/dist/types/index.d.ts +19 -0
  46. package/dist/types/output/image-writer.d.ts +5 -0
  47. package/dist/types/output/index.d.ts +4 -0
  48. package/dist/types/output/page-number.d.ts +1 -0
  49. package/dist/types/output/types.d.ts +17 -0
  50. package/dist/types/output/zip.d.ts +5 -0
  51. package/dist/types/overlay/page-break-overlay.d.ts +8 -0
  52. package/dist/types/react.d.ts +2 -0
  53. package/docs/migration-to-web-printer.md +42 -0
  54. package/docs/output-formats.md +47 -0
  55. package/package.json +140 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 darialan (https://github.com/darialan/web-pdf-printer)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,107 @@
1
- # Temporary Holding Version
1
+ # Web Printer
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 把已渲染的长网页按内容分页,保留现有样式,输出 PDF 或逐页 PNG。
4
+
5
+ [在线工作台](https://pdf-demo-phi.vercel.app/#/playground) · [安装与迁移](docs/migration-to-web-printer.md) · [输出层说明](docs/output-formats.md)
6
+
7
+ ## 安装
8
+
9
+ ```sh
10
+ npm install @darialan/web-printer
11
+ ```
12
+
13
+ `html2canvas` 与 `jspdf` 随包安装。核心入口不依赖 React;React Hook 从可选的 `/react` 入口使用。
14
+
15
+ ## 导出 PDF 或分页图片
16
+
17
+ ```ts
18
+ import { outputDocument } from '@darialan/web-printer';
19
+
20
+ await outputDocument({
21
+ element: document.getElementById('content'),
22
+ filename: 'report',
23
+ format: 'pdf', // 'png':逐页 PNG,打包为 ZIP 下载
24
+ settings: {
25
+ paper: 'a4',
26
+ marginTopMm: 12,
27
+ marginRightMm: 12,
28
+ marginBottomMm: 12,
29
+ marginLeftMm: 12,
30
+ },
31
+ });
32
+ ```
33
+
34
+ `download: false` 返回 Blob;`signal` 支持取消;`onProgress(completed, total)` 报告实际页进度。PDF 与图片共用布局、测量、分页和截图管线,由独立 writer 组装输出。旧 PDF 专用接口 `outputPDF()` 保留。
35
+
36
+ ## React
37
+
38
+ ```tsx
39
+ import { useRef } from 'react';
40
+ import { useWebPrinter } from '@darialan/web-printer/react';
41
+
42
+ export function Report() {
43
+ const content = useRef<HTMLDivElement>(null);
44
+ const { exportDocument, isExporting, error, cancel } = useWebPrinter();
45
+ return <>
46
+ <button disabled={isExporting} onClick={() => {
47
+ exportDocument({ element: content.current, filename: 'report', format: 'png' })
48
+ .catch(() => { /* error 已记录,可在界面展示 */ });
49
+ }}>导出分页图片</button>
50
+ {isExporting && <button onClick={cancel}>取消导出</button>}
51
+ {error && <p role="alert">{error.message}</p>}
52
+ <div ref={content}>你的页面内容</div>
53
+ </>;
54
+ }
55
+ ```
56
+
57
+ React 由宿主项目安装。旧名 `usePdfPrint` 在同一 `/react` 入口作为兼容别名保留;`exportPDF` 与 `isPrinting` 仍可使用。
58
+
59
+ ## 内容保护与排除
60
+
61
+ ```html
62
+ <article data-print-splittable="true">长文章正文</article>
63
+ <figure data-print-atomic="true">整块保护的配图与说明</figure>
64
+ <div data-print-ignore="true">不参与输出的工具栏</div>
65
+ ```
66
+
67
+ | 标记 | 行为 |
68
+ | --- | --- |
69
+ | `data-print-atomic="true"` / `.print-atomic` | 整块换页;整块高于一页时报错,提示调整布局或尺寸 |
70
+ | `data-print-splittable="true"` / `.print-splittable` | 继续深入内容,按文字行与子元素分页 |
71
+ | `data-print-ignore="true"` / `.print-ignore` | 快照排版前移除,不占用输出空间 |
72
+ | `data-print-keep-together="split"` / `.print-keep-or-split` | 优先整体换页,过高时允许深入拆分;表格行默认采用该规则 |
73
+
74
+ `PRINT_ATTRIBUTES` 与 `PRINT_CLASSES` 提供协议常量。旧 `data-pdf-*` / `.pdf-*` 与旧常量继续可用,详见[迁移说明](docs/migration-to-web-printer.md)。
75
+
76
+ `configurePrint()` 可注册组件库选择器;`inspectPrintLayout()` 只测量与检查,不导出;`visualizePageBreaks()` 显示 `atomic`、`splittable`、`ignore` 和 `page-break`,`clearPageBreaks()` 清理标记。
77
+
78
+ ## 四个真实场景
79
+
80
+ | 场景 | 验证内容 |
81
+ | --- | --- |
82
+ | 长表格 | 45 行采购明细,行保护与超高单元格文字分页 |
83
+ | 长文章 | 连续段落按实际文字行换页 |
84
+ | 复杂图文 | 原样式文章中的配图、公式和代码整体保护 |
85
+ | 自定义页眉页脚 | 品牌信息与页码跨页重复 |
86
+
87
+ 工作台支持尺寸、方向、边距、页码、纸张与社媒图片比例。检查包含页面标记和纸张预览,两部分独立失败与重试。
88
+
89
+ ## 支持边界
90
+
91
+ 核心为 TypeScript,接收 DOM,可在原生 JS、Vue、React 等客户端页面使用。图片和字体需完成加载,跨域图片需允许 CORS。复杂 CSS 的还原受 html2canvas 支持范围影响;跨域 iframe、Shadow DOM 和视频不属于无条件完整支持范围。PDF 正文为光栅图像,没有可搜索的文字层;PNG 像素尺寸受截图清晰度与画布预算影响,页面 px 用于布局。
92
+
93
+ 默认最多 100 页;采用逐页画布,避免创建整篇长画布。压缩图像字节仍会随总页数增长,不表示任意长度文档无内存成本。
94
+
95
+ ## 开发与验证
96
+
97
+ ```sh
98
+ npm ci
99
+ npm start
100
+ npm run check
101
+ ```
102
+
103
+ `npm run check` 依次执行 TypeScript、单测、ESM/CJS 与类型构建、网页生产构建及 Chromium 自动化。浏览器测试覆盖真实 PDF/PNG 下载、预览一致性、取消、重试、主题、键盘与窄屏。
104
+
105
+ 源码布局:`src/lib/core` 为分页与几何,`adapters` 为 DOM/画布/PDF 适配,`application` 编排生命周期,`output` 区分格式,`hooks` 提供可选 React 集成;`src/demo` 和 `src/landing` 分别为工作台与首页。
106
+
107
+ MIT License。原包 `@darialan/web-pdf-printer@1.0.2` 保持可下载,新开发建议使用 `@darialan/web-printer`。
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./page-break-overlay-50796a2a.js");require("html2canvas");async function y(s){var h,T,_;const i=new AbortController,g=()=>i.abort();(h=s.signal)==null||h.addEventListener("abort",g,{once:!0}),(T=s.signal)!=null&&T.aborted&&i.abort();const f=performance.now();let t;try{t=await e.prepareLayout({...s,signal:i.signal})}catch(r){throw(_=s.signal)==null||_.removeEventListener("abort",g),r}const l=e.createPageCapture(t.width,i.signal),m=s.settings?JSON.parse(JSON.stringify(s.settings)):void 0;let E=!1,c=!1;const p=()=>{if(E)throw new Error("打印会话已关闭,请重新生成预览");if(e.checkCancelled(i.signal),c)throw new Error("正在处理上一项任务,请稍候")},R=performance.now()-f;return{layout:t,preparedMs:R,async thumbnail(r,P=480){if(p(),!Number.isInteger(r)||r<0||r>=t.pages.length)throw new Error("预览页码无效");c=!0;let n,a;try{const o=t.pages[r],u=await l.capture(t.root,o.start,o.end-o.start);try{const d=t.header?await l.capture(t.header,0,t.headerHeight/t.ratio):void 0,S=t.footer?await l.capture(t.footer,0,t.footerHeight/t.ratio):void 0;try{n=e.composePageCanvas(u,(o.end-o.start)*t.ratio,r,{geometry:t,settings:m,headerCanvas:d,footerCanvas:S,totalPages:t.pages.length})}finally{d&&l.release(d),S&&l.release(S)}}finally{l.release(u)}a=document.createElement("canvas"),a.width=Math.max(1,Math.min(640,P,n.width)),a.height=Math.ceil(n.height*a.width/n.width);const v=a.getContext("2d");if(!v)throw new Error("浏览器无法生成预览");return v.drawImage(n,0,0,a.width,a.height),e.checkCancelled(i.signal),a.toDataURL("image/jpeg",.85)}finally{n&&(n.width=0,n.height=0),a&&(a.width=0,a.height=0),c=!1}},async exportDocument(r){var a,o,u;p(),c=!0;const P=new AbortController,n=()=>P.abort();i.signal.addEventListener("abort",n,{once:!0}),(a=r.signal)==null||a.addEventListener("abort",n,{once:!0}),((o=r.signal)!=null&&o.aborted||i.signal.aborted)&&P.abort();try{return await e.exportPreparedLayout(t,{...r,settings:m,signal:P.signal},R)}finally{i.signal.removeEventListener("abort",n),(u=r.signal)==null||u.removeEventListener("abort",n),c=!1}},dispose(){var r;E||(E=!0,i.abort(),l.dispose(),t.cleanup(),(r=s.signal)==null||r.removeEventListener("abort",g))}}}exports.BASE_PRINT_RULES=e.BASE_PRINT_RULES;exports.DEFAULT_PRINT_RULES=e.DEFAULT_PRINT_RULES;exports.DEFAULT_SETTINGS=e.DEFAULT_SETTINGS;exports.IMAGE_PAPERS=e.IMAGE_PAPERS;exports.IMAGE_PAPER_SIZES=e.IMAGE_PAPER_SIZES;exports.MM_PER_PX=e.MM_PER_PX;exports.PAPER_PRESETS=e.PAPER_PRESETS;exports.PAPER_SIZES=e.PAPER_SIZES;exports.PDF_PRINT_ATTRIBUTES=e.PDF_PRINT_ATTRIBUTES;exports.PDF_PRINT_CLASSES=e.PDF_PRINT_CLASSES;exports.PRINT_ATTRIBUTES=e.PRINT_ATTRIBUTES;exports.PRINT_CLASSES=e.PRINT_CLASSES;exports.PT_PER_MM=e.PT_PER_MM;exports.PX_PER_MM=e.PX_PER_MM;exports.UNIT_FIELDS=e.UNIT_FIELDS;exports.buildPrintRules=e.buildPrintRules;exports.calculateGeometry=e.calculateGeometry;exports.calculatePagesArray=e.calculatePagesArray;exports.checkCancelled=e.checkCancelled;exports.classifyPrintNode=e.classifyPrintNode;exports.clearPageBreaks=e.clearPageBreaks;exports.cloneWithResolvedStyles=e.cloneWithResolvedStyles;exports.configurePrint=e.configurePrint;exports.convertFields=e.convertFields;exports.copyResolvedStyle=e.copyResolvedStyle;exports.createDeclarativeElement=e.createDeclarativeElement;exports.createOutputWriter=e.createOutputWriter;exports.createPageCapture=e.createPageCapture;exports.createPdfWriter=e.createPdfWriter;exports.createPrintSnapshot=e.createPrintSnapshot;exports.createTextMeasurer=e.createTextMeasurer;exports.exportPreparedLayout=e.exportPreparedLayout;exports.formatPageNumber=e.formatPageNumber;exports.getPresetDimensions=e.getPresetDimensions;exports.getPresetUnit=e.getPresetUnit;exports.getPrintRules=e.getPrintRules;exports.inspectPrintLayout=e.inspectPrintLayout;exports.isImagePaper=e.isImagePaper;exports.isPrintableElement=e.isPrintableElement;exports.measureDocument=e.measureDocument;exports.measureTextLines=e.measureTextLines;exports.mmToPt=e.mmToPt;exports.namespacePreviewHtml=e.namespacePreviewHtml;exports.outputDocument=e.outputDocument;exports.outputPDF=e.outputPDF;exports.paginate=e.paginate;exports.planDocument=e.planDocument;exports.prepareLayout=e.prepareLayout;exports.readRootHeight=e.readRootHeight;exports.resetPrintRules=e.resetPrintRules;exports.resolveAtomicOverflow=e.resolveAtomicOverflow;exports.resolvePaper=e.resolvePaper;exports.resolvePrintElement=e.resolvePrintElement;exports.serializePrintSnapshot=e.serializePrintSnapshot;exports.validateOutputFormat=e.validateOutputFormat;exports.validatePageBreaks=e.validatePageBreaks;exports.visualizePageBreaks=e.visualizePageBreaks;exports.waitForResources=e.waitForResources;exports.walkPrintTree=e.walkPrintTree;exports.createPrintSession=y;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/lib/application/print-session.ts"],"sourcesContent":["import { createPageCapture } from '../adapters/canvas/page-capture';\nimport { composePageCanvas } from '../output/image-writer';\nimport { PrintSettings } from '../core/types';\nimport { checkCancelled } from './cancellation';\nimport { LayoutOptions, prepareLayout } from './print-pipeline';\nimport { DocumentExportOptions, exportPreparedLayout } from './print-service';\n\n/** A frozen document shared by preview, inspection and all output formats. */\nexport async function createPrintSession(options: LayoutOptions) {\n const lifetime = new AbortController();\n const forwardAbort = () => lifetime.abort();\n options.signal?.addEventListener('abort', forwardAbort, { once: true });\n if (options.signal?.aborted) lifetime.abort();\n const started = performance.now();\n let layout;\n try { layout = await prepareLayout({ ...options, signal: lifetime.signal }); }\n catch (error) { options.signal?.removeEventListener('abort', forwardAbort); throw error; }\n const renderer = createPageCapture(layout.width, lifetime.signal);\n const settings: Partial<PrintSettings> | undefined = options.settings ? JSON.parse(JSON.stringify(options.settings)) : undefined;\n let disposed = false;\n let busy = false;\n const assertLive = () => {\n if (disposed) throw new Error('打印会话已关闭,请重新生成预览');\n checkCancelled(lifetime.signal);\n if (busy) throw new Error('正在处理上一项任务,请稍候');\n };\n const preparedMs = performance.now() - started;\n return {\n layout,\n preparedMs,\n async thumbnail(index: number, maxWidth = 480): Promise<string> {\n assertLive();\n if (!Number.isInteger(index) || index < 0 || index >= layout.pages.length) throw new Error('预览页码无效');\n busy = true;\n let sheet: HTMLCanvasElement | undefined;\n let thumb: HTMLCanvasElement | undefined;\n try {\n const page = layout.pages[index];\n const body = await renderer.capture(layout.root, page.start, page.end - page.start);\n try {\n const headerCanvas = layout.header ? await renderer.capture(layout.header, 0, layout.headerHeight / layout.ratio) : undefined;\n const footerCanvas = layout.footer ? await renderer.capture(layout.footer, 0, layout.footerHeight / layout.ratio) : undefined;\n try {\n sheet = composePageCanvas(body, (page.end - page.start) * layout.ratio, index, { geometry: layout, settings, headerCanvas, footerCanvas, totalPages: layout.pages.length });\n } finally { if (headerCanvas) renderer.release(headerCanvas); if (footerCanvas) renderer.release(footerCanvas); }\n } finally { renderer.release(body); }\n thumb = document.createElement('canvas');\n thumb.width = Math.max(1, Math.min(640, maxWidth, sheet.width));\n thumb.height = Math.ceil(sheet.height * thumb.width / sheet.width);\n const ctx = thumb.getContext('2d');\n if (!ctx) throw new Error('浏览器无法生成预览');\n ctx.drawImage(sheet, 0, 0, thumb.width, thumb.height);\n checkCancelled(lifetime.signal);\n return thumb.toDataURL('image/jpeg', 0.85);\n } finally {\n if (sheet) { sheet.width = 0; sheet.height = 0; }\n if (thumb) { thumb.width = 0; thumb.height = 0; }\n busy = false;\n }\n },\n async exportDocument(params: Omit<DocumentExportOptions, 'element' | 'settings'>) {\n assertLive(); busy = true;\n const controller = new AbortController();\n const cancel = () => controller.abort();\n lifetime.signal.addEventListener('abort', cancel, { once: true });\n params.signal?.addEventListener('abort', cancel, { once: true });\n if (params.signal?.aborted || lifetime.signal.aborted) controller.abort();\n try { return await exportPreparedLayout(layout, { ...params, settings, signal: controller.signal }, preparedMs); }\n finally {\n lifetime.signal.removeEventListener('abort', cancel);\n params.signal?.removeEventListener('abort', cancel);\n busy = false;\n }\n },\n dispose() {\n if (disposed) return;\n disposed = true; lifetime.abort(); renderer.dispose(); layout.cleanup();\n options.signal?.removeEventListener('abort', forwardAbort);\n },\n };\n}\nexport type PrintSession = Awaited<ReturnType<typeof createPrintSession>>;\n"],"names":["createPrintSession","options","lifetime","forwardAbort","_a","_b","started","layout","prepareLayout","error","_c","renderer","createPageCapture","settings","disposed","busy","assertLive","checkCancelled","preparedMs","index","maxWidth","sheet","thumb","page","body","headerCanvas","footerCanvas","composePageCanvas","ctx","params","controller","cancel","exportPreparedLayout"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './types/index';
package/dist/index.mjs ADDED
@@ -0,0 +1,131 @@
1
+ import { p as R, c as T, a as _, b, e as L } from "./page-break-overlay-e5f1b145.mjs";
2
+ import { B as C, y as F, D as U, g as B, I as k, M as x, k as O, j as G, w as H, x as W, t as z, u as J, P as X, f as Z, U as j, z as q, o as K, a3 as Q, F as V, d as Y, Q as $, A as ee, n as ae, O as te, Y as re, a5 as se, W as ne, R as oe, J as ie, X as le, l as ce, h as ge, C as Pe, a2 as ue, i as de, _ as he, N as me, K as Ee, m as fe, T as pe, a0 as we, a1 as ve, q as Se, Z as be, L as ye, E as Re, G as Te, r as _e, $ as Le, S as Ae, a4 as Ie, s as De, v as Me, V as Ne, H as Ce } from "./page-break-overlay-e5f1b145.mjs";
3
+ import "html2canvas";
4
+ async function D(o) {
5
+ var p, w, v;
6
+ const s = new AbortController(), P = () => s.abort();
7
+ (p = o.signal) == null || p.addEventListener("abort", P, { once: !0 }), (w = o.signal) != null && w.aborted && s.abort();
8
+ const y = performance.now();
9
+ let e;
10
+ try {
11
+ e = await R({ ...o, signal: s.signal });
12
+ } catch (a) {
13
+ throw (v = o.signal) == null || v.removeEventListener("abort", P), a;
14
+ }
15
+ const i = T(e.width, s.signal), m = o.settings ? JSON.parse(JSON.stringify(o.settings)) : void 0;
16
+ let u = !1, l = !1;
17
+ const E = () => {
18
+ if (u)
19
+ throw new Error("打印会话已关闭,请重新生成预览");
20
+ if (b(s.signal), l)
21
+ throw new Error("正在处理上一项任务,请稍候");
22
+ }, f = performance.now() - y;
23
+ return {
24
+ layout: e,
25
+ preparedMs: f,
26
+ async thumbnail(a, c = 480) {
27
+ if (E(), !Number.isInteger(a) || a < 0 || a >= e.pages.length)
28
+ throw new Error("预览页码无效");
29
+ l = !0;
30
+ let r, t;
31
+ try {
32
+ const n = e.pages[a], g = await i.capture(e.root, n.start, n.end - n.start);
33
+ try {
34
+ const d = e.header ? await i.capture(e.header, 0, e.headerHeight / e.ratio) : void 0, h = e.footer ? await i.capture(e.footer, 0, e.footerHeight / e.ratio) : void 0;
35
+ try {
36
+ r = _(g, (n.end - n.start) * e.ratio, a, { geometry: e, settings: m, headerCanvas: d, footerCanvas: h, totalPages: e.pages.length });
37
+ } finally {
38
+ d && i.release(d), h && i.release(h);
39
+ }
40
+ } finally {
41
+ i.release(g);
42
+ }
43
+ t = document.createElement("canvas"), t.width = Math.max(1, Math.min(640, c, r.width)), t.height = Math.ceil(r.height * t.width / r.width);
44
+ const S = t.getContext("2d");
45
+ if (!S)
46
+ throw new Error("浏览器无法生成预览");
47
+ return S.drawImage(r, 0, 0, t.width, t.height), b(s.signal), t.toDataURL("image/jpeg", 0.85);
48
+ } finally {
49
+ r && (r.width = 0, r.height = 0), t && (t.width = 0, t.height = 0), l = !1;
50
+ }
51
+ },
52
+ async exportDocument(a) {
53
+ var t, n, g;
54
+ E(), l = !0;
55
+ const c = new AbortController(), r = () => c.abort();
56
+ s.signal.addEventListener("abort", r, { once: !0 }), (t = a.signal) == null || t.addEventListener("abort", r, { once: !0 }), ((n = a.signal) != null && n.aborted || s.signal.aborted) && c.abort();
57
+ try {
58
+ return await L(e, { ...a, settings: m, signal: c.signal }, f);
59
+ } finally {
60
+ s.signal.removeEventListener("abort", r), (g = a.signal) == null || g.removeEventListener("abort", r), l = !1;
61
+ }
62
+ },
63
+ dispose() {
64
+ var a;
65
+ u || (u = !0, s.abort(), i.dispose(), e.cleanup(), (a = o.signal) == null || a.removeEventListener("abort", P));
66
+ }
67
+ };
68
+ }
69
+ export {
70
+ C as BASE_PRINT_RULES,
71
+ F as DEFAULT_PRINT_RULES,
72
+ U as DEFAULT_SETTINGS,
73
+ B as IMAGE_PAPERS,
74
+ k as IMAGE_PAPER_SIZES,
75
+ x as MM_PER_PX,
76
+ O as PAPER_PRESETS,
77
+ G as PAPER_SIZES,
78
+ H as PDF_PRINT_ATTRIBUTES,
79
+ W as PDF_PRINT_CLASSES,
80
+ z as PRINT_ATTRIBUTES,
81
+ J as PRINT_CLASSES,
82
+ X as PT_PER_MM,
83
+ Z as PX_PER_MM,
84
+ j as UNIT_FIELDS,
85
+ q as buildPrintRules,
86
+ K as calculateGeometry,
87
+ Q as calculatePagesArray,
88
+ b as checkCancelled,
89
+ V as classifyPrintNode,
90
+ Y as clearPageBreaks,
91
+ $ as cloneWithResolvedStyles,
92
+ ee as configurePrint,
93
+ ae as convertFields,
94
+ te as copyResolvedStyle,
95
+ re as createDeclarativeElement,
96
+ se as createOutputWriter,
97
+ T as createPageCapture,
98
+ ne as createPdfWriter,
99
+ D as createPrintSession,
100
+ oe as createPrintSnapshot,
101
+ ie as createTextMeasurer,
102
+ L as exportPreparedLayout,
103
+ le as formatPageNumber,
104
+ ce as getPresetDimensions,
105
+ ge as getPresetUnit,
106
+ Pe as getPrintRules,
107
+ ue as inspectPrintLayout,
108
+ de as isImagePaper,
109
+ he as isPrintableElement,
110
+ me as measureDocument,
111
+ Ee as measureTextLines,
112
+ fe as mmToPt,
113
+ pe as namespacePreviewHtml,
114
+ we as outputDocument,
115
+ ve as outputPDF,
116
+ Se as paginate,
117
+ be as planDocument,
118
+ R as prepareLayout,
119
+ ye as readRootHeight,
120
+ Re as resetPrintRules,
121
+ Te as resolveAtomicOverflow,
122
+ _e as resolvePaper,
123
+ Le as resolvePrintElement,
124
+ Ae as serializePrintSnapshot,
125
+ Ie as validateOutputFormat,
126
+ De as validatePageBreaks,
127
+ Me as visualizePageBreaks,
128
+ Ne as waitForResources,
129
+ Ce as walkPrintTree
130
+ };
131
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/lib/application/print-session.ts"],"sourcesContent":["import { createPageCapture } from '../adapters/canvas/page-capture';\nimport { composePageCanvas } from '../output/image-writer';\nimport { PrintSettings } from '../core/types';\nimport { checkCancelled } from './cancellation';\nimport { LayoutOptions, prepareLayout } from './print-pipeline';\nimport { DocumentExportOptions, exportPreparedLayout } from './print-service';\n\n/** A frozen document shared by preview, inspection and all output formats. */\nexport async function createPrintSession(options: LayoutOptions) {\n const lifetime = new AbortController();\n const forwardAbort = () => lifetime.abort();\n options.signal?.addEventListener('abort', forwardAbort, { once: true });\n if (options.signal?.aborted) lifetime.abort();\n const started = performance.now();\n let layout;\n try { layout = await prepareLayout({ ...options, signal: lifetime.signal }); }\n catch (error) { options.signal?.removeEventListener('abort', forwardAbort); throw error; }\n const renderer = createPageCapture(layout.width, lifetime.signal);\n const settings: Partial<PrintSettings> | undefined = options.settings ? JSON.parse(JSON.stringify(options.settings)) : undefined;\n let disposed = false;\n let busy = false;\n const assertLive = () => {\n if (disposed) throw new Error('打印会话已关闭,请重新生成预览');\n checkCancelled(lifetime.signal);\n if (busy) throw new Error('正在处理上一项任务,请稍候');\n };\n const preparedMs = performance.now() - started;\n return {\n layout,\n preparedMs,\n async thumbnail(index: number, maxWidth = 480): Promise<string> {\n assertLive();\n if (!Number.isInteger(index) || index < 0 || index >= layout.pages.length) throw new Error('预览页码无效');\n busy = true;\n let sheet: HTMLCanvasElement | undefined;\n let thumb: HTMLCanvasElement | undefined;\n try {\n const page = layout.pages[index];\n const body = await renderer.capture(layout.root, page.start, page.end - page.start);\n try {\n const headerCanvas = layout.header ? await renderer.capture(layout.header, 0, layout.headerHeight / layout.ratio) : undefined;\n const footerCanvas = layout.footer ? await renderer.capture(layout.footer, 0, layout.footerHeight / layout.ratio) : undefined;\n try {\n sheet = composePageCanvas(body, (page.end - page.start) * layout.ratio, index, { geometry: layout, settings, headerCanvas, footerCanvas, totalPages: layout.pages.length });\n } finally { if (headerCanvas) renderer.release(headerCanvas); if (footerCanvas) renderer.release(footerCanvas); }\n } finally { renderer.release(body); }\n thumb = document.createElement('canvas');\n thumb.width = Math.max(1, Math.min(640, maxWidth, sheet.width));\n thumb.height = Math.ceil(sheet.height * thumb.width / sheet.width);\n const ctx = thumb.getContext('2d');\n if (!ctx) throw new Error('浏览器无法生成预览');\n ctx.drawImage(sheet, 0, 0, thumb.width, thumb.height);\n checkCancelled(lifetime.signal);\n return thumb.toDataURL('image/jpeg', 0.85);\n } finally {\n if (sheet) { sheet.width = 0; sheet.height = 0; }\n if (thumb) { thumb.width = 0; thumb.height = 0; }\n busy = false;\n }\n },\n async exportDocument(params: Omit<DocumentExportOptions, 'element' | 'settings'>) {\n assertLive(); busy = true;\n const controller = new AbortController();\n const cancel = () => controller.abort();\n lifetime.signal.addEventListener('abort', cancel, { once: true });\n params.signal?.addEventListener('abort', cancel, { once: true });\n if (params.signal?.aborted || lifetime.signal.aborted) controller.abort();\n try { return await exportPreparedLayout(layout, { ...params, settings, signal: controller.signal }, preparedMs); }\n finally {\n lifetime.signal.removeEventListener('abort', cancel);\n params.signal?.removeEventListener('abort', cancel);\n busy = false;\n }\n },\n dispose() {\n if (disposed) return;\n disposed = true; lifetime.abort(); renderer.dispose(); layout.cleanup();\n options.signal?.removeEventListener('abort', forwardAbort);\n },\n };\n}\nexport type PrintSession = Awaited<ReturnType<typeof createPrintSession>>;\n"],"names":["createPrintSession","options","lifetime","forwardAbort","_a","_b","started","layout","prepareLayout","error","_c","renderer","createPageCapture","settings","disposed","busy","assertLive","checkCancelled","preparedMs","index","maxWidth","sheet","thumb","page","body","headerCanvas","footerCanvas","composePageCanvas","ctx","params","controller","cancel","exportPreparedLayout"],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ "use strict";var Lt=Object.create;var at=Object.defineProperty;var It=Object.getOwnPropertyDescriptor;var _t=Object.getOwnPropertyNames;var Bt=Object.getPrototypeOf,Ft=Object.prototype.hasOwnProperty;var Ut=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of _t(e))!Ft.call(t,n)&&n!==o&&at(t,n,{get:()=>e[n],enumerable:!(r=It(e,n))||r.enumerable});return t};var Ot=(t,e,o)=>(o=t!=null?Lt(Bt(t)):{},Ut(e||!t||!t.__esModule?at(o,"default",{value:t,enumerable:!0}):o,t));const $t=require("html2canvas"),st=72/25.4,v=25.4/96,S=96/25.4,A=t=>Number((t*v).toFixed(4)),U={"card-3x4":{widthPx:1242,heightPx:1656,marginPx:60},"square-1x1":{widthPx:1080,heightPx:1080,marginPx:54},"card-4x5":{widthPx:1080,heightPx:1350,marginPx:54},"story-9x16":{widthPx:1080,heightPx:1920,marginPx:54},"ecom-750x1000":{widthPx:750,heightPx:1e3,marginPx:0}},Dt=Object.keys(U);function ct(t){return t in U}function Ht(t){return ct(t)?"px":"mm"}const X={a4:[210,297],a3:[297,420],a5:[148,210],letter:[215.9,279.4],...Object.fromEntries(Object.entries(U).map(([t,e])=>[t,[A(e.widthPx),A(e.heightPx)]]))},j={a4:{widthMm:210,heightMm:297,marginTopMm:10,marginRightMm:10,marginBottomMm:10,marginLeftMm:10},a3:{widthMm:297,heightMm:420,marginTopMm:10,marginRightMm:10,marginBottomMm:10,marginLeftMm:10},a5:{widthMm:148,heightMm:210,marginTopMm:10,marginRightMm:10,marginBottomMm:10,marginLeftMm:10},letter:{widthMm:215.9,heightMm:279.4,marginTopMm:10,marginRightMm:10,marginBottomMm:10,marginLeftMm:10},custom:{widthMm:210,heightMm:Number((200*v).toFixed(2)),marginTopMm:Number((2*v).toFixed(2)),marginRightMm:Number((2*v).toFixed(2)),marginBottomMm:Number((2*v).toFixed(2)),marginLeftMm:Number((2*v).toFixed(2))},...Object.fromEntries(Object.entries(U).map(([t,e])=>[t,{widthMm:A(e.widthPx),heightMm:A(e.heightPx),marginTopMm:A(e.marginPx),marginRightMm:A(e.marginPx),marginBottomMm:A(e.marginPx),marginLeftMm:A(e.marginPx)}]))},lt={unit:"mm",paper:"a4",widthMm:210,heightMm:297,orientation:"portrait",marginTopMm:10,marginRightMm:10,marginBottomMm:10,marginLeftMm:10,pageNumber:{enabled:!0,position:"bottom-right",format:"slash"}};function Wt(t,e="portrait",o="mm"){const r=j[t]||j.a4;let n,i;if(t==="custom")n=r.widthMm,i=r.heightMm;else{const[u,d]=X[t];n=e==="landscape"?d:u,i=e==="landscape"?u:d}const{marginTopMm:a,marginRightMm:s,marginBottomMm:l,marginLeftMm:c}=r;return o==="px"?t==="custom"?{width:Number((n*S).toFixed(1)),height:200,marginTop:2,marginRight:2,marginBottom:2,marginLeft:2}:{width:Number((n*S).toFixed(1)),height:Number((i*S).toFixed(1)),marginTop:Number((a*S).toFixed(1)),marginRight:Number((s*S).toFixed(1)),marginBottom:Number((l*S).toFixed(1)),marginLeft:Number((c*S).toFixed(1))}:{width:n,height:i,marginTop:a,marginRight:s,marginBottom:l,marginLeft:c}}function T(t){return t*st}function dt(t){const e=t.paper==="custom"?[t.widthMm,t.heightMm]:X[t.paper];if(!e||e.some(s=>!Number.isFinite(s)||s<=0))throw new Error("页面宽高必须是大于零的数值");if(!["portrait","landscape"].includes(t.orientation))throw new Error("纸张方向无效");const o=[t.marginTopMm,t.marginRightMm,t.marginBottomMm,t.marginLeftMm];if(o.some(s=>!Number.isFinite(s)||s<0))throw new Error("页边距必须为非负数");const[r,n]=[...e].sort((s,l)=>s-l),[i,a]=t.paper==="custom"?e:t.orientation==="portrait"?[r,n]:[n,r];if(i-o[1]-o[3]<=0||a-o[0]-o[2]<=0)throw new Error("页边距占满了页面,请减小边距");return{pageWidth:T(i),pageHeight:T(a),left:T(o[3]),right:T(o[1]),top:T(o[0]),bottom:T(o[2]),widthMm:i,heightMm:a}}const ut=["widthMm","heightMm","marginTopMm","marginRightMm","marginBottomMm","marginLeftMm"];function zt(t,e){const o={...t};return ut.forEach(r=>{typeof t[r]=="number"&&(o[r]=t[r]*e)}),o}function pt(t,e,o,r,n=!0){var y;const{pageWidth:i,pageHeight:a}=t;if(!Number.isFinite(e)||e<=0||[o,r].some(E=>E!==void 0&&(!Number.isFinite(E)||E<0)))throw new Error("打印区域或页眉页脚尺寸无效");const s=typeof n=="boolean"?n:n.enabled,l=typeof n=="object"&&((y=n.position)==null?void 0:y.startsWith("top")),c=s&&l?14:0,u=s&&!l?14:0,d=i-t.left-t.right,p=d/e,m=(o||0)*p,h=(r||0)*p,f=t.top+m+(o!==void 0?6:0)+c,w=a-t.bottom-u-h,g=(w-(r!==void 0?6:0)-f)/p;if(g<=0)throw new Error("页眉页脚过高,没有剩余正文空间");return{pageWidth:i,pageHeight:a,contentWidth:d,ratio:p,headerHeight:m,footerHeight:h,bodyTop:f,left:t.left,headerY:t.top,footerY:w,pageNumberY:l?f-5:a-Math.max(6,t.bottom/2),capacity:g}}function mt(t,e,o,r=100){if(![t,e].every(Number.isFinite)||t<=0||e<=0||!Number.isSafeInteger(r)||r<1)throw new Error("打印区域或纸张尺寸无效");const n=[],i=o.map(c=>{if(!Number.isFinite(c.top)||!Number.isFinite(c.bottom)||c.bottom<c.top)throw new Error("分页测量结果无效");return{top:Math.max(0,c.top),bottom:Math.min(t,c.bottom)}}).filter(c=>c.bottom>c.top).sort((c,u)=>c.top-u.top);for(const c of i){if(c.bottom-c.top>e)throw new Error("存在超过单页高度且不可拆分的内容,请缩小图片或调整布局");const u=n[n.length-1];u&&c.top<u.bottom?u.bottom=Math.max(u.bottom,c.bottom):n.push({...c})}if(n.some(c=>c.bottom-c.top>e))throw new Error("重叠的不可拆分内容超过单页高度,无法安全分页");const a=[];let s=0,l=0;for(;s<t;){if(a.length>=r)throw new Error(`文档超过 ${r} 页限制,请拆分导出或增大页面高度`);let c=Math.min(s+e,t);if(c<t){for(;l<n.length&&n[l].bottom<=c;)l++;l<n.length&&n[l].top<c&&(c=n[l].top)}if(c<=s)throw new Error("页面高度不足,无法安全分页,请增大页面高度");a.push({start:s,end:c}),s=c}return a}function ht(t,e,o=.25){const r=t.slice(1).filter(n=>e.some(i=>i.top+o<n.start&&i.bottom-o>n.start));if(r.length)throw new Error(`分页预览与原页面布局不一致:${r.length} 个断点穿过受保护内容,首个位置 ${r[0].start.toFixed(1)}px`)}const Gt=3,jt=1,Vt={ATOMIC:'data-print-atomic="true"',SPLITTABLE:'data-print-splittable="true"',IGNORE:'data-print-ignore="true"',KEEP_TOGETHER:'data-print-keep-together="true"',KEEP_OR_SPLIT:'data-print-keep-together="split"',FORCE_SPLIT:'data-print-break="split"'},Yt={ATOMIC:"print-atomic",SPLITTABLE:"print-splittable",IGNORE:"print-ignore",KEEP_TOGETHER:"print-keep-together",KEEP_OR_SPLIT:"print-keep-or-split",FORCE_SPLIT:"print-force-split"},qt={ATOMIC:'data-pdf-atomic="true"',SPLITTABLE:'data-pdf-splittable="true"',IGNORE:'data-pdf-ignore="true"',KEEP_TOGETHER:'data-pdf-keep-together="true"',KEEP_OR_SPLIT:'data-pdf-keep-together="split"',FORCE_SPLIT:'data-pdf-break="split"'},Kt={ATOMIC:"pdf-atomic",SPLITTABLE:"pdf-splittable",IGNORE:"pdf-ignore",KEEP_TOGETHER:"pdf-keep-together",KEEP_OR_SPLIT:"pdf-keep-or-split",FORCE_SPLIT:"pdf-force-split"},D=[{selector:'script, style, template, [hidden], [data-print-debug], [data-print-ignore="true"], .print-ignore, [data-pdf-debug], [data-pdf-ignore="true"], .pdf-ignore',result:{kind:"ignore"}},{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',result:{kind:"container"}},{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',result:{kind:"atomic",label:"不可分割区域",overflow:"error"}},{selector:'[data-print-keep-together="split"], .print-keep-or-split, [data-pdf-keep-together="split"], .pdf-keep-or-split, tr',result:{kind:"atomic",label:"表格行与复合块",overflow:"split"}},{selector:"img, canvas, svg",result:{kind:"atomic",label:"图片媒体",overflow:"error"}},{selector:"h1, h2, h3, h4, h5, h6",result:{kind:"atomic",label:"标题",overflow:"error"}}],ft=D;function C(t){var n,i,a;if(!t)return[...D];const e=[];(n=t.customRules)!=null&&n.length&&e.push(...t.customRules),(i=t.ignore)!=null&&i.length&&e.push({selector:t.ignore.join(", "),result:{kind:"ignore"}});const o=[...t.splittable||[],...t.forceSplit||[]];o.length&&e.push({selector:o.join(", "),result:{kind:"container"}});const r=[...t.atomic||[],...t.keepTogether||[]];return r.length&&e.push({selector:r.join(", "),result:{kind:"atomic",label:"自定义原子项",overflow:"error"}}),(a=t.keepOrSplit)!=null&&a.length&&e.push({selector:t.keepOrSplit.join(", "),result:{kind:"atomic",label:"可降级拆分区域",overflow:"split"}}),[...e,...D]}let Z=C();function Xt(t){Z=C(t)}function M(){return Z}function Zt(){Z=C()}function N(t,e=M()){var o,r;return t.nodeType===Gt?(o=t.textContent)!=null&&o.trim()?{kind:"text"}:{kind:"ignore"}:t.nodeType!==jt||typeof t.matches!="function"?{kind:"ignore"}:((r=e.find(n=>t.matches(n.selector)))==null?void 0:r.result)||{kind:"container"}}function V(t,e,o,r){if(e<=o)return"protect";if(t.overflow==="split")return"descend";const n=r||t.label;throw new Error(`不可拆分区域「${n}」高 ${Math.ceil(e)}px,超过正文可用高度 ${Math.floor(o)}px,请缩小该区域或增大页面高度`)}function H(t,e){const o=[],r=n=>{for(let i=n.childNodes.length-1;i>=0;i--)o.push(n.childNodes[i])};for(r(t);o.length;){const n=o.pop();e(n)==="descend"&&r(n)}}function Q(t,e=o=>o){const o=new WeakMap,r=document.createRange();let n=0;return i=>{var c,u;if(n+=((c=i.textContent)==null?void 0:c.length)||0,n>2e5)throw new Error("文本超过 200,000 字符限制,请拆分导出");const a=i.parentElement;if(a&&!o.has(a)){const d=((u=a.ownerDocument)==null?void 0:u.defaultView)||window,p=d.getComputedStyle?d.getComputedStyle(a).lineHeight:window.getComputedStyle(a).lineHeight;o.set(a,parseFloat(p))}const s=a?o.get(a):NaN;return r.selectNodeContents(i),(r.getClientRects?Array.from(r.getClientRects()):[]).filter(d=>d.width>0&&d.height>0).map(d=>{const p=Number.isFinite(s)?Math.max(0,s-d.height)/2:0;return{top:e(d.top-t-p),bottom:e(d.bottom-t+p)}})}}function Qt(t){const e=Q(t.getBoundingClientRect().top),o=[];return H(t,r=>{const n=N(r);return n.kind==="ignore"?"skip":n.kind==="text"?(o.push(...e(r)),"skip"):"descend"}),o}function gt(t){const e=Math.max(t.getBoundingClientRect().height,t.scrollHeight);if(e<=0||e>2e5)throw new Error("打印区域为空或超过 200,000px 高度限制");return e}function J(t,e,o=ft){const r=t.getBoundingClientRect(),n=gt(t),i=[],a=Q(r.top),s={visitedNodes:0,atomicElements:0,textNodes:0,textFragments:0},l=N(t,o);if(l.kind==="ignore")throw new Error("打印区域已被 ignore 规则排除,请选择其他区域");if(l.kind==="atomic"&&V(l,n,e,t.getAttribute("data-print-label")||t.getAttribute("data-pdf-label")||t.getAttribute("alt"))==="protect")return{height:n,ranges:[{top:0,bottom:n}],stats:{...s,visitedNodes:1,atomicElements:1}};const c=u=>{const d=Math.max(0,u.top),p=Math.min(n,u.bottom);p>d&&i.push({top:d,bottom:p})};return H(t,u=>{s.visitedNodes++;const d=N(u,o);if(d.kind==="ignore")return"skip";if(d.kind==="container")return"descend";if(d.kind==="text"){const f=a(u);return s.textNodes++,s.textFragments+=f.length,f.forEach(c),"skip"}const p=u,m=p.getBoundingClientRect();if(m.width<=0||m.height<=0)return"skip";const h=p.getAttribute("data-print-label")||p.getAttribute("data-pdf-label")||p.getAttribute("alt");return V(d,m.height,e,h)==="descend"?"descend":(s.atomicElements++,c({top:m.top-r.top,bottom:m.bottom-r.top}),"skip")}),{height:n,ranges:i,stats:s}}function P(t){if(t!=null&&t.aborted)throw new Error("导出已取消")}async function Jt(t){for(let e=0;e<2;e++)P(t),await new Promise(o=>setTimeout(o,16));P(t)}async function tt(t,e,o=M()){P(e);let r,n=()=>{};const i=new Promise((a,s)=>{r=setTimeout(()=>s(new Error("字体或图片加载超时,请稍后重试")),15e3),n=()=>s(new Error("导出已取消")),e==null||e.addEventListener("abort",n,{once:!0})});try{await Promise.race([i,(async()=>{var a;await Promise.all([(a=t.ownerDocument.fonts)==null?void 0:a.ready,...[...t.tagName==="IMG"?[t]:[],...Array.from(t.querySelectorAll("img"))].filter(s=>{for(let l=s;l;l=l.parentElement){if(N(l,o).kind==="ignore")return!1;if(l===t)break}return!0}).map(async s=>{try{await s.decode()}catch{throw new Error(`图片加载失败:${s.alt||"未命名图片"}`)}if(!s.naturalWidth)throw new Error(`图片内容为空:${s.alt||"未命名图片"}`)})]),await Jt(e)})()]),P(e)}finally{clearTimeout(r),e==null||e.removeEventListener("abort",n)}}function bt(t,e){var n;const o=((n=t.ownerDocument)==null?void 0:n.defaultView)||(typeof window<"u"?window:null),r=o!=null&&o.getComputedStyle?o.getComputedStyle(t):null;if(r){for(let i=0;i<r.length;i++){const a=r.item(i);/^(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))}e.style.animation="none",e.style.transition="none"}}function wt(t,e=M()){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("*"))];n.forEach((s,l)=>{const c=i[l];if(!c||c.nodeType!==1)return;if(s!==t&&N(s,e).kind==="ignore"){c.remove();return}for(const d of Array.from(c.attributes))(/^on/i.test(d.name)||d.name==="autofocus")&&c.removeAttribute(d.name);const u=(s.tagName||"").toLowerCase();if(u==="input"){const d=s,p=c;p.value=d.value,p.checked=d.checked}else if(u==="textarea")c.value=s.value;else if(u==="select")c.selectedIndex=s.selectedIndex;else if(u==="canvas"){const d=s,p=c;p.width=d.width,p.height=d.height;try{d.toDataURL();const m=p.getContext("2d");if(!m)throw new Error("canvas context unavailable");m.drawImage(d,0,0)}catch{throw new Error("画布内容无法读取,请检查跨域图片或浏览器的画布支持")}}else if(u==="img"){const d=c;if(d.loading="eager",d.src=s.currentSrc||s.src,d.removeAttribute("srcset"),d.removeAttribute("sizes"),/^https?:/.test(d.src)&&typeof window<"u")try{new URL(d.src).origin!==window.location.origin&&(d.crossOrigin="anonymous")}catch{}}c.style&&bt(s,c)}),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");const a=t.getBoundingClientRect().width;return a>0&&(r.style.width=`${a}px`,r.style.maxWidth="none",r.style.boxSizing="border-box"),r}function Et(t,e=M()){const o=document.createElement("div");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;`,{clone:n=>{const i=wt(n,e);return i.style.width=`${t}px`,i.style.maxWidth="none",i.style.boxSizing="border-box",o.appendChild(i),i},mount:()=>document.body.appendChild(o),ready:n=>tt(o,n),dispose:()=>o.remove()}}function te(t){const e=t.cloneNode(!0);let o=e;const r=[t,...Array.from(t.querySelectorAll("*"))],n=[e,...Array.from(e.querySelectorAll("*"))];return r.forEach((i,a)=>{const s=n[a];for(const l of Array.from(s.attributes))/^on/i.test(l.name)&&s.removeAttribute(l.name);if(i instanceof HTMLCanvasElement){const l=document.createElement("img");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)}else 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);s.matches("a, button, input, textarea, select, [tabindex]")&&s.setAttribute("tabindex","-1")}),o.outerHTML}function ee(t,e){const o=new Map;return t.replace(/\sid="([^"]+)"/g,(r,n)=>(o.set(n,`${e}-${n}`),r)),t.replace(/(\s(?:id|for|href|xlink:href|aria-labelledby|aria-describedby)="|url\(#)([^")]+)("|\))/g,(r,n,i,a)=>{const s=i.startsWith("#"),l=(s?i.slice(1):i).split(" ").map(c=>o.get(c)||c).join(" ");return`${n}${s?"#":""}${l}${a}`})}const re=8e6;function yt(t,e){const o=new Set,r=n=>{n.width=0,n.height=0,o.delete(n)};return{async capture(n,i,a){if(e!=null&&e.aborted)throw new Error("导出已取消");const s=Math.min(2,Math.sqrt(re/(Math.ceil(t)*Math.ceil(a))),8192/t,8192/a);if(!Number.isFinite(s)||s<.5)throw new Error("页面像素超限,请缩小打印区域宽度");const l=await $t(n,{x:0,y:i,width:t,height:a,scale:s,useCORS:!0,allowTaint:!1,backgroundColor:"#ffffff",logging:!1,imageTimeout:15e3,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)});if(o.add(l),e!=null&&e.aborted)throw new Error("导出已取消");if(!l.width||!l.height)throw new Error("截图为空,请检查打印区域");return l},release:r,dispose:()=>o.forEach(r)}}function et(t,e,o){const r=t+1;switch(o){case"chinese":return`第 ${r} 页 / 共 ${e} 页`;case"hyphen":return`- ${r} -`;case"slash":default:return`${r} / ${e}`}}async function Pt({geometry:t,settings:e,headerCanvas:o,footerCanvas:r,totalPages:n}){const{jsPDF:i}=await import("jspdf"),{pageWidth:a,pageHeight:s,contentWidth:l,headerHeight:c,footerHeight:u,left:d,bodyTop:p,headerY:m,footerY:h,pageNumberY:f}=t,w=a>s?"landscape":"portrait",g=new i({unit:"pt",format:[a,s],orientation:w}),y=(e==null?void 0:e.marginRightMm)!==void 0?T(e.marginRightMm):T(10);return{addPageSlice(E,R,x){E>0&&g.addPage(),g.addImage(R,"PNG",d,p,l,x,void 0,"FAST"),o&&g.addImage(o,"PNG",d,m,l,c,"print-header","FAST"),r&&g.addImage(r,"PNG",d,h,l,u,"print-footer","FAST");const b=e==null?void 0:e.pageNumber;if(b?b.enabled:!0){g.setFontSize(9),g.setTextColor(120,120,120);const L=(b==null?void 0:b.position)||"bottom-right",k=et(E,n,b==null?void 0:b.format);let O,$;L==="bottom-center"||L==="top-center"?(O=a/2,$="center"):(O=a-y,$="right");const ot=f;if((b==null?void 0:b.format)==="chinese"){const I=document.createElement("canvas");I.width=640,I.height=48;const B=I.getContext("2d");if(!B)throw new Error("浏览器无法渲染中文页码");B.font="24px sans-serif";const Nt=Math.ceil(B.measureText(k).width);B.fillStyle="#787878",B.fillText(k,0,34);const it=Nt*9/24,Ct=$==="center"?it/2:it;g.addImage(I,"PNG",O-Ct,ot-12.75,240,18),I.width=0,I.height=0}else g.text(k,O,ot,{align:$})}},async finalize(E,R=!0){const x=g.output("blob");return R&&await g.save(`${E.replace(/\.pdf$/i,"")||"document"}.pdf`,{returnPromise:!0}),x}}}function Y(t,e,o){const r=document.createElement("div");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}const z=new WeakSet;function xt({root:t,capacity:e,maxPages:o,rules:r,ruleConfig:n}){const i=performance.now(),a=r||(n?C(n):M()),s=J(t,e,a),l=performance.now();return{pages:mt(s.height,e,s.ranges,o),stats:s.stats,timing:{measurementMs:l-i,paginationMs:performance.now()-l}}}function F(t){var n,i,a;if(!t||typeof t!="object")return!1;const e=t;if(e.nodeType!==1)return!1;const o=(n=e.ownerDocument)==null?void 0:n.defaultView;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}function rt(t){var e,o,r;if(!F(t))return null;if(((e=t.tagName)==null?void 0:e.toLowerCase())==="iframe"){const n=t;let i;try{i=n.contentDocument||((o=n.contentWindow)==null?void 0:o.document)}catch{throw new Error("无法读取跨域 iframe,请在嵌入系统内接入打印工具或使用其导出接口")}if(!(i!=null&&i.body)||i.readyState==="loading"||i.URL==="about:blank"&&n.getAttribute("src"))throw new Error("iframe 内容尚未就绪,请等待加载完成后重试");const a=i.getElementById("iframe-report-content")||i.body;if(!F(a)||!a.childElementCount&&!((r=a.textContent)!=null&&r.trim()))throw new Error("iframe 中没有可打印的业务内容");return a}return t}async function nt(t){var p,m,h,f,w;const{header:e,footer:o,signal:r,orientation:n="portrait"}=t,i=t.maxPages??100,a=rt(t.element);if(!a)throw new Error("找不到有效的打印区域");if(!["portrait","landscape"].includes(n))throw new Error("纸张方向必须为 portrait 或 landscape");const s=dt({...lt,orientation:n,...t.settings||{}});if(z.has(a))throw new Error("该区域正在导出,请勿重复提交");let l=a.getBoundingClientRect().width;if(!Number.isFinite(l)||l<=0)throw new Error("打印区域宽度为零,请先显示内容");P(r),z.add(a);const c=t.rules||(t.ruleConfig?C(t.ruleConfig):M());let u;const d=()=>{u==null||u.dispose(),z.delete(a)};try{if(await tt(a,r,c),l=a.getBoundingClientRect().width,!Number.isFinite(l)||l<=0)throw new Error("打印区域宽度为零,请先显示内容");u=Et(l,c);const g=u.clone(a);let y;if(e&&F(e))y=u.clone(e);else if((m=(p=t.settings)==null?void 0:p.header)!=null&&m.enabled&&t.settings.header.text){const k=Y(t.settings.header,"header",l);y=u.clone(k)}let E;if(o&&F(o))E=u.clone(o);else if((f=(h=t.settings)==null?void 0:h.footer)!=null&&f.enabled&&t.settings.footer.text){const k=Y(t.settings.footer,"footer",l);E=u.clone(k)}u.mount(),await u.ready(r),P(r);const R=((w=t.settings)==null?void 0:w.pageNumber)??!0,x=pt(s,l,y==null?void 0:y.getBoundingClientRect().height,E==null?void 0:E.getBoundingClientRect().height,R),{pages:b,stats:_,timing:L}=xt({root:g,capacity:x.capacity,maxPages:i,rules:c});return{...x,root:g,header:y,footer:E,width:l,pages:b,stats:_,timing:L,cleanup:d}}catch(g){throw d(),g}}const ne=Array.from({length:256},(t,e)=>{let o=e;for(let r=0;r<8;r++)o=o>>>1^3988292384&-(o&1);return o>>>0});function oe(t){if(t.length>65535)throw new Error("图片页数超出 ZIP 限制");const e=[],o=[];let r=0,n=0;for(const{name:s,data:l}of t){const c=Uint8Array.from(s,f=>f.charCodeAt(0));let u=4294967295;for(let f=0;f<l.length;f++)u=u>>>8^ne[(u^l[f])&255];if(u=(u^4294967295)>>>0,r+l.length+c.length+30>4294967295)throw new Error("图片包超过 4GB,请分批导出");const d=new Uint8Array(30+c.length),p=new DataView(d.buffer);p.setUint32(0,67324752,!0),p.setUint16(4,20,!0),p.setUint16(12,33,!0),p.setUint32(14,u,!0),p.setUint32(18,l.length,!0),p.setUint32(22,l.length,!0),p.setUint16(26,c.length,!0),d.set(c,30);const m=new Uint8Array(46+c.length),h=new DataView(m.buffer);h.setUint32(0,33639248,!0),h.setUint16(4,20,!0),h.setUint16(6,20,!0),h.setUint16(14,33,!0),h.setUint32(16,u,!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}if(r+n+22>4294967295)throw new Error("图片包超过 4GB,请分批导出");const i=new Uint8Array(22),a=new DataView(i.buffer);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"})}function ie(t){return new Promise((e,o)=>t.toBlob(r=>r?e(r):o(new Error("图片编码失败,请重试导出")),"image/png"))}function ae(t){return new Promise((e,o)=>{const r=new FileReader;r.onload=()=>e(new Uint8Array(r.result)),r.onerror=()=>o(new Error("图片读取失败,请重试导出")),r.readAsArrayBuffer(t)})}function Tt(t,e,o,{geometry:r,settings:n,headerCanvas:i,footerCanvas:a,totalPages:s}){var d,p,m,h;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);l.width=Math.ceil(r.pageWidth*c),l.height=Math.ceil(r.pageHeight*c);const u=l.getContext("2d");if(!u)throw new Error("浏览器无法生成分页图片");if(u.scale(c,c),u.fillStyle="#fff",u.fillRect(0,0,r.pageWidth,r.pageHeight),u.drawImage(t,r.left,r.bodyTop,r.contentWidth,e),i&&u.drawImage(i,r.left,r.headerY,r.contentWidth,r.headerHeight),a&&u.drawImage(a,r.left,r.footerY,r.contentWidth,r.footerHeight),((d=n==null?void 0:n.pageNumber)==null?void 0:d.enabled)!==!1){const f=(m=(p=n==null?void 0:n.pageNumber)==null?void 0:p.position)==null?void 0:m.endsWith("center");u.font="9px sans-serif",u.fillStyle="#787878",u.textAlign=f?"center":"right",u.fillText(et(o,s,(h=n==null?void 0:n.pageNumber)==null?void 0:h.format),f?r.pageWidth/2:r.pageWidth-T((n==null?void 0:n.marginRightMm)??10),r.pageNumberY)}return l}function se({geometry:t,settings:e,headerCanvas:o,footerCanvas:r,totalPages:n,signal:i}){const a=[];return{async addPageSlice(s,l,c){P(i);const u=Tt(l,c,s,{geometry:t,settings:e,headerCanvas:o,footerCanvas:r,totalPages:n,signal:i});try{const d=await ae(await ie(u));P(i),a.push({name:`page-${String(s+1).padStart(Math.max(3,String(n).length),"0")}.png`,data:d})}finally{u.width=0,u.height=0}},async finalize(s,l=!0){P(i);const c=oe(a);if(P(i),l){const u=URL.createObjectURL(c),d=document.createElement("a");d.href=u,d.download=`${s.replace(/\.(pdf|zip|png)$/i,"")||"document"}-pages.zip`,document.body.appendChild(d);try{d.click()}finally{d.remove(),setTimeout(()=>URL.revokeObjectURL(u),6e4)}}return c},dispose(){a.length=0}}}const Mt={pdf:Pt,png:se};function W(t){if(!Object.prototype.hasOwnProperty.call(Mt,t))throw new Error(`不支持的输出格式:${t}`)}function Rt(t,e){return W(t),Mt[t](e)}async function St({format:t="pdf",filename:e,download:o=!0,onProgress:r,...n}){W(t);const i=performance.now(),a=await nt(n);try{return await At(a,{format:t,filename:e,download:o,onProgress:r,settings:n.settings,signal:n.signal},performance.now()-i)}finally{a.cleanup()}}async function At(t,e,o=0){var f;const{format:r="pdf",filename:n,download:i=!0,onProgress:a}=e;W(r);const s=performance.now(),{root:l,headerHeight:c,footerHeight:u,ratio:d,pages:p}=t;let m,h;try{m=yt(t.width,e.signal);const{capture:w,release:g}=m,y=t.header?await w(t.header,0,c/d):void 0,E=t.footer?await w(t.footer,0,u/d):void 0;h=await Rt(r,{signal:e.signal,geometry:t,settings:e.settings,headerCanvas:y,footerCanvas:E,totalPages:p.length}),a==null||a(0,p.length);for(let x=0;x<p.length;x++){P(e.signal);const b=p[x],_=await w(l,b.start,b.end-b.start);try{await h.addPageSlice(x,_,(b.end-b.start)*d)}finally{g(_)}a==null||a(x+1,p.length),await new Promise(L=>setTimeout(L,0))}P(e.signal);const R=await h.finalize(n,i);return{blob:R,pages:p.length,layoutMs:o,totalMs:performance.now()-s,bytes:R.size}}finally{(f=h==null?void 0:h.dispose)==null||f.call(h),m==null||m.dispose()}}function ce(t){return St({...t,format:"pdf"})}async function kt({contentElement:t,...e}){var i,a;const o=performance.now(),r=rt(t),n=await nt({element:r,...e});try{const s=n.pages.map(d=>d.start),l=e.rules||(e.ruleConfig?C(e.ruleConfig):M()),c=J(n.root,n.capacity,l);ht(n.pages,c.ranges);const u={pageBreaks:s,pages:n.pages,totalHeight:c.height,capacity:n.capacity,protectedRanges:c.ranges,stats:n.stats,timing:{measurementMs:((i=n.timing)==null?void 0:i.measurementMs)??0,paginationMs:((a=n.timing)==null?void 0:a.paginationMs)??0,totalMs:performance.now()-o}};return window.dispatchEvent(new CustomEvent("print-inspection",{detail:u})),window.dispatchEvent(new CustomEvent("pdf-print-inspection",{detail:u})),u}finally{n.cleanup()}}async function le(t){return(await kt(t)).pageBreaks}const q=new Map;function vt(t){(t||document).querySelectorAll("[data-print-debug]").forEach(o=>o.remove());for(const[o,r]of Array.from(q))(!t||t===o||t.nodeType===9&&o.ownerDocument===t)&&(r(),q.delete(o))}function de(t,e,o=M()){var c;vt(e);const r={atomic:0,splittable:0,ignore:0},n=((c=e.ownerDocument)==null?void 0:c.defaultView)||(typeof window<"u"?window:null),i=n!=null&&n.getComputedStyle?n.getComputedStyle(e):null;if(i&&i.position==="static"){const u=e.style.getPropertyValue("position"),d=e.style.getPropertyPriority("position");e.style.position="relative",q.set(e,()=>{u?e.style.setProperty("position",u,d):e.style.removeProperty("position")})}const a=e.getBoundingClientRect(),s=i&&parseFloat(i.borderTopWidth)||0,l=i&&parseFloat(i.borderLeftWidth)||0;return H(e,u=>{if(u.nodeType!==1)return"skip";const d=u;if(d.hasAttribute("data-print-debug"))return"skip";const p=N(d,o);if(p.kind==="ignore"){r.ignore++;const w=d.getBoundingClientRect();return w.width>0&&w.height>0&&e.appendChild(G({left:w.left-a.left-l,top:w.top-a.top-s,width:w.width,height:w.height,borderColor:"#94a3b8",borderStyle:"dashed",backgroundColor:"rgba(148, 163, 184, 0.08)",badgeText:"ignore",badgeBg:"#64748b",badgePosition:"left"})),"skip"}const m=d.getBoundingClientRect();if(m.width<=0||m.height<=0)return"skip";if(p.kind==="atomic")return r.atomic++,e.appendChild(G({left:m.left-a.left-l,top:m.top-a.top-s,width:m.width,height:m.height,borderColor:"#ef4444",borderStyle:"solid",backgroundColor:"rgba(239, 68, 68, 0.05)",badgeText:"atomic",badgeBg:"#ef4444",badgePosition:"right"})),"skip";if(he(d,n))return"skip";const h=d.matches(ue),f=me(d);return h||f?(r.splittable++,e.appendChild(G({left:m.left-a.left-l,top:m.top-a.top-s,width:m.width,height:m.height,borderColor:"#3b82f6",borderStyle:"dashed",backgroundColor:"rgba(59, 130, 246, 0.04)",badgeText:"splittable",badgeBg:"#3b82f6",badgePosition:"right"})),h?"descend":"skip"):"descend"}),t.slice(1).forEach((u,d)=>{const p=u-s,m=e.ownerDocument.createElement("div");m.setAttribute("data-print-debug","true"),m.style.cssText=`
2
+ position: absolute;
3
+ left: 0;
4
+ top: ${p}px;
5
+ width: 100%;
6
+ height: 0;
7
+ border-top: 2px dashed #7c3aed;
8
+ z-index: ${K.line};
9
+ pointer-events: none;
10
+ box-sizing: border-box;
11
+ `;const h=e.ownerDocument.createElement("span");h.textContent=`✂️ page-break: ${Math.round(u)}px (p.${d+1} ➔ p.${d+2})`,h.style.cssText=`
12
+ position: absolute;
13
+ right: 16px;
14
+ top: -11px;
15
+ background: #7c3aed;
16
+ color: #fff;
17
+ font-size: 11px;
18
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
19
+ line-height: 1;
20
+ padding: 3px 8px;
21
+ border-radius: 10px;
22
+ font-weight: 600;
23
+ letter-spacing: 0.2px;
24
+ box-shadow: 0 1px 4px rgba(124, 58, 237, 0.35);
25
+ white-space: nowrap;
26
+ `,m.appendChild(h),e.appendChild(m)}),r}const ue='[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',K={box:2,badge:3,line:4},pe=new Set(["SPAN","B","STRONG","EM","I","CODE","A","SMALL","SUP","SUB","MARK","ABBR","CITE","Q","TIME","U","S","KBD","SAMP","VAR","BR"]);function me(t){var e;for(let o=0;o<t.childNodes.length;o++){const r=t.childNodes[o];if(r.nodeType===3&&((e=r.textContent)!=null&&e.trim()))return!0}return!1}function he(t,e){return pe.has(t.tagName)?!0:e!=null&&e.getComputedStyle?e.getComputedStyle(t).display.startsWith("inline"):!1}function G(t){const e=document.createElement("div");e.setAttribute("data-print-debug","true"),e.style.cssText=`
27
+ position: absolute;
28
+ left: ${t.left}px;
29
+ top: ${t.top}px;
30
+ width: ${t.width}px;
31
+ height: ${t.height}px;
32
+ border: 1.5px ${t.borderStyle} ${t.borderColor};
33
+ background: ${t.backgroundColor};
34
+ box-sizing: border-box;
35
+ z-index: ${K.box};
36
+ pointer-events: none;
37
+ border-radius: 2px;
38
+ `;const o=document.createElement("span");o.textContent=t.badgeText;const r=t.badgePosition==="right",n="2px",i=r?"right: 4px;":"left: 4px;";return o.style.cssText=`
39
+ position: absolute;
40
+ ${i}
41
+ top: ${n};
42
+ background: ${t.badgeBg};
43
+ color: #ffffff;
44
+ font-size: 9px;
45
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
46
+ font-weight: 600;
47
+ line-height: 1;
48
+ padding: 1.5px 5px;
49
+ border-radius: 3px;
50
+ white-space: nowrap;
51
+ box-shadow: 0 1px 2px rgba(0,0,0,0.18);
52
+ z-index: ${K.badge};
53
+ opacity: 0.95;
54
+ letter-spacing: 0.2px;
55
+ `,e.appendChild(o),e}exports.BASE_PRINT_RULES=D;exports.DEFAULT_PRINT_RULES=ft;exports.DEFAULT_SETTINGS=lt;exports.IMAGE_PAPERS=Dt;exports.IMAGE_PAPER_SIZES=U;exports.MM_PER_PX=v;exports.PAPER_PRESETS=j;exports.PAPER_SIZES=X;exports.PDF_PRINT_ATTRIBUTES=qt;exports.PDF_PRINT_CLASSES=Kt;exports.PRINT_ATTRIBUTES=Vt;exports.PRINT_CLASSES=Yt;exports.PT_PER_MM=st;exports.PX_PER_MM=S;exports.UNIT_FIELDS=ut;exports.buildPrintRules=C;exports.calculateGeometry=pt;exports.calculatePagesArray=le;exports.checkCancelled=P;exports.classifyPrintNode=N;exports.clearPageBreaks=vt;exports.cloneWithResolvedStyles=wt;exports.composePageCanvas=Tt;exports.configurePrint=Xt;exports.convertFields=zt;exports.copyResolvedStyle=bt;exports.createDeclarativeElement=Y;exports.createOutputWriter=Rt;exports.createPageCapture=yt;exports.createPdfWriter=Pt;exports.createPrintSnapshot=Et;exports.createTextMeasurer=Q;exports.exportPreparedLayout=At;exports.formatPageNumber=et;exports.getPresetDimensions=Wt;exports.getPresetUnit=Ht;exports.getPrintRules=M;exports.inspectPrintLayout=kt;exports.isImagePaper=ct;exports.isPrintableElement=F;exports.measureDocument=J;exports.measureTextLines=Qt;exports.mmToPt=T;exports.namespacePreviewHtml=ee;exports.outputDocument=St;exports.outputPDF=ce;exports.paginate=mt;exports.planDocument=xt;exports.prepareLayout=nt;exports.readRootHeight=gt;exports.resetPrintRules=Zt;exports.resolveAtomicOverflow=V;exports.resolvePaper=dt;exports.resolvePrintElement=rt;exports.serializePrintSnapshot=te;exports.validateOutputFormat=W;exports.validatePageBreaks=ht;exports.visualizePageBreaks=de;exports.waitForResources=tt;exports.walkPrintTree=H;
56
+ //# sourceMappingURL=page-break-overlay-50796a2a.js.map