pptx-react-viewer 2.11.1 → 2.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/{AiChatPanel-RMQIJDUJ.mjs → AiChatPanel-CGGUPVQX.mjs} +4 -4
  3. package/dist/AiChatPanel-CGGUPVQX.mjs.br +0 -0
  4. package/dist/AiChatPanel-CGGUPVQX.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-E6W3EACA.js → AiChatPanel-UEFYTUJN.js} +23 -23
  6. package/dist/AiChatPanel-UEFYTUJN.js.br +0 -0
  7. package/dist/AiChatPanel-UEFYTUJN.js.gz +0 -0
  8. package/dist/{Model3DScene-U4B4NZJT.js → Model3DScene-QYXJNALP.js} +2 -2
  9. package/dist/{Model3DScene-U4B4NZJT.js.br → Model3DScene-QYXJNALP.js.br} +0 -0
  10. package/dist/Model3DScene-QYXJNALP.js.gz +0 -0
  11. package/dist/{Model3DScene-WHSHBMR5.mjs → Model3DScene-TU4NTHRM.mjs} +1 -1
  12. package/dist/Model3DScene-TU4NTHRM.mjs.br +0 -0
  13. package/dist/Model3DScene-TU4NTHRM.mjs.gz +0 -0
  14. package/dist/{SurfaceChart3DScene-5S43UBRD.js → SurfaceChart3DScene-4VCO3DRP.js} +2 -2
  15. package/dist/SurfaceChart3DScene-4VCO3DRP.js.br +0 -0
  16. package/dist/SurfaceChart3DScene-4VCO3DRP.js.gz +0 -0
  17. package/dist/{SurfaceChart3DScene-77JP5XH5.mjs → SurfaceChart3DScene-VTJBKUQY.mjs} +1 -1
  18. package/dist/{SurfaceChart3DScene-77JP5XH5.mjs.br → SurfaceChart3DScene-VTJBKUQY.mjs.br} +0 -0
  19. package/dist/SurfaceChart3DScene-VTJBKUQY.mjs.gz +0 -0
  20. package/dist/{chunk-NJ4PTG4F.mjs → chunk-4GYNTY2G.mjs} +28 -48
  21. package/dist/chunk-4GYNTY2G.mjs.br +0 -0
  22. package/dist/chunk-4GYNTY2G.mjs.gz +0 -0
  23. package/dist/{chunk-PXYZFWDA.mjs → chunk-4SGXEGVL.mjs} +339 -256
  24. package/dist/chunk-4SGXEGVL.mjs.br +0 -0
  25. package/dist/chunk-4SGXEGVL.mjs.gz +0 -0
  26. package/dist/{chunk-IOVOQ6ZJ.js → chunk-BXAK3JFM.js} +301 -1
  27. package/dist/chunk-BXAK3JFM.js.br +0 -0
  28. package/dist/chunk-BXAK3JFM.js.gz +0 -0
  29. package/dist/{chunk-FV7HEYCX.mjs → chunk-CABQXGPI.mjs} +621 -70
  30. package/dist/chunk-CABQXGPI.mjs.br +0 -0
  31. package/dist/chunk-CABQXGPI.mjs.gz +0 -0
  32. package/dist/{chunk-IXBM3HWH.js → chunk-GBKIWNW6.js} +2047 -1964
  33. package/dist/chunk-GBKIWNW6.js.br +0 -0
  34. package/dist/chunk-GBKIWNW6.js.gz +0 -0
  35. package/dist/{chunk-FAP6OPLL.js → chunk-LE6YA5WB.js} +262 -296
  36. package/dist/chunk-LE6YA5WB.js.br +0 -0
  37. package/dist/chunk-LE6YA5WB.js.gz +0 -0
  38. package/dist/{chunk-HF6L2CTF.mjs → chunk-N3NKU7SC.mjs} +1 -1
  39. package/dist/chunk-N3NKU7SC.mjs.br +0 -0
  40. package/dist/{chunk-HF6L2CTF.mjs.gz → chunk-N3NKU7SC.mjs.gz} +0 -0
  41. package/dist/{chunk-QT6BPOZM.js → chunk-NUDH7TI2.js} +355 -375
  42. package/dist/chunk-NUDH7TI2.js.br +0 -0
  43. package/dist/chunk-NUDH7TI2.js.gz +0 -0
  44. package/dist/{chunk-KDJBWJJH.js → chunk-TDUDH7S4.js} +648 -71
  45. package/dist/chunk-TDUDH7S4.js.br +0 -0
  46. package/dist/chunk-TDUDH7S4.js.gz +0 -0
  47. package/dist/{chunk-RHR7GTDX.mjs → chunk-TEXIGSA6.mjs} +301 -1
  48. package/dist/chunk-TEXIGSA6.mjs.br +0 -0
  49. package/dist/chunk-TEXIGSA6.mjs.gz +0 -0
  50. package/dist/{chunk-X3SFCKAF.js → chunk-UIWY4XJT.js} +3 -3
  51. package/dist/chunk-UIWY4XJT.js.br +0 -0
  52. package/dist/chunk-UIWY4XJT.js.gz +0 -0
  53. package/dist/{chunk-DD54KUDG.mjs → chunk-YIPR3GKG.mjs} +24 -58
  54. package/dist/chunk-YIPR3GKG.mjs.br +0 -0
  55. package/dist/chunk-YIPR3GKG.mjs.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.js +36 -36
  63. package/dist/index.js.br +0 -0
  64. package/dist/index.js.gz +0 -0
  65. package/dist/index.mjs +6 -6
  66. package/dist/index.mjs.br +0 -0
  67. package/dist/index.mjs.gz +0 -0
  68. package/dist/internals.d.ts.map +1 -1
  69. package/dist/internals.js +79 -79
  70. package/dist/internals.js.br +0 -0
  71. package/dist/internals.js.gz +0 -0
  72. package/dist/internals.mjs +4 -4
  73. package/dist/internals.mjs.br +0 -0
  74. package/dist/internals.mjs.gz +0 -0
  75. package/dist/pptx-viewer.css +1 -1
  76. package/dist/pptx-viewer.css.br +0 -0
  77. package/dist/pptx-viewer.css.gz +0 -0
  78. package/dist/viewer/index.js +22 -22
  79. package/dist/viewer/index.js.br +0 -0
  80. package/dist/viewer/index.js.gz +0 -0
  81. package/dist/viewer/index.mjs +6 -6
  82. package/dist/viewer/index.mjs.br +0 -0
  83. package/dist/viewer/index.mjs.gz +0 -0
  84. package/package.json +1 -1
  85. package/dist/AiChatPanel-E6W3EACA.js.br +0 -0
  86. package/dist/AiChatPanel-E6W3EACA.js.gz +0 -0
  87. package/dist/AiChatPanel-RMQIJDUJ.mjs.br +0 -0
  88. package/dist/AiChatPanel-RMQIJDUJ.mjs.gz +0 -0
  89. package/dist/Model3DScene-U4B4NZJT.js.gz +0 -0
  90. package/dist/Model3DScene-WHSHBMR5.mjs.br +0 -0
  91. package/dist/Model3DScene-WHSHBMR5.mjs.gz +0 -0
  92. package/dist/SurfaceChart3DScene-5S43UBRD.js.br +0 -0
  93. package/dist/SurfaceChart3DScene-5S43UBRD.js.gz +0 -0
  94. package/dist/SurfaceChart3DScene-77JP5XH5.mjs.gz +0 -0
  95. package/dist/chunk-DD54KUDG.mjs.br +0 -0
  96. package/dist/chunk-DD54KUDG.mjs.gz +0 -0
  97. package/dist/chunk-FAP6OPLL.js.br +0 -0
  98. package/dist/chunk-FAP6OPLL.js.gz +0 -0
  99. package/dist/chunk-FV7HEYCX.mjs.br +0 -0
  100. package/dist/chunk-FV7HEYCX.mjs.gz +0 -0
  101. package/dist/chunk-HF6L2CTF.mjs.br +0 -0
  102. package/dist/chunk-IOVOQ6ZJ.js.br +0 -0
  103. package/dist/chunk-IOVOQ6ZJ.js.gz +0 -0
  104. package/dist/chunk-IXBM3HWH.js.br +0 -0
  105. package/dist/chunk-IXBM3HWH.js.gz +0 -0
  106. package/dist/chunk-KDJBWJJH.js.br +0 -0
  107. package/dist/chunk-KDJBWJJH.js.gz +0 -0
  108. package/dist/chunk-NJ4PTG4F.mjs.br +0 -0
  109. package/dist/chunk-NJ4PTG4F.mjs.gz +0 -0
  110. package/dist/chunk-PXYZFWDA.mjs.br +0 -0
  111. package/dist/chunk-PXYZFWDA.mjs.gz +0 -0
  112. package/dist/chunk-QT6BPOZM.js.br +0 -0
  113. package/dist/chunk-QT6BPOZM.js.gz +0 -0
  114. package/dist/chunk-RHR7GTDX.mjs.br +0 -0
  115. package/dist/chunk-RHR7GTDX.mjs.gz +0 -0
  116. package/dist/chunk-X3SFCKAF.js.br +0 -0
  117. package/dist/chunk-X3SFCKAF.js.gz +0 -0
