@office-open/core 0.11.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/chart/index.d.mts +2 -2
  2. package/dist/chart/index.mjs +2 -2
  3. package/dist/{chart-Kf_utasF.mjs → chart-BAnjzVoe.mjs} +861 -287
  4. package/dist/chart-BAnjzVoe.mjs.map +1 -0
  5. package/dist/data-type-CZMKVaaT.d.mts.map +1 -1
  6. package/dist/descriptor/index.d.mts +1 -1
  7. package/dist/descriptor/index.mjs +1 -1
  8. package/dist/{descriptor-BX8xW8na.mjs → descriptor-BqaNZrrZ.mjs} +38 -10
  9. package/dist/{descriptor-BX8xW8na.mjs.map → descriptor-BqaNZrrZ.mjs.map} +1 -1
  10. package/dist/drawing/index.d.mts +2 -2
  11. package/dist/drawing/index.mjs +2 -2
  12. package/dist/{drawing-FBzd2I0m.mjs → drawing-BVwCkNXB.mjs} +3062 -3131
  13. package/dist/drawing-BVwCkNXB.mjs.map +1 -0
  14. package/dist/{generators-CElPsAhd.mjs → ext-uri-BHBcIrW7.mjs} +599 -343
  15. package/dist/ext-uri-BHBcIrW7.mjs.map +1 -0
  16. package/dist/index-BAxlDUQ1.d.mts +590 -0
  17. package/dist/index-BAxlDUQ1.d.mts.map +1 -0
  18. package/dist/{index-CLX7gU9J.d.mts → index-BQLIofaF.d.mts} +3 -2
  19. package/dist/index-BQLIofaF.d.mts.map +1 -0
  20. package/dist/{index-k8WKLXnA.d.mts → index-CaNwM5_e.d.mts} +19 -20
  21. package/dist/index-CaNwM5_e.d.mts.map +1 -0
  22. package/dist/{index-CnjCK-lF.d.mts → index-DPkf_CtG.d.mts} +566 -597
  23. package/dist/index-DPkf_CtG.d.mts.map +1 -0
  24. package/dist/{index-BsTUn4K1.d.mts → index-DcukVskh.d.mts} +9 -6
  25. package/dist/index-DcukVskh.d.mts.map +1 -0
  26. package/dist/{index-Cgz88FU0.d.mts → index-Di6XPdGl.d.mts} +26 -12
  27. package/dist/index-Di6XPdGl.d.mts.map +1 -0
  28. package/dist/{index-C0ClOhmZ.d.mts → index-L6AXewfV.d.mts} +11 -8
  29. package/dist/index-L6AXewfV.d.mts.map +1 -0
  30. package/dist/{index-DxwLMnBF.d.mts → index-k1h_t946.d.mts} +219 -99
  31. package/dist/index-k1h_t946.d.mts.map +1 -0
  32. package/dist/index.d.mts +161 -29
  33. package/dist/index.d.mts.map +1 -1
  34. package/dist/index.mjs +873 -87
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/{output-D_G_JR_8.d.mts → output-yyxdkG0C.d.mts} +2 -3
  37. package/dist/output-yyxdkG0C.d.mts.map +1 -0
  38. package/dist/patch/index.d.mts +2 -2
  39. package/dist/patch/index.mjs +2 -2
  40. package/dist/{patch-3KLx2yEP.mjs → patch-AkQY17CD.mjs} +71 -26
  41. package/dist/patch-AkQY17CD.mjs.map +1 -0
  42. package/dist/smartart/index.d.mts +2 -2
  43. package/dist/smartart/index.mjs +1 -1
  44. package/dist/{smartart-BxnkROOp.mjs → smartart-DV6ZcN5R.mjs} +27 -26
  45. package/dist/smartart-DV6ZcN5R.mjs.map +1 -0
  46. package/dist/{style-matrix-DAP6XrLv.mjs → style-matrix-DjhMuuQg.mjs} +4 -4
  47. package/dist/style-matrix-DjhMuuQg.mjs.map +1 -0
  48. package/dist/theme/index.d.mts +4 -4
  49. package/dist/theme/index.mjs +3 -2
  50. package/dist/{theme-OAuRcA9_.mjs → theme-Dx0Db9bX.mjs} +37 -71
  51. package/dist/theme-Dx0Db9bX.mjs.map +1 -0
  52. package/dist/{theme-options-BbWccl85.d.mts → theme-options-kO89NUEX.d.mts} +17 -17
  53. package/dist/theme-options-kO89NUEX.d.mts.map +1 -0
  54. package/dist/util/index.d.mts +3 -3
  55. package/dist/util/index.mjs +3 -3
  56. package/dist/{util-C94-JKtp.mjs → util-ptE16MEk.mjs} +69 -37
  57. package/dist/util-ptE16MEk.mjs.map +1 -0
  58. package/dist/{values-aVoirbWB.d.mts → values-BECDm4zr.d.mts} +15 -31
  59. package/dist/values-BECDm4zr.d.mts.map +1 -0
  60. package/dist/vector/index.d.mts +2 -2
  61. package/dist/vector/index.mjs +2 -2
  62. package/dist/{vector-TpjW6ZSc.mjs → vector-DhLGZjP5.mjs} +104 -147
  63. package/dist/vector-DhLGZjP5.mjs.map +1 -0
  64. package/package.json +3 -3
  65. package/dist/chart-Kf_utasF.mjs.map +0 -1
  66. package/dist/drawing-FBzd2I0m.mjs.map +0 -1
  67. package/dist/generators-CElPsAhd.mjs.map +0 -1
  68. package/dist/index-BsTUn4K1.d.mts.map +0 -1
  69. package/dist/index-C0ClOhmZ.d.mts.map +0 -1
  70. package/dist/index-CLX7gU9J.d.mts.map +0 -1
  71. package/dist/index-Cgz88FU0.d.mts.map +0 -1
  72. package/dist/index-CnjCK-lF.d.mts.map +0 -1
  73. package/dist/index-DpPeyf5f.d.mts +0 -316
  74. package/dist/index-DpPeyf5f.d.mts.map +0 -1
  75. package/dist/index-DxwLMnBF.d.mts.map +0 -1
  76. package/dist/index-k8WKLXnA.d.mts.map +0 -1
  77. package/dist/output-D_G_JR_8.d.mts.map +0 -1
  78. package/dist/patch-3KLx2yEP.mjs.map +0 -1
  79. package/dist/smartart-BxnkROOp.mjs.map +0 -1
  80. package/dist/style-matrix-DAP6XrLv.mjs.map +0 -1
  81. package/dist/theme-OAuRcA9_.mjs.map +0 -1
  82. package/dist/theme-options-BbWccl85.d.mts.map +0 -1
  83. package/dist/util-C94-JKtp.mjs.map +0 -1
  84. package/dist/values-aVoirbWB.d.mts.map +0 -1
  85. package/dist/vector-TpjW6ZSc.mjs.map +0 -1
@@ -1,9 +1,9 @@
1
- import { ut as parseOnOff } from "./generators-CElPsAhd.mjs";
2
- import { o as parse$1, s as stringify$1 } from "./descriptor-BX8xW8na.mjs";
3
- import { B as blipFillDesc, C as shapePropertiesDesc, S as groupShapePropertiesDesc, T as transform2DDesc, a as textBodyDesc, pt as stringifyNonVisualDrawingProperties } from "./drawing-FBzd2I0m.mjs";
4
- import { i as stringifyShapeStyle, n as parseShapeStyle } from "./style-matrix-DAP6XrLv.mjs";
1
+ import { B as xsdAxisCrossBetween, Ct as xsdSizeRepresents, Ft as xsdTrendlineType, H as xsdAxisLabelAlignment, Tt as xsdSplitType, U as xsdAxisOrientation, V as xsdAxisCrosses, W as xsdAxisPosition, Z as xsdDataLabelPosition, Zt as parseOnOff, st as xsdLegendPosition, tt as xsdErrorValueType } from "./ext-uri-BHBcIrW7.mjs";
2
+ import { A as groupShapePropertiesDesc, N as transform2DDesc, a as textBodyDesc, dt as stringifyNonVisualDrawingProperties, hn as blipFillDesc, j as shapePropertiesDesc } from "./drawing-BVwCkNXB.mjs";
3
+ import { o as parse$1, s as stringify$1 } from "./descriptor-BqaNZrrZ.mjs";
4
+ import { i as stringifyShapeStyle, n as parseShapeStyle } from "./style-matrix-DjhMuuQg.mjs";
5
5
  import { n as parseColorMapping, r as stringifyColorMapping } from "./color-mapping-CFF0vRSe.mjs";
6
- import { attr, children, escapeXml, findChild, stringifyElement, textOf } from "@office-open/xml";
6
+ import { attr, children, escapeXml, findChild, findFirst, stringify, stringifyElement, textOf } from "@office-open/xml";
7
7
  //#region src/chart/chart-collection.ts
