pptx-react-viewer 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/{AiChatPanel-35CHYS5N.mjs → AiChatPanel-EX2TBRJM.mjs} +4 -4
  3. package/dist/AiChatPanel-EX2TBRJM.mjs.br +0 -0
  4. package/dist/AiChatPanel-EX2TBRJM.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-KTMWRUD5.js → AiChatPanel-PJPSDMN4.js} +23 -23
  6. package/dist/AiChatPanel-PJPSDMN4.js.br +0 -0
  7. package/dist/AiChatPanel-PJPSDMN4.js.gz +0 -0
  8. package/dist/{Model3DScene-2VMN3B65.mjs → Model3DScene-TTQFV7OS.mjs} +1 -1
  9. package/dist/Model3DScene-TTQFV7OS.mjs.br +0 -0
  10. package/dist/Model3DScene-TTQFV7OS.mjs.gz +0 -0
  11. package/dist/{Model3DScene-TMNUKCL6.js → Model3DScene-UCBPTEAY.js} +2 -2
  12. package/dist/Model3DScene-UCBPTEAY.js.br +0 -0
  13. package/dist/Model3DScene-UCBPTEAY.js.gz +0 -0
  14. package/dist/{SurfaceChart3DScene-GKRDDN2U.mjs → SurfaceChart3DScene-5SZCRHZI.mjs} +1 -1
  15. package/dist/{SurfaceChart3DScene-GKRDDN2U.mjs.br → SurfaceChart3DScene-5SZCRHZI.mjs.br} +0 -0
  16. package/dist/SurfaceChart3DScene-5SZCRHZI.mjs.gz +0 -0
  17. package/dist/{SurfaceChart3DScene-KPNP3QD5.js → SurfaceChart3DScene-ADKCYYOQ.js} +2 -2
  18. package/dist/SurfaceChart3DScene-ADKCYYOQ.js.br +0 -0
  19. package/dist/SurfaceChart3DScene-ADKCYYOQ.js.gz +0 -0
  20. package/dist/{chunk-A7HLINZU.js → chunk-4J7SPY64.js} +334 -324
  21. package/dist/chunk-4J7SPY64.js.br +0 -0
  22. package/dist/chunk-4J7SPY64.js.gz +0 -0
  23. package/dist/{chunk-SL3XPERE.mjs → chunk-53NXKDMZ.mjs} +47 -0
  24. package/dist/chunk-53NXKDMZ.mjs.br +0 -0
  25. package/dist/chunk-53NXKDMZ.mjs.gz +0 -0
  26. package/dist/{chunk-TJ55KUWH.mjs → chunk-C2UWTH42.mjs} +859 -112
  27. package/dist/chunk-C2UWTH42.mjs.br +0 -0
  28. package/dist/chunk-C2UWTH42.mjs.gz +0 -0
  29. package/dist/{chunk-JWMXOYSX.js → chunk-E367QIKR.js} +2162 -1736
  30. package/dist/chunk-E367QIKR.js.br +0 -0
  31. package/dist/chunk-E367QIKR.js.gz +0 -0
  32. package/dist/{chunk-OHPF2HTP.mjs → chunk-HK2UERUX.mjs} +13 -3
  33. package/dist/chunk-HK2UERUX.mjs.br +0 -0
  34. package/dist/chunk-HK2UERUX.mjs.gz +0 -0
  35. package/dist/{chunk-H74UXL4Q.js → chunk-HMQVOPQH.js} +880 -111
  36. package/dist/chunk-HMQVOPQH.js.br +0 -0
  37. package/dist/chunk-HMQVOPQH.js.gz +0 -0
  38. package/dist/{chunk-LCG7WBAG.mjs → chunk-L2CM5EUD.mjs} +491 -65
  39. package/dist/chunk-L2CM5EUD.mjs.br +0 -0
  40. package/dist/chunk-L2CM5EUD.mjs.gz +0 -0
  41. package/dist/{chunk-IJVDNQLG.js → chunk-MM5RMRSP.js} +275 -249
  42. package/dist/chunk-MM5RMRSP.js.br +0 -0
  43. package/dist/chunk-MM5RMRSP.js.gz +0 -0
  44. package/dist/{chunk-MMK4K3QI.js → chunk-N6IHR6PS.js} +47 -0
  45. package/dist/chunk-N6IHR6PS.js.br +0 -0
  46. package/dist/chunk-N6IHR6PS.js.gz +0 -0
  47. package/dist/{chunk-FY2AFXKP.mjs → chunk-RJEY2KZH.mjs} +29 -4
  48. package/dist/chunk-RJEY2KZH.mjs.br +0 -0
  49. package/dist/chunk-RJEY2KZH.mjs.gz +0 -0
  50. package/dist/{chunk-LXTKPSIG.mjs → chunk-UZVRM6LD.mjs} +1 -1
  51. package/dist/chunk-UZVRM6LD.mjs.br +0 -0
  52. package/dist/{chunk-LXTKPSIG.mjs.gz → chunk-UZVRM6LD.mjs.gz} +0 -0
  53. package/dist/{chunk-SPJR6MPI.js → chunk-VNP627O5.js} +3 -3
  54. package/dist/chunk-VNP627O5.js.br +0 -0
  55. package/dist/chunk-VNP627O5.js.gz +0 -0
  56. package/dist/i18n.js +4 -4
  57. package/dist/i18n.js.br +0 -0
  58. package/dist/i18n.js.gz +0 -0
  59. package/dist/i18n.mjs +1 -1
  60. package/dist/i18n.mjs.br +0 -0
  61. package/dist/i18n.mjs.gz +0 -0
  62. package/dist/index.d.ts +24 -3
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +36 -36
  65. package/dist/index.js.br +0 -0
  66. package/dist/index.js.gz +0 -0
  67. package/dist/index.mjs +6 -6
  68. package/dist/index.mjs.br +0 -0
  69. package/dist/index.mjs.gz +0 -0
  70. package/dist/internals.d.ts +26 -2
  71. package/dist/internals.d.ts.map +1 -1
  72. package/dist/internals.js +79 -79
  73. package/dist/internals.js.br +0 -0
  74. package/dist/internals.js.gz +0 -0
  75. package/dist/internals.mjs +4 -4
  76. package/dist/internals.mjs.br +0 -0
  77. package/dist/internals.mjs.gz +0 -0
  78. package/dist/pptx-viewer.css +1 -1
  79. package/dist/pptx-viewer.css.br +0 -0
  80. package/dist/pptx-viewer.css.gz +0 -0
  81. package/dist/{useViewerBuildingBlocks-CpUwhBD5.d.ts → useViewerBuildingBlocks-Rqxm0pRS.d.ts} +17 -5
  82. package/dist/useViewerBuildingBlocks-Rqxm0pRS.d.ts.map +1 -0
  83. package/dist/viewer/index.js +22 -22
  84. package/dist/viewer/index.js.br +0 -0
  85. package/dist/viewer/index.js.gz +0 -0
  86. package/dist/viewer/index.mjs +6 -6
  87. package/dist/viewer/index.mjs.br +0 -0
  88. package/dist/viewer/index.mjs.gz +0 -0
  89. package/package.json +1 -1
  90. package/dist/AiChatPanel-35CHYS5N.mjs.br +0 -0
  91. package/dist/AiChatPanel-35CHYS5N.mjs.gz +0 -0
  92. package/dist/AiChatPanel-KTMWRUD5.js.br +0 -0
  93. package/dist/AiChatPanel-KTMWRUD5.js.gz +0 -0
  94. package/dist/Model3DScene-2VMN3B65.mjs.br +0 -0
  95. package/dist/Model3DScene-2VMN3B65.mjs.gz +0 -0
  96. package/dist/Model3DScene-TMNUKCL6.js.br +0 -0
  97. package/dist/Model3DScene-TMNUKCL6.js.gz +0 -0
  98. package/dist/SurfaceChart3DScene-GKRDDN2U.mjs.gz +0 -0
  99. package/dist/SurfaceChart3DScene-KPNP3QD5.js.br +0 -0
  100. package/dist/SurfaceChart3DScene-KPNP3QD5.js.gz +0 -0
  101. package/dist/chunk-A7HLINZU.js.br +0 -0
  102. package/dist/chunk-A7HLINZU.js.gz +0 -0
  103. package/dist/chunk-FY2AFXKP.mjs.br +0 -0
  104. package/dist/chunk-FY2AFXKP.mjs.gz +0 -0
  105. package/dist/chunk-H74UXL4Q.js.br +0 -0
  106. package/dist/chunk-H74UXL4Q.js.gz +0 -0
  107. package/dist/chunk-IJVDNQLG.js.br +0 -0
  108. package/dist/chunk-IJVDNQLG.js.gz +0 -0
  109. package/dist/chunk-JWMXOYSX.js.br +0 -0
  110. package/dist/chunk-JWMXOYSX.js.gz +0 -0
  111. package/dist/chunk-LCG7WBAG.mjs.br +0 -0
  112. package/dist/chunk-LCG7WBAG.mjs.gz +0 -0
  113. package/dist/chunk-LXTKPSIG.mjs.br +0 -0
  114. package/dist/chunk-MMK4K3QI.js.br +0 -0
  115. package/dist/chunk-MMK4K3QI.js.gz +0 -0
  116. package/dist/chunk-OHPF2HTP.mjs.br +0 -0
  117. package/dist/chunk-OHPF2HTP.mjs.gz +0 -0
  118. package/dist/chunk-SL3XPERE.mjs.br +0 -0
  119. package/dist/chunk-SL3XPERE.mjs.gz +0 -0
  120. package/dist/chunk-SPJR6MPI.js.br +0 -0
  121. package/dist/chunk-SPJR6MPI.js.gz +0 -0
  122. package/dist/chunk-TJ55KUWH.mjs.br +0 -0
  123. package/dist/chunk-TJ55KUWH.mjs.gz +0 -0
  124. package/dist/useViewerBuildingBlocks-CpUwhBD5.d.ts.map +0 -1
