@reportwright/cli 0.12.0 → 0.12.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/CHANGELOG.md +55 -1
- package/README.md +1 -1
- package/dist/pw.mjs +198 -94
- package/dist/pw.mjs.map +2 -2
- package/package.json +2 -2
package/dist/pw.mjs
CHANGED
|
@@ -3849,9 +3849,23 @@ function nodeRequest(url, init, trusted) {
|
|
|
3849
3849
|
for (let i = 0; i < res.rawHeaders.length; i += 2) pairs2.push([res.rawHeaders[i], res.rawHeaders[i + 1]]);
|
|
3850
3850
|
const none = [101, 204, 205, 304].includes(res.statusCode) || (init.method || "GET").toUpperCase() === "HEAD";
|
|
3851
3851
|
if (none) res.resume();
|
|
3852
|
-
|
|
3852
|
+
const enc = String(res.headers["content-encoding"] || "").trim().toLowerCase();
|
|
3853
|
+
let body = res, decoded = false;
|
|
3854
|
+
if (!none && enc && enc !== "identity") {
|
|
3855
|
+
const zlib = nodeMod("node:zlib");
|
|
3856
|
+
const dec2 = enc === "gzip" || enc === "x-gzip" ? zlib.createGunzip() : enc === "deflate" ? zlib.createInflate() : enc === "br" ? zlib.createBrotliDecompress() : null;
|
|
3857
|
+
if (!dec2) {
|
|
3858
|
+
res.resume();
|
|
3859
|
+
return reject(Object.assign(new Error(`the response is encoded as "${enc}", which the data fetch cannot decode`), { status: 415 }));
|
|
3860
|
+
}
|
|
3861
|
+
body = stream.pipeline(res, dec2, () => {
|
|
3862
|
+
});
|
|
3863
|
+
decoded = true;
|
|
3864
|
+
}
|
|
3865
|
+
const kept = decoded ? pairs2.filter(([k]) => !/^(content-encoding|content-length)$/i.test(k)) : pairs2;
|
|
3866
|
+
resolve(new Response(none ? null : stream.Readable.toWeb(body), { status: res.statusCode, statusText: res.statusMessage, headers: (
|
|
3853
3867
|
/** @type {any} */
|
|
3854
|
-
|
|
3868
|
+
kept
|
|
3855
3869
|
) }));
|
|
3856
3870
|
});
|
|
3857
3871
|
req.on("error", reject);
|
|
@@ -3869,7 +3883,7 @@ function redirectRequest(from, to, req, status) {
|
|
|
3869
3883
|
}
|
|
3870
3884
|
function guardedFetch(opt, base) {
|
|
3871
3885
|
const allow = (opt.allowHosts || []).map((h) => String(h).toLowerCase().replace(/^\[|\]$/g, ""));
|
|
3872
|
-
const node2 = inNode();
|
|
3886
|
+
const node2 = !opt.viaBase && inNode();
|
|
3873
3887
|
return (
|
|
3874
3888
|
/** @type {any} */
|
|
3875
3889
|
(async (input, init = {}) => {
|
|
@@ -4802,7 +4816,10 @@ function fetcherFor(opt) {
|
|
|
4802
4816
|
return boundedFetch(f4, opt);
|
|
4803
4817
|
}
|
|
4804
4818
|
function checkHostSource(src, url, opt) {
|
|
4805
|
-
|
|
4819
|
+
const rule = opt.fetch ? opt.fetch.hostRule : opt.unsafeFetch ? null : opt;
|
|
4820
|
+
if (!rule) return;
|
|
4821
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(String(url).trim());
|
|
4822
|
+
if (scheme && !/^https?$/i.test(scheme[1])) throw Object.assign(new Error(`Only http and https URLs can be fetched, not ${scheme[1].toLowerCase()}:`), { status: 400 });
|
|
4806
4823
|
const t = String(src.url ?? "").trim();
|
|
4807
4824
|
if (/^\/(?![/\\])/.test(t)) return;
|
|
4808
4825
|
const m = /^https?:\/\/([^/?#\\]*)/i.exec(t);
|
|
@@ -4813,7 +4830,7 @@ function checkHostSource(src, url, opt) {
|
|
|
4813
4830
|
host = new URL(url).hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
4814
4831
|
} catch {
|
|
4815
4832
|
}
|
|
4816
|
-
if (whole && host && (
|
|
4833
|
+
if (whole && host && (rule.allowHosts || []).map((h) => String(h).toLowerCase()).includes(host)) return;
|
|
4817
4834
|
throw Object.assign(new Error("its host is made by a parameter or an expression: write the scheme and host out (parameters may fill the path and query), or make the whole URL a parameter and list its host in allowHosts"), { status: 403 });
|
|
4818
4835
|
}
|
|
4819
4836
|
async function loadSources(def, opt) {
|
|
@@ -11348,7 +11365,8 @@ function toRdlx3(root, notes, reportName) {
|
|
|
11348
11365
|
const on = prop(b, "aggregateOn") ?? simpleList(b, "aggregateOn")[0]?.text;
|
|
11349
11366
|
const gc = { ...c, group: on && on !== "All" ? on : void 0 };
|
|
11350
11367
|
if (fn3) {
|
|
11351
|
-
const arg = listProp(b, "arguments").map((x) => prop(x, "value")).find((x) => x != null);
|
|
11368
|
+
const arg = listProp(b, "arguments").map((x) => prop(x, "value")).find((x) => x != null) ?? prop(b, "expression");
|
|
11369
|
+
if (arg == null && fn3 !== "count") throw new Untranslatable2(`the aggregate ${fn3.toUpperCase()} with no expression`);
|
|
11352
11370
|
const inner2 = arg != null ? vb2(arg, { ...c, inSet: false }, depth) : "1";
|
|
11353
11371
|
if (prop(b, "filterExpr")) throw new Untranslatable2(`the bound column "${prop(b, "name")}", an aggregate with a filter`);
|
|
11354
11372
|
const all = gc.group ?? c.region;
|
|
@@ -12126,6 +12144,7 @@ function special(cp) {
|
|
|
12126
12144
|
if (cp >= 8192 && cp <= 8303) return cp >= 8203 && cp <= 8207 || cp >= 8234 && cp <= 8238 || cp >= 8288;
|
|
12127
12145
|
return cp >= 11904 && cp <= 42191 || cp >= 43056 && cp <= 44031 || cp >= 44032 && cp <= 55215 || cp >= 63744 && cp <= 64255 || cp >= 64285 && cp <= 65023 || cp >= 65024 && cp <= 65039 || cp >= 65072 && cp <= 65103 || cp >= 65136 && cp <= 65278 || cp >= 65280 && cp <= 65519 || cp >= 65536;
|
|
12128
12146
|
}
|
|
12147
|
+
var FORMAT_CHAR = new RegExp("^\\p{Cf}$", "u");
|
|
12129
12148
|
var cjk = (cp) => cp >= 11904 && cp <= 40959 || cp >= 44032 && cp <= 55215 || cp >= 63744 && cp <= 64255 || cp >= 65280 && cp <= 65519 || cp >= 131072 && cp <= 262143;
|
|
12130
12149
|
var NO_START = new Set("、。,.・:;?!ー)」』】〕〉》〗〙〟’”}⦆ぁぃぅぇぉっゃゅょゎゕゖァィゥェォッャュョヮヵヶ々〻‐゠–〜~…‥,.!?:;)]}%ゝゞヽヾ゛゜ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ。」、・ー%]⦆");
|
|
12131
12150
|
var NO_END = new Set("(「『【〔〈《〖〘〝‘“{⦅([{[「$¥£");
|
|
@@ -12521,7 +12540,7 @@ var TextMeasurer = class {
|
|
|
12521
12540
|
}
|
|
12522
12541
|
/** The font for one character: the chosen one, else the bundled fallback for its script, else the one before. */
|
|
12523
12542
|
pick(cp, key, prev) {
|
|
12524
|
-
if (cp < 32 || this.has(key, cp)) return key;
|
|
12543
|
+
if (cp < 32 || this.has(key, cp) || FORMAT_CHAR.test(String.fromCodePoint(cp))) return key;
|
|
12525
12544
|
const fb = fallbackKey(cp, key);
|
|
12526
12545
|
if (fb && !this.store.failed.has(fb)) {
|
|
12527
12546
|
if (!this.store.has(fb)) {
|
|
@@ -13377,6 +13396,11 @@ function niceScale(min, max, ticks = 5) {
|
|
|
13377
13396
|
const step3 = niceNum(range / Math.max(1, ticks - 1), true);
|
|
13378
13397
|
return { lo: Math.floor(min / step3) * step3, hi: Math.ceil(max / step3) * step3, step: step3 };
|
|
13379
13398
|
}
|
|
13399
|
+
function niceScaleSpan(min, max, ticks = 5) {
|
|
13400
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || !(max > min)) return niceScale(min, max, ticks);
|
|
13401
|
+
const step3 = niceNum((max - min) / Math.max(1, ticks - 1), true);
|
|
13402
|
+
return { lo: Math.floor(min / step3) * step3, hi: Math.ceil(max / step3) * step3, step: step3 };
|
|
13403
|
+
}
|
|
13380
13404
|
function niceNum(x, round) {
|
|
13381
13405
|
const e2 = Math.floor(Math.log10(x));
|
|
13382
13406
|
const f4 = x / 10 ** e2;
|
|
@@ -14334,7 +14358,7 @@ var byName = (lc, pal) => (name) => {
|
|
|
14334
14358
|
};
|
|
14335
14359
|
function chartData(item, ctx, lc, pal = paletteOf(item.palette)) {
|
|
14336
14360
|
let rows = item.dataSet ? related(lc.dataSets[item.dataSet] || [], ctx) : ctx.aggRows || [];
|
|
14337
|
-
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name}: the data set "${item.dataSet}" does not exist`);
|
|
14361
|
+
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name || item.type}: the data set "${item.dataSet}" does not exist`);
|
|
14338
14362
|
if (item.filters?.length) rows = applyFilters(rows, item.filters, ctx);
|
|
14339
14363
|
if (item.sort?.length) rows = applySort(rows, item.sort, ctx);
|
|
14340
14364
|
const who = item.name || "Chart";
|
|
@@ -14622,13 +14646,15 @@ function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs: fs
|
|
|
14622
14646
|
lo = lo < 0 ? -1 : 0;
|
|
14623
14647
|
hi = 1;
|
|
14624
14648
|
}
|
|
14649
|
+
let padded = false;
|
|
14625
14650
|
if (pad2 > 0 && hi > lo) {
|
|
14626
14651
|
const d = (hi - lo) * pad2;
|
|
14627
|
-
if (smin == null) lo
|
|
14628
|
-
if (smax == null) hi
|
|
14652
|
+
if (smin == null) lo = lo >= 0 && lo - d < 0 ? 0 : lo - d;
|
|
14653
|
+
if (smax == null) hi = hi <= 0 && hi + d > 0 ? 0 : hi + d;
|
|
14654
|
+
padded = true;
|
|
14629
14655
|
}
|
|
14630
14656
|
const want = len < fs2 * 6 ? 3 : 5;
|
|
14631
|
-
const sc = niceScale(smin ?? lo, smax ?? hi, want);
|
|
14657
|
+
const sc = padded && smin == null && smax == null && (lo >= 0 || hi <= 0) ? niceScaleSpan(lo, hi, want) : niceScale(smin ?? lo, smax ?? hi, want);
|
|
14632
14658
|
let a = sc.lo, b = sc.hi, ticks;
|
|
14633
14659
|
if (smin != null || smax != null) {
|
|
14634
14660
|
a = smin ?? sc.lo;
|
|
@@ -15056,31 +15082,27 @@ function rowPoints(type, g) {
|
|
|
15056
15082
|
rows = rows.slice(0, cap2);
|
|
15057
15083
|
}
|
|
15058
15084
|
const blank2 = (v) => v == null || v === "";
|
|
15059
|
-
const
|
|
15085
|
+
const drawn = /* @__PURE__ */ new Set();
|
|
15060
15086
|
const sets = data.series.map((s, si) => {
|
|
15061
15087
|
const pts2 = [];
|
|
15062
15088
|
rows.forEach((r, ri) => {
|
|
15063
15089
|
c.fields = r;
|
|
15064
15090
|
const rx = safe2(item.xValue, c, lc, who), ry = safe2(s.def.value || "=0", { ...c, aggRows: [r] }, lc, who);
|
|
15065
|
-
if (blank2(rx) || blank2(ry))
|
|
15066
|
-
missing2.add(ri);
|
|
15067
|
-
return;
|
|
15068
|
-
}
|
|
15091
|
+
if (blank2(rx) || blank2(ry)) return;
|
|
15069
15092
|
const x = Number(rx), y = Number(ry);
|
|
15070
|
-
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
15071
|
-
missing2.add(ri);
|
|
15072
|
-
return;
|
|
15073
|
-
}
|
|
15093
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return;
|
|
15074
15094
|
let size = 1;
|
|
15075
15095
|
if (type === "bubble") {
|
|
15076
15096
|
size = Number(safe2(s.def.size || "=1", { ...c, aggRows: [r] }, lc, who));
|
|
15077
15097
|
if (!Number.isFinite(size) || size <= 0) return;
|
|
15078
15098
|
}
|
|
15079
15099
|
pts2.push({ x, y, size });
|
|
15100
|
+
drawn.add(ri);
|
|
15080
15101
|
});
|
|
15081
15102
|
return { s, pts: pts2, i: si };
|
|
15082
15103
|
});
|
|
15083
|
-
|
|
15104
|
+
const missing2 = rows.length - drawn.size;
|
|
15105
|
+
if (missing2 > 0) lc.warn(`${who}: ${missing2} of ${rows.length} rows have no x or y value and are not drawn`);
|
|
15084
15106
|
return sets;
|
|
15085
15107
|
}
|
|
15086
15108
|
function paintXY(type, g) {
|
|
@@ -17512,7 +17534,7 @@ function hidden(item, ctx, lc) {
|
|
|
17512
17534
|
const r = evalSafe(item.hidden, ctx, lc, item.name || item.type);
|
|
17513
17535
|
h = !r.err && truthy(r.v);
|
|
17514
17536
|
}
|
|
17515
|
-
return item.name && lc.state?.toggles?.[`item:${item.name}`] ? !h : h;
|
|
17537
|
+
return item.name && lc.state?.toggles?.[`item:${item.name || item.type}`] ? !h : h;
|
|
17516
17538
|
}
|
|
17517
17539
|
var SHRINK_DEFAULTS = { minFontSize: 4, step: 0.5 };
|
|
17518
17540
|
function rotationOf(item) {
|
|
@@ -17848,7 +17870,7 @@ register("table", {
|
|
|
17848
17870
|
else {
|
|
17849
17871
|
rows = item.dataSet && lc.dataSets[item.dataSet] || [];
|
|
17850
17872
|
rows = related(rows, tctx);
|
|
17851
|
-
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name ||
|
|
17873
|
+
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name || item.type}: the data set "${item.dataSet}" does not exist`);
|
|
17852
17874
|
if (item.filters?.length) rows = applyFilters(rows, item.filters, tctx);
|
|
17853
17875
|
const sort = lc.state?.sort?.[item.name] || item.sort;
|
|
17854
17876
|
if (sort?.length) rows = applySort(rows, sort, tctx);
|
|
@@ -17864,11 +17886,11 @@ register("table", {
|
|
|
17864
17886
|
if (overflow === "shrink" && room > 0) {
|
|
17865
17887
|
const k = room / designedW;
|
|
17866
17888
|
cols = cols.map((c) => ({ ...c, width: (Number(c.width) || 0) * k }));
|
|
17867
|
-
lc.warn(`${item.name ||
|
|
17889
|
+
lc.warn(`${item.name || item.type}: its columns are ${Math.round(designedW)}pt wide, wider than the page (${Math.round(room)}pt), so they are narrowed to fit`);
|
|
17868
17890
|
} else if (overflow === "clip" || overflow === "paginate" && lc.fixed) {
|
|
17869
|
-
lc.warn(`${item.name ||
|
|
17891
|
+
lc.warn(`${item.name || item.type}: its columns are ${Math.round(designedW)}pt wide, wider than the page (${Math.round(room)}pt), so the columns past the page edge are cut`, true);
|
|
17870
17892
|
} else if (overflow === "paginate" && item.overflow !== "paginate") {
|
|
17871
|
-
lc.warn(`${item.name ||
|
|
17893
|
+
lc.warn(`${item.name || item.type}: its columns are ${Math.round(designedW)}pt wide, wider than the page (${Math.round(room)}pt), so they continue on the next pages`);
|
|
17872
17894
|
}
|
|
17873
17895
|
const colX = [];
|
|
17874
17896
|
let acc = item.x;
|
|
@@ -17878,6 +17900,7 @@ register("table", {
|
|
|
17878
17900
|
}
|
|
17879
17901
|
const width = acc - item.x;
|
|
17880
17902
|
const region = { name: item.name, columns: cols.map((c) => c.width), rows: [] };
|
|
17903
|
+
if (lc.tablesSeen) lc.tablesSeen.n++;
|
|
17881
17904
|
const tableScope = { rows, index: -1, run: [] };
|
|
17882
17905
|
const scopes = { ...tctx.scopes || {}, [item.name]: tableScope };
|
|
17883
17906
|
const groupChains = {};
|
|
@@ -17901,7 +17924,7 @@ register("table", {
|
|
|
17901
17924
|
const covered = (ci) => cover[ci] !== null;
|
|
17902
17925
|
const cellsAt = /* @__PURE__ */ new WeakMap();
|
|
17903
17926
|
const layRow = (row, ctx, kind, extra) => {
|
|
17904
|
-
if (row.hidden != null && row.hidden !== false && row.hidden !== "" && hidden({ hidden: row.hidden, name: `${item.name ||
|
|
17927
|
+
if (row.hidden != null && row.hidden !== false && row.hidden !== "" && hidden({ hidden: row.hidden, name: `${item.name || item.type} row` }, ctx, lc)) {
|
|
17905
17928
|
if (openSpans.length) {
|
|
17906
17929
|
for (const s of openSpans) s.left--;
|
|
17907
17930
|
for (const s of openSpans) if (s.left <= 0) closeSpan(s);
|
|
@@ -17935,7 +17958,7 @@ register("table", {
|
|
|
17935
17958
|
else try {
|
|
17936
17959
|
v = evalValue(cell.value ?? "", cctx);
|
|
17937
17960
|
} catch (e2) {
|
|
17938
|
-
lc.warn(`${item.name ||
|
|
17961
|
+
lc.warn(`${item.name || item.type} cell: ${e2.message}`);
|
|
17939
17962
|
v = "#Error";
|
|
17940
17963
|
}
|
|
17941
17964
|
let text2 = textOf(v, st, cctx, lc);
|
|
@@ -17978,7 +18001,7 @@ register("table", {
|
|
|
17978
18001
|
cells.forEach((c, k) => {
|
|
17979
18002
|
if (c.cell.visual?.type) {
|
|
17980
18003
|
items.push(...paintBox({ x: c.x, y: 0, w: c.w, h, st: c.st, tl: null, m: lc.m }));
|
|
17981
|
-
if (first) items.push(...paintVisual(c.cell.visual, { x: c.x, y: 0, w: c.w, h }, c.ctx, lc, c.st, `${item.name} cell`, { cell: true }));
|
|
18004
|
+
if (first) items.push(...paintVisual(c.cell.visual, { x: c.x, y: 0, w: c.w, h }, c.ctx, lc, c.st, `${item.name || item.type} cell`, { cell: true }));
|
|
17982
18005
|
return;
|
|
17983
18006
|
}
|
|
17984
18007
|
if (c.nested) {
|
|
@@ -18033,7 +18056,7 @@ register("table", {
|
|
|
18033
18056
|
};
|
|
18034
18057
|
const layoutInCell = (inner2, x, cw, st, cctx, row) => {
|
|
18035
18058
|
const pd = padding(st);
|
|
18036
|
-
const it = { ...inner2, name: inner2.name || `${item.name}_cell`, x: x + pd[3], y: 0, w: Math.max(1, cw - pd[1] - pd[3]), h: Number(inner2.h) || Math.max(1, (row.height || 18) - pd[0] - pd[2]) };
|
|
18059
|
+
const it = { ...inner2, name: inner2.name || `${item.name || item.type}_cell`, x: x + pd[3], y: 0, w: Math.max(1, cw - pd[1] - pd[3]), h: Number(inner2.h) || Math.max(1, (row.height || 18) - pd[0] - pd[2]) };
|
|
18037
18060
|
const scopeRows2 = cctx.aggIndex != null ? [cctx.fields] : cctx.aggRows || [];
|
|
18038
18061
|
const current = item.dataSet ? { ...cctx.current || {}, [item.dataSet]: scopeRows2 } : cctx.current;
|
|
18039
18062
|
const child = {
|
|
@@ -18053,7 +18076,7 @@ register("table", {
|
|
|
18053
18076
|
const reads = (it.dataSet && it.dataSet !== item.dataSet ? child.ctxFor(it).aggRows?.length : scopeRows2.length) || 1;
|
|
18054
18077
|
if (budget.left < reads) {
|
|
18055
18078
|
budget.left = 0;
|
|
18056
|
-
lc.warn(`${item.name}: more than ${CELL_ITEM_UNITS} rows of items inside cells; the rest are left empty`);
|
|
18079
|
+
lc.warn(`${item.name || item.type}: more than ${CELL_ITEM_UNITS} rows of items inside cells; the rest are left empty`);
|
|
18057
18080
|
return { items: [], height: 0 };
|
|
18058
18081
|
}
|
|
18059
18082
|
budget.left -= reads;
|
|
@@ -18097,7 +18120,7 @@ register("table", {
|
|
|
18097
18120
|
u.items.splice(at2 < 0 ? u.items.length : at2, 0, ...add2);
|
|
18098
18121
|
});
|
|
18099
18122
|
if (s.tl.needed > s.units[0].height + GROW_TOLERANCE || s.st.verticalAlign && s.st.verticalAlign !== "top") {
|
|
18100
|
-
const id = `${item.name}:span:${lc.nextId()}`;
|
|
18123
|
+
const id = `${item.name || item.type}:span:${lc.nextId()}`;
|
|
18101
18124
|
for (const u of s.units) u.block ||= id;
|
|
18102
18125
|
} else {
|
|
18103
18126
|
let above = s.units[0].height;
|
|
@@ -18139,7 +18162,7 @@ register("table", {
|
|
|
18139
18162
|
const groups = item.groups || [];
|
|
18140
18163
|
let rowNo = lc.win?.rowOffset || 0;
|
|
18141
18164
|
const groupTables = [];
|
|
18142
|
-
const tableKey = `${item.name}#${lc.nextId()}`;
|
|
18165
|
+
const tableKey = `${item.name || item.type}#${lc.nextId()}`;
|
|
18143
18166
|
const emit2 = (level, grows, ctx, chain, keyPath) => {
|
|
18144
18167
|
if (level === groups.length) {
|
|
18145
18168
|
for (let i = 0; i < grows.length; i++) {
|
|
@@ -18201,7 +18224,7 @@ register("table", {
|
|
|
18201
18224
|
kids = /* @__PURE__ */ new Map();
|
|
18202
18225
|
roots = [];
|
|
18203
18226
|
for (const b of buckets) {
|
|
18204
|
-
const pk = evalSafe(g.parent, { ...ctx, fields: b.rows[0], aggRows: b.rows, aggIndex: void 0 }, lc, `${item.name} group parent`).v;
|
|
18227
|
+
const pk = evalSafe(g.parent, { ...ctx, fields: b.rows[0], aggRows: b.rows, aggIndex: void 0 }, lc, `${item.name || item.type} group parent`).v;
|
|
18205
18228
|
const pr = pk == null || pk === "" ? null : byText.get(pk instanceof Date ? String(pk.getTime()) : String(pk));
|
|
18206
18229
|
if (!pr || pr === b) roots.push(b);
|
|
18207
18230
|
else {
|
|
@@ -18233,7 +18256,7 @@ register("table", {
|
|
|
18233
18256
|
if (g.indent) gctx.indent = (ctx.indent || 0) + depth * Number(g.indent);
|
|
18234
18257
|
}
|
|
18235
18258
|
const path2 = `${parentPath}/${bk.text}`;
|
|
18236
|
-
const tkey = `${item.name}|${level}|${path2}`;
|
|
18259
|
+
const tkey = `${item.name || item.type}|${level}|${path2}`;
|
|
18237
18260
|
const dflt = kids && g.expandLevels != null ? depth < Number(g.expandLevels) : !g.initiallyCollapsed;
|
|
18238
18261
|
const open = !g.collapsible ? true : lc.state?.toggles?.[tkey] ?? dflt;
|
|
18239
18262
|
const start = units.length;
|
|
@@ -18255,7 +18278,7 @@ register("table", {
|
|
|
18255
18278
|
const ch = kids?.get(bk) || [];
|
|
18256
18279
|
if (open) {
|
|
18257
18280
|
emit2(level + 1, bk.rows, gctx, [...chain, sc], path2);
|
|
18258
|
-
if (ch.length && depth + 1 >= MAX_TREE_DEPTH) lc.warn(`${item.name}: the group "${gname}" is more than ${MAX_TREE_DEPTH} levels deep; deeper rows are listed at the top level`);
|
|
18281
|
+
if (ch.length && depth + 1 >= MAX_TREE_DEPTH) lc.warn(`${item.name || item.type}: the group "${gname}" is more than ${MAX_TREE_DEPTH} levels deep; deeper rows are listed at the top level`);
|
|
18259
18282
|
else ch.forEach((c, ci) => node2(c, ci, ch, depth + 1, path2));
|
|
18260
18283
|
} else {
|
|
18261
18284
|
const rs = recOf.get(bk) || bk.rows;
|
|
@@ -18284,7 +18307,7 @@ register("table", {
|
|
|
18284
18307
|
if (g.newSection) units[start].sectionStart = true;
|
|
18285
18308
|
if (g.pageBreak === "after" && bi < sibs.length - 1) units[units.length - 1].breakAfter = true;
|
|
18286
18309
|
if (g.keepTogether) {
|
|
18287
|
-
const id = `${item.name}:g${level}:${path2}:${lc.nextId()}`;
|
|
18310
|
+
const id = `${item.name || item.type}:g${level}:${path2}:${lc.nextId()}`;
|
|
18288
18311
|
for (let k = start; k < units.length; k++) if (!units[k].block) {
|
|
18289
18312
|
units[k].block = id;
|
|
18290
18313
|
if (cont) units[k].blockOpen = true;
|
|
@@ -18305,7 +18328,7 @@ register("table", {
|
|
|
18305
18328
|
if (kids) {
|
|
18306
18329
|
const rest2 = buckets.filter((b) => !shown2.has(b));
|
|
18307
18330
|
if (rest2.length) {
|
|
18308
|
-
lc.warn(`${item.name}: ${rest2.length} rows of the group "${gname}" have no root (a cycle or too deep); they are listed at the top level`);
|
|
18331
|
+
lc.warn(`${item.name || item.type}: ${rest2.length} rows of the group "${gname}" have no root (a cycle or too deep); they are listed at the top level`);
|
|
18309
18332
|
rest2.forEach((bk, bi) => node2(bk, bi, rest2, 0, keyPath));
|
|
18310
18333
|
}
|
|
18311
18334
|
}
|
|
@@ -18333,7 +18356,7 @@ register("table", {
|
|
|
18333
18356
|
units[units.length - 1].breakAfter = true;
|
|
18334
18357
|
}
|
|
18335
18358
|
if (item.bookmark && units.length) {
|
|
18336
|
-
const b = evalSafe(item.bookmark, base, lc, `${item.name ||
|
|
18359
|
+
const b = evalSafe(item.bookmark, base, lc, `${item.name || item.type} bookmark`).v;
|
|
18337
18360
|
if (b != null && b !== "" && b !== "#Error") units[0].items.unshift({ t: "bookmark", label: String(b), x: item.x, y: 0, level: item.bookmarkLevel ?? 0 });
|
|
18338
18361
|
}
|
|
18339
18362
|
if (!lc.fixed) lc.regions?.push(region);
|
|
@@ -18428,7 +18451,7 @@ register("container", {
|
|
|
18428
18451
|
const ctx = lc.ctxFor(item);
|
|
18429
18452
|
if (hidden(item, ctx, lc)) return { height: 0, units: [] };
|
|
18430
18453
|
const res = lc.layoutItems(item.items, lc, { dx: item.x });
|
|
18431
|
-
return frame2(item, lc, ctx, res, item.keepTogether !== false ? `c:${item.name}:${lc.nextId()}` : null);
|
|
18454
|
+
return frame2(item, lc, ctx, res, item.keepTogether !== false ? `c:${item.name || item.type}:${lc.nextId()}` : null);
|
|
18432
18455
|
}
|
|
18433
18456
|
});
|
|
18434
18457
|
function frame2(item, lc, ctx, res, blockId0) {
|
|
@@ -18485,7 +18508,7 @@ register("list", {
|
|
|
18485
18508
|
let rows = item.dataSet && lc.dataSets[item.dataSet] || [];
|
|
18486
18509
|
if (item.inheritRows && item.dataSet && ctx.current?.[item.dataSet]) rows = ctx.current[item.dataSet];
|
|
18487
18510
|
else rows = related(rows, ctx);
|
|
18488
|
-
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name}: the data set "${item.dataSet}" does not exist`);
|
|
18511
|
+
if (item.dataSet && !lc.dataSets[item.dataSet]) lc.warn(`${item.name || item.type}: the data set "${item.dataSet}" does not exist`);
|
|
18489
18512
|
if (item.filters?.length) rows = applyFilters(rows, item.filters, ctx);
|
|
18490
18513
|
if (item.sort?.length) rows = applySort(rows, item.sort, ctx);
|
|
18491
18514
|
const reps = item.groupBy ? groupRows(rows, item.groupBy, ctx, lc, item.name, item.groupAdjacent === true).map((b) => b.rows) : rows.map((r) => [r]);
|
|
@@ -18514,7 +18537,7 @@ register("list", {
|
|
|
18514
18537
|
} };
|
|
18515
18538
|
const k = i % ncol;
|
|
18516
18539
|
const res = lc.layoutItems(item.items, child, { dx: item.x + k * (item.w + gap) });
|
|
18517
|
-
const fr = frame2({ ...item, x: item.x + k * (item.w + gap), name: `${item.name}[${i + 1}]` }, child, rctx, res, item.keepTogether !== false ? `l:${item.name}:${i}:${lc.nextId()}` : null);
|
|
18540
|
+
const fr = frame2({ ...item, x: item.x + k * (item.w + gap), name: `${item.name || item.type}[${i + 1}]` }, child, rctx, res, item.keepTogether !== false ? `l:${item.name || item.type}:${i}:${lc.nextId()}` : null);
|
|
18518
18541
|
if (ncol > 1) {
|
|
18519
18542
|
if (k === 0) {
|
|
18520
18543
|
cells = { top: y, height: 0, items: [], x0: item.x, x1: item.x + ncol * item.w + (ncol - 1) * gap, block: void 0 };
|
|
@@ -18985,7 +19008,7 @@ register("subreport", {
|
|
|
18985
19008
|
if (hidden(item, ctx, lc)) return { height: 0, units: [] };
|
|
18986
19009
|
const params = {};
|
|
18987
19010
|
for (const [k, v] of Object.entries(item.params || {})) {
|
|
18988
|
-
const r = evalSafe(v, ctx, lc, `${item.name} parameter ${k}`);
|
|
19011
|
+
const r = evalSafe(v, ctx, lc, `${item.name || item.type} parameter ${k}`);
|
|
18989
19012
|
params[k] = r.v instanceof Date ? isoDate(r.v, ctx.timeZone) : r.v;
|
|
18990
19013
|
}
|
|
18991
19014
|
const key = `${item.report}|${JSON.stringify(params)}`;
|
|
@@ -19004,10 +19027,10 @@ register("subreport", {
|
|
|
19004
19027
|
const res = sub.results.get(key);
|
|
19005
19028
|
if (!res) return placeholder(`Subreport "${item.report}" did not load`);
|
|
19006
19029
|
if (res.error) {
|
|
19007
|
-
lc.warn(`${item.name}: ${res.error}`);
|
|
19030
|
+
lc.warn(`${item.name || item.type}: ${res.error}`);
|
|
19008
19031
|
return placeholder(`Subreport "${item.report}": ${res.error}`);
|
|
19009
19032
|
}
|
|
19010
|
-
const block = item.keepTogether ? `s:${item.name}:${lc.nextId()}` : void 0;
|
|
19033
|
+
const block = item.keepTogether ? `s:${item.name || item.type}:${lc.nextId()}` : void 0;
|
|
19011
19034
|
const units = res.units.map((u) => ({ ...u, items: shiftItems(u.items, item.x, 0), ...u.cont ? { cont: shiftItems(u.cont, item.x, 0) } : {}, x0: (u.x0 ?? 0) + item.x, x1: (u.x1 ?? item.w) + item.x, block: u.block || block, tableId: void 0 }));
|
|
19012
19035
|
const tables = res.tables.map((t) => ({ ...t, x0: t.x0 + item.x, x1: t.x1 + item.x, headerItems: shiftItems(t.headerItems, item.x, 0), id: `sub${lc.nextId()}` }));
|
|
19013
19036
|
for (const r of res.regions || []) lc.regions?.push(r);
|
|
@@ -22027,6 +22050,7 @@ var SCHEMA_ALIAS = "reportwright/report@1";
|
|
|
22027
22050
|
var ITEM_KEYS = new Set("id type name x y w h style styleName items hidden layer locked label alt value dataSet canGrow canShrink action bookmark tooltip keepTogether pageBreakBefore pageBreakAfter pageBreakBetween newSection filters sort groups groupBy groupAdjacent inheritRows columns header detail footer repeatHeader widowControl noRowsText pageBreakEvery cells rows rowGroup rowGroups columnGro\
|
|
22028
22051
|
up columnGroups values value valueFormat rowSort columnSort rowTotals columnTotals cellStyle headerStyle totalStyle corner partProps library part properties overflow overflowTo src fit headingLevel rotate shrinkToFit minFontSize shrinkStep tocDots tocLink tocPage format chartType series seriesGroup category title legend palette stacked valueAxis xTitle maxCategories outliers categorySort categoryF\
|
|
22029
22052
|
ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description".split(" "));
|
|
22053
|
+
var NO_SERIES_CHARTS = /* @__PURE__ */ new Set(["gantt"]);
|
|
22030
22054
|
function looksLikeLink(it) {
|
|
22031
22055
|
if (it.type !== "textbox" || it.action && it.action.type && it.action.type !== "none") return false;
|
|
22032
22056
|
const st = it.style && typeof it.style === "object" ? it.style : {};
|
|
@@ -22155,6 +22179,9 @@ function validate(def) {
|
|
|
22155
22179
|
if (p?.hidden && p.required && (p.default == null || p.default === "") && !p.nullable) {
|
|
22156
22180
|
warnings.push(`Parameter "${p.name}" is hidden and required but has no default: only a URL, the API or a drill-through can set it`);
|
|
22157
22181
|
}
|
|
22182
|
+
if (p?.required && p.nullable && !p.multi && (p.default == null || p.default === "")) {
|
|
22183
|
+
warnings.push(`Parameter "${p.name}" is required and nullable with no default: when no value is given it is null and the report can draw blank; give it a default, or drop "nullable" to require a value`);
|
|
22184
|
+
}
|
|
22158
22185
|
if (p?.type === "date" && typeof p.default === "string" && p.default.trim() && !p.default.startsWith("=") && !toDate(p.default)) {
|
|
22159
22186
|
warnings.push(`Parameter "${p.name}": its default "${p.default}" is not a date; write it as 2026-12-31 (year-month-day)`);
|
|
22160
22187
|
}
|
|
@@ -22235,7 +22262,7 @@ function validate(def) {
|
|
|
22235
22262
|
warnings.push(`${label}: there is no named style "${it.styleName}"${g ? ` (did you mean "${g}"?)` : ""}; it is ignored`);
|
|
22236
22263
|
}
|
|
22237
22264
|
if (Array.isArray(it.sort)) sortIssues(it.sort, label, warnings);
|
|
22238
|
-
if (it.type === "chart" && Array.isArray(it.series) &&
|
|
22265
|
+
if (it.type === "chart" && !NO_SERIES_CHARTS.has(it.chartType) && !(Array.isArray(it.series) && it.series.length)) warnings.push(`${label}: the chart has no series, so it plots a count of its rows; add one, e.g. series: [{ "name": "Value", "value": "=Sum(Fields.Amount)" }]`);
|
|
22239
22266
|
if (it.type === "image" && typeof it.src === "string" && !it.src.startsWith("=") && LOCAL_IMAGE.test(it.src.trim())) warnings.push(`${label}: "${it.src}" is a local file path, which a browser cannot load; embed the image (images: { name: "data:image/png;base64,..." } and src: "embedded:name") or use an https:// address`);
|
|
22240
22267
|
if (it.style != null && (typeof it.style !== "object" || Array.isArray(it.style))) warnings.push(`${label}: "style" must be an object of style properties, such as { "fontWeight": "bold" }; ${JSON.stringify(it.style).slice(0, 40)} is ignored`);
|
|
22241
22268
|
const own = ownKeys(it.type);
|
|
@@ -22278,6 +22305,9 @@ function validate(def) {
|
|
|
22278
22305
|
const n5 = Array.isArray(it.columns) ? it.columns.length : 0;
|
|
22279
22306
|
const rowsOf = [["header", it.header], ["detail", it.detail], ["footer", it.footer], ...(it.groups || []).flatMap((g, gi) => [[`group ${gi + 1} header`, g?.header], [`group ${gi + 1} footer`, g?.footer]])];
|
|
22280
22307
|
for (const [part2, rows] of rowsOf) (Array.isArray(rows) ? rows : []).forEach((row, ri) => {
|
|
22308
|
+
const cells = Array.isArray(row?.cells) ? row.cells : [];
|
|
22309
|
+
const placed = cells.length < n5 && cells.some((c) => Number(c?.colSpan) > 1) ? cells.reduce((s, c) => s + Math.max(1, Math.floor(Number(c?.colSpan)) || 1), 0) : cells.length;
|
|
22310
|
+
if (placed < n5) warnings.push(`${label} ${part2} row ${ri + 1}: the row has ${placed} of ${n5} cells and no colSpan covers the other ${n5 - placed}; add the cells or a colSpan`);
|
|
22281
22311
|
for (const [k, j] of rowCells(row?.cells, n5).covered) warnings.push(`${label} ${part2} row ${ri + 1}: cell ${k} is covered by colSpan of cell ${j}, so it is not drawn (leave it null, or omit the spanned cells: a row with fewer cells than columns places each cell after the previous one's span)`);
|
|
22282
22312
|
});
|
|
22283
22313
|
}
|
|
@@ -22693,7 +22723,7 @@ function* textsOf(def, dataSets) {
|
|
|
22693
22723
|
}
|
|
22694
22724
|
}
|
|
22695
22725
|
}
|
|
22696
|
-
var NO_CJK_FONTS = "Text in Japanese/Chinese/Korean needs the optional CJK fonts: npm run fonts:cjk";
|
|
22726
|
+
var NO_CJK_FONTS = "Text in Japanese/Chinese/Korean needs the optional CJK fonts: npm i @reportwright/fonts-cjk, then npx reportwright-fonts-cjk (npm); in the app, npm run fonts:cjk";
|
|
22697
22727
|
async function render(def0, opts = {}) {
|
|
22698
22728
|
const t0 = Date.now();
|
|
22699
22729
|
const reuseWarnings = [];
|
|
@@ -22764,6 +22794,7 @@ async function render(def0, opts = {}) {
|
|
|
22764
22794
|
const base = { ...BASE_STYLE, ...def.styles?.base || {} };
|
|
22765
22795
|
let idSeq = 0;
|
|
22766
22796
|
const regions = [];
|
|
22797
|
+
const tablesSeen = { n: 0 };
|
|
22767
22798
|
const imageBudget = opts.imageBudget || { seen: /* @__PURE__ */ new Set(), bytes: 0 };
|
|
22768
22799
|
const makeLc = (globals, fixed2) => {
|
|
22769
22800
|
const lc = {
|
|
@@ -22774,6 +22805,7 @@ async function render(def0, opts = {}) {
|
|
|
22774
22805
|
fixed: fixed2,
|
|
22775
22806
|
maxUnitHeight: contentH,
|
|
22776
22807
|
state: opts.state || {},
|
|
22808
|
+
tablesSeen,
|
|
22777
22809
|
regions: opts.exportData || opts.dataOnly ? regions : null,
|
|
22778
22810
|
dataOnly: !!opts.dataOnly,
|
|
22779
22811
|
// exportData: true: table data and cell tags (Excel, CSV, Word, HTML, accessible PDF)
|
|
@@ -22891,8 +22923,8 @@ async function render(def0, opts = {}) {
|
|
|
22891
22923
|
u.breakBefore = false;
|
|
22892
22924
|
u.breakAfter = false;
|
|
22893
22925
|
}
|
|
22894
|
-
const
|
|
22895
|
-
parts2.push({ body, slices, g });
|
|
22926
|
+
const slices2 = paginate(body.units, body.tables, g.cH, warn);
|
|
22927
|
+
parts2.push({ body, slices: slices2, g });
|
|
22896
22928
|
if (lc.rowBudget?.cut) break sections;
|
|
22897
22929
|
if (!overflow.more) break;
|
|
22898
22930
|
if (rep + 1 >= REUSE_LIMITS.repeats) {
|
|
@@ -22933,7 +22965,7 @@ async function render(def0, opts = {}) {
|
|
|
22933
22965
|
const headings = [];
|
|
22934
22966
|
const pages2 = [];
|
|
22935
22967
|
list2.forEach(({ part: part2, k, last }, n5) => {
|
|
22936
|
-
const { body, slices, g } = part2;
|
|
22968
|
+
const { body, slices: slices2, g } = part2;
|
|
22937
22969
|
const { pg, colCount, colW, colGap, cH } = g;
|
|
22938
22970
|
const ph = parts2.length === 1 ? pageH : pg.height;
|
|
22939
22971
|
const ml = pg.margins.left, mt = pg.margins.top;
|
|
@@ -22971,7 +23003,7 @@ async function render(def0, opts = {}) {
|
|
|
22971
23003
|
band(g.hdr, mt, g.own.h ? k === 0 : isFirst, g.own.h ? last : isLast);
|
|
22972
23004
|
const frozen = [];
|
|
22973
23005
|
for (let c = 0; c < colCount; c++) {
|
|
22974
|
-
const p =
|
|
23006
|
+
const p = slices2[k * colCount + c];
|
|
22975
23007
|
if (!p) break;
|
|
22976
23008
|
const cx = ml + c * (colW + colGap);
|
|
22977
23009
|
for (const t of p.repeat) placeItems(t.headerItems, cx, bodyTop, items);
|
|
@@ -23003,7 +23035,7 @@ async function render(def0, opts = {}) {
|
|
|
23003
23035
|
items.length = j;
|
|
23004
23036
|
const out = frozen.length ? { items, frozen } : { items };
|
|
23005
23037
|
if (win) {
|
|
23006
|
-
const u =
|
|
23038
|
+
const u = slices2[k * colCount]?.units[0];
|
|
23007
23039
|
if (u?.dataRow != null) {
|
|
23008
23040
|
out.firstRow = u.dataRow;
|
|
23009
23041
|
out.rowHead = !!u.rowHead;
|
|
@@ -23077,7 +23109,7 @@ async function render(def0, opts = {}) {
|
|
|
23077
23109
|
if (m.noGlyph.size) {
|
|
23078
23110
|
const cjk2 = [...m.noGlyph].some((c) => /[\u1100-\u11ff\u2600-\u27bf\u2b00-\u2bff\u3000-\u9fff\uac00-\ud7af\uf900-\ufaff\uff00-\uffef]|[\u{1f000}-\u{1faff}]/u.test(c));
|
|
23079
23111
|
const list2 = [...m.noGlyph].slice(0, 20).join(" ");
|
|
23080
|
-
warn(cjk2 ? `${NO_CJK_FONTS}
|
|
23112
|
+
warn(cjk2 ? `${NO_CJK_FONTS}. Until then these characters show as boxes: ${list2}.` : `No font has these characters, so they show as boxes: ${list2}. Upload a font that has them and use it for this text.`);
|
|
23081
23113
|
}
|
|
23082
23114
|
if (opts.bodyOnly) return { units: result.body.units, tables: result.body.tables, height: result.body.height, regions, warnings, clipped: clipped() };
|
|
23083
23115
|
if (opts.dataOnly) return {
|
|
@@ -23117,6 +23149,7 @@ async function render(def0, opts = {}) {
|
|
|
23117
23149
|
headings: result.headings || [],
|
|
23118
23150
|
pageStarts: result.pageStarts || [],
|
|
23119
23151
|
regions: opts.exportData ? regions : null,
|
|
23152
|
+
hasTables: tablesSeen.n > 0,
|
|
23120
23153
|
name: def.name || "",
|
|
23121
23154
|
partial: cutRows(),
|
|
23122
23155
|
timeZone: timeZone || null,
|
|
@@ -24144,7 +24177,7 @@ function cellVisuals(items, used, tables) {
|
|
|
24144
24177
|
|
|
24145
24178
|
// src/exporters/regions.js
|
|
24146
24179
|
function needsTableData(model, what) {
|
|
24147
|
-
if (model && model.regions === null) throw Object.assign(new Error(`${what} needs the report's table data: render it with { exportData: true }`), { code: "NO_EXPORT_DATA" });
|
|
24180
|
+
if (model && model.regions === null && model.hasTables !== false) throw Object.assign(new Error(`${what} needs the report's table data: render it with { exportData: true }`), { code: "NO_EXPORT_DATA" });
|
|
24148
24181
|
}
|
|
24149
24182
|
function mergedRegions(model) {
|
|
24150
24183
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -24595,6 +24628,10 @@ var n4 = (v) => Math.round(v * 1e4) / 1e4;
|
|
|
24595
24628
|
var hex4 = (id) => id.toString(16).padStart(4, "0");
|
|
24596
24629
|
var KAPPA = 4 * ((Math.SQRT2 - 1) / 3);
|
|
24597
24630
|
var cleanText = (t) => t.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
|
|
24631
|
+
var formatAt = (run, cl) => {
|
|
24632
|
+
const cp = run.text.codePointAt(cl);
|
|
24633
|
+
return cp !== void 0 && FORMAT_CHAR.test(String.fromCodePoint(cp));
|
|
24634
|
+
};
|
|
24598
24635
|
function drawRun(c, run, x, y, size, pf, color2, spans2, texts) {
|
|
24599
24636
|
const f4 = pf.embedder.font;
|
|
24600
24637
|
const per = 1e3 / size;
|
|
@@ -24647,7 +24684,7 @@ function drawRun(c, run, x, y, size, pf, color2, spans2, texts) {
|
|
|
24647
24684
|
rise = gy;
|
|
24648
24685
|
}
|
|
24649
24686
|
const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
|
|
24650
|
-
if (id === 0 && c.tagged) pen = gx;
|
|
24687
|
+
if (id === 0 && (c.tagged || formatAt(run, cl))) pen = gx;
|
|
24651
24688
|
else {
|
|
24652
24689
|
arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
|
|
24653
24690
|
pen = gx + adv(id) * size / f4.unitsPerEm;
|
|
@@ -24706,6 +24743,7 @@ var Content = class {
|
|
|
24706
24743
|
this.saved = [];
|
|
24707
24744
|
this.lines = null;
|
|
24708
24745
|
this.tagged = false;
|
|
24746
|
+
this.artLines = false;
|
|
24709
24747
|
}
|
|
24710
24748
|
/**
|
|
24711
24749
|
* The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
|
|
@@ -24724,7 +24762,7 @@ var Content = class {
|
|
|
24724
24762
|
* ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
|
|
24725
24763
|
*/
|
|
24726
24764
|
line(stroke, w, dash, x1, y1, x2, y2) {
|
|
24727
|
-
if (this.tagged) {
|
|
24765
|
+
if (this.tagged && !this.artLines) {
|
|
24728
24766
|
this.paint(null, stroke, w, dash);
|
|
24729
24767
|
this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
|
|
24730
24768
|
`;
|
|
@@ -24744,6 +24782,8 @@ var Content = class {
|
|
|
24744
24782
|
if (!L) return;
|
|
24745
24783
|
this.lines = null;
|
|
24746
24784
|
this.et();
|
|
24785
|
+
const end = this.artLines ? "EMC\n" : "";
|
|
24786
|
+
if (end) this._s += "/Artifact BMC\n";
|
|
24747
24787
|
this.paint(null, L.stroke, L.w, L.dash);
|
|
24748
24788
|
const g = L.segs;
|
|
24749
24789
|
const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
|
|
@@ -24752,10 +24792,10 @@ var Content = class {
|
|
|
24752
24792
|
`;
|
|
24753
24793
|
this._s += `q
|
|
24754
24794
|
${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
|
|
24755
|
-
`;
|
|
24795
|
+
${end}`;
|
|
24756
24796
|
return;
|
|
24757
24797
|
}
|
|
24758
|
-
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
|
|
24798
|
+
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n" + end;
|
|
24759
24799
|
}
|
|
24760
24800
|
q() {
|
|
24761
24801
|
this.et();
|
|
@@ -25541,6 +25581,7 @@ function createSubsetter(loadWasm) {
|
|
|
25541
25581
|
for (const g of opt.glyphs) x.hb_set_add(gs, g);
|
|
25542
25582
|
}
|
|
25543
25583
|
x.hb_subset_input_pin_all_axes_to_default(input, face);
|
|
25584
|
+
x.hb_subset_input_pin_axis_location(input, face, tag3("wght"), opt.weight ?? 400);
|
|
25544
25585
|
const sub = x.hb_subset_or_fail(face, input);
|
|
25545
25586
|
if (!sub) throw new Error("HarfBuzz: subsetting failed");
|
|
25546
25587
|
const res = x.hb_face_reference_blob(sub);
|
|
@@ -25561,6 +25602,7 @@ function createSubsetter(loadWasm) {
|
|
|
25561
25602
|
|
|
25562
25603
|
// src/exporters/htmldata.js
|
|
25563
25604
|
init_format();
|
|
25605
|
+
var dateKey = (d, tz) => tz ? toWall(d, tz) : Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
|
|
25564
25606
|
var MAX_DATA_ROWS = 2e4;
|
|
25565
25607
|
var DATA_STRINGS = { pages: "Pages", tables: "Tables", all: "All", filter: "Filter", toggle: "Show or hide the rows of this group", sortAsc: "Sort ascending", sortDesc: "Sort descending" };
|
|
25566
25608
|
function tablesData(model, o = {}) {
|
|
@@ -25583,7 +25625,7 @@ function tablesData(model, o = {}) {
|
|
|
25583
25625
|
rows: r.rows.map((row) => ({
|
|
25584
25626
|
k: row.kind,
|
|
25585
25627
|
l: row.level || 0,
|
|
25586
|
-
c: row.cells.filter((c) => c.colIndex >= 0).map((c) => [c.colIndex, String(show(c) ?? ""), c.value instanceof Date ? c.value.
|
|
25628
|
+
c: row.cells.filter((c) => c.colIndex >= 0).map((c) => [c.colIndex, String(show(c) ?? ""), c.value instanceof Date ? dateKey(c.value, model.timeZone || void 0) : typeof c.value === "number" ? c.value : String(c.value ?? "").toLowerCase(), c.span || 1])
|
|
25587
25629
|
}))
|
|
25588
25630
|
}));
|
|
25589
25631
|
}
|
|
@@ -25715,13 +25757,29 @@ async function cspHash(text2) {
|
|
|
25715
25757
|
}
|
|
25716
25758
|
|
|
25717
25759
|
// src/exporters/html.js
|
|
25718
|
-
function exportHtml(model,
|
|
25760
|
+
function exportHtml(model, options, legacyOpt) {
|
|
25761
|
+
const isStore = (x) => !!x && typeof x.load === "function" && typeof x.get === "function" && x.bytes instanceof Map;
|
|
25762
|
+
let fontStore2, opt;
|
|
25763
|
+
if (isStore(options)) {
|
|
25764
|
+
if (!warnedLegacy) {
|
|
25765
|
+
warnedLegacy = true;
|
|
25766
|
+
console.warn("[reportwright] DEPRECATED: exportHtml(model, fontStore, options) is replaced by exportHtml(model, { fonts: fontStore, ...options }); the old form is removed in 0.9");
|
|
25767
|
+
}
|
|
25768
|
+
fontStore2 = options;
|
|
25769
|
+
opt = legacyOpt || {};
|
|
25770
|
+
} else {
|
|
25771
|
+
opt = /** @type {any} */
|
|
25772
|
+
options || {};
|
|
25773
|
+
fontStore2 = opt.fonts || opt.fontStore;
|
|
25774
|
+
if (!isStore(fontStore2)) throw new TypeError("exportHtml(model, { fonts }): fonts must be a FontStore (defaultFontStore() or new FontStore(loader)), got " + (fontStore2 === void 0 ? "nothing" : typeof fontStore2));
|
|
25775
|
+
}
|
|
25719
25776
|
return withDeadline(
|
|
25720
25777
|
htmlOf(model, fontStore2, opt),
|
|
25721
25778
|
/** @type {any} */
|
|
25722
25779
|
opt.timeoutMs
|
|
25723
25780
|
);
|
|
25724
25781
|
}
|
|
25782
|
+
var warnedLegacy = false;
|
|
25725
25783
|
async function htmlOf(model, fontStore2, opt) {
|
|
25726
25784
|
const used = /* @__PURE__ */ new Map();
|
|
25727
25785
|
const layout = /* @__PURE__ */ new Set();
|
|
@@ -26473,9 +26531,22 @@ async function xlsxOf(model, opt) {
|
|
|
26473
26531
|
}
|
|
26474
26532
|
|
|
26475
26533
|
// src/exporters/docx.js
|
|
26476
|
-
import {
|
|
26534
|
+
import { Zip, ZipDeflate, strToU8 as strToU83 } from "fflate";
|
|
26477
26535
|
var TW = 20;
|
|
26478
26536
|
var EMU = 12700;
|
|
26537
|
+
var XML_CHUNK = 4 * 1024 * 1024;
|
|
26538
|
+
function slices(s, max) {
|
|
26539
|
+
const out = [];
|
|
26540
|
+
let i = 0;
|
|
26541
|
+
while (s.length - i > max) {
|
|
26542
|
+
const j = s.indexOf(">", i + max);
|
|
26543
|
+
if (j < 0) break;
|
|
26544
|
+
out.push(s.slice(i, j + 1));
|
|
26545
|
+
i = j + 1;
|
|
26546
|
+
}
|
|
26547
|
+
out.push(s.slice(i));
|
|
26548
|
+
return out;
|
|
26549
|
+
}
|
|
26479
26550
|
var esc3 = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
26480
26551
|
var hex5 = (c) => {
|
|
26481
26552
|
const m = /^#?([0-9a-f]{6})$/i.exec(String(c || "").trim());
|
|
@@ -26619,9 +26690,9 @@ async function docxOf(model, opt) {
|
|
|
26619
26690
|
const margin = 18;
|
|
26620
26691
|
const media = [];
|
|
26621
26692
|
let docPr = 0;
|
|
26622
|
-
const addMedia = (
|
|
26693
|
+
const addMedia = (bytes2, ext) => {
|
|
26623
26694
|
const rid = `rIdm${media.length + 1}`;
|
|
26624
|
-
media.push({ name: `image${media.length + 1}.${ext}`, bytes, rid });
|
|
26695
|
+
media.push({ name: `image${media.length + 1}.${ext}`, bytes: bytes2, rid });
|
|
26625
26696
|
return rid;
|
|
26626
26697
|
};
|
|
26627
26698
|
const pictureRun = (pic, alt) => {
|
|
@@ -26685,7 +26756,7 @@ async function docxOf(model, opt) {
|
|
|
26685
26756
|
}
|
|
26686
26757
|
for (const f4 of figs) if (!f4.used) blocks.push({ kind: "fig", y: f4.box.y, x: f4.box.x, fig: f4 });
|
|
26687
26758
|
blocks.sort((a, b) => a.y - b.y || a.x - b.x);
|
|
26688
|
-
let
|
|
26759
|
+
let xml2 = "";
|
|
26689
26760
|
for (let bi = 0; bi < blocks.length; bi++) {
|
|
26690
26761
|
const b = blocks[bi];
|
|
26691
26762
|
if (b.kind === "fig") {
|
|
@@ -26700,7 +26771,7 @@ async function docxOf(model, opt) {
|
|
|
26700
26771
|
right = pic.x + pic.w;
|
|
26701
26772
|
}
|
|
26702
26773
|
const first = row[0];
|
|
26703
|
-
|
|
26774
|
+
xml2 += `<w:p><w:pPr><w:spacing w:before="0" w:after="80"/>${Math.abs(first.x - margin) > 0.5 ? `<w:ind w:left="${Math.round(Math.max(-margin, first.x - margin) * TW)}"/>` : ""}</w:pPr>${runs}</w:p>`;
|
|
26704
26775
|
} else if (b.kind === "table") {
|
|
26705
26776
|
const pics = /* @__PURE__ */ new Map();
|
|
26706
26777
|
for (const [k, v] of visuals.get(b.key) || []) {
|
|
@@ -26708,19 +26779,19 @@ async function docxOf(model, opt) {
|
|
|
26708
26779
|
const svg = figureSvg({ items: v.items, box: v.box }, opt.fontStore);
|
|
26709
26780
|
pics.set(k, pictureRun({ svg, png: await rasterize(svg, v.box.w, v.box.h, picOpt), w: v.box.w, h: v.box.h }, "Chart in a table cell"));
|
|
26710
26781
|
}
|
|
26711
|
-
|
|
26712
|
-
} else if (b.kind === "rich")
|
|
26782
|
+
xml2 += table(b.cells, b.x - margin, pics);
|
|
26783
|
+
} else if (b.kind === "rich") xml2 += richPara(b.items, b.x - margin);
|
|
26713
26784
|
else {
|
|
26714
26785
|
const row = [b];
|
|
26715
26786
|
const top = (t) => t.it.clip?.y ?? t.y - t.it.size;
|
|
26716
26787
|
while (blocks[bi + 1]?.kind === "text" && Math.abs(top(blocks[bi + 1]) - top(b)) < 3 && blocks[bi + 1].it.clip && b.it.clip) row.push(blocks[++bi]);
|
|
26717
26788
|
row.sort((p, q3) => p.it.clip.x - q3.it.clip.x);
|
|
26718
26789
|
const apart = row.every((r, k) => k === 0 || r.it.clip.x >= row[k - 1].it.clip.x + row[k - 1].it.clip.w - 0.5);
|
|
26719
|
-
if (row.length > 1 && apart)
|
|
26720
|
-
else for (const r of row)
|
|
26790
|
+
if (row.length > 1 && apart) xml2 += layoutRow(row, margin);
|
|
26791
|
+
else for (const r of row) xml2 += para(r.it, (r.it.clip?.x ?? r.x) - margin, r.decor);
|
|
26721
26792
|
}
|
|
26722
26793
|
}
|
|
26723
|
-
body.push(
|
|
26794
|
+
body.push(xml2);
|
|
26724
26795
|
}
|
|
26725
26796
|
const M = margin * TW, V = 36 * TW;
|
|
26726
26797
|
const sectPr = (pg) => {
|
|
@@ -26728,17 +26799,39 @@ async function docxOf(model, opt) {
|
|
|
26728
26799
|
return `<w:sectPr><w:pgSz w:w="${W2}" w:h="${H}"${W2 > H ? ' w:orient="landscape"' : ""}/><w:pgMar w:top="${V}" w:right="${M}" w:bottom="${V}" w:left="${M}" w:header="0" w:footer="0" w:gutter="0"/></w:sectPr>`;
|
|
26729
26800
|
};
|
|
26730
26801
|
const sizeOf = (pg) => `${pg.width ?? model.width}x${pg.height ?? model.height}`;
|
|
26731
|
-
|
|
26802
|
+
const zipOut = [];
|
|
26803
|
+
const zip = new Zip((err, data) => {
|
|
26804
|
+
if (err) throw err;
|
|
26805
|
+
zipOut.push(data);
|
|
26806
|
+
});
|
|
26807
|
+
const put = (name, bytes2) => {
|
|
26808
|
+
const e2 = new ZipDeflate(name, { level: 6 });
|
|
26809
|
+
zip.add(e2);
|
|
26810
|
+
e2.push(bytes2, true);
|
|
26811
|
+
};
|
|
26812
|
+
const parts = [];
|
|
26813
|
+
const max = opt.xmlChunk || XML_CHUNK;
|
|
26814
|
+
let buf = "";
|
|
26815
|
+
const write = (str) => {
|
|
26816
|
+
for (const p of slices(str, max)) {
|
|
26817
|
+
if (buf.length + p.length > max) {
|
|
26818
|
+
parts.push(buf);
|
|
26819
|
+
buf = "";
|
|
26820
|
+
}
|
|
26821
|
+
buf += p;
|
|
26822
|
+
}
|
|
26823
|
+
};
|
|
26824
|
+
write(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
26825
|
+
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><w:body>`);
|
|
26732
26826
|
model.pages.forEach((pg, i) => {
|
|
26733
|
-
|
|
26827
|
+
write(body[i]);
|
|
26734
26828
|
const next = model.pages[i + 1];
|
|
26735
26829
|
if (!next) return;
|
|
26736
|
-
|
|
26830
|
+
write(sizeOf(next) !== sizeOf(pg) ? `<w:p><w:pPr>${sectPr(pg)}</w:pPr></w:p>` : '<w:p><w:pPr><w:pageBreakBefore/><w:spacing w:before="0" w:after="0" w:line="20" w:lineRule="exact"/><w:rPr><w:sz w:val="2"/></w:rPr></w:pPr></w:p>');
|
|
26737
26831
|
});
|
|
26738
26832
|
const last = model.pages[model.pages.length - 1] || {};
|
|
26739
|
-
|
|
26740
|
-
|
|
26741
|
-
last)}</w:body></w:document>`;
|
|
26833
|
+
write(`${sectPr(last)}</w:body></w:document>`);
|
|
26834
|
+
parts.push(buf);
|
|
26742
26835
|
const lang = `<w:lang w:val="${esc3(opt.lang || model.locale || "en-US")}"/>`;
|
|
26743
26836
|
const headings = [28, 24, 22, 20, 18, 18].map((sz, i) => `<w:style w:type="paragraph" w:styleId="Heading${i + 1}"><w:name w:val="heading ${i + 1}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:qFormat/><w:pPr><w:keepNext/><w:outlineLvl w:val="${i}"/></w:pPr><w:rPr><w:b/><w:sz w:val="${sz}"/></w:rPr></w:style>`).join("");
|
|
26744
26837
|
const styles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
@@ -26748,24 +26841,32 @@ name w:val="Normal"/></w:style>${headings}</w:styles>`;
|
|
|
26748
26841
|
const core = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
26749
26842
|
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc3(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc3(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type=\
|
|
26750
26843
|
"dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
|
|
26751
|
-
|
|
26752
|
-
"[Content_Types].xml": strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
26844
|
+
put("[Content_Types].xml", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
26753
26845
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="svg" ContentType="image/svg+xml"/><Override Part\
|
|
26754
|
-
Name="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`)
|
|
26755
|
-
|
|
26756
|
-
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`)
|
|
26757
|
-
|
|
26758
|
-
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>${media.map((m) => `<Relationship Id="${m.rid}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/${m.name}"/>`).join("")}</Relationships>`)
|
|
26759
|
-
|
|
26760
|
-
|
|
26761
|
-
|
|
26762
|
-
|
|
26763
|
-
|
|
26764
|
-
|
|
26846
|
+
Name="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`));
|
|
26847
|
+
put("_rels/.rels", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
26848
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`));
|
|
26849
|
+
put("word/_rels/document.xml.rels", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
26850
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>${media.map((m) => `<Relationship Id="${m.rid}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/${m.name}"/>`).join("")}</Relationships>`));
|
|
26851
|
+
const doc = new ZipDeflate("word/document.xml", { level: 6 });
|
|
26852
|
+
zip.add(doc);
|
|
26853
|
+
for (const p of parts) doc.push(strToU83(p), false);
|
|
26854
|
+
doc.push(new Uint8Array(0), true);
|
|
26855
|
+
put("word/styles.xml", strToU83(styles));
|
|
26856
|
+
put("docProps/core.xml", strToU83(core));
|
|
26857
|
+
for (const m of media) put(`word/media/${m.name}`, m.bytes);
|
|
26858
|
+
zip.end();
|
|
26859
|
+
const total = zipOut.reduce((n5, c) => n5 + c.length, 0), bytes = new Uint8Array(total);
|
|
26860
|
+
let at2 = 0;
|
|
26861
|
+
for (const c of zipOut) {
|
|
26862
|
+
bytes.set(c, at2);
|
|
26863
|
+
at2 += c.length;
|
|
26864
|
+
}
|
|
26865
|
+
return bytes;
|
|
26765
26866
|
}
|
|
26766
26867
|
|
|
26767
26868
|
// src/exporters/pptx.js
|
|
26768
|
-
import { zipSync as
|
|
26869
|
+
import { zipSync as zipSync3, strToU8 as strToU84 } from "fflate";
|
|
26769
26870
|
var EMU2 = 12700;
|
|
26770
26871
|
var e = (v) => Math.round(v * EMU2);
|
|
26771
26872
|
var esc4 = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f]/g, "");
|
|
@@ -26948,7 +27049,7 @@ rops/core.xml"/></Relationships>`);
|
|
|
26948
27049
|
="svg" ContentType="image/svg+xml"/><Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/><Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/><Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="applic\
|
|
26949
27050
|
ation/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>${slides.map((n5) => `<Override PartName="/ppt/slides/slide${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>`).join("")}<Override PartName="/docProps/core.xml" Conte\
|
|
26950
27051
|
ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
|
|
26951
|
-
return
|
|
27052
|
+
return zipSync3(files, { level: 6 });
|
|
26952
27053
|
}
|
|
26953
27054
|
var THEME = `${XML2}<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="ReportWright"><a:themeElements><a:clrScheme name="ReportWright"><a:dk1><a:srgbClr val="000000"/></a:dk1><a:lt1><a:srgbClr val="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F2328"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="2563EB"/></a:accent1><a:accent2><a:srgbClr val="F5\
|
|
26954
27055
|
9E0B"/></a:accent2><a:accent3><a:srgbClr val="16A34A"/></a:accent3><a:accent4><a:srgbClr val="DC2626"/></a:accent4><a:accent5><a:srgbClr val="7C3AED"/></a:accent5><a:accent6><a:srgbClr val="0891B2"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="ReportWright"><a:majorFont><a:latin typeface="Inter"/><a:ea t\
|
|
@@ -26968,6 +27069,7 @@ pw test [folder] [--update] [--layout]
|
|
|
26968
27069
|
render every <folder>/__tests__/*.test.json case and compare it with its snapshot
|
|
26969
27070
|
(the words; --layout: the layout, see the CLI README)
|
|
26970
27071
|
pw diff <old.pw.json> <new.pw.json> [-p name=value]… [-d source=data.json]… [--base URL]
|
|
27072
|
+
SERVER ONLY (the self-hosted app, run in its folder; the npm CLI does not include these):
|
|
26971
27073
|
pw audit verify [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--json] [--public-key file.pem]
|
|
26972
27074
|
check the server's audit log (hash chain, signed checkpoints); run it in the app
|
|
26973
27075
|
folder with the server's PW_STORAGE and PW_AUDIT_KEY / PW_SESSION_SECRET
|
|
@@ -26984,7 +27086,7 @@ pw audit rekey --old-secret S | --old-key file.pem
|
|
|
26984
27086
|
--ua an accessible PDF (PDF/UA-1; with --pdfa, PDF/A-2a) --values Excel totals as values, not formulas
|
|
26985
27087
|
--layout CSV of the printed layout (every table, group lines, totals), not just the data
|
|
26986
27088
|
--static an HTML file without its Tables view (sort, groups, filter)
|
|
26987
|
-
pw migrate-storage --to <url> [--from file|<url>]
|
|
27089
|
+
pw migrate-storage --to <url> [--from file|<url>] (SERVER ONLY, as above)
|
|
26988
27090
|
copy everything (reports and their versions, users, grants, folders, schedules,
|
|
26989
27091
|
jobs, fonts, settings, blobs, the audit log) from one storage to another, e.g. the
|
|
26990
27092
|
files in this folder to sqlite:/srv/pw.db or postgres://…; stop the server first
|
|
@@ -27030,7 +27132,9 @@ var baseHost = (base, internal) => {
|
|
|
27030
27132
|
};
|
|
27031
27133
|
async function renderModel(def, { parameters = {}, data, base, internal = false, now, state, file, exportData = true, dataOnly = false } = {}) {
|
|
27032
27134
|
try {
|
|
27033
|
-
|
|
27135
|
+
const m = await render(withData(def, data), { fontStore, parameters, exportData, dataOnly, baseUrl: base, allowHosts: baseHost(base, internal), now: now ? new Date(now) : void 0, ...state ? { state } : {}, ...file ? { loadReport: siblingLoader(file) } : {} });
|
|
27136
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27137
|
+
return { ...m, warnings: m.warnings.filter((w) => !seen.has(w.toLowerCase()) && seen.add(w.toLowerCase())) };
|
|
27034
27138
|
} catch (e2) {
|
|
27035
27139
|
const relative = /fetch|URL|Invalid URL/i.test(e2.message) && !base;
|
|
27036
27140
|
fail(`${e2.message}${relative ? "\n A data source needs a server: pass --base http://localhost:3000, or push the data with -d source=file.json." : ""}`);
|
|
@@ -27095,7 +27199,7 @@ async function cmdRender(args) {
|
|
|
27095
27199
|
if (encrypt && values.pdfa) usage("a PDF/A file cannot have a password");
|
|
27096
27200
|
if (values.ua && fmt2 !== "pdf") usage("--ua applies to -f pdf only");
|
|
27097
27201
|
if (fmt2 === "pdf") bytes = await exportPdf(model, fontStore, { title: def.name, subset, encrypt, drillBase: values.base, pdfa: values.pdfa ? { icc: fs.readFileSync(path.join(PUB, "icc", "sRGB-v2-magic.icc")) } : void 0, tagged: values.ua ? { lang: def.locale || "en" } : void 0 });
|
|
27098
|
-
else if (fmt2 === "html") bytes = await exportHtml(model, fontStore,
|
|
27202
|
+
else if (fmt2 === "html") bytes = await exportHtml(model, { fonts: fontStore, title: def.name, subset, static: !!values.static, locale: def.locale, currency: def.currency });
|
|
27099
27203
|
else if (fmt2 === "csv") bytes = exportCsv(model, { locale: def.locale, currency: def.currency, layout: !!values.layout });
|
|
27100
27204
|
else if (fmt2 === "xlsx") bytes = await exportXlsx(model, { currency: def.currency, title: def.name, formulas: !values.values, fontStore });
|
|
27101
27205
|
else if (fmt2 === "docx") bytes = await exportDocx(model, { title: def.name, lang: def.locale, fontStore });
|