@agile-team/mach-report 2.2.0 → 2.3.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.
- package/README.md +54 -10
- package/dist/ReportPreview-B-mwUSk9.cjs +6 -0
- package/dist/ReportPreview-DKjr4cwO.js +1688 -0
- package/dist/defaults-D4o0NCLo.js +9 -0
- package/dist/defaults-DOO1yHwx.cjs +1 -0
- package/dist/grid-geometry-Dw7BlENr.js +130 -0
- package/dist/grid-geometry-bkciiZ4Q.cjs +1 -0
- package/dist/index.cjs +6 -6
- package/dist/index.d.cts +37 -5
- package/dist/index.d.ts +37 -5
- package/dist/index.js +1163 -1037
- package/dist/pdf.cjs +48 -48
- package/dist/pdf.d.cts +18 -0
- package/dist/pdf.d.ts +18 -0
- package/dist/pdf.js +5605 -5575
- package/dist/{plugin-BMoMUxrw.cjs → plugin-2lqgTX26.cjs} +1 -1
- package/dist/{plugin-CAcNe0FT.js → plugin-5R00MJQs.js} +1 -1
- package/dist/render-plan-CfJ3wf1l.cjs +1 -0
- package/dist/render-plan-I9AHvQv7.js +13 -0
- package/dist/sql.cjs +42 -42
- package/dist/sql.js +1366 -1363
- package/dist/style.css +1 -1
- package/dist/textwrap-nH0UYU6D.js +108 -0
- package/dist/textwrap-oD-t4b4B.cjs +4 -0
- package/dist/vue/async.d.cts +33 -7
- package/dist/vue/async.d.ts +33 -7
- package/dist/vue/index.d.cts +36 -10
- package/dist/vue/index.d.ts +36 -10
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +3 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +4 -4
- package/dist/xlsx.cjs +24 -24
- package/dist/xlsx.d.cts +24 -4
- package/dist/xlsx.d.ts +24 -4
- package/dist/xlsx.js +8287 -8166
- package/package.json +1 -1
- package/dist/ReportPreview-BWrQCj9M.js +0 -1643
- package/dist/ReportPreview-DY0PGGqF.cjs +0 -6
- package/dist/grid-geometry-DBH9ExuY.cjs +0 -1
- package/dist/grid-geometry-DONcjshk.js +0 -130
- package/dist/textwrap-DdaewxAd.js +0 -117
- package/dist/textwrap-DqiFwAV3.cjs +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const T="#333333",E="#000000",_="1.0.0-mach";exports.DEFAULT_BORDER_PT=.75;exports.DEFAULT_FONT_PT=10.5;exports.DEFAULT_STROKE_COLOR=T;exports.DEFAULT_TEXT_COLOR=E;exports.LINE_HEIGHT=1.35;exports.SCHEMA_VERSION_MACH=_;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { D as F, c as O, a as B, L as H, b as $ } from "./defaults-D4o0NCLo.js";
|
|
2
|
+
const k = 25.4, M = 96;
|
|
3
|
+
function R(t = M) {
|
|
4
|
+
return t / k;
|
|
5
|
+
}
|
|
6
|
+
function K(t, o = M) {
|
|
7
|
+
return (t || 0) * R(o);
|
|
8
|
+
}
|
|
9
|
+
function N(t, o = M) {
|
|
10
|
+
return t / R(o);
|
|
11
|
+
}
|
|
12
|
+
function I(t, o = M) {
|
|
13
|
+
return t * o / 72;
|
|
14
|
+
}
|
|
15
|
+
function W(t, o) {
|
|
16
|
+
const s = 10 ** o;
|
|
17
|
+
return Math.round(t * s) / s;
|
|
18
|
+
}
|
|
19
|
+
const G = {
|
|
20
|
+
a3: { widthMm: 297, heightMm: 420 },
|
|
21
|
+
a4: { widthMm: 210, heightMm: 297 },
|
|
22
|
+
a5: { widthMm: 148, heightMm: 210 },
|
|
23
|
+
b4: { widthMm: 250, heightMm: 353 },
|
|
24
|
+
b5: { widthMm: 176, heightMm: 250 }
|
|
25
|
+
};
|
|
26
|
+
function X(t, o = 96, s = F) {
|
|
27
|
+
if (t?.fontSizePx != null)
|
|
28
|
+
return { fontSizePt: t.fontSizePx * 72 / o, fontSizePx: t.fontSizePx };
|
|
29
|
+
const c = t?.fontSize ?? s;
|
|
30
|
+
return { fontSizePt: c, fontSizePx: I(c, o) };
|
|
31
|
+
}
|
|
32
|
+
function Z(t, o = O) {
|
|
33
|
+
return {
|
|
34
|
+
color: t?.borderColor ?? t?.lineColor ?? o,
|
|
35
|
+
widthPt: t?.lineWidthPt ?? $
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function j(t, o = B) {
|
|
39
|
+
return t?.color ?? o;
|
|
40
|
+
}
|
|
41
|
+
function q(t) {
|
|
42
|
+
return t?.lineHeight ?? H;
|
|
43
|
+
}
|
|
44
|
+
function J(t) {
|
|
45
|
+
const o = t?.borderTop !== !1, s = t?.borderRight !== !1, c = t?.borderBottom !== !1, i = t?.borderLeft !== !1;
|
|
46
|
+
return { top: o, right: s, bottom: c, left: i, inner: o || s || c || i };
|
|
47
|
+
}
|
|
48
|
+
function Q(t, o) {
|
|
49
|
+
const s = { ...t, ...o };
|
|
50
|
+
return o?.fontSize != null && o.fontSizePx == null && delete s.fontSizePx, o?.fontSizePx != null && o.fontSize == null && delete s.fontSize, s;
|
|
51
|
+
}
|
|
52
|
+
function U(t, o) {
|
|
53
|
+
const s = t.length;
|
|
54
|
+
if (s === 0) return [];
|
|
55
|
+
const c = t.reduce((l, f) => l + f, 0), i = c > 0 && o > 0 ? o / c : 1, a = [];
|
|
56
|
+
let m = 0;
|
|
57
|
+
for (let l = 0; l < s; l++) {
|
|
58
|
+
const f = Math.max(0, t[l] * i);
|
|
59
|
+
a.push({ pos: m, size: f }), m += f;
|
|
60
|
+
}
|
|
61
|
+
return a;
|
|
62
|
+
}
|
|
63
|
+
function L(t, o, s) {
|
|
64
|
+
return t?.length ? U(t, o) : Array.from({ length: s }, (c, i) => ({
|
|
65
|
+
pos: o * i / s,
|
|
66
|
+
size: o / s
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
function V(t, o, s) {
|
|
70
|
+
const c = t.cells ?? [], i = Math.max(c.length, 1), a = t.colWidthsMm?.length ?? Math.max(1, ...c.map((n) => Array.isArray(n) ? n.length : 0)), m = L(t.colWidthsMm, o, a), l = (n) => n <= 0 ? 0 : n >= a ? m[m.length - 1].pos + m[m.length - 1].size : m[n].pos, f = L(t.rowHeightsMm, s, i), S = (n) => n <= 0 ? 0 : n >= i ? f[f.length - 1].pos + f[f.length - 1].size : f[n].pos, x = /* @__PURE__ */ new Set(), w = (n, r) => `${n}:${r}`, T = [], z = /* @__PURE__ */ new Set(), E = /* @__PURE__ */ new Set(), _ = (n, r) => `v${n}:${r}`, b = (n, r) => `h${n}:${r}`;
|
|
71
|
+
c.forEach((n, r) => {
|
|
72
|
+
if (!Array.isArray(n)) return;
|
|
73
|
+
let e = 0;
|
|
74
|
+
for (const d of n) {
|
|
75
|
+
for (; e < a && x.has(w(r, e)); ) e++;
|
|
76
|
+
if (e >= a) break;
|
|
77
|
+
const v = Math.max(1, Math.min(d?.colSpan ?? 1, a - e)), D = Math.max(1, d?.rowSpan ?? 1), g = Math.min(i, r + D), p = Math.min(a, e + v);
|
|
78
|
+
for (let h = r; h < g; h++)
|
|
79
|
+
for (let u = e; u < p; u++)
|
|
80
|
+
x.add(w(h, u));
|
|
81
|
+
for (let h = e + 1; h < p; h++)
|
|
82
|
+
for (let u = r; u < g; u++) z.add(_(h, u));
|
|
83
|
+
for (let h = r + 1; h < g; h++)
|
|
84
|
+
for (let u = e; u < p; u++) E.add(b(h, u));
|
|
85
|
+
const A = l(e), C = S(r);
|
|
86
|
+
T.push({
|
|
87
|
+
ri: r,
|
|
88
|
+
ci: e,
|
|
89
|
+
cell: d ?? {},
|
|
90
|
+
xMm: A,
|
|
91
|
+
yMm: C,
|
|
92
|
+
widthMm: l(p) - A,
|
|
93
|
+
heightMm: S(g) - C
|
|
94
|
+
}), e = p;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
const P = [];
|
|
98
|
+
for (let n = 1; n < a; n++) {
|
|
99
|
+
let r = -1;
|
|
100
|
+
for (let e = 0; e <= i; e++) {
|
|
101
|
+
const d = e < i && !z.has(_(n, e));
|
|
102
|
+
d && r < 0 && (r = e), !d && r >= 0 && (P.push({ kind: "v", pos: l(n), from: S(r), to: S(e) }), r = -1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
for (let n = 1; n < i; n++) {
|
|
106
|
+
let r = -1;
|
|
107
|
+
for (let e = 0; e <= a; e++) {
|
|
108
|
+
const d = e < a && !E.has(b(n, e));
|
|
109
|
+
d && r < 0 && (r = e), !d && r >= 0 && (P.push({ kind: "h", pos: S(n), from: l(r), to: l(e) }), r = -1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { columns: m, rows: f, cells: T, edges: P };
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
M as C,
|
|
116
|
+
k as M,
|
|
117
|
+
G as P,
|
|
118
|
+
W as a,
|
|
119
|
+
q as b,
|
|
120
|
+
Z as c,
|
|
121
|
+
J as d,
|
|
122
|
+
V as e,
|
|
123
|
+
K as f,
|
|
124
|
+
j as g,
|
|
125
|
+
R as h,
|
|
126
|
+
N as i,
|
|
127
|
+
Q as m,
|
|
128
|
+
I as p,
|
|
129
|
+
X as r
|
|
130
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const p=require("./defaults-DOO1yHwx.cjs"),F=25.4,x=96;function T(t=x){return t/F}function D(t,o=x){return(t||0)*T(o)}function O(t,o=x){return t/T(o)}function B(t,o=x){return t*o/72}function k(t,o){const s=10**o;return Math.round(t*s)/s}const $={a3:{widthMm:297,heightMm:420},a4:{widthMm:210,heightMm:297},a5:{widthMm:148,heightMm:210},b4:{widthMm:250,heightMm:353},b5:{widthMm:176,heightMm:250}};function y(t,o=96,s=p.DEFAULT_FONT_PT){if(t?.fontSizePx!=null)return{fontSizePt:t.fontSizePx*72/o,fontSizePx:t.fontSizePx};const c=t?.fontSize??s;return{fontSizePt:c,fontSizePx:B(c,o)}}function N(t,o=p.DEFAULT_STROKE_COLOR){return{color:t?.borderColor??t?.lineColor??o,widthPt:t?.lineWidthPt??p.DEFAULT_BORDER_PT}}function U(t,o=p.DEFAULT_TEXT_COLOR){return t?.color??o}function G(t){return t?.lineHeight??p.LINE_HEIGHT}function K(t){const o=t?.borderTop!==!1,s=t?.borderRight!==!1,c=t?.borderBottom!==!1,l=t?.borderLeft!==!1;return{top:o,right:s,bottom:c,left:l,inner:o||s||c||l}}function W(t,o){const s={...t,...o};return o?.fontSize!=null&&o.fontSizePx==null&&delete s.fontSizePx,o?.fontSizePx!=null&&o.fontSize==null&&delete s.fontSize,s}function Z(t,o){const s=t.length;if(s===0)return[];const c=t.reduce((f,h)=>f+h,0),l=c>0&&o>0?o/c:1,i=[];let m=0;for(let f=0;f<s;f++){const h=Math.max(0,t[f]*l);i.push({pos:m,size:h}),m+=h}return i}function b(t,o,s){return t?.length?Z(t,o):Array.from({length:s},(c,l)=>({pos:o*l/s,size:o/s}))}function q(t,o,s){const c=t.cells??[],l=Math.max(c.length,1),i=t.colWidthsMm?.length??Math.max(1,...c.map(n=>Array.isArray(n)?n.length:0)),m=b(t.colWidthsMm,o,i),f=n=>n<=0?0:n>=i?m[m.length-1].pos+m[m.length-1].size:m[n].pos,h=b(t.rowHeightsMm,s,l),d=n=>n<=0?0:n>=l?h[h.length-1].pos+h[h.length-1].size:h[n].pos,w=new Set,E=(n,r)=>`${n}:${r}`,_=[],z=new Set,C=new Set,v=(n,r)=>`v${n}:${r}`,A=(n,r)=>`h${n}:${r}`;c.forEach((n,r)=>{if(!Array.isArray(n))return;let e=0;for(const S of n){for(;e<i&&w.has(E(r,e));)e++;if(e>=i)break;const H=Math.max(1,Math.min(S?.colSpan??1,i-e)),I=Math.max(1,S?.rowSpan??1),g=Math.min(l,r+I),P=Math.min(i,e+H);for(let u=r;u<g;u++)for(let a=e;a<P;a++)w.add(E(u,a));for(let u=e+1;u<P;u++)for(let a=r;a<g;a++)z.add(v(u,a));for(let u=r+1;u<g;u++)for(let a=e;a<P;a++)C.add(A(u,a));const L=f(e),R=d(r);_.push({ri:r,ci:e,cell:S??{},xMm:L,yMm:R,widthMm:f(P)-L,heightMm:d(g)-R}),e=P}});const M=[];for(let n=1;n<i;n++){let r=-1;for(let e=0;e<=l;e++){const S=e<l&&!z.has(v(n,e));S&&r<0&&(r=e),!S&&r>=0&&(M.push({kind:"v",pos:f(n),from:d(r),to:d(e)}),r=-1)}}for(let n=1;n<l;n++){let r=-1;for(let e=0;e<=i;e++){const S=e<i&&!C.has(A(n,e));S&&r<0&&(r=e),!S&&r>=0&&(M.push({kind:"h",pos:d(n),from:f(r),to:f(e)}),r=-1)}}return{columns:m,rows:h,cells:_,edges:M}}exports.CSS_DPI=x;exports.MM_PER_INCH=F;exports.PAPER_SIZES=$;exports.mergeComponentStyles=W;exports.mmToPx=D;exports.mmToPxFactor=T;exports.ptToPx=B;exports.pxToMm=O;exports.resolveBoxBorders=K;exports.resolveFontSize=y;exports.resolveGridLayout=q;exports.resolveLineHeight=G;exports.resolveStroke=N;exports.resolveTextColor=U;exports.round=k;
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("./grid-geometry-DBH9ExuY.cjs"),x=require("./textwrap-DqiFwAV3.cjs"),Qe=require("./page-window-index-DEjnM6IB.cjs"),et=require("./report-params-D1gZ1DME.cjs");function ye(e){if(!e||e.kind==="date")return;const t=e.digits;if(!(t!==void 0&&(!Number.isInteger(t)||t<0||t>100))){if(e.kind==="percent"){const n=t??2;return`0${n?`.${"0".repeat(n)}`:""}%`}return t===void 0?e.thousands?"#,##0.###############":void 0:`${e.thousands?"#,##0":"0"}${t?`.${"0".repeat(t)}`:""}`}}function Oe(e){const t=/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/.exec(e.trim());if(t){const r=new Date(Number(t[1]),Number(t[2])-1,Number(t[3]));return Number.isNaN(r.getTime())?null:r}const n=new Date(e);return Number.isNaN(n.getTime())?null:n}function pe(e,t){return e.toLocaleString("en-US",{minimumFractionDigits:t,maximumFractionDigits:t})}function tt(e,t){const n=r=>String(r).padStart(2,"0");return t.replace(/YYYY/g,String(e.getFullYear())).replace(/MM/g,n(e.getMonth()+1)).replace(/DD/g,n(e.getDate())).replace(/hh/g,n(e.getHours())).replace(/mm/g,n(e.getMinutes())).replace(/ss/g,n(e.getSeconds()))}function nt(e,t,n){return n!=null?t?pe(e,n):e.toFixed(n):t?pe(e):String(e)}function de(e){const t=typeof e=="number"?e:Number(String(e).replace(/,/g,""));return Number.isFinite(t)?t:null}function Me(e,t){if(e==null||e===""||!t)return String(e??"");switch(t.kind){case"number":{const n=de(e);return n==null?String(e):nt(n,t.thousands===!0,t.digits)}case"percent":{const n=de(e);return n==null?String(e):`${pe(n*100,t.digits??2)}%`}case"date":{const n=t.pattern??"YYYY-MM-DD",r=e instanceof Date?e:Oe(String(e));return r?tt(r,n):String(e)}default:return String(e)}}function Fe(e,t){const n=e[t.field];if(n==null||n==="")return!1;if(typeof t.value=="number"){const s=de(n);if(s==null)return!1;switch(t.op){case">":return s>t.value;case">=":return s>=t.value;case"<":return s<t.value;case"<=":return s<=t.value;case"==":return s===t.value;case"!=":return s!==t.value}}const r=String(n),o=String(t.value);switch(t.op){case"==":return r===o;case"!=":return r!==o;case">":return r>o;case">=":return r>=o;case"<":return r<o;case"<=":return r<=o}return!1}const rt=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function K(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ot(e,t,n,r){const o=e[t];(typeof o!="number"||!Number.isFinite(o))&&r.push({path:`${n}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(o)}`})}function he(e,t,n,r=[]){if(!K(e)){n.push({path:t,message:"组件应为对象"});return}const o=e.kind;typeof o!="string"?n.push({path:`${t}.kind`,message:"组件缺少 kind 字符串"}):rt.has(o)||r.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(o)},将以兜底方式渲染`});for(const a of["leftMm","topMm","widthMm","heightMm"])ot(e,a,t,n);typeof e.leftMm=="number"&&e.leftMm<-100&&n.push({path:`${t}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const a of["widthMm","heightMm"])typeof e[a]=="number"&&e[a]<0&&n.push({path:`${t}.${a}`,message:"组件尺寸不能为负数"});const s=e.grid;s!==void 0&&(!K(s)||!Array.isArray(s.cells)?n.push({path:`${t}.grid.cells`,message:"grid.cells 应为二维数组"}):s.cells.forEach((a,l)=>{if(!Array.isArray(a)){n.push({path:`${t}.grid.cells.${l}`,message:"行应为数组"});return}a.forEach((c,f)=>{c!=null&&K(c)&&Array.isArray(c.children)&&c.children.forEach((h,m)=>{he(h,`${t}.grid.cells.${l}.${f}.children.${m}`,n,r)})})}));const i=e.richParagraphs;i!==void 0&&(Array.isArray(i)?i.forEach((a,l)=>{(!K(a)||!Array.isArray(a.segments))&&n.push({path:`${t}.richParagraphs.${l}`,message:"段落缺少 segments 数组"})}):n.push({path:`${t}.richParagraphs`,message:"richParagraphs 应为数组"}))}function Be(e,t,n,r=[]){if(!K(e)){n.push({path:t,message:"页应为对象"});return}const o=e.pageWidthMm,s=e.pageHeightMm;(typeof o!="number"||!(o>0&&o<3e3))&&n.push({path:`${t}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(o)}`}),(typeof s!="number"||!(s>0&&s<5e3))&&n.push({path:`${t}.pageHeightMm`,message:`页高非法: ${JSON.stringify(s)}`});const i=e.components;Array.isArray(i)?Array.isArray(i)&&i.forEach((a,l)=>he(a,`${t}.components.${l}`,n,r)):n.push({path:`${t}.components`,message:"components 应为数组"})}function be(e){const t=[],n=[],r=K(e)?e.pages:void 0;if(!Array.isArray(r))t.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{r.forEach((s,i)=>Be(s,`$.pages.${i}`,t,n)),r.length>2e3&&n.push({path:"$.pages",message:`页数异常大(${r.length} 页),渲染与打印耗时可能显著增加`});const o=r.reduce((s,i)=>s+(K(i)&&Array.isArray(i.components)?i.components.length:0),0);o>5e4&&n.push({path:"$.pages",message:`组件总数异常大(${o} 个),可能触发浏览器性能限制`})}return{ok:t.length===0,errors:t,warnings:n}}function it(e){const t=be(e);if(!t.ok){const n=t.errors.slice(0,3).map(r=>`${r.path}: ${r.message}`).join("; ");throw new Error(`渲染计划校验失败(${t.errors.length} 处): ${n}`)}return e.pages}function Re(e){return{widthMm:e.widthMm,heightMm:e.heightMm,marginTopMm:e.marginTopMm??0,marginBottomMm:e.marginBottomMm??0,marginLeftMm:e.marginLeftMm??0,marginRightMm:e.marginRightMm??0,components:[]}}function st(e,t){return t.heightMm-(e.marginBottomMm??t.marginBottomMm)}function Le(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number")return String(e);if(typeof e=="boolean")return e?"是":"否";if(e instanceof Date)return e.toISOString().slice(0,10);try{return JSON.stringify(e)}catch{return String(e)}}function Ie(e,t){let n=e.textMetrics.get(t);if(!n){const r=g.resolveFontSize(t).fontSizePt;n={measureOptions:{fontSizePt:r,bold:t.bold,letterSpacingPt:t.letterSpacing===void 0?void 0:t.letterSpacing*72/96},lineMm:r*(t.lineHeight??g.LINE_HEIGHT)*25.4/72},e.textMetrics.set(t,n)}return n}function De(e,t){return t?.kind==="number"||t?.kind==="percent"?"right":t?.kind==="date"||e instanceof Date||typeof e=="boolean"?"center":typeof e=="number"&&Number.isFinite(e)?"right":"left"}function at(e){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e}function lt(e,t){const n=e.fontSizePt??g.DEFAULT_FONT_PT,r=e.paddingMm??1,o=e.columns.map(d=>d.align??d.style?.align??e.align??"left"),s=e.columns.map((d,p)=>({fontSize:n,verticalAlign:"middle",...d.style,align:o[p]==="auto"?"left":o[p]})),i=s.map((d,p)=>o[p]==="auto"?{left:d,center:{...d,align:"center"},right:{...d,align:"right"}}:void 0),a=e.columns.map((d,p)=>d.rules?.map(S=>{const T=i[p];if(T)return{left:{...T.left,...S.style},center:{...T.center,...S.style},right:{...T.right,...S.style}};const u={...s[p],...S.style};return{left:u,center:u,right:u}})),l=e.columns.map(d=>({fontSize:n,bold:e.headerBold??!0,align:"center",verticalAlign:"middle",backgroundColor:e.headerBackgroundColor,...d.style||{},...e.headerAlign===void 0?{}:{align:e.headerAlign},...e.headerStyle,...d.headerAlign===void 0?{}:{align:d.headerAlign},...d.headerStyle})),c=e.columns.map(d=>d.header);let f=e.rowHeightMm??0;for(let d=0;d<c.length;d++){const p=l[d],S=g.resolveFontSize(p).fontSizePt,T=x.wrapText(c[d],e.columns[d].widthMm-r*2,{fontSizePt:S,bold:p.bold},t),u=S*(p.lineHeight??g.LINE_HEIGHT)*25.4/72;f=Math.max(f,Math.max(T.length,1)*u+r*2)}const h=c.map((d,p)=>({text:d,style:l[p]})),m=e.border===!1?{borderTop:!1,borderRight:!1,borderBottom:!1,borderLeft:!1}:{borderBottom:!0,borderLeft:!0,borderRight:!0,borderTop:!0},w=e.columns.map(d=>d.widthMm);return{fontSizePt:n,paddingMm:r,cellStyles:s,autoStyles:i,ruleStyles:a,textMetrics:new WeakMap,numberFormats:e.columns.map(d=>ye(d.format)),borderStyle:m,headerHeightMm:f,headerGrid:{cells:[h],colWidthsMm:w,rowHeightsMm:[f]},colWidthsMm:w,columns:e.columns}}function Ce(e,t,n){const r=e.columns;let o=e.rowHeightFloorMm;const s=new Array(r.length);for(let i=0;i<r.length;i++){const a=r[i],l=t[a.field],c=e.autoStyles[i]?De(l,a.format):"left";let f=e.autoStyles[i]?.[c]??e.cellStyles[i];if(a.rules)for(let S=0;S<a.rules.length;S++){const T=a.rules[S];if(Fe(t,T.when)){f=e.ruleStyles[i][S][c];break}}const h=a.format?Me(l,a.format):Le(l),m=Ie(e,f),w=x.wrapText(h,a.widthMm-e.paddingMm*2,m.measureOptions,n);o=Math.max(o,w.length*m.lineMm+e.paddingMm*2);const d=at(l),p={text:h,style:f};d!==void 0&&(p.value=d),typeof d=="number"&&e.numberFormats[i]!==void 0&&(p.numberFormat=e.numberFormats[i]),s[i]=p}return{grid:{cells:[s],colWidthsMm:e.colWidthsMm,rowHeightsMm:[o]},heightMm:o}}function ze(e,t,n={}){const r=typeof n=="number"?{mmPerRow:n}:n,o=r.mmPerRow??0,s=r.measurer??x.heuristicMeasurer,i=[],a=[];let l=0;const c=h=>`${h}_${(++l).toString(36)}`,f=[];for(const h of e.pages){const m=Re(h),w=()=>st(h,m),d=m.marginTopMm,p=[],S=()=>{if(a.push({pageWidthMm:m.widthMm,pageHeightMm:m.heightMm,marginTopMm:m.marginTopMm,marginBottomMm:m.marginBottomMm,marginLeftMm:m.marginLeftMm,marginRightMm:m.marginRightMm,components:m.components}),p.length>0){const T=a.length;for(const u of p){const k={...u,text:String(u.text??"").replace(/\{page\}/g,String(T))};a[a.length-1].components.push(k),k.text.includes("{totalPages}")&&f.push(k)}}};for(const T of h.components){if(T.kind!=="list"){if(T.kind==="text"&&typeof T.text=="string"){const $=T.text;if($.includes("{page}")||$.includes("{totalPages}")){p.push(T);continue}}m.components.push(T);continue}const u=T,k=t[u.dataset];Array.isArray(k)||i.push(`数据集 ${u.dataset} 未提供数据,列表 ${u.id??""} 输出为空`);const A=Array.isArray(k)?k:[],v=u.columns.reduce(($,M)=>$+M.widthMm,0),V=v>u.widthMm?u.widthMm/v:1,y=V===1?u:{...u,columns:u.columns.map($=>({...$,widthMm:$.widthMm*V}))},E={...lt(y,s),rowHeightFloorMm:y.rowHeightMm??0},Z={kind:"rect",leftMm:u.leftMm,topMm:0,widthMm:u.widthMm,heightMm:E.headerHeightMm,grid:E.headerGrid,nid:c("listh"),style:E.borderStyle};let b=u.topMm;const H=($,M)=>{$.components.push({...Z,topMm:M})};H(m,b),b+=E.headerHeightMm+o;const D=$=>{if(b+$>w()){S();const M=Re(h);m.components=M.components,m.heightMm=M.heightMm,y.headerEveryPage!==!1?(H(m,u.topMm),b=u.topMm+E.headerHeightMm):b=d}},P=($,M,N)=>{const R=y.headerEveryPage!==!1?u.topMm+E.headerHeightMm:d,F=w()-R;M>F&&i.push(`列表 ${u.id??u.dataset} 行高 ${M.toFixed(2)}mm 超出单页可用高度 ${F.toFixed(2)}mm,预览与打印可能截断内容`),D(M),m.components.push({kind:"rect",leftMm:u.leftMm,topMm:b,widthMm:u.widthMm,heightMm:M,grid:$,nid:c(N),style:E.borderStyle}),b+=M},O=()=>Ce(E,{},s).heightMm,_=($,M,N,R)=>{const F=[],ie=Math.max(1,Math.min(R,y.columns.length)),Ne={fontSize:E.fontSizePt,...N};F.push({text:$,colSpan:ie,style:{bold:!0,...Ne}});for(let G=ie;G<y.columns.length;G++){const te=y.columns[G],ne=M.get(te.field),le=E.autoStyles[G]?.[De(ne?.value,te.format)]??E.cellStyles[G];F.push({...ne,text:ne?.text??"",style:{...le,...Ne}})}let se=E.rowHeightFloorMm,ae=0;for(const G of F){let te=0;const ne=ae+(G.colSpan??1);for(;ae<ne;ae++)te+=E.colWidthsMm[ae]??0;const le=Ie(E,G.style),Ze=x.wrapText(G.text??"",te-E.paddingMm*2,le.measureOptions,s);se=Math.max(se,Ze.length*le.lineMm+E.paddingMm*2)}return{grid:{cells:[F],colWidthsMm:E.colWidthsMm,rowHeightsMm:[se]},heightMm:se}},Y=($,M)=>{let N=0;for(const R of $){const F=typeof R[M]=="number"?R[M]:Number(R[M]);Number.isFinite(F)&&(N+=F)}return N},oe=($,M)=>{const R=y.columns.find(ie=>ie.field===M)?.format??{kind:"number",thousands:!0},F=Y($,M);return{text:Me(F,R),value:F,numberFormat:ye(R)}},j=y.groupBy,ke=$=>{const M=y.columns.findIndex(N=>$.includes(N.field));return M>0?M:1},ee=[];if(j){const $=new Map;for(const M of A){const N=Le(M[j.field]),R=$.get(N);R?R.push(M):$.set(N,[M])}for(const[M,N]of $){ee.push({kind:"groupHeader",label:(j.headerTemplate??"{value}").replace(/\{value\}/g,M)});for(const R of N)ee.push({kind:"row",row:R});j.subtotal&&j.subtotal.length>0&&ee.push({kind:"subtotal",label:j.subtotalLabel??"小计",rows:N})}}else for(const $ of A)ee.push({kind:"row",row:$});const xe=O();for(const $ of ee)if($.kind==="row"){const M=Ce(E,$.row,s);P(M.grid,M.heightMm,"listr")}else if($.kind==="groupHeader"){const M=_($.label,new Map,j?.headerStyle??{},y.columns.length);j?.keepWithNext!==!1&&b+M.heightMm+xe>w()&&D(M.heightMm+xe),P(M.grid,M.heightMm,"listg")}else if($.kind==="subtotal"){const M=new Map;for(const R of j.subtotal??[])M.set(R,oe($.rows,R));const N=_($.label,M,j?.subtotalStyle??{},ke(j.subtotal??[]));P(N.grid,N.heightMm,"listst")}if(y.grandTotal){const $=typeof y.grandTotal=="object"?y.grandTotal:void 0,M=$?.fields??j?.subtotal??[];if(M.length>0){const N=new Map;for(const F of M)N.set(F,oe(A,F));const R=_($?.label??"合计",N,$?.style??{},ke(M));P(R.grid,R.heightMm,"listgt")}else i.push(`列表 ${u.id??""} 配置了 grandTotal 但未提供合计字段(groupBy.subtotal 或 grandTotal.fields)`)}}S()}for(const h of f){const m=h.text;typeof m=="string"&&m.includes("{totalPages}")&&(h.text=m.replace(/\{totalPages\}/g,String(a.length)))}return{plan:{schemaVersion:x.RENDER_PLAN_SCHEMA_VERSION,pages:a},warnings:i}}const ct={root:"mr-root",page:"mr-page",comp:"mr-comp",text:"mr-text",lines:"mr-lines",line:"mr-line",rich:"mr-rich",paragraph:"mr-paragraph",segment:"mr-segment",image:"mr-image",shape:"mr-shape",grid:"mr-grid",row:"mr-row",cell:"mr-cell",unknown:"mr-unknown"};function L(e,t){return t?.classNames?.[e]??ct[e]}class W{constructor(){this.props=[]}add(t,n){return n==null||n===!1||n===""?this:(this.props.push([t,String(n)]),this)}mm(t,n,r,o=2){return this.add(t,`${g.round(g.mmToPx(n,r),o)}px`)}toString(){let t="";for(const[n,r]of this.props)t+=`${n}:${r};`;return t}applyTo(t){const n=this.toString();n&&(t.style.cssText=n)}}function je(e,t,n){const r=t.style||{};e.add("color",r.color).add("background-color",r.backgroundColor).add("font-family",r.fontFamily).add("font-weight",r.bold?"700":void 0).add("font-style",r.italic?"italic":void 0).add("text-decoration",r.underline?"underline":void 0).add("letter-spacing",r.letterSpacing!=null?`${r.letterSpacing}pt`:void 0).add("opacity",r.opacity!=null?String(r.opacity):void 0).add("transform",r.rotateDeg?`rotate(${r.rotateDeg}deg)`:void 0);const o=g.resolveFontSize(r,n);e.add("font-size",`${g.round(o.fontSizePx,2)}px`)}function dt(e,t,n,r,o){const s=o.createElement("table");if(s.className=L("grid",r),new W().add("width","100%").add("height","100%").add("border-collapse","collapse").add("table-layout",e.colWidthsMm?"fixed":"auto").applyTo(s),e.colWidthsMm){const c=o.createElement("colgroup");for(const f of e.colWidthsMm){const h=o.createElement("col");new W().mm("width",f,n).applyTo(h),c.appendChild(h)}s.appendChild(c)}const i=g.resolveBoxBorders(t.style),a=g.resolveStroke(t.style),l=i.inner?`${g.round(a.widthPt*n/72,2)}px solid ${a.color}`:"";return e.cells.forEach((c,f)=>{const h=o.createElement("tr");h.className=L("row",r),e.rowHeightsMm?.[f]!=null&&new W().mm("height",e.rowHeightsMm[f],n).applyTo(h),(c||[]).forEach(m=>{const w=o.createElement("td");w.className=L("cell",r),m?.colSpan&&(w.colSpan=m.colSpan),m?.rowSpan&&(w.rowSpan=m.rowSpan);const d=new W;if(l&&d.add("border",l),m?.style){const p=m.style;d.add("text-align",p.align).add("vertical-align",p.verticalAlign).add("background-color",p.backgroundColor).add("color",p.color).add("font-weight",p.bold?"700":void 0),d.add("font-size",`${g.round(g.resolveFontSize(p,n).fontSizePx,2)}px`)}if(d.applyTo(w),m?.text!=null&&(w.textContent=m.text),m?.children?.length)for(const p of m.children)w.appendChild(we(p,n,r,o));h.appendChild(w)}),s.appendChild(h)}),s}function mt(e,t,n,r){const o=r.createElement("div");o.className=L("text",n);const s=e.style||{},i=new W().add("text-align",s.align).add("display","flex").add("flex-direction","column").add("justify-content",s.verticalAlign==="middle"?"center":s.verticalAlign==="bottom"?"flex-end":"flex-start").add("overflow","hidden");if(je(i,e,t),i.applyTo(o),x.isRichText(e)){const a=r.createElement("div");a.className=L("rich",n);for(const l of e.richParagraphs){const c=r.createElement("div");c.className=L("paragraph",n),new W().add("text-align",l.align).add("line-height",l.lineHeight!=null?String(l.lineHeight):void 0).mm("margin-top",l.spaceBeforeMm??0,t).mm("margin-bottom",l.spaceAfterMm??0,t).mm("text-indent",l.indentMm??0,t).applyTo(c);for(const h of l.segments||[]){const m=r.createElement("span");if(m.className=L("segment",n),m.textContent=h.kind==="field"?h.field??"":h.text??"",h.style){const w=new W().add("color",h.style.color).add("font-weight",h.style.bold?"700":void 0);w.add("font-size",`${g.round(g.resolveFontSize(h.style,t).fontSizePx,2)}px`),w.applyTo(m)}c.appendChild(m)}a.appendChild(c)}return o.appendChild(a),o}if(Array.isArray(e.lines)&&e.lines.length>0){const a=r.createElement("div");a.className=L("lines",n),s.lineHeight!=null&&new W().add("line-height",String(s.lineHeight)).applyTo(a);for(const l of e.lines){const c=r.createElement("div");c.className=L("line",n),c.textContent=l,a.appendChild(c)}return o.appendChild(a),o}return o.textContent=e.text??"",o}function ft(e,t,n){const r=n.createElement("img");return r.className=L("image",t),r.src=e.imageData,new W().add("width","100%").add("height","100%").add("object-fit","contain").add("display","block").applyTo(r),r.alt=e.kind,r}function _e(e,t,n,r){const o=r.createElement("div");o.className=L("shape",n);const s=e.style||{},i=g.resolveStroke(s),a=g.resolveBoxBorders(s),l=`${g.round(i.widthPt*t/72,2)}px solid ${i.color}`,c=new W;return e.grid||e.kind==="rect"?(a.top&&c.add("border-top",l),a.right&&c.add("border-right",l),a.bottom&&c.add("border-bottom",l),a.left&&c.add("border-left",l)):e.kind==="ellipse"?(a.inner&&c.add("border",l).add("border-radius","50%"),s.backgroundColor&&c.add("background-color",s.backgroundColor)):e.kind==="line"&&c.add("height","0").add("border-top",l),c.add("box-sizing","border-box").add("width","100%").add("height","100%"),c.applyTo(o),o}function we(e,t,n,r){const o=r.createElement("div");o.className=`${L("comp",n)} mr-kind-${e.kind}`;const s=new W().add("position","absolute").mm("left",e.leftMm,t).mm("top",e.topMm,t).mm("width",e.widthMm,t).mm("height",e.heightMm,t).add("box-sizing","border-box");if(je(s,e,t),s.applyTo(o),x.isImageBackedComponent(e))return o.appendChild(ft(e,n,r)),o;if(e.kind==="text")return o.appendChild(mt(e,t,n,r)),o;if(e.grid){const a=_e(e,t,n,r);return a.appendChild(dt(e.grid,e,t,n,r)),o.appendChild(a),o}if(e.kind==="line"||e.kind==="rect"||e.kind==="ellipse"||e.kind==="chart")return o.appendChild(_e(e,t,n,r)),o;const i=r.createElement("div");return i.className=L("unknown",n),i.textContent=e.fallbackText??"",o.appendChild(i),o}function We(e,t,n,r){const o=r.createElement("div");o.className=L("page",n),new W().add("position","relative").mm("width",e.pageWidthMm,t).mm("height",e.pageHeightMm,t).add("background-color","#fff").add("overflow","hidden").add("box-sizing","border-box").applyTo(o);for(const s of e.components)o.appendChild(we(s,t,n,r));return o}function ht(e,t,n={}){const r=n.dpi??96,o=t.createElement("div");return o.className=L("root",n),o.dataset.schemaVersion=e.schemaVersion,e.pages.forEach(s=>{o.appendChild(We(s,r,n,t))}),o}function Ve(e){return Qe.createPageWindowIndex(e.pageHeightsPx,e.gapPx).window(e.viewportHeightPx,e.scrollTopPx,e.overscan)}const Se=96/25.4;function $e(e,t=96){const n=t/96*Se;return{widthPx:Math.max(1,Math.round(e.pageWidthMm*n)),heightPx:Math.max(1,Math.round(e.pageHeightMm*n))}}function gt(e,t,n){const r=document.createElement("canvas"),{widthPx:o,heightPx:s}=$e(e,n);r.width=Math.round(o*t),r.height=Math.round(s*t),r.style.width=`${o}px`,r.style.height=`${s}px`;const i=r.getContext("2d");if(!i)throw new Error("当前环境不支持 Canvas 2D(测试需真浏览器,见 e2e/canvas.spec.ts)");return i.scale(t,t),i.fillStyle="#ffffff",i.fillRect(0,0,o,s),{canvas:r,ctx:i}}function ut(e,t=96){return g.resolveFontSize(e,t).fontSizePx}function Ge(e,t,n,r,o,s,i,a="top"){e.font=`${t.bold?"bold ":""}${t.fontSizePx}px ${i}`,e.fillStyle=t.color,e.textBaseline="alphabetic";const l=t.fontSizePx*t.lineHeight,c=t.text===""?[""]:t.text.split(`
|
|
2
|
-
`),
|
|
3
|
-
`);
|
|
4
|
-
`):
|
|
5
|
-
`):
|
|
6
|
-
`);Ge(e,{text:m,fontSizePx:g.resolveFontSize(f,r).fontSizePx,bold:f.bold??!1,color:g.resolveTextColor(f),align:f.align??"left",lineHeight:g.resolveLineHeight(f)},i,a,l,c,o,f.verticalAlign);break}case"rect":{const h=g.resolveStroke(f),m=g.resolveBoxBorders(f);f.backgroundColor&&(e.fillStyle=f.backgroundColor,e.fillRect(i,a,l,c)),m.inner&&(e.strokeStyle=h.color,e.lineWidth=g.ptToPx(h.widthPt,r),e.beginPath(),m.top&&(e.moveTo(i,a),e.lineTo(i+l,a)),m.right&&(e.moveTo(i+l,a),e.lineTo(i+l,a+c)),m.bottom&&(e.moveTo(i+l,a+c),e.lineTo(i,a+c)),m.left&&(e.moveTo(i,a+c),e.lineTo(i,a)),e.stroke());break}case"line":{const h=g.resolveStroke({...f,borderColor:f.lineColor??f.borderColor});e.strokeStyle=h.color,e.lineWidth=g.ptToPx(h.widthPt,r),e.beginPath(),e.moveTo(i,a+c/2),e.lineTo(i+l,a+c/2),e.stroke();break}case"ellipse":{const h=g.resolveStroke(f);e.strokeStyle=h.color,e.lineWidth=g.ptToPx(h.widthPt,r),f.backgroundColor&&(e.fillStyle=f.backgroundColor,e.beginPath(),e.ellipse(i+l/2,a+c/2,l/2,c/2,0,0,Math.PI*2),e.fill()),e.beginPath(),e.ellipse(i+l/2,a+c/2,l/2,c/2,0,0,Math.PI*2),e.stroke();break}}}async function yt(e,t={}){if(typeof document>"u")throw new Error("renderPlanToImages 需要浏览器环境(SSR/Node 请在客户端钩子中调用)");const{format:n="png",quality:r=.92,...o}=t,{canvases:s}=Je(e,o),i=n==="jpeg"?"image/jpeg":"image/png",a=[];for(const l of s)a.push(await new Promise(c=>l.toBlob(f=>c(f),i,r))??new Blob([],{type:i}));return{blobs:a}}function Je(e,t={}){if(typeof document>"u")throw new Error("renderPlanToCanvas 需要浏览器环境(SSR 请在客户端钩子中调用)");const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),r=t.dpi??96,o=r/96*Se,s=t.fontFamily??'"Microsoft YaHei", sans-serif',i=t.measurer??x.heuristicMeasurer,a=Math.max(0,t.start??0),l=Math.min(e.pages.length-1,t.end??e.pages.length-1),c=[];for(let f=a;f<=l;f++){const h=e.pages[f],{canvas:m,ctx:w}=gt(h,n,r);for(const d of h.components)Ue(w,d,o,r,s,i);c.push(m)}return{canvases:c}}function Mt(e,t={}){const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),r=t.dpi??96,o=r/96*Se,s=t.fontFamily??'"Microsoft YaHei", sans-serif',i=t.measurer??x.heuristicMeasurer,a=t.overscan??1,l=t.gapPx??18,c=t.pagesPerFrame??1,f=e.pages.map(b=>b.pageHeightMm*o),h=Math.max(1,...e.pages.map(b=>b.pageWidthMm*o)),m={start:0,end:-1};let w=null,d=null,p=null,S=null,T=[],u=0,k=[];function A(){const b=w;b.innerHTML="",d=document.createElement("div"),d.style.cssText=`width:${h}px;margin:0 auto;`,p=document.createElement("div"),S=document.createElement("div"),d.appendChild(p),T=[];const H=Math.min(e.pages.length,3+a*2);for(let D=0;D<H;D++){const P=document.createElement("div");P.style.cssText=`margin:0 auto ${l}px;box-shadow:0 2px 8px rgba(0,0,0,.35);background:#fff;`,d.appendChild(P),T.push(P)}d.appendChild(S),b.appendChild(d)}function v(b,H){const D=e.pages[H],{widthPx:P,heightPx:O}=$e(D,r);let _=b.firstElementChild;(!_||_.tagName!=="CANVAS")&&(_=document.createElement("canvas"),b.innerHTML="",b.appendChild(_)),_.width=Math.round(P*n),_.height=Math.round(O*n),_.style.width=`${P}px`,_.style.height=`${O}px`;const Y=_.getContext("2d");if(Y){Y.setTransform(1,0,0,1,0,0),Y.scale(n,n),Y.fillStyle="#ffffff",Y.fillRect(0,0,P,O);for(const oe of D.components)Ue(Y,oe,o,r,s,i);_.dataset.canvasPage=String(H),b.style.height=`${O}px`,b.style.width=`${P}px`}}function V(b){m.start=b.start,m.end=b.end,p.style.height=`${b.start*l+f.slice(0,b.start).reduce((P,O)=>P+O,0)}px`;const H=e.pages.length-1-b.end;S.style.height=`${H*l+f.slice(b.end+1).reduce((P,O)=>P+O,0)}px`;const D=b.end-b.start+1;T.forEach((P,O)=>{if(O<D){P.style.display="";const _=b.start+O;P.style.height=`${f[_]??0}px`}else P.style.display="none"}),k=[];for(let P=b.start;P<=b.end;P++){const O=T[P-b.start];if(!O)continue;O.firstElementChild?.dataset?.canvasPage!==String(P)&&k.push(P)}y()}function y(){u||k.length===0||(u=requestAnimationFrame(()=>{u=0;let b=Math.max(1,c);for(;k.length>0&&b-- >0;){const H=k.shift(),D=T[H-m.start];D&&v(D,H)}k.length>0&&y()}))}function E(){u||(u=requestAnimationFrame(()=>{u=0;const b=w,H=Ve({pageHeightsPx:f,viewportHeightPx:b.clientHeight,scrollTopPx:b.scrollTop,overscan:a,gapPx:l});H.start!==m.start||H.end!==m.end?V(H):y()}))}let Z=null;return{attach(b){if(typeof document>"u")throw new Error("createCanvasPager 需要浏览器环境(SSR 请在客户端钩子中调用 attach)");w=b,A(),b.addEventListener("scroll",E,{passive:!0}),typeof ResizeObserver<"u"&&(Z=new ResizeObserver(()=>E()),Z.observe(b)),E()},destroy(){u&&cancelAnimationFrame(u),u=0,Z?.disconnect(),Z=null,w?.removeEventListener("scroll",E),k=[],d?.remove(),w=null},window(){return{...m}}}}function Te(e,t,n){let r,o;if(typeof e=="string"){const s=g.PAPER_SIZES[e];if(!s)throw new Error(`未知纸张预设 "${e}"(可用:${Object.keys(g.PAPER_SIZES).join("/")})`);r=s.widthMm,o=s.heightMm}else typeof e=="number"?(r=e,o=t??297):(r=e.widthMm,o=e.heightMm);return n?{widthMm:o,heightMm:r}:{widthMm:r,heightMm:o}}class Ye{constructor(){this.pages=[],this.pending=null,this.templateParams=void 0}params(t){return this.templateParams=t,this}page(t="a4",n={},r){this.collect();const s=r!=null&&!("margins"in r)&&!("landscape"in r)&&("marginTopMm"in r||"marginBottomMm"in r||"marginLeftMm"in r||"marginRightMm"in r)?{margins:r}:typeof n=="number"?r??{}:n,{widthMm:i,heightMm:a}=Te(t,typeof n=="number"?n:void 0,s.landscape),l=s.margins??{};return this.pending=new qe(this,{widthMm:i,heightMm:a,marginTopMm:l.marginTopMm??10,marginBottomMm:l.marginBottomMm??10,marginLeftMm:l.marginLeftMm??10,marginRightMm:l.marginRightMm??10}),this.pending}collect(){this.pending&&(this.pages.push(this.pending.buildPage()),this.pending=null)}build(){if(this.collect(),this.pages.length===0)throw new Error("模板至少需要一页:先调用 .page() 添加内容");return this.templateParams?{params:this.templateParams,pages:this.pages}:{pages:this.pages}}}class qe{constructor(t,n){this.parent=t,this.page=n,this.components=[]}text(t,n={},r={}){return this.components.push({kind:"text",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??60,heightMm:n.heightMm??8,text:t,style:r}),this}list(t,n,r,o={}){return this.components.push({kind:"list",leftMm:n.leftMm??10,topMm:n.topMm??30,widthMm:n.widthMm??180,dataset:t,columns:r,...o}),this}rect(t,n={}){return this.components.push({kind:"rect",...t,style:n}),this}line(t,n,r,o={}){return this.components.push({kind:"line",leftMm:t,topMm:n,widthMm:r,heightMm:.5,style:o}),this}barcode(t,n){return this.components.push({kind:"barcode",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??40,heightMm:n.heightMm??12,fallbackText:t}),this}qrcode(t,n,r,o){return this.components.push({kind:"qrcode",leftMm:r,topMm:o,widthMm:n,heightMm:n,fallbackText:t}),this}buildPage(){return{...this.page,components:this.components}}done(){return this.parent}build(){return this.done().build()}}function bt(){return new Ye}function U(e,t,n=!1){if(!Number.isFinite(e)||(n?e<0:e<=0))throw new Error(`${t} 必须是有限${n?"非负":"正"}数`)}function ce(e,t,n){if(e!==void 0&&!["left","center","right","justify",...n?["auto"]:[]].includes(e))throw new Error(`${t} 必须是 left/center/right/justify${n?"/auto":""}`)}function wt(e){if(!e||typeof e!="object")throw new Error("标准明细模板需要 options 对象");if(!Array.isArray(e.columns)||e.columns.length===0)throw new Error("columns 至少需要一列");const t=e.paper===void 0?"a4":e.paper;if(typeof t!="string"&&(typeof t!="object"||t===null)||e.landscape!==void 0&&typeof e.landscape!="boolean")throw new Error("paper 必须是纸张预设名或 { widthMm, heightMm } 对象,landscape 必须是布尔值");if(typeof t=="string"&&!Object.prototype.hasOwnProperty.call(g.PAPER_SIZES,t))throw new Error(`未知纸张预设 "${t}"(可用:${Object.keys(g.PAPER_SIZES).join("/")})`);const{widthMm:n,heightMm:r}=Te(t,void 0,e.landscape);if(U(n,"纸张 widthMm"),U(r,"纸张 heightMm"),e.margins!==void 0&&(!e.margins||typeof e.margins!="object"||Array.isArray(e.margins)))throw new Error("margins 必须是页边距对象");const o=e.margins??{},s={marginTopMm:o.marginTopMm===void 0?10:o.marginTopMm,marginBottomMm:o.marginBottomMm===void 0?10:o.marginBottomMm,marginLeftMm:o.marginLeftMm===void 0?10:o.marginLeftMm,marginRightMm:o.marginRightMm===void 0?10:o.marginRightMm};for(const[A,v]of Object.entries(s))U(v,A,!0);const i=n-s.marginLeftMm-s.marginRightMm,a=r-s.marginTopMm-s.marginBottomMm;if(i<=0||a<=0)throw new Error("页边距占满纸张,必须保留正的可用宽度和高度");const l=e.dataset===void 0?"detail":e.dataset;if(typeof l!="string"||!l.trim())throw new Error("dataset 必须是非空字符串");if(e.title!==void 0&&typeof e.title!="string")throw new Error("title 必须是字符串");const c=e.titleHeightMm===void 0?10:e.titleHeightMm,f=e.titleGapMm===void 0?4:e.titleGapMm;U(c,"titleHeightMm"),U(f,"titleGapMm",!0);const h=e.title!==void 0&&e.title.length>0,m=h?c+f:0;if(m>=a)throw new Error("标题高度与间距占满页面,必须为表格保留可用高度");if(e.listOptions!==void 0&&(!e.listOptions||typeof e.listOptions!="object"||Array.isArray(e.listOptions)))throw new Error("listOptions 必须是列表配置对象");const w=e.listOptions??{};ce(w.align,"listOptions.align",!0),ce(w.headerAlign,"listOptions.headerAlign",!1);for(const A of["fontSizePt","rowHeightMm","paddingMm"]){const v=w[A];v!==void 0&&U(v,`listOptions.${A}`,A==="paddingMm")}let d=0,p=0;for(const[A,v]of e.columns.entries()){if(!v||typeof v.header!="string"||typeof v.field!="string"||!v.field.trim())throw new Error(`columns[${A}] 需要字符串 header 与非空 field`);ce(v.align,`columns[${A}].align`,!0),ce(v.headerAlign,`columns[${A}].headerAlign`,!1),v.flex!==void 0&&U(v.flex,`columns[${A}].flex`),v.widthMm!==void 0?(U(v.widthMm,`columns[${A}].widthMm`),d+=v.widthMm):p=Math.max(p,v.flex??1)}if(d>i)throw new Error(`固定列宽 ${d}mm 超出页面可用宽度 ${i}mm`);const S=i-d;if(p>0&&S<=0)throw new Error("固定列占满页面可用宽度,自动列需要正的剩余宽度");const T=p>0?e.columns.reduce((A,v)=>A+(v.widthMm===void 0?(v.flex??1)/p:0),0):0,u=e.columns.map(({widthMm:A,flex:v,...V},y)=>{const E=A??S*((v??1)/p)/T;return U(E,`columns[${y}] 分配后的 widthMm`),{...V,widthMm:E}}),k={widthMm:n,heightMm:r,...s,components:[]};return h&&k.components.push({kind:"text",text:e.title,leftMm:s.marginLeftMm,topMm:s.marginTopMm,widthMm:i,heightMm:c,style:{fontSize:16,bold:!0,align:"center",verticalAlign:"middle",...e.titleStyle}}),k.components.push({align:"auto",headerAlign:"center",...w,kind:"list",dataset:l,columns:u,leftMm:s.marginLeftMm,topMm:s.marginTopMm+m,widthMm:p>0?i:d}),e.params===void 0?{pages:[k]}:{params:e.params,pages:[k]}}const Ee="1.0";class X extends Error{constructor(t){super(`模板校验失败:${t.slice(0,3).map(n=>`${n.path}: ${n.message}`).join("; ")}`),this.errors=t,this.name="ReportTemplateError"}}const St=new Set(["__proto__","prototype","constructor"]),$t=new Set(["schemaVersion","id","name","revision","description","template"]),Tt=new Set(["left","center","right","justify"]),ue=2e5,Et=64,ve=1e7;function C(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Pe(e,t){const n=new Set;let r=0,o=0,s=!1;const i=(a,l,c)=>{if(s)return;if(++r>ue){r===ue+1&&t.push({path:l,message:"模板超过 JSON 节点安全上限"});return}if(c>Et){t.push({path:l,message:"模板嵌套层级过深"});return}if(typeof a=="string"){o+=a.length,o>ve&&(s=!0,t.push({path:l,message:"模板文本超过 1000 万字符的安全上限"}));return}if(a===null||typeof a=="boolean"||typeof a=="number"&&Number.isFinite(a))return;if(!a||typeof a!="object"){t.push({path:l,message:"模板只允许 JSON 值,不允许函数、undefined 或非有限数字"});return}if(n.has(a)){t.push({path:l,message:"模板不能包含循环引用"});return}const f=Object.getPrototypeOf(a);if(Array.isArray(a)&&f!==Array.prototype||!Array.isArray(a)&&f!==Object.prototype&&f!==null){t.push({path:l,message:"模板对象必须使用普通 JSON 对象原型"});return}if(Array.isArray(a)&&(Object.keys(a).length!==a.length||Object.keys(a).some(h=>!/^(0|[1-9]\d*)$/.test(h)||Number(h)>=a.length))){t.push({path:l,message:"模板数组不能包含空位或额外属性"});return}if(Object.getOwnPropertySymbols(a).length>0){t.push({path:l,message:"模板不能包含 Symbol 键"});return}n.add(a);for(const[h,m]of Object.entries(Object.getOwnPropertyDescriptors(a)))if(!(Array.isArray(a)&&h==="length")&&(St.has(h)?t.push({path:`${l}.${h}`,message:"模板不能包含可能污染原型的键"}):m.get||m.set||!m.enumerable?t.push({path:`${l}.${h}`,message:"模板不能包含访问器或不可枚举字段"}):i(m.value,`${l}.${h}`,c+1),r>ue||s))break;n.delete(a)};i(e,"$",0)}function B(e,t,n,r,o=!1){const s=e[t];s===void 0&&!o||(typeof s!="string"||o&&!s.trim())&&r.push({path:`${n}.${t}`,message:o?"应为非空字符串":"应为字符串"})}function z(e,t,n,r,o=0,s=!1){const i=e[t];i===void 0&&!s||(typeof i!="number"||!Number.isFinite(i)||i<o)&&r.push({path:`${n}.${t}`,message:`应为大于等于 ${o} 的有限数字`})}function re(e,t,n,r){e[t]!==void 0&&typeof e[t]!="boolean"&&r.push({path:`${n}.${t}`,message:"应为布尔值"})}function Q(e,t,n,r=!1){e!==void 0&&!Tt.has(e)&&!(r&&e==="auto")&&n.push({path:t,message:`未知对齐方式${r?"(支持 auto)":""}`})}function J(e,t,n){if(e!==void 0){if(!C(e)){n.push({path:t,message:"样式应为对象"});return}Q(e.align,`${t}.align`,n),e.verticalAlign!==void 0&&!["top","middle","bottom"].includes(e.verticalAlign)&&n.push({path:`${t}.verticalAlign`,message:"未知垂直对齐方式"});for(const r of["fontSize","fontSizePx","lineWidthPt","lineHeight"])z(e,r,t,n);for(const r of["letterSpacing","rotateDeg"])z(e,r,t,n,-1/0);z(e,"opacity",t,n),typeof e.opacity=="number"&&e.opacity>1&&n.push({path:`${t}.opacity`,message:"透明度不能大于 1"});for(const r of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])re(e,r,t,n);for(const r of["fontFamily","color","backgroundColor","lineColor","borderColor"])B(e,r,t,n)}}function vt(e,t,n){if(e===void 0)return;if(!Array.isArray(e)){n.push({path:t,message:"参数定义应为数组"});return}const r=new Set;e.forEach((o,s)=>{const i=`${t}.${s}`;if(!C(o)){n.push({path:i,message:"参数定义应为对象"});return}B(o,"field",i,n,!0),typeof o.field=="string"&&(r.has(o.field)&&n.push({path:`${i}.field`,message:"参数名重复"}),r.add(o.field)),o.type!==void 0&&!["text","number","date","select"].includes(o.type)&&n.push({path:`${i}.type`,message:"未知参数类型"});for(const a of["label","defaultValue","placeholder"])B(o,a,i,n);re(o,"required",i,n),o.options!==void 0&&(Array.isArray(o.options)?o.options.forEach((a,l)=>{const c=`${i}.options.${l}`;if(!C(a))n.push({path:c,message:"选项应为对象"});else for(const f of["label","value"])typeof a[f]!="string"&&n.push({path:`${c}.${f}`,message:"选项标签与值应为字符串(允许空白选项)"})}):n.push({path:`${i}.options`,message:"选项应为数组"}))})}function Pt(e,t,n){for(const r of["leftMm","topMm"])z(e,r,t,n,-1/0,!0);z(e,"widthMm",t,n,Number.MIN_VALUE,!0),B(e,"dataset",t,n,!0),!Array.isArray(e.columns)||e.columns.length===0?n.push({path:`${t}.columns`,message:"列表至少需要一列"}):e.columns.forEach((r,o)=>{const s=`${t}.columns.${o}`;if(!C(r)){n.push({path:s,message:"列应为对象"});return}if(typeof r.header!="string"&&n.push({path:`${s}.header`,message:"表头应为字符串(允许空白表头)"}),B(r,"field",s,n,!0),z(r,"widthMm",s,n,Number.MIN_VALUE,!0),J(r.style,`${s}.style`,n),J(r.headerStyle,`${s}.headerStyle`,n),Q(r.align,`${s}.align`,n,!0),Q(r.headerAlign,`${s}.headerAlign`,n),r.format!==void 0)if(!C(r.format)||!["number","percent","date"].includes(r.format.kind))n.push({path:`${s}.format`,message:"未知列格式"});else{const i=r.format.digits;i!==void 0&&(typeof i!="number"||!Number.isInteger(i)||i<0||i>100)&&n.push({path:`${s}.format.digits`,message:"小数位应为 0–100 的整数"}),re(r.format,"thousands",`${s}.format`,n),B(r.format,"pattern",`${s}.format`,n)}r.rules!==void 0&&(Array.isArray(r.rules)?r.rules.forEach((i,a)=>{const l=`${s}.rules.${a}`;if(!C(i)||!C(i.when)){n.push({path:l,message:"条件格式缺少 when 对象"});return}B(i.when,"field",`${l}.when`,n,!0),[">",">=","<","<=","==","!="].includes(i.when.op)||n.push({path:`${l}.when.op`,message:"未知条件运算符"}),typeof i.when.value!="number"&&typeof i.when.value!="string"&&n.push({path:`${l}.when.value`,message:"条件值应为数字或字符串"}),J(i.style,`${l}.style`,n)}):n.push({path:`${s}.rules`,message:"条件格式应为数组"}))});for(const r of["fontSizePt","rowHeightMm"])z(e,r,t,n,Number.MIN_VALUE);z(e,"paddingMm",t,n);for(const r of["headerBold","headerEveryPage","border"])re(e,r,t,n);if(B(e,"headerBackgroundColor",t,n),Q(e.align,`${t}.align`,n,!0),Q(e.headerAlign,`${t}.headerAlign`,n),J(e.headerStyle,`${t}.headerStyle`,n),e.groupBy!==void 0)if(!C(e.groupBy))n.push({path:`${t}.groupBy`,message:"分组应为对象"});else{B(e.groupBy,"field",`${t}.groupBy`,n,!0);for(const r of["headerTemplate","subtotalLabel"])B(e.groupBy,r,`${t}.groupBy`,n);for(const r of["headerStyle","subtotalStyle"])J(e.groupBy[r],`${t}.groupBy.${r}`,n);re(e.groupBy,"keepWithNext",`${t}.groupBy`,n),e.groupBy.subtotal!==void 0&&(!Array.isArray(e.groupBy.subtotal)||e.groupBy.subtotal.some(r=>typeof r!="string"))&&n.push({path:`${t}.groupBy.subtotal`,message:"小计字段应为字符串数组"})}e.grandTotal!==void 0&&typeof e.grandTotal!="boolean"&&(C(e.grandTotal)?(B(e.grandTotal,"label",`${t}.grandTotal`,n),J(e.grandTotal.style,`${t}.grandTotal.style`,n),e.grandTotal.fields!==void 0&&(!Array.isArray(e.grandTotal.fields)||e.grandTotal.fields.some(r=>typeof r!="string"))&&n.push({path:`${t}.grandTotal.fields`,message:"合计字段应为字符串数组"})):n.push({path:`${t}.grandTotal`,message:"合计应为布尔值或对象"}))}function Xe(e,t,n){J(e.style,`${t}.style`,n);for(const o of["text","rawText","imageData","fallbackText","nid","rkey"])B(e,o,t,n);if(e.lines!==void 0&&(!Array.isArray(e.lines)||e.lines.some(o=>typeof o!="string"))&&n.push({path:`${t}.lines`,message:"文本行应为字符串数组"}),Array.isArray(e.richParagraphs)&&e.richParagraphs.forEach((o,s)=>{if(!C(o))return;const i=`${t}.richParagraphs.${s}`;Q(o.align,`${i}.align`,n);for(const a of["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"])z(o,a,i,n);Array.isArray(o.segments)&&o.segments.forEach((a,l)=>{const c=`${i}.segments.${l}`;if(!C(a)){n.push({path:c,message:"富文本片段应为对象"});return}a.kind!==void 0&&a.kind!=="text"&&a.kind!=="field"&&n.push({path:`${c}.kind`,message:"未知富文本片段类型"});for(const f of["text","field"])B(a,f,c,n);J(a.style,`${c}.style`,n)})}),!C(e.grid))return;const r=e.grid;z(r,"gapMm",`${t}.grid`,n);for(const o of["colWidthsMm","rowHeightsMm"]){const s=r[o];s!==void 0&&(!Array.isArray(s)||s.some(i=>typeof i!="number"||!Number.isFinite(i)||i<0))&&n.push({path:`${t}.grid.${o}`,message:"网格尺寸应为有限非负数字数组"})}Array.isArray(r.cells)&&r.cells.forEach((o,s)=>{Array.isArray(o)&&o.forEach((i,a)=>{const l=`${t}.grid.cells.${s}.${a}`;if(i!==null){if(!C(i)){n.push({path:l,message:"网格单元格应为对象或 null"});return}for(const c of["text","rawText","numberFormat"])B(i,c,l,n);for(const c of["colSpan","rowSpan"]){const f=i[c];f!==void 0&&(typeof f!="number"||!Number.isInteger(f)||f<=0)&&n.push({path:`${l}.${c}`,message:"跨度应为正整数"})}i.value!==void 0&&i.value!==null&&!["string","number","boolean"].includes(typeof i.value)&&n.push({path:`${l}.value`,message:"Excel 原始值应为字符串、数字、布尔值或 null"}),J(i.style,`${l}.style`,n),i.children!==void 0&&(Array.isArray(i.children)?i.children.forEach((c,f)=>{C(c)&&Xe(c,`${l}.children.${f}`,n)}):n.push({path:`${l}.children`,message:"嵌套组件应为数组"}))}})})}function Ae(e){const t=[],n=[];return Pe(e,t),t.length?{ok:!1,errors:t,warnings:n}:(C(e)?(e.schemaVersion!==void 0&&e.schemaVersion!==x.RENDER_PLAN_SCHEMA_VERSION&&t.push({path:"$.schemaVersion",message:"不支持的模板 schemaVersion"}),vt(e.params,"$.params",t),!Array.isArray(e.pages)||e.pages.length===0?t.push({path:"$.pages",message:"模板至少需要一页"}):e.pages.forEach((r,o)=>{const s=`$.pages.${o}`;if(!C(r)){t.push({path:s,message:"页应为对象"});return}z(r,"widthMm",s,t,Number.MIN_VALUE,!0),z(r,"heightMm",s,t,Number.MIN_VALUE,!0),typeof r.widthMm=="number"&&r.widthMm>=3e3&&t.push({path:`${s}.widthMm`,message:"页宽应小于 3000mm"}),typeof r.heightMm=="number"&&r.heightMm>=5e3&&t.push({path:`${s}.heightMm`,message:"页高应小于 5000mm"});for(const i of["marginTopMm","marginBottomMm","marginLeftMm","marginRightMm"])z(r,i,s,t);typeof r.widthMm=="number"&&Number(r.marginLeftMm??0)+Number(r.marginRightMm??0)>=r.widthMm&&t.push({path:s,message:"横向页边距占满页面"}),typeof r.heightMm=="number"&&Number(r.marginTopMm??0)+Number(r.marginBottomMm??0)>=r.heightMm&&t.push({path:s,message:"纵向页边距占满页面"}),Array.isArray(r.components)?r.components.forEach((i,a)=>{const l=`${s}.components.${a}`;C(i)&&i.kind==="list"?Pt(i,l,t):(he(i,l,t,n),C(i)&&Xe(i,l,t))}):t.push({path:`${s}.components`,message:"组件应为数组"})})):t.push({path:"$",message:"模板应为对象"}),{ok:t.length===0,errors:t,warnings:n})}function Ke(e){const t=[],n=[];if(Pe(e,t),t.length)return{ok:!1,errors:t,warnings:n};if(!C(e))t.push({path:"$",message:"模板文档应为对象"});else{for(const o of Object.keys(e))$t.has(o)||t.push({path:`$.${o}`,message:"模板文档存在未知字段;只保存模板与描述,不保存取数或业务数据"});e.schemaVersion!==Ee&&t.push({path:"$.schemaVersion",message:"不支持的模板文档版本"});for(const o of["id","name"])B(e,o,"$",t,!0);for(const o of["revision","description"])B(e,o,"$",t);const r=Ae(e.template);t.push(...r.errors.map(o=>({...o,path:`$.template${o.path.slice(1)}`}))),n.push(...r.warnings.map(o=>({...o,path:`$.template${o.path.slice(1)}`})))}return{ok:t.length===0,errors:t,warnings:n}}function ge(e){const t=Ke(e);if(!t.ok)throw new X(t.errors)}function At(e){const t=[];if(Pe(e,t),t.length)throw new X(t);const n={...e,schemaVersion:e.schemaVersion??Ee};return ge(n),me(n)}function kt(e){let t=e;if(typeof e=="string"){if(e.length>ve)throw new X([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);try{t=JSON.parse(e)}catch{throw new X([{path:"$",message:"模板 JSON 语法无效"}])}}return ge(t),me(t)}function xt(e){ge(e);const t=JSON.stringify(e,null,2);if(t.length>ve)throw new X([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);return t}function me(e){return JSON.parse(JSON.stringify(e))}function Nt(e=[]){const t=new Map,n={get:r=>{const o=t.get(r);return o?me(o):void 0},list:()=>Array.from(t.values(),({template:r,...o})=>({...o})),register:(r,o={})=>{if(ge(r),t.has(r.id)&&!o.replace)throw new X([{path:"$.id",message:`模板 ID ${r.id} 已注册;更新需显式 replace:true`}]);t.set(r.id,me(r))},remove:r=>t.delete(r)};for(const r of e)n.register(r);return n}function Rt(e){if(!("mapData"in e))return e;const{load:t,mapData:n,...r}=e;return{...r,load:async o=>{const s=await t(o);q(o.signal);try{return n(s,o)}catch(i){throw new I("validate",`报表 ${o.reportId} 数据映射失败`,i)}}}}class I extends Error{constructor(t,n,r){super(n),this.name="ReportSourceError",this.code=t,this.cause=r}}function fe(e){const t=new Error("报表加载已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e.reason}),t}function q(e){if(e?.aborted)throw fe(e)}function He(e,t){return t?new Promise((n,r)=>{const o=()=>t.removeEventListener("abort",s),s=()=>{o(),r(fe(t))};t.addEventListener("abort",s,{once:!0}),t.aborted&&s(),Promise.resolve(e).then(i=>{o(),n(i)},i=>{o(),r(i)})}):Promise.resolve(e)}function Ct(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new I("validate",`报表 ${t} 的数据集应为对象`);for(const[n,r]of Object.entries(e))if(!Array.isArray(r)||r.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new I("validate",`报表 ${t} 的数据集 ${n} 应为对象数组`)}function _t(e,t={}){function n(o){const s=Object.prototype.hasOwnProperty.call(e,o)?e[o]:void 0;if(!s)throw new I("config",`未注册报表 ${o}`);return s}return Object.assign(async({reportIds:o,params:s,signal:i,onWarning:a})=>{q(i);const l=[...o],c={...s};if(l.length===0)throw new I("config","缺少报表 ID");const f=l.map(n),h=[],m=[];for(const[S,T]of f.entries()){q(i);const u=l[S],k={reportId:u,params:{...c},signal:i};let A;if(typeof T.template=="function")try{A=await He(T.template(k),i),q(i);const y=Ae(A);if(!y.ok)throw new I("validate",`报表 ${u} 模板校验失败:${y.errors.slice(0,3).map(E=>`${E.path}: ${E.message}`).join("; ")}`);m.push(...y.warnings.map(E=>`${u}: ${E.path}: ${E.message}`))}catch(y){throw i?.aborted?fe(i):y instanceof I?y:y instanceof X?new I("validate",`报表 ${u} 模板校验失败:${y.message}`,y):new I("fetch",`报表 ${u} 模板加载失败:${y instanceof Error?y.message:String(y)}`,y)}else A=T.template;let v;try{v=await He(T.load?T.load(k):T.datasets??{},i)}catch(y){throw i?.aborted?fe(i):y instanceof I?y:new I("fetch",`报表 ${u} 取数失败:${y instanceof Error?y.message:String(y)}`,y)}q(i),Ct(v,u);let V;try{V=ze(A,v,T.pagination)}catch(y){throw new I("validate",`报表 ${u} 排版失败:${y instanceof Error?y.message:String(y)}`,y)}for(const y of V.plan.pages)h.push(y);m.push(...V.warnings.map(y=>`${u}: ${y}`))}q(i);const w={schemaVersion:x.RENDER_PLAN_SCHEMA_VERSION,pages:h},d=be(w);if(!d.ok)throw new I("validate",`渲染计划校验失败:${d.errors.slice(0,3).map(S=>`${S.path}: ${S.message}`).join("; ")}`);m.push(...d.warnings.map(S=>`${S.path}: ${S.message}`));const p=a??t.onWarning??(S=>console.warn("[mach-report]",S));for(const S of m)q(i),p(S);return q(i),w},{getParamDefs:o=>et.getReportParamDefs(e,o)})}exports.CSS_DPI=g.CSS_DPI;exports.DEFAULT_BORDER_PT=g.DEFAULT_BORDER_PT;exports.DEFAULT_FONT_PT=g.DEFAULT_FONT_PT;exports.DEFAULT_STROKE_COLOR=g.DEFAULT_STROKE_COLOR;exports.DEFAULT_TEXT_COLOR=g.DEFAULT_TEXT_COLOR;exports.LINE_HEIGHT=g.LINE_HEIGHT;exports.MM_PER_INCH=g.MM_PER_INCH;exports.PAPER_SIZES=g.PAPER_SIZES;exports.SCHEMA_VERSION_MACH=g.SCHEMA_VERSION_MACH;exports.mmToPx=g.mmToPx;exports.mmToPxFactor=g.mmToPxFactor;exports.ptToPx=g.ptToPx;exports.pxToMm=g.pxToMm;exports.resolveBoxBorders=g.resolveBoxBorders;exports.resolveFontSize=g.resolveFontSize;exports.resolveGridLayout=g.resolveGridLayout;exports.resolveLineHeight=g.resolveLineHeight;exports.resolveStroke=g.resolveStroke;exports.resolveTextColor=g.resolveTextColor;exports.round=g.round;exports.RENDER_PLAN_SCHEMA_VERSION=x.RENDER_PLAN_SCHEMA_VERSION;exports.charWidthEm=x.charWidthEm;exports.createCanvasMeasurer=x.createCanvasMeasurer;exports.createHeuristicMeasurer=x.createHeuristicMeasurer;exports.heuristicMeasurer=x.heuristicMeasurer;exports.isImageBackedComponent=x.isImageBackedComponent;exports.isRichText=x.isRichText;exports.measureTextMm=x.measureTextMm;exports.wrapText=x.wrapText;exports.PageBuilder=qe;exports.REPORT_TEMPLATE_DOCUMENT_VERSION=Ee;exports.ReportSourceError=I;exports.ReportTemplateError=X;exports.TemplateBuilder=Ye;exports.assertRenderPlan=it;exports.classOf=L;exports.computePageWindow=Ve;exports.createCanvasPager=Mt;exports.createReportSource=_t;exports.createTableTemplate=wt;exports.createTemplate=bt;exports.createTemplateRegistry=Nt;exports.defineReport=Rt;exports.defineReportTemplate=At;exports.evalStyleRule=Fe;exports.formatValue=Me;exports.measurePageSizePx=$e;exports.paginateTemplate=ze;exports.parseDateLocal=Oe;exports.parseReportTemplate=kt;exports.planFontSizePx=ut;exports.renderComponent=we;exports.renderPage=We;exports.renderPlan=ht;exports.renderPlanToCanvas=Je;exports.renderPlanToImages=yt;exports.resolvePaper=Te;exports.serializeReportTemplate=xt;exports.toExcelNumberFormat=ye;exports.toNumber=de;exports.validateComponent=he;exports.validatePage=Be;exports.validateRenderPlan=be;exports.validateReportTemplate=Ae;exports.validateReportTemplateDocument=Ke;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("./defaults-DOO1yHwx.cjs"),h=require("./grid-geometry-bkciiZ4Q.cjs"),B=require("./render-plan-CfJ3wf1l.cjs"),N=require("./textwrap-oD-t4b4B.cjs"),ze=require("./page-window-index-DEjnM6IB.cjs"),je=require("./report-params-D1gZ1DME.cjs");function re(e){if(!e||e.kind==="date")return;const t=e.digits;if(!(t!==void 0&&(!Number.isInteger(t)||t<0||t>100))){if(e.kind==="percent"){const n=t??2;return`0${n?`.${"0".repeat(n)}`:""}%`}return t===void 0?e.thousands?"#,##0.###############":void 0:`${e.thousands?"#,##0":"0"}${t?`.${"0".repeat(t)}`:""}`}}function be(e){const t=/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/.exec(e.trim());if(t){const i=new Date(Number(t[1]),Number(t[2])-1,Number(t[3]));return Number.isNaN(i.getTime())?null:i}const n=new Date(e);return Number.isNaN(n.getTime())?null:n}function ie(e,t){return e.toLocaleString("en-US",{minimumFractionDigits:t,maximumFractionDigits:t})}function We(e,t){const n=i=>String(i).padStart(2,"0");return t.replace(/YYYY/g,String(e.getFullYear())).replace(/MM/g,n(e.getMonth()+1)).replace(/DD/g,n(e.getDate())).replace(/hh/g,n(e.getHours())).replace(/mm/g,n(e.getMinutes())).replace(/ss/g,n(e.getSeconds()))}function Ve(e,t,n){return n!=null?t?ie(e,n):e.toFixed(n):t?ie(e):String(e)}function K(e){const t=typeof e=="number"?e:Number(String(e).replace(/,/g,""));return Number.isFinite(t)?t:null}function ae(e,t){if(e==null||e===""||!t)return String(e??"");switch(t.kind){case"number":{const n=K(e);return n==null?String(e):Ve(n,t.thousands===!0,t.digits)}case"percent":{const n=K(e);return n==null?String(e):`${ie(n*100,t.digits??2)}%`}case"date":{const n=t.pattern??"YYYY-MM-DD",i=e instanceof Date?e:be(String(e));return i?We(i,n):String(e)}default:return String(e)}}function we(e,t){const n=e[t.field];if(n==null||n==="")return!1;if(typeof t.value=="number"){const r=K(n);if(r==null)return!1;switch(t.op){case">":return r>t.value;case">=":return r>=t.value;case"<":return r<t.value;case"<=":return r<=t.value;case"==":return r===t.value;case"!=":return r!==t.value}}const i=String(n),o=String(t.value);switch(t.op){case"==":return i===o;case"!=":return i!==o;case">":return i>o;case">=":return i>=o;case"<":return i<o;case"<=":return i<=o}return!1}const Ge=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function j(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Je(e,t,n,i){const o=e[t];(typeof o!="number"||!Number.isFinite(o))&&i.push({path:`${n}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(o)}`})}function Ue(e,t,n){if(e!==void 0){const i=`${t}.table`;if(!j(e))n.push({path:i,message:"逻辑表来源应为对象"});else{(typeof e.id!="string"||!e.id.trim())&&n.push({path:`${i}.id`,message:"逻辑表 ID 应为非空字符串"});const o=e.role;["header","body","group-header","subtotal","grand-total"].includes(o)||n.push({path:`${i}.role`,message:"未知逻辑表行角色"});const r=e.rowIndex;(typeof r!="number"||!Number.isInteger(r)||(o==="header"?r!==-1:r<0))&&n.push({path:`${i}.rowIndex`,message:"表头索引应为 -1,内容行索引应为非负整数"}),(!Array.isArray(e.columnKeys)||e.columnKeys.some(a=>typeof a!="string"))&&n.push({path:`${i}.columnKeys`,message:"逻辑列字段应为字符串数组"}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&n.push({path:`${i}.layout`,message:"布局应为 page 或 wide"}),e.title!==void 0&&typeof e.title!="string"&&n.push({path:`${i}.title`,message:"逻辑表名称应为字符串"})}}}function qe(e,t,n,i){if(e!==void 0)if(!j(e)||!Array.isArray(e.cells))n.push({path:`${t}.grid.cells`,message:"grid.cells 应为二维数组"});else{const o=e.paddingMm;o!==void 0&&(typeof o!="number"||!Number.isFinite(o)||o<0)&&n.push({path:`${t}.grid.paddingMm`,message:"单元格内距应为有限非负数"}),e.cells.forEach((r,a)=>{if(!Array.isArray(r)){n.push({path:`${t}.grid.cells.${a}`,message:"行应为数组"});return}r.forEach((s,l)=>{s!=null&&j(s)&&Array.isArray(s.children)&&s.children.forEach((d,m)=>{Q(d,`${t}.grid.cells.${a}.${l}.children.${m}`,n,i)})})})}}function Ye(e,t,n){e!==void 0&&(Array.isArray(e)?e.forEach((i,o)=>{(!j(i)||!Array.isArray(i.segments))&&n.push({path:`${t}.richParagraphs.${o}`,message:"段落缺少 segments 数组"})}):n.push({path:`${t}.richParagraphs`,message:"richParagraphs 应为数组"}))}function Q(e,t,n,i=[]){if(!j(e)){n.push({path:t,message:"组件应为对象"});return}const o=e.kind;typeof o!="string"?n.push({path:`${t}.kind`,message:"组件缺少 kind 字符串"}):Ge.has(o)||i.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(o)},将以兜底方式渲染`});for(const r of["leftMm","topMm","widthMm","heightMm"])Je(e,r,t,n);typeof e.leftMm=="number"&&e.leftMm<-100&&n.push({path:`${t}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const r of["widthMm","heightMm"])typeof e[r]=="number"&&e[r]<0&&n.push({path:`${t}.${r}`,message:"组件尺寸不能为负数"});Ue(e.table,t,n),qe(e.grid,t,n,i),Ye(e.richParagraphs,t,n)}function Se(e,t,n,i=[]){if(!j(e)){n.push({path:t,message:"页应为对象"});return}const o=e.pageWidthMm,r=e.pageHeightMm;(typeof o!="number"||!Number.isFinite(o)||o<=0)&&n.push({path:`${t}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(o)}`}),(typeof r!="number"||!(r>0&&r<5e3))&&n.push({path:`${t}.pageHeightMm`,message:`页高非法: ${JSON.stringify(r)}`}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&n.push({path:`${t}.layout`,message:"布局应为 page 或 wide"});const a=e.components;Array.isArray(a)?Array.isArray(a)&&a.forEach((s,l)=>Q(s,`${t}.components.${l}`,n,i)):n.push({path:`${t}.components`,message:"components 应为数组"})}function se(e){const t=[],n=[],i=j(e)?e.pages:void 0;if(!Array.isArray(i))t.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{i.forEach((r,a)=>Se(r,`$.pages.${a}`,t,n)),i.length>2e3&&n.push({path:"$.pages",message:`页数异常大(${i.length} 页),渲染与打印耗时可能显著增加`});const o=i.reduce((r,a)=>r+(j(a)&&Array.isArray(a.components)?a.components.length:0),0);o>5e4&&n.push({path:"$.pages",message:`组件总数异常大(${o} 个),可能触发浏览器性能限制`})}return{ok:t.length===0,errors:t,warnings:n}}function Ke(e){const t=se(e);if(!t.ok){const n=t.errors.slice(0,3).map(i=>`${i.path}: ${i.message}`).join("; ");throw new Error(`渲染计划校验失败(${t.errors.length} 处): ${n}`)}return e.pages}function Xe(e){return{widthMm:e.widthMm,heightMm:e.heightMm,marginTopMm:e.marginTopMm??0,marginBottomMm:e.marginBottomMm??0,marginLeftMm:e.marginLeftMm??0,marginRightMm:e.marginRightMm??0,components:[]}}function Ze(e,t){return t.heightMm-(e.layout==="wide"?t.marginBottomMm:e.marginBottomMm??t.marginBottomMm)}function $e(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number")return String(e);if(typeof e=="boolean")return e?"是":"否";if(e instanceof Date)return e.toISOString().slice(0,10);try{return JSON.stringify(e)}catch{return String(e)}}function ve(e,t){let n=e.textMetrics.get(t);if(!n){const i=h.resolveFontSize(t).fontSizePt;n={measureOptions:{fontSizePt:i,bold:t.bold,letterSpacingPt:t.letterSpacing},lineMm:i*(t.lineHeight??_.LINE_HEIGHT)*25.4/72},e.textMetrics.set(t,n)}return n}function Te(e,t){return t?.kind==="number"||t?.kind==="percent"?"right":t?.kind==="date"||e instanceof Date||typeof e=="boolean"?"center":typeof e=="number"&&Number.isFinite(e)?"right":"left"}function Qe(e){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e}function et(e,t){const n=e.fontSizePt??_.DEFAULT_FONT_PT,i=e.paddingMm??1,o=e.columns.map(c=>c.align??c.style?.align??e.align??"left"),r=e.columns.map((c,u)=>({...h.mergeComponentStyles({fontSize:n,verticalAlign:"middle"},c.style),align:o[u]==="auto"?"left":o[u]})),a=r.map((c,u)=>o[u]==="auto"?{left:c,center:{...c,align:"center"},right:{...c,align:"right"}}:void 0),s=e.columns.map((c,u)=>c.rules?.map(y=>{const b=a[u];if(b)return{left:h.mergeComponentStyles(b.left,y.style),center:h.mergeComponentStyles(b.center,y.style),right:h.mergeComponentStyles(b.right,y.style)};const w=h.mergeComponentStyles(r[u],y.style);return{left:w,center:w,right:w}})),l=e.columns.map(c=>{let u=h.mergeComponentStyles({fontSize:n,bold:e.headerBold??!0,align:"center",verticalAlign:"middle",backgroundColor:e.headerBackgroundColor},c.style);return e.headerAlign!==void 0&&(u.align=e.headerAlign),u=h.mergeComponentStyles(u,e.headerStyle),c.headerAlign!==void 0&&(u.align=c.headerAlign),h.mergeComponentStyles(u,c.headerStyle)}),d=e.columns.map(c=>c.header);let m=e.rowHeightMm??0;for(let c=0;c<d.length;c++){const u=l[c],y=h.resolveFontSize(u).fontSizePt,b=N.wrapText(d[c],e.columns[c].widthMm-i*2,{fontSizePt:y,bold:u.bold,letterSpacingPt:u.letterSpacing},t),w=y*(u.lineHeight??_.LINE_HEIGHT)*25.4/72;m=Math.max(m,Math.max(b.length,1)*w+i*2)}const f=d.map((c,u)=>({text:c,style:l[u]})),p=e.border===!1?{borderTop:!1,borderRight:!1,borderBottom:!1,borderLeft:!1}:{borderBottom:!0,borderLeft:!0,borderRight:!0,borderTop:!0},g=e.columns.map(c=>c.widthMm);return{fontSizePt:n,paddingMm:i,cellStyles:r,autoStyles:a,ruleStyles:s,textMetrics:new WeakMap,numberFormats:e.columns.map(c=>re(c.format)),borderStyle:p,headerHeightMm:m,headerGrid:{cells:[f],colWidthsMm:g,rowHeightsMm:[m],paddingMm:i},colWidthsMm:g,columns:e.columns}}function pe(e,t,n){const i=e.columns;let o=e.rowHeightFloorMm;const r=new Array(i.length);for(let a=0;a<i.length;a++){const s=i[a],l=t[s.field],d=e.autoStyles[a]?Te(l,s.format):"left";let m=e.autoStyles[a]?.[d]??e.cellStyles[a];if(s.rules)for(let y=0;y<s.rules.length;y++){const b=s.rules[y];if(we(t,b.when)){m=e.ruleStyles[a][y][d];break}}const f=s.format?ae(l,s.format):$e(l),p=ve(e,m),g=N.wrapText(f,s.widthMm-e.paddingMm*2,p.measureOptions,n);o=Math.max(o,g.length*p.lineMm+e.paddingMm*2);const c=Qe(l),u={text:f,style:m};c!==void 0&&(u.value=c),typeof c=="number"&&e.numberFormats[a]!==void 0&&(u.numberFormat=e.numberFormats[a]),r[a]=u}return{grid:{cells:[r],colWidthsMm:e.colWidthsMm,rowHeightsMm:[o],paddingMm:e.paddingMm},heightMm:o}}function*tt(e,t){if(!t){for(const i of e)yield{kind:"row",row:i};return}const n=new Map;for(const i of e){const o=$e(i[t.field]),r=n.get(o);r?r.push(i):n.set(o,[i])}for(const[i,o]of n){yield{kind:"groupHeader",label:(t.headerTemplate??"{value}").replace(/\{value\}/g,i),firstRow:o[0]};for(const r of o)yield{kind:"row",row:r};t.subtotal?.length&&(yield{kind:"subtotal",label:t.subtotalLabel??"小计",rows:o})}}function nt(e,t){let n=0;for(const i of e){const o=typeof i[t]=="number"?i[t]:Number(i[t]);Number.isFinite(o)&&(n+=o)}return n}function Ee(e,t,n){return new Map(n.map(i=>{const o=e.find(a=>a.field===i)?.format??{kind:"number",thousands:!0},r=nt(t,i);return[i,{text:ae(r,o),value:r,numberFormat:re(o)}]}))}function Pe(e,t){const n=e.findIndex(i=>t.includes(i.field));return n>0?n:1}function oe(e,t,n,i,o,r){const a=[],s=Math.max(1,Math.min(r,e.columns.length)),l=h.mergeComponentStyles({fontSize:e.fontSizePt},o);a.push({text:n,colSpan:s,style:{bold:!0,...l}});for(let f=s;f<e.columns.length;f++){const p=e.columns[f],g=i.get(p.field),c=e.autoStyles[f]?.[Te(g?.value,p.format)]??e.cellStyles[f];a.push({...g,text:g?.text??"",style:h.mergeComponentStyles(c,o)})}let d=e.rowHeightFloorMm,m=0;for(const f of a){let p=0;const g=m+(f.colSpan??1);for(;m<g;m++)p+=e.colWidthsMm[m]??0;const c=ve(e,f.style),u=N.wrapText(f.text??"",p-e.paddingMm*2,c.measureOptions,t);d=Math.max(d,u.length*c.lineMm+e.paddingMm*2)}return{grid:{cells:[a],colWidthsMm:e.colWidthsMm,rowHeightsMm:[d],paddingMm:e.paddingMm},heightMm:d}}function it(e,t,n){const{templatePage:i,current:o,warnings:r,nextId:a,pushCurrent:s}=n,l=()=>Ze(i,o),d=o.marginTopMm,m={id:n.tableId,columnKeys:e.columns.map(S=>S.field),...e.layout===void 0?{}:{layout:e.layout},...e.title===void 0?{}:{title:e.title}};let f=0;const p={kind:"rect",leftMm:e.leftMm,topMm:0,widthMm:e.widthMm,heightMm:t.headerHeightMm,grid:t.headerGrid,nid:a("listh"),table:{...m,role:"header",rowIndex:-1},style:t.borderStyle},g=S=>o.components.push({...p,topMm:S});let c=e.topMm;g(c),c+=t.headerHeightMm+n.mmPerRow;function u(){const S=i.layout==="wide"?0:e.topMm;return e.headerEveryPage!==!1?S+t.headerHeightMm:i.layout==="wide"?0:d}function y(){const S=i.layout==="wide"?0:o.marginBottomMm;return i.heightMm-S-u()}function b(S){if(c+S<=l())return;s(),o.components=[],o.heightMm=i.heightMm,i.layout==="wide"&&(o.marginTopMm=0,o.marginBottomMm=0);const D=i.layout==="wide"?0:e.topMm;e.headerEveryPage!==!1?(g(D),c=D+t.headerHeightMm):c=i.layout==="wide"?0:d}function w(S,D,V){const z=y();S.heightMm>z&&r.push(`列表 ${e.id??e.dataset} 行高 ${S.heightMm.toFixed(2)}mm 超出单页可用高度 ${z.toFixed(2)}mm,预览与打印可能截断内容`),b(S.heightMm),o.components.push({kind:"rect",leftMm:e.leftMm,topMm:c,widthMm:e.widthMm,heightMm:S.heightMm,grid:S.grid,nid:a(D),table:{...m,role:V,rowIndex:f++},style:t.borderStyle}),c+=S.heightMm}function k(S){S<=y()&&b(S)}return{keepTogether:k,placeGridRow:w}}function ot(e,t,n,i,o){if(!e.grandTotal)return;const r=typeof e.grandTotal=="object"?e.grandTotal:void 0,a=r?.fields??e.groupBy?.subtotal??[];if(a.length===0){i.warnings.push(`列表 ${e.id??""} 配置了 grandTotal 但未提供合计字段(groupBy.subtotal 或 grandTotal.fields)`);return}const s=oe(n,i.measurer,r?.label??"合计",Ee(e.columns,t,a),r?.style??{},Pe(e.columns,a));o.placeGridRow(s,"listgt","grand-total")}function rt(e,t,n){const i=e.columns.reduce((d,m)=>d+m.widthMm,0),o=i>e.widthMm?e.widthMm/i:1,r=o===1?e:{...e,columns:e.columns.map(d=>({...d,widthMm:d.widthMm*o}))},a={...et(r,n.measurer),rowHeightFloorMm:r.rowHeightMm??0},s=it(r,a,n);let l;for(const d of tt(t,r.groupBy))if(d.kind==="row")s.placeGridRow(l??pe(a,d.row,n.measurer),"listr","body"),l=void 0;else if(d.kind==="groupHeader"){const m=oe(a,n.measurer,d.label,new Map,r.groupBy?.headerStyle??{},r.columns.length);l=pe(a,d.firstRow,n.measurer),r.groupBy?.keepWithNext!==!1&&s.keepTogether(m.heightMm+l.heightMm),s.placeGridRow(m,"listg","group-header")}else{const m=r.groupBy?.subtotal??[],f=oe(a,n.measurer,d.label,Ee(r.columns,d.rows,m),r.groupBy?.subtotalStyle??{},Pe(r.columns,m));s.placeGridRow(f,"listst","subtotal")}ot(r,t,a,n,s)}function ye(e){return e.kind==="text"&&typeof e.text=="string"&&(e.text.includes("{page}")||e.text.includes("{totalPages}"))}function at(e,t,n,i,o,r){const a={pageWidthMm:t.widthMm,pageHeightMm:t.heightMm,...e.layout===void 0?{}:{layout:e.layout},marginTopMm:t.marginTopMm,marginBottomMm:t.marginBottomMm,marginLeftMm:t.marginLeftMm,marginRightMm:t.marginRightMm,components:t.components};i.push(a);for(const s of n){const l={...s,text:String(s.text??"").replace(/\{page\}/g,String(i.length))};a.components.push(l),l.text.includes("{totalPages}")&&o.push(l)}if(e.layout==="wide"){const s=a.components.reduce((l,d)=>Math.max(l,d.topMm+d.heightMm),0);a.marginBottomMm=r?e.marginBottomMm??0:0,a.pageHeightMm=Math.max(1,s+a.marginBottomMm)}}function ke(e,t,n={}){const i=typeof n=="number"?{mmPerRow:n}:n,o=[],r=[],a=[];let s=0;const l=d=>`${d}_${(++s).toString(36)}`;for(const[d,m]of e.pages.entries()){const f=Xe(m),p=m.components.filter(ye),g=(c=!1)=>at(m,f,p,r,a,c);for(const[c,u]of m.components.entries()){if(ye(u))continue;if(u.kind!=="list"){f.components.push(u);continue}const y=t[u.dataset];Array.isArray(y)||o.push(`数据集 ${u.dataset} 未提供数据,列表 ${u.id??""} 输出为空`),rt(u,Array.isArray(y)?y:[],{templatePage:m,current:f,warnings:o,nextId:l,pushCurrent:g,measurer:i.measurer??N.heuristicMeasurer,mmPerRow:i.mmPerRow??0,tableId:`table:${d}:${c}`})}g(!0)}for(const d of a)d.text=d.text.replace(/\{totalPages\}/g,String(r.length));return{plan:{schemaVersion:B.RENDER_PLAN_SCHEMA_VERSION,pages:r},warnings:o}}const st={root:"mr-root",page:"mr-page",comp:"mr-comp",text:"mr-text",lines:"mr-lines",line:"mr-line",rich:"mr-rich",paragraph:"mr-paragraph",segment:"mr-segment",image:"mr-image",shape:"mr-shape",grid:"mr-grid",row:"mr-row",cell:"mr-cell",unknown:"mr-unknown"};function P(e,t){return t?.classNames?.[e]??st[e]}class lt{constructor(){this.props=[]}add(t,n){return n==null||n===!1||n===""?this:(this.props.push([t,String(n)]),this)}mm(t,n,i,o=2){return this.add(t,`${h.round(h.mmToPx(n,i),o)}px`)}toString(){let t="";for(const[n,i]of this.props)t+=`${n}:${i};`;return t}applyTo(t){const n=this.toString();n&&(t.style.cssText=n)}}function T(e,t="unset"){return new lt().add("all",t).add("display",e).add("box-sizing","border-box")}function Ae(e,t,n){e.add("color",t.color).add("font-family",t.fontFamily).add("font-weight",t.bold!=null?t.bold?"700":"400":void 0).add("font-style",t.italic!=null?t.italic?"italic":"normal":void 0).add("text-decoration",t.underline!=null?t.underline?"underline":"none":void 0).add("letter-spacing",t.letterSpacing!=null?`${t.letterSpacing}pt`:void 0).add("line-height",String(h.resolveLineHeight(t))).add("text-align",t.align);const i=h.resolveFontSize(t,n);e.add("font-size",`${h.round(i.fontSizePx,2)}px`)}function dt(e,t,n){const i=t.style??{};Ae(e,i,n),e.add("background-color",i.backgroundColor).add("opacity",i.opacity!=null?String(i.opacity):void 0).add("transform",i.rotateDeg?`rotate(${i.rotateDeg}deg)`:void 0)}function mt(e,t,n,i,o,r){const a=e.cell,s=r.createElement("td");s.className=P("cell",o),s.setAttribute("role",t.table?.role==="header"?"columnheader":"cell"),a.colSpan&&(s.colSpan=a.colSpan),a.rowSpan&&(s.rowSpan=a.rowSpan);const l=h.mergeComponentStyles(t.style,a.style),d=T("block").add("position","absolute").mm("left",e.xMm,i).mm("top",e.yMm,i).mm("width",e.widthMm,i).mm("height",e.heightMm,i).add("background-color",l.backgroundColor).add("vertical-align",l.verticalAlign??"middle");Ae(d,l,i),d.applyTo(s);const m=r.createElement("div");m.className="mr-cell-content",T("flex").add("position","absolute").mm("left",n,i).mm("right",n,i).mm("top",n,i).mm("bottom",n,i).add("flex-direction","column").add("justify-content",l.verticalAlign==="top"?"flex-start":l.verticalAlign==="bottom"?"flex-end":"center").add("overflow-wrap","anywhere").add("overflow","hidden").applyTo(m),a.text!=null&&m.append(a.text);for(const f of a.children??[])m.appendChild(le(f,i,o,r));return s.appendChild(m),s}function ct(e,t,n,i){const o=h.resolveBoxBorders(t.style),r=o.inner?[...e.edges]:[];o.top&&r.push({kind:"h",pos:0,from:0,to:t.widthMm}),o.bottom&&r.push({kind:"h",pos:t.heightMm,from:0,to:t.widthMm}),o.left&&r.push({kind:"v",pos:0,from:0,to:t.heightMm}),o.right&&r.push({kind:"v",pos:t.widthMm,from:0,to:t.heightMm});const a=h.resolveStroke(t.style),s=`${h.round(a.widthPt*n/72,2)}px solid ${a.color}`;return r.map(l=>{const d=i.createElement("div");d.className="mr-grid-edge",d.setAttribute("aria-hidden","true");const m=l.kind==="h";return T("block").add("position","absolute").add("pointer-events","none").mm("left",m?l.from:l.pos,n).mm("top",m?l.pos:l.from,n).mm("width",m?l.to-l.from:0,n).mm("height",m?0:l.to-l.from,n).add(m?"border-top":"border-left",s).applyTo(d),d})}function ft(e,t,n,i,o){const r=o.createElement("table");r.className=P("grid",i),r.setAttribute("role","table"),T("block").add("position","relative").add("width","100%").add("height","100%").applyTo(r);const a=h.resolveGridLayout(e,t.widthMm,t.heightMm),s=o.createElement("tbody");T("contents").applyTo(s),r.appendChild(s);const l=e.cells.map(()=>{const m=o.createElement("tr");return m.className=P("row",i),m.setAttribute("role","row"),T("contents").applyTo(m),s.appendChild(m),m});for(const m of a.cells)l[m.ri].appendChild(mt(m,t,e.paddingMm??.5,n,i,o));const d=o.createElement("div");return T("block").add("position","relative").add("width","100%").add("height","100%").applyTo(d),d.append(r,...ct(a,t,n,o)),d}function ht(e,t,n,i){const o=i.createElement("div");o.className=P("paragraph",n),T("block").add("text-align",e.align).add("line-height",e.lineHeight!=null?String(e.lineHeight):void 0).mm("margin-top",e.spaceBeforeMm??0,t).mm("margin-bottom",e.spaceAfterMm??0,t).mm("text-indent",e.indentMm??0,t).applyTo(o);for(const r of e.segments||[]){const a=i.createElement("span");a.className=P("segment",n),a.textContent=r.kind==="field"?r.field??"":r.text??"";const s=T("inline");if(r.style){const l=r.style;s.add("color",l.color).add("font-family",l.fontFamily).add("font-weight",l.bold!=null?l.bold?"700":"400":void 0).add("font-style",l.italic!=null?l.italic?"italic":"normal":void 0).add("text-decoration",l.underline!=null?l.underline?"underline":"none":void 0),(l.fontSize!=null||l.fontSizePx!=null)&&s.add("font-size",`${h.round(h.resolveFontSize(l,t).fontSizePx,2)}px`)}s.applyTo(a),o.appendChild(a)}return o}function ut(e,t,n,i){if(B.isRichText(e)){const o=i.createElement("div");o.className=P("rich",n),T("block").applyTo(o);for(const r of e.richParagraphs)o.appendChild(ht(r,t,n,i));return o}if(Array.isArray(e.lines)&&e.lines.length>0){const o=i.createElement("div");o.className=P("lines",n),T("block").applyTo(o);for(const r of e.lines){const a=i.createElement("div");a.className=P("line",n),a.textContent=r,T("block").add("white-space","pre").add("min-height","1lh").applyTo(a),o.appendChild(a)}return o}return e.text??""}function gt(e,t,n,i){const o=i.createElement("div");o.className=P("text",n);const r=e.style||{};return T("flex").add("width","100%").add("height","100%").add("flex-direction","column").add("justify-content",r.verticalAlign==="middle"?"center":r.verticalAlign==="bottom"?"flex-end":"flex-start").add("overflow-wrap","anywhere").add("overflow","hidden").applyTo(o),o.append(ut(e,t,n,i)),o}function pt(e,t,n){const i=n.createElement("img");return i.className=P("image",t),i.src=e.imageData,T("block").add("width","100%").add("height","100%").add("object-fit","contain").applyTo(i),i.alt=e.kind,i}function Me(e,t,n,i){const o=i.createElement("div");o.className=P("shape",n);const r=e.style||{},a=h.resolveStroke(r),s=h.resolveBoxBorders(r),l=`${h.round(a.widthPt*t/72,2)}px solid ${a.color}`,d=T("block");return e.grid?d.add("position","relative"):e.kind==="rect"?(s.top&&d.add("border-top",l),s.right&&d.add("border-right",l),s.bottom&&d.add("border-bottom",l),s.left&&d.add("border-left",l)):e.kind==="ellipse"?(s.inner&&d.add("border",l).add("border-radius","50%"),r.backgroundColor&&d.add("background-color",r.backgroundColor)):e.kind==="line"&&d.add("height","0").add("border-top",l),d.add("box-sizing","border-box").add("width","100%").add("height","100%"),d.applyTo(o),o}function le(e,t,n,i){const o=i.createElement("div");o.className=`${P("comp",n)} mr-kind-${e.kind}`;const r=T("block").add("position","absolute").mm("left",e.leftMm,t).mm("top",e.topMm,t).mm("width",e.widthMm,t).mm("height",e.heightMm,t).add("box-sizing","border-box");if(dt(r,e,t),r.applyTo(o),B.isImageBackedComponent(e))return o.appendChild(pt(e,n,i)),o;if(e.kind==="text")return o.appendChild(gt(e,t,n,i)),o;if(e.grid){const s=Me(e,t,n,i);return s.appendChild(ft(e.grid,e,t,n,i)),o.appendChild(s),o}if(e.kind==="line"||e.kind==="rect"||e.kind==="ellipse"||e.kind==="chart")return o.appendChild(Me(e,t,n,i)),o;const a=i.createElement("div");return a.className=P("unknown",n),T("block").applyTo(a),a.textContent=e.fallbackText??"",o.appendChild(a),o}function xe(e,t,n,i){const o=i.createElement("div");o.className=P("page",n),T("block","initial").add("position","relative").add("font-family",'"Microsoft YaHei", sans-serif').add("font-size",`${h.round(h.resolveFontSize(void 0,t).fontSizePx,2)}px`).add("line-height",String(h.resolveLineHeight(void 0))).add("white-space","pre-wrap").add("direction","ltr").mm("width",e.pageWidthMm,t).mm("height",e.pageHeightMm,t).add("background-color","#fff").add("color",_.DEFAULT_TEXT_COLOR).add("overflow","hidden").add("box-sizing","border-box").applyTo(o);for(const r of e.components)o.appendChild(le(r,t,n,i));return o}function yt(e,t,n={}){const i=n.dpi??96,o=t.createElement("div");return o.className=P("root",n),T("block").applyTo(o),o.dataset.schemaVersion=e.schemaVersion,e.pages.forEach(r=>{o.appendChild(xe(r,i,n,t))}),o}function Ce(e){return ze.createPageWindowIndex(e.pageHeightsPx,e.gapPx).window(e.viewportHeightPx,e.scrollTopPx,e.overscan)}const de=96/25.4;function me(e,t=96){const n=t/96*de;return{widthPx:Math.max(1,Math.round(e.pageWidthMm*n)),heightPx:Math.max(1,Math.round(e.pageHeightMm*n))}}function Mt(e,t,n){const i=document.createElement("canvas"),{widthPx:o,heightPx:r}=me(e,n);i.width=Math.round(o*t),i.height=Math.round(r*t),i.style.width=`${o}px`,i.style.height=`${r}px`;const a=i.getContext("2d");if(!a)throw new Error("当前环境不支持 Canvas 2D(测试需真浏览器,见 e2e/canvas.spec.ts)");return a.scale(t,t),a.fillStyle="#ffffff",a.fillRect(0,0,o,r),{canvas:i,ctx:a}}function bt(e,t=96){return h.resolveFontSize(e,t).fontSizePx}function Ne(e,t,n,i,o,r,a,s="top"){e.font=`${t.italic?"italic ":""}${t.bold?"bold ":""}${t.fontSizePx}px ${a}`,e.fillStyle=t.color,e.textBaseline="alphabetic";const l=t.fontSizePx*t.lineHeight,d=t.text===""?[""]:t.text.split(`
|
|
2
|
+
`),m=d.length*l;let f=i;s==="middle"?f=i+(r-m)/2:s==="bottom"&&(f=i+r-m),d.forEach((p,g)=>{e.textAlign=t.align==="center"?"center":t.align==="right"?"right":"left";const c=t.align==="center"?n+o/2:t.align==="right"?n+o:n;e.fillText(p,c,f+g*l+t.fontSizePx*.8,o)}),e.textAlign="left"}function wt(e,t,n,i,o,r,a,s,l){const d=h.resolveBoxBorders(n.style);if(!d.inner)return;const m=h.resolveStroke(n.style);e.strokeStyle=m.color,e.lineWidth=h.ptToPx(m.widthPt,l);for(const f of t.edges)e.beginPath(),f.kind==="v"?(e.moveTo(i+f.pos*s,o+f.from*s),e.lineTo(i+f.pos*s,o+f.to*s)):(e.moveTo(i+f.from*s,o+f.pos*s),e.lineTo(i+f.to*s,o+f.pos*s)),e.stroke();Re(e,d,i,o,r,a)}function Re(e,t,n,i,o,r){e.beginPath(),t.top&&(e.moveTo(n,i),e.lineTo(n+o,i)),t.right&&(e.moveTo(n+o,i),e.lineTo(n+o,i+r)),t.bottom&&(e.moveTo(n+o,i+r),e.lineTo(n,i+r)),t.left&&(e.moveTo(n,i+r),e.lineTo(n,i)),e.stroke()}function St(e,t,n,i,o,r,a,s,l,d,m){const f=h.resolveGridLayout(t,r/s,a/s);for(const g of f.cells){const c=g.cell.style?.backgroundColor??n.style?.backgroundColor;c&&(e.fillStyle=c,e.fillRect(i+g.xMm*s,o+g.yMm*s,g.widthMm*s,g.heightMm*s))}wt(e,f,n,i,o,r,a,s,l);const p=t.paddingMm??.5;for(const g of f.cells){const c=g.cell.text??"";if(!c)continue;const u=h.mergeComponentStyles(n.style,g.cell.style),y=h.resolveFontSize(u,l),b=Math.max(0,g.widthMm-2*p),w=N.wrapText(c,b,{fontSizePt:y.fontSizePt,bold:u.bold},m).join(`
|
|
3
|
+
`);Ne(e,{text:w,fontSizePx:y.fontSizePx,bold:u.bold??!1,italic:u.italic,color:h.resolveTextColor(u,_.DEFAULT_TEXT_COLOR),align:u.align??"left",lineHeight:h.resolveLineHeight(u)},i+(g.xMm+p)*s,o+(g.yMm+p)*s,b*s,Math.max(0,g.heightMm-2*p)*s,u.fontFamily??d,u.verticalAlign??"middle")}}function $t(e,t,n,i,o,r,a,s,l){const d=t.style??{},m=h.resolveFontSize(d,a),f=B.isRichText(t)?t.richParagraphs.map(p=>p.segments.map(g=>g.text??g.field??"").join("")).join(`
|
|
4
|
+
`):t.lines?.length?t.lines.join(`
|
|
5
|
+
`):N.wrapText(t.text??"",t.widthMm,{fontSizePt:m.fontSizePt,bold:d.bold},l).join(`
|
|
6
|
+
`);Ne(e,{text:f,fontSizePx:m.fontSizePx,bold:d.bold??!1,italic:d.italic,color:h.resolveTextColor(d),align:d.align??"left",lineHeight:h.resolveLineHeight(d)},n,i,o,r,d.fontFamily??s,d.verticalAlign)}function Le(e,t,n,i,o,r){const a=t.leftMm*n,s=t.topMm*n,l=t.widthMm*n,d=t.heightMm*n,m=t.style??{};if(t.grid){St(e,t.grid,t,a,s,l,d,n,i,o,r);return}switch(t.kind){case"text":{$t(e,t,a,s,l,d,i,o,r);break}case"rect":{const f=h.resolveStroke(m),p=h.resolveBoxBorders(m);m.backgroundColor&&(e.fillStyle=m.backgroundColor,e.fillRect(a,s,l,d)),p.inner&&(e.strokeStyle=f.color,e.lineWidth=h.ptToPx(f.widthPt,i),Re(e,p,a,s,l,d));break}case"line":{const f=h.resolveStroke({...m,borderColor:m.lineColor??m.borderColor});e.strokeStyle=f.color,e.lineWidth=h.ptToPx(f.widthPt,i),e.beginPath(),e.moveTo(a,s+d/2),e.lineTo(a+l,s+d/2),e.stroke();break}case"ellipse":{const f=h.resolveStroke(m);e.strokeStyle=f.color,e.lineWidth=h.ptToPx(f.widthPt,i),m.backgroundColor&&(e.fillStyle=m.backgroundColor,e.beginPath(),e.ellipse(a+l/2,s+d/2,l/2,d/2,0,0,Math.PI*2),e.fill()),e.beginPath(),e.ellipse(a+l/2,s+d/2,l/2,d/2,0,0,Math.PI*2),e.stroke();break}}}async function vt(e,t={}){if(typeof document>"u")throw new Error("renderPlanToImages 需要浏览器环境(SSR/Node 请在客户端钩子中调用)");const{format:n="png",quality:i=.92,...o}=t,{canvases:r}=Oe(e,o),a=n==="jpeg"?"image/jpeg":"image/png",s=[];for(const l of r)s.push(await new Promise(d=>l.toBlob(m=>d(m),a,i))??new Blob([],{type:a}));return{blobs:s}}function Oe(e,t={}){if(typeof document>"u")throw new Error("renderPlanToCanvas 需要浏览器环境(SSR 请在客户端钩子中调用)");const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),i=t.dpi??96,o=i/96*de,r=t.fontFamily??'"Microsoft YaHei", sans-serif',a=t.measurer??N.heuristicMeasurer,s=Math.max(0,t.start??0),l=Math.min(e.pages.length-1,t.end??e.pages.length-1),d=[];for(let m=s;m<=l;m++){const f=e.pages[m],{canvas:p,ctx:g}=Mt(f,n,i);for(const c of f.components)Le(g,c,o,i,r,a);d.push(p)}return{canvases:d}}function Tt(e,t={}){const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),i=t.dpi??96,o=i/96*de,r=t.fontFamily??'"Microsoft YaHei", sans-serif',a=t.measurer??N.heuristicMeasurer,s=t.overscan??1,l=t.gapPx??18,d=t.pagesPerFrame??1,m=e.pages.map(M=>M.pageHeightMm*o),f=Math.max(1,...e.pages.map(M=>M.pageWidthMm*o)),p={start:0,end:-1};let g=null,c=null,u=null,y=null,b=[],w=0,k=[];function S(){const M=g;M.innerHTML="",c=document.createElement("div"),c.style.cssText=`width:${f}px;margin:0 auto;`,u=document.createElement("div"),y=document.createElement("div"),c.appendChild(u),b=[];const R=Math.min(e.pages.length,3+s*2);for(let F=0;F<R;F++){const $=document.createElement("div");$.style.cssText=`margin:0 auto ${l}px;box-shadow:0 2px 8px rgba(0,0,0,.35);background:#fff;`,c.appendChild($),b.push($)}c.appendChild(y),M.appendChild(c)}function D(M,R){const F=e.pages[R],{widthPx:$,heightPx:A}=me(F,i);let L=M.firstElementChild;(!L||L.tagName!=="CANVAS")&&(L=document.createElement("canvas"),M.innerHTML="",M.appendChild(L)),L.width=Math.round($*n),L.height=Math.round(A*n),L.style.width=`${$}px`,L.style.height=`${A}px`;const G=L.getContext("2d");if(G){G.setTransform(1,0,0,1,0,0),G.scale(n,n),G.fillStyle="#ffffff",G.fillRect(0,0,$,A);for(const De of F.components)Le(G,De,o,i,r,a);L.dataset.canvasPage=String(R),M.style.height=`${A}px`,M.style.width=`${$}px`}}function V(M){p.start=M.start,p.end=M.end,u.style.height=`${M.start*l+m.slice(0,M.start).reduce(($,A)=>$+A,0)}px`;const R=e.pages.length-1-M.end;y.style.height=`${R*l+m.slice(M.end+1).reduce(($,A)=>$+A,0)}px`;const F=M.end-M.start+1;b.forEach(($,A)=>{if(A<F){$.style.display="";const L=M.start+A;$.style.height=`${m[L]??0}px`}else $.style.display="none"}),k=[];for(let $=M.start;$<=M.end;$++){const A=b[$-M.start];if(!A)continue;A.firstElementChild?.dataset?.canvasPage!==String($)&&k.push($)}z()}function z(){w||k.length===0||(w=requestAnimationFrame(()=>{w=0;let M=Math.max(1,d);for(;k.length>0&&M-- >0;){const R=k.shift(),F=b[R-p.start];F&&D(F,R)}k.length>0&&z()}))}function q(){w||(w=requestAnimationFrame(()=>{w=0;const M=g,R=Ce({pageHeightsPx:m,viewportHeightPx:M.clientHeight,scrollTopPx:M.scrollTop,overscan:s,gapPx:l});R.start!==p.start||R.end!==p.end?V(R):z()}))}let Y=null;return{attach(M){if(typeof document>"u")throw new Error("createCanvasPager 需要浏览器环境(SSR 请在客户端钩子中调用 attach)");g=M,S(),M.addEventListener("scroll",q,{passive:!0}),typeof ResizeObserver<"u"&&(Y=new ResizeObserver(()=>q()),Y.observe(M)),q()},destroy(){w&&cancelAnimationFrame(w),w=0,Y?.disconnect(),Y=null,g?.removeEventListener("scroll",q),k=[],c?.remove(),g=null},window(){return{...p}}}}function ce(e,t,n){let i,o;if(typeof e=="string"){const r=h.PAPER_SIZES[e];if(!r)throw new Error(`未知纸张预设 "${e}"(可用:${Object.keys(h.PAPER_SIZES).join("/")})`);i=r.widthMm,o=r.heightMm}else typeof e=="number"?(i=e,o=t??297):(i=e.widthMm,o=e.heightMm);return n?{widthMm:o,heightMm:i}:{widthMm:i,heightMm:o}}class _e{constructor(){this.pages=[],this.pending=null,this.templateParams=void 0}params(t){return this.templateParams=t,this}page(t="a4",n={},i){this.collect();const r=i!=null&&!("margins"in i)&&!("landscape"in i)&&("marginTopMm"in i||"marginBottomMm"in i||"marginLeftMm"in i||"marginRightMm"in i)?{margins:i}:typeof n=="number"?i??{}:n,{widthMm:a,heightMm:s}=ce(t,typeof n=="number"?n:void 0,r.landscape),l=r.margins??{};return this.pending=new Fe(this,{widthMm:a,heightMm:s,marginTopMm:l.marginTopMm??10,marginBottomMm:l.marginBottomMm??10,marginLeftMm:l.marginLeftMm??10,marginRightMm:l.marginRightMm??10}),this.pending}collect(){this.pending&&(this.pages.push(this.pending.buildPage()),this.pending=null)}build(){if(this.collect(),this.pages.length===0)throw new Error("模板至少需要一页:先调用 .page() 添加内容");return this.templateParams?{params:this.templateParams,pages:this.pages}:{pages:this.pages}}}class Fe{constructor(t,n){this.parent=t,this.page=n,this.components=[]}text(t,n={},i={}){return this.components.push({kind:"text",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??60,heightMm:n.heightMm??8,text:t,style:i}),this}list(t,n,i,o={}){return this.components.push({kind:"list",leftMm:n.leftMm??10,topMm:n.topMm??30,widthMm:n.widthMm??180,dataset:t,columns:i,...o}),this}rect(t,n={}){return this.components.push({kind:"rect",...t,style:n}),this}line(t,n,i,o={}){return this.components.push({kind:"line",leftMm:t,topMm:n,widthMm:i,heightMm:.5,style:o}),this}barcode(t,n){return this.components.push({kind:"barcode",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??40,heightMm:n.heightMm??12,fallbackText:t}),this}qrcode(t,n,i,o){return this.components.push({kind:"qrcode",leftMm:i,topMm:o,widthMm:n,heightMm:n,fallbackText:t}),this}buildPage(){return{...this.page,components:this.components}}done(){return this.parent}build(){return this.done().build()}}function Et(){return new _e}function O(e,t,n=!1){if(!Number.isFinite(e)||(n?e<0:e<=0))throw new Error(`${t} 必须是有限${n?"非负":"正"}数`)}function X(e,t,n){if(e!==void 0&&!["left","center","right","justify",...n?["auto"]:[]].includes(e))throw new Error(`${t} 必须是 left/center/right/justify${n?"/auto":""}`)}function Pt(e){const t=e.layout??"page";if(t!=="page"&&t!=="wide")throw new Error("layout 必须是 page 或 wide");if(t==="wide"&&(e.paper!==void 0||e.landscape!==void 0))throw new Error('宽表布局不能同时指定 paper 或 landscape;标准纸型请使用 layout: "page"');if(t!=="wide"&&e.columnWidthMm!==void 0)throw new Error('columnWidthMm 仅适用于 layout: "wide"');const n=e.columnWidthMm??30;return O(n,"columnWidthMm"),{layout:t,columnWidthMm:n}}function kt(e){const t=e.paper===void 0?"a4":e.paper;if(typeof t!="string"&&(typeof t!="object"||t===null)||e.landscape!==void 0&&typeof e.landscape!="boolean")throw new Error("paper 必须是纸张预设名或 { widthMm, heightMm } 对象,landscape 必须是布尔值");if(typeof t=="string"&&!Object.prototype.hasOwnProperty.call(h.PAPER_SIZES,t))throw new Error(`未知纸张预设 "${t}"(可用:${Object.keys(h.PAPER_SIZES).join("/")})`);const n=ce(t,void 0,e.landscape),i=n.widthMm,o=n.heightMm;return O(i,"纸张 widthMm"),O(o,"纸张 heightMm"),{widthMm:i,heightMm:o}}function At(e){if(e.margins!==void 0&&(!e.margins||typeof e.margins!="object"||Array.isArray(e.margins)))throw new Error("margins 必须是页边距对象");const t=e.margins??{},n={marginTopMm:t.marginTopMm===void 0?10:t.marginTopMm,marginBottomMm:t.marginBottomMm===void 0?10:t.marginBottomMm,marginLeftMm:t.marginLeftMm===void 0?10:t.marginLeftMm,marginRightMm:t.marginRightMm===void 0?10:t.marginRightMm};for(const[i,o]of Object.entries(n))O(o,i,!0);return n}function xt(e,t){const n=e.dataset===void 0?"detail":e.dataset;if(typeof n!="string"||!n.trim())throw new Error("dataset 必须是非空字符串");if(e.title!==void 0&&typeof e.title!="string")throw new Error("title 必须是字符串");const i=e.titleHeightMm===void 0?10:e.titleHeightMm,o=e.titleGapMm===void 0?4:e.titleGapMm;O(i,"titleHeightMm"),O(o,"titleGapMm",!0);const r=e.title!==void 0&&e.title.length>0,a=r?i+o:0;if(a>=t)throw new Error("标题高度与间距占满页面,必须为表格保留可用高度");return{dataset:n,titleHeightMm:i,hasTitle:r,titleSpaceMm:a}}function Ct(e){if(e.listOptions!==void 0&&(!e.listOptions||typeof e.listOptions!="object"||Array.isArray(e.listOptions)))throw new Error("listOptions 必须是列表配置对象");const t=e.listOptions??{};X(t.align,"listOptions.align",!0),X(t.headerAlign,"listOptions.headerAlign",!1);for(const n of["fontSizePt","rowHeightMm","paddingMm"]){const i=t[n];i!==void 0&&O(i,`listOptions.${n}`,n==="paddingMm")}return t}function Nt(e){let t=0,n=0;for(const[i,o]of e.entries()){if(!o||typeof o.header!="string"||typeof o.field!="string"||!o.field.trim())throw new Error(`columns[${i}] 需要字符串 header 与非空 field`);X(o.align,`columns[${i}].align`,!0),X(o.headerAlign,`columns[${i}].headerAlign`,!1),o.flex!==void 0&&O(o.flex,`columns[${i}].flex`),o.widthMm!==void 0?(O(o.widthMm,`columns[${i}].widthMm`),t+=o.widthMm):n=Math.max(n,o.flex??1)}return{fixedWidthMm:t,maxFlex:n}}function Rt(e,t,n,i){const{fixedWidthMm:o,maxFlex:r}=Nt(e.columns);if(t==="page"&&o>i)throw new Error(`固定列宽 ${o}mm 超出页面可用宽度 ${i}mm`);const a=i-o;if(t==="page"&&r>0&&a<=0)throw new Error("固定列占满页面可用宽度,自动列需要正的剩余宽度");const s=r>0?e.columns.reduce((d,m)=>d+(m.widthMm===void 0?(m.flex??1)/r:0),0):0;return{columns:e.columns.map(({widthMm:d,flex:m,...f},p)=>{const g=d??(t==="wide"?n*(m??1):a*((m??1)/r)/s);return O(g,`columns[${p}] 分配后的 widthMm`),{...f,widthMm:g}}),fixedWidthMm:o,maxFlex:r}}function Lt(e){if(!e||typeof e!="object")throw new Error("标准明细模板需要 options 对象");if(!Array.isArray(e.columns)||e.columns.length===0)throw new Error("columns 至少需要一列");const{layout:t,columnWidthMm:n}=Pt(e),i=kt(e);let o=i.widthMm;const r=i.heightMm,a=At(e);let s=o-a.marginLeftMm-a.marginRightMm;const l=r-a.marginTopMm-a.marginBottomMm;if(t==="page"&&s<=0||l<=0)throw new Error("页边距占满纸张,必须保留正的可用宽度和高度");const{dataset:d,titleHeightMm:m,hasTitle:f,titleSpaceMm:p}=xt(e,l),g=Ct(e),{columns:c,fixedWidthMm:u,maxFlex:y}=Rt(e,t,n,s);t==="wide"&&(s=c.reduce((w,k)=>w+k.widthMm,0),O(s,"宽表总列宽"),o=s+a.marginLeftMm+a.marginRightMm,O(o,"宽表总宽度"));const b={widthMm:o,heightMm:r,...a,components:[],...t==="wide"?{layout:t}:{}};return f&&b.components.push({kind:"text",text:e.title,leftMm:a.marginLeftMm,topMm:a.marginTopMm,widthMm:s,heightMm:m,style:{fontSize:16,bold:!0,align:"center",verticalAlign:"middle",...e.titleStyle}}),b.components.push({align:"auto",headerAlign:"center",...g,kind:"list",...t==="wide"?{layout:t}:{},...f?{title:e.title}:{},dataset:d,columns:c,leftMm:a.marginLeftMm,topMm:a.marginTopMm+p,widthMm:t==="wide"||y>0?s:u}),e.params===void 0?{pages:[b]}:{params:e.params,pages:[b]}}const fe="1.0";class W extends Error{constructor(t){super(`模板校验失败:${t.slice(0,3).map(n=>`${n.path}: ${n.message}`).join("; ")}`),this.errors=t,this.name="ReportTemplateError"}}const Ot=new Set(["__proto__","prototype","constructor"]),_t=new Set(["schemaVersion","id","name","revision","description","template"]),Ft=new Set(["left","center","right","justify"]),ne=2e5,Ht=64,he=1e7;function v(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function It(e,t,n){const i=Object.getPrototypeOf(e),o=Array.isArray(e);if(o?i!==Array.prototype:i!==Object.prototype&&i!==null)return n.push({path:t,message:"模板对象必须使用普通 JSON 对象原型"}),!1;if(o){const r=Object.keys(e);if(r.length!==e.length||r.some(a=>!/^(0|[1-9]\d*)$/.test(a)||Number(a)>=e.length))return n.push({path:t,message:"模板数组不能包含空位或额外属性"}),!1}return Object.getOwnPropertySymbols(e).length>0?(n.push({path:t,message:"模板不能包含 Symbol 键"}),!1):!0}function Bt(e,t,n,i){return Ot.has(e)?(i.push({path:n,message:"模板不能包含可能污染原型的键"}),!1):t.get||t.set||!t.enumerable?(i.push({path:n,message:"模板不能包含访问器或不可枚举字段"}),!1):!0}function Dt(e){return e===null||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e)}function ue(e,t){const n=new Set;let i=0,o=0,r=!1;const a=(s,l,d)=>{if(!r){if(++i>ne){i===ne+1&&t.push({path:l,message:"模板超过 JSON 节点安全上限"});return}if(d>Ht){t.push({path:l,message:"模板嵌套层级过深"});return}if(typeof s=="string"){o+=s.length,o>he&&(r=!0,t.push({path:l,message:"模板文本超过 1000 万字符的安全上限"}));return}if(!Dt(s)){if(!s||typeof s!="object"){t.push({path:l,message:"模板只允许 JSON 值,不允许函数、undefined 或非有限数字"});return}if(n.has(s)){t.push({path:l,message:"模板不能包含循环引用"});return}if(It(s,l,t)){n.add(s);for(const[m,f]of Object.entries(Object.getOwnPropertyDescriptors(s))){if(Array.isArray(s)&&m==="length")continue;const p=`${l}.${m}`;if(Bt(m,f,p,t)&&a(f.value,p,d+1),i>ne||r)break}n.delete(s)}}}};a(e,"$",0)}function E(e,t,n,i,o=!1){const r=e[t];r===void 0&&!o||(typeof r!="string"||o&&!r.trim())&&i.push({path:`${n}.${t}`,message:o?"应为非空字符串":"应为字符串"})}function x(e,t,n,i,o=0,r=!1){const a=e[t];a===void 0&&!r||(typeof a!="number"||!Number.isFinite(a)||a<o)&&i.push({path:`${n}.${t}`,message:`应为大于等于 ${o} 的有限数字`})}function U(e,t,n,i){e[t]!==void 0&&typeof e[t]!="boolean"&&i.push({path:`${n}.${t}`,message:"应为布尔值"})}function J(e,t,n,i=!1){e!==void 0&&!Ft.has(e)&&!(i&&e==="auto")&&n.push({path:t,message:`未知对齐方式${i?"(支持 auto)":""}`})}function I(e,t,n){if(e!==void 0){if(!v(e)){n.push({path:t,message:"样式应为对象"});return}J(e.align,`${t}.align`,n),e.verticalAlign!==void 0&&!["top","middle","bottom"].includes(e.verticalAlign)&&n.push({path:`${t}.verticalAlign`,message:"未知垂直对齐方式"});for(const i of["fontSize","fontSizePx","lineWidthPt","lineHeight"])x(e,i,t,n);for(const i of["letterSpacing","rotateDeg"])x(e,i,t,n,-1/0);x(e,"opacity",t,n),typeof e.opacity=="number"&&e.opacity>1&&n.push({path:`${t}.opacity`,message:"透明度不能大于 1"});for(const i of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])U(e,i,t,n);for(const i of["fontFamily","color","backgroundColor","lineColor","borderColor"])E(e,i,t,n)}}function zt(e,t,n){if(e===void 0)return;if(!Array.isArray(e)){n.push({path:t,message:"参数定义应为数组"});return}const i=new Set;e.forEach((o,r)=>{const a=`${t}.${r}`;if(!v(o)){n.push({path:a,message:"参数定义应为对象"});return}E(o,"field",a,n,!0),typeof o.field=="string"&&(i.has(o.field)&&n.push({path:`${a}.field`,message:"参数名重复"}),i.add(o.field)),o.type!==void 0&&!["text","number","date","select"].includes(o.type)&&n.push({path:`${a}.type`,message:"未知参数类型"});for(const s of["label","defaultValue","placeholder"])E(o,s,a,n);U(o,"required",a,n),o.options!==void 0&&(Array.isArray(o.options)?o.options.forEach((s,l)=>{const d=`${a}.options.${l}`;if(!v(s))n.push({path:d,message:"选项应为对象"});else for(const m of["label","value"])typeof s[m]!="string"&&n.push({path:`${d}.${m}`,message:"选项标签与值应为字符串(允许空白选项)"})}):n.push({path:`${a}.options`,message:"选项应为数组"}))})}function jt(e,t,n){if(!Array.isArray(e)||e.length===0){n.push({path:t,message:"列表至少需要一列"});return}e.forEach((i,o)=>{const r=`${t}.${o}`;if(!v(i)){n.push({path:r,message:"列应为对象"});return}if(typeof i.header!="string"&&n.push({path:`${r}.header`,message:"表头应为字符串(允许空白表头)"}),E(i,"field",r,n,!0),x(i,"widthMm",r,n,Number.MIN_VALUE,!0),I(i.style,`${r}.style`,n),I(i.headerStyle,`${r}.headerStyle`,n),J(i.align,`${r}.align`,n,!0),J(i.headerAlign,`${r}.headerAlign`,n),i.format!==void 0)if(!v(i.format)||!["number","percent","date"].includes(i.format.kind))n.push({path:`${r}.format`,message:"未知列格式"});else{const a=i.format.digits;a!==void 0&&(typeof a!="number"||!Number.isInteger(a)||a<0||a>100)&&n.push({path:`${r}.format.digits`,message:"小数位应为 0–100 的整数"}),U(i.format,"thousands",`${r}.format`,n),E(i.format,"pattern",`${r}.format`,n)}i.rules!==void 0&&(Array.isArray(i.rules)?i.rules.forEach((a,s)=>{const l=`${r}.rules.${s}`;if(!v(a)||!v(a.when)){n.push({path:l,message:"条件格式缺少 when 对象"});return}E(a.when,"field",`${l}.when`,n,!0),[">",">=","<","<=","==","!="].includes(a.when.op)||n.push({path:`${l}.when.op`,message:"未知条件运算符"}),typeof a.when.value!="number"&&typeof a.when.value!="string"&&n.push({path:`${l}.when.value`,message:"条件值应为数字或字符串"}),I(a.style,`${l}.style`,n)}):n.push({path:`${r}.rules`,message:"条件格式应为数组"}))})}function Wt(e,t,n){if(e!==void 0){if(!v(e)){n.push({path:t,message:"分组应为对象"});return}E(e,"field",t,n,!0);for(const i of["headerTemplate","subtotalLabel"])E(e,i,t,n);for(const i of["headerStyle","subtotalStyle"])I(e[i],`${t}.${i}`,n);U(e,"keepWithNext",t,n),e.subtotal!==void 0&&(!Array.isArray(e.subtotal)||e.subtotal.some(i=>typeof i!="string"))&&n.push({path:`${t}.subtotal`,message:"小计字段应为字符串数组"})}}function Vt(e,t,n){if(!(e===void 0||typeof e=="boolean")){if(!v(e)){n.push({path:t,message:"合计应为布尔值或对象"});return}E(e,"label",t,n),I(e.style,`${t}.style`,n),e.fields!==void 0&&(!Array.isArray(e.fields)||e.fields.some(i=>typeof i!="string"))&&n.push({path:`${t}.fields`,message:"合计字段应为字符串数组"})}}function Gt(e,t,n){for(const i of["leftMm","topMm"])x(e,i,t,n,-1/0,!0);x(e,"widthMm",t,n,Number.MIN_VALUE,!0),E(e,"dataset",t,n,!0),E(e,"title",t,n),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&n.push({path:`${t}.layout`,message:"布局应为 page 或 wide"}),jt(e.columns,`${t}.columns`,n);for(const i of["fontSizePt","rowHeightMm"])x(e,i,t,n,Number.MIN_VALUE);x(e,"paddingMm",t,n);for(const i of["headerBold","headerEveryPage","border"])U(e,i,t,n);E(e,"headerBackgroundColor",t,n),J(e.align,`${t}.align`,n,!0),J(e.headerAlign,`${t}.headerAlign`,n),I(e.headerStyle,`${t}.headerStyle`,n),Wt(e.groupBy,`${t}.groupBy`,n),Vt(e.grandTotal,`${t}.grandTotal`,n)}function He(e,t,n){I(e.style,`${t}.style`,n);for(const o of["text","rawText","imageData","fallbackText","nid","rkey"])E(e,o,t,n);if(e.lines!==void 0&&(!Array.isArray(e.lines)||e.lines.some(o=>typeof o!="string"))&&n.push({path:`${t}.lines`,message:"文本行应为字符串数组"}),Array.isArray(e.richParagraphs)&&e.richParagraphs.forEach((o,r)=>{if(!v(o))return;const a=`${t}.richParagraphs.${r}`;J(o.align,`${a}.align`,n);for(const s of["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"])x(o,s,a,n);Array.isArray(o.segments)&&o.segments.forEach((s,l)=>{const d=`${a}.segments.${l}`;if(!v(s)){n.push({path:d,message:"富文本片段应为对象"});return}s.kind!==void 0&&s.kind!=="text"&&s.kind!=="field"&&n.push({path:`${d}.kind`,message:"未知富文本片段类型"});for(const m of["text","field"])E(s,m,d,n);I(s.style,`${d}.style`,n)})}),!v(e.grid))return;const i=e.grid;x(i,"gapMm",`${t}.grid`,n),x(i,"paddingMm",`${t}.grid`,n);for(const o of["colWidthsMm","rowHeightsMm"]){const r=i[o];r!==void 0&&(!Array.isArray(r)||r.some(a=>typeof a!="number"||!Number.isFinite(a)||a<0))&&n.push({path:`${t}.grid.${o}`,message:"网格尺寸应为有限非负数字数组"})}Array.isArray(i.cells)&&i.cells.forEach((o,r)=>{Array.isArray(o)&&o.forEach((a,s)=>{const l=`${t}.grid.cells.${r}.${s}`;if(a!==null){if(!v(a)){n.push({path:l,message:"网格单元格应为对象或 null"});return}for(const d of["text","rawText","numberFormat"])E(a,d,l,n);for(const d of["colSpan","rowSpan"]){const m=a[d];m!==void 0&&(typeof m!="number"||!Number.isInteger(m)||m<=0)&&n.push({path:`${l}.${d}`,message:"跨度应为正整数"})}a.value!==void 0&&a.value!==null&&!["string","number","boolean"].includes(typeof a.value)&&n.push({path:`${l}.value`,message:"Excel 原始值应为字符串、数字、布尔值或 null"}),I(a.style,`${l}.style`,n),a.children!==void 0&&(Array.isArray(a.children)?a.children.forEach((d,m)=>{v(d)&&He(d,`${l}.children.${m}`,n)}):n.push({path:`${l}.children`,message:"嵌套组件应为数组"}))}})})}function ge(e){const t=[],n=[];return ue(e,t),t.length?{ok:!1,errors:t,warnings:n}:(v(e)?(e.schemaVersion!==void 0&&e.schemaVersion!==B.RENDER_PLAN_SCHEMA_VERSION&&t.push({path:"$.schemaVersion",message:"不支持的模板 schemaVersion"}),zt(e.params,"$.params",t),!Array.isArray(e.pages)||e.pages.length===0?t.push({path:"$.pages",message:"模板至少需要一页"}):e.pages.forEach((i,o)=>{const r=`$.pages.${o}`;if(!v(i)){t.push({path:r,message:"页应为对象"});return}x(i,"widthMm",r,t,Number.MIN_VALUE,!0),x(i,"heightMm",r,t,Number.MIN_VALUE,!0),i.layout!==void 0&&i.layout!=="page"&&i.layout!=="wide"&&t.push({path:`${r}.layout`,message:"布局应为 page 或 wide"}),typeof i.heightMm=="number"&&i.heightMm>=5e3&&t.push({path:`${r}.heightMm`,message:"页高应小于 5000mm"});for(const a of["marginTopMm","marginBottomMm","marginLeftMm","marginRightMm"])x(i,a,r,t);typeof i.widthMm=="number"&&Number(i.marginLeftMm??0)+Number(i.marginRightMm??0)>=i.widthMm&&t.push({path:r,message:"横向页边距占满页面"}),typeof i.heightMm=="number"&&Number(i.marginTopMm??0)+Number(i.marginBottomMm??0)>=i.heightMm&&t.push({path:r,message:"纵向页边距占满页面"}),Array.isArray(i.components)?i.components.forEach((a,s)=>{const l=`${r}.components.${s}`;v(a)&&a.kind==="list"?Gt(a,l,t):(Q(a,l,t,n),v(a)&&He(a,l,t))}):t.push({path:`${r}.components`,message:"组件应为数组"})})):t.push({path:"$",message:"模板应为对象"}),{ok:t.length===0,errors:t,warnings:n})}function Ie(e){const t=[],n=[];if(ue(e,t),t.length)return{ok:!1,errors:t,warnings:n};if(!v(e))t.push({path:"$",message:"模板文档应为对象"});else{for(const o of Object.keys(e))_t.has(o)||t.push({path:`$.${o}`,message:"模板文档存在未知字段;只保存模板与描述,不保存取数或业务数据"});e.schemaVersion!==fe&&t.push({path:"$.schemaVersion",message:"不支持的模板文档版本"});for(const o of["id","name"])E(e,o,"$",t,!0);for(const o of["revision","description"])E(e,o,"$",t);const i=ge(e.template);t.push(...i.errors.map(o=>({...o,path:`$.template${o.path.slice(1)}`}))),n.push(...i.warnings.map(o=>({...o,path:`$.template${o.path.slice(1)}`})))}return{ok:t.length===0,errors:t,warnings:n}}function ee(e){const t=Ie(e);if(!t.ok)throw new W(t.errors)}function Jt(e){const t=[];if(ue(e,t),t.length)throw new W(t);const n={...e,schemaVersion:e.schemaVersion??fe};return ee(n),Z(n)}function Ut(e){let t=e;if(typeof e=="string"){if(e.length>he)throw new W([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);try{t=JSON.parse(e)}catch{throw new W([{path:"$",message:"模板 JSON 语法无效"}])}}return ee(t),Z(t)}function qt(e){ee(e);const t=JSON.stringify(e,null,2);if(t.length>he)throw new W([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);return t}function Z(e){return JSON.parse(JSON.stringify(e))}function Yt(e=[]){const t=new Map,n={get:i=>{const o=t.get(i);return o?Z(o):void 0},list:()=>Array.from(t.values(),({template:i,...o})=>({...o})),register:(i,o={})=>{if(ee(i),t.has(i.id)&&!o.replace)throw new W([{path:"$.id",message:`模板 ID ${i.id} 已注册;更新需显式 replace:true`}]);t.set(i.id,Z(i))},remove:i=>t.delete(i)};for(const i of e)n.register(i);return n}function Kt(e){if(!("mapData"in e))return e;const{load:t,mapData:n,...i}=e;return{...i,load:async o=>{const r=await t(o);H(o.signal);try{return n(r,o)}catch(a){throw new C("validate",`报表 ${o.reportId} 数据映射失败`,a)}}}}class C extends Error{constructor(t,n,i){super(n),this.name="ReportSourceError",this.code=t,this.cause=i}}function te(e){const t=new Error("报表加载已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e.reason}),t}function H(e){if(e?.aborted)throw te(e)}function Be(e,t){return t?new Promise((n,i)=>{const o=()=>t.removeEventListener("abort",r),r=()=>{o(),i(te(t))};t.addEventListener("abort",r,{once:!0}),t.aborted&&r(),Promise.resolve(e).then(a=>{o(),n(a)},a=>{o(),i(a)})}):Promise.resolve(e)}function Xt(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new C("validate",`报表 ${t} 的数据集应为对象`);for(const[n,i]of Object.entries(e))if(!Array.isArray(i)||i.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new C("validate",`报表 ${t} 的数据集 ${n} 应为对象数组`)}async function Zt(e,t,n){const{reportId:i,signal:o}=t;try{const r=await Be(e(t),o);H(o);const a=ge(r);if(!a.ok)throw new C("validate",`报表 ${i} 模板校验失败:${a.errors.slice(0,3).map(s=>`${s.path}: ${s.message}`).join("; ")}`);return n.push(...a.warnings.map(s=>`${i}: ${s.path}: ${s.message}`)),r}catch(r){throw o?.aborted?te(o):r instanceof C?r:r instanceof W?new C("validate",`报表 ${i} 模板校验失败:${r.message}`,r):new C("fetch",`报表 ${i} 模板加载失败:${r instanceof Error?r.message:String(r)}`,r)}}async function Qt(e,t,n,i){let o;try{o=await Be(e.load?e.load(t):e.datasets??{},i)}catch(r){throw i?.aborted?te(i):r instanceof C?r:new C("fetch",`报表 ${n} 取数失败:${r instanceof Error?r.message:String(r)}`,r)}return H(i),Xt(o,n),o}function en(e,t,n,i){try{return ke(e,t,n.pagination)}catch(o){throw new C("validate",`报表 ${i} 排版失败:${o instanceof Error?o.message:String(o)}`,o)}}function tn(e,t,n,i){const o=new Map,r=a=>{let s=o.get(a);return s===void 0&&(s=JSON.stringify([n,i,a]),o.set(a,s)),s};for(const a of t.pages)e.push({...a,components:a.components.map(s=>s.table?{...s,table:{...s.table,id:r(s.table.id)}}:s)})}function nn(e,t={}){function n(o){const r=Object.prototype.hasOwnProperty.call(e,o)?e[o]:void 0;if(!r)throw new C("config",`未注册报表 ${o}`);return r}return Object.assign(async({reportIds:o,params:r,signal:a,onWarning:s})=>{H(a);const l=[...o],d={...r};if(l.length===0)throw new C("config","缺少报表 ID");const m=l.map(n),f=[],p=[];for(const[y,b]of m.entries()){H(a);const w=l[y],k={reportId:w,params:{...d},signal:a},S=typeof b.template=="function"?await Zt(b.template,k,p):b.template,D=await Qt(b,k,w,a);H(a);const V=en(S,D,b,w);tn(f,V.plan,y,w),p.push(...V.warnings.map(z=>`${w}: ${z}`))}H(a);const g={schemaVersion:B.RENDER_PLAN_SCHEMA_VERSION,pages:f},c=se(g);if(!c.ok)throw new C("validate",`渲染计划校验失败:${c.errors.slice(0,3).map(y=>`${y.path}: ${y.message}`).join("; ")}`);p.push(...c.warnings.map(y=>`${y.path}: ${y.message}`));const u=s??t.onWarning??(y=>console.warn("[mach-report]",y));for(const y of p)H(a),u(y);return H(a),g},{getParamDefs:o=>je.getReportParamDefs(e,o)})}exports.DEFAULT_BORDER_PT=_.DEFAULT_BORDER_PT;exports.DEFAULT_FONT_PT=_.DEFAULT_FONT_PT;exports.DEFAULT_STROKE_COLOR=_.DEFAULT_STROKE_COLOR;exports.DEFAULT_TEXT_COLOR=_.DEFAULT_TEXT_COLOR;exports.LINE_HEIGHT=_.LINE_HEIGHT;exports.SCHEMA_VERSION_MACH=_.SCHEMA_VERSION_MACH;exports.CSS_DPI=h.CSS_DPI;exports.MM_PER_INCH=h.MM_PER_INCH;exports.PAPER_SIZES=h.PAPER_SIZES;exports.mergeComponentStyles=h.mergeComponentStyles;exports.mmToPx=h.mmToPx;exports.mmToPxFactor=h.mmToPxFactor;exports.ptToPx=h.ptToPx;exports.pxToMm=h.pxToMm;exports.resolveBoxBorders=h.resolveBoxBorders;exports.resolveFontSize=h.resolveFontSize;exports.resolveGridLayout=h.resolveGridLayout;exports.resolveLineHeight=h.resolveLineHeight;exports.resolveStroke=h.resolveStroke;exports.resolveTextColor=h.resolveTextColor;exports.round=h.round;exports.RENDER_PLAN_SCHEMA_VERSION=B.RENDER_PLAN_SCHEMA_VERSION;exports.isImageBackedComponent=B.isImageBackedComponent;exports.isRichText=B.isRichText;exports.charWidthEm=N.charWidthEm;exports.createCanvasMeasurer=N.createCanvasMeasurer;exports.createHeuristicMeasurer=N.createHeuristicMeasurer;exports.heuristicMeasurer=N.heuristicMeasurer;exports.measureTextMm=N.measureTextMm;exports.wrapText=N.wrapText;exports.PageBuilder=Fe;exports.REPORT_TEMPLATE_DOCUMENT_VERSION=fe;exports.ReportSourceError=C;exports.ReportTemplateError=W;exports.TemplateBuilder=_e;exports.assertRenderPlan=Ke;exports.classOf=P;exports.computePageWindow=Ce;exports.createCanvasPager=Tt;exports.createReportSource=nn;exports.createTableTemplate=Lt;exports.createTemplate=Et;exports.createTemplateRegistry=Yt;exports.defineReport=Kt;exports.defineReportTemplate=Jt;exports.evalStyleRule=we;exports.formatValue=ae;exports.measurePageSizePx=me;exports.paginateTemplate=ke;exports.parseDateLocal=be;exports.parseReportTemplate=Ut;exports.planFontSizePx=bt;exports.renderComponent=le;exports.renderPage=xe;exports.renderPlan=yt;exports.renderPlanToCanvas=Oe;exports.renderPlanToImages=vt;exports.resolvePaper=ce;exports.serializeReportTemplate=qt;exports.toExcelNumberFormat=re;exports.toNumber=K;exports.validateComponent=Q;exports.validatePage=Se;exports.validateRenderPlan=se;exports.validateReportTemplate=ge;exports.validateReportTemplateDocument=Ie;
|
package/dist/index.d.cts
CHANGED
|
@@ -133,8 +133,8 @@ export declare function createReportSource(reports: ReportRegistry, options?: {
|
|
|
133
133
|
}): ReportSource;
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
136
|
+
* 创建明细模板;校验、列宽分配、标题与页面装配分别处理。
|
|
137
|
+
* page 自动列共享纸张余量;wide 保留自然列宽,公开配置保持不变。
|
|
138
138
|
*/
|
|
139
139
|
export declare function createTableTemplate(options: TableTemplateOptions): ReportTemplate;
|
|
140
140
|
|
|
@@ -276,6 +276,10 @@ export declare interface ListColumn {
|
|
|
276
276
|
export declare interface ListComponent {
|
|
277
277
|
kind: "list";
|
|
278
278
|
id?: string;
|
|
279
|
+
/** 宽表标记用于连续 Excel;不改变低层列表的列宽和分页算法。 */
|
|
280
|
+
layout?: "page" | "wide";
|
|
281
|
+
/** 逻辑表名称,供 Excel Sheet 命名;不额外生成标题组件。 */
|
|
282
|
+
title?: string;
|
|
279
283
|
leftMm: number;
|
|
280
284
|
topMm: number;
|
|
281
285
|
widthMm: number;
|
|
@@ -328,6 +332,9 @@ export declare function measurePageSizePx(page: Pick<PlanPage, "pageWidthMm" | "
|
|
|
328
332
|
|
|
329
333
|
export declare function measureTextMm(text: string, options: TextMeasureOptions): number;
|
|
330
334
|
|
|
335
|
+
/** Merge a declared style layer while keeping its explicit font unit authoritative. */
|
|
336
|
+
export declare function mergeComponentStyles(base: ComponentStyle | undefined, override: ComponentStyle | undefined): ComponentStyle;
|
|
337
|
+
|
|
331
338
|
export declare const MM_PER_INCH = 25.4;
|
|
332
339
|
|
|
333
340
|
export declare function mmToPx(value: number, dpi?: number): number;
|
|
@@ -386,6 +393,7 @@ export declare interface PaginateResult {
|
|
|
386
393
|
warnings: string[];
|
|
387
394
|
}
|
|
388
395
|
|
|
396
|
+
/** 模板遍历只编排静态组件和列表;行测量、分组、换页与汇总各自独立。 */
|
|
389
397
|
export declare function paginateTemplate(template: ReportTemplate, datasets: DatasetRows, optionsOrMmPerRow?: number | PaginateOptions): PaginateResult;
|
|
390
398
|
|
|
391
399
|
export declare const PAPER_SIZES: Record<string, {
|
|
@@ -416,6 +424,7 @@ export declare interface PlanComponent {
|
|
|
416
424
|
richParagraphs?: RichParagraph[];
|
|
417
425
|
imageData?: string;
|
|
418
426
|
grid?: PlanGrid;
|
|
427
|
+
table?: PlanTableFragment;
|
|
419
428
|
style?: ComponentStyle;
|
|
420
429
|
meta?: Record<string, unknown>;
|
|
421
430
|
/** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
|
|
@@ -434,9 +443,13 @@ export declare interface PlanGrid {
|
|
|
434
443
|
colWidthsMm?: number[];
|
|
435
444
|
rowHeightsMm?: number[];
|
|
436
445
|
gapMm?: number;
|
|
446
|
+
/** 单元格四边内距;旧静态网格默认 0.5mm,分页列表使用其真实测量内距。 */
|
|
447
|
+
paddingMm?: number;
|
|
437
448
|
}
|
|
438
449
|
|
|
439
450
|
export declare interface PlanPage {
|
|
451
|
+
/** wide 表示完整自然列宽;页面仅为预览的垂直窗口分段。 */
|
|
452
|
+
layout?: "page" | "wide";
|
|
440
453
|
pageWidthMm: number;
|
|
441
454
|
pageHeightMm: number;
|
|
442
455
|
marginTopMm?: number;
|
|
@@ -446,6 +459,19 @@ export declare interface PlanPage {
|
|
|
446
459
|
components: PlanComponent[];
|
|
447
460
|
}
|
|
448
461
|
|
|
462
|
+
/** 列表的逻辑行来源;用于连续 Excel 重组,避免按文本猜测重复表头。 */
|
|
463
|
+
export declare interface PlanTableFragment {
|
|
464
|
+
/** 在整个计划中唯一的逻辑表身份;同一表的分页片段共享身份。 */
|
|
465
|
+
id: string;
|
|
466
|
+
/** 表头固定 -1;其余行(包括组头/小计/总计)从 0 连续递增。 */
|
|
467
|
+
rowIndex: number;
|
|
468
|
+
role: "header" | "body" | "group-header" | "subtotal" | "grand-total";
|
|
469
|
+
/** 按物理列顺序保存字段身份;不以表头显示文本判断列结构。 */
|
|
470
|
+
columnKeys: string[];
|
|
471
|
+
layout?: "page" | "wide";
|
|
472
|
+
title?: string;
|
|
473
|
+
}
|
|
474
|
+
|
|
449
475
|
export declare function ptToPx(pt: number, dpi?: number): number;
|
|
450
476
|
|
|
451
477
|
export declare function pxToMm(value: number, dpi?: number): number;
|
|
@@ -675,16 +701,20 @@ export declare interface StyleRule {
|
|
|
675
701
|
style: Record<string, unknown>;
|
|
676
702
|
}
|
|
677
703
|
|
|
678
|
-
/**
|
|
704
|
+
/** 明细列:显式 widthMm 优先;纸张模式按 flex 分余量,宽表模式按 flex 放大基准列宽。 */
|
|
679
705
|
export declare type TableTemplateColumn = Omit<ListColumn, "widthMm"> & {
|
|
680
706
|
widthMm?: number;
|
|
681
707
|
/** 自动列的宽度权重,默认 1(有 widthMm 时不参与分配)。 */
|
|
682
708
|
flex?: number;
|
|
683
709
|
};
|
|
684
710
|
|
|
685
|
-
export declare type TableTemplateListOptions = Partial<Omit<ListComponent, "kind" | "leftMm" | "topMm" | "widthMm" | "dataset" | "columns">>;
|
|
711
|
+
export declare type TableTemplateListOptions = Partial<Omit<ListComponent, "kind" | "leftMm" | "topMm" | "widthMm" | "dataset" | "columns" | "layout" | "title">>;
|
|
686
712
|
|
|
687
713
|
export declare interface TableTemplateOptions extends PageOptions {
|
|
714
|
+
/** page 保持旧版纸张布局;wide 按所有列的自然宽度扩展,纵向分段仅供预览与渲染。 */
|
|
715
|
+
layout?: "page" | "wide";
|
|
716
|
+
/** 宽表模式自动列的基准宽度,默认 30mm;widthMm 优先,flex 为基准宽度的倍数。 */
|
|
717
|
+
columnWidthMm?: number;
|
|
688
718
|
title?: string;
|
|
689
719
|
/** 标题占高,默认 10mm;没有标题时不占空间。 */
|
|
690
720
|
titleHeightMm?: number;
|
|
@@ -693,7 +723,7 @@ export declare interface TableTemplateOptions extends PageOptions {
|
|
|
693
723
|
titleStyle?: ComponentStyle;
|
|
694
724
|
dataset?: string;
|
|
695
725
|
columns: readonly TableTemplateColumn[];
|
|
696
|
-
/**
|
|
726
|
+
/** 纸张模式默认 A4;与 layout: "wide" 互斥;页边距各默认 10mm。 */
|
|
697
727
|
paper?: PaperName | {
|
|
698
728
|
widthMm: number;
|
|
699
729
|
heightMm: number;
|
|
@@ -741,6 +771,8 @@ export declare type TemplateComponent = PlanComponent | ListComponent;
|
|
|
741
771
|
export declare interface TemplatePage {
|
|
742
772
|
widthMm: number;
|
|
743
773
|
heightMm: number;
|
|
774
|
+
/** 宽表保持全列自然宽度,页高只控制内部纵向分段。 */
|
|
775
|
+
layout?: "page" | "wide";
|
|
744
776
|
marginTopMm?: number;
|
|
745
777
|
marginBottomMm?: number;
|
|
746
778
|
marginLeftMm?: number;
|