@pixerate/editor 0.52.0 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/agent/index.cjs +23 -23
  2. package/dist/agent/index.js +4 -4
  3. package/dist/chart/index.cjs +174 -131
  4. package/dist/chart/index.cjs.map +1 -1
  5. package/dist/chart/index.d.cts +68 -21
  6. package/dist/chart/index.d.ts +68 -21
  7. package/dist/chart/index.js +64 -21
  8. package/dist/chart/index.js.map +1 -1
  9. package/dist/{chunk-UAW5FEMD.js → chunk-3S72F46R.js} +66 -8
  10. package/dist/chunk-3S72F46R.js.map +1 -0
  11. package/dist/{chunk-5TWIN7ZJ.js → chunk-47WWV3LI.js} +34 -4
  12. package/dist/chunk-47WWV3LI.js.map +1 -0
  13. package/dist/{chunk-OV7UAKIY.js → chunk-633QC34G.js} +172 -1
  14. package/dist/chunk-633QC34G.js.map +1 -0
  15. package/dist/{chunk-5N6AQCVB.js → chunk-BQQZ6MOI.js} +3 -3
  16. package/dist/{chunk-M5Z77GFH.cjs → chunk-C3JHII3M.cjs} +53 -53
  17. package/dist/{chunk-M5Z77GFH.cjs.map → chunk-C3JHII3M.cjs.map} +1 -1
  18. package/dist/{chunk-JOX6MJW4.cjs → chunk-CKRNELPO.cjs} +176 -5
  19. package/dist/chunk-CKRNELPO.cjs.map +1 -0
  20. package/dist/{chunk-TGBCBQFV.cjs → chunk-DK6QBGCS.cjs} +45 -15
  21. package/dist/chunk-DK6QBGCS.cjs.map +1 -0
  22. package/dist/{chunk-GTZXF4BI.cjs → chunk-NK3WL5TJ.cjs} +298 -133
  23. package/dist/chunk-NK3WL5TJ.cjs.map +1 -0
  24. package/dist/{chunk-3ZBAXET6.cjs → chunk-NN3JGUSX.cjs} +80 -22
  25. package/dist/chunk-NN3JGUSX.cjs.map +1 -0
  26. package/dist/{chunk-YMKPMXZ4.js → chunk-OIKYP7XC.js} +4 -4
  27. package/dist/{chunk-FEMIVHN3.cjs → chunk-P43HUQRX.cjs} +16 -16
  28. package/dist/{chunk-FEMIVHN3.cjs.map → chunk-P43HUQRX.cjs.map} +1 -1
  29. package/dist/{chunk-QFTVLEVN.js → chunk-RIXTW3C4.js} +3 -3
  30. package/dist/{chunk-WBOAXDKD.js → chunk-VODBAO32.js} +222 -57
  31. package/dist/chunk-VODBAO32.js.map +1 -0
  32. package/dist/{chunk-2DEBI6KU.cjs → chunk-YZZMX6V7.cjs} +10 -10
  33. package/dist/{chunk-2DEBI6KU.cjs.map → chunk-YZZMX6V7.cjs.map} +1 -1
  34. package/dist/{controller-DS3drIvy.d.cts → controller-CX0QfSv0.d.cts} +53 -2
  35. package/dist/{controller-BdKzaxs2.d.ts → controller-DscWQbjO.d.ts} +53 -2
  36. package/dist/export/index.cjs +4 -4
  37. package/dist/export/index.js +3 -3
  38. package/dist/extensions/index.cjs +6 -6
  39. package/dist/extensions/index.d.cts +2 -2
  40. package/dist/extensions/index.d.ts +2 -2
  41. package/dist/extensions/index.js +5 -5
  42. package/dist/{index-Dt9lzydb.d.ts → index-CALDD35B.d.ts} +1 -1
  43. package/dist/{index-DOy9HzfC.d.cts → index-DIWB6xMf.d.cts} +1 -1
  44. package/dist/index.cjs +13 -13
  45. package/dist/index.d.cts +3 -3
  46. package/dist/index.d.ts +3 -3
  47. package/dist/index.js +6 -6
  48. package/package.json +1 -1
  49. package/dist/chunk-3ZBAXET6.cjs.map +0 -1
  50. package/dist/chunk-5TWIN7ZJ.js.map +0 -1
  51. package/dist/chunk-GTZXF4BI.cjs.map +0 -1
  52. package/dist/chunk-JOX6MJW4.cjs.map +0 -1
  53. package/dist/chunk-OV7UAKIY.js.map +0 -1
  54. package/dist/chunk-TGBCBQFV.cjs.map +0 -1
  55. package/dist/chunk-UAW5FEMD.js.map +0 -1
  56. package/dist/chunk-WBOAXDKD.js.map +0 -1
  57. /package/dist/{chunk-5N6AQCVB.js.map → chunk-BQQZ6MOI.js.map} +0 -0
  58. /package/dist/{chunk-YMKPMXZ4.js.map → chunk-OIKYP7XC.js.map} +0 -0
  59. /package/dist/{chunk-QFTVLEVN.js.map → chunk-RIXTW3C4.js.map} +0 -0
@@ -6,7 +6,7 @@ import {
6
6
  isCartesianChart,
7
7
  normalizeChartSpec,
8
8
  parseChartColor
9
- } from "./chunk-OV7UAKIY.js";
9
+ } from "./chunk-633QC34G.js";
10
10
 
11
11
  // src/chart/ooxml.ts
12
12
  var CHART_OOXML_NS = "http://schemas.openxmlformats.org/drawingml/2006/chart";
@@ -81,6 +81,27 @@ var MARKERS = { circle: "circle", dot: "circle", square: "square", diamond: "dia
81
81
  var TREND_IN = { linear: "linear", exp: "exponential", log: "logarithmic", poly: "polynomial", power: "power", movingAvg: "moving-average" };
82
82
  var TREND_OUT = { linear: "linear", exponential: "exp", logarithmic: "log", polynomial: "poly", power: "power", "moving-average": "movingAvg" };
83
83
  var LEGEND_IN = { b: "bottom", t: "top", l: "left", r: "right", tr: "right" };
84
+ var ERR_IN = { fixedVal: "fixed", percentage: "percent", stdDev: "stddev", stdErr: "stderr", cust: "custom" };
85
+ var ERR_OUT = { fixed: "fixedVal", percent: "percentage", stddev: "stdDev", stderr: "stdErr", custom: "cust" };
86
+ function readErrorBars(e) {
87
+ const type = ERR_IN[val(e, "errValType") ?? "fixedVal"];
88
+ if (!type) return null;
89
+ const bars = { type };
90
+ const value = numberOf(val(e, "val"));
91
+ if (value !== null && type !== "custom" && type !== "stderr") bars.value = Math.abs(value);
92
+ if (type === "custom") {
93
+ const plus = kid(e, "plus");
94
+ const minus = kid(e, "minus");
95
+ const p = plus ? numbers(plus).map((v) => v === null ? null : Math.abs(v)) : [];
96
+ const m = minus ? numbers(minus).map((v) => v === null ? null : Math.abs(v)) : [];
97
+ if (p.some((v) => v !== null)) bars.plus = p;
98
+ if (m.some((v) => v !== null) && JSON.stringify(m) !== JSON.stringify(p)) bars.minus = m;
99
+ }
100
+ const direction = val(e, "errBarType");
101
+ if (direction === "plus" || direction === "minus") bars.direction = direction;
102
+ if (bool(val(e, "noEndCap"))) bars.cap = false;
103
+ return bars;
104
+ }
84
105
  function chartFromOoxml(xml, options = {}) {
85
106
  const issues = [];
86
107
  const unsupported = [];
@@ -240,7 +261,18 @@ function chartFromOoxml(xml, options = {}) {
240
261
  trends.push(line);
241
262
  }
242
263
  if (trends.length) out.trendlines = trends;
243
- if (kids(s, "errBars").length) unsupported.push("error bars");
264
+ for (const e of kids(s, "errBars")) {
265
+ const bars = readErrorBars(e);
266
+ if (!bars) {
267
+ unsupported.push(`error bars of type "${val(e, "errValType")}"`);
268
+ continue;
269
+ }
270
+ if (val(e, "errDir") === "x") {
271
+ if (type === "scatter" || type === "bubble") out.xErrorBars = bars;
272
+ else unsupported.push("x error bars on a category chart");
273
+ } else if (type === "pie" || type === "donut" || type === "radar") unsupported.push(`error bars on a ${type} chart`);
274
+ else out.errorBars = bars;
275
+ }
244
276
  series.push(out);
245
277
  }
246
278
  }
@@ -273,8 +305,15 @@ function chartFromOoxml(xml, options = {}) {
273
305
  const scaling = kid(a, "scaling");
274
306
  axis.min = numberOf(val(scaling, "min"));
275
307
  axis.max = numberOf(val(scaling, "max"));
276
- if (val(scaling, "orientation") === "maxMin") unsupported.push("a reversed axis");
277
- if (kid(scaling, "logBase")) unsupported.push("a logarithmic axis");
308
+ if (val(scaling, "orientation") === "maxMin") axis.reverse = true;
309
+ if (kid(scaling, "logBase")) {
310
+ if (a.localName !== "valAx") unsupported.push("a logarithmic category axis");
311
+ else {
312
+ axis.scale = "log";
313
+ const base = numberOf(val(scaling, "logBase")) ?? 10;
314
+ if (base !== 10) axis.logBase = base;
315
+ }
316
+ }
278
317
  axis.step = numberOf(val(a, "majorUnit"));
279
318
  const fmt = kid(a, "numFmt");
280
319
  const code = fmt?.getAttribute("formatCode");
@@ -384,6 +423,14 @@ function chartFormatToCode(format) {
384
423
  return d !== void 0 || format.prefix || format.suffix ? wrap(`#,##0${frac(d, 0)}`) : "General";
385
424
  }
386
425
  }
426
+ function errBarsXml(bars, dir) {
427
+ let x = `<c:errBars>${dir ? `<c:errDir val="${dir}"/>` : ""}<c:errBarType val="${bars.direction ?? "both"}"/><c:errValType val="${ERR_OUT[bars.type]}"/><c:noEndCap val="${bars.cap === false ? 1 : 0}"/>`;
428
+ if (bars.type === "custom") {
429
+ const plus = bars.plus ?? (bars.minus ?? []).map(() => null);
430
+ x += `<c:plus>${numLit(plus)}</c:plus><c:minus>${numLit(bars.minus ?? plus)}</c:minus>`;
431
+ } else if (bars.type !== "stderr") x += `<c:val val="${bars.value ?? (bars.type === "percent" ? 5 : 1)}"/>`;
432
+ return `${x}</c:errBars>`;
433
+ }
387
434
  var MARKER_OUT = { circle: "circle", square: "square", diamond: "diamond", triangle: "triangle", cross: "x", none: "none" };
388
435
  function chartToOoxml(spec) {
389
436
  const issues = [];
@@ -442,6 +489,14 @@ function chartToOoxml(spec) {
442
489
  x += `<c:dispRSqr val="${t.showR2 ? 1 : 0}"/><c:dispEq val="${t.showEquation ? 1 : 0}"/></c:trendline>`;
443
490
  parts.push(x);
444
491
  }
492
+ if (!pieLike && kind !== "radar") {
493
+ const xyKind = kind === "scatter" || kind === "bubble";
494
+ if (s.errorBars) parts.push(errBarsXml(s.errorBars, xyKind ? "y" : null));
495
+ if (s.xErrorBars) {
496
+ if (xyKind) parts.push(errBarsXml(s.xErrorBars, "x"));
497
+ else issues.push(`"${s.name}" has x error bars, which only scatter and bubble charts can hold; they are left out.`);
498
+ }
499
+ } else if (s.errorBars || s.xErrorBars) issues.push(`Error bars on "${s.name}" are left out: ${kind} charts cannot show them.`);
445
500
  const valCode = chartFormatToCode(s.format ?? (s.axis === "secondary" ? spec.yAxis2.format : spec.yAxis.format));
446
501
  if (kind === "scatter" || kind === "bubble") {
447
502
  const xs = s.x ?? spec.categories.map((_, i) => i + 1);
@@ -484,7 +539,7 @@ function chartToOoxml(spec) {
484
539
  return `<c:pieChart><c:varyColors val="1"/>${sers}${dLbls}<c:firstSliceAng val="0"/></c:pieChart>`;
485
540
  }
486
541
  });
487
- const scaling = (a) => `<c:scaling><c:orientation val="minMax"/>${a.max !== null ? `<c:max val="${a.max}"/>` : ""}${a.min !== null ? `<c:min val="${a.min}"/>` : ""}</c:scaling>`;
542
+ const scaling = (a) => `<c:scaling>${a.scale === "log" ? `<c:logBase val="${a.logBase ?? 10}"/>` : ""}<c:orientation val="${a.reverse ? "maxMin" : "minMax"}"/>${a.max !== null ? `<c:max val="${a.max}"/>` : ""}${a.min !== null ? `<c:min val="${a.min}"/>` : ""}</c:scaling>`;
488
543
  const title = (a) => a.title ? `<c:title>${rich(a.title)}</c:title>` : "";
