pptx-react-viewer 1.25.3 → 1.25.5

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 (97) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/{Model3DScene-IQLE5JLL.mjs → Model3DScene-XVYOISVJ.mjs} +2 -2
  3. package/dist/Model3DScene-XVYOISVJ.mjs.br +0 -0
  4. package/dist/Model3DScene-XVYOISVJ.mjs.gz +0 -0
  5. package/dist/{Model3DScene-F2GUSTZI.js → Model3DScene-Y5ABLO7K.js} +3 -3
  6. package/dist/Model3DScene-Y5ABLO7K.js.br +0 -0
  7. package/dist/Model3DScene-Y5ABLO7K.js.gz +0 -0
  8. package/dist/{SurfaceChart3DScene-JG26PJ7O.mjs → SurfaceChart3DScene-RXZADECL.mjs} +2 -2
  9. package/dist/SurfaceChart3DScene-RXZADECL.mjs.br +0 -0
  10. package/dist/SurfaceChart3DScene-RXZADECL.mjs.gz +0 -0
  11. package/dist/{SurfaceChart3DScene-4OMD7LWR.js → SurfaceChart3DScene-WMY5JTW4.js} +3 -3
  12. package/dist/{SurfaceChart3DScene-4OMD7LWR.js.br → SurfaceChart3DScene-WMY5JTW4.js.br} +0 -0
  13. package/dist/SurfaceChart3DScene-WMY5JTW4.js.gz +0 -0
  14. package/dist/{chunk-5G3SPYQE.js → chunk-7CSBUYRN.js} +849 -808
  15. package/dist/chunk-7CSBUYRN.js.br +0 -0
  16. package/dist/chunk-7CSBUYRN.js.gz +0 -0
  17. package/dist/{chunk-ZUJHFLOR.js → chunk-E55Q4AC7.js} +556 -476
  18. package/dist/chunk-E55Q4AC7.js.br +0 -0
  19. package/dist/chunk-E55Q4AC7.js.gz +0 -0
  20. package/dist/{chunk-NYBERTS7.mjs → chunk-F4WPQRZU.mjs} +96 -16
  21. package/dist/chunk-F4WPQRZU.mjs.br +0 -0
  22. package/dist/chunk-F4WPQRZU.mjs.gz +0 -0
  23. package/dist/{chunk-DAI4KM5W.mjs → chunk-FOMF7POV.mjs} +2285 -490
  24. package/dist/chunk-FOMF7POV.mjs.br +0 -0
  25. package/dist/chunk-FOMF7POV.mjs.gz +0 -0
  26. package/dist/{chunk-DVM75RMN.mjs → chunk-FVQDRA5N.mjs} +1100 -126
  27. package/dist/chunk-FVQDRA5N.mjs.br +0 -0
  28. package/dist/chunk-FVQDRA5N.mjs.gz +0 -0
  29. package/dist/{chunk-2V6BD4JQ.js → chunk-IPYAN574.js} +2288 -490
  30. package/dist/chunk-IPYAN574.js.br +0 -0
  31. package/dist/chunk-IPYAN574.js.gz +0 -0
  32. package/dist/{chunk-GNXWU7UG.mjs → chunk-L4ZADJOM.mjs} +48 -7
  33. package/dist/chunk-L4ZADJOM.mjs.br +0 -0
  34. package/dist/chunk-L4ZADJOM.mjs.gz +0 -0
  35. package/dist/{chunk-UXVFNGJH.js → chunk-TEN35NUX.js} +1133 -159
  36. package/dist/chunk-TEN35NUX.js.br +0 -0
  37. package/dist/chunk-TEN35NUX.js.gz +0 -0
  38. package/dist/{dist-ZA77P2O5.js → dist-755SJ3ZH.js} +574 -562
  39. package/dist/dist-755SJ3ZH.js.br +0 -0
  40. package/dist/dist-755SJ3ZH.js.gz +0 -0
  41. package/dist/dist-FFWP5NQZ.mjs +2 -0
  42. package/dist/dist-FFWP5NQZ.mjs.br +0 -0
  43. package/dist/dist-FFWP5NQZ.mjs.gz +0 -0
  44. package/dist/hooks-unstable.d.ts +350 -5
  45. package/dist/hooks-unstable.d.ts.map +1 -1
  46. package/dist/hooks-unstable.js +78 -78
  47. package/dist/hooks-unstable.js.br +0 -0
  48. package/dist/hooks-unstable.js.gz +0 -0
  49. package/dist/hooks-unstable.mjs +3 -3
  50. package/dist/hooks-unstable.mjs.br +0 -0
  51. package/dist/hooks-unstable.mjs.gz +0 -0
  52. package/dist/{index-DWvM1PBB.d.ts → index-J6IuHQ2_.d.ts} +21 -4
  53. package/dist/index-J6IuHQ2_.d.ts.map +1 -0
  54. package/dist/index.d.ts +330 -2
  55. package/dist/index.js +33 -33
  56. package/dist/index.js.br +0 -0
  57. package/dist/index.js.gz +0 -0
  58. package/dist/index.mjs +4 -4
  59. package/dist/index.mjs.br +0 -0
  60. package/dist/index.mjs.gz +0 -0
  61. package/dist/viewer/index.d.ts +330 -2
  62. package/dist/viewer/index.js +20 -20
  63. package/dist/viewer/index.js.br +0 -0
  64. package/dist/viewer/index.js.gz +0 -0
  65. package/dist/viewer/index.mjs +4 -4
  66. package/dist/viewer/index.mjs.br +0 -0
  67. package/dist/viewer/index.mjs.gz +0 -0
  68. package/package.json +1 -1
  69. package/dist/Model3DScene-F2GUSTZI.js.br +0 -0
  70. package/dist/Model3DScene-F2GUSTZI.js.gz +0 -0
  71. package/dist/Model3DScene-IQLE5JLL.mjs.br +0 -0
  72. package/dist/Model3DScene-IQLE5JLL.mjs.gz +0 -0
  73. package/dist/SurfaceChart3DScene-4OMD7LWR.js.gz +0 -0
  74. package/dist/SurfaceChart3DScene-JG26PJ7O.mjs.br +0 -0
  75. package/dist/SurfaceChart3DScene-JG26PJ7O.mjs.gz +0 -0
  76. package/dist/chunk-2V6BD4JQ.js.br +0 -0
  77. package/dist/chunk-2V6BD4JQ.js.gz +0 -0
  78. package/dist/chunk-5G3SPYQE.js.br +0 -0
  79. package/dist/chunk-5G3SPYQE.js.gz +0 -0
  80. package/dist/chunk-DAI4KM5W.mjs.br +0 -0
  81. package/dist/chunk-DAI4KM5W.mjs.gz +0 -0
  82. package/dist/chunk-DVM75RMN.mjs.br +0 -0
  83. package/dist/chunk-DVM75RMN.mjs.gz +0 -0
  84. package/dist/chunk-GNXWU7UG.mjs.br +0 -0
  85. package/dist/chunk-GNXWU7UG.mjs.gz +0 -0
  86. package/dist/chunk-NYBERTS7.mjs.br +0 -0
  87. package/dist/chunk-NYBERTS7.mjs.gz +0 -0
  88. package/dist/chunk-UXVFNGJH.js.br +0 -0
  89. package/dist/chunk-UXVFNGJH.js.gz +0 -0
  90. package/dist/chunk-ZUJHFLOR.js.br +0 -0
  91. package/dist/chunk-ZUJHFLOR.js.gz +0 -0
  92. package/dist/dist-E3IHM3OU.mjs +0 -2
  93. package/dist/dist-E3IHM3OU.mjs.br +0 -0
  94. package/dist/dist-E3IHM3OU.mjs.gz +0 -0
  95. package/dist/dist-ZA77P2O5.js.br +0 -0
  96. package/dist/dist-ZA77P2O5.js.gz +0 -0
  97. package/dist/index-DWvM1PBB.d.ts.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk2V6BD4JQ_js = require('./chunk-2V6BD4JQ.js');
3
+ var chunkIPYAN574_js = require('./chunk-IPYAN574.js');
4
4
  var DOMPurify = require('dompurify');
5
5
 
6
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -307,7 +307,7 @@ function buildInitialGuides(presentationGuides, firstSlideGuides) {
307
307
  guides.push({
308
308
  id: g.id,
309
309
  axis: g.orientation === "horz" ? "h" : "v",
310
- position: chunk2V6BD4JQ_js.guideEmuToPx(g.positionEmu)
310
+ position: chunkIPYAN574_js.guideEmuToPx(g.positionEmu)
311
311
  });
312
312
  }
313
313
  }
@@ -316,7 +316,7 @@ function buildInitialGuides(presentationGuides, firstSlideGuides) {
316
316
  guides.push({
317
317
  id: g.id,
318
318
  axis: g.orientation === "horz" ? "h" : "v",
319
- position: chunk2V6BD4JQ_js.guideEmuToPx(g.positionEmu)
319
+ position: chunkIPYAN574_js.guideEmuToPx(g.positionEmu)
320
320
  });
321
321
  }
322
322
  }
@@ -329,23 +329,23 @@ function getResolvedShapeClipPathFor(shapeType, width, height, adjustments) {
329
329
  return void 0;
330
330
  }
331
331
  if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
332
- return chunk2V6BD4JQ_js.getShapeClipPath(shapeType);
332
+ return chunkIPYAN574_js.getShapeClipPath(shapeType);
333
333
  }
334
334
  if (adjustments && Object.keys(adjustments).length > 0) {
335
- const adjusted = chunk2V6BD4JQ_js.getAdjustmentAwareShapeClipPath(shapeType, width, height, adjustments);
335
+ const adjusted = chunkIPYAN574_js.getAdjustmentAwareShapeClipPath(shapeType, width, height, adjustments);
336
336
  if (adjusted !== void 0) {
337
337
  return adjusted;
338
338
  }
339
339
  }
340
- const fromPreset = chunk2V6BD4JQ_js.getShapeClipPathFromPreset(shapeType, width, height, adjustments);
340
+ const fromPreset = chunkIPYAN574_js.getShapeClipPathFromPreset(shapeType, width, height, adjustments);
341
341
  if (fromPreset !== void 0) {
342
342
  return fromPreset;
343
343
  }
344
- const cloud = chunk2V6BD4JQ_js.getCloudPathForRendering(shapeType, width, height);
344
+ const cloud = chunkIPYAN574_js.getCloudPathForRendering(shapeType, width, height);
345
345
  if (cloud !== void 0) {
346
346
  return cloud;
347
347
  }
348
- return chunk2V6BD4JQ_js.getShapeClipPath(shapeType);
348
+ return chunkIPYAN574_js.getShapeClipPath(shapeType);
349
349
  }
350
350
  function buildCustomGeometryClipPath(pathData, pathWidth, pathHeight, elemWidth, elemHeight) {
351
351
  if (!pathData || !Number.isFinite(pathWidth) || !Number.isFinite(pathHeight) || pathWidth <= 0 || pathHeight <= 0 || !Number.isFinite(elemWidth) || !Number.isFinite(elemHeight) || elemWidth <= 0 || elemHeight <= 0) {
@@ -562,7 +562,27 @@ function buildReflectedGradientStops(stops) {
562
562
  }));
563
563
  return [...forward, ...reversed];
564
564
  }