@@ -46608,8 +46608,8 @@ function applyImageColorEffects(blip, effects, parseColor, extractOpacity) {
46608
46608
  const rawFrom = child19(change.rawXml, "clrFrom");
46609
46609
  const rawTo = child19(change.rawXml, "clrTo");
46610
46610
  const rawTransparent = rawTo ? (opacity(rawTo, extractOpacity) ?? 1) <= 0 : void 0;
46611
- const unchanged = sameRawColor(rawFrom, change.clrFrom, parseColor) && sameRawColor(rawTo, change.clrTo, parseColor) && (rawTransparent === void 0 || change.clrToTransparent === rawTransparent);
46612
- if (unchanged && change.rawXml) {
46611
+ const unchanged2 = sameRawColor(rawFrom, change.clrFrom, parseColor) && sameRawColor(rawTo, change.clrTo, parseColor) && (rawTransparent === void 0 || change.clrToTransparent === rawTransparent);
46612
+ if (unchanged2 && change.rawXml) {
46613
46613
  setChild6(blip, "clrChange", change.rawXml);
46614
46614
  } else {
46615
46615
  const fromChoice = sameRawColor(rawFrom, change.clrFrom, parseColor) ? extractColorChoiceXml(rawFrom) : buildSrgbColorChoice(change.clrFrom);
@@ -50614,8 +50614,8 @@ var PptxHandlerRuntime14 = class extends PptxHandlerRuntime13 {
50614
50614
  }
50615
50615
  const notesBodyShape = shapes.find((shape) => {
50616
50616
  const placeholder = shape?.["p:nvSpPr"]?.["p:nvPr"]?.["p:ph"];
50617
- const placeholderType = String(placeholder?.["@_type"] || "").trim().toLowerCase();
50618
- return placeholderType === "body";
50617
+ const placeholderType2 = String(placeholder?.["@_type"] || "").trim().toLowerCase();
50618
+ return placeholderType2 === "body";
50619
50619
  }) || shapes.find((shape) => Boolean(shape?.["p:txBody"])) || shapes[0];
50620
50620
  if (!notesBodyShape) {
50621
50621
  return false;
@@ -51453,10 +51453,16 @@ var PptxHandlerRuntime17 = class extends PptxHandlerRuntime16 {
51453
51453
  * survive a save: collapsing them to the plain-text path silently downgrades
51454
51454
  * a field to static text (e.g. a slide-number field becomes a frozen number)
51455
51455
  * or drops the equation, ruby, or bullet.
51456
+ *
51457
+ * `paragraphLevel` (`a:pPr/@lvl`) belongs on this list for the same reason
51458
+ * and used to be missing from it: a nested bullet whose runs all share one
51459
+ * style looked "uniform", so the save path discarded its segments and rebuilt
51460
+ * the paragraph from the flat string, which carries no indent level. Every
51461
+ * such paragraph came back from a round-trip flattened to the top level.
51456
51462
  */
51457
51463
  isStructuralTextSegment(segment) {
51458
51464
  return Boolean(
51459
- segment.fieldType || segment.equationXml || segment.rubyText || segment.bulletInfo
51465
+ segment.fieldType || segment.equationXml || segment.rubyText || segment.bulletInfo || segment.paragraphLevel
51460
51466
  );
51461
51467
  }
51462
51468
  areTextSegmentsUniform(textSegments) {
@@ -87147,6 +87153,14 @@ function resolveDataPointExplosion(series, pointIndex) {
87147
87153
  const point = findDataPoint(series, pointIndex);
87148
87154
  return point?.explosion ?? series.explosion ?? 0;
87149
87155
  }
87156
+ function resolveDataPointMarker(series, pointIndex) {
87157
+ const point = findDataPoint(series, pointIndex)?.marker;
87158
+ return {
87159
+ symbol: point?.symbol ?? series.marker?.symbol,
87160
+ size: point?.size ?? series.marker?.size,
87161
+ fill: point?.spPr?.fillColor ?? series.marker?.spPr?.fillColor
87162
+ };
87163
+ }
87150
87164
  function addChartSeries(data) {
87151
87165
  return chartDataAddSeries(data, {
87152
87166
  name: `Series ${data.series.length + 1}`,
@@ -88034,13 +88048,16 @@ function buildMarkerPrimitive(input) {
88034
88048
  return { kind: "circle", cx, cy, r, fill, part };
88035
88049
  }
88036
88050
  }
88037
- function pushMarker(out, series, cx, cy, fill, defaultRadius2, part, opacity2) {
88051
+ function pushMarker(out, series, pointIndex, cx, cy, fill, defaultRadius2, part, opacity2) {
88052
+ const marker = resolveDataPointMarker(series, pointIndex);
88038
88053
  const m = buildMarkerPrimitive({
88039
- symbol: series.marker?.symbol,
88040
- size: series.marker?.size,
88054
+ symbol: marker.symbol,
88055
+ size: marker.size,
88041
88056
  cx,
88042
88057
  cy,
88043
- fill,
88058
+ // A marker fill (series or per-point) wins over the plot fill, which is
88059
+ // what the line/area body is drawn with.
88060
+ fill: marker.fill ?? fill,
88044
88061
  defaultRadius: defaultRadius2,
88045
88062
  part
88046
88063
  });
@@ -88120,6 +88137,7 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
88120
88137
  pushMarker(
88121
88138
  primitives,
88122
88139
  series,
88140
+ idx,
88123
88141
  pt.x,
88124
88142
  pt.y,
88125
88143
  resolveDataPointFill(series, idx, c) ?? c,
@@ -88191,6 +88209,7 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices2, xPositio
88191
88209
  pushMarker(
88192
88210
  primitives,
88193
88211
  series,
88212
+ idx,
88194
88213
  pt.x,
88195
88214
  pt.y,
88196
88215
  resolveDataPointFill(series, idx, c) ?? c,
@@ -88234,6 +88253,7 @@ function buildScatter(chartData, layout, range) {
88234
88253
  pushMarker(
88235
88254
  primitives,
88236
88255
  series,
88256
+ vi,
88237
88257
  dot.cx,
88238
88258
  dot.cy,
88239
88259
  resolveDataPointFill(series, vi, c) ?? c,
@@ -93703,6 +93723,10 @@ function applyFlyDirection(effect, subtype) {
93703
93723
  const suffix = `${edge.charAt(0).toUpperCase()}${edge.slice(1)}`;
93704
93724
  return `${prefix}${suffix}`;
93705
93725
  }
93726
+ function slideOffset(percent2, axis) {
93727
+ const fallback = axis === "w" ? "1280px" : "720px";
93728
+ return `calc(var(--pptx-slide-${axis}, ${fallback}) * ${(percent2 / 100).toFixed(4)})`;
93729
+ }
93706
93730
  function buildDynamicKeyframe(anim, uid) {
93707
93731
  if (anim.motionPath) {
93708
93732
  const name = `pptx-tl-motion-${uid}`;
@@ -93713,8 +93737,8 @@ function buildDynamicKeyframe(anim, uid) {
93713
93737
  const lines = [];
93714
93738
  for (let i = 0; i < points3.length; i++) {
93715
93739
  const pct = Math.round(i / (points3.length - 1) * 100);
93716
- const tx = points3[i].x.toFixed(2);
93717
- const ty = points3[i].y.toFixed(2);
93740
+ const tx = slideOffset(points3[i].x, "w");
93741
+ const ty = slideOffset(points3[i].y, "h");
93718
93742
  if (anim.motionPathRotateAuto) {
93719
93743
  const next = i < points3.length - 1 ? points3[i + 1] : points3[i];
93720
93744
  const prev = i > 0 ? points3[i - 1] : points3[i];
@@ -93722,10 +93746,10 @@ function buildDynamicKeyframe(anim, uid) {
93722
93746
  const dy = i < points3.length - 1 ? next.y - points3[i].y : points3[i].y - prev.y;
93723
93747
  const angleDeg = Math.atan2(dy, dx) * (180 / Math.PI);
93724
93748
  lines.push(
93725
- ` ${pct}% { transform: translate(${tx}%, ${ty}%) rotate(${angleDeg.toFixed(2)}deg); }`
93749
+ ` ${pct}% { transform: translate(${tx}, ${ty}) rotate(${angleDeg.toFixed(2)}deg); }`
93726
93750
  );
93727
93751
  } else {
93728
- lines.push(` ${pct}% { transform: translate(${tx}%, ${ty}%); }`);
93752
+ lines.push(` ${pct}% { transform: translate(${tx}, ${ty}); }`);
93729
93753
  }
93730
93754
  }
93731
93755
  return {
@@ -94860,6 +94884,422 @@ var TimelineEngine = class _TimelineEngine {
94860
94884
  }
94861
94885
  }
94862
94886
  };
94887
+ var PRESET_TO_EFFECT = {
94888
+ fadeIn: "fadeIn",
94889
+ flyIn: "flyInBottom",
94890
+ zoomIn: "zoomIn",
94891
+ fadeOut: "fadeOut",
94892
+ flyOut: "flyOutBottom",
94893
+ zoomOut: "zoomOut",
94894
+ spin: "spin",
94895
+ pulse: "pulse",
94896
+ colorWave: "colorWave",
94897
+ bounce: "bounce",
94898
+ flash: "flash"
94899
+ };
94900
+ var DIRECTION_FLY_MAP = {
94901
+ fromLeft: { flyIn: "flyInLeft", flyOut: "flyOutLeft" },
94902
+ fromRight: { flyIn: "flyInRight", flyOut: "flyOutRight" },
94903
+ fromTop: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94904
+ fromBottom: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
94905
+ fromTopLeft: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94906
+ fromTopRight: { flyIn: "flyInTop", flyOut: "flyOutTop" },
94907
+ fromBottomLeft: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
94908
+ fromBottomRight: { flyIn: "flyInBottom", flyOut: "flyOutBottom" }
94909
+ };
94910
+ function resolvePreviewEffect(preset, direction) {
94911
+ if ((preset === "flyIn" || preset === "flyOut") && direction) {
94912
+ const dirMap = DIRECTION_FLY_MAP[direction];
94913
+ if (dirMap) {
94914
+ return preset === "flyIn" ? dirMap.flyIn : dirMap.flyOut;
94915
+ }
94916
+ }
94917
+ return PRESET_TO_EFFECT[preset];
94918
+ }
94919
+ function timingCurveToCss(curve, cubicBezierValues) {
94920
+ if (cubicBezierValues) {
94921
+ const parts = cubicBezierValues.split(",").map((s) => s.trim());
94922
+ if (parts.length === 4 && parts.every((p) => !Number.isNaN(Number(p)))) {
94923
+ return `cubic-bezier(${parts.join(", ")})`;
94924
+ }
94925
+ }
94926
+ switch (curve) {
94927
+ case "ease":
94928
+ return "ease";
94929
+ case "ease-in":
94930
+ return "ease-in";
94931
+ case "ease-out":
94932
+ return "ease-out";
94933
+ case "linear":
94934
+ return "linear";
94935
+ default:
94936
+ return "ease";
94937
+ }
94938
+ }
94939
+ function buildPreviewAnimation(preset, options) {
94940
+ if (preset === "none") {
94941
+ return void 0;
94942
+ }
94943
+ const effectName = resolvePreviewEffect(preset, options?.direction);
94944
+ if (!effectName) {
94945
+ return void 0;
94946
+ }
94947
+ const keyframeName = `pptx-${effectName}`;
94948
+ const keyframesCss = getEffectKeyframes(effectName);
94949
+ if (!keyframesCss) {
94950
+ return void 0;
94951
+ }
94952
+ const duration = options?.durationMs ?? 600;
94953
+ const easing = timingCurveToCss(options?.timingCurve, options?.cubicBezier);
94954
+ return {
94955
+ keyframeName,
94956
+ keyframesCss,
94957
+ cssAnimation: `${keyframeName} ${duration}ms ${easing} 0ms 1 normal both`,
94958
+ durationMs: duration
94959
+ };
94960
+ }
94961
+ var EDITABLE = /* @__PURE__ */ new Set(["M", "L", "C", "Z", "m", "l", "c", "z"]);
94962
+ var ARITY = { m: 2, l: 2, c: 6, z: 0 };
94963
+ function scanPath(path) {
94964
+ const tokens = path.match(/[A-Za-z]|-?\d*\.?\d+(?:[eE][-+]?\d+)?/gu);
94965
+ if (!tokens) {
94966
+ return void 0;
94967
+ }
94968
+ const segments = [];
94969
+ let i = 0;
94970
+ let cmd = "";
94971
+ while (i < tokens.length) {
94972
+ if (/^[A-Za-z]$/u.test(tokens[i])) {
94973
+ cmd = tokens[i];
94974
+ i++;
94975
+ if (!EDITABLE.has(cmd)) {
94976
+ return void 0;
94977
+ }
94978
+ if (cmd === "Z" || cmd === "z") {
94979
+ segments.push({ cmd, coords: [] });
94980
+ }
94981
+ continue;
94982
+ }
94983
+ const arity = ARITY[cmd.toLowerCase()];
94984
+ if (!arity) {
94985
+ return void 0;
94986
+ }
94987
+ const coords = [];
94988
+ for (let n = 0; n < arity; n++) {
94989
+ const value = Number(tokens[i++]);
94990
+ if (!Number.isFinite(value)) {
94991
+ return void 0;
94992
+ }
94993
+ coords.push(value);
94994
+ }
94995
+ segments.push({ cmd, coords });
94996
+ if (cmd === "M") {
94997
+ cmd = "L";
94998
+ } else if (cmd === "m") {
94999
+ cmd = "l";
95000
+ }
95001
+ }
95002
+ return segments.length > 0 ? segments : void 0;
95003
+ }
95004
+ function formatPath(segments) {
95005
+ return segments.map(
95006
+ (segment) => segment.coords.length === 0 ? segment.cmd : `${segment.cmd} ${segment.coords.map((n) => trimNumber(n)).join(" ")}`
95007
+ ).join(" ");
95008
+ }
95009
+ function trimNumber(value) {
95010
+ return String(Number(value.toFixed(4)));
95011
+ }
95012
+ function motionPathFractionPoints(path) {
95013
+ return parseMotionPathPoints(path).map((point) => ({ x: point.x / 100, y: point.y / 100 }));
95014
+ }
95015
+ function toPixels(point, frame2) {
95016
+ return {
95017
+ x: frame2.originX + point.x * frame2.slideWidth,
95018
+ y: frame2.originY + point.y * frame2.slideHeight
95019
+ };
95020
+ }
95021
+ function motionPathToSvgD(path, frame2) {
95022
+ const points3 = motionPathFractionPoints(path).map((point) => toPixels(point, frame2));
95023
+ if (points3.length === 0) {
95024
+ return "";
95025
+ }
95026
+ const head = `M ${trimNumber(frame2.originX)} ${trimNumber(frame2.originY)}`;
95027
+ const rest = points3.map((point) => `L ${trimNumber(point.x)} ${trimNumber(point.y)}`);
95028
+ return [head, ...rest].join(" ");
95029
+ }
95030
+ function motionPathEndPixel(path, frame2) {
95031
+ const points3 = motionPathFractionPoints(path);
95032
+ const last = points3.length > 0 ? points3[points3.length - 1] : void 0;
95033
+ return last ? toPixels(last, frame2) : { x: frame2.originX, y: frame2.originY };
95034
+ }
95035
+ function setMotionPathEnd(path, x, y) {
95036
+ const segments = scanPath(path);
95037
+ if (!segments) {
95038
+ return path;
95039
+ }
95040
+ let lastIndex = -1;
95041
+ for (let i = segments.length - 1; i >= 0; i--) {
95042
+ if (segments[i].coords.length > 0) {
95043
+ lastIndex = i;
95044
+ break;
95045
+ }
95046
+ }
95047
+ if (lastIndex < 0 || segments.some((segment) => segment.cmd === "Z" || segment.cmd === "z")) {
95048
+ return path;
95049
+ }
95050
+ const last = segments[lastIndex];
95051
+ if (last.cmd === last.cmd.toLowerCase()) {
95052
+ return path;
95053
+ }
95054
+ const coords = [...last.coords];
95055
+ const endX = coords[coords.length - 2];
95056
+ const endY = coords[coords.length - 1];
95057
+ const dx = x - endX;
95058
+ const dy = y - endY;
95059
+ coords[coords.length - 2] = x;
95060
+ coords[coords.length - 1] = y;
95061
+ if (last.cmd === "C") {
95062
+ coords[2] += dx;
95063
+ coords[3] += dy;
95064
+ }
95065
+ const next = segments.map(
95066
+ (segment, index) => index === lastIndex ? { ...last, coords } : segment
95067
+ );
95068
+ return formatPath(next);
95069
+ }
95070
+ function isEditableMotionPath(path) {
95071
+ const segments = scanPath(path);
95072
+ if (!segments) {
95073
+ return false;
95074
+ }
95075
+ return !segments.some((segment) => segment.cmd === "Z" || segment.cmd === "z");
95076
+ }
95077
+ function buildMotionPathKeyframes(args) {
95078
+ const points3 = motionPathFractionPoints(args.path);
95079
+ if (points3.length < 2) {
95080
+ return void 0;
95081
+ }
95082
+ const frames = points3.map((point, index) => {
95083
+ const percent2 = Math.round(index / (points3.length - 1) * 100);
95084
+ const x = trimNumber(point.x * args.slideWidth);
95085
+ const y = trimNumber(point.y * args.slideHeight);
95086
+ return ` ${percent2}% { transform: translate(${x}px, ${y}px); }`;
95087
+ });
95088
+ return {
95089
+ keyframeName: args.keyframeName,
95090
+ css: `@keyframes ${args.keyframeName} {
95091
+ ${frames.join("\n")}
95092
+ }`
95093
+ };
95094
+ }
95095
+ var K = 0.5523;
95096
+ var RX = 0.125;
95097
+ var RY = 0.2222;
95098
+ var CIRCLE = [
95099
+ "M 0 0",
95100
+ `C ${-K * RX} 0 ${-RX} ${-RY + K * RY} ${-RX} ${-RY}`,
95101
+ `C ${-RX} ${-RY - K * RY} ${-K * RX} ${ -2 * RY} 0 ${ -2 * RY}`,
95102
+ `C ${K * RX} ${ -2 * RY} ${RX} ${-RY - K * RY} ${RX} ${-RY}`,
95103
+ `C ${RX} ${-RY + K * RY} ${K * RX} 0 0 0`
95104
+ ].join(" ").replace(/(\d\.\d{4})\d+/gu, "$1");
95105
+ var MOTION_PATH_PRESETS2 = [
95106
+ // -- Lines ---------------------------------------------------------------
95107
+ { id: "lineRight", family: "lines", path: "M 0 0 L 0.25 0" },
95108
+ { id: "lineLeft", family: "lines", path: "M 0 0 L -0.25 0" },
95109
+ { id: "lineDown", family: "lines", path: "M 0 0 L 0 0.25" },
95110
+ { id: "lineUp", family: "lines", path: "M 0 0 L 0 -0.25" },
95111
+ { id: "lineDiagonalUpRight", family: "lines", path: "M 0 0 L 0.25 -0.25" },
95112
+ { id: "lineDiagonalDownRight", family: "lines", path: "M 0 0 L 0.25 0.25" },
95113
+ { id: "lineDiagonalUpLeft", family: "lines", path: "M 0 0 L -0.25 -0.25" },
95114
+ { id: "lineDiagonalDownLeft", family: "lines", path: "M 0 0 L -0.25 0.25" },
95115
+ // -- Arcs ----------------------------------------------------------------
95116
+ {
95117
+ id: "arcUp",
95118
+ family: "arcs",
95119
+ path: "M 0 0 C 0 -0.1227 0.0559 -0.2222 0.125 -0.2222 C 0.1941 -0.2222 0.25 -0.1227 0.25 0"
95120
+ },
95121
+ {
95122
+ id: "arcDown",
95123
+ family: "arcs",
95124
+ path: "M 0 0 C 0 0.1227 0.0559 0.2222 0.125 0.2222 C 0.1941 0.2222 0.25 0.1227 0.25 0"
95125
+ },
95126
+ {
95127
+ id: "arcRight",
95128
+ family: "arcs",
95129
+ path: "M 0 0 C 0.069 0 0.125 0.0995 0.125 0.2222 C 0.125 0.3449 0.069 0.4444 0 0.4444"
95130
+ },
95131
+ {
95132
+ id: "arcLeft",
95133
+ family: "arcs",
95134
+ path: "M 0 0 C -0.069 0 -0.125 0.0995 -0.125 0.2222 C -0.125 0.3449 -0.069 0.4444 0 0.4444"
95135
+ },
95136
+ // -- Turns ---------------------------------------------------------------
95137
+ { id: "turnUp", family: "turns", path: "M 0 0 L 0.25 0 L 0.25 -0.25" },
95138
+ { id: "turnDown", family: "turns", path: "M 0 0 L 0.25 0 L 0.25 0.25" },
95139
+ { id: "turnRight", family: "turns", path: "M 0 0 L 0 0.25 L 0.25 0.25" },
95140
+ { id: "turnLeft", family: "turns", path: "M 0 0 L 0 0.25 L -0.25 0.25" },
95141
+ {
95142
+ id: "sCurve",
95143
+ family: "turns",
95144
+ path: "M 0 0 C 0.0833 -0.1111 0.1667 0.1111 0.25 0"
95145
+ },
95146
+ {
95147
+ id: "zigzag",
95148
+ family: "turns",
95149
+ path: "M 0 0 L 0.0625 -0.1111 L 0.125 0 L 0.1875 -0.1111 L 0.25 0"
95150
+ },
95151
+ // -- Shapes --------------------------------------------------------------
95152
+ { id: "circle", family: "shapes", path: CIRCLE },
95153
+ { id: "square", family: "shapes", path: "M 0 0 L 0.125 0 L 0.125 -0.2222 L 0 -0.2222 Z" },
95154
+ { id: "triangle", family: "shapes", path: "M 0 0 L 0.0625 -0.2222 L 0.125 0 Z" },
95155
+ {
95156
+ id: "diamond",
95157
+ family: "shapes",
95158
+ path: "M 0 0 L 0.0625 -0.1111 L 0.125 0 L 0.0625 0.1111 Z"
95159
+ },
95160
+ {
95161
+ id: "hexagon",
95162
+ family: "shapes",
95163
+ path: "M 0 0 L 0.0417 -0.1111 L 0.125 -0.1111 L 0.1667 0 L 0.125 0.1111 L 0.0417 0.1111 Z"
95164
+ },
95165
+ // -- Loops ---------------------------------------------------------------
95166
+ {
95167
+ id: "loopDeLoop",
95168
+ family: "loops",
95169
+ path: "M 0 0 C 0.0625 0 0.0972 -0.2222 0.1667 -0.2222 C 0.2361 -0.2222 0.2708 0 0.1667 0 L 0.3333 0"
95170
+ },
95171
+ {
95172
+ id: "figureEight",
95173
+ family: "loops",
95174
+ path: "M 0 0 C -0.0833 0 -0.0833 -0.2222 0 -0.2222 C 0.0833 -0.2222 0.0833 0 0.1667 0 C 0.25 0 0.25 -0.2222 0.1667 -0.2222 C 0.0833 -0.2222 0.0833 0 0 0"
95175
+ },
95176
+ {
95177
+ id: "spiral",
95178
+ family: "loops",
95179
+ path: "M 0 0 C 0.0417 0 0.0417 -0.0741 0 -0.0741 C -0.0625 -0.0741 -0.0625 -0.1852 0 -0.1852 C 0.0833 -0.1852 0.0833 -0.3333 0 -0.3333"
95180
+ }
95181
+ ];
95182
+ var MOTION_PATH_FAMILIES = [
95183
+ "lines",
95184
+ "arcs",
95185
+ "turns",
95186
+ "shapes",
95187
+ "loops"
95188
+ ];
95189
+ function motionPathFamilyLabelKey(family) {
95190
+ return `pptx.animation.motionPath.family.${family}`;
95191
+ }
95192
+ function motionPathPresetLabelKey(presetId) {
95193
+ return `pptx.animation.motionPath.preset.${presetId}`;
95194
+ }
95195
+ function motionPathPresetById(presetId) {
95196
+ return MOTION_PATH_PRESETS2.find((preset) => preset.id === presetId);
95197
+ }
95198
+ function motionPathPresetsByFamily(family) {
95199
+ return MOTION_PATH_PRESETS2.filter((preset) => preset.family === family);
95200
+ }
95201
+ function motionPathPresetIdForPath(path) {
95202
+ if (!path) {
95203
+ return void 0;
95204
+ }
95205
+ const normalized = path.trim().replace(/\s+/gu, " ");
95206
+ return MOTION_PATH_PRESETS2.find(
95207
+ (preset) => preset.path.trim().replace(/\s+/gu, " ") === normalized
95208
+ )?.id;
95209
+ }
95210
+ var DEFAULT_MOTION_PATH_PRESET_ID = "lineRight";
95211
+ var DEFAULT_MOTION_PATH_DURATION_MS = 2e3;
95212
+ var DEFAULT_TRIGGER2 = "onClick";
95213
+ function motionPathFor(animations, elementId) {
95214
+ return animations.find((animation) => animation.elementId === elementId)?.motionPath;
95215
+ }
95216
+ function setMotionPath(animations, elementId, path) {
95217
+ const index = animations.findIndex((animation) => animation.elementId === elementId);
95218
+ if (index >= 0) {
95219
+ return animations.map(
95220
+ (animation, i) => i === index ? {
95221
+ ...animation,
95222
+ motionPath: path,
95223
+ motionPathEditMode: animation.motionPathEditMode ?? "relative",
95224
+ durationMs: animation.durationMs ?? DEFAULT_MOTION_PATH_DURATION_MS
95225
+ } : animation
95226
+ );
95227
+ }
95228
+ return [
95229
+ ...animations,
95230
+ {
95231
+ elementId,
95232
+ motionPath: path,
95233
+ motionPathEditMode: "relative",
95234
+ durationMs: DEFAULT_MOTION_PATH_DURATION_MS,
95235
+ order: animations.length,
95236
+ trigger: DEFAULT_TRIGGER2
95237
+ }
95238
+ ];
95239
+ }
95240
+ function applyMotionPathPreset(animations, elementId, presetId) {
95241
+ const preset = motionPathPresetById(presetId);
95242
+ if (!preset) {
95243
+ return [...animations];
95244
+ }
95245
+ return setMotionPath(animations, elementId, preset.path);
95246
+ }
95247
+ function clearMotionPath(animations, elementId) {
95248
+ const index = animations.findIndex((animation) => animation.elementId === elementId);
95249
+ if (index < 0) {
95250
+ return [...animations];
95251
+ }
95252
+ const current = animations[index];
95253
+ const stillHasEffect = Boolean(current.entrance || current.emphasis || current.exit);
95254
+ if (!stillHasEffect) {
95255
+ return animations.filter((animation) => animation.elementId !== elementId).map((animation, i) => ({ ...animation, order: i }));
95256
+ }
95257
+ return animations.map(
95258
+ (animation, i) => i === index ? {
95259
+ ...animation,
95260
+ motionPath: void 0,
95261
+ motionPathEditMode: void 0,
95262
+ motionPtsTypes: void 0
95263
+ } : animation
95264
+ );
95265
+ }
95266
+ function motionPathNativeAnimations(slide) {
95267
+ const native = slide.nativeAnimations ?? [];
95268
+ const alreadyNative = new Set(
95269
+ native.filter((animation) => animation.motionPath).map((animation) => animation.targetId)
95270
+ );
95271
+ return (slide.animations ?? []).filter((animation) => Boolean(animation.motionPath) && !alreadyNative.has(animation.elementId)).map((animation) => ({
95272
+ targetId: animation.elementId,
95273
+ trigger: animation.trigger ?? DEFAULT_TRIGGER2,
95274
+ triggerShapeId: animation.triggerShapeId,
95275
+ presetClass: "path",
95276
+ durationMs: animation.durationMs ?? DEFAULT_MOTION_PATH_DURATION_MS,
95277
+ delayMs: animation.delayMs ?? 0,
95278
+ motionPath: animation.motionPath,
95279
+ motionPathEditMode: animation.motionPathEditMode ?? "relative"
95280
+ }));
95281
+ }
95282
+ function buildMotionPathPreview(args) {
95283
+ const keyframeName = `pptx-motion-preview-${args.uid ?? 0}`;
95284
+ const keyframes = buildMotionPathKeyframes({
95285
+ path: args.path,
95286
+ slideWidth: args.slideWidth,
95287
+ slideHeight: args.slideHeight,
95288
+ keyframeName
95289
+ });
95290
+ if (!keyframes) {
95291
+ return void 0;
95292
+ }
95293
+ const durationMs = args.durationMs ?? DEFAULT_MOTION_PATH_DURATION_MS;
95294
+ const delayMs = args.delayMs ?? 0;
95295
+ const easing = timingCurveToCss(args.timingCurve);
95296
+ return {
95297
+ keyframeName,
95298
+ keyframesCss: keyframes.css,
95299
+ cssAnimation: `${keyframeName} ${durationMs}ms ${easing} ${delayMs}ms 1 normal both`,
95300
+ durationMs
95301
+ };
95302
+ }
94863
95303
  function buildSegmentCounts(slide, nativeAnims) {
94864
95304
  const segmentCounts = /* @__PURE__ */ new Map();
94865
95305
  for (const anim of nativeAnims) {
@@ -94892,7 +95332,7 @@ var PresentationAnimationController = class _PresentationAnimationController {
94892
95332
  * id list (base element ids + text-build sub-element ids) to track.
94893
95333
  */
94894
95334
  static fromSlide(slide) {
94895
- const nativeAnims = slide.nativeAnimations ?? [];
95335
+ const nativeAnims = [...slide.nativeAnimations ?? [], ...motionPathNativeAnimations(slide)];
94896
95336
  const segmentCounts = buildSegmentCounts(slide, nativeAnims);
94897
95337
  const expandedAnims = segmentCounts.size > 0 ? expandTextBuildAnimations(nativeAnims, segmentCounts) : nativeAnims;
94898
95338
  const engine = TimelineEngine.fromAnimations(expandedAnims);
@@ -95083,80 +95523,6 @@ function runMediaCommand(command, resolve) {
95083
95523
  }
95084
95524
  return applyMediaCommandVerb(el, parsed);
95085
95525
  }
95086
- var PRESET_TO_EFFECT = {
95087
- fadeIn: "fadeIn",
95088
- flyIn: "flyInBottom",
95089
- zoomIn: "zoomIn",
95090
- fadeOut: "fadeOut",
95091
- flyOut: "flyOutBottom",
95092
- zoomOut: "zoomOut",
95093
- spin: "spin",
95094
- pulse: "pulse",
95095
- colorWave: "colorWave",
95096
- bounce: "bounce",
95097
- flash: "flash"
95098
- };
95099
- var DIRECTION_FLY_MAP = {
95100
- fromLeft: { flyIn: "flyInLeft", flyOut: "flyOutLeft" },
95101
- fromRight: { flyIn: "flyInRight", flyOut: "flyOutRight" },
95102
- fromTop: { flyIn: "flyInTop", flyOut: "flyOutTop" },
95103
- fromBottom: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
95104
- fromTopLeft: { flyIn: "flyInTop", flyOut: "flyOutTop" },
95105
- fromTopRight: { flyIn: "flyInTop", flyOut: "flyOutTop" },
95106
- fromBottomLeft: { flyIn: "flyInBottom", flyOut: "flyOutBottom" },
95107
- fromBottomRight: { flyIn: "flyInBottom", flyOut: "flyOutBottom" }
95108
- };
95109
- function resolvePreviewEffect(preset, direction) {
95110
- if ((preset === "flyIn" || preset === "flyOut") && direction) {
95111
- const dirMap = DIRECTION_FLY_MAP[direction];
95112
- if (dirMap) {
95113
- return preset === "flyIn" ? dirMap.flyIn : dirMap.flyOut;
95114
- }
95115
- }
95116
- return PRESET_TO_EFFECT[preset];
95117
- }
95118
- function timingCurveToCss(curve, cubicBezierValues) {
95119
- if (cubicBezierValues) {
95120
- const parts = cubicBezierValues.split(",").map((s) => s.trim());
95121
- if (parts.length === 4 && parts.every((p) => !Number.isNaN(Number(p)))) {
95122
- return `cubic-bezier(${parts.join(", ")})`;
95123
- }
95124
- }
95125
- switch (curve) {
95126
- case "ease":
95127
- return "ease";
95128
- case "ease-in":
95129
- return "ease-in";
95130
- case "ease-out":
95131
- return "ease-out";
95132
- case "linear":
95133
- return "linear";
95134
- default:
95135
- return "ease";
95136
- }
95137
- }
95138
- function buildPreviewAnimation(preset, options) {
95139
- if (preset === "none") {
95140
- return void 0;
95141
- }
95142
- const effectName = resolvePreviewEffect(preset, options?.direction);
95143
- if (!effectName) {
95144
- return void 0;
95145
- }
95146
- const keyframeName = `pptx-${effectName}`;
95147
- const keyframesCss = getEffectKeyframes(effectName);
95148
- if (!keyframesCss) {
95149
- return void 0;
95150
- }
95151
- const duration = options?.durationMs ?? 600;
95152
- const easing = timingCurveToCss(options?.timingCurve, options?.cubicBezier);
95153
- return {
95154
- keyframeName,
95155
- keyframesCss,
95156
- cssAnimation: `${keyframeName} ${duration}ms ${easing} 0ms 1 normal both`,
95157
- durationMs: duration
95158
- };
95159
- }
95160
95526
  var CAMERA_PRESET_MAP = {
95161
95527
  orthographicFront: { rotateX: 0, rotateY: 0, rotateZ: 0 },
95162
95528
  perspectiveFront: { perspective: "1000px", rotateX: 0, rotateY: 0, rotateZ: 0 },
@@ -107203,6 +107569,410 @@ function clampIndex(index, slideCount) {
107203
107569
  }
107204
107570
  return Math.min(Math.max(Math.trunc(index), 0), slideCount - 1);
107205
107571
  }
107572
+ var OUTLINE_VIEW_ATTR = "data-pptx-outline-view";
107573
+ var OUTLINE_ROW_ATTR = "data-pptx-outline-row";
107574
+ var OUTLINE_SLIDE_ATTR = "data-pptx-outline-slide";
107575
+ var OUTLINE_LEVEL_ATTR = "data-pptx-outline-level";
107576
+ var MAX_PARAGRAPH_LEVEL = 8;
107577
+ var TITLE_PH_TYPES = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
107578
+ var CHROME_PH_TYPES = /* @__PURE__ */ new Set(["ftr", "hdr", "dt", "sldnum"]);
107579
+ var OUTLINE_TITLE_ELEMENT_NAME = "Title";
107580
+ function placeholderType(element) {
107581
+ const ph = element.rawXml?.["p:nvSpPr"]?.["p:nvPr"]?.["p:ph"];
107582
+ if (!ph) {
107583
+ return void 0;
107584
+ }
107585
+ const type = typeof ph["@_type"] === "string" ? ph["@_type"].trim().toLowerCase() : "";
107586
+ return type.length > 0 ? type : "body";
107587
+ }
107588
+ function isTextBearing(element) {
107589
+ return hasTextProperties(element);
107590
+ }
107591
+ function elementHasText(element) {
107592
+ if (!hasTextProperties(element)) {
107593
+ return false;
107594
+ }
107595
+ if (typeof element.text === "string" && element.text.trim().length > 0) {
107596
+ return true;
107597
+ }
107598
+ return (element.textSegments ?? []).some((segment) => segment.text.trim().length > 0);
107599
+ }
107600
+ function resolveSlideOutlineElements(slide) {
107601
+ const elements = (slide.elements ?? []).filter(isTextBearing);
107602
+ const placeholderTitle = elements.find((element) => {
107603
+ const type = placeholderType(element);
107604
+ return type !== void 0 && TITLE_PH_TYPES.has(type);
107605
+ });
107606
+ const placeholderBody = elements.filter((element) => {
107607
+ const type = placeholderType(element);
107608
+ return type !== void 0 && !TITLE_PH_TYPES.has(type) && !CHROME_PH_TYPES.has(type);
107609
+ });
107610
+ if (placeholderTitle || placeholderBody.length > 0) {
107611
+ return { title: placeholderTitle ?? null, body: placeholderBody };
107612
+ }
107613
+ const named = elements.find(
107614
+ (element) => (element.name ?? "").trim().toLowerCase() === OUTLINE_TITLE_ELEMENT_NAME.toLowerCase()
107615
+ );
107616
+ const withText = elements.filter(elementHasText);
107617
+ const title = named ?? withText[0] ?? null;
107618
+ return { title, body: withText.filter((element) => element !== title) };
107619
+ }
107620
+ function isBulletMarker(segment) {
107621
+ const bullet = segment.bulletInfo;
107622
+ if (!bullet) {
107623
+ return false;
107624
+ }
107625
+ const marker = bullet.char ? `${bullet.char} ` : bullet.imageRelId || bullet.imageDataUrl ? "\u{1F4CE} " : bullet.autoNumType ? void 0 : "\u2022 ";
107626
+ return marker ? segment.text === marker : bullet.paragraphIndex !== void 0;
107627
+ }
107628
+ function isParagraphSeparator(segment) {
107629
+ return Boolean(segment.isParagraphBreak) || segment.text === "\n" && !segment.isLineBreak;
107630
+ }
107631
+ function groupElementParagraphs(element) {
107632
+ const withText = hasTextProperties(element) ? element : void 0;
107633
+ const segments = withText?.textSegments;
107634
+ if (!segments || segments.length === 0) {
107635
+ const style = { ...withText?.textStyle ?? {} };
107636
+ return (withText?.text ?? "").split("\n").map((text2) => ({
107637
+ content: [{ text: text2, style: { ...style } }]
107638
+ }));
107639
+ }
107640
+ const groups = [{ content: [] }];
107641
+ for (const segment of segments) {
107642
+ if (isParagraphSeparator(segment)) {
107643
+ groups.push({ content: [] });
107644
+ continue;
107645
+ }
107646
+ const current = groups[groups.length - 1];
107647
+ if (current.content.length === 0 && current.marker === void 0 && isBulletMarker(segment)) {
107648
+ current.marker = segment;
107649
+ continue;
107650
+ }
107651
+ current.content.push(segment);
107652
+ }
107653
+ return groups;
107654
+ }
107655
+ function paragraphGroupText(group) {
107656
+ return group.content.map((segment) => segment.isLineBreak ? " " : segment.text).join("");
107657
+ }
107658
+ function paragraphGroupLevel(group) {
107659
+ const first = group.marker ?? group.content[0];
107660
+ const level = first?.paragraphLevel;
107661
+ return typeof level === "number" && level > 0 ? Math.min(level, MAX_PARAGRAPH_LEVEL) : 0;
107662
+ }
107663
+ function readElementParagraphs(element) {
107664
+ const groups = groupElementParagraphs(element);
107665
+ const paragraphs = groups.map((group) => ({
107666
+ text: paragraphGroupText(group),
107667
+ level: paragraphGroupLevel(group)
107668
+ }));
107669
+ let last = paragraphs.length - 1;
107670
+ while (last >= 0 && paragraphs[last].text.length === 0) {
107671
+ last -= 1;
107672
+ }
107673
+ return paragraphs.slice(0, last + 1);
107674
+ }
107675
+ function outlineRowKey(slideId, elementId, paragraphIndex) {
107676
+ return `${slideId}|${elementId ?? "\0new-title"}|${paragraphIndex}`;
107677
+ }
107678
+ function pushElementRows(rows, element, kind, slide, slideIndex) {
107679
+ for (const [paragraphIndex, paragraph] of readElementParagraphs(element).entries()) {
107680
+ rows.push({
107681
+ key: outlineRowKey(slide.id, element.id, paragraphIndex),
107682
+ slideIndex,
107683
+ slideId: slide.id,
107684
+ kind,
107685
+ elementId: element.id,
107686
+ paragraphIndex,
107687
+ // A title always sits in the leftmost column; body text is pushed one
107688
+ // column right of it, so authored level 0 reads as outline level 1.
107689
+ level: kind === "title" ? 0 : paragraph.level + 1,
107690
+ text: paragraph.text
107691
+ });
107692
+ }
107693
+ }
107694
+ function buildOutline(slides) {
107695
+ const rows = [];
107696
+ for (const [slideIndex, slide] of slides.entries()) {
107697
+ const { title, body } = resolveSlideOutlineElements(slide);
107698
+ const before = rows.length;
107699
+ if (title) {
107700
+ pushElementRows(rows, title, "title", slide, slideIndex);
107701
+ }
107702
+ if (rows.length === before) {
107703
+ rows.push({
107704
+ key: outlineRowKey(slide.id, title?.id ?? null, 0),
107705
+ slideIndex,
107706
+ slideId: slide.id,
107707
+ kind: "title",
107708
+ elementId: title?.id ?? null,
107709
+ paragraphIndex: 0,
107710
+ level: 0,
107711
+ text: ""
107712
+ });
107713
+ }
107714
+ for (const element of body) {
107715
+ pushElementRows(rows, element, "body", slide, slideIndex);
107716
+ }
107717
+ }
107718
+ return rows;
107719
+ }
107720
+ function findOutlineRow(rows, key) {
107721
+ return rows.find((row) => row.key === key);
107722
+ }
107723
+ var PASTE_OFFSET_PX = 20;
107724
+ function generateElementId() {
107725
+ return `el-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
107726
+ }
107727
+ function makeCloneId(intoTemplate, sourceId) {
107728
+ if (!intoTemplate) {
107729
+ return generateElementId();
107730
+ }
107731
+ if (sourceId.startsWith("master-")) {
107732
+ return `master-${generateElementId()}`;
107733
+ }
107734
+ return `layout-${generateElementId()}`;
107735
+ }
107736
+ function buildElementClipboardPayload(element, isTemplate) {
107737
+ return { element: structuredClone(element), isTemplate };
107738
+ }
107739
+ function cloneElementForPaste(element, options = {}) {
107740
+ const clone3 = structuredClone(element);
107741
+ clone3.id = makeCloneId(options.intoTemplate ?? false, element.id);
107742
+ clone3.x += options.offsetX ?? PASTE_OFFSET_PX;
107743
+ clone3.y += options.offsetY ?? PASTE_OFFSET_PX;
107744
+ return clone3;
107745
+ }
107746
+ function mapOutlineKey(input, rowKey) {
107747
+ const none = { edit: null, preventDefault: false };
107748
+ if (input.ctrlKey || input.metaKey) {
107749
+ return none;
107750
+ }
107751
+ if (input.key === "Tab" && !input.altKey) {
107752
+ return {
107753
+ edit: { type: "indent", key: rowKey, delta: input.shiftKey ? -1 : 1 },
107754
+ preventDefault: true
107755
+ };
107756
+ }
107757
+ if (input.altKey && input.shiftKey && (input.key === "ArrowRight" || input.key === "ArrowLeft")) {
107758
+ return {
107759
+ edit: { type: "indent", key: rowKey, delta: input.key === "ArrowRight" ? 1 : -1 },
107760
+ preventDefault: true
107761
+ };
107762
+ }
107763
+ if (input.key === "Enter" && !input.shiftKey && !input.altKey) {
107764
+ return { edit: { type: "insertAfter", key: rowKey }, preventDefault: true };
107765
+ }
107766
+ return none;
107767
+ }
107768
+ function withLevel(segments, level) {
107769
+ return segments.map((segment, index) => {
107770
+ if (index > 0) {
107771
+ return segment;
107772
+ }
107773
+ const next = { ...segment };
107774
+ if (level > 0) {
107775
+ next.paragraphLevel = Math.min(level, MAX_PARAGRAPH_LEVEL);
107776
+ } else {
107777
+ delete next.paragraphLevel;
107778
+ }
107779
+ return next;
107780
+ });
107781
+ }
107782
+ function rebuildParagraph(group, donor, text2, elementStyle) {
107783
+ if (group && paragraphGroupText(group) === text2) {
107784
+ return [...group.marker ? [group.marker] : [], ...group.content];
107785
+ }
107786
+ const source = group ?? donor;
107787
+ const marker = source?.marker ? [source.marker] : [];
107788
+ const content = remapTextToSegments(text2, source?.content, elementStyle);
107789
+ return [...marker, ...content];
107790
+ }
107791
+ function writeElementParagraphs(element, paragraphs) {
107792
+ const groups = groupElementParagraphs(element);
107793
+ const donor = groups[groups.length - 1];
107794
+ const style = hasTextProperties(element) ? element.textStyle : void 0;
107795
+ const segments = [];
107796
+ for (const [index, paragraph] of paragraphs.entries()) {
107797
+ if (index > 0) {
107798
+ const previous = segments[segments.length - 1];
107799
+ segments.push({
107800
+ text: "\n",
107801
+ style: { ...previous?.style ?? style ?? {} },
107802
+ isParagraphBreak: true
107803
+ });
107804
+ }
107805
+ segments.push(
107806
+ ...withLevel(rebuildParagraph(groups[index], donor, paragraph.text, style), paragraph.level)
107807
+ );
107808
+ }
107809
+ return {
107810
+ ...element,
107811
+ text: paragraphs.map((paragraph) => paragraph.text).join("\n"),
107812
+ textSegments: segments
107813
+ };
107814
+ }
107815
+ var DEFAULT_CANVAS = { width: 960, height: 540 };
107816
+ function createTitleElement(text2, options) {
107817
+ const canvas = options.canvas ?? DEFAULT_CANVAS;
107818
+ return {
107819
+ type: "text",
107820
+ id: options.idGenerator ? options.idGenerator() : generateElementId(),
107821
+ name: OUTLINE_TITLE_ELEMENT_NAME,
107822
+ x: Math.round(canvas.width * 0.06),
107823
+ y: Math.round(canvas.height * 0.08),
107824
+ width: Math.round(canvas.width * 0.88),
107825
+ height: Math.round(canvas.height * 0.17),
107826
+ text: text2,
107827
+ textStyle: { fontSize: 36, bold: true },
107828
+ textSegments: [{ text: text2, style: { fontSize: 36, bold: true } }]
107829
+ };
107830
+ }
107831
+ function renumber(slides) {
107832
+ return slides.map((slide, index) => ({ ...slide, slideNumber: index + 1 }));
107833
+ }
107834
+ function unchanged(slides, row) {
107835
+ return {
107836
+ slides,
107837
+ changed: false,
107838
+ focusKey: row?.key ?? null,
107839
+ activeSlideIndex: row?.slideIndex ?? 0
107840
+ };
107841
+ }
107842
+ function replaceElement(slides, slideIndex, elementId, next) {
107843
+ return slides.map(
107844
+ (slide, index) => index === slideIndex ? {
107845
+ ...slide,
107846
+ elements: (slide.elements ?? []).map(
107847
+ (element) => element.id === elementId ? next : element
107848
+ )
107849
+ } : slide
107850
+ );
107851
+ }
107852
+ function editParagraphs(slides, row, mutate) {
107853
+ const slide = slides[row.slideIndex];
107854
+ const element = (slide?.elements ?? []).find((candidate) => candidate.id === row.elementId);
107855
+ if (!element) {
107856
+ return null;
107857
+ }
107858
+ const paragraphs = readElementParagraphs(element);
107859
+ while (paragraphs.length <= row.paragraphIndex) {
107860
+ paragraphs.push({ text: "", level: 0 });
107861
+ }
107862
+ const next = mutate(paragraphs);
107863
+ if (!next) {
107864
+ return null;
107865
+ }
107866
+ return {
107867
+ slides: replaceElement(
107868
+ slides,
107869
+ row.slideIndex,
107870
+ element.id,
107871
+ writeElementParagraphs(element, next)
107872
+ ),
107873
+ changed: true,
107874
+ focusKey: row.key,
107875
+ activeSlideIndex: row.slideIndex
107876
+ };
107877
+ }
107878
+ function oneLine(text2) {
107879
+ return text2.replace(/[\r\n]+/g, " ");
107880
+ }
107881
+ function applySetText(slides, row, raw, options) {
107882
+ const text2 = oneLine(raw);
107883
+ if (row.elementId === null) {
107884
+ if (text2.length === 0) {
107885
+ return unchanged([...slides], row);
107886
+ }
107887
+ const element = createTitleElement(text2, options);
107888
+ const next = slides.map(
107889
+ (slide, index) => index === row.slideIndex ? { ...slide, elements: [element, ...slide.elements ?? []] } : slide
107890
+ );
107891
+ return {
107892
+ slides: next,
107893
+ changed: true,
107894
+ focusKey: outlineRowKey(row.slideId, element.id, 0),
107895
+ activeSlideIndex: row.slideIndex
107896
+ };
107897
+ }
107898
+ const result = editParagraphs(slides, row, (paragraphs) => {
107899
+ if (paragraphs[row.paragraphIndex].text === text2) {
107900
+ return null;
107901
+ }
107902
+ const next = [...paragraphs];
107903
+ next[row.paragraphIndex] = { ...next[row.paragraphIndex], text: text2 };
107904
+ return next;
107905
+ });
107906
+ return result ?? unchanged([...slides], row);
107907
+ }
107908
+ function applyIndent(slides, row, delta) {
107909
+ if (row.kind !== "body" || row.elementId === null || delta === 0) {
107910
+ return unchanged([...slides], row);
107911
+ }
107912
+ const result = editParagraphs(slides, row, (paragraphs) => {
107913
+ const current = paragraphs[row.paragraphIndex];
107914
+ const level = Math.min(Math.max(current.level + (delta > 0 ? 1 : -1), 0), MAX_PARAGRAPH_LEVEL);
107915
+ if (level === current.level) {
107916
+ return null;
107917
+ }
107918
+ const next = [...paragraphs];
107919
+ next[row.paragraphIndex] = { ...current, level };
107920
+ return next;
107921
+ });
107922
+ return result ?? unchanged([...slides], row);
107923
+ }
107924
+ function applyInsertAfter(slides, row, options) {
107925
+ if (row.kind === "title") {
107926
+ const slide = {
107927
+ id: makeSlideId(options.idGenerator),
107928
+ rId: "",
107929
+ slideNumber: row.slideIndex + 2,
107930
+ elements: []
107931
+ };
107932
+ const next = renumber([
107933
+ ...slides.slice(0, row.slideIndex + 1),
107934
+ slide,
107935
+ ...slides.slice(row.slideIndex + 1)
107936
+ ]);
107937
+ return {
107938
+ slides: next,
107939
+ changed: true,
107940
+ focusKey: outlineRowKey(slide.id, null, 0),
107941
+ activeSlideIndex: row.slideIndex + 1
107942
+ };
107943
+ }
107944
+ const result = editParagraphs(slides, row, (paragraphs) => {
107945
+ const next = [...paragraphs];
107946
+ next.splice(row.paragraphIndex + 1, 0, {
107947
+ text: "",
107948
+ level: paragraphs[row.paragraphIndex].level
107949
+ });
107950
+ return next;
107951
+ });
107952
+ if (!result) {
107953
+ return unchanged([...slides], row);
107954
+ }
107955
+ return {
107956
+ ...result,
107957
+ focusKey: outlineRowKey(row.slideId, row.elementId, row.paragraphIndex + 1)
107958
+ };
107959
+ }
107960
+ function applyOutlineEdit(slides, edit, options = {}) {
107961
+ const row = findOutlineRow(buildOutline(slides), edit.key);
107962
+ if (!row) {
107963
+ return unchanged([...slides]);
107964
+ }
107965
+ switch (edit.type) {
107966
+ case "setText":
107967
+ return applySetText(slides, row, edit.text, options);
107968
+ case "indent":
107969
+ return applyIndent(slides, row, edit.delta);
107970
+ case "insertAfter":
107971
+ return applyInsertAfter(slides, row, options);
107972
+ default:
107973
+ return unchanged([...slides], row);
107974
+ }
107975
+ }
107206
107976
  var NUDGE_SMALL = 1;
107207
107977
  var NUDGE_LARGE = 10;
107208
107978
  var GUARD_DEFAULTS = {
@@ -109227,29 +109997,6 @@ var COMMON_FONTS = [
109227
109997
  "Tw Cen MT",
109228
109998
  "Verdana"
109229
109999
  ];
109230
- var PASTE_OFFSET_PX = 20;
109231
- function generateElementId() {
109232
- return `el-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
109233
- }
109234
- function makeCloneId(intoTemplate, sourceId) {
109235
- if (!intoTemplate) {
109236
- return generateElementId();
109237
- }
109238
- if (sourceId.startsWith("master-")) {
109239
- return `master-${generateElementId()}`;
109240
- }
109241
- return `layout-${generateElementId()}`;
109242
- }
109243
- function buildElementClipboardPayload(element, isTemplate) {
109244
- return { element: structuredClone(element), isTemplate };
109245
- }
109246
- function cloneElementForPaste(element, options = {}) {
109247
- const clone3 = structuredClone(element);
109248
- clone3.id = makeCloneId(options.intoTemplate ?? false, element.id);
109249
- clone3.x += options.offsetX ?? PASTE_OFFSET_PX;
109250
- clone3.y += options.offsetY ?? PASTE_OFFSET_PX;
109251
- return clone3;
109252
- }
109253
110000
  var DEFAULT_PREVIEW_ELEMENT_CAP = 500;
109254
110001
  function buildPreviewElements(slide, templateElements = [], options) {
109255
110002
  const cap = options?.cap ?? DEFAULT_PREVIEW_ELEMENT_CAP;
@@ -112898,6 +113645,7 @@ exports.DEFAULT_BROADCAST_SERVER_URL = DEFAULT_BROADCAST_SERVER_URL;
112898
113645
  exports.DEFAULT_COLOR_CHANGE_TOLERANCE = DEFAULT_COLOR_CHANGE_TOLERANCE;
112899
113646
  exports.DEFAULT_COLOR_MAP = DEFAULT_COLOR_MAP;
112900
113647
  exports.DEFAULT_INSERT_CHART_TYPE = DEFAULT_INSERT_CHART_TYPE;
113648
+ exports.DEFAULT_MOTION_PATH_PRESET_ID = DEFAULT_MOTION_PATH_PRESET_ID;
112901
113649
  exports.DEFAULT_QUICK_ACCESS_COMMAND_IDS = DEFAULT_QUICK_ACCESS_COMMAND_IDS;
112902
113650
  exports.DEFAULT_ROW_HEIGHT = DEFAULT_ROW_HEIGHT;
112903
113651
  exports.DEFAULT_VIEWER_OPTIONS = DEFAULT_VIEWER_OPTIONS;
@@ -112924,11 +113672,16 @@ exports.MATERIAL_PRESETS = MATERIAL_PRESETS;
112924
113672
  exports.MAX_ZOOM_SCALE = MAX_ZOOM_SCALE;
112925
113673
  exports.MIN_ZOOM_SCALE = MIN_ZOOM_SCALE;
112926
113674
  exports.MOBILE_BREAKPOINT = MOBILE_BREAKPOINT;
113675
+ exports.MOTION_PATH_FAMILIES = MOTION_PATH_FAMILIES;
112927
113676
  exports.NOTES_FONT_SIZE_DEFAULT = NOTES_FONT_SIZE_DEFAULT;
112928
113677
  exports.NOTES_FONT_SIZE_MAX = NOTES_FONT_SIZE_MAX;
112929
113678
  exports.NOTES_FONT_SIZE_MIN = NOTES_FONT_SIZE_MIN;
112930
113679
  exports.NOTES_FONT_SIZE_STEP = NOTES_FONT_SIZE_STEP;
112931
113680
  exports.NUM = NUM;
113681
+ exports.OUTLINE_LEVEL_ATTR = OUTLINE_LEVEL_ATTR;
113682
+ exports.OUTLINE_ROW_ATTR = OUTLINE_ROW_ATTR;
113683
+ exports.OUTLINE_SLIDE_ATTR = OUTLINE_SLIDE_ATTR;
113684
+ exports.OUTLINE_VIEW_ATTR = OUTLINE_VIEW_ATTR;
112932
113685
  exports.PATTERN_OPTIONS = PATTERN_OPTIONS;
112933
113686
  exports.PRESENTATION_CHANNEL_NAME = PRESENTATION_CHANNEL_NAME;
112934
113687
  exports.PRESENTATION_HASH = PRESENTATION_HASH;
@@ -112997,6 +113750,8 @@ exports.applyChartBuildReveal = applyChartBuildReveal;
112997
113750
  exports.applyColorChange = applyColorChange;
112998
113751
  exports.applyDuotone = applyDuotone;
112999
113752
  exports.applyFormatToElement = applyFormatToElement;
113753
+ exports.applyMotionPathPreset = applyMotionPathPreset;
113754
+ exports.applyOutlineEdit = applyOutlineEdit;
113000
113755
  exports.applyPreferenceToOptions = applyPreferenceToOptions;
113001
113756
  exports.applyReadingViewCommand = applyReadingViewCommand;
113002
113757
  exports.applyRehearsalTimings = applyRehearsalTimings;
@@ -113028,9 +113783,11 @@ exports.buildInitialGuides = buildInitialGuides;
113028
113783
  exports.buildInnerShadowCssFromShapeStyle = buildInnerShadowCssFromShapeStyle;
113029
113784
  exports.buildJoinCollaborationConfig = buildJoinCollaborationConfig;
113030
113785
  exports.buildMorphTransitionPlan = buildMorphTransitionPlan;
113786
+ exports.buildMotionPathPreview = buildMotionPathPreview;
113031
113787
  exports.buildMultiLayerShadowCss = buildMultiLayerShadowCss;
113032
113788
  exports.buildNotesHtml = buildNotesHtml;
113033
113789
  exports.buildNotesPdfBytes = buildNotesPdfBytes;
113790
+ exports.buildOutline = buildOutline;
113034
113791
  exports.buildOutlineHtml = buildOutlineHtml;
113035
113792
  exports.buildPatternFillCss = buildPatternFillCss;
113036
113793
  exports.buildPresentationAudienceUrl = buildPresentationAudienceUrl;
@@ -113075,6 +113832,7 @@ exports.clampZoomScale = clampZoomScale;
113075
113832
  exports.clearAllLocalViewerData = clearAllLocalViewerData;
113076
113833
  exports.clearAudienceContent = clearAudienceContent;
113077
113834
  exports.clearLocalAwareness = clearLocalAwareness;
113835
+ exports.clearMotionPath = clearMotionPath;
113078
113836
  exports.clearStoredViewerPrefs = clearStoredViewerPrefs;
113079
113837
  exports.cloneElementForPaste = cloneElementForPaste;
113080
113838
  exports.cloneHistorySnapshot = cloneHistorySnapshot;
@@ -113251,6 +114009,7 @@ exports.isActionHidden = isActionHidden;
113251
114009
  exports.isBrowserOpenableMime = isBrowserOpenableMime;
113252
114010
  exports.isCalloutShape = isCalloutShape;
113253
114011
  exports.isCellInRect = isCellInRect;
114012
+ exports.isEditableMotionPath = isEditableMotionPath;
113254
114013
  exports.isEditableTextElement = isEditableTextElement;
113255
114014
  exports.isEditorTextInputTarget = isEditorTextInputTarget;
113256
114015
  exports.isElementActionable = isElementActionable;
@@ -113276,6 +114035,7 @@ exports.loadAudienceContent = loadAudienceContent;
113276
114035
  exports.makeCloneId = makeCloneId;
113277
114036
  exports.makeSlideId = makeSlideId;
113278
114037
  exports.mapEditorKey = mapEditorKey;
114038
+ exports.mapOutlineKey = mapOutlineKey;
113279
114039
  exports.mapPresentationKey = mapPresentationKey;
113280
114040
  exports.mayLeaveSlideShow = mayLeaveSlideShow;
113281
114041
  exports.mergeAdditiveSelection = mergeAdditiveSelection;
@@ -113286,6 +114046,13 @@ exports.mergeSlideTransition = mergeSlideTransition;
113286
114046
  exports.mobileElapsedSince = mobileElapsedSince;
113287
114047
  exports.mobileSlideCounter = mobileSlideCounter;
113288
114048
  exports.morphOptionToMode = morphOptionToMode;
114049
+ exports.motionPathEndPixel = motionPathEndPixel;
114050
+ exports.motionPathFamilyLabelKey = motionPathFamilyLabelKey;
114051
+ exports.motionPathFor = motionPathFor;
114052
+ exports.motionPathPresetIdForPath = motionPathPresetIdForPath;
114053
+ exports.motionPathPresetLabelKey = motionPathPresetLabelKey;
114054
+ exports.motionPathPresetsByFamily = motionPathPresetsByFamily;
114055
+ exports.motionPathToSvgD = motionPathToSvgD;
113289
114056
  exports.mountModel3D = mountModel3D;
113290
114057
  exports.mountSurfaceChart3D = mountSurfaceChart3D;
113291
114058
  exports.movePresenterPointer = movePresenterPointer;
@@ -113406,6 +114173,8 @@ exports.setChartDataPointMarker = setChartDataPointMarker;
113406
114173
  exports.setChartSeriesChartType = setChartSeriesChartType;
113407
114174
  exports.setChartSeriesMarker = setChartSeriesMarker;
113408
114175
  exports.setDuotoneCachedResult = setDuotoneCachedResult;
114176
+ exports.setMotionPath = setMotionPath;
114177
+ exports.setMotionPathEnd = setMotionPathEnd;
113409
114178
  exports.setPendingSelectionRestore = setPendingSelectionRestore;
113410
114179
  exports.setSmartArtNodeStyle = setSmartArtNodeStyle;
113411
114180
  exports.setTableElementCellText = setTableElementCellText;