489
544
  const fmt = (a) => {
490
545
  const code = chartFormatToCode(a.format);
@@ -494,11 +549,14 @@ function chartToOoxml(spec) {
494
549
  const catPos = horizontal ? "l" : "b";
495
550
  const valPos = horizontal ? "b" : "l";
496
551
  const valAx = (id, cross, a, pos, crosses, catKind = false) => `<c:valAx><c:axId val="${id}"/>${scaling(a)}<c:delete val="${a.show ? 0 : 1}"/><c:axPos val="${pos}"/>${a.gridlines ? "<c:majorGridlines/>" : ""}${title(a)}${fmt(a)}<c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${crosses}"/><c:crossBetween val="${catKind ? "midCat" : "between"}"/>${a.step ? `<c:majorUnit val="${a.step}"/>` : ""}</c:valAx>`;
497
- const catAx = (id, cross, a, pos, hidden = false) => `<c:${a.kind === "date" ? "dateAx" : "catAx"}><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${a.show && !hidden ? 0 : 1}"/><c:axPos val="${pos}"/>${a.gridlines ? "<c:majorGridlines/>" : ""}${title(a)}<c:numFmt formatCode="General" sourceLinked="1"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/>${a.kind === "date" ? '<c:lblOffset val="100"/><c:baseTimeUnit val="days"/>' : '<c:lblAlgn val="ctr"/><c:lblOffset val="100"/><c:noMultiLvlLbl val="0"/>'}</c:${a.kind === "date" ? "dateAx" : "catAx"}>`;
552
+ const catAx = (id, cross, a, pos, hidden = false) => `<c:${a.kind === "date" ? "dateAx" : "catAx"}><c:axId val="${id}"/><c:scaling><c:orientation val="${a.reverse ? "maxMin" : "minMax"}"/></c:scaling><c:delete val="${a.show && !hidden ? 0 : 1}"/><c:axPos val="${pos}"/>${a.gridlines ? "<c:majorGridlines/>" : ""}${title(a)}<c:numFmt formatCode="General" sourceLinked="1"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/>${a.kind === "date" ? '<c:lblOffset val="100"/><c:baseTimeUnit val="days"/>' : '<c:lblAlgn val="ctr"/><c:lblOffset val="100"/><c:noMultiLvlLbl val="0"/>'}</c:${a.kind === "date" ? "dateAx" : "catAx"}>`;
498
553
  let axes = "";
499
554
  if (!pieLike) {
500
555
  if (xy) axes = valAx(ids.cat, ids.val, spec.xAxis, "b", "autoZero", true) + valAx(ids.val, ids.cat, spec.yAxis, "l", "autoZero", true);
501
- else axes = catAx(ids.cat, ids.val, spec.xAxis, catPos) + valAx(ids.val, ids.cat, spec.yAxis, valPos, "autoZero");
556
+ else {
557
+ if (spec.xAxis.scale === "log") issues.push("The category axis cannot be logarithmic; its log scale is left out.");
558
+ axes = catAx(ids.cat, ids.val, spec.xAxis, catPos) + valAx(ids.val, ids.cat, spec.yAxis, valPos, "autoZero");
559
+ }
502
560
  if (groups.some((g) => g.secondary)) axes += catAx(ids.cat2, ids.val2, spec.xAxis, catPos, true) + valAx(ids.val2, ids.cat2, spec.yAxis2, horizontal ? "t" : "r", "max");
503
561
  }
504
562
  const legendPos = { bottom: "b", top: "t", left: "l", right: "r" }[spec.legend.position];
@@ -838,4 +896,4 @@ export {
838
896
  ZipArchive,
839
897
  readZip
840
898
  };
841
- //# sourceMappingURL=chunk-UAW5FEMD.js.map
899
+ //# sourceMappingURL=chunk-3S72F46R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chart/ooxml.ts","../src/import/zip.ts"],"sourcesContent":["// The DrawingML chart reader follows deckcraft-main/crates/pptx/src/read/chart.rs (group → type mapping,\n// secondary-axis detection by axis id and position, cache / literal data, number-format precedence) and the\n// chartex reader gridcraft-main/crates/xlsx/src/chartex.rs; the \"editable only when it regenerates\" idea is\n// from wordcraft-main/crates/docx/src/chart_spec.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors).\n// See THIRD_PARTY_NOTICES.md.\nimport { parseChartColor, chartRgbToHex } from './color.js';\nimport { chartFamily, chartSeriesType, defaultChartAxis, isCartesianChart, normalizeChartSpec } from './spec.js';\nimport type { ChartAxis, ChartErrorBars, ChartErrorBarType, ChartIssue, ChartLegendPosition, ChartMarker, ChartNumberFormat, ChartSeries, ChartSpec, ChartTrendline, ChartTrendlineType, ChartType, ChartValue } from './types.js';\n\nexport const CHART_OOXML_NS = 'http://schemas.openxmlformats.org/drawingml/2006/chart';\nexport const CHART_OOXML_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml';\nexport const CHART_OOXML_RELATIONSHIP = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart';\n\ntype ParserCtor = { new (): DOMParser };\n\nexport interface ChartOoxmlReadOptions {\n\t/** `DOMParser` constructor (default: the global one; pass jsdom's or xmldom's in Node). */\n\tDOMParser?: ParserCtor;\n}\n\nexport interface ChartOoxmlReadResult {\n\tspec: ChartSpec;\n\t/** Problems and simplifications, as sentences. */\n\tissues: ChartIssue[];\n\t/** Features the file uses that the spec cannot hold (3-D, stock, surface, gradients, …). */\n\tunsupported: string[];\n\t/**\n\t * Nothing was dropped: writing `spec` back gives an equivalent chart. When false, keep the\n\t * original part (or show the chart read-only) if the file must stay as it was.\n\t */\n\tlossless: boolean;\n}\n\nconst MAX_POINTS = 100_000;\n\nfunction parser(options: ChartOoxmlReadOptions): ParserCtor {\n\tconst P = options.DOMParser ?? (globalThis as { DOMParser?: ParserCtor }).DOMParser;\n\tif (!P) throw new Error('Reading chart XML needs a DOMParser. In Node, pass one (e.g. from jsdom or @xmldom/xmldom) as { DOMParser }.');\n\treturn P;\n}\n\nconst kids = (el: Element | null | undefined, name?: string): Element[] => (el ? Array.from(el.childNodes).filter((n): n is Element => n.nodeType === 1 && (!name || (n as Element).localName === name)) : []);\nconst kid = (el: Element | null | undefined, name: string) => kids(el, name)[0];\nconst val = (el: Element | null | undefined, name: string) => kid(el, name)?.getAttribute('val') ?? undefined;\nconst path = (el: Element | null | undefined, ...names: string[]) => names.reduce<Element | undefined>((e, n) => kid(e, n), el ?? undefined);\nconst find = (el: Element | null | undefined, name: string): Element | undefined => {\n\tif (!el) return undefined;\n\tfor (const c of kids(el)) {\n\t\tif (c.localName === name) return c;\n\t\tconst deep = find(c, name);\n\t\tif (deep) return deep;\n\t}\n\treturn undefined;\n};\nconst bool = (v: string | undefined, fallback = false) => (v === undefined ? fallback : v === '1' || v === 'true');\nconst numberOf = (v: string | undefined) => {\n\tif (v === undefined) return null;\n\tconst n = Number(v);\n\treturn Number.isFinite(n) ? n : null;\n};\n\nfunction strings(e: Element | undefined): string[] {\n\tif (!e) return [];\n\tconst cache = find(e, 'strCache') ?? find(e, 'numCache') ?? find(e, 'strLit') ?? find(e, 'numLit');\n\tif (cache) {\n\t\tconst n = Math.min(MAX_POINTS, Number(val(cache, 'ptCount') ?? 0) || 0);\n\t\tconst out: string[] = Array(n).fill('');\n\t\tfor (const pt of kids(cache, 'pt').slice(0, MAX_POINTS)) {\n\t\t\tconst i = Number(pt.getAttribute('idx') ?? 0);\n\t\t\tif (!Number.isInteger(i) || i < 0 || i >= MAX_POINTS) continue;\n\t\t\twhile (out.length <= i) out.push('');\n\t\t\tout[i] = kid(pt, 'v')?.textContent ?? '';\n\t\t}\n\t\treturn out;\n\t}\n\tconst multi = find(e, 'multiLvlStrCache');\n\tif (multi) {\n\t\tconst lvl = kid(multi, 'lvl');\n\t\treturn kids(lvl, 'pt').map((p) => kid(p, 'v')?.textContent ?? '');\n\t}\n\tconst v = kid(e, 'v') ?? find(e, 'v');\n\treturn v ? [v.textContent ?? ''] : [];\n}\n\nconst numbers = (e: Element | undefined): ChartValue[] => strings(e).map((s) => (s.trim() === '' ? null : numberOf(s.trim())));\n\nfunction formatCodeOf(e: Element | undefined): string | undefined {\n\treturn find(e, 'numCache') ? (kid(find(e, 'numCache'), 'formatCode')?.textContent ?? undefined) : undefined;\n}\n\nfunction richText(t: Element | undefined): string | undefined {\n\tif (!t) return undefined;\n\tconst tx = kid(t, 'tx');\n\tconst rich = kid(tx, 'rich');\n\tif (rich) return kids(rich, 'p').map((p) => Array.from(p.getElementsByTagNameNS('*', 't')).map((x) => x.textContent ?? '').join('')).join('\\n');\n\tconst v = find(tx, 'v');\n\treturn v?.textContent ?? undefined;\n}\n\nfunction solidColor(spPr: Element | undefined): string | undefined {\n\tconst fill = kid(spPr, 'solidFill') ?? kid(kid(spPr, 'ln'), 'solidFill');\n\tconst srgb = kid(fill, 'srgbClr');\n\tconst v = srgb?.getAttribute('val');\n\treturn v && /^[0-9a-f]{6}$/i.test(v) ? `#${v.toLowerCase()}` : undefined;\n}\n\nconst MARKERS: Record<string, ChartMarker> = { circle: 'circle', dot: 'circle', square: 'square', diamond: 'diamond', triangle: 'triangle', x: 'cross', plus: 'cross', star: 'cross', dash: 'square', none: 'none' };\nconst TREND_IN: Record<string, ChartTrendlineType> = { linear: 'linear', exp: 'exponential', log: 'logarithmic', poly: 'polynomial', power: 'power', movingAvg: 'moving-average' };\nconst TREND_OUT: Record<ChartTrendlineType, string> = { linear: 'linear', exponential: 'exp', logarithmic: 'log', polynomial: 'poly', power: 'power', 'moving-average': 'movingAvg' };\nconst LEGEND_IN: Record<string, ChartLegendPosition> = { b: 'bottom', t: 'top', l: 'left', r: 'right', tr: 'right' };\nconst ERR_IN: Record<string, ChartErrorBarType> = { fixedVal: 'fixed', percentage: 'percent', stdDev: 'stddev', stdErr: 'stderr', cust: 'custom' };\nconst ERR_OUT: Record<ChartErrorBarType, string> = { fixed: 'fixedVal', percent: 'percentage', stddev: 'stdDev', stderr: 'stdErr', custom: 'cust' };\n\n/** Reads one `c:errBars` (Excel's error amount types map one to one); `null` for an unknown type. */\nfunction readErrorBars(e: Element): ChartErrorBars | null {\n\tconst type = ERR_IN[val(e, 'errValType') ?? 'fixedVal'];\n\tif (!type) return null;\n\tconst bars: ChartErrorBars = { type };\n\tconst value = numberOf(val(e, 'val'));\n\tif (value !== null && type !== 'custom' && type !== 'stderr') bars.value = Math.abs(value);\n\tif (type === 'custom') {\n\t\tconst plus = kid(e, 'plus');\n\t\tconst minus = kid(e, 'minus');\n\t\tconst p = plus ? numbers(plus).map((v) => (v === null ? null : Math.abs(v))) : [];\n\t\tconst m = minus ? numbers(minus).map((v) => (v === null ? null : Math.abs(v))) : [];\n\t\t// Minus amounts default to the plus ones; an empty side is left out.\n\t\tif (p.some((v) => v !== null)) bars.plus = p;\n\t\tif (m.some((v) => v !== null) && JSON.stringify(m) !== JSON.stringify(p)) bars.minus = m;\n\t}\n\tconst direction = val(e, 'errBarType');\n\tif (direction === 'plus' || direction === 'minus') bars.direction = direction;\n\tif (bool(val(e, 'noEndCap'))) bars.cap = false;\n\treturn bars;\n}\n\n/**\n * Reads a DrawingML chart part (`c:chartSpace`, e.g. `word/charts/chart1.xml`) or an Office\n * 2016 chartex part (`cx:chartSpace`: waterfall, funnel, treemap, histogram, box & whisker)\n * as a chart spec. Data comes from the cached values. Never throws for a malformed chart: it\n * returns an empty chart and says why.\n */\nexport function chartFromOoxml(xml: string, options: ChartOoxmlReadOptions = {}): ChartOoxmlReadResult {\n\tconst issues: ChartIssue[] = [];\n\tconst unsupported: string[] = [];\n\tlet doc: Document;\n\ttry {\n\t\tdoc = new (parser(options))().parseFromString(xml, 'application/xml');\n\t} catch (error) {\n\t\treturn { spec: normalizeChartSpec({}).spec, issues: [{ path: '', message: `The chart XML could not be read: ${(error as Error).message}` }], unsupported, lossless: false };\n\t}\n\tconst root = doc.documentElement;\n\tif (!root || root.localName !== 'chartSpace' || doc.getElementsByTagName('parsererror').length) {\n\t\treturn { spec: normalizeChartSpec({}).spec, issues: [{ path: '', message: 'This is not a chart part: expected a c:chartSpace (or cx:chartSpace) root element.' }], unsupported, lossless: false };\n\t}\n\tif (root.namespaceURI?.includes('chartex') || kid(root, 'chartData')) return readChartex(root, issues, unsupported);\n\n\tconst chart = kid(root, 'chart');\n\tconst plot = kid(chart, 'plotArea');\n\tconst input: Record<string, unknown> = { type: 'bar' };\n\tconst titleEl = kid(chart, 'title');\n\tif (titleEl && !bool(val(chart, 'autoTitleDeleted'))) input.title = richText(titleEl) ?? '';\n\tconst legend = kid(chart, 'legend');\n\tinput.legend = { show: !!legend, position: LEGEND_IN[val(legend, 'legendPos') ?? 'r'] ?? 'right' };\n\tif (kid(root, 'roundedCorners') && bool(val(root, 'roundedCorners'))) unsupported.push('rounded corners');\n\n\tconst valAxes = kids(plot, 'valAx');\n\tconst vertical = (a: Element) => ['l', 'r'].includes(val(a, 'axPos') ?? '');\n\tconst secondaryPlaced = (a: Element) => val(a, 'crosses') === 'max' || ['r', 't'].includes(val(a, 'axPos') ?? '');\n\tconst groupValAxis = (g: Element) => {\n\t\tconst ids = kids(g, 'axId').map((a) => a.getAttribute('val'));\n\t\tconst axes = ids.map((id) => valAxes.find((a) => val(a, 'axId') === id)).filter((a): a is Element => !!a);\n\t\treturn axes.find(vertical) ?? axes[0];\n\t};\n\tconst groups = kids(plot).filter((g) => g.localName.endsWith('Chart'));\n\tconst used = groups.map(groupValAxis).filter((a): a is Element => !!a);\n\tconst primaryAxis = used.find((a) => !secondaryPlaced(a)) ?? used[0];\n\n\tconst series: ChartSeries[] = [];\n\tlet categories: string[] = [];\n\tconst types: ChartType[] = [];\n\tlet stacking: ChartSpec['stacking'] = 'none';\n\tlet orientation: ChartSpec['orientation'] = 'vertical';\n\tlet dataLabels = false;\n\tlet points = false;\n\tfor (const g of groups) {\n\t\tconst name = g.localName;\n\t\tconst grouping = val(g, 'grouping') ?? 'clustered';\n\t\tlet type: ChartType;\n\t\tif (/3D/.test(name)) unsupported.push(`3-D ${name.replace(/3DChart$/, '')} chart (drawn flat)`);\n\t\tswitch (name) {\n\t\t\tcase 'barChart':\n\t\t\tcase 'bar3DChart':\n\t\t\t\ttype = 'bar';\n\t\t\t\tif (val(g, 'barDir') === 'bar') orientation = 'horizontal';\n\t\t\t\tbreak;\n\t\t\tcase 'lineChart':\n\t\t\tcase 'line3DChart':\n\t\t\t\ttype = 'line';\n\t\t\t\t// Points are on when a series shows a marker (the group's marker flag is usually set).\n\t\t\t\tif (kids(g, 'ser').some((s) => (val(kid(s, 'marker'), 'symbol') ?? (bool(val(g, 'marker'), true) ? 'auto' : 'none')) !== 'none')) points = true;\n\t\t\t\tbreak;\n\t\t\tcase 'areaChart':\n\t\t\tcase 'area3DChart':\n\t\t\t\ttype = 'area';\n\t\t\t\tbreak;\n\t\t\tcase 'pieChart':\n\t\t\tcase 'pie3DChart':\n\t\t\tcase 'ofPieChart':\n\t\t\t\ttype = 'pie';\n\t\t\t\tif (name === 'ofPieChart') unsupported.push('pie-of-pie (drawn as one pie)');\n\t\t\t\tbreak;\n\t\t\tcase 'doughnutChart':\n\t\t\t\ttype = 'donut';\n\t\t\t\tinput.innerRadius = Math.min(0.9, Math.max(0, (numberOf(val(g, 'holeSize')) ?? 50) / 100));\n\t\t\t\tbreak;\n\t\t\tcase 'scatterChart':\n\t\t\t\ttype = 'scatter';\n\t\t\t\tif (/line/i.test(val(g, 'scatterStyle') ?? '')) points = true;\n\t\t\t\tbreak;\n\t\t\tcase 'bubbleChart':\n\t\t\t\ttype = 'bubble';\n\t\t\t\tbreak;\n\t\t\tcase 'radarChart':\n\t\t\t\ttype = 'radar';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tunsupported.push(`${name.replace(/Chart$/, '')} chart`);\n\t\t\t\tcontinue;\n\t\t}\n\t\tif (grouping === 'stacked') stacking = 'stacked';\n\t\telse if (grouping === 'percentStacked') stacking = 'percent';\n\t\tconst gap = numberOf(val(g, 'gapWidth'));\n\t\tconst overlap = numberOf(val(g, 'overlap'));\n\t\tif (type === 'bar') {\n\t\t\t// gapWidth is the gap between groups as a % of one bar; ours is a fraction of the category.\n\t\t\tconst n = Math.max(1, kids(g, 'ser').length);\n\t\t\tconst g100 = (gap ?? 150) / 100;\n\t\t\tconst o = Math.max(-1, Math.min(1, (overlap ?? (grouping === 'clustered' ? 0 : 100)) / 100));\n\t\t\tconst barsWidth = grouping === 'clustered' ? n - (n - 1) * o : 1;\n\t\t\tinput.gapWidth = Math.round(Math.max(0, Math.min(0.9, g100 / (barsWidth + g100))) * 100) / 100;\n\t\t\tif (grouping === 'clustered') input.overlap = o;\n\t\t}\n\t\tif (bool(val(kid(g, 'dLbls'), 'showVal'))) dataLabels = true;\n\t\ttypes.push(type);\n\t\tconst axis = groupValAxis(g);\n\t\tconst secondary = !!axis && !!primaryAxis && axis !== primaryAxis;\n\t\tfor (const s of kids(g, 'ser').slice(0, 1000)) {\n\t\t\tconst out: ChartSeries = { id: `series-${series.length + 1}`, name: strings(kid(s, 'tx'))[0] ?? `Series ${series.length + 1}`, values: [] };\n\t\t\tconst color = solidColor(kid(s, 'spPr'));\n\t\t\tif (color) out.color = color;\n\t\t\tout.type = type === 'bubble' ? undefined : (type as ChartSeries['type']);\n\t\t\tif (secondary) out.axis = 'secondary';\n\t\t\tconst marker = val(kid(s, 'marker'), 'symbol');\n\t\t\t// Circles (and none on a line chart without points) are the defaults; other shapes are kept.\n\t\t\tif (marker && MARKERS[marker] && MARKERS[marker] !== 'circle' && (type === 'scatter' || MARKERS[marker] !== 'none') && (type === 'line' || type === 'scatter')) out.marker = MARKERS[marker];\n\t\t\tif (bool(val(s, 'smooth'))) out.curve = 'smooth';\n\t\t\tconst sl = kid(s, 'dLbls');\n\t\t\tif (sl && val(sl, 'showVal') !== undefined) out.dataLabels = bool(val(sl, 'showVal'));\n\t\t\tconst labelCode = [kid(sl, 'numFmt'), kid(kid(g, 'dLbls'), 'numFmt')].find((n) => n && n.getAttribute('sourceLinked') !== '1')?.getAttribute('formatCode');\n\t\t\tconst valueEl = kid(s, 'val') ?? kid(s, 'yVal');\n\t\t\tconst code = labelCode ?? formatCodeOf(valueEl);\n\t\t\tif (code && code !== 'General') out.format = { code };\n\t\t\tconst catEl = kid(s, 'cat') ?? kid(s, 'xVal');\n\t\t\tconst cats = strings(catEl);\n\t\t\tif (type === 'scatter' || type === 'bubble') {\n\t\t\t\tconst xs = cats.map((c) => numberOf(c.trim()));\n\t\t\t\tif (xs.some((x) => x !== null)) out.x = xs;\n\t\t\t}\n\t\t\tif (!categories.length && cats.length) categories = cats;\n\t\t\tout.values = numbers(valueEl);\n\t\t\tif (type === 'bubble') out.sizes = numbers(kid(s, 'bubbleSize'));\n\t\t\tconst dPts = kids(s, 'dPt');\n\t\t\tif (dPts.length) {\n\t\t\t\tconst pc: (string | null)[] = [];\n\t\t\t\tfor (const dp of dPts) {\n\t\t\t\t\tconst i = Number(val(dp, 'idx'));\n\t\t\t\t\tconst c = solidColor(kid(dp, 'spPr'));\n\t\t\t\t\tif (Number.isInteger(i) && i >= 0 && i < MAX_POINTS && c) {\n\t\t\t\t\t\twhile (pc.length <= i) pc.push(null);\n\t\t\t\t\t\tpc[i] = c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (pc.some(Boolean)) out.pointColors = pc;\n\t\t\t}\n\t\t\tconst trends: ChartTrendline[] = [];\n\t\t\tfor (const t of kids(s, 'trendline')) {\n\t\t\t\tconst kind = TREND_IN[val(t, 'trendlineType') ?? ''];\n\t\t\t\tif (!kind) continue;\n\t\t\t\tconst line: ChartTrendline = { type: kind };\n\t\t\t\tconst order = numberOf(val(t, 'order'));\n\t\t\t\tconst period = numberOf(val(t, 'period'));\n\t\t\t\tif (kind === 'polynomial' && order) line.order = order;\n\t\t\t\tif (kind === 'moving-average' && period) line.period = period;\n\t\t\t\tfor (const k of ['forward', 'backward', 'intercept'] as const) {\n\t\t\t\t\tconst n = numberOf(val(t, k));\n\t\t\t\t\tif (n !== null && (k === 'intercept' || n > 0)) line[k] = n;\n\t\t\t\t}\n\t\t\t\tif (bool(val(t, 'dispEq'))) line.showEquation = true;\n\t\t\t\tif (bool(val(t, 'dispRSqr'))) line.showR2 = true;\n\t\t\t\tconst tName = kid(t, 'name')?.textContent;\n\t\t\t\tif (tName) line.name = tName;\n\t\t\t\tconst tc = solidColor(kid(t, 'spPr'));\n\t\t\t\tif (tc) line.color = tc;\n\t\t\t\ttrends.push(line);\n\t\t\t}\n\t\t\tif (trends.length) out.trendlines = trends;\n\t\t\tfor (const e of kids(s, 'errBars')) {\n\t\t\t\tconst bars = readErrorBars(e);\n\t\t\t\tif (!bars) {\n\t\t\t\t\tunsupported.push(`error bars of type \"${val(e, 'errValType')}\"`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// x error bars only exist on scatter and bubble series.\n\t\t\t\tif (val(e, 'errDir') === 'x') {\n\t\t\t\t\tif (type === 'scatter' || type === 'bubble') out.xErrorBars = bars;\n\t\t\t\t\telse unsupported.push('x error bars on a category chart');\n\t\t\t\t} else if (type === 'pie' || type === 'donut' || type === 'radar') unsupported.push(`error bars on a ${type} chart`);\n\t\t\t\telse out.errorBars = bars;\n\t\t\t}\n\t\t\tseries.push(out);\n\t\t}\n\t}\n\tif (!types.length) {\n\t\tissues.push({ path: 'plotArea', message: unsupported.length ? `The chart type is not supported: ${unsupported.join(', ')}.` : 'The chart has no plot groups.' });\n\t\treturn { spec: normalizeChartSpec(input).spec, issues, unsupported, lossless: false };\n\t}\n\tconst first = types[0];\n\tconst combo = types.some((t) => t !== first);\n\tinput.type = combo ? (types.includes('bar') ? 'bar' : first) : first;\n\tif (!combo) for (const s of series) delete s.type;\n\telse for (const s of series) if (s.type === input.type) delete s.type;\n\tif (!combo) for (const s of series) if (s.axis) issues.push({ path: 'series', message: `\"${s.name}\" is on a second value axis.` });\n\tif (types.some((t) => !isCartesianChart(t)) && combo) unsupported.push('a pie or radar mixed with other chart types');\n\tinput.series = series;\n\tinput.categories = categories.length ? categories : Array.from({ length: Math.max(0, ...series.map((s) => s.values.length)) }, (_, i) => `${i + 1}`);\n\tinput.stacking = stacking;\n\tinput.orientation = orientation;\n\tinput.dataLabels = dataLabels;\n\tinput.points = points || first !== 'line';\n\tif (bool(val(groups[0], 'varyColors')) && (first === 'bar' || first === 'line') && series.length === 1) unsupported.push('one colour per point (vary colours)');\n\n\t// Axes\n\tconst readAxis = (a: Element | undefined, fallback: ChartAxis): ChartAxis => {\n\t\tconst axis: ChartAxis = { ...fallback, format: {} };\n\t\tif (!a) return axis;\n\t\taxis.show = !bool(val(a, 'delete'));\n\t\taxis.title = richText(kid(a, 'title')) ?? '';\n\t\taxis.gridlines = !!kid(a, 'majorGridlines');\n\t\tconst scaling = kid(a, 'scaling');\n\t\taxis.min = numberOf(val(scaling, 'min'));\n\t\taxis.max = numberOf(val(scaling, 'max'));\n\t\tif (val(scaling, 'orientation') === 'maxMin') axis.reverse = true;\n\t\tif (kid(scaling, 'logBase')) {\n\t\t\tif (a.localName !== 'valAx') unsupported.push('a logarithmic category axis');\n\t\t\telse {\n\t\t\t\taxis.scale = 'log';\n\t\t\t\tconst base = numberOf(val(scaling, 'logBase')) ?? 10;\n\t\t\t\tif (base !== 10) axis.logBase = base;\n\t\t\t}\n\t\t}\n\t\taxis.step = numberOf(val(a, 'majorUnit'));\n\t\tconst fmt = kid(a, 'numFmt');\n\t\tconst code = fmt?.getAttribute('formatCode');\n\t\tif (code && code !== 'General' && fmt?.getAttribute('sourceLinked') !== '1') axis.format = { code };\n\t\treturn axis;\n\t};\n\tconst xy = first === 'scatter' || first === 'bubble';\n\tconst catAxis = kid(plot, 'catAx') ?? kid(plot, 'dateAx') ?? (xy ? valAxes.find((a) => !vertical(a)) : undefined);\n\tinput.xAxis = readAxis(catAxis, defaultChartAxis(false));\n\tif (kid(plot, 'dateAx')) (input.xAxis as ChartAxis).kind = 'date';\n\tinput.yAxis = readAxis(primaryAxis ?? valAxes.find(vertical) ?? valAxes[0], defaultChartAxis(true));\n\tconst secondaryAxis = valAxes.find((a) => a !== primaryAxis && (xy ? vertical(a) && a !== primaryAxis : true) && a !== catAxis);\n\tif (series.some((s) => s.axis === 'secondary') && secondaryAxis) input.yAxis2 = readAxis(secondaryAxis, defaultChartAxis(false));\n\tconst { spec, issues: specIssues } = normalizeChartSpec(input);\n\tissues.push(...specIssues);\n\tconst uniq = [...new Set(unsupported)];\n\treturn { spec, issues, unsupported: uniq, lossless: uniq.length === 0 && specIssues.length === 0 };\n}\n\nfunction readChartex(root: Element, issues: ChartIssue[], unsupported: string[]): ChartOoxmlReadResult {\n\tconst data = new Map<string, { categories: string[]; values: ChartValue[]; code?: string }>();\n\tfor (const d of kids(kid(root, 'chartData'), 'data')) {\n\t\tconst id = d.getAttribute('id') ?? String(data.size);\n\t\tconst strDim = kids(d, 'strDim')[0];\n\t\tconst numDim = kids(d, 'numDim')[0];\n\t\tconst lvl = (dim: Element | undefined) => kids(dim, 'lvl')[0];\n\t\tconst cats = kids(lvl(strDim), 'pt').map((p) => p.textContent ?? '');\n\t\tconst values: ChartValue[] = [];\n\t\tconst nl = lvl(numDim);\n\t\tfor (const p of kids(nl, 'pt')) {\n\t\t\tconst i = Number(p.getAttribute('idx') ?? values.length);\n\t\t\twhile (values.length < i) values.push(null);\n\t\t\tvalues[i] = numberOf((p.textContent ?? '').trim());\n\t\t}\n\t\tdata.set(id, { categories: cats, values, code: nl?.getAttribute('formatCode') ?? undefined });\n\t}\n\tconst chart = kid(root, 'chart');\n\tconst region = path(chart, 'plotArea', 'plotAreaRegion');\n\tconst seriesEls = kids(region, 'series');\n\tconst layouts: Record<string, ChartType> = { waterfall: 'waterfall', funnel: 'funnel', treemap: 'treemap', sunburst: 'treemap', boxWhisker: 'box', clusteredColumn: 'histogram', paretoLine: 'histogram' };\n\tconst layout = seriesEls[0]?.getAttribute('layoutId') ?? '';\n\tconst type = layouts[layout];\n\tif (!type) {\n\t\tissues.push({ path: 'plotArea', message: `The chart layout \"${layout || 'unknown'}\" is not supported.` });\n\t\treturn { spec: normalizeChartSpec({}).spec, issues, unsupported: [layout || 'unknown chartex layout'], lossless: false };\n\t}\n\tif (layout === 'sunburst') unsupported.push('sunburst (drawn as a treemap of the innermost level)');\n\tif (layout === 'paretoLine') unsupported.push('pareto line');\n\tconst series: ChartSeries[] = [];\n\tlet categories: string[] = [];\n\tfor (const s of seriesEls) {\n\t\tif (s.getAttribute('layoutId') === 'paretoLine') continue;\n\t\tconst ref = kid(s, 'dataId')?.getAttribute('val') ?? '0';\n\t\tconst d = data.get(ref);\n\t\tif (!d) continue;\n\t\tif (!categories.length) categories = d.categories;\n\t\tconst out: ChartSeries = { id: `series-${series.length + 1}`, name: strings(kid(s, 'tx'))[0] ?? `Series ${series.length + 1}`, values: d.values };\n\t\tif (d.code && d.code !== 'General') out.format = { code: d.code };\n\t\tseries.push(out);\n\t}\n\tconst title = richText(kid(chart, 'title'));\n\tconst longest = Math.max(0, ...series.map((s) => s.values.length));\n\tconst input: Record<string, unknown> = {\n\t\ttype,\n\t\ttitle: title ?? '',\n\t\tseries,\n\t\tcategories: categories.length >= longest ? categories : Array.from({ length: longest }, (_, i) => categories[i] ?? `${i + 1}`)\n\t};\n\tif (type === 'waterfall') input.showTotal = false;\n\tconst { spec, issues: specIssues } = normalizeChartSpec(input);\n\tissues.push(...specIssues);\n\treturn { spec, issues, unsupported, lossless: unsupported.length === 0 && specIssues.length === 0 };\n}\n\n// ---------------------------------------------------------------------------\n// Writing\n// ---------------------------------------------------------------------------\n\nconst esc = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\nconst hex = (color: string | undefined) => {\n\tif (!color) return null;\n\tconst rgb = parseChartColor(color);\n\treturn rgb ? chartRgbToHex(rgb).slice(1).toUpperCase() : null;\n};\nconst fillXml = (color: string | undefined, line = false) => {\n\tconst h = hex(color);\n\tif (!h) return '';\n\treturn line ? `<c:spPr><a:ln w=\"28575\" cap=\"rnd\"><a:solidFill><a:srgbClr val=\"${h}\"/></a:solidFill><a:round/></a:ln></c:spPr>` : `<c:spPr><a:solidFill><a:srgbClr val=\"${h}\"/></a:solidFill></c:spPr>`;\n};\nconst rich = (text: string) => `<c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${esc(text)}</a:t></a:r></a:p></c:rich></c:tx><c:overlay val=\"0\"/>`;\nconst strLit = (items: readonly string[]) => `<c:strLit><c:ptCount val=\"${items.length}\"/>${items.map((s, i) => `<c:pt idx=\"${i}\"><c:v>${esc(s)}</c:v></c:pt>`).join('')}</c:strLit>`;\nconst numLit = (items: readonly ChartValue[], code = 'General') =>\n\t`<c:numLit><c:formatCode>${esc(code)}</c:formatCode><c:ptCount val=\"${items.length}\"/>${items.map((v, i) => (v === null || !Number.isFinite(v) ? '' : `<c:pt idx=\"${i}\"><c:v>${v}</c:v></c:pt>`)).join('')}</c:numLit>`;\n\nconst CURRENCY_SYMBOL: Record<string, string> = { USD: '$', EUR: '€', GBP: '£', JPY: '¥', CNY: '¥', INR: '₹' };\n\n/** A spreadsheet format code equivalent to a chart number format (`General` when there is none). */\nexport function chartFormatToCode(format: ChartNumberFormat): string {\n\tif (format.code) return format.code;\n\tconst d = format.decimals;\n\tconst frac = (n: number | undefined, fallback: number) => {\n\t\tconst k = n ?? fallback;\n\t\treturn k > 0 ? `.${'0'.repeat(k)}` : '';\n\t};\n\tconst wrap = (body: string) => `${format.prefix ? `\"${format.prefix.replace(/\"/g, '')}\"` : ''}${body}${format.suffix ? `\"${format.suffix.replace(/\"/g, '')}\"` : ''}`;\n\tswitch (format.style) {\n\t\tcase 'percent':\n\t\t\treturn wrap(`#,##0${frac(d, 0)}%`);\n\t\tcase 'currency': {\n\t\t\tconst code = (format.currency || 'USD').toUpperCase();\n\t\t\tconst sym = CURRENCY_SYMBOL[code] ?? `${code} `;\n\t\t\treturn wrap(`\"${sym}\"#,##0${frac(d, 0)}`);\n\t\t}\n\t\tcase 'compact':\n\t\t\treturn wrap('#,##0.0,,\"M\"');\n\t\tdefault:\n\t\t\treturn d !== undefined || format.prefix || format.suffix ? wrap(`#,##0${frac(d, 0)}`) : 'General';\n\t}\n}\n\n/** One `c:errBars` (CT_ErrBars order: errDir, errBarType, errValType, noEndCap, plus, minus, val). */\nfunction errBarsXml(bars: ChartErrorBars, dir: 'x' | 'y' | null): string {\n\tlet x = `<c:errBars>${dir ? `<c:errDir val=\"${dir}\"/>` : ''}<c:errBarType val=\"${bars.direction ?? 'both'}\"/><c:errValType val=\"${ERR_OUT[bars.type]}\"/><c:noEndCap val=\"${bars.cap === false ? 1 : 0}\"/>`;\n\tif (bars.type === 'custom') {\n\t\tconst plus = bars.plus ?? (bars.minus ?? []).map(() => null);\n\t\tx += `<c:plus>${numLit(plus)}</c:plus><c:minus>${numLit(bars.minus ?? plus)}</c:minus>`;\n\t} else if (bars.type !== 'stderr') x += `<c:val val=\"${bars.value ?? (bars.type === 'percent' ? 5 : 1)}\"/>`;\n\treturn `${x}</c:errBars>`;\n}\n\nconst MARKER_OUT: Record<ChartMarker, string> = { circle: 'circle', square: 'square', diamond: 'diamond', triangle: 'triangle', cross: 'x', none: 'none' };\n\nexport interface ChartOoxmlWriteResult {\n\t/** The `c:chartSpace` part. */\n\txml: string;\n\t/** What could not be written as DrawingML, as sentences (empty when nothing was lost). */\n\tissues: string[];\n}\n\n/**\n * Writes a chart as a DrawingML chart part (`c:chartSpace`) with the data as literals (no\n * embedded workbook), for `word/charts/chartN.xml` or `ppt/charts/chartN.xml`. Waterfall,\n * histogram, box, funnel and treemap charts need Office 2016 chartex parts; they are written\n * as the closest classic chart and reported in `issues`.\n */\nexport function chartToOoxml(spec: ChartSpec): ChartOoxmlWriteResult {\n\tconst issues: string[] = [];\n\tconst family = chartFamily(spec);\n\tlet type = spec.type;\n\tif (family === 'waterfall' || family === 'histogram' || family === 'box' || family === 'funnel') {\n\t\tissues.push(`${spec.type} charts are written as bar charts: DrawingML has no ${spec.type} type (Office 2016 stores it as chartex).`);\n\t\ttype = 'bar';\n\t} else if (family === 'treemap') {\n\t\tissues.push('Treemaps are written as pie charts: DrawingML has no treemap type.');\n\t\ttype = 'pie';\n\t}\n\tconst visible = spec.series.filter((s) => !s.hidden);\n\tif (visible.length < spec.series.length) issues.push(`${spec.series.length - visible.length} hidden series ${spec.series.length - visible.length === 1 ? 'is' : 'are'} left out.`);\n\tconst grouping = spec.stacking === 'stacked' ? 'stacked' : spec.stacking === 'percent' ? 'percentStacked' : 'standard';\n\tconst ids = { cat: 500000001, val: 500000002, cat2: 500000003, val2: 500000004 };\n\tconst xy = family === 'xy' || type === 'scatter' || type === 'bubble';\n\tconst pieLike = type === 'pie' || type === 'donut';\n\tconst typed = (s: ChartSeries) => (pieLike || type === 'radar' ? type : type === 'bubble' ? 'bubble' : xy ? 'scatter' : chartSeriesType({ type }, s));\n\t// Groups: (kind, axis) in first-appearance order.\n\tconst groups: { kind: string; secondary: boolean; series: { s: ChartSeries; index: number }[] }[] = [];\n\tvisible.forEach((s) => {\n\t\tconst kind = typed(s);\n\t\tconst secondary = !pieLike && s.axis === 'secondary';\n\t\tlet g = groups.find((x) => x.kind === kind && x.secondary === secondary);\n\t\tif (!g) groups.push((g = { kind, secondary, series: [] }));\n\t\tg.series.push({ s, index: spec.series.indexOf(s) });\n\t});\n\tif (pieLike && visible.length > 1) issues.push('Only the first series of a pie is drawn; the others are kept in the part.');\n\tconst catLit = strLit(spec.categories);\n\tlet order = 0;\n\tconst serXml = (kind: string, s: ChartSeries, index: number) => {\n\t\tconst parts = [`<c:idx val=\"${index}\"/>`, `<c:order val=\"${order++}\"/>`, `<c:tx><c:v>${esc(s.name)}</c:v></c:tx>`];\n\t\tconst lineLike = kind === 'line' || kind === 'scatter' || kind === 'radar';\n\t\tparts.push(fillXml(s.color, lineLike));\n\t\tif (kind === 'bar' || kind === 'bubble') parts.push('<c:invertIfNegative val=\"0\"/>');\n\t\tif (lineLike) {\n\t\t\tconst marker = s.marker ?? (spec.points || kind === 'scatter' ? 'circle' : 'none');\n\t\t\tparts.push(`<c:marker><c:symbol val=\"${MARKER_OUT[marker]}\"/>${marker !== 'none' ? '<c:size val=\"5\"/>' : ''}</c:marker>`);\n\t\t}\n\t\t(s.pointColors ?? []).forEach((c, i) => {\n\t\t\tconst h = hex(c ?? undefined);\n\t\t\tif (h) parts.push(`<c:dPt><c:idx val=\"${i}\"/>${kind === 'bar' ? '<c:invertIfNegative val=\"0\"/>' : ''}<c:bubble3D val=\"0\"/><c:spPr><a:solidFill><a:srgbClr val=\"${h}\"/></a:solidFill></c:spPr></c:dPt>`);\n\t\t});\n\t\tconst labels = s.dataLabels ?? spec.dataLabels;\n\t\tconst code = s.format ? chartFormatToCode(s.format) : undefined;\n\t\tif (s.dataLabels !== undefined || code)\n\t\t\tparts.push(`<c:dLbls>${code ? `<c:numFmt formatCode=\"${esc(code)}\" sourceLinked=\"0\"/>` : ''}<c:showLegendKey val=\"0\"/><c:showVal val=\"${labels ? 1 : 0}\"/><c:showCatName val=\"0\"/><c:showSerName val=\"0\"/><c:showPercent val=\"0\"/><c:showBubbleSize val=\"0\"/></c:dLbls>`);\n\t\tif (!pieLike && kind !== 'radar')\n\t\t\tfor (const t of s.trendlines ?? []) {\n\t\t\t\tlet x = `<c:trendline>${t.name ? `<c:name>${esc(t.name)}</c:name>` : ''}${fillXml(t.color, true)}<c:trendlineType val=\"${TREND_OUT[t.type]}\"/>`;\n\t\t\t\tif (t.type === 'polynomial') x += `<c:order val=\"${t.order ?? 2}\"/>`;\n\t\t\t\tif (t.type === 'moving-average') x += `<c:period val=\"${t.period ?? 2}\"/>`;\n\t\t\t\tif (t.forward) x += `<c:forward val=\"${t.forward}\"/>`;\n\t\t\t\tif (t.backward) x += `<c:backward val=\"${t.backward}\"/>`;\n\t\t\t\tif (t.intercept !== undefined && t.intercept !== null) x += `<c:intercept val=\"${t.intercept}\"/>`;\n\t\t\t\tx += `<c:dispRSqr val=\"${t.showR2 ? 1 : 0}\"/><c:dispEq val=\"${t.showEquation ? 1 : 0}\"/></c:trendline>`;\n\t\t\t\tparts.push(x);\n\t\t\t}\n\t\tif (!pieLike && kind !== 'radar') {\n\t\t\tconst xyKind = kind === 'scatter' || kind === 'bubble';\n\t\t\tif (s.errorBars) parts.push(errBarsXml(s.errorBars, xyKind ? 'y' : null));\n\t\t\tif (s.xErrorBars) {\n\t\t\t\tif (xyKind) parts.push(errBarsXml(s.xErrorBars, 'x'));\n\t\t\t\telse issues.push(`\"${s.name}\" has x error bars, which only scatter and bubble charts can hold; they are left out.`);\n\t\t\t}\n\t\t} else if (s.errorBars || s.xErrorBars) issues.push(`Error bars on \"${s.name}\" are left out: ${kind} charts cannot show them.`);\n\t\tconst valCode = chartFormatToCode(s.format ?? (s.axis === 'secondary' ? spec.yAxis2.format : spec.yAxis.format));\n\t\tif (kind === 'scatter' || kind === 'bubble') {\n\t\t\tconst xs = s.x ?? spec.categories.map((_, i) => i + 1);\n\t\t\tparts.push(`<c:xVal>${numLit(xs)}</c:xVal><c:yVal>${numLit(s.values, valCode)}</c:yVal>`);\n\t\t\tif (kind === 'bubble') parts.push(`<c:bubbleSize>${numLit(s.sizes ?? s.values.map(() => 1))}</c:bubbleSize><c:bubble3D val=\"0\"/>`);\n\t\t\telse parts.push(`<c:smooth val=\"${(s.curve ?? spec.curve) === 'smooth' ? 1 : 0}\"/>`);\n\t\t} else {\n\t\t\tparts.push(`<c:cat>${catLit}</c:cat><c:val>${numLit(s.values, valCode)}</c:val>`);\n\t\t\tif (kind === 'line') parts.push(`<c:smooth val=\"${(s.curve ?? spec.curve) === 'smooth' ? 1 : 0}\"/>`);\n\t\t}\n\t\tif ((s.curve ?? spec.curve) === 'step' && lineLike) issues.push(`\"${s.name}\" uses step lines, which DrawingML cannot express; they are written straight.`);\n\t\tif ((s.curve ?? spec.curve) === 'smooth' && kind === 'area') issues.push(`\"${s.name}\" is a smoothed area, which DrawingML cannot express; it is written straight.`);\n\t\treturn `<c:ser>${parts.join('')}</c:ser>`;\n\t};\n\tconst dLbls = `<c:dLbls><c:showLegendKey val=\"0\"/><c:showVal val=\"${spec.dataLabels ? 1 : 0}\"/><c:showCatName val=\"0\"/><c:showSerName val=\"0\"/><c:showPercent val=\"0\"/><c:showBubbleSize val=\"0\"/></c:dLbls>`;\n\tconst groupXml = groups.map((g) => {\n\t\tconst axes = g.secondary ? `<c:axId val=\"${ids.cat2}\"/><c:axId val=\"${ids.val2}\"/>` : `<c:axId val=\"${ids.cat}\"/><c:axId val=\"${ids.val}\"/>`;\n\t\tconst sers = g.series.map(({ s, index }) => serXml(g.kind, s, index)).join('');\n\t\tswitch (g.kind) {\n\t\t\tcase 'bar': {\n\t\t\t\tconst n = g.series.length;\n\t\t\t\tconst barsWidth = spec.stacking === 'none' ? n - (n - 1) * spec.overlap : 1;\n\t\t\t\tconst gapPct = Math.round(Math.min(500, (spec.gapWidth / Math.max(0.01, 1 - spec.gapWidth)) * barsWidth * 100));\n\t\t\t\tconst overlapPct = spec.stacking === 'none' ? Math.round(spec.overlap * 100) : 100;\n\t\t\t\treturn `<c:barChart><c:barDir val=\"${spec.orientation === 'horizontal' ? 'bar' : 'col'}\"/><c:grouping val=\"${spec.stacking === 'none' ? 'clustered' : grouping}\"/><c:varyColors val=\"0\"/>${sers}${dLbls}<c:gapWidth val=\"${gapPct}\"/><c:overlap val=\"${overlapPct}\"/>${axes}</c:barChart>`;\n\t\t\t}\n\t\t\tcase 'line':\n\t\t\t\treturn `<c:lineChart><c:grouping val=\"${spec.stacking === 'none' ? 'standard' : 'standard'}\"/><c:varyColors val=\"0\"/>${sers}${dLbls}<c:marker val=\"1\"/>${axes}</c:lineChart>`;\n\t\t\tcase 'area':\n\t\t\t\treturn `<c:areaChart><c:grouping val=\"${grouping}\"/><c:varyColors val=\"0\"/>${sers}${dLbls}${axes}</c:areaChart>`;\n\t\t\tcase 'scatter':\n\t\t\t\treturn `<c:scatterChart><c:scatterStyle val=\"lineMarker\"/><c:varyColors val=\"0\"/>${sers}${dLbls}${axes}</c:scatterChart>`;\n\t\t\tcase 'bubble':\n\t\t\t\treturn `<c:bubbleChart><c:varyColors val=\"0\"/>${sers}${dLbls}<c:bubbleScale val=\"100\"/>${axes}</c:bubbleChart>`;\n\t\t\tcase 'radar':\n\t\t\t\treturn `<c:radarChart><c:radarStyle val=\"marker\"/><c:varyColors val=\"0\"/>${sers}${dLbls}${axes}</c:radarChart>`;\n\t\t\tcase 'donut':\n\t\t\t\treturn `<c:doughnutChart><c:varyColors val=\"1\"/>${sers}${dLbls}<c:firstSliceAng val=\"0\"/><c:holeSize val=\"${Math.round(Math.max(10, Math.min(90, spec.innerRadius * 100)))}\"/></c:doughnutChart>`;\n\t\t\tdefault:\n\t\t\t\treturn `<c:pieChart><c:varyColors val=\"1\"/>${sers}${dLbls}<c:firstSliceAng val=\"0\"/></c:pieChart>`;\n\t\t}\n\t});\n\t// CT_Scaling order: logBase, orientation, max, min.\n\tconst scaling = (a: ChartAxis) =>\n\t\t`<c:scaling>${a.scale === 'log' ? `<c:logBase val=\"${a.logBase ?? 10}\"/>` : ''}<c:orientation val=\"${a.reverse ? 'maxMin' : 'minMax'}\"/>${a.max !== null ? `<c:max val=\"${a.max}\"/>` : ''}${a.min !== null ? `<c:min val=\"${a.min}\"/>` : ''}</c:scaling>`;\n\tconst title = (a: ChartAxis) => (a.title ? `<c:title>${rich(a.title)}</c:title>` : '');\n\tconst fmt = (a: ChartAxis) => {\n\t\tconst code = chartFormatToCode(a.format);\n\t\treturn code !== 'General' ? `<c:numFmt formatCode=\"${esc(code)}\" sourceLinked=\"0\"/>` : `<c:numFmt formatCode=\"${spec.stacking === 'percent' ? '0%' : 'General'}\" sourceLinked=\"1\"/>`;\n\t};\n\tconst horizontal = spec.orientation === 'horizontal';\n\tconst catPos = horizontal ? 'l' : 'b';\n\tconst valPos = horizontal ? 'b' : 'l';\n\tconst valAx = (id: number, cross: number, a: ChartAxis, pos: string, crosses: string, catKind = false) =>\n\t\t`<c:valAx><c:axId val=\"${id}\"/>${scaling(a)}<c:delete val=\"${a.show ? 0 : 1}\"/><c:axPos val=\"${pos}\"/>${a.gridlines ? '<c:majorGridlines/>' : ''}${title(a)}${fmt(a)}<c:majorTickMark val=\"out\"/><c:minorTickMark val=\"none\"/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"${cross}\"/><c:crosses val=\"${crosses}\"/><c:crossBetween val=\"${catKind ? 'midCat' : 'between'}\"/>${a.step ? `<c:majorUnit val=\"${a.step}\"/>` : ''}</c:valAx>`;\n\tconst catAx = (id: number, cross: number, a: ChartAxis, pos: string, hidden = false) =>\n\t\t`<c:${a.kind === 'date' ? 'dateAx' : 'catAx'}><c:axId val=\"${id}\"/><c:scaling><c:orientation val=\"${a.reverse ? 'maxMin' : 'minMax'}\"/></c:scaling><c:delete val=\"${a.show && !hidden ? 0 : 1}\"/><c:axPos val=\"${pos}\"/>${a.gridlines ? '<c:majorGridlines/>' : ''}${title(a)}<c:numFmt formatCode=\"General\" sourceLinked=\"1\"/><c:majorTickMark val=\"out\"/><c:minorTickMark val=\"none\"/><c:tickLblPos val=\"nextTo\"/><c:crossAx val=\"${cross}\"/><c:crosses val=\"autoZero\"/><c:auto val=\"1\"/>${a.kind === 'date' ? '<c:lblOffset val=\"100\"/><c:baseTimeUnit val=\"days\"/>' : '<c:lblAlgn val=\"ctr\"/><c:lblOffset val=\"100\"/><c:noMultiLvlLbl val=\"0\"/>'}</c:${a.kind === 'date' ? 'dateAx' : 'catAx'}>`;\n\tlet axes = '';\n\tif (!pieLike) {\n\t\tif (xy) axes = valAx(ids.cat, ids.val, spec.xAxis, 'b', 'autoZero', true) + valAx(ids.val, ids.cat, spec.yAxis, 'l', 'autoZero', true);\n\t\telse {\n\t\t\tif (spec.xAxis.scale === 'log') issues.push('The category axis cannot be logarithmic; its log scale is left out.');\n\t\t\taxes = catAx(ids.cat, ids.val, spec.xAxis, catPos) + valAx(ids.val, ids.cat, spec.yAxis, valPos, 'autoZero');\n\t\t}\n\t\tif (groups.some((g) => g.secondary)) axes += catAx(ids.cat2, ids.val2, spec.xAxis, catPos, true) + valAx(ids.val2, ids.cat2, spec.yAxis2, horizontal ? 't' : 'r', 'max');\n\t}\n\tconst legendPos = { bottom: 'b', top: 't', left: 'l', right: 'r' }[spec.legend.position];\n\tconst legend = spec.legend.show ? `<c:legend><c:legendPos val=\"${legendPos}\"/><c:overlay val=\"0\"/></c:legend>` : '';\n\tconst titleXml = spec.title ? `<c:title>${rich(spec.title)}</c:title><c:autoTitleDeleted val=\"0\"/>` : '<c:autoTitleDeleted val=\"1\"/>';\n\tif (spec.subtitle) issues.push('The subtitle is left out: DrawingML charts have one title.');\n\tif (family === 'radar' && spec.series.some((s) => s.trendlines?.length)) issues.push('Trendlines on a radar chart are left out.');\n\tconst xml =\n\t\t`<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>` +\n\t\t`<c:chartSpace xmlns:c=\"${CHART_OOXML_NS}\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">` +\n\t\t`<c:roundedCorners val=\"0\"/><c:chart>${titleXml}<c:plotArea><c:layout/>${groupXml.join('')}${axes}</c:plotArea>${legend}<c:plotVisOnly val=\"1\"/><c:dispBlanksAs val=\"gap\"/></c:chart>` +\n\t\t`<c:txPr><a:bodyPr/><a:lstStyle/><a:p><a:pPr><a:defRPr sz=\"${Math.round(10 * 100)}\"/></a:pPr><a:endParaRPr lang=\"en-US\"/></a:p></c:txPr></c:chartSpace>`;\n\treturn { xml, issues: [...new Set(issues)] };\n}\n","/**\n * Minimal, dependency-free ZIP reader used by the DOCX and zipped-export\n * import adapters.\n *\n * - Reads the central directory (including ZIP64 end records and extra\n * fields), so sizes come from the authoritative directory rather than local\n * headers or data descriptors.\n * - Supports stored (method 0) and deflate (method 8) entries; deflate is\n * inflated with the platform `DecompressionStream(\"deflate-raw\")` (modern\n * browsers, Node ≥ 18).\n * - Guards against zip bombs (entry-count and total-uncompressed-size caps,\n * enforced on the bytes actually inflated, not only the declared sizes),\n * path traversal in entry names and encrypted entries.\n * - Verifies CRC-32 checksums of extracted entries.\n */\n\nexport type ZipErrorCode =\n /** Not a ZIP archive, or its directory is truncated / inconsistent. */\n | \"invalid_archive\"\n /** Compression method other than stored/deflate, multi-disk archives, … */\n | \"unsupported_feature\"\n /** The entry is encrypted (general-purpose flag bit 0). */\n | \"encrypted\"\n /** An entry name is absolute or contains `..` segments. */\n | \"unsafe_path\"\n /** More entries than `maxEntries`. */\n | \"too_many_entries\"\n /** Extracting would exceed `maxTotalSize` uncompressed bytes. */\n | \"too_large\"\n /** The entry data is corrupt (bad header, size or CRC mismatch, bad deflate stream). */\n | \"corrupt_entry\"\n /** No entry with the requested name. */\n | \"entry_not_found\"\n /** `DecompressionStream` is unavailable in this environment. */\n | \"unsupported_environment\";\n\nexport class ZipError extends Error {\n readonly code: ZipErrorCode;\n readonly entryName?: string;\n\n constructor(code: ZipErrorCode, message: string, details: { entryName?: string; cause?: unknown } = {}) {\n super(message, details.cause !== undefined ? { cause: details.cause } : undefined);\n this.name = \"ZipError\";\n this.code = code;\n this.entryName = details.entryName;\n }\n}\n\nexport interface ZipEntry {\n /** Entry path with `/` separators (backslashes are normalized). */\n name: string;\n /** Whether the entry is a directory (name ends with `/`). */\n isDirectory: boolean;\n /** Whether the entry is encrypted; reading it throws `ZipError(\"encrypted\")`. */\n encrypted: boolean;\n /** Compression method (0 = stored, 8 = deflate). */\n method: number;\n /** Declared compressed size in bytes. */\n compressedSize: number;\n /** Declared uncompressed size in bytes. */\n size: number;\n /** CRC-32 of the uncompressed data. */\n crc32: number;\n /** Offset of the entry's local file header. */\n localHeaderOffset: number;\n}\n\nexport interface ZipReadOptions {\n /** Maximum number of entries in the central directory (default 10 000). */\n maxEntries?: number;\n /**\n * Maximum number of uncompressed bytes extracted from the archive, summed\n * over every `read` call (default 256 MiB). Enforced while inflating.\n */\n maxTotalSize?: number;\n /**\n * What to do with entries whose names are absolute or contain `..`\n * segments: `\"error\"` (default) rejects the archive, `\"skip\"` leaves them\n * out of `entries`.\n */\n unsafePaths?: \"error\" | \"skip\";\n}\n\nexport const DEFAULT_ZIP_MAX_ENTRIES = 10_000;\nexport const DEFAULT_ZIP_MAX_TOTAL_SIZE = 256 * 1024 * 1024;\n\nconst SIG_EOCD = 0x06054b50;\nconst SIG_ZIP64_EOCD = 0x06064b50;\nconst SIG_ZIP64_LOCATOR = 0x07064b50;\nconst SIG_CENTRAL = 0x02014b50;\nconst SIG_LOCAL = 0x04034b50;\nconst EOCD_SIZE = 22;\nconst MAX_COMMENT = 0xffff;\n\nlet crcTable: Uint32Array | null = null;\n\n/** CRC-32 (IEEE 802.3), as used by ZIP. */\nexport function zipCrc32(data: Uint8Array): number {\n if (!crcTable) {\n crcTable = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n crcTable[n] = c >>> 0;\n }\n }\n let crc = 0xffffffff;\n for (let i = 0; i < data.length; i++) crc = crcTable[(crc ^ data[i]) & 0xff] ^ (crc >>> 8);\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction toBytes(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n // Duck-typed so ArrayBuffers from other realms (iframes, jsdom) work too.\n if (ArrayBuffer.isView(data)) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n return new Uint8Array(data as ArrayBuffer);\n}\n\n/** Whether `name` is absolute, has a drive letter, or contains `..` / NUL. */\nexport function isUnsafeZipPath(name: string): boolean {\n if (!name || name.includes(\"\\0\")) return true;\n const normalized = name.replace(/\\\\/g, \"/\");\n if (normalized.startsWith(\"/\") || /^[a-zA-Z]:/.test(normalized)) return true;\n return normalized.split(\"/\").some((segment) => segment === \"..\");\n}\n\nconst utf8 = new TextDecoder(\"utf-8\");\n\n/** CP437 high half, used for names without the UTF-8 flag. */\nconst CP437_HIGH =\n \"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ \";\n\nfunction decodeName(bytes: Uint8Array, isUtf8: boolean): string {\n if (isUtf8 || bytes.every((b) => b < 0x80)) return utf8.decode(bytes);\n let out = \"\";\n for (const b of bytes) out += b < 0x80 ? String.fromCharCode(b) : CP437_HIGH[b - 0x80];\n return out;\n}\n\n/**\n * A parsed ZIP archive. Entry data is extracted lazily with {@link read}.\n * Create it with {@link readZip}.\n */\nexport class ZipArchive {\n /** Entries in central-directory order. */\n readonly entries: readonly ZipEntry[];\n private readonly byName = new Map<string, ZipEntry>();\n private extracted = 0;\n\n constructor(\n private readonly bytes: Uint8Array,\n entries: ZipEntry[],\n private readonly maxTotalSize: number,\n ) {\n this.entries = entries;\n entries.forEach((entry) => {\n if (!this.byName.has(entry.name)) this.byName.set(entry.name, entry);\n });\n }\n\n /** Looks up an entry by exact name (a leading `/` is ignored). */\n get(name: string): ZipEntry | undefined {\n return this.byName.get(name.replace(/^\\/+/, \"\"));\n }\n\n has(name: string): boolean {\n return !!this.get(name);\n }\n\n /** Uncompressed bytes extracted so far (counted against `maxTotalSize`). */\n get extractedSize(): number {\n return this.extracted;\n }\n\n /** Extracts an entry's data, verifying its size and CRC-32. */\n async read(entryOrName: ZipEntry | string): Promise<Uint8Array> {\n const entry = typeof entryOrName === \"string\" ? this.get(entryOrName) : entryOrName;\n if (!entry) {\n throw new ZipError(\"entry_not_found\", `ZIP entry \"${String(entryOrName)}\" not found.`, {\n entryName: String(entryOrName),\n });\n }\n const name = entry.name;\n if (entry.encrypted) {\n throw new ZipError(\"encrypted\", `ZIP entry \"${name}\" is encrypted; encrypted archives are not supported.`, {\n entryName: name,\n });\n }\n if (entry.isDirectory) return new Uint8Array(0);\n const remaining = this.maxTotalSize - this.extracted;\n if (entry.size > remaining) {\n throw new ZipError(\n \"too_large\",\n `Extracting \"${name}\" (${entry.size} bytes) would exceed the ${this.maxTotalSize}-byte limit.`,\n { entryName: name },\n );\n }\n\n const { bytes } = this;\n const offset = entry.localHeaderOffset;\n if (offset + 30 > bytes.length || readU32(bytes, offset) !== SIG_LOCAL) {\n throw new ZipError(\"corrupt_entry\", `ZIP entry \"${name}\" has no valid local header.`, { entryName: name });\n }\n const dataStart = offset + 30 + readU16(bytes, offset + 26) + readU16(bytes, offset + 28);\n const dataEnd = dataStart + entry.compressedSize;\n if (dataEnd > bytes.length) {\n throw new ZipError(\"corrupt_entry\", `ZIP entry \"${name}\" is truncated.`, { entryName: name });\n }\n const raw = bytes.subarray(dataStart, dataEnd);\n\n let data: Uint8Array;\n if (entry.method === 0) {\n if (entry.compressedSize !== entry.size) {\n throw new ZipError(\"corrupt_entry\", `Stored ZIP entry \"${name}\" has inconsistent sizes.`, { entryName: name });\n }\n data = raw.slice();\n } else if (entry.method === 8) {\n // Cap at the declared size: more output means a lying header (or a bomb).\n data = await inflateRaw(raw, entry.size, name);\n } else {\n throw new ZipError(\n \"unsupported_feature\",\n `ZIP entry \"${name}\" uses unsupported compression method ${entry.method}; only stored and deflate are supported.`,\n { entryName: name },\n );\n }\n if (data.length !== entry.size) {\n throw new ZipError(\"corrupt_entry\", `ZIP entry \"${name}\" size does not match the directory.`, { entryName: name });\n }\n this.extracted += data.length;\n if (zipCrc32(data) !== entry.crc32) {\n throw new ZipError(\"corrupt_entry\", `ZIP entry \"${name}\" failed its CRC-32 check.`, { entryName: name });\n }\n return data;\n }\n\n /** Extracts an entry and decodes it as UTF-8 (a leading BOM is removed). */\n async readText(entryOrName: ZipEntry | string): Promise<string> {\n const text = utf8.decode(await this.read(entryOrName));\n return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n }\n}\n\nfunction readU16(bytes: Uint8Array, offset: number): number {\n return bytes[offset] | (bytes[offset + 1] << 8);\n}\n\nfunction readU32(bytes: Uint8Array, offset: number): number {\n return (bytes[offset] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24)) >>> 0;\n}\n\nfunction readU64(bytes: Uint8Array, offset: number): number {\n const value = readU32(bytes, offset) + readU32(bytes, offset + 4) * 0x100000000;\n if (!Number.isSafeInteger(value)) {\n throw new ZipError(\"unsupported_feature\", \"ZIP64 value exceeds the supported range.\");\n }\n return value;\n}\n\n/** Inflates a raw deflate stream, failing as soon as output exceeds `limit` bytes. */\nasync function inflateRaw(raw: Uint8Array, limit: number, entryName: string): Promise<Uint8Array> {\n const Stream: typeof DecompressionStream | undefined = (globalThis as any).DecompressionStream;\n if (typeof Stream !== \"function\") {\n throw new ZipError(\n \"unsupported_environment\",\n \"Inflating ZIP entries needs DecompressionStream (modern browsers, Node 18+).\",\n { entryName },\n );\n }\n const stream = new Stream(\"deflate-raw\");\n const writer = stream.writable.getWriter();\n const reader = stream.readable.getReader();\n // Feed the input in slices so output is pulled (and checked) incrementally.\n const CHUNK = 64 * 1024;\n const feeding = (async () => {\n for (let i = 0; i < raw.length; i += CHUNK) await writer.write(raw.subarray(i, i + CHUNK) as unknown as BufferSource);\n await writer.close();\n })();\n feeding.catch(() => {});\n\n const chunks: Uint8Array[] = [];\n let total = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n total += value.length;\n if (total > limit) {\n throw new ZipError(\n \"corrupt_entry\",\n `ZIP entry \"${entryName}\" inflates beyond its declared size of ${limit} bytes.`,\n { entryName },\n );\n }\n chunks.push(value);\n }\n } catch (error) {\n reader.cancel().catch(() => {});\n writer.abort().catch(() => {});\n if (error instanceof ZipError) throw error;\n throw new ZipError(\"corrupt_entry\", `ZIP entry \"${entryName}\" has an invalid deflate stream.`, {\n entryName,\n cause: error,\n });\n }\n await feeding.catch(() => {});\n const out = new Uint8Array(total);\n let pos = 0;\n for (const chunk of chunks) {\n out.set(chunk, pos);\n pos += chunk.length;\n }\n return out;\n}\n\nfunction findEndOfCentralDirectory(bytes: Uint8Array): number {\n const min = Math.max(0, bytes.length - EOCD_SIZE - MAX_COMMENT);\n for (let i = bytes.length - EOCD_SIZE; i >= min; i--) {\n if (readU32(bytes, i) === SIG_EOCD && i + EOCD_SIZE + readU16(bytes, i + 20) <= bytes.length) return i;\n }\n return -1;\n}\n\n/**\n * Parses a ZIP archive's central directory. Entry data is not extracted until\n * {@link ZipArchive.read} is called. Throws {@link ZipError}.\n */\nexport async function readZip(data: ArrayBuffer | ArrayBufferView, options: ZipReadOptions = {}): Promise<ZipArchive> {\n const bytes = toBytes(data);\n const maxEntries = options.maxEntries ?? DEFAULT_ZIP_MAX_ENTRIES;\n const maxTotalSize = options.maxTotalSize ?? DEFAULT_ZIP_MAX_TOTAL_SIZE;\n\n const eocd = findEndOfCentralDirectory(bytes);\n if (eocd < 0) throw new ZipError(\"invalid_archive\", \"Not a ZIP archive (no end of central directory record).\");\n\n let diskNumber = readU16(bytes, eocd + 4);\n let cdDisk = readU16(bytes, eocd + 6);\n let count = readU16(bytes, eocd + 10);\n let cdSize = readU32(bytes, eocd + 12);\n let cdOffset = readU32(bytes, eocd + 16);\n\n if (count === 0xffff || cdSize === 0xffffffff || cdOffset === 0xffffffff) {\n const locator = eocd - 20;\n if (locator < 0 || readU32(bytes, locator) !== SIG_ZIP64_LOCATOR) {\n throw new ZipError(\"invalid_archive\", \"ZIP64 archive is missing its end of central directory locator.\");\n }\n const record = readU64(bytes, locator + 8);\n if (record + 56 > bytes.length || readU32(bytes, record) !== SIG_ZIP64_EOCD) {\n throw new ZipError(\"invalid_archive\", \"ZIP64 end of central directory record not found.\");\n }\n diskNumber = readU32(bytes, record + 16);\n cdDisk = readU32(bytes, record + 20);\n count = readU64(bytes, record + 32);\n cdSize = readU64(bytes, record + 40);\n cdOffset = readU64(bytes, record + 48);\n }\n if (diskNumber !== 0 || cdDisk !== 0) {\n throw new ZipError(\"unsupported_feature\", \"Multi-disk (spanned) ZIP archives are not supported.\");\n }\n if (count > maxEntries) {\n throw new ZipError(\"too_many_entries\", `ZIP archive has ${count} entries; the limit is ${maxEntries}.`);\n }\n if (cdOffset + cdSize > bytes.length) {\n throw new ZipError(\"invalid_archive\", \"ZIP central directory lies outside the file.\");\n }\n\n const entries: ZipEntry[] = [];\n let p = cdOffset;\n for (let i = 0; i < count; i++) {\n if (p + 46 > bytes.length || readU32(bytes, p) !== SIG_CENTRAL) {\n throw new ZipError(\"invalid_archive\", \"ZIP central directory is corrupt.\");\n }\n const flags = readU16(bytes, p + 8);\n const method = readU16(bytes, p + 10);\n const crc32 = readU32(bytes, p + 16);\n let compressedSize = readU32(bytes, p + 20);\n let size = readU32(bytes, p + 24);\n const nameLength = readU16(bytes, p + 28);\n const extraLength = readU16(bytes, p + 30);\n const commentLength = readU16(bytes, p + 32);\n let localHeaderOffset = readU32(bytes, p + 42);\n const nameStart = p + 46;\n const extraStart = nameStart + nameLength;\n const next = extraStart + extraLength + commentLength;\n if (next > bytes.length) throw new ZipError(\"invalid_archive\", \"ZIP central directory is truncated.\");\n\n // ZIP64 extended information: only the fields that overflowed are present, in order.\n for (let e = extraStart; e + 4 <= extraStart + extraLength; ) {\n const id = readU16(bytes, e);\n const len = readU16(bytes, e + 2);\n if (id === 0x0001) {\n let f = e + 4;\n const end = f + len;\n if (size === 0xffffffff && f + 8 <= end) {\n size = readU64(bytes, f);\n f += 8;\n }\n if (compressedSize === 0xffffffff && f + 8 <= end) {\n compressedSize = readU64(bytes, f);\n f += 8;\n }\n if (localHeaderOffset === 0xffffffff && f + 8 <= end) localHeaderOffset = readU64(bytes, f);\n }\n e += 4 + len;\n }\n\n const rawName = decodeName(bytes.subarray(nameStart, extraStart), (flags & 0x0800) !== 0);\n const name = rawName.replace(/\\\\/g, \"/\");\n p = next;\n if (isUnsafeZipPath(rawName)) {\n if (options.unsafePaths === \"skip\") continue;\n throw new ZipError(\"unsafe_path\", `ZIP entry name \"${rawName}\" is absolute or escapes the archive root.`, {\n entryName: rawName,\n });\n }\n entries.push({\n name,\n isDirectory: name.endsWith(\"/\"),\n encrypted: (flags & 0x0001) !== 0,\n method,\n compressedSize,\n size,\n crc32,\n localHeaderOffset,\n });\n }\n return new ZipArchive(bytes, entries, maxTotalSize);\n}\n"],"mappings":"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","names":["rich","axes"]}
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  CHART_AXIS_KINDS,
3
+ CHART_AXIS_SCALES,
3
4
  CHART_CURVES,
5
+ CHART_ERROR_BAR_DIRECTIONS,
6
+ CHART_ERROR_BAR_TYPES,
4
7
  CHART_LABEL_POSITIONS,
5
8
  CHART_LEGEND_POSITIONS,
6
9
  CHART_MARKERS,
@@ -10,7 +13,7 @@ import {
10
13
  CHART_STACKINGS,
11
14
  CHART_TRENDLINE_TYPES,
12
15
  CHART_TYPES
13
- } from "./chunk-OV7UAKIY.js";
16
+ } from "./chunk-633QC34G.js";
14
17
 
15
18
  // src/chart/schemas.ts
16
19
  var VALUE = { type: ["number", "string", "null"], description: 'A number, numeric text ("1,200", "12%", "$40", "(3)") or null for a gap.' };
@@ -42,7 +45,14 @@ var AXIS = (what) => ({
42
45
  step: { type: ["number", "null"], exclusiveMinimum: 0, description: "Fixed distance between ticks, or null for automatic." },
43
46
  gridlines: { type: "boolean", description: "Grid lines at each tick." },
44
47
  format: FORMAT,
45
- kind: { type: ["string", "null"], enum: [...CHART_AXIS_KINDS, null], description: 'Category axis only: "date" reads categories as dates and labels them by calendar steps.' }
48
+ kind: { type: ["string", "null"], enum: [...CHART_AXIS_KINDS, null], description: 'Category axis only: "date" reads categories as dates and labels them by calendar steps.' },
49
+ scale: {
50
+ type: ["string", "null"],
51
+ enum: [...CHART_AXIS_SCALES, null],
52
+ description: 'Value axes and the numeric x axis of scatter / bubble charts: "log" spaces ticks by powers of logBase (values of 0 or less are skipped; min and max must be above 0; not with percent stacking). "linear" or null is the default. Ignored on a category axis.'
53
+ },
54
+ logBase: { type: ["number", "null"], minimum: 2, maximum: 1e3, description: "Base of a log axis, 2 to 1000 (default 10; null resets)." },
55
+ reverse: { type: ["boolean", "null"], description: "Run the axis the other way: values from the top down (or right to left), categories from the far end. Default false." }
46
56
  },
47
57
  additionalProperties: false
48
58
  });