8
8
  var ChartCollection = class {
9
9
  map;
@@ -45,7 +45,7 @@ const CHART_TYPE_TAGS_3D = {
45
45
  pie: "c:pie3DChart",
46
46
  area: "c:area3DChart"
47
47
  };
48
- const NO_AXES_TYPES = new Set([
48
+ const NO_AXES_TYPES = /* @__PURE__ */ new Set([
49
49
  "pie",
50
50
  "doughnut",
51
51
  "ofPie"
@@ -93,7 +93,7 @@ function valEl(tag, value) {
93
93
  return `<${tag} ${attrVal("val", value)}/>`;
94
94
  }
95
95
  function boolVal(value) {
96
- return value === false ? ` val="0"` : "";
96
+ return ` val="${value === false ? 0 : 1}"`;
97
97
  }
98
98
  function stringifyNumLit(value) {
99
99
  return `<c:numLit><c:formatCode>General</c:formatCode><c:ptCount val="1"/><c:pt idx="0"><c:v>${value}</c:v></c:pt></c:numLit>`;
@@ -101,7 +101,7 @@ function stringifyNumLit(value) {
101
101
  function stringifyTrendline(opts) {
102
102
  const parts = [];
103
103
  if (opts.name !== void 0) parts.push(`<c:name>${escapeXml(opts.name)}</c:name>`);
104
- parts.push(valEl("c:trendlineType", opts.type ?? "linear"));
104
+ parts.push(valEl("c:trendlineType", xsdTrendlineType.to(opts.type ?? "linear")));
105
105
  if (opts.order !== void 0) parts.push(valEl("c:order", opts.order));
106
106
  if (opts.period !== void 0) parts.push(valEl("c:period", opts.period));
107
107
  if (opts.forward !== void 0) parts.push(valEl("c:forward", opts.forward));
@@ -115,26 +115,58 @@ function stringifyTrendline(opts) {
115
115
  }
116
116
  function stringifyErrBars(opts) {
117
117
  const parts = [];
118
- if (opts.direction !== void 0) parts.push(valEl("c:errDir", opts.direction));
118
+ if (opts.direction === "x" || opts.direction === "y") parts.push(valEl("c:errDir", opts.direction));
119
119
  parts.push(valEl("c:errBarType", opts.barType ?? "both"));
120
- parts.push(valEl("c:errValType", opts.valueType ?? "fixedVal"));
120
+ parts.push(valEl("c:errValType", xsdErrorValueType.to(opts.valueType ?? "fixedValue")));
121
121
  if (opts.noEndCap !== void 0) parts.push(`<c:noEndCap${boolVal(opts.noEndCap)}/>`);
122
122
  if (opts.plusValue !== void 0) parts.push(`<c:plus>${stringifyNumLit(opts.plusValue)}</c:plus>`);
123
123
  if (opts.minusValue !== void 0) parts.push(`<c:minus>${stringifyNumLit(opts.minusValue)}</c:minus>`);
124
124
  if (opts.value !== void 0) parts.push(valEl("c:val", opts.value));
125
125
  return `<c:errBars>${parts.join("")}</c:errBars>`;
126
126
  }
127
- function stringifyDataLabel(opts) {
127
+ function stringifyDataLabel(opts, ctx) {
128
128
  if (opts.delete) return `<c:dLbl><c:idx val="${opts.index}"/><c:delete val="1"/></c:dLbl>`;
129
129
  const inner = [];
130
+ if (opts.layout === true) inner.push("<c:layout/>");
131
+ else if (opts.layout) inner.push(stringifyLayout(opts.layout));
132
+ if (opts.text) inner.push(`<c:tx><c:rich>${textBodyDesc.stringify(opts.text, ctx) ?? ""}</c:rich></c:tx>`);
130
133
  if (opts.numberFormat !== void 0) inner.push(`<c:numFmt formatCode="${escapeXml(opts.numberFormat)}" sourceLinked="0"/>`);
131
- if (opts.position !== void 0) inner.push(valEl("c:dLblPos", opts.position));
134
+ inner.push(chartSpPr(opts.shapeProperties, ctx));
135
+ if (opts.textProperties) inner.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
136
+ if (opts.position !== void 0) inner.push(valEl("c:dLblPos", xsdDataLabelPosition.to(opts.position)));
137
+ if (opts.showLegendKey !== void 0) inner.push(`<c:showLegendKey${boolVal(opts.showLegendKey)}/>`);
138
+ if (opts.showVal !== void 0) inner.push(`<c:showVal${boolVal(opts.showVal)}/>`);
139
+ if (opts.showCatName !== void 0) inner.push(`<c:showCatName${boolVal(opts.showCatName)}/>`);
140
+ if (opts.showSerName !== void 0) inner.push(`<c:showSerName${boolVal(opts.showSerName)}/>`);
141
+ if (opts.showPercent !== void 0) inner.push(`<c:showPercent${boolVal(opts.showPercent)}/>`);
142
+ if (opts.showBubbleSize !== void 0) inner.push(`<c:showBubbleSize${boolVal(opts.showBubbleSize)}/>`);
143
+ if (opts.separator !== void 0) inner.push(`<c:separator>${escapeXml(opts.separator)}</c:separator>`);
132
144
  return `<c:dLbl><c:idx val="${opts.index}"/>${inner.join("")}</c:dLbl>`;
133
145
  }
134
- function stringifyDataLabels(opts) {
146
+ const DATA_LABELS_SHARED_KEYS = [
147
+ "numberFormat",
148
+ "shapeProperties",
149
+ "textProperties",
150
+ "position",
151
+ "showLegendKey",
152
+ "showVal",
153
+ "showCatName",
154
+ "showSerName",
155
+ "showPercent",
156
+ "showBubbleSize",
157
+ "separator",
158
+ "showLeaderLines",
159
+ "leaderLines"
160
+ ];
161
+ function stringifyDataLabels(opts, ctx) {
162
+ const head = opts.labels?.map((lbl) => stringifyDataLabel(lbl, ctx)).join("") ?? "";
163
+ const hasShared = DATA_LABELS_SHARED_KEYS.some((key) => opts[key] !== void 0);
164
+ if (opts.delete === true || opts.delete !== void 0 && !hasShared) return `<c:dLbls>${head}<c:delete val="${opts.delete ? 1 : 0}"/></c:dLbls>`;
135
165
  const parts = [];
136
- if (opts.labels) for (const lbl of opts.labels) parts.push(stringifyDataLabel(lbl));
137
- if (opts.position !== void 0) parts.push(valEl("c:dLblPos", opts.position));
166
+ if (opts.numberFormat !== void 0) parts.push(`<c:numFmt formatCode="${escapeXml(opts.numberFormat)}" sourceLinked="0"/>`);
167
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
168
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
169
+ if (opts.position !== void 0) parts.push(valEl("c:dLblPos", xsdDataLabelPosition.to(opts.position)));
138
170
  if (opts.showLegendKey !== void 0) parts.push(`<c:showLegendKey${boolVal(opts.showLegendKey)}/>`);
139
171
  if (opts.showVal !== void 0) parts.push(`<c:showVal${boolVal(opts.showVal)}/>`);
140
172
  if (opts.showCatName !== void 0) parts.push(`<c:showCatName${boolVal(opts.showCatName)}/>`);
@@ -144,7 +176,7 @@ function stringifyDataLabels(opts) {
144
176
  if (opts.separator !== void 0) parts.push(`<c:separator>${escapeXml(opts.separator)}</c:separator>`);
145
177
  if (opts.showLeaderLines !== void 0) parts.push(`<c:showLeaderLines${boolVal(opts.showLeaderLines)}/>`);
146
178
  if (opts.leaderLines) parts.push(emptyEl("c:leaderLines"));
147
- return `<c:dLbls>${parts.join("")}</c:dLbls>`;
179
+ return `<c:dLbls>${head}${parts.join("")}</c:dLbls>`;
148
180
  }
149
181
  function stringifyView3D(opts) {
150
182
  const parts = [];
@@ -170,10 +202,11 @@ function stringifyLayout(manualLayout) {
170
202
  if (manualLayout.h !== void 0) parts.push(valEl("c:h", manualLayout.h));
171
203
  return `<c:layout><c:manualLayout>${parts.join("")}</c:manualLayout></c:layout>`;
172
204
  }
173
- function stringifySurface(tag, opts) {
205
+ function stringifySurface(tag, opts, ctx) {
174
206
  if (!opts) return "";
175
207
  const parts = [];
176
208
  if (opts.thickness !== void 0) parts.push(valEl("c:thickness", typeof opts.thickness === "string" ? Number(opts.thickness.replace("%", "")) : opts.thickness));
209
+ if (opts.shapeProperties) parts.push(chartSpPr(opts.shapeProperties, ctx));
177
210
  return parts.length ? `<${tag}>${parts.join("")}</${tag}>` : `<${tag}/>`;
178
211
  }
179
212
  const AXIS_TAG = {
@@ -186,14 +219,11 @@ function stringifyScaling(opts) {
186
219
  if (!opts) return emptyEl("c:scaling");
187
220
  const parts = [];
188
221
  if (opts.logBase !== void 0) parts.push(valEl("c:logBase", opts.logBase));
189
- if (opts.orientation !== void 0) parts.push(valEl("c:orientation", opts.orientation));
222
+ if (opts.orientation !== void 0) parts.push(valEl("c:orientation", xsdAxisOrientation.to(opts.orientation)));
190
223
  if (opts.max !== void 0) parts.push(valEl("c:max", opts.max));
191
224
  if (opts.min !== void 0) parts.push(valEl("c:min", opts.min));
192
225
  return `<c:scaling>${parts.join("")}</c:scaling>`;
193
226
  }
194
- function stringifyAxisTitle(title) {
195
- return `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title)}</a:t></a:r></a:p></c:rich></c:tx><c:overlay val="0"/></c:title>`;
196
- }
197
227
  function stringifyDisplayUnits(opts) {
198
228
  const parts = [];
199
229
  if (opts.customUnit !== void 0) parts.push(valEl("c:custUnit", opts.customUnit));
@@ -206,26 +236,33 @@ function stringifyDisplayUnits(opts) {
206
236
  * EG_AxShared (axId…crosses/crossesAt), then the kind-specific tail from
207
237
  * CT_CatAx / CT_DateAx / CT_SerAx / CT_ValAx.
208
238
  */
209
- function stringifyAxis(opts) {
239
+ function stringifyAxis(opts, ctx) {
210
240
  const parts = [];
211
241
  parts.push(valEl("c:axId", opts.id));
212
242
  parts.push(stringifyScaling(opts.scaling));
213
243
  if (opts.delete !== void 0) parts.push(`<c:delete${boolVal(opts.delete)}/>`);
214
- if (opts.position !== void 0) parts.push(valEl("c:axPos", opts.position));
215
- if (opts.majorGridlines) parts.push(emptyEl("c:majorGridlines"));
216
- if (opts.minorGridlines) parts.push(emptyEl("c:minorGridlines"));
217
- if (opts.title !== void 0) parts.push(stringifyAxisTitle(opts.title));
218
- if (opts.numberFormat !== void 0) parts.push(`<c:numFmt formatCode="${escapeXml(opts.numberFormat)}" sourceLinked="1"/>`);
244
+ const axPos = opts.position ?? (opts.kind === "value" ? "left" : "bottom");
245
+ parts.push(valEl("c:axPos", xsdAxisPosition.to(axPos)));
246
+ parts.push(stringifyChartLines("c:majorGridlines", opts.majorGridlines, ctx));
247
+ parts.push(stringifyChartLines("c:minorGridlines", opts.minorGridlines, ctx));
248
+ if (opts.title !== void 0) parts.push(typeof opts.title === "string" && opts.title === "" ? emptyEl("c:title") : stringifyTitle(opts.title, ctx));
249
+ if (opts.numberFormat !== void 0) {
250
+ const fmt = typeof opts.numberFormat === "string" ? { formatCode: opts.numberFormat } : opts.numberFormat;
251
+ const linked = fmt.sourceLinked === void 0 || fmt.sourceLinked ? 1 : 0;
252
+ parts.push(`<c:numFmt formatCode="${escapeXml(fmt.formatCode)}" sourceLinked="${linked}"/>`);
253
+ }
219
254
  if (opts.majorTickMark !== void 0) parts.push(valEl("c:majorTickMark", opts.majorTickMark));
220
255
  if (opts.minorTickMark !== void 0) parts.push(valEl("c:minorTickMark", opts.minorTickMark));
221
256
  if (opts.tickLabelPosition !== void 0) parts.push(valEl("c:tickLblPos", opts.tickLabelPosition));
257
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
258
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
222
259
  parts.push(valEl("c:crossAx", opts.crossAxisId));
223
260
  if (opts.crossesAt !== void 0) parts.push(valEl("c:crossesAt", opts.crossesAt));
224
- else if (opts.crosses !== void 0) parts.push(valEl("c:crosses", opts.crosses));
261
+ else if (opts.crosses !== void 0) parts.push(valEl("c:crosses", xsdAxisCrosses.to(opts.crosses)));
225
262
  switch (opts.kind) {
226
263
  case "category":
227
264
  if (opts.auto !== void 0) parts.push(`<c:auto${boolVal(opts.auto)}/>`);
228
- if (opts.labelAlignment !== void 0) parts.push(valEl("c:lblAlgn", opts.labelAlignment));
265
+ if (opts.labelAlignment !== void 0) parts.push(valEl("c:lblAlgn", xsdAxisLabelAlignment.to(opts.labelAlignment)));
229
266
  if (opts.labelOffset !== void 0) parts.push(valEl("c:lblOffset", opts.labelOffset));
230
267
  if (opts.tickLabelSkip !== void 0) parts.push(valEl("c:tickLblSkip", opts.tickLabelSkip));
231
268
  if (opts.tickMarkSkip !== void 0) parts.push(valEl("c:tickMarkSkip", opts.tickMarkSkip));
@@ -245,38 +282,54 @@ function stringifyAxis(opts) {
245
282
  if (opts.tickMarkSkip !== void 0) parts.push(valEl("c:tickMarkSkip", opts.tickMarkSkip));
246
283
  break;
247
284
  case "value":
248
- if (opts.crossBetween !== void 0) parts.push(valEl("c:crossBetween", opts.crossBetween));
285
+ if (opts.crossBetween !== void 0) parts.push(valEl("c:crossBetween", xsdAxisCrossBetween.to(opts.crossBetween)));
249
286
  if (opts.majorUnit !== void 0) parts.push(valEl("c:majorUnit", opts.majorUnit));
250
287
  if (opts.minorUnit !== void 0) parts.push(valEl("c:minorUnit", opts.minorUnit));
251
288
  if (opts.displayUnits) parts.push(stringifyDisplayUnits(opts.displayUnits));
252
- break;
253
289
  }
254
290
  const tag = AXIS_TAG[opts.kind];
255
291
  return `<${tag}>${parts.join("")}</${tag}>`;
256
292
  }
257
- function stringifyStrRef(values) {
258
- const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("");
259
- return `<c:strRef><c:f/><c:strCache><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:strCache></c:strRef>`;
293
+ /** Worksheet reference formula (c:f); empty element when not round-tripped. */
294
+ function refFormula(formula) {
295
+ return `<c:f>${escapeXml(formula ?? "")}</c:f>`;
296
+ }
297
+ function stringifyStrRef(values, formula) {
298
+ const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v ?? "")}</c:v></c:pt>`).join("");
299
+ return `<c:strRef>${refFormula(formula)}<c:strCache><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:strCache></c:strRef>`;
260
300
  }
261
301
  function stringifyStrLit(values) {
262
302
  const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("");
263
303
  return `<c:strLit><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:strLit>`;
264
304
  }
265
- function stringifyMultiLvlStrRef(levels) {
305
+ function stringifyMultiLvlStrRef(levels, formula) {
266
306
  const ptCount = levels.reduce((max, lvl) => Math.max(max, lvl.length), 0);
267
307
  const lvls = levels.map((lvl) => {
268
308
  return `<c:lvl>${lvl.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("")}</c:lvl>`;
269
309
  }).join("");
270
- return `<c:multiLvlStrRef><c:f/><c:multiLvlStrCache><c:ptCount ${attrVal("val", ptCount)}/>${lvls}</c:multiLvlStrCache></c:multiLvlStrRef>`;
310
+ return `<c:multiLvlStrRef>${refFormula(formula)}<c:multiLvlStrCache><c:ptCount ${attrVal("val", ptCount)}/>${lvls}</c:multiLvlStrCache></c:multiLvlStrRef>`;
311
+ }
312
+ function stringifyNumCatRef(values, formula, formatCode) {
313
+ const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("");
314
+ return `<c:numRef>${refFormula(formula)}<c:numCache><c:formatCode>${escapeXml(formatCode ?? "General")}</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numCache></c:numRef>`;
315
+ }
316
+ /** Whether the chart carries category-source data (c:cat is optional in CT_Ser). */
317
+ function hasCategoryData(opts) {
318
+ return opts.categories !== void 0 || opts.categoryLabels !== void 0 || opts.multiLevelCategories !== void 0 || opts.numericCategories === true;
271
319
  }
272
320
  function stringifyCategorySource(opts) {
273
- if (opts.multiLevelCategories) return stringifyMultiLvlStrRef(opts.multiLevelCategories);
321
+ if (opts.multiLevelCategories) return stringifyMultiLvlStrRef(opts.multiLevelCategories, opts.categoryFormula);
274
322
  if (opts.categoryLabels) return stringifyStrLit(opts.categoryLabels);
275
- return stringifyStrRef(opts.categories ?? []);
323
+ if (opts.numericCategories) return stringifyNumCatRef(opts.categories ?? [], opts.categoryFormula, opts.categoryFormatCode);
324
+ return stringifyStrRef(opts.categories ?? [], opts.categoryFormula);
276
325
  }
277
- function stringifyNumRef(values) {
326
+ function stringifyNumRef(values, formula, formatCode) {
278
327
  const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${v}</c:v></c:pt>`).join("");
279
- return `<c:numRef><c:f/><c:numCache><c:formatCode>General</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numCache></c:numRef>`;
328
+ return `<c:numRef>${refFormula(formula)}<c:numCache><c:formatCode>${escapeXml(formatCode ?? "General")}</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numCache></c:numRef>`;
329
+ }
330
+ function stringifyNumLitList(values, formatCode) {
331
+ const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${v}</c:v></c:pt>`).join("");
332
+ return `<c:numLit><c:formatCode>${escapeXml(formatCode ?? "General")}</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numLit>`;
280
333
  }
281
334
  function stringifyUpDownBars(gapWidth) {
282
335
  const inner = [];
@@ -285,12 +338,14 @@ function stringifyUpDownBars(gapWidth) {
285
338
  inner.push(emptyEl("c:downBars"));
286
339
  return `<c:upDownBars>${inner.join("")}</c:upDownBars>`;
287
340
  }
288
- function stringifyDataTable(opts) {
341
+ function stringifyDataTable(opts, ctx) {
289
342
  const parts = [];
290
343
  if (opts.showHorizontalBorder !== void 0) parts.push(`<c:showHorzBorder${boolVal(opts.showHorizontalBorder)}/>`);
291
344
  if (opts.showVerticalBorder !== void 0) parts.push(`<c:showVertBorder${boolVal(opts.showVerticalBorder)}/>`);
292
345
  if (opts.showOutline !== void 0) parts.push(`<c:showOutline${boolVal(opts.showOutline)}/>`);
293
346
  if (opts.showLegendKeys !== void 0) parts.push(`<c:showKeys${boolVal(opts.showLegendKeys)}/>`);
347
+ if (opts.shapeProperties) parts.push(chartSpPr(opts.shapeProperties, ctx));
348
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
294
349
  return `<c:dTable>${parts.join("")}</c:dTable>`;
295
350
  }
296
351
  function stringifyProtection(opts) {
@@ -303,6 +358,7 @@ function stringifyProtection(opts) {
303
358
  return `<c:protection>${parts.join("")}</c:protection>`;
304
359
  }
305
360
  function stringifyExternalData(opts) {
361
+ if (!opts.relationshipId || /^r?Id?(0|undefined)?$/i.test(opts.relationshipId)) return void 0;
306
362
  const auto = opts.autoUpdate !== void 0 ? `<c:autoUpdate val="${opts.autoUpdate ? 1 : 0}"/>` : "";
307
363
  return `<c:externalData r:id="${escapeXml(opts.relationshipId)}">${auto}</c:externalData>`;
308
364
  }
@@ -318,7 +374,9 @@ function stringifyHeaderFooter(opts) {
318
374
  if (opts.alignWithMargins !== void 0) attrs.push(`alignWithMargins="${opts.alignWithMargins ? 1 : 0}"`);
319
375
  if (opts.differentOddEven !== void 0) attrs.push(`differentOddEven="${opts.differentOddEven ? 1 : 0}"`);
320
376
  if (opts.differentFirst !== void 0) attrs.push(`differentFirst="${opts.differentFirst ? 1 : 0}"`);
321
- return `<c:headerFooter${attrs.length ? " " + attrs.join(" ") : ""}>${parts.join("")}</c:headerFooter>`;
377
+ const attrStr = attrs.length ? " " + attrs.join(" ") : "";
378
+ if (parts.length === 0) return `<c:headerFooter${attrStr}/>`;
379
+ return `<c:headerFooter${attrStr}>${parts.join("")}</c:headerFooter>`;
322
380
  }
323
381
  function stringifyPageMargins(opts) {
324
382
  return `<c:pageMargins l="${opts.left ?? .7}" r="${opts.right ?? .7}" t="${opts.top ?? .75}" b="${opts.bottom ?? .75}" header="${opts.header ?? .3}" footer="${opts.footer ?? .3}"/>`;
@@ -336,6 +394,7 @@ function stringifyPageSetup(opts) {
336
394
  if (opts.horizontalDpi !== void 0) attrs.push(`horizontalDpi="${opts.horizontalDpi}"`);
337
395
  if (opts.verticalDpi !== void 0) attrs.push(`verticalDpi="${opts.verticalDpi}"`);
338
396
  if (opts.copies !== void 0) attrs.push(`copies="${opts.copies}"`);
397
+ if (attrs.length === 0) return `<c:pageSetup/>`;
339
398
  return `<c:pageSetup ${attrs.join(" ")}/>`;
340
399
  }
341
400
  function stringifyPrintSettings(opts) {
@@ -354,34 +413,27 @@ function chartTypeHeader(opts) {
354
413
  case "column":
355
414
  case "bar":
356
415
  headerParts.push(valEl("c:barDir", opts.type === "column" ? "col" : "bar"));
357
- headerParts.push(valEl("c:grouping", "clustered"));
416
+ headerParts.push(valEl("c:grouping", opts.grouping ?? "clustered"));
358
417
  break;
359
418
  case "line":
360
419
  case "area":
361
- headerParts.push(valEl("c:grouping", "standard"));
420
+ headerParts.push(valEl("c:grouping", opts.grouping ?? "standard"));
362
421
  break;
363
422
  case "scatter":
364
423
  headerParts.push(valEl("c:scatterStyle", "line"));
365
424
  break;
366
425
  case "radar":
367
- headerParts.push(valEl("c:radarStyle", "standard"));
426
+ headerParts.push(valEl("c:radarStyle", opts.radarStyle ?? "standard"));
368
427
  break;
369
428
  case "ofPie":
370
429
  headerParts.push(valEl("c:ofPieType", opts.ofPieType ?? "pie"));
371
- headerParts.push(valEl("c:varyColors", 1));
372
- break;
373
- case "pie":
374
- case "doughnut":
375
- case "bubble":
376
- headerParts.push(valEl("c:varyColors", 1));
377
- break;
378
- case "surface":
379
- if (opts.wireframe !== void 0) headerParts.push(`<c:wireframe${boolVal(opts.wireframe)}/>`);
380
430
  break;
431
+ case "surface": if (opts.wireframe !== void 0) headerParts.push(`<c:wireframe${boolVal(opts.wireframe)}/>`);
381
432
  }
433
+ if (opts.varyColors !== void 0) headerParts.push(`<c:varyColors${boolVal(opts.varyColors)}/>`);
382
434
  return `<${tag}>${headerParts.join("")}`;
383
435
  }
384
- function chartTypeFooter(opts) {
436
+ function chartTypeFooter(opts, ctx) {
385
437
  const tag = opts.threeD ? CHART_TYPE_TAGS_3D[opts.type] : CHART_TYPE_TAGS[opts.type];
386
438
  const parts = [];
387
439
  switch (opts.type) {
@@ -390,25 +442,28 @@ function chartTypeFooter(opts) {
390
442
  if (opts.gapWidth !== void 0) parts.push(valEl("c:gapWidth", opts.gapWidth));
391
443
  if (opts.threeD) {
392
444
  if (opts.gapDepth !== void 0) parts.push(valEl("c:gapDepth", opts.gapDepth));
445
+ if (opts.shape !== void 0) parts.push(valEl("c:shape", opts.shape));
393
446
  } else {
394
447
  if (opts.overlap !== void 0) parts.push(valEl("c:overlap", opts.overlap));
395
- if (opts.seriesLines) parts.push(emptyEl("c:serLines"));
448
+ parts.push(stringifyChartLines("c:serLines", opts.seriesLines, ctx));
396
449
  }
397
450
  break;
398
451
  case "line":
399
- if (opts.dropLines) parts.push(emptyEl("c:dropLines"));
452
+ parts.push(stringifyChartLines("c:dropLines", opts.dropLines, ctx));
400
453
  if (!opts.threeD) {
401
- if (opts.highLowLines) parts.push(emptyEl("c:hiLowLines"));
454
+ parts.push(stringifyChartLines("c:hiLowLines", opts.highLowLines, ctx));
402
455
  if (opts.upDownBars) parts.push(stringifyUpDownBars(opts.upDownBarsGapWidth));
456
+ if (opts.markers !== void 0) parts.push(`<c:marker${boolVal(opts.markers)}/>`);
457
+ if (opts.smooth !== void 0) parts.push(`<c:smooth${boolVal(opts.smooth)}/>`);
403
458
  } else if (opts.gapDepth !== void 0) parts.push(valEl("c:gapDepth", opts.gapDepth));
404
459
  break;
405
460
  case "area":
406
- if (opts.dropLines) parts.push(emptyEl("c:dropLines"));
461
+ parts.push(stringifyChartLines("c:dropLines", opts.dropLines, ctx));
407
462
  if (opts.threeD && opts.gapDepth !== void 0) parts.push(valEl("c:gapDepth", opts.gapDepth));
408
463
  break;
409
464
  case "stock":
410
- if (opts.dropLines) parts.push(emptyEl("c:dropLines"));
411
- if (opts.highLowLines) parts.push(emptyEl("c:hiLowLines"));
465
+ parts.push(stringifyChartLines("c:dropLines", opts.dropLines, ctx));
466
+ parts.push(stringifyChartLines("c:hiLowLines", opts.highLowLines, ctx));
412
467
  if (opts.upDownBars) parts.push(stringifyUpDownBars(opts.upDownBarsGapWidth));
413
468
  break;
414
469
  case "pie":
@@ -416,35 +471,37 @@ function chartTypeFooter(opts) {
416
471
  break;
417
472
  case "doughnut":
418
473
  if (opts.firstSliceAngle !== void 0) parts.push(valEl("c:firstSliceAng", opts.firstSliceAngle));
419
- if (opts.holeSize !== void 0) parts.push(valEl("c:holeSize", opts.holeSize));
474
+ parts.push(valEl("c:holeSize", opts.holeSize ?? 10));
420
475
  break;
421
476
  case "bubble":
422
477
  if (opts.bubbleScale !== void 0) parts.push(valEl("c:bubbleScale", opts.bubbleScale));
423
478
  if (opts.showNegativeBubbles !== void 0) parts.push(`<c:showNegBubbles${boolVal(opts.showNegativeBubbles)}/>`);
424
- if (opts.sizeRepresents !== void 0) parts.push(valEl("c:sizeRepresents", opts.sizeRepresents));
479
+ if (opts.sizeRepresents !== void 0) parts.push(valEl("c:sizeRepresents", xsdSizeRepresents.to(opts.sizeRepresents)));
425
480
  break;
426
481
  case "ofPie":
427
482
  if (opts.gapWidth !== void 0) parts.push(valEl("c:gapWidth", opts.gapWidth));
428
- if (opts.splitType !== void 0) parts.push(valEl("c:splitType", opts.splitType));
483
+ if (opts.splitType !== void 0) parts.push(valEl("c:splitType", xsdSplitType.to(opts.splitType)));
429
484
  if (opts.splitPosition !== void 0) parts.push(valEl("c:splitPos", opts.splitPosition));
430
485
  if (opts.customSplitPoints?.length) {
431
486
  const pts = opts.customSplitPoints.map((p) => valEl("c:secondPiePt", p)).join("");
432
487
  parts.push(`<c:custSplit>${pts}</c:custSplit>`);
433
488
  }
434
489
  if (opts.secondPieSize !== void 0) parts.push(valEl("c:secondPieSize", opts.secondPieSize));
435
- if (opts.seriesLines) parts.push(emptyEl("c:serLines"));
436
- break;
437
- case "surface":
438
- if (opts.bandFormats?.length) parts.push(stringifyBandFormats(opts.bandFormats));
490
+ parts.push(stringifyChartLines("c:serLines", opts.seriesLines, ctx));
439
491
  break;
492
+ case "surface": if (opts.bandFormats?.length) parts.push(stringifyBandFormats(opts.bandFormats));
493
+ }
494
+ if (!NO_AXES_TYPES.has(opts.type)) {
495
+ const ids = opts.axes && opts.axisIds ? opts.axisIds : axesFor(opts).map((axis) => axis.id);
496
+ for (const id of ids) parts.push(valEl("c:axId", id));
440
497
  }
441
- if (!NO_AXES_TYPES.has(opts.type)) for (const axis of axesFor(opts)) parts.push(valEl("c:axId", axis.id));
442
498
  return `${parts.join("")}</${tag}>`;
443
499
  }
444
- function stringifyMarker$1(opts) {
500
+ function stringifyMarker$1(opts, ctx) {
445
501
  const parts = [];
446
502
  if (opts.symbol !== void 0) parts.push(valEl("c:symbol", opts.symbol));
447
503
  if (opts.size !== void 0) parts.push(valEl("c:size", opts.size));
504
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
448
505
  return `<c:marker>${parts.join("")}</c:marker>`;
449
506
  }
450
507
  function stringifyPictureOptions(opts) {
@@ -456,26 +513,27 @@ function stringifyPictureOptions(opts) {
456
513
  if (opts.pictureStackUnit !== void 0) parts.push(valEl("c:pictureStackUnit", opts.pictureStackUnit));
457
514
  return `<c:pictureOptions>${parts.join("")}</c:pictureOptions>`;
458
515
  }
459
- function stringifyDataPoint(opts) {
516
+ function stringifyDataPoint(opts, ctx) {
460
517
  const parts = [valEl("c:idx", opts.index)];
461
518
  if (opts.invertIfNegative !== void 0) parts.push(`<c:invertIfNegative${boolVal(opts.invertIfNegative)}/>`);
462
- if (opts.marker) parts.push(stringifyMarker$1(opts.marker));
519
+ if (opts.marker) parts.push(stringifyMarker$1(opts.marker, ctx));
463
520
  if (opts.bubble3D !== void 0) parts.push(`<c:bubble3D${boolVal(opts.bubble3D)}/>`);
464
521
  if (opts.explosion !== void 0) parts.push(valEl("c:explosion", opts.explosion));
522
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
465
523
  if (opts.pictureOptions) parts.push(stringifyPictureOptions(opts.pictureOptions));
466
524
  return `<c:dPt>${parts.join("")}</c:dPt>`;
467
525
  }
468
- function stringifySeries(index, series, opts) {
469
- const chartType = opts.type;
470
- const categories = opts.categories ?? [];
526
+ function stringifySeries(index, series, opts, ctx, groupType) {
527
+ const chartType = groupType ?? opts.type;
471
528
  const parts = [];
472
529
  const s = series;
473
- parts.push(valEl("c:idx", index));
474
- parts.push(valEl("c:order", index));
475
- parts.push(`<c:tx>${stringifyStrRef([series.name])}</c:tx>`);
476
- parts.push(emptyEl("c:spPr"));
530
+ parts.push(valEl("c:idx", s.index ?? index));
531
+ parts.push(valEl("c:order", s.order ?? index));
532
+ if (series.nameLiteral && series.name !== void 0) parts.push(`<c:tx><c:v>${escapeXml(series.name)}</c:v></c:tx>`);
533
+ else if (series.name !== void 0 || series.nameFormula !== void 0) parts.push(`<c:tx>${stringifyStrRef([series.name], series.nameFormula)}</c:tx>`);
534
+ parts.push(chartSpPr(s.shapeProperties, ctx));
477
535
  if (chartType === "line" || chartType === "scatter" || chartType === "radar") {
478
- if (s.marker) parts.push(stringifyMarker$1(s.marker));
536
+ if (s.marker) parts.push(stringifyMarker$1(s.marker, ctx));
479
537
  } else if (chartType === "column" || chartType === "bar") {
480
538
  if (s.invertIfNegative !== void 0) parts.push(`<c:invertIfNegative${boolVal(s.invertIfNegative)}/>`);
481
539
  if (s.pictureOptions) parts.push(stringifyPictureOptions(s.pictureOptions));
@@ -486,8 +544,8 @@ function stringifySeries(index, series, opts) {
486
544
  } else if (chartType === "pie" || chartType === "doughnut" || chartType === "ofPie") {
487
545
  if (s.explosion !== void 0) parts.push(valEl("c:explosion", s.explosion));
488
546
  }
489
- if (s.dataPoints) for (const dp of s.dataPoints) parts.push(stringifyDataPoint(dp));
490
- if (s.dataLabels) parts.push(stringifyDataLabels(s.dataLabels));
547
+ if (s.dataPoints) for (const dp of s.dataPoints) parts.push(stringifyDataPoint(dp, ctx));
548
+ if (s.dataLabels) parts.push(stringifyDataLabels(s.dataLabels, ctx));
491
549
  if (s.trendlines) for (const tl of s.trendlines) parts.push(stringifyTrendline(tl));
492
550
  if (s.errorBars) parts.push(stringifyErrBars(s.errorBars));
493
551
  if (chartType === "bubble") {
@@ -496,46 +554,186 @@ function stringifySeries(index, series, opts) {
496
554
  parts.push(`<c:yVal>${stringifyNumRef(bs.yValues)}</c:yVal>`);
497
555
  parts.push(`<c:bubbleSize>${stringifyNumRef(bs.bubbleSize)}</c:bubbleSize>`);
498
556
  } else if (chartType === "scatter") {
499
- parts.push(`<c:xVal>${stringifyStrRef(categories)}</c:xVal>`);
500
- parts.push(`<c:yVal>${stringifyNumRef(s.values)}</c:yVal>`);
501
- } else {
557
+ if ("xValues" in series) {
558
+ parts.push(`<c:xVal>${stringifyNumRef(series.xValues)}</c:xVal>`);
559
+ parts.push(`<c:yVal>${stringifyNumRef(series.yValues, series.valueFormula, series.formatCode)}</c:yVal>`);
560
+ } else {
561
+ parts.push(`<c:xVal>${stringifyCategorySource(opts)}</c:xVal>`);
562
+ parts.push(`<c:yVal>${stringifyNumRef(s.values, s.valueFormula, s.formatCode)}</c:yVal>`);
563
+ }
564
+ } else if (hasCategoryData(opts)) {
502
565
  parts.push(`<c:cat>${stringifyCategorySource(opts)}</c:cat>`);
503
- parts.push(`<c:val>${stringifyNumRef(s.values)}</c:val>`);
504
- }
566
+ parts.push(`<c:val>${s.valueLiteral ? stringifyNumLitList(s.values, s.formatCode) : stringifyNumRef(s.values, s.valueFormula, s.formatCode)}</c:val>`);
567
+ } else parts.push(`<c:val>${s.valueLiteral ? stringifyNumLitList(s.values, s.formatCode) : stringifyNumRef(s.values, s.valueFormula, s.formatCode)}</c:val>`);
505
568
  if ((chartType === "line" || chartType === "scatter") && s.smooth !== void 0) parts.push(`<c:smooth${boolVal(s.smooth)}/>`);
506
569
  if ((chartType === "column" || chartType === "bar") && s.shape !== void 0) parts.push(valEl("c:shape", s.shape));
507
570
  if (chartType === "bubble" && s.bubble3D !== void 0) parts.push(`<c:bubble3D${boolVal(s.bubble3D)}/>`);
571
+ if (s.ext) parts.push(`<c:extLst>${s.ext}</c:extLst>`);
508
572
  return `<c:ser>${parts.join("")}</c:ser>`;
509
573
  }
510
- function stringifyTitle(title) {
511
- return `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title)}</a:t></a:r></a:p></c:rich></c:tx><c:overlay val="0"/></c:title>`;
574
+ function stringifyChartLines(tag, opts, ctx) {
575
+ if (opts === void 0 || opts === false) return "";
576
+ if (opts === true) return emptyEl(tag);
577
+ return `<${tag}>${chartSpPr(opts.shapeProperties, ctx)}</${tag}>`;
578
+ }
579
+ /** Read any CT_ChartLines element: true when bare, decorations when carried. */
580
+ function readChartLines(parent, tag, ctx) {
581
+ const el = findChild(parent, tag);
582
+ if (!el) return void 0;
583
+ const spPrEl = findChild(el, "c:spPr");
584
+ if (!spPrEl) return true;
585
+ const lines = {};
586
+ const shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
587
+ if (shapeProperties) lines.shapeProperties = shapeProperties;
588
+ return lines;
589
+ }
590
+ /** Read one secondary chart group (combo): own series, flags, and 2D group tail. */
591
+ function readSecondaryGroup(secondaryEl, ctx) {
592
+ const mapping = TAG_TO_CHART_TYPE[secondaryEl.name ?? ""];
593
+ if (!mapping) return void 0;
594
+ let secType = mapping.type;
595
+ if (secondaryEl.name === "c:barChart" || secondaryEl.name === "c:bar3DChart") {
596
+ const barDir = findChild(secondaryEl, "c:barDir");
597
+ const barDirVal = barDir ? attr(barDir, "val") : void 0;
598
+ if (barDirVal === "bar") secType = "bar";
599
+ else if (barDirVal === "col") secType = "column";
600
+ }
601
+ const g = {
602
+ type: secType,
603
+ series: []
604
+ };
605
+ const grouping = readValStr(secondaryEl, "c:grouping");
606
+ if (grouping) g.grouping = grouping;
607
+ const varyColors = readBoolAttr(secondaryEl, "c:varyColors");
608
+ if (varyColors !== void 0) g.varyColors = varyColors;
609
+ const groupLabels = readDataLabels(secondaryEl, ctx);
610
+ if (groupLabels) g.dataLabels = groupLabels;
611
+ if (secType === "bar" || secType === "column") {
612
+ const gapWidth = readValNum(secondaryEl, "c:gapWidth");
613
+ if (gapWidth !== void 0) g.gapWidth = gapWidth;
614
+ if (!mapping.threeD) {
615
+ const overlap = readValNum(secondaryEl, "c:overlap");
616
+ if (overlap !== void 0) g.overlap = overlap;
617
+ } else {
618
+ const gapDepth = readValNum(secondaryEl, "c:gapDepth");
619
+ if (gapDepth !== void 0) g.gapDepth = gapDepth;
620
+ }
621
+ const seriesLines = readChartLines(secondaryEl, "c:serLines", ctx);
622
+ if (seriesLines !== void 0) g.seriesLines = seriesLines;
623
+ } else if (secType === "line") {
624
+ const dropLines = readChartLines(secondaryEl, "c:dropLines", ctx);
625
+ if (dropLines !== void 0) g.dropLines = dropLines;
626
+ const highLowLines = readChartLines(secondaryEl, "c:hiLowLines", ctx);
627
+ if (highLowLines !== void 0) g.highLowLines = highLowLines;
628
+ const upDownBars = findChild(secondaryEl, "c:upDownBars");
629
+ if (upDownBars) {
630
+ g.upDownBars = true;
631
+ const gw = readValNum(upDownBars, "c:gapWidth");
632
+ if (gw !== void 0) g.upDownBarsGapWidth = gw;
633
+ }
634
+ const markers = readBoolAttr(secondaryEl, "c:marker");
635
+ if (markers !== void 0) g.markers = markers;
636
+ const smooth = readBoolAttr(secondaryEl, "c:smooth");
637
+ if (smooth !== void 0) g.smooth = smooth;
638
+ } else if (secType === "area") {
639
+ const dropLines = readChartLines(secondaryEl, "c:dropLines", ctx);
640
+ if (dropLines !== void 0) g.dropLines = dropLines;
641
+ }
642
+ const secAxIds = children(secondaryEl, "c:axId");
643
+ if (secAxIds.length > 0) {
644
+ const ids = secAxIds.map((e) => Number(attr(e, "val"))).filter((n) => !isNaN(n));
645
+ if (ids.length > 0) g.axisIds = ids;
646
+ }
647
+ const secSeries = [];
648
+ for (const serEl of children(secondaryEl, "c:ser")) {
649
+ const { name, literal: nameLiteral } = readSeriesName(serEl);
650
+ const txEl = findChild(serEl, "c:tx");
651
+ const nameFormula = txEl ? readRefMeta(txEl).formula : void 0;
652
+ const valueEl = findChild(serEl, "c:val") ?? findChild(serEl, "c:yVal");
653
+ const valueLiteral = valueEl ? findChild(valueEl, "c:numLit") !== void 0 : false;
654
+ const values = valueEl ? readNumCache(valueEl) : [];
655
+ const valMeta = valueEl ? readRefMeta(valueEl) : {};
656
+ secSeries.push({
657
+ name,
658
+ ...nameLiteral ? { nameLiteral } : {},
659
+ ...nameFormula ? { nameFormula } : {},
660
+ ...valueLiteral ? { valueLiteral } : {},
661
+ ...valMeta.formula ? { valueFormula: valMeta.formula } : {},
662
+ ...valMeta.formatCode ? { formatCode: valMeta.formatCode } : {},
663
+ values,
664
+ ...readSeriesCommon(serEl, ctx)
665
+ });
666
+ }
667
+ g.series = secSeries;
668
+ return g;
669
+ }
670
+ function stringifySecondaryGroup(g, opts, ctx) {
671
+ const parts = [chartTypeHeader(g)];
672
+ for (const [i, series] of (g.series ?? []).entries()) parts.push(stringifySeries(i, series, opts, ctx, g.type));
673
+ if (g.dataLabels) parts.push(stringifyDataLabels(g.dataLabels, ctx));
674
+ switch (g.type) {
675
+ case "bar":
676
+ case "column":
677
+ if (g.gapWidth !== void 0) parts.push(valEl("c:gapWidth", g.gapWidth));
678
+ if (g.overlap !== void 0) parts.push(valEl("c:overlap", g.overlap));
679
+ parts.push(stringifyChartLines("c:serLines", g.seriesLines, ctx));
680
+ break;
681
+ case "line":
682
+ parts.push(stringifyChartLines("c:dropLines", g.dropLines, ctx));
683
+ parts.push(stringifyChartLines("c:hiLowLines", g.highLowLines, ctx));
684
+ if (g.upDownBars) parts.push(stringifyUpDownBars(g.upDownBarsGapWidth));
685
+ if (g.markers !== void 0) parts.push(`<c:marker${boolVal(g.markers)}/>`);
686
+ if (g.smooth !== void 0) parts.push(`<c:smooth${boolVal(g.smooth)}/>`);
687
+ break;
688
+ case "area": parts.push(stringifyChartLines("c:dropLines", g.dropLines, ctx));
689
+ }
690
+ for (const id of g.axisIds ?? []) parts.push(valEl("c:axId", id));
691
+ return `${parts.join("")}</${CHART_TYPE_TAGS[g.type]}>`;
692
+ }
693
+ function stringifyTitle(title, ctx) {
694
+ if (typeof title !== "string") {
695
+ const parts = [];
696
+ if (title.text !== void 0) parts.push(typeof title.text === "string" ? `<c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title.text)}</a:t></a:r></a:p></c:rich></c:tx>` : `<c:tx><c:rich>${textBodyDesc.stringify(title.text, ctx) ?? ""}</c:rich></c:tx>`);
697
+ if (title.layout !== void 0) parts.push(title.layout === true ? "<c:layout/>" : stringifyLayout(title.layout));
698
+ if (title.overlay !== void 0) parts.push(`<c:overlay${boolVal(title.overlay)}/>`);
699
+ if (title.shapeProperties) parts.push(chartSpPr(title.shapeProperties, ctx));
700
+ if (title.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(title.textProperties, ctx) ?? ""}</c:txPr>`);
701
+ return `<c:title>${parts.join("")}</c:title>`;
702
+ }
703
+ return `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title)}</a:t></a:r></a:p></c:rich></c:tx></c:title>`;
512
704
  }
513
- const LEGEND_TXPR = "<c:txPr><a:bodyPr rot=\"0\" spcFirstLastPara=\"1\" vertOverflow=\"ellipsis\" vert=\"horz\" wrap=\"square\" anchor=\"ctr\" anchorCtr=\"1\"/><a:lstStyle/><a:p><a:pPr><a:defRPr/></a:pPr><a:endParaRPr lang=\"en-US\"/></a:p></c:txPr>";
514
- function stringifyLegendEntry(entry) {
515
- if (!entry.delete) return "";
516
- return `<c:legendEntry><c:idx val="${entry.index}"/><c:delete val="1"/></c:legendEntry>`;
705
+ function stringifyLegendEntry(entry, ctx) {
706
+ if (entry.delete) return `<c:legendEntry><c:idx val="${entry.index}"/><c:delete val="1"/></c:legendEntry>`;
707
+ if (entry.textProperties) {
708
+ const txPr = textBodyDesc.stringify(entry.textProperties, ctx) ?? "";
709
+ return `<c:legendEntry><c:idx val="${entry.index}"/><c:txPr>${txPr}</c:txPr></c:legendEntry>`;
710
+ }
711
+ return "";
517
712
  }
518
- function stringifyLegend(opts) {
519
- return `<c:legend><c:legendPos val="${opts.legendPosition ?? "b"}"/>${(opts.legendEntries ?? []).map(stringifyLegendEntry).join("")}<c:layout/><c:overlay val="0"/><c:spPr><a:noFill/><a:ln><a:noFill/></a:ln><a:effectLst/></c:spPr>${LEGEND_TXPR}</c:legend>`;
713
+ function stringifyLegend(opts, ctx) {
714
+ return `<c:legend>${opts.legendPosition !== void 0 ? `<c:legendPos val="${xsdLegendPosition.to(opts.legendPosition)}"/>` : opts.showLegend === true ? "" : `<c:legendPos val="b"/>`}${(opts.legendEntries ?? []).map((e) => stringifyLegendEntry(e, ctx)).join("")}${opts.legendLayout === true ? "<c:layout/>" : opts.legendLayout ? stringifyLayout(opts.legendLayout) : ""}${opts.legendOverlay !== void 0 ? `<c:overlay${boolVal(opts.legendOverlay)}/>` : ""}${chartSpPr(opts.legendShapeProperties, ctx)}${opts.legendTextProperties ? `<c:txPr>${textBodyDesc.stringify(opts.legendTextProperties, ctx) ?? ""}</c:txPr>` : ""}</c:legend>`;
520
715
  }
521
716
  function stringifyPivotSource(opts) {
522
717
  return `<c:pivotSource><c:name>${escapeXml(opts.name)}</c:name><c:fmtId val="${opts.formatId}"/></c:pivotSource>`;
523
718
  }
524
- function stringifyPivotFormats(formats) {
719
+ function stringifyPivotFormats(formats, ctx) {
525
720
  return `<c:pivotFmts>${formats.map((f) => {
526
721
  let entry = `<c:idx val="${f.index}"/>`;
527
- if (f.marker) entry += stringifyMarker$1(f.marker);
722
+ if (f.marker) entry += stringifyMarker$1(f.marker, ctx);
528
723
  return `<c:pivotFmt>${entry}</c:pivotFmt>`;
529
724
  }).join("")}</c:pivotFmts>`;
530
725
  }
531
726
  function stringifyBandFormats(formats) {
532
727
  return `<c:bandFmts>${formats.map((f) => `<c:bandFmt><c:idx val="${f.index}"/></c:bandFmt>`).join("")}</c:bandFmts>`;
533
728
  }
534
- function noFillSpPr() {
535
- return `<c:spPr><a:noFill/><a:ln><a:noFill/></a:ln><a:effectLst/></c:spPr>`;
536
- }
537
- function chartTxPr() {
538
- return `<c:txPr><a:bodyPr/><a:lstStyle/><a:p><a:pPr><a:defRPr/></a:pPr><a:endParaRPr lang="en-US"/></a:p></c:txPr>`;
729
+ /**
730
+ * Wrap c:spPr inner content. An empty shape-properties object is a real
731
+ * `<c:spPr/>` placeholder (presence itself is the content), so undefined
732
+ * inner still emits the bare element.
733
+ */
734
+ function chartSpPr(opts, ctx) {
735
+ if (!opts) return "";
736
+ return `<c:spPr>${shapePropertiesDesc.stringify(opts, ctx) ?? ""}</c:spPr>`;
539
737
  }
540
738
  /** Default bottom category axis (c:catAx) for generated charts. */
541
739
  function categoryAxis(id, crossAxisId) {
@@ -543,10 +741,10 @@ function categoryAxis(id, crossAxisId) {
543
741
  kind: "category",
544
742
  id,
545
743
  crossAxisId,
546
- scaling: { orientation: "minMax" },
744
+ scaling: { orientation: "ascending" },
547
745
  delete: false,
548
- position: "b",
549
- crosses: "autoZero",
746
+ position: "bottom",
747
+ crosses: "zero",
550
748
  auto: true,
551
749
  labelOffset: 100,
552
750
  noMultiLevelLabel: false
@@ -558,11 +756,11 @@ function valueAxis(id, crossAxisId) {
558
756
  kind: "value",
559
757
  id,
560
758
  crossAxisId,
561
- scaling: { orientation: "minMax" },
759
+ scaling: { orientation: "ascending" },
562
760
  delete: false,
563
- position: "l",
761
+ position: "left",
564
762
  numberFormat: "General",
565
- crosses: "autoZero"
763
+ crosses: "zero"
566
764
  };
567
765
  }
568
766
  /** Default series axis (c:serAx) for surface charts. */
@@ -571,11 +769,11 @@ function seriesAxis(id, crossAxisId) {
571
769
  kind: "series",
572
770
  id,
573
771
  crossAxisId,
574
- scaling: { orientation: "minMax" },
772
+ scaling: { orientation: "ascending" },
575
773
  delete: false,
576
- position: "b",
774
+ position: "bottom",
577
775
  numberFormat: "General",
578
- crosses: "autoZero",
776
+ crosses: "zero",
579
777
  tickLabelSkip: 1
580
778
  };
581
779
  }
@@ -598,10 +796,19 @@ function defaultAxesFor(chartType, threeD) {
598
796
  }
599
797
  /** Provided axes override defaults; otherwise defaults are derived from chart type. */
600
798
  function axesFor(opts) {
601
- return opts.axes ?? defaultAxesFor(opts.type, opts.threeD);
799
+ if (!opts.axes) return defaultAxesFor(opts.type, opts.threeD);
800
+ const slots = defaultAxesFor(opts.type, opts.threeD);
801
+ return opts.axes.map((axis, i) => {
802
+ const slot = slots[i] ?? slots[slots.length - 1];
803
+ return {
804
+ ...axis,
805
+ id: axis.id ?? slot.id,
806
+ crossAxisId: axis.crossAxisId ?? slot.crossAxisId
807
+ };
808
+ });
602
809
  }
603
- function stringifyAxes(opts) {
604
- return axesFor(opts).map(stringifyAxis).join("");
810
+ function stringifyAxes(opts, ctx) {
811
+ return axesFor(opts).map((axis) => stringifyAxis(axis, ctx)).join("");
605
812
  }
606
813
  function readStrCache(el) {
607
814
  const strRef = findChild(el, "c:strRef");
@@ -609,13 +816,53 @@ function readStrCache(el) {
609
816
  const strCache = findChild(strRef, "c:strCache");
610
817
  if (!strCache?.elements) return [];
611
818
  const result = [];
612
- for (const pt of strCache.elements) if (pt.name === "c:pt" && pt.elements) {
613
- const v = pt.elements.find((c) => c.name === "c:v");
819
+ for (const pt of strCache.elements) if (pt.name === "c:pt") {
820
+ const v = findChild(pt, "c:v");
614
821
  const text = v ? textOf(v) : "";
615
822
  if (text !== "") result.push(text);
616
823
  }
617
824
  return result;
618
825
  }
826
+ /** Numeric category labels read as literal text (c:cat > c:numRef > c:numCache). */
827
+ function readNumCacheText(el) {
828
+ const numRef = findChild(el, "c:numRef");
829
+ if (!numRef) return [];
830
+ const numCache = findChild(numRef, "c:numCache");
831
+ if (!numCache?.elements) return [];
832
+ const result = [];
833
+ for (const pt of numCache.elements) if (pt.name === "c:pt") {
834
+ const v = findChild(pt, "c:v");
835
+ const text = v ? textOf(v) ?? "" : "";
836
+ result.push(text);
837
+ }
838
+ return result;
839
+ }
840
+ /** Reference metadata on a data-source slot: the c:f formula and, for numRef,
841
+ * the cached c:formatCode — both round-trip only. */
842
+ function readRefMeta(el) {
843
+ const strRef = findChild(el, "c:strRef");
844
+ const numRef = strRef ? void 0 : findChild(el, "c:numRef");
845
+ const ref = strRef ?? numRef;
846
+ const meta = {};
847
+ if (ref) {
848
+ const f = findChild(ref, "c:f");
849
+ const text = f ? textOf(f) : "";
850
+ if (text) meta.formula = text;
851
+ }
852
+ if (numRef) {
853
+ const cache = findChild(numRef, "c:numCache");
854
+ const fc = cache ? findChild(cache, "c:formatCode") : void 0;
855
+ const text = fc ? textOf(fc) : "";
856
+ if (text) meta.formatCode = text;
857
+ }
858
+ const numLit = strRef || numRef ? void 0 : findChild(el, "c:numLit");
859
+ if (numLit) {
860
+ const fc = findChild(numLit, "c:formatCode");
861
+ const text = fc ? textOf(fc) : "";
862
+ if (text) meta.formatCode = text;
863
+ }
864
+ return meta;
865
+ }
619
866
  function readStrLit(el) {
620
867
  const strLit = findChild(el, "c:strLit");
621
868
  if (!strLit) return void 0;
@@ -645,14 +892,32 @@ function readMultiLvlStrCache(el) {
645
892
  }
646
893
  return levels;
647
894
  }
895
+ function readNumLitPoints(numLit) {
896
+ const result = [];
897
+ for (const pt of numLit.elements ?? []) if (pt.name === "c:pt") {
898
+ const v = findChild(pt, "c:v");
899
+ const text = v ? textOf(v) : "";
900
+ if (text !== "") result.push(Number(text));
901
+ }
902
+ return result;
903
+ }
904
+ /** A scatter series carries numeric x values when c:xVal holds the
905
+ * CT_NumDataSource choice (numRef/numLit); the label-x shape stringifies
906
+ * x as a strRef category source instead. */
907
+ function hasNumericXRef(serEl) {
908
+ const xVal = findChild(serEl, "c:xVal");
909
+ return xVal !== void 0 && (findChild(xVal, "c:numRef") !== void 0 || findChild(xVal, "c:numLit") !== void 0);
910
+ }
648
911
  function readNumCache(el) {
912
+ const numLit = findChild(el, "c:numLit");
913
+ if (numLit) return readNumLitPoints(numLit);
649
914
  const numRef = findChild(el, "c:numRef");
650
915
  if (!numRef) return [];
651
916
  const numCache = findChild(numRef, "c:numCache");
652
917
  if (!numCache?.elements) return [];
653
918
  const result = [];
654
- for (const pt of numCache.elements) if (pt.name === "c:pt" && pt.elements) {
655
- const v = pt.elements.find((c) => c.name === "c:v");
919
+ for (const pt of numCache.elements) if (pt.name === "c:pt") {
920
+ const v = findChild(pt, "c:v");
656
921
  const text = v ? textOf(v) : "";
657
922
  if (text !== "") result.push(Number(text));
658
923
  }
@@ -660,16 +925,79 @@ function readNumCache(el) {
660
925
  }
661
926
  function readSeriesName(serEl) {
662
927
  const tx = findChild(serEl, "c:tx");
663
- if (!tx) return "";
664
- return readStrCache(tx)[0] ?? "";
928
+ if (!tx) return {
929
+ name: void 0,
930
+ literal: false
931
+ };
932
+ const v = findChild(tx, "c:v");
933
+ if (v && !findChild(tx, "c:strRef")) {
934
+ const text = textOf(v);
935
+ return {
936
+ name: text !== "" ? text : void 0,
937
+ literal: true
938
+ };
939
+ }
940
+ return {
941
+ name: readStrCache(tx)[0] ?? "",
942
+ literal: false
943
+ };
944
+ }
945
+ /** Read a c:title. Plain text stays a string; layout/overlay/spPr/txPr
946
+ * decorations promote it to the ChartTitleOptions object form. */
947
+ /** Read the title's c:tx > c:rich body; undefined when absent or strRef-linked. */
948
+ function readTitleBody(titleEl, ctx) {
949
+ const rich = findChild(findChild(titleEl, "c:tx") ?? titleEl, "c:rich");
950
+ if (!rich) return void 0;
951
+ return collapseTitleBody(textBodyDesc.parse(rich, ctx));
952
+ }
953
+ /**
954
+ * Collapse a parsed title body to its plain text when it is exactly what the
955
+ * string form emits (empty bodyPr/listStyle, one bare run), keeping simple
956
+ * titles readable in the Options JSON.
957
+ */
958
+ function collapseTitleBody(body) {
959
+ if (body.listStyle !== void 0) return body;
960
+ if (body.bodyProperties !== void 0 && Object.keys(body.bodyProperties).length > 0) return body;
961
+ const ps = body.paragraphs ?? [];
962
+ if (ps.length !== 1) return body;
963
+ const p = ps[0];
964
+ if (p === void 0) return body;
965
+ if (typeof p === "string") return p;
966
+ if (p.properties !== void 0 || p.children !== void 0) return body;
967
+ if (p.endParagraphProperties !== void 0 && p.endParagraphProperties !== false) return body;
968
+ return p.text ?? "";
969
+ }
970
+ function readTitle(titleEl, ctx) {
971
+ const body = readTitleBody(titleEl, ctx);
972
+ const text = body === void 0 ? readTitleText(titleEl) : void 0;
973
+ const layoutEl = findChild(titleEl, "c:layout");
974
+ const overlayEl = findChild(titleEl, "c:overlay");
975
+ const spPrEl = findChild(titleEl, "c:spPr");
976
+ const txPrEl = findChild(titleEl, "c:txPr");
977
+ if (!layoutEl && !overlayEl && !spPrEl && !txPrEl) {
978
+ if (typeof body === "string" || body === void 0) return body ?? text ?? "";
979
+ return { text: body };
980
+ }
981
+ const title = {};
982
+ if (body !== void 0) title.text = body;
983
+ else if (text !== void 0) title.text = text;
984
+ if (layoutEl) title.layout = readManualLayout(layoutEl) ?? true;
985
+ if (overlayEl) title.overlay = parseOnOff(attr(overlayEl, "val")) ?? false;
986
+ if (spPrEl) title.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
987
+ if (txPrEl) title.textProperties = textBodyDesc.parse(txPrEl, ctx);
988
+ return title;
665
989
  }
666
990
  function readTitleText(titleEl) {
667
991
  const tx = findChild(titleEl, "c:tx");
668
992
  if (!tx?.elements) return void 0;
669
- for (const child of tx.elements) if (child.name === "c:rich" && child.elements) {
670
- for (const sub of child.elements) if (sub.name === "a:p" && sub.elements) {
671
- for (const r of sub.elements) if (r.name === "a:r" && r.elements) {
672
- for (const t of r.elements) if (t.name === "a:t") {
993
+ for (const child of tx.elements) {
994
+ if (child.name !== "c:rich") continue;
995
+ for (const sub of child.elements ?? []) {
996
+ if (sub.name !== "a:p") continue;
997
+ for (const r of sub.elements ?? []) {
998
+ if (r.name !== "a:r") continue;
999
+ const t = findChild(r, "a:t");
1000
+ if (t) {
673
1001
  const text = textOf(t);
674
1002
  if (text) return text;
675
1003
  }
@@ -700,8 +1028,8 @@ function readNumLit(el, childName) {
700
1028
  if (!child) return void 0;
701
1029
  const numLit = findChild(child, "c:numLit");
702
1030
  if (!numLit?.elements) return void 0;
703
- for (const pt of numLit.elements) if (pt.name === "c:pt" && pt.elements) {
704
- const v = pt.elements.find((c) => c.name === "c:v");
1031
+ for (const pt of numLit.elements) if (pt.name === "c:pt") {
1032
+ const v = findChild(pt, "c:v");
705
1033
  if (v) {
706
1034
  const text = textOf(v);
707
1035
  if (text) return Number(text);
@@ -714,7 +1042,7 @@ function readTrendlines(serEl) {
714
1042
  return tlEls.map((tl) => {
715
1043
  const opts = {};
716
1044
  const type = readValStr(tl, "c:trendlineType");
717
- if (type) opts.type = type;
1045
+ if (type) opts.type = xsdTrendlineType.from(type);
718
1046
  const order = readValNum(tl, "c:order");
719
1047
  if (order !== void 0) opts.order = order;
720
1048
  const period = readValNum(tl, "c:period");
@@ -729,7 +1057,8 @@ function readTrendlines(serEl) {
729
1057
  if (dispRSqr !== void 0) opts.dispRSqr = dispRSqr;
730
1058
  const dispEq = readBoolAttr(tl, "c:dispEq");
731
1059
  if (dispEq !== void 0) opts.dispEq = dispEq;
732
- const nameText = textOf(findChild(tl, "c:name"));
1060
+ const nameEl = findChild(tl, "c:name");
1061
+ const nameText = textOf(nameEl);
733
1062
  if (nameText) opts.name = nameText;
734
1063
  const labelFmt = attr(findChild(findChild(tl, "c:trendlineLbl"), "c:numFmt"), "formatCode");
735
1064
  if (labelFmt) opts.label = { numberFormat: labelFmt };
@@ -745,7 +1074,7 @@ function readErrBars(serEl) {
745
1074
  const barType = readValStr(ebEl, "c:errBarType");
746
1075
  if (barType) opts.barType = barType;
747
1076
  const valueType = readValStr(ebEl, "c:errValType");
748
- if (valueType) opts.valueType = valueType;
1077
+ if (valueType) opts.valueType = xsdErrorValueType.from(valueType);
749
1078
  const noEndCap = readBoolAttr(ebEl, "c:noEndCap");
750
1079
  if (noEndCap !== void 0) opts.noEndCap = noEndCap;
751
1080
  const plusValue = readNumLit(ebEl, "c:plus");
@@ -756,12 +1085,26 @@ function readErrBars(serEl) {
756
1085
  if (value !== void 0) opts.value = value;
757
1086
  return opts;
758
1087
  }
759
- function readDataLabels(serEl) {
1088
+ function readDataLabels(serEl, ctx) {
760
1089
  const dlEl = findChild(serEl, "c:dLbls");
761
1090
  if (!dlEl) return void 0;
762
1091
  const opts = {};
1092
+ const groupDelete = readBoolAttr(dlEl, "c:delete");
1093
+ if (groupDelete !== void 0) opts.delete = groupDelete;
1094
+ const numFmt = attr(findChild(dlEl, "c:numFmt"), "formatCode");
1095
+ if (numFmt) opts.numberFormat = numFmt;
1096
+ const dlSpPr = findChild(dlEl, "c:spPr");
1097
+ if (dlSpPr) {
1098
+ const shapeProperties = shapePropertiesDesc.parse(dlSpPr, ctx);
1099
+ if (shapeProperties) opts.shapeProperties = shapeProperties;
1100
+ }
1101
+ const dlTxPr = findChild(dlEl, "c:txPr");
1102
+ if (dlTxPr) {
1103
+ const textProperties = textBodyDesc.parse(dlTxPr, ctx);
1104
+ if (textProperties) opts.textProperties = textProperties;
1105
+ }
763
1106
  const position = readValStr(dlEl, "c:dLblPos");
764
- if (position) opts.position = position;
1107
+ if (position) opts.position = xsdDataLabelPosition.from(position);
765
1108
  const showLegendKey = readBoolAttr(dlEl, "c:showLegendKey");
766
1109
  if (showLegendKey !== void 0) opts.showLegendKey = showLegendKey;
767
1110
  const showVal = readBoolAttr(dlEl, "c:showVal");
@@ -776,22 +1119,54 @@ function readDataLabels(serEl) {
776
1119
  if (showBubbleSize !== void 0) opts.showBubbleSize = showBubbleSize;
777
1120
  const showLeaderLines = readBoolAttr(dlEl, "c:showLeaderLines");
778
1121
  if (showLeaderLines !== void 0) opts.showLeaderLines = showLeaderLines;
779
- const sepText = textOf(findChild(dlEl, "c:separator"));
1122
+ const sepEl = findChild(dlEl, "c:separator");
1123
+ const sepText = textOf(sepEl);
780
1124
  if (sepText) opts.separator = sepText;
781
1125
  const lblEls = children(dlEl, "c:dLbl");
782
1126
  if (lblEls.length > 0) opts.labels = lblEls.map((el) => {
783
1127
  const result = { index: readValNum(el, "c:idx") ?? 0 };
784
- if (findChild(el, "c:delete")) result.delete = true;
1128
+ const labelDelete = readBoolAttr(el, "c:delete");
1129
+ if (labelDelete !== void 0) result.delete = labelDelete;
1130
+ const layoutEl = findChild(el, "c:layout");
1131
+ if (layoutEl) result.layout = readManualLayout(layoutEl) ?? true;
1132
+ const richEl = findChild(findChild(el, "c:tx"), "c:rich");
1133
+ if (richEl) {
1134
+ const text = textBodyDesc.parse(richEl, ctx);
1135
+ if (text) result.text = text;
1136
+ }
785
1137
  const numFmt = attr(findChild(el, "c:numFmt"), "formatCode");
786
1138
  if (numFmt) result.numberFormat = numFmt;
1139
+ const lblSpPr = findChild(el, "c:spPr");
1140
+ if (lblSpPr) {
1141
+ const shapeProperties = shapePropertiesDesc.parse(lblSpPr, ctx);
1142
+ if (shapeProperties) result.shapeProperties = shapeProperties;
1143
+ }
1144
+ const lblTxPr = findChild(el, "c:txPr");
1145
+ if (lblTxPr) {
1146
+ const textProperties = textBodyDesc.parse(lblTxPr, ctx);
1147
+ if (textProperties) result.textProperties = textProperties;
1148
+ }
787
1149
  const pos = readValStr(el, "c:dLblPos");
788
- if (pos) result.position = pos;
1150
+ if (pos) result.position = xsdDataLabelPosition.from(pos);
1151
+ for (const flag of [
1152
+ "showLegendKey",
1153
+ "showVal",
1154
+ "showCatName",
1155
+ "showSerName",
1156
+ "showPercent",
1157
+ "showBubbleSize"
1158
+ ]) {
1159
+ const v = readBoolAttr(el, `c:${flag}`);
1160
+ if (v !== void 0) result[flag] = v;
1161
+ }
1162
+ const sep = textOf(findChild(el, "c:separator"));
1163
+ if (sep) result.separator = sep;
789
1164
  return result;
790
1165
  });
791
1166
  if (findChild(dlEl, "c:leaderLines")) opts.leaderLines = true;
792
1167
  return opts;
793
1168
  }
794
- function readMarker$1(parent) {
1169
+ function readMarker$1(parent, ctx) {
795
1170
  const el = findChild(parent, "c:marker");
796
1171
  if (!el) return void 0;
797
1172
  const opts = {};
@@ -799,6 +1174,11 @@ function readMarker$1(parent) {
799
1174
  if (symbol) opts.symbol = symbol;
800
1175
  const size = readValNum(el, "c:size");
801
1176
  if (size !== void 0) opts.size = size;
1177
+ const spPr = findChild(el, "c:spPr");
1178
+ if (spPr) {
1179
+ const shapeProperties = shapePropertiesDesc.parse(spPr, ctx);
1180
+ if (shapeProperties) opts.shapeProperties = shapeProperties;
1181
+ }
802
1182
  return Object.keys(opts).length ? opts : void 0;
803
1183
  }
804
1184
  function readPictureOptions(parent) {
@@ -817,36 +1197,47 @@ function readPictureOptions(parent) {
817
1197
  if (stack !== void 0) opts.pictureStackUnit = stack;
818
1198
  return Object.keys(opts).length ? opts : void 0;
819
1199
  }
820
- function readDataPoints(serEl) {
1200
+ function readDataPoints(serEl, ctx) {
821
1201
  const els = children(serEl, "c:dPt");
822
1202
  if (els.length === 0) return void 0;
823
1203
  return els.map((el) => {
824
1204
  const dp = { index: readValNum(el, "c:idx") ?? 0 };
825
1205
  const invertIfNegative = readBoolAttr(el, "c:invertIfNegative");
826
1206
  if (invertIfNegative !== void 0) dp.invertIfNegative = invertIfNegative;
827
- const marker = readMarker$1(el);
1207
+ const marker = readMarker$1(el, ctx);
828
1208
  if (marker) dp.marker = marker;
829
1209
  const bubble3D = readBoolAttr(el, "c:bubble3D");
830
1210
  if (bubble3D !== void 0) dp.bubble3D = bubble3D;
831
1211
  const explosion = readValNum(el, "c:explosion");
832
1212
  if (explosion !== void 0) dp.explosion = explosion;
1213
+ const spPr = findChild(el, "c:spPr");
1214
+ if (spPr) {
1215
+ const shapeProperties = shapePropertiesDesc.parse(spPr, ctx);
1216
+ if (shapeProperties) dp.shapeProperties = shapeProperties;
1217
+ }
833
1218
  const pictureOptions = readPictureOptions(el);
834
1219
  if (pictureOptions) dp.pictureOptions = pictureOptions;
835
1220
  return dp;
836
1221
  });
837
1222
  }
838
1223
  /** Read shared ser enhancement fields (CT_Ser children beyond EG_SerShared). */
839
- function readSeriesCommon(serEl) {
1224
+ function readSeriesCommon(serEl, ctx) {
840
1225
  const common = {};
1226
+ const idx = readValNum(serEl, "c:idx");
1227
+ if (idx !== void 0) common.index = idx;
1228
+ const order = readValNum(serEl, "c:order");
1229
+ if (order !== void 0) common.order = order;
1230
+ const spPrEl = findChild(serEl, "c:spPr");
1231
+ if (spPrEl) common.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
841
1232
  const trendlines = readTrendlines(serEl);
842
1233
  if (trendlines) common.trendlines = trendlines;
843
1234
  const errorBars = readErrBars(serEl);
844
1235
  if (errorBars) common.errorBars = errorBars;
845
- const dataLabels = readDataLabels(serEl);
1236
+ const dataLabels = readDataLabels(serEl, ctx);
846
1237
  if (dataLabels) common.dataLabels = dataLabels;
847
- const dataPoints = readDataPoints(serEl);
1238
+ const dataPoints = readDataPoints(serEl, ctx);
848
1239
  if (dataPoints) common.dataPoints = dataPoints;
849
- const marker = readMarker$1(serEl);
1240
+ const marker = readMarker$1(serEl, ctx);
850
1241
  if (marker) common.marker = marker;
851
1242
  const invertIfNegative = readBoolAttr(serEl, "c:invertIfNegative");
852
1243
  if (invertIfNegative !== void 0) common.invertIfNegative = invertIfNegative;
@@ -860,6 +1251,11 @@ function readSeriesCommon(serEl) {
860
1251
  if (shape) common.shape = shape;
861
1252
  const bubble3D = readBoolAttr(serEl, "c:bubble3D");
862
1253
  if (bubble3D !== void 0) common.bubble3D = bubble3D;
1254
+ const extLst = findChild(serEl, "c:extLst");
1255
+ if (extLst) {
1256
+ const inner = stringify(extLst);
1257
+ if (inner) common.ext = inner;
1258
+ }
863
1259
  return common;
864
1260
  }
865
1261
  function readView3D(chartEl) {
@@ -905,25 +1301,43 @@ function readManualLayout(layoutEl) {
905
1301
  if (h !== void 0) opts.h = h;
906
1302
  return Object.keys(opts).length ? opts : void 0;
907
1303
  }
908
- function readSurface(chartEl, tag) {
1304
+ function readSurface(chartEl, tag, ctx) {
909
1305
  const el = findChild(chartEl, tag);
910
1306
  if (!el) return void 0;
1307
+ const opts = {};
911
1308
  const thickness = readValStr(el, "c:thickness");
912
- if (thickness === void 0) return void 0;
913
- return { thickness: thickness.endsWith("%") ? thickness : Number(thickness) };
1309
+ if (thickness !== void 0) opts.thickness = thickness.endsWith("%") ? thickness : Number(thickness);
1310
+ const spPr = findChild(el, "c:spPr");
1311
+ if (spPr) opts.shapeProperties = shapePropertiesDesc.parse(spPr, ctx);
1312
+ return opts;
914
1313
  }
915
- function readChartTypeScalars(chartTypeEl, type, threeD, result) {
1314
+ function readChartTypeScalars(chartTypeEl, type, threeD, result, ctx) {
916
1315
  if (!chartTypeEl) return;
1316
+ if (type !== "surface" && type !== "stock") {
1317
+ const varyColors = readBoolAttr(chartTypeEl, "c:varyColors");
1318
+ if (varyColors !== void 0) result.varyColors = varyColors;
1319
+ }
1320
+ if (type === "column" || type === "bar" || type === "line" || type === "area") {
1321
+ const grouping = readValStr(chartTypeEl, "c:grouping");
1322
+ if (grouping) {
1323
+ if (grouping !== (type === "column" || type === "bar" ? "clustered" : "standard")) result.grouping = grouping;
1324
+ }
1325
+ }
917
1326
  if (type === "column" || type === "bar") {
918
1327
  const gapWidth = readValNum(chartTypeEl, "c:gapWidth");
919
1328
  if (gapWidth !== void 0) result.gapWidth = gapWidth;
920
1329
  if (threeD) {
921
1330
  const gapDepth = readValNum(chartTypeEl, "c:gapDepth");
922
1331
  if (gapDepth !== void 0) result.gapDepth = gapDepth;
1332
+ const shape = readValStr(chartTypeEl, "c:shape");
1333
+ if (shape) result.shape = shape;
923
1334
  } else {
924
1335
  const overlap = readValNum(chartTypeEl, "c:overlap");
925
1336
  if (overlap !== void 0) result.overlap = overlap;
926
1337
  }
1338
+ } else if (type === "area" && threeD) {
1339
+ const gapDepth = readValNum(chartTypeEl, "c:gapDepth");
1340
+ if (gapDepth !== void 0) result.gapDepth = gapDepth;
927
1341
  } else if (type === "pie" || type === "doughnut") {
928
1342
  const firstSliceAng = readValNum(chartTypeEl, "c:firstSliceAng");
929
1343
  if (firstSliceAng !== void 0) result.firstSliceAngle = firstSliceAng;
@@ -935,19 +1349,22 @@ function readChartTypeScalars(chartTypeEl, type, threeD, result) {
935
1349
  const showNeg = readBoolAttr(chartTypeEl, "c:showNegBubbles");
936
1350
  if (showNeg !== void 0) result.showNegativeBubbles = showNeg;
937
1351
  const sizeRep = readValStr(chartTypeEl, "c:sizeRepresents");
938
- if (sizeRep) result.sizeRepresents = sizeRep;
1352
+ if (sizeRep) result.sizeRepresents = xsdSizeRepresents.from(sizeRep);
939
1353
  } else if (type === "surface") {
940
1354
  const wireframe = readBoolAttr(chartTypeEl, "c:wireframe");
941
1355
  if (wireframe !== void 0) result.wireframe = wireframe;
942
1356
  const bandFormats = readBandFormats(chartTypeEl);
943
1357
  if (bandFormats) result.bandFormats = bandFormats;
1358
+ } else if (type === "radar") {
1359
+ const radarStyle = readValStr(chartTypeEl, "c:radarStyle");
1360
+ if (radarStyle) result.radarStyle = radarStyle;
944
1361
  } else if (type === "ofPie") {
945
1362
  const ofPieType = readValStr(chartTypeEl, "c:ofPieType");
946
1363
  if (ofPieType) result.ofPieType = ofPieType;
947
1364
  const gapWidth = readValNum(chartTypeEl, "c:gapWidth");
948
1365
  if (gapWidth !== void 0) result.gapWidth = gapWidth;
949
1366
  const splitType = readValStr(chartTypeEl, "c:splitType");
950
- if (splitType) result.splitType = splitType;
1367
+ if (splitType) result.splitType = xsdSplitType.from(splitType);
951
1368
  const splitPos = readValNum(chartTypeEl, "c:splitPos");
952
1369
  if (splitPos !== void 0) result.splitPosition = splitPos;
953
1370
  const custSplit = findChild(chartTypeEl, "c:custSplit");
@@ -957,38 +1374,53 @@ function readChartTypeScalars(chartTypeEl, type, threeD, result) {
957
1374
  }
958
1375
  const secondPieSize = readValStr(chartTypeEl, "c:secondPieSize");
959
1376
  if (secondPieSize !== void 0) result.secondPieSize = secondPieSize.endsWith("%") ? secondPieSize : Number(secondPieSize);
960
- if (findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1377
+ const seriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1378
+ if (seriesLines !== void 0) result.seriesLines = seriesLines;
961
1379
  }
962
1380
  }
963
- function readChartTypeDecorations(chartTypeEl, type, threeD, result) {
1381
+ function readChartTypeDecorations(chartTypeEl, type, threeD, result, ctx) {
964
1382
  if (!chartTypeEl) return;
965
1383
  const readUpDownBars = (el) => {
966
1384
  result.upDownBars = true;
967
1385
  const gw = readValNum(el, "c:gapWidth");
968
1386
  if (gw !== void 0) result.upDownBarsGapWidth = gw;
969
1387
  };
970
- if (type === "line") if (threeD) {
971
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
972
- } else {
973
- if (findChild(chartTypeEl, "c:hiLowLines")) result.highLowLines = true;
974
- const upDownBars = findChild(chartTypeEl, "c:upDownBars");
975
- if (upDownBars) readUpDownBars(upDownBars);
976
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
977
- }
978
- else if (type === "area") {
979
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
980
- if (threeD && findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1388
+ if (type === "line") {
1389
+ if (threeD) {
1390
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1391
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1392
+ } else {
1393
+ const highLowLinesV = readChartLines(chartTypeEl, "c:hiLowLines", ctx);
1394
+ if (highLowLinesV !== void 0) result.highLowLines = highLowLinesV;
1395
+ const upDownBars = findChild(chartTypeEl, "c:upDownBars");
1396
+ if (upDownBars) readUpDownBars(upDownBars);
1397
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1398
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1399
+ const markers = readBoolAttr(chartTypeEl, "c:marker");
1400
+ if (markers !== void 0) result.markers = markers;
1401
+ const smooth = readBoolAttr(chartTypeEl, "c:smooth");
1402
+ if (smooth !== void 0) result.smooth = smooth;
1403
+ }
1404
+ } else if (type === "area") {
1405
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1406
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1407
+ const threeDSeriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1408
+ if (threeD && threeDSeriesLines !== void 0) result.seriesLines = threeDSeriesLines;
981
1409
  } else if (type === "stock") {
982
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
983
- if (findChild(chartTypeEl, "c:hiLowLines")) result.highLowLines = true;
1410
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1411
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1412
+ const highLowLinesV = readChartLines(chartTypeEl, "c:hiLowLines", ctx);
1413
+ if (highLowLinesV !== void 0) result.highLowLines = highLowLinesV;
984
1414
  const upDownBars = findChild(chartTypeEl, "c:upDownBars");
985
1415
  if (upDownBars) readUpDownBars(upDownBars);
986
- if (findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1416
+ const seriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1417
+ if (seriesLines !== void 0) result.seriesLines = seriesLines;
987
1418
  } else if ((type === "column" || type === "bar") && !threeD) {
988
- if (findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1419
+ const seriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1420
+ if (seriesLines !== void 0) result.seriesLines = seriesLines;
989
1421
  }
990
1422
  }
991
- function readDataTable(plotArea) {
1423
+ function readDataTable(plotArea, ctx) {
992
1424
  if (!plotArea) return void 0;
993
1425
  const dTable = findChild(plotArea, "c:dTable");
994
1426
  if (!dTable) return void 0;
@@ -1001,7 +1433,11 @@ function readDataTable(plotArea) {
1001
1433
  if (outline !== void 0) opts.showOutline = outline;
1002
1434
  const keys = readBoolAttr(dTable, "c:showKeys");
1003
1435
  if (keys !== void 0) opts.showLegendKeys = keys;
1004
- return Object.keys(opts).length ? opts : void 0;
1436
+ const spPrEl = findChild(dTable, "c:spPr");
1437
+ if (spPrEl) opts.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
1438
+ const txPrEl = findChild(dTable, "c:txPr");
1439
+ if (txPrEl) opts.textProperties = textBodyDesc.parse(txPrEl, ctx);
1440
+ return opts;
1005
1441
  }
1006
1442
  function readProtection(el) {
1007
1443
  const protection = findChild(el, "c:protection");
@@ -1049,7 +1485,7 @@ function readPivotSource(el) {
1049
1485
  formatId: Number(attr(fmtIdEl, "val"))
1050
1486
  };
1051
1487
  }
1052
- function readPivotFormats(chart) {
1488
+ function readPivotFormats(chart, ctx) {
1053
1489
  const pf = findChild(chart, "c:pivotFmts");
1054
1490
  if (!pf) return void 0;
1055
1491
  const result = [];
@@ -1057,7 +1493,7 @@ function readPivotFormats(chart) {
1057
1493
  const idxEl = findChild(fmt, "c:idx");
1058
1494
  if (!idxEl) continue;
1059
1495
  const opt = { index: Number(attr(idxEl, "val")) };
1060
- const marker = readMarker$1(fmt);
1496
+ const marker = readMarker$1(fmt, ctx);
1061
1497
  if (marker) opt.marker = marker;
1062
1498
  result.push(opt);
1063
1499
  }
@@ -1073,7 +1509,7 @@ function readBandFormats(chartTypeEl) {
1073
1509
  }
1074
1510
  return result.length ? result : void 0;
1075
1511
  }
1076
- function readLegendEntries(legend) {
1512
+ function readLegendEntries(legend, ctx) {
1077
1513
  const entries = children(legend, "c:legendEntry");
1078
1514
  if (!entries.length) return void 0;
1079
1515
  const result = [];
@@ -1081,26 +1517,41 @@ function readLegendEntries(legend) {
1081
1517
  const idxEl = findChild(entry, "c:idx");
1082
1518
  if (!idxEl) continue;
1083
1519
  const deleteEl = findChild(entry, "c:delete");
1084
- if (!deleteEl) continue;
1085
- const v = attr(deleteEl, "val");
1086
- result.push({
1520
+ if (deleteEl) {
1521
+ const v = attr(deleteEl, "val");
1522
+ result.push({
1523
+ index: Number(attr(idxEl, "val")),
1524
+ delete: parseOnOff(v) ?? true
1525
+ });
1526
+ continue;
1527
+ }
1528
+ const txPrEl = findChild(entry, "c:txPr");
1529
+ if (txPrEl) result.push({
1087
1530
  index: Number(attr(idxEl, "val")),
1088
- delete: parseOnOff(v) ?? true
1531
+ textProperties: textBodyDesc.parse(txPrEl, ctx)
1089
1532
  });
1090
1533
  }
1091
1534
  return result.length ? result : void 0;
1092
1535
  }
1093
- function readLegend(chart) {
1536
+ function readLegend(chart, ctx) {
1094
1537
  const legend = findChild(chart, "c:legend");
1095
1538
  if (!legend) return void 0;
1096
1539
  const result = {};
1097
1540
  const posEl = findChild(legend, "c:legendPos");
1098
1541
  if (posEl) {
1099
1542
  const v = attr(posEl, "val");
1100
- if (v) result.position = v;
1543
+ if (v) result.position = xsdLegendPosition.from(v);
1101
1544
  }
1102
- const entries = readLegendEntries(legend);
1545
+ const entries = readLegendEntries(legend, ctx);
1103
1546
  if (entries) result.entries = entries;
1547
+ const layoutEl = findChild(legend, "c:layout");
1548
+ if (layoutEl) result.layout = readManualLayout(layoutEl) ?? true;
1549
+ const overlayEl = findChild(legend, "c:overlay");
1550
+ if (overlayEl) result.overlay = parseOnOff(attr(overlayEl, "val")) ?? false;
1551
+ const spPrEl = findChild(legend, "c:spPr");
1552
+ if (spPrEl) result.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
1553
+ const txPr = findChild(legend, "c:txPr");
1554
+ if (txPr) result.textProperties = textBodyDesc.parse(txPr, ctx);
1104
1555
  return Object.keys(result).length ? result : void 0;
1105
1556
  }
1106
1557
  function readHeaderFooter(ps) {
@@ -1133,7 +1584,7 @@ function readHeaderFooter(ps) {
1133
1584
  if (differentOddEven !== void 0) opts.differentOddEven = differentOddEven;
1134
1585
  const differentFirst = readFlag("differentFirst");
1135
1586
  if (differentFirst !== void 0) opts.differentFirst = differentFirst;
1136
- return Object.keys(opts).length ? opts : void 0;
1587
+ return opts;
1137
1588
  }
1138
1589
  function readPageMargins(ps) {
1139
1590
  const pm = findChild(ps, "c:pageMargins");
@@ -1191,7 +1642,7 @@ function readPageSetup(ps) {
1191
1642
  if (verticalDpi !== void 0) opts.verticalDpi = verticalDpi;
1192
1643
  const copies = readNum("copies");
1193
1644
  if (copies !== void 0) opts.copies = copies;
1194
- return Object.keys(opts).length ? opts : void 0;
1645
+ return opts;
1195
1646
  }
1196
1647
  function readPrintSettings(el) {
1197
1648
  const ps = findChild(el, "c:printSettings");
@@ -1216,7 +1667,7 @@ const AXIS_KIND_BY_TAG = {
1216
1667
  "c:dateAx": "date",
1217
1668
  "c:serAx": "series"
1218
1669
  };
1219
- function readAxis(el, kind) {
1670
+ function readAxis(el, kind, ctx) {
1220
1671
  const result = {
1221
1672
  kind,
1222
1673
  id: readValNum(el, "c:axId") ?? 0,
@@ -1228,7 +1679,7 @@ function readAxis(el, kind) {
1228
1679
  const logBase = readValNum(scalingEl, "c:logBase");
1229
1680
  if (logBase !== void 0) scaling.logBase = logBase;
1230
1681
  const orientation = readValStr(scalingEl, "c:orientation");
1231
- if (orientation) scaling.orientation = orientation;
1682
+ if (orientation) scaling.orientation = xsdAxisOrientation.from(orientation);
1232
1683
  const max = readValNum(scalingEl, "c:max");
1233
1684
  if (max !== void 0) scaling.max = max;
1234
1685
  const min = readValNum(scalingEl, "c:min");
@@ -1238,18 +1689,18 @@ function readAxis(el, kind) {
1238
1689
  const del = readBoolAttr(el, "c:delete");
1239
1690
  if (del !== void 0) result.delete = del;
1240
1691
  const pos = readValStr(el, "c:axPos");
1241
- if (pos) result.position = pos;
1242
- if (findChild(el, "c:majorGridlines")) result.majorGridlines = true;
1243
- if (findChild(el, "c:minorGridlines")) result.minorGridlines = true;
1692
+ if (pos) result.position = xsdAxisPosition.from(pos);
1693
+ result.majorGridlines = readChartLines(el, "c:majorGridlines", ctx);
1694
+ result.minorGridlines = readChartLines(el, "c:minorGridlines", ctx);
1244
1695
  const titleEl = findChild(el, "c:title");
1245
- if (titleEl) {
1246
- const titleText = readTitleText(titleEl);
1247
- if (titleText !== void 0) result.title = titleText;
1248
- }
1696
+ if (titleEl) result.title = readTitle(titleEl, ctx);
1249
1697
  const numFmtEl = findChild(el, "c:numFmt");
1250
1698
  if (numFmtEl) {
1251
1699
  const formatCode = attr(numFmtEl, "formatCode");
1252
- if (formatCode) result.numberFormat = formatCode;
1700
+ if (formatCode) result.numberFormat = attr(numFmtEl, "sourceLinked") === "0" ? {
1701
+ formatCode,
1702
+ sourceLinked: false
1703
+ } : formatCode;
1253
1704
  }
1254
1705
  const majorTickMark = readValStr(el, "c:majorTickMark");
1255
1706
  if (majorTickMark) result.majorTickMark = majorTickMark;
@@ -1257,11 +1708,15 @@ function readAxis(el, kind) {
1257
1708
  if (minorTickMark) result.minorTickMark = minorTickMark;
1258
1709
  const tickLblPos = readValStr(el, "c:tickLblPos");
1259
1710
  if (tickLblPos) result.tickLabelPosition = tickLblPos;
1711
+ const spPrEl = findChild(el, "c:spPr");
1712
+ if (spPrEl) result.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
1713
+ const axisTxPr = findChild(el, "c:txPr");
1714
+ if (axisTxPr) result.textProperties = textBodyDesc.parse(axisTxPr, ctx);
1260
1715
  const crossesAt = readValNum(el, "c:crossesAt");
1261
1716
  if (crossesAt !== void 0) result.crossesAt = crossesAt;
1262
1717
  else {
1263
1718
  const crosses = readValStr(el, "c:crosses");
1264
- if (crosses) result.crosses = crosses;
1719
+ if (crosses) result.crosses = xsdAxisCrosses.from(crosses);
1265
1720
  }
1266
1721
  if (kind === "category" || kind === "date") {
1267
1722
  const auto = readBoolAttr(el, "c:auto");
@@ -1269,7 +1724,7 @@ function readAxis(el, kind) {
1269
1724
  }
1270
1725
  if (kind === "category") {
1271
1726
  const lblAlgn = readValStr(el, "c:lblAlgn");
1272
- if (lblAlgn) result.labelAlignment = lblAlgn;
1727
+ if (lblAlgn) result.labelAlignment = xsdAxisLabelAlignment.from(lblAlgn);
1273
1728
  }
1274
1729
  if (kind === "category" || kind === "date") {
1275
1730
  const lblOffsetEl = findChild(el, "c:lblOffset");
@@ -1304,7 +1759,7 @@ function readAxis(el, kind) {
1304
1759
  }
1305
1760
  if (kind === "value") {
1306
1761
  const crossBetween = readValStr(el, "c:crossBetween");
1307
- if (crossBetween) result.crossBetween = crossBetween;
1762
+ if (crossBetween) result.crossBetween = xsdAxisCrossBetween.from(crossBetween);
1308
1763
  const dispUnitsEl = findChild(el, "c:dispUnits");
1309
1764
  if (dispUnitsEl) {
1310
1765
  const displayUnits = {};
@@ -1319,60 +1774,88 @@ function readAxis(el, kind) {
1319
1774
  return result;
1320
1775
  }
1321
1776
  /** Read all axis elements (c:catAx/c:valAx/c:dateAx/c:serAx) under plotArea. */
1322
- function readAxes(plotArea) {
1777
+ function readAxes(plotArea, ctx) {
1323
1778
  if (!plotArea?.elements) return void 0;
1324
1779
  const axes = [];
1325
1780
  for (const child of plotArea.elements) {
1326
1781
  if (!child.name) continue;
1327
1782
  const kind = AXIS_KIND_BY_TAG[child.name];
1328
- if (kind) axes.push(readAxis(child, kind));
1783
+ if (kind) axes.push(readAxis(child, kind, ctx));
1329
1784
  }
1330
1785
  return axes.length > 0 ? axes : void 0;
1331
1786
  }
1332
1787
  const chartSpaceDesc = {
1333
1788
  kind: "custom",
1334
- stringify(opts, _ctx) {
1789
+ stringify(opts, ctx) {
1335
1790
  const parts = [];
1336
- parts.push(`<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">`);
1337
- parts.push(valEl("c:date1904", 0));
1338
- parts.push(valEl("c:lang", "en-US"));
1339
- parts.push(valEl("c:roundedCorners", 0));
1340
- if (opts.style !== void 0) parts.push(valEl("c:style", opts.style));
1791
+ const ns = opts.dialect === "strict" ? `xmlns:c="http://purl.oclc.org/ooxml/drawingml/chart" xmlns:a="http://purl.oclc.org/ooxml/drawingml/main" xmlns:r="http://purl.oclc.org/ooxml/officeDocument/relationships"` : `xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"`;
1792
+ parts.push(`<c:chartSpace ${ns}>`);
1793
+ if (opts.date1904 !== void 0) parts.push(`<c:date1904${boolVal(opts.date1904)}/>`);
1794
+ if (opts.lang !== void 0) parts.push(valEl("c:lang", opts.lang));
1795
+ if (opts.roundedCorners !== void 0) parts.push(`<c:roundedCorners${boolVal(opts.roundedCorners)}/>`);
1796
+ if (opts.style2010) {
1797
+ const fallback = opts.style2010.fallbackStyle !== void 0 ? `<mc:Fallback>${valEl("c:style", opts.style2010.fallbackStyle)}</mc:Fallback>` : "";
1798
+ parts.push(`<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><mc:Choice xmlns:c14="http://schemas.microsoft.com/office/drawing/2007/8/2/chart" Requires="c14"><c14:style val="${opts.style2010.style}"/></mc:Choice>${fallback}</mc:AlternateContent>`);
1799
+ } else if (opts.style !== void 0) parts.push(valEl("c:style", opts.style));
1341
1800
  if (opts.colorMappingOverride) parts.push(stringifyColorMapping(opts.colorMappingOverride, "c:clrMapOvr"));
1342
1801
  if (opts.pivotSource) parts.push(stringifyPivotSource(opts.pivotSource));
1343
1802
  if (opts.protection) parts.push(stringifyProtection(opts.protection));
1344
1803
  parts.push("<c:chart>");
1345
- if (opts.title) parts.push(stringifyTitle(opts.title));
1346
- parts.push(valEl("c:autoTitleDeleted", 0));
1347
- if (opts.pivotFormats?.length) parts.push(stringifyPivotFormats(opts.pivotFormats));
1804
+ if (opts.title !== void 0) parts.push(typeof opts.title === "string" && opts.title === "" ? emptyEl("c:title") : stringifyTitle(opts.title, ctx));
1805
+ if (opts.autoTitleDeleted !== void 0) parts.push(`<c:autoTitleDeleted${boolVal(opts.autoTitleDeleted)}/>`);
1806
+ if (opts.pivotFormats?.length) parts.push(stringifyPivotFormats(opts.pivotFormats, ctx));
1348
1807
  if (opts.view3D) parts.push(stringifyView3D(opts.view3D));
1349
- parts.push(stringifySurface("c:floor", opts.floor));
1350
- parts.push(stringifySurface("c:sideWall", opts.sideWall));
1351
- parts.push(stringifySurface("c:backWall", opts.backWall));
1808
+ parts.push(stringifySurface("c:floor", opts.floor, ctx));
1809
+ parts.push(stringifySurface("c:sideWall", opts.sideWall, ctx));
1810
+ parts.push(stringifySurface("c:backWall", opts.backWall, ctx));
1352
1811
  parts.push(`<c:plotArea>${stringifyLayout(opts.plotAreaLayout)}`);
1353
1812
  parts.push(chartTypeHeader(opts));
1354
- for (const [i, series] of opts.series.entries()) parts.push(stringifySeries(i, series, opts));
1355
- parts.push(chartTypeFooter(opts));
1356
- parts.push(stringifyAxes(opts));
1357
- if (opts.dataTable) parts.push(stringifyDataTable(opts.dataTable));
1813
+ for (const [i, series] of (opts.series ?? []).entries()) parts.push(stringifySeries(i, series, opts, ctx));
1814
+ if (opts.dataLabels) parts.push(stringifyDataLabels(opts.dataLabels, ctx));
1815
+ parts.push(chartTypeFooter(opts, ctx));
1816
+ for (const g of opts.secondaryGroups ?? []) parts.push(stringifySecondaryGroup(g, opts, ctx));
1817
+ parts.push(stringifyAxes(opts, ctx));
1818
+ if (opts.dataTable) parts.push(stringifyDataTable(opts.dataTable, ctx));
1819
+ parts.push(chartSpPr(opts.plotAreaShapeProperties, ctx));
1358
1820
  parts.push("</c:plotArea>");
1359
- if (opts.showLegend !== false) parts.push(stringifyLegend(opts));
1821
+ if (opts.showLegend !== false) parts.push(stringifyLegend(opts, ctx));
1360
1822
  parts.push(`<c:plotVisOnly${boolVal(opts.plotVisOnly ?? true)}/>`);
1361
1823
  if (opts.displayBlanksAs !== void 0) parts.push(valEl("c:dispBlanksAs", opts.displayBlanksAs));
1362
1824
  if (opts.showDataLabelsOverMax !== void 0) parts.push(`<c:showDLblsOverMax${boolVal(opts.showDataLabelsOverMax)}/>`);
1363
1825
  parts.push("</c:chart>");
1364
- parts.push(noFillSpPr());
1365
- parts.push(chartTxPr());
1366
- if (opts.externalData) parts.push(stringifyExternalData(opts.externalData));
1826
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
1827
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
1828
+ if (opts.externalData) {
1829
+ const ext = stringifyExternalData(opts.externalData);
1830
+ if (ext) parts.push(ext);
1831
+ }
1367
1832
  if (opts.printSettings) parts.push(stringifyPrintSettings(opts.printSettings));
1368
- if (opts.userShapes !== void 0) parts.push(`<c:userShapes r:id="${escapeXml(opts.userShapes)}"/>`);
1833
+ if (opts.userShapes !== void 0) parts.push(`<c:userShapes r:id="${escapeXml(opts.userShapes.relationshipId ?? "rId1")}"/>`);
1834
+ if (opts.ext) parts.push(`<c:extLst>${opts.ext}</c:extLst>`);
1369
1835
  parts.push("</c:chartSpace>");
1370
1836
  return parts.join("");
1371
1837
  },
1372
- parse(el, _ctx) {
1838
+ parse(el, ctx) {
1373
1839
  const result = {};
1374
- const styleEl = findChild(el, "c:style");
1375
- if (styleEl?.attributes?.["val"] !== void 0) result.style = Number(styleEl.attributes["val"]);
1840
+ if (el.attributes?.["xmlns:c"] === "http://purl.oclc.org/ooxml/drawingml/chart") result.dialect = "strict";
1841
+ const date1904 = readBoolAttr(el, "c:date1904");
1842
+ if (date1904 !== void 0) result.date1904 = date1904;
1843
+ const langVal = readValStr(el, "c:lang");
1844
+ if (langVal) result.lang = langVal;
1845
+ const roundedCorners = readBoolAttr(el, "c:roundedCorners");
1846
+ if (roundedCorners !== void 0) result.roundedCorners = roundedCorners;
1847
+ const mcStyleEl = findChild(el, "mc:AlternateContent");
1848
+ const c14StyleEl = mcStyleEl && findChild(findChild(mcStyleEl, "mc:Choice") ?? mcStyleEl, "c14:style");
1849
+ if (c14StyleEl?.attributes?.["val"] !== void 0) {
1850
+ const fallbackEl = findFirst(mcStyleEl, "c:style");
1851
+ result.style2010 = {
1852
+ style: Number(c14StyleEl.attributes["val"]),
1853
+ ...fallbackEl?.attributes?.["val"] !== void 0 ? { fallbackStyle: Number(fallbackEl.attributes["val"]) } : {}
1854
+ };
1855
+ } else {
1856
+ const styleEl = findChild(el, "c:style");
1857
+ if (styleEl?.attributes?.["val"] !== void 0) result.style = Number(styleEl.attributes["val"]);
1858
+ }
1376
1859
  const colorMappingOverride = parseColorMapping(findChild(el, "c:clrMapOvr"));
1377
1860
  if (colorMappingOverride) result.colorMappingOverride = colorMappingOverride;
1378
1861
  const protection = readProtection(el);
@@ -1382,33 +1865,37 @@ const chartSpaceDesc = {
1382
1865
  const chart = findChild(el, "c:chart");
1383
1866
  if (!chart) return result;
1384
1867
  const titleEl = findChild(chart, "c:title");
1385
- if (titleEl) {
1386
- const title = readTitleText(titleEl);
1387
- if (title !== void 0) result.title = title;
1388
- }
1389
- const pivotFormats = readPivotFormats(chart);
1868
+ if (titleEl) result.title = readTitle(titleEl, ctx);
1869
+ const autoTitleDeleted = readBoolAttr(chart, "c:autoTitleDeleted");
1870
+ if (autoTitleDeleted !== void 0) result.autoTitleDeleted = autoTitleDeleted;
1871
+ const pivotFormats = readPivotFormats(chart, ctx);
1390
1872
  if (pivotFormats) result.pivotFormats = pivotFormats;
1391
1873
  const view3D = readView3D(chart);
1392
1874
  if (view3D) result.view3D = view3D;
1393
- const floor = readSurface(chart, "c:floor");
1875
+ const floor = readSurface(chart, "c:floor", ctx);
1394
1876
  if (floor) result.floor = floor;
1395
- const sideWall = readSurface(chart, "c:sideWall");
1877
+ const sideWall = readSurface(chart, "c:sideWall", ctx);
1396
1878
  if (sideWall) result.sideWall = sideWall;
1397
- const backWall = readSurface(chart, "c:backWall");
1879
+ const backWall = readSurface(chart, "c:backWall", ctx);
1398
1880
  if (backWall) result.backWall = backWall;
1399
1881
  const plotArea = findChild(chart, "c:plotArea");
1400
1882
  if (plotArea?.elements) {
1401
1883
  const manualLayout = readManualLayout(findChild(plotArea, "c:layout"));
1402
1884
  if (manualLayout) result.plotAreaLayout = manualLayout;
1403
- const dataTable = readDataTable(plotArea);
1885
+ const dataTable = readDataTable(plotArea, ctx);
1404
1886
  if (dataTable) result.dataTable = dataTable;
1405
1887
  let detectedType;
1406
1888
  let threeD = false;
1407
1889
  let chartTypeEl;
1890
+ const secondaryEls = [];
1408
1891
  for (const child of plotArea.elements) {
1409
1892
  if (!child.name) continue;
1410
1893
  const mapping = TAG_TO_CHART_TYPE[child.name];
1411
1894
  if (mapping) {
1895
+ if (chartTypeEl) {
1896
+ secondaryEls.push(child);
1897
+ continue;
1898
+ }
1412
1899
  detectedType = mapping.type;
1413
1900
  threeD = mapping.threeD ?? false;
1414
1901
  chartTypeEl = child;
@@ -1418,69 +1905,132 @@ const chartSpaceDesc = {
1418
1905
  if (barDirVal === "bar") detectedType = "bar";
1419
1906
  else if (barDirVal === "col") detectedType = "column";
1420
1907
  }
1421
- break;
1422
1908
  }
1423
1909
  }
1424
- if (detectedType) {
1910
+ if (detectedType && chartTypeEl) {
1425
1911
  result.type = detectedType;
1426
1912
  if (threeD) result.threeD = true;
1427
- readChartTypeScalars(chartTypeEl, detectedType, threeD, result);
1428
- readChartTypeDecorations(chartTypeEl, detectedType, threeD, result);
1913
+ readChartTypeScalars(chartTypeEl, detectedType, threeD, result, ctx);
1914
+ readChartTypeDecorations(chartTypeEl, detectedType, threeD, result, ctx);
1915
+ const groupLabels = readDataLabels(chartTypeEl, ctx);
1916
+ if (groupLabels) result.dataLabels = groupLabels;
1917
+ const axIdEls = children(chartTypeEl, "c:axId");
1918
+ if (axIdEls.length > 0) result.axisIds = axIdEls.map((e) => Number(attr(e, "val"))).filter((n) => !isNaN(n));
1429
1919
  }
1430
1920
  const seriesEls = chartTypeEl ? children(chartTypeEl, "c:ser") : [];
1431
- if (seriesEls.length > 0) if (detectedType === "bubble") {
1432
- const bubbleSeries = [];
1433
- for (const serEl of seriesEls) {
1434
- const name = readSeriesName(serEl);
1435
- const xVal = findChild(serEl, "c:xVal");
1436
- const yVal = findChild(serEl, "c:yVal");
1437
- const bubbleSize = findChild(serEl, "c:bubbleSize");
1438
- bubbleSeries.push({
1439
- name,
1440
- xValues: xVal ? readNumCache(xVal) : [],
1441
- yValues: yVal ? readNumCache(yVal) : [],
1442
- bubbleSize: bubbleSize ? readNumCache(bubbleSize) : [],
1443
- ...readSeriesCommon(serEl)
1444
- });
1445
- }
1446
- result.series = bubbleSeries;
1447
- } else {
1448
- const chartSeries = [];
1449
- let categories;
1450
- for (const serEl of seriesEls) {
1451
- const name = readSeriesName(serEl);
1452
- if (!categories && !result.multiLevelCategories && !result.categoryLabels) {
1453
- const catEl = findChild(serEl, "c:cat") ?? findChild(serEl, "c:xVal");
1454
- if (catEl) {
1455
- const multi = readMultiLvlStrCache(catEl);
1456
- if (multi) result.multiLevelCategories = multi;
1457
- else {
1458
- const lit = readStrLit(catEl);
1459
- if (lit) {
1460
- result.categoryLabels = lit;
1461
- categories = lit;
1462
- } else categories = readStrCache(catEl);
1921
+ if (seriesEls.length > 0) {
1922
+ if (detectedType === "bubble") {
1923
+ const bubbleSeries = [];
1924
+ for (const serEl of seriesEls) {
1925
+ const { name } = readSeriesName(serEl);
1926
+ const xVal = findChild(serEl, "c:xVal");
1927
+ const yVal = findChild(serEl, "c:yVal");
1928
+ const bubbleSize = findChild(serEl, "c:bubbleSize");
1929
+ bubbleSeries.push({
1930
+ name,
1931
+ xValues: xVal ? readNumCache(xVal) : [],
1932
+ yValues: yVal ? readNumCache(yVal) : [],
1933
+ bubbleSize: bubbleSize ? readNumCache(bubbleSize) : [],
1934
+ ...readSeriesCommon(serEl, ctx)
1935
+ });
1936
+ }
1937
+ result.series = bubbleSeries;
1938
+ } else if (detectedType === "scatter" && hasNumericXRef(seriesEls[0])) {
1939
+ const xySeries = [];
1940
+ for (const serEl of seriesEls) {
1941
+ const { name, literal: nameLiteral } = readSeriesName(serEl);
1942
+ const txEl = findChild(serEl, "c:tx");
1943
+ const nameFormula = txEl ? readRefMeta(txEl).formula : void 0;
1944
+ const xVal = findChild(serEl, "c:xVal");
1945
+ const yVal = findChild(serEl, "c:yVal");
1946
+ const valueLiteral = yVal ? findChild(yVal, "c:numLit") !== void 0 : false;
1947
+ const yMeta = yVal ? readRefMeta(yVal) : {};
1948
+ xySeries.push({
1949
+ name,
1950
+ ...nameLiteral ? { nameLiteral } : {},
1951
+ ...nameFormula ? { nameFormula } : {},
1952
+ ...valueLiteral ? { valueLiteral } : {},
1953
+ ...yMeta.formula ? { valueFormula: yMeta.formula } : {},
1954
+ ...yMeta.formatCode ? { formatCode: yMeta.formatCode } : {},
1955
+ xValues: xVal ? readNumCache(xVal) : [],
1956
+ yValues: yVal ? readNumCache(yVal) : [],
1957
+ ...readSeriesCommon(serEl, ctx)
1958
+ });
1959
+ }
1960
+ result.series = xySeries;
1961
+ } else {
1962
+ const chartSeries = [];
1963
+ let categories;
1964
+ for (const serEl of seriesEls) {
1965
+ const { name, literal: nameLiteral } = readSeriesName(serEl);
1966
+ const txEl = findChild(serEl, "c:tx");
1967
+ const nameFormula = txEl ? readRefMeta(txEl).formula : void 0;
1968
+ if (!categories && !result.multiLevelCategories && !result.categoryLabels) {
1969
+ const catEl = findChild(serEl, "c:cat") ?? findChild(serEl, "c:xVal");
1970
+ if (catEl) {
1971
+ const multi = readMultiLvlStrCache(catEl);
1972
+ if (multi) {
1973
+ result.multiLevelCategories = multi;
1974
+ const multiRef = findChild(catEl, "c:multiLvlStrRef");
1975
+ const multiF = multiRef ? findChild(multiRef, "c:f") : void 0;
1976
+ const multiText = multiF ? textOf(multiF) : "";
1977
+ if (multiText) result.categoryFormula = multiText;
1978
+ } else {
1979
+ const lit = readStrLit(catEl);
1980
+ if (lit) {
1981
+ result.categoryLabels = lit;
1982
+ categories = lit;
1983
+ } else if (findChild(catEl, "c:numRef")) {
1984
+ result.numericCategories = true;
1985
+ categories = readNumCacheText(catEl);
1986
+ } else categories = readStrCache(catEl);
1987
+ const catMeta = readRefMeta(catEl);
1988
+ if (catMeta.formula) result.categoryFormula = catMeta.formula;
1989
+ if (catMeta.formatCode) result.categoryFormatCode = catMeta.formatCode;
1990
+ }
1463
1991
  }
1464
1992
  }
1993
+ const valueEl = findChild(serEl, "c:val") ?? findChild(serEl, "c:yVal");
1994
+ const valueLiteral = valueEl ? findChild(valueEl, "c:numLit") !== void 0 : false;
1995
+ const values = valueEl ? readNumCache(valueEl) : [];
1996
+ const valMeta = valueEl ? readRefMeta(valueEl) : {};
1997
+ chartSeries.push({
1998
+ name,
1999
+ ...nameLiteral ? { nameLiteral } : {},
2000
+ ...nameFormula ? { nameFormula } : {},
2001
+ ...valueLiteral ? { valueLiteral } : {},
2002
+ ...valMeta.formula ? { valueFormula: valMeta.formula } : {},
2003
+ ...valMeta.formatCode ? { formatCode: valMeta.formatCode } : {},
2004
+ values,
2005
+ ...readSeriesCommon(serEl, ctx)
2006
+ });
1465
2007
  }
1466
- const valEl = findChild(serEl, "c:val") ?? findChild(serEl, "c:yVal");
1467
- const values = valEl ? readNumCache(valEl) : [];
1468
- chartSeries.push({
1469
- name,
1470
- values,
1471
- ...readSeriesCommon(serEl)
1472
- });
2008
+ result.series = chartSeries;
2009
+ if (categories) result.categories = categories;
2010
+ }
2011
+ }
2012
+ if (secondaryEls.length > 0) {
2013
+ const groups = [];
2014
+ for (const secondaryEl of secondaryEls) {
2015
+ const g = readSecondaryGroup(secondaryEl, ctx);
2016
+ if (g) groups.push(g);
1473
2017
  }
1474
- result.series = chartSeries;
1475
- if (categories?.length) result.categories = categories;
2018
+ if (groups.length > 0) result.secondaryGroups = groups;
1476
2019
  }
1477
2020
  }
1478
- const axes = readAxes(plotArea);
2021
+ const axes = readAxes(plotArea, ctx);
1479
2022
  if (axes) result.axes = axes;
2023
+ const plotSpPr = plotArea && findChild(plotArea, "c:spPr");
2024
+ if (plotSpPr) result.plotAreaShapeProperties = shapePropertiesDesc.parse(plotSpPr, ctx);
1480
2025
  if (!findChild(chart, "c:legend")) result.showLegend = false;
1481
2026
  else {
1482
- const legendData = readLegend(chart);
2027
+ result.showLegend = true;
2028
+ const legendData = readLegend(chart, ctx);
1483
2029
  if (legendData?.position) result.legendPosition = legendData.position;
2030
+ if (legendData?.layout !== void 0) result.legendLayout = legendData.layout;
2031
+ if (legendData?.overlay !== void 0) result.legendOverlay = legendData.overlay;
2032
+ if (legendData?.shapeProperties) result.legendShapeProperties = legendData.shapeProperties;
2033
+ if (legendData?.textProperties) result.legendTextProperties = legendData.textProperties;
1484
2034
  if (legendData?.entries) result.legendEntries = legendData.entries;
1485
2035
  }
1486
2036
  const plotVisOnly = readBoolAttr(chart, "c:plotVisOnly");
@@ -1489,6 +2039,10 @@ const chartSpaceDesc = {
1489
2039
  if (dispBlanksAs) result.displayBlanksAs = dispBlanksAs;
1490
2040
  const showDLblsOverMax = readBoolAttr(chart, "c:showDLblsOverMax");
1491
2041
  if (showDLblsOverMax !== void 0) result.showDataLabelsOverMax = showDLblsOverMax;
2042
+ const spPrEl = findChild(el, "c:spPr");
2043
+ if (spPrEl) result.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
2044
+ const spaceTxPr = findChild(el, "c:txPr");
2045
+ if (spaceTxPr) result.textProperties = textBodyDesc.parse(spaceTxPr, ctx);
1492
2046
  const externalData = readExternalData(el);
1493
2047
  if (externalData) result.externalData = externalData;
1494
2048
  const printSettings = readPrintSettings(el);
@@ -1496,8 +2050,13 @@ const chartSpaceDesc = {
1496
2050
  const userShapesEl = findChild(el, "c:userShapes");
1497
2051
  if (userShapesEl) {
1498
2052
  const rid = attr(userShapesEl, "r:id");
1499
- if (rid !== void 0) result.userShapes = rid;
2053
+ if (rid !== void 0) result.userShapes = {
2054
+ relationshipId: rid,
2055
+ anchors: []
2056
+ };
1500
2057
  }
2058
+ const spaceExtLst = findChild(el, "c:extLst");
2059
+ if (spaceExtLst) result.ext = (spaceExtLst.elements ?? []).map((e) => stringifyElement(e)).join("");
1501
2060
  return result;
1502
2061
  }
1503
2062
  };
@@ -1549,7 +2108,7 @@ function stringifyObject(obj) {
1549
2108
  const nvSpPr = `<cdr:nvSpPr>${stringifyCnvPr(obj.id, obj.nonVisualProperties)}<cdr:cNvSpPr${obj.textBox ? " txBox=\"1\"" : ""}/></cdr:nvSpPr>`;
1550
2109
  const spPrXml = stringify$1(shapePropertiesDesc, obj.shapeProperties, DIRECT_CTX) ?? "";
1551
2110
  const styleXml = obj.style ? stringifyShapeStyle(obj.style, DIRECT_CTX) : "";
1552
- const txBodyXml = obj.textBody ? stringify$1(textBodyDesc, obj.textBody, DIRECT_CTX) ?? "" : "";
2111
+ const txBodyXml = obj.textBody ? `<cdr:txBody>${stringify$1(textBodyDesc, obj.textBody, DIRECT_CTX) ?? ""}</cdr:txBody>` : "";
1553
2112
  return `<cdr:sp${commonAttrs(obj)}${textLinkAttr}${locksTextAttr}>` + nvSpPr + `<cdr:spPr>${spPrXml}</cdr:spPr>` + styleXml + txBodyXml + "</cdr:sp>";
1554
2113
  }
1555
2114
  case "connector": {
@@ -1560,10 +2119,11 @@ function stringifyObject(obj) {
1560
2119
  }
1561
2120
  case "picture": {
1562
2121
  const nvPicPr = `<cdr:nvPicPr>${stringifyCnvPr(obj.id, obj.nonVisualProperties)}<cdr:cNvPicPr/></cdr:nvPicPr>`;
1563
- const blipFillXml = (stringify$1(blipFillDesc, {
2122
+ const fillOpts = {
1564
2123
  ...obj.blipFill,
1565
2124
  referenceId: obj.referenceId
1566
- }, DIRECT_CTX) ?? "").replace(/pic:blipFill/g, "cdr:blipFill");
2125
+ };
2126
+ const blipFillXml = (stringify$1(blipFillDesc, fillOpts, DIRECT_CTX) ?? "").replace(/pic:blipFill/g, "cdr:blipFill");
1567
2127
  const spPrXml = stringify$1(shapePropertiesDesc, obj.shapeProperties, DIRECT_CTX) ?? "";
1568
2128
  const styleXml = obj.style ? stringifyShapeStyle(obj.style, DIRECT_CTX) : "";
1569
2129
  return `<cdr:pic${commonAttrs(obj)}>` + nvPicPr + blipFillXml + `<cdr:spPr>${spPrXml}</cdr:spPr>` + styleXml + "</cdr:pic>";
@@ -1605,6 +2165,13 @@ function readCnvPr(el) {
1605
2165
  nvp
1606
2166
  };
1607
2167
  }
2168
+ /** macro/fPublished attributes shared by every non-group user-shape object. */
2169
+ function readCommonAttrs(el) {
2170
+ const out = {};
2171
+ if (el.attributes?.["macro"] !== void 0) out.macro = String(el.attributes["macro"]);
2172
+ if (el.attributes?.["fPublished"] !== void 0) out.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2173
+ return out;
2174
+ }
1608
2175
  function readObject(el, ctx) {
1609
2176
  switch (el.name) {
1610
2177
  case "cdr:sp": {
@@ -1625,10 +2192,9 @@ function readObject(el, ctx) {
1625
2192
  if (styleEl) result.style = parseShapeStyle(styleEl, ctx);
1626
2193
  const txBody = findChild(el, "cdr:txBody");
1627
2194
  if (txBody) result.textBody = parse$1(textBodyDesc, txBody, ctx);
1628
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
2195
+ Object.assign(result, readCommonAttrs(el));
1629
2196
  if (el.attributes?.["textlink"] !== void 0) result.textLink = String(el.attributes["textlink"]);
1630
2197
  if (el.attributes?.["fLocksText"] !== void 0) result.locksText = parseOnOff(el.attributes["fLocksText"]) ?? true;
1631
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
1632
2198
  return result;
1633
2199
  }
1634
2200
  case "cdr:cxnSp": {
@@ -1645,8 +2211,7 @@ function readObject(el, ctx) {
1645
2211
  };
1646
2212
  const styleEl = findChild(el, "a:style");
1647
2213
  if (styleEl) result.style = parseShapeStyle(styleEl, ctx);
1648
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
1649
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2214
+ Object.assign(result, readCommonAttrs(el));
1650
2215
  return result;
1651
2216
  }
1652
2217
  case "cdr:pic": {
@@ -1667,8 +2232,7 @@ function readObject(el, ctx) {
1667
2232
  if (Object.keys(blipFillOpts).length > 0) result.blipFill = blipFillOpts;
1668
2233
  const styleEl = findChild(el, "a:style");
1669
2234
  if (styleEl) result.style = parseShapeStyle(styleEl, ctx);
1670
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
1671
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2235
+ Object.assign(result, readCommonAttrs(el));
1672
2236
  return result;
1673
2237
  }
1674
2238
  case "cdr:graphicFrame": {
@@ -1704,8 +2268,7 @@ function readObject(el, ctx) {
1704
2268
  if (Object.keys(flags).length > 0) result.graphicFrameLocks = flags;
1705
2269
  } else result.graphicFrameLocks = {};
1706
2270
  }
1707
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
1708
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2271
+ Object.assign(result, readCommonAttrs(el));
1709
2272
  return result;
1710
2273
  }
1711
2274
  case "cdr:grpSp": {
@@ -1774,7 +2337,18 @@ function readAnchorObject(anchorEl, ctx) {
1774
2337
  if (object) return object;
1775
2338
  }
1776
2339
  }
2340
+ /**
2341
+ * Companion part entry the format compilers register alongside the chart
2342
+ * space: the serialized body plus the relationship id the c:userShapes
2343
+ * reference carries (same rId1 default as the chart-space reference).
2344
+ */
2345
+ function buildUserShapesData(userShapes) {
2346
+ return {
2347
+ relationshipId: userShapes.relationshipId ?? "rId1",
2348
+ xml: userShapesDesc.stringify({ anchors: userShapes.anchors }, DIRECT_CTX) ?? ""
2349
+ };
2350
+ }
1777
2351
  //#endregion
1778
- export { chartSpaceDesc as n, ChartCollection as r, userShapesDesc as t };
2352
+ export { ChartCollection as i, userShapesDesc as n, chartSpaceDesc as r, buildUserShapesData as t };
1779
2353
 
1780
- //# sourceMappingURL=chart-Kf_utasF.mjs.map
2354
+ //# sourceMappingURL=chart-BAnjzVoe.mjs.map