@reportwright/cli 0.13.1 → 0.13.2-rc.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/dist/pw.mjs CHANGED
@@ -5415,18 +5415,18 @@ function fontsForDef(def, unknown = void 0) {
5415
5415
  const keys = /* @__PURE__ */ new Set();
5416
5416
  const seen = /* @__PURE__ */ new Set();
5417
5417
  const baseFamily = def?.styles?.base?.fontFamily;
5418
- const walk = (o) => {
5418
+ const walk2 = (o) => {
5419
5419
  if (!o || typeof o !== "object" || seen.has(o)) return;
5420
5420
  seen.add(o);
5421
5421
  if (Array.isArray(o)) {
5422
- for (const x of o) walk(x);
5422
+ for (const x of o) walk2(x);
5423
5423
  return;
5424
5424
  }
5425
5425
  if (o.fontFamily != null || o.fontWeight != null || o.fontStyle != null) keys.add(resolveFontKey(o.fontFamily ?? baseFamily, o.fontWeight, o.fontStyle, unknown));
5426
5426
  if (o.type === "chart") keys.add(resolveFontKey(o.fontFamily ?? baseFamily, "bold", "normal"));
5427
- for (const [k, v] of Object.entries(o)) if (v && typeof v === "object" && k !== "dataSources" && k !== "data") walk(v);
5427
+ for (const [k, v] of Object.entries(o)) if (v && typeof v === "object" && k !== "dataSources" && k !== "data") walk2(v);
5428
5428
  };
5429
- walk(def);
5429
+ walk2(def);
5430
5430
  return [...keys];
5431
5431
  }
5432
5432
  function fontsFor(texts) {
@@ -7126,8 +7126,8 @@ function formatDate(d, fmt2, locale, tz) {
7126
7126
  return localName(locale, "month", style, w) ?? fallback;
7127
7127
  };
7128
7128
  const p2 = (n5) => String(n5).padStart(2, "0");
7129
- return fmt2.replace(/(y+|M+|d+|H+|h+|m+|s+|f+|F+|t+|z+|\/)|'([^']*)'?|"([^"]*)"?|\\(.?)/g, (tok, run, q1, q22, esc8) => {
7130
- if (!run) return q1 ?? q22 ?? esc8 ?? "";
7129
+ return fmt2.replace(/(y+|M+|d+|H+|h+|m+|s+|f+|F+|t+|z+|\/)|'([^']*)'?|"([^"]*)"?|\\(.?)/g, (tok, run, q1, q22, esc9) => {
7130
+ if (!run) return q1 ?? q22 ?? esc9 ?? "";
7131
7131
  const n5 = run.length;
7132
7132
  switch (run[0]) {
7133
7133
  case "y": {
@@ -7728,8 +7728,8 @@ function rowLocal(ast) {
7728
7728
  const k = n5.name.toLowerCase();
7729
7729
  return !n5.obj && (k in FUNCTIONS || k === "iif" || k === "switch" || k === "choose" || k === "lookup" || k === "lookupset");
7730
7730
  };
7731
- const walk = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk) : local(n5) && Object.values(n5).every(walk));
7732
- r = walk(ast);
7731
+ const walk2 = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk2) : local(n5) && Object.values(n5).every(walk2));
7732
+ r = walk2(ast);
7733
7733
  ROW_LOCAL.set(ast, r);
7734
7734
  }
7735
7735
  return r;
@@ -7801,8 +7801,8 @@ function aggregator(name, ctx) {
7801
7801
  function pureRows(ast) {
7802
7802
  let r = PURE_ROWS.get(ast);
7803
7803
  if (r === void 0) {
7804
- const walk = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk) : !(n5.type === "id" && ["globals", "parent", "partproperties"].includes(n5.name.toLowerCase())) && Object.values(n5).every(walk));
7805
- r = rowLocal(ast) && walk(ast);
7804
+ const walk2 = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk2) : !(n5.type === "id" && ["globals", "parent", "partproperties"].includes(n5.name.toLowerCase())) && Object.values(n5).every(walk2));
7805
+ r = rowLocal(ast) && walk2(ast);
7806
7806
  PURE_ROWS.set(ast, r);
7807
7807
  }
7808
7808
  return r;