565
- function buildGradientCss(gradient) {
565
+ function normalizeDegrees(deg) {
566
+ return (deg % 360 + 360) % 360;
567
+ }
568
+ function adjustLinearGradientAngle(angle, gradient, context) {
569
+ if (!context) {
570
+ return angle;
571
+ }
572
+ let result = angle;
573
+ const { width, height, rotation } = context;
574
+ if (gradient.fillGradientScaled !== false && typeof width === "number" && typeof height === "number" && width > 0 && height > 0 && width !== height) {
575
+ const rad = result * Math.PI / 180;
576
+ result = normalizeDegrees(
577
+ Math.atan2(height * Math.sin(rad), width * Math.cos(rad)) * 180 / Math.PI
578
+ );
579
+ }
580
+ if (gradient.fillGradientRotWithShape === false && typeof rotation === "number") {
581
+ result = normalizeDegrees(result - rotation);
582
+ }
583
+ return result;
584
+ }
585
+ function buildGradientCss(gradient, context) {
566
586
  if (!gradient || gradient.fillMode !== "gradient") {
567
587
  return void 0;
568
588
  }
@@ -584,9 +604,10 @@ function buildGradientCss(gradient) {
584
604
  return buildCirclePathGradient(stops, fp, ftr);
585
605
  }
586
606
  const normalizedAngle = typeof gradient.fillGradientAngle === "number" && Number.isFinite(gradient.fillGradientAngle) ? gradient.fillGradientAngle : 90;
607
+ const effectiveAngle = adjustLinearGradientAngle(normalizedAngle, gradient, context);
587
608
  const flip = gradient.fillGradientFlip;
588
609
  const linearStops = flip && flip !== "none" ? buildReflectedGradientStops(stops) : stops;
589
- return `linear-gradient(${Math.round(normalizedAngle)}deg, ${linearStops.map(toCssGradientStop).join(", ")})`;
610
+ return `linear-gradient(${Math.round(effectiveAngle)}deg, ${linearStops.map(toCssGradientStop).join(", ")})`;
590
611
  }
591
612
  var buildCssGradientFromShapeStyle = buildGradientCss;
592
613
  function getPatternSvg(preset, fg, bg) {
@@ -1117,7 +1138,7 @@ var DEFAULT_SCHEME_COLOR_MAP = {
1117
1138
  phclr: "#4472C4"
1118
1139
  };
1119
1140
  function applyDrawingColorTransforms2(baseColor, colorNode) {
1120
- return chunk2V6BD4JQ_js.applyDrawingColorTransforms(baseColor, colorNode);
1141
+ return chunkIPYAN574_js.applyDrawingColorTransforms(baseColor, colorNode);
1121
1142
  }
1122
1143
  function parseDrawingColorChoice(colorNode, schemeColorOverrides) {
1123
1144
  if (!colorNode) {
@@ -1169,7 +1190,7 @@ function parseDrawingColorChoice(colorNode, schemeColorOverrides) {
1169
1190
  const h = hueRaw / 6e4;
1170
1191
  const s = clampUnitInterval(satRaw / 1e5);
1171
1192
  const l = clampUnitInterval(lumRaw / 1e5);
1172
- const rgb = chunk2V6BD4JQ_js.hslToRgb(h, s, l);
1193
+ const rgb = chunkIPYAN574_js.hslToRgb(h, s, l);
1173
1194
  const toHex = (value) => Math.min(255, Math.max(0, Math.round(value))).toString(16).padStart(2, "0").toUpperCase();
1174
1195
  const base = `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
1175
1196
  return applyDrawingColorTransforms2(base, hslNode);
@@ -1179,7 +1200,7 @@ function parseDrawingColorChoice(colorNode, schemeColorOverrides) {
1179
1200
  const preset = String(
1180
1201
  colorNode["a:prstClr"]?.["@_val"] || ""
1181
1202
  ).toLowerCase();
1182
- const mapped = chunk2V6BD4JQ_js.PRESET_COLOR_MAP[preset];
1203
+ const mapped = chunkIPYAN574_js.PRESET_COLOR_MAP[preset];
1183
1204
  if (!mapped) {
1184
1205
  return void 0;
1185
1206
  }
@@ -1534,7 +1555,7 @@ function hexToRgbUnit2(hex) {
1534
1555
  };
1535
1556
  }
1536
1557
  function getEffects(element) {
1537
- if (!chunk2V6BD4JQ_js.isImageLikeElement(element)) {
1558
+ if (!chunkIPYAN574_js.isImageLikeElement(element)) {
1538
1559
  return void 0;
1539
1560
  }
1540
1561
  return element.imageEffects;
@@ -1723,7 +1744,7 @@ function buildDuotoneFilterMarkup(color1, color2) {
1723
1744
  const c2 = hexToRgbUnit2(color2);
1724
1745
  return `<feColorMatrix type="matrix" values="${GRAYSCALE_LUMINANCE_MATRIX}"/><feComponentTransfer><feFuncR type="linear" slope="${c2.r - c1.r}" intercept="${c1.r}"/><feFuncG type="linear" slope="${c2.g - c1.g}" intercept="${c1.g}"/><feFuncB type="linear" slope="${c2.b - c1.b}" intercept="${c1.b}"/></feComponentTransfer>`;
1725
1746
  }
1726
- function getDuotoneImageFilter(element, elementId = chunk2V6BD4JQ_js.isImageLikeElement(element) ? element.id : "") {
1747
+ function getDuotoneImageFilter(element, elementId = chunkIPYAN574_js.isImageLikeElement(element) ? element.id : "") {
1727
1748
  const effects = getEffects(element);
1728
1749
  if (!effects?.duotone) {
1729
1750
  return void 0;
@@ -1825,7 +1846,7 @@ function buildImageAlphaFilterMarkup(effects) {
1825
1846
  }
1826
1847
  return parts.length > 0 ? parts.join("") : void 0;
1827
1848
  }
1828
- function getImageAlphaFilter(element, elementId = chunk2V6BD4JQ_js.isImageLikeElement(element) ? element.id : "") {
1849
+ function getImageAlphaFilter(element, elementId = chunkIPYAN574_js.isImageLikeElement(element) ? element.id : "") {
1829
1850
  const effects = getEffects(element);
1830
1851
  if (!effects || !hasAdvancedImageAlphaEffects(element)) {
1831
1852
  return void 0;
@@ -1915,7 +1936,7 @@ function buildArtisticFilterMarkup(effectName, radius) {
1915
1936
  return void 0;
1916
1937
  }
1917
1938
  }
1918
- function getArtisticImageFilter(element, elementId = chunk2V6BD4JQ_js.isImageLikeElement(element) ? element.id : "") {
1939
+ function getArtisticImageFilter(element, elementId = chunkIPYAN574_js.isImageLikeElement(element) ? element.id : "") {
1919
1940
  const effects = getEffects(element);
1920
1941
  if (!effects?.artisticEffect || !needsSvgArtisticFilter(effects.artisticEffect)) {
1921
1942
  return void 0;
@@ -2874,7 +2895,7 @@ function convertChildren(node) {
2874
2895
  if (key.startsWith("@_")) {
2875
2896
  continue;
2876
2897
  }
2877
- const tag = chunk2V6BD4JQ_js.stripXmlOrderSuffix(key);
2898
+ const tag = chunkIPYAN574_js.stripXmlOrderSuffix(key);
2878
2899
  if (tag === "m:oMathPara") {
2879
2900
  continue;
2880
2901
  }
@@ -2946,7 +2967,7 @@ function findOmathRoots(node) {
2946
2967
  }
2947
2968
  }
2948
2969
  const contentTags = /* @__PURE__ */ new Set(["m:r", "m:f", "m:rad", "m:sSup", "m:sSub", "m:box"]);
2949
- if (Object.keys(node).some((key) => contentTags.has(chunk2V6BD4JQ_js.stripXmlOrderSuffix(key)))) {
2970
+ if (Object.keys(node).some((key) => contentTags.has(chunkIPYAN574_js.stripXmlOrderSuffix(key)))) {
2950
2971
  return [node];
2951
2972
  }
2952
2973
  return [];
@@ -3156,7 +3177,7 @@ function mergeSiblings(nodes) {
3156
3177
  }
3157
3178
  const ordered = {};
3158
3179
  for (const [position, [key, value]] of entries.entries()) {
3159
- ordered[(counts.get(key) ?? 0) > 1 ? chunk2V6BD4JQ_js.orderedXmlKey(key, position) : key] = value;
3180
+ ordered[(counts.get(key) ?? 0) > 1 ? chunkIPYAN574_js.orderedXmlKey(key, position) : key] = value;
3160
3181
  }
3161
3182
  return ordered;
3162
3183
  }
@@ -3560,7 +3581,7 @@ function ommlChildrenToLatex(node) {
3560
3581
  if (key.startsWith("@_")) {
3561
3582
  continue;
3562
3583
  }
3563
- const tag = chunk2V6BD4JQ_js.stripXmlOrderSuffix(key);
3584
+ const tag = chunkIPYAN574_js.stripXmlOrderSuffix(key);
3564
3585
  const items = ensureArr(node[key]);
3565
3586
  for (const item of items) {
3566
3587
  const result = ommlElementToLatex(tag, item);
@@ -4169,6 +4190,20 @@ function splitSeriesByAxis(series, axes) {
4169
4190
  }
4170
4191
  return { primary, secondary };
4171
4192
  }
4193
+ function findDataPoint(series, pointIndex) {
4194
+ return series.dataPoints?.find((p) => p.idx === pointIndex);
4195
+ }
4196
+ function resolveDataPointFill(series, pointIndex, fallbackColor) {
4197
+ const point = findDataPoint(series, pointIndex);
4198
+ return point?.spPr?.fillColor ?? series.color ?? fallbackColor;
4199
+ }
4200
+ function resolveVaryColorFill(series, pointIndex, paletteColor3) {
4201
+ return findDataPoint(series, pointIndex)?.spPr?.fillColor ?? paletteColor3;
4202
+ }
4203
+ function resolveDataPointExplosion(series, pointIndex) {
4204
+ const point = findDataPoint(series, pointIndex);
4205
+ return point?.explosion ?? series.explosion ?? 0;
4206
+ }
4172
4207
  function clamp3(value, min, max) {
4173
4208
  return Math.min(Math.max(value, min), max);
4174
4209
  }
@@ -4541,34 +4576,59 @@ function categoryTotals(series, catCount) {
4541
4576
  (_, ci) => series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0)
4542
4577
  );
4543
4578
  }
4579
+ function blendToWhite(color) {
4580
+ const match = /^#?([0-9a-f]{6})$/iu.exec(color.trim());
4581
+ if (!match) {
4582
+ return color;
4583
+ }
4584
+ const value = Number.parseInt(match[1], 16);
4585
+ const mix = (channel) => Math.round(channel + (255 - channel) * 0.5);
4586
+ const r = mix(value >> 16 & 255);
4587
+ const g = mix(value >> 8 & 255);
4588
+ const b = mix(value & 255);
4589
+ return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0").toUpperCase()}`;
4590
+ }
4591
+ function invertNegativeFill(series, pointIndex, value, baseFill) {
4592
+ if (value >= 0) {
4593
+ return baseFill;
4594
+ }
4595
+ const point = series.dataPoints?.find((p) => p.idx === pointIndex);
4596
+ const invert = point?.invertIfNegative ?? series.invertIfNegative ?? false;
4597
+ return invert ? blendToWhite(baseFill) : baseFill;
4598
+ }
4544
4599
  function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, grouping, sourceIndices2) {
4545
4600
  const primitives = [];
4546
4601
  const dataLabels = [];
4547
4602
  const series = chartData.series;
4548
4603
  const palette = chartData.colorPalette;
4549
4604
  const showLabels = chartData.style?.hasDataLabels;
4605
+ const varyColorsSingle = chartData.varyColors === true && series.length === 1;
4550
4606
  if (grouping === "clustered") {
4551
4607
  const seriesCount = Math.max(series.length, 1);
4552
4608
  const barGroupWidth2 = layout.plotWidth / Math.max(catCount, 1);
4553
- const singleBarWidth = barGroupWidth2 * 0.7 / seriesCount;
4554
- const groupOffset = (barGroupWidth2 - singleBarWidth * seriesCount) / 2;
4609
+ const singleBarWidth = chartData.barGapWidth !== void 0 ? barGroupWidth2 / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100) : barGroupWidth2 * 0.7 / seriesCount;
4610
+ const overlap = chartData.barOverlap ?? 0;
4611
+ const step = singleBarWidth * (1 - overlap / 100);
4612
+ const clusterWidth = singleBarWidth + step * (seriesCount - 1);
4613
+ const groupOffset = (barGroupWidth2 - clusterWidth) / 2;
4555
4614
  for (let displayIndex = 0; displayIndex < catCount; displayIndex++) {
4556
4615
  const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
4557
4616
  for (let si = 0; si < series.length; si++) {
4558
4617
  const val2 = series[si].values[sourceIndex] ?? 0;
4559
- const x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + singleBarWidth * si;
4618
+ const x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + step * si;
4560
4619
  const activeRange = secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange;
4561
4620
  const zeroY = valueToY2(0, activeRange, layout.plotTop, layout.plotBottom);
4562
4621
  const valY = valueToY2(val2, activeRange, layout.plotTop, layout.plotBottom);
4563
4622
  const y = Math.min(zeroY, valY);
4564
4623
  const h = Math.max(Math.abs(zeroY - valY), 1);
4624
+ const baseFill = varyColorsSingle ? resolveVaryColorFill(series[si], sourceIndex, paletteColor2(sourceIndex, palette)) : resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4565
4625
  primitives.push({
4566
4626
  kind: "rect",
4567
4627
  x,
4568
4628
  y,
4569
4629
  w: singleBarWidth,
4570
4630
  h,
4571
- fill: seriesColor2(series[si], si, palette),
4631
+ fill: invertNegativeFill(series[si], sourceIndex, val2, baseFill),
4572
4632
  rx: 1,
4573
4633
  part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4574
4634
  });
@@ -4594,20 +4654,16 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4594
4654
  }));
4595
4655
  const rects = computeStackedBarRects(displaySeries2, catCount, layout, primaryRange, palette);
4596
4656
  for (const r of rects) {
4597
- primitives.push({
4598
- kind: "rect",
4599
- x: r.x,
4600
- y: r.y,
4601
- w: r.w,
4602
- h: r.h,
4603
- fill: r.fill,
4604
- rx: 1,
4605
- part: r.seriesIndex !== void 0 && r.pointIndex !== void 0 ? {
4606
- role: "dataPoint",
4607
- seriesIndex: r.seriesIndex,
4608
- pointIndex: sourceIndices2[r.pointIndex] ?? r.pointIndex
4609
- } : void 0
4610
- });
4657
+ let fill = r.fill;
4658
+ let part;
4659
+ if (r.seriesIndex !== void 0 && r.pointIndex !== void 0) {
4660
+ const sourcePointIndex = sourceIndices2[r.pointIndex] ?? r.pointIndex;
4661
+ fill = resolveDataPointFill(series[r.seriesIndex], sourcePointIndex, r.fill) ?? r.fill;
4662
+ const value = series[r.seriesIndex].values[sourcePointIndex] ?? 0;
4663
+ fill = invertNegativeFill(series[r.seriesIndex], sourcePointIndex, value, fill);
4664
+ part = { role: "dataPoint", seriesIndex: r.seriesIndex, pointIndex: sourcePointIndex };
4665
+ }
4666
+ primitives.push({ kind: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill, rx: 1, part });
4611
4667
  }
4612
4668
  if (showLabels) {
4613
4669
  pushClusteredStackedLabels(series, sourceIndices2, catCount, layout, primaryRange, dataLabels);
@@ -4638,13 +4694,14 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4638
4694
  const topY = valueToY2(top, primaryRange, layout.plotTop, layout.plotBottom);
4639
4695
  const y = Math.min(baseY, topY);
4640
4696
  const h = Math.max(Math.abs(baseY - topY), 0.5);
4697
+ const pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4641
4698
  primitives.push({
4642
4699
  kind: "rect",
4643
4700
  x,
4644
4701
  y,
4645
4702
  w: barW,
4646
4703
  h,
4647
- fill: seriesColor2(series[si], si, palette),
4704
+ fill: invertNegativeFill(series[si], sourceIndex, rawVal, pctBaseFill),
4648
4705
  part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4649
4706
  });
4650
4707
  if (showLabels && Math.abs(val2) > 0) {
@@ -4693,6 +4750,139 @@ function pushClusteredStackedLabels(series, sourceIndices2, catCount, layout, ra
4693
4750
  }
4694
4751
  }
4695
4752
  }
4753
+ function smoothLinePath(points) {
4754
+ if (points.length === 0) {
4755
+ return "";
4756
+ }
4757
+ if (points.length === 1) {
4758
+ return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
4759
+ }
4760
+ if (points.length === 2) {
4761
+ return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)} L${points[1].x.toFixed(2)},${points[1].y.toFixed(2)}`;
4762
+ }
4763
+ let d = `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
4764
+ for (let i = 0; i < points.length - 1; i++) {
4765
+ const p0 = points[i - 1] ?? points[i];
4766
+ const p1 = points[i];
4767
+ const p2 = points[i + 1];
4768
+ const p3 = points[i + 2] ?? p2;
4769
+ const cp1x = p1.x + (p2.x - p0.x) / 6;
4770
+ const cp1y = p1.y + (p2.y - p0.y) / 6;
4771
+ const cp2x = p2.x - (p3.x - p1.x) / 6;
4772
+ const cp2y = p2.y - (p3.y - p1.y) / 6;
4773
+ d += ` C${cp1x.toFixed(2)},${cp1y.toFixed(2)} ${cp2x.toFixed(2)},${cp2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
4774
+ }
4775
+ return d;
4776
+ }
4777
+ function markerRadius(size, defaultRadius2) {
4778
+ if (size === void 0 || !Number.isFinite(size) || size <= 0) {
4779
+ return defaultRadius2;
4780
+ }
4781
+ return size / 2;
4782
+ }
4783
+ function polygonPoints(vertices) {
4784
+ return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
4785
+ }
4786
+ function starVertices(cx, cy, r) {
4787
+ const inner = r * 0.5;
4788
+ const out = [];
4789
+ for (let i = 0; i < 10; i++) {
4790
+ const radius = i % 2 === 0 ? r : inner;
4791
+ const angle = -Math.PI / 2 + Math.PI * i / 5;
4792
+ out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
4793
+ }
4794
+ return out;
4795
+ }
4796
+ function buildMarkerPrimitive(input) {
4797
+ const { symbol, cx, cy, fill, part } = input;
4798
+ if (symbol === "none") {
4799
+ return null;
4800
+ }
4801
+ const r = markerRadius(input.size, input.defaultRadius);
4802
+ const stroke = fill;
4803
+ switch (symbol) {
4804
+ case "square":
4805
+ return { kind: "rect", x: cx - r, y: cy - r, w: r * 2, h: r * 2, fill, part };
4806
+ case "dash":
4807
+ return { kind: "rect", x: cx - r, y: cy - r * 0.32, w: r * 2, h: r * 0.64, fill, part };
4808
+ case "diamond":
4809
+ return {
4810
+ kind: "polygon",
4811
+ points: polygonPoints([
4812
+ [cx, cy - r],
4813
+ [cx + r, cy],
4814
+ [cx, cy + r],
4815
+ [cx - r, cy]
4816
+ ]),
4817
+ fill,
4818
+ stroke,
4819
+ strokeWidth: 0,
4820
+ part
4821
+ };
4822
+ case "triangle":
4823
+ return {
4824
+ kind: "polygon",
4825
+ points: polygonPoints([
4826
+ [cx, cy - r],
4827
+ [cx + r * 0.9, cy + r * 0.75],
4828
+ [cx - r * 0.9, cy + r * 0.75]
4829
+ ]),
4830
+ fill,
4831
+ stroke,
4832
+ strokeWidth: 0,
4833
+ part
4834
+ };
4835
+ case "star":
4836
+ return {
4837
+ kind: "polygon",
4838
+ points: polygonPoints(starVertices(cx, cy, r)),
4839
+ fill,
4840
+ stroke,
4841
+ strokeWidth: 0,
4842
+ part
4843
+ };
4844
+ case "plus":
4845
+ return {
4846
+ kind: "path",
4847
+ d: `M${(cx - r).toFixed(2)},${cy.toFixed(2)} L${(cx + r).toFixed(2)},${cy.toFixed(2)} M${cx.toFixed(2)},${(cy - r).toFixed(2)} L${cx.toFixed(2)},${(cy + r).toFixed(2)}`,
4848
+ fill: "none",
4849
+ stroke,
4850
+ strokeWidth: Math.max(1, r * 0.4),
4851
+ part
4852
+ };
4853
+ case "x":
4854
+ return {
4855
+ kind: "path",
4856
+ d: `M${(cx - r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx + r).toFixed(2)},${(cy + r).toFixed(2)} M${(cx + r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx - r).toFixed(2)},${(cy + r).toFixed(2)}`,
4857
+ fill: "none",
4858
+ stroke,
4859
+ strokeWidth: Math.max(1, r * 0.4),
4860
+ part
4861
+ };
4862
+ case "dot":
4863
+ return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, part };
4864
+ default:
4865
+ return { kind: "circle", cx, cy, r, fill, part };
4866
+ }
4867
+ }
4868
+ function pushMarker(out, series, cx, cy, fill, defaultRadius2, part, opacity) {
4869
+ const m = buildMarkerPrimitive({
4870
+ symbol: series.marker?.symbol,
4871
+ size: series.marker?.size,
4872
+ cx,
4873
+ cy,
4874
+ fill,
4875
+ defaultRadius: defaultRadius2,
4876
+ part
4877
+ });
4878
+ if (!m) {
4879
+ return;
4880
+ }
4881
+ if (opacity !== void 0) {
4882
+ m.opacity = opacity;
4883
+ }
4884
+ out.push(m);
4885
+ }
4696
4886
  function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, sourceIndices2, xPositions) {
4697
4887
  const primitives = [];
4698
4888
  const dataLabels = [];
@@ -4711,24 +4901,36 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
4711
4901
  })
4712
4902
  );
4713
4903
  const c = seriesColor2(series, si, chartData.colorPalette);
4714
- primitives.push({
4715
- kind: "polyline",
4716
- points: linePointsToSvgString(pts),
4717
- stroke: c,
4718
- strokeWidth: 2.4,
4719
- fill: "none",
4720
- part: { role: "series", seriesIndex: si }
4721
- });
4904
+ const seriesPart = { role: "series", seriesIndex: si };
4905
+ primitives.push(
4906
+ series.smooth ? {
4907
+ kind: "path",
4908
+ d: smoothLinePath(pts),
4909
+ stroke: c,
4910
+ strokeWidth: 2.4,
4911
+ fill: "none",
4912
+ part: seriesPart
4913
+ } : {
4914
+ kind: "polyline",
4915
+ points: linePointsToSvgString(pts),
4916
+ stroke: c,
4917
+ strokeWidth: 2.4,
4918
+ fill: "none",
4919
+ part: seriesPart
4920
+ }
4921
+ );
4722
4922
  pts.forEach((pt, displayIndex) => {
4723
- const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
4724
- primitives.push({
4725
- kind: "circle",
4726
- cx: pt.x,
4727
- cy: pt.y,
4728
- r: 2.5,
4729
- fill: c,
4730
- part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4731
- });
4923
+ const idx = sourceIndices2[displayIndex] ?? displayIndex;
4924
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
4925
+ pushMarker(
4926
+ primitives,
4927
+ series,
4928
+ pt.x,
4929
+ pt.y,
4930
+ resolveDataPointFill(series, idx, c) ?? c,
4931
+ 2.5,
4932
+ part
4933
+ );
4732
4934
  });
4733
4935
  if (showLabels) {
4734
4936
  displayValues.forEach((val2, displayIndex) => {
@@ -4789,18 +4991,17 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
4789
4991
  part: { role: "series", seriesIndex: si }
4790
4992
  });
4791
4993
  pts.forEach((pt, displayIndex) => {
4792
- primitives.push({
4793
- kind: "circle",
4794
- cx: pt.x,
4795
- cy: pt.y,
4796
- r: 2,
4797
- fill: c,
4798
- part: {
4799
- role: "dataPoint",
4800
- seriesIndex: si,
4801
- pointIndex: sourceIndices2[displayIndex] ?? displayIndex
4802
- }
4803
- });
4994
+ const idx = sourceIndices2[displayIndex] ?? displayIndex;
4995
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
4996
+ pushMarker(
4997
+ primitives,
4998
+ series,
4999
+ pt.x,
5000
+ pt.y,
5001
+ resolveDataPointFill(series, idx, c) ?? c,
5002
+ 2,
5003
+ part
5004
+ );
4804
5005
  });
4805
5006
  if (showLabels) {
4806
5007
  displayValues.forEach((val2, displayIndex) => {
@@ -4834,15 +5035,17 @@ function buildScatter(chartData, layout, range) {
4834
5035
  const c = seriesColor2(series, si, chartData.colorPalette);
4835
5036
  const dots = computeScatterDots(series.values, maxXIndex, layout, range, xValues);
4836
5037
  dots.forEach((dot, vi) => {
4837
- primitives.push({
4838
- kind: "circle",
4839
- cx: dot.cx,
4840
- cy: dot.cy,
4841
- r: 4,
4842
- fill: c,
4843
- opacity: 0.85,
4844
- part: { role: "dataPoint", seriesIndex: si, pointIndex: vi }
4845
- });
5038
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: vi };
5039
+ pushMarker(
5040
+ primitives,
5041
+ series,
5042
+ dot.cx,
5043
+ dot.cy,
5044
+ resolveDataPointFill(series, vi, c) ?? c,
5045
+ 4,
5046
+ part,
5047
+ 0.85
5048
+ );
4846
5049
  });
4847
5050
  if (showLabels) {
4848
5051
  series.values.forEach((val2, vi) => {
@@ -4886,7 +5089,7 @@ function buildBubbles(chartData, layout, range) {
4886
5089
  cx: dot.cx,
4887
5090
  cy: dot.cy,
4888
5091
  r,
4889
- fill: c,
5092
+ fill: resolveDataPointFill(series, vi, c) ?? c,
4890
5093
  opacity: 0.6,
4891
5094
  part: { role: "dataPoint", seriesIndex: si, pointIndex: vi }
4892
5095
  });
@@ -4911,7 +5114,124 @@ function buildBubbles(chartData, layout, range) {
4911
5114
  }
4912
5115
  return { primitives, dataLabels };
4913
5116
  }
4914
- function categoryX(displayIndex, count, layout, spacing) {
5117
+ function categoryX(index, catCount, layout, options) {
5118
+ const explicit = options.xPositions?.[index];
5119
+ if (explicit !== void 0) {
5120
+ return explicit;
5121
+ }
5122
+ if (options.mode === "bar") {
5123
+ const slot = layout.plotWidth / Math.max(catCount, 1);
5124
+ return layout.plotLeft + slot * index + slot / 2;
5125
+ }
5126
+ const maxIdx = Math.max(catCount - 1, 1);
5127
+ return layout.plotLeft + index / maxIdx * layout.plotWidth;
5128
+ }
5129
+ function dashFor(dashStyle) {
5130
+ if (!dashStyle || dashStyle === "solid") {
5131
+ return void 0;
5132
+ }
5133
+ return dashStyle === "dot" || dashStyle === "sysDot" ? "1 2" : "4 3";
5134
+ }
5135
+ function computeDropLinePrimitives(chartData, layout, range, catCount, options) {
5136
+ const style = chartData.dropLines;
5137
+ if (!style) {
5138
+ return [];
5139
+ }
5140
+ const baselineY = valueToY2(range.min, range, layout.plotTop, layout.plotBottom);
5141
+ const dashArray2 = dashFor(style.dashStyle);
5142
+ const out = [];
5143
+ for (const series of chartData.series) {
5144
+ series.values.forEach((val2, vi) => {
5145
+ const x = categoryX(vi, catCount, layout, options);
5146
+ out.push({
5147
+ kind: "line",
5148
+ x1: x,
5149
+ y1: valueToY2(val2, range, layout.plotTop, layout.plotBottom),
5150
+ x2: x,
5151
+ y2: baselineY,
5152
+ stroke: style.color ?? "#94a3b8",
5153
+ strokeWidth: style.width ?? 0.8,
5154
+ dashArray: dashArray2
5155
+ });
5156
+ });
5157
+ }
5158
+ return out;
5159
+ }
5160
+ function computeHiLowLinePrimitives(chartData, layout, range, catCount, options) {
5161
+ const style = chartData.hiLowLines;
5162
+ if (!style || chartData.series.length < 2) {
5163
+ return [];
5164
+ }
5165
+ const dashArray2 = dashFor(style.dashStyle);
5166
+ const out = [];
5167
+ for (let vi = 0; vi < catCount; vi++) {
5168
+ let high = Number.NEGATIVE_INFINITY;
5169
+ let low = Number.POSITIVE_INFINITY;
5170
+ for (const series of chartData.series) {
5171
+ const v = series.values[vi];
5172
+ if (v !== void 0) {
5173
+ high = Math.max(high, v);
5174
+ low = Math.min(low, v);
5175
+ }
5176
+ }
5177
+ if (!Number.isFinite(high) || !Number.isFinite(low)) {
5178
+ continue;
5179
+ }
5180
+ const x = categoryX(vi, catCount, layout, options);
5181
+ out.push({
5182
+ kind: "line",
5183
+ x1: x,
5184
+ y1: valueToY2(high, range, layout.plotTop, layout.plotBottom),
5185
+ x2: x,
5186
+ y2: valueToY2(low, range, layout.plotTop, layout.plotBottom),
5187
+ stroke: style.color ?? "#334155",
5188
+ strokeWidth: style.width ?? 1,
5189
+ dashArray: dashArray2
5190
+ });
5191
+ }
5192
+ return out;
5193
+ }
5194
+ function computeUpDownBarPrimitives(chartData, layout, range, catCount, options) {
5195
+ const bars = chartData.upDownBars;
5196
+ if (!bars || chartData.series.length < 2) {
5197
+ return [];
5198
+ }
5199
+ const first = chartData.series[0];
5200
+ const last = chartData.series[chartData.series.length - 1];
5201
+ const slot = layout.plotWidth / Math.max(catCount, 1);
5202
+ const gapWidth = bars.gapWidth ?? 150;
5203
+ const barW = Math.max(slot / (1 + Math.max(gapWidth, 0) / 100), 1);
5204
+ const upFill = bars.upBars?.fillColor ?? "#e2e8f0";
5205
+ const downFill = bars.downBars?.fillColor ?? "#334155";
5206
+ const out = [];
5207
+ for (let vi = 0; vi < catCount; vi++) {
5208
+ const firstVal = first.values[vi];
5209
+ const lastVal = last.values[vi];
5210
+ if (firstVal === void 0 || lastVal === void 0) {
5211
+ continue;
5212
+ }
5213
+ const firstY = valueToY2(firstVal, range, layout.plotTop, layout.plotBottom);
5214
+ const lastY = valueToY2(lastVal, range, layout.plotTop, layout.plotBottom);
5215
+ const x = categoryX(vi, catCount, layout, options) - barW / 2;
5216
+ out.push({
5217
+ kind: "rect",
5218
+ x,
5219
+ y: Math.min(firstY, lastY),
5220
+ w: barW,
5221
+ h: Math.max(Math.abs(firstY - lastY), 1),
5222
+ fill: lastVal >= firstVal ? upFill : downFill
5223
+ });
5224
+ }
5225
+ return out;
5226
+ }
5227
+ function computeHelperLinePrimitives(chartData, layout, range, catCount, options) {
5228
+ return [
5229
+ ...computeUpDownBarPrimitives(chartData, layout, range, catCount, options),
5230
+ ...computeDropLinePrimitives(chartData, layout, range, catCount, options),
5231
+ ...computeHiLowLinePrimitives(chartData, layout, range, catCount, options)
5232
+ ];
5233
+ }
5234
+ function categoryX2(displayIndex, count, layout, spacing) {
4915
5235
  if (spacing === "bar") {
4916
5236
  return layout.plotLeft + layout.plotWidth / Math.max(count, 1) * (displayIndex + 0.5);
4917
5237
  }
@@ -4942,8 +5262,8 @@ function buildMultiLevelCategoryLabels(categoryLabels, categoryLevels, sourceInd
4942
5262
  if (!group.text || group.start % skip !== 0) {
4943
5263
  return [];
4944
5264
  }
4945
- const startX = categoryX(group.start, sourceIndices2.length, layout, spacing);
4946
- const endX = categoryX(group.end, sourceIndices2.length, layout, spacing);
5265
+ const startX = categoryX2(group.start, sourceIndices2.length, layout, spacing);
5266
+ const endX = categoryX2(group.end, sourceIndices2.length, layout, spacing);
4947
5267
  return [
4948
5268
  {
4949
5269
  kind: "text",
@@ -4998,13 +5318,13 @@ function buildTickMarks(axis, sourceCount, layout, spacing, axisY) {
4998
5318
  }
4999
5319
  const majorSkip = Math.max(1, axis.tickMarkSkip ?? 1);
5000
5320
  for (let displayIndex = 0; displayIndex < sourceCount; displayIndex += majorSkip) {
5001
- const x = categoryX(displayIndex, sourceCount, layout, spacing);
5321
+ const x = categoryX2(displayIndex, sourceCount, layout, spacing);
5002
5322
  const major = tickLine(x, y, axis.majorTickMark, topAxis, 4, axis);
5003
5323
  if (major) {
5004
5324
  result.push(major);
5005
5325
  }
5006
5326
  if (axis.minorTickMark !== void 0 && displayIndex + majorSkip < sourceCount) {
5007
- const nextX = categoryX(displayIndex + majorSkip, sourceCount, layout, spacing);
5327
+ const nextX = categoryX2(displayIndex + majorSkip, sourceCount, layout, spacing);
5008
5328
  const minor = tickLine((x + nextX) / 2, y, axis.minorTickMark, topAxis, 2.5, axis);
5009
5329
  if (minor) {
5010
5330
  result.push(minor);
@@ -5282,7 +5602,7 @@ function buildCartesianHorizontalAxis(chartData, categoryLabels, layout, kind, p
5282
5602
  catAxisStyle,
5283
5603
  sourceIndices: sourceIndices2,
5284
5604
  xPositions: datePlan?.xPositions ?? categoryPlan?.sourceIndices.map(
5285
- (_sourceIndex, displayIndex) => categoryX(displayIndex, categoryPlan.sourceIndices.length, layout, catAxisStyle)
5605
+ (_sourceIndex, displayIndex) => categoryX2(displayIndex, categoryPlan.sourceIndices.length, layout, catAxisStyle)
5286
5606
  ),
5287
5607
  labels: [
5288
5608
  ...datePlan?.labels ?? categoryPlan?.labels ?? buildCategoryLabels(categoryLabels, layout, catAxisStyle),
@@ -5297,7 +5617,7 @@ function buildCartesianHorizontalAxis(chartData, categoryLabels, layout, kind, p
5297
5617
  }
5298
5618
  var DEFAULT_COLOR3 = "#334155";
5299
5619
  var CAP_HALF_WIDTH = 4;
5300
- function categoryX2(value, count, layout, mode) {
5620
+ function categoryX3(value, count, layout, mode) {
5301
5621
  if (mode === "bar") {
5302
5622
  const slot = layout.plotWidth / Math.max(count, 1);
5303
5623
  return layout.plotLeft + slot * value + slot / 2;
@@ -5404,7 +5724,7 @@ function computeErrorBarPrimitives(chartData, catCount, layout, range, mode = "l
5404
5724
  const categoryMapper = (value) => positionedCategoryX(
5405
5725
  value,
5406
5726
  options.xPositions,
5407
- (index) => categoryX2(index, indexes.length || catCount, layout, seriesMode)
5727
+ (index) => categoryX3(index, indexes.length || catCount, layout, seriesMode)
5408
5728
  );
5409
5729
  const toPixel = xValues.numeric ? (value) => numericX(value, xRange, layout) : categoryMapper;
5410
5730
  const x = toPixel(baseXValue);
@@ -5978,7 +6298,15 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
5978
6298
  } else {
5979
6299
  plot = buildBubbles(chartData, layout, primaryRange);
5980
6300
  }
5981
- const primitives = [...plot.primitives, ...horizontalAxis.tickMarks];
6301
+ const helperLines = kind === "line" || kind === "area" ? computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, {
6302
+ mode: "line",
6303
+ xPositions: horizontalAxis.xPositions
6304
+ }) : [];
6305
+ const primitives = [
6306
+ ...helperLines,
6307
+ ...plot.primitives,
6308
+ ...horizontalAxis.tickMarks
6309
+ ];
5982
6310
  const overlays = [
5983
6311
  ...computeTrendlinePrimitives(
5984
6312
  displayChartData,
@@ -6104,6 +6432,10 @@ function buildComboViewModel(element, chartData, categoryLabels) {
6104
6432
  );
6105
6433
  const primitives = [];
6106
6434
  const dataLabels = [];
6435
+ const helperOpts = { mode: "line", xPositions: horizontalAxis.xPositions };
6436
+ primitives.push(
6437
+ ...computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, helperOpts)
6438
+ );
6107
6439
  const barSeries = chartData.series.slice(0, 1);
6108
6440
  if (barSeries[0]) {
6109
6441
  const barRange = rangeForSeries(0, primaryRange, secondaryRange, secondaryIndexes);
@@ -8511,16 +8843,30 @@ function computePieLayout(elementWidth, elementHeight, chartData, isDoughnut) {
8511
8843
  const cx = size / 2;
8512
8844
  const cy = titleOffset + (size - titleOffset - legendOffset) / 2;
8513
8845
  const outerR = Math.max((size - titleOffset - legendOffset) * 0.42, 0);
8514
- const innerR = isDoughnut ? outerR * 0.55 : 0;
8846
+ const holeRatio = isDoughnut && chartData.doughnutHoleSize !== void 0 ? Math.min(Math.max(chartData.doughnutHoleSize, 10), 90) / 100 : 0.55;
8847
+ const innerR = isDoughnut ? outerR * holeRatio : 0;
8515
8848
  return { cx, cy, outerR, innerR, size };
8516
8849
  }
8517
- function computePieSlices(values, cx, cy, outerR, innerR) {
8850
+ function computePieSlices(values, cx, cy, outerR, innerR, options) {
8518
8851
  const total = values.reduce((s, v) => s + Math.abs(v), 0) || 1;
8519
- let cumAngle = -Math.PI / 2;
8520
- return values.map((val2) => {
8852
+ let cumAngle = options?.startAngle ?? -Math.PI / 2;
8853
+ return values.map((val2, i) => {
8521
8854
  const sliceAngle = Math.abs(val2) / total * Math.PI * 2;
8522
8855
  const startAngle = cumAngle;
8523
8856
  cumAngle += sliceAngle;
8857
+ const explosion = options?.explosions?.[i] ?? 0;
8858
+ if (explosion > 0) {
8859
+ const mid = (startAngle + cumAngle) / 2;
8860
+ const offset = outerR * (explosion / 100);
8861
+ return computePieSlicePath(
8862
+ cx + Math.cos(mid) * offset,
8863
+ cy + Math.sin(mid) * offset,
8864
+ outerR,
8865
+ innerR,
8866
+ startAngle,
8867
+ cumAngle
8868
+ );
8869
+ }
8524
8870
  return computePieSlicePath(cx, cy, outerR, innerR, startAngle, cumAngle);
8525
8871
  });
8526
8872
  }
@@ -8713,13 +9059,18 @@ function buildPieViewModel(element, chartData, categoryLabels, isDoughnut) {
8713
9059
  );
8714
9060
  const svgWidth = Math.max(size, 100);
8715
9061
  const svgHeight = Math.max(size, 60);
8716
- const values = chartData.series[0]?.values ?? [];
8717
- const slices = computePieSlices(values, cx, cy, outerR, innerR);
9062
+ const pieSeries = chartData.series[0];
9063
+ const values = pieSeries?.values ?? [];
9064
+ const startAngle = -Math.PI / 2 + (chartData.firstSliceAngle ?? 0) * Math.PI / 180;
9065
+ const explosions = pieSeries ? values.map((_v, i) => resolveDataPointExplosion(pieSeries, i)) : void 0;
9066
+ const slices = computePieSlices(values, cx, cy, outerR, innerR, { startAngle, explosions });
8718
9067
  const primitives = slices.map(
8719
9068
  ({ d }, i) => ({
8720
9069
  kind: "path",
8721
9070
  d,
8722
- fill: chartData.series[0]?.color ?? paletteColor2(i, chartData.colorPalette),
9071
+ // Pie/doughnut vary colours per slice (c:varyColors defaults on), so each
9072
+ // slice takes its palette colour, with a per-point c:dPt fill overriding.
9073
+ fill: pieSeries ? resolveVaryColorFill(pieSeries, i, paletteColor2(i, chartData.colorPalette)) : paletteColor2(i, chartData.colorPalette),
8723
9074
  stroke: "#ffffff",
8724
9075
  strokeWidth: 1.5,
8725
9076
  part: { role: "dataPoint", seriesIndex: 0, pointIndex: i }
@@ -9045,6 +9396,21 @@ var PRESET_ID_TO_EFFECT = {
9045
9396
  26: "pulse"
9046
9397
  }
9047
9398
  };
9399
+ var FLY_SUBTYPE_TO_EDGE = {
9400
+ 1: "top",
9401
+ 2: "right",
9402
+ 4: "bottom",
9403
+ 8: "left",
9404
+ // Corners -> nearest (horizontal) edge.
9405
+ 3: "right",
9406
+ // top-right (1|2)
9407
+ 6: "right",
9408
+ // bottom-right (4|2)
9409
+ 9: "left",
9410
+ // top-left (8|1)
9411
+ 12: "left"
9412
+ // bottom-left (8|4)
9413
+ };
9048
9414
  var KEYFRAME_DEFINITIONS = {
9049
9415
  // ---- Entrance effects ----
9050
9416
  appear: `@keyframes pptx-appear {
@@ -9416,16 +9782,31 @@ function resolveEffect(anim) {
9416
9782
  return void 0;
9417
9783
  }
9418
9784
  if (cls === "entr") {
9419
- return PRESET_ID_TO_EFFECT.entr[id];
9785
+ return applyFlyDirection(PRESET_ID_TO_EFFECT.entr[id], anim.presetSubtype);
9420
9786
  }
9421
9787
  if (cls === "exit") {
9422
- return PRESET_ID_TO_EFFECT.exit[id];
9788
+ return applyFlyDirection(PRESET_ID_TO_EFFECT.exit[id], anim.presetSubtype);
9423
9789
  }
9424
9790
  if (cls === "emph") {
9425
9791
  return PRESET_ID_TO_EFFECT.emph[id];
9426
9792
  }
9427
9793
  return void 0;
9428
9794
  }
9795
+ function applyFlyDirection(effect, subtype) {
9796
+ if (effect !== "flyInBottom" && effect !== "flyOutBottom") {
9797
+ return effect;
9798
+ }
9799
+ if (subtype === void 0) {
9800
+ return effect;
9801
+ }
9802
+ const edge = FLY_SUBTYPE_TO_EDGE[subtype];
9803
+ if (!edge) {
9804
+ return effect;
9805
+ }
9806
+ const prefix = effect === "flyInBottom" ? "flyIn" : "flyOut";
9807
+ const suffix = `${edge.charAt(0).toUpperCase()}${edge.slice(1)}`;
9808
+ return `${prefix}${suffix}`;
9809
+ }
9429
9810
  function parseMotionPathPoints(motionPath) {
9430
9811
  const cmds = motionPath.replace(/\s+/gu, " ").trim().split(/(?=[MLCZ])/iu).filter(Boolean);
9431
9812
  const points = [];
@@ -9827,6 +10208,29 @@ function getAnimationInitialStyle(preset, nativeAnimation) {
9827
10208
  }
9828
10209
  return {};
9829
10210
  }
10211
+ function cssEasingForAnimation(anim) {
10212
+ const hasAccel = anim.accel !== void 0 && anim.accel > 0;
10213
+ const hasDecel = anim.decel !== void 0 && anim.decel > 0;
10214
+ if (hasAccel && hasDecel) {
10215
+ return "ease-in-out";
10216
+ }
10217
+ if (hasAccel) {
10218
+ return "ease-in";
10219
+ }
10220
+ if (hasDecel) {
10221
+ return "ease-out";
10222
+ }
10223
+ return "ease";
10224
+ }
10225
+ function fallbackEffectForClass(presetClass) {
10226
+ if (presetClass === "entr") {
10227
+ return "fadeIn";
10228
+ }
10229
+ if (presetClass === "exit") {
10230
+ return "fadeOut";
10231
+ }
10232
+ return void 0;
10233
+ }
9830
10234
  function buildTimeline(nativeAnimations) {
9831
10235
  if (nativeAnimations.length === 0) {
9832
10236
  return {
@@ -9861,10 +10265,13 @@ function buildTimeline(nativeAnimations) {
9861
10265
  for (const anim of regularAnims) {
9862
10266
  const expandedSteps = expandIterateAnimation(anim);
9863
10267
  for (const singleAnim of expandedSteps) {
9864
- const effect = resolveEffect(singleAnim);
10268
+ let effect = resolveEffect(singleAnim);
9865
10269
  const dynamic = effect ? void 0 : buildDynamicKeyframe(singleAnim, dynamicUid++);
9866
10270
  if (!effect && !dynamic) {
9867
- continue;
10271
+ effect = fallbackEffectForClass(singleAnim.presetClass);
10272
+ if (!effect) {
10273
+ continue;
10274
+ }
9868
10275
  }
9869
10276
  const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
9870
10277
  if (effect) {
@@ -9910,7 +10317,8 @@ function buildTimeline(nativeAnimations) {
9910
10317
  delayMs = animDelay + triggerDelay;
9911
10318
  }
9912
10319
  const iterStr = iterCount === Infinity ? "infinite" : String(iterCount);
9913
- const cssAnimation = `${keyframe} ${duration}ms ease ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10320
+ const easing = cssEasingForAnimation(singleAnim);
10321
+ const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
9914
10322
  currentGroup.push({
9915
10323
  elementId,
9916
10324
  cssAnimation,
@@ -9993,10 +10401,13 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
9993
10401
  const seqGroups = [];
9994
10402
  let seqGroup = [];
9995
10403
  for (const anim of anims) {
9996
- const effect = resolveEffect(anim);
10404
+ let effect = resolveEffect(anim);
9997
10405
  const dynamic = effect ? void 0 : buildDynamicKeyframe(anim, dynamicUid++);
9998
10406
  if (!effect && !dynamic) {
9999
- continue;
10407
+ effect = fallbackEffectForClass(anim.presetClass);
10408
+ if (!effect) {
10409
+ continue;
10410
+ }
10000
10411
  }
10001
10412
  const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
10002
10413
  if (effect) {
@@ -10033,7 +10444,8 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
10033
10444
  delayMs = animDelay + triggerDelay;
10034
10445
  }
10035
10446
  const iterStr = iterCount === Infinity ? "infinite" : String(iterCount);
10036
- const cssAnimation = `${keyframe} ${duration}ms ease ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10447
+ const easing = cssEasingForAnimation(anim);
10448
+ const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10037
10449
  seqGroup.push({
10038
10450
  elementId,
10039
10451
  cssAnimation,
@@ -12169,7 +12581,7 @@ function rotateDelta(dx, dy, rotationDeg) {
12169
12581
  }
12170
12582
  function applyResize(box, handle, dxScreen, dyScreen, zoom, opts = {}) {
12171
12583
  const scale = zoom || 1;
12172
- const minSize = opts.minSize ?? chunk2V6BD4JQ_js.MIN_ELEMENT_SIZE;
12584
+ const minSize = opts.minSize ?? chunkIPYAN574_js.MIN_ELEMENT_SIZE;
12173
12585
  const rotation = rotationOf(box);
12174
12586
  const local = rotateDelta(dxScreen / scale, dyScreen / scale, rotation);
12175
12587
  const dx = local.x;
@@ -12196,7 +12608,7 @@ function applyResize(box, handle, dxScreen, dyScreen, zoom, opts = {}) {
12196
12608
  }
12197
12609
  return { x: newX, y: newY, width: newW, height: newH, rotation };
12198
12610
  }
12199
- function snapBoxToGrid(box, handle, gridSpacingPx, minSize = chunk2V6BD4JQ_js.MIN_ELEMENT_SIZE) {
12611
+ function snapBoxToGrid(box, handle, gridSpacingPx, minSize = chunkIPYAN574_js.MIN_ELEMENT_SIZE) {
12200
12612
  if (handle === null || gridSpacingPx <= 0) {
12201
12613
  return box;
12202
12614
  }
@@ -12226,7 +12638,7 @@ function snapBoxToGrid(box, handle, gridSpacingPx, minSize = chunk2V6BD4JQ_js.MI
12226
12638
  }
12227
12639
  return { x, y, width, height };
12228
12640
  }
12229
- function computeMarqueeHitIds(marquee, elements, minSize = chunk2V6BD4JQ_js.MIN_ELEMENT_SIZE) {
12641
+ function computeMarqueeHitIds(marquee, elements, minSize = chunkIPYAN574_js.MIN_ELEMENT_SIZE) {
12230
12642
  const minX = Math.min(marquee.startX, marquee.currentX);
12231
12643
  const minY = Math.min(marquee.startY, marquee.currentY);
12232
12644
  const maxX = Math.max(marquee.startX, marquee.currentX);
@@ -13781,7 +14193,7 @@ var THEME_COLOR_LABELS = {
13781
14193
  };
13782
14194
  function buildThemeColorGrid(colorScheme) {
13783
14195
  return THEME_COLOR_TINT_ROWS.map(
13784
- (row) => chunk2V6BD4JQ_js.THEME_COLOR_SCHEME_KEYS.map((key) => ({
14196
+ (row) => chunkIPYAN574_js.THEME_COLOR_SCHEME_KEYS.map((key) => ({
13785
14197
  hex: row.transform(colorScheme[key]),
13786
14198
  schemeKey: key,
13787
14199
  rowLabel: row.label,
@@ -14109,6 +14521,23 @@ function getConnectionSites(width, height) {
14109
14521
  // left center
14110
14522
  ];
14111
14523
  }
14524
+ function getShapeConnectionSites(shape) {
14525
+ const geo = shape;
14526
+ const cxn = geo.customGeometryConnectionSites;
14527
+ if (!cxn || cxn.length === 0) {
14528
+ return getConnectionSites(shape.width, shape.height);
14529
+ }
14530
+ const pathW = geo.pathWidth && geo.pathWidth > 0 ? geo.pathWidth : shape.width;
14531
+ const pathH = geo.pathHeight && geo.pathHeight > 0 ? geo.pathHeight : shape.height;
14532
+ const vars = chunkIPYAN574_js.createBuiltinVariables({ w: pathW, h: pathH });
14533
+ const scaleX = pathW > 0 ? shape.width / pathW : 1;
14534
+ const scaleY = pathH > 0 ? shape.height / pathH : 1;
14535
+ return cxn.map((site, index) => ({
14536
+ x: chunkIPYAN574_js.resolveCoordinate(site.posX, vars) * scaleX,
14537
+ y: chunkIPYAN574_js.resolveCoordinate(site.posY, vars) * scaleY,
14538
+ index
14539
+ }));
14540
+ }
14112
14541
  function rerouteConnectorsForMovedElements(elements, movedElementIds) {
14113
14542
  if (movedElementIds.size === 0) {
14114
14543
  return [];
@@ -14152,7 +14581,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14152
14581
  if (!startShape) {
14153
14582
  return null;
14154
14583
  }
14155
- const sites = getConnectionSites(startShape.width, startShape.height);
14584
+ const sites = getShapeConnectionSites(startShape);
14156
14585
  const siteIndex = startConn.connectionSiteIndex ?? 0;
14157
14586
  const site = sites[siteIndex] ?? sites[0];
14158
14587
  sx = startShape.x + site.x;
@@ -14168,7 +14597,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14168
14597
  if (!endShape) {
14169
14598
  return null;
14170
14599
  }
14171
- const sites = getConnectionSites(endShape.width, endShape.height);
14600
+ const sites = getShapeConnectionSites(endShape);
14172
14601
  const siteIndex = endConn.connectionSiteIndex ?? 0;
14173
14602
  const site = sites[siteIndex] ?? sites[0];
14174
14603
  ex = endShape.x + site.x;
@@ -14177,12 +14606,16 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14177
14606
  ex = connector.x + connector.width;
14178
14607
  ey = connector.y + connector.height;
14179
14608
  }
14609
+ const flipHorizontal = ex < sx;
14610
+ const flipVertical = ey < sy;
14180
14611
  return {
14181
14612
  id: connector.id,
14182
14613
  x: Math.min(sx, ex),
14183
14614
  y: Math.min(sy, ey),
14184
14615
  width: Math.abs(ex - sx) || 1,
14185
- height: Math.abs(ey - sy) || 1
14616
+ height: Math.abs(ey - sy) || 1,
14617
+ flipHorizontal,
14618
+ flipVertical
14186
14619
  };
14187
14620
  }
14188
14621
  function applyReroutedConnectors(elements, rerouted) {
@@ -14198,13 +14631,20 @@ function applyReroutedConnectors(elements, rerouted) {
14198
14631
  if (!update) {
14199
14632
  return el;
14200
14633
  }
14201
- return {
14634
+ const next = {
14202
14635
  ...el,
14203
14636
  x: update.x,
14204
14637
  y: update.y,
14205
14638
  width: update.width,
14206
14639
  height: update.height
14207
14640
  };
14641
+ if (update.flipHorizontal !== void 0) {
14642
+ next.flipHorizontal = update.flipHorizontal;
14643
+ }
14644
+ if (update.flipVertical !== void 0) {
14645
+ next.flipVertical = update.flipVertical;
14646
+ }
14647
+ return next;
14208
14648
  });
14209
14649
  }
14210
14650
  function getCompoundLineOffsets(compoundLine, strokeWidth) {
@@ -14257,7 +14697,7 @@ function svgLineCap(lineCap) {
14257
14697
  }
14258
14698
  function copyFormatFromElement(element) {
14259
14699
  const result = {};
14260
- if (chunk2V6BD4JQ_js.hasShapeProperties(element) && element.shapeStyle) {
14700
+ if (chunkIPYAN574_js.hasShapeProperties(element) && element.shapeStyle) {
14261
14701
  const s = element.shapeStyle;
14262
14702
  result.shapeStyle = {
14263
14703
  fillColor: s.fillColor,
@@ -14286,7 +14726,7 @@ function copyFormatFromElement(element) {
14286
14726
  softEdgeRadius: s.softEdgeRadius
14287
14727
  };
14288
14728
  }
14289
- if (chunk2V6BD4JQ_js.hasTextProperties(element) && element.textStyle) {
14729
+ if (chunkIPYAN574_js.hasTextProperties(element) && element.textStyle) {
14290
14730
  const t = element.textStyle;
14291
14731
  result.textStyle = {
14292
14732
  fontFamily: t.fontFamily,
@@ -14317,7 +14757,7 @@ function definedEntries(obj) {
14317
14757
  }
14318
14758
  function applyFormatToElement(element, format) {
14319
14759
  let updated = { ...element };
14320
- if (format.shapeStyle && chunk2V6BD4JQ_js.hasShapeProperties(updated)) {
14760
+ if (format.shapeStyle && chunkIPYAN574_js.hasShapeProperties(updated)) {
14321
14761
  updated = {
14322
14762
  ...updated,
14323
14763
  shapeStyle: {
@@ -14326,7 +14766,7 @@ function applyFormatToElement(element, format) {
14326
14766
  }
14327
14767
  };
14328
14768
  }
14329
- if (format.textStyle && chunk2V6BD4JQ_js.hasTextProperties(updated)) {
14769
+ if (format.textStyle && chunkIPYAN574_js.hasTextProperties(updated)) {
14330
14770
  updated = {
14331
14771
  ...updated,
14332
14772
  textStyle: {
@@ -14341,7 +14781,7 @@ function hasCopyableFormat(element) {
14341
14781
  if (!element) {
14342
14782
  return false;
14343
14783
  }
14344
- return chunk2V6BD4JQ_js.hasShapeProperties(element) || chunk2V6BD4JQ_js.hasTextProperties(element);
14784
+ return chunkIPYAN574_js.hasShapeProperties(element) || chunkIPYAN574_js.hasTextProperties(element);
14345
14785
  }
14346
14786
  function copySegmentMetadata(from, to) {
14347
14787
  if (from.equationXml !== void 0) {
@@ -14478,7 +14918,7 @@ function getRoundRectRadiusPx(element) {
14478
14918
  return Math.min(Math.max(element.width, 1), Math.max(element.height, 1)) * 0.5 * normalizedAdjustment;
14479
14919
  }
14480
14920
  function getShapeAdjustmentHandleDescriptor(element) {
14481
- if (!chunk2V6BD4JQ_js.hasShapeProperties(element)) {
14921
+ if (!chunkIPYAN574_js.hasShapeProperties(element)) {
14482
14922
  return null;
14483
14923
  }
14484
14924
  const normalizedShapeType = String(element.shapeType || "").toLowerCase();
@@ -15470,7 +15910,7 @@ function createSyncGate(onOpen, graceMs = INITIAL_SYNC_GRACE_MS) {
15470
15910
  var POSITION_THRESHOLD = 2;
15471
15911
  var SIZE_THRESHOLD = 2;
15472
15912
  function getElementText(element) {
15473
- if (!chunk2V6BD4JQ_js.hasTextProperties(element)) {
15913
+ if (!chunkIPYAN574_js.hasTextProperties(element)) {
15474
15914
  return "";
15475
15915
  }
15476
15916
  if (element.textSegments && element.textSegments.length > 0) {
@@ -15738,7 +16178,308 @@ var INSTANT = {
15738
16178
  };
15739
16179
  var DEFAULT_TRANSITION_DURATION_MS = 1e3;
15740
16180
  var EASE = "ease-in-out";
15741
- var SLIDE_TRANSITION_KEYFRAMES = `
16181
+ var P14_TRANSITION_KEYFRAMES = `
16182
+ /* \u2500\u2500 Conveyor (translate X with staggered timing) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16183
+ @keyframes pptx-tr-conveyor-in-from-right {
16184
+ from { transform: translateX(100%) rotateY(-30deg); }
16185
+ 60% { transform: translateX(20%) rotateY(-10deg); }
16186
+ to { transform: translateX(0) rotateY(0deg); }
16187
+ }
16188
+ @keyframes pptx-tr-conveyor-out-to-left {
16189
+ from { transform: translateX(0) rotateY(0deg); }
16190
+ 40% { transform: translateX(-20%) rotateY(10deg); }
16191
+ to { transform: translateX(-100%) rotateY(30deg); }
16192
+ }
16193
+ @keyframes pptx-tr-conveyor-in-from-left {
16194
+ from { transform: translateX(-100%) rotateY(30deg); }
16195
+ 60% { transform: translateX(-20%) rotateY(10deg); }
16196
+ to { transform: translateX(0) rotateY(0deg); }
16197
+ }
16198
+ @keyframes pptx-tr-conveyor-out-to-right {
16199
+ from { transform: translateX(0) rotateY(0deg); }
16200
+ 40% { transform: translateX(20%) rotateY(-10deg); }
16201
+ to { transform: translateX(100%) rotateY(-30deg); }
16202
+ }
16203
+
16204
+ /* \u2500\u2500 Doors (clip-path from center split) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16205
+ @keyframes pptx-tr-doors-horz {
16206
+ from { clip-path: inset(0 50%); }
16207
+ to { clip-path: inset(0 0); }
16208
+ }
16209
+ @keyframes pptx-tr-doors-vert {
16210
+ from { clip-path: inset(50% 0); }
16211
+ to { clip-path: inset(0 0); }
16212
+ }
16213
+
16214
+ /* \u2500\u2500 Ferris (rotate elements around center) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16215
+ @keyframes pptx-tr-ferris-in-from-right {
16216
+ from { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
16217
+ to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16218
+ }
16219
+ @keyframes pptx-tr-ferris-out-to-left {
16220
+ from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16221
+ to { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
16222
+ }
16223
+ @keyframes pptx-tr-ferris-in-from-left {
16224
+ from { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
16225
+ to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16226
+ }
16227
+ @keyframes pptx-tr-ferris-out-to-right {
16228
+ from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16229
+ to { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
16230
+ }
16231
+
16232
+ /* \u2500\u2500 Flash (bright flash opacity burst) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16233
+ @keyframes pptx-tr-flash-white {
16234
+ 0% { opacity: 1; }
16235
+ 30% { opacity: 0; }
16236
+ 50% { opacity: 0; }
16237
+ 100% { opacity: 1; }
16238
+ }
16239
+ @keyframes pptx-tr-flash-in {
16240
+ 0% { opacity: 0; }
16241
+ 50% { opacity: 0; }
16242
+ 70% { opacity: 1; }
16243
+ 100% { opacity: 1; }
16244
+ }
16245
+
16246
+ /* \u2500\u2500 Flythrough (scale + translate Z-axis feel) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16247
+ @keyframes pptx-tr-flythrough-in {
16248
+ from { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
16249
+ to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16250
+ }
16251
+ @keyframes pptx-tr-flythrough-out {
16252
+ from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16253
+ to { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
16254
+ }
16255
+ @keyframes pptx-tr-flythrough-reverse-in {
16256
+ from { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
16257
+ to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16258
+ }
16259
+ @keyframes pptx-tr-flythrough-reverse-out {
16260
+ from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16261
+ to { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
16262
+ }
16263
+
16264
+ /* \u2500\u2500 Gallery (translate with perspective) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16265
+ @keyframes pptx-tr-gallery-in-from-right {
16266
+ from { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
16267
+ to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16268
+ }
16269
+ @keyframes pptx-tr-gallery-out-to-left {
16270
+ from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16271
+ to { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
16272
+ }
16273
+ @keyframes pptx-tr-gallery-in-from-left {
16274
+ from { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
16275
+ to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16276
+ }
16277
+ @keyframes pptx-tr-gallery-out-to-right {
16278
+ from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16279
+ to { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
16280
+ }
16281
+
16282
+ /* \u2500\u2500 Glitter (particle dissolve effect) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16283
+ @keyframes pptx-tr-glitter-in {
16284
+ from { opacity: 0; filter: brightness(1.5) contrast(1.3) blur(2px); }
16285
+ 60% { opacity: 0.7; filter: brightness(1.2) contrast(1.1) blur(1px); }
16286
+ to { opacity: 1; filter: brightness(1) contrast(1) blur(0); }
16287
+ }
16288
+
16289
+ /* \u2500\u2500 Honeycomb (hexagonal reveal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16290
+ @keyframes pptx-tr-honeycomb-in {
16291
+ from {
16292
+ clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%);
16293
+ opacity: 0;
16294
+ }
16295
+ to {
16296
+ clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
16297
+ opacity: 1;
16298
+ }
16299
+ }
16300
+ @keyframes pptx-tr-honeycomb-out {
16301
+ from { opacity: 1; }
16302
+ to { opacity: 0; filter: blur(2px); }
16303
+ }
16304
+
16305
+ /* \u2500\u2500 Pan (large-scale translate) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16306
+ @keyframes pptx-tr-pan-from-right {
16307
+ from { transform: translateX(100%); }
16308
+ to { transform: translateX(0); }
16309
+ }
16310
+ @keyframes pptx-tr-pan-to-left {
16311
+ from { transform: translateX(0); }
16312
+ to { transform: translateX(-100%); }
16313
+ }
16314
+ @keyframes pptx-tr-pan-from-left {
16315
+ from { transform: translateX(-100%); }
16316
+ to { transform: translateX(0); }
16317
+ }
16318
+ @keyframes pptx-tr-pan-to-right {
16319
+ from { transform: translateX(0); }
16320
+ to { transform: translateX(100%); }
16321
+ }
16322
+ @keyframes pptx-tr-pan-from-bottom {
16323
+ from { transform: translateY(100%); }
16324
+ to { transform: translateY(0); }
16325
+ }
16326
+ @keyframes pptx-tr-pan-to-top {
16327
+ from { transform: translateY(0); }
16328
+ to { transform: translateY(-100%); }
16329
+ }
16330
+ @keyframes pptx-tr-pan-from-top {
16331
+ from { transform: translateY(-100%); }
16332
+ to { transform: translateY(0); }
16333
+ }
16334
+ @keyframes pptx-tr-pan-to-bottom {
16335
+ from { transform: translateY(0); }
16336
+ to { transform: translateY(100%); }
16337
+ }
16338
+ `;
16339
+ var P14_TRANSITION_KEYFRAMES_2 = `
16340
+ /* \u2500\u2500 Prism (3D rotation via perspective transform) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16341
+ @keyframes pptx-tr-prism-in-from-right {
16342
+ from { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
16343
+ to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16344
+ }
16345
+ @keyframes pptx-tr-prism-out-to-left {
16346
+ from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16347
+ to { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
16348
+ }
16349
+ @keyframes pptx-tr-prism-in-from-left {
16350
+ from { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
16351
+ to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16352
+ }
16353
+ @keyframes pptx-tr-prism-out-to-right {
16354
+ from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16355
+ to { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
16356
+ }
16357
+ @keyframes pptx-tr-prism-in-from-bottom {
16358
+ from { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
16359
+ to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16360
+ }
16361
+ @keyframes pptx-tr-prism-out-to-top {
16362
+ from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16363
+ to { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
16364
+ }
16365
+ @keyframes pptx-tr-prism-in-from-top {
16366
+ from { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
16367
+ to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16368
+ }
16369
+ @keyframes pptx-tr-prism-out-to-bottom {
16370
+ from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16371
+ to { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
16372
+ }
16373
+
16374
+ /* \u2500\u2500 Reveal (slide away reveal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16375
+ @keyframes pptx-tr-reveal-out-to-right {
16376
+ from { transform: translateX(0); }
16377
+ to { transform: translateX(100%); }
16378
+ }
16379
+ @keyframes pptx-tr-reveal-out-to-left {
16380
+ from { transform: translateX(0); }
16381
+ to { transform: translateX(-100%); }
16382
+ }
16383
+ @keyframes pptx-tr-reveal-in {
16384
+ from { opacity: 0.5; }
16385
+ to { opacity: 1; }
16386
+ }
16387
+
16388
+ /* \u2500\u2500 Ripple (expanding ring clip-path) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16389
+ @keyframes pptx-tr-ripple-in {
16390
+ from { clip-path: circle(0% at 50% 50%); opacity: 0.5; }
16391
+ 30% { clip-path: circle(20% at 50% 50%); opacity: 0.7; }
16392
+ 60% { clip-path: circle(50% at 50% 50%); opacity: 0.9; }
16393
+ to { clip-path: circle(75% at 50% 50%); opacity: 1; }
16394
+ }
16395
+
16396
+ /* \u2500\u2500 Shred (fragmented clip-path pieces) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16397
+ @keyframes pptx-tr-shred-strips-in {
16398
+ from { clip-path: inset(0 100% 0 0); opacity: 0; }
16399
+ 30% { clip-path: inset(0 60% 0 0); opacity: 0.5; }
16400
+ to { clip-path: inset(0); opacity: 1; }
16401
+ }
16402
+ @keyframes pptx-tr-shred-rectangles-in {
16403
+ from { clip-path: inset(50%); opacity: 0; }
16404
+ 40% { clip-path: inset(20%); opacity: 0.6; }
16405
+ to { clip-path: inset(0); opacity: 1; }
16406
+ }
16407
+ @keyframes pptx-tr-shred-out {
16408
+ from { opacity: 1; }
16409
+ to { opacity: 0; filter: blur(2px); }
16410
+ }
16411
+
16412
+ /* \u2500\u2500 Switch (flip/rotate swap) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16413
+ @keyframes pptx-tr-switch-in-from-right {
16414
+ from { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
16415
+ to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16416
+ }
16417
+ @keyframes pptx-tr-switch-out-to-left {
16418
+ from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16419
+ to { transform: perspective(800px) rotateY(180deg); opacity: 0; }
16420
+ }
16421
+ @keyframes pptx-tr-switch-in-from-left {
16422
+ from { transform: perspective(800px) rotateY(180deg); opacity: 0; }
16423
+ to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16424
+ }
16425
+ @keyframes pptx-tr-switch-out-to-right {
16426
+ from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16427
+ to { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
16428
+ }
16429
+
16430
+ /* \u2500\u2500 Vortex (rotate + scale spiral) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16431
+ @keyframes pptx-tr-vortex-in {
16432
+ from { transform: rotate(720deg) scale(0); opacity: 0; }
16433
+ to { transform: rotate(0deg) scale(1); opacity: 1; }
16434
+ }
16435
+ @keyframes pptx-tr-vortex-out {
16436
+ from { transform: rotate(0deg) scale(1); opacity: 1; }
16437
+ to { transform: rotate(-720deg) scale(0); opacity: 0; }
16438
+ }
16439
+
16440
+ /* \u2500\u2500 Warp (skew distortion) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16441
+ @keyframes pptx-tr-warp-in {
16442
+ from { transform: scale(0.3) skewX(30deg) skewY(15deg); opacity: 0; }
16443
+ 50% { transform: scale(0.8) skewX(-5deg) skewY(-3deg); opacity: 0.7; }
16444
+ to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
16445
+ }
16446
+ @keyframes pptx-tr-warp-out {
16447
+ from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
16448
+ 50% { transform: scale(0.8) skewX(5deg) skewY(3deg); opacity: 0.7; }
16449
+ to { transform: scale(0.3) skewX(-30deg) skewY(-15deg); opacity: 0; }
16450
+ }
16451
+ @keyframes pptx-tr-warp-reverse-in {
16452
+ from { transform: scale(3) skewX(-20deg) skewY(-10deg); opacity: 0; filter: blur(4px); }
16453
+ to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
16454
+ }
16455
+ @keyframes pptx-tr-warp-reverse-out {
16456
+ from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
16457
+ to { transform: scale(3) skewX(20deg) skewY(10deg); opacity: 0; filter: blur(4px); }
16458
+ }
16459
+
16460
+ /* \u2500\u2500 WheelReverse (reverse wheel rotation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16461
+ @keyframes pptx-tr-wheel-reverse-in {
16462
+ from { clip-path: circle(0% at 50% 50%); transform: rotate(180deg); }
16463
+ to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
16464
+ }
16465
+
16466
+ /* \u2500\u2500 Window (scale from center with border) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
16467
+ @keyframes pptx-tr-window-horz {
16468
+ from { clip-path: inset(0 50%); }
16469
+ to { clip-path: inset(0 0); }
16470
+ }
16471
+ @keyframes pptx-tr-window-vert {
16472
+ from { clip-path: inset(50% 0); }
16473
+ to { clip-path: inset(0 0); }
16474
+ }
16475
+ @keyframes pptx-tr-window-out {
16476
+ from { opacity: 1; transform: scale(1); }
16477
+ to { opacity: 0; transform: scale(0.9); }
16478
+ }
16479
+ `;
16480
+ var P14_TRANSITION_KEYFRAMES_ALL = `${P14_TRANSITION_KEYFRAMES}
16481
+ ${P14_TRANSITION_KEYFRAMES_2}`;
16482
+ var CORE_SLIDE_TRANSITION_KEYFRAMES = `
15742
16483
  /* \u2500\u2500 Fade \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
15743
16484
  @keyframes pptx-tr-fade-in {
15744
16485
  from { opacity: 0; }
@@ -16001,8 +16742,243 @@ var SLIDE_TRANSITION_KEYFRAMES = `
16001
16742
  to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
16002
16743
  }
16003
16744
  `;
16745
+ var SLIDE_TRANSITION_KEYFRAMES = `${CORE_SLIDE_TRANSITION_KEYFRAMES}
16746
+ ${P14_TRANSITION_KEYFRAMES_ALL}`;
16747
+ function resolveLR(direction) {
16748
+ if (direction === "l" || direction === "r") {
16749
+ return direction;
16750
+ }
16751
+ return "l";
16752
+ }
16753
+ function resolveP14Orientation(direction, orient) {
16754
+ if (orient === "horz" || orient === "vert") {
16755
+ return orient;
16756
+ }
16757
+ if (direction === "horz" || direction === "vert") {
16758
+ return direction;
16759
+ }
16760
+ return "horz";
16761
+ }
16762
+ function resolveCardinal(direction) {
16763
+ switch (direction) {
16764
+ case "l":
16765
+ return "left";
16766
+ case "r":
16767
+ return "right";
16768
+ case "u":
16769
+ return "up";
16770
+ case "d":
16771
+ return "down";
16772
+ default:
16773
+ return "left";
16774
+ }
16775
+ }
16776
+ function directionalPair(direction, prefix, dur, ease) {
16777
+ const dir = resolveCardinal(direction);
16778
+ const opposites = {
16779
+ left: ["to-left", "from-right"],
16780
+ right: ["to-right", "from-left"],
16781
+ up: ["to-top", "from-bottom"],
16782
+ down: ["to-bottom", "from-top"]
16783
+ };
16784
+ const [outSuffix, inSuffix] = opposites[dir];
16785
+ return {
16786
+ outgoing: `${prefix}-${outSuffix} ${dur} ${ease} forwards`,
16787
+ incoming: `${prefix}-${inSuffix} ${dur} ${ease} forwards`,
16788
+ outgoingOnTop: false
16789
+ };
16790
+ }
16791
+ function cardinalOutInPair(direction, prefix, dur, ease) {
16792
+ const dir = resolveCardinal(direction);
16793
+ const map = {
16794
+ left: ["out-to-left", "in-from-right"],
16795
+ right: ["out-to-right", "in-from-left"],
16796
+ up: ["out-to-top", "in-from-bottom"],
16797
+ down: ["out-to-bottom", "in-from-top"]
16798
+ };
16799
+ const [outSuffix, inSuffix] = map[dir];
16800
+ return {
16801
+ outgoing: `${prefix}-${outSuffix} ${dur} ${ease} forwards`,
16802
+ incoming: `${prefix}-${inSuffix} ${dur} ${ease} forwards`,
16803
+ outgoingOnTop: false
16804
+ };
16805
+ }
16806
+ function getP14TransitionAnimations(type, durationMs, direction, orient) {
16807
+ const dur = `${durationMs}ms`;
16808
+ const ease = EASE;
16809
+ switch (type) {
16810
+ case "conveyor": {
16811
+ const lr = resolveLR(direction);
16812
+ if (lr === "l") {
16813
+ return {
16814
+ outgoing: `pptx-tr-conveyor-out-to-left ${dur} ${ease} forwards`,
16815
+ incoming: `pptx-tr-conveyor-in-from-right ${dur} ${ease} forwards`,
16816
+ outgoingOnTop: false
16817
+ };
16818
+ }
16819
+ return {
16820
+ outgoing: `pptx-tr-conveyor-out-to-right ${dur} ${ease} forwards`,
16821
+ incoming: `pptx-tr-conveyor-in-from-left ${dur} ${ease} forwards`,
16822
+ outgoingOnTop: false
16823
+ };
16824
+ }
16825
+ case "doors": {
16826
+ const o = resolveP14Orientation(direction, orient);
16827
+ return {
16828
+ outgoing: "none",
16829
+ incoming: o === "vert" ? `pptx-tr-doors-vert ${dur} ${ease} forwards` : `pptx-tr-doors-horz ${dur} ${ease} forwards`,
16830
+ outgoingOnTop: false
16831
+ };
16832
+ }
16833
+ case "ferris": {
16834
+ const lr = resolveLR(direction);
16835
+ if (lr === "l") {
16836
+ return {
16837
+ outgoing: `pptx-tr-ferris-out-to-left ${dur} ${ease} forwards`,
16838
+ incoming: `pptx-tr-ferris-in-from-right ${dur} ${ease} forwards`,
16839
+ outgoingOnTop: false
16840
+ };
16841
+ }
16842
+ return {
16843
+ outgoing: `pptx-tr-ferris-out-to-right ${dur} ${ease} forwards`,
16844
+ incoming: `pptx-tr-ferris-in-from-left ${dur} ${ease} forwards`,
16845
+ outgoingOnTop: false
16846
+ };
16847
+ }
16848
+ case "flash":
16849
+ return {
16850
+ outgoing: `pptx-tr-flash-white ${dur} ${ease} forwards`,
16851
+ incoming: `pptx-tr-flash-in ${dur} ${ease} forwards`,
16852
+ outgoingOnTop: true
16853
+ };
16854
+ case "flythrough": {
16855
+ const isOut = direction === "out";
16856
+ if (isOut) {
16857
+ return {
16858
+ outgoing: `pptx-tr-flythrough-reverse-out ${dur} ${ease} forwards`,
16859
+ incoming: `pptx-tr-flythrough-reverse-in ${dur} ${ease} forwards`,
16860
+ outgoingOnTop: true
16861
+ };
16862
+ }
16863
+ return {
16864
+ outgoing: `pptx-tr-flythrough-out ${dur} ${ease} forwards`,
16865
+ incoming: `pptx-tr-flythrough-in ${dur} ${ease} forwards`,
16866
+ outgoingOnTop: true
16867
+ };
16868
+ }
16869
+ case "gallery": {
16870
+ const lr = resolveLR(direction);
16871
+ if (lr === "l") {
16872
+ return {
16873
+ outgoing: `pptx-tr-gallery-out-to-left ${dur} ${ease} forwards`,
16874
+ incoming: `pptx-tr-gallery-in-from-right ${dur} ${ease} forwards`,
16875
+ outgoingOnTop: false
16876
+ };
16877
+ }
16878
+ return {
16879
+ outgoing: `pptx-tr-gallery-out-to-right ${dur} ${ease} forwards`,
16880
+ incoming: `pptx-tr-gallery-in-from-left ${dur} ${ease} forwards`,
16881
+ outgoingOnTop: false
16882
+ };
16883
+ }
16884
+ case "glitter":
16885
+ return {
16886
+ outgoing: `pptx-tr-fade-out ${dur} ${ease} forwards`,
16887
+ incoming: `pptx-tr-glitter-in ${dur} ${ease} forwards`,
16888
+ outgoingOnTop: true
16889
+ };
16890
+ case "honeycomb":
16891
+ return {
16892
+ outgoing: `pptx-tr-honeycomb-out ${dur} ${ease} forwards`,
16893
+ incoming: `pptx-tr-honeycomb-in ${dur} ${ease} forwards`,
16894
+ outgoingOnTop: true
16895
+ };
16896
+ case "pan":
16897
+ return directionalPair(direction, "pptx-tr-pan", dur, ease);
16898
+ case "prism":
16899
+ return cardinalOutInPair(direction, "pptx-tr-prism", dur, ease);
16900
+ case "reveal": {
16901
+ const lr = resolveLR(direction);
16902
+ return {
16903
+ outgoing: lr === "l" ? `pptx-tr-reveal-out-to-left ${dur} ${ease} forwards` : `pptx-tr-reveal-out-to-right ${dur} ${ease} forwards`,
16904
+ incoming: `pptx-tr-reveal-in ${dur} ${ease} forwards`,
16905
+ outgoingOnTop: true
16906
+ };
16907
+ }
16908
+ case "ripple":
16909
+ return {
16910
+ outgoing: "none",
16911
+ incoming: `pptx-tr-ripple-in ${dur} ${ease} forwards`,
16912
+ outgoingOnTop: false
16913
+ };
16914
+ case "shred": {
16915
+ const pattern = direction === "rectangles" ? "rectangles" : "strips";
16916
+ return {
16917
+ outgoing: `pptx-tr-shred-out ${dur} ${ease} forwards`,
16918
+ incoming: pattern === "rectangles" ? `pptx-tr-shred-rectangles-in ${dur} ${ease} forwards` : `pptx-tr-shred-strips-in ${dur} ${ease} forwards`,
16919
+ outgoingOnTop: true
16920
+ };
16921
+ }
16922
+ case "switch": {
16923
+ const lr = resolveLR(direction);
16924
+ if (lr === "l") {
16925
+ return {
16926
+ outgoing: `pptx-tr-switch-out-to-left ${dur} ${ease} forwards`,
16927
+ incoming: `pptx-tr-switch-in-from-right ${dur} ${ease} forwards`,
16928
+ outgoingOnTop: false
16929
+ };
16930
+ }
16931
+ return {
16932
+ outgoing: `pptx-tr-switch-out-to-right ${dur} ${ease} forwards`,
16933
+ incoming: `pptx-tr-switch-in-from-left ${dur} ${ease} forwards`,
16934
+ outgoingOnTop: false
16935
+ };
16936
+ }
16937
+ case "vortex":
16938
+ return {
16939
+ outgoing: `pptx-tr-vortex-out ${dur} ${ease} forwards`,
16940
+ incoming: `pptx-tr-vortex-in ${dur} ${ease} forwards`,
16941
+ outgoingOnTop: true
16942
+ };
16943
+ case "warp": {
16944
+ const isOut = direction === "out";
16945
+ if (isOut) {
16946
+ return {
16947
+ outgoing: `pptx-tr-warp-reverse-out ${dur} ${ease} forwards`,
16948
+ incoming: `pptx-tr-warp-reverse-in ${dur} ${ease} forwards`,
16949
+ outgoingOnTop: true
16950
+ };
16951
+ }
16952
+ return {
16953
+ outgoing: `pptx-tr-warp-out ${dur} ${ease} forwards`,
16954
+ incoming: `pptx-tr-warp-in ${dur} ${ease} forwards`,
16955
+ outgoingOnTop: true
16956
+ };
16957
+ }
16958
+ case "wheelReverse":
16959
+ return {
16960
+ outgoing: "none",
16961
+ incoming: `pptx-tr-wheel-reverse-in ${dur} ${ease} forwards`,
16962
+ outgoingOnTop: false
16963
+ };
16964
+ case "window": {
16965
+ const o = resolveP14Orientation(direction, orient);
16966
+ return {
16967
+ outgoing: `pptx-tr-window-out ${dur} ${ease} forwards`,
16968
+ incoming: o === "vert" ? `pptx-tr-window-vert ${dur} ${ease} forwards` : `pptx-tr-window-horz ${dur} ${ease} forwards`,
16969
+ outgoingOnTop: true
16970
+ };
16971
+ }
16972
+ default:
16973
+ return void 0;
16974
+ }
16975
+ }
16004
16976
  function getSlideTransitionAnimations(type, durationMs, direction, orient, spokes) {
16005
16977
  const dur = `${durationMs}ms`;
16978
+ const p14 = getP14TransitionAnimations(type, durationMs, direction, orient);
16979
+ if (p14) {
16980
+ return p14;
16981
+ }
16006
16982
  switch (type) {
16007
16983
  case "none":
16008
16984
  case "cut":
@@ -16204,31 +17180,13 @@ function getSlideTransitionAnimations(type, durationMs, direction, orient, spoke
16204
17180
  const randomType = RANDOM_ELIGIBLE_TYPES[Math.floor(Math.random() * RANDOM_ELIGIBLE_TYPES.length)];
16205
17181
  return getSlideTransitionAnimations(randomType, durationMs, direction, orient);
16206
17182
  }
16207
- // ── Exotic / 3-D transitions approximated with the closest well-tested
16208
- // 2-D CSS behaviour (delegates to an existing case rather than emitting a
16209
- // plain fade). A faithful per-effect keyframe set is available via
16210
- // `getP14TransitionAnimations`.
16211
- case "pan":
16212
- case "gallery":
16213
- case "conveyor":
16214
- return getSlideTransitionAnimations("push", durationMs, direction, orient);
16215
- case "reveal":
16216
- return getSlideTransitionAnimations("wipe", durationMs, direction, orient);
16217
- case "doors":
16218
- return getSlideTransitionAnimations("split", durationMs, direction, orient);
16219
- case "switch":
16220
- case "flythrough":
16221
- case "ferris":
16222
- case "prism":
16223
- return getSlideTransitionAnimations("zoom", durationMs, direction, orient);
16224
- case "ripple":
16225
- case "honeycomb":
16226
- case "glitter":
16227
- case "shred":
16228
- return getSlideTransitionAnimations("dissolve", durationMs, direction, orient);
16229
- case "flash":
16230
- return getSlideTransitionAnimations("fade", durationMs, direction, orient);
16231
- // Fallback (unknown / not-yet-mapped type) — symmetrical cross-fade.
17183
+ // The exotic / 3-D transition family (conveyor/doors/ferris/flash/
17184
+ // flythrough/gallery/glitter/honeycomb/pan/prism/reveal/ripple/shred/
17185
+ // switch/vortex/warp/wheelReverse/window) is handled faithfully above via
17186
+ // `getP14TransitionAnimations` and never reaches this switch.
17187
+ // Fallback (unknown / not-yet-mapped type, e.g. the p15 cinematic set:
17188
+ // cube/flip/rotate/orbit/fracture/peelOff/pageCurl*/airplane/origami)
17189
+ // — symmetrical cross-fade.
16232
17190
  default:
16233
17191
  return {
16234
17192
  outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
@@ -16953,30 +17911,46 @@ function computeTargetLayout(nodes, box, palette, style, elementId) {
16953
17911
  family: "target"
16954
17912
  };
16955
17913
  }
16956
- function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout) {
17914
+ function interpolateSmartArtPalette(palette, count, method, hueDirection) {
17915
+ if (count <= 0 || palette.length === 0) {
17916
+ return [];
17917
+ }
17918
+ if (palette.length < 2 || count <= palette.length) {
17919
+ return Array.from({ length: count }, (_, i) => palette[i % palette.length]);
17920
+ }
17921
+ const segments = palette.length - 1;
17922
+ return Array.from({ length: count }, (_, i) => {
17923
+ const pos = i / (count - 1) * segments;
17924
+ const lower = Math.min(Math.floor(pos), segments - 1);
17925
+ const frac = pos - lower;
17926
+ return interpolateColor(palette[lower], palette[lower + 1], frac, "hsl", hueDirection);
17927
+ });
17928
+ }
17929
+ function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout, interpolation) {
16957
17930
  const flat = flattenNodes(nodes);
16958
17931
  const family = resolveLayoutFamily(nodes, resolvedLayoutType, layout);
17932
+ const pal = interpolation?.method === "span" ? interpolateSmartArtPalette(palette, flat.length, "span", interpolation.hueDirection) : palette;
16959
17933
  switch (family) {
16960
17934
  case "list":
16961
- return computeListLayout(flat, box, palette, style, elementId);
17935
+ return computeListLayout(flat, box, pal, style, elementId);
16962
17936
  case "process":
16963
- return computeProcessLayout(flat, box, palette, style, elementId);
17937
+ return computeProcessLayout(flat, box, pal, style, elementId);
16964
17938
  case "cycle":
16965
- return computeCycleLayout(flat, box, palette, style, elementId);
17939
+ return computeCycleLayout(flat, box, pal, style, elementId);
16966
17940
  case "hierarchy":
16967
- return computeHierarchyLayout(nodes, box, palette, style, elementId);
17941
+ return computeHierarchyLayout(nodes, box, pal, style, elementId);
16968
17942
  case "matrix":
16969
- return computeMatrixLayout(flat, box, palette, style, elementId);
17943
+ return computeMatrixLayout(flat, box, pal, style, elementId);
16970
17944
  case "radial":
16971
- return computeRadialLayout(flat, box, palette, style, elementId);
17945
+ return computeRadialLayout(flat, box, pal, style, elementId);
16972
17946
  case "pyramid":
16973
- return computePyramidLayout(flat, box, palette, style, elementId);
17947
+ return computePyramidLayout(flat, box, pal, style, elementId);
16974
17948
  case "venn":
16975
- return computeVennLayout(flat, box, palette, style, elementId);
17949
+ return computeVennLayout(flat, box, pal, style, elementId);
16976
17950
  case "funnel":
16977
- return computeFunnelLayout(flat, box, palette, style, elementId);
17951
+ return computeFunnelLayout(flat, box, pal, style, elementId);
16978
17952
  case "target":
16979
- return computeTargetLayout(flat, box, palette, style, elementId);
17953
+ return computeTargetLayout(flat, box, pal, style, elementId);
16980
17954
  }
16981
17955
  }
16982
17956
  function parseViewBox(viewBox) {
@@ -19044,7 +20018,7 @@ function getAriaRole(element) {
19044
20018
  case "model3d":
19045
20019
  return "img";
19046
20020
  case "shape": {
19047
- if (chunk2V6BD4JQ_js.hasTextProperties(element) && element.text) {
20021
+ if (chunkIPYAN574_js.hasTextProperties(element) && element.text) {
19048
20022
  return "group";
19049
20023
  }
19050
20024
  return "img";
@@ -19057,7 +20031,7 @@ function getAriaLabel(element) {
19057
20031
  if ((element.type === "image" || element.type === "picture") && "altText" in element && typeof element.altText === "string" && element.altText.trim()) {
19058
20032
  return element.altText.trim();
19059
20033
  }
19060
- if (chunk2V6BD4JQ_js.hasTextProperties(element) && element.text) {
20034
+ if (chunkIPYAN574_js.hasTextProperties(element) && element.text) {
19061
20035
  const text = element.text.trim();
19062
20036
  if (text) {
19063
20037
  return text.length > 120 ? `${text.slice(0, 117)}...` : text;
@@ -19464,7 +20438,7 @@ var DEFAULT_CHART_POSITION = { x: 120, y: 120, width: 480, height: 320 };
19464
20438
  var DEFAULT_CATEGORIES = ["Category 1", "Category 2", "Category 3"];
19465
20439
  var DEFAULT_SERIES_VALUES = [4, 3, 5];
19466
20440
  function createDefaultChartElement(chartType = DEFAULT_INSERT_CHART_TYPE, position) {
19467
- return chunk2V6BD4JQ_js.createChartElement(
20441
+ return chunkIPYAN574_js.createChartElement(
19468
20442
  chartType,
19469
20443
  {
19470
20444
  categories: [...DEFAULT_CATEGORIES],
@@ -20484,7 +21458,7 @@ function computeVirtualRange(totalItems, itemHeight, scrollTop, viewportHeight,
20484
21458
  };
20485
21459
  }
20486
21460
  function collectFontsFromElement(element, fonts) {
20487
- if (chunk2V6BD4JQ_js.hasTextProperties(element)) {
21461
+ if (chunkIPYAN574_js.hasTextProperties(element)) {
20488
21462
  if (element.textStyle?.fontFamily) {
20489
21463
  fonts.add(element.textStyle.fontFamily);
20490
21464
  }