@agile-team/mach-report 2.4.1 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2188 @@
1
+ import { computed as M, unref as C, ref as W, onScopeDispose as De, getCurrentScope as En, watch as Q, shallowRef as ke, defineComponent as Be, nextTick as Pn, openBlock as w, createElementBlock as E, createElementVNode as R, toDisplayString as F, Fragment as ye, createCommentVNode as I, normalizeClass as ie, createStaticVNode as Ut, createTextVNode as Oe, onMounted as Vt, onUnmounted as Kt, withModifiers as kn, renderSlot as ht, renderList as $e, withKeys as zt, inject as Je, provide as Zt, useCssVars as $n, watchEffect as Lt, normalizeStyle as fe, createBlock as Ue, createVNode as Cn, withCtx as Mn } from "vue";
2
+ import { renderPlanToImages as Fn, renderPage as Jt, getReportCellContext as At, createReportCellEdit as Rn, applyReportCellEdit as Tn, ReportCellEditError as Yt, paginateTemplate as Sn, validateRenderPlan as Ht, ReportSourceError as In, renderPlanToCanvas as On } from "@agile-team/mach-report";
3
+ import { c as Gt } from "./page-window-index-CIuT4BAv.js";
4
+ import { i as Dn, b as Bn } from "./render-plan-CXBWRog4.js";
5
+ import { b as bt, c as Wn, d as zn, a as Ln } from "./plugin-DDLcFWlk.js";
6
+ function Xt(e) {
7
+ return e == null ? [] : Array.isArray(e) ? e.map(String).filter((t) => t !== "") : String(e).split(",").map((t) => t.trim()).filter((t) => t !== "");
8
+ }
9
+ function So(e) {
10
+ return Xt(e).join(",");
11
+ }
12
+ class pt extends Error {
13
+ constructor(t) {
14
+ super(t), this.name = "PlanLoadError";
15
+ }
16
+ }
17
+ function Io(e = {}) {
18
+ const { baseUrl: t = "", headers: n, credentials: r, timeoutMs: a = 3e4 } = e, o = t.replace(/\/+$/, "");
19
+ return async ({ url: s, method: f, params: v, signal: h }) => {
20
+ let u = `${o}${s}`;
21
+ if (v && Object.keys(v).length > 0) {
22
+ const x = u.indexOf("#"), O = x >= 0 ? u.slice(x) : "", k = x >= 0 ? u.slice(0, x) : u, D = k.indexOf("?"), S = D >= 0 ? k.slice(0, D) : k, z = new URLSearchParams(D >= 0 ? k.slice(D + 1) : "");
23
+ for (const [A, _] of Object.entries(v)) z.set(A, _);
24
+ u = `${S}?${z}${O}`;
25
+ }
26
+ const d = (x, O) => {
27
+ const k = new pt(x);
28
+ return Object.defineProperty(k, "cause", { value: O, configurable: !0, writable: !0 }), k;
29
+ };
30
+ if (h?.aborted)
31
+ throw d(`请求已取消: ${s}`, h.reason);
32
+ const m = new AbortController();
33
+ let i;
34
+ const P = () => {
35
+ m.signal.aborted || (i = "external", m.abort(h?.reason));
36
+ };
37
+ h?.addEventListener("abort", P, { once: !0 });
38
+ const T = setTimeout(() => {
39
+ m.signal.aborted || (i = "timeout", m.abort());
40
+ }, a);
41
+ try {
42
+ const x = await fetch(u, {
43
+ method: f.toUpperCase(),
44
+ headers: { Accept: "application/json", ...n },
45
+ credentials: r,
46
+ signal: m.signal
47
+ });
48
+ if (!x.ok)
49
+ throw new pt(`HTTP ${x.status} ${s}`);
50
+ return await x.json();
51
+ } catch (x) {
52
+ throw i === "timeout" ? d(`请求超时(${a}ms): ${s}`, x) : i === "external" ? d(`请求已取消: ${s}`, x) : x instanceof pt ? x : d(`请求失败(${s}): ${x instanceof Error ? x.message : String(x)}`, x);
53
+ } finally {
54
+ clearTimeout(T), h?.removeEventListener("abort", P);
55
+ }
56
+ };
57
+ }
58
+ function An(e, t, n = {}) {
59
+ const r = n.pxPerMm ?? 3.7795275590551185, a = M(() => Math.max(0, C(n.gapPx) ?? 18)), o = W(0), s = W(800), f = M(() => {
60
+ const x = e.value?.pages ?? [];
61
+ return Gt(x.map((O) => O.pageHeightMm * r), a.value);
62
+ }), v = M(() => {
63
+ let x = 0;
64
+ for (const O of e.value?.pages ?? []) x = Math.max(x, O.pageWidthMm * r);
65
+ return { w: x, h: f.value.totalHeightPx };
66
+ }), h = M(() => f.value.window(
67
+ s.value / t.value,
68
+ o.value / t.value,
69
+ C(n.overscan) ?? 1
70
+ )), u = M(() => {
71
+ const x = e.value;
72
+ if (!x) return [];
73
+ const { start: O, end: k } = h.value;
74
+ return x.pages.slice(O, k + 1).map((D, S) => ({ page: D, index: O + S }));
75
+ });
76
+ let d = 0, m = !1;
77
+ function i(x) {
78
+ x && (o.value = x.scrollTop, s.value = x.clientHeight || 800);
79
+ }
80
+ function P(x, O) {
81
+ return (k) => {
82
+ d || m || (d = requestAnimationFrame(() => {
83
+ if (d = 0, m || (i(k), O.value <= 0)) return;
84
+ const D = Math.max(0, k.scrollTop + 32) / t.value;
85
+ x.value = Math.min(O.value, f.value.pageAt(D) + 1);
86
+ }));
87
+ };
88
+ }
89
+ function T() {
90
+ m = !0, d && cancelAnimationFrame(d), d = 0;
91
+ }
92
+ return De(T), {
93
+ contentSize: v,
94
+ windowRange: h,
95
+ visiblePages: u,
96
+ makeScrollHandler: P,
97
+ refreshViewport: i,
98
+ pageOffsetPx: (x) => f.value.offsetAt(x),
99
+ destroy: T
100
+ };
101
+ }
102
+ function Hn(e) {
103
+ const t = W(1), n = W("fit");
104
+ let r = 0;
105
+ function a() {
106
+ r && cancelAnimationFrame(r), r = 0;
107
+ }
108
+ function o() {
109
+ a(), r = requestAnimationFrame(() => {
110
+ if (r = 0, n.value !== "fit") return;
111
+ const f = e();
112
+ !f?.viewport || f.viewport.clientWidth <= 48 || !Number.isFinite(f.pageWidthPx) || (t.value = Math.min(1, (f.viewport.clientWidth - 48) / Math.max(1, f.pageWidthPx)));
113
+ });
114
+ }
115
+ function s(f) {
116
+ if (f === "fit")
117
+ n.value = "fit", o();
118
+ else {
119
+ if (!Number.isFinite(f)) return;
120
+ a(), n.value = "raw", t.value = Math.min(3, Math.max(0.3, f / 100));
121
+ }
122
+ }
123
+ return En() && De(a), { zoom: t, zoomMode: n, applyFitZoom: o, setZoom: s };
124
+ }
125
+ const Ye = 8;
126
+ function Ge() {
127
+ return new Promise((e) => setTimeout(e, 0));
128
+ }
129
+ function Ke(e) {
130
+ return `p${e.pageWidthMm}x${e.pageHeightMm}`.replace(/[.+]/g, "_");
131
+ }
132
+ function xt(e) {
133
+ const t = /* @__PURE__ */ new Map();
134
+ return e.pages.forEach((a) => {
135
+ t.has(Ke(a)) || t.set(Ke(a), a);
136
+ }), `<!doctype html><html><head><meta charset="utf-8"><style>${`.mr-page{margin:0 auto;page-break-after:always;}
137
+ .mr-page tr{break-inside:avoid;page-break-inside:avoid;}
138
+ .mr-comp{break-inside:avoid;page-break-inside:avoid;}
139
+ ${[...t.values()].map(
140
+ (a) => `@page ${Ke(a)}{size:${a.pageWidthMm}mm ${a.pageHeightMm}mm;margin:0;}`
141
+ ).join(`
142
+ `)}
143
+ body{margin:0;background:#fff;}`}</style></head><body>`;
144
+ }
145
+ function Et(e) {
146
+ const t = Jt(e, 96, {}, document);
147
+ return t.style.page = Ke(e), t.outerHTML;
148
+ }
149
+ function Qt(e) {
150
+ return { head: xt(e), pageChunks: e.pages.map(Et) };
151
+ }
152
+ async function Oo(e, t = {}) {
153
+ const n = {
154
+ schemaVersion: "mach-report-batch-print",
155
+ pages: e.flatMap((s) => s.pages)
156
+ };
157
+ if (n.pages.length === 0) return;
158
+ const r = xt(n), a = document.createElement("iframe");
159
+ a.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;", document.body.appendChild(a);
160
+ let o = !1;
161
+ try {
162
+ const s = a.contentDocument;
163
+ s.open(), s.write(r);
164
+ for (let f = 0; f < n.pages.length; f++)
165
+ s.write(Et(n.pages[f])), f % Ye === Ye - 1 && (t.onProgress?.(f + 1, n.pages.length), await Ge());
166
+ s.write("</body></html>"), s.close(), await Ge(), t.onProgress?.(n.pages.length, n.pages.length), o = !0, a.contentWindow?.focus(), a.contentWindow?.print();
167
+ } catch (s) {
168
+ t.onError?.(s instanceof Error ? `批量打印失败: ${s.message}` : "批量打印失败");
169
+ } finally {
170
+ o ? setTimeout(() => a.remove(), 6e4) : a.remove();
171
+ }
172
+ }
173
+ function jn(e) {
174
+ const { head: t, pageChunks: n } = Qt(e);
175
+ return {
176
+ html: `${`<!doctype html><html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head><meta charset="utf-8"><!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:Zoom>100</w:Zoom></w:WordDocument></xml><![endif]-->${t.replace(/^<!doctype html><html><head>/, "")}`}${n.join("")}</body></html>`,
177
+ filename: "mach-report.doc"
178
+ };
179
+ }
180
+ function Nn(e, t) {
181
+ let n = null, r = !1, a = !1, o = 0;
182
+ const s = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
183
+ let v = null, h = null, u = null, d = null, m = null;
184
+ function i(c, b) {
185
+ return !a && e.value === c && o === b;
186
+ }
187
+ function P() {
188
+ if (a) return;
189
+ const c = [...s.values()].reverse().find((b) => i(b.plan, b.epoch))?.format ?? null;
190
+ c !== v && (v = c, t.onBusy?.(c));
191
+ }
192
+ function T(c, b, y) {
193
+ const $ = {};
194
+ return s.set($, { plan: c, epoch: b, format: y }), P(), $;
195
+ }
196
+ function x(c) {
197
+ s.delete(c), P();
198
+ }
199
+ function O() {
200
+ for (const [c, b] of f)
201
+ i(b.plan, b.epoch) || (c.close(), f.delete(c));
202
+ }
203
+ function k() {
204
+ o++, S(), P(), O();
205
+ }
206
+ const D = Q(e, k, { flush: "sync" });
207
+ function S() {
208
+ n?.remove(), n = null;
209
+ }
210
+ function z() {
211
+ a = !0, o++, D(), S(), O(), s.clear(), t.onPrinting?.(!1);
212
+ }
213
+ function A(c, b) {
214
+ const y = URL.createObjectURL(c);
215
+ setTimeout(() => URL.revokeObjectURL(y), 1e4);
216
+ const $ = document.createElement("a");
217
+ $.href = y, $.download = b, $.click();
218
+ }
219
+ async function _() {
220
+ if (r) return;
221
+ const c = e.value;
222
+ if (a || !c || c.pages.length === 0) return;
223
+ const b = o;
224
+ r = !0, t.onPrinting?.(!0), S();
225
+ const y = xt(c);
226
+ n = document.createElement("iframe"), n.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;", document.body.appendChild(n);
227
+ const $ = n;
228
+ try {
229
+ const B = $.contentDocument;
230
+ B.open(), B.write(y);
231
+ for (let Z = 0; Z < c.pages.length; Z++)
232
+ if (B.write(Et(c.pages[Z])), Z % Ye === Ye - 1 && await Ge(), $ !== n) return;
233
+ if (B.write("</body></html>"), B.close(), await Ge(), !i(c, b) || $ !== n) return;
234
+ $.contentWindow?.focus(), $.contentWindow?.print();
235
+ } catch {
236
+ $ === n && S(), i(c, b) && t.onError("调用打印失败,请改用导出 PDF", "print");
237
+ } finally {
238
+ r = !1, a || t.onPrinting?.(!1);
239
+ }
240
+ }
241
+ function V(c, b) {
242
+ if (h?.plan === c && h.epoch === b) return h.promise;
243
+ const y = Promise.resolve().then(() => {
244
+ if (!i(c, b)) throw new Error("报表已切换或卸载");
245
+ return t.getPdfExporter()(c, ($) => {
246
+ i(c, b) && t.onWarning?.($);
247
+ });
248
+ }).finally(() => {
249
+ h?.promise === y && (h = null);
250
+ });
251
+ return h = { plan: c, epoch: b, promise: y }, y;
252
+ }
253
+ async function ee() {
254
+ const c = e.value;
255
+ if (a || !c || c.pages.length === 0) return;
256
+ const b = o;
257
+ if (u?.plan === c && u.epoch === b) return u.promise;
258
+ const y = T(c, b, "PDF"), $ = (async () => {
259
+ try {
260
+ const B = await V(c, b);
261
+ if (!i(c, b)) return;
262
+ A(new Blob([B], { type: "application/pdf" }), "mach-report.pdf");
263
+ } catch (B) {
264
+ i(c, b) && t.onError(B instanceof Error ? `PDF 导出失败: ${B.message}` : "PDF 导出失败", "pdf");
265
+ } finally {
266
+ x(y), u?.token === y && (u = null);
267
+ }
268
+ })();
269
+ return u = { plan: c, epoch: b, promise: $, token: y }, $;
270
+ }
271
+ async function Y() {
272
+ const c = e.value;
273
+ if (a || !c || c.pages.length === 0) return;
274
+ const b = o;
275
+ if (d?.plan === c && d.epoch === b) return d.promise;
276
+ const y = { ...t.getXlsxOptions?.() }, $ = T(c, b, "Excel"), B = (async () => {
277
+ try {
278
+ const { renderPlanToXlsx: Z } = await import("@agile-team/mach-report/xlsx");
279
+ if (!i(c, b)) return;
280
+ const { buffer: G, warnings: oe } = await Z(c, y);
281
+ if (!i(c, b) || (oe.length > 0 && t.onWarning?.(`Excel 导出有 ${oe.length} 条提示:${oe.slice(0, 2).join(";")}`), !i(c, b))) return;
282
+ A(new Blob([G], {
283
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
284
+ }), "mach-report.xlsx");
285
+ } catch (Z) {
286
+ i(c, b) && t.onError(Z instanceof Error ? `Excel 导出失败: ${Z.message}` : "Excel 导出失败", "export");
287
+ } finally {
288
+ x($), d?.token === $ && (d = null);
289
+ }
290
+ })();
291
+ return d = { plan: c, epoch: b, promise: B, token: $ }, B;
292
+ }
293
+ async function ae() {
294
+ const c = e.value;
295
+ if (a || !c || c.pages.length === 0) return;
296
+ const b = o;
297
+ if (m?.plan === c && m.epoch === b) return m.promise;
298
+ const y = T(c, b, "图片"), $ = (async () => {
299
+ try {
300
+ const { blobs: B } = await Fn(c, {
301
+ dpr: Math.min(2, typeof devicePixelRatio == "number" ? devicePixelRatio : 1)
302
+ });
303
+ if (!i(c, b)) return;
304
+ B.forEach((Z, G) => {
305
+ A(Z, B.length > 1 ? `mach-report-page-${G + 1}.png` : "mach-report.png");
306
+ });
307
+ } catch (B) {
308
+ i(c, b) && t.onError(
309
+ B instanceof Error ? `图片导出失败: ${B.message}` : "图片导出失败",
310
+ "export"
311
+ );
312
+ } finally {
313
+ x(y), m?.token === y && (m = null);
314
+ }
315
+ })();
316
+ return m = { plan: c, epoch: b, promise: $, token: y }, $;
317
+ }
318
+ function me() {
319
+ const c = e.value;
320
+ if (!(a || !c || c.pages.length === 0))
321
+ try {
322
+ const { html: b, filename: y } = jn(c);
323
+ A(new Blob([b], { type: "application/msword;charset=utf-8" }), y);
324
+ } catch (b) {
325
+ t.onError(
326
+ b instanceof Error ? `Word 导出失败: ${b.message}` : "Word 导出失败",
327
+ "export"
328
+ );
329
+ }
330
+ }
331
+ async function U(c) {
332
+ const b = e.value;
333
+ if (!(a || !b || b.pages.length === 0)) {
334
+ if (c === "pdf") {
335
+ await ee();
336
+ return;
337
+ }
338
+ if (c === "xlsx" || c === "excel") {
339
+ await Y();
340
+ return;
341
+ }
342
+ if (c === "png" || c === "image") {
343
+ await ae();
344
+ return;
345
+ }
346
+ if (c === "word" || c === "doc") {
347
+ me();
348
+ return;
349
+ }
350
+ if (c !== "html") {
351
+ t.onError(`不支持的导出格式:${c}`, "export");
352
+ return;
353
+ }
354
+ try {
355
+ const { head: y, pageChunks: $ } = Qt(b), B = `${y}${$.join("")}</body></html>`;
356
+ A(new Blob([B], { type: "text/html;charset=utf-8" }), "mach-report.html");
357
+ } catch (y) {
358
+ t.onError(y instanceof Error ? `HTML 导出失败: ${y.message}` : "HTML 导出失败", "export");
359
+ }
360
+ }
361
+ }
362
+ function ue() {
363
+ const c = e.value;
364
+ if (a || !c || c.pages.length === 0) return;
365
+ const b = o, y = window.open("", "_blank");
366
+ if (!y) {
367
+ t.onError("浏览器拦截了弹窗,请允许弹窗后重试", "pdf");
368
+ return;
369
+ }
370
+ f.set(y, { plan: c, epoch: b });
371
+ const $ = T(c, b, "PDF");
372
+ V(c, b).then((B) => {
373
+ if (!i(c, b) || y.closed) {
374
+ f.delete(y) && y.close();
375
+ return;
376
+ }
377
+ const Z = URL.createObjectURL(new Blob([B], { type: "application/pdf" }));
378
+ setTimeout(() => URL.revokeObjectURL(Z), 6e4);
379
+ const G = y.document;
380
+ G.title = "PDF 预览", G.documentElement.style.height = "100%", G.body.style.cssText = "margin:0;height:100%;";
381
+ const oe = G.createElement("iframe");
382
+ oe.title = "PDF 预览", oe.style.cssText = "display:block;width:100%;height:100%;border:0;", oe.src = Z, G.body.replaceChildren(oe), f.delete(y);
383
+ }).catch((B) => {
384
+ y.close(), f.delete(y), i(c, b) && t.onError(B instanceof Error ? `PDF 预览失败: ${B.message}` : "PDF 预览失败", "pdf");
385
+ }).finally(() => x($));
386
+ }
387
+ return {
388
+ print: _,
389
+ exportAs: U,
390
+ exportImages: ae,
391
+ exportWord: me,
392
+ openPdfWindow: ue,
393
+ invalidatePending: k,
394
+ releasePrintFrame: S,
395
+ dispose: z
396
+ };
397
+ }
398
+ const _t = "mrp-hit";
399
+ function qn(e) {
400
+ e.querySelectorAll(`mark.${_t}`).forEach((n) => {
401
+ const r = n.parentNode;
402
+ if (r) {
403
+ for (; n.firstChild; ) r.insertBefore(n.firstChild, n);
404
+ n.remove(), r.normalize();
405
+ }
406
+ });
407
+ }
408
+ function Un(e, t) {
409
+ const n = t.trim();
410
+ if (!n) return 0;
411
+ const r = n.toLowerCase(), a = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, {
412
+ acceptNode(f) {
413
+ const v = f.parentElement;
414
+ return !v || v.closest("mark") || /^(SCRIPT|STYLE)$/.test(v.tagName) ? NodeFilter.FILTER_REJECT : (f.nodeValue ?? "").toLowerCase().includes(r) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
415
+ }
416
+ }), o = [];
417
+ for (let f = a.nextNode(); f; f = a.nextNode()) o.push(f);
418
+ let s = 0;
419
+ for (const f of o) {
420
+ const v = f.nodeValue ?? "", h = v.toLowerCase(), u = f.parentElement;
421
+ if (!u) continue;
422
+ const d = document.createDocumentFragment();
423
+ let m = 0, i = h.indexOf(r);
424
+ for (; i >= 0; ) {
425
+ i > m && d.appendChild(document.createTextNode(v.slice(m, i)));
426
+ const P = document.createElement("mark");
427
+ P.className = _t, P.textContent = v.slice(i, i + n.length), d.appendChild(P), s++, m = i + n.length, i = h.indexOf(r, m);
428
+ }
429
+ m < v.length && d.appendChild(document.createTextNode(v.slice(m))), u.replaceChild(d, f);
430
+ }
431
+ return s;
432
+ }
433
+ const Vn = /* @__PURE__ */ new Set(["line", "rect", "ellipse", "chart"]);
434
+ function* Kn(e) {
435
+ for (const t of e.cells ?? [])
436
+ for (const n of t ?? [])
437
+ yield n?.text ?? "", yield* n?.children ?? [];
438
+ }
439
+ function* Zn(e) {
440
+ if (Bn(e))
441
+ for (const t of e.richParagraphs)
442
+ for (const n of t.segments ?? [])
443
+ yield (n.kind === "field" ? n.field : n.text) ?? "";
444
+ else e.lines?.length ? yield* e.lines : yield e.text ?? "";
445
+ }
446
+ function* Jn(e) {
447
+ const t = [e.values()];
448
+ for (; t.length > 0; ) {
449
+ const n = t[t.length - 1].next();
450
+ if (n.done) {
451
+ t.pop();
452
+ continue;
453
+ }
454
+ const r = n.value;
455
+ if (typeof r == "string") {
456
+ yield r;
457
+ continue;
458
+ }
459
+ yield "", !Dn(r) && (r.kind === "text" ? t.push(Zn(r)) : r.grid ? t.push(Kn(r.grid)) : Vn.has(r.kind) || (yield r.fallbackText ?? ""));
460
+ }
461
+ }
462
+ function* Yn(e) {
463
+ for (let t = 0; t < e.pages.length; t++) {
464
+ for (const n of Jn(e.pages[t].components)) yield { text: n, pageIndex: t };
465
+ yield { text: "", pageIndex: t };
466
+ }
467
+ }
468
+ function Gn(e, t) {
469
+ const n = e.toLowerCase();
470
+ let r = 0;
471
+ for (let a = n.indexOf(t); a >= 0; a = n.indexOf(t, a + t.length)) r++;
472
+ return r;
473
+ }
474
+ function Xn(e) {
475
+ const { plan: t, gotoPage: n, highlight: r, clearHighlights: a } = e, o = W(!1), s = W(""), f = W(0), v = W(0), h = W(!1);
476
+ let u = [];
477
+ const d = M(() => {
478
+ if (v.value === 0) return null;
479
+ const S = f.value;
480
+ let z = 0, A = u.length - 1;
481
+ for (; z < A; ) {
482
+ const V = z + A >>> 1;
483
+ u[V].cumulative <= S ? z = V + 1 : A = V;
484
+ }
485
+ const _ = u[z];
486
+ return _ ? { pageIndex: _.pageIndex, occurrence: S - (u[z - 1]?.cumulative ?? 0) } : null;
487
+ });
488
+ let m = null, i = null, P = 0;
489
+ function T() {
490
+ P++, m && clearTimeout(m), i && clearTimeout(i), m = i = null, h.value = !1;
491
+ }
492
+ function x(S) {
493
+ s.value = S, f.value = 0, v.value = 0, u = [], h.value = !1;
494
+ const z = S.trim().toLowerCase(), A = t.value;
495
+ if (!z || !A) return;
496
+ h.value = !0;
497
+ const _ = P, V = Yn(A), ee = [];
498
+ let Y = 0;
499
+ function ae() {
500
+ if (i = null, _ !== P || A !== t.value) return;
501
+ const me = performance.now();
502
+ let U = 0;
503
+ for (; U < 5e3 && performance.now() - me < 4; ) {
504
+ const ue = V.next();
505
+ if (ue.done) {
506
+ u = ee, v.value = Y, h.value = !1, u[0] && n(u[0].pageIndex + 1);
507
+ return;
508
+ }
509
+ const c = Gn(ue.value.text, z);
510
+ if (c > 0) {
511
+ Y += c;
512
+ const b = ee[ee.length - 1];
513
+ b?.pageIndex === ue.value.pageIndex ? b.cumulative = Y : ee.push({ pageIndex: ue.value.pageIndex, cumulative: Y });
514
+ }
515
+ U++;
516
+ }
517
+ i = setTimeout(ae, 0);
518
+ }
519
+ ae();
520
+ }
521
+ function O(S) {
522
+ if (T(), s.value = S, f.value = v.value = 0, u = [], !S.trim()) {
523
+ x("");
524
+ return;
525
+ }
526
+ h.value = !0, m = setTimeout(() => {
527
+ m = null, x(S);
528
+ }, Math.max(0, C(e.debounceMs) ?? 200));
529
+ }
530
+ function k(S) {
531
+ const z = v.value;
532
+ if (z === 0 || h.value) return;
533
+ f.value = (f.value + S + z) % z;
534
+ const A = d.value;
535
+ A && n(A.pageIndex + 1);
536
+ }
537
+ function D() {
538
+ T(), s.value = "", f.value = v.value = 0, u = [];
539
+ }
540
+ return Q(t, D, { flush: "sync" }), De(D), {
541
+ visible: o,
542
+ query: s,
543
+ matchIndex: f,
544
+ matchCount: v,
545
+ activeMatch: d,
546
+ searching: h,
547
+ toggle: () => {
548
+ o.value = !o.value;
549
+ },
550
+ onInput: O,
551
+ onNav: k,
552
+ apply: (S) => {
553
+ s.value.trim() && r(S, s.value.trim());
554
+ },
555
+ clear: (S) => {
556
+ a(S);
557
+ },
558
+ reset: D
559
+ };
560
+ }
561
+ function Qn(e, t) {
562
+ const n = M(() => {
563
+ if (e.value) return !0;
564
+ if (typeof location > "u") return !1;
565
+ try {
566
+ return new URLSearchParams(location.search).get("mrp-debug") === "1";
567
+ } catch {
568
+ return !1;
569
+ }
570
+ }), r = M(() => !n.value || !t.plan.value ? 0 : Math.round(JSON.stringify(t.plan.value).length / 1024)), a = M(() => !n.value || !t.plan.value ? null : {
571
+ pages: t.pageCount.value,
572
+ window: `${t.windowRange.value.start}-${t.windowRange.value.end}`,
573
+ zoom: `${Math.round(t.zoom.value * 100)}%`,
574
+ loadMs: `${t.loadMs.value}ms`,
575
+ planKB: r.value
576
+ });
577
+ return { enabled: n, debugStats: a };
578
+ }
579
+ function _n(e, t) {
580
+ const { thumbsRoot: n, visible: r, renderThumbCanvas: a } = t, o = W(0), s = W(800), f = M(() => (e.value?.pages ?? []).map(
581
+ (k) => Math.round(k.pageHeightMm / k.pageWidthMm * 116)
582
+ )), v = M(() => Gt(f.value.map((k) => k + 20), 8)), h = M(() => v.value.window(s.value, o.value, 1)), u = M(() => {
583
+ if (!r.value) return [];
584
+ const { start: k, end: D } = h.value;
585
+ return f.value.slice(k, D + 1).map((S, z) => ({ index: k + z, height: S }));
586
+ });
587
+ let d = 0, m = 0, i = !1;
588
+ function P() {
589
+ const k = n.value;
590
+ k && (o.value = k.scrollTop, s.value = k.clientHeight || 800);
591
+ }
592
+ function T() {
593
+ i || m || (m = requestAnimationFrame(() => {
594
+ m = 0, P();
595
+ }));
596
+ }
597
+ function x() {
598
+ if (u.value, d && cancelAnimationFrame(d), d = 0, i || !r.value || !e.value || !n.value) return;
599
+ P();
600
+ const k = u.value, D = e.value, S = n.value;
601
+ let z = 0;
602
+ function A() {
603
+ if (d = 0, !(i || !r.value || e.value !== D || n.value !== S)) {
604
+ for (let _ = 0; z < k.length && _ < 2; _++, z++) {
605
+ const V = k[z].index, ee = S.querySelector(`[data-thumb="${V + 1}"]`);
606
+ if (!ee || ee.childElementCount > 0) continue;
607
+ const Y = a(V);
608
+ Y && (Y.style.width = "100%", Y.style.height = "100%", Y.style.display = "block", ee.appendChild(Y));
609
+ }
610
+ z < k.length && (d = requestAnimationFrame(A));
611
+ }
612
+ }
613
+ d = requestAnimationFrame(A);
614
+ }
615
+ function O() {
616
+ i = !0, d && cancelAnimationFrame(d), m && cancelAnimationFrame(m), d = m = 0;
617
+ }
618
+ return De(O), { schedule: x, destroy: O, onScroll: T, windowRange: h, visibleThumbs: u };
619
+ }
620
+ function ea() {
621
+ const e = ke(0);
622
+ return {
623
+ loadMs: e,
624
+ start() {
625
+ return typeof performance < "u" ? performance.now() : 0;
626
+ },
627
+ end(t) {
628
+ e.value = t ? Math.round(performance.now() - t) : 0;
629
+ }
630
+ };
631
+ }
632
+ const ta = ["aria-label"], na = { class: "mrp-title" }, aa = ["disabled"], oa = { class: "mrp-pageinfo" }, ra = ["disabled"], sa = ["disabled"], la = {
633
+ key: 2,
634
+ class: "mrp-search"
635
+ }, ia = ["placeholder", "value"], ua = {
636
+ key: 0,
637
+ class: "mrp-search-count",
638
+ role: "status"
639
+ }, ca = ["disabled"], da = ["disabled"], fa = ["aria-label"], ma = ["disabled"], pa = ["disabled"], va = ["disabled"], ga = ["disabled"], ha = ["disabled"], ba = ["disabled"], ya = ["disabled"], wa = ["aria-label", "aria-expanded"], xa = /* @__PURE__ */ Be({
640
+ __name: "ReportToolbar",
641
+ props: {
642
+ pageCount: {},
643
+ currentPage: {},
644
+ zoomMode: {},
645
+ zoom: {},
646
+ showExport: { type: Boolean },
647
+ showPrint: { type: Boolean },
648
+ showPdfWindow: { type: Boolean },
649
+ messages: {},
650
+ search: {},
651
+ thumbsVisible: { type: Boolean },
652
+ showImport: { type: Boolean },
653
+ showSearch: { type: Boolean },
654
+ showThumbnails: { type: Boolean },
655
+ showZoom: { type: Boolean },
656
+ exportFormats: {},
657
+ showSettings: { type: Boolean },
658
+ settingsOpen: { type: Boolean },
659
+ busy: { type: Boolean }
660
+ },
661
+ emits: ["goto", "zoom", "export", "print", "pdf-window", "search-input", "search-nav", "search-toggle", "thumbs-toggle", "import-excel", "settings-toggle"],
662
+ setup(e) {
663
+ const t = e, n = W(null);
664
+ Q(
665
+ () => t.search.visible,
666
+ (a) => {
667
+ a && Pn(() => n.value?.focus());
668
+ }
669
+ );
670
+ function r(a, o, s) {
671
+ return a.replace("{cur}", String(o)).replace("{total}", String(s));
672
+ }
673
+ return (a, o) => (w(), E("div", {
674
+ class: "mrp-toolbar",
675
+ role: "toolbar",
676
+ "aria-label": e.messages.title
677
+ }, [
678
+ R("span", na, F(e.messages.title), 1),
679
+ e.pageCount > 0 ? (w(), E(ye, { key: 0 }, [
680
+ R("button", {
681
+ class: "mrp-nav",
682
+ type: "button",
683
+ disabled: e.currentPage <= 1,
684
+ onClick: o[0] || (o[0] = (s) => a.$emit("goto", e.currentPage - 1))
685
+ }, F(e.messages.prevPage), 9, aa),
686
+ R("span", oa, F(r(e.messages.pageInfo, e.currentPage, e.pageCount)), 1),
687
+ R("button", {
688
+ class: "mrp-nav",
689
+ type: "button",
690
+ disabled: e.currentPage >= e.pageCount,
691
+ onClick: o[1] || (o[1] = (s) => a.$emit("goto", e.currentPage + 1))
692
+ }, F(e.messages.nextPage), 9, ra)
693
+ ], 64)) : I("", !0),
694
+ o[21] || (o[21] = R("span", { class: "mrp-spacer" }, null, -1)),
695
+ e.showImport ? (w(), E("button", {
696
+ key: 1,
697
+ class: "mrp-nav mrp-import-excel",
698
+ type: "button",
699
+ disabled: e.busy,
700
+ onClick: o[2] || (o[2] = (s) => a.$emit("import-excel"))
701
+ }, F(e.messages.importExcel ?? "导入 Excel 模板"), 9, sa)) : I("", !0),
702
+ e.showSearch !== !1 && e.search.visible ? (w(), E("div", la, [
703
+ R("input", {
704
+ ref_key: "searchInputRef",
705
+ ref: n,
706
+ class: "mrp-search-input",
707
+ type: "text",
708
+ placeholder: e.messages.searchPlaceholder,
709
+ value: e.search.query,
710
+ onInput: o[3] || (o[3] = (s) => a.$emit("search-input", s.target.value))
711
+ }, null, 40, ia),
712
+ e.search.query ? (w(), E("span", ua, F(e.search.searching ? e.messages.searching ?? "搜索中…" : r(e.messages.matchInfo, e.search.matchCount > 0 ? e.search.matchIndex + 1 : 0, e.search.matchCount)), 1)) : I("", !0),
713
+ R("button", {
714
+ class: "mrp-nav",
715
+ type: "button",
716
+ disabled: e.search.matchCount === 0,
717
+ onClick: o[4] || (o[4] = (s) => a.$emit("search-nav", -1))
718
+ }, F(e.messages.prevMatch), 9, ca),
719
+ R("button", {
720
+ class: "mrp-nav",
721
+ type: "button",
722
+ disabled: e.search.matchCount === 0,
723
+ onClick: o[5] || (o[5] = (s) => a.$emit("search-nav", 1))
724
+ }, F(e.messages.nextMatch), 9, da)
725
+ ])) : I("", !0),
726
+ e.showSearch !== !1 ? (w(), E("button", {
727
+ key: 3,
728
+ class: ie(["mrp-nav", { "mrp-active": e.search.visible }]),
729
+ type: "button",
730
+ title: "Ctrl+F",
731
+ "aria-label": e.messages.search ?? e.messages.searchPlaceholder,
732
+ onClick: o[6] || (o[6] = (s) => a.$emit("search-toggle"))
733
+ }, [...o[19] || (o[19] = [
734
+ R("svg", {
735
+ width: "13",
736
+ height: "13",
737
+ viewBox: "0 0 20 20",
738
+ fill: "none",
739
+ "aria-hidden": "true"
740
+ }, [
741
+ R("circle", {
742
+ cx: "8.5",
743
+ cy: "8.5",
744
+ r: "5.5",
745
+ stroke: "currentColor",
746
+ "stroke-width": "1.6"
747
+ }),
748
+ R("path", {
749
+ d: "m13 13 4 4",
750
+ stroke: "currentColor",
751
+ "stroke-width": "1.6",
752
+ "stroke-linecap": "round"
753
+ })
754
+ ], -1)
755
+ ])], 10, fa)) : I("", !0),
756
+ e.showThumbnails !== !1 ? (w(), E("button", {
757
+ key: 4,
758
+ class: ie(["mrp-nav", { "mrp-active": e.thumbsVisible }]),
759
+ type: "button",
760
+ onClick: o[7] || (o[7] = (s) => a.$emit("thumbs-toggle"))
761
+ }, " ▦ " + F(e.messages.thumbnails), 3)) : I("", !0),
762
+ e.showZoom !== !1 ? (w(), E("button", {
763
+ key: 5,
764
+ class: ie(["mrp-nav", { "mrp-active": e.zoomMode === "fit" }]),
765
+ type: "button",
766
+ onClick: o[8] || (o[8] = (s) => a.$emit("zoom", "fit"))
767
+ }, F(e.messages.fitWidth), 3)) : I("", !0),
768
+ e.showZoom !== !1 ? (w(), E("button", {
769
+ key: 6,
770
+ class: ie(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 100 }]),
771
+ type: "button",
772
+ onClick: o[9] || (o[9] = (s) => a.$emit("zoom", 100))
773
+ }, " 100% ", 2)) : I("", !0),
774
+ e.showZoom !== !1 ? (w(), E("button", {
775
+ key: 7,
776
+ class: ie(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 150 }]),
777
+ type: "button",
778
+ onClick: o[10] || (o[10] = (s) => a.$emit("zoom", 150))
779
+ }, " 150% ", 2)) : I("", !0),
780
+ e.showExport && (!e.exportFormats || e.exportFormats.includes("html")) ? (w(), E("button", {
781
+ key: 8,
782
+ class: "mrp-nav",
783
+ type: "button",
784
+ disabled: e.busy,
785
+ onClick: o[11] || (o[11] = (s) => a.$emit("export", "html"))
786
+ }, F(e.messages.exportHtml), 9, ma)) : I("", !0),
787
+ e.showExport && (!e.exportFormats || e.exportFormats.includes("pdf")) ? (w(), E("button", {
788
+ key: 9,
789
+ class: "mrp-nav",
790
+ type: "button",
791
+ disabled: e.busy,
792
+ onClick: o[12] || (o[12] = (s) => a.$emit("export", "pdf"))
793
+ }, F(e.messages.exportPdf), 9, pa)) : I("", !0),
794
+ e.showExport && (!e.exportFormats || e.exportFormats.includes("xlsx")) ? (w(), E("button", {
795
+ key: 10,
796
+ class: "mrp-nav",
797
+ type: "button",
798
+ disabled: e.busy,
799
+ onClick: o[13] || (o[13] = (s) => a.$emit("export", "xlsx"))
800
+ }, F(e.messages.exportExcel), 9, va)) : I("", !0),
801
+ e.showExport && (!e.exportFormats || e.exportFormats.includes("png")) ? (w(), E("button", {
802
+ key: 11,
803
+ class: "mrp-nav",
804
+ type: "button",
805
+ disabled: e.busy,
806
+ onClick: o[14] || (o[14] = (s) => a.$emit("export", "png"))
807
+ }, F(e.messages.exportImage), 9, ga)) : I("", !0),
808
+ e.showExport && (!e.exportFormats || e.exportFormats.includes("word")) ? (w(), E("button", {
809
+ key: 12,
810
+ class: "mrp-nav",
811
+ type: "button",
812
+ disabled: e.busy,
813
+ onClick: o[15] || (o[15] = (s) => a.$emit("export", "word"))
814
+ }, F(e.messages.exportWord), 9, ha)) : I("", !0),
815
+ e.showPrint ? (w(), E("button", {
816
+ key: 13,
817
+ class: "mrp-nav",
818
+ type: "button",
819
+ disabled: e.busy,
820
+ onClick: o[16] || (o[16] = (s) => a.$emit("print"))
821
+ }, F(e.messages.print), 9, ba)) : I("", !0),
822
+ e.showPdfWindow ? (w(), E("button", {
823
+ key: 14,
824
+ class: "mrp-nav",
825
+ type: "button",
826
+ disabled: e.busy,
827
+ onClick: o[17] || (o[17] = (s) => a.$emit("pdf-window"))
828
+ }, F(e.messages.pdfWindow), 9, ya)) : I("", !0),
829
+ e.showSettings ? (w(), E("button", {
830
+ key: 15,
831
+ class: "mrp-nav mrp-settings-toggle",
832
+ type: "button",
833
+ "aria-label": e.messages.settings,
834
+ "aria-haspopup": "dialog",
835
+ "aria-expanded": !!e.settingsOpen,
836
+ onClick: o[18] || (o[18] = (s) => a.$emit("settings-toggle"))
837
+ }, [
838
+ o[20] || (o[20] = Ut('<svg width="14" height="14" viewBox="0 0 20 20" fill="none" aria-hidden="true" data-v-4223ad9f><path d="M3 5h14M3 10h14M3 15h14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" data-v-4223ad9f></path><circle cx="7" cy="5" r="2" fill="var(--mrp-toolbar-bg)" stroke="currentColor" stroke-width="1.5" data-v-4223ad9f></circle><circle cx="13" cy="10" r="2" fill="var(--mrp-toolbar-bg)" stroke="currentColor" stroke-width="1.5" data-v-4223ad9f></circle><circle cx="8" cy="15" r="2" fill="var(--mrp-toolbar-bg)" stroke="currentColor" stroke-width="1.5" data-v-4223ad9f></circle></svg>', 1)),
839
+ Oe(" " + F(e.messages.settings), 1)
840
+ ], 8, wa)) : I("", !0)
841
+ ], 8, ta));
842
+ }
843
+ }), We = (e, t) => {
844
+ const n = e.__vccOpts || e;
845
+ for (const [r, a] of t)
846
+ n[r] = a;
847
+ return n;
848
+ }, Ea = /* @__PURE__ */ We(xa, [["__scopeId", "data-v-4223ad9f"]]), Pa = ["aria-label"], ka = { class: "mrp-settings-header" }, $a = ["aria-label"], Ca = { class: "mrp-settings-content" }, Ma = { key: 0 }, Fa = ["checked", "disabled", "onChange"], Ra = {
849
+ key: 0,
850
+ class: "mrp-settings-note"
851
+ }, Ta = {
852
+ key: 1,
853
+ class: "mrp-settings-note"
854
+ }, Sa = ["disabled"], Ia = /* @__PURE__ */ Be({
855
+ __name: "ReportSettings",
856
+ props: {
857
+ available: {},
858
+ enabled: {},
859
+ messages: {},
860
+ persistedEditing: { type: Boolean },
861
+ busy: { type: Boolean }
862
+ },
863
+ emits: ["change", "reset", "close"],
864
+ setup(e, { emit: t }) {
865
+ const n = e, r = t, a = W(null), o = W(null);
866
+ let s = null;
867
+ const f = M(() => [
868
+ { label: n.messages.settingsDisplay, tools: [
869
+ ["search", n.messages.search],
870
+ ["thumbnails", n.messages.thumbnails],
871
+ ["zoom", n.messages.zoom]
872
+ ] },
873
+ { label: n.messages.settingsExport, tools: [
874
+ ["html", n.messages.exportHtml],
875
+ ["pdf", n.messages.exportPdf],
876
+ ["xlsx", n.messages.exportExcel],
877
+ ["png", n.messages.exportImage],
878
+ ["word", n.messages.exportWord],
879
+ ["print", n.messages.print],
880
+ ["pdfWindow", n.messages.pdfWindow]
881
+ ] },
882
+ { label: n.messages.settingsData, tools: [
883
+ ["editing", n.messages.editCell],
884
+ ["import", n.messages.importExcel]
885
+ ] }
886
+ ].map((u) => ({ ...u, tools: u.tools.map(([d, m]) => ({ key: d, label: m })) })));
887
+ function v(u, d) {
888
+ const m = u.target, i = m.checked;
889
+ m.checked = n.enabled[d], r("change", d, i);
890
+ }
891
+ function h(u) {
892
+ if (u.key === "Escape") {
893
+ u.preventDefault(), r("close");
894
+ return;
895
+ }
896
+ if (u.key !== "Tab") return;
897
+ const d = a.value?.querySelectorAll("a[href],button:not(:disabled),input:not(:disabled),textarea:not(:disabled),select:not(:disabled),[tabindex='0']"), m = d?.[0], i = d?.[d.length - 1];
898
+ u.shiftKey && document.activeElement === m && (u.preventDefault(), i?.focus()), !u.shiftKey && document.activeElement === i && (u.preventDefault(), m?.focus());
899
+ }
900
+ return Vt(() => {
901
+ s = document.activeElement instanceof HTMLElement ? document.activeElement : null, o.value?.focus();
902
+ }), Kt(() => s?.focus()), (u, d) => (w(), E("div", {
903
+ class: "mrp-settings-backdrop",
904
+ onClick: d[2] || (d[2] = kn((m) => u.$emit("close"), ["self"])),
905
+ onKeydown: h
906
+ }, [
907
+ R("section", {
908
+ ref_key: "panel",
909
+ ref: a,
910
+ class: "mrp-settings-panel",
911
+ role: "dialog",
912
+ "aria-modal": "true",
913
+ "aria-label": e.messages.settings
914
+ }, [
915
+ R("header", ka, [
916
+ R("div", null, [
917
+ R("strong", null, F(e.messages.settings), 1),
918
+ R("p", null, F(e.messages.settingsLocal), 1)
919
+ ]),
920
+ R("button", {
921
+ ref_key: "closeButton",
922
+ ref: o,
923
+ class: "mrp-settings-close",
924
+ type: "button",
925
+ "aria-label": e.messages.settingsClose,
926
+ onClick: d[0] || (d[0] = (m) => u.$emit("close"))
927
+ }, "×", 8, $a)
928
+ ]),
929
+ R("div", Ca, [
930
+ ht(u.$slots, "default", {}, void 0, !0),
931
+ (w(!0), E(ye, null, $e(f.value, (m) => (w(), E("fieldset", {
932
+ key: m.label
933
+ }, [
934
+ R("legend", null, F(m.label), 1),
935
+ (w(!0), E(ye, null, $e(m.tools, (i) => (w(), E("label", {
936
+ key: i.key,
937
+ class: ie(["mrp-settings-option", { "mrp-settings-unavailable": !e.available[i.key] }])
938
+ }, [
939
+ R("span", null, [
940
+ Oe(F(i.label), 1),
941
+ e.available[i.key] ? I("", !0) : (w(), E("small", Ma, F(e.messages.settingsUnavailable), 1))
942
+ ]),
943
+ R("input", {
944
+ type: "checkbox",
945
+ checked: e.enabled[i.key],
946
+ disabled: e.busy || !e.available[i.key],
947
+ onChange: (P) => v(P, i.key)
948
+ }, null, 40, Fa)
949
+ ], 2))), 128))
950
+ ]))), 128)),
951
+ e.available.editing ? (w(), E("p", Ra, F(e.persistedEditing ? e.messages.editingSaved : e.messages.editingLocal), 1)) : I("", !0),
952
+ e.available.import ? (w(), E("p", Ta, F(e.messages.importLocal), 1)) : I("", !0)
953
+ ]),
954
+ R("footer", null, [
955
+ R("button", {
956
+ type: "button",
957
+ disabled: e.busy,
958
+ onClick: d[1] || (d[1] = (m) => u.$emit("reset"))
959
+ }, F(e.messages.settingsReset), 9, Sa)
960
+ ])
961
+ ], 8, Pa)
962
+ ], 32));
963
+ }
964
+ }), Oa = /* @__PURE__ */ We(Ia, [["__scopeId", "data-v-fe89b48b"]]), Da = {
965
+ class: "mrp-empty",
966
+ role: "status"
967
+ }, Ba = { key: 0 }, Wa = /* @__PURE__ */ Be({
968
+ __name: "ReportEmpty",
969
+ props: {
970
+ title: {},
971
+ description: {}
972
+ },
973
+ setup(e) {
974
+ return (t, n) => (w(), E("div", Da, [
975
+ n[0] || (n[0] = Ut('<svg class="mrp-empty-art" viewBox="0 0 160 112" fill="none" aria-hidden="true" data-v-07e9cb82><ellipse cx="80" cy="100" rx="54" ry="7" fill="currentColor" opacity=".05" data-v-07e9cb82></ellipse><rect x="34" y="15" width="92" height="78" rx="9" fill="currentColor" opacity=".04" data-v-07e9cb82></rect><rect x="42" y="9" width="76" height="78" rx="7" fill="var(--mrp-toolbar-bg, #fff)" stroke="currentColor" stroke-opacity=".2" stroke-width="1.5" data-v-07e9cb82></rect><path d="M55 27H105M55 42H105M55 57H85M55 72H76M71 27V72M89 27V57" stroke="currentColor" stroke-opacity=".15" stroke-width="1.5" stroke-linecap="round" data-v-07e9cb82></path><circle cx="112" cy="76" r="16" fill="var(--mrp-toolbar-bg, #fff)" stroke="currentColor" stroke-opacity=".35" stroke-width="2" data-v-07e9cb82></circle><path d="M124 88L137 101M106 76H118" stroke="currentColor" stroke-opacity=".45" stroke-width="3" stroke-linecap="round" data-v-07e9cb82></path><circle cx="27" cy="38" r="3" fill="currentColor" opacity=".12" data-v-07e9cb82></circle><circle cx="132" cy="24" r="2" fill="currentColor" opacity=".2" data-v-07e9cb82></circle></svg>', 1)),
976
+ R("strong", null, F(e.title), 1),
977
+ e.description ? (w(), E("p", Ba, F(e.description), 1)) : I("", !0)
978
+ ]));
979
+ }
980
+ }), jt = /* @__PURE__ */ We(Wa, [["__scopeId", "data-v-07e9cb82"]]), za = { class: "mrp-params" }, La = { class: "mrp-params-title" }, Aa = { class: "mrp-params-grid" }, Ha = { class: "mrp-param-label" }, ja = {
981
+ key: 0,
982
+ class: "mrp-param-star"
983
+ }, Na = ["value", "onChange"], qa = {
984
+ value: "",
985
+ disabled: "",
986
+ hidden: ""
987
+ }, Ua = ["value"], Va = ["type", "placeholder", "value", "onInput"], Ka = { class: "mrp-params-actions" }, Za = /* @__PURE__ */ Be({
988
+ __name: "ReportParamPanel",
989
+ props: {
990
+ defs: {},
991
+ modelValue: {},
992
+ messages: {},
993
+ attempted: { type: Boolean }
994
+ },
995
+ emits: ["update:modelValue", "query", "reset"],
996
+ setup(e, { emit: t }) {
997
+ const n = e, r = t, a = W({ ...n.modelValue });
998
+ Q(
999
+ () => n.modelValue,
1000
+ (v) => {
1001
+ a.value = { ...v };
1002
+ }
1003
+ );
1004
+ const o = M(
1005
+ () => n.defs.map((v) => ({
1006
+ def: v,
1007
+ label: v.label ?? v.field,
1008
+ value: a.value[v.field] ?? ""
1009
+ }))
1010
+ );
1011
+ function s(v, h) {
1012
+ a.value = { ...a.value, [v]: h }, r("update:modelValue", { ...a.value });
1013
+ }
1014
+ function f(v) {
1015
+ const h = n.defs.find((u) => u.field === v);
1016
+ return n.attempted && h?.required === !0 && !(a.value[v] ?? "").trim();
1017
+ }
1018
+ return (v, h) => (w(), E("div", za, [
1019
+ R("span", La, F(e.messages.paramsTitle), 1),
1020
+ R("div", Aa, [
1021
+ (w(!0), E(ye, null, $e(o.value, (u) => (w(), E("label", {
1022
+ key: u.def.field,
1023
+ class: ie(["mrp-param", { "mrp-param-missing": f(u.def.field) }])
1024
+ }, [
1025
+ R("span", Ha, [
1026
+ Oe(F(u.label), 1),
1027
+ u.def.required ? (w(), E("i", ja, "*")) : I("", !0)
1028
+ ]),
1029
+ (u.def.type ?? "text") === "select" ? (w(), E("select", {
1030
+ key: 0,
1031
+ class: "mrp-param-input",
1032
+ value: u.value,
1033
+ onChange: (d) => s(u.def.field, d.target.value),
1034
+ onKeydown: h[0] || (h[0] = zt((d) => v.$emit("query"), ["enter"]))
1035
+ }, [
1036
+ R("option", qa, F(u.def.placeholder ?? `请选择${u.label}`), 1),
1037
+ (w(!0), E(ye, null, $e(u.def.options ?? [], (d) => (w(), E("option", {
1038
+ key: d.value,
1039
+ value: d.value
1040
+ }, F(d.label), 9, Ua))), 128))
1041
+ ], 40, Na)) : (w(), E("input", {
1042
+ key: 1,
1043
+ class: "mrp-param-input",
1044
+ type: u.def.type === "number" ? "number" : u.def.type === "date" ? "date" : "text",
1045
+ placeholder: u.def.placeholder ?? `请输入${u.label}`,
1046
+ value: u.value,
1047
+ onInput: (d) => s(u.def.field, d.target.value),
1048
+ onKeydown: h[1] || (h[1] = zt((d) => v.$emit("query"), ["enter"]))
1049
+ }, null, 40, Va))
1050
+ ], 2))), 128))
1051
+ ]),
1052
+ R("div", Ka, [
1053
+ R("button", {
1054
+ class: "mrp-nav mrp-param-query",
1055
+ type: "button",
1056
+ onClick: h[2] || (h[2] = (u) => v.$emit("query"))
1057
+ }, F(e.messages.query), 1),
1058
+ R("button", {
1059
+ class: "mrp-nav",
1060
+ type: "button",
1061
+ onClick: h[3] || (h[3] = (u) => v.$emit("reset"))
1062
+ }, F(e.messages.reset), 1)
1063
+ ])
1064
+ ]));
1065
+ }
1066
+ }), Ja = /* @__PURE__ */ We(Za, [["__scopeId", "data-v-aafce92d"]]), Ya = {
1067
+ title: "报表预览",
1068
+ prevPage: "‹ 上一页",
1069
+ nextPage: "下一页 ›",
1070
+ pageInfo: "{cur} / {total}",
1071
+ fitWidth: "适宽",
1072
+ exportHtml: "导出 HTML",
1073
+ exportPdf: "导出 PDF",
1074
+ exportExcel: "导出 Excel",
1075
+ exportImage: "导出图片",
1076
+ exportWord: "导出 Word",
1077
+ exporting: "正在生成 {format}…",
1078
+ print: "打印",
1079
+ pdfWindow: "PDF 窗口",
1080
+ loading: "报表渲染中…",
1081
+ empty: "暂无预览数据",
1082
+ errorPrefix: "",
1083
+ retry: "重试",
1084
+ pdfFontUnavailable: "PDF 字体尚未就绪,请联系管理员检查字体配置;预览及其它导出仍可使用。",
1085
+ searchPlaceholder: "搜索报表内容",
1086
+ matchInfo: "{cur}/{total}",
1087
+ prevMatch: "‹",
1088
+ nextMatch: "›",
1089
+ thumbnails: "缩略图",
1090
+ paramsTitle: "查询条件",
1091
+ query: "查 询",
1092
+ reset: "重 置",
1093
+ paramRequired: "请填写{label}",
1094
+ searching: "搜索中…",
1095
+ importExcel: "导入 Excel 模板",
1096
+ importing: "正在导入 Excel…",
1097
+ editCell: "编辑单元格",
1098
+ editingHint: "双击单元格编辑 · Enter 确认 · Esc 取消",
1099
+ saving: "正在保存修改…",
1100
+ editInvalidNumber: "请输入有效数字;清空表示无值",
1101
+ editInvalidBoolean: "请输入 true / false、是 / 否或 1 / 0",
1102
+ editConflict: "该单元格已变化,请重新打开编辑",
1103
+ settings: "设置",
1104
+ settingsDisplay: "阅读工具",
1105
+ settingsExport: "导出与打印",
1106
+ settingsData: "数据操作",
1107
+ settingsUnavailable: "需由接入方配置启用",
1108
+ settingsReset: "恢复默认",
1109
+ settingsClose: "关闭设置",
1110
+ search: "内容搜索",
1111
+ zoom: "缩放工具",
1112
+ settingsLocal: "按需启用工具,仅作用于当前预览。",
1113
+ editingLocal: "修改为本地草稿;不会自动写入业务数据库。",
1114
+ editingSaved: "修改将通过接入方配置的保存回调提交。",
1115
+ importLocal: "导入仅生成本地预览,不自动替换业务数据。",
1116
+ emptyDescription: "当前查询没有明细,请调整查询条件后重试。"
1117
+ }, Ga = {
1118
+ shellBg: "#525659",
1119
+ shellFg: "#e8e8e8",
1120
+ toolbarBg: "#323639",
1121
+ toolbarBorder: "#22252a",
1122
+ toolbarFg: "#e8e8e8",
1123
+ btnFg: "#cfcfcf",
1124
+ btnBorder: "#4a4d52",
1125
+ btnHoverBg: "#414549",
1126
+ btnHoverFg: "#ffffff",
1127
+ btnActiveBg: "#2d5fb8"
1128
+ };
1129
+ function Xa(e = {}) {
1130
+ return { ...e, defaults: e.defaults ?? {}, presets: e.presets ?? {} };
1131
+ }
1132
+ function Do(e) {
1133
+ return e;
1134
+ }
1135
+ const ge = {
1136
+ showExport: !0,
1137
+ showPrint: !0,
1138
+ showPdfWindow: !0,
1139
+ showSettings: !0,
1140
+ showParams: !0,
1141
+ gapPx: 18,
1142
+ pdfFontUrl: "/simhei.ttf",
1143
+ logger: console
1144
+ }, Bo = { warn: () => {
1145
+ }, info: () => {
1146
+ } };
1147
+ function Ze(e, t) {
1148
+ return {
1149
+ ...e,
1150
+ ...t,
1151
+ theme: { ...e?.theme, ...t?.theme },
1152
+ messages: { ...e?.messages, ...t?.messages },
1153
+ preview: { ...e?.preview, ...t?.preview },
1154
+ xlsx: { ...e?.xlsx, ...t?.xlsx },
1155
+ toolbar: { ...e?.toolbar, ...t?.toolbar }
1156
+ };
1157
+ }
1158
+ function Qa(e) {
1159
+ return {
1160
+ showExport: e.showExport ?? ge.showExport,
1161
+ showPrint: e.showPrint ?? ge.showPrint,
1162
+ showPdfWindow: e.showPdfWindow ?? ge.showPdfWindow,
1163
+ showSettings: e.showSettings ?? ge.showSettings,
1164
+ showParams: e.showParams ?? ge.showParams,
1165
+ gapPx: e.gapPx ?? ge.gapPx
1166
+ };
1167
+ }
1168
+ function _a(e, t) {
1169
+ const n = t ? e?.presets?.[t] : e?.defaultPreset ? e?.presets?.[e.defaultPreset] : void 0, r = Ze(e?.defaults, n);
1170
+ return {
1171
+ ...Qa(r),
1172
+ pdfFontUrl: r.pdfFontUrl ?? ge.pdfFontUrl,
1173
+ theme: { ...Ga, ...r.theme },
1174
+ messages: { ...Ya, ...r.messages },
1175
+ logger: r.logger ?? ge.logger,
1176
+ preview: {
1177
+ overscanPages: Nt(r.preview?.overscanPages, 1, 10, !0),
1178
+ searchDebounceMs: Nt(r.preview?.searchDebounceMs, 200, 2e3)
1179
+ },
1180
+ xlsx: { ...r.xlsx },
1181
+ editable: r.editable ?? !1,
1182
+ excelImport: r.excelImport ?? !1,
1183
+ toolbar: { ...r.toolbar }
1184
+ };
1185
+ }
1186
+ function Nt(e, t, n, r = !1) {
1187
+ if (e == null || !Number.isFinite(e)) return t;
1188
+ const a = Math.max(0, Math.min(n, e));
1189
+ return r ? Math.floor(a) : a;
1190
+ }
1191
+ function eo(e) {
1192
+ const t = {};
1193
+ return e.shellBg != null && (t["--mrp-shell-bg"] = e.shellBg), e.shellFg != null && (t["--mrp-shell-fg"] = e.shellFg), e.toolbarBg != null && (t["--mrp-toolbar-bg"] = e.toolbarBg), e.toolbarBorder != null && (t["--mrp-toolbar-border"] = e.toolbarBorder), e.toolbarFg != null && (t["--mrp-toolbar-fg"] = e.toolbarFg), e.btnFg != null && (t["--mrp-btn-fg"] = e.btnFg), e.btnBorder != null && (t["--mrp-btn-border"] = e.btnBorder), e.btnHoverBg != null && (t["--mrp-btn-hover-bg"] = e.btnHoverBg), e.btnHoverFg != null && (t["--mrp-btn-hover-fg"] = e.btnHoverFg), e.btnActiveBg != null && (t["--mrp-btn-active-bg"] = e.btnActiveBg), t;
1194
+ }
1195
+ function Wo(e) {
1196
+ const t = Je(bt, null), n = M(() => {
1197
+ const r = t?.value ?? null, a = "defaults" in e || "presets" in e || "defaultPreset" in e ? Xa(e) : { defaults: e, presets: {} };
1198
+ if (!r) return a;
1199
+ const o = { ...r.presets, ...a.presets };
1200
+ for (const s of Object.keys(o))
1201
+ o[s] = Ze(
1202
+ Ze(r.presets[s], a.defaults),
1203
+ a.presets[s]
1204
+ );
1205
+ return {
1206
+ defaults: Ze(r.defaults, a.defaults),
1207
+ presets: o,
1208
+ defaultPreset: a.defaultPreset ?? r.defaultPreset
1209
+ };
1210
+ });
1211
+ Zt(bt, n);
1212
+ }
1213
+ function to() {
1214
+ return Je(bt, M(() => null));
1215
+ }
1216
+ const qt = /* @__PURE__ */ new Map(), Ee = /* @__PURE__ */ new Map(), no = 15e3;
1217
+ function yt(e, t) {
1218
+ return Object.assign(new Error(e), { cause: t });
1219
+ }
1220
+ function Ie(e, t) {
1221
+ return `PDF 字体 ${JSON.stringify(e)}:${t}。请部署支持报表文字的字体文件,并将 pdfFontUrl 配置为可访问的字体 URL;西文报表可设为空串`;
1222
+ }
1223
+ function Xe(e) {
1224
+ if (e?.reason instanceof Error && e.reason.name === "AbortError") return e.reason;
1225
+ const t = yt("PDF 字体检查已取消", e?.reason);
1226
+ return t.name = "AbortError", t;
1227
+ }
1228
+ async function ao(e, t) {
1229
+ let n = !1;
1230
+ const r = setTimeout(() => {
1231
+ n = !0, t.abort();
1232
+ }, no);
1233
+ try {
1234
+ const a = await fetch(e, { method: "HEAD", signal: t.signal });
1235
+ if (t.signal.aborted) throw Xe(t.signal);
1236
+ if (a.status === 405 || a.status === 501 || a.type === "opaque")
1237
+ return {
1238
+ status: "unverified",
1239
+ fontUrl: e,
1240
+ message: `PDF 字体 ${JSON.stringify(e)} 无法通过 HEAD 检查验证;仍可尝试导出,届时会加载并校验字体`
1241
+ };
1242
+ if (!a.ok) {
1243
+ const s = new Error(`字体请求返回 HTTP ${a.status}`);
1244
+ return { status: "error", fontUrl: e, message: Ie(e, s.message), cause: s };
1245
+ }
1246
+ const o = a.headers.get("content-type") ?? "";
1247
+ if (/text\/html|application\/xhtml\+xml/i.test(o)) {
1248
+ const s = new Error("字体 URL 返回 HTML 页面(可能是 SPA 路由回退),不是字体文件");
1249
+ return { status: "error", fontUrl: e, message: Ie(e, s.message), cause: s };
1250
+ }
1251
+ if (/^text\//i.test(o) || /(?:\/|\+)json(?:\s*;|$)/i.test(o)) {
1252
+ const s = new Error(`字体 URL 返回 ${o} 文本响应,不是字体文件`);
1253
+ return { status: "error", fontUrl: e, message: Ie(e, s.message), cause: s };
1254
+ }
1255
+ return {
1256
+ status: "available",
1257
+ fontUrl: e,
1258
+ message: "PDF 字体资源可达;文字覆盖范围将在实际导出时校验"
1259
+ };
1260
+ } catch (a) {
1261
+ if (t.signal.aborted && !n) throw Xe(t.signal);
1262
+ return {
1263
+ status: "error",
1264
+ fontUrl: e,
1265
+ message: Ie(e, n ? "字体检查超时,请检查网络或字体服务" : "字体检查失败,请检查网络、字体服务或跨域访问配置"),
1266
+ cause: a
1267
+ };
1268
+ } finally {
1269
+ clearTimeout(r);
1270
+ }
1271
+ }
1272
+ function oo(e, t) {
1273
+ if (t?.aborted) return Promise.reject(Xe(t));
1274
+ if (!e)
1275
+ return Promise.resolve({ status: "disabled", fontUrl: e, message: "已停用自定义 PDF 字体;内置字体用于西文,其他文字会在导出时校验" });
1276
+ const n = qt.get(e);
1277
+ if (n) return Promise.resolve(n);
1278
+ let r = Ee.get(e);
1279
+ if (!r) {
1280
+ const o = new AbortController();
1281
+ r = { controller: o, promise: ao(e, o), subscribers: 0 };
1282
+ const s = r;
1283
+ Ee.set(e, s), s.promise = s.promise.then((f) => (!o.signal.aborted && f.status === "available" && qt.set(e, f), f)).finally(() => {
1284
+ Ee.get(e) === s && Ee.delete(e);
1285
+ });
1286
+ }
1287
+ const a = r;
1288
+ return a.subscribers++, new Promise((o, s) => {
1289
+ let f = !1;
1290
+ const v = () => f ? !1 : (f = !0, a.subscribers--, t?.removeEventListener("abort", h), !0), h = () => {
1291
+ v() && (a.subscribers === 0 && (Ee.get(e) === a && Ee.delete(e), a.controller.abort()), s(Xe(t)));
1292
+ };
1293
+ t?.addEventListener("abort", h, { once: !0 }), a.promise.then(
1294
+ (u) => {
1295
+ v() && o(u);
1296
+ },
1297
+ (u) => {
1298
+ v() && s(u);
1299
+ }
1300
+ ), t?.aborted && h();
1301
+ });
1302
+ }
1303
+ function ro(e = { fontUrl: "/simhei.ttf" }) {
1304
+ let t = null;
1305
+ const n = async (r, a) => {
1306
+ t || (t = await import("@agile-team/mach-report/pdf"));
1307
+ let o = null;
1308
+ if (e.fontUrl)
1309
+ try {
1310
+ if (o = await t.loadFontWithCache(e.fontUrl, { strict: !0 }), !o?.byteLength) throw new Error("字体文件为空或加载失败");
1311
+ } catch (d) {
1312
+ const m = d instanceof Error ? d.message : String(d);
1313
+ throw yt(Ie(e.fontUrl, m), d);
1314
+ }
1315
+ let s;
1316
+ try {
1317
+ s = await t.renderPlanToPdf(r, o ? { customFontBytes: o } : {});
1318
+ } catch (d) {
1319
+ if (!o) throw d;
1320
+ const m = d instanceof Error ? d.message : String(d);
1321
+ throw yt(`PDF 生成失败:${m}。当前字体 URL 为 ${JSON.stringify(e.fontUrl)};请确认该文件是有效字体,或重新配置 pdfFontUrl`, d);
1322
+ }
1323
+ const { bytes: f, unsupportedTextCount: v, pageErrors: h, fidelityWarnings: u } = s;
1324
+ if (v > 0)
1325
+ throw new Error(`PDF 中有 ${v} 行文字无法编码;请部署支持所用文字的字体并配置 pdfFontUrl`);
1326
+ if (h.length > 0)
1327
+ throw new Error(`PDF 有 ${h.length} 页渲染失败:${h[0]}`);
1328
+ return u.length > 0 && a?.(`PDF 有 ${u.length} 处版式降级:${u.slice(0, 2).join(";")}`), f;
1329
+ };
1330
+ return n.checkFont = (r) => oo(e.fontUrl, r), n;
1331
+ }
1332
+ class ve extends Error {
1333
+ constructor(t, n, r) {
1334
+ super(n), this.name = "MachReportError", this.code = t, this.cause = r;
1335
+ }
1336
+ }
1337
+ function so(e) {
1338
+ return e instanceof ve ? { code: e.code, cause: e.cause } : { code: "render", cause: e };
1339
+ }
1340
+ function Pe(e) {
1341
+ return JSON.parse(JSON.stringify(e));
1342
+ }
1343
+ function lo(e) {
1344
+ const t = e.closest(".mrp-page-holder"), n = e.closest("[data-mr-component-index]");
1345
+ if (!t || !n) return null;
1346
+ const r = {
1347
+ pageIndex: Number(t.dataset.page) - 1,
1348
+ componentIndex: Number(n.dataset.mrComponentIndex),
1349
+ rowIndex: Number(e.dataset.mrRowIndex),
1350
+ columnIndex: Number(e.dataset.mrColumnIndex)
1351
+ };
1352
+ return Object.values(r).every((a) => Number.isInteger(a) && a >= 0) ? r : null;
1353
+ }
1354
+ function io(e, t, n) {
1355
+ const r = e.ownerDocument.createElement("textarea");
1356
+ return r.className = "mrp-cell-editor", r.setAttribute("aria-label", t), r.value = n == null ? "" : String(n), r.style.cssText = "position:absolute;inset:0;width:100%;height:100%;min-height:20px;box-sizing:border-box;z-index:10;resize:none;margin:0;padding:2px 4px;border:2px solid #2563eb;outline:none;background:#fff;color:#111;font:inherit;line-height:1.25;white-space:pre-wrap;", e.appendChild(r), r;
1357
+ }
1358
+ function uo(e) {
1359
+ const t = ke(null), n = W(!1), r = ke([]);
1360
+ let a = null;
1361
+ function o() {
1362
+ const i = t.value;
1363
+ t.value = null, n.value = !1, a = null, i?.controller.abort(), i?.input.remove();
1364
+ }
1365
+ function s() {
1366
+ o(), r.value = [];
1367
+ }
1368
+ function f(i) {
1369
+ return t.value === i && !i.controller.signal.aborted && e.plan.value === i.plan;
1370
+ }
1371
+ function v(i) {
1372
+ const P = e.options.value, T = At(i.plan, i.address);
1373
+ if (!(typeof P == "object" ? P === i.options : P === !0) || !T?.editable || i.options.canEdit?.(T) === !1)
1374
+ throw new Yt("readonly");
1375
+ }
1376
+ async function h(i) {
1377
+ try {
1378
+ v(i);
1379
+ const P = Rn(i.plan, i.address, i.input.value);
1380
+ if (Object.is(P.value, P.previousValue))
1381
+ return o(), !0;
1382
+ const T = { signal: i.controller.signal }, x = await i.options.validate?.(Pe(P), T);
1383
+ if (!f(i)) return !1;
1384
+ if (x) throw new Error(x);
1385
+ if (v(i), await i.options.save?.(Pe(P), T), !f(i)) return !1;
1386
+ v(i);
1387
+ const O = Tn(i.plan, P);
1388
+ return o(), r.value = [...r.value, P], e.plan.value = O, e.onChange(Pe(P)), !0;
1389
+ } catch (P) {
1390
+ return f(i) && (e.onError(e.errorMessage?.(P) ?? (P instanceof Error ? P.message : "单元格保存失败"), P), i.input.disabled = !1, i.input.setAttribute("aria-invalid", "true"), i.input.focus()), !1;
1391
+ } finally {
1392
+ t.value === i && (n.value = !1);
1393
+ }
1394
+ }
1395
+ async function u() {
1396
+ if (a) return a;
1397
+ const i = t.value;
1398
+ if (!i) return !0;
1399
+ if (!f(i))
1400
+ return o(), !1;
1401
+ n.value = !0, i.input.disabled = !0;
1402
+ const P = h(i);
1403
+ a = P;
1404
+ const T = await P;
1405
+ return a === P && (a = null), T;
1406
+ }
1407
+ function d(i) {
1408
+ i.stopPropagation(), !i.isComposing && (i.key === "Escape" && (i.preventDefault(), o()), i.key === "Enter" && !i.shiftKey && (i.preventDefault(), u()));
1409
+ }
1410
+ async function m(i) {
1411
+ if (!e.options.value || e.blocked()) return;
1412
+ const P = i.target;
1413
+ if (!(P instanceof Element) || P.closest(".mrp-cell-editor")) return;
1414
+ const T = P.closest("td[data-mr-row-index]");
1415
+ if (!T || !await u() || !T.isConnected) return;
1416
+ const x = e.plan.value, O = lo(T);
1417
+ if (!x || !O || !e.options.value || e.blocked()) return;
1418
+ const k = typeof e.options.value == "object" ? e.options.value : {};
1419
+ try {
1420
+ const D = At(x, O);
1421
+ if (!D?.editable || k.canEdit?.(D) === !1) return;
1422
+ const S = io(T, e.label(), D.value);
1423
+ t.value = { plan: x, address: O, input: S, controller: new AbortController(), options: k }, S.addEventListener("keydown", d), S.addEventListener("blur", () => {
1424
+ n.value || u();
1425
+ }), S.focus(), S.select();
1426
+ } catch (D) {
1427
+ e.onError(D instanceof Error ? D.message : "无法编辑单元格", D);
1428
+ }
1429
+ }
1430
+ return Q(e.options, (i, P) => {
1431
+ (!i || i !== P) && o();
1432
+ }, { flush: "sync" }), Q(e.plan, () => {
1433
+ t.value && e.plan.value !== t.value.plan && o();
1434
+ }, { flush: "sync" }), De(s), {
1435
+ active: t,
1436
+ saving: n,
1437
+ changes: r,
1438
+ cancel: o,
1439
+ reset: s,
1440
+ commit: u,
1441
+ onDoubleClick: m,
1442
+ getChanges: () => Pe(r.value)
1443
+ };
1444
+ }
1445
+ const wt = ["html", "pdf", "xlsx", "png", "word"], co = ["search", "thumbnails", "zoom", ...wt, "print", "pdfWindow", "editing", "import"];
1446
+ function fo(e, t) {
1447
+ const n = W({}), r = M(() => Object.fromEntries(co.map((s) => [
1448
+ s,
1449
+ e.value[s] && (n.value[s] ?? t.value[s] ?? !0)
1450
+ ])));
1451
+ function a(s, f) {
1452
+ e.value[s] && (n.value = { ...n.value, [s]: f });
1453
+ }
1454
+ function o() {
1455
+ n.value = {};
1456
+ }
1457
+ return { enabled: r, setEnabled: a, reset: o };
1458
+ }
1459
+ const mo = {
1460
+ key: 3,
1461
+ class: "mrp-edit-hint",
1462
+ role: "status"
1463
+ }, po = {
1464
+ key: 5,
1465
+ class: "mrp-export-notice mrp-export-warning",
1466
+ role: "status"
1467
+ }, vo = { class: "mrp-main" }, go = {
1468
+ key: 0,
1469
+ class: "mrp-state"
1470
+ }, ho = {
1471
+ key: 1,
1472
+ class: "mrp-state mrp-error"
1473
+ }, bo = ["data-page"], yo = ["onClick"], wo = ["data-thumb"], xo = { class: "mrp-thumb-no" }, Eo = { class: "mrp-overlay" }, Po = {
1474
+ key: 6,
1475
+ class: "mrp-debug",
1476
+ "aria-hidden": "true"
1477
+ }, Ve = 96 / 25.4, vt = "mach-report:ui", gt = "mach-report:ui:wide", ko = /* @__PURE__ */ Be({
1478
+ __name: "ReportPreview",
1479
+ props: {
1480
+ reportId: {
1481
+ type: [String, Array],
1482
+ default: null
1483
+ },
1484
+ params: {
1485
+ type: Object,
1486
+ default: () => ({})
1487
+ },
1488
+ height: { type: String, default: "100vh" },
1489
+ autoLoad: { type: Boolean, default: !0 },
1490
+ /** 以下显隐/间距不传时走配置中心(preset > defaults > 内置缺省) */
1491
+ showExport: { type: Boolean, default: void 0 },
1492
+ showPrint: { type: Boolean, default: void 0 },
1493
+ showPdfWindow: { type: Boolean, default: void 0 },
1494
+ showSettings: { type: Boolean, default: void 0 },
1495
+ toolbar: { type: Object, default: void 0 },
1496
+ /** 保留表头的零行业务结果;不改变计划和导出内容。 */
1497
+ emptyState: { type: [Boolean, Object], default: !1 },
1498
+ /** 页间距(px);不传走配置中心 */
1499
+ gapPx: { type: Number, default: void 0 },
1500
+ /** 工具栏/状态文案覆写(不传走配置中心 messages) */
1501
+ messages: { type: Object, default: void 0 },
1502
+ /** 启用的 preset 名(不传用配置中心 defaultPreset) */
1503
+ preset: { type: String, default: void 0 },
1504
+ /** 调试面板(也可用 URL ?mrp-debug=1 开启) */
1505
+ debug: { type: Boolean, default: !1 },
1506
+ /** 参数定义(优先级:prop > 模板 params;有定义且未关闭时显示查询面板) */
1507
+ paramDefs: {
1508
+ type: Array,
1509
+ default: void 0
1510
+ },
1511
+ /** 参数面板显隐(不传走配置中心,缺省 true;有参数定义才渲染) */
1512
+ showParams: { type: Boolean, default: void 0 },
1513
+ editable: { type: [Boolean, Object], default: void 0 },
1514
+ excelImport: { type: [Boolean, Object], default: void 0 },
1515
+ fetcher: {
1516
+ type: Function,
1517
+ default: null
1518
+ }
1519
+ },
1520
+ emits: ["loaded", "error", "warning", "cell-edit", "template-import", "preferences-change"],
1521
+ setup(e, { expose: t, emit: n }) {
1522
+ $n((l) => ({
1523
+ v54e94a63: _.value + "px"
1524
+ }));
1525
+ const r = e, a = n, o = ke(null), s = W(!1), f = W(""), v = ke(null), h = W(null), u = W(!1), d = ke(Object.freeze({ status: "unchecked", fontUrl: "" })), m = W(null), i = W(1), P = W(null), T = W(null), x = W(null), O = W(!1), k = W(!1), D = W(!1), S = W(null), z = ea(), A = M(() => !!o.value?.pages.length && o.value.pages.every((l) => l.layout === "wide")), _ = M(() => Math.max(0, Pt.value));
1526
+ let V = vt;
1527
+ const ee = Je(Wn, null), Y = Je(zn, null), ae = M(() => Xt(r.reportId)), me = M(() => r.fetcher ?? ee), U = M(() => o.value?.pages.length ?? 0), ue = M(() => Object.freeze({
1528
+ loading: s.value,
1529
+ hasPlan: U.value > 0,
1530
+ pageCount: U.value,
1531
+ currentPage: i.value,
1532
+ exporting: h.value,
1533
+ printing: u.value,
1534
+ canExport: !s.value && !k.value && !q.saving.value && U.value > 0 && h.value === null,
1535
+ canPrint: !s.value && !k.value && !q.saving.value && U.value > 0 && !u.value,
1536
+ error: v.value,
1537
+ pdfFont: d.value,
1538
+ editing: q.active.value !== null,
1539
+ saving: q.saving.value,
1540
+ importing: k.value,
1541
+ dirty: q.changes.value.length > 0
1542
+ }));
1543
+ function c(l, p, g) {
1544
+ v.value = Object.freeze({ message: l, code: p, cause: g }), a("error", l, { code: p, cause: g });
1545
+ }
1546
+ const b = to(), y = M(() => _a(b.value, r.preset)), $ = M(() => ({
1547
+ ...y.value.messages,
1548
+ ...r.messages
1549
+ })), B = M(() => r.showExport ?? y.value.showExport), Z = M(() => r.showPrint ?? y.value.showPrint), G = M(() => r.showPdfWindow ?? y.value.showPdfWindow), oe = M(() => r.showSettings ?? y.value.showSettings), we = M(() => ({ ...y.value.toolbar, ...r.toolbar })), Pt = M(() => r.gapPx ?? (A.value ? 0 : y.value.gapPx)), en = M(() => r.showParams ?? y.value.showParams), ze = M(() => r.editable ?? y.value.editable), kt = M(() => r.excelImport ?? y.value.excelImport), $t = M(() => ({
1550
+ search: we.value.search !== !1,
1551
+ thumbnails: we.value.thumbnails !== !1,
1552
+ zoom: we.value.zoom !== !1,
1553
+ ...Object.fromEntries(wt.map((l) => [
1554
+ l,
1555
+ B.value && (we.value.exportFormats?.includes(l) ?? !0)
1556
+ ])),
1557
+ print: Z.value,
1558
+ pdfWindow: G.value,
1559
+ editing: !!ze.value,
1560
+ import: !!kt.value
1561
+ })), Qe = fo($t, M(() => ({
1562
+ editing: we.value.editing,
1563
+ import: we.value.excelImport
1564
+ }))), K = Qe.enabled, tn = M(() => wt.filter((l) => K.value[l])), Ct = M(() => K.value.editing ? ze.value : !1), Le = M(() => K.value.import ? kt.value : !1), nn = M(() => typeof ze.value == "object" && typeof ze.value.save == "function"), _e = M(() => typeof r.emptyState == "object" ? r.emptyState : {});
1565
+ async function an(l, p) {
1566
+ l === "editing" && !p && !await q.commit() || (Qe.setEnabled(l, p), a("preferences-change", Object.freeze({ ...K.value })));
1567
+ }
1568
+ async function on() {
1569
+ await q.commit() && (Qe.reset(), a("preferences-change", Object.freeze({ ...K.value })));
1570
+ }
1571
+ function rn(l) {
1572
+ return l instanceof Yt ? {
1573
+ number: $.value.editInvalidNumber,
1574
+ boolean: $.value.editInvalidBoolean,
1575
+ conflict: $.value.editConflict
1576
+ }[l.code] ?? l.message : l instanceof Error ? l.message : "单元格保存失败";
1577
+ }
1578
+ const q = uo({
1579
+ plan: o,
1580
+ options: Ct,
1581
+ blocked: () => s.value || k.value || h.value !== null || u.value,
1582
+ label: () => $.value.editCell ?? "编辑单元格",
1583
+ errorMessage: rn,
1584
+ onChange: (l) => {
1585
+ v.value = null, m.value = null, a("cell-edit", l);
1586
+ },
1587
+ onError: (l, p) => {
1588
+ m.value = { kind: "error", message: l }, c(l, "edit", p);
1589
+ }
1590
+ });
1591
+ let Mt = null, et = null;
1592
+ function Ft() {
1593
+ if (Y) return Y;
1594
+ const l = y.value.pdfFontUrl;
1595
+ return (!et || Mt !== l) && (Mt = l, et = ro({ fontUrl: l })), et;
1596
+ }
1597
+ let Ae = 0, Ce = null, He = null, ce = !1;
1598
+ function tt() {
1599
+ Ae++, Ce?.abort(), Ce = null;
1600
+ }
1601
+ async function je() {
1602
+ if (ce) throw new ve("config", "报表预览已卸载");
1603
+ tt();
1604
+ const l = Ae, p = new AbortController();
1605
+ Ce = p;
1606
+ const g = y.value.pdfFontUrl;
1607
+ d.value = Object.freeze({ status: "checking", fontUrl: g });
1608
+ try {
1609
+ const N = Ft(), H = N.checkFont ? await N.checkFont(p.signal) : { status: "unverified", fontUrl: "", message: "自定义 PDF 导出器未提供字体预检查;字体由宿主确认" };
1610
+ return !ce && l === Ae && !p.signal.aborted && (d.value = Object.freeze({ ...H })), H;
1611
+ } catch (N) {
1612
+ if (p.signal.aborted) throw N;
1613
+ const H = {
1614
+ status: "error",
1615
+ fontUrl: g,
1616
+ message: N instanceof Error ? N.message : "PDF 字体检查失败",
1617
+ cause: N
1618
+ };
1619
+ return !ce && l === Ae && (d.value = Object.freeze(H)), H;
1620
+ } finally {
1621
+ Ce === p && (Ce = null);
1622
+ }
1623
+ }
1624
+ function sn() {
1625
+ je().catch(() => {
1626
+ });
1627
+ }
1628
+ Q(
1629
+ [o, () => y.value.pdfFontUrl, B, G],
1630
+ () => {
1631
+ const l = d.value.fontUrl === y.value.pdfFontUrl;
1632
+ l && d.value.status === "available" || (tt(), (!l || d.value.status === "checking") && (d.value = Object.freeze({ status: "unchecked", fontUrl: y.value.pdfFontUrl })), !ce && U.value > 0 && (B.value || G.value) && je().catch(() => {
1633
+ }));
1634
+ },
1635
+ { immediate: !0 }
1636
+ );
1637
+ const pe = M(
1638
+ () => r.paramDefs ?? me.value?.getParamDefs?.(ae.value) ?? []
1639
+ ), he = W({}), nt = W(!1);
1640
+ function Me(l) {
1641
+ const p = {};
1642
+ for (const g of l)
1643
+ p[g.field] = r.params[g.field] ?? g.defaultValue ?? "";
1644
+ he.value = p, nt.value = !1;
1645
+ }
1646
+ Me(pe.value), Q(pe, (l) => Me(l)), Q(ae, () => Me(pe.value)), Q(() => JSON.stringify(r.params), () => Me(pe.value));
1647
+ const ln = M(() => {
1648
+ const l = { ...r.params };
1649
+ for (const [p, g] of Object.entries(he.value))
1650
+ g === "" ? delete l[p] : l[p] = g;
1651
+ return l;
1652
+ });
1653
+ function un() {
1654
+ return pe.value.filter(
1655
+ (l) => l.required === !0 && !(he.value[l.field] ?? "").trim()
1656
+ );
1657
+ }
1658
+ function cn() {
1659
+ nt.value = !0;
1660
+ const l = un();
1661
+ if (l.length > 0) {
1662
+ const p = l[0].label ?? l[0].field, g = $.value.paramRequired.replace("{label}", p);
1663
+ f.value = g, c(g, "param");
1664
+ return;
1665
+ }
1666
+ be();
1667
+ }
1668
+ function dn() {
1669
+ Me(pe.value);
1670
+ }
1671
+ const fn = M(() => ({
1672
+ height: r.height,
1673
+ ...eo(y.value.theme)
1674
+ })), { zoom: te, zoomMode: Fe, applyFitZoom: Rt, setZoom: Re } = Hn(() => ({
1675
+ viewport: T.value,
1676
+ pageWidthPx: at.contentSize.value.w || 210 * Ve
1677
+ })), at = An(o, te, {
1678
+ pxPerMm: Ve,
1679
+ gapPx: Pt,
1680
+ overscan: M(() => y.value.preview.overscanPages)
1681
+ }), { contentSize: ot, windowRange: Te, visiblePages: Tt, makeScrollHandler: mn, refreshViewport: rt } = at, pn = mn(i, U);
1682
+ function st(l) {
1683
+ Re(l * 100);
1684
+ }
1685
+ function Ne() {
1686
+ k.value = !1, q.reset(), St(), o.value = null, i.value = 1, j.reset();
1687
+ }
1688
+ let J = 0, re = null;
1689
+ async function be() {
1690
+ if (ce) return;
1691
+ const l = ++J;
1692
+ k.value = !1, re?.abort(), re = null;
1693
+ const p = me.value;
1694
+ if (s.value = !1, v.value = null, ae.value.length === 0) {
1695
+ f.value = "缺少报表 ID", Ne(), c(f.value, "param");
1696
+ return;
1697
+ }
1698
+ if (!p) {
1699
+ f.value = "未提供渲染数据源 fetcher", Ne(), c(f.value, "config");
1700
+ return;
1701
+ }
1702
+ s.value = !0, f.value = "", m.value = null, Ne();
1703
+ const g = z.start(), N = new AbortController();
1704
+ re = N;
1705
+ const H = /* @__PURE__ */ new Set();
1706
+ function se(L) {
1707
+ l !== J || N.signal.aborted || H.has(L) || (H.add(L), y.value.logger.warn("[mach-report] 报表告警:", L), a("warning", L));
1708
+ }
1709
+ try {
1710
+ const L = await p({
1711
+ reportIds: ae.value,
1712
+ params: { ...ln.value },
1713
+ signal: N.signal,
1714
+ onWarning: se
1715
+ });
1716
+ if (l !== J) return;
1717
+ const X = Ht(L);
1718
+ if (!X.ok) {
1719
+ const qe = X.errors.slice(0, 3).map((Wt) => `${Wt.path}: ${Wt.message}`).join("; ");
1720
+ throw new ve(
1721
+ "validate",
1722
+ `渲染计划校验失败(${X.errors.length} 处): ${qe}`
1723
+ );
1724
+ }
1725
+ if (X.warnings.forEach((qe) => se(`${qe.path}: ${qe.message}`)), l !== J || N.signal.aborted) return;
1726
+ o.value = L, i.value = 1, z.end(g), T.value && (T.value.scrollTop = 0, T.value.scrollLeft = 0);
1727
+ const ne = A.value ? gt : vt;
1728
+ ne !== V && (V = ne, mt()), Fe.value === "fit" && Rt(), a("loaded", L.pages.length);
1729
+ } catch (L) {
1730
+ if (l !== J) return;
1731
+ const X = L instanceof ve ? L : L instanceof In ? new ve(L.code, L.message, L.cause) : new ve(
1732
+ "fetch",
1733
+ L instanceof Error ? L.message : "预览加载失败",
1734
+ L
1735
+ );
1736
+ f.value = X.message;
1737
+ const ne = so(X);
1738
+ c(X.message, ne.code, ne.cause);
1739
+ } finally {
1740
+ l === J && (s.value = !1), re === N && (re = null);
1741
+ }
1742
+ }
1743
+ function de(l) {
1744
+ if (ce || U.value <= 0) return;
1745
+ const p = Math.max(1, Math.min(U.value, l));
1746
+ i.value = p;
1747
+ const g = T.value;
1748
+ g && (g.scrollTop = at.pageOffsetPx(p - 1) * te.value, rt(g));
1749
+ }
1750
+ const Se = Nn(o, {
1751
+ getPdfExporter: Ft,
1752
+ getXlsxOptions: () => y.value.xlsx,
1753
+ onError: (l, p) => {
1754
+ m.value = { kind: "error", message: l }, c(l, p ?? "print");
1755
+ },
1756
+ onWarning: (l) => {
1757
+ m.value = { kind: "warning", message: l }, a("warning", l);
1758
+ },
1759
+ onBusy: (l) => {
1760
+ h.value = l, l ? m.value = {
1761
+ kind: "progress",
1762
+ message: $.value.exporting.replace("{format}", l)
1763
+ } : m.value?.kind === "progress" && (m.value = null);
1764
+ },
1765
+ onPrinting: (l) => {
1766
+ u.value = l;
1767
+ }
1768
+ }), { releasePrintFrame: St, dispose: vn } = Se;
1769
+ async function lt() {
1770
+ s.value || k.value || q.active.value && !await q.commit() || (v.value = null, await Se.print());
1771
+ }
1772
+ async function it(l) {
1773
+ s.value || k.value || q.active.value && !await q.commit() || (v.value = null, await Se.exportAs(l));
1774
+ }
1775
+ function ut() {
1776
+ if (s.value || k.value || q.active.value) {
1777
+ m.value = { kind: "warning", message: $.value.editingHint ?? "请先确认单元格修改" };
1778
+ return;
1779
+ }
1780
+ v.value = null, Se.openPdfWindow();
1781
+ }
1782
+ async function It(l, p = {}) {
1783
+ ce || (he.value = { ...he.value, ...l }, p.reload !== !1 && await be());
1784
+ }
1785
+ const gn = {
1786
+ reload: be,
1787
+ print: lt,
1788
+ exportAs: it,
1789
+ openPdfWindow: ut,
1790
+ gotoPage: de,
1791
+ setParams: It,
1792
+ checkPdfFont: je,
1793
+ importExcel: ct,
1794
+ getPlan: Ot,
1795
+ getChanges: q.getChanges,
1796
+ get state() {
1797
+ return ue.value;
1798
+ }
1799
+ };
1800
+ Zt(Ln, gn);
1801
+ function Ot() {
1802
+ return o.value ? Pe(o.value) : null;
1803
+ }
1804
+ async function ct(l, p) {
1805
+ if (ce) throw new ve("config", "报表预览已卸载");
1806
+ const g = ++J;
1807
+ re?.abort(), re = null, s.value = !1, q.cancel(), Se.invalidatePending(), k.value = !0, v.value = null, m.value = { kind: "progress", message: $.value.importing ?? "正在导入 Excel…" };
1808
+ try {
1809
+ const { importExcelTemplate: N } = await import("@agile-team/mach-report/xlsx");
1810
+ if (g !== J) return null;
1811
+ const H = typeof Le.value == "object" ? Le.value : {}, se = await N(l, { ...H, ...p, limits: { ...H.limits, ...p?.limits } });
1812
+ if (g !== J) return null;
1813
+ const L = Sn(Pe(se.template), {}).plan, X = Ht(L);
1814
+ if (!X.ok) throw new Error(X.errors.map((ne) => ne.message).slice(0, 3).join("; "));
1815
+ for (const ne of se.warnings) {
1816
+ if (g !== J) return null;
1817
+ a("warning", ne);
1818
+ }
1819
+ return g !== J ? null : (q.reset(), St(), j.reset(), o.value = L, i.value = 1, f.value = "", m.value = se.warnings.length ? { kind: "warning", message: se.warnings.join(";") } : null, T.value && (T.value.scrollTop = 0, T.value.scrollLeft = 0), V = A.value ? gt : vt, mt(), a("template-import", se), g === J && a("loaded", L.pages.length), se);
1820
+ } catch (N) {
1821
+ if (g !== J) return null;
1822
+ const H = new ve("import", N instanceof Error ? N.message : "Excel 模板导入失败", N);
1823
+ throw m.value = { kind: "error", message: H.message }, c(H.message, "import", N), H;
1824
+ } finally {
1825
+ g === J && (k.value = !1);
1826
+ }
1827
+ }
1828
+ function hn(l) {
1829
+ const p = l.target, g = p.files?.[0];
1830
+ p.value = "", g && ct(g).catch(() => {
1831
+ });
1832
+ }
1833
+ const j = Xn({
1834
+ plan: o,
1835
+ gotoPage: de,
1836
+ debounceMs: M(() => y.value.preview.searchDebounceMs),
1837
+ highlight: Un,
1838
+ clearHighlights: qn
1839
+ });
1840
+ Q(() => K.value.search, (l) => {
1841
+ l || (j.reset(), j.visible.value = !1);
1842
+ });
1843
+ function bn(l) {
1844
+ !l.ctrlKey || !K.value.zoom || (l.preventDefault(), st(te.value * (l.deltaY < 0 ? 1.1 : 1 / 1.1)));
1845
+ }
1846
+ function yn(l) {
1847
+ if (!(l.target instanceof Element && l.target.closest("input,textarea,select,[contenteditable='true']"))) {
1848
+ if (K.value.search && (l.ctrlKey || l.metaKey) && l.key.toLowerCase() === "f") {
1849
+ l.preventDefault(), j.visible.value || j.toggle();
1850
+ return;
1851
+ }
1852
+ switch (l.key) {
1853
+ case "PageDown":
1854
+ l.preventDefault(), de(i.value + 1);
1855
+ break;
1856
+ case "PageUp":
1857
+ l.preventDefault(), de(i.value - 1);
1858
+ break;
1859
+ case "Home":
1860
+ l.preventDefault(), de(1);
1861
+ break;
1862
+ case "End":
1863
+ l.preventDefault(), de(U.value);
1864
+ break;
1865
+ case "+":
1866
+ case "=":
1867
+ l.preventDefault(), K.value.zoom && st(te.value * 1.1);
1868
+ break;
1869
+ case "-":
1870
+ l.preventDefault(), K.value.zoom && st(te.value / 1.1);
1871
+ break;
1872
+ }
1873
+ }
1874
+ }
1875
+ function wn() {
1876
+ try {
1877
+ localStorage.setItem(
1878
+ V,
1879
+ JSON.stringify({ zoomMode: Fe.value === "fit" ? "fit" : Math.round(te.value * 100) })
1880
+ );
1881
+ } catch {
1882
+ }
1883
+ }
1884
+ Q([Fe, te], wn);
1885
+ let dt = "";
1886
+ const Dt = /* @__PURE__ */ new WeakMap();
1887
+ function Bt(l = !1) {
1888
+ const p = j.activeMatch.value;
1889
+ if (!A.value || !p) return;
1890
+ const g = `${j.query.value}:${j.matchIndex.value}:${p.pageIndex}`;
1891
+ if (!l && g === dt) return;
1892
+ const H = P.value?.querySelector(`[data-page="${p.pageIndex + 1}"]`)?.querySelectorAll("mark.mrp-hit")[p.occurrence];
1893
+ H && (H.scrollIntoView?.({ block: "nearest", inline: "nearest" }), dt = g);
1894
+ }
1895
+ Lt(() => {
1896
+ const l = o.value;
1897
+ if (!l) return;
1898
+ const p = j.activeMatch.value;
1899
+ j.matchIndex.value, p || (dt = ""), Tt.value;
1900
+ const g = P.value;
1901
+ if (!g) return;
1902
+ g.querySelectorAll(".mrp-page-holder").forEach((H) => {
1903
+ const se = Number(H.dataset.page ?? 0) - 1, L = l.pages[se];
1904
+ if (!L || H.childElementCount > 0 && Dt.get(H) === L) {
1905
+ if (H.firstElementChild) {
1906
+ const ne = H.firstElementChild;
1907
+ j.clear(ne), j.apply(ne);
1908
+ }
1909
+ return;
1910
+ }
1911
+ H.style.width = `${L.pageWidthMm * Ve}px`;
1912
+ const X = Jt(L, 96, {}, document);
1913
+ j.apply(X), H.replaceChildren(X), Dt.set(H, L);
1914
+ }), Bt();
1915
+ }, { flush: "post" }), Q(() => j.query.value, (l) => {
1916
+ l || P.value?.querySelectorAll(".mrp-page-holder").forEach((p) => {
1917
+ j.clear(p);
1918
+ });
1919
+ });
1920
+ const le = _n(o, {
1921
+ thumbsRoot: x,
1922
+ visible: O,
1923
+ renderThumbCanvas: (l) => {
1924
+ try {
1925
+ const p = o.value.pages[l], g = Math.min(0.2, 116 / Math.max(1, p.pageWidthMm * Ve)), { canvases: N } = On(o.value, { start: l, end: l, dpr: g });
1926
+ return N[0] ?? null;
1927
+ } catch {
1928
+ return null;
1929
+ }
1930
+ }
1931
+ });
1932
+ Lt(() => {
1933
+ le.schedule();
1934
+ }, { flush: "post" });
1935
+ const xn = M(() => r.debug), { debugStats: xe } = Qn(xn, {
1936
+ plan: o,
1937
+ pageCount: U,
1938
+ windowRange: Te,
1939
+ zoom: te,
1940
+ loadMs: z.loadMs
1941
+ });
1942
+ function ft() {
1943
+ rt(T.value), le.schedule(), Fe.value === "fit" && Rt(), Bt(!0);
1944
+ }
1945
+ function mt() {
1946
+ Re(V === gt ? 100 : "fit");
1947
+ try {
1948
+ const l = JSON.parse(localStorage.getItem(V) ?? "{}");
1949
+ l.zoomMode === "fit" ? Re("fit") : typeof l.zoomMode == "number" && Re(l.zoomMode);
1950
+ } catch {
1951
+ }
1952
+ }
1953
+ return Vt(() => {
1954
+ window.addEventListener("resize", ft), typeof ResizeObserver < "u" && T.value && (He = new ResizeObserver(ft), He.observe(T.value)), rt(T.value), mt(), r.autoLoad && be();
1955
+ }), Kt(() => {
1956
+ ce = !0, q.reset(), k.value = !1, tt(), J++, re?.abort(), re = null, window.removeEventListener("resize", ft), He?.disconnect(), He = null, le.destroy(), j.reset(), vn();
1957
+ }), Q(
1958
+ () => [JSON.stringify(ae.value), JSON.stringify(r.params), me.value],
1959
+ () => {
1960
+ if (r.autoLoad) {
1961
+ be();
1962
+ return;
1963
+ }
1964
+ J++, re?.abort(), re = null, s.value = !1, f.value = "", v.value = null, m.value = null, Ne();
1965
+ }
1966
+ ), t({ reload: be, print: lt, exportAs: it, openPdfWindow: ut, gotoPage: de, setParams: It, checkPdfFont: je, importExcel: ct, getPlan: Ot, getChanges: q.getChanges, state: ue }), (l, p) => (w(), E("div", {
1967
+ class: ie(["mach-report-preview", { "mrp-wide-report": A.value }]),
1968
+ style: fe(fn.value)
1969
+ }, [
1970
+ en.value && pe.value.length > 0 ? (w(), Ue(Ja, {
1971
+ key: 0,
1972
+ defs: pe.value,
1973
+ modelValue: he.value,
1974
+ "onUpdate:modelValue": p[0] || (p[0] = (g) => he.value = g),
1975
+ messages: $.value,
1976
+ attempted: nt.value,
1977
+ onQuery: cn,
1978
+ onReset: dn
1979
+ }, null, 8, ["defs", "modelValue", "messages", "attempted"])) : I("", !0),
1980
+ Cn(Ea, {
1981
+ "page-count": U.value,
1982
+ "current-page": i.value,
1983
+ "zoom-mode": C(Fe),
1984
+ zoom: C(te),
1985
+ "show-export": B.value,
1986
+ "show-print": C(K).print,
1987
+ "show-pdf-window": C(K).pdfWindow,
1988
+ "show-search": C(K).search,
1989
+ "show-thumbnails": C(K).thumbnails,
1990
+ "show-zoom": C(K).zoom,
1991
+ "export-formats": tn.value,
1992
+ "show-settings": oe.value,
1993
+ "settings-open": D.value,
1994
+ messages: $.value,
1995
+ search: { visible: C(j).visible.value, query: C(j).query.value, matchIndex: C(j).matchIndex.value, matchCount: C(j).matchCount.value, searching: C(j).searching.value },
1996
+ "thumbs-visible": O.value,
1997
+ "show-import": !!Le.value,
1998
+ busy: s.value || k.value || C(q).saving.value,
1999
+ onGoto: de,
2000
+ onZoom: C(Re),
2001
+ onExport: p[1] || (p[1] = (g) => it(g)),
2002
+ onPrint: lt,
2003
+ onPdfWindow: ut,
2004
+ onSearchInput: C(j).onInput,
2005
+ onSearchNav: C(j).onNav,
2006
+ onSearchToggle: C(j).toggle,
2007
+ onThumbsToggle: p[2] || (p[2] = (g) => O.value = !O.value),
2008
+ onImportExcel: p[3] || (p[3] = (g) => S.value?.click()),
2009
+ onSettingsToggle: p[4] || (p[4] = (g) => D.value = !D.value)
2010
+ }, null, 8, ["page-count", "current-page", "zoom-mode", "zoom", "show-export", "show-print", "show-pdf-window", "show-search", "show-thumbnails", "show-zoom", "export-formats", "show-settings", "settings-open", "messages", "search", "thumbs-visible", "show-import", "busy", "onZoom", "onSearchInput", "onSearchNav", "onSearchToggle"]),
2011
+ D.value && oe.value ? (w(), Ue(Oa, {
2012
+ key: 1,
2013
+ available: $t.value,
2014
+ enabled: C(K),
2015
+ messages: $.value,
2016
+ "persisted-editing": nn.value,
2017
+ busy: s.value || k.value || C(q).saving.value || !!h.value || u.value,
2018
+ onChange: an,
2019
+ onReset: on,
2020
+ onClose: p[5] || (p[5] = (g) => D.value = !1)
2021
+ }, {
2022
+ default: Mn(() => [
2023
+ ht(l.$slots, "settings", {}, void 0, !0)
2024
+ ]),
2025
+ _: 3
2026
+ }, 8, ["available", "enabled", "messages", "persisted-editing", "busy"])) : I("", !0),
2027
+ Le.value ? (w(), E("input", {
2028
+ key: 2,
2029
+ ref_key: "importInputRef",
2030
+ ref: S,
2031
+ class: "mrp-import-input",
2032
+ type: "file",
2033
+ accept: ".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
2034
+ hidden: "",
2035
+ onChange: hn
2036
+ }, null, 544)) : I("", !0),
2037
+ Ct.value && U.value > 0 ? (w(), E("div", mo, F(C(q).saving.value ? $.value.saving : $.value.editingHint), 1)) : I("", !0),
2038
+ m.value ? (w(), E("div", {
2039
+ key: 4,
2040
+ class: ie(["mrp-export-notice", `mrp-export-${m.value.kind}`]),
2041
+ role: "alert"
2042
+ }, F(m.value.message), 3)) : I("", !0),
2043
+ d.value.status === "error" && (B.value || G.value) ? (w(), E("div", po, [
2044
+ Oe(F($.value.pdfFontUnavailable) + " ", 1),
2045
+ R("button", {
2046
+ type: "button",
2047
+ onClick: sn
2048
+ }, F($.value.retry), 1)
2049
+ ])) : I("", !0),
2050
+ R("div", vo, [
2051
+ R("div", {
2052
+ ref_key: "viewportRef",
2053
+ ref: T,
2054
+ class: "mrp-body",
2055
+ tabindex: "0",
2056
+ onWheel: bn,
2057
+ onKeydown: yn,
2058
+ onDblclick: p[6] || (p[6] = //@ts-ignore
2059
+ (...g) => C(q).onDoubleClick && C(q).onDoubleClick(...g)),
2060
+ onScrollPassive: p[7] || (p[7] = (g) => C(pn)(g.target))
2061
+ }, [
2062
+ s.value ? (w(), E("div", go, F($.value.loading), 1)) : f.value ? (w(), E("div", ho, [
2063
+ Oe(F(f.value) + " ", 1),
2064
+ R("button", {
2065
+ class: "mrp-retry",
2066
+ type: "button",
2067
+ onClick: be
2068
+ }, F($.value.retry), 1)
2069
+ ])) : !o.value || U.value === 0 ? (w(), Ue(jt, {
2070
+ key: 2,
2071
+ title: $.value.empty,
2072
+ description: _e.value.description ?? $.value.emptyDescription
2073
+ }, null, 8, ["title", "description"])) : (w(), E("div", {
2074
+ key: 3,
2075
+ class: "mrp-scale",
2076
+ style: fe({ width: `${C(ot).w * C(te)}px`, height: `${C(ot).h * C(te)}px` })
2077
+ }, [
2078
+ R("div", {
2079
+ ref_key: "containerRef",
2080
+ ref: P,
2081
+ class: "mrp-scale-inner",
2082
+ style: fe({ transform: `scale(${C(te)})`, transformOrigin: "top left", width: `${C(ot).w}px` })
2083
+ }, [
2084
+ C(Te).padTopPx > 0 ? (w(), E("div", {
2085
+ key: 0,
2086
+ class: "mrp-spacer-top",
2087
+ style: fe({ height: `${C(Te).padTopPx}px` }),
2088
+ "aria-hidden": "true"
2089
+ }, null, 4)) : I("", !0),
2090
+ (w(!0), E(ye, null, $e(C(Tt), (g) => (w(), E("div", {
2091
+ key: g.index,
2092
+ class: "mrp-page-holder",
2093
+ "data-page": g.index + 1
2094
+ }, null, 8, bo))), 128)),
2095
+ C(Te).padBottomPx > 0 ? (w(), E("div", {
2096
+ key: 1,
2097
+ class: "mrp-spacer-bottom",
2098
+ style: fe({ height: `${C(Te).padBottomPx}px` }),
2099
+ "aria-hidden": "true"
2100
+ }, null, 4)) : I("", !0)
2101
+ ], 4)
2102
+ ], 4)),
2103
+ !s.value && !f.value && o.value && U.value > 0 && e.emptyState ? (w(), Ue(jt, {
2104
+ key: 4,
2105
+ title: _e.value.title ?? $.value.empty,
2106
+ description: _e.value.description ?? $.value.emptyDescription
2107
+ }, null, 8, ["title", "description"])) : I("", !0)
2108
+ ], 544),
2109
+ C(K).thumbnails && O.value && U.value > 0 ? (w(), E("aside", {
2110
+ key: 0,
2111
+ ref_key: "thumbsRef",
2112
+ ref: x,
2113
+ class: "mrp-thumbs",
2114
+ onScrollPassive: p[8] || (p[8] = //@ts-ignore
2115
+ (...g) => C(le).onScroll && C(le).onScroll(...g))
2116
+ }, [
2117
+ C(le).windowRange.value.padTopPx > 0 ? (w(), E("div", {
2118
+ key: 0,
2119
+ class: "mrp-thumb-spacer",
2120
+ style: fe({ height: `${C(le).windowRange.value.padTopPx}px` }),
2121
+ "aria-hidden": "true"
2122
+ }, null, 4)) : I("", !0),
2123
+ (w(!0), E(ye, null, $e(C(le).visibleThumbs.value, (g) => (w(), E("div", {
2124
+ key: g.index,
2125
+ class: ie(["mrp-thumb", { "mrp-thumb-active": g.index + 1 === i.value }]),
2126
+ style: fe({ height: `${g.height + 20}px` }),
2127
+ onClick: (N) => de(g.index + 1)
2128
+ }, [
2129
+ R("div", {
2130
+ class: "mrp-thumb-box",
2131
+ "data-thumb": g.index + 1,
2132
+ style: fe({ height: `${g.height}px` })
2133
+ }, null, 12, wo),
2134
+ R("span", xo, F(g.index + 1), 1)
2135
+ ], 14, yo))), 128)),
2136
+ C(le).windowRange.value.padBottomPx > 0 ? (w(), E("div", {
2137
+ key: 1,
2138
+ class: "mrp-thumb-spacer",
2139
+ style: fe({ height: `${C(le).windowRange.value.padBottomPx}px` }),
2140
+ "aria-hidden": "true"
2141
+ }, null, 4)) : I("", !0)
2142
+ ], 544)) : I("", !0)
2143
+ ]),
2144
+ R("div", Eo, [
2145
+ ht(l.$slots, "default", {}, void 0, !0)
2146
+ ]),
2147
+ C(xe) ? (w(), E("div", Po, [
2148
+ p[9] || (p[9] = R("div", null, "mach-report debug", -1)),
2149
+ R("div", null, "pages: " + F(C(xe).pages) + " | window: [" + F(C(xe).window) + "]", 1),
2150
+ R("div", null, "zoom: " + F(C(xe).zoom) + " | load: " + F(C(xe).loadMs), 1),
2151
+ R("div", null, "plan: " + F(C(xe).planKB) + "KB", 1)
2152
+ ])) : I("", !0)
2153
+ ], 6));
2154
+ }
2155
+ }), $o = /* @__PURE__ */ We(ko, [["__scopeId", "data-v-a8ee1f0e"]]), zo = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2156
+ __proto__: null,
2157
+ default: $o
2158
+ }, Symbol.toStringTag, { value: "Module" }));
2159
+ export {
2160
+ Ya as D,
2161
+ ve as M,
2162
+ pt as P,
2163
+ wt as R,
2164
+ Bo as S,
2165
+ Ga as a,
2166
+ co as b,
2167
+ Ja as c,
2168
+ $o as d,
2169
+ Ea as e,
2170
+ Qt as f,
2171
+ jn as g,
2172
+ ro as h,
2173
+ Io as i,
2174
+ Xa as j,
2175
+ Do as k,
2176
+ So as l,
2177
+ Wo as m,
2178
+ Xt as n,
2179
+ so as o,
2180
+ Oo as p,
2181
+ An as q,
2182
+ _a as r,
2183
+ Nn as s,
2184
+ eo as t,
2185
+ to as u,
2186
+ Hn as v,
2187
+ zo as w
2188
+ };