@@ -8055,7 +8055,7 @@ function pad(fname, s, width, c, left) {
8055
8055
  function jasperValue(n5, ctx) {
8056
8056
  const a = n5.args;
8057
8057
  if (a.length < 6) throw new ExprError("JasperValue needs a data set, a calculation, an expression, a time, a reset and an end", n5.p);
8058
- const ds = String(evaluate(a[0], ctx)), at2 = String(evaluate(a[3], ctx)).toLowerCase();
8058
+ const ds = String(evaluate(a[0], ctx)), at3 = String(evaluate(a[3], ctx)).toLowerCase();
8059
8059
  const [calc, incrS] = String(evaluate(a[1], ctx)).toLowerCase().split("@");
8060
8060
  const incr = incrS ? Math.trunc(Number(incrS)) || 0 : 0;
8061
8061
  const reset = Math.trunc(Number(evaluate(a[4], ctx))) || 0, end = Math.trunc(Number(evaluate(a[5], ctx)));
@@ -8077,18 +8077,18 @@ function jasperValue(n5, ctx) {
8077
8077
  const N = rows.length;
8078
8078
  const posOf = (r) => r ? info.pos.get(r) : void 0;
8079
8079
  let anchor;
8080
- if (at2 === "detail") anchor = posOf(ctx.fields);
8081
- else if (at2 === "header") anchor = posOf(ctx.aggRows?.[0]);
8082
- else if (at2 === "footer") anchor = posOf(ctx.aggRows?.[ctx.aggRows.length - 1]);
8083
- else if (at2 === "start") anchor = -1;
8080
+ if (at3 === "detail") anchor = posOf(ctx.fields);
8081
+ else if (at3 === "header") anchor = posOf(ctx.aggRows?.[0]);
8082
+ else if (at3 === "footer") anchor = posOf(ctx.aggRows?.[ctx.aggRows.length - 1]);
8083
+ else if (at3 === "start") anchor = -1;
8084
8084
  else anchor = N - 1;
8085
8085
  if (anchor === void 0) return null;
8086
8086
  let b;
8087
8087
  if (end === 0) b = N - 1;
8088
8088
  else if (end > 0) b = N ? info.end[end][Math.max(0, anchor)] : -1;
8089
- else b = at2 === "header" ? anchor - 1 : anchor;
8089
+ else b = at3 === "header" ? anchor - 1 : anchor;
8090
8090
  if (b < 0) return calc === "rows" ? 0 : null;
8091
- if (end < 0 && at2 === "header" && reset > 0 && info.start[reset][anchor] > b) return calc === "rows" ? 0 : null;
8091
+ if (end < 0 && at3 === "header" && reset > 0 && info.start[reset][anchor] > b) return calc === "rows" ? 0 : null;
8092
8092
  const vk = `v|${astId(a[2])}|${calc}|${reset}|${incr}|${kid}`;
8093
8093
  let vals = byRows.get(vk);
8094
8094
  if (!vals) {
@@ -8378,10 +8378,10 @@ function callIssues(ast, custom, suggest) {
8378
8378
  }
8379
8379
  };
8380
8380
  const known = () => [...FUNCTION_NAMES, ...Object.keys(FUNCTIONS)];
8381
- const walk = (n5, depth) => {
8381
+ const walk2 = (n5, depth) => {
8382
8382
  if (!n5 || typeof n5 !== "object" || depth > 200) return;
8383
8383
  if (Array.isArray(n5)) {
8384
- for (const x of n5) walk(x, depth + 1);
8384
+ for (const x of n5) walk2(x, depth + 1);
8385
8385
  return;
8386
8386
  }
8387
8387
  if (n5.type === "call") {
@@ -8394,9 +8394,9 @@ function callIssues(ast, custom, suggest) {
8394
8394
  } else if (isCode && !custom.has(lower)) say(`code.${lower}`, `The report has no function "${n5.name}" (Code.${n5.name})`);
8395
8395
  else if (n5.obj && !isCode && !isString && !METHODS[lower]) say(`.${lower}`, `"${n5.name}(…)" after "." is not supported`);
8396
8396
  }
8397
- for (const k in n5) if (k !== "p" && n5[k] && typeof n5[k] === "object") walk(n5[k], depth + 1);
8397
+ for (const k in n5) if (k !== "p" && n5[k] && typeof n5[k] === "object") walk2(n5[k], depth + 1);
8398
8398
  };
8399
- walk(ast, 0);
8399
+ walk2(ast, 0);
8400
8400
  return out;
8401
8401
  }
8402
8402
  function checkFunctions(list2) {
@@ -9270,8 +9270,8 @@ function fetchFailure(e2, input) {
9270
9270
  const code = String(e2.cause?.code || e2.code || "");
9271
9271
  if (!code && e2.message !== "fetch failed") return e2;
9272
9272
  const why = CAUSES[code] || (/^ERR_TLS|CERT_|SSL/.test(code) ? "TLS error" : "");
9273
- const at2 = redactUrl(input?.href ?? input);
9274
- return Object.assign(new Error(`the request to ${at2} failed${why ? `: ${why}` : ""}${code ? ` (${code})` : ""}`), { code: e2.code });
9273
+ const at3 = redactUrl(input?.href ?? input);
9274
+ return Object.assign(new Error(`the request to ${at3} failed${why ? `: ${why}` : ""}${code ? ` (${code})` : ""}`), { code: e2.code });
9275
9275
  }
9276
9276
  function anySignal(list2) {
9277
9277
  const S3 = (
@@ -9330,7 +9330,7 @@ var init_guard = __esm({
9330
9330
  });
9331
9331
 
9332
9332
  // src/importers/xml.js
9333
- function decode(s, at2) {
9333
+ function decode(s, at3) {
9334
9334
  if (!s.includes("&")) return s;
9335
9335
  let out = "", i = 0;
9336
9336
  for (; ; ) {
@@ -9338,7 +9338,7 @@ function decode(s, at2) {
9338
9338
  if (amp < 0) return out + s.slice(i);
9339
9339
  out += s.slice(i, amp);
9340
9340
  const semi = s.indexOf(";", amp);
9341
- if (semi < 0 || semi - amp > 12) throw new XmlError(`A "&" that does not start a reference, near character ${at2 + amp}`);
9341
+ if (semi < 0 || semi - amp > 12) throw new XmlError(`A "&" that does not start a reference, near character ${at3 + amp}`);
9342
9342
  const ref2 = s.slice(amp + 1, semi);
9343
9343
  if (ref2[0] === "#") {
9344
9344
  const hex6 = ref2[1] === "x" || ref2[1] === "X";
@@ -9355,20 +9355,21 @@ function parseXml(src, limits = {}) {
9355
9355
  const L = { ...XML_LIMITS, ...limits };
9356
9356
  if (typeof src !== "string") throw new XmlError("The file is not text");
9357
9357
  if (src.length > L.maxChars) throw new XmlError(`The file is too large (more than ${L.maxChars} characters)`);
9358
- if (src.charCodeAt(0) === 65279) src = src.slice(1);
9358
+ const bom = src.charCodeAt(0) === 65279 ? 1 : 0;
9359
+ if (bom) src = src.slice(1);
9359
9360
  const stack2 = [];
9360
9361
  const nsStack = [Object.assign(/* @__PURE__ */ Object.create(null), { xml: "http://www.w3.org/XML/1998/namespace" })];
9361
9362
  let root = null;
9362
9363
  let count = 0, i = 0;
9363
9364
  const n5 = src.length;
9364
- const fail2 = (msg, at2 = i) => {
9365
- throw new XmlError(`${msg} (character ${at2})`);
9365
+ const fail2 = (msg, at3 = i) => {
9366
+ throw new XmlError(`${msg} (character ${at3})`);
9366
9367
  };
9367
- const addText = (t, at2) => {
9368
+ const addText = (t, at3) => {
9368
9369
  if (!t) return;
9369
9370
  const top = stack2[stack2.length - 1];
9370
9371
  if (top) top.text += t;
9371
- else for (let k = 0; k < t.length; k++) if (!isSpace(t[k])) fail2("Text outside the root element", at2 + k);
9372
+ else for (let k = 0; k < t.length; k++) if (!isSpace(t[k])) fail2("Text outside the root element", at3 + k);
9372
9373
  };
9373
9374
  while (i < n5) {
9374
9375
  const lt = src.indexOf("<", i);
@@ -9471,7 +9472,7 @@ function parseXml(src, limits = {}) {
9471
9472
  const colon = qname.indexOf(":");
9472
9473
  const prefix = colon < 0 ? "" : qname.slice(0, colon);
9473
9474
  const ns = scope[prefix] ?? (prefix ? fail2(`The prefix "${prefix}" is not declared`) : "");
9474
- const el = { name: colon < 0 ? qname : qname.slice(colon + 1), ns, attrs: attrsOut, children: [], text: "" };
9475
+ const el = { name: colon < 0 ? qname : qname.slice(colon + 1), ns, attrs: attrsOut, children: [], text: "", pos: i + bom };
9475
9476
  if (stack2.length) stack2[stack2.length - 1].children.push(el);
9476
9477
  else root = el;
9477
9478
  if (!selfClose) {
@@ -9521,15 +9522,15 @@ function soapBody(text2, src = {}) {
9521
9522
  DOCS.add(out);
9522
9523
  return out;
9523
9524
  }
9524
- function compileXPath(path2) {
9525
- path2 = String(path2 ?? "").trim();
9526
- const hit = pathCache.get(path2);
9525
+ function compileXPath(path3) {
9526
+ path3 = String(path3 ?? "").trim();
9527
+ const hit = pathCache.get(path3);
9527
9528
  if (hit) return hit;
9528
- if (path2.length > XPATH_MAX) throw new Error(`The XPath is longer than ${XPATH_MAX} characters`);
9529
- if (!path2) throw new Error("Give an XPath");
9529
+ if (path3.length > XPATH_MAX) throw new Error(`The XPath is longer than ${XPATH_MAX} characters`);
9530
+ if (!path3) throw new Error("Give an XPath");
9530
9531
  const parts = [];
9531
9532
  let cur = "", depth = 0, q3 = "";
9532
- for (const c of path2) {
9533
+ for (const c of path3) {
9533
9534
  if (q3) {
9534
9535
  if (c === q3) q3 = "";
9535
9536
  cur += c;
@@ -9549,7 +9550,7 @@ function compileXPath(path2) {
9549
9550
  }
9550
9551
  cur += c;
9551
9552
  }
9552
- if (q3 || depth) throw new Error(`The XPath "${path2}" has an unclosed quote or [`);
9553
+ if (q3 || depth) throw new Error(`The XPath "${path3}" has an unclosed quote or [`);
9553
9554
  parts.push(cur);
9554
9555
  const abs = parts[0] === "";
9555
9556
  if (abs) parts.shift();
@@ -9558,30 +9559,30 @@ function compileXPath(path2) {
9558
9559
  for (let k = 0; k < parts.length; k++) {
9559
9560
  const p = parts[k].trim();
9560
9561
  if (p === "") {
9561
- if (desc || k === parts.length - 1) throw new Error(`The XPath "${path2}" has an empty step`);
9562
+ if (desc || k === parts.length - 1) throw new Error(`The XPath "${path3}" has an empty step`);
9562
9563
  desc = true;
9563
9564
  continue;
9564
9565
  }
9565
- steps.push(step(p, desc, path2));
9566
+ steps.push(step(p, desc, path3));
9566
9567
  desc = false;
9567
9568
  }
9568
- if (!steps.length) throw new Error(`The XPath "${path2}" has no steps`);
9569
+ if (!steps.length) throw new Error(`The XPath "${path3}" has no steps`);
9569
9570
  steps.forEach((s, k) => {
9570
- if ((s.test.kind === "attr" || s.test.kind === "text") && k < steps.length - 1) throw new Error(`In "${path2}", @attribute and text() must come last`);
9571
+ if ((s.test.kind === "attr" || s.test.kind === "text") && k < steps.length - 1) throw new Error(`In "${path3}", @attribute and text() must come last`);
9571
9572
  });
9572
9573
  const out = { abs, steps };
9573
9574
  if (pathCache.size > 500) pathCache.clear();
9574
- pathCache.set(path2, out);
9575
+ pathCache.set(path3, out);
9575
9576
  return out;
9576
9577
  }
9577
- function step(p, desc, path2) {
9578
+ function step(p, desc, path3) {
9578
9579
  const b = p.indexOf("[");
9579
9580
  const head = (b < 0 ? p : p.slice(0, b)).trim();
9580
9581
  const preds = [];
9581
9582
  if (b >= 0) {
9582
9583
  let rest2 = p.slice(b);
9583
9584
  while (rest2) {
9584
- if (rest2[0] !== "[") throw new Error(`The XPath "${path2}": text after a predicate`);
9585
+ if (rest2[0] !== "[") throw new Error(`The XPath "${path3}": text after a predicate`);
9585
9586
  let k = 1, q3 = "";
9586
9587
  for (; k < rest2.length; k++) {
9587
9588
  const c = rest2[k];
@@ -9590,7 +9591,7 @@ function step(p, desc, path2) {
9590
9591
  } else if (c === "'" || c === '"') q3 = c;
9591
9592
  else if (c === "]") break;
9592
9593
  }
9593
- preds.push(pred(rest2.slice(1, k).trim(), path2));
9594
+ preds.push(pred(rest2.slice(1, k).trim(), path3));
9594
9595
  rest2 = rest2.slice(k + 1).trim();
9595
9596
  }
9596
9597
  }
@@ -9600,29 +9601,29 @@ function step(p, desc, path2) {
9600
9601
  else if (head === "text()") test = { kind: "text" };
9601
9602
  else if (head.startsWith("@")) {
9602
9603
  const m = NAME.exec(head.slice(1));
9603
- if (!m) throw new Error(`The XPath "${path2}": "${head}" is not an attribute name`);
9604
+ if (!m) throw new Error(`The XPath "${path3}": "${head}" is not an attribute name`);
9604
9605
  test = { kind: "attr", local: m[2] };
9605
9606
  } else {
9606
9607
  const m = NAME.exec(head);
9607
- if (!m) throw new Error(`The XPath "${path2}": "${head}" is not supported (names, *, ., .., @attr, text() and simple [predicates] are)`);
9608
+ if (!m) throw new Error(`The XPath "${path3}": "${head}" is not supported (names, *, ., .., @attr, text() and simple [predicates] are)`);
9608
9609
  test = { kind: "name", prefix: m[1] || "", local: m[2] };
9609
9610
  }
9610
- if (preds.length && test.kind !== "name") throw new Error(`The XPath "${path2}": a predicate goes on an element step`);
9611
+ if (preds.length && test.kind !== "name") throw new Error(`The XPath "${path3}": a predicate goes on an element step`);
9611
9612
  return { desc, test, preds };
9612
9613
  }
9613
- function pred(s, path2) {
9614
+ function pred(s, path3) {
9614
9615
  if (/^\d+$/.test(s)) {
9615
9616
  const n5 = Number(s);
9616
- if (n5 < 1) throw new Error(`The XPath "${path2}": positions start at 1`);
9617
+ if (n5 < 1) throw new Error(`The XPath "${path3}": positions start at 1`);
9617
9618
  return { pos: n5 };
9618
9619
  }
9619
9620
  if (s === "last()") return { last: true };
9620
9621
  const m = /^(@?[A-Za-z_][\w.:-]*|text\(\)|\.)\s*(?:(!?=)\s*(.+))?$/.exec(s);
9621
- if (!m) throw new Error(`The XPath "${path2}": the predicate [${s}] is not supported`);
9622
+ if (!m) throw new Error(`The XPath "${path3}": the predicate [${s}] is not supported`);
9622
9623
  let value = null;
9623
9624
  if (m[2]) {
9624
9625
  const l = LIT.exec(m[3].trim());
9625
- if (!l) throw new Error(`The XPath "${path2}": compare with a quoted value in [${s}]`);
9626
+ if (!l) throw new Error(`The XPath "${path3}": compare with a quoted value in [${s}]`);
9626
9627
  value = l[1] ?? l[2] ?? l[3];
9627
9628
  }
9628
9629
  const what = m[1];
@@ -9661,8 +9662,8 @@ function stringValue(el) {
9661
9662
  }
9662
9663
  return s.trim();
9663
9664
  }
9664
- function selectXml(doc, path2, context) {
9665
- const { abs, steps } = compileXPath(path2);
9665
+ function selectXml(doc, path3, context) {
9666
+ const { abs, steps } = compileXPath(path3);
9666
9667
  const root = doc.$xml;
9667
9668
  const DOC = { name: "#document", ns: "", attrs: {}, children: [root], text: "" };
9668
9669
  let cur = abs ? [DOC] : [context || root];
@@ -9731,8 +9732,8 @@ function filterPred(list2, p) {
9731
9732
  return p.op === "=" ? eq : vals.length > 0 && !eq;
9732
9733
  });
9733
9734
  }
9734
- function xmlValue(doc, el, path2) {
9735
- const r = selectXml(doc, path2, el)[0];
9735
+ function xmlValue(doc, el, path3) {
9736
+ const r = selectXml(doc, path3, el)[0];
9736
9737
  return r == null ? null : typeof r === "string" ? r : stringValue(r);
9737
9738
  }
9738
9739
  function xmlObject(el) {
@@ -9764,14 +9765,14 @@ function xmlRowPaths(doc) {
9764
9765
  const seen = /* @__PURE__ */ new Map();
9765
9766
  const stack2 = [{ e: doc.$xml, path: `/${doc.$xml.name}`, depth: 0 }];
9766
9767
  while (stack2.length) {
9767
- const { e: e2, path: path2, depth } = (
9768
+ const { e: e2, path: path3, depth } = (
9768
9769
  /** @type {any} */
9769
9770
  stack2.pop()
9770
9771
  );
9771
9772
  const counts = /* @__PURE__ */ new Map();
9772
9773
  for (const c of e2.children) counts.set(c.name, (counts.get(c.name) || 0) + 1);
9773
9774
  for (const c of e2.children) {
9774
- const p = `${path2}/${c.name}`;
9775
+ const p = `${path3}/${c.name}`;
9775
9776
  let s = seen.get(p);
9776
9777
  if (!s) seen.set(p, s = { rows: 0, repeats: false, fields: /* @__PURE__ */ new Set(), depth: depth + 1 });
9777
9778
  s.rows++;
@@ -9784,14 +9785,14 @@ function xmlRowPaths(doc) {
9784
9785
  if (c.children.length) stack2.push({ e: c, path: p, depth: depth + 1 });
9785
9786
  }
9786
9787
  }
9787
- return [...seen].filter(([, s]) => s.repeats).map(([path2, s]) => ({ path: path2, rows: s.rows, objects: true, fields: [...s.fields], spreads: s.depth }));
9788
+ return [...seen].filter(([, s]) => s.repeats).map(([path3, s]) => ({ path: path3, rows: s.rows, objects: true, fields: [...s.fields], spreads: s.depth }));
9788
9789
  }
9789
9790
  function bestXmlRows(doc) {
9790
9791
  const list2 = xmlRowPaths(doc).sort((a, b) => b.rows - a.rows || a.spreads - b.spreads);
9791
9792
  return list2[0] || null;
9792
9793
  }
9793
- function xmlRows(doc, path2) {
9794
- let p = path2 && path2 !== "$" ? path2 : bestXmlRows(doc)?.path;
9794
+ function xmlRows(doc, path3) {
9795
+ let p = path3 && path3 !== "$" ? path3 : bestXmlRows(doc)?.path;
9795
9796
  if (!p) return { els: [doc.$xml], rows: [xmlObject(doc.$xml)] };
9796
9797
  const found = selectXml(doc, p);
9797
9798
  const els = found.filter((x) => typeof x !== "string");
@@ -9914,23 +9915,23 @@ var init_odata = __esm({
9914
9915
  });
9915
9916
 
9916
9917
  // src/engine/data/index.js
9917
- function pathTokens(path2) {
9918
+ function pathTokens(path3) {
9918
9919
  const toks = [];
9919
9920
  const re = /\.([A-Za-z_$][\w$]*)|\[(\d+|\*)\]|\['([^']+)'\]|\["([^"]+)"\]/g;
9920
- const p = path2.startsWith("$") ? path2.slice(1) : "." + path2;
9921
+ const p = path3.startsWith("$") ? path3.slice(1) : "." + path3;
9921
9922
  let m, last = 0;
9922
9923
  while (m = re.exec(p)) {
9923
- if (m.index !== last) throw new Error(`Bad data path "${path2}"`);
9924
+ if (m.index !== last) throw new Error(`Bad data path "${path3}"`);
9924
9925
  toks.push(m[1] ?? m[3] ?? m[4] ?? (m[2] === "*" ? "*" : Number(m[2])));
9925
9926
  last = re.lastIndex;
9926
9927
  }
9927
- if (last !== p.length) throw new Error(`Bad data path "${path2}"`);
9928
+ if (last !== p.length) throw new Error(`Bad data path "${path3}"`);
9928
9929
  return toks;
9929
9930
  }
9930
- function jsonPath(obj, path2) {
9931
- if (!path2 || path2 === "$") return obj;
9931
+ function jsonPath(obj, path3) {
9932
+ if (!path3 || path3 === "$") return obj;
9932
9933
  let cur = [obj], spread = false;
9933
- for (const t of pathTokens(path2)) {
9934
+ for (const t of pathTokens(path3)) {
9934
9935
  const nxt = [];
9935
9936
  for (const c of cur) {
9936
9937
  if (c == null) continue;
@@ -9943,10 +9944,10 @@ function jsonPath(obj, path2) {
9943
9944
  }
9944
9945
  return spread ? cur : cur[0];
9945
9946
  }
9946
- function jsonPathRows(obj, path2) {
9947
- if (!path2 || path2 === "$") return { rows: obj, parents: null };
9947
+ function jsonPathRows(obj, path3) {
9948
+ if (!path3 || path3 === "$") return { rows: obj, parents: null };
9948
9949
  let cur = [obj], hold = [null], par = [null], spread = false;
9949
- for (const t of pathTokens(path2)) {
9950
+ for (const t of pathTokens(path3)) {
9950
9951
  const nv = [], nh = [], np = [];
9951
9952
  for (let i = 0; i < cur.length; i++) {
9952
9953
  const c = cur[i];
@@ -10424,8 +10425,8 @@ function buildDataSets(def, sources, baseCtx) {
10424
10425
  const declared = (ds.fields || []).filter((fd) => !fd.expr && !fd.path);
10425
10426
  const hasFields = Object.values(asObject).some((v) => v != null && typeof v !== "object");
10426
10427
  if (inner2.length && !hasFields && !declared.some((fd) => Object.hasOwn(asObject, fd.name))) {
10427
- const at2 = ds.path && ds.path !== "$" ? ds.path : `$.${ds.source}`;
10428
- baseCtx.warn?.(`Data set "${ds.name}": ${at2} is an object, not a list of rows, so it is one row; expected an array of rows (did you mean ${at2}.${inner2[0]}?)`);
10428
+ const at3 = ds.path && ds.path !== "$" ? ds.path : `$.${ds.source}`;
10429
+ baseCtx.warn?.(`Data set "${ds.name}": ${at3} is an object, not a list of rows, so it is one row; expected an array of rows (did you mean ${at3}.${inner2[0]}?)`);
10429
10430
  }
10430
10431
  }
10431
10432
  const keys = /* @__PURE__ */ new Set();
@@ -11315,6 +11316,8 @@ function newContext() {
11315
11316
  /** @type {Set<string>} part libraries referenced (report ids) */
11316
11317
  libraries: /* @__PURE__ */ new Set(),
11317
11318
  cells: 0,
11319
+ /** @type {any[]} every item tracked, with what happened to it (see items() in importRdlx's result) */
11320
+ items: [],
11318
11321
  warn(msg) {
11319
11322
  if (!cx.warnings.includes(msg)) cx.warnings.push(msg);
11320
11323
  }
@@ -11324,24 +11327,35 @@ function newContext() {
11324
11327
  function track(cx, ar, label) {
11325
11328
  cx.stats.items++;
11326
11329
  const name = String(ar?.Name || label || ar?.Type || "item");
11330
+ const say = (kind, msg) => {
11331
+ if (!t.notes.some((n5) => n5.message === msg)) t.notes.push({ kind, message: msg });
11332
+ cx.warn(`${name}: ${msg}`);
11333
+ };
11327
11334
  const t = {
11328
11335
  name,
11329
11336
  state: "mapped",
11337
+ pos: typeof ar?.__pos === "number" ? ar.__pos : void 0,
11338
+ /** @type {{ kind: string, message: string }[]} */
11339
+ notes: [],
11340
+ /** @type {string[]} expressions that could not be translated */
11341
+ exprs: [],
11330
11342
  /** in the report, with something lost or changed */
11331
11343
  approx(msg) {
11332
11344
  if (t.state === "mapped") t.state = "approximated";
11333
- cx.warn(`${name}: ${msg}`);
11345
+ say("approximated", msg);
11334
11346
  },
11335
11347
  /** for information only */
11336
11348
  note(msg) {
11337
- cx.warn(`${name}: ${msg}`);
11349
+ say("info", msg);
11338
11350
  },
11339
11351
  /** not in the report */
11340
11352
  drop(msg) {
11341
11353
  t.state = "dropped";
11342
- cx.warn(`${name}: ${msg}`);
11354
+ say("dropped", msg);
11343
11355
  }
11344
11356
  };
11357
+ cx.items.push(t);
11358
+ for (const x of Array.isArray(ar?.__exprs) ? ar.__exprs : []) if (typeof x === "string" && !t.exprs.includes(x)) t.exprs.push(x);
11345
11359
  for (const n5 of Array.isArray(ar?.__notes) ? ar.__notes : []) t.approx(n5);
11346
11360
  for (const n5 of Array.isArray(ar?.__info) ? ar.__info : []) t.note(n5);
11347
11361
  return t;
@@ -11359,6 +11373,7 @@ function uniq(cx, base, generated = false) {
11359
11373
  }
11360
11374
  function ex(cx, t, v, ctx, opt = {}) {
11361
11375
  const r = translateExpression(v, { text: opt.text, fields: opt.fields, lit: opt.lit, region: ctx.region, scopes: cx.scopes, runScopes: cx.runScopes });
11376
+ if (!r.ok && typeof v === "string" && !t.exprs.includes(v)) t.exprs.push(v);
11362
11377
  if (!r.ok) t.approx(`${r.notes.join("; ")}; ${opt.text ? "the expression is shown as text" : `${opt.what || "that setting"} is left out`}.`);
11363
11378
  else for (const n5 of r.notes) t.approx(`${n5}.`);
11364
11379
  return r.value;
@@ -11560,12 +11575,13 @@ function convertItem(ar, cx, ctx) {
11560
11575
  dropInside(ar, cx);
11561
11576
  return finish(cx, t, null);
11562
11577
  }
11563
- const snap = { ...cx.stats };
11578
+ const snap = { ...cx.stats }, tracked = cx.items.length;
11564
11579
  try {
11565
11580
  return conv(ar, cx, ctx);
11566
11581
  } catch (e2) {
11567
11582
  if (e2 instanceof ImportBudgetError) throw e2;
11568
11583
  Object.assign(cx.stats, snap);
11584
+ cx.items.length = tracked;
11569
11585
  const t = track(cx, ar);
11570
11586
  t.drop(`it could not be converted (${e2 instanceof Error ? e2.message : e2}), so it was left out.`);
11571
11587
  dropInside(ar, cx);
@@ -11574,25 +11590,25 @@ function convertItem(ar, cx, ctx) {
11574
11590
  }
11575
11591
  function dropInside(ar, cx) {
11576
11592
  let n5 = 0;
11577
- const walk = (o) => {
11593
+ const walk2 = (o) => {
11578
11594
  if (!o || typeof o !== "object") return;
11579
11595
  if (Array.isArray(o)) {
11580
- o.forEach(walk);
11596
+ o.forEach(walk2);
11581
11597
  return;
11582
11598
  }
11583
11599
  for (const [k, v] of Object.entries(o)) {
11584
11600
  if (k === "ReportItems" && Array.isArray(v)) {
11585
11601
  for (const x of v) if (x && typeof x === "object" && x.Type) {
11586
11602
  n5++;
11587
- walk(x);
11603
+ walk2(x);
11588
11604
  }
11589
11605
  } else if (k === "Item" && v && typeof v === "object" && v.Type) {
11590
11606
  n5++;
11591
- walk(v);
11592
- } else if (v && typeof v === "object") walk(v);
11607
+ walk2(v);
11608
+ } else if (v && typeof v === "object") walk2(v);
11593
11609
  }
11594
11610
  };
11595
- walk(ar);
11611
+ walk2(ar);
11596
11612
  cx.stats.items += n5;
11597
11613
  cx.stats.dropped += n5;
11598
11614
  }
@@ -12184,14 +12200,14 @@ function tablix(ar, cx, ctx) {
12184
12200
  function tablixItems(ar) {
12185
12201
  const out = [];
12186
12202
  for (const row of ar.Corner || []) for (const c of row || []) if (c?.Item) out.push(c.Item);
12187
- const walk = (ms) => {
12203
+ const walk2 = (ms) => {
12188
12204
  for (const m of ms || []) {
12189
12205
  if (m?.Header?.Item) out.push(m.Header.Item);
12190
- walk(m?.Children);
12206
+ walk2(m?.Children);
12191
12207
  }
12192
12208
  };
12193
- walk(ar.ColumnHierarchy?.Members);
12194
- walk(ar.RowHierarchy?.Members);
12209
+ walk2(ar.ColumnHierarchy?.Members);
12210
+ walk2(ar.RowHierarchy?.Members);
12195
12211
  for (const r of ar.Body?.Rows || []) for (const c of r?.Cells || []) if (c?.Item) out.push(c.Item);
12196
12212
  return out;
12197
12213
  }
@@ -12232,13 +12248,13 @@ function tablixTable(ar, cx, ctx) {
12232
12248
  }
12233
12249
  const groups = [], leaves = [];
12234
12250
  let detailVis, problem = null;
12235
- const walkRows = (ms, level, path2, depth, hint) => {
12251
+ const walkRows = (ms, level, path3, depth, hint) => {
12236
12252
  const localDyn = ms.some((m) => m.Group);
12237
12253
  if (ms.filter((m) => m.Group).length > 1) problem = "two row groups sit side by side";
12238
12254
  let seen = false;
12239
12255
  for (const m of ms) {
12240
12256
  const span = m.Header ? Number(m.Header.LevelCount) || 1 : 0;
12241
- const p = [...path2, { m, level, span }];
12257
+ const p = [...path3, { m, level, span }];
12242
12258
  const kids = members({ Members: m.Children });
12243
12259
  if (isDyn(m)) {
12244
12260
  if (depth !== groups.length) problem = "its row groups are not nested in one chain";
@@ -12365,15 +12381,15 @@ function tablixMatrix(ar, cx, ctx) {
12365
12381
  const leafIndex = (ms) => {
12366
12382
  const map = /* @__PURE__ */ new Map();
12367
12383
  let n5 = 0;
12368
- const walk = (list2) => {
12384
+ const walk2 = (list2) => {
12369
12385
  for (const m of list2) {
12370
12386
  map.set(m, m.BodyIndex ?? n5);
12371
12387
  const kids = members({ Members: m.Children });
12372
- if (kids.length) walk(kids);
12388
+ if (kids.length) walk2(kids);
12373
12389
  else n5++;
12374
12390
  }
12375
12391
  };
12376
- walk(ms);
12392
+ walk2(ms);
12377
12393
  return map;
12378
12394
  };
12379
12395
  const rIdx = leafIndex(rowMs), cIdx = leafIndex(colMs);
@@ -12506,9 +12522,9 @@ function tablixMatrix(ar, cx, ctx) {
12506
12522
  if (rhs && Object.keys(textStyle(rhs, cx, t, rctx)).length) it.style = { padding: textStyle(rhs, cx, t, rctx).padding ?? 0 };
12507
12523
  if (isFalse(ar.RepeatColumnHeaders)) it.repeatHeader = false;
12508
12524
  regionData(ar, it, cx, t, rctx, ctx);
12509
- for (const inside of tablixItems(ar)) {
12510
- const ti = track(cx, inside);
12511
- if (!used.has(inside) && inside.Value != null && String(inside.Value).trim() !== "") ti.approx("this cell is not shown: a ReportWright matrix shows group headers, values and totals.");
12525
+ for (const inside2 of tablixItems(ar)) {
12526
+ const ti = track(cx, inside2);
12527
+ if (!used.has(inside2) && inside2.Value != null && String(inside2.Value).trim() !== "") ti.approx("this cell is not shown: a ReportWright matrix shows group headers, values and totals.");
12512
12528
  finish(cx, ti, null);
12513
12529
  }
12514
12530
  return finish(cx, t, it);
@@ -13375,11 +13391,11 @@ function fixedPage(fp, cx, info) {
13375
13391
  }
13376
13392
  function collectScopes(ar, cx) {
13377
13393
  const seen = /* @__PURE__ */ new Set();
13378
- const walk = (o) => {
13394
+ const walk2 = (o) => {
13379
13395
  if (!o || typeof o !== "object" || seen.has(o)) return;
13380
13396
  seen.add(o);
13381
13397
  if (Array.isArray(o)) {
13382
- o.forEach(walk);
13398
+ o.forEach(walk2);
13383
13399
  return;
13384
13400
  }
13385
13401
  const type = String(o.Type || "").toLowerCase();
@@ -13412,9 +13428,9 @@ function collectScopes(ar, cx) {
13412
13428
  if (type.includes("chart")) {
13413
13429
  for (const p of o.Plots || []) for (const g of [...p?.CategoryGroupings || [], ...p?.SeriesGroupings || []]) if (g?.Grouping?.Name) cx.scopes.set(g.Grouping.Name, null);
13414
13430
  }
13415
- for (const v of Object.values(o)) if (v && typeof v === "object") walk(v);
13431
+ for (const v of Object.values(o)) if (v && typeof v === "object") walk2(v);
13416
13432
  };
13417
- walk(ar);
13433
+ walk2(ar);
13418
13434
  for (const d of Array.isArray(ar.DataSets) ? ar.DataSets : []) if (d?.Name) cx.scopes.set(d.Name, d.Name);
13419
13435
  }
13420
13436
  function convertReport(ar, cx, opts) {
@@ -13477,7 +13493,7 @@ function convertReport(ar, cx, opts) {
13477
13493
  if (cx.columns) body.columns = cx.columns;
13478
13494
  if (more.length) body.name = sec0?.Name || "Section1";
13479
13495
  return {
13480
- $schema: "pagewright/report@1",
13496
+ $schema: "reportwright/report@1",
13481
13497
  name,
13482
13498
  locale: lang,
13483
13499
  ...currencyOf(lang) ? { currency: currencyOf(lang) } : {},
@@ -13518,15 +13534,15 @@ function importRdlx(input, opts = {}) {
13518
13534
  } catch (e2) {
13519
13535
  if (e2 instanceof ImportBudgetError) {
13520
13536
  const error = `The report is too large to import: ${e2.message}`;
13521
- return { definition: convertReport({}, newContext(), opts), warnings: [`${error}.`], stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, error };
13537
+ return { definition: convertReport({}, newContext(), opts), warnings: [`${error}.`], stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, items: [], error };
13522
13538
  }
13523
13539
  cx.warn(`The import stopped early (${e2 instanceof Error ? e2.message : e2}), so parts of the report are missing.`);
13524
13540
  definition = convertReport({}, newContext(), opts);
13525
13541
  }
13526
- return { definition, warnings: cx.warnings, stats: cx.stats };
13542
+ return { definition, warnings: cx.warnings, stats: cx.stats, items: importedItems(cx.items) };
13527
13543
  }
13528
13544
  var UNIT2, r25, NAMED3, MONO2, weightOf, ALIGN, VALIGN, LITS, safeName, Untranslatable, no, bad, CONT, NUM, NAME2, at, MAX_RESULT, VB_OPS, BIN2, q2, wrap, atom, fn, ROOT, cap, GLOBALS, INTERVAL, DATEFORMAT, AGG2, SAME, CONVERT, MATH, VB_DAYS, escText, isExpr, inner, AGG_RE, ImportBudgetError, OUTPUT_LIMITS, hasDeco, CONVERTERS, TARGETS, bare, isTrue, isFalse, stripHtml, SYMBOLOGY, missing, FILTER_OPS,
13529
- joinKeys, CELL_ITEMS, TEXT_CELL, isDyn, anyDyn, members, shiftY, CHART_TYPES2, PALETTES2, SERIES_KIND, SQL_PROVIDERS, CONN_KEYS, getKey, unescapeTpl, TYPE_HINT, PTYPE, coerceLit, PAGE_NO;
13545
+ joinKeys, CELL_ITEMS, TEXT_CELL, isDyn, anyDyn, members, shiftY, CHART_TYPES2, PALETTES2, SERIES_KIND, SQL_PROVIDERS, CONN_KEYS, getKey, unescapeTpl, TYPE_HINT, PTYPE, coerceLit, PAGE_NO, importedItems, rewordItems;
13530
13546
  var init_rdlx = __esm({
13531
13547
  "src/importers/rdlx.js"() {
13532
13548
  init_units();
@@ -13536,13 +13552,13 @@ var init_rdlx = __esm({
13536
13552
  init_data();
13537
13553
  UNIT2 = { in: 72, cm: 72 / 2.54, mm: 72 / 25.4, pt: 1, pc: 12, px: 0.75 };
13538
13554
  r25 = (n5) => Math.round(n5 * 100) / 100;
13539
- NAMED3 = Object.fromEntries("aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,dar\
13540
- kgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkgrey:a9a9a9,darkkhaki:bdb76b,darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,darkslategrey:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,dimgray:696969,dimgrey:696969,dodgerblue:1e90ff,f\
13541
- irebrick:b22222,floralwhite:fffaf0,forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,gray:808080,green:008000,greenyellow:adff2f,grey:808080,honeydew:f0fff0,hotpink:ff69b4,indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ff\
13542
- ff,lightgoldenrodyellow:fafad2,lightgray:d3d3d3,lightgreen:90ee90,lightgrey:d3d3d3,lightpink:ffb6c1,lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,lightslategrey:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,mediumorchid:ba55d3,mediumpurple:9370db,me\
13543
- diumseagreen:3cb371,mediumslateblue:7b68ee,mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,palegreen:98fb98,paleturquoise:afeeee,palevioletred:db7093,papayawhip:ffef\
13544
- d5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,slategray:708090,slategrey:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,teal:00808\
13545
- 0,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32".split(",").map((p) => p.split(":")));
13555
+ NAMED3 = Object.fromEntries(("aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,dar"+
13556
+ "kgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkgrey:a9a9a9,darkkhaki:bdb76b,darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,darkslategrey:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,dimgray:696969,dimgrey:696969,dodgerblue:1e90ff,f"+
13557
+ "irebrick:b22222,floralwhite:fffaf0,forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,gray:808080,green:008000,greenyellow:adff2f,grey:808080,honeydew:f0fff0,hotpink:ff69b4,indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ff"+
13558
+ "ff,lightgoldenrodyellow:fafad2,lightgray:d3d3d3,lightgreen:90ee90,lightgrey:d3d3d3,lightpink:ffb6c1,lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,lightslategrey:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,mediumorchid:ba55d3,mediumpurple:9370db,me"+
13559
+ "diumseagreen:3cb371,mediumslateblue:7b68ee,mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,palegreen:98fb98,paleturquoise:afeeee,palevioletred:db7093,papayawhip:ffef"+
13560
+ "d5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,slategray:708090,slategrey:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,teal:00808"+
13561
+ "0,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32").split(",").map((p) => p.split(":")));
13546
13562
  MONO2 = /mono|courier|consol|menlo|monaco|lucida console|typewriter/i;
13547
13563
  weightOf = (w) => {
13548
13564
  const s = String(w).trim().toLowerCase();
@@ -13914,6 +13930,8 @@ d5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple
13914
13930
  return v;
13915
13931
  };
13916
13932
  PAGE_NO = /Globals!\s*(PageNumber|TotalPages|PageNumberInSection|TotalPagesInSection|OverallPageNumber|OverallTotalPages)\b/i;
13933
+ importedItems = (items) => items.filter((t) => t.state !== "mapped" || t.notes.length || t.exprs.length).map((t) => ({ name: t.name, state: t.state, ...t.pos != null ? { pos: t.pos } : {}, notes: t.notes, exprs: t.exprs }));
13934
+ rewordItems = (items, f4) => (items || []).map((i) => ({ ...i, notes: i.notes.map((n5) => ({ ...n5, message: f4(n5.message) })) }));
13917
13935
  }
13918
13936
  });
13919
13937
 
@@ -13935,7 +13953,7 @@ function importRdl(input, opts = {}) {
13935
13953
  const notes = [];
13936
13954
  let ar;
13937
13955
  try {
13938
- ar = toRdlx(root, notes, m ? Number(m[1]) : 2016);
13956
+ ar = toRdlx(root, notes, m ? Number(m[1]) : 2016, opts.resolve);
13939
13957
  } catch (e2) {
13940
13958
  if (e2 instanceof ImportBudgetError) {
13941
13959
  const error = `The report is too large to import: ${e2.message}`;
@@ -13949,10 +13967,12 @@ function importRdl(input, opts = {}) {
13949
13967
  const def = r.definition;
13950
13968
  for (const p of def.parameters || []) if (ar.__hidden?.has(p.name)) p.hidden = true;
13951
13969
  if (ar.__code) def.customCode = ar.__code;
13952
- const warnings = [...notes, ...r.warnings.filter((w) => !/is hidden in ActiveReports; ReportWright shows it/.test(w))].map((w) => w.replace(/ActiveReports/g, "SSRS"));
13953
- return { definition: def, warnings: [...new Set(warnings)], stats: r.stats };
13970
+ const hiddenNote = /is hidden in ActiveReports; ReportWright shows it/;
13971
+ const warnings = [...notes, ...r.warnings.filter((w) => !hiddenNote.test(w))].map((w) => w.replace(/ActiveReports/g, "SSRS"));
13972
+ const items = rewordItems(r.items.map((i) => ({ ...i, notes: i.notes.filter((n5) => !hiddenNote.test(n5.message)) })), (w) => w.replace(/ActiveReports/g, "SSRS"));
13973
+ return { definition: def, warnings: [...new Set(warnings)], stats: r.stats, items };
13954
13974
  }
13955
- function toRdlx(root, notes, year) {
13975
+ function toRdlx(root, notes, year, resolve) {
13956
13976
  const NS3 = root.ns;
13957
13977
  const kids = (e2, name) => e2 ? e2.children.filter((c) => c.ns === NS3 && (name == null || c.name === name)) : [];
13958
13978
  const kid = (e2, name) => e2?.children.find((c) => c.ns === NS3 && c.name === name);
@@ -13961,7 +13981,7 @@ function toRdlx(root, notes, year) {
13961
13981
  return c ? c.attrs.nil === "true" ? null : c.text : void 0;
13962
13982
  };
13963
13983
  const val = (e2, name) => fix(raw(e2, name));
13964
- const path2 = (e2, ...names) => names.reduce((x, n5) => kid(x, n5), e2);
13984
+ const path3 = (e2, ...names) => names.reduce((x, n5) => kid(x, n5), e2);
13965
13985
  const list2 = (e2, outer, inner2) => kids(kid(e2, outer), inner2);
13966
13986
  const variables = /* @__PURE__ */ new Map();
13967
13987
  const boxes = /* @__PURE__ */ new Map();
@@ -14119,6 +14139,7 @@ function toRdlx(root, notes, year) {
14119
14139
  Name: e2.attrs.Name,
14120
14140
  __notes: itemNotes,
14121
14141
  __info: itemInfo,
14142
+ __pos: e2.pos,
14122
14143
  Left: raw(e2, "Left"),
14123
14144
  Top: raw(e2, "Top"),
14124
14145
  Width: raw(e2, "Width"),
@@ -14544,7 +14565,7 @@ function toRdlx(root, notes, year) {
14544
14565
  const vals = kid(dp, "ChartDataPointValues");
14545
14566
  const srcs = pt.values.map((n5) => val(vals, n5)).filter((v) => v != null && v !== "");
14546
14567
  if (!srcs.length) return;
14547
- const caption = val(path2(s, "ChartItemInLegend"), "LegendText") || statics[i] && val(statics[i], "Label") || s.attrs.Name;
14568
+ const caption = val(path3(s, "ChartItemInLegend"), "LegendText") || statics[i] && val(statics[i], "Label") || s.attrs.Name;
14548
14569
  p.Encodings.Values.push({ Field: { Value: srcs }, Caption: isExpr2(caption) ? s.attrs.Name : caption });
14549
14570
  const x = val(vals, "X");
14550
14571
  if (x && !p.x) p.x = x;
@@ -14654,23 +14675,52 @@ function toRdlx(root, notes, year) {
14654
14675
  const r = e2.name === "Tablix" || e2.name === "Chart" ? e2.attrs.Name || reg : reg;
14655
14676
  for (const c of e2.children) prepass(c, r);
14656
14677
  })(root, null);
14678
+ function sharedSource(ref2) {
14679
+ let text2;
14680
+ try {
14681
+ text2 = resolve?.("datasource", ref2);
14682
+ } catch {
14683
+ text2 = null;
14684
+ }
14685
+ if (typeof text2 !== "string") return null;
14686
+ let doc;
14687
+ try {
14688
+ doc = parseXml(text2);
14689
+ } catch (e2) {
14690
+ notes.push(`The shared data source "${ref2}" could not be read (${e2 instanceof Error ? e2.message : e2}); it is treated as SQL Server.`);
14691
+ return null;
14692
+ }
14693
+ const sub = (e2, n5) => e2?.children.find((c) => c.name === n5);
14694
+ const props = doc.name === "RptDataSource" ? sub(doc, "ConnectionProperties") : doc.name === "DataSourceDefinition" ? doc : null;
14695
+ if (!props) {
14696
+ notes.push(`The shared data source "${ref2}" is not an SSRS data source (its root is <${doc.name}>); it is treated as SQL Server.`);
14697
+ return null;
14698
+ }
14699
+ return { provider: (sub(props, "Extension")?.text || "SQL").trim(), connect: (sub(props, "ConnectString")?.text ?? "").trim() };
14700
+ }
14657
14701
  const TYPE_OF = (t) => /datetime|date$/i.test(t) ? "date" : /int|decimal|double|single|byte|float/i.test(t) ? "number" : /boolean/i.test(t) ? "boolean" : null;
14658
14702
  const DataSources = list2(root, "DataSources", "DataSource").map((d) => {
14659
14703
  const name = d.attrs.Name;
14660
14704
  const cp = kid(d, "ConnectionProperties");
14661
14705
  let provider = raw(cp, "DataProvider") || "";
14706
+ let connect = raw(cp, "ConnectString") ?? "";
14662
14707
  if (!cp && kid(d, "DataSourceReference")) {
14663
- provider = "SQL";
14664
- notes.push(`Data source "${name}" is the shared data source "${raw(d, "DataSourceReference")}", whose connection is not in the file; it is treated as SQL Server.`);
14708
+ const ref2 = raw(d, "DataSourceReference") ?? "";
14709
+ const shared = sharedSource(ref2);
14710
+ if (shared) ({ provider, connect } = shared);
14711
+ else {
14712
+ provider = "SQL";
14713
+ notes.push(`Data source "${name}" is the shared data source "${ref2}", whose connection is not in the file; it is treated as SQL Server.`);
14714
+ }
14665
14715
  }
14666
14716
  if (/^(OLEDB-MD|ESSBASE|SAPBW|SQLAS|HYPERION)/i.test(provider)) provider = `${provider} (MDX)`;
14667
- return { Name: name, ConnectionProperties: { DataProvider: provider, ConnectString: raw(cp, "ConnectString") ?? "" } };
14717
+ return { Name: name, ConnectionProperties: { DataProvider: provider, ConnectString: connect } };
14668
14718
  });
14669
14719
  const entered = /* @__PURE__ */ new Map();
14670
14720
  const providers = new Map(DataSources.map((d) => [d.Name, String(d.ConnectionProperties.DataProvider).toUpperCase()]));
14671
14721
  const DataSets = list2(root, "DataSets", "DataSet").map((d) => {
14672
14722
  const q3 = kid(d, "Query");
14673
- const shared = path2(d, "SharedDataSet", "SharedDataSetReference");
14723
+ const shared = path3(d, "SharedDataSet", "SharedDataSetReference");
14674
14724
  if (shared) notes.push(`Data set "${d.attrs.Name}" is the shared data set "${shared.text}", which is not in the file; set its source and query.`);
14675
14725
  const types = /* @__PURE__ */ new Map();
14676
14726
  const Fields = list2(d, "Fields", "Field").map((f4) => {
@@ -15296,9 +15346,9 @@ function dotted(n5) {
15296
15346
  return null;
15297
15347
  }
15298
15348
  function emMember2(n5, env, d) {
15299
- const path2 = dotted(n5);
15300
- if (path2) {
15301
- const short = path2.replace(/^java\.(lang|math|util)\./, "");
15349
+ const path3 = dotted(n5);
15350
+ if (path3) {
15351
+ const short = path3.replace(/^java\.(lang|math|util)\./, "");
15302
15352
  if (short === "Boolean.TRUE") return A("True", "bool");
15303
15353
  if (short === "Boolean.FALSE") return A("False", "bool");
15304
15354
  if (short === "Math.PI") return A("Math.PI", "num");
@@ -15308,7 +15358,7 @@ function emMember2(n5, env, d) {
15308
15358
  if (/^(RoundingMode|BigDecimal)\.[A-Z_]+$/.test(short)) return A(vbStr(short.split(".")[1]), "str");
15309
15359
  }
15310
15360
  if (n5.name === "length" && n5.obj) throw new Untranslatable2("an array length");
15311
- throw new Untranslatable2(`the field ${path2 || `.${n5.name}`}`);
15361
+ throw new Untranslatable2(`the field ${path3 || `.${n5.name}`}`);
15312
15362
  }
15313
15363
  function emNew(n5, env, d) {
15314
15364
  const name = n5.name.replace(/^java\.(lang|math|util|sql)\./, "");
@@ -15338,9 +15388,9 @@ function emCall2(n5, env, d) {
15338
15388
  }
15339
15389
  throw new Untranslatable2(`the function ${n5.name}()`);
15340
15390
  }
15341
- const path2 = dotted(n5.obj);
15342
- if (path2 && !(n5.obj.k === "id" && /^[a-z]/.test(n5.obj.name) && !/^java$/.test(n5.obj.name))) {
15343
- const cls = path2.replace(/^java\.(lang|math|util|sql)\./, "");
15391
+ const path3 = dotted(n5.obj);
15392
+ if (path3 && !(n5.obj.k === "id" && /^[a-z]/.test(n5.obj.name) && !/^java$/.test(n5.obj.name))) {
15393
+ const cls = path3.replace(/^java\.(lang|math|util|sql)\./, "");
15344
15394
  const a2 = args();
15345
15395
  const m = n5.name;
15346
15396
  if (cls === "String" && m === "valueOf" && a2.length === 1) return jstr(a2[0]);
@@ -15521,7 +15571,7 @@ function importJrxml(input, opts = {}) {
15521
15571
  const charts = /* @__PURE__ */ new Map();
15522
15572
  let ar;
15523
15573
  try {
15524
- ar = toRdlx2(root, notes, charts, opts.name || root.attrs.name);
15574
+ ar = toRdlx2(root, notes, charts, opts.name || root.attrs.name, opts.resolve);
15525
15575
  } catch (e2) {
15526
15576
  if (e2 instanceof ImportBudgetError) {
15527
15577
  const error = `The report is too large to import: ${e2.message}`;
@@ -15547,7 +15597,7 @@ function importJrxml(input, opts = {}) {
15547
15597
  r.definition.arithmetic = "double";
15548
15598
  placeCharts(r.definition, charts);
15549
15599
  const warnings = [...notes, ...r.warnings].map((w) => w.replace(/ActiveReports/g, "JasperReports"));
15550
- return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats };
15600
+ return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats, items: rewordItems(r.items, (w) => w.replace(/ActiveReports/g, "JasperReports")) };
15551
15601
  }
15552
15602
  function stripJasperDoctype(s) {
15553
15603
  const i = s.indexOf("<!DOCTYPE");
@@ -15556,9 +15606,9 @@ function stripJasperDoctype(s) {
15556
15606
  if (e2 < 0) return s;
15557
15607
  const decl = s.slice(i, e2 + 1);
15558
15608
  if (decl.includes("[") || !/^<!DOCTYPE\s+jasperReport\s/.test(decl)) return s;
15559
- return s.slice(0, i) + s.slice(e2 + 1);
15609
+ return s.slice(0, i) + decl.replace(/[^\n]/g, " ") + s.slice(e2 + 1);
15560
15610
  }
15561
- function toRdlx2(root, notes, charts, reportName) {
15611
+ function toRdlx2(root, notes, charts, reportName, resolve) {
15562
15612
  const kid = (e2, n5) => e2?.children.find((c) => c.name === n5);
15563
15613
  const kids = (e2, n5) => e2 ? e2.children.filter((c) => n5 == null || c.name === n5) : [];
15564
15614
  const txt = (e2, n5) => {
@@ -15651,8 +15701,8 @@ function toRdlx2(root, notes, charts, reportName) {
15651
15701
  };
15652
15702
  const BAND_AT = { detail: "detail", gh: "header", gf: "footer", title: "start", summary: "end" };
15653
15703
  function jasper(calc, inner2, reset, c) {
15654
- const at2 = BAND_AT[c.band];
15655
- const keys = at2 && reset != null ? groupKeys() : null;
15704
+ const at3 = BAND_AT[c.band];
15705
+ const keys = at3 && reset != null ? groupKeys() : null;
15656
15706
  if (!keys) return null;
15657
15707
  let end = -1;
15658
15708
  if (c.evalTime === "Report") end = 0;
@@ -15660,7 +15710,7 @@ function toRdlx2(root, notes, charts, reportName) {
15660
15710
  const k = groups.findIndex((g) => g.attrs.name === c.evalGroup);
15661
15711
  end = k >= 0 ? k + 1 : -1;
15662
15712
  } else if (c.evalTime === "Auto") end = reset;
15663
- return `JasperValue("${MAIN}", "${calc}", ${inner2}, "${at2}", ${reset}, ${end}${keys.map((k) => `, ${k}`).join("")})`;
15713
+ return `JasperValue("${MAIN}", "${calc}", ${inner2}, "${at3}", ${reset}, ${end}${keys.map((k) => `, ${k}`).join("")})`;
15664
15714
  }
15665
15715
  const depthOf = (gname) => {
15666
15716
  const k = groups.findIndex((g) => g.attrs.name === gname);
@@ -15742,6 +15792,7 @@ function toRdlx2(root, notes, charts, reportName) {
15742
15792
  return "=" + v.s;
15743
15793
  } catch (e2) {
15744
15794
  if (!(e2 instanceof Untranslatable2)) throw e2;
15795
+ (item2.__exprs ||= []).push(s);
15745
15796
  (item2.__notes ||= []).push(`${e2.message} has no ReportWright equivalent, so the expression ${s.length > 200 ? s.slice(0, 200) + "…" : s} is shown as text.`);
15746
15797
  return s.startsWith("=") ? `="${s.replace(/"/g, '""')}"` : s;
15747
15798
  }
@@ -15751,12 +15802,50 @@ function toRdlx2(root, notes, charts, reportName) {
15751
15802
  return "=" + vb2(String(src).trim(), c);
15752
15803
  } catch (e2) {
15753
15804
  if (!(e2 instanceof Untranslatable2)) throw e2;
15805
+ (item2.__exprs ||= []).push(String(src).trim());
15754
15806
  (item2.__notes ||= []).push(`${what} uses ${e2.message}, which has no ReportWright equivalent, so it is left out.`);
15755
15807
  return void 0;
15756
15808
  }
15757
15809
  }
15758
15810
  const styles = new Map(kids(root, "style").map((s) => [s.attrs.name, s]));
15759
- const defStyle = kids(root, "style").find((s) => s.attrs.isDefault === "true" || s.attrs.default === "true");
15811
+ const seenTemplates = /* @__PURE__ */ new Set();
15812
+ (function templates(el, depth) {
15813
+ for (const t of kids(el, "template")) {
15814
+ const src = (kid(t, "expression")?.text ?? t.text).trim();
15815
+ const lit2 = /^"([^"]+)"$/.exec(src);
15816
+ const ref2 = lit2 ? lit2[1] : depth > 0 && !/["$(){}+]/.test(src) ? src : null;
15817
+ if (!ref2) {
15818
+ if (src) note(`A style template is chosen by an expression (${src.slice(0, 120)}), so its styles are missing.`);
15819
+ continue;
15820
+ }
15821
+ if (seenTemplates.has(ref2) || seenTemplates.size >= 32) continue;
15822
+ seenTemplates.add(ref2);
15823
+ let text2;
15824
+ try {
15825
+ text2 = resolve?.("template", ref2);
15826
+ } catch {
15827
+ text2 = null;
15828
+ }
15829
+ if (typeof text2 !== "string") {
15830
+ note(`The style template "${ref2}" is not in the file, so items that use its styles have the default style.`);
15831
+ continue;
15832
+ }
15833
+ let doc;
15834
+ try {
15835
+ doc = parseXml(text2);
15836
+ } catch (e2) {
15837
+ note(`The style template "${ref2}" could not be read (${e2 instanceof Error ? e2.message : e2}), so its styles are missing.`);
15838
+ continue;
15839
+ }
15840
+ if (doc.name !== "jasperTemplate") {
15841
+ note(`The style template "${ref2}" is not a JasperReports template (its root is <${doc.name}>), so its styles are missing.`);
15842
+ continue;
15843
+ }
15844
+ for (const s of kids(doc, "style")) if (s.attrs.name && !styles.has(s.attrs.name)) styles.set(s.attrs.name, s);
15845
+ if (depth < 8) templates(doc, depth + 1);
15846
+ }
15847
+ })(root, 0);
15848
+ const defStyle = [...styles.values()].find((s) => s.attrs.isDefault === "true" || s.attrs.default === "true");
15760
15849
  function styleAttrs(name, seen = 0) {
15761
15850
  const s = styles.get(name);
15762
15851
  if (!s || seen > 10) return {};
@@ -15910,7 +15999,7 @@ function toRdlx2(root, notes, charts, reportName) {
15910
15999
  }
15911
16000
  function item(n5, c) {
15912
16001
  const a = n5.a, re = n5.re, e2 = n5.el;
15913
- const base = { Name: nameFor(n5, n5.kind), Left: pt(a.x), Top: pt(a.y), Width: pt(a.width), Height: pt(a.height) };
16002
+ const base = { __pos: e2.pos, Name: nameFor(n5, n5.kind), Left: pt(a.x), Top: pt(a.y), Width: pt(a.width), Height: pt(a.height) };
15914
16003
  const it = { ...base };
15915
16004
  const st = { ...defStyle ? styleAttrs(defStyle.attrs.name) : {}, ...a.style ? styleAttrs(a.style) : {}, ...stripUndef(normAttrs(re.attrs === e2.attrs ? e2.attrs : { ...re.attrs, ...e2.attrs, ...n5.te?.attrs || {}, ...kid(n5.te, "font")?.attrs || {} })), ...boxAttrs(kid(e2, "box")) };
15916
16005
  if (a.style && !styles.has(a.style)) (it.__notes ||= []).push(`its style "${a.style}" is not in the file (a style template?), so it has the default style.`);
@@ -16371,9 +16460,9 @@ function toRdlx2(root, notes, charts, reportName) {
16371
16460
  DataSources.push({ Name: srcName, ConnectionProperties: { DataProvider: "SQL", ConnectString: "" } });
16372
16461
  } else if (xpath) {
16373
16462
  set.Query.CommandText = q3?.text.trim() || "";
16374
- const at2 = String(root.children.find((c) => c.name === "property" && c.attrs.name === "net.sf.jasperreports.xml.source")?.attrs.value || "").trim();
16375
- if (!at2) note(`Data set "${name}": JasperReports gets its XML from Java code; set the XML source's URL in ReportWright.`);
16376
- DataSources.push({ Name: srcName, ConnectionProperties: { DataProvider: "XML", ConnectString: at2 ? `XmlDoc=${at2}` : "" } });
16463
+ const at3 = String(root.children.find((c) => c.name === "property" && c.attrs.name === "net.sf.jasperreports.xml.source")?.attrs.value || "").trim();
16464
+ if (!at3) note(`Data set "${name}": JasperReports gets its XML from Java code; set the XML source's URL in ReportWright.`);
16465
+ DataSources.push({ Name: srcName, ConnectionProperties: { DataProvider: "XML", ConnectString: at3 ? `XmlDoc=${at3}` : "" } });
16377
16466
  } else {
16378
16467
  if (q3 && q3.text.trim()) note(`Data set "${name}": its ${q3.attrs.language || "query"} query is not converted; point the data source at the data (JSON or CSV) and set its path.`);
16379
16468
  else note(`Data set "${name}": JasperReports gets its rows from Java code (a data source); point the ReportWright data source at the data.`);
@@ -16513,19 +16602,19 @@ function importBirt(input, opts = {}) {
16513
16602
  const r = importRdlx(ar, { name });
16514
16603
  if (r.error) return r;
16515
16604
  const warnings = [...notes, ...r.warnings].map((w) => w.replace(/ActiveReports/g, "BIRT"));
16516
- const walk = (items) => {
16605
+ const walk2 = (items) => {
16517
16606
  for (const i of items || []) {
16518
16607
  if (i.type === "table" && PAGE_BREAKS.get(i.name) > 0) i.pageBreakEvery = PAGE_BREAKS.get(i.name);
16519
- walk(i.items);
16608
+ walk2(i.items);
16520
16609
  }
16521
16610
  };
16522
- for (const sec of [r.definition.sections?.body].flat()) walk(sec?.items);
16611
+ for (const sec of [r.definition.sections?.body].flat()) walk2(sec?.items);
16523
16612
  PAGE_BREAKS.clear();
16524
16613
  r.definition.collation = "ordinal";
16525
16614
  r.definition.nullOrder = "low";
16526
16615
  r.definition.arithmetic = "double";
16527
16616
  r.definition.bandRows = "first-last";
16528
- return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats };
16617
+ return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats, items: rewordItems(r.items, (w) => w.replace(/ActiveReports/g, "BIRT")) };
16529
16618
  }
16530
16619
  function toRdlx3(root, notes, reportName) {
16531
16620
  const kid = (e2, n5) => e2?.children.find((c) => c.name === n5);
@@ -16739,6 +16828,7 @@ function toRdlx3(root, notes, reportName) {
16739
16828
  return "=" + vb2(s, c);
16740
16829
  } catch (e2) {
16741
16830
  if (!(e2 instanceof Untranslatable2)) throw e2;
16831
+ (item2.__exprs ||= []).push(s);
16742
16832
  (item2.__notes ||= []).push(`${e2.message} has no ReportWright equivalent, so the expression ${s.length > 200 ? s.slice(0, 200) + "…" : s} is shown as text.`);
16743
16833
  return s.startsWith("=") ? `="${s.replace(/"/g, '""')}"` : s;
16744
16834
  }
@@ -16748,6 +16838,7 @@ function toRdlx3(root, notes, reportName) {
16748
16838
  return "=" + vb2(src, c);
16749
16839
  } catch (e2) {
16750
16840
  if (!(e2 instanceof Untranslatable2)) throw e2;
16841
+ (item2.__exprs ||= []).push(String(src));
16751
16842
  (item2.__notes ||= []).push(`${what} uses ${e2.message}, which has no ReportWright equivalent, so it is left out.`);
16752
16843
  return void 0;
16753
16844
  }
@@ -16829,8 +16920,8 @@ function toRdlx3(root, notes, reportName) {
16829
16920
  function rdlxStyle(st, item2, c, opt = {}) {
16830
16921
  const o = {};
16831
16922
  if (st.fontFamily) o.FontFamily = genericFont(st.fontFamily);
16832
- const fs2 = fontPt(st.fontSize);
16833
- if (fs2) o.FontSize = pt(fs2);
16923
+ const fs3 = fontPt(st.fontSize);
16924
+ if (fs3) o.FontSize = pt(fs3);
16834
16925
  if (st.fontWeight && /bold|[6-9]00/.test(st.fontWeight)) o.FontWeight = "Bold";
16835
16926
  if (st.fontStyle === "italic" || st.fontStyle === "oblique") o.FontStyle = "Italic";
16836
16927
  if (st.textUnderline === "underline") o.TextDecoration = "Underline";
@@ -16889,18 +16980,18 @@ function toRdlx3(root, notes, reportName) {
16889
16980
  const nameFor = (e2, kind) => e2.attrs.name && NAME_OK.test(e2.attrs.name) ? e2.attrs.name : `${kind}${++seq}`;
16890
16981
  const ITEM_KINDS = /* @__PURE__ */ new Set(["label", "data", "text", "text-data", "auto-text", "image", "grid", "table", "list", "extended-item", "line", "free-form", "template-report-item", "multi-line-data"]);
16891
16982
  const textH = (text2, st) => {
16892
- const fs2 = fontPt(st.fontSize) || 10;
16893
- return Math.max(1, String(text2 || "").split("\n").length) * fs2 * 1.25 + 2;
16983
+ const fs3 = fontPt(st.fontSize) || 10;
16984
+ return Math.max(1, String(text2 || "").split("\n").length) * fs3 * 1.25 + 2;
16894
16985
  };
16895
16986
  function htmlParts(html) {
16896
16987
  const parts = [];
16897
16988
  const re = /<value-of[^>]*>([\s\S]*?)<\/value-of>/gi;
16898
- let at2 = 0, m2;
16989
+ let at3 = 0, m2;
16899
16990
  while (m2 = re.exec(html)) {
16900
- parts.push({ t: html.slice(at2, m2.index) }, { e: m2[1] });
16901
- at2 = re.lastIndex;
16991
+ parts.push({ t: html.slice(at3, m2.index) }, { e: m2[1] });
16992
+ at3 = re.lastIndex;
16902
16993
  }
16903
- parts.push({ t: html.slice(at2) });
16994
+ parts.push({ t: html.slice(at3) });
16904
16995
  const out = parts.map((p) => p.t == null ? p : { t: decodeHtml(p.t, false) });
16905
16996
  if (out[0].t != null) out[0].t = out[0].t.trimStart();
16906
16997
  const last = out[out.length - 1];
@@ -16928,7 +17019,7 @@ function toRdlx3(root, notes, reportName) {
16928
17019
  const w = Math.min(W2, len(prop(e2, "width"), W2, W2)) || W2;
16929
17020
  const given = len(prop(e2, "height"), 0, 0);
16930
17021
  const x = len(prop(e2, "x"), W2, 0);
16931
- const it = { Name: nameFor(e2, e2.name.replace(/(^|-)(\w)/g, (_, __, ch) => ch.toUpperCase())), Left: pt(x), Width: pt(w) };
17022
+ const it = { __pos: e2.pos, Name: nameFor(e2, e2.name.replace(/(^|-)(\w)/g, (_, __, ch) => ch.toUpperCase())), Left: pt(x), Width: pt(w) };
16932
17023
  const vis = listProp(e2, "visibility")[0];
16933
17024
  if (vis) {
16934
17025
  const ve = prop(vis, "valueExpr");
@@ -16986,6 +17077,7 @@ function toRdlx3(root, notes, reportName) {
16986
17077
  v = "=" + binding(b, c, 0);
16987
17078
  } catch (er) {
16988
17079
  if (!(er instanceof Untranslatable2)) throw er;
17080
+ (it.__exprs ||= []).push(String(prop(b, "expression") ?? col3));
16989
17081
  (it.__notes ||= []).push(`its column "${col3}" uses ${er.message}, so it is shown as text.`);
16990
17082
  v = col3;
16991
17083
  }
@@ -17014,6 +17106,7 @@ function toRdlx3(root, notes, reportName) {
17014
17106
  pieces.push(`(${vb2(decodeHtml(p.e), c)})`);
17015
17107
  } catch (er) {
17016
17108
  if (!(er instanceof Untranslatable2)) throw er;
17109
+ (it.__exprs ||= []).push(decodeHtml(p.e));
17017
17110
  (it.__notes ||= []).push(`a <value-of> uses ${er.message}, so it is left out.`);
17018
17111
  }
17019
17112
  }
@@ -17440,9 +17533,337 @@ var init_importers = __esm({
17440
17533
  }
17441
17534
  });
17442
17535
 
17443
- // bin/pw.mjs
17536
+ // src/importers/batch.js
17537
+ var batch_exports = {};
17538
+ __export(batch_exports, {
17539
+ BATCH_LIMITS: () => BATCH_LIMITS,
17540
+ MANIFEST: () => MANIFEST,
17541
+ exitCode: () => exitCode,
17542
+ importFolder: () => importFolder,
17543
+ reportHtml: () => reportHtml
17544
+ });
17444
17545
  import fs from "node:fs";
17445
17546
  import path from "node:path";
17547
+ import crypto2 from "node:crypto";
17548
+ function walk(root, o) {
17549
+ const files = [];
17550
+ const refused = [];
17551
+ let capped2 = false;
17552
+ const visit = (dir, rel2) => {
17553
+ for (const ent of fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : 1)) {
17554
+ if (capped2) return;
17555
+ const r = join(rel2, ent.name), abs = path.join(dir, ent.name);
17556
+ let real = abs, st;
17557
+ try {
17558
+ if (ent.isSymbolicLink()) {
17559
+ real = fs.realpathSync(abs);
17560
+ if (!inside(root, real)) {
17561
+ refused.push({ path: r, reason: "a symbolic link to outside the input folder: not followed" });
17562
+ continue;
17563
+ }
17564
+ st = fs.statSync(real);
17565
+ if (st.isDirectory()) {
17566
+ refused.push({ path: r, reason: "a symbolic link to a folder: not followed" });
17567
+ continue;
17568
+ }
17569
+ } else st = fs.statSync(abs);
17570
+ } catch (e2) {
17571
+ refused.push({ path: r, reason: `cannot be read (${e2 instanceof Error ? e2.message : e2})` });
17572
+ continue;
17573
+ }
17574
+ if (st.isDirectory()) {
17575
+ if (o.recursive && real !== o.skip) visit(abs, r);
17576
+ continue;
17577
+ }
17578
+ if (!st.isFile() || !(REPORT.test(r) || IMAGE.test(r) || RESOURCE.test(r))) continue;
17579
+ if (files.length >= o.maxFiles) {
17580
+ capped2 = true;
17581
+ refused.push({ path: r, reason: `more than ${o.maxFiles} files: this one and the rest are not imported (--max-files)` });
17582
+ return;
17583
+ }
17584
+ files.push({ rel: r, abs: real, size: st.size });
17585
+ }
17586
+ };
17587
+ visit(root, "");
17588
+ return { files, refused };
17589
+ }
17590
+ function positions(text2) {
17591
+ let starts = null;
17592
+ return (pos) => {
17593
+ if (typeof pos !== "number") return {};
17594
+ starts ||= [0, ...[...text2.matchAll(/\n/g)].map((m) => (
17595
+ /** @type {number} */
17596
+ m.index + 1
17597
+ ))];
17598
+ let lo = 0, hi = starts.length - 1;
17599
+ while (lo < hi) {
17600
+ const mid = lo + hi + 1 >> 1;
17601
+ if (starts[mid] <= pos) lo = mid;
17602
+ else hi = mid - 1;
17603
+ }
17604
+ return { line: lo + 1, column: pos - starts[lo] + 1 };
17605
+ };
17606
+ }
17607
+ function* objects(o, depth = 0) {
17608
+ if (!o || typeof o !== "object" || depth > 200) return;
17609
+ yield o;
17610
+ for (const v of Array.isArray(o) ? o : Object.values(o)) if (v && typeof v === "object") yield* objects(v, depth + 1);
17611
+ }
17612
+ async function importFolder(input, output, opts = {}) {
17613
+ const maxFiles = opts.maxFiles ?? BATCH_LIMITS.maxFiles, maxBytes = opts.maxBytes ?? BATCH_LIMITS.maxBytes;
17614
+ const log = opts.log || (() => {
17615
+ });
17616
+ const inRoot = fs.realpathSync(input);
17617
+ if (!fs.statSync(inRoot).isDirectory()) throw new Error(`${input} is not a folder`);
17618
+ fs.mkdirSync(output, { recursive: true });
17619
+ const outRoot = fs.realpathSync(output);
17620
+ const { files, refused } = walk(inRoot, { recursive: opts.recursive, maxFiles, skip: outRoot });
17621
+ let old = {};
17622
+ try {
17623
+ const m = JSON.parse(fs.readFileSync(path.join(outRoot, MANIFEST), "utf8"));
17624
+ if (m && typeof m.files === "object") old = m.files;
17625
+ } catch {
17626
+ }
17627
+ const manifest = {};
17628
+ for (const [k, v] of Object.entries(old)) if (typeof v === "string" && /^[0-9a-f]{64}$/.test(v)) manifest[k] = v;
17629
+ function writeTarget(rel2, bytes) {
17630
+ const abs = path.resolve(outRoot, ...rel2.split("/"));
17631
+ if (!inside(outRoot, abs) || abs === outRoot) throw new Error(`the output path ${rel2} is outside the output folder`);
17632
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
17633
+ if (!inside(outRoot, fs.realpathSync(path.dirname(abs)))) throw new Error(`the output folder of ${rel2} is a link to outside the output folder`);
17634
+ const h = sha2(bytes);
17635
+ let st = null;
17636
+ try {
17637
+ st = fs.lstatSync(abs);
17638
+ } catch {
17639
+ }
17640
+ if (st && !st.isFile()) throw new Error(`${rel2} is in the output folder and is not a plain file (a link or a folder): not overwritten`);
17641
+ let previous2, cur;
17642
+ if (st) {
17643
+ previous2 = fs.readFileSync(abs);
17644
+ cur = sha2(previous2);
17645
+ if (cur === h) {
17646
+ manifest[rel2] = h;
17647
+ return { write: "unchanged", previous: previous2 };
17648
+ }
17649
+ if (cur !== old[rel2] && !opts.force) return { write: "skipped-edited", previous: previous2 };
17650
+ }
17651
+ const tmp = path.join(path.dirname(abs), `.${path.basename(abs)}.${process.pid}.tmp`);
17652
+ fs.rmSync(tmp, { force: true });
17653
+ fs.writeFileSync(tmp, bytes, { flag: "wx" });
17654
+ fs.renameSync(tmp, abs);
17655
+ manifest[rel2] = h;
17656
+ return { write: !st ? "written" : cur !== old[rel2] ? "overwritten" : "refreshed", previous: previous2 };
17657
+ }
17658
+ const byRel = new Map(files.map((f4) => [f4.rel, f4]));
17659
+ function find(test, ref2, fromDir) {
17660
+ const r = String(ref2 ?? "").trim().replace(/\\/g, "/").replace(/^file:(\/\/)?/i, "");
17661
+ if (!r || /^[a-z][a-z0-9+.-]*:/i.test(r) && !/^[a-z]:\//i.test(r)) return null;
17662
+ if (!r.startsWith("/") && !/^[a-z]:\//i.test(r)) {
17663
+ const rel2 = path.posix.normalize(join(fromDir, r));
17664
+ const hit = !rel2.startsWith("../") && byRel.get(rel2);
17665
+ if (hit && test.test(hit.rel)) return hit;
17666
+ }
17667
+ const base = r.split("/").pop()?.toLowerCase();
17668
+ const cands = files.filter((f4) => test.test(f4.rel) && (path.posix.basename(f4.rel).toLowerCase() === base || stemOf(f4.rel).toLowerCase() === base));
17669
+ return cands.find((f4) => dirOf(f4.rel) === fromDir) || cands[0] || null;
17670
+ }
17671
+ const readText = (f4) => {
17672
+ if (f4.size > maxBytes) throw new Error(`${f4.rel} is larger than ${maxBytes} bytes`);
17673
+ return fs.readFileSync(f4.abs, "utf8");
17674
+ };
17675
+ const reports = files.filter((f4) => REPORT.test(f4.rel));
17676
+ const taken = /* @__PURE__ */ new Set();
17677
+ const outOf = new Map(reports.map((f4) => {
17678
+ const dir = dirOf(f4.rel);
17679
+ let id = reportId(path.posix.basename(f4.rel));
17680
+ if (taken.has(join(dir, id))) id = `${id}-${extOf(f4.rel)}`.slice(0, 64);
17681
+ for (let k = 2; taken.has(join(dir, id)); k++) id = `${reportId(path.posix.basename(f4.rel))}-${k}`;
17682
+ taken.add(join(dir, id));
17683
+ return [f4.rel, { dir, id, rel: join(dir, `${id}.pw.json`) }];
17684
+ }));
17685
+ const images = /* @__PURE__ */ new Map();
17686
+ const results = [];
17687
+ for (const f4 of reports) {
17688
+ const o = (
17689
+ /** @type {{ dir: string, id: string, rel: string }} */
17690
+ outOf.get(f4.rel)
17691
+ );
17692
+ const rec = { source: f4.rel, format: FORMAT[extOf(f4.rel)], output: o.rel, status: "failed", stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, items: [], expressions: [], notes: [], references: [] };
17693
+ results.push(rec);
17694
+ try {
17695
+ const text2 = readText(f4);
17696
+ const at3 = positions(text2);
17697
+ const resolve = (kind, ref2) => {
17698
+ const hit = find(kind === "datasource" ? /\.rds$/i : /\.jrtx$/i, ref2, o.dir);
17699
+ rec.references.push({ kind: kind === "datasource" ? "shared data source" : "style template", ref: ref2, resolved: hit ? hit.rel : null });
17700
+ return hit ? readText(hit) : null;
17701
+ };
17702
+ const name = stemOf(f4.rel);
17703
+ const r = extOf(f4.rel) === "rdlx-json" ? importRdlx(JSON.parse(text2.replace(/^/, "")), { name }) : importXmlReport(text2, { name, resolve });
17704
+ if (r.error) throw new Error(r.error);
17705
+ const def = r.definition;
17706
+ rec.stats = r.stats;
17707
+ const itemLines = /* @__PURE__ */ new Set();
17708
+ for (const it of r.items || []) {
17709
+ const p = at3(it.pos);
17710
+ rec.items.push({ name: it.name, state: it.state, ...p, notes: it.notes });
17711
+ for (const n6 of it.notes) itemLines.add(`${it.name}: ${n6.message}`);
17712
+ for (const e2 of it.exprs) rec.expressions.push({ item: it.name, expression: e2, ...p });
17713
+ }
17714
+ rec.notes = r.warnings.filter((w2) => !itemLines.has(w2));
17715
+ for (const s of objects(def)) {
17716
+ if (s.type !== "subreport" || typeof s.report !== "string") continue;
17717
+ const hits = reports.filter((x) => outOf.get(x.rel)?.id === s.report);
17718
+ const hit = hits.find((x) => dirOf(x.rel) === o.dir) || hits[0];
17719
+ const where = hit && /** @type {any} */
17720
+ outOf.get(hit.rel).rel;
17721
+ rec.references.push({
17722
+ kind: "subreport",
17723
+ ref: s.report,
17724
+ resolved: hit ? hit.rel : null,
17725
+ ...hit ? { output: where } : {},
17726
+ ...hit && dirOf(hit.rel) !== o.dir ? { note: `it is imported to ${where}, another folder: pw render finds a subreport next to its report (the server by its id)` } : {}
17727
+ });
17728
+ }
17729
+ for (const im of objects(def)) {
17730
+ if (im.type !== "image" || typeof im.src !== "string" || !im.src || im.src.startsWith("=") || /^(https?:|data:|embedded:)/i.test(im.src)) continue;
17731
+ const hit = find(IMAGE, im.src, dirOf(f4.rel));
17732
+ if (!hit) {
17733
+ rec.references.push({ kind: "image", ref: im.src, resolved: null });
17734
+ continue;
17735
+ }
17736
+ if (hit.size > maxBytes) {
17737
+ rec.references.push({ kind: "image", ref: im.src, resolved: null, note: `${hit.rel} is larger than ${maxBytes} bytes` });
17738
+ continue;
17739
+ }
17740
+ const bytes = fs.readFileSync(hit.abs), h = sha2(bytes);
17741
+ let copy = images.get(h);
17742
+ if (!copy) {
17743
+ const base = path.posix.basename(hit.rel);
17744
+ copy = join(o.dir, base);
17745
+ if ([...images.values()].includes(copy)) copy = join(o.dir, `${stemOf(base)}-${h.slice(0, 8)}${path.posix.extname(base)}`);
17746
+ const w2 = writeTarget(copy, bytes);
17747
+ if (w2.write === "skipped-edited") rec.notes.push(`The image ${copy} in the output folder was changed since the last import, so it was not replaced (--force replaces it).`);
17748
+ images.set(h, copy);
17749
+ }
17750
+ rec.references.push({ kind: "image", ref: im.src, resolved: hit.rel, output: copy });
17751
+ im.src = path.posix.relative(o.dir, copy);
17752
+ }
17753
+ if (extOf(f4.rel) === "rptdesign") {
17754
+ const libs = /<list-property\s+name="libraries">([\s\S]*?)<\/list-property>/.exec(text2)?.[1] || "";
17755
+ for (const m of libs.matchAll(/<property\s+name="fileName">([^<]{1,500})<\/property>/g)) {
17756
+ const hit = find(/\.rptlibrary$/i, m[1], o.dir);
17757
+ rec.references.push({ kind: "BIRT library", ref: m[1], resolved: hit ? hit.rel : null, note: "the BIRT importer does not read libraries: items from it are missing" });
17758
+ }
17759
+ }
17760
+ const w = writeTarget(o.rel, JSON.stringify(def, null, 2) + "\n");
17761
+ rec.status = "imported";
17762
+ rec.write = w.write;
17763
+ if (w.write === "skipped-edited") rec.notes.unshift(`${o.rel} was changed since the last import, so it was not overwritten (--force overwrites it).`);
17764
+ log(`${f4.rel} → ${o.rel}: ${w.write}${rec.references.some((x) => !x.resolved) ? `, ${rec.references.filter((x) => !x.resolved).length} unresolved` : ""}`);
17765
+ if (opts.verify) {
17766
+ let baseline = null, onDisk = def;
17767
+ try {
17768
+ if (w.write === "skipped-edited") onDisk = JSON.parse(fs.readFileSync(path.join(outRoot, ...o.rel.split("/")), "utf8"));
17769
+ else if (w.previous && w.write !== "unchanged") baseline = JSON.parse(w.previous.toString("utf8"));
17770
+ } catch {
17771
+ }
17772
+ try {
17773
+ rec.verify = await opts.verify({ file: path.join(outRoot, ...o.rel.split("/")), definition: onDisk, baseline });
17774
+ } catch (e2) {
17775
+ rec.verify = { status: "failed", error: e2 instanceof Error ? e2.message : String(e2) };
17776
+ }
17777
+ }
17778
+ } catch (e2) {
17779
+ rec.status = "failed";
17780
+ rec.error = e2 instanceof Error ? e2.message : String(e2);
17781
+ log(`${f4.rel}: FAILED: ${rec.error}`);
17782
+ }
17783
+ }
17784
+ fs.writeFileSync(path.join(outRoot, MANIFEST), JSON.stringify({ version: 1, note: "pw import: the hash of each file as written; a file whose hash differs was edited and is not overwritten without --force", files: manifest }, null, 2) + "\n");
17785
+ const n5 = (s) => results.filter((r) => r.status === s).length;
17786
+ return {
17787
+ tool: "pw import",
17788
+ schema: 1,
17789
+ created: (/* @__PURE__ */ new Date()).toISOString(),
17790
+ input: inRoot,
17791
+ output: outRoot,
17792
+ options: { recursive: !!opts.recursive, force: !!opts.force, verify: !!opts.verify, maxFiles, maxBytes },
17793
+ summary: {
17794
+ reports: results.length,
17795
+ imported: n5("imported"),
17796
+ failed: n5("failed"),
17797
+ refused: refused.length,
17798
+ images: images.size,
17799
+ skippedEdited: results.filter((r) => r.write === "skipped-edited").length,
17800
+ unresolved: results.reduce((k, r) => k + r.references.filter((x) => !x.resolved).length, 0)
17801
+ },
17802
+ files: results,
17803
+ refused
17804
+ };
17805
+ }
17806
+ function reportHtml(r) {
17807
+ const s = r.summary;
17808
+ const verifyCell = (v) => !v ? "" : `<span class="v-${esc8(v.status)}">${esc8(v.status)}</span>`;
17809
+ const rows = r.files.map((f4, i) => `<tr class="${f4.status}"><td><a href="#f${i}">${esc8(f4.source)}</a></td><td>${esc8(f4.format)}</td><td>${esc8(f4.status)}${f4.write ? ` · ${esc8(f4.write)}` : ""}</td><td class="n">${f4.stats.mapped}</td><td class="n">${f4.stats.approximated}</td><td class="n">${f4.stats.dropped}</td><td class="n">${f4.expressions.length}</td><td class="n">${f4.references.filter(
17810
+ (x) => !x.resolved).length}</td><td>${verifyCell(f4.verify)}</td></tr>`).join("\n");
17811
+ const detail = r.files.map((f4, i) => {
17812
+ const items = f4.items.filter((it) => it.notes.length);
17813
+ return `<section id="f${i}"><h2>${esc8(f4.source)} <small>${esc8(f4.format)} → ${esc8(f4.output)}</small></h2>` + (f4.error ? `<p class="err">Failed: ${esc8(f4.error)}</p>` : "") + (f4.references.length ? `<h3>References</h3><table><tr><th>Kind</th><th>Name</th><th>Resolved to</th><th>Note</th></tr>${f4.references.map((x) => `<tr class="${x.resolved ? "" : "failed"}"><td>${esc8(x.kind)}</td>${
17814
+ ""}<td><code>${esc8(x.ref)}</code></td><td>${x.resolved ? esc8(x.resolved) + (x.output ? ` → ${esc8(x.output)}` : "") : "<b>unresolved</b>"}</td><td>${esc8(x.note)}</td></tr>`).join("")}</table>` : "") + (f4.expressions.length ? `<h3>Expressions not translated</h3><table><tr><th>Line:col</th><th>Item</th><th>Expression</th></tr>${f4.expressions.map((e2) => `<tr><td>${esc8(at2(e2))}</td><td>${esc8(e2.
17815
+ item)}</td><td><code>${esc8(e2.expression)}</code></td></tr>`).join("")}</table>` : "") + (items.length ? `<h3>Items</h3><table><tr><th>Line:col</th><th>Item</th><th>Status</th><th>Why</th></tr>${items.map((it) => `<tr class="${esc8(it.state)}"><td>${esc8(at2(it))}</td><td>${esc8(it.name)}</td><td>${esc8(it.state)}</td><td><ul>${it.notes.map((n5) => `<li class="${esc8(n5.kind)}">${esc8(n5.message)}${
17816
+ ""}</li>`).join("")}</ul></td></tr>`).join("")}</table>` : "") + (f4.notes.length ? `<h3>Report notes</h3><ul>${f4.notes.map((n5) => `<li>${esc8(n5)}</li>`).join("")}</ul>` : "") + (f4.verify ? `<h3>Verify</h3><p>${verifyCell(f4.verify)} ${esc8(f4.verify.note || f4.verify.error || "")}${f4.verify.pages != null ? ` (${f4.verify.pages} pages)` : ""}</p>${f4.verify.diff?.length ? `<pre>${esc8(f4.verify.
17817
+ diff.join("\n"))}</pre>` : ""}` : "") + "</section>";
17818
+ }).join("\n");
17819
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
17820
+ <title>Import report</title><style>
17821
+ :root{color-scheme:light dark;--bg:#fff;--fg:#1d2025;--mute:#636a74;--line:#dfe2e6;--bad:#b42318;--warn:#9a6700;--ok:#1a7f37;--head:#f4f5f7}
17822
+ @media (prefers-color-scheme:dark){:root{--bg:#16181c;--fg:#e6e8eb;--mute:#9aa1ab;--line:#30343a;--bad:#ff7b72;--warn:#d29922;--ok:#3fb950;--head:#1f2228}}
17823
+ body{margin:0;padding:16px 24px;background:var(--bg);color:var(--fg);font:14px/1.45 system-ui,sans-serif}
17824
+ h1{font-size:20px;margin:0 0 4px}h2{font-size:16px;margin:28px 0 6px;border-top:1px solid var(--line);padding-top:14px;overflow-wrap:anywhere}h2 small{color:var(--mute);font-weight:400}h3{font-size:14px;margin:14px 0 4px}
17825
+ p.meta{color:var(--mute);margin:0 0 12px;overflow-wrap:anywhere}
17826
+ table{border-collapse:collapse;width:100%;margin:4px 0}th,td{border-bottom:1px solid var(--line);padding:4px 8px;text-align:left;vertical-align:top;overflow-wrap:anywhere}
17827
+ th{background:var(--head);font-weight:600}td.n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
17828
+ tr.failed td:first-child,.err,li.dropped,.v-failed,.v-changed{color:var(--bad)}tr.dropped td,li.approximated{color:var(--warn)}.v-ok{color:var(--ok)}
17829
+ code,pre{font:12px/1.4 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere}ul{margin:0;padding-left:18px}
17830
+ .cards{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0 16px}.cards div{border:1px solid var(--line);border-radius:6px;padding:6px 12px}.cards b{display:block;font-size:18px}
17831
+ </style></head><body><h1>Import report</h1>
17832
+ <p class="meta">${esc8(r.input)} → ${esc8(r.output)} · ${esc8(r.created)}</p>
17833
+ <div class="cards"><div><b>${s.reports}</b>reports</div><div><b>${s.imported}</b>imported</div><div><b>${s.failed}</b>failed</div><div><b>${s.unresolved}</b>unresolved references</div><div><b>${s.images}</b>images copied</div><div><b>${s.skippedEdited}</b>kept (edited)</div><div><b>${s.refused}</b>refused</div></div>
17834
+ <table><tr><th>File</th><th>Format</th><th>Status</th><th>Mapped</th><th>Approximated</th><th>Dropped</th><th>Expressions not translated</th><th>Unresolved</th><th>Verify</th></tr>
17835
+ ${rows}</table>
17836
+ ${r.refused.length ? `<h2>Refused</h2><ul>${r.refused.map((x) => `<li><code>${esc8(x.path)}</code>: ${esc8(x.reason)}</li>`).join("")}</ul>` : ""}
17837
+ ${detail}
17838
+ </body></html>
17839
+ `;
17840
+ }
17841
+ var BATCH_LIMITS, MANIFEST, REPORT, IMAGE, RESOURCE, FORMAT, sha2, inside, extOf, stemOf, dirOf, join, exitCode, esc8, at2;
17842
+ var init_batch = __esm({
17843
+ "src/importers/batch.js"() {
17844
+ init_importers();
17845
+ init_rdlx();
17846
+ BATCH_LIMITS = { maxFiles: 2e3, maxBytes: 16 * 1024 * 1024 };
17847
+ MANIFEST = ".pw-import.json";
17848
+ REPORT = /\.(rdlc?|jrxml|rptdesign|rdlx-json)$/i;
17849
+ IMAGE = /\.(png|jpe?g|gif|svg|bmp|webp)$/i;
17850
+ RESOURCE = /\.(rds|jrtx|rptlibrary)$/i;
17851
+ FORMAT = { rdl: "SSRS", rdlc: "SSRS", jrxml: "JasperReports", rptdesign: "BIRT", "rdlx-json": "ActiveReports" };
17852
+ sha2 = (b) => crypto2.createHash("sha256").update(b).digest("hex");
17853
+ inside = (root, p) => p === root || p.startsWith(root + path.sep);
17854
+ extOf = (f4) => /\.rdlx-json$/i.test(f4) ? "rdlx-json" : path.extname(f4).slice(1).toLowerCase();
17855
+ stemOf = (f4) => path.basename(f4).replace(/\.rdlx-json$/i, "").replace(/\.[^.]+$/, "");
17856
+ dirOf = (rel2) => path.posix.dirname(rel2) === "." ? "" : path.posix.dirname(rel2);
17857
+ join = (dir, f4) => dir ? `${dir}/${f4}` : f4;
17858
+ exitCode = (report) => !report.summary.imported ? 1 : report.summary.failed ? 2 : 0;
17859
+ esc8 = (s) => String(s ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[c]);
17860
+ at2 = (o) => o.line ? `${o.line}:${o.column}` : "";
17861
+ }
17862
+ });
17863
+
17864
+ // bin/pw.mjs
17865
+ import fs2 from "node:fs";
17866
+ import path2 from "node:path";
17446
17867
  import { createRequire } from "node:module";
17447
17868
  import { parseArgs } from "node:util";
17448
17869
 
@@ -17807,10 +18228,10 @@ var TextMeasurer = class {
17807
18228
  wrapComplex(para2, key, size, maxWidth, dir, sp, out) {
17808
18229
  const tokens = [];
17809
18230
  const sa = SA.test(para2) ? saBreaks(para2) : null;
17810
- let cur = "", space = false, prev = "", at2 = 0;
18231
+ let cur = "", space = false, prev = "", at3 = 0;
17811
18232
  for (const ch of para2) {
17812
- const i = at2;
17813
- at2 += ch.length;
18233
+ const i = at3;
18234
+ at3 += ch.length;
17814
18235
  if (ch === " ") {
17815
18236
  if (cur) {
17816
18237
  tokens.push({ text: cur, space });
@@ -18961,7 +19382,7 @@ function paintRound(type, g) {
18961
19382
  return paintPie(type, g);
18962
19383
  }
18963
19384
  function paintPie(type, g) {
18964
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, bold, text: text2, measure, fmtV, pointFill, pointLink, pal, label, labelText, anim } = g;
19385
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, bold, text: text2, measure, fmtV, pointFill, pointLink, pal, label, labelText, anim } = g;
18965
19386
  const vals = (data.series[0]?.values || []).map((v) => Math.max(0, v || 0));
18966
19387
  const total = vals.reduce((a, b) => a + b, 0) || 1;
18967
19388
  const showL = item.showValues !== false;
@@ -18990,7 +19411,7 @@ function paintPie(type, g) {
18990
19411
  lw[0] *= k;
18991
19412
  lw[1] *= k;
18992
19413
  }
18993
- r = Math.max(4, Math.min((W2 - lw[0] - lw[1] - gap * 2) / 2, (bottom - top) / 2 - fs2));
19414
+ r = Math.max(4, Math.min((W2 - lw[0] - lw[1] - gap * 2) / 2, (bottom - top) / 2 - fs3));
18994
19415
  const slack = W2 - lw[0] - lw[1] - gap * 2 - r * 2;
18995
19416
  cx = X + gap + lw[0] + r + slack / 2;
18996
19417
  } else r = Math.max(4, Math.min(W2, bottom - top) / 2 - 6);
@@ -19010,16 +19431,16 @@ function paintPie(type, g) {
19010
19431
  else if (!outside && frac >= 0.05 && showL) {
19011
19432
  const s = item.labelTemplate ? labelText(i, data.series[0], v, frac) : pctOf(v);
19012
19433
  const lr = ri ? (r + ri) / 2 : r * 0.62;
19013
- label(s, cx + Math.cos(mid) * lr, cy + Math.sin(mid) * lr + fs2 * 0.35, { color: inkOn(fill3), f: bold, size: fs2 });
19434
+ label(s, cx + Math.cos(mid) * lr, cy + Math.sin(mid) * lr + fs3 * 0.35, { color: inkOn(fill3), f: bold, size: fs3 });
19014
19435
  }
19015
19436
  a0 = a1;
19016
19437
  });
19017
- if (outside) placeOutside(sides, { cx, cy, r, lw, lh: fs2 * 1.3, lo: top + fs2 * 0.9, hi: bottom - fs2 * 0.4, out, text: text2, texts, fs: fs2, ink: g.ink });
19438
+ if (outside) placeOutside(sides, { cx, cy, r, lw, lh: fs3 * 1.3, lo: top + fs3 * 0.9, hi: bottom - fs3 * 0.4, out, text: text2, texts, fs: fs3, ink: g.ink });
19018
19439
  if (type === "donut" && item.centerText !== false) {
19019
- text2(fmtV(total), cx, cy + fs2 * 0.45, { align: "center", size: fs2 * 1.4, f: bold, color: "#111827" });
19440
+ text2(fmtV(total), cx, cy + fs3 * 0.45, { align: "center", size: fs3 * 1.4, f: bold, color: "#111827" });
19020
19441
  }
19021
19442
  }
19022
- function placeOutside(sides, { cx, cy, r, lw, lh, lo, hi, out, text: text2, texts, fs: fs2, ink }) {
19443
+ function placeOutside(sides, { cx, cy, r, lw, lh, lo, hi, out, text: text2, texts, fs: fs3, ink }) {
19023
19444
  sides.forEach((list2, right) => {
19024
19445
  const room = Math.max(1, Math.floor((hi - lo) / lh) + 1);
19025
19446
  if (list2.length > room) {
@@ -19044,16 +19465,16 @@ function placeOutside(sides, { cx, cy, r, lw, lh, lo, hi, out, text: text2, text
19044
19465
  const ex2 = cx + c * (r + 8), ey = cy + s * (r + 8);
19045
19466
  const kx = cx + dir * (r + 12);
19046
19467
  out.push({ t: "path", x: 0, y: 0, d: `M ${f(cx + c * r)} ${f(cy + s * r)} L ${f(ex2)} ${f(ey)} L ${f(kx)} ${f(l.y)}`, fill: null, stroke: "#9ca3af", strokeWidth: 0.6 });
19047
- text2(texts[l.i], kx + dir * 3, l.y + fs2 * 0.35, { align: right ? "left" : "right", maxW: Math.max(fs2, lw[right] + 1), color: ink });
19468
+ text2(texts[l.i], kx + dir * 3, l.y + fs3 * 0.35, { align: right ? "left" : "right", maxW: Math.max(fs3, lw[right] + 1), color: ink });
19048
19469
  }
19049
19470
  });
19050
19471
  }
19051
19472
  function paintRadar(g) {
19052
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, text: text2, measure, fmtV, pointLink, label, labelsOn, labelText, grid, anim, axes } = g;
19473
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, text: text2, measure, fmtV, pointLink, label, labelsOn, labelText, grid, anim, axes } = g;
19053
19474
  const n5 = data.categories.length;
19054
19475
  const catW = Math.min(W2 * 0.25, data.categories.reduce((m, c) => Math.max(m, measure(c).w), 10));
19055
- const cx = X + W2 / 2, cy = (top + bottom) / 2 + fs2 * 0.3;
19056
- const R2 = Math.max(6, Math.min(W2 / 2 - catW - 8, (bottom - top) / 2 - fs2 * 1.6));
19476
+ const cx = X + W2 / 2, cy = (top + bottom) / 2 + fs3 * 0.3;
19477
+ const R2 = Math.max(6, Math.min(W2 / 2 - catW - 8, (bottom - top) / 2 - fs3 * 1.6));
19057
19478
  let lo = 0, hi = 0;
19058
19479
  for (const s of data.series) for (const v of s.values) if (v != null) {
19059
19480
  lo = Math.min(lo, v);
@@ -19065,34 +19486,34 @@ function paintRadar(g) {
19065
19486
  const ticks = linearTicks(a, b, sc.step);
19066
19487
  const rad = (v) => Math.max(0, Math.min(1, (v - a) / (b - a || 1))) * R2;
19067
19488
  const ang = (i) => -Math.PI / 2 + i / Math.max(1, n5) * Math.PI * 2;
19068
- const at2 = (i, r) => ({ x: cx + Math.cos(ang(i)) * r, y: cy + Math.sin(ang(i)) * r });
19069
- const poly = (r) => Array.from({ length: n5 }, (_, i) => at2(i, r)).map((p, i) => `${i ? "L" : "M"} ${f(p.x)} ${f(p.y)}`).join(" ") + " Z";
19489
+ const at3 = (i, r) => ({ x: cx + Math.cos(ang(i)) * r, y: cy + Math.sin(ang(i)) * r });
19490
+ const poly = (r) => Array.from({ length: n5 }, (_, i) => at3(i, r)).map((p, i) => `${i ? "L" : "M"} ${f(p.x)} ${f(p.y)}`).join(" ") + " Z";
19070
19491
  if (ys.gridlines !== false) {
19071
19492
  for (const t of ticks) if (rad(t) > 0) out.push({ t: "path", x: 0, y: 0, d: n5 > 2 ? poly(rad(t)) : "", fill: null, stroke: grid, strokeWidth: 0.5 });
19072
19493
  }
19073
19494
  for (let i = 0; i < n5; i++) {
19074
- const e2 = at2(i, R2);
19495
+ const e2 = at3(i, R2);
19075
19496
  out.push({ t: "line", x1: cx, y1: cy, x2: e2.x, y2: e2.y, stroke: grid, strokeWidth: 0.5 });
19076
19497
  }
19077
- for (const t of ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtV(t), cx + 3, cy - rad(t) + fs2 * 0.3, { size: fs2 * 0.8, color: "#6b7280" });
19498
+ for (const t of ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtV(t), cx + 3, cy - rad(t) + fs3 * 0.3, { size: fs3 * 0.8, color: "#6b7280" });
19078
19499
  data.categories.forEach((c, i) => {
19079
- const p = at2(i, R2 + 4), cos = Math.cos(ang(i));
19080
- text2(c, p.x, p.y + fs2 * 0.35 + (Math.sin(ang(i)) > 0.5 ? fs2 * 0.5 : 0), { align: Math.abs(cos) < 0.2 ? "center" : cos > 0 ? "left" : "right", maxW: catW });
19500
+ const p = at3(i, R2 + 4), cos = Math.cos(ang(i));
19501
+ text2(c, p.x, p.y + fs3 * 0.35 + (Math.sin(ang(i)) > 0.5 ? fs3 * 0.5 : 0), { align: Math.abs(cos) < 0.2 ? "center" : cos > 0 ? "left" : "right", maxW: catW });
19081
19502
  });
19082
19503
  data.series.forEach((s, si) => {
19083
- const pts2 = s.values.map((v, i) => v == null ? null : { ...at2(i, rad(v)), v, i }).filter(Boolean);
19504
+ const pts2 = s.values.map((v, i) => v == null ? null : { ...at3(i, rad(v)), v, i }).filter(Boolean);
19084
19505
  if (!pts2.length) return;
19085
19506
  const d = pts2.map((p, i) => `${i ? "L" : "M"} ${f(p.x)} ${f(p.y)}`).join(" ") + " Z";
19086
19507
  out.push(tag({ t: "path", x: 0, y: 0, d, fill: s.color + (s.def.type === "line" ? "00" : "2e"), stroke: s.color, strokeWidth: 1.4 }, anim && { k: anim === "grow" ? "scale" : "fade", i: si }));
19087
19508
  if (n5 <= 40) for (const p of pts2) out.push({ t: "ellipse", cx: p.x, cy: p.y, rx: 1.8, ry: 1.8, fill: s.color, stroke: null });
19088
19509
  for (const p of pts2) pointLink(p.i, { x: p.x - 4, y: p.y - 4, w: 8, h: 8 }, `${data.categories[p.i]}${data.series.length > 1 ? ` · ${s.name}` : ""}: ${fmtV(p.v)}`);
19089
- if (labelsOn || item.labelTemplate) for (const p of pts2) label(labelText(p.i, s, p.v), p.x, p.y - 3, { size: fs2 * 0.85 });
19510
+ if (labelsOn || item.labelTemplate) for (const p of pts2) label(labelText(p.i, s, p.v), p.x, p.y - 3, { size: fs3 * 0.85 });
19090
19511
  });
19091
19512
  }
19092
19513
  var GAUGE_SHAPES = { half: [Math.PI, Math.PI], threeQuarter: [Math.PI * 0.75, Math.PI * 1.5], full: [-Math.PI / 2, Math.PI * 2] };
19093
19514
  var GAUGE_INDICATORS = ["needle", "pointer", "bar"];
19094
19515
  function paintGauge(g) {
19095
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, bold, text: text2, fmtV, pointLink, axes, lc, who, safe: safe3, ctx } = g;
19516
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, bold, text: text2, fmtV, pointLink, axes, lc, who, safe: safe3, ctx } = g;
19096
19517
  const v = data.series[0]?.values?.[0] ?? null;
19097
19518
  const ys = axes.y || {};
19098
19519
  const num6 = (x) => x == null || x === "" ? null : Number.isFinite(Number(x)) ? Number(x) : null;
@@ -19111,14 +19532,14 @@ function paintGauge(g) {
19111
19532
  R2 = Math.max(8, Math.min(W2 / 2 - 8, H / 2 - 4));
19112
19533
  cy = (top + bottom) / 2;
19113
19534
  } else if (shape2 === "threeQuarter") {
19114
- R2 = Math.max(8, Math.min(W2 / 2 - 8, (H - fs2 * 1.4 - 4) / (1 + Math.SQRT1_2)));
19535
+ R2 = Math.max(8, Math.min(W2 / 2 - 8, (H - fs3 * 1.4 - 4) / (1 + Math.SQRT1_2)));
19115
19536
  cy = top + 4 + R2;
19116
19537
  } else {
19117
- R2 = Math.max(8, Math.min(W2 / 2 - 8, H - fs2 * 3.6));
19538
+ R2 = Math.max(8, Math.min(W2 / 2 - 8, H - fs3 * 3.6));
19118
19539
  cy = top + 4 + R2;
19119
19540
  }
19120
19541
  const th = R2 * 0.22;
19121
- const at2 = (a2, rad) => ({ x: cx + Math.cos(a2) * rad, y: cy + Math.sin(a2) * rad });
19542
+ const at3 = (a2, rad) => ({ x: cx + Math.cos(a2) * rad, y: cy + Math.sin(a2) * rad });
19122
19543
  const scope = { ...ctx, fields: data.rows[0] || null, aggRows: data.rows, aggIndex: void 0 };
19123
19544
  const val = (o, k) => typeof o[k] === "number" ? o[k] : num6(safe3(o[k], scope, lc, who));
19124
19545
  const overlays = (Array.isArray(item.overlays) ? item.overlays : []).slice(0, 20).filter((o) => o && typeof o === "object");
@@ -19139,55 +19560,55 @@ function paintGauge(g) {
19139
19560
  for (const o of overlays) if (o.type === "line") {
19140
19561
  const t = val(o, "value");
19141
19562
  if (t == null) continue;
19142
- const a2 = ang(t), p1 = at2(a2, R2 - th - 2), p2 = at2(a2, R2 + 2);
19563
+ const a2 = ang(t), p1 = at3(a2, R2 - th - 2), p2 = at3(a2, R2 + 2);
19143
19564
  out.push({ t: "line", x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y, stroke: o.color || "#111827", strokeWidth: 1.5 });
19144
19565
  }
19145
19566
  const sc = niceScale(lo, hi, shape2 === "half" ? 5 : 7);
19146
19567
  const ticks = linearTicks(Math.ceil(lo / sc.step - 1e-9) * sc.step, hi, sc.step).filter((t) => t >= lo - 1e-9 && t <= hi + 1e-9);
19147
- const tickOn = item.gaugeTicks !== false && R2 >= fs2 * 5 && ticks.length > 1;
19568
+ const tickOn = item.gaugeTicks !== false && R2 >= fs3 * 5 && ticks.length > 1;
19148
19569
  if (tickOn) {
19149
19570
  const ri = R2 - th - 1;
19150
19571
  const minor = sc.step / 5;
19151
19572
  for (let t = ticks[0] - sc.step, k = 0; t <= hi + 1e-9 && k < 200; t += minor, k++) {
19152
19573
  if (t < lo - 1e-9) continue;
19153
19574
  const isMajor = ticks.some((m) => Math.abs(m - t) < minor / 2);
19154
- const a2 = ang(t), p1 = at2(a2, ri), p2 = at2(a2, ri - th * (isMajor ? 0.4 : 0.2));
19575
+ const a2 = ang(t), p1 = at3(a2, ri), p2 = at3(a2, ri - th * (isMajor ? 0.4 : 0.2));
19155
19576
  out.push({ t: "line", x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y, stroke: isMajor ? "#6b7280" : "#9ca3af", strokeWidth: isMajor ? 0.9 : 0.5 });
19156
19577
  }
19157
- const lr = ri - th * 0.4 - fs2 * 1.1;
19578
+ const lr = ri - th * 0.4 - fs3 * 1.1;
19158
19579
  ticks.forEach((t, k) => {
19159
19580
  if (shape2 === "full" && k === ticks.length - 1 && Math.abs(frac(t) - 1) < 1e-9) return;
19160
- const p = at2(ang(t), lr);
19161
- text2(fmtV(t), p.x, p.y + fs2 * 0.3, { align: "center", size: fs2 * 0.8, color: "#6b7280" });
19581
+ const p = at3(ang(t), lr);
19582
+ text2(fmtV(t), p.x, p.y + fs3 * 0.3, { align: "center", size: fs3 * 0.8, color: "#6b7280" });
19162
19583
  });
19163
19584
  } else if (shape2 !== "full") {
19164
- const e0 = at2(start, R2 - th / 2), e1 = at2(start + sweep2, R2 - th / 2);
19165
- text2(fmtV(lo), e0.x, e0.y + fs2 * 1.3, { align: "center", color: "#6b7280" });
19166
- text2(fmtV(hi), e1.x, e1.y + fs2 * 1.3, { align: "center", color: "#6b7280" });
19585
+ const e0 = at3(start, R2 - th / 2), e1 = at3(start + sweep2, R2 - th / 2);
19586
+ text2(fmtV(lo), e0.x, e0.y + fs3 * 1.3, { align: "center", color: "#6b7280" });
19587
+ text2(fmtV(hi), e1.x, e1.y + fs3 * 1.3, { align: "center", color: "#6b7280" });
19167
19588
  }
19168
- const vy = shape2 === "half" ? cy + fs2 * 2.6 : cy + R2 * 0.5 + fs2 * 0.6;
19589
+ const vy = shape2 === "half" ? cy + fs3 * 2.6 : cy + R2 * 0.5 + fs3 * 0.6;
19169
19590
  if (v == null) {
19170
- text2("No data", cx, shape2 === "half" ? cy - R2 / 3 : cy + fs2 * 0.35, { align: "center", color: "#9ca3af" });
19591
+ text2("No data", cx, shape2 === "half" ? cy - R2 / 3 : cy + fs3 * 0.35, { align: "center", color: "#9ca3af" });
19171
19592
  return;
19172
19593
  }
19173
19594
  const a = ang(v), ink = typeof item.pointerColor === "string" && /^#[0-9a-f]{6}$/i.test(item.pointerColor) ? item.pointerColor : "#1f2937";
19174
19595
  if (indicator2 === "needle") {
19175
19596
  const len = R2 - th * 0.4, bw = Math.max(1.5, R2 * 0.03);
19176
- const tip = at2(a, len), n1 = at2(a + Math.PI / 2, bw), n22 = at2(a - Math.PI / 2, bw);
19597
+ const tip = at3(a, len), n1 = at3(a + Math.PI / 2, bw), n22 = at3(a - Math.PI / 2, bw);
19177
19598
  const d = `M ${f(n1.x)} ${f(n1.y)} L ${f(tip.x)} ${f(tip.y)} L ${f(n22.x)} ${f(n22.y)} Z`;
19178
19599
  out.push(tag({ t: "path", x: 0, y: 0, d, fill: ink, stroke: null }, g.anim && { k: "fade", i: 0 }));
19179
19600
  out.push({ t: "ellipse", cx, cy, rx: bw * 1.4, ry: bw * 1.4, fill: ink, stroke: null });
19180
19601
  } else if (indicator2 === "pointer") {
19181
- const tip = at2(a, R2 - th * 0.85), half = Math.max(0.05, Math.min(0.2, th * 0.55 / Math.max(1, R2 - th)));
19182
- const b1 = at2(a - half, R2 - th * 1.7), b2 = at2(a + half, R2 - th * 1.7);
19602
+ const tip = at3(a, R2 - th * 0.85), half = Math.max(0.05, Math.min(0.2, th * 0.55 / Math.max(1, R2 - th)));
19603
+ const b1 = at3(a - half, R2 - th * 1.7), b2 = at3(a + half, R2 - th * 1.7);
19183
19604
  const d = `M ${f(b1.x)} ${f(b1.y)} L ${f(tip.x)} ${f(tip.y)} L ${f(b2.x)} ${f(b2.y)} Z`;
19184
19605
  out.push(tag({ t: "path", x: 0, y: 0, d, fill: ink, stroke: "#ffffff", strokeWidth: 0.6 }, g.anim && { k: "fade", i: 0 }));
19185
19606
  }
19186
- text2(item.labelTemplate ? g.labelText(0, data.series[0], v) : fmtV(v), cx, indicator2 === "needle" || shape2 === "half" ? vy : cy + fs2 * 0.55, { align: "center", size: fs2 * 1.6, f: bold, color: "#111827" });
19607
+ text2(item.labelTemplate ? g.labelText(0, data.series[0], v) : fmtV(v), cx, indicator2 === "needle" || shape2 === "half" ? vy : cy + fs3 * 0.55, { align: "center", size: fs3 * 1.6, f: bold, color: "#111827" });
19187
19608
  pointLink(0, { x: cx - R2, y: cy - R2, w: R2 * 2, h: shape2 === "half" ? R2 : R2 * 2 }, `${data.series[0]?.name || "Value"}: ${fmtV(v)}`);
19188
19609
  }
19189
19610
  function paintFunnel(g) {
19190
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, text: text2, measure, fmtV, pointFill, pointLink, pal, labelText, anim } = g;
19611
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, text: text2, measure, fmtV, pointFill, pointLink, pal, labelText, anim } = g;
19191
19612
  const vals = (data.series[0]?.values || []).map((v) => Math.max(0, v || 0));
19192
19613
  const n5 = vals.length;
19193
19614
  let max = 0;
@@ -19197,9 +19618,9 @@ function paintFunnel(g) {
19197
19618
  return;
19198
19619
  }
19199
19620
  const gap = n5 > 1 ? Math.min(2, (bottom - top) / n5 / 4) : 0;
19200
- const sh = (bottom - top - fs2 * 0.6 - gap * (n5 - 1)) / n5;
19621
+ const sh = (bottom - top - fs3 * 0.6 - gap * (n5 - 1)) / n5;
19201
19622
  const maxW = W2 * 0.62, cx = X + W2 * 0.36;
19202
- let y = top + fs2 * 0.6;
19623
+ let y = top + fs3 * 0.6;
19203
19624
  const total = vals.reduce((a, b) => a + b, 0) || 1;
19204
19625
  vals.forEach((v, i) => {
19205
19626
  const tw = Math.max(2, maxW * v / max), bw = Math.max(2, i < n5 - 1 ? maxW * vals[i + 1] / max : tw * 0.6);
@@ -19209,7 +19630,7 @@ function paintFunnel(g) {
19209
19630
  pointLink(i, { x: cx - tw / 2, y, w: tw, h: sh }, `${data.categories[i]}: ${fmtV(v)} (${Math.round(v / total * 100)}%)`, d);
19210
19631
  if (item.showValues !== false) {
19211
19632
  const s = item.labelTemplate ? labelText(i, data.series[0], v, v / total) : `${data.categories[i]}: ${fmtV(v)}`;
19212
- const sz = Math.min(fs2, sh * 0.7);
19633
+ const sz = Math.min(fs3, sh * 0.7);
19213
19634
  const { w } = measure(s, { size: sz });
19214
19635
  const narrow = Math.min(tw, bw);
19215
19636
  if (w + 6 < narrow) text2(s, cx, y + sh / 2 + sz * 0.35, { align: "center", size: sz, color: inkOn(fill3) });
@@ -19270,32 +19691,32 @@ function capRows(g, rows) {
19270
19691
  }
19271
19692
  var noData = (g) => g.text("No data", g.X + g.W / 2, (g.top + g.bottom) / 2, { align: "center", color: "#9ca3af" });
19272
19693
  function frame(g, lo, hi, fmt2, { cats = null, catW = 0 } = {}) {
19273
- const { item, lc, X, W: W2, top, bottom, fs: fs2, text: text2, out, axes, who, grid } = g;
19694
+ const { item, lc, X, W: W2, top, bottom, fs: fs3, text: text2, out, axes, who, grid } = g;
19274
19695
  const ys = axes.y || {};
19275
- const plotTop = top + fs2 * 0.6;
19696
+ const plotTop = top + fs3 * 0.6;
19276
19697
  const xTitle = axes.x?.title || item.xTitle, yTitle = ys.title;
19277
- const plotBottom = bottom - fs2 * 1.8 - (xTitle ? fs2 * 1.6 : 0);
19278
- const ay = g.valueAxis(ys, lo, hi, Infinity, { includeZero: true, len: plotBottom - plotTop, fs: fs2, fmt: fmt2, lc, who, name: "y" });
19279
- const valW = Math.max(10, ...ay.ticks.map((t) => lc.m.width(ay.fmt(t), g.font, fs2)));
19280
- const left = X + 4 + (yTitle ? fs2 * 1.6 : 0) + valW + 6, right = X + W2 - 6;
19698
+ const plotBottom = bottom - fs3 * 1.8 - (xTitle ? fs3 * 1.6 : 0);
19699
+ const ay = g.valueAxis(ys, lo, hi, Infinity, { includeZero: true, len: plotBottom - plotTop, fs: fs3, fmt: fmt2, lc, who, name: "y" });
19700
+ const valW = Math.max(10, ...ay.ticks.map((t) => lc.m.width(ay.fmt(t), g.font, fs3)));
19701
+ const left = X + 4 + (yTitle ? fs3 * 1.6 : 0) + valW + 6, right = X + W2 - 6;
19281
19702
  const vy = (v) => {
19282
19703
  const fr = Math.max(0, Math.min(1, ay.frac(v) ?? 0));
19283
19704
  return ys.reversed ? plotTop + fr * (plotBottom - plotTop) : plotBottom - fr * (plotBottom - plotTop);
19284
19705
  };
19285
19706
  for (const t of ay.ticks) {
19286
19707
  if (ys.gridlines !== false) out.push({ t: "line", x1: left, y1: vy(t), x2: right, y2: vy(t), stroke: grid, strokeWidth: 0.5 });
19287
- text2(ay.fmt(t), left - 5, vy(t) + fs2 * 0.35, { align: "right" });
19708
+ text2(ay.fmt(t), left - 5, vy(t) + fs3 * 0.35, { align: "right" });
19288
19709
  }
19289
19710
  if (xTitle) text2(xTitle, (left + right) / 2, bottom - 2, { align: "center", color: "#6b7280" });
19290
19711
  if (yTitle) {
19291
19712
  const my = (plotTop + plotBottom) / 2;
19292
- text2(yTitle, X + 4 + fs2, my, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs2, cy: my } });
19713
+ text2(yTitle, X + 4 + fs3, my, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs3, cy: my } });
19293
19714
  }
19294
19715
  const band = (right - left) / Math.max(1, cats ? cats.length : 1);
19295
19716
  if (cats) {
19296
19717
  const every = Math.max(1, Math.ceil((catW + 6) / band));
19297
19718
  cats.forEach((c, i) => {
19298
- if (i % every === 0) text2(c, left + band * (i + 0.5), plotBottom + fs2 * 1.35, { align: "center", maxW: band * every - 2 });
19719
+ if (i % every === 0) text2(c, left + band * (i + 0.5), plotBottom + fs3 * 1.35, { align: "center", maxW: band * every - 2 });
19299
19720
  });
19300
19721
  }
19301
19722
  return { left, right, plotTop, plotBottom, vy, band, ay };
@@ -19348,7 +19769,7 @@ function squarify(items, x, y, w, h) {
19348
19769
  return out;
19349
19770
  }
19350
19771
  function paintTreemap(g) {
19351
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, pal, pointFill, pointLink, fmtV, lc, who, anim } = g;
19772
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, pal, pointFill, pointLink, fmtV, lc, who, anim } = g;
19352
19773
  const s = data.series[0];
19353
19774
  const items = [];
19354
19775
  let dropped = 0;
@@ -19366,10 +19787,10 @@ function paintTreemap(g) {
19366
19787
  out.push({ t: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill: fill3, stroke: "#ffffff", strokeWidth: 1, ...anim ? { anim: { k: "fade", i: r.i } } : {} });
19367
19788
  const v = s.values[r.i];
19368
19789
  pointLink(r.i, { x: r.x, y: r.y, w: r.w, h: r.h }, `${data.categories[r.i]}: ${fmtV(v)} (${Math.round(v / total * 100)}%)`);
19369
- if (r.w > fs2 * 3 && r.h > fs2 * 1.6) {
19790
+ if (r.w > fs3 * 3 && r.h > fs3 * 1.6) {
19370
19791
  const ink = inkOn(fill3);
19371
- g.text(data.categories[r.i], r.x + 4, r.y + fs2 * 1.3, { color: ink, maxW: r.w - 8, f: g.bold });
19372
- if (r.h > fs2 * 3 && item.showValues !== false) g.text(g.labelText(r.i, s, v, v / total), r.x + 4, r.y + fs2 * 2.5, { color: ink, maxW: r.w - 8, size: fs2 * 0.9 });
19792
+ g.text(data.categories[r.i], r.x + 4, r.y + fs3 * 1.3, { color: ink, maxW: r.w - 8, f: g.bold });
19793
+ if (r.h > fs3 * 3 && item.showValues !== false) g.text(g.labelText(r.i, s, v, v / total), r.x + 4, r.y + fs3 * 2.5, { color: ink, maxW: r.w - 8, size: fs3 * 0.9 });
19373
19794
  }
19374
19795
  }
19375
19796
  }
@@ -19406,7 +19827,7 @@ function binValues(vals, { binCount, binWidth } = {}) {
19406
19827
  return { lo, hi: lo + width * n5, width, counts, capped: capped2 };
19407
19828
  }
19408
19829
  function paintHistogram(g) {
19409
- const { item, data, out, fs: fs2, lc, who, ctx, pal, axes, anim } = g;
19830
+ const { item, data, out, fs: fs3, lc, who, ctx, pal, axes, anim } = g;
19410
19831
  const s = data.series[0];
19411
19832
  const rows = capRows(g, data.rows);
19412
19833
  const vals = rowValues(g, s?.def?.value || "=0", rows).filter((v) => v != null);
@@ -19422,11 +19843,11 @@ function paintHistogram(g) {
19422
19843
  const x = f4.left + i * bw, y = f4.vy(c), base = f4.vy(0);
19423
19844
  if (c > 0) out.push({ t: "rect", x: x + 0.5, y, w: Math.max(0.5, bw - 1), h: base - y, fill: color2, ...anim ? { anim: { k: anim === "grow" ? "growY" : "fade", o: "bottom", i } } : {} });
19424
19845
  if (item.tooltips !== false) g.links.push({ t: "link", x, y: f4.plotTop, w: bw, h: f4.plotBottom - f4.plotTop, action: null, tip: `${fmtX(b.lo + i * b.width)} – ${fmtX(b.lo + (i + 1) * b.width)}: ${c}` });
19425
- if (g.labelsOn && c > 0) g.label(String(c), x + bw / 2, y - 3, { size: fs2 * 0.85 });
19846
+ if (g.labelsOn && c > 0) g.label(String(c), x + bw / 2, y - 3, { size: fs3 * 0.85 });
19426
19847
  });
19427
19848
  const edgeW = Math.max(...[b.lo, b.hi].map((v) => g.measure(fmtX(v)).w));
19428
19849
  const every = Math.max(1, Math.ceil((edgeW + 6) / bw));
19429
- for (let i = 0; i <= n5; i += every) g.text(fmtX(b.lo + i * b.width), f4.left + i * bw, f4.plotBottom + fs2 * 1.35, { align: "center" });
19850
+ for (let i = 0; i <= n5; i += every) g.text(fmtX(b.lo + i * b.width), f4.left + i * bw, f4.plotBottom + fs3 * 1.35, { align: "center" });
19430
19851
  out.push({ t: "line", x1: f4.left, y1: f4.plotBottom, x2: f4.right, y2: f4.plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 });
19431
19852
  }
19432
19853
  function boxStats(sorted) {
@@ -19451,7 +19872,7 @@ function boxStats(sorted) {
19451
19872
  return { min: sorted[0], max: sorted[n5 - 1], q1, med, q3: q32, lo, hi, outliers, mean: sum / n5, n: n5 };
19452
19873
  }
19453
19874
  function paintBoxPlot(g) {
19454
- const { item, data, out, fs: fs2, pal, lc, who, pointFill, pointLink, fmtV, ctx } = g;
19875
+ const { item, data, out, fs: fs3, pal, lc, who, pointFill, pointLink, fmtV, ctx } = g;
19455
19876
  const s = data.series[0];
19456
19877
  let budget = CAPS.points;
19457
19878
  const stats = data.buckets.map((bk) => {
@@ -19495,13 +19916,13 @@ function paintBoxPlot(g) {
19495
19916
  out.push({ t: "ellipse", cx, cy: f4.vy(v), rx: 2, ry: 2, fill: null, stroke: color2, strokeWidth: 0.9 });
19496
19917
  }
19497
19918
  pointLink(i, { x: cx - f4.band / 2, y: f4.plotTop, w: f4.band, h: f4.plotBottom - f4.plotTop }, `${data.categories[i]}: min ${fmtV(st.lo)}, Q1 ${fmtV(st.q1)}, median ${fmtV(st.med)}, Q3 ${fmtV(st.q3)}, max ${fmtV(st.hi)}${st.outliers.length ? `, ${st.outliers.length} outliers` : ""} (n ${st.n})`);
19498
- if (g.labelsOn) g.label(fmtV(st.med), cx + bw / 2 + 3, f4.vy(st.med) + fs2 * 0.3, { align: "left", size: fs2 * 0.85 });
19919
+ if (g.labelsOn) g.label(fmtV(st.med), cx + bw / 2 + 3, f4.vy(st.med) + fs3 * 0.3, { align: "left", size: fs3 * 0.85 });
19499
19920
  });
19500
19921
  if (cut) lc.warn(`${who}: more than ${MORE_CAPS.outliers} outliers; the rest are not drawn`);
19501
19922
  out.push({ t: "line", x1: f4.left, y1: f4.plotBottom, x2: f4.right, y2: f4.plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 });
19502
19923
  }
19503
19924
  function paintWaterfall(g) {
19504
- const { item, data, out, fs: fs2, ctx, lc, who, pointLink, fmtV, anim } = g;
19925
+ const { item, data, out, fs: fs3, ctx, lc, who, pointLink, fmtV, anim } = g;
19505
19926
  const s = data.series[0];
19506
19927
  const up = item.upColor || "#16a34a", down = item.downColor || "#dc2626", tot = item.totalColor || "#2563eb";
19507
19928
  const isTotal = (i) => {
@@ -19547,7 +19968,7 @@ function paintWaterfall(g) {
19547
19968
  const tip = `${b.label}: ${b.kind === "total" ? fmtV(b.v) : `${b.v >= 0 ? "+" : ""}${fmtV(b.v)} → ${fmtV(b.b)}`}`;
19548
19969
  if (b.i >= 0) pointLink(b.i, rect, tip);
19549
19970
  else if (item.tooltips !== false) g.links.push({ t: "link", ...rect, action: null, tip });
19550
- if (g.labelsOn) g.label(b.kind === "total" ? fmtV(b.v) : `${b.v >= 0 ? "+" : ""}${fmtV(b.v)}`, cx, Math.min(y0, y1) - 3, { size: fs2 * 0.85, alt: { y: Math.max(y0, y1) + fs2, color: g.ink } });
19971
+ if (g.labelsOn) g.label(b.kind === "total" ? fmtV(b.v) : `${b.v >= 0 ? "+" : ""}${fmtV(b.v)}`, cx, Math.min(y0, y1) - 3, { size: fs3 * 0.85, alt: { y: Math.max(y0, y1) + fs3, color: g.ink } });
19551
19972
  });
19552
19973
  out.push({ t: "line", x1: f4.left, y1: f4.vy(0), x2: f4.right, y2: f4.vy(0), stroke: "#9ca3af", strokeWidth: 0.75 });
19553
19974
  }
@@ -19611,7 +20032,7 @@ function step2(d, n5, u) {
19611
20032
  else d.setUTCFullYear(d.getUTCFullYear() + n5);
19612
20033
  }
19613
20034
  function paintGantt(g) {
19614
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, ctx, lc, who, pal, pointFill, pointLink, axes, grid, text: text2, anim } = g;
20035
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, ctx, lc, who, pal, pointFill, pointLink, axes, grid, text: text2, anim } = g;
19615
20036
  const cats = data.categories;
19616
20037
  if (!item.ganttStart || !item.ganttEnd) {
19617
20038
  text2("Set the start and end of the bars", X + W2 / 2, (top + bottom) / 2, { align: "center", color: "#9ca3af" });
@@ -19671,18 +20092,18 @@ function paintGantt(g) {
19671
20092
  }
19672
20093
  const catW = Math.min(cats.reduce((m, s) => Math.max(m, g.measure(s).w), 10), W2 * 0.32);
19673
20094
  const plotLeft = X + 4 + catW + 6, plotRight = X + W2 - 6;
19674
- const plotTop = top + fs2 * 0.6, plotBottom = bottom - fs2 * 1.8 - (xs.title ? fs2 * 1.6 : 0);
20095
+ const plotTop = top + fs3 * 0.6, plotBottom = bottom - fs3 * 1.8 - (xs.title ? fs3 * 1.6 : 0);
19675
20096
  const px = (t) => plotLeft + (t - lo) / (hi - lo) * (plotRight - plotLeft);
19676
20097
  for (const t of ticks) {
19677
20098
  if (t < lo || t > hi) continue;
19678
20099
  if (xs.gridlines !== false) out.push({ t: "line", x1: px(t), y1: plotTop, x2: px(t), y2: plotBottom, stroke: grid, strokeWidth: 0.5 });
19679
- text2(fmtT(t), px(t), plotBottom + fs2 * 1.35, { align: "center" });
20100
+ text2(fmtT(t), px(t), plotBottom + fs3 * 1.35, { align: "center" });
19680
20101
  }
19681
20102
  if (xs.title) text2(xs.title, (plotLeft + plotRight) / 2, bottom - 2, { align: "center", color: "#6b7280" });
19682
20103
  const lane = (plotBottom - plotTop) / Math.max(1, cats.length);
19683
- const every = Math.max(1, Math.ceil(fs2 * 1.2 / lane));
20104
+ const every = Math.max(1, Math.ceil(fs3 * 1.2 / lane));
19684
20105
  cats.forEach((s, i) => {
19685
- if (i % every === 0) text2(s, plotLeft - 5, plotTop + lane * (i + 0.5) + fs2 * 0.35, { align: "right", maxW: catW });
20106
+ if (i % every === 0) text2(s, plotLeft - 5, plotTop + lane * (i + 0.5) + fs3 * 0.35, { align: "right", maxW: catW });
19686
20107
  });
19687
20108
  const bh = Math.max(1, Math.min(lane * 0.62, 22));
19688
20109
  bars.forEach((b, k) => {
@@ -19691,13 +20112,13 @@ function paintGantt(g) {
19691
20112
  const fill3 = groups.keyOf.get(b.r)?.color || pointFill(b.ci, pal[0]);
19692
20113
  out.push({ t: "rect", x: x0, y, w: Math.max(1, x1 - x0), h: bh, fill: fill3, radius: Math.min(2, bh / 4), ...anim ? { anim: { k: anim === "grow" ? "growX" : "fade", o: "left", i: k } } : {} });
19693
20114
  pointLink(b.ci, { x: x0, y, w: Math.max(4, x1 - x0), h: bh }, `${cats[b.ci]}: ${fmtT(b.a)} – ${fmtT(b.b)}`);
19694
- if (g.labelsOn) g.label(cats[b.ci], x1 + 3, y + bh / 2 + fs2 * 0.3, { align: "left", size: fs2 * 0.85 });
20115
+ if (g.labelsOn) g.label(cats[b.ci], x1 + 3, y + bh / 2 + fs3 * 0.3, { align: "left", size: fs3 * 0.85 });
19695
20116
  });
19696
20117
  out.push({ t: "line", x1: plotLeft, y1: plotBottom, x2: plotRight, y2: plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 });
19697
20118
  if (today != null && today >= lo && today <= hi) {
19698
20119
  const tx = px(today);
19699
20120
  out.push({ t: "line", x1: tx, y1: plotTop, x2: tx, y2: plotBottom, stroke: item.todayColor || "#dc2626", strokeWidth: 1, dash: [3, 2] });
19700
- text2("Today", tx + 2, plotTop + fs2 * 0.9, { color: item.todayColor || "#dc2626", size: fs2 * 0.85 });
20121
+ text2("Today", tx + 2, plotTop + fs3 * 0.9, { color: item.todayColor || "#dc2626", size: fs3 * 0.85 });
19701
20122
  }
19702
20123
  }
19703
20124
 
@@ -19829,18 +20250,18 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19829
20250
  const m = lc.m;
19830
20251
  const font = resolveFontKey(base.fontFamily, "normal", "normal");
19831
20252
  const bold = resolveFontKey(base.fontFamily, "bold", "normal");
19832
- const fs2 = Math.max(6, Number(item.fontSize) || 7.5);
20253
+ const fs3 = Math.max(6, Number(item.fontSize) || 7.5);
19833
20254
  const ink = item.textColor || "#374151";
19834
20255
  const grid = "#e5e7eb";
19835
20256
  const X = item.x, W2 = item.w, H = item.h;
19836
20257
  const who = item.name || "Chart";
19837
20258
  const out = [];
19838
- const measure = (s, { size = fs2, f: fk2 = font, maxW = 9999 } = {}) => {
20259
+ const measure = (s, { size = fs3, f: fk2 = font, maxW = 9999 } = {}) => {
19839
20260
  let str = String(s).slice(0, 200);
19840
20261
  if (m.width(str, fk2, size) > maxW) str = m.ellipsize(str, fk2, size, maxW);
19841
20262
  return { str, w: m.width(str, fk2, size) };
19842
20263
  };
19843
- const text2 = (s, x, y, { size = fs2, f: fk2 = font, color: color2 = ink, align = "left", maxW = 9999, rotate = null } = {}) => {
20264
+ const text2 = (s, x, y, { size = fs3, f: fk2 = font, color: color2 = ink, align = "left", maxW = 9999, rotate = null } = {}) => {
19844
20265
  const { str, w } = measure(s, { size, f: fk2, maxW });
19845
20266
  const lx = align === "right" ? x - w : align === "center" ? x - w / 2 : x;
19846
20267
  const t = { t: "text", font: fk2, size, color: color2, lines: [{ x: lx, y, text: str, w }] };
@@ -19878,19 +20299,19 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19878
20299
  let top = 4, bottom = H - 4;
19879
20300
  const title2 = item.title ? String(safe2(item.title, ctx, lc, who) ?? "") : "";
19880
20301
  if (title2) {
19881
- const tw = W2 - 8, full = fs2 * 1.35, s = String(title2).slice(0, 200);
19882
- const fit = m.width(s, bold, full) <= tw ? full : Math.max(fs2, Math.floor(full * tw / m.width(s, bold, full) * 10) / 10);
20302
+ const tw = W2 - 8, full = fs3 * 1.35, s = String(title2).slice(0, 200);
20303
+ const fit = m.width(s, bold, full) <= tw ? full : Math.max(fs3, Math.floor(full * tw / m.width(s, bold, full) * 10) / 10);
19883
20304
  if (m.width(s, bold, fit) <= tw) {
19884
- text2(s, X + 4, top + fs2 * 1.4, { size: fit, f: bold, color: "#111827", maxW: tw });
19885
- top += fs2 * 2.1;
20305
+ text2(s, X + 4, top + fs3 * 1.4, { size: fit, f: bold, color: "#111827", maxW: tw });
20306
+ top += fs3 * 2.1;
19886
20307
  } else {
19887
20308
  const words = s.split(/\s+/);
19888
20309
  let first = "";
19889
- while (words.length && m.width(first ? `${first} ${words[0]}` : words[0], bold, fs2) <= tw) first = first ? `${first} ${words.shift()}` : words.shift();
20310
+ while (words.length && m.width(first ? `${first} ${words[0]}` : words[0], bold, fs3) <= tw) first = first ? `${first} ${words.shift()}` : words.shift();
19890
20311
  if (!first) first = words.shift() || "";
19891
- text2(first, X + 4, top + fs2 * 1.4, { size: fs2, f: bold, color: "#111827", maxW: tw });
19892
- if (words.length) text2(words.join(" "), X + 4, top + fs2 * 2.6, { size: fs2, f: bold, color: "#111827", maxW: tw });
19893
- top += fs2 * (words.length ? 3.3 : 2.1);
20312
+ text2(first, X + 4, top + fs3 * 1.4, { size: fs3, f: bold, color: "#111827", maxW: tw });
20313
+ if (words.length) text2(words.join(" "), X + 4, top + fs3 * 2.6, { size: fs3, f: bold, color: "#111827", maxW: tw });
20314
+ top += fs3 * (words.length ? 3.3 : 2.1);
19894
20315
  }
19895
20316
  }
19896
20317
  const byCategory = type === "pie" || type === "donut" || type === "funnel";
@@ -19903,7 +20324,7 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19903
20324
  let line3 = [], lw = 0;
19904
20325
  for (const li of legendItems.slice(0, 200)) {
19905
20326
  const key = li.mark ? 14 : 10;
19906
- const w = key + m.width(String(li.name).slice(0, 200), font, fs2) + 12;
20327
+ const w = key + m.width(String(li.name).slice(0, 200), font, fs3) + 12;
19907
20328
  if (lw + w > W2 - 8 && line3.length) {
19908
20329
  rowsL.push(line3);
19909
20330
  line3 = [];
@@ -19913,16 +20334,16 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19913
20334
  lw += w;
19914
20335
  }
19915
20336
  if (line3.length) rowsL.push(line3);
19916
- const lh = fs2 * 1.6;
20337
+ const lh = fs3 * 1.6;
19917
20338
  const keep = rowsL.slice(0, Math.max(1, Math.floor((bottom - top) / 2 / lh)));
19918
20339
  bottom -= keep.length * lh;
19919
20340
  keep.forEach((ln, ri) => {
19920
20341
  let lx = X + (W2 - ln.reduce((s, l) => s + l.w, 0)) / 2;
19921
20342
  const ly = bottom + ri * lh + lh * 0.75;
19922
20343
  for (const l of ln) {
19923
- if (l.mark === "line") out.push({ t: "line", x1: lx, y1: ly - fs2 * 0.35, x2: lx + 11, y2: ly - fs2 * 0.35, stroke: l.color, strokeWidth: 1.4, ...l.dash ? { dash: [3, 2] } : {} });
19924
- else if (l.mark === "band") out.push({ t: "rect", x: lx, y: ly - fs2 * 0.75, w: 11, h: 7, fill: l.color + "40", stroke: l.color, strokeWidth: 0.5, radius: 1.5 });
19925
- else out.push({ t: "rect", x: lx, y: ly - fs2 * 0.75, w: 7, h: 7, fill: l.color, radius: 1.5 });
20344
+ if (l.mark === "line") out.push({ t: "line", x1: lx, y1: ly - fs3 * 0.35, x2: lx + 11, y2: ly - fs3 * 0.35, stroke: l.color, strokeWidth: 1.4, ...l.dash ? { dash: [3, 2] } : {} });
20345
+ else if (l.mark === "band") out.push({ t: "rect", x: lx, y: ly - fs3 * 0.75, w: 11, h: 7, fill: l.color + "40", stroke: l.color, strokeWidth: 0.5, radius: 1.5 });
20346
+ else out.push({ t: "rect", x: lx, y: ly - fs3 * 0.75, w: 7, h: 7, fill: l.color, radius: 1.5 });
19926
20347
  text2(l.name, lx + l.key, ly, { maxW: l.w - l.key });
19927
20348
  lx += l.w;
19928
20349
  }
@@ -19937,7 +20358,7 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19937
20358
  const fmtV = (v) => toText(v, axes.y?.format || item.valueFormat || "N0", ctx);
19938
20359
  const anim = item.animation === "grow" || item.animation === "fade" ? item.animation : null;
19939
20360
  const placer = new LabelPlacer({ x: X, y: 0, w: W2, h: H });
19940
- const label = (s, x, y, { size = fs2 * 0.9, align = "center", color: color2 = ink, f: fk2 = font, alt: alt2 = null } = {}) => {
20361
+ const label = (s, x, y, { size = fs3 * 0.9, align = "center", color: color2 = ink, f: fk2 = font, alt: alt2 = null } = {}) => {
19941
20362
  const { str, w } = measure(s, { size, f: fk2 });
19942
20363
  if (!str.trim()) return false;
19943
20364
  const tries = [{ x, y, align, color: color2 }];
@@ -19960,7 +20381,7 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19960
20381
  return String(tpl).slice(0, 500).replace(/\{(\w+)\}/g, (all, k) => Object.hasOwn(vars, k.toLowerCase()) ? vars[k.toLowerCase()] : all);
19961
20382
  };
19962
20383
  const inLegend = (o) => legendOn && o.legend !== false;
19963
- const g = { inLegend, item, ctx, lc, data, out, links, X, W: W2, H, top, bottom, fs: fs2, font, bold, ink, grid, text: text2, measure, fmtV, pointFill, pointLink, pointCtx, pal, label, labelsOn, labelText, anim, who, axes, safe: safe2, valueAxis };
20384
+ const g = { inLegend, item, ctx, lc, data, out, links, X, W: W2, H, top, bottom, fs: fs3, font, bold, ink, grid, text: text2, measure, fmtV, pointFill, pointLink, pointCtx, pal, label, labelsOn, labelText, anim, who, axes, safe: safe2, valueAxis };
19964
20385
  if (MORE_TYPES.has(type)) paintMore(type, g);
19965
20386
  else if (ROUND_TYPES.has(type)) paintRound(type, g);
19966
20387
  else if (PER_ROW.has(type)) paintXY(type, g);
@@ -20005,7 +20426,7 @@ var stepDecimals = (step3) => {
20005
20426
  const m = /\.(\d+)$/.exec(t);
20006
20427
  return t.includes("e-") ? Math.min(6, Number(t.split("e-")[1])) : m ? Math.min(6, m[1].length) : 0;
20007
20428
  };
20008
- function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs: fs2 = 7.5, fmt: fmt2, percent = false, pad: pad2 = 0, lc, who, name, autoFmt }) {
20429
+ function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs: fs3 = 7.5, fmt: fmt2, percent = false, pad: pad2 = 0, lc, who, name, autoFmt }) {
20009
20430
  spec = spec && typeof spec === "object" ? spec : {};
20010
20431
  const smin = numOrNull(spec.min), smax = numOrNull(spec.max);
20011
20432
  if (spec.log) {
@@ -20031,7 +20452,7 @@ function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs: fs
20031
20452
  if (smax == null) hi = hi <= 0 && hi + d > 0 ? 0 : hi + d;
20032
20453
  padded = true;
20033
20454
  }
20034
- const want = len < fs2 * 6 ? 3 : 5;
20455
+ const want = len < fs3 * 6 ? 3 : 5;
20035
20456
  const sc = padded && smin == null && smax == null && (lo >= 0 || hi <= 0) ? niceScaleSpan(lo, hi, want) : niceScale(smin ?? lo, smax ?? hi, want);
20036
20457
  let a = sc.lo, b = sc.hi, ticks;
20037
20458
  if (smin != null || smax != null) {
@@ -20079,7 +20500,7 @@ function overlaysOf(item, lc, who) {
20079
20500
  }
20080
20501
  var CAT_KINDS = /* @__PURE__ */ new Set(["column", "bar", "line", "area"]);
20081
20502
  function paintCartesian(type, g) {
20082
- const { item, lc, data, out, X, W: W2, top, bottom, fs: fs2, font, text: text2, measure, pointFill, pointLink, label, labelsOn, labelText, anim, who, axes, ink, grid } = g;
20503
+ const { item, lc, data, out, X, W: W2, top, bottom, fs: fs3, font, text: text2, measure, pointFill, pointLink, label, labelsOn, labelText, anim, who, axes, ink, grid } = g;
20083
20504
  const m = lc.m;
20084
20505
  const horiz = type === "bar";
20085
20506
  const financialChart = type === "candlestick" || type === "ohlc";
@@ -20183,18 +20604,18 @@ function paintCartesian(type, g) {
20183
20604
  const angleSet = !horiz ? Math.max(-90, Math.min(90, Number(xSpec.labelAngle) || 0)) : 0;
20184
20605
  const layoutAt = (angle2) => {
20185
20606
  const sin2 = Math.abs(Math.sin(angle2 * Math.PI / 180)), cos2 = Math.abs(Math.cos(angle2 * Math.PI / 180));
20186
- const catBand2 = angle2 ? Math.min(catW, (bottom - top) * 0.4) * sin2 + fs2 * cos2 + fs2 * 0.8 : fs2 * 1.8;
20187
- const plotTop2 = top + fs2 * 0.6 + (horiz && hasY2 ? fs2 * 1.6 : 0);
20188
- const plotBottom2 = bottom - (horiz ? fs2 * 1.6 : catBand2) - (bottomTitle ? fs2 * 1.6 : 0);
20189
- const opt = { len: horiz ? W2 * 0.6 : plotBottom2 - plotTop2, fs: fs2, lc, who, percent: stackMode === "percent" };
20607
+ const catBand2 = angle2 ? Math.min(catW, (bottom - top) * 0.4) * sin2 + fs3 * cos2 + fs3 * 0.8 : fs3 * 1.8;
20608
+ const plotTop2 = top + fs3 * 0.6 + (horiz && hasY2 ? fs3 * 1.6 : 0);
20609
+ const plotBottom2 = bottom - (horiz ? fs3 * 1.6 : catBand2) - (bottomTitle ? fs3 * 1.6 : 0);
20610
+ const opt = { len: horiz ? W2 * 0.6 : plotBottom2 - plotTop2, fs: fs3, lc, who, percent: stackMode === "percent" };
20190
20611
  const ax2 = [
20191
20612
  valueAxis(ySpec, rng[0].lo, rng[0].hi, rng[0].minPos, { ...opt, includeZero: !rng[0].allFin || !rng[0].any, fmt: fmt1, name: "y", autoFmt: auto(ySpec, item.valueFormat) }),
20192
20613
  valueAxis(y2Spec, rng[1].lo, rng[1].hi, rng[1].minPos, { ...opt, includeZero: !rng[1].allFin, fmt: fmt2, name: "secondary y", autoFmt: auto(y2Spec, ySpec.format, item.valueFormat) })
20193
20614
  ];
20194
- const valW3 = Math.max(10, ...ax2[0].ticks.map((t) => m.width(ax2[0].fmt(t), font, fs2)));
20195
- const valW22 = hasY2 ? Math.max(10, ...ax2[1].ticks.map((t) => m.width(ax2[1].fmt(t), font, fs2))) : 0;
20196
- const left2 = X + 4 + (leftTitle ? fs2 * 1.6 : 0) + (horiz ? Math.min(catW, W2 * 0.32) : valW3) + 6;
20197
- const right2 = X + W2 - 6 - (!horiz && hasY2 ? valW22 + 6 + (y2Spec.title ? fs2 * 1.6 : 0) : 0);
20615
+ const valW3 = Math.max(10, ...ax2[0].ticks.map((t) => m.width(ax2[0].fmt(t), font, fs3)));
20616
+ const valW22 = hasY2 ? Math.max(10, ...ax2[1].ticks.map((t) => m.width(ax2[1].fmt(t), font, fs3))) : 0;
20617
+ const left2 = X + 4 + (leftTitle ? fs3 * 1.6 : 0) + (horiz ? Math.min(catW, W2 * 0.32) : valW3) + 6;
20618
+ const right2 = X + W2 - 6 - (!horiz && hasY2 ? valW22 + 6 + (y2Spec.title ? fs3 * 1.6 : 0) : 0);
20198
20619
  return { angle: angle2, sin: sin2, cos: cos2, catBand: catBand2, plotTop: plotTop2, plotBottom: plotBottom2, ax: ax2, valW: valW3, valW2: valW22, left: left2, right: right2 };
20199
20620
  };
20200
20621
  let lay = layoutAt(angleSet);
@@ -20206,10 +20627,10 @@ function paintCartesian(type, g) {
20206
20627
  }
20207
20628
  if (bottomTitle) text2(bottomTitle, (left + right) / 2, bottom - 2, { align: "center", color: "#6b7280" });
20208
20629
  const midY = (plotTop + plotBottom) / 2;
20209
- if (leftTitle) text2(leftTitle, X + 4 + fs2, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs2, cy: midY } });
20630
+ if (leftTitle) text2(leftTitle, X + 4 + fs3, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs3, cy: midY } });
20210
20631
  if (hasY2 && y2Spec.title) {
20211
- if (horiz) text2(y2Spec.title, (left + right) / 2, top + fs2, { align: "center", color: "#6b7280" });
20212
- else text2(y2Spec.title, X + W2 - 4 - fs2, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: 90, cx: X + W2 - 4 - fs2, cy: midY } });
20632
+ if (horiz) text2(y2Spec.title, (left + right) / 2, top + fs3, { align: "center", color: "#6b7280" });
20633
+ else text2(y2Spec.title, X + W2 - 4 - fs3, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: 90, cx: X + W2 - 4 - fs3, cy: midY } });
20213
20634
  }
20214
20635
  const vpos = (ai, v) => {
20215
20636
  let fr = ax[ai].frac(v);
@@ -20226,10 +20647,10 @@ function paintCartesian(type, g) {
20226
20647
  const showGrid = ySpec.gridlines !== false;
20227
20648
  if (horiz) {
20228
20649
  if (showGrid) out.push({ t: "line", x1: p, y1: plotTop, x2: p, y2: plotBottom, stroke: grid, strokeWidth: 0.5 });
20229
- if (i % e1 === 0) text2(ax[0].fmt(t), p, plotBottom + fs2 * 1.3, { align: "center" });
20650
+ if (i % e1 === 0) text2(ax[0].fmt(t), p, plotBottom + fs3 * 1.3, { align: "center" });
20230
20651
  } else {
20231
20652
  if (showGrid) out.push({ t: "line", x1: left, y1: p, x2: right, y2: p, stroke: grid, strokeWidth: 0.5 });
20232
- text2(ax[0].fmt(t), left - 5, p + fs2 * 0.35, { align: "right" });
20653
+ text2(ax[0].fmt(t), left - 5, p + fs3 * 0.35, { align: "right" });
20233
20654
  }
20234
20655
  });
20235
20656
  if (hasY2) {
@@ -20238,8 +20659,8 @@ function paintCartesian(type, g) {
20238
20659
  const p = vpos(1, t);
20239
20660
  if (y2Spec.gridlines) out.push(horiz ? { t: "line", x1: p, y1: plotTop, x2: p, y2: plotBottom, stroke: grid, strokeWidth: 0.5, dash: [2, 2] } : { t: "line", x1: left, y1: p, x2: right, y2: p, stroke: grid, strokeWidth: 0.5, dash: [2, 2] });
20240
20661
  if (horiz) {
20241
- if (i % e2 === 0) text2(ax[1].fmt(t), p, plotTop - fs2 * 0.5, { align: "center" });
20242
- } else text2(ax[1].fmt(t), right + 5, p + fs2 * 0.35);
20662
+ if (i % e2 === 0) text2(ax[1].fmt(t), p, plotTop - fs3 * 0.5, { align: "center" });
20663
+ } else text2(ax[1].fmt(t), right + 5, p + fs3 * 0.35);
20243
20664
  });
20244
20665
  }
20245
20666
  const span = horiz ? plotBottom - plotTop : right - left;
@@ -20258,25 +20679,25 @@ function paintCartesian(type, g) {
20258
20679
  const p0 = vpos(ai, o.vals[0]), p1 = vpos(ai, o.vals[1]);
20259
20680
  const color2 = typeof o.color === "string" && /^#[0-9a-f]{6}$/i.test(o.color) ? o.color : "#f59e0b";
20260
20681
  out.push(horiz ? { t: "rect", x: Math.min(p0, p1), y: plotTop, w: Math.abs(p1 - p0), h: plotBottom - plotTop, fill: color2 + "26" } : { t: "rect", x: left, y: Math.min(p0, p1), w: right - left, h: Math.abs(p1 - p0), fill: color2 + "26" });
20261
- if (o.label && !g.inLegend(o)) text2(String(o.label), horiz ? Math.max(p0, p1) - 2 : right - 2, horiz ? plotTop + fs2 : Math.min(p0, p1) + fs2 * 1.1, { align: "right", color: "#92400e", size: fs2 * 0.9 });
20682
+ if (o.label && !g.inLegend(o)) text2(String(o.label), horiz ? Math.max(p0, p1) - 2 : right - 2, horiz ? plotTop + fs3 : Math.min(p0, p1) + fs3 * 1.1, { align: "right", color: "#92400e", size: fs3 * 0.9 });
20262
20683
  }
20263
20684
  const zero = vpos(0, baseOf(0));
20264
20685
  out.push(horiz ? { t: "line", x1: zero, y1: plotTop, x2: zero, y2: plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 } : { t: "line", x1: left, y1: zero, x2: right, y2: zero, stroke: "#9ca3af", strokeWidth: 0.75 });
20265
20686
  if (angle) {
20266
- const every = Math.max(1, Math.ceil(fs2 * 1.2 / Math.max(band * sin, 0.01)));
20267
- const maxW = Math.max(10, (catBand - fs2 * cos - fs2 * 0.8) / Math.max(sin, 0.01));
20687
+ const every = Math.max(1, Math.ceil(fs3 * 1.2 / Math.max(band * sin, 0.01)));
20688
+ const maxW = Math.max(10, (catBand - fs3 * cos - fs3 * 0.8) / Math.max(sin, 0.01));
20268
20689
  data.categories.forEach((c, i) => {
20269
20690
  if (i % every) return;
20270
- const cx = center(i), cy = plotBottom + fs2 * 0.6;
20271
- text2(c, cx, cy + fs2 * 0.35 * cos, { align: angle < 0 ? "right" : "left", maxW, rotate: { a: angle, cx, cy } });
20691
+ const cx = center(i), cy = plotBottom + fs3 * 0.6;
20692
+ text2(c, cx, cy + fs3 * 0.35 * cos, { align: angle < 0 ? "right" : "left", maxW, rotate: { a: angle, cx, cy } });
20272
20693
  });
20273
20694
  if (every > 1) lc.warn(`${who}: ${n5 - Math.ceil(n5 / every)} of ${n5} category labels do not fit even turned, so they are not shown (every bar is drawn)`);
20274
20695
  } else {
20275
- const every = Math.max(1, Math.ceil((horiz ? fs2 * 1.3 : catW + 6) / band));
20696
+ const every = Math.max(1, Math.ceil((horiz ? fs3 * 1.3 : catW + 6) / band));
20276
20697
  data.categories.forEach((c, i) => {
20277
20698
  if (i % every) return;
20278
- if (horiz) text2(c, left - 5, center(i) + fs2 * 0.35, { align: "right", maxW: left - X - 8 - (leftTitle ? fs2 * 1.6 : 0) });
20279
- else text2(c, center(i), plotBottom + fs2 * 1.35, { align: "center", maxW: band * every - 2 });
20699
+ if (horiz) text2(c, left - 5, center(i) + fs3 * 0.35, { align: "right", maxW: left - X - 8 - (leftTitle ? fs3 * 1.6 : 0) });
20700
+ else text2(c, center(i), plotBottom + fs3 * 1.35, { align: "center", maxW: band * every - 2 });
20280
20701
  });
20281
20702
  if (every > 1) lc.warn(`${who}: ${n5 - Math.ceil(n5 / every)} of ${n5} category labels do not fit, so they are not shown (every bar is drawn)`);
20282
20703
  }
@@ -20336,7 +20757,7 @@ function paintCartesian(type, g) {
20336
20757
  pointLink(ci, horiz ? { x: Math.min(ph, pl2) - 2, y: c - band / 2, w: Math.abs(ph - pl2) + 4, h: band } : { x: c - band / 2, y: Math.min(ph, pl2) - 2, w: band, h: Math.abs(ph - pl2) + 4 }, tipOf(r, ci, p));
20337
20758
  if (labelsOn) {
20338
20759
  const q3 = P(c, ph);
20339
- if (horiz) label(labelText(ci, s, p.v), q3.x + 3, q3.y + fs2 * 0.35, { align: "left" });
20760
+ if (horiz) label(labelText(ci, s, p.v), q3.x + 3, q3.y + fs3 * 0.35, { align: "left" });
20340
20761
  else label(labelText(ci, s, p.v), q3.x, q3.y - 3);
20341
20762
  }
20342
20763
  });
@@ -20354,14 +20775,14 @@ function paintCartesian(type, g) {
20354
20775
  if (!labelsOn) return;
20355
20776
  const str = labelText(ci, s, p.v, p.pct ?? share(r, p.v));
20356
20777
  const where = pos === "inside" || pos === "center" || pos === "outside" ? pos : r.stacks ? "center" : "outside";
20357
- const sz = fs2 * 0.9;
20778
+ const sz = fs3 * 0.9;
20358
20779
  const color2 = where === "outside" ? ink : inkOn(fill3);
20359
20780
  const back = horiz ? p1 < p0 : p1 > p0;
20360
20781
  if (where === "center") label(str, rect.x + rect.w / 2, rect.y + rect.h / 2 + sz * 0.35, { color: color2, size: sz });
20361
20782
  else if (where === "inside") {
20362
20783
  if (horiz) label(str, back ? rect.x + 3 : rect.x + rect.w - 3, rect.y + rect.h / 2 + sz * 0.35, { align: back ? "left" : "right", color: color2, size: sz });
20363
20784
  else label(str, rect.x + rect.w / 2, back ? rect.y + rect.h - 3 : rect.y + sz + 2, { color: color2, size: sz });
20364
- } else if (horiz) label(str, Math.max(p0, p1) + 3, rect.y + rect.h / 2 + fs2 * 0.35, { align: "left", size: sz, alt: { x: Math.max(p0, p1) - 3, align: "right", color: inkOn(fill3) } });
20785
+ } else if (horiz) label(str, Math.max(p0, p1) + 3, rect.y + rect.h / 2 + fs3 * 0.35, { align: "left", size: sz, alt: { x: Math.max(p0, p1) - 3, align: "right", color: inkOn(fill3) } });
20365
20786
  else label(str, rect.x + rect.w / 2, Math.min(p0, p1) - 3, { size: sz, alt: { y: Math.min(p0, p1) + sz + 2, color: inkOn(fill3) } });
20366
20787
  });
20367
20788
  continue;
@@ -20388,7 +20809,7 @@ function paintCartesian(type, g) {
20388
20809
  for (const q3 of pts2) pointLink(q3.ci, horiz ? { x: left, y: q3.y - band / 2, w: right - left, h: band } : { x: q3.x - band / 2, y: plotTop, w: band, h: plotBottom - plotTop }, tipOf(r, q3.ci, q3.p));
20389
20810
  if (labelsOn) for (const q3 of pts2) {
20390
20811
  const str = labelText(q3.ci, s, q3.v, q3.p.pct ?? share(r, q3.v));
20391
- const sz = fs2 * 0.85;
20812
+ const sz = fs3 * 0.85;
20392
20813
  if (horiz) label(str, q3.x + 4, q3.y - 3, { align: "left", size: sz, alt: q3.y + sz + 3 });
20393
20814
  else if (pos === "center" || pos === "inside") label(str, q3.x, q3.y + sz * 0.35, { size: sz });
20394
20815
  else label(str, q3.x, q3.y - 4, { size: sz, alt: q3.y + sz + 4 });
@@ -20404,8 +20825,8 @@ function paintCartesian(type, g) {
20404
20825
  out.push(horiz ? { t: "line", x1: p, y1: plotTop, x2: p, y2: plotBottom, stroke: color2, strokeWidth: 1, dash: [4, 3] } : { t: "line", x1: left, y1: p, x2: right, y2: p, stroke: color2, strokeWidth: 1, dash: [4, 3] });
20405
20826
  if (o.label) {
20406
20827
  const s = `${o.label}${o.showValue === false ? "" : ` ${ax[ai2].fmt(v)}`}`;
20407
- if (horiz) text2(s, p + 2, plotTop + fs2, { color: color2, size: fs2 * 0.9 });
20408
- else text2(s, right - 2, p - 2.5, { align: "right", color: color2, size: fs2 * 0.9 });
20828
+ if (horiz) text2(s, p + 2, plotTop + fs3, { color: color2, size: fs3 * 0.9 });
20829
+ else text2(s, right - 2, p - 2.5, { align: "right", color: color2, size: fs3 * 0.9 });
20409
20830
  }
20410
20831
  }
20411
20832
  continue;
@@ -20438,16 +20859,16 @@ function paintCartesian(type, g) {
20438
20859
  out.push({ t: "path", x: 0, y: 0, d: curvePath(pts2, "straight"), fill: null, stroke: color2, strokeWidth: 1.2, ...o.type === "trend" ? { dash: [4, 3] } : {} });
20439
20860
  if (o.label && !g.inLegend(o)) {
20440
20861
  const e2 = pts2[pts2.length - 1];
20441
- if (horiz) text2(String(o.label), e2.x + 3, e2.y + fs2 * 0.35, { color: color2, size: fs2 * 0.9 });
20442
- else text2(String(o.label), Math.min(e2.x, right) - 2, e2.y - 4, { align: "right", color: color2, size: fs2 * 0.9 });
20862
+ if (horiz) text2(String(o.label), e2.x + 3, e2.y + fs3 * 0.35, { color: color2, size: fs3 * 0.9 });
20863
+ else text2(String(o.label), Math.min(e2.x, right) - 2, e2.y - 4, { align: "right", color: color2, size: fs3 * 0.9 });
20443
20864
  }
20444
20865
  }
20445
20866
  }
20446
20867
  function robustWindow(vals) {
20447
20868
  const s = vals.filter(Number.isFinite).sort((a, b) => a - b);
20448
20869
  if (s.length < 2) return null;
20449
- const at2 = (q3) => s[Math.min(s.length - 1, Math.floor(q3 * (s.length - 1)))];
20450
- const p1 = at2(0.01), p99 = at2(0.99);
20870
+ const at3 = (q3) => s[Math.min(s.length - 1, Math.floor(q3 * (s.length - 1)))];
20871
+ const p1 = at3(0.01), p99 = at3(0.99);
20451
20872
  return { p1, p99, extreme: p99 > p1 && s[s.length - 1] - s[0] > 5 * (p99 - p1) };
20452
20873
  }
20453
20874
  function rowPoints(type, g) {
@@ -20484,7 +20905,7 @@ function rowPoints(type, g) {
20484
20905
  return sets;
20485
20906
  }
20486
20907
  function paintXY(type, g) {
20487
- const { item, ctx, lc, out, X, W: W2, top, bottom, fs: fs2, font, text: text2, label, labelsOn, axes, who, grid, anim } = g;
20908
+ const { item, ctx, lc, out, X, W: W2, top, bottom, fs: fs3, font, text: text2, label, labelsOn, axes, who, grid, anim } = g;
20488
20909
  const sets = rowPoints(type, g);
20489
20910
  g.xy = sets;
20490
20911
  if (!sets.some((x) => x.pts.length)) {
@@ -20527,11 +20948,11 @@ function paintXY(type, g) {
20527
20948
  ylo = clipY.lo;
20528
20949
  yhi = clipY.hi;
20529
20950
  }
20530
- const ay = valueAxis(ys, ylo, yhi, ymp, { includeZero: false, pad: 0.05, len: bottom - top, fs: fs2, fmt: fmtY, lc, who, name: "y" });
20531
- const axx = valueAxis(xs, xlo, xhi, xmp, { includeZero: false, pad: 0.05, len: W2, fs: fs2, fmt: fmtX, lc, who, name: "x" });
20951
+ const ay = valueAxis(ys, ylo, yhi, ymp, { includeZero: false, pad: 0.05, len: bottom - top, fs: fs3, fmt: fmtY, lc, who, name: "y" });
20952
+ const axx = valueAxis(xs, xlo, xhi, xmp, { includeZero: false, pad: 0.05, len: W2, fs: fs3, fmt: fmtX, lc, who, name: "x" });
20532
20953
  const leftTitle = ys.title, bottomTitle = xs.title || item.xTitle;
20533
- const left = X + 10 + (leftTitle ? fs2 * 1.6 : 0) + Math.max(...ay.ticks.map((t) => lc.m.width(fmtY(t), font, fs2)));
20534
- const right = X + W2 - 6, pb = bottom - fs2 * 1.8 - (bottomTitle ? fs2 * 1.6 : 0), pt = top + fs2 * 0.6;
20954
+ const left = X + 10 + (leftTitle ? fs3 * 1.6 : 0) + Math.max(...ay.ticks.map((t) => lc.m.width(fmtY(t), font, fs3)));
20955
+ const right = X + W2 - 6, pb = bottom - fs3 * 1.8 - (bottomTitle ? fs3 * 1.6 : 0), pt = top + fs3 * 0.6;
20535
20956
  const maxR = Math.max(4, Math.min(right - left, pb - pt) / 12);
20536
20957
  const ins = type === "bubble" ? maxR : 0;
20537
20958
  const clamp2 = (v) => Math.max(0, Math.min(1, v ?? 0));
@@ -20544,16 +20965,16 @@ function paintXY(type, g) {
20544
20965
  return ys.reversed ? pt + ins + fr * (pb - pt - 2 * ins) : pb - ins - fr * (pb - pt - 2 * ins);
20545
20966
  };
20546
20967
  if (bottomTitle) text2(bottomTitle, (left + right) / 2, bottom - 2, { align: "center", color: "#6b7280" });
20547
- if (leftTitle) text2(leftTitle, X + 4 + fs2, (pt + pb) / 2, { align: "center", color: "#6b7280", rotate: { a: -90, cx: X + 4 + fs2, cy: (pt + pb) / 2 } });
20968
+ if (leftTitle) text2(leftTitle, X + 4 + fs3, (pt + pb) / 2, { align: "center", color: "#6b7280", rotate: { a: -90, cx: X + 4 + fs3, cy: (pt + pb) / 2 } });
20548
20969
  for (const t of ay.ticks) {
20549
20970
  if (ys.gridlines !== false) out.push({ t: "line", x1: left, y1: py(t), x2: right, y2: py(t), stroke: grid, strokeWidth: 0.5 });
20550
- text2(fmtY(t), left - 5, py(t) + fs2 * 0.35, { align: "right" });
20971
+ text2(fmtY(t), left - 5, py(t) + fs3 * 0.35, { align: "right" });
20551
20972
  }
20552
- const tw = Math.max(...axx.ticks.map((t) => lc.m.width(fmtX(t), font, fs2)));
20973
+ const tw = Math.max(...axx.ticks.map((t) => lc.m.width(fmtX(t), font, fs3)));
20553
20974
  const every = Math.max(1, Math.ceil((tw + 6) / (Math.abs(right - left) / Math.max(1, axx.ticks.length - 1))));
20554
20975
  axx.ticks.forEach((t, i) => {
20555
20976
  if (xs.gridlines) out.push({ t: "line", x1: px(t), y1: pt, x2: px(t), y2: pb, stroke: grid, strokeWidth: 0.5 });
20556
- if (i % every === 0) text2(fmtX(t), px(t), pb + fs2 * 1.35, { align: "center" });
20977
+ if (i % every === 0) text2(fmtX(t), px(t), pb + fs3 * 1.35, { align: "center" });
20557
20978
  });
20558
20979
  out.push({ t: "line", x1: left, y1: pb, x2: right, y2: pb, stroke: "#9ca3af", strokeWidth: 0.75 });
20559
20980
  const overlays = overlaysOf(item, lc, who);
@@ -20572,11 +20993,11 @@ function paintXY(type, g) {
20572
20993
  out.push(tag2(e2, anim && { k: anim === "grow" ? "scale" : "fade", i: j }));
20573
20994
  const isClipped = clipped && beyond(p) || pastAxis(p);
20574
20995
  if (isClipped) out.push({ t: "ellipse", cx: e2.cx, cy: e2.cy, rx: r + 1.6, ry: r + 1.6, fill: "none", stroke: col3, strokeWidth: 0.9 });
20575
- if (item.tooltips !== false && (type === "bubble" || multi || isClipped)) g.links.push({ t: "link", x: e2.cx - r, y: e2.cy - r, w: r * 2, h: r * 2, action: null, tip: `${multi ? `${s.name}: ` : ""}${fmtX(p.x)}, ${fmtY(p.y)}${type === "bubble" ? ` (${toText(p.size, null, ctx)})` : ""}${isClipped ? clipped && beyond(p) ? " (outlier, drawn at the edge)" : " (outside the axis range you set, draw\
20576
- n at the edge)" : ""}` });
20996
+ if (item.tooltips !== false && (type === "bubble" || multi || isClipped)) g.links.push({ t: "link", x: e2.cx - r, y: e2.cy - r, w: r * 2, h: r * 2, action: null, tip: `${multi ? `${s.name}: ` : ""}${fmtX(p.x)}, ${fmtY(p.y)}${type === "bubble" ? ` (${toText(p.size, null, ctx)})` : ""}${isClipped ? clipped && beyond(p) ? " (outlier, drawn at the edge)" : (" (outside the axis range you set, draw"+
20997
+ "n at the edge)") : ""}` });
20577
20998
  if (labelsOn) {
20578
20999
  const str = item.labelTemplate ? String(item.labelTemplate).slice(0, 500).replace(/\{(\w+)\}/g, (all, k) => ({ value: fmtY(p.y), x: fmtX(p.x), series: s.name, size: toText(p.size, null, ctx) })[k.toLowerCase()] ?? all) : fmtY(p.y);
20579
- label(str, e2.cx, e2.cy - r - 2, { size: fs2 * 0.85 });
21000
+ label(str, e2.cx, e2.cy - r - 2, { size: fs3 * 0.85 });
20580
21001
  }
20581
21002
  });
20582
21003
  }
@@ -20585,7 +21006,7 @@ n at the edge)" : ""}` });
20585
21006
  if (o.type === "line") {
20586
21007
  for (const v of overlayValues(o, g)) {
20587
21008
  out.push({ t: "line", x1: left, y1: py(v), x2: right, y2: py(v), stroke: color2, strokeWidth: 1, dash: [4, 3] });
20588
- if (o.label) text2(`${o.label} ${fmtY(v)}`, right - 2, py(v) - 2.5, { align: "right", color: color2, size: fs2 * 0.9 });
21009
+ if (o.label) text2(`${o.label} ${fmtY(v)}`, right - 2, py(v) - 2.5, { align: "right", color: color2, size: fs3 * 0.9 });
20589
21010
  }
20590
21011
  } else if (o.type === "trend") {
20591
21012
  const set = sets[Math.max(0, Math.min(sets.length - 1, Math.floor(Number(o.series)) || 0))];
@@ -20604,24 +21025,24 @@ n at the edge)" : ""}` });
20604
21025
  }
20605
21026
  if (pts2.length > 1) {
20606
21027
  out.push({ t: "path", x: 0, y: 0, d: curvePath(pts2, "straight"), fill: null, stroke: color2, strokeWidth: 1.2, dash: [4, 3] });
20607
- if (o.label && !g.inLegend(o)) text2(String(o.label), pts2[pts2.length - 1].x - 2, pts2[pts2.length - 1].y - 4, { align: "right", color: color2, size: fs2 * 0.9 });
21028
+ if (o.label && !g.inLegend(o)) text2(String(o.label), pts2[pts2.length - 1].x - 2, pts2[pts2.length - 1].y - 4, { align: "right", color: color2, size: fs3 * 0.9 });
20608
21029
  }
20609
21030
  }
20610
21031
  }
20611
21032
  }
20612
21033
  function paintPolar(g, sets) {
20613
- const { item, ctx, out, X, W: W2, top, bottom, fs: fs2, text: text2, grid, axes, lc, who, anim } = g;
21034
+ const { item, ctx, out, X, W: W2, top, bottom, fs: fs3, text: text2, grid, axes, lc, who, anim } = g;
20614
21035
  const cx = X + W2 / 2, cy = (top + bottom) / 2;
20615
- const R2 = Math.max(6, Math.min(W2, bottom - top) / 2 - fs2 * 2);
21036
+ const R2 = Math.max(6, Math.min(W2, bottom - top) / 2 - fs3 * 2);
20616
21037
  let hi = 0, lo = 0;
20617
21038
  for (const st of sets) for (const p of st.pts) {
20618
21039
  hi = Math.max(hi, p.y);
20619
21040
  lo = Math.min(lo, p.y);
20620
21041
  }
20621
21042
  const fmtY = (v) => toText(v, axes.y?.format || item.valueFormat || "N0", ctx);
20622
- const ay = valueAxis(axes.y, lo, hi, Infinity, { includeZero: true, len: R2 * 2, fs: fs2, fmt: fmtY, lc, who, name: "radius" });
21043
+ const ay = valueAxis(axes.y, lo, hi, Infinity, { includeZero: true, len: R2 * 2, fs: fs3, fmt: fmtY, lc, who, name: "radius" });
20623
21044
  const rad = (v) => Math.max(0, Math.min(1, ay.frac(v) ?? 0)) * R2;
20624
- const at2 = (deg, r) => {
21045
+ const at3 = (deg, r) => {
20625
21046
  const a = (deg - 90) * Math.PI / 180;
20626
21047
  return { x: cx + Math.cos(a) * r, y: cy + Math.sin(a) * r };
20627
21048
  };
@@ -20630,13 +21051,13 @@ function paintPolar(g, sets) {
20630
21051
  if (r > 0) out.push({ t: "ellipse", cx, cy, rx: r, ry: r, fill: null, stroke: grid, strokeWidth: 0.5 });
20631
21052
  }
20632
21053
  for (let d = 0; d < 360; d += 45) {
20633
- const e2 = at2(d, R2), l = at2(d, R2 + fs2 * 0.9);
21054
+ const e2 = at3(d, R2), l = at3(d, R2 + fs3 * 0.9);
20634
21055
  out.push({ t: "line", x1: cx, y1: cy, x2: e2.x, y2: e2.y, stroke: grid, strokeWidth: 0.5 });
20635
- text2(`${d}°`, l.x, l.y + fs2 * 0.35, { align: Math.abs(l.x - cx) < 1 ? "center" : l.x > cx ? "left" : "right", size: fs2 * 0.85, color: "#6b7280" });
21056
+ text2(`${d}°`, l.x, l.y + fs3 * 0.35, { align: Math.abs(l.x - cx) < 1 ? "center" : l.x > cx ? "left" : "right", size: fs3 * 0.85, color: "#6b7280" });
20636
21057
  }
20637
- for (const t of ay.ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtY(t), cx + 3, cy - rad(t) + fs2 * 0.3, { size: fs2 * 0.8, color: "#6b7280" });
21058
+ for (const t of ay.ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtY(t), cx + 3, cy - rad(t) + fs3 * 0.3, { size: fs3 * 0.8, color: "#6b7280" });
20638
21059
  for (const { s, pts: pts2, i } of sets) {
20639
- const q3 = pts2.map((p) => ({ ...at2(p.x, rad(p.y)), p }));
21060
+ const q3 = pts2.map((p) => ({ ...at3(p.x, rad(p.y)), p }));
20640
21061
  if (s.def.type === "line" || s.def.type === "area") {
20641
21062
  const deg = (e2) => (e2.p.x % 360 + 360) % 360;
20642
21063
  const sorted = [...q3].sort((a, b) => deg(a) - deg(b));
@@ -21341,14 +21762,14 @@ function paintMap(item, ctx, lc, base) {
21341
21762
  }
21342
21763
  const out = [];
21343
21764
  const font = resolveFontKey(base.fontFamily, "normal", "normal");
21344
- const fs2 = Math.max(6, Number(item.fontSize) || 7);
21765
+ const fs3 = Math.max(6, Number(item.fontSize) || 7);
21345
21766
  const text2 = (s, x, y, align = "left") => {
21346
- const str = String(s), w = lc.m.width(str, font, fs2);
21347
- out.push({ t: "text", font, size: fs2, color: "#374151", lines: [{ x: align === "right" ? x - w : x, y, text: str, w }] });
21767
+ const str = String(s), w = lc.m.width(str, font, fs3);
21768
+ out.push({ t: "text", font, size: fs3, color: "#374151", lines: [{ x: align === "right" ? x - w : x, y, text: str, w }] });
21348
21769
  };
21349
21770
  const pts2 = [...shapes.flatMap((s) => s.polys.flat(2)), ...lines.flatMap((l) => l.lines.flat(1)), ...points.map((p) => [p.lon, p.lat])].map(([lon, lat]) => project(lon, lat));
21350
21771
  if (!pts2.length) {
21351
- text2("No shapes or points to draw", item.x + 4, fs2 + 4);
21772
+ text2("No shapes or points to draw", item.x + 4, fs3 + 4);
21352
21773
  return out;
21353
21774
  }
21354
21775
  const showLegend = item.legend !== "none" && values.size > 0;
@@ -21414,14 +21835,14 @@ function paintMap(item, ctx, lc, base) {
21414
21835
  const [cx, cy] = toXY(p.lon, p.lat);
21415
21836
  const r = p.size != null && maxSize > 0 ? Math.max(1, maxR * Math.sqrt(Math.max(0, p.size) / maxSize)) : 3;
21416
21837
  out.push({ t: "ellipse", cx, cy, rx: r, ry: r, fill: item.pointColor || "#dc2626", stroke: "#ffffff", strokeWidth: 0.5 });
21417
- if (p.label != null && p.label !== "") text2(p.label, cx + r + 2, cy + fs2 / 3);
21838
+ if (p.label != null && p.label !== "") text2(p.label, cx + r + 2, cy + fs3 / 3);
21418
21839
  }
21419
21840
  if (showLegend) {
21420
21841
  const ly = H + 4;
21421
21842
  if (nk) {
21422
21843
  const step3 = (hi - lo) / nk;
21423
21844
  const labels = Array.from({ length: nk }, (_, i) => `${fmt2(lo + step3 * i)} – ${fmt2(i === nk - 1 ? hi : lo + step3 * (i + 1))}`);
21424
- const ws = labels.map((s) => 10 + lc.m.width(s, font, fs2) + 8);
21845
+ const ws = labels.map((s) => 10 + lc.m.width(s, font, fs3) + 8);
21425
21846
  let lx = item.x + Math.max(0, (W2 - ws.reduce((a, b) => a + b, 0)) / 2);
21426
21847
  labels.forEach((s, i) => {
21427
21848
  out.push({ t: "rect", x: lx, y: ly, w: 8, h: 8, fill: mix(low, high, i / (nk - 1)) });
@@ -22335,10 +22756,10 @@ function buildTree(groups, rows, ctx, lc, who, axis, state) {
22335
22756
  }
22336
22757
  const seen = /* @__PURE__ */ new Set(), late = [];
22337
22758
  let deep = false;
22338
- const visit = (x, d, path2) => {
22759
+ const visit = (x, d, path3) => {
22339
22760
  seen.add(x);
22340
22761
  x.depth = d;
22341
- x.path = `${path2}/${x.text}`;
22762
+ x.path = `${path3}/${x.text}`;
22342
22763
  let all = x.rows;
22343
22764
  const kids = [];
22344
22765
  for (const c of x.rec || []) {
@@ -22436,7 +22857,7 @@ function visible(root, groups) {
22436
22857
  for (let p = n5; p && p.level >= 0; p = p.parent) c.unshift(p);
22437
22858
  return c;
22438
22859
  };
22439
- const walk = (n5, l) => {
22860
+ const walk2 = (n5, l) => {
22440
22861
  const g = groups[l];
22441
22862
  const total = { kind: "total", node: n5, level: l, chain: chainOf(n5) };
22442
22863
  if (g.total === "before") out.push(total);
@@ -22451,11 +22872,11 @@ function visible(root, groups) {
22451
22872
  for (const c of n5.children || []) {
22452
22873
  if (l === groups.length - 1) leaf(c);
22453
22874
  else if (!c.open) out.push({ kind: "collapsed", node: c, level: l, chain: chainOf(c) });
22454
- else walk(c, l + 1);
22875
+ else walk2(c, l + 1);
22455
22876
  }
22456
22877
  if (g.total === "after") out.push(total);
22457
22878
  };
22458
- walk(root, 0);
22879
+ walk2(root, 0);
22459
22880
  return out;
22460
22881
  }
22461
22882
  function spans(entries) {
@@ -22710,10 +23131,10 @@ function sliceColumns(o) {
22710
23131
  if (k >= 2) {
22711
23132
  const base = Math.floor(blocks.length / k), extra = blocks.length % k;
22712
23133
  const even = [];
22713
- let at2 = 0;
23134
+ let at3 = 0;
22714
23135
  for (let p = 0; p < k; p++) {
22715
- const part2 = blocks.slice(at2, at2 + base + (p < extra ? 1 : 0));
22716
- at2 += part2.length;
23136
+ const part2 = blocks.slice(at3, at3 + base + (p < extra ? 1 : 0));
23137
+ at3 += part2.length;
22717
23138
  even.push({ from: part2[0].from, to: part2[part2.length - 1].to, w: part2.reduce((s, b) => s + b.w, 0) });
22718
23139
  }
22719
23140
  if (even.every((s) => s.w <= avail + EPS)) sets = even;
@@ -22842,16 +23263,16 @@ function sliceColumns(o) {
22842
23263
  function rowCells(cells, ncols) {
22843
23264
  const list2 = Array.isArray(cells) ? cells : [];
22844
23265
  const span = (c) => Math.max(1, Math.floor(Number(c?.colSpan)) || 1);
22845
- const at2 = new Array(ncols).fill(null);
23266
+ const at3 = new Array(ncols).fill(null);
22846
23267
  const covered = [];
22847
23268
  if (list2.length < ncols && list2.some((c) => span(c) > 1)) {
22848
23269
  let pos = 0;
22849
23270
  for (const c of list2) {
22850
23271
  if (pos >= ncols) break;
22851
- at2[pos] = c ?? null;
23272
+ at3[pos] = c ?? null;
22852
23273
  pos += span(c);
22853
23274
  }
22854
- return { at: at2, covered };
23275
+ return { at: at3, covered };
22855
23276
  }
22856
23277
  let until = -1, by = -1;
22857
23278
  for (let k = 0; k < Math.min(list2.length, ncols); k++) {
@@ -22860,13 +23281,13 @@ function rowCells(cells, ncols) {
22860
23281
  if (c) covered.push([k, by]);
22861
23282
  continue;
22862
23283
  }
22863
- at2[k] = c ?? null;
23284
+ at3[k] = c ?? null;
22864
23285
  if (span(c) > 1) {
22865
23286
  until = k + span(c) - 1;
22866
23287
  by = k;
22867
23288
  }
22868
23289
  }
22869
- return { at: at2, covered };
23290
+ return { at: at3, covered };
22870
23291
  }
22871
23292
 
22872
23293
  // src/engine/items/index.js
@@ -22930,20 +23351,20 @@ function paintTextbox(item, lc, ctx, forcedH) {
22930
23351
  const size0 = Number(st.fontSize) || 9;
22931
23352
  const shrink = (min, fits, step3) => {
22932
23353
  const steps = Number.isFinite(size0) ? Math.max(0, Math.floor((size0 - min) / step3 + 1e-9)) : 0;
22933
- const at2 = (i) => {
23354
+ const at3 = (i) => {
22934
23355
  const s2 = { ...st, fontSize: Math.max(min, size0 - step3 * (i + 1)) };
22935
23356
  return { s2, t2: layoutTextLines(text2, s2, layoutW, lc.m) };
22936
23357
  };
22937
23358
  let lo = 0, hi = steps - 1, best = null;
22938
23359
  while (lo <= hi) {
22939
23360
  const mid = Math.floor((lo + hi) / 2);
22940
- const c = at2(mid);
23361
+ const c = at3(mid);
22941
23362
  if (fits(c.t2)) {
22942
23363
  best = c;
22943
23364
  hi = mid - 1;
22944
23365
  } else lo = mid + 1;
22945
23366
  }
22946
- return { best, last: steps > 0 ? () => at2(steps - 1) : null };
23367
+ return { best, last: steps > 0 ? () => at3(steps - 1) : null };
22947
23368
  };
22948
23369
  const fitsBox = (t) => t.needed <= layoutH + GROW_TOLERANCE;
22949
23370
  if (item.shrinkToFit && !fitsBox(tl)) {
@@ -23182,9 +23603,9 @@ function fitColumns(item, cols, rows, tctx, lc) {
23182
23603
  const nat = cols.map(() => 0);
23183
23604
  const measure = (row, ctx) => {
23184
23605
  const rst = resolveStyle([lc.base, lc.named?.[item.styleName], item.style, row.style], ctx);
23185
- const { at: at2 } = rowCells(row.cells, cols.length);
23606
+ const { at: at3 } = rowCells(row.cells, cols.length);
23186
23607
  for (let ci = 0; ci < cols.length; ci++) {
23187
- const cell = at2[ci];
23608
+ const cell = at3[ci];
23188
23609
  if (!auto[ci] || !cell || (cell.colSpan || 1) > 1 || cell.item) continue;
23189
23610
  let v;
23190
23611
  try {
@@ -23314,10 +23735,10 @@ register("table", {
23314
23735
  const cells = [];
23315
23736
  let started = null;
23316
23737
  let need = row.height || 18;
23317
- let at2 = cellsAt.get(row);
23318
- if (!at2) cellsAt.set(row, at2 = rowCells(row.cells, cols.length).at);
23738
+ let at3 = cellsAt.get(row);
23739
+ if (!at3) cellsAt.set(row, at3 = rowCells(row.cells, cols.length).at);
23319
23740
  for (let ci = 0; ci < cols.length; ci++) {
23320
- const cell = at2[ci];
23741
+ const cell = at3[ci];
23321
23742
  if (!cell || covered(ci)) continue;
23322
23743
  const span = Math.max(1, Math.min(cell.colSpan || 1, cols.length - ci));
23323
23744
  let cw = 0;
@@ -23494,8 +23915,8 @@ register("table", {
23494
23915
  cellLinks(add2, s, u.height, kind, s.level);
23495
23916
  if (s.toggle) add2.push(toggleLink(s, s.w, u.height));
23496
23917
  }
23497
- const at2 = u.items.findIndex((it) => itemLeft(it) >= s.x + s.w - 0.01);
23498
- u.items.splice(at2 < 0 ? u.items.length : at2, 0, ...add2);
23918
+ const at3 = u.items.findIndex((it) => itemLeft(it) >= s.x + s.w - 0.01);
23919
+ u.items.splice(at3 < 0 ? u.items.length : at3, 0, ...add2);
23499
23920
  });
23500
23921
  if (s.tl.needed > s.units[0].height + GROW_TOLERANCE || s.st.verticalAlign && s.st.verticalAlign !== "top") {
23501
23922
  const id = `${item.name || item.type}:span:${lc.nextId()}`;
@@ -23633,8 +24054,8 @@ register("table", {
23633
24054
  gctx.level = depth;
23634
24055
  if (g.indent) gctx.indent = (ctx.indent || 0) + depth * Number(g.indent);
23635
24056
  }
23636
- const path2 = `${parentPath}/${bk.text}`;
23637
- const tkey = `${item.name || item.type}|${level}|${path2}`;
24057
+ const path3 = `${parentPath}/${bk.text}`;
24058
+ const tkey = `${item.name || item.type}|${level}|${path3}`;
23638
24059
  const dflt = kids && g.expandLevels != null ? depth < Number(g.expandLevels) : !g.initiallyCollapsed;
23639
24060
  const open = !g.collapsible ? true : lc.state?.toggles?.[tkey] ?? dflt;
23640
24061
  const start = units.length;
@@ -23655,9 +24076,9 @@ register("table", {
23655
24076
  if (rep) gctx.__rep = rep;
23656
24077
  const ch = kids?.get(bk) || [];
23657
24078
  if (open) {
23658
- emit2(level + 1, bk.rows, gctx, [...chain, sc], path2);
24079
+ emit2(level + 1, bk.rows, gctx, [...chain, sc], path3);
23659
24080
  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`);
23660
- else ch.forEach((c, ci) => node3(c, ci, ch, depth + 1, path2));
24081
+ else ch.forEach((c, ci) => node3(c, ci, ch, depth + 1, path3));
23661
24082
  } else {
23662
24083
  const rs = recOf.get(bk) || bk.rows;
23663
24084
  for (const s of [...chain, sc]) {
@@ -23685,7 +24106,7 @@ register("table", {
23685
24106
  if (g.newSection) units[start].sectionStart = true;
23686
24107
  if (g.pageBreak === "after" && bi < sibs.length - 1) units[units.length - 1].breakAfter = true;
23687
24108
  if (g.keepTogether) {
23688
- const id = `${item.name || item.type}:g${level}:${path2}:${lc.nextId()}`;
24109
+ const id = `${item.name || item.type}:g${level}:${path3}:${lc.nextId()}`;
23689
24110
  for (let k = start; k < units.length; k++) if (!units[k].block) {
23690
24111
  units[k].block = id;
23691
24112
  if (cont) units[k].blockOpen = true;
@@ -27189,14 +27610,14 @@ var REPORT_SCHEMA = {
27189
27610
  "additionalProperties": true
27190
27611
  },
27191
27612
  "Report": {
27192
- "description": "A ReportWright report definition (pagewright/report@1).",
27613
+ "description": "A ReportWright report definition (reportwright/report@1).",
27193
27614
  "type": "object",
27194
27615
  "properties": {
27195
27616
  "$schema": {
27196
- "description": "pagewright/report@1; reportwright/report@1 is the same format under the new name.",
27617
+ "description": "reportwright/report@1; pagewright/report@1 (deprecated, the name before the rename) is the same format.",
27197
27618
  "enum": [
27198
- "pagewright/report@1",
27199
- "reportwright/report@1"
27619
+ "reportwright/report@1",
27620
+ "pagewright/report@1"
27200
27621
  ]
27201
27622
  },
27202
27623
  "name": {
@@ -27314,7 +27735,7 @@ var REPORT_SCHEMA = {
27314
27735
  ],
27315
27736
  "examples": [
27316
27737
  {
27317
- "$schema": "pagewright/report@1",
27738
+ "$schema": "reportwright/report@1",
27318
27739
  "name": "Invoice",
27319
27740
  "page": {
27320
27741
  "size": "A4",
@@ -27432,11 +27853,11 @@ var REPORT_SCHEMA = {
27432
27853
  // src/engine/schema/validate.js
27433
27854
  init_format();
27434
27855
  init_units();
27435
- var SCHEMA_ID = "pagewright/report@1";
27436
- var SCHEMA_ALIAS = "reportwright/report@1";
27437
- 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\
27438
- 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\
27439
- ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description".split(" "));
27856
+ var SCHEMA_ID = "reportwright/report@1";
27857
+ var SCHEMA_ALIAS = "pagewright/report@1";
27858
+ 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"+
27859
+ "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"+
27860
+ "ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description").split(" "));
27440
27861
  var NO_SERIES_CHARTS = /* @__PURE__ */ new Set(["gantt"]);
27441
27862
  function looksLikeLink(it) {
27442
27863
  if (it.type !== "textbox" || it.action && it.action.type && it.action.type !== "none") return false;
@@ -27447,8 +27868,8 @@ function looksLikeLink(it) {
27447
27868
  const [r, g, b] = m.slice(1).map((h) => parseInt(h, 16));
27448
27869
  return b > 150 && b > r + 60 && b > g + 30;
27449
27870
  }
27450
- var DEF_KEYS = new Set("$schema name description locale currency timeZone page parameters dataSources dataSets styles sections functions layers images theme themeDef master nullPropagation caseSensitive naturalSort nullOrder collation arithmetic bandRows version id tags author folder stylesheet parts partProperties dashboard comment notes customCode libraries liveParameters parameterLayout drafts \
27451
- history nonFinite".split(" "));
27871
+ var DEF_KEYS = new Set(("$schema name description locale currency timeZone page parameters dataSources dataSets styles sections functions layers images theme themeDef master nullPropagation caseSensitive naturalSort nullOrder collation arithmetic bandRows version id tags author folder stylesheet parts partProperties dashboard comment notes customCode libraries liveParameters parameterLayout drafts "+
27872
+ "history nonFinite").split(" "));
27452
27873
  for (const k of Object.keys(REPORT_SCHEMA.$defs.Report.properties)) DEF_KEYS.add(k);
27453
27874
  var lev = (a, b) => {
27454
27875
  if (Math.abs(a.length - b.length) > 2) return 3;
@@ -27498,17 +27919,29 @@ function formatIssue(f4, label, out) {
27498
27919
  }
27499
27920
  function sortIssues(sort, label, out) {
27500
27921
  sort.forEach((s, i) => {
27501
- const at2 = `${label}, sort ${i + 1}`;
27922
+ const at3 = `${label}, sort ${i + 1}`;
27502
27923
  if (!s || typeof s !== "object" || Array.isArray(s) || !("by" in s)) {
27503
- out.push(`${at2}: a sort entry is {by, dir}, e.g. {"by": "=Fields.Name", "dir": "asc"}; this one has no "by" and is ignored`);
27924
+ out.push(`${at3}: a sort entry is {by, dir}, e.g. {"by": "=Fields.Name", "dir": "asc"}; this one has no "by" and is ignored`);
27504
27925
  return;
27505
27926
  }
27506
27927
  for (const k of Object.keys(s)) {
27507
27928
  if (k === "by" || k === "dir" || k.startsWith("_")) continue;
27508
27929
  const g = SORT_ALIAS[k] || didYouMean(k, ["by", "dir"]);
27509
- out.push(`${at2}: "${k}" is ignored; a sort entry is {by, dir}${g ? ` (did you mean "${g}"?)` : ""}`);
27930
+ out.push(`${at3}: "${k}" is ignored; a sort entry is {by, dir}${g ? ` (did you mean "${g}"?)` : ""}`);
27931
+ }
27932
+ if (s.dir != null && !["asc", "desc"].includes(s.dir)) out.push(`${at3}: "dir" is ${JSON.stringify(s.dir)}; expected "asc" or "desc"`);
27933
+ });
27934
+ }
27935
+ var FILTER_KEYS = ["expr", "op", "value", "value2", "skipBlank"];
27936
+ var FILTER_ALIAS = { expression: "expr", field: "expr", by: "expr", operator: "op", comparison: "op", values: "value", value1: "value" };
27937
+ function filterIssues(filters, label, out) {
27938
+ filters.forEach((f4, i) => {
27939
+ if (!f4 || typeof f4 !== "object" || Array.isArray(f4)) return;
27940
+ for (const k of Object.keys(f4)) {
27941
+ if (FILTER_KEYS.includes(k) || k.startsWith("_")) continue;
27942
+ const g = FILTER_ALIAS[k] || didYouMean(k, FILTER_KEYS);
27943
+ out.push(`${label}, filter ${i + 1}: "${k}" is ignored; a filter is {${FILTER_KEYS.join(", ")}}${g ? ` (did you mean "${g}"?)` : ""}`);
27510
27944
  }
27511
- if (s.dir != null && !["asc", "desc"].includes(s.dir)) out.push(`${at2}: "dir" is ${JSON.stringify(s.dir)}; expected "asc" or "desc"`);
27512
27945
  });
27513
27946
  }
27514
27947
  var SCHEMA_ITEMS = (() => {
@@ -27593,6 +28026,7 @@ function validate(def) {
27593
28026
  } else if (!srcNames.has(d.source)) errors.push(`Data set "${d.name}" uses the source "${d.source}", which does not exist`);
27594
28027
  dsNames.add(d.name);
27595
28028
  if (Array.isArray(d.sort)) sortIssues(d.sort, `Data set "${d.name}"`, warnings);
28029
+ if (Array.isArray(d.filters)) filterIssues(d.filters, `Data set "${d.name}"`, warnings);
27596
28030
  }
27597
28031
  const names = /* @__PURE__ */ new Set();
27598
28032
  const check = (where, v, label) => {
@@ -27655,6 +28089,7 @@ function validate(def) {
27655
28089
  warnings.push(`${label}: there is no named style "${it.styleName}"${g ? ` (did you mean "${g}"?)` : ""}; it is ignored`);
27656
28090
  }
27657
28091
  if (Array.isArray(it.sort)) sortIssues(it.sort, label, warnings);
28092
+ if (Array.isArray(it.filters)) filterIssues(it.filters, label, warnings);
27658
28093
  if (it.type === "chart" && it.legend != null && it.legend !== "bottom" && it.legend !== "none") {
27659
28094
  const shown2 = typeof it.legend === "object" ? `is an object (${JSON.stringify(it.legend).slice(0, 60)})` : `is ${JSON.stringify(it.legend)}`;
27660
28095
  warnings.push(`${label}: "legend" ${shown2}; only "bottom" (show the legend) or "none" (hide it) is supported, and the legend is drawn at the bottom`);
@@ -28054,15 +28489,15 @@ async function loadParts(def, get, warn, budget) {
28054
28489
  for (const q3 of Array.isArray(p.properties) ? p.properties : []) if (q3?.name) props[q3.name] = q3.default ?? null;
28055
28490
  const inner2 = [];
28056
28491
  let own = 0;
28057
- const walk = (list2) => {
28492
+ const walk2 = (list2) => {
28058
28493
  for (const x of list2 || []) {
28059
28494
  if (!x || typeof x !== "object") continue;
28060
28495
  own++;
28061
28496
  if (x.type === "part") inner2.push(x);
28062
- walk(x.items);
28497
+ walk2(x.items);
28063
28498
  }
28064
28499
  };
28065
- walk([item]);
28500
+ walk2([item]);
28066
28501
  parts.set(key, { item, props, own, inner: inner2.filter((x) => x !== item) });
28067
28502
  libs.set(lib, d);
28068
28503
  for (const x of inner2) {
@@ -28880,20 +29315,20 @@ async function encryptPdf(doc, opt) {
28880
29315
  return cat(iv, await aesCbc(fileKey, iv, bytes));
28881
29316
  };
28882
29317
  const seen = /* @__PURE__ */ new Set();
28883
- const walk = async (obj) => {
29318
+ const walk2 = async (obj) => {
28884
29319
  if (obj instanceof PDFString || obj instanceof PDFHexString) return PDFHexString.of(hex2(await enc(obj.asBytes())));
28885
29320
  if (obj instanceof PDFArray) {
28886
- for (let i = 0; i < obj.size(); i++) obj.set(i, await walk(obj.get(i)));
29321
+ for (let i = 0; i < obj.size(); i++) obj.set(i, await walk2(obj.get(i)));
28887
29322
  return obj;
28888
29323
  }
28889
29324
  if (obj instanceof PDFDict) {
28890
29325
  if (seen.has(obj)) return obj;
28891
29326
  seen.add(obj);
28892
- for (const [k, v] of obj.entries()) obj.set(k, await walk(v));
29327
+ for (const [k, v] of obj.entries()) obj.set(k, await walk2(v));
28893
29328
  return obj;
28894
29329
  }
28895
29330
  if (obj instanceof PDFStream) {
28896
- await walk(obj.dict);
29331
+ await walk2(obj.dict);
28897
29332
  const contents = obj instanceof PDFRawStream ? obj.contents : (
28898
29333
  /** @type {any} */
28899
29334
  obj.getContents()
@@ -28902,7 +29337,7 @@ async function encryptPdf(doc, opt) {
28902
29337
  }
28903
29338
  return obj;
28904
29339
  };
28905
- for (const [ref2, obj] of ctx.enumerateIndirectObjects()) ctx.assign(ref2, await walk(obj));
29340
+ for (const [ref2, obj] of ctx.enumerateIndirectObjects()) ctx.assign(ref2, await walk2(obj));
28906
29341
  const encrypt = ctx.obj({
28907
29342
  Filter: "Standard",
28908
29343
  V: 5,
@@ -28997,9 +29432,9 @@ ${pdfa ? `<rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/n
28997
29432
  </x:xmpmeta>
28998
29433
  <?xpacket end="w"?>`;
28999
29434
  }
29000
- var PDFUA_SCHEMA = `<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"><pdfaExtension:schemas><rdf:Bag><rdf:li rdf:parseType="Resource"><pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema><pdfaSchema:namespaceURI>http://www.aiim.or\
29001
- g/pdfua/ns/id/</pdfaSchema:namespaceURI><pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix><pdfaSchema:property><rdf:Seq><rdf:li rdf:parseType="Resource"><pdfaProperty:name>part</pdfaProperty:name><pdfaProperty:valueType>Integer</pdfaProperty:valueType><pdfaProperty:category>internal</pdfaProperty:category><pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description></rdf:li></rdf:Seq>\
29002
- </pdfaSchema:property></rdf:li></rdf:Bag></pdfaExtension:schemas></rdf:Description>
29435
+ var PDFUA_SCHEMA = `<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"><pdfaExtension:schemas><rdf:Bag><rdf:li rdf:parseType="Resource"><pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema><pdfaSchema:namespaceURI>http://www.aiim.or${
29436
+ ""}g/pdfua/ns/id/</pdfaSchema:namespaceURI><pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix><pdfaSchema:property><rdf:Seq><rdf:li rdf:parseType="Resource"><pdfaProperty:name>part</pdfaProperty:name><pdfaProperty:valueType>Integer</pdfaProperty:valueType><pdfaProperty:category>internal</pdfaProperty:category><pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description></rdf:li></rdf:Seq>${
29437
+ ""}</pdfaSchema:property></rdf:li></rdf:Bag></pdfaExtension:schemas></rdf:Description>
29003
29438
  `;
29004
29439
  function setMetadata(doc, xmp) {
29005
29440
  const ctx = doc.context;
@@ -29176,8 +29611,8 @@ function parseSvg(text2) {
29176
29611
  }
29177
29612
  var clamp01 = (v) => Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : 1;
29178
29613
  var paint = (v) => v === "currentColor" ? "#000" : /^url\(/.test(String(v || "")) ? "none" : v;
29179
- function drawSvg(page, svg, at2) {
29180
- const place = [at2.sx, 0, 0, -at2.sy, at2.x, at2.y + svg.h * at2.sy];
29614
+ function drawSvg(page, svg, at3) {
29615
+ const place = [at3.sx, 0, 0, -at3.sy, at3.x, at3.y + svg.h * at3.sy];
29181
29616
  for (const s of svg.shapes) {
29182
29617
  if (!s.fill && !s.stroke) continue;
29183
29618
  const m = mul(mul(place, s.m), [1, 0, 0, -1, 0, 0]);
@@ -29220,8 +29655,8 @@ function imageHref(src, proxyBase = "") {
29220
29655
  return "";
29221
29656
  }
29222
29657
  var n = (v) => Math.round(v * 100) / 100;
29223
- var ANIM_CSS = "<style>@media (prefers-reduced-motion:no-preference){.pw-a{transform-box:fill-box;animation:pw-fade .55s ease-out both}.pw-a-growY{animation-name:pw-growY}.pw-a-growX{animation-name:pw-growX}.pw-a-scale{animation-name:pw-scale}@keyframes pw-fade{from{opacity:0}}@keyframes pw-growY{from{transform:scaleY(0)}}@keyframes pw-growX{from{transform:scaleX(0)}}@keyframes pw-scale{from{trans\
29224
- form:scale(0);opacity:0}}}</style>";
29658
+ var ANIM_CSS = ("<style>@media (prefers-reduced-motion:no-preference){.pw-a{transform-box:fill-box;animation:pw-fade .55s ease-out both}.pw-a-growY{animation-name:pw-growY}.pw-a-growX{animation-name:pw-growX}.pw-a-scale{animation-name:pw-scale}@keyframes pw-fade{from{opacity:0}}@keyframes pw-growY{from{transform:scaleY(0)}}@keyframes pw-growX{from{transform:scaleX(0)}}@keyframes pw-scale{from{trans"+
29659
+ "form:scale(0);opacity:0}}}</style>");
29225
29660
  var ANIM_KINDS = /* @__PURE__ */ new Set(["growY", "growX", "scale", "fade"]);
29226
29661
  var ANIM_ORIGIN = { bottom: "center bottom", top: "center top", left: "left center", right: "right center" };
29227
29662
  function pageToSvg(page, w, h, { background = true, animate = false, box = void 0, outline: outline2 = null, proxyBase = "" } = {}) {
@@ -29785,15 +30220,15 @@ function createTagger(model, doc) {
29785
30220
  const refOf = /* @__PURE__ */ new Map();
29786
30221
  const all = [];
29787
30222
  for (const t of root.tables?.values() || []) regular(t);
29788
- const walk = (n5) => {
30223
+ const walk2 = (n5) => {
29789
30224
  refOf.set(n5, ctx.nextRef());
29790
30225
  all.push(n5);
29791
30226
  for (const k of n5.kids) if (k.S) {
29792
30227
  k.parent ||= n5;
29793
- walk(k);
30228
+ walk2(k);
29794
30229
  }
29795
30230
  };
29796
- walk(root);
30231
+ walk2(root);
29797
30232
  const nums2 = [];
29798
30233
  let key = 0;
29799
30234
  pages.forEach((pg, pi) => {
@@ -30200,27 +30635,27 @@ async function* readerIter(rs) {
30200
30635
  r.releaseLock?.();
30201
30636
  }
30202
30637
  }
30203
- function splitPath(path2) {
30204
- if (!path2 || path2 === "$") return [];
30205
- const p = path2.startsWith("$") ? path2.slice(1) : "." + path2;
30638
+ function splitPath(path3) {
30639
+ if (!path3 || path3 === "$") return [];
30640
+ const p = path3.startsWith("$") ? path3.slice(1) : "." + path3;
30206
30641
  const re = /\.([A-Za-z_$][\w$]*)|\['([^']+)'\]|\["([^"]+)"\]|(\[\*\])$/y;
30207
30642
  const keys = [];
30208
- let at2 = 0;
30209
- while (at2 < p.length) {
30210
- re.lastIndex = at2;
30643
+ let at3 = 0;
30644
+ while (at3 < p.length) {
30645
+ re.lastIndex = at3;
30211
30646
  const m = re.exec(p);
30212
30647
  if (!m) return null;
30213
30648
  if (!m[4]) keys.push(m[1] ?? m[2] ?? m[3]);
30214
- at2 = re.lastIndex;
30649
+ at3 = re.lastIndex;
30215
30650
  }
30216
30651
  return keys;
30217
30652
  }
30218
- async function* jsonRows(body, path2, { maxElementBytes = 1048576, maxWholeBytes = 64 * 1048576, maxDepth = 512, batch = 1e3 } = {}) {
30219
- const keys = splitPath(path2);
30653
+ async function* jsonRows(body, path3, { maxElementBytes = 1048576, maxWholeBytes = 64 * 1048576, maxDepth = 512, batch = 1e3 } = {}) {
30654
+ const keys = splitPath(path3);
30220
30655
  let whole = keys == null ? "" : null;
30221
30656
  let buf = "", i = 0;
30222
30657
  const stack2 = [];
30223
- let inStr = false, esc8 = false, strStart = -1;
30658
+ let inStr = false, esc9 = false, strStart = -1;
30224
30659
  let target = -1;
30225
30660
  let elemStart = -1, done = false;
30226
30661
  let out = [], outLen = 0;
@@ -30246,8 +30681,8 @@ async function* jsonRows(body, path2, { maxElementBytes = 1048576, maxWholeBytes
30246
30681
  for (; i < buf.length; i++) {
30247
30682
  const c = buf.charCodeAt(i);
30248
30683
  if (inStr) {
30249
- if (esc8) esc8 = false;
30250
- else if (c === 92) esc8 = true;
30684
+ if (esc9) esc9 = false;
30685
+ else if (c === 92) esc9 = true;
30251
30686
  else if (c === 34) {
30252
30687
  inStr = false;
30253
30688
  const top = stack2[stack2.length - 1];
@@ -30329,7 +30764,7 @@ async function* jsonRows(body, path2, { maxElementBytes = 1048576, maxWholeBytes
30329
30764
  }
30330
30765
  if (whole != null) {
30331
30766
  const raw = whole === "" ? null : JSON.parse(whole);
30332
- let { rows } = jsonPathRows(raw, path2 || "$");
30767
+ let { rows } = jsonPathRows(raw, path3 || "$");
30333
30768
  if (rows == null) rows = [];
30334
30769
  else if (!Array.isArray(rows)) rows = [rows];
30335
30770
  for (let k = 0; k < rows.length; k += batch) yield rows.slice(k, k + batch);
@@ -30594,7 +31029,7 @@ async function planStream(def0, opts) {
30594
31029
  const setCtx = { ...baseCtx, ...ds.caseSensitive != null ? { caseSensitive: ds.caseSensitive === true } : {} };
30595
31030
  const tctx = { ...baseCtx };
30596
31031
  const cellsAt = /* @__PURE__ */ new WeakMap();
30597
- const at2 = (row) => {
31032
+ const at3 = (row) => {
30598
31033
  let a = cellsAt.get(row);
30599
31034
  if (!a) cellsAt.set(row, a = rowCells(row.cells, ncols).at);
30600
31035
  return a;
@@ -30603,7 +31038,7 @@ async function planStream(def0, opts) {
30603
31038
  if (row.hidden === true) return null;
30604
31039
  const rst = resolveStyle([base, named?.[item.styleName], item.style, named?.[row.styleName], row.style], ctx);
30605
31040
  const cells = [];
30606
- const a = at2(row);
31041
+ const a = at3(row);
30607
31042
  for (let ci = 0; ci < ncols; ci++) {
30608
31043
  const cell = a[ci];
30609
31044
  if (!cell) continue;
@@ -30709,11 +31144,11 @@ async function planStream(def0, opts) {
30709
31144
  }
30710
31145
  return out;
30711
31146
  };
30712
- const ready = (fs2) => {
30713
- fields = seen = fs2;
30714
- plain2 = plainOf(fs2);
30715
- calc = fs2.filter((fd) => fd.expr);
30716
- fopts = new Map(fs2.map((fd) => [fd, optFor(fd)]));
31147
+ const ready = (fs3) => {
31148
+ fields = seen = fs3;
31149
+ plain2 = plainOf(fs3);
31150
+ calc = fs3.filter((fd) => fd.expr);
31151
+ fopts = new Map(fs3.map((fd) => [fd, optFor(fd)]));
30717
31152
  cc = { ...baseCtx, dataSets: {}, fields: null };
30718
31153
  };
30719
31154
  if (fields) ready(fields);
@@ -30807,7 +31242,7 @@ async function planStream(def0, opts) {
30807
31242
  let seq = 0;
30808
31243
  for await (const r of inOrder(true)) {
30809
31244
  gc.fields = r;
30810
- let path2 = "";
31245
+ let path3 = "";
30811
31246
  const g = [];
30812
31247
  for (let l = 0; l < groups.length; l++) {
30813
31248
  let key;
@@ -30817,12 +31252,12 @@ async function planStream(def0, opts) {
30817
31252
  warn(`${item.name || item.type} group: ${e2.message}`);
30818
31253
  key = "#Error";
30819
31254
  }
30820
- path2 += `\0${groupKeyText(key, tctx)}`;
30821
- let p = paths[l].get(path2);
31255
+ path3 += `\0${groupKeyText(key, tctx)}`;
31256
+ let p = paths[l].get(path3);
30822
31257
  if (!p) {
30823
- keyText += path2.length;
31258
+ keyText += path3.length;
30824
31259
  if (ord > 1e6 || keyText > 64 * 1048576) throw Object.assign(new Error("Too many groups (or group keys too long) to stream: filter the data."), { status: 413, fallBack: true });
30825
- paths[l].set(path2, p = [ord++, key]);
31260
+ paths[l].set(path3, p = [ord++, key]);
30826
31261
  }
30827
31262
  g.push(p);
30828
31263
  }
@@ -30850,7 +31285,7 @@ async function planStream(def0, opts) {
30850
31285
  const foldCells = (rows2) => {
30851
31286
  const out = [];
30852
31287
  for (const row of rows2 || []) {
30853
- const a = at2(row);
31288
+ const a = at3(row);
30854
31289
  for (let ci = 0; ci < ncols; ci++) {
30855
31290
  const f4 = a[ci] && foldOf(a[ci].value);
30856
31291
  if (f4) out.push({ row, ci, ...f4 });
@@ -30972,8 +31407,8 @@ async function planStream(def0, opts) {
30972
31407
  }
30973
31408
  return { name: item.name, columns: cols.map((c) => c.width), title: def.name || "", timeZone: timeZone || null, locale: def.locale || null, currency: def.currency || null, warnings, rows, records: inOrder, grouped: displayOrder, fieldList, stats };
30974
31409
  }
30975
- function listAt(raw, path2) {
30976
- let { rows } = jsonPathRows(raw, path2 || "$");
31410
+ function listAt(raw, path3) {
31411
+ let { rows } = jsonPathRows(raw, path3 || "$");
30977
31412
  if (rows == null) rows = [];
30978
31413
  return Array.isArray(rows) ? rows : [rows];
30979
31414
  }
@@ -31059,7 +31494,7 @@ async function planPaged(def0, opts = {}) {
31059
31494
  if (!fields.length) return no2("undeclared fields (no rows to detect them from)");
31060
31495
  ds = { ...ds, fields };
31061
31496
  }
31062
- const strip = (fields) => fields.map(({ expr, path: path2, ...f4 }) => f4);
31497
+ const strip = (fields) => fields.map(({ expr, path: path3, ...f4 }) => f4);
31063
31498
  const windowDef = (first, last, done) => {
31064
31499
  const t = { ...gtable, sort: void 0, filters: void 0 };
31065
31500
  if (!last) delete t.footer;
@@ -31093,11 +31528,11 @@ async function planPaged(def0, opts = {}) {
31093
31528
  []
31094
31529
  ), pages: 0 };
31095
31530
  const L = groups.length;
31096
- const newAcc = (fs2) => fs2.map((f4) => f4.fn === "countrows" ? { n: 0 } : { agg: aggregator(f4.fn, fctx), err: null });
31531
+ const newAcc = (fs3) => fs3.map((f4) => f4.fn === "countrows" ? { n: 0 } : { agg: aggregator(f4.fn, fctx), err: null });
31097
31532
  const value = (a) => a.n ?? (a.err ? "#Error" : a.agg.value());
31098
- const addTo = (fs2, acc, r) => {
31533
+ const addTo = (fs3, acc, r) => {
31099
31534
  fctx.fields = r;
31100
- fs2.forEach((f4, i) => {
31535
+ fs3.forEach((f4, i) => {
31101
31536
  const a = acc[i];
31102
31537
  if (a.n != null) a.n++;
31103
31538
  else if (!a.err) {
@@ -31229,7 +31664,7 @@ async function planPaged(def0, opts = {}) {
31229
31664
  const m = await render(job.def, { ...opts, exportData: !!(opts.exportData || opts.tagged), sources: { __rows: { rows: job.rows } }, pageWindow: job.pageWindow });
31230
31665
  return { pages: m.pages, count: m.pages.length, nextFirst: m.pages[job.keep]?.firstRow, bookmarks: m.bookmarks, headings: m.headings, warnings: m.warnings };
31231
31666
  };
31232
- const run = o.run || local, at2 = o.run ? 2 * Math.max(1, Number(o.parallel) || 1) : 1;
31667
+ const run = o.run || local, at3 = o.run ? 2 * Math.max(1, Number(o.parallel) || 1) : 1;
31233
31668
  const queue = (
31234
31669
  /** @type {any[]} */
31235
31670
  []
@@ -31282,7 +31717,7 @@ async function planPaged(def0, opts = {}) {
31282
31717
  res.catch(() => {
31283
31718
  });
31284
31719
  queue.push({ job, res });
31285
- if (queue.length >= at2) {
31720
+ if (queue.length >= at3) {
31286
31721
  const q3 = queue.shift();
31287
31722
  yield* handOut(q3.job, await q3.res);
31288
31723
  }
@@ -32143,10 +32578,10 @@ function createPdfStream(sink, opt) {
32143
32578
  const flush = async () => {
32144
32579
  if (!size) return;
32145
32580
  const all = new Uint8Array(size);
32146
- let at2 = 0;
32581
+ let at3 = 0;
32147
32582
  for (const p of parts) {
32148
- all.set(p, at2);
32149
- at2 += p.length;
32583
+ all.set(p, at3);
32584
+ at3 += p.length;
32150
32585
  }
32151
32586
  parts = [];
32152
32587
  size = 0;
@@ -32446,10 +32881,10 @@ endobj
32446
32881
  row[6] = i & 255;
32447
32882
  }
32448
32883
  }
32449
- const at2 = (n5 - from) * 8;
32450
- rows[at2] = 2;
32884
+ const at3 = (n5 - from) * 8;
32885
+ rows[at3] = 2;
32451
32886
  for (let b = 0; b < 7; b++) {
32452
- rows[at2 + 1 + b] = row[b] - prev[b] & 255;
32887
+ rows[at3 + 1 + b] = row[b] - prev[b] & 255;
32453
32888
  prev[b] = row[b];
32454
32889
  }
32455
32890
  }
@@ -33427,10 +33862,10 @@ async function ownWriter(model, fontStore2, opt) {
33427
33862
  } }
33428
33863
  );
33429
33864
  const out = new Uint8Array(parts.reduce((n5, p) => n5 + p.length, 0));
33430
- let at2 = 0;
33865
+ let at3 = 0;
33431
33866
  for (const p of parts) {
33432
- out.set(p, at2);
33433
- at2 += p.length;
33867
+ out.set(p, at3);
33868
+ at3 += p.length;
33434
33869
  }
33435
33870
  return out;
33436
33871
  }
@@ -33486,7 +33921,7 @@ function plainEncoding(pf) {
33486
33921
  return w * size / f4.unitsPerEm;
33487
33922
  };
33488
33923
  const lit2 = /* @__PURE__ */ new Map();
33489
- const esc8 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
33924
+ const esc9 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
33490
33925
  e2.tjOf = (text2) => {
33491
33926
  let out = "", cur = "", any = false;
33492
33927
  for (const ch of text2) {
@@ -33515,7 +33950,7 @@ function plainEncoding(pf) {
33515
33950
  let b = lit2.get(cp);
33516
33951
  if (b === void 0) {
33517
33952
  const id = f4.glyphForCodePoint(cp).id;
33518
- lit2.set(cp, b = esc8(id >> 8) + esc8(id & 255));
33953
+ lit2.set(cp, b = esc9(id >> 8) + esc9(id & 255));
33519
33954
  }
33520
33955
  out += b;
33521
33956
  }
@@ -33624,24 +34059,24 @@ var usedKB = () => {
33624
34059
  var live = /* @__PURE__ */ new Set();
33625
34060
  var hooked = false;
33626
34061
  var sweep = () => {
33627
- const fs2 = node2("node:fs");
34062
+ const fs3 = node2("node:fs");
33628
34063
  for (const d of live) {
33629
34064
  try {
33630
- fs2.rmSync(d, { recursive: true, force: true });
34065
+ fs3.rmSync(d, { recursive: true, force: true });
33631
34066
  } catch {
33632
34067
  }
33633
34068
  }
33634
34069
  live.clear();
33635
34070
  };
33636
34071
  function sweepStale(root, staleMs) {
33637
- const fs2 = node2("node:fs"), path2 = node2("node:path");
34072
+ const fs3 = node2("node:fs"), path3 = node2("node:path");
33638
34073
  try {
33639
- for (const n5 of fs2.readdirSync(root)) {
34074
+ for (const n5 of fs3.readdirSync(root)) {
33640
34075
  if (!n5.startsWith("pw-spill-")) continue;
33641
- const d = path2.join(root, n5);
34076
+ const d = path3.join(root, n5);
33642
34077
  if (live.has(d)) continue;
33643
34078
  try {
33644
- if (Date.now() - fs2.statSync(d).mtimeMs > staleMs) fs2.rmSync(d, { recursive: true, force: true });
34079
+ if (Date.now() - fs3.statSync(d).mtimeMs > staleMs) fs3.rmSync(d, { recursive: true, force: true });
33645
34080
  } catch {
33646
34081
  }
33647
34082
  }
@@ -33650,9 +34085,9 @@ function sweepStale(root, staleMs) {
33650
34085
  }
33651
34086
  var MB = 1048576;
33652
34087
  function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB, frame: frame3 = 200, maxMB = 2048, totalMB = 8192, dir: root = node2("node:os").tmpdir(), staleMs = 18e4 } = {}) {
33653
- const fs2 = node2("node:fs"), path2 = node2("node:path"), v8 = node2("node:v8"), { threadId } = node2("node:worker_threads");
34088
+ const fs3 = node2("node:fs"), path3 = node2("node:path"), v8 = node2("node:v8"), { threadId } = node2("node:worker_threads");
33654
34089
  try {
33655
- fs2.accessSync(root, fs2.constants.W_OK);
34090
+ fs3.accessSync(root, fs3.constants.W_OK);
33656
34091
  } catch {
33657
34092
  throw Object.assign(new Error(`spill.dir "${root}" does not exist or is not writable`), { status: 400 });
33658
34093
  }
@@ -33671,15 +34106,15 @@ function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB,
33671
34106
  };
33672
34107
  const writeRun = async (batches) => {
33673
34108
  if (!dir) {
33674
- dir = fs2.mkdtempSync(path2.join(root, `pw-spill-${process.pid}-${threadId}-`));
34109
+ dir = fs3.mkdtempSync(path3.join(root, `pw-spill-${process.pid}-${threadId}-`));
33675
34110
  live.add(dir);
33676
34111
  if (!hooked) {
33677
34112
  hooked = true;
33678
34113
  process.once("exit", sweep);
33679
34114
  }
33680
34115
  }
33681
- const file = path2.join(dir, `run-${made++}`);
33682
- const fh = await fs2.promises.open(file, "wx", 384);
34116
+ const file = path3.join(dir, `run-${made++}`);
34117
+ const fh = await fs3.promises.open(file, "wx", 384);
33683
34118
  let size = 0;
33684
34119
  sizes.set(file, 0);
33685
34120
  try {
@@ -33808,7 +34243,7 @@ function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB,
33808
34243
  for (const f4 of group2) {
33809
34244
  onDisk -= sizes.get(f4) || 0;
33810
34245
  sizes.delete(f4);
33811
- await fs2.promises.rm(f4, { force: true });
34246
+ await fs3.promises.rm(f4, { force: true });
33812
34247
  }
33813
34248
  account();
33814
34249
  passes++;
@@ -33826,7 +34261,7 @@ function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB,
33826
34261
  const d = dir;
33827
34262
  dir = null;
33828
34263
  live.delete(d);
33829
- await fs2.promises.rm(d, { recursive: true, force: true }).catch(() => {
34264
+ await fs3.promises.rm(d, { recursive: true, force: true }).catch(() => {
33830
34265
  });
33831
34266
  }
33832
34267
  },
@@ -33848,8 +34283,8 @@ function approx(x, d = 0) {
33848
34283
  return n5;
33849
34284
  }
33850
34285
  async function openRun(file) {
33851
- const fs2 = node2("node:fs"), v8 = node2("node:v8");
33852
- const fh = await fs2.promises.open(file, "r");
34286
+ const fs3 = node2("node:fs"), v8 = node2("node:v8");
34287
+ const fh = await fs3.promises.open(file, "r");
33853
34288
  let pos = 0, batch = [], i = 0;
33854
34289
  const head = Buffer.alloc(4);
33855
34290
  return {
@@ -33954,7 +34389,7 @@ function setNameStrings(name, strings) {
33954
34389
  o.setUint16(0, 0);
33955
34390
  o.setUint16(2, count);
33956
34391
  o.setUint16(4, 6 + 12 * count);
33957
- let at2 = 6 + 12 * count;
34392
+ let at3 = 6 + 12 * count;
33958
34393
  recs.forEach((r, i) => {
33959
34394
  const p = 6 + 12 * i;
33960
34395
  o.setUint16(p, r.platform);
@@ -33962,9 +34397,9 @@ function setNameStrings(name, strings) {
33962
34397
  o.setUint16(p + 4, r.lang);
33963
34398
  o.setUint16(p + 6, r.id);
33964
34399
  o.setUint16(p + 8, r.raw.length);
33965
- o.setUint16(p + 10, at2 - (6 + 12 * count));
33966
- out.set(r.raw, at2);
33967
- at2 += r.raw.length;
34400
+ o.setUint16(p + 10, at3 - (6 + 12 * count));
34401
+ out.set(r.raw, at3);
34402
+ at3 += r.raw.length;
33968
34403
  });
33969
34404
  return out;
33970
34405
  }
@@ -34304,7 +34739,7 @@ async function htmlOf(model, fontStore2, opt) {
34304
34739
  }
34305
34740
  faces.push(`@font-face{font-family:"${fontFamilyCss(key)}";src:url(data:font/ttf;base64,${b642(bytes)}) format("truetype")}`);
34306
34741
  }
34307
- const esc8 = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;");
34742
+ const esc9 = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;");
34308
34743
  const anchors = /* @__PURE__ */ new Map();
34309
34744
  const jumpTo = (a) => {
34310
34745
  const to = a.page ? a : model.bookmarks?.find((b) => b.label === a.target) || model.headings?.find((b) => b.label === a.target);
@@ -34337,7 +34772,7 @@ async function htmlOf(model, fontStore2, opt) {
34337
34772
  } catch {
34338
34773
  }
34339
34774
  if (t && "href" in t) return `<a href="${attr(t.href)}"${t.external ? ' target="_blank" rel="noopener"' : ""}><rect${a}/>${ttl}</a>`;
34340
- if (t && "off" in t) return `<g class="pw-off"><rect${a}/><title>${esc8(t.off)}</title></g>`;
34775
+ if (t && "off" in t) return `<g class="pw-off"><rect${a}/><title>${esc9(t.off)}</title></g>`;
34341
34776
  return `<rect${a}/>`;
34342
34777
  }));
34343
34778
  const pages = model.pages.map((p, i) => {
@@ -34353,7 +34788,7 @@ async function htmlOf(model, fontStore2, opt) {
34353
34788
  const lang = opt.lang && /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/.test(opt.lang) ? opt.lang : "en";
34354
34789
  return `<!doctype html>
34355
34790
  <html lang="${data ? lang : "en"}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
34356
- ${csp}<title>${esc8(opt.title || model.name || "Report")}</title>
34791
+ ${csp}<title>${esc9(opt.title || model.name || "Report")}</title>
34357
34792
  <style>
34358
34793
  ${faces.join("\n")}
34359
34794
  html{background:#e6eaee}body{margin:0;padding:24px 12px;display:flex;flex-direction:column;align-items:center;gap:18px;font-family:system-ui,sans-serif}
@@ -34362,7 +34797,7 @@ html{background:#e6eaee}body{margin:0;padding:24px 12px;display:flex;flex-direct
34362
34797
  .page svg{display:block;width:100%;height:auto}
34363
34798
  @media print{html{background:#fff}body{padding:0;gap:0}.page{box-shadow:none;width:100%;break-after:page}@page{size:${model.width}pt ${model.height}pt;margin:0}}
34364
34799
  ${data ? DATA_CSS + "\n" : ""}</style></head><body>
34365
- ${data ? `<nav class="pw-bar" id="pw-bar" hidden><button type="button" data-view="pages" aria-pressed="true">${esc8(S3.pages)}</button><button type="button" data-view="tables" aria-pressed="false">${esc8(S3.tables)}</button></nav>
34800
+ ${data ? `<nav class="pw-bar" id="pw-bar" hidden><button type="button" data-view="pages" aria-pressed="true">${esc9(S3.pages)}</button><button type="button" data-view="tables" aria-pressed="false">${esc9(S3.tables)}</button></nav>
34366
34801
  ` : ""}${pages}
34367
34802
  ${data ? `<div id="pw-tables" hidden></div>
34368
34803
  <script type="application/json" id="pw-data">${JSON.stringify({ tables: data, strings: S3 }).replace(/</g, "\\u003c")}</script>
@@ -34522,8 +34957,8 @@ function chartXml(spec, sheet) {
34522
34957
  const per = t === "bubble" ? 3 : 2;
34523
34958
  const body = spec.series.map((s, i) => {
34524
34959
  const c = 1 + i * per, n5 = s.x.length;
34525
- return `<c:ser><c:idx val="${i}"/><c:order val="${i}"/><c:tx><c:strRef><c:f>${ref(sheet, c + 1, 1, c + 1, 1)}</c:f>${strCache([s.name])}</c:strRef></c:tx>${t === "bubble" ? fill(s.color) : `<c:spPr><a:ln w="19050"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="5"/>${fill(s.color)}</c:marker>`}<c:xVal><c:numRef><c:f>${ref(sheet, c, 2, c, n5 + 1)}</c:f>${numCache(s.x)}\
34526
- </c:numRef></c:xVal><c:yVal><c:numRef><c:f>${ref(sheet, c + 1, 2, c + 1, n5 + 1)}</c:f>${numCache(s.y, fmt2)}</c:numRef></c:yVal>` + (t === "bubble" ? `<c:bubbleSize><c:numRef><c:f>${ref(sheet, c + 2, 2, c + 2, n5 + 1)}</c:f>${numCache(s.size || [])}</c:numRef></c:bubbleSize><c:bubble3D val="0"/>` : '<c:smooth val="0"/>') + "</c:ser>";
34960
+ return `<c:ser><c:idx val="${i}"/><c:order val="${i}"/><c:tx><c:strRef><c:f>${ref(sheet, c + 1, 1, c + 1, 1)}</c:f>${strCache([s.name])}</c:strRef></c:tx>${t === "bubble" ? fill(s.color) : `<c:spPr><a:ln w="19050"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="5"/>${fill(s.color)}</c:marker>`}<c:xVal><c:numRef><c:f>${ref(sheet, c, 2, c, n5 + 1)}</c:f>${numCache(s.x)}${
34961
+ ""}</c:numRef></c:xVal><c:yVal><c:numRef><c:f>${ref(sheet, c + 1, 2, c + 1, n5 + 1)}</c:f>${numCache(s.y, fmt2)}</c:numRef></c:yVal>` + (t === "bubble" ? `<c:bubbleSize><c:numRef><c:f>${ref(sheet, c + 2, 2, c + 2, n5 + 1)}</c:f>${numCache(s.size || [])}</c:numRef></c:bubbleSize><c:bubble3D val="0"/>` : '<c:smooth val="0"/>') + "</c:ser>";
34527
34962
  }).join("");
34528
34963
  plot = t === "bubble" ? `<c:bubbleChart><c:varyColors val="0"/>${body}<c:bubbleScale val="100"/>${axIds(false)}</c:bubbleChart>` : `<c:scatterChart><c:scatterStyle val="lineMarker"/><c:varyColors val="0"/>${body}${axIds(false)}</c:scatterChart>`;
34529
34964
  axes = valAx(AX.cat, AX.val, "b", false, "General", spec.xTitle) + valAx(AX.val, AX.cat, "l", false, fmt2, spec.yTitle);
@@ -34534,18 +34969,18 @@ function chartXml(spec, sheet) {
34534
34969
  }
34535
34970
  var axTitle = (t) => t ? title(t) : "";
34536
34971
  function catAx(id, cross, pos, second, t) {
34537
- return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${second ? 1 : 0}"/><c:axPos val="${pos}"/>${axTitle(t)}<c:numFmt formatCode="General" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffs\
34538
- et val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
34972
+ return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${second ? 1 : 0}"/><c:axPos val="${pos}"/>${axTitle(t)}<c:numFmt formatCode="General" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffs${
34973
+ ""}et val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
34539
34974
  }
34540
34975
  function valAx(id, cross, pos, second, fmt2, t) {
34541
- return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="${pos}"/>${second ? "" : "<c:majorGridlines/>"}${axTitle(t)}<c:numFmt formatCode="${esc4(fmt2)}" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${second ? "max" : "autoZero"}"/\
34542
- ><c:crossBetween val="between"/></c:valAx>`;
34976
+ return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="${pos}"/>${second ? "" : "<c:majorGridlines/>"}${axTitle(t)}<c:numFmt formatCode="${esc4(fmt2)}" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${second ? "max" : "autoZero"}"/${
34977
+ ""}><c:crossBetween val="between"/></c:valAx>`;
34543
34978
  }
34544
34979
  var PALETTE2 = ["#2563eb", "#16a34a", "#f59e0b", "#dc2626", "#7c3aed", "#0891b2", "#db2777", "#65a30d", "#ea580c", "#475569"];
34545
34980
  var drawingXml = (c0, r0, cols, rows) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
34546
- <xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><xdr:twoCellAnchor editAs="oneCell"><xdr:from><xdr:col>${c0}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:to><xdr:col>${c0 + cols}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0 + rows}</x\
34547
- dr:row><xdr:rowOff>0</xdr:rowOff></xdr:to><xdr:graphicFrame macro=""><xdr:nvGraphicFramePr><xdr:cNvPr id="2" name="Chart 1"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr><xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmln\
34548
- s:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"/></a:graphicData></a:graphic></xdr:graphicFrame><xdr:clientData/></xdr:twoCellAnchor></xdr:wsDr>`;
34981
+ <xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><xdr:twoCellAnchor editAs="oneCell"><xdr:from><xdr:col>${c0}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:to><xdr:col>${c0 + cols}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0 + rows}</x${
34982
+ ""}dr:row><xdr:rowOff>0</xdr:rowOff></xdr:to><xdr:graphicFrame macro=""><xdr:nvGraphicFramePr><xdr:cNvPr id="2" name="Chart 1"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr><xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmln${
34983
+ ""}s:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"/></a:graphicData></a:graphic></xdr:graphicFrame><xdr:clientData/></xdr:twoCellAnchor></xdr:wsDr>`;
34549
34984
  var rels = (list2) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
34550
34985
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${list2.join("")}</Relationships>`;
34551
34986
  var rel = (id, type, target) => `<Relationship Id="${id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/${type}" Target="${target}"/>`;
@@ -34583,8 +35018,8 @@ function addCharts(bytes, charts) {
34583
35018
  let ws = read(sheetPath) || "";
34584
35019
  if (!/xmlns:r=/.test(ws.slice(0, 600))) ws = ws.replace("<worksheet ", '<worksheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" ');
34585
35020
  const before = ["<legacyDrawing", "<legacyDrawingHF", "<picture", "<oleObjects", "<controls", "<webPublishItems", "<tableParts", "<extLst", "</worksheet>"].map((t) => ws.indexOf(t)).filter((k) => k >= 0);
34586
- const at2 = Math.min(...before);
34587
- write(sheetPath, ws.slice(0, at2) + '<drawing r:id="rIdPW1"/>' + ws.slice(at2));
35021
+ const at3 = Math.min(...before);
35022
+ write(sheetPath, ws.slice(0, at3) + '<drawing r:id="rIdPW1"/>' + ws.slice(at3));
34588
35023
  types = types.replace("</Types>", `<Override PartName="/xl/charts/chartPW${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/><Override PartName="/xl/drawings/drawingPW${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.drawing+xml"/></Types>`);
34589
35024
  });
34590
35025
  write("[Content_Types].xml", types);
@@ -34697,9 +35132,9 @@ var Book = class {
34697
35132
  const [fmt2, bold, fill3] = k.split("|").map(Number);
34698
35133
  return `<xf numFmtId="${fmt2 || 0}" fontId="${bold ? 1 : 0}" fillId="${fill3 ? 2 : 0}" borderId="0" xfId="0"${fmt2 ? ' applyNumberFormat="1"' : ""}${bold ? ' applyFont="1"' : ""}${fill3 ? ' applyFill="1"' : ""}/>`;
34699
35134
  }).join("");
34700
- return `${XML}<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${fmts ? `<numFmts count="${this.numFmts.size}">${fmts}</numFmts>` : ""}<fonts count="2"><font><sz val="11"/><name val="Calibri"/><family val="2"/></font><font><b/><sz val="11"/><name val="Calibri"/><family val="2"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><pat\
34701
- ternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="${HEADER_FILL}"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${this.styles.size}">${xfs}</cellXfs><cellSt\
34702
- yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
35135
+ return `${XML}<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${fmts ? `<numFmts count="${this.numFmts.size}">${fmts}</numFmts>` : ""}<fonts count="2"><font><sz val="11"/><name val="Calibri"/><family val="2"/></font><font><b/><sz val="11"/><name val="Calibri"/><family val="2"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><pat${
35136
+ ""}ternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="${HEADER_FILL}"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${this.styles.size}">${xfs}</cellXfs><cellSt${
35137
+ ""}yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
34703
35138
  }
34704
35139
  /** The .xlsx bytes. */
34705
35140
  write() {
@@ -34719,8 +35154,8 @@ yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></s
34719
35154
  const anchors = sh.images.map((im, k) => {
34720
35155
  img++;
34721
35156
  put(`xl/media/image${img}.${im.ext}`, im.bytes);
34722
- return `<xdr:oneCellAnchor><xdr:from><xdr:col>${im.col}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${im.row}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="${k + 2}" name="Picture ${k + 1}"/><xdr:cNvPicPr><a:picLocks noChangeAspect="1"/></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill><\
34723
- a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic><xdr:clientData/></xdr:oneCellAnchor>`;
35157
+ return `<xdr:oneCellAnchor><xdr:from><xdr:col>${im.col}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${im.row}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="${k + 2}" name="Picture ${k + 1}"/><xdr:cNvPicPr><a:picLocks noChangeAspect="1"/></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill><${
35158
+ ""}a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic><xdr:clientData/></xdr:oneCellAnchor>`;
34724
35159
  });
34725
35160
  let first = img - sh.images.length;
34726
35161
  put(`xl/drawings/_rels/drawing${n5}.xml.rels`, rels2(sh.images.map((im, k) => [`rId${k + 1}`, "image", `../media/image${++first}.${im.ext}`])));
@@ -34741,12 +35176,12 @@ a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill
34741
35176
  put("xl/styles.xml", this.stylesXml());
34742
35177
  put("xl/workbook.xml", `${XML}<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="${R}"><bookViews><workbookView/></bookViews><sheets>${this.sheets.map((s, i) => `<sheet name="${esc4(s.name)}" sheetId="${i + 1}" r:id="rId${i + 1}"/>`).join("")}</sheets><calcPr calcId="171027"${this.fullCalcOnLoad ? ' fullCalcOnLoad="1"' : ""}/></workbook>`);
34743
35178
  put("xl/_rels/workbook.xml.rels", rels2([...this.sheets.map((s, i) => [`rId${i + 1}`, "worksheet", `worksheets/sheet${i + 1}.xml`]), [`rId${this.sheets.length + 1}`, "styles", "styles.xml"]]));
34744
- put("docProps/core.xml", `${XML}<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>${esc4(this.title)}</dc:title><dc:creator>${esc4(this.creator)}</dc:creator><dcterms:created xsi:type="dcterms:W\
34745
- 3CDTF">${(/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z")}</dcterms:created></cp:coreProperties>`);
35179
+ put("docProps/core.xml", `${XML}<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>${esc4(this.title)}</dc:title><dc:creator>${esc4(this.creator)}</dc:creator><dcterms:created xsi:type="dcterms:W${
35180
+ ""}3CDTF">${(/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z")}</dcterms:created></cp:coreProperties>`);
34746
35181
  put("_rels/.rels", rels2([["rId1", "officeDocument", "xl/workbook.xml"], ["rId2", "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties", "docProps/core.xml"]]));
34747
- put("[Content_Types].xml", `${XML}<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"/><Override PartName="/xl/workbo\
34748
- ok.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>${over.map(([p, t]) => `<Override PartName="${p}" ContentType="${t}\
34749
- "/>`).join("")}</Types>`);
35182
+ put("[Content_Types].xml", `${XML}<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"/><Override PartName="/xl/workbo${
35183
+ ""}ok.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>${over.map(([p, t]) => `<Override PartName="${p}" ContentType="${t}${
35184
+ ""}"/>`).join("")}</Types>`);
34750
35185
  return out;
34751
35186
  }
34752
35187
  };
@@ -34856,11 +35291,11 @@ function subtotalFn(c, st) {
34856
35291
  }
34857
35292
  return null;
34858
35293
  }
34859
- function totalFormula(rows, at2, c, made) {
34860
- const row = rows[at2];
35294
+ function totalFormula(rows, at3, c, made) {
35295
+ const row = rows[at3];
34861
35296
  if (typeof c.value !== "number" || !Number.isFinite(c.value)) return null;
34862
35297
  const covered = [];
34863
- for (let k = at2 - 1; k >= 0; k--) {
35298
+ for (let k = at3 - 1; k >= 0; k--) {
34864
35299
  const r = rows[k];
34865
35300
  if (r.kind === "header") break;
34866
35301
  if (row.kind === "groupFooter" && (r.kind === "groupFooter" || r.kind === "groupHeader") && r.level <= row.level) break;
@@ -35022,8 +35457,8 @@ init_fonts();
35022
35457
  var TW = 20;
35023
35458
  var EMU = 12700;
35024
35459
  var CONTENT_TYPES = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35025
- <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\
35026
- 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>`;
35460
+ <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${
35461
+ ""}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>`;
35027
35462
  var RELS = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35028
35463
  <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>`;
35029
35464
  var XML_CHUNK = 4 * 1024 * 1024;
@@ -35148,8 +35583,8 @@ function table(cells, indentPt, pics) {
35148
35583
  }
35149
35584
  return `<w:tr>${r.kind === "header" ? "<w:trPr><w:tblHeader/></w:trPr>" : ""}${tcs.join("")}</w:tr>`;
35150
35585
  }).join("");
35151
- return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${indentPt > 0 ? `<w:tblInd w:w="${Math.round(indentPt * TW)}" w:type="dxa"/>` : ""}<w:tblBorders>${tblB}</w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="60" w:type="dxa"/><w:right w:w="60" w:type="dxa"/></w:tblCellMar></w:tblPr><w:tblGrid>${grid}</w:tblGrid>${out}</w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="0"/\
35152
- ></w:pPr></w:p>`;
35586
+ return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${indentPt > 0 ? `<w:tblInd w:w="${Math.round(indentPt * TW)}" w:type="dxa"/>` : ""}<w:tblBorders>${tblB}</w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="60" w:type="dxa"/><w:right w:w="60" w:type="dxa"/></w:tblCellMar></w:tblPr><w:tblGrid>${grid}</w:tblGrid>${out}</w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="0"/${
35587
+ ""}></w:pPr></w:p>`;
35153
35588
  }
35154
35589
  function layoutRow(row, margin) {
35155
35590
  const cols = [], cells = [];
@@ -35167,8 +35602,8 @@ function layoutRow(row, margin) {
35167
35602
  x = c.x + c.w;
35168
35603
  }
35169
35604
  const ind = row[0].it.clip.x - margin;
35170
- return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${Math.abs(ind) > 0.5 ? `<w:tblInd w:w="${Math.round(ind * TW)}" w:type="dxa"/>` : ""}<w:tblBorders><w:top w:val="nil"/><w:left w:val="nil"/><w:bottom w:val="nil"/><w:right w:val="nil"/><w:insideH w:val="nil"/><w:insideV w:val="nil"/></w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="0" w:type="dxa"/><w:right w:w="0" w:ty\
35171
- pe="dxa"/></w:tblCellMar><w:tblLook w:val="0000"/></w:tblPr><w:tblGrid>${cols.map((w) => `<w:gridCol w:w="${Math.round(w * TW)}"/>`).join("")}</w:tblGrid><w:tr>${cells.join("")}</w:tr></w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="40"/><w:rPr><w:sz w:val="4"/></w:rPr></w:pPr></w:p>`;
35605
+ return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${Math.abs(ind) > 0.5 ? `<w:tblInd w:w="${Math.round(ind * TW)}" w:type="dxa"/>` : ""}<w:tblBorders><w:top w:val="nil"/><w:left w:val="nil"/><w:bottom w:val="nil"/><w:right w:val="nil"/><w:insideH w:val="nil"/><w:insideV w:val="nil"/></w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="0" w:type="dxa"/><w:right w:w="0" w:ty${
35606
+ ""}pe="dxa"/></w:tblCellMar><w:tblLook w:val="0000"/></w:tblPr><w:tblGrid>${cols.map((w) => `<w:gridCol w:w="${Math.round(w * TW)}"/>`).join("")}</w:tblGrid><w:tr>${cells.join("")}</w:tr></w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="40"/><w:rPr><w:sz w:val="4"/></w:rPr></w:pPr></w:p>`;
35172
35607
  }
35173
35608
  function exportDocx(model, opt = {}) {
35174
35609
  return withDeadline(
@@ -35184,10 +35619,10 @@ async function docxOf(model, opt) {
35184
35619
  chunks.push(u8);
35185
35620
  });
35186
35621
  const bytes = new Uint8Array(chunks.reduce((n5, c) => n5 + c.length, 0));
35187
- let at2 = 0;
35622
+ let at3 = 0;
35188
35623
  for (const c of chunks) {
35189
- bytes.set(c, at2);
35190
- at2 += c.length;
35624
+ bytes.set(c, at3);
35625
+ at3 += c.length;
35191
35626
  }
35192
35627
  return bytes;
35193
35628
  }
@@ -35207,8 +35642,8 @@ async function writeDocx(pages, model, opt, put) {
35207
35642
  const id = ++docPr, cx = Math.max(1, Math.round(pic.w * EMU)), cy = Math.max(1, Math.round(pic.h * EMU));
35208
35643
  const name = `Picture ${id}`, descr = alt ? ` descr="${esc5(alt)}"` : "";
35209
35644
  const ext = svg ? `<a:extLst><a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="${svg}"/></a:ext></a:extLst>` : "";
35210
- return `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${cx}" cy="${cy}"/><wp:docPr id="${id}" name="${name}"${descr}/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:nvPicPr><pic:cNvPr id="${id}" name="${name}"${descr}/\
35211
- ><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
35645
+ return `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${cx}" cy="${cy}"/><wp:docPr id="${id}" name="${name}"${descr}/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:nvPicPr><pic:cNvPr id="${id}" name="${name}"${descr}/${
35646
+ ""}><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
35212
35647
  };
35213
35648
  const picOpt = { fontStore: opt.fontStore, fetchImage: opt.fetchImage, rasterize: opt.rasterize };
35214
35649
  const pageXml = async (pg) => {
@@ -35351,12 +35786,12 @@ async function writeDocx(pages, model, opt, put) {
35351
35786
  const lang = `<w:lang w:val="${esc5(opt.lang || model.locale || "en-US")}"/>`;
35352
35787
  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("");
35353
35788
  const styles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35354
- <w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Inter" w:hAnsi="Inter" w:cs="Inter"/><w:sz w:val="18"/>${lang}</w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:\
35355
- name w:val="Normal"/></w:style>${headings}</w:styles>`;
35789
+ <w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Inter" w:hAnsi="Inter" w:cs="Inter"/><w:sz w:val="18"/>${lang}</w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:${
35790
+ ""}name w:val="Normal"/></w:style>${headings}</w:styles>`;
35356
35791
  const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
35357
35792
  const core = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35358
- <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>${esc5(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc5(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type=\
35359
- "dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
35793
+ <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>${esc5(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc5(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type=${
35794
+ ""}"dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
35360
35795
  await file("word/_rels/document.xml.rels", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35361
35796
  <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>`));
35362
35797
  await file("word/styles.xml", strToU83(styles));
@@ -35446,8 +35881,8 @@ async function pptxOf(model, opt) {
35446
35881
  const svg = pic.png && pic.svg ? media(strToU84(pic.svg), "svg") : null;
35447
35882
  const n5 = ++id;
35448
35883
  const ext = svg ? `<a:extLst><a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="${svg}"/></a:ext></a:extLst>` : "";
35449
- return `<p:pic><p:nvPicPr><p:cNvPr id="${n5}" name="Picture ${n5}" descr="${esc6(alt)}"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="${e(pic.x)}" y="${e(pic.y)}"/><a:ext cx="${Math.max(1, e(pic.w))}" cy="${Math.max(1, e(pic.h))}"/><\
35450
- /a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
35884
+ return `<p:pic><p:nvPicPr><p:cNvPr id="${n5}" name="Picture ${n5}" descr="${esc6(alt)}"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="${e(pic.x)}" y="${e(pic.y)}"/><a:ext cx="${Math.max(1, e(pic.w))}" cy="${Math.max(1, e(pic.h))}"/><${
35885
+ ""}/a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
35451
35886
  };
35452
35887
  const sp = (name, x, y, w, h, geom, body, extra = "") => {
35453
35888
  const n5 = ++id;
@@ -35530,43 +35965,133 @@ async function pptxOf(model, opt) {
35530
35965
  slides.push(pi + 1);
35531
35966
  }
35532
35967
  const cx = Math.min(51206400, Math.max(914400, e(W2))), cy = Math.min(51206400, Math.max(914400, e(H)));
35533
- files["ppt/presentation.xml"] = strToU84(`${XML2}<p:presentation ${NS2} saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>${slides.map((n5, i) => `<p:sldId id="${256 + i}" r:id="rId${n5 + 2}"/>`).join("")}</p:sldIdLst><p:sldSz cx="${cx}" cy="${cy}"/><p:notesSz cx="${cy}" cy="${cx}"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="${lang}\
35534
- "/></a:defPPr></p:defaultTextStyle></p:presentation>`);
35535
- files["ppt/_rels/presentation.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\
35536
- " Target="theme/theme1.xml"/>${slides.map((n5) => `<Relationship Id="rId${n5 + 2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide${n5}.xml"/>`).join("")}</Relationships>`);
35968
+ files["ppt/presentation.xml"] = strToU84(`${XML2}<p:presentation ${NS2} saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>${slides.map((n5, i) => `<p:sldId id="${256 + i}" r:id="rId${n5 + 2}"/>`).join("")}</p:sldIdLst><p:sldSz cx="${cx}" cy="${cy}"/><p:notesSz cx="${cy}" cy="${cx}"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="${lang}${
35969
+ ""}"/></a:defPPr></p:defaultTextStyle></p:presentation>`);
35970
+ files["ppt/_rels/presentation.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme${
35971
+ ""}" Target="theme/theme1.xml"/>${slides.map((n5) => `<Relationship Id="rId${n5 + 2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide${n5}.xml"/>`).join("")}</Relationships>`);
35537
35972
  const emptyTree = '<p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/></p:spTree>';
35538
- files["ppt/slideMasters/slideMaster1.xml"] = strToU84(`${XML2}<p:sldMaster ${NS2}><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>${emptyTree}</p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLay\
35539
- outId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst><p:txStyles><p:titleStyle><a:lvl1pPr><a:defRPr sz="2400"/></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:bodyStyle><p:otherStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:otherStyle></p:txStyles></p:sldMaster>`);
35540
- files["ppt/slideMasters/_rels/slideMaster1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/rel\
35541
- ationships/theme" Target="../theme/theme1.xml"/></Relationships>`);
35973
+ files["ppt/slideMasters/slideMaster1.xml"] = strToU84(`${XML2}<p:sldMaster ${NS2}><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>${emptyTree}</p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLay${
35974
+ ""}outId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst><p:txStyles><p:titleStyle><a:lvl1pPr><a:defRPr sz="2400"/></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:bodyStyle><p:otherStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:otherStyle></p:txStyles></p:sldMaster>`);
35975
+ files["ppt/slideMasters/_rels/slideMaster1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/rel${
35976
+ ""}ationships/theme" Target="../theme/theme1.xml"/></Relationships>`);
35542
35977
  files["ppt/slideLayouts/slideLayout1.xml"] = strToU84(`${XML2}<p:sldLayout ${NS2} type="blank" preserve="1"><p:cSld name="Blank">${emptyTree}</p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr></p:sldLayout>`);
35543
35978
  files["ppt/slideLayouts/_rels/slideLayout1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster1.xml"/></Relationships>`);
35544
35979
  files["ppt/theme/theme1.xml"] = strToU84(THEME);
35545
35980
  const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
35546
- files["docProps/core.xml"] = strToU84(`${XML2}<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>${esc6(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc6(opt.author)}\
35547
- </dc:creator>` : ""}<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`);
35548
- files["_rels/.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docP\
35549
- rops/core.xml"/></Relationships>`);
35550
- files["[Content_Types].xml"] = strToU84(`${XML2}<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\
35551
- ="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\
35552
- 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\
35553
- ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
35981
+ files["docProps/core.xml"] = strToU84(`${XML2}<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>${esc6(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc6(opt.author)}${
35982
+ ""}</dc:creator>` : ""}<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`);
35983
+ files["_rels/.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docP${
35984
+ ""}rops/core.xml"/></Relationships>`);
35985
+ files["[Content_Types].xml"] = strToU84(`${XML2}<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${
35986
+ ""}="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${
35987
+ ""}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${
35988
+ ""}ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
35554
35989
  return zipSync3(files, { level: 6 });
35555
35990
  }
35556
- 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\
35557
- 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\
35558
- ypeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Inter"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="ReportWright"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="\
35559
- 6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="12700"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="19050"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyl\
35560
- eLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`;
35991
+ 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${
35992
+ ""}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${
35993
+ ""}ypeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Inter"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="ReportWright"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="${
35994
+ ""}6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="12700"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="19050"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyl${
35995
+ ""}eLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`;
35996
+
35997
+ // package.json
35998
+ var package_default = {
35999
+ name: "reportwright",
36000
+ version: "0.13.2-rc.1",
36001
+ license: "MIT",
36002
+ private: true,
36003
+ engines: { node: "22.x" },
36004
+ type: "module",
36005
+ bin: {
36006
+ reportwright: "bin/pw.mjs",
36007
+ pw: "bin/pw.mjs"
36008
+ },
36009
+ scripts: {
36010
+ dev: "next dev -p 3000",
36011
+ build: "node scripts/build-embed.mjs && node scripts/build-worker.mjs && next build",
36012
+ start: "next start -p 3000",
36013
+ test: "vitest run",
36014
+ pw: "node bin/pw.mjs",
36015
+ "test:reports": "node bin/pw.mjs test reports",
36016
+ "test:diff": "vitest run tests/diff",
36017
+ "diff:engines": "node scripts/diff-engines.mjs",
36018
+ "fonts:cjk": "node scripts/fetch-fonts-cjk.mjs",
36019
+ "lint:engine": "node scripts/check-engine-boundary.mjs",
36020
+ typecheck: "node scripts/typecheck.mjs",
36021
+ "test:e2e": ("for t in build-from-scratch smoke expr-editor phase2 phase3 phase4 api progressive phase-bc data-setup galleries charts-p5 tablix ai designer-gaps reuse ssrs-import outline-charts layout-charts-b4 exports-b2 import-b6 data-xml gov-b5 ux-r1c r3b-conflict r4-fixes b2-ui b2-a11y b6j-viewer-handle b6k-designer-a11y b7a-axe b6k-designer-csp viewer-strict-csp viewer-font-errors viewer-e"+
36022
+ "xport-in-ready drilldown fonts standalone-viewer vite-build react-wrapper; do node tests/e2e/$t.mjs || exit 1; done"),
36023
+ sample: "node scripts/make-sample.mjs",
36024
+ "build:embed": "node scripts/build-embed.mjs",
36025
+ "build:packages": "node scripts/build-embed.mjs && node scripts/build-packages.mjs",
36026
+ "scan:packages": "node scripts/scan-packages.mjs",
36027
+ perf: "node scripts/perf.mjs",
36028
+ "build:site": "node scripts/build-site.mjs"
36029
+ },
36030
+ dependencies: {
36031
+ "@anthropic-ai/sdk": "^0.131.0",
36032
+ "@codemirror/autocomplete": "^6.20.3",
36033
+ "@codemirror/commands": "^6.11.1",
36034
+ "@codemirror/language": "^6.12.4",
36035
+ "@codemirror/state": "^6.7.6",
36036
+ "@codemirror/view": "^6.43.13",
36037
+ "@lezer/highlight": "^1.2.5",
36038
+ "@node-saml/node-saml": "^5.1.0",
36039
+ "@pdf-lib/fontkit": "^1.1.1",
36040
+ "@pdf-lib/standard-fonts": "^1.0.0",
36041
+ "@signpdf/placeholder-pdf-lib": "^3.3.0",
36042
+ "@signpdf/signer-p12": "^3.3.0",
36043
+ "@signpdf/signpdf": "^3.3.0",
36044
+ "bidi-js": "~1.0.3",
36045
+ "bwip-js": "^4.11.4",
36046
+ fflate: "^0.8.3",
36047
+ harfbuzzjs: "^1.6.2",
36048
+ immer: "^11.1.21",
36049
+ jose: "^6.2.12",
36050
+ next: "^16.3.8",
36051
+ "node-forge": "^1.4.0",
36052
+ nodemailer: "^10.0.14",
36053
+ "pdf-lib": "^1.17.1",
36054
+ react: "^19.3.0",
36055
+ "react-dom": "^19.3.0",
36056
+ zustand: "^5.0.15"
36057
+ },
36058
+ devDependencies: {
36059
+ "@expo-google-fonts/inter": "^0.4.2",
36060
+ "@expo-google-fonts/jetbrains-mono": "^0.4.1",
36061
+ "axe-core": "^4.14.0",
36062
+ esbuild: "^0.28.2",
36063
+ exceljs: "^4.4.0",
36064
+ playwright: "^1.56.0",
36065
+ typescript: "^5.9.3",
36066
+ vitest: "^5.0.3",
36067
+ "xml-crypto": "^6.3.2"
36068
+ },
36069
+ overrides: {
36070
+ uuid: "^11.1.1"
36071
+ },
36072
+ optionalDependencies: {
36073
+ "@google-cloud/bigquery": "^9.1.0",
36074
+ mssql: "^12.7.2",
36075
+ mysql2: "^3.24.5",
36076
+ oracledb: "^7.0.1",
36077
+ pg: "^8.23.1",
36078
+ "snowflake-sdk": "^3.4.0"
36079
+ }
36080
+ };
35561
36081
 
35562
36082
  // bin/pw.mjs
35563
- var ROOT2 = path.join(import.meta.dirname, "..");
35564
- var PUB = fs.existsSync(path.join(ROOT2, "public", "fonts")) ? path.join(ROOT2, "public") : path.join(path.dirname(createRequire(import.meta.url).resolve("@reportwright/fonts/package.json")), "public");
36083
+ var ROOT2 = path2.join(import.meta.dirname, "..");
36084
+ var PUB = fs2.existsSync(path2.join(ROOT2, "public", "fonts")) ? path2.join(ROOT2, "public") : path2.join(path2.dirname(createRequire(import.meta.url).resolve("@reportwright/fonts/package.json")), "public");
35565
36085
  var HELP = `pw render <report.pw.json> [-p name=value]… [-d source=data.json]… [-f pdf|xlsx|docx|pptx|html|csv|json|txt] [-o file|-] [--base URL [--allow-internal]] [--pdfa] [--ua]
35566
36086
  [--values] [--static] [--layout]
35567
36087
  [--password PW] [--owner-password PW] [--deny print|modify|copy|annotate|fillForms|accessibility|assemble|printHighQuality]…
35568
36088
  pw import <report.jrxml|.rdl|.rptdesign> [-o out.pw.json]
35569
36089
  convert a JasperReports, SSRS or BIRT report to a ReportWright definition
36090
+ pw import <folder> -o <outDir> [--recursive] [--force] [--verify] [--report path] [--max-files N] [--max-bytes N]
36091
+ bulk import (.rdl, .rdlc, .rds, .jrxml, .jrtx, .rptdesign, .rdlx-json and images) into
36092
+ outDir with import-report.json and .html; never overwrites an output edited since the
36093
+ last import (--force does); exit 0 all imported, 2 some failed, 1 none (see the CLI README)
36094
+ pw --version, pw -v the CLI and engine versions
35570
36095
  pw test [folder] [--update] [--layout]
35571
36096
  render every <folder>/__tests__/*.test.json case and compare it with its snapshot
35572
36097
  (the words; --layout: the layout, see the CLI README)
@@ -35593,9 +36118,9 @@ pw migrate-storage --to <url> [--from file|<url>] (SERVER ONLY, as above)
35593
36118
  jobs, fonts, settings, blobs, the audit log) from one storage to another, e.g. the
35594
36119
  files in this folder to sqlite:/srv/pw.db or postgres://…; stop the server first
35595
36120
  Exit codes: 0 ok, 1 a test failed, the pages differ or the audit log does not check, 2 bad usage.`;
35596
- var fontStore = new FontStore((k) => fs.readFileSync(path.join(PUB, "fonts", fontFile(k))));
35597
- var subset = createSubsetter(() => fs.promises.readFile(path.join(PUB, "harfbuzz-subset.wasm")));
35598
- var readJson = (f4) => JSON.parse(fs.readFileSync(f4, "utf8").replace(/^/, ""));
36121
+ var fontStore = new FontStore((k) => fs2.readFileSync(path2.join(PUB, "fonts", fontFile(k))));
36122
+ var subset = createSubsetter(() => fs2.promises.readFile(path2.join(PUB, "harfbuzz-subset.wasm")));
36123
+ var readJson = (f4) => JSON.parse(fs2.readFileSync(f4, "utf8").replace(/^/, ""));
35599
36124
  var pairs2 = (list2 = []) => Object.fromEntries(list2.map((s) => {
35600
36125
  const i = s.indexOf("=");
35601
36126
  if (i < 1) usage(`"${s}" should be name=value`);
@@ -35620,7 +36145,7 @@ function withData(def, data) {
35620
36145
  var siblingLoader = (file) => async (id) => {
35621
36146
  if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(id)) throw new Error(`Report "${id}" not found`);
35622
36147
  try {
35623
- return readJson(path.join(path.dirname(path.resolve(file)), `${id}.pw.json`));
36148
+ return readJson(path2.join(path2.dirname(path2.resolve(file)), `${id}.pw.json`));
35624
36149
  } catch {
35625
36150
  throw new Error(`Report "${id}" not found`);
35626
36151
  }
@@ -35652,10 +36177,10 @@ function renderFailed(e2, base) {
35652
36177
  async function writePdf(def, { parameters = {}, data, base, internal = false, file, exportData = false }, pdfOpts, out) {
35653
36178
  const d = withData(def, data);
35654
36179
  const tmp = `${out}.${process.pid}.part`;
35655
- const sink = fs.createWriteStream(tmp);
36180
+ const sink = fs2.createWriteStream(tmp);
35656
36181
  const stop = (sig, n5) => () => {
35657
36182
  sink.destroy();
35658
- fs.rmSync(tmp, { force: true });
36183
+ fs2.rmSync(tmp, { force: true });
35659
36184
  process.exit(128 + n5);
35660
36185
  };
35661
36186
  const sigs = [["SIGINT", 2], ["SIGTERM", 15], ["SIGHUP", 1]].map(([s, n5]) => [s, stop(s, n5)]);
@@ -35676,11 +36201,11 @@ async function writePdf(def, { parameters = {}, data, base, internal = false, fi
35676
36201
  sink.once("error", no2);
35677
36202
  sink.end(ok);
35678
36203
  });
35679
- fs.renameSync(tmp, out);
36204
+ fs2.renameSync(tmp, out);
35680
36205
  return { pages: r.pages, streamed: r.streamed, warnings: uniq2(r.streamed ? r.warnings : r.warnings.slice(1)) };
35681
36206
  } catch (e2) {
35682
36207
  sink.destroy();
35683
- fs.rmSync(tmp, { force: true });
36208
+ fs2.rmSync(tmp, { force: true });
35684
36209
  renderFailed(e2, base);
35685
36210
  } finally {
35686
36211
  for (const [s, f4] of sigs) process.off(s, f4);
@@ -35707,20 +36232,20 @@ function diffLines(a, b, context = 2) {
35707
36232
  const keep = ops.map((o, k) => o[0] !== " " || ops.slice(Math.max(0, k - context), k + context + 1).some((x) => x[0] !== " "));
35708
36233
  return ops.filter((_, k) => keep[k]).map(([op, line3]) => `${op} ${line3}`);
35709
36234
  }
35710
- function compare(label, before, after) {
36235
+ function compare(label, before, after, out = console.log) {
35711
36236
  const pa = pageTexts(before), pb = pageTexts(after);
35712
36237
  let changed = false;
35713
36238
  if (pa.length !== pb.length) {
35714
- console.log(`${label}: ${pa.length} pages → ${pb.length} pages`);
36239
+ out(`${label}: ${pa.length} pages → ${pb.length} pages`);
35715
36240
  changed = true;
35716
36241
  }
35717
36242
  for (let k = 0; k < Math.max(pa.length, pb.length); k++) {
35718
36243
  const d = diffLines(pa[k] || [], pb[k] || []);
35719
36244
  if (!d.some((l) => l[0] !== " ")) continue;
35720
36245
  changed = true;
35721
- console.log(`${label}: page ${k + 1} changed`);
35722
- for (const l of d.slice(0, 60)) console.log(l);
35723
- if (d.length > 60) console.log(` … ${d.length - 60} more lines`);
36246
+ out(`${label}: page ${k + 1} changed`);
36247
+ for (const l of d.slice(0, 60)) out(l);
36248
+ if (d.length > 60) out(` … ${d.length - 60} more lines`);
35724
36249
  }
35725
36250
  return changed;
35726
36251
  }
@@ -35741,8 +36266,8 @@ async function cmdRender(args) {
35741
36266
  if (encrypt && fmt2 !== "pdf") usage("--password, --owner-password and --deny apply to -f pdf only");
35742
36267
  if (encrypt && values.pdfa) usage("a PDF/A file cannot have a password");
35743
36268
  if (values.ua && fmt2 !== "pdf") usage("--ua applies to -f pdf only");
35744
- const out = values.o ?? `${path.basename(positionals[0]).replace(/\.pw\.json$|\.json$/, "")}.${fmt2}`;
35745
- const pdfOpts = () => ({ 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 });
36269
+ const out = values.o ?? `${path2.basename(positionals[0]).replace(/\.pw\.json$|\.json$/, "")}.${fmt2}`;
36270
+ const pdfOpts = () => ({ title: def.name, subset, encrypt, drillBase: values.base, pdfa: values.pdfa ? { icc: fs2.readFileSync(path2.join(PUB, "icc", "sRGB-v2-magic.icc")) } : void 0, tagged: values.ua ? { lang: def.locale || "en" } : void 0 });
35746
36271
  if (fmt2 === "pdf" && out !== "-") {
35747
36272
  const r = await writePdf(def, ro, pdfOpts(), out);
35748
36273
  console.error(`pw: wrote ${out} (${r.pages} pages${r.streamed ? ", streamed" : ""}${r.warnings.length ? `, ${r.warnings.length} warnings` : ""})`);
@@ -35762,7 +36287,7 @@ async function cmdRender(args) {
35762
36287
  else usage(`unknown format "${fmt2}"`);
35763
36288
  if (out === "-") process.stdout.write(typeof bytes === "string" ? bytes : Buffer.from(bytes));
35764
36289
  else {
35765
- fs.writeFileSync(out, typeof bytes === "string" ? bytes : Buffer.from(bytes));
36290
+ fs2.writeFileSync(out, typeof bytes === "string" ? bytes : Buffer.from(bytes));
35766
36291
  console.error(`pw: wrote ${out} (${model.pages.length} pages${model.warnings.length ? `, ${model.warnings.length} warnings` : ""})`);
35767
36292
  }
35768
36293
  }
@@ -35787,32 +36312,32 @@ function layoutLines(model) {
35787
36312
  async function cmdTest(args) {
35788
36313
  const { values, positionals } = parseArgs({ args, allowPositionals: true, options: { update: { type: "boolean" }, layout: { type: "boolean" } } });
35789
36314
  const dir = positionals[0] || "reports";
35790
- const testsDir = path.join(dir, "__tests__");
36315
+ const testsDir = path2.join(dir, "__tests__");
35791
36316
  let files = [];
35792
36317
  try {
35793
- files = fs.readdirSync(testsDir).filter((f4) => f4.endsWith(".test.json")).sort();
36318
+ files = fs2.readdirSync(testsDir).filter((f4) => f4.endsWith(".test.json")).sort();
35794
36319
  } catch {
35795
- fail(`no tests: add ${path.join(testsDir, "<report>.test.json")}`);
36320
+ fail(`no tests: add ${path2.join(testsDir, "<report>.test.json")}`);
35796
36321
  }
35797
36322
  let passed = 0, failed = 0, written2 = 0;
35798
36323
  for (const f4 of files) {
35799
- const spec = readJson(path.join(testsDir, f4));
36324
+ const spec = readJson(path2.join(testsDir, f4));
35800
36325
  const id = f4.replace(/\.test\.json$/, "");
35801
- const def = readJson(path.resolve(testsDir, spec.report));
36326
+ const def = readJson(path2.resolve(testsDir, spec.report));
35802
36327
  for (const c of spec.cases || [{ name: "default" }]) {
35803
- const data = Object.fromEntries(Object.entries(c.data || {}).map(([k, v]) => [k, typeof v === "string" ? readJson(path.resolve(testsDir, v)) : v]));
35804
- const model = await renderModel(def, { parameters: c.parameters, data, now: c.now || "2026-01-01T09:00:00", state: c.state, file: path.resolve(testsDir, spec.report) });
36328
+ const data = Object.fromEntries(Object.entries(c.data || {}).map(([k, v]) => [k, typeof v === "string" ? readJson(path2.resolve(testsDir, v)) : v]));
36329
+ const model = await renderModel(def, { parameters: c.parameters, data, now: c.now || "2026-01-01T09:00:00", state: c.state, file: path2.resolve(testsDir, spec.report) });
35805
36330
  const label = `${id} › ${c.name}`;
35806
36331
  const layout = !!values.layout || c.layout === true;
35807
- const snapFile = path.join(testsDir, `${id}.${c.name}.${layout ? "layout." : ""}snap.txt`);
36332
+ const snapFile = path2.join(testsDir, `${id}.${c.name}.${layout ? "layout." : ""}snap.txt`);
35808
36333
  const text2 = layout ? layoutLines(model).join("\n") + "\n" : snapshotText(label, model);
35809
- if (values.update || !fs.existsSync(snapFile)) {
35810
- fs.writeFileSync(snapFile, text2);
36334
+ if (values.update || !fs2.existsSync(snapFile)) {
36335
+ fs2.writeFileSync(snapFile, text2);
35811
36336
  written2++;
35812
36337
  passed++;
35813
36338
  continue;
35814
36339
  }
35815
- const old = fs.readFileSync(snapFile, "utf8");
36340
+ const old = fs2.readFileSync(snapFile, "utf8");
35816
36341
  if (old === text2) {
35817
36342
  passed++;
35818
36343
  continue;
@@ -35841,7 +36366,7 @@ async function cmdDiff(args) {
35841
36366
  const data = Object.fromEntries(Object.entries(pairs2(values.d)).map(([k, f4]) => [k, readJson(f4)]));
35842
36367
  const opts = { parameters: pairs2(values.p), data, base: values.base, internal: !!values["allow-internal"], now: "2026-01-01T09:00:00" };
35843
36368
  const [a, b] = await Promise.all(positionals.map((f4) => renderModel(readJson(f4), { ...opts, file: f4 })));
35844
- if (!compare(path.basename(positionals[1]), a, b)) {
36369
+ if (!compare(path2.basename(positionals[1]), a, b)) {
35845
36370
  console.log("No differences.");
35846
36371
  return;
35847
36372
  }
@@ -35852,7 +36377,7 @@ async function cmdAudit(args) {
35852
36377
  const audit = await Promise.resolve().then(() => __toESM(require_audit(), 1));
35853
36378
  if (positionals[0] === "rekey") {
35854
36379
  const { createPrivateKey } = await import("node:crypto");
35855
- const old = values["old-key"] ? createPrivateKey(fs.readFileSync(values["old-key"], "utf8")) : values["old-secret"] ? audit.keyFromSecret(values["old-secret"]) : usage("give --old-secret or --old-key");
36380
+ const old = values["old-key"] ? createPrivateKey(fs2.readFileSync(values["old-key"], "utf8")) : values["old-secret"] ? audit.keyFromSecret(values["old-secret"]) : usage("give --old-secret or --old-key");
35856
36381
  const e2 = await audit.rekey(old);
35857
36382
  console.log(`re-keyed: ${e2.detail.oldFingerprint} -> ${e2.detail.newFingerprint} (${e2.id})`);
35858
36383
  return;
@@ -35864,7 +36389,7 @@ async function cmdAudit(args) {
35864
36389
  }
35865
36390
  if (positionals[0] !== "verify") usage("pw audit verify | pw audit checkpoint | pw audit rekey");
35866
36391
  for (const k of ["from", "to"]) if (values[k] && !/^\d{4}-\d{2}-\d{2}$/.test(values[k])) usage(`--${k} is a date, YYYY-MM-DD`);
35867
- if (values["public-key"]) process.env.PW_AUDIT_PUBLIC_KEY = fs.readFileSync(values["public-key"], "utf8");
36392
+ if (values["public-key"]) process.env.PW_AUDIT_PUBLIC_KEY = fs2.readFileSync(values["public-key"], "utf8");
35868
36393
  const r = await audit.verifyAudit({ from: values.from, to: values.to, onProgress: values.json ? void 0 : (n5) => process.stderr.write(`\r${n5} events checked`) });
35869
36394
  if (values.json) console.log(JSON.stringify(r, null, 2));
35870
36395
  else {
@@ -35887,20 +36412,70 @@ async function cmdMigrateStorage(args) {
35887
36412
  console.log(`copied ${n5.records} records, ${n5.versions} versions and ${n5.audit} audit events to ${values.to.replace(/\/\/[^@/]*@/, "//***@")}`);
35888
36413
  }
35889
36414
  async function cmdImport(args) {
35890
- const { values, positionals } = parseArgs({ args, allowPositionals: true, options: { o: { type: "string" } } });
35891
- if (positionals.length !== 1) usage("give one .jrxml, .rdl or .rptdesign file");
35892
- const { importXmlReport: importXmlReport2 } = await Promise.resolve().then(() => (init_importers(), importers_exports));
36415
+ const { values, positionals } = parseArgs({ args, allowPositionals: true, options: { o: { type: "string" }, recursive: { type: "boolean" }, force: { type: "boolean" }, verify: { type: "boolean" }, report: { type: "string" }, "max-files": { type: "string" }, "max-bytes": { type: "string" } } });
36416
+ if (positionals.length !== 1) usage("give one .jrxml, .rdl or .rptdesign file, or a folder");
35893
36417
  const file = positionals[0];
35894
- const r = importXmlReport2(fs.readFileSync(file, "utf8"), { name: path.basename(file).replace(/\.[^.]+$/, "") });
36418
+ if (fs2.statSync(file, { throwIfNoEntry: false })?.isDirectory()) return importFolderCmd(file, values);
36419
+ if (values.recursive || values.force || values.verify || values.report) usage("--recursive, --force, --verify and --report are for a folder");
36420
+ const { importXmlReport: importXmlReport2 } = await Promise.resolve().then(() => (init_importers(), importers_exports));
36421
+ const r = importXmlReport2(fs2.readFileSync(file, "utf8"), { name: path2.basename(file).replace(/\.[^.]+$/, "") });
35895
36422
  for (const w of r.warnings) console.error(`pw: ${w}`);
35896
36423
  if (r.error) fail(r.error);
35897
36424
  const out = values.o || file.replace(/\.[^.]+$/, ".pw.json");
35898
36425
  const json = JSON.stringify(r.definition, null, 2) + "\n";
35899
36426
  if (out === "-") process.stdout.write(json);
35900
- else fs.writeFileSync(out, json);
36427
+ else fs2.writeFileSync(out, json);
35901
36428
  if (out !== "-") console.error(`${out}: ${r.stats.items} items (${r.stats.mapped} mapped, ${r.stats.approximated} approximated, ${r.stats.dropped} dropped)`);
35902
36429
  }
36430
+ async function importFolderCmd(dir, values) {
36431
+ if (!values.o || values.o === "-") usage("pw import <folder> needs -o <outDir>");
36432
+ const num6 = (k) => {
36433
+ const v = values[k];
36434
+ if (v == null) return void 0;
36435
+ if (!/^\d+$/.test(v) || !(Number(v) > 0)) usage(`--${k} is a positive whole number`);
36436
+ return Number(v);
36437
+ };
36438
+ const { importFolder: importFolder2, reportHtml: reportHtml2, exitCode: exitCode2 } = await Promise.resolve().then(() => (init_batch(), batch_exports));
36439
+ const report = await importFolder2(dir, values.o, {
36440
+ recursive: !!values.recursive,
36441
+ force: !!values.force,
36442
+ maxFiles: num6("max-files"),
36443
+ maxBytes: num6("max-bytes"),
36444
+ verify: values.verify ? verifyImported : void 0,
36445
+ log: (m) => console.error(`pw: ${m}`)
36446
+ });
36447
+ const json = values.report && /\.json$/i.test(values.report) ? values.report : path2.join(values.report || values.o, "import-report.json");
36448
+ const html = json.replace(/\.json$/i, ".html");
36449
+ fs2.mkdirSync(path2.dirname(json), { recursive: true });
36450
+ fs2.writeFileSync(json, JSON.stringify(report, null, 2) + "\n");
36451
+ fs2.writeFileSync(html, reportHtml2(report));
36452
+ const s = report.summary;
36453
+ console.error(`pw: ${s.imported} of ${s.reports} reports imported${s.failed ? `, ${s.failed} failed` : ""}${s.skippedEdited ? `, ${s.skippedEdited} edited outputs kept` : ""}${s.unresolved ? `, ${s.unresolved} unresolved references` : ""}${s.refused ? `, ${s.refused} files refused` : ""}; report: ${html}`);
36454
+ process.exitCode = exitCode2(report);
36455
+ }
36456
+ async function verifyImported({ file, definition, baseline }) {
36457
+ const sample = file.replace(/\.pw\.json$/, ".data.json");
36458
+ let data = {};
36459
+ if (fs2.existsSync(sample)) data = readJson(sample);
36460
+ const embedded = (s) => s.type === "json" && s.data != null || (s.type === "csv" || s.type === "xml") && !!s.data;
36461
+ const missing2 = (definition.dataSources || []).filter((s) => !embedded(s) && !Object.hasOwn(data, s.name)).map((s) => `"${s.name}"`);
36462
+ if (missing2.length) return { status: "skipped", note: `no data for ${missing2.join(", ")}: it is not embedded, and there is no ${path2.basename(sample)}` };
36463
+ const go = (def) => render(
36464
+ { ...def, dataSources: (def.dataSources || []).map((s) => Object.hasOwn(data, s.name) ? { name: s.name, type: "json", data: data[s.name] } : s) },
36465
+ { fontStore, parameters: {}, now: /* @__PURE__ */ new Date("2026-01-01T09:00:00"), loadReport: siblingLoader(file), fetch: () => Promise.reject(new Error("pw import --verify makes no network requests")) }
36466
+ );
36467
+ const model = await go(definition);
36468
+ if (!baseline) return { status: "ok", pages: model.pages.length, warnings: model.warnings.length, note: "renders (no earlier output to compare with)" };
36469
+ const diff = [];
36470
+ const changed = compare(path2.basename(file), await go(baseline), model, (l) => diff.push(l));
36471
+ return { status: changed ? "changed" : "ok", pages: model.pages.length, warnings: model.warnings.length, note: changed ? "renders differently from the output it replaced" : "renders the same as the output it replaced", diff };
36472
+ }
35903
36473
  var commands = { render: cmdRender, import: cmdImport, test: cmdTest, diff: cmdDiff, audit: cmdAudit, "migrate-storage": cmdMigrateStorage };
36474
+ if (cmd === "--version" || cmd === "-v") {
36475
+ const cli = JSON.parse(fs2.readFileSync(path2.join(ROOT2, "package.json"), "utf8"));
36476
+ console.log(`pw ${cli.version} (${cli.name}), engine ${package_default.version}`);
36477
+ process.exit(0);
36478
+ }
35904
36479
  if (!commands[cmd]) usage(cmd && cmd !== "help" && cmd !== "--help" ? `unknown command "${cmd}"` : "");
35905
36480
  try {
35906
36481
  await commands[cmd](rest);