@@ -15931,6 +15931,15 @@ var MC_NAMESPACE_CAPABILITIES = {
15931
15931
  "hiddenFill",
15932
15932
  "hiddenLine"
15933
15933
  ]),
15934
+ // PowerPoint 2016+ writes the Morph transition as `<p159:morph @option>`,
15935
+ // either inside an `mc:Choice Requires="p159"` or in a `p:transition/p:extLst`
15936
+ // extension. Both forms are parsed (see `PptxSlideTransitionService`), so the
15937
+ // choice IS supported: without this entry every morph slide reported
15938
+ // `UNSUPPORTED_ALTERNATE_CONTENT_CHOICE`, which reads as "the transition was
15939
+ // dropped and the fallback fade was used" when in fact the morph plays.
15940
+ // `morph` alone is listed on purpose: any OTHER `p159:*` element still makes
15941
+ // the choice unsupported and falls back, which is the honest answer.
15942
+ p159: /* @__PURE__ */ new Set(["morph"]),
15934
15943
  a14: /* @__PURE__ */ new Set(["m", "hiddenFill", "hiddenLine", "imgEffect", "imgLayer"]),
15935
15944
  a16: /* @__PURE__ */ new Set(["svgBlip", "colId"]),
15936
15945
  asvg: /* @__PURE__ */ new Set(["svgBlip"]),
@@ -93072,6 +93081,28 @@ var DIRECTIONAL_PRESETS = /* @__PURE__ */ new Set([
93072
93081
  "floatIn",
93073
93082
  "peekIn"
93074
93083
  ]);
