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,4 +1,4 @@
1
- import { MIN_ELEMENT_SIZE, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hasShapeProperties, hasTextProperties, createChartElement, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, hslToRgb, PRESET_COLOR_MAP, isImageLikeElement, stripXmlOrderSuffix, orderedXmlKey, applyDrawingColorTransforms } from './chunk-DAI4KM5W.mjs';
1
+ import { MIN_ELEMENT_SIZE, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hasShapeProperties, hasTextProperties, createChartElement, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, hslToRgb, PRESET_COLOR_MAP, isImageLikeElement, stripXmlOrderSuffix, orderedXmlKey, createBuiltinVariables, resolveCoordinate, applyDrawingColorTransforms } from './chunk-FOMF7POV.mjs';
2
2
  import DOMPurify from 'dompurify';
3
3
 
4
4
  var defaultThemeColors = {
@@ -556,7 +556,27 @@ function buildReflectedGradientStops(stops) {
556
556
  }));
557
557
  return [...forward, ...reversed];
558
558
  }
559
- function buildGradientCss(gradient) {
559
+ function normalizeDegrees(deg) {
560
+ return (deg % 360 + 360) % 360;
561
+ }
562
+ function adjustLinearGradientAngle(angle, gradient, context) {
563
+ if (!context) {
564
+ return angle;
565
+ }
566
+ let result = angle;
567
+ const { width, height, rotation } = context;
568
+ if (gradient.fillGradientScaled !== false && typeof width === "number" && typeof height === "number" && width > 0 && height > 0 && width !== height) {
569
+ const rad = result * Math.PI / 180;
570
+ result = normalizeDegrees(
571
+ Math.atan2(height * Math.sin(rad), width * Math.cos(rad)) * 180 / Math.PI
572
+ );
573
+ }
574
+ if (gradient.fillGradientRotWithShape === false && typeof rotation === "number") {
575
+ result = normalizeDegrees(result - rotation);
576
+ }
577
+ return result;
578
+ }
579
+ function buildGradientCss(gradient, context) {
560
580
  if (!gradient || gradient.fillMode !== "gradient") {
561
581
  return void 0;
562
582
  }
@@ -578,9 +598,10 @@ function buildGradientCss(gradient) {
578
598
  return buildCirclePathGradient(stops, fp, ftr);
579
599
  }
580
600
  const normalizedAngle = typeof gradient.fillGradientAngle === "number" && Number.isFinite(gradient.fillGradientAngle) ? gradient.fillGradientAngle : 90;
601
+ const effectiveAngle = adjustLinearGradientAngle(normalizedAngle, gradient, context);
581
602
  const flip = gradient.fillGradientFlip;
582
603
  const linearStops = flip && flip !== "none" ? buildReflectedGradientStops(stops) : stops;
583
- return `linear-gradient(${Math.round(normalizedAngle)}deg, ${linearStops.map(toCssGradientStop).join(", ")})`;
604
+ return `linear-gradient(${Math.round(effectiveAngle)}deg, ${linearStops.map(toCssGradientStop).join(", ")})`;
584
605
  }
585
606
  var buildCssGradientFromShapeStyle = buildGradientCss;
586
607
  function getPatternSvg(preset, fg, bg) {
@@ -4163,6 +4184,20 @@ function splitSeriesByAxis(series, axes) {
4163
4184
  }
4164
4185
  return { primary, secondary };
4165
4186
  }
4187
+ function findDataPoint(series, pointIndex) {
4188
+ return series.dataPoints?.find((p) => p.idx === pointIndex);
4189
+ }
4190
+ function resolveDataPointFill(series, pointIndex, fallbackColor) {
4191
+ const point = findDataPoint(series, pointIndex);
4192
+ return point?.spPr?.fillColor ?? series.color ?? fallbackColor;
4193
+ }
4194
+ function resolveVaryColorFill(series, pointIndex, paletteColor3) {
4195
+ return findDataPoint(series, pointIndex)?.spPr?.fillColor ?? paletteColor3;
4196
+ }
4197
+ function resolveDataPointExplosion(series, pointIndex) {
4198
+ const point = findDataPoint(series, pointIndex);
4199
+ return point?.explosion ?? series.explosion ?? 0;
4200
+ }
4166
4201
  function clamp3(value, min, max) {
4167
4202
  return Math.min(Math.max(value, min), max);
4168
4203
  }
@@ -4535,34 +4570,59 @@ function categoryTotals(series, catCount) {
4535
4570
  (_, ci) => series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0)
4536
4571
  );
4537
4572
  }
4573
+ function blendToWhite(color) {
4574
+ const match = /^#?([0-9a-f]{6})$/iu.exec(color.trim());
4575
+ if (!match) {
4576
+ return color;
4577
+ }
4578
+ const value = Number.parseInt(match[1], 16);
4579
+ const mix = (channel) => Math.round(channel + (255 - channel) * 0.5);
4580
+ const r = mix(value >> 16 & 255);
4581
+ const g = mix(value >> 8 & 255);
4582
+ const b = mix(value & 255);
4583
+ return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0").toUpperCase()}`;
4584
+ }
4585
+ function invertNegativeFill(series, pointIndex, value, baseFill) {
4586
+ if (value >= 0) {
4587
+ return baseFill;
4588
+ }
4589
+ const point = series.dataPoints?.find((p) => p.idx === pointIndex);
4590
+ const invert = point?.invertIfNegative ?? series.invertIfNegative ?? false;
4591
+ return invert ? blendToWhite(baseFill) : baseFill;
4592
+ }
4538
4593
  function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, grouping, sourceIndices2) {
4539
4594
  const primitives = [];
4540
4595
  const dataLabels = [];
4541
4596
  const series = chartData.series;
4542
4597
  const palette = chartData.colorPalette;
4543
4598
  const showLabels = chartData.style?.hasDataLabels;
4599
+ const varyColorsSingle = chartData.varyColors === true && series.length === 1;
4544
4600
  if (grouping === "clustered") {
4545
4601
  const seriesCount = Math.max(series.length, 1);
4546
4602
  const barGroupWidth2 = layout.plotWidth / Math.max(catCount, 1);
4547
- const singleBarWidth = barGroupWidth2 * 0.7 / seriesCount;
4548
- const groupOffset = (barGroupWidth2 - singleBarWidth * seriesCount) / 2;
4603
+ const singleBarWidth = chartData.barGapWidth !== void 0 ? barGroupWidth2 / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100) : barGroupWidth2 * 0.7 / seriesCount;
4604
+ const overlap = chartData.barOverlap ?? 0;
4605
+ const step = singleBarWidth * (1 - overlap / 100);
4606
+ const clusterWidth = singleBarWidth + step * (seriesCount - 1);
4607
+ const groupOffset = (barGroupWidth2 - clusterWidth) / 2;
4549
4608
  for (let displayIndex = 0; displayIndex < catCount; displayIndex++) {
4550
4609
  const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
4551
4610
  for (let si = 0; si < series.length; si++) {
4552
4611
  const val2 = series[si].values[sourceIndex] ?? 0;
4553
- const x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + singleBarWidth * si;
4612
+ const x = layout.plotLeft + barGroupWidth2 * displayIndex + groupOffset + step * si;
4554
4613
  const activeRange = secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange;
4555
4614
  const zeroY = valueToY2(0, activeRange, layout.plotTop, layout.plotBottom);
4556
4615
  const valY = valueToY2(val2, activeRange, layout.plotTop, layout.plotBottom);
4557
4616
  const y = Math.min(zeroY, valY);
4558
4617
  const h = Math.max(Math.abs(zeroY - valY), 1);
4618
+ const baseFill = varyColorsSingle ? resolveVaryColorFill(series[si], sourceIndex, paletteColor2(sourceIndex, palette)) : resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4559
4619
  primitives.push({
4560
4620
  kind: "rect",
4561
4621
  x,
4562
4622
  y,
4563
4623
  w: singleBarWidth,
4564
4624
  h,
4565
- fill: seriesColor2(series[si], si, palette),
4625
+ fill: invertNegativeFill(series[si], sourceIndex, val2, baseFill),
4566
4626
  rx: 1,
4567
4627
  part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4568
4628
  });
@@ -4588,20 +4648,16 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4588
4648
  }));
4589
4649
  const rects = computeStackedBarRects(displaySeries2, catCount, layout, primaryRange, palette);
4590
4650
  for (const r of rects) {
4591
- primitives.push({
4592
- kind: "rect",
4593
- x: r.x,
4594
- y: r.y,
4595
- w: r.w,
4596
- h: r.h,
4597
- fill: r.fill,
4598
- rx: 1,
4599
- part: r.seriesIndex !== void 0 && r.pointIndex !== void 0 ? {
4600
- role: "dataPoint",
4601
- seriesIndex: r.seriesIndex,
4602
- pointIndex: sourceIndices2[r.pointIndex] ?? r.pointIndex
4603
- } : void 0
4604
- });
4651
+ let fill = r.fill;
4652
+ let part;
4653
+ if (r.seriesIndex !== void 0 && r.pointIndex !== void 0) {
4654
+ const sourcePointIndex = sourceIndices2[r.pointIndex] ?? r.pointIndex;
4655
+ fill = resolveDataPointFill(series[r.seriesIndex], sourcePointIndex, r.fill) ?? r.fill;
4656
+ const value = series[r.seriesIndex].values[sourcePointIndex] ?? 0;
4657
+ fill = invertNegativeFill(series[r.seriesIndex], sourcePointIndex, value, fill);
4658
+ part = { role: "dataPoint", seriesIndex: r.seriesIndex, pointIndex: sourcePointIndex };
4659
+ }
4660
+ primitives.push({ kind: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill, rx: 1, part });
4605
4661
  }