@@ -58,6 +68,24 @@ var TRENDLINE_PROPS = {
58
68
  name: { type: "string", description: 'Legend name (default e.g. "Linear (Sales)").' },
59
69
  color: { type: "string", description: "CSS colour (default: the series colour)." }
60
70
  };
71
+ var ERROR_BARS = (what) => ({
72
+ type: ["object", "null"],
73
+ description: `${what} null removes them.`,
74
+ properties: {
75
+ type: {
76
+ type: "string",
77
+ enum: [...CHART_ERROR_BAR_TYPES],
78
+ description: "fixed: the same amount at every point; percent: a percentage of each value; stddev: value standard deviations of the series, drawn around the series mean (as Excel does); stderr: the standard error of the series at every point; custom: per-point plus / minus amounts."
79
+ },
80
+ value: { type: "number", minimum: 0, description: "Amount in data units for fixed (default 1), percent of each value for percent (default 5), number of standard deviations for stddev (default 1). Not for stderr or custom." },
81
+ plus: { type: "array", items: VALUE, description: "custom only: amount above each point, one per category, in data units (0 or more; null for none)." },
82
+ minus: { type: "array", items: VALUE, description: "custom only: amount below each point, one per category (default: the plus amounts)." },
83
+ direction: { type: "string", enum: [...CHART_ERROR_BAR_DIRECTIONS], description: "both (default), plus (only above) or minus (only below)." },
84
+ cap: { type: "boolean", description: "Draw end caps (default true)." }
85
+ },
86
+ required: ["type"],
87
+ additionalProperties: false
88
+ });
61
89
  var SERIES_PROPS = {
62
90
  name: { type: "string", description: "Series name (legend and data grid header)." },
63
91
  values: { type: "array", items: VALUE, description: "One value per category, in category order (padded with gaps)." },
@@ -71,7 +99,9 @@ var SERIES_PROPS = {
71
99
  marker: { type: ["string", "null"], enum: [...CHART_MARKERS, null], description: "Point marker shape for line, area and scatter series." },
72
100
  curve: { type: ["string", "null"], enum: [...CHART_CURVES, null], description: "Line shape for this series: linear, smooth or step." },
73
101
  dataLabels: { type: ["boolean", "null"], description: "Value labels for this series (null follows the chart)." },
74
- format: { ...FORMAT, type: ["object", "null"], description: "How this series' labels are written (null follows the value axis)." }
102
+ format: { ...FORMAT, type: ["object", "null"], description: "How this series' labels are written (null follows the value axis)." },
103
+ errorBars: ERROR_BARS("Error bars along the value axis (bar, line, area and scatter series; on stacked charts they sit on the stack top)."),
104
+ xErrorBars: ERROR_BARS("Error bars along the x axis (scatter and bubble charts with numeric x values; amounts in x units).")
75
105
  };
76
106
  var CHART_UPDATE_PROPERTIES = {
77
107
  type: { type: "string", enum: [...CHART_TYPES], description: "Chart type." },
@@ -110,4 +140,4 @@ export {
110
140
  SERIES_PROPS,
111
141
  CHART_UPDATE_PROPERTIES
112
142
  };
113
- //# sourceMappingURL=chunk-5TWIN7ZJ.js.map
143
+ //# sourceMappingURL=chunk-47WWV3LI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chart/schemas.ts"],"sourcesContent":["import type { JsonSchema } from '../tools/schema.js';\nimport { CHART_ERROR_BAR_DIRECTIONS, CHART_ERROR_BAR_TYPES } from './errorbars.js';\nimport {\n\tCHART_AXIS_KINDS,\n\tCHART_AXIS_SCALES,\n\tCHART_CURVES,\n\tCHART_LABEL_POSITIONS,\n\tCHART_LEGEND_POSITIONS,\n\tCHART_MARKERS,\n\tCHART_NUMBER_STYLES,\n\tCHART_ORIENTATIONS,\n\tCHART_SERIES_TYPES,\n\tCHART_STACKINGS,\n\tCHART_TRENDLINE_TYPES,\n\tCHART_TYPES\n} from './spec.js';\n\n// JSON Schema fragments shared by the chart commands and the chart agent tools.\n\nexport const VALUE: JsonSchema = { type: ['number', 'string', 'null'], description: 'A number, numeric text (\"1,200\", \"12%\", \"$40\", \"(3)\") or null for a gap.' };\nexport const SERIES_REF: JsonSchema = { type: 'string', description: 'Series id (from get_chart) or exact series name.' };\nexport const CATEGORY_REF: JsonSchema = { type: ['string', 'integer'], description: 'Category index (0-based) or exact category label.' };\nexport const WIDTH: JsonSchema = { type: 'number', minimum: 50, maximum: 4096, description: 'Width in pixels (default 640).' };\nexport const HEIGHT: JsonSchema = { type: 'number', minimum: 50, maximum: 4096, description: 'Height in pixels (default 400).' };\n\nexport const FORMAT: JsonSchema = {\n\ttype: 'object',\n\tdescription: 'How numbers are written on this axis or series.',\n\tproperties: {\n\t\tstyle: { type: 'string', enum: [...CHART_NUMBER_STYLES], description: 'number (default), percent (0.25 → 25%), currency or compact (1.2K).' },\n\t\tdecimals: { type: 'integer', minimum: 0, maximum: 10, description: 'Fixed decimals (default: what the ticks need).' },\n\t\tcurrency: { type: 'string', description: 'ISO currency code for style \"currency\", e.g. \"EUR\" (default USD).' },\n\t\tprefix: { type: 'string', description: 'Text before every number.' },\n\t\tsuffix: { type: 'string', description: 'Text after every number.' },\n\t\tcode: { type: 'string', description: 'Spreadsheet format code such as \"#,##0.0,,\\\\\"M\\\\\"\" or \"0.0%\"; wins over the other fields.' }\n\t},\n\tadditionalProperties: false\n};\n\nexport const AXIS = (what: string): JsonSchema => ({\n\ttype: 'object',\n\tdescription: what,\n\tproperties: {\n\t\tshow: { type: 'boolean', description: 'Draw the axis labels (default true).' },\n\t\ttitle: { type: 'string', description: 'Axis title (\"\" for none).' },\n\t\tmin: { type: ['number', 'null'], description: 'Fixed lower bound, or null for automatic.' },\n\t\tmax: { type: ['number', 'null'], description: 'Fixed upper bound, or null for automatic.' },\n\t\tstep: { type: ['number', 'null'], exclusiveMinimum: 0, description: 'Fixed distance between ticks, or null for automatic.' },\n\t\tgridlines: { type: 'boolean', description: 'Grid lines at each tick.' },\n\t\tformat: FORMAT,\n\t\tkind: { type: ['string', 'null'], enum: [...CHART_AXIS_KINDS, null], description: 'Category axis only: \"date\" reads categories as dates and labels them by calendar steps.' },\n\t\tscale: {\n\t\t\ttype: ['string', 'null'],\n\t\t\tenum: [...CHART_AXIS_SCALES, null],\n\t\t\tdescription:\n\t\t\t\t'Value axes and the numeric x axis of scatter / bubble charts: \"log\" spaces ticks by powers of logBase (values of 0 or less are skipped; min and max must be above 0; not with percent stacking). \"linear\" or null is the default. Ignored on a category axis.'\n\t\t},\n\t\tlogBase: { type: ['number', 'null'], minimum: 2, maximum: 1000, description: 'Base of a log axis, 2 to 1000 (default 10; null resets).' },\n\t\treverse: { type: ['boolean', 'null'], description: 'Run the axis the other way: values from the top down (or right to left), categories from the far end. Default false.' }\n\t},\n\tadditionalProperties: false\n});\n\nexport const TRENDLINE_PROPS: Record<string, JsonSchema> = {\n\ttype: { type: 'string', enum: [...CHART_TRENDLINE_TYPES], description: 'Fit: linear, exponential, logarithmic, power, polynomial or moving-average.' },\n\torder: { type: 'integer', minimum: 2, maximum: 6, description: 'Polynomial order (default 2).' },\n\tperiod: { type: 'integer', minimum: 2, description: 'Moving-average period in points (default 2).' },\n\tforward: { type: 'number', minimum: 0, description: 'Extend the line this many x units past the last point (default 0).' },\n\tbackward: { type: 'number', minimum: 0, description: 'Extend the line this many x units before the first point (default 0).' },\n\tintercept: { type: ['number', 'null'], description: 'Force the fit through this y at x = 0 (linear, polynomial, exponential).' },\n\tshowEquation: { type: 'boolean', description: 'Write the fitted equation on the chart.' },\n\tshowR2: { type: 'boolean', description: 'Write R² on the chart.' },\n\tname: { type: 'string', description: 'Legend name (default e.g. \"Linear (Sales)\").' },\n\tcolor: { type: 'string', description: 'CSS colour (default: the series colour).' }\n};\n\nexport const ERROR_BARS = (what: string): JsonSchema => ({\n\ttype: ['object', 'null'],\n\tdescription: `${what} null removes them.`,\n\tproperties: {\n\t\ttype: {\n\t\t\ttype: 'string',\n\t\t\tenum: [...CHART_ERROR_BAR_TYPES],\n\t\t\tdescription: 'fixed: the same amount at every point; percent: a percentage of each value; stddev: value standard deviations of the series, drawn around the series mean (as Excel does); stderr: the standard error of the series at every point; custom: per-point plus / minus amounts.'\n\t\t},\n\t\tvalue: { type: 'number', minimum: 0, description: 'Amount in data units for fixed (default 1), percent of each value for percent (default 5), number of standard deviations for stddev (default 1). Not for stderr or custom.' },\n\t\tplus: { type: 'array', items: VALUE, description: 'custom only: amount above each point, one per category, in data units (0 or more; null for none).' },\n\t\tminus: { type: 'array', items: VALUE, description: 'custom only: amount below each point, one per category (default: the plus amounts).' },\n\t\tdirection: { type: 'string', enum: [...CHART_ERROR_BAR_DIRECTIONS], description: 'both (default), plus (only above) or minus (only below).' },\n\t\tcap: { type: 'boolean', description: 'Draw end caps (default true).' }\n\t},\n\trequired: ['type'],\n\tadditionalProperties: false\n});\n\nexport const SERIES_PROPS: Record<string, JsonSchema> = {\n\tname: { type: 'string', description: 'Series name (legend and data grid header).' },\n\tvalues: { type: 'array', items: VALUE, description: 'One value per category, in category order (padded with gaps).' },\n\tcolor: { type: ['string', 'null'], description: 'CSS colour, or null for the palette colour.' },\n\ttype: { type: ['string', 'null'], enum: [...CHART_SERIES_TYPES, null], description: 'Draw this series as bar, line, area or scatter (a combo chart); null follows the chart type.' },\n\thidden: { type: 'boolean', description: 'Hide the series (its data is kept).' },\n\taxis: { type: ['string', 'null'], enum: ['primary', 'secondary', null], description: 'Value axis: secondary is drawn on the right with its own scale.' },\n\tx: { type: ['array', 'null'], items: VALUE, description: 'Numeric x per category, for scatter and bubble charts.' },\n\tsizes: { type: ['array', 'null'], items: VALUE, description: 'Bubble sizes per category (area is proportional to size).' },\n\tpointColors: { type: ['array', 'null'], items: { type: ['string', 'null'] }, description: 'Colour per category (null keeps the series colour).' },\n\tmarker: { type: ['string', 'null'], enum: [...CHART_MARKERS, null], description: 'Point marker shape for line, area and scatter series.' },\n\tcurve: { type: ['string', 'null'], enum: [...CHART_CURVES, null], description: 'Line shape for this series: linear, smooth or step.' },\n\tdataLabels: { type: ['boolean', 'null'], description: 'Value labels for this series (null follows the chart).' },\n\tformat: { ...FORMAT, type: ['object', 'null'], description: 'How this series\\' labels are written (null follows the value axis).' },\n\terrorBars: ERROR_BARS('Error bars along the value axis (bar, line, area and scatter series; on stacked charts they sit on the stack top).'),\n\txErrorBars: ERROR_BARS('Error bars along the x axis (scatter and bubble charts with numeric x values; amounts in x units).')\n};\n\n\nexport const CHART_UPDATE_PROPERTIES: Record<string, JsonSchema> = {\n\t\t\t\ttype: { type: 'string', enum: [...CHART_TYPES], description: 'Chart type.' },\n\t\t\t\ttitle: { type: 'string', description: 'Title (\"\" for none).' },\n\t\t\t\tsubtitle: { type: 'string', description: 'Subtitle (\"\" for none).' },\n\t\t\t\txAxis: AXIS('Category axis (or numeric x axis of scatter / bubble charts).'),\n\t\t\t\tyAxis: AXIS('Value axis.'),\n\t\t\t\tyAxis2: AXIS('Secondary value axis (for series with axis \"secondary\").'),\n\t\t\t\tlegend: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tdescription: 'Legend.',\n\t\t\t\t\tproperties: { show: { type: 'boolean', description: 'Show the legend.' }, position: { type: 'string', enum: [...CHART_LEGEND_POSITIONS], description: 'Where the legend goes.' } },\n\t\t\t\t\tadditionalProperties: false\n\t\t\t\t},\n\t\t\t\tstacking: { type: 'string', enum: [...CHART_STACKINGS], description: 'none, stacked, or percent (each category scaled to 100%).' },\n\t\t\t\torientation: { type: 'string', enum: [...CHART_ORIENTATIONS], description: 'horizontal draws bars sideways.' },\n\t\t\t\tcurve: { type: 'string', enum: [...CHART_CURVES], description: 'Line shape: linear, smooth or step.' },\n\t\t\t\tpoints: { type: 'boolean', description: 'Dots on line and area series.' },\n\t\t\t\tdataLabels: { type: 'boolean', description: 'Value labels on bars, points and slices.' },\n\t\t\t\tlabelPosition: { type: 'string', enum: [...CHART_LABEL_POSITIONS], description: 'Bar label position; auto drops labels that do not fit.' },\n\t\t\t\tpalette: { type: 'array', items: { type: 'string' }, minItems: 1, description: 'Series colours in order (CSS colours).' },\n\t\t\t\tinnerRadius: { type: 'number', minimum: 0, maximum: 0.9, description: 'Donut hole as a fraction of the radius.' },\n\t\t\t\tgapWidth: { type: 'number', minimum: 0, maximum: 0.9, description: 'Space between bar groups as a fraction of the category (default 0.28).' },\n\t\t\t\toverlap: { type: 'number', minimum: -1, maximum: 1, description: 'Bar overlap within a group as a fraction of a bar (negative: a gap; default -0.12).' },\n\t\t\t\tbins: { type: ['integer', 'null'], minimum: 1, maximum: 500, description: 'Histogram bin count, or null for √n.' },\n\t\t\t\tshowTotal: { type: 'boolean', description: 'Waterfall: append a total bar.' }\n\t\t\t};\n"],"mappings":"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","names":[]}