93084
+ function animationPresetLabelKey(preset) {
93085
+ return `pptx.animation.preset.${preset}`;
93086
+ }
93087
+ function animationCatalogPresetSlug(presetId) {
93088
+ return presetId.split(".").map((part, index) => index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
93089
+ }
93090
+ function animationCatalogPresetLabelKey(presetId) {
93091
+ return `pptx.animation.catalogPreset.${animationCatalogPresetSlug(presetId)}`;
93092
+ }
93093
+ function isAnimationCatalogPresetId(token2) {
93094
+ return token2.includes(".");
93095
+ }
93096
+ function animationEffectLabelKey(anim) {
93097
+ const token2 = anim.entrance ?? anim.emphasis ?? anim.exit;
93098
+ if (!token2 || token2 === "none") {
93099
+ return anim.motionPath ? "pptx.animation.motionPath.label" : "pptx.animation.animation";
93100
+ }
93101
+ return isAnimationCatalogPresetId(token2) ? animationCatalogPresetLabelKey(token2) : animationPresetLabelKey(token2);
93102
+ }
93103
+ function animationEffectLabel(anim, translate) {
93104
+ return translate(animationEffectLabelKey(anim));
93105
+ }
93075
93106
  var PRESET_ID_TO_EFFECT = {
93076
93107
  entr: {
93077
93108
  1: "appear",
@@ -93945,6 +93976,9 @@ function normalizeDelay(delay) {
93945
93976
  }
93946
93977
  return { ms: delay, indefinite: false };
93947
93978
  }
93979
+ function isInteractiveTrigger(trigger) {
93980
+ return trigger === "onClick" || trigger === "onShapeClick" || trigger === "onHover";
93981
+ }
93948
93982
  function classifyCondition(cond) {
93949
93983
  const evt = cond.event;
93950
93984
  if (evt && CLICK_EVENTS.has(evt)) {
@@ -93964,7 +93998,8 @@ function resolveEffectiveStartCondition(conditions, fallbackTrigger) {
93964
93998
  delayMs: 0,
93965
93999
  hasClickAlternative: false,
93966
94000
  hasHoverAlternative: false,
93967
- indefinite: false
94001
+ indefinite: false,
94002
+ requiresInteraction: isInteractiveTrigger(fallbackTrigger)
93968
94003
  };
93969
94004
  if (!conditions || conditions.length === 0) {
93970
94005
  return base;
@@ -94009,6 +94044,7 @@ function resolveEffectiveStartCondition(conditions, fallbackTrigger) {
94009
94044
  base.indefinite = indefinite;
94010
94045
  base.dependsOnTimeNodeId = timenode.targetTimeNodeId;
94011
94046
  base.dependsOnEvent = timenode.event;
94047
+ base.requiresInteraction = false;
94012
94048
  return base;
94013
94049
  }
94014
94050
  if (delayCond && (delayCond.delay ?? 0) !== 0) {
@@ -94016,19 +94052,23 @@ function resolveEffectiveStartCondition(conditions, fallbackTrigger) {
94016
94052
  base.trigger = clickCond ? "onClick" : "afterDelay";
94017
94053
  base.delayMs = ms;
94018
94054
  base.indefinite = indefinite;
94055
+ base.requiresInteraction = indefinite;
94019
94056
  return base;
94020
94057
  }
94021
94058
  if (clickCond) {
94022
94059
  base.trigger = clickCond.targetShapeId ? "onShapeClick" : "onClick";
94060
+ base.requiresInteraction = true;
94023
94061
  return base;
94024
94062
  }
94025
94063
  if (hoverCond) {
94026
94064
  base.trigger = "onHover";
94065
+ base.requiresInteraction = true;
94027
94066
  return base;
94028
94067
  }
94029
94068
  if (delayCond) {
94030
94069
  base.trigger = fallbackTrigger;
94031
94070
  base.delayMs = 0;
94071
+ base.requiresInteraction = false;
94032
94072
  }
94033
94073
  return base;
94034
94074
  }
@@ -94367,7 +94407,7 @@ function parseMediaCommand(commandString) {
94367
94407
  if (lower === "stop" || lower === "stopmedia") {
94368
94408
  return { verb: "stop" };
94369
94409
  }
94370
- if (lower === "toggleplay") {
94410
+ if (lower === "toggleplay" || lower === "togglepause") {
94371
94411
  return { verb: "togglePlay" };
94372
94412
  }
94373
94413
  return void 0;
@@ -94499,7 +94539,7 @@ function buildTimeline(nativeAnimations) {
94499
94539
  }
94500
94540
  currentGroup = [];
94501
94541
  currentGroupIsClick = isOnClick || isFirstAnimation;
94502
- currentGroupAutoStart = !isOnClick && singleAnim.groupAutoStart === true;
94542
+ currentGroupAutoStart = singleAnim.groupAutoStart === true && !effective.requiresInteraction;
94503
94543
  subGroupIndex = singleAnim.parGroupIndex;
94504
94544
  subGroupStartMs = 0;
94505
94545
  }
@@ -94604,25 +94644,26 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
94604
94644
  for (const anim of anims) {
94605
94645
  let effect = resolveEffect(anim);
94606
94646
  const dynamic = effect ? void 0 : buildDynamicKeyframe(anim, dynamicUid++);
94607
- if (!effect && !dynamic) {
94647
+ const isCommand = !effect && !dynamic && isMediaCommandAnimation(anim);
94648
+ if (!effect && !dynamic && !isCommand) {
94608
94649
  effect = fallbackEffectForClass(anim.presetClass);
94609
94650
  if (!effect) {
94610
94651
  continue;
94611
94652
  }
94612
94653
  }
94613
- const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
94654
+ const keyframe = isCommand ? "" : effect ? cssKeyframeName(effect) : dynamic.keyframeName;
94614
94655
  if (effect) {
94615
94656
  neededKeyframes.add(effect);
94616
94657
  }
94617
94658
  if (dynamic) {
94618
94659
  dynamicBlocks.push(dynamic.css);
94619
94660
  }
94620
- const elementId = anim.targetId ?? "";
94661
+ const elementId = isCommand ? "" : anim.targetId ?? "";
94621
94662
  const seqTrigger = anim.trigger ?? "onShapeClick";
94622
- const duration = anim.durationMs ?? defaultDuration(anim.presetClass);
94663
+ const duration = isCommand ? 0 : anim.durationMs ?? defaultDuration(anim.presetClass);
94623
94664
  const animDelay = Math.max(anim.delayMs ?? 0, anim.triggerDelayMs ?? 0);
94624
94665
  const triggerDelay = 0;
94625
- const presetClass = anim.presetClass ?? "entr";
94666
+ const presetClass = isCommand ? "emph" : anim.presetClass ?? "entr";
94626
94667
  const fill = fillModeForClass(anim.presetClass);
94627
94668
  const iterCount = anim.repeatCount ?? 1;
94628
94669
  const direction = anim.autoReverse ? "alternate" : "normal";
@@ -94646,7 +94687,7 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
94646
94687
  }
94647
94688
  const iterStr = iterCount === Infinity ? "infinite" : String(iterCount);
94648
94689
  const easing = cssEasingForAnimation(anim);
94649
- const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
94690
+ const cssAnimation = isCommand ? "" : `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
94650
94691
  seqGroup.push({
94651
94692
  elementId,
94652
94693
  cssAnimation,
@@ -94658,8 +94699,9 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
94658
94699
  presetClass,
94659
94700
  soundPath: anim.soundPath,
94660
94701
  stopSound: anim.stopSound,
94661
- build: resolveStepBuildDescriptor(anim),
94662
- colorTargets: stepColorTargets(anim)
94702
+ command: isCommand ? buildStepCommand(anim) : void 0,
94703
+ build: isCommand ? void 0 : resolveStepBuildDescriptor(anim),
94704
+ colorTargets: isCommand ? void 0 : stepColorTargets(anim)
94663
94705
  });
94664
94706
  }
94665
94707
  if (seqGroup.length > 0) {
@@ -97800,6 +97842,45 @@ function computeMarqueeHitIds(marquee, elements, minSize = MIN_ELEMENT_SIZE) {
97800
97842
  function mergeAdditiveSelection(baseSelectionIds, hitIds) {
97801
97843
  return Array.from(/* @__PURE__ */ new Set([...baseSelectionIds ?? [], ...hitIds]));
97802
97844
  }
97845
+ function getImageFitStyle(el) {
97846
+ const uncropped = {
97847
+ width: "100%",
97848
+ height: "100%",
97849
+ objectFit: "cover"
97850
+ };
97851
+ if (!isImageLikeElement(el)) {
97852
+ return uncropped;
97853
+ }
97854
+ const cropLeft = clampCropValue(el.cropLeft);
97855
+ const cropTop = clampCropValue(el.cropTop);
97856
+ const cropRight = clampCropValue(el.cropRight);
97857
+ const cropBottom = clampCropValue(el.cropBottom);
97858
+ if (cropLeft + cropRight <= 1e-4 && cropTop + cropBottom <= 1e-4) {
97859
+ return uncropped;
97860
+ }
97861
+ const horizontalScale = cropLeft + cropRight >= 0.99 ? 0.99 / (cropLeft + cropRight) : 1;
97862
+ const verticalScale = cropTop + cropBottom >= 0.99 ? 0.99 / (cropTop + cropBottom) : 1;
97863
+ const left = clampCropValue(cropLeft * horizontalScale);
97864
+ const right = clampCropValue(cropRight * horizontalScale);
97865
+ const top = clampCropValue(cropTop * verticalScale);
97866
+ const bottom = clampCropValue(cropBottom * verticalScale);
97867
+ const remainingWidth = Math.max(0.01, 1 - left - right);
97868
+ const remainingHeight = Math.max(0.01, 1 - top - bottom);
97869
+ const tx = Math.round(-left / remainingWidth * 1e4) / 100;
97870
+ const ty = Math.round(-top / remainingHeight * 1e4) / 100;
97871
+ const sx = Math.round(1 / remainingWidth * 1e6) / 1e6;
97872
+ const sy = Math.round(1 / remainingHeight * 1e6) / 1e6;
97873
+ return {
97874
+ position: "absolute",
97875
+ width: "100%",
97876
+ height: "100%",
97877
+ maxWidth: "none",
97878
+ maxHeight: "none",
97879
+ objectFit: "fill",
97880
+ transformOrigin: "top left",
97881
+ transform: `translate(${tx}%, ${ty}%) scale(${sx}, ${sy})`
97882
+ };
97883
+ }
97803
97884
  function groupElements(elements, ids, groupId) {
97804
97885
  const idSet = new Set(ids);
97805
97886
  const gathered = [];
@@ -106753,12 +106834,6 @@ function mobileSlideCounter(currentIndex, total) {
106753
106834
  }
106754
106835
  return `${currentIndex + 1} / ${total}`;
106755
106836
  }
106756
- function isFirstSlide(currentIndex) {
106757
- return currentIndex <= 0;
106758
- }
106759
- function isLastSlide(currentIndex, total) {
106760
- return currentIndex >= total - 1;
106761
- }
106762
106837
  function pad2(value) {
106763
106838
  return String(value).padStart(2, "0");
106764
106839
  }
@@ -107518,9 +107593,260 @@ async function openNativeEyeDropper() {
107518
107593
  return null;
107519
107594
  }
107520
107595
  }
107596
+ var PEN_COLORS = [
107597
+ "#ff0000",
107598
+ "#0000ff",
107599
+ "#00aa00",
107600
+ "#ff8800",
107601
+ "#ffffff",
107602
+ "#000000",
107603
+ "#ff00ff",
107604
+ "#00cccc"
107605
+ ];
107606
+ var HIGHLIGHTER_COLORS = [
107607
+ "#ffff00",
107608
+ "#00ff00",
107609
+ "#ff69b4",
107610
+ "#00bfff",
107611
+ "#ff8c00",
107612
+ "#adff2f",
107613
+ "#ff6347",
107614
+ "#87ceeb"
107615
+ ];
107521
107616
  function formatSlideCounter(currentSlide, totalSlides) {
107522
107617
  return `${currentSlide + 1} / ${totalSlides}`;
107523
107618
  }
107619
+ var PRESENT_TOOLBAR_CONTROLS = [
107620
+ {
107621
+ id: "previous",
107622
+ kind: "button",
107623
+ labelKey: "pptx.presenter.previousSlide",
107624
+ icon: "chevron-left"
107625
+ },
107626
+ { id: "counter", kind: "counter" },
107627
+ { id: "next", kind: "button", labelKey: "pptx.presenter.nextSlide", icon: "chevron-right" },
107628
+ { id: "divider-navigation", kind: "divider" },
107629
+ { id: "timer", kind: "timer", labelKey: "pptx.presenter.elapsed", icon: "timer" },
107630
+ { id: "divider-timer", kind: "divider" },
107631
+ {
107632
+ id: "laser",
107633
+ kind: "toggle",
107634
+ labelKey: "pptx.presentation.laserPointer",
107635
+ icon: "mouse-pointer-2"
107636
+ },
107637
+ { id: "pen", kind: "toggle", labelKey: "pptx.presentation.pen", icon: "pen-tool" },
107638
+ {
107639
+ id: "pen-color",
107640
+ kind: "caret",
107641
+ labelKey: "pptx.presentationToolbar.penColor",
107642
+ icon: "chevron-down"
107643
+ },
107644
+ {
107645
+ id: "highlighter",
107646
+ kind: "toggle",
107647
+ labelKey: "pptx.presentation.highlighter",
107648
+ icon: "highlighter"
107649
+ },
107650
+ {
107651
+ id: "highlighter-color",
107652
+ kind: "caret",
107653
+ labelKey: "pptx.presentationToolbar.highlighterColor",
107654
+ icon: "chevron-down"
107655
+ },
107656
+ { id: "eraser", kind: "toggle", labelKey: "pptx.presentation.eraser", icon: "eraser" },
107657
+ { id: "clear", kind: "button", labelKey: "pptx.presentation.clearAnnotations", icon: "trash-2" },
107658
+ { id: "divider-tools", kind: "divider" },
107659
+ {
107660
+ id: "presenter-view",
107661
+ kind: "toggle",
107662
+ labelKey: "pptx.presenter.presenterView",
107663
+ icon: "panel-right"
107664
+ },
107665
+ { id: "end", kind: "button", labelKey: "pptx.presenter.endPresentation", icon: "x" }
107666
+ ];
107667
+ PRESENT_TOOLBAR_CONTROLS.map(
107668
+ (control) => control.id
107669
+ );
107670
+ PRESENT_TOOLBAR_CONTROLS.flatMap(
107671
+ (control) => control.labelKey === void 0 ? [] : [control.labelKey]
107672
+ );
107673
+ var PRESENT_TOOLBAR_CLASSES = {
107674
+ /** The floating bar itself. */
107675
+ container: "flex items-center gap-1 px-3 py-2 rounded-xl bg-neutral-900/90 backdrop-blur-md border border-white/15 shadow-2xl",
107676
+ /** The auto-hiding positioner the bar sits in. */
107677
+ wrapper: "absolute bottom-6 left-1/2 -translate-x-1/2 z-[80] transition-opacity duration-300",
107678
+ /** Navigation / action button. */
107679
+ button: "flex items-center justify-center w-9 h-9 rounded-md transition-colors text-white/70 hover:text-white hover:bg-white/10 disabled:text-white/20 disabled:cursor-not-allowed",
107680
+ /** Annotation-tool toggle, inactive. */
107681
+ toggle: "relative flex items-center justify-center w-9 h-9 rounded-md transition-colors text-white/70 hover:text-white hover:bg-white/10",
107682
+ /** Annotation-tool toggle, active. */
107683
+ toggleActive: "relative flex items-center justify-center w-9 h-9 rounded-md transition-colors bg-white/25 text-white",
107684
+ /** Colour caret beside a tool toggle. */
107685
+ caret: "flex items-center justify-center w-7 h-9 -ml-1 rounded-r-md transition-colors text-white/50 hover:text-white hover:bg-white/10",
107686
+ /** Vertical hairline between groups. */
107687
+ divider: "w-px h-6 bg-white/20 mx-1",
107688
+ /** Slide counter. */
107689
+ counter: "text-xs font-mono tabular-nums text-white/80 px-1.5 select-none min-w-[48px] text-center",
107690
+ /** Elapsed-time readout. */
107691
+ timer: "flex items-center gap-1.5 text-xs font-mono tabular-nums text-white/60 px-1 select-none",
107692
+ /**
107693
+ * Colour palette popover.
107694
+ *
107695
+ * `w-max` is load-bearing. An absolutely positioned grid shrink-to-fits its
107696
+ * positioned ancestor, which here is the 64px tool+caret pair, so without it
107697
+ * the four 36px swatch columns are squeezed into 50px and overlap each other
107698
+ * to the point that a swatch cannot be clicked. React shipped it that way,
107699
+ * and the ports faithfully reproduced the defect.
107700
+ */
107701
+ palette: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 p-3 w-max bg-neutral-800 rounded-lg border border-white/20 shadow-xl grid grid-cols-4 gap-2",
107702
+ /** One colour swatch inside the palette. */
107703
+ swatch: "w-9 h-9 rounded-full border-2 transition-transform hover:scale-110",
107704
+ /** Underline showing a tool's current colour. */
107705
+ swatchBar: "absolute bottom-0.5 left-1/2 -translate-x-1/2 w-3 h-0.5 rounded-full"
107706
+ };
107707
+ var PRESENTER_CONSOLE_CONTROLS = [
107708
+ {
107709
+ id: "timer-toggle",
107710
+ kind: "button",
107711
+ labelKey: "pptx.presenter.toggleTimer",
107712
+ icon: "circle-pause",
107713
+ activeIcon: "circle-play"
107714
+ },
107715
+ { id: "timer-reset", kind: "button", labelKey: "pptx.presenter.resetTimer", icon: "rotate-ccw" },
107716
+ { id: "divider-timer", kind: "divider" },
107717
+ {
107718
+ id: "all-slides",
107719
+ kind: "button",
107720
+ labelKey: "pptx.presenter.seeAllSlides",
107721
+ icon: "grid-2x2"
107722
+ },
107723
+ { id: "zoom-in", kind: "button", labelKey: "pptx.presenter.zoomIn", icon: "zoom-in" },
107724
+ { id: "zoom-out", kind: "button", labelKey: "pptx.presenter.zoomOut", icon: "zoom-out" },
107725
+ { id: "zoom-reset", kind: "button", labelKey: "pptx.presenter.resetZoom", icon: "scan" },
107726
+ { id: "divider-zoom", kind: "divider" },
107727
+ {
107728
+ id: "laser",
107729
+ kind: "toggle",
107730
+ labelKey: "pptx.presentation.laserPointer",
107731
+ icon: "mouse-pointer-2"
107732
+ },
107733
+ { id: "pen", kind: "toggle", labelKey: "pptx.presentation.pen", icon: "pen-tool" },
107734
+ {
107735
+ id: "highlighter",
107736
+ kind: "toggle",
107737
+ labelKey: "pptx.presentation.highlighter",
107738
+ icon: "highlighter"
107739
+ },
107740
+ { id: "eraser", kind: "toggle", labelKey: "pptx.presentation.eraser", icon: "eraser" },
107741
+ { id: "divider-tools", kind: "divider" },
107742
+ { id: "blackout-black", kind: "toggle", labelKey: "pptx.presenter.blackScreen", glyph: "B" },
107743
+ { id: "blackout-white", kind: "toggle", labelKey: "pptx.presenter.whiteScreen", glyph: "W" },
107744
+ {
107745
+ id: "captions",
107746
+ kind: "toggle",
107747
+ labelKey: "pptx.slideShow.subtitlesTooltip",
107748
+ icon: "captions"
107749
+ },
107750
+ { id: "spacer", kind: "spacer" },
107751
+ {
107752
+ id: "audience",
107753
+ kind: "toggle",
107754
+ labelKey: "pptx.presenter.openAudienceWindow",
107755
+ activeLabelKey: "pptx.presenter.closeAudienceWindow",
107756
+ icon: "monitor",
107757
+ activeIcon: "monitor-off"
107758
+ },
107759
+ {
107760
+ id: "swap-displays",
107761
+ kind: "button",
107762
+ labelKey: "pptx.presenter.swapDisplays",
107763
+ icon: "arrow-left-right"
107764
+ },
107765
+ { id: "end", kind: "button", labelKey: "pptx.presenter.endPresentation", icon: "x" }
107766
+ ];
107767
+ PRESENTER_CONSOLE_CONTROLS.map(
107768
+ (control) => control.id
107769
+ );
107770
+ PRESENTER_CONSOLE_CONTROLS.flatMap(
107771
+ (control) => control.labelKey === void 0 ? [] : [control.labelKey]
107772
+ );
107773
+ var PRESENTER_NAVIGATOR_LABEL_KEYS = {
107774
+ title: "pptx.presenter.slideNavigator",
107775
+ subtitle: "pptx.presenter.seeAllSlides",
107776
+ close: "pptx.presenter.closeNavigator"
107777
+ };
107778
+ function presenterNextDisabled() {
107779
+ return false;
107780
+ }
107781
+ function presenterPrevDisabled(currentIndex) {
107782
+ return currentIndex <= 0;
107783
+ }
107784
+ var PRESENTER_TIMER_SEGMENT_MS = 5 * 60 * 1e3;
107785
+ function presenterTimerProgress(elapsedMs) {
107786
+ const elapsed = Math.max(0, elapsedMs);
107787
+ return {
107788
+ percent: Math.min(
107789
+ 100,
107790
+ elapsed % PRESENTER_TIMER_SEGMENT_MS / PRESENTER_TIMER_SEGMENT_MS * 100
107791
+ ),
107792
+ segment: Math.floor(elapsed / PRESENTER_TIMER_SEGMENT_MS)
107793
+ };
107794
+ }
107795
+ var PRESENTER_CONSOLE_CLASSES = {
107796
+ /** The console root, laid over the show stage. */
107797
+ root: "absolute inset-0 z-50 flex flex-col bg-card text-foreground",
107798
+ /** The control strip across the top. */
107799
+ strip: "flex flex-wrap items-center gap-1 border-b border-border bg-card px-3 py-2",
107800
+ /** A strip control, inactive. */
107801
+ control: "inline-flex h-9 min-w-9 items-center justify-center gap-2 rounded-md px-2 text-xs transition-colors bg-muted text-foreground hover:bg-accent",
107802
+ /** A strip control, active. */
107803
+ controlActive: "inline-flex h-9 min-w-9 items-center justify-center gap-2 rounded-md px-2 text-xs transition-colors bg-primary text-primary-foreground",
107804
+ /** Vertical hairline between strip groups. */
107805
+ divider: "mx-1 h-6 w-px bg-border",
107806
+ /** Flexible gap pushing the trailing group right. */
107807
+ spacer: "flex-1",
107808
+ /** The body row: current-slide pane plus rail. */
107809
+ body: "flex flex-1 min-h-0",
107810
+ /** The current-slide pane. */
107811
+ main: "relative flex-[7] flex flex-col items-center justify-center bg-black p-6 min-w-0 overflow-hidden",
107812
+ /** The right-hand rail. */
107813
+ rail: "flex flex-[3] min-w-[260px] max-w-[440px] flex-col border-l border-border bg-background",
107814
+ /** Rail section heading (Current Time / Next Slide / Speaker Notes). */
107815
+ railHeading: "text-[10px] uppercase tracking-wider text-muted-foreground",
107816
+ /** Timer progress bar track. */
107817
+ progressTrack: "h-1.5 w-full bg-muted/60 flex-shrink-0",
107818
+ /** Timer progress bar fill. */
107819
+ progressFill: "h-full bg-primary transition-[width] duration-1000 ease-linear",
107820
+ /** The "all slides" navigator overlay. */
107821
+ navigator: "absolute inset-0 z-[120] overflow-auto bg-card p-6",
107822
+ /** The navigator's tile grid. */
107823
+ navigatorGrid: "grid gap-5 [grid-template-columns:repeat(auto-fill,minmax(220px,1fr))]"
107824
+ };
107825
+ var AUDIENCE_FULLSCREEN_BOUNCE_MS = 1e3;
107826
+ function createPresenterShowGuard(options) {
107827
+ const graceMs = options?.graceMs ?? AUDIENCE_FULLSCREEN_BOUNCE_MS;
107828
+ let armedAt;
107829
+ const stillArmed = (now) => armedAt !== void 0 && now - armedAt >= 0 && now - armedAt <= graceMs;
107830
+ return {
107831
+ expectAudienceBounce(now = Date.now()) {
107832
+ armedAt = now;
107833
+ },
107834
+ classifyFullscreenExit(now = Date.now()) {
107835
+ if (!stillArmed(now)) {
107836
+ armedAt = void 0;
107837
+ return "end-show";
107838
+ }
107839
+ armedAt = void 0;
107840
+ return "restore-show";
107841
+ },
107842
+ isExpectingBounce(now = Date.now()) {
107843
+ return stillArmed(now);
107844
+ },
107845
+ disarm() {
107846
+ armedAt = void 0;
107847
+ }
107848
+ };
107849
+ }
107524
107850
  function createPresentationKeyBuffer() {
107525
107851
  return { digits: "" };
107526
107852
  }
@@ -109022,6 +109348,134 @@ function getAriaRoleDescription(element) {
109022
109348
  return void 0;
109023
109349
  }
109024
109350
  }
109351
+ function shouldLoopContinuously(input) {
109352
+ return Boolean(input.loopContinuously) || input.showType === "kiosk";
109353
+ }
109354
+ function resolveAutoAdvanceDelayMs(slide, options) {
109355
+ if (options?.useTimings === false) {
109356
+ return void 0;
109357
+ }
109358
+ const advanceAfterMs = slide?.transition?.advanceAfterMs;
109359
+ if (typeof advanceAfterMs !== "number" || !Number.isFinite(advanceAfterMs) || advanceAfterMs < 0) {
109360
+ return void 0;
109361
+ }
109362
+ return advanceAfterMs;
109363
+ }
109364
+ var PRESENTATION_INERT_CLICK_SELECTOR = 'a, button, input, select, textarea, video, audio, [data-pptx-action], [role="dialog"]';
109365
+ function isInertMedia(node) {
109366
+ return (node.tagName === "VIDEO" || node.tagName === "AUDIO") && !node.controls;
109367
+ }
109368
+ function isPresentationAdvanceClick(target) {
109369
+ if (typeof Element === "undefined" || !(target instanceof Element)) {
109370
+ return false;
109371
+ }
109372
+ for (let node = target; node !== null; node = node.parentElement) {
109373
+ if (isInertMedia(node)) {
109374
+ continue;
109375
+ }
109376
+ if (node.matches(PRESENTATION_INERT_CLICK_SELECTOR)) {
109377
+ return false;
109378
+ }
109379
+ }
109380
+ return true;
109381
+ }
109382
+ function applyRehearsalTimings(slides, timings) {
109383
+ return slides.map((slide, index) => {
109384
+ const advanceAfterMs = timings[index];
109385
+ if (typeof advanceAfterMs !== "number") {
109386
+ return slide;
109387
+ }
109388
+ return {
109389
+ ...slide,
109390
+ transition: {
109391
+ ...slide.transition,
109392
+ type: slide.transition?.type ?? "none",
109393
+ advanceAfterMs
109394
+ }
109395
+ };
109396
+ });
109397
+ }
109398
+ function computeEntranceAnimationDelay(delayMs, animationIndex) {
109399
+ return Math.max(0, delayMs || 0) + animationIndex * 60;
109400
+ }
109401
+ var NO_OP_ACTION = "ppaction://noaction";
109402
+ function isNoOpPresentationAction(action) {
109403
+ if (!action) {
109404
+ return true;
109405
+ }
109406
+ const verb = (action.action ?? "").trim().toLowerCase();
109407
+ if (verb === NO_OP_ACTION) {
109408
+ return true;
109409
+ }
109410
+ return verb.length === 0 && typeof action.targetSlideIndex !== "number" && !(action.url ?? "").trim();
109411
+ }
109412
+ function resolvePresentationAction(action, options) {
109413
+ const soundPath = action?.soundPath;
109414
+ if (!action || isNoOpPresentationAction(action)) {
109415
+ return { intent: { kind: "none" }, soundPath };
109416
+ }
109417
+ const verb = (action.action ?? "").toLowerCase();
109418
+ if (typeof action.targetSlideIndex === "number" && Number.isFinite(action.targetSlideIndex)) {
109419
+ if (options.slideCount <= 0) {
109420
+ return { intent: { kind: "none" }, soundPath };
109421
+ }
109422
+ const slideIndex = Math.max(
109423
+ 0,
109424
+ Math.min(options.slideCount - 1, Math.floor(action.targetSlideIndex))
109425
+ );
109426
+ return { intent: { kind: "goToSlide", slideIndex }, soundPath };
109427
+ }
109428
+ if (verb.includes("hlinkshowjump")) {
109429
+ if (verb.includes("nextslide")) {
109430
+ return { intent: { kind: "move", direction: 1 }, soundPath };
109431
+ }
109432
+ if (verb.includes("previousslide")) {
109433
+ return { intent: { kind: "move", direction: -1 }, soundPath };
109434
+ }
109435
+ if (verb.includes("firstslide")) {
109436
+ return { intent: { kind: "goToSlide", slideIndex: 0 }, soundPath };
109437
+ }
109438
+ if (verb.includes("lastslide")) {
109439
+ return {
109440
+ intent: options.slideCount > 0 ? { kind: "goToSlide", slideIndex: options.slideCount - 1 } : { kind: "none" },
109441
+ soundPath
109442
+ };
109443
+ }
109444
+ if (verb.includes("endshow")) {
109445
+ return { intent: { kind: "endShow" }, soundPath };
109446
+ }
109447
+ return { intent: { kind: "none" }, soundPath };
109448
+ }
109449
+ if (verb.includes("hlinksldjump")) {
109450
+ return { intent: { kind: "none" }, soundPath };
109451
+ }
109452
+ const url = (action.url ?? "").trim();
109453
+ if (url && isUrlSafe(url)) {
109454
+ return { intent: { kind: "openUrl", url }, soundPath };
109455
+ }
109456
+ return { intent: { kind: "none" }, soundPath };
109457
+ }
109458
+ function runPresentationAction(action, options, runner) {
109459
+ const { intent, soundPath } = resolvePresentationAction(action, options);
109460
+ if (soundPath && runner.playSound) {
109461
+ runner.playSound(soundPath);
109462
+ }
109463
+ switch (intent.kind) {
109464
+ case "goToSlide":
109465
+ runner.goToSlide(intent.slideIndex);
109466
+ return true;
109467
+ case "move":
109468
+ runner.move(intent.direction);
109469
+ return true;
109470
+ case "endShow":
109471
+ runner.endShow();
109472
+ return true;
109473
+ case "openUrl":
109474
+ return safeOpenUrl(intent.url);
109475
+ default:
109476
+ return false;
109477
+ }
109478
+ }
109025
109479
  function elementHasTextHyperlink(element) {
109026
109480
  if (!hasTextProperties(element)) {
109027
109481
  return false;
@@ -109030,10 +109484,10 @@ function elementHasTextHyperlink(element) {
109030
109484
  }
109031
109485
  function isElementActionable(element, options = {}) {
109032
109486
  const { hasActionHandler = true, hasHyperlinkHandler = true, hasZoomHandler = true } = options;
109033
- if (element.actionClick && hasActionHandler) {
109487
+ if (element.actionClick && hasActionHandler && !isNoOpPresentationAction(element.actionClick)) {
109034
109488
  return true;
109035
109489
  }
109036
- if (element.actionHover) {
109490
+ if (element.actionHover && !isNoOpPresentationAction(element.actionHover)) {
109037
109491
  return true;
109038
109492
  }
109039
109493
  if (hasHyperlinkHandler && elementHasTextHyperlink(element)) {
@@ -109041,6 +109495,129 @@ function isElementActionable(element, options = {}) {
109041
109495
  }
109042
109496
  return element.type === "zoom" && hasZoomHandler;
109043
109497
  }
109498
+ var LINK_TOOLTIP_HOST_CLASS = "pptx-link-host";
109499
+ var LINK_TOOLTIP_CLASS = "pptx-link-tooltip";
109500
+ var LINK_TOOLTIP_PANEL_CLASS = "pptx-link-tooltip-panel";
109501
+ var LINK_TOOLTIP_LABEL_CLASS = "pptx-link-tooltip-label";
109502
+ var LINK_TOOLTIP_HINT_CLASS = "pptx-link-tooltip-hint";
109503
+ var ACTION_INDICATOR_CLASS = "pptx-action-indicator";
109504
+ var ACTION_INDICATOR_ICON_PATH = "M13 2L3 14h9l-1 8 10-12h-9l1-8z";
109505
+ var ACTION_AFFORDANCE_CSS = `
109506
+ .${ACTION_INDICATOR_CLASS} {
109507
+ position: absolute;
109508
+ top: -4px;
109509
+ right: -4px;
109510
+ z-index: 20;
109511
+ display: flex;
109512
+ width: 16px;
109513
+ height: 16px;
109514
+ align-items: center;
109515
+ justify-content: center;
109516
+ border-radius: 9999px;
109517
+ background: #f59e0b;
109518
+ /* Left pointer-interactive on purpose: the badge's native title attribute is
109519
+ the only place the deck's screen tip is readable, and a title on a
109520
+ pointer-transparent node never fires. Clicks still reach the element
109521
+ underneath by bubbling, so nothing is swallowed. */
109522
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 10%), 0 1px 2px -1px rgb(0 0 0 / 10%);
109523
+ }
109524
+ .${ACTION_INDICATOR_CLASS} svg {
109525
+ width: 10px;
109526
+ height: 10px;
109527
+ color: #fff;
109528
+ }
109529
+ .${LINK_TOOLTIP_CLASS} {
109530
+ position: absolute;
109531
+ top: 100%;
109532
+ left: 4px;
109533
+ z-index: 9999;
109534
+ max-width: 16rem;
109535
+ margin-top: 4px;
109536
+ opacity: 0;
109537
+ transition: opacity 150ms;
109538
+ pointer-events: none;
109539
+ font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
109540
+ text-align: left;
109541
+ }
109542
+ .${LINK_TOOLTIP_HOST_CLASS}:hover > .${LINK_TOOLTIP_CLASS} {
109543
+ opacity: 1;
109544
+ }
109545
+ .${LINK_TOOLTIP_PANEL_CLASS} {
109546
+ border: 1px solid var(--pptx-border, #374151);
109547
+ border-radius: 0.25rem;
109548
+ background: var(--pptx-popover, #111827);
109549
+ padding: 6px 10px;
109550
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 10%), 0 4px 6px -4px rgb(0 0 0 / 10%);
109551
+ }
109552
+ .${LINK_TOOLTIP_LABEL_CLASS} {
109553
+ overflow: hidden;
109554
+ color: var(--pptx-foreground, #f3f4f6);
109555
+ font-size: 12px;
109556
+ font-weight: 400;
109557
+ font-style: normal;
109558
+ line-height: 16px;
109559
+ letter-spacing: normal;
109560
+ text-decoration: none;
109561
+ text-overflow: ellipsis;
109562
+ text-transform: none;
109563
+ white-space: nowrap;
109564
+ }
109565
+ .${LINK_TOOLTIP_HINT_CLASS} {
109566
+ margin-top: 2px;
109567
+ color: var(--pptx-muted-foreground, #9ca3af);
109568
+ font-size: 10px;
109569
+ font-weight: 400;
109570
+ font-style: normal;
109571
+ line-height: 12px;
109572
+ letter-spacing: normal;
109573
+ text-decoration: none;
109574
+ text-transform: none;
109575
+ }
109576
+ `;
109577
+ var AFFORDANCE_STYLE_ELEMENT_ID = "pptx-action-affordance-styles";
109578
+ function ensureActionAffordanceStyles(doc) {
109579
+ const target = doc ?? (typeof document === "undefined" ? void 0 : document);
109580
+ if (!target || target.getElementById(AFFORDANCE_STYLE_ELEMENT_ID)) {
109581
+ return;
109582
+ }
109583
+ const style = target.createElement("style");
109584
+ style.id = AFFORDANCE_STYLE_ELEMENT_ID;
109585
+ style.textContent = ACTION_AFFORDANCE_CSS;
109586
+ (target.head ?? target.documentElement).appendChild(style);
109587
+ }
109588
+ function actionAffordanceLabels(translate) {
109589
+ return {
109590
+ hasAction: translate("pptx.element.hasAction"),
109591
+ link: translate("pptx.element.linkFallback"),
109592
+ followLink: translate("pptx.linkTooltip.followLink"),
109593
+ presentationMode: translate("pptx.linkTooltip.presentationMode")
109594
+ };
109595
+ }
109596
+ var NO_AFFORDANCE = Object.freeze({
109597
+ showIndicator: false,
109598
+ indicatorTitle: "",
109599
+ showLinkTooltip: false,
109600
+ linkTooltipLabel: "",
109601
+ linkTooltipHint: ""
109602
+ });
109603
+ function resolveElementActionAffordance(element, context) {
109604
+ const { canInteract, presenting = false, labels } = context;
109605
+ const click = element.actionClick;
109606
+ const hover = element.actionHover;
109607
+ if (!canInteract || presenting || !click && !hover) {
109608
+ return NO_AFFORDANCE;
109609
+ }
109610
+ const hasUrl = Boolean(click?.url);
109611
+ return {
109612
+ showIndicator: true,
109613
+ indicatorTitle: click?.tooltip || hover?.tooltip || labels.hasAction,
109614
+ // The tooltip names a CLICK destination, so a hover-only action gets the
109615
+ // badge but no popover: there is nothing to follow and no key to press.
109616
+ showLinkTooltip: Boolean(click),
109617
+ linkTooltipLabel: click?.tooltip || click?.url || click?.action || labels.link,
109618
+ linkTooltipHint: hasUrl ? labels.followLink : labels.presentationMode
109619
+ };
109620
+ }
109044
109621
  var ELEMENT_ACTION_TYPE_OPTIONS = [
109045
109622
  { value: "none", labelKey: "pptx.hyperlink.actionNone" },
109046
109623
  { value: "url", labelKey: "pptx.action.gotoUrl" },
@@ -109529,6 +110106,19 @@ function rebuildDrawingShapesIfCleared(smartArtData, layout, palette, style, ele
109529
110106
  drawingShapes: reflowToDrawingShapes(layoutResult, smartArtData.nodes)
109530
110107
  };
109531
110108
  }
110109
+ function mediaPlaybackAttributes(source) {
110110
+ return {
110111
+ loop: source.loop === true,
110112
+ volume: Math.max(0, Math.min(1, source.volume ?? 1)),
110113
+ playbackRate: Math.max(0.25, Math.min(4, source.playbackSpeed ?? 1))
110114
+ };
110115
+ }
110116
+ function mediaTransportVisible(surface) {
110117
+ if (surface.presenting || surface.preview) {
110118
+ return false;
110119
+ }
110120
+ return surface.canvasTransport;
110121
+ }
109532
110122
  function buildSummaryZoomView(element, lookup) {
109533
110123
  if (element.zoomType !== "summary" || !element.summaryTargets?.length) {
109534
110124
  return void 0;
@@ -111098,56 +111688,6 @@ var VIEWER_SHORTCUT_REFERENCE = [
111098
111688
  { actionKey: "pptx.shortcuts.title", shortcut: "?" }
111099
111689
  ];
111100
111690
  var SHORTCUT_REFERENCE_ITEMS = VIEWER_SHORTCUT_REFERENCE;
111101
- function shouldLoopContinuously(input) {
111102
- return Boolean(input.loopContinuously) || input.showType === "kiosk";
111103
- }
111104
- function resolveAutoAdvanceDelayMs(slide, options) {
111105
- if (options?.useTimings === false) {
111106
- return void 0;
111107
- }
111108
- const advanceAfterMs = slide?.transition?.advanceAfterMs;
111109
- if (typeof advanceAfterMs !== "number" || !Number.isFinite(advanceAfterMs) || advanceAfterMs < 0) {
111110
- return void 0;
111111
- }
111112
- return advanceAfterMs;
111113
- }
111114
- var PRESENTATION_INERT_CLICK_SELECTOR = 'a, button, input, select, textarea, video, audio, [data-pptx-action], [role="dialog"]';
111115
- function isInertMedia(node) {
111116
- return (node.tagName === "VIDEO" || node.tagName === "AUDIO") && !node.controls;
111117
- }
111118
- function isPresentationAdvanceClick(target) {
111119
- if (typeof Element === "undefined" || !(target instanceof Element)) {
111120
- return false;
111121
- }
111122
- for (let node = target; node !== null; node = node.parentElement) {
111123
- if (isInertMedia(node)) {
111124
- continue;
111125
- }
111126
- if (node.matches(PRESENTATION_INERT_CLICK_SELECTOR)) {
111127
- return false;
111128
- }
111129
- }
111130
- return true;
111131
- }
111132
- function applyRehearsalTimings(slides, timings) {
111133
- return slides.map((slide, index) => {
111134
- const advanceAfterMs = timings[index];
111135
- if (typeof advanceAfterMs !== "number") {
111136
- return slide;
111137
- }
111138
- return {
111139
- ...slide,
111140
- transition: {
111141
- ...slide.transition,
111142
- type: slide.transition?.type ?? "none",
111143
- advanceAfterMs
111144
- }
111145
- };
111146
- });
111147
- }
111148
- function computeEntranceAnimationDelay(delayMs, animationIndex) {
111149
- return Math.max(0, delayMs || 0) + animationIndex * 60;
111150
- }
111151
111691
  function resolveCustomShowIndexes(slides, customShow) {
111152
111692
  const keys = customShow.slideRIds ?? customShow.slideIds;
111153
111693
  if (!keys || keys.length === 0) {
@@ -111233,6 +111773,17 @@ function firstShowSlideIndex(showIndexes) {
111233
111773
  function lastShowSlideIndex(showIndexes) {
111234
111774
  return showIndexes.length > 0 ? showIndexes[showIndexes.length - 1] : void 0;
111235
111775
  }
111776
+ var HIDDEN_SLIDE_LABEL_KEY = "pptx.slideSorter.hidden";
111777
+ var HIDDEN_SLIDE_SLASH_GRADIENT = "linear-gradient(to top right, transparent 47%, color-mix(in srgb, currentColor 60%, transparent) 47%, color-mix(in srgb, currentColor 60%, transparent) 53%, transparent 53%)";
111778
+ function hiddenSlideLabelId(surface, slideIndex) {
111779
+ return `pptx-hidden-slide-${surface}-${slideIndex}`;
111780
+ }
111781
+ function hiddenSlideCue(hidden, surface, slideIndex) {
111782
+ if (!hidden) {
111783
+ return { hidden: false, labelId: void 0, marker: void 0 };
111784
+ }
111785
+ return { hidden: true, labelId: hiddenSlideLabelId(surface, slideIndex), marker: "true" };
111786
+ }
111236
111787
  var VIEWER_PREFS_STORAGE_KEY = "pptx-viewer-prefs";
111237
111788
  function hasLocalStorage() {
111238
111789
  return typeof localStorage !== "undefined";
@@ -113839,6 +114390,8 @@ function segmentFrameCount(durationMs, fps) {
113839
114390
  */
113840
114391
 
113841
114392
  exports.ACTION_BUTTON_PRESETS = ACTION_BUTTON_PRESETS;
114393
+ exports.ACTION_INDICATOR_CLASS = ACTION_INDICATOR_CLASS;
114394
+ exports.ACTION_INDICATOR_ICON_PATH = ACTION_INDICATOR_ICON_PATH;
113842
114395
  exports.ARTISTIC_EFFECTS = ARTISTIC_EFFECTS;
113843
114396
  exports.AVATAR_COLOR_SWATCHES = AVATAR_COLOR_SWATCHES;
113844
114397
  exports.BACKSTAGE_NAV = BACKSTAGE_NAV;
@@ -113873,9 +114426,17 @@ exports.FILL_MODE_OPTIONS = FILL_MODE_OPTIONS;
113873
114426
  exports.FILL_PATTERN_LABEL_KEYS = FILL_PATTERN_LABEL_KEYS;
113874
114427
  exports.GRADIENT_TYPE_OPTIONS = GRADIENT_TYPE_OPTIONS;
113875
114428
  exports.HANDOUT_OPTIONS = HANDOUT_OPTIONS;
114429
+ exports.HIDDEN_SLIDE_LABEL_KEY = HIDDEN_SLIDE_LABEL_KEY;
114430
+ exports.HIDDEN_SLIDE_SLASH_GRADIENT = HIDDEN_SLIDE_SLASH_GRADIENT;
114431
+ exports.HIGHLIGHTER_COLORS = HIGHLIGHTER_COLORS;
113876
114432
  exports.INK_REPLAY_KEYFRAMES = INK_REPLAY_KEYFRAMES;
113877
114433
  exports.INSERT_CHART_TYPES = INSERT_CHART_TYPES;
113878
114434
  exports.LBL = LBL;
114435
+ exports.LINK_TOOLTIP_CLASS = LINK_TOOLTIP_CLASS;
114436
+ exports.LINK_TOOLTIP_HINT_CLASS = LINK_TOOLTIP_HINT_CLASS;
114437
+ exports.LINK_TOOLTIP_HOST_CLASS = LINK_TOOLTIP_HOST_CLASS;
114438
+ exports.LINK_TOOLTIP_LABEL_CLASS = LINK_TOOLTIP_LABEL_CLASS;
114439
+ exports.LINK_TOOLTIP_PANEL_CLASS = LINK_TOOLTIP_PANEL_CLASS;
113879
114440
  exports.LOCAL_SYNC_ORIGIN = LOCAL_SYNC_ORIGIN;
113880
114441
  exports.MATERIAL_PRESETS = MATERIAL_PRESETS;
113881
114442
  exports.MAX_ZOOM_SCALE = MAX_ZOOM_SCALE;
@@ -113892,10 +114453,15 @@ exports.OUTLINE_ROW_ATTR = OUTLINE_ROW_ATTR;
113892
114453
  exports.OUTLINE_SLIDE_ATTR = OUTLINE_SLIDE_ATTR;
113893
114454
  exports.OUTLINE_VIEW_ATTR = OUTLINE_VIEW_ATTR;
113894
114455
  exports.PATTERN_OPTIONS = PATTERN_OPTIONS;
114456
+ exports.PEN_COLORS = PEN_COLORS;
113895
114457
  exports.PRESENTATION_CHANNEL_NAME = PRESENTATION_CHANNEL_NAME;
113896
114458
  exports.PRESENTATION_HASH = PRESENTATION_HASH;
113897
114459
  exports.PRESENTATION_MESSAGE_ORIGIN = PRESENTATION_MESSAGE_ORIGIN;
113898
114460
  exports.PRESENTATION_NONCE_KEY = PRESENTATION_NONCE_KEY;
114461
+ exports.PRESENTER_CONSOLE_CLASSES = PRESENTER_CONSOLE_CLASSES;
114462
+ exports.PRESENTER_CONSOLE_CONTROLS = PRESENTER_CONSOLE_CONTROLS;
114463
+ exports.PRESENTER_NAVIGATOR_LABEL_KEYS = PRESENTER_NAVIGATOR_LABEL_KEYS;
114464
+ exports.PRESENT_TOOLBAR_CLASSES = PRESENT_TOOLBAR_CLASSES;
113899
114465
  exports.PRESETS = PRESETS;
113900
114466
  exports.PRESET_THEMES = PRESET_THEMES;
113901
114467
  exports.PptxHandler = PptxHandler;
@@ -113942,6 +114508,7 @@ exports.VIEWER_PREFS_STORAGE_KEY = VIEWER_PREFS_STORAGE_KEY;
113942
114508
  exports.VIEWER_SHORTCUT_REFERENCE = VIEWER_SHORTCUT_REFERENCE;
113943
114509
  exports.WEBM_MIME_CANDIDATES = WEBM_MIME_CANDIDATES;
113944
114510
  exports.acceptsPresentationInput = acceptsPresentationInput;
114511
+ exports.actionAffordanceLabels = actionAffordanceLabels;
113945
114512
  exports.activateModalFocus = activateModalFocus;
113946
114513
  exports.addChartCategory = addChartCategory;
113947
114514
  exports.addChartSeries = addChartSeries;
@@ -113951,6 +114518,7 @@ exports.addSmartArtNode = addSmartArtNode;
113951
114518
  exports.addSmartArtNodeAsChild = addSmartArtNodeAsChild;
113952
114519
  exports.addTagToCollections = addTagToCollections;
113953
114520
  exports.alignElements = alignElements;
114521
+ exports.animationEffectLabel = animationEffectLabel;
113954
114522
  exports.appendPresentationInkPoint = appendPresentationInkPoint;
113955
114523
  exports.appendTableElementColumn = appendTableElementColumn;
113956
114524
  exports.appendTableElementRow = appendTableElementRow;
@@ -114090,6 +114658,7 @@ exports.createDepartureChannel = createDepartureChannel;
114090
114658
  exports.createInitialPresentationSnapshot = createInitialPresentationSnapshot;
114091
114659
  exports.createPresentationKeyBuffer = createPresentationKeyBuffer;
114092
114660
  exports.createPresentationSessionId = createPresentationSessionId;
114661
+ exports.createPresenterShowGuard = createPresenterShowGuard;
114093
114662
  exports.createPresenterTimer = createPresenterTimer;
114094
114663
  exports.createSyncGate = createSyncGate;
114095
114664
  exports.createTouchGestureRecognizer = createTouchGestureRecognizer;
@@ -114116,6 +114685,7 @@ exports.dragValueForPart = dragValueForPart;
114116
114685
  exports.elementActionToPptxAction = elementActionToPptxAction;
114117
114686
  exports.encodeGif = encodeGif;
114118
114687
  exports.endAudienceDisplay = endAudienceDisplay;
114688
+ exports.ensureActionAffordanceStyles = ensureActionAffordanceStyles;
114119
114689
  exports.erasePresentationInkAt = erasePresentationInkAt;
114120
114690
  exports.evaluatePresetShape = evaluatePresetShape;
114121
114691
  exports.extraQuickAccessCommands = extraQuickAccessCommands;
@@ -114177,6 +114747,7 @@ exports.getGroupChildParentFill = getGroupChildParentFill;
114177
114747
  exports.getImageColorWashStyle = getImageColorWashStyle;
114178
114748
  exports.getImageEffectsFilter = getImageEffectsFilter;
114179
114749
  exports.getImageEffectsOpacity = getImageEffectsOpacity;
114750
+ exports.getImageFitStyle = getImageFitStyle;
114180
114751
  exports.getImageSvgFilters = getImageSvgFilters;
114181
114752
  exports.getInkReplayStyles = getInkReplayStyles;
114182
114753
  exports.getInlineEditorSelection = getInlineEditorSelection;
@@ -114217,6 +114788,7 @@ exports.hasShapeProperties = hasShapeProperties;
114217
114788
  exports.hasShowSlideAfter = hasShowSlideAfter;
114218
114789
  exports.hasTextProperties = hasTextProperties;
114219
114790
  exports.hexToRgbChannels = hexToRgbChannels2;
114791
+ exports.hiddenSlideCue = hiddenSlideCue;
114220
114792
  exports.insertTableColumn = insertTableColumn;
114221
114793
  exports.insertTableRow = insertTableRow;
114222
114794
  exports.isActionHidden = isActionHidden;
@@ -114229,11 +114801,9 @@ exports.isEditorTextInputTarget = isEditorTextInputTarget;
114229
114801
  exports.isElementActionable = isElementActionable;
114230
114802
  exports.isElementRendered = isElementRendered;
114231
114803
  exports.isExportAbortError = isExportAbortError;
114232
- exports.isFirstSlide = isFirstSlide;
114233
114804
  exports.isImageLikeElement = isImageLikeElement;
114234
114805
  exports.isInkElement = isInkElement;
114235
114806
  exports.isKeyboardOpen = isKeyboardOpen;
114236
- exports.isLastSlide = isLastSlide;
114237
114807
  exports.isLinkedTextBox = isLinkedTextBox;
114238
114808
  exports.isMixedContentBlocked = isMixedContentBlocked;
114239
114809
  exports.isMobileViewport = isMobileViewport;
@@ -114253,6 +114823,8 @@ exports.mapEditorKey = mapEditorKey;
114253
114823
  exports.mapOutlineKey = mapOutlineKey;
114254
114824
  exports.mapPresentationKey = mapPresentationKey;
114255
114825
  exports.mayLeaveSlideShow = mayLeaveSlideShow;
114826
+ exports.mediaPlaybackAttributes = mediaPlaybackAttributes;
114827
+ exports.mediaTransportVisible = mediaTransportVisible;
114256
114828
  exports.mergeAdditiveSelection = mergeAdditiveSelection;
114257
114829
  exports.mergeCells = mergeCells;
114258
114830
  exports.mergePresentationSnapshot = mergePresentationSnapshot;
@@ -114301,7 +114873,10 @@ exports.pptxActionToElementAction = pptxActionToElementAction;
114301
114873
  exports.preprocessCssForCapture = preprocessCssForCapture;
114302
114874
  exports.presentationInkPath = presentationInkPath;
114303
114875
  exports.presenterElapsed = presenterElapsed;
114876
+ exports.presenterNextDisabled = presenterNextDisabled;
114304
114877
  exports.presenterPaneAdvancesOnClick = presenterPaneAdvancesOnClick;
114878
+ exports.presenterPrevDisabled = presenterPrevDisabled;
114879
+ exports.presenterTimerProgress = presenterTimerProgress;
114305
114880
  exports.pressuresToWidths = pressuresToWidths;
114306
114881
  exports.previousShowSlideIndex = previousShowSlideIndex;
114307
114882
  exports.printPropertiesFrameSlides = printPropertiesFrameSlides;
@@ -114341,6 +114916,7 @@ exports.resolveAutoAdvanceDelayMs = resolveAutoAdvanceDelayMs;
114341
114916
  exports.resolveAutoFitFontScale = resolveAutoFitFontScale;
114342
114917
  exports.resolveCssTextAlign = resolveCssTextAlign;
114343
114918
  exports.resolveDrawingShapeNodeId = resolveDrawingShapeNodeId;
114919
+ exports.resolveElementActionAffordance = resolveElementActionAffordance;
114344
114920
  exports.resolveFontForScript = resolveFontForScript;
114345
114921
  exports.resolveFontRefIdx = resolveFontRefIdx;
114346
114922
  exports.resolveGroupChildFill = resolveGroupChildFill;
@@ -114365,6 +114941,7 @@ exports.restoreSegmentSelection = restoreSegmentSelection;
114365
114941
  exports.revealedSmartArtNodeCount = revealedSmartArtNodeCount;
114366
114942
  exports.rulerDragToGuidePosition = rulerDragToGuidePosition;
114367
114943
  exports.runMediaCommand = runMediaCommand;
114944
+ exports.runPresentationAction = runPresentationAction;
114368
114945
  exports.safeOpenUrl = safeOpenUrl;
114369
114946
  exports.sanitizeColor = sanitizeColor;
114370
114947
  exports.sanitizeDownloadFilename = sanitizeDownloadFilename;