4606
4662
  if (showLabels) {
4607
4663
  pushClusteredStackedLabels(series, sourceIndices2, catCount, layout, primaryRange, dataLabels);
@@ -4632,13 +4688,14 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
4632
4688
  const topY = valueToY2(top, primaryRange, layout.plotTop, layout.plotBottom);
4633
4689
  const y = Math.min(baseY, topY);
4634
4690
  const h = Math.max(Math.abs(baseY - topY), 0.5);
4691
+ const pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor2(si, palette)) ?? seriesColor2(series[si], si, palette);
4635
4692
  primitives.push({
4636
4693
  kind: "rect",
4637
4694
  x,
4638
4695
  y,
4639
4696
  w: barW,
4640
4697
  h,
4641
- fill: seriesColor2(series[si], si, palette),
4698
+ fill: invertNegativeFill(series[si], sourceIndex, rawVal, pctBaseFill),
4642
4699
  part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4643
4700
  });
4644
4701
  if (showLabels && Math.abs(val2) > 0) {
@@ -4687,6 +4744,139 @@ function pushClusteredStackedLabels(series, sourceIndices2, catCount, layout, ra
4687
4744
  }
4688
4745
  }
4689
4746
  }
4747
+ function smoothLinePath(points) {
4748
+ if (points.length === 0) {
4749
+ return "";
4750
+ }
4751
+ if (points.length === 1) {
4752
+ return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
4753
+ }
4754
+ if (points.length === 2) {
4755
+ return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)} L${points[1].x.toFixed(2)},${points[1].y.toFixed(2)}`;
4756
+ }
4757
+ let d = `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
4758
+ for (let i = 0; i < points.length - 1; i++) {
4759
+ const p0 = points[i - 1] ?? points[i];
4760
+ const p1 = points[i];
4761
+ const p2 = points[i + 1];
4762
+ const p3 = points[i + 2] ?? p2;
4763
+ const cp1x = p1.x + (p2.x - p0.x) / 6;
4764
+ const cp1y = p1.y + (p2.y - p0.y) / 6;
4765
+ const cp2x = p2.x - (p3.x - p1.x) / 6;
4766
+ const cp2y = p2.y - (p3.y - p1.y) / 6;
4767
+ d += ` C${cp1x.toFixed(2)},${cp1y.toFixed(2)} ${cp2x.toFixed(2)},${cp2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
4768
+ }
4769
+ return d;
4770
+ }
4771
+ function markerRadius(size, defaultRadius2) {
4772
+ if (size === void 0 || !Number.isFinite(size) || size <= 0) {
4773
+ return defaultRadius2;
4774
+ }
4775
+ return size / 2;
4776
+ }
4777
+ function polygonPoints(vertices) {
4778
+ return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
4779
+ }
4780
+ function starVertices(cx, cy, r) {
4781
+ const inner = r * 0.5;
4782
+ const out = [];
4783
+ for (let i = 0; i < 10; i++) {
4784
+ const radius = i % 2 === 0 ? r : inner;
4785
+ const angle = -Math.PI / 2 + Math.PI * i / 5;
4786
+ out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
4787
+ }
4788
+ return out;
4789
+ }
4790
+ function buildMarkerPrimitive(input) {
4791
+ const { symbol, cx, cy, fill, part } = input;
4792
+ if (symbol === "none") {
4793
+ return null;
4794
+ }
4795
+ const r = markerRadius(input.size, input.defaultRadius);
4796
+ const stroke = fill;
4797
+ switch (symbol) {
4798
+ case "square":
4799
+ return { kind: "rect", x: cx - r, y: cy - r, w: r * 2, h: r * 2, fill, part };
4800
+ case "dash":
4801
+ return { kind: "rect", x: cx - r, y: cy - r * 0.32, w: r * 2, h: r * 0.64, fill, part };
4802
+ case "diamond":
4803
+ return {
4804
+ kind: "polygon",
4805
+ points: polygonPoints([
4806
+ [cx, cy - r],
4807
+ [cx + r, cy],
4808
+ [cx, cy + r],
4809
+ [cx - r, cy]
4810
+ ]),
4811
+ fill,
4812
+ stroke,
4813
+ strokeWidth: 0,
4814
+ part
4815
+ };
4816
+ case "triangle":
4817
+ return {
4818
+ kind: "polygon",
4819
+ points: polygonPoints([
4820
+ [cx, cy - r],
4821
+ [cx + r * 0.9, cy + r * 0.75],
4822
+ [cx - r * 0.9, cy + r * 0.75]
4823
+ ]),
4824
+ fill,
4825
+ stroke,
4826
+ strokeWidth: 0,
4827
+ part
4828
+ };
4829
+ case "star":
4830
+ return {
4831
+ kind: "polygon",
4832
+ points: polygonPoints(starVertices(cx, cy, r)),
4833
+ fill,
4834
+ stroke,
4835
+ strokeWidth: 0,
4836
+ part
4837
+ };
4838
+ case "plus":
4839
+ return {
4840
+ kind: "path",
4841
+ 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)}`,
4842
+ fill: "none",
4843
+ stroke,
4844
+ strokeWidth: Math.max(1, r * 0.4),
4845
+ part
4846
+ };
4847
+ case "x":
4848
+ return {
4849
+ kind: "path",
4850
+ 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)}`,
4851
+ fill: "none",
4852
+ stroke,
4853
+ strokeWidth: Math.max(1, r * 0.4),
4854
+ part
4855
+ };
4856
+ case "dot":
4857
+ return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, part };
4858
+ default:
4859
+ return { kind: "circle", cx, cy, r, fill, part };
4860
+ }
4861
+ }
4862
+ function pushMarker(out, series, cx, cy, fill, defaultRadius2, part, opacity) {
4863
+ const m = buildMarkerPrimitive({
4864
+ symbol: series.marker?.symbol,
4865
+ size: series.marker?.size,
4866
+ cx,
4867
+ cy,
4868
+ fill,
4869
+ defaultRadius: defaultRadius2,
4870
+ part
4871
+ });
4872
+ if (!m) {
4873
+ return;
4874
+ }
4875
+ if (opacity !== void 0) {
4876
+ m.opacity = opacity;
4877
+ }
4878
+ out.push(m);
4879
+ }
4690
4880
  function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, sourceIndices2, xPositions) {
4691
4881
  const primitives = [];
4692
4882
  const dataLabels = [];
@@ -4705,24 +4895,36 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
4705
4895
  })
4706
4896
  );
4707
4897
  const c = seriesColor2(series, si, chartData.colorPalette);
4708
- primitives.push({
4709
- kind: "polyline",
4710
- points: linePointsToSvgString(pts),
4711
- stroke: c,
4712
- strokeWidth: 2.4,
4713
- fill: "none",
4714
- part: { role: "series", seriesIndex: si }
4715
- });
4898
+ const seriesPart = { role: "series", seriesIndex: si };
4899
+ primitives.push(
4900
+ series.smooth ? {
4901
+ kind: "path",
4902
+ d: smoothLinePath(pts),
4903
+ stroke: c,
4904
+ strokeWidth: 2.4,
4905
+ fill: "none",
4906
+ part: seriesPart
4907
+ } : {
4908
+ kind: "polyline",
4909
+ points: linePointsToSvgString(pts),
4910
+ stroke: c,
4911
+ strokeWidth: 2.4,
4912
+ fill: "none",
4913
+ part: seriesPart
4914
+ }
4915
+ );
4716
4916
  pts.forEach((pt, displayIndex) => {
4717
- const sourceIndex = sourceIndices2[displayIndex] ?? displayIndex;
4718
- primitives.push({
4719
- kind: "circle",
4720
- cx: pt.x,
4721
- cy: pt.y,
4722
- r: 2.5,
4723
- fill: c,
4724
- part: { role: "dataPoint", seriesIndex: si, pointIndex: sourceIndex }
4725
- });
4917
+ const idx = sourceIndices2[displayIndex] ?? displayIndex;
4918
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
4919
+ pushMarker(
4920
+ primitives,
4921
+ series,
4922
+ pt.x,
4923
+ pt.y,
4924
+ resolveDataPointFill(series, idx, c) ?? c,
4925
+ 2.5,
4926
+ part
4927
+ );
4726
4928
  });
4727
4929
  if (showLabels) {
4728
4930
  displayValues.forEach((val2, displayIndex) => {
@@ -4783,18 +4985,17 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
4783
4985
  part: { role: "series", seriesIndex: si }
4784
4986
  });
4785
4987
  pts.forEach((pt, displayIndex) => {
4786
- primitives.push({
4787
- kind: "circle",
4788
- cx: pt.x,
4789
- cy: pt.y,
4790
- r: 2,
4791
- fill: c,
4792
- part: {
4793
- role: "dataPoint",
4794
- seriesIndex: si,
4795
- pointIndex: sourceIndices2[displayIndex] ?? displayIndex
4796
- }
4797
- });
4988
+ const idx = sourceIndices2[displayIndex] ?? displayIndex;
4989
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: idx };
4990
+ pushMarker(
4991
+ primitives,
4992
+ series,
4993
+ pt.x,
4994
+ pt.y,
4995
+ resolveDataPointFill(series, idx, c) ?? c,
4996
+ 2,
4997
+ part
4998
+ );
4798
4999
  });
4799
5000
  if (showLabels) {
4800
5001
  displayValues.forEach((val2, displayIndex) => {
@@ -4828,15 +5029,17 @@ function buildScatter(chartData, layout, range) {
4828
5029
  const c = seriesColor2(series, si, chartData.colorPalette);
4829
5030
  const dots = computeScatterDots(series.values, maxXIndex, layout, range, xValues);
4830
5031
  dots.forEach((dot, vi) => {
4831
- primitives.push({
4832
- kind: "circle",
4833
- cx: dot.cx,
4834
- cy: dot.cy,
4835
- r: 4,
4836
- fill: c,
4837
- opacity: 0.85,
4838
- part: { role: "dataPoint", seriesIndex: si, pointIndex: vi }
4839
- });
5032
+ const part = { role: "dataPoint", seriesIndex: si, pointIndex: vi };
5033
+ pushMarker(
5034
+ primitives,
5035
+ series,
5036
+ dot.cx,
5037
+ dot.cy,
5038
+ resolveDataPointFill(series, vi, c) ?? c,
5039
+ 4,
5040
+ part,
5041
+ 0.85
5042
+ );
4840
5043
  });
4841
5044
  if (showLabels) {
4842
5045
  series.values.forEach((val2, vi) => {
@@ -4880,7 +5083,7 @@ function buildBubbles(chartData, layout, range) {
4880
5083
  cx: dot.cx,
4881
5084
  cy: dot.cy,
4882
5085
  r,
4883
- fill: c,
5086
+ fill: resolveDataPointFill(series, vi, c) ?? c,
4884
5087
  opacity: 0.6,
4885
5088
  part: { role: "dataPoint", seriesIndex: si, pointIndex: vi }
4886
5089
  });
@@ -4905,7 +5108,124 @@ function buildBubbles(chartData, layout, range) {
4905
5108
  }
4906
5109
  return { primitives, dataLabels };
4907
5110
  }
4908
- function categoryX(displayIndex, count, layout, spacing) {
5111
+ function categoryX(index, catCount, layout, options) {
5112
+ const explicit = options.xPositions?.[index];
5113
+ if (explicit !== void 0) {
5114
+ return explicit;
5115
+ }
5116
+ if (options.mode === "bar") {
5117
+ const slot = layout.plotWidth / Math.max(catCount, 1);
5118
+ return layout.plotLeft + slot * index + slot / 2;
5119
+ }
5120
+ const maxIdx = Math.max(catCount - 1, 1);
5121
+ return layout.plotLeft + index / maxIdx * layout.plotWidth;
5122
+ }
5123
+ function dashFor(dashStyle) {
5124
+ if (!dashStyle || dashStyle === "solid") {
5125
+ return void 0;
5126
+ }
5127
+ return dashStyle === "dot" || dashStyle === "sysDot" ? "1 2" : "4 3";
5128
+ }
5129
+ function computeDropLinePrimitives(chartData, layout, range, catCount, options) {
5130
+ const style = chartData.dropLines;
5131
+ if (!style) {
5132
+ return [];
5133
+ }
5134
+ const baselineY = valueToY2(range.min, range, layout.plotTop, layout.plotBottom);
5135
+ const dashArray2 = dashFor(style.dashStyle);
5136
+ const out = [];
5137
+ for (const series of chartData.series) {
5138
+ series.values.forEach((val2, vi) => {
5139
+ const x = categoryX(vi, catCount, layout, options);
5140
+ out.push({
5141
+ kind: "line",
5142
+ x1: x,
5143
+ y1: valueToY2(val2, range, layout.plotTop, layout.plotBottom),
5144
+ x2: x,
5145
+ y2: baselineY,
5146
+ stroke: style.color ?? "#94a3b8",
5147
+ strokeWidth: style.width ?? 0.8,
5148
+ dashArray: dashArray2
5149
+ });
5150
+ });
5151
+ }
5152
+ return out;
5153
+ }
5154
+ function computeHiLowLinePrimitives(chartData, layout, range, catCount, options) {
5155
+ const style = chartData.hiLowLines;
5156
+ if (!style || chartData.series.length < 2) {
5157
+ return [];
5158
+ }
5159
+ const dashArray2 = dashFor(style.dashStyle);
5160
+ const out = [];
5161
+ for (let vi = 0; vi < catCount; vi++) {
5162
+ let high = Number.NEGATIVE_INFINITY;
5163
+ let low = Number.POSITIVE_INFINITY;
5164
+ for (const series of chartData.series) {
5165
+ const v = series.values[vi];
5166
+ if (v !== void 0) {
5167
+ high = Math.max(high, v);
5168
+ low = Math.min(low, v);
5169
+ }
5170
+ }
5171
+ if (!Number.isFinite(high) || !Number.isFinite(low)) {
5172
+ continue;
5173
+ }
5174
+ const x = categoryX(vi, catCount, layout, options);
5175
+ out.push({
5176
+ kind: "line",
5177
+ x1: x,
5178
+ y1: valueToY2(high, range, layout.plotTop, layout.plotBottom),
5179
+ x2: x,
5180
+ y2: valueToY2(low, range, layout.plotTop, layout.plotBottom),
5181
+ stroke: style.color ?? "#334155",
5182
+ strokeWidth: style.width ?? 1,
5183
+ dashArray: dashArray2
5184
+ });
5185
+ }
5186
+ return out;
5187
+ }
5188
+ function computeUpDownBarPrimitives(chartData, layout, range, catCount, options) {
5189
+ const bars = chartData.upDownBars;
5190
+ if (!bars || chartData.series.length < 2) {
5191
+ return [];
5192
+ }
5193
+ const first = chartData.series[0];
5194
+ const last = chartData.series[chartData.series.length - 1];
5195
+ const slot = layout.plotWidth / Math.max(catCount, 1);
5196
+ const gapWidth = bars.gapWidth ?? 150;
5197
+ const barW = Math.max(slot / (1 + Math.max(gapWidth, 0) / 100), 1);
5198
+ const upFill = bars.upBars?.fillColor ?? "#e2e8f0";
5199
+ const downFill = bars.downBars?.fillColor ?? "#334155";
5200
+ const out = [];
5201
+ for (let vi = 0; vi < catCount; vi++) {
5202
+ const firstVal = first.values[vi];
5203
+ const lastVal = last.values[vi];
5204
+ if (firstVal === void 0 || lastVal === void 0) {
5205
+ continue;
5206
+ }
5207
+ const firstY = valueToY2(firstVal, range, layout.plotTop, layout.plotBottom);
5208
+ const lastY = valueToY2(lastVal, range, layout.plotTop, layout.plotBottom);
5209
+ const x = categoryX(vi, catCount, layout, options) - barW / 2;
5210
+ out.push({
5211
+ kind: "rect",
5212
+ x,
5213
+ y: Math.min(firstY, lastY),
5214
+ w: barW,
5215
+ h: Math.max(Math.abs(firstY - lastY), 1),
5216
+ fill: lastVal >= firstVal ? upFill : downFill
5217
+ });
5218
+ }
5219
+ return out;
5220
+ }
5221
+ function computeHelperLinePrimitives(chartData, layout, range, catCount, options) {
5222
+ return [
5223
+ ...computeUpDownBarPrimitives(chartData, layout, range, catCount, options),
5224
+ ...computeDropLinePrimitives(chartData, layout, range, catCount, options),
5225
+ ...computeHiLowLinePrimitives(chartData, layout, range, catCount, options)
5226
+ ];
5227
+ }
5228
+ function categoryX2(displayIndex, count, layout, spacing) {
4909
5229
  if (spacing === "bar") {
4910
5230
  return layout.plotLeft + layout.plotWidth / Math.max(count, 1) * (displayIndex + 0.5);
4911
5231
  }
@@ -4936,8 +5256,8 @@ function buildMultiLevelCategoryLabels(categoryLabels, categoryLevels, sourceInd
4936
5256
  if (!group.text || group.start % skip !== 0) {
4937
5257
  return [];
4938
5258
  }
4939
- const startX = categoryX(group.start, sourceIndices2.length, layout, spacing);
4940
- const endX = categoryX(group.end, sourceIndices2.length, layout, spacing);
5259
+ const startX = categoryX2(group.start, sourceIndices2.length, layout, spacing);
5260
+ const endX = categoryX2(group.end, sourceIndices2.length, layout, spacing);
4941
5261
  return [
4942
5262
  {
4943
5263
  kind: "text",
@@ -4992,13 +5312,13 @@ function buildTickMarks(axis, sourceCount, layout, spacing, axisY) {
4992
5312
  }
4993
5313
  const majorSkip = Math.max(1, axis.tickMarkSkip ?? 1);
4994
5314
  for (let displayIndex = 0; displayIndex < sourceCount; displayIndex += majorSkip) {
4995
- const x = categoryX(displayIndex, sourceCount, layout, spacing);
5315
+ const x = categoryX2(displayIndex, sourceCount, layout, spacing);
4996
5316
  const major = tickLine(x, y, axis.majorTickMark, topAxis, 4, axis);
4997
5317
  if (major) {
4998
5318
  result.push(major);
4999
5319
  }
5000
5320
  if (axis.minorTickMark !== void 0 && displayIndex + majorSkip < sourceCount) {
5001
- const nextX = categoryX(displayIndex + majorSkip, sourceCount, layout, spacing);
5321
+ const nextX = categoryX2(displayIndex + majorSkip, sourceCount, layout, spacing);
5002
5322
  const minor = tickLine((x + nextX) / 2, y, axis.minorTickMark, topAxis, 2.5, axis);
5003
5323
  if (minor) {
5004
5324
  result.push(minor);
@@ -5276,7 +5596,7 @@ function buildCartesianHorizontalAxis(chartData, categoryLabels, layout, kind, p
5276
5596
  catAxisStyle,
5277
5597
  sourceIndices: sourceIndices2,
5278
5598
  xPositions: datePlan?.xPositions ?? categoryPlan?.sourceIndices.map(
5279
- (_sourceIndex, displayIndex) => categoryX(displayIndex, categoryPlan.sourceIndices.length, layout, catAxisStyle)
5599
+ (_sourceIndex, displayIndex) => categoryX2(displayIndex, categoryPlan.sourceIndices.length, layout, catAxisStyle)
5280
5600
  ),
5281
5601
  labels: [
5282
5602
  ...datePlan?.labels ?? categoryPlan?.labels ?? buildCategoryLabels(categoryLabels, layout, catAxisStyle),
@@ -5291,7 +5611,7 @@ function buildCartesianHorizontalAxis(chartData, categoryLabels, layout, kind, p
5291
5611
  }
5292
5612
  var DEFAULT_COLOR3 = "#334155";
5293
5613
  var CAP_HALF_WIDTH = 4;
5294
- function categoryX2(value, count, layout, mode) {
5614
+ function categoryX3(value, count, layout, mode) {
5295
5615
  if (mode === "bar") {
5296
5616
  const slot = layout.plotWidth / Math.max(count, 1);
5297
5617
  return layout.plotLeft + slot * value + slot / 2;
@@ -5398,7 +5718,7 @@ function computeErrorBarPrimitives(chartData, catCount, layout, range, mode = "l
5398
5718
  const categoryMapper = (value) => positionedCategoryX(
5399
5719
  value,
5400
5720
  options.xPositions,
5401
- (index) => categoryX2(index, indexes.length || catCount, layout, seriesMode)
5721
+ (index) => categoryX3(index, indexes.length || catCount, layout, seriesMode)
5402
5722
  );
5403
5723
  const toPixel = xValues.numeric ? (value) => numericX(value, xRange, layout) : categoryMapper;
5404
5724
  const x = toPixel(baseXValue);
@@ -5972,7 +6292,15 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
5972
6292
  } else {
5973
6293
  plot = buildBubbles(chartData, layout, primaryRange);
5974
6294
  }
5975
- const primitives = [...plot.primitives, ...horizontalAxis.tickMarks];
6295
+ const helperLines = kind === "line" || kind === "area" ? computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, {
6296
+ mode: "line",
6297
+ xPositions: horizontalAxis.xPositions
6298
+ }) : [];
6299
+ const primitives = [
6300
+ ...helperLines,
6301
+ ...plot.primitives,
6302
+ ...horizontalAxis.tickMarks
6303
+ ];
5976
6304
  const overlays = [
5977
6305
  ...computeTrendlinePrimitives(
5978
6306
  displayChartData,
@@ -6098,6 +6426,10 @@ function buildComboViewModel(element, chartData, categoryLabels) {
6098
6426
  );
6099
6427
  const primitives = [];
6100
6428
  const dataLabels = [];
6429
+ const helperOpts = { mode: "line", xPositions: horizontalAxis.xPositions };
6430
+ primitives.push(
6431
+ ...computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, helperOpts)
6432
+ );
6101
6433
  const barSeries = chartData.series.slice(0, 1);
6102
6434
  if (barSeries[0]) {
6103
6435
  const barRange = rangeForSeries(0, primaryRange, secondaryRange, secondaryIndexes);
@@ -8505,16 +8837,30 @@ function computePieLayout(elementWidth, elementHeight, chartData, isDoughnut) {
8505
8837
  const cx = size / 2;
8506
8838
  const cy = titleOffset + (size - titleOffset - legendOffset) / 2;
8507
8839
  const outerR = Math.max((size - titleOffset - legendOffset) * 0.42, 0);
8508
- const innerR = isDoughnut ? outerR * 0.55 : 0;
8840
+ const holeRatio = isDoughnut && chartData.doughnutHoleSize !== void 0 ? Math.min(Math.max(chartData.doughnutHoleSize, 10), 90) / 100 : 0.55;
8841
+ const innerR = isDoughnut ? outerR * holeRatio : 0;
8509
8842
  return { cx, cy, outerR, innerR, size };
8510
8843
  }
8511
- function computePieSlices(values, cx, cy, outerR, innerR) {
8844
+ function computePieSlices(values, cx, cy, outerR, innerR, options) {
8512
8845
  const total = values.reduce((s, v) => s + Math.abs(v), 0) || 1;
8513
- let cumAngle = -Math.PI / 2;
8514
- return values.map((val2) => {
8846
+ let cumAngle = options?.startAngle ?? -Math.PI / 2;
8847
+ return values.map((val2, i) => {
8515
8848
  const sliceAngle = Math.abs(val2) / total * Math.PI * 2;
8516
8849
  const startAngle = cumAngle;
8517
8850
  cumAngle += sliceAngle;
8851
+ const explosion = options?.explosions?.[i] ?? 0;
8852
+ if (explosion > 0) {
8853
+ const mid = (startAngle + cumAngle) / 2;
8854
+ const offset = outerR * (explosion / 100);
8855
+ return computePieSlicePath(
8856
+ cx + Math.cos(mid) * offset,
8857
+ cy + Math.sin(mid) * offset,
8858
+ outerR,
8859
+ innerR,
8860
+ startAngle,
8861
+ cumAngle
8862
+ );
8863
+ }
8518
8864
  return computePieSlicePath(cx, cy, outerR, innerR, startAngle, cumAngle);
8519
8865
  });
8520
8866
  }
@@ -8707,13 +9053,18 @@ function buildPieViewModel(element, chartData, categoryLabels, isDoughnut) {
8707
9053
  );
8708
9054
  const svgWidth = Math.max(size, 100);
8709
9055
  const svgHeight = Math.max(size, 60);
8710
- const values = chartData.series[0]?.values ?? [];
8711
- const slices = computePieSlices(values, cx, cy, outerR, innerR);
9056
+ const pieSeries = chartData.series[0];
9057
+ const values = pieSeries?.values ?? [];
9058
+ const startAngle = -Math.PI / 2 + (chartData.firstSliceAngle ?? 0) * Math.PI / 180;
9059
+ const explosions = pieSeries ? values.map((_v, i) => resolveDataPointExplosion(pieSeries, i)) : void 0;
9060
+ const slices = computePieSlices(values, cx, cy, outerR, innerR, { startAngle, explosions });
8712
9061
  const primitives = slices.map(
8713
9062
  ({ d }, i) => ({
8714
9063
  kind: "path",
8715
9064
  d,
8716
- fill: chartData.series[0]?.color ?? paletteColor2(i, chartData.colorPalette),
9065
+ // Pie/doughnut vary colours per slice (c:varyColors defaults on), so each
9066
+ // slice takes its palette colour, with a per-point c:dPt fill overriding.
9067
+ fill: pieSeries ? resolveVaryColorFill(pieSeries, i, paletteColor2(i, chartData.colorPalette)) : paletteColor2(i, chartData.colorPalette),
8717
9068
  stroke: "#ffffff",
8718
9069
  strokeWidth: 1.5,
8719
9070
  part: { role: "dataPoint", seriesIndex: 0, pointIndex: i }
@@ -9039,6 +9390,21 @@ var PRESET_ID_TO_EFFECT = {
9039
9390
  26: "pulse"
9040
9391
  }
9041
9392
  };
9393
+ var FLY_SUBTYPE_TO_EDGE = {
9394
+ 1: "top",
9395
+ 2: "right",
9396
+ 4: "bottom",
9397
+ 8: "left",
9398
+ // Corners -> nearest (horizontal) edge.
9399
+ 3: "right",
9400
+ // top-right (1|2)
9401
+ 6: "right",
9402
+ // bottom-right (4|2)
9403
+ 9: "left",
9404
+ // top-left (8|1)
9405
+ 12: "left"
9406
+ // bottom-left (8|4)
9407
+ };
9042
9408
  var KEYFRAME_DEFINITIONS = {
9043
9409
  // ---- Entrance effects ----
9044
9410
  appear: `@keyframes pptx-appear {
@@ -9410,16 +9776,31 @@ function resolveEffect(anim) {
9410
9776
  return void 0;
9411
9777
  }
9412
9778
  if (cls === "entr") {
9413
- return PRESET_ID_TO_EFFECT.entr[id];
9779
+ return applyFlyDirection(PRESET_ID_TO_EFFECT.entr[id], anim.presetSubtype);
9414
9780
  }
9415
9781
  if (cls === "exit") {
9416
- return PRESET_ID_TO_EFFECT.exit[id];
9782
+ return applyFlyDirection(PRESET_ID_TO_EFFECT.exit[id], anim.presetSubtype);
9417
9783
  }
9418
9784
  if (cls === "emph") {
9419
9785
  return PRESET_ID_TO_EFFECT.emph[id];
9420
9786
  }
9421
9787
  return void 0;
9422
9788
  }
9789
+ function applyFlyDirection(effect, subtype) {
9790
+ if (effect !== "flyInBottom" && effect !== "flyOutBottom") {
9791
+ return effect;
9792
+ }
9793
+ if (subtype === void 0) {
9794
+ return effect;
9795
+ }
9796
+ const edge = FLY_SUBTYPE_TO_EDGE[subtype];
9797
+ if (!edge) {
9798
+ return effect;
9799
+ }
9800
+ const prefix = effect === "flyInBottom" ? "flyIn" : "flyOut";
9801
+ const suffix = `${edge.charAt(0).toUpperCase()}${edge.slice(1)}`;
9802
+ return `${prefix}${suffix}`;
9803
+ }
9423
9804
  function parseMotionPathPoints(motionPath) {
9424
9805
  const cmds = motionPath.replace(/\s+/gu, " ").trim().split(/(?=[MLCZ])/iu).filter(Boolean);
9425
9806
  const points = [];
@@ -9821,6 +10202,29 @@ function getAnimationInitialStyle(preset, nativeAnimation) {
9821
10202
  }
9822
10203
  return {};
9823
10204
  }
10205
+ function cssEasingForAnimation(anim) {
10206
+ const hasAccel = anim.accel !== void 0 && anim.accel > 0;
10207
+ const hasDecel = anim.decel !== void 0 && anim.decel > 0;
10208
+ if (hasAccel && hasDecel) {
10209
+ return "ease-in-out";
10210
+ }
10211
+ if (hasAccel) {
10212
+ return "ease-in";
10213
+ }
10214
+ if (hasDecel) {
10215
+ return "ease-out";
10216
+ }
10217
+ return "ease";
10218
+ }
10219
+ function fallbackEffectForClass(presetClass) {
10220
+ if (presetClass === "entr") {
10221
+ return "fadeIn";
10222
+ }
10223
+ if (presetClass === "exit") {
10224
+ return "fadeOut";
10225
+ }
10226
+ return void 0;
10227
+ }
9824
10228
  function buildTimeline(nativeAnimations) {
9825
10229
  if (nativeAnimations.length === 0) {
9826
10230
  return {
@@ -9855,10 +10259,13 @@ function buildTimeline(nativeAnimations) {
9855
10259
  for (const anim of regularAnims) {
9856
10260
  const expandedSteps = expandIterateAnimation(anim);
9857
10261
  for (const singleAnim of expandedSteps) {
9858
- const effect = resolveEffect(singleAnim);
10262
+ let effect = resolveEffect(singleAnim);
9859
10263
  const dynamic = effect ? void 0 : buildDynamicKeyframe(singleAnim, dynamicUid++);
9860
10264
  if (!effect && !dynamic) {
9861
- continue;
10265
+ effect = fallbackEffectForClass(singleAnim.presetClass);
10266
+ if (!effect) {
10267
+ continue;
10268
+ }
9862
10269
  }
9863
10270
  const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
9864
10271
  if (effect) {
@@ -9904,7 +10311,8 @@ function buildTimeline(nativeAnimations) {
9904
10311
  delayMs = animDelay + triggerDelay;
9905
10312
  }
9906
10313
  const iterStr = iterCount === Infinity ? "infinite" : String(iterCount);
9907
- const cssAnimation = `${keyframe} ${duration}ms ease ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10314
+ const easing = cssEasingForAnimation(singleAnim);
10315
+ const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
9908
10316
  currentGroup.push({
9909
10317
  elementId,
9910
10318
  cssAnimation,
@@ -9987,10 +10395,13 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
9987
10395
  const seqGroups = [];
9988
10396
  let seqGroup = [];
9989
10397
  for (const anim of anims) {
9990
- const effect = resolveEffect(anim);
10398
+ let effect = resolveEffect(anim);
9991
10399
  const dynamic = effect ? void 0 : buildDynamicKeyframe(anim, dynamicUid++);
9992
10400
  if (!effect && !dynamic) {
9993
- continue;
10401
+ effect = fallbackEffectForClass(anim.presetClass);
10402
+ if (!effect) {
10403
+ continue;
10404
+ }
9994
10405
  }
9995
10406
  const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
9996
10407
  if (effect) {
@@ -10027,7 +10438,8 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
10027
10438
  delayMs = animDelay + triggerDelay;
10028
10439
  }
10029
10440
  const iterStr = iterCount === Infinity ? "infinite" : String(iterCount);
10030
- const cssAnimation = `${keyframe} ${duration}ms ease ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10441
+ const easing = cssEasingForAnimation(anim);
10442
+ const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
10031
10443
  seqGroup.push({
10032
10444
  elementId,
10033
10445
  cssAnimation,
@@ -14103,6 +14515,23 @@ function getConnectionSites(width, height) {
14103
14515
  // left center
14104
14516
  ];
14105
14517
  }
14518
+ function getShapeConnectionSites(shape) {
14519
+ const geo = shape;
14520
+ const cxn = geo.customGeometryConnectionSites;
14521
+ if (!cxn || cxn.length === 0) {
14522
+ return getConnectionSites(shape.width, shape.height);
14523
+ }
14524
+ const pathW = geo.pathWidth && geo.pathWidth > 0 ? geo.pathWidth : shape.width;
14525
+ const pathH = geo.pathHeight && geo.pathHeight > 0 ? geo.pathHeight : shape.height;
14526
+ const vars = createBuiltinVariables({ w: pathW, h: pathH });
14527
+ const scaleX = pathW > 0 ? shape.width / pathW : 1;
14528
+ const scaleY = pathH > 0 ? shape.height / pathH : 1;
14529
+ return cxn.map((site, index) => ({
14530
+ x: resolveCoordinate(site.posX, vars) * scaleX,
14531
+ y: resolveCoordinate(site.posY, vars) * scaleY,
14532
+ index
14533
+ }));
14534
+ }
14106
14535
  function rerouteConnectorsForMovedElements(elements, movedElementIds) {
14107
14536
  if (movedElementIds.size === 0) {
14108
14537
  return [];
@@ -14146,7 +14575,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14146
14575
  if (!startShape) {
14147
14576
  return null;
14148
14577
  }
14149
- const sites = getConnectionSites(startShape.width, startShape.height);
14578
+ const sites = getShapeConnectionSites(startShape);
14150
14579
  const siteIndex = startConn.connectionSiteIndex ?? 0;
14151
14580
  const site = sites[siteIndex] ?? sites[0];
14152
14581
  sx = startShape.x + site.x;
@@ -14162,7 +14591,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14162
14591
  if (!endShape) {
14163
14592
  return null;
14164
14593
  }
14165
- const sites = getConnectionSites(endShape.width, endShape.height);
14594
+ const sites = getShapeConnectionSites(endShape);
14166
14595
  const siteIndex = endConn.connectionSiteIndex ?? 0;
14167
14596
  const site = sites[siteIndex] ?? sites[0];
14168
14597
  ex = endShape.x + site.x;
@@ -14171,12 +14600,16 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
14171
14600
  ex = connector.x + connector.width;
14172
14601
  ey = connector.y + connector.height;
14173
14602
  }
14603
+ const flipHorizontal = ex < sx;
14604
+ const flipVertical = ey < sy;
14174
14605
  return {
14175
14606
  id: connector.id,
14176
14607
  x: Math.min(sx, ex),
14177
14608
  y: Math.min(sy, ey),
14178
14609
  width: Math.abs(ex - sx) || 1,
14179
- height: Math.abs(ey - sy) || 1
14610
+ height: Math.abs(ey - sy) || 1,
14611
+ flipHorizontal,
14612
+ flipVertical
14180
14613
  };
14181
14614
  }
14182
14615
  function applyReroutedConnectors(elements, rerouted) {
@@ -14192,13 +14625,20 @@ function applyReroutedConnectors(elements, rerouted) {
14192
14625
  if (!update) {
14193
14626
  return el;
14194
14627
  }
14195
- return {
14628
+ const next = {
14196
14629
  ...el,
14197
14630
  x: update.x,
14198
14631
  y: update.y,
14199
14632
  width: update.width,
14200
14633
  height: update.height
14201
14634
  };
14635
+ if (update.flipHorizontal !== void 0) {
14636
+ next.flipHorizontal = update.flipHorizontal;
14637
+ }
14638
+ if (update.flipVertical !== void 0) {
14639
+ next.flipVertical = update.flipVertical;
14640
+ }
14641
+ return next;
14202
14642
  });
14203
14643
  }
14204
14644
  function getCompoundLineOffsets(compoundLine, strokeWidth) {
@@ -15732,7 +16172,308 @@ var INSTANT = {
15732
16172
  };
15733
16173
  var DEFAULT_TRANSITION_DURATION_MS = 1e3;
15734
16174
  var EASE = "ease-in-out";
15735
- var SLIDE_TRANSITION_KEYFRAMES = `
16175
+ var P14_TRANSITION_KEYFRAMES = `
16176
+ /* \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 */
16177
+ @keyframes pptx-tr-conveyor-in-from-right {
16178
+ from { transform: translateX(100%) rotateY(-30deg); }
16179
+ 60% { transform: translateX(20%) rotateY(-10deg); }
16180
+ to { transform: translateX(0) rotateY(0deg); }
16181
+ }
16182
+ @keyframes pptx-tr-conveyor-out-to-left {
16183
+ from { transform: translateX(0) rotateY(0deg); }
16184
+ 40% { transform: translateX(-20%) rotateY(10deg); }
16185
+ to { transform: translateX(-100%) rotateY(30deg); }
16186
+ }
16187
+ @keyframes pptx-tr-conveyor-in-from-left {
16188
+ from { transform: translateX(-100%) rotateY(30deg); }
16189
+ 60% { transform: translateX(-20%) rotateY(10deg); }
16190
+ to { transform: translateX(0) rotateY(0deg); }
16191
+ }
16192
+ @keyframes pptx-tr-conveyor-out-to-right {
16193
+ from { transform: translateX(0) rotateY(0deg); }
16194
+ 40% { transform: translateX(20%) rotateY(-10deg); }
16195
+ to { transform: translateX(100%) rotateY(-30deg); }
16196
+ }
16197
+
16198
+ /* \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 */
16199
+ @keyframes pptx-tr-doors-horz {
16200
+ from { clip-path: inset(0 50%); }
16201
+ to { clip-path: inset(0 0); }
16202
+ }
16203
+ @keyframes pptx-tr-doors-vert {
16204
+ from { clip-path: inset(50% 0); }
16205
+ to { clip-path: inset(0 0); }
16206
+ }
16207
+
16208
+ /* \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 */
16209
+ @keyframes pptx-tr-ferris-in-from-right {
16210
+ from { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
16211
+ to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16212
+ }
16213
+ @keyframes pptx-tr-ferris-out-to-left {
16214
+ from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16215
+ to { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
16216
+ }
16217
+ @keyframes pptx-tr-ferris-in-from-left {
16218
+ from { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
16219
+ to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16220
+ }
16221
+ @keyframes pptx-tr-ferris-out-to-right {
16222
+ from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
16223
+ to { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
16224
+ }
16225
+
16226
+ /* \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 */
16227
+ @keyframes pptx-tr-flash-white {
16228
+ 0% { opacity: 1; }
16229
+ 30% { opacity: 0; }
16230
+ 50% { opacity: 0; }
16231
+ 100% { opacity: 1; }
16232
+ }
16233
+ @keyframes pptx-tr-flash-in {
16234
+ 0% { opacity: 0; }
16235
+ 50% { opacity: 0; }
16236
+ 70% { opacity: 1; }
16237
+ 100% { opacity: 1; }
16238
+ }
16239
+
16240
+ /* \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 */
16241
+ @keyframes pptx-tr-flythrough-in {
16242
+ from { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
16243
+ to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16244
+ }
16245
+ @keyframes pptx-tr-flythrough-out {
16246
+ from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16247
+ to { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
16248
+ }
16249
+ @keyframes pptx-tr-flythrough-reverse-in {
16250
+ from { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
16251
+ to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16252
+ }
16253
+ @keyframes pptx-tr-flythrough-reverse-out {
16254
+ from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
16255
+ to { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
16256
+ }
16257
+
16258
+ /* \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 */
16259
+ @keyframes pptx-tr-gallery-in-from-right {
16260
+ from { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
16261
+ to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16262
+ }
16263
+ @keyframes pptx-tr-gallery-out-to-left {
16264
+ from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16265
+ to { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
16266
+ }
16267
+ @keyframes pptx-tr-gallery-in-from-left {
16268
+ from { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
16269
+ to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16270
+ }
16271
+ @keyframes pptx-tr-gallery-out-to-right {
16272
+ from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
16273
+ to { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
16274
+ }
16275
+
16276
+ /* \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 */
16277
+ @keyframes pptx-tr-glitter-in {
16278
+ from { opacity: 0; filter: brightness(1.5) contrast(1.3) blur(2px); }
16279
+ 60% { opacity: 0.7; filter: brightness(1.2) contrast(1.1) blur(1px); }
16280
+ to { opacity: 1; filter: brightness(1) contrast(1) blur(0); }
16281
+ }
16282
+
16283
+ /* \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 */
16284
+ @keyframes pptx-tr-honeycomb-in {
16285
+ from {
16286
+ clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%);
16287
+ opacity: 0;
16288
+ }
16289
+ to {
16290
+ clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
16291
+ opacity: 1;
16292
+ }
16293
+ }
16294
+ @keyframes pptx-tr-honeycomb-out {
16295
+ from { opacity: 1; }
16296
+ to { opacity: 0; filter: blur(2px); }
16297
+ }
16298
+
16299
+ /* \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 */
16300
+ @keyframes pptx-tr-pan-from-right {
16301
+ from { transform: translateX(100%); }
16302
+ to { transform: translateX(0); }
16303
+ }
16304
+ @keyframes pptx-tr-pan-to-left {
16305
+ from { transform: translateX(0); }
16306
+ to { transform: translateX(-100%); }
16307
+ }
16308
+ @keyframes pptx-tr-pan-from-left {
16309
+ from { transform: translateX(-100%); }
16310
+ to { transform: translateX(0); }
16311
+ }
16312
+ @keyframes pptx-tr-pan-to-right {
16313
+ from { transform: translateX(0); }
16314
+ to { transform: translateX(100%); }
16315
+ }
16316
+ @keyframes pptx-tr-pan-from-bottom {
16317
+ from { transform: translateY(100%); }
16318
+ to { transform: translateY(0); }
16319
+ }
16320
+ @keyframes pptx-tr-pan-to-top {
16321
+ from { transform: translateY(0); }
16322
+ to { transform: translateY(-100%); }
16323
+ }
16324
+ @keyframes pptx-tr-pan-from-top {
16325
+ from { transform: translateY(-100%); }
16326
+ to { transform: translateY(0); }
16327
+ }
16328
+ @keyframes pptx-tr-pan-to-bottom {
16329
+ from { transform: translateY(0); }
16330
+ to { transform: translateY(100%); }
16331
+ }
16332
+ `;
16333
+ var P14_TRANSITION_KEYFRAMES_2 = `
16334
+ /* \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 */
16335
+ @keyframes pptx-tr-prism-in-from-right {
16336
+ from { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
16337
+ to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16338
+ }
16339
+ @keyframes pptx-tr-prism-out-to-left {
16340
+ from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16341
+ to { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
16342
+ }
16343
+ @keyframes pptx-tr-prism-in-from-left {
16344
+ from { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
16345
+ to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16346
+ }
16347
+ @keyframes pptx-tr-prism-out-to-right {
16348
+ from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
16349
+ to { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
16350
+ }
16351
+ @keyframes pptx-tr-prism-in-from-bottom {
16352
+ from { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
16353
+ to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16354
+ }
16355
+ @keyframes pptx-tr-prism-out-to-top {
16356
+ from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16357
+ to { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
16358
+ }
16359
+ @keyframes pptx-tr-prism-in-from-top {
16360
+ from { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
16361
+ to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16362
+ }
16363
+ @keyframes pptx-tr-prism-out-to-bottom {
16364
+ from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
16365
+ to { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
16366
+ }
16367
+
16368
+ /* \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 */
16369
+ @keyframes pptx-tr-reveal-out-to-right {
16370
+ from { transform: translateX(0); }
16371
+ to { transform: translateX(100%); }
16372
+ }
16373
+ @keyframes pptx-tr-reveal-out-to-left {
16374
+ from { transform: translateX(0); }
16375
+ to { transform: translateX(-100%); }
16376
+ }
16377
+ @keyframes pptx-tr-reveal-in {
16378
+ from { opacity: 0.5; }
16379
+ to { opacity: 1; }
16380
+ }
16381
+
16382
+ /* \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 */
16383
+ @keyframes pptx-tr-ripple-in {
16384
+ from { clip-path: circle(0% at 50% 50%); opacity: 0.5; }
16385
+ 30% { clip-path: circle(20% at 50% 50%); opacity: 0.7; }
16386
+ 60% { clip-path: circle(50% at 50% 50%); opacity: 0.9; }
16387
+ to { clip-path: circle(75% at 50% 50%); opacity: 1; }
16388
+ }
16389
+
16390
+ /* \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 */
16391
+ @keyframes pptx-tr-shred-strips-in {
16392
+ from { clip-path: inset(0 100% 0 0); opacity: 0; }
16393
+ 30% { clip-path: inset(0 60% 0 0); opacity: 0.5; }
16394
+ to { clip-path: inset(0); opacity: 1; }
16395
+ }
16396
+ @keyframes pptx-tr-shred-rectangles-in {
16397
+ from { clip-path: inset(50%); opacity: 0; }
16398
+ 40% { clip-path: inset(20%); opacity: 0.6; }
16399
+ to { clip-path: inset(0); opacity: 1; }
16400
+ }
16401
+ @keyframes pptx-tr-shred-out {
16402
+ from { opacity: 1; }
16403
+ to { opacity: 0; filter: blur(2px); }
16404
+ }
16405
+
16406
+ /* \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 */
16407
+ @keyframes pptx-tr-switch-in-from-right {
16408
+ from { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
16409
+ to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16410
+ }
16411
+ @keyframes pptx-tr-switch-out-to-left {
16412
+ from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16413
+ to { transform: perspective(800px) rotateY(180deg); opacity: 0; }
16414
+ }
16415
+ @keyframes pptx-tr-switch-in-from-left {
16416
+ from { transform: perspective(800px) rotateY(180deg); opacity: 0; }
16417
+ to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16418
+ }
16419
+ @keyframes pptx-tr-switch-out-to-right {
16420
+ from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
16421
+ to { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
16422
+ }
16423
+
16424
+ /* \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 */
16425
+ @keyframes pptx-tr-vortex-in {
16426
+ from { transform: rotate(720deg) scale(0); opacity: 0; }
16427
+ to { transform: rotate(0deg) scale(1); opacity: 1; }
16428
+ }
16429
+ @keyframes pptx-tr-vortex-out {
16430
+ from { transform: rotate(0deg) scale(1); opacity: 1; }
16431
+ to { transform: rotate(-720deg) scale(0); opacity: 0; }
16432
+ }
16433
+
16434
+ /* \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 */
16435
+ @keyframes pptx-tr-warp-in {
16436
+ from { transform: scale(0.3) skewX(30deg) skewY(15deg); opacity: 0; }
16437
+ 50% { transform: scale(0.8) skewX(-5deg) skewY(-3deg); opacity: 0.7; }
16438
+ to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
16439
+ }
16440
+ @keyframes pptx-tr-warp-out {
16441
+ from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
16442
+ 50% { transform: scale(0.8) skewX(5deg) skewY(3deg); opacity: 0.7; }
16443
+ to { transform: scale(0.3) skewX(-30deg) skewY(-15deg); opacity: 0; }
16444
+ }
16445
+ @keyframes pptx-tr-warp-reverse-in {
16446
+ from { transform: scale(3) skewX(-20deg) skewY(-10deg); opacity: 0; filter: blur(4px); }
16447
+ to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
16448
+ }
16449
+ @keyframes pptx-tr-warp-reverse-out {
16450
+ from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
16451
+ to { transform: scale(3) skewX(20deg) skewY(10deg); opacity: 0; filter: blur(4px); }
16452
+ }
16453
+
16454
+ /* \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 */
16455
+ @keyframes pptx-tr-wheel-reverse-in {
16456
+ from { clip-path: circle(0% at 50% 50%); transform: rotate(180deg); }
16457
+ to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
16458
+ }
16459
+
16460
+ /* \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 */
16461
+ @keyframes pptx-tr-window-horz {
16462
+ from { clip-path: inset(0 50%); }
16463
+ to { clip-path: inset(0 0); }
16464
+ }
16465
+ @keyframes pptx-tr-window-vert {
16466
+ from { clip-path: inset(50% 0); }
16467
+ to { clip-path: inset(0 0); }
16468
+ }
16469
+ @keyframes pptx-tr-window-out {
16470
+ from { opacity: 1; transform: scale(1); }
16471
+ to { opacity: 0; transform: scale(0.9); }
16472
+ }
16473
+ `;
16474
+ var P14_TRANSITION_KEYFRAMES_ALL = `${P14_TRANSITION_KEYFRAMES}
16475
+ ${P14_TRANSITION_KEYFRAMES_2}`;
16476
+ var CORE_SLIDE_TRANSITION_KEYFRAMES = `
15736
16477
  /* \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 */
15737
16478
  @keyframes pptx-tr-fade-in {
15738
16479
  from { opacity: 0; }
@@ -15995,8 +16736,243 @@ var SLIDE_TRANSITION_KEYFRAMES = `
15995
16736
  to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
15996
16737
  }
15997
16738
  `;
16739
+ var SLIDE_TRANSITION_KEYFRAMES = `${CORE_SLIDE_TRANSITION_KEYFRAMES}
16740
+ ${P14_TRANSITION_KEYFRAMES_ALL}`;
16741
+ function resolveLR(direction) {
16742
+ if (direction === "l" || direction === "r") {
16743
+ return direction;
16744
+ }
16745
+ return "l";
16746
+ }
16747
+ function resolveP14Orientation(direction, orient) {
16748
+ if (orient === "horz" || orient === "vert") {
16749
+ return orient;
16750
+ }
16751
+ if (direction === "horz" || direction === "vert") {
16752
+ return direction;
16753
+ }
16754
+ return "horz";
16755
+ }
16756
+ function resolveCardinal(direction) {
16757
+ switch (direction) {
16758
+ case "l":
16759
+ return "left";
16760
+ case "r":
16761
+ return "right";
16762
+ case "u":
16763
+ return "up";
16764
+ case "d":
16765
+ return "down";
16766
+ default:
16767
+ return "left";
16768
+ }
16769
+ }
16770
+ function directionalPair(direction, prefix, dur, ease) {
16771
+ const dir = resolveCardinal(direction);
16772
+ const opposites = {
16773
+ left: ["to-left", "from-right"],
16774
+ right: ["to-right", "from-left"],
16775
+ up: ["to-top", "from-bottom"],
16776
+ down: ["to-bottom", "from-top"]
16777
+ };
16778
+ const [outSuffix, inSuffix] = opposites[dir];
16779
+ return {
16780
+ outgoing: `${prefix}-${outSuffix} ${dur} ${ease} forwards`,
16781
+ incoming: `${prefix}-${inSuffix} ${dur} ${ease} forwards`,
16782
+ outgoingOnTop: false
16783
+ };
16784
+ }
16785
+ function cardinalOutInPair(direction, prefix, dur, ease) {
16786
+ const dir = resolveCardinal(direction);
16787
+ const map = {
16788
+ left: ["out-to-left", "in-from-right"],
16789
+ right: ["out-to-right", "in-from-left"],
16790
+ up: ["out-to-top", "in-from-bottom"],
16791
+ down: ["out-to-bottom", "in-from-top"]
16792
+ };
16793
+ const [outSuffix, inSuffix] = map[dir];
16794
+ return {
16795
+ outgoing: `${prefix}-${outSuffix} ${dur} ${ease} forwards`,
16796
+ incoming: `${prefix}-${inSuffix} ${dur} ${ease} forwards`,
16797
+ outgoingOnTop: false
16798
+ };
16799
+ }
16800
+ function getP14TransitionAnimations(type, durationMs, direction, orient) {
16801
+ const dur = `${durationMs}ms`;
16802
+ const ease = EASE;
16803
+ switch (type) {
16804
+ case "conveyor": {
16805
+ const lr = resolveLR(direction);
16806
+ if (lr === "l") {
16807
+ return {
16808
+ outgoing: `pptx-tr-conveyor-out-to-left ${dur} ${ease} forwards`,
16809
+ incoming: `pptx-tr-conveyor-in-from-right ${dur} ${ease} forwards`,
16810
+ outgoingOnTop: false
16811
+ };
16812
+ }
16813
+ return {
16814
+ outgoing: `pptx-tr-conveyor-out-to-right ${dur} ${ease} forwards`,
16815
+ incoming: `pptx-tr-conveyor-in-from-left ${dur} ${ease} forwards`,
16816
+ outgoingOnTop: false
16817
+ };
16818
+ }
16819
+ case "doors": {
16820
+ const o = resolveP14Orientation(direction, orient);
16821
+ return {
16822
+ outgoing: "none",
16823
+ incoming: o === "vert" ? `pptx-tr-doors-vert ${dur} ${ease} forwards` : `pptx-tr-doors-horz ${dur} ${ease} forwards`,
16824
+ outgoingOnTop: false
16825
+ };
16826
+ }
16827
+ case "ferris": {
16828
+ const lr = resolveLR(direction);
16829
+ if (lr === "l") {
16830
+ return {
16831
+ outgoing: `pptx-tr-ferris-out-to-left ${dur} ${ease} forwards`,
16832
+ incoming: `pptx-tr-ferris-in-from-right ${dur} ${ease} forwards`,
16833
+ outgoingOnTop: false
16834
+ };
16835
+ }
16836
+ return {
16837
+ outgoing: `pptx-tr-ferris-out-to-right ${dur} ${ease} forwards`,
16838
+ incoming: `pptx-tr-ferris-in-from-left ${dur} ${ease} forwards`,
16839
+ outgoingOnTop: false
16840
+ };
16841
+ }
16842
+ case "flash":
16843
+ return {
16844
+ outgoing: `pptx-tr-flash-white ${dur} ${ease} forwards`,
16845
+ incoming: `pptx-tr-flash-in ${dur} ${ease} forwards`,
16846
+ outgoingOnTop: true
16847
+ };
16848
+ case "flythrough": {
16849
+ const isOut = direction === "out";
16850
+ if (isOut) {
16851
+ return {
16852
+ outgoing: `pptx-tr-flythrough-reverse-out ${dur} ${ease} forwards`,
16853
+ incoming: `pptx-tr-flythrough-reverse-in ${dur} ${ease} forwards`,
16854
+ outgoingOnTop: true
16855
+ };
16856
+ }
16857
+ return {
16858
+ outgoing: `pptx-tr-flythrough-out ${dur} ${ease} forwards`,
16859
+ incoming: `pptx-tr-flythrough-in ${dur} ${ease} forwards`,
16860
+ outgoingOnTop: true
16861
+ };
16862
+ }
16863
+ case "gallery": {
16864
+ const lr = resolveLR(direction);
16865
+ if (lr === "l") {
16866
+ return {
16867
+ outgoing: `pptx-tr-gallery-out-to-left ${dur} ${ease} forwards`,
16868
+ incoming: `pptx-tr-gallery-in-from-right ${dur} ${ease} forwards`,
16869
+ outgoingOnTop: false
16870
+ };
16871
+ }
16872
+ return {
16873
+ outgoing: `pptx-tr-gallery-out-to-right ${dur} ${ease} forwards`,
16874
+ incoming: `pptx-tr-gallery-in-from-left ${dur} ${ease} forwards`,
16875
+ outgoingOnTop: false
16876
+ };
16877
+ }
16878
+ case "glitter":
16879
+ return {
16880
+ outgoing: `pptx-tr-fade-out ${dur} ${ease} forwards`,
16881
+ incoming: `pptx-tr-glitter-in ${dur} ${ease} forwards`,
16882
+ outgoingOnTop: true
16883
+ };
16884
+ case "honeycomb":
16885
+ return {
16886
+ outgoing: `pptx-tr-honeycomb-out ${dur} ${ease} forwards`,
16887
+ incoming: `pptx-tr-honeycomb-in ${dur} ${ease} forwards`,
16888
+ outgoingOnTop: true
16889
+ };
16890
+ case "pan":
16891
+ return directionalPair(direction, "pptx-tr-pan", dur, ease);
16892
+ case "prism":
16893
+ return cardinalOutInPair(direction, "pptx-tr-prism", dur, ease);
16894
+ case "reveal": {
16895
+ const lr = resolveLR(direction);
16896
+ return {
16897
+ outgoing: lr === "l" ? `pptx-tr-reveal-out-to-left ${dur} ${ease} forwards` : `pptx-tr-reveal-out-to-right ${dur} ${ease} forwards`,
16898
+ incoming: `pptx-tr-reveal-in ${dur} ${ease} forwards`,
16899
+ outgoingOnTop: true
16900
+ };
16901
+ }
16902
+ case "ripple":
16903
+ return {
16904
+ outgoing: "none",
16905
+ incoming: `pptx-tr-ripple-in ${dur} ${ease} forwards`,
16906
+ outgoingOnTop: false
16907
+ };
16908
+ case "shred": {
16909
+ const pattern = direction === "rectangles" ? "rectangles" : "strips";
16910
+ return {
16911
+ outgoing: `pptx-tr-shred-out ${dur} ${ease} forwards`,
16912
+ incoming: pattern === "rectangles" ? `pptx-tr-shred-rectangles-in ${dur} ${ease} forwards` : `pptx-tr-shred-strips-in ${dur} ${ease} forwards`,
16913
+ outgoingOnTop: true
16914
+ };
16915
+ }
16916
+ case "switch": {
16917
+ const lr = resolveLR(direction);
16918
+ if (lr === "l") {
16919
+ return {
16920
+ outgoing: `pptx-tr-switch-out-to-left ${dur} ${ease} forwards`,
16921
+ incoming: `pptx-tr-switch-in-from-right ${dur} ${ease} forwards`,
16922
+ outgoingOnTop: false
16923
+ };
16924
+ }
16925
+ return {
16926
+ outgoing: `pptx-tr-switch-out-to-right ${dur} ${ease} forwards`,
16927
+ incoming: `pptx-tr-switch-in-from-left ${dur} ${ease} forwards`,
16928
+ outgoingOnTop: false
16929
+ };
16930
+ }
16931
+ case "vortex":
16932
+ return {
16933
+ outgoing: `pptx-tr-vortex-out ${dur} ${ease} forwards`,
16934
+ incoming: `pptx-tr-vortex-in ${dur} ${ease} forwards`,
16935
+ outgoingOnTop: true
16936
+ };
16937
+ case "warp": {
16938
+ const isOut = direction === "out";
16939
+ if (isOut) {
16940
+ return {
16941
+ outgoing: `pptx-tr-warp-reverse-out ${dur} ${ease} forwards`,
16942
+ incoming: `pptx-tr-warp-reverse-in ${dur} ${ease} forwards`,
16943
+ outgoingOnTop: true
16944
+ };
16945
+ }
16946
+ return {
16947
+ outgoing: `pptx-tr-warp-out ${dur} ${ease} forwards`,
16948
+ incoming: `pptx-tr-warp-in ${dur} ${ease} forwards`,
16949
+ outgoingOnTop: true
16950
+ };
16951
+ }
16952
+ case "wheelReverse":
16953
+ return {
16954
+ outgoing: "none",
16955
+ incoming: `pptx-tr-wheel-reverse-in ${dur} ${ease} forwards`,
16956
+ outgoingOnTop: false
16957
+ };
16958
+ case "window": {
16959
+ const o = resolveP14Orientation(direction, orient);
16960
+ return {
16961
+ outgoing: `pptx-tr-window-out ${dur} ${ease} forwards`,
16962
+ incoming: o === "vert" ? `pptx-tr-window-vert ${dur} ${ease} forwards` : `pptx-tr-window-horz ${dur} ${ease} forwards`,
16963
+ outgoingOnTop: true
16964
+ };
16965
+ }
16966
+ default:
16967
+ return void 0;
16968
+ }
16969
+ }
15998
16970
  function getSlideTransitionAnimations(type, durationMs, direction, orient, spokes) {
15999
16971
  const dur = `${durationMs}ms`;
16972
+ const p14 = getP14TransitionAnimations(type, durationMs, direction, orient);
16973
+ if (p14) {
16974
+ return p14;
16975
+ }
16000
16976
  switch (type) {
16001
16977
  case "none":
16002
16978
  case "cut":
@@ -16198,31 +17174,13 @@ function getSlideTransitionAnimations(type, durationMs, direction, orient, spoke
16198
17174
  const randomType = RANDOM_ELIGIBLE_TYPES[Math.floor(Math.random() * RANDOM_ELIGIBLE_TYPES.length)];
16199
17175
  return getSlideTransitionAnimations(randomType, durationMs, direction, orient);
16200
17176
  }
16201
- // ── Exotic / 3-D transitions approximated with the closest well-tested
16202
- // 2-D CSS behaviour (delegates to an existing case rather than emitting a
16203
- // plain fade). A faithful per-effect keyframe set is available via
16204
- // `getP14TransitionAnimations`.
16205
- case "pan":
16206
- case "gallery":
16207
- case "conveyor":
16208
- return getSlideTransitionAnimations("push", durationMs, direction, orient);
16209
- case "reveal":
16210
- return getSlideTransitionAnimations("wipe", durationMs, direction, orient);
16211
- case "doors":
16212
- return getSlideTransitionAnimations("split", durationMs, direction, orient);
16213
- case "switch":
16214
- case "flythrough":
16215
- case "ferris":
16216
- case "prism":
16217
- return getSlideTransitionAnimations("zoom", durationMs, direction, orient);
16218
- case "ripple":
16219
- case "honeycomb":
16220
- case "glitter":
16221
- case "shred":
16222
- return getSlideTransitionAnimations("dissolve", durationMs, direction, orient);
16223
- case "flash":
16224
- return getSlideTransitionAnimations("fade", durationMs, direction, orient);
16225
- // Fallback (unknown / not-yet-mapped type) — symmetrical cross-fade.
17177
+ // The exotic / 3-D transition family (conveyor/doors/ferris/flash/
17178
+ // flythrough/gallery/glitter/honeycomb/pan/prism/reveal/ripple/shred/
17179
+ // switch/vortex/warp/wheelReverse/window) is handled faithfully above via
17180
+ // `getP14TransitionAnimations` and never reaches this switch.
17181
+ // Fallback (unknown / not-yet-mapped type, e.g. the p15 cinematic set:
17182
+ // cube/flip/rotate/orbit/fracture/peelOff/pageCurl*/airplane/origami)
17183
+ // — symmetrical cross-fade.
16226
17184
  default:
16227
17185
  return {
16228
17186
  outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
@@ -16947,30 +17905,46 @@ function computeTargetLayout(nodes, box, palette, style, elementId) {
16947
17905
  family: "target"
16948
17906
  };
16949
17907
  }
16950
- function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout) {
17908
+ function interpolateSmartArtPalette(palette, count, method, hueDirection) {
17909
+ if (count <= 0 || palette.length === 0) {
17910
+ return [];
17911
+ }
17912
+ if (palette.length < 2 || count <= palette.length) {
17913
+ return Array.from({ length: count }, (_, i) => palette[i % palette.length]);
17914
+ }
17915
+ const segments = palette.length - 1;
17916
+ return Array.from({ length: count }, (_, i) => {
17917
+ const pos = i / (count - 1) * segments;
17918
+ const lower = Math.min(Math.floor(pos), segments - 1);
17919
+ const frac = pos - lower;
17920
+ return interpolateColor(palette[lower], palette[lower + 1], frac, "hsl", hueDirection);
17921
+ });
17922
+ }
17923
+ function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout, interpolation) {
16951
17924
  const flat = flattenNodes(nodes);
16952
17925
  const family = resolveLayoutFamily(nodes, resolvedLayoutType, layout);
17926
+ const pal = interpolation?.method === "span" ? interpolateSmartArtPalette(palette, flat.length, "span", interpolation.hueDirection) : palette;
16953
17927
  switch (family) {
16954
17928
  case "list":
16955
- return computeListLayout(flat, box, palette, style, elementId);
17929
+ return computeListLayout(flat, box, pal, style, elementId);
16956
17930
  case "process":
16957
- return computeProcessLayout(flat, box, palette, style, elementId);
17931
+ return computeProcessLayout(flat, box, pal, style, elementId);
16958
17932
  case "cycle":
16959
- return computeCycleLayout(flat, box, palette, style, elementId);
17933
+ return computeCycleLayout(flat, box, pal, style, elementId);
16960
17934
  case "hierarchy":
16961
- return computeHierarchyLayout(nodes, box, palette, style, elementId);
17935
+ return computeHierarchyLayout(nodes, box, pal, style, elementId);
16962
17936
  case "matrix":
16963
- return computeMatrixLayout(flat, box, palette, style, elementId);
17937
+ return computeMatrixLayout(flat, box, pal, style, elementId);
16964
17938
  case "radial":
16965
- return computeRadialLayout(flat, box, palette, style, elementId);
17939
+ return computeRadialLayout(flat, box, pal, style, elementId);
16966
17940
  case "pyramid":
16967
- return computePyramidLayout(flat, box, palette, style, elementId);
17941
+ return computePyramidLayout(flat, box, pal, style, elementId);
16968
17942
  case "venn":
16969
- return computeVennLayout(flat, box, palette, style, elementId);
17943
+ return computeVennLayout(flat, box, pal, style, elementId);
16970
17944
  case "funnel":
16971
- return computeFunnelLayout(flat, box, palette, style, elementId);
17945
+ return computeFunnelLayout(flat, box, pal, style, elementId);
16972
17946
  case "target":
16973
- return computeTargetLayout(flat, box, palette, style, elementId);
17947
+ return computeTargetLayout(flat, box, pal, style, elementId);
16974
17948
  }
16975
17949
  }
16976
17950
  function parseViewBox(viewBox) {