pptx-react-viewer 4.65.0 → 4.67.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 (104) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +10 -0
  3. package/dist/{AiChatPanel-7U7IJRNY.mjs → AiChatPanel-E7CJSTW7.mjs} +1 -1
  4. package/dist/AiChatPanel-E7CJSTW7.mjs.br +0 -0
  5. package/dist/AiChatPanel-E7CJSTW7.mjs.gz +0 -0
  6. package/dist/{AiChatPanel-7AFFNYEN.js → AiChatPanel-PLQ3NBTK.js} +19 -19
  7. package/dist/AiChatPanel-PLQ3NBTK.js.br +0 -0
  8. package/dist/AiChatPanel-PLQ3NBTK.js.gz +0 -0
  9. package/dist/ai.js +2 -2
  10. package/dist/ai.js.br +0 -0
  11. package/dist/ai.js.gz +0 -0
  12. package/dist/ai.mjs +1 -1
  13. package/dist/ai.mjs.br +0 -0
  14. package/dist/ai.mjs.gz +0 -0
  15. package/dist/{chunk-G5JGUSBL.mjs → chunk-3LJ5QUU3.mjs} +271 -261
  16. package/dist/chunk-3LJ5QUU3.mjs.br +0 -0
  17. package/dist/chunk-3LJ5QUU3.mjs.gz +0 -0
  18. package/dist/{chunk-VGU5S37T.js → chunk-F5UOILTY.js} +466 -456
  19. package/dist/chunk-F5UOILTY.js.br +0 -0
  20. package/dist/chunk-F5UOILTY.js.gz +0 -0
  21. package/dist/{chunk-5ZW3GP6C.mjs → chunk-FBSPQYRE.mjs} +72 -738
  22. package/dist/chunk-FBSPQYRE.mjs.br +0 -0
  23. package/dist/chunk-FBSPQYRE.mjs.gz +0 -0
  24. package/dist/{chunk-WAIX4VJ2.mjs → chunk-JZE6BORE.mjs} +1 -1
  25. package/dist/chunk-JZE6BORE.mjs.br +0 -0
  26. package/dist/chunk-JZE6BORE.mjs.gz +0 -0
  27. package/dist/{chunk-VMX3IDQB.mjs → chunk-LRDW6EH7.mjs} +22 -11
  28. package/dist/chunk-LRDW6EH7.mjs.br +0 -0
  29. package/dist/chunk-LRDW6EH7.mjs.gz +0 -0
  30. package/dist/{chunk-PNDORR6S.js → chunk-LVEFHZ76.js} +1 -1
  31. package/dist/chunk-LVEFHZ76.js.br +0 -0
  32. package/dist/chunk-LVEFHZ76.js.gz +0 -0
  33. package/dist/{chunk-5DBKW7F3.js → chunk-P2COO2QO.js} +71 -736
  34. package/dist/chunk-P2COO2QO.js.br +0 -0
  35. package/dist/chunk-P2COO2QO.js.gz +0 -0
  36. package/dist/{chunk-LUKGXRHZ.js → chunk-ZLPMXC55.js} +578 -567
  37. package/dist/chunk-ZLPMXC55.js.br +0 -0
  38. package/dist/chunk-ZLPMXC55.js.gz +0 -0
  39. package/dist/i18n/de.cjs +3 -0
  40. package/dist/i18n/de.cjs.br +0 -0
  41. package/dist/i18n/de.cjs.gz +0 -0
  42. package/dist/i18n/de.mjs +3 -0
  43. package/dist/i18n/de.mjs.br +0 -0
  44. package/dist/i18n/de.mjs.gz +0 -0
  45. package/dist/i18n/es.cjs +3 -0
  46. package/dist/i18n/es.cjs.br +0 -0
  47. package/dist/i18n/es.cjs.gz +0 -0
  48. package/dist/i18n/es.mjs +3 -0
  49. package/dist/i18n/es.mjs.br +0 -0
  50. package/dist/i18n/es.mjs.gz +0 -0
  51. package/dist/i18n/fr.cjs +3 -0
  52. package/dist/i18n/fr.cjs.br +0 -0
  53. package/dist/i18n/fr.cjs.gz +0 -0
  54. package/dist/i18n/fr.mjs +3 -0
  55. package/dist/i18n/fr.mjs.br +0 -0
  56. package/dist/i18n/fr.mjs.gz +0 -0
  57. package/dist/i18n/zh-CN.cjs +3 -0
  58. package/dist/i18n/zh-CN.cjs.br +0 -0
  59. package/dist/i18n/zh-CN.cjs.gz +0 -0
  60. package/dist/i18n/zh-CN.mjs +3 -0
  61. package/dist/i18n/zh-CN.mjs.br +0 -0
  62. package/dist/i18n/zh-CN.mjs.gz +0 -0
  63. package/dist/index.d.ts +4 -1
  64. package/dist/index.js +27 -27
  65. package/dist/index.js.br +0 -0
  66. package/dist/index.js.gz +0 -0
  67. package/dist/index.mjs +4 -4
  68. package/dist/index.mjs.br +0 -0
  69. package/dist/index.mjs.gz +0 -0
  70. package/dist/internals.d.ts +9 -2
  71. package/dist/internals.js +81 -81
  72. package/dist/internals.js.br +0 -0
  73. package/dist/internals.js.gz +0 -0
  74. package/dist/internals.mjs +2 -2
  75. package/dist/internals.mjs.br +0 -0
  76. package/dist/internals.mjs.gz +0 -0
  77. package/dist/viewer/index.d.ts +4 -1
  78. package/dist/viewer/index.js +21 -21
  79. package/dist/viewer/index.js.br +0 -0
  80. package/dist/viewer/index.js.gz +0 -0
  81. package/dist/viewer/index.mjs +4 -4
  82. package/dist/viewer/index.mjs.br +0 -0
  83. package/dist/viewer/index.mjs.gz +0 -0
  84. package/package.json +4 -4
  85. package/dist/AiChatPanel-7AFFNYEN.js.br +0 -0
  86. package/dist/AiChatPanel-7AFFNYEN.js.gz +0 -0
  87. package/dist/AiChatPanel-7U7IJRNY.mjs.br +0 -0
  88. package/dist/AiChatPanel-7U7IJRNY.mjs.gz +0 -0
  89. package/dist/chunk-5DBKW7F3.js.br +0 -0
  90. package/dist/chunk-5DBKW7F3.js.gz +0 -0
  91. package/dist/chunk-5ZW3GP6C.mjs.br +0 -0
  92. package/dist/chunk-5ZW3GP6C.mjs.gz +0 -0
  93. package/dist/chunk-G5JGUSBL.mjs.br +0 -0
  94. package/dist/chunk-G5JGUSBL.mjs.gz +0 -0
  95. package/dist/chunk-LUKGXRHZ.js.br +0 -0
  96. package/dist/chunk-LUKGXRHZ.js.gz +0 -0
  97. package/dist/chunk-PNDORR6S.js.br +0 -0
  98. package/dist/chunk-PNDORR6S.js.gz +0 -0
  99. package/dist/chunk-VGU5S37T.js.br +0 -0
  100. package/dist/chunk-VGU5S37T.js.gz +0 -0
  101. package/dist/chunk-VMX3IDQB.mjs.br +0 -0
  102. package/dist/chunk-VMX3IDQB.mjs.gz +0 -0
  103. package/dist/chunk-WAIX4VJ2.mjs.br +0 -0
  104. package/dist/chunk-WAIX4VJ2.mjs.gz +0 -0
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk5DBKW7F3_js = require('./chunk-5DBKW7F3.js');
3
+ var chunkP2COO2QO_js = require('./chunk-P2COO2QO.js');
4
4
  var pptx = require('ooxml-ui/pptx');
5
5
  var React17 = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
@@ -604,9 +604,9 @@ function differsOnlyInMasterSet(previous, next) {
604
604
  }
605
605
  function recordExplicitSlideUpdate(history, previous, before, label) {
606
606
  if (previous && serializeHistoryDocument(previous) !== serializeHistoryDocument(before)) {
607
- history.record(chunk5DBKW7F3_js.cloneHistorySnapshot(previous), previous.actionLabel);
607
+ history.record(chunkP2COO2QO_js.cloneHistorySnapshot(previous), previous.actionLabel);
608
608
  }
609
- history.record({ ...chunk5DBKW7F3_js.cloneHistorySnapshot(before), actionLabel: label }, label);
609
+ history.record({ ...chunkP2COO2QO_js.cloneHistorySnapshot(before), actionLabel: label }, label);
610
610
  }
611
611
  var POLL_INTERVAL_MS = 16;
612
612
  function usePointerReleaseWakeup(hasActivePointerInteraction) {
@@ -688,8 +688,8 @@ function useEditorHistory(input) {
688
688
  width: canvasSize.width,
689
689
  height: canvasSize.height,
690
690
  activeSlideIndex,
691
- slides: slides.map(chunk5DBKW7F3_js.cloneSlide),
692
- templateElementsBySlideId: chunk5DBKW7F3_js.cloneTemplateElementsBySlideId(templateElementsBySlideId),
691
+ slides: slides.map(chunkP2COO2QO_js.cloneSlide),
692
+ templateElementsBySlideId: chunkP2COO2QO_js.cloneTemplateElementsBySlideId(templateElementsBySlideId),
693
693
  ...recordedTheme ? { theme: recordedTheme } : {},
694
694
  ...actionLabel ? { actionLabel } : {}
695
695
  };
@@ -703,9 +703,9 @@ function useEditorHistory(input) {
703
703
  width: snapshot.width,
704
704
  height: snapshot.height
705
705
  });
706
- setSlides(snapshot.slides.map(chunk5DBKW7F3_js.cloneSlide));
706
+ setSlides(snapshot.slides.map(chunkP2COO2QO_js.cloneSlide));
707
707
  setTemplateElementsBySlideId(
708
- chunk5DBKW7F3_js.cloneTemplateElementsBySlideId(snapshot.templateElementsBySlideId)
708
+ chunkP2COO2QO_js.cloneTemplateElementsBySlideId(snapshot.templateElementsBySlideId)
709
709
  );
710
710
  setActiveSlideIndex(Math.min(snapshot.activeSlideIndex, maxSlideIndex));
711
711
  setSelectedElementIds([]);
@@ -771,8 +771,8 @@ function useEditorHistory(input) {
771
771
  return;
772
772
  }
773
773
  isApplyingHistoryRef.current = true;
774
- const nextSnapshot = chunk5DBKW7F3_js.cloneHistorySnapshot(result.snapshot);
775
- lastHistorySnapshotRef.current = chunk5DBKW7F3_js.cloneHistorySnapshot(nextSnapshot);
774
+ const nextSnapshot = chunkP2COO2QO_js.cloneHistorySnapshot(result.snapshot);
775
+ lastHistorySnapshotRef.current = chunkP2COO2QO_js.cloneHistorySnapshot(nextSnapshot);
776
776
  lastHistorySerializedRef.current = serializeHistoryDocument(nextSnapshot);
777
777
  applyHistorySnapshot(nextSnapshot);
778
778
  restoreTheme(currentSnapshot, nextSnapshot);
@@ -796,8 +796,8 @@ function useEditorHistory(input) {
796
796
  return;
797
797
  }
798
798
  isApplyingHistoryRef.current = true;
799
- const targetSnapshot = chunk5DBKW7F3_js.cloneHistorySnapshot(result.snapshot);
800
- lastHistorySnapshotRef.current = chunk5DBKW7F3_js.cloneHistorySnapshot(targetSnapshot);
799
+ const targetSnapshot = chunkP2COO2QO_js.cloneHistorySnapshot(result.snapshot);
800
+ lastHistorySnapshotRef.current = chunkP2COO2QO_js.cloneHistorySnapshot(targetSnapshot);
801
801
  lastHistorySerializedRef.current = serializeHistoryDocument(targetSnapshot);
802
802
  applyHistorySnapshot(targetSnapshot);
803
803
  restoreTheme(currentSnapshot, targetSnapshot);
@@ -815,7 +815,7 @@ function useEditorHistory(input) {
815
815
  (initialSnapshot) => {
816
816
  history.clear();
817
817
  if (initialSnapshot) {
818
- const clonedInitial = chunk5DBKW7F3_js.cloneHistorySnapshot(initialSnapshot);
818
+ const clonedInitial = chunkP2COO2QO_js.cloneHistorySnapshot(initialSnapshot);
819
819
  lastHistorySnapshotRef.current = clonedInitial;
820
820
  lastHistorySerializedRef.current = serializeHistoryDocument(clonedInitial);
821
821
  } else {
@@ -889,16 +889,16 @@ function useEditorHistory(input) {
889
889
  slides
890
890
  ]);
891
891
  const commitSlides = (nextSlides, label, beforeSlides = slides, nextSlideMasters) => {
892
- const before = { ...buildHistorySnapshot(), slides: beforeSlides.map(chunk5DBKW7F3_js.cloneSlide) };
892
+ const before = { ...buildHistorySnapshot(), slides: beforeSlides.map(chunkP2COO2QO_js.cloneSlide) };
893
893
  const { theme: beforeTheme, ...unthemed } = before;
894
894
  const afterTheme = nextSlideMasters ? pptx.historyTheme(theme, nextSlideMasters) : beforeTheme;
895
895
  const after = {
896
896
  ...unthemed,
897
- slides: nextSlides.map(chunk5DBKW7F3_js.cloneSlide),
897
+ slides: nextSlides.map(chunkP2COO2QO_js.cloneSlide),
898
898
  ...afterTheme ? { theme: afterTheme } : {}
899
899
  };
900
900
  recordExplicitSlideUpdate(history, lastHistorySnapshotRef.current, before, label);
901
- lastHistorySnapshotRef.current = chunk5DBKW7F3_js.cloneHistorySnapshot(after);
901
+ lastHistorySnapshotRef.current = chunkP2COO2QO_js.cloneHistorySnapshot(after);
902
902
  lastHistorySerializedRef.current = serializeHistoryDocument(after);
903
903
  isApplyingHistoryRef.current = false;
904
904
  setSlides(nextSlides);
@@ -1092,22 +1092,22 @@ function useZoomViewport({
1092
1092
  selectedElements.forEach((element) => {
1093
1093
  minX = Math.min(minX, element.x);
1094
1094
  minY = Math.min(minY, element.y);
1095
- maxX = Math.max(maxX, element.x + Math.max(element.width, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE));
1096
- maxY = Math.max(maxY, element.y + Math.max(element.height, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE));
1095
+ maxX = Math.max(maxX, element.x + Math.max(element.width, chunkP2COO2QO_js.MIN_ELEMENT_SIZE));
1096
+ maxY = Math.max(maxY, element.y + Math.max(element.height, chunkP2COO2QO_js.MIN_ELEMENT_SIZE));
1097
1097
  });
1098
1098
  if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {
1099
1099
  return;
1100
1100
  }
1101
1101
  const selectionBounds = { minX, minY, maxX, maxY };
1102
- const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE);
1103
- const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE);
1102
+ const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX, chunkP2COO2QO_js.MIN_ELEMENT_SIZE);
1103
+ const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY, chunkP2COO2QO_js.MIN_ELEMENT_SIZE);
1104
1104
  const availableWidth = Math.max(
1105
- effectiveEditorDimensions.width - chunk5DBKW7F3_js.ZOOM_TO_SELECTION_PADDING,
1106
- chunk5DBKW7F3_js.MIN_ELEMENT_SIZE
1105
+ effectiveEditorDimensions.width - chunkP2COO2QO_js.ZOOM_TO_SELECTION_PADDING,
1106
+ chunkP2COO2QO_js.MIN_ELEMENT_SIZE
1107
1107
  );
1108
1108
  const availableHeight = Math.max(
1109
- effectiveEditorDimensions.height - chunk5DBKW7F3_js.ZOOM_TO_SELECTION_PADDING,
1110
- chunk5DBKW7F3_js.MIN_ELEMENT_SIZE
1109
+ effectiveEditorDimensions.height - chunkP2COO2QO_js.ZOOM_TO_SELECTION_PADDING,
1110
+ chunkP2COO2QO_js.MIN_ELEMENT_SIZE
1111
1111
  );
1112
1112
  const targetEditorScale = Math.min(
1113
1113
  availableWidth / boundsWidth,
@@ -4022,12 +4022,13 @@ function useViewerCoreState(_input) {
4022
4022
  React17.useEffect(() => () => livePatcher.dispose(), [livePatcher]);
4023
4023
  const [mode, setMode] = React17.useState("edit");
4024
4024
  const [loading, setLoading] = React17.useState(true);
4025
+ const [fontProgress, setFontProgress] = React17.useState(null);
4025
4026
  const [error, setError] = React17.useState(null);
4026
4027
  const { slides, setSlides, slidesRef } = useSlideState();
4027
4028
  const [templateElementsBySlideId, setTemplateElementsBySlideId] = React17.useState({});
4028
4029
  const [canvasSize, setCanvasSize] = React17.useState({
4029
- width: chunk5DBKW7F3_js.DEFAULT_CANVAS_WIDTH,
4030
- height: chunk5DBKW7F3_js.DEFAULT_CANVAS_HEIGHT
4030
+ width: chunkP2COO2QO_js.DEFAULT_CANVAS_WIDTH,
4031
+ height: chunkP2COO2QO_js.DEFAULT_CANVAS_HEIGHT
4031
4032
  });
4032
4033
  const [slideSizeEmu, setSlideSizeEmu] = React17.useState();
4033
4034
  const [activeSlideIndex, setActiveSlideIndex] = React17.useState(0);
@@ -4124,6 +4125,8 @@ function useViewerCoreState(_input) {
4124
4125
  setMode,
4125
4126
  loading,
4126
4127
  setLoading,
4128
+ fontProgress,
4129
+ setFontProgress,
4127
4130
  error,
4128
4131
  setError,
4129
4132
  slides,
@@ -4363,6 +4366,98 @@ function useViewerState(input) {
4363
4366
  var glyphOutlineFontCache = /* @__PURE__ */ new pptx.GlyphOutlineFontCache();
4364
4367
  var getGlyphOutline = /* @__PURE__ */ pptx.createGlyphOutlineLookup(glyphOutlineFontCache);
4365
4368
 
4369
+ // src/viewer/hooks/useFontInjection.ts
4370
+ var EMBEDDED_FONTS_STYLE_ID = "pptx-embedded-fonts";
4371
+ var GOOGLE_FONTS_LINK_ID = "pptx-google-fonts";
4372
+ var SYMBOL_FONTS_STYLE_ID = "pptx-symbol-font-fallback";
4373
+ var SYMBOL_FONT_FAMILIES = [
4374
+ "Wingdings",
4375
+ "Wingdings 2",
4376
+ "Wingdings 3",
4377
+ "Symbol",
4378
+ "Webdings"
4379
+ ];
4380
+ var FONT_NAME_UNSAFE_CHARS = /["\\\n\r;}<>]/u;
4381
+ function useFontInjection({
4382
+ embeddedFonts,
4383
+ slides,
4384
+ googleFonts
4385
+ }) {
4386
+ const googleFontsBase = pptx.resolveGoogleFontsCss2Base(googleFonts);
4387
+ React17.useEffect(() => {
4388
+ if (!embeddedFonts.length) {
4389
+ return;
4390
+ }
4391
+ const sheet = pptx.createEmbeddedFontsSheet(document, EMBEDDED_FONTS_STYLE_ID);
4392
+ sheet.set(embeddedFonts);
4393
+ return () => sheet.dispose();
4394
+ }, [embeddedFonts]);
4395
+ const referencedFamilies = React17.useMemo(() => pptx.collectReferencedFontFamilies(slides), [slides]);
4396
+ React17.useEffect(() => {
4397
+ let cancelled = false;
4398
+ void pptx.resolveGoogleWebfontHref(slides, embeddedFonts, void 0, googleFontsBase).then(
4399
+ (href) => {
4400
+ if (cancelled) {
4401
+ return null;
4402
+ }
4403
+ pptx.syncGoogleWebfontStylesheet(document, GOOGLE_FONTS_LINK_ID, href);
4404
+ return href;
4405
+ }
4406
+ );
4407
+ return () => {
4408
+ cancelled = true;
4409
+ };
4410
+ }, [embeddedFonts, slides, googleFontsBase]);
4411
+ React17.useEffect(() => () => document.getElementById(GOOGLE_FONTS_LINK_ID)?.remove(), []);
4412
+ const [, setOutlineFontsTick] = React17.useState(0);
4413
+ React17.useEffect(() => {
4414
+ let cancelled = false;
4415
+ void pptx.loadDeckWebfontOutlines({
4416
+ slides,
4417
+ embeddedFonts,
4418
+ googleFontsBase,
4419
+ cache: glyphOutlineFontCache,
4420
+ isCancelled: () => cancelled
4421
+ }).then((registered) => {
4422
+ if (registered && !cancelled) {
4423
+ setOutlineFontsTick((tick) => tick + 1);
4424
+ }
4425
+ return void 0;
4426
+ });
4427
+ return () => {
4428
+ cancelled = true;
4429
+ };
4430
+ }, [embeddedFonts, slides, googleFontsBase]);
4431
+ React17.useEffect(() => {
4432
+ const neededSymbolFonts = SYMBOL_FONT_FAMILIES.filter((f) => referencedFamilies.has(f));
4433
+ if (neededSymbolFonts.length === 0) {
4434
+ return;
4435
+ }
4436
+ const styleEl = document.createElement("style");
4437
+ styleEl.id = SYMBOL_FONTS_STYLE_ID;
4438
+ const rules = neededSymbolFonts.flatMap((font) => {
4439
+ if (typeof font !== "string" || FONT_NAME_UNSAFE_CHARS.test(font)) {
4440
+ return [];
4441
+ }
4442
+ return [
4443
+ `@font-face {
4444
+ font-family: "${font}";
4445
+ src: local("${font}"), local("${font} Regular");
4446
+ font-display: swap;
4447
+ }`
4448
+ ];
4449
+ }).join("\n");
4450
+ styleEl.textContent = rules;
4451
+ document.head.appendChild(styleEl);
4452
+ return () => {
4453
+ const existing = document.getElementById(SYMBOL_FONTS_STYLE_ID);
4454
+ if (existing) {
4455
+ document.head.removeChild(existing);
4456
+ }
4457
+ };
4458
+ }, [referencedFamilies]);
4459
+ }
4460
+
4366
4461
  // src/viewer/hooks/useLoadContent.ts
4367
4462
  function useLoadContent({
4368
4463
  content,
@@ -4406,6 +4501,8 @@ function useLoadContent({
4406
4501
  setModifyVerifier,
4407
4502
  setCompatToasts,
4408
4503
  setLoading,
4504
+ setFontProgress,
4505
+ googleFonts,
4409
4506
  setError,
4410
4507
  setIsDirty,
4411
4508
  setIsEncrypted,
@@ -4419,7 +4516,9 @@ function useLoadContent({
4419
4516
  initialSlideRef.current = initialSlide;
4420
4517
  const limitsRef = React17.useRef(limits);
4421
4518
  limitsRef.current = limits;
4422
- const { t } = chunk5DBKW7F3_js.useTranslation();
4519
+ const googleFontsRef = React17.useRef(googleFonts);
4520
+ googleFontsRef.current = googleFonts;
4521
+ const { t } = chunkP2COO2QO_js.useTranslation();
4423
4522
  const translateRef = React17.useRef(t);
4424
4523
  translateRef.current = t;
4425
4524
  const originalBufferRef = React17.useRef(null);
@@ -4437,6 +4536,7 @@ function useLoadContent({
4437
4536
  (async () => {
4438
4537
  try {
4439
4538
  setLoading(true);
4539
+ setFontProgress?.(null);
4440
4540
  setError(null);
4441
4541
  const buffer = content instanceof Uint8Array ? content.buffer.slice(content.byteOffset, content.byteOffset + content.byteLength) : content;
4442
4542
  originalBufferRef.current = buffer instanceof ArrayBuffer ? buffer : null;
@@ -4504,6 +4604,21 @@ function useLoadContent({
4504
4604
  nextSlides,
4505
4605
  (path) => handler.getImageData(path)
4506
4606
  );
4607
+ const partition = chunkP2COO2QO_js.partitionTemplateElements(nextSlides);
4608
+ if (typeof document !== "undefined") {
4609
+ await pptx.prepareDeckWebfonts({
4610
+ document,
4611
+ linkId: GOOGLE_FONTS_LINK_ID,
4612
+ slides: partition.slides,
4613
+ embeddedFonts: parsed.embeddedFonts ?? [],
4614
+ googleFontsBase: pptx.resolveGoogleFontsCss2Base(googleFontsRef.current),
4615
+ onProgress: (progress) => {
4616
+ if (!cancelled && token === renderTokenRef.current) {
4617
+ setFontProgress?.(progress);
4618
+ }
4619
+ }
4620
+ });
4621
+ }
4507
4622
  if (cancelled || token !== renderTokenRef.current) {
4508
4623
  return;
4509
4624
  }
@@ -4519,12 +4634,11 @@ function useLoadContent({
4519
4634
  }
4520
4635
  resources.commit();
4521
4636
  handlerRef.current = handler;
4522
- const partition = chunk5DBKW7F3_js.partitionTemplateElements(nextSlides);
4523
4637
  setSlides(partition.slides);
4524
4638
  setTemplateElementsBySlideId(partition.templateElementsBySlideId);
4525
4639
  setCanvasSize({
4526
- width: parsed.width ?? chunk5DBKW7F3_js.DEFAULT_CANVAS_WIDTH,
4527
- height: parsed.height ?? chunk5DBKW7F3_js.DEFAULT_CANVAS_HEIGHT
4640
+ width: parsed.width ?? chunkP2COO2QO_js.DEFAULT_CANVAS_WIDTH,
4641
+ height: parsed.height ?? chunkP2COO2QO_js.DEFAULT_CANVAS_HEIGHT
4528
4642
  });
4529
4643
  setSlideSizeEmu(
4530
4644
  typeof parsed.widthEmu === "number" && typeof parsed.heightEmu === "number" && parsed.widthEmu > 0 && parsed.heightEmu > 0 ? {
@@ -4600,6 +4714,7 @@ function useLoadContent({
4600
4714
  } finally {
4601
4715
  resources.releaseIfUncommitted();
4602
4716
  if (!cancelled && token === renderTokenRef.current) {
4717
+ setFontProgress?.(null);
4603
4718
  setLoading(false);
4604
4719
  }
4605
4720
  }
@@ -4940,7 +5055,7 @@ function useElementOperations(input) {
4940
5055
  );
4941
5056
  return;
4942
5057
  }
4943
- if (chunk5DBKW7F3_js.isTemplateElementId(elementId)) {
5058
+ if (chunkP2COO2QO_js.isTemplateElementId(elementId)) {
4944
5059
  const slideId = activeSlide?.id;
4945
5060
  if (slideId) {
4946
5061
  setTemplateElementsBySlideId((prev) => ({
@@ -5227,8 +5342,8 @@ function createCanvasGestures(getInput, frames = animationFrames) {
5227
5342
  }
5228
5343
  function paintResize(resize, transform) {
5229
5344
  const { x, y } = transform;
5230
- const width = Math.max(transform.width, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE);
5231
- const height = Math.max(transform.height, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE);
5345
+ const width = Math.max(transform.width, chunkP2COO2QO_js.MIN_ELEMENT_SIZE);
5346
+ const height = Math.max(transform.height, chunkP2COO2QO_js.MIN_ELEMENT_SIZE);
5232
5347
  resize.lastX = x;
5233
5348
  resize.lastY = y;
5234
5349
  resize.lastWidth = transform.width;
@@ -5285,7 +5400,7 @@ function createCanvasGestures(getInput, frames = animationFrames) {
5285
5400
  getGridSize: () => getInput().gridSpacingPx,
5286
5401
  getSnapToShape: () => getInput().snapToShape,
5287
5402
  getGuides: () => getInput().guides.map(({ axis, position }) => ({ axis, position })),
5288
- getMinSize: () => chunk5DBKW7F3_js.MIN_ELEMENT_SIZE,
5403
+ getMinSize: () => chunkP2COO2QO_js.MIN_ELEMENT_SIZE,
5289
5404
  getSnapExcludeIds: () => armed?.kind === "move" ? Object.keys(armed.drag.startPositionsById) : [],
5290
5405
  getStageOrigin: () => {
5291
5406
  const rect = getInput().canvasStageRef.current?.getBoundingClientRect();
@@ -5366,7 +5481,7 @@ function commitMove(input, drag) {
5366
5481
  const start = drag.startPositionsById[el.id];
5367
5482
  return start ? { ...el, x: start.x + dx, y: start.y + dy } : el;
5368
5483
  });
5369
- return chunk5DBKW7F3_js.applyReroutedConnectors(moved, chunk5DBKW7F3_js.rerouteConnectorsForMovedElements(moved, movedIds));
5484
+ return chunkP2COO2QO_js.applyReroutedConnectors(moved, chunkP2COO2QO_js.rerouteConnectorsForMovedElements(moved, movedIds));
5370
5485
  };
5371
5486
  if (input.editTemplateMode) {
5372
5487
  const slideId = input.activeSlide?.id;
@@ -5397,8 +5512,8 @@ function commitResize(input, resize) {
5397
5512
  if (i !== input.activeSlideIndex) {
5398
5513
  return s;
5399
5514
  }
5400
- const rerouted = chunk5DBKW7F3_js.rerouteConnectorsForMovedElements(s.elements, movedIds);
5401
- return rerouted.length === 0 ? s : { ...s, elements: chunk5DBKW7F3_js.applyReroutedConnectors(s.elements, rerouted) };
5515
+ const rerouted = chunkP2COO2QO_js.rerouteConnectorsForMovedElements(s.elements, movedIds);
5516
+ return rerouted.length === 0 ? s : { ...s, elements: chunkP2COO2QO_js.applyReroutedConnectors(s.elements, rerouted) };
5402
5517
  })
5403
5518
  );
5404
5519
  }
@@ -6233,7 +6348,7 @@ function createStructuredElementHandlers(deps) {
6233
6348
  return;
6234
6349
  }
6235
6350
  const resolved = resolveHyperlinkEditResult(data);
6236
- if (resolved.url && !chunk5DBKW7F3_js.isUrlSafe(resolved.url)) {
6351
+ if (resolved.url && !chunkP2COO2QO_js.isUrlSafe(resolved.url)) {
6237
6352
  return;
6238
6353
  }
6239
6354
  const actionClick = {
@@ -6279,7 +6394,7 @@ function createStructuredElementHandlers(deps) {
6279
6394
  if (!activeSlide) {
6280
6395
  return;
6281
6396
  }
6282
- const preset = chunk5DBKW7F3_js.ACTION_BUTTON_PRESETS.find((p) => p.shapeType === shapeType);
6397
+ const preset = chunkP2COO2QO_js.ACTION_BUTTON_PRESETS.find((p) => p.shapeType === shapeType);
6283
6398
  if (!preset) {
6284
6399
  return;
6285
6400
  }
@@ -6366,7 +6481,7 @@ function useInsertElements(input) {
6366
6481
  width: 300,
6367
6482
  height: 60,
6368
6483
  text: "",
6369
- textStyle: { fontSize: chunk5DBKW7F3_js.DEFAULT_TEXT_FONT_SIZE }
6484
+ textStyle: { fontSize: chunkP2COO2QO_js.DEFAULT_TEXT_FONT_SIZE }
6370
6485
  });
6371
6486
  };
6372
6487
  const handleAddShape = () => {
@@ -6388,7 +6503,7 @@ function useInsertElements(input) {
6388
6503
  }
6389
6504
  });
6390
6505
  };
6391
- const handleAddTable = (rows = chunk5DBKW7F3_js.DEFAULT_TABLE_ROWS, columns = chunk5DBKW7F3_js.DEFAULT_TABLE_COLUMNS) => {
6506
+ const handleAddTable = (rows = chunkP2COO2QO_js.DEFAULT_TABLE_ROWS, columns = chunkP2COO2QO_js.DEFAULT_TABLE_COLUMNS) => {
6392
6507
  if (!activeSlide) {
6393
6508
  return;
6394
6509
  }
@@ -6562,7 +6677,7 @@ function useGroupAlignLayerHandlers(input) {
6562
6677
  history
6563
6678
  } = input;
6564
6679
  const updateElementsOwning = (elementId, updater) => {
6565
- if (editTemplateMode && !chunk5DBKW7F3_js.isTemplateElementId(elementId)) {
6680
+ if (editTemplateMode && !chunkP2COO2QO_js.isTemplateElementId(elementId)) {
6566
6681
  ops.updateSlides(
6567
6682
  (prev) => prev.map(
6568
6683
  (slide, index) => index === activeSlideIndex ? { ...slide, elements: updater(slide.elements) } : slide
@@ -6596,9 +6711,9 @@ function useGroupAlignLayerHandlers(input) {
6596
6711
  return;
6597
6712
  }
6598
6713
  const group = selectedElement;
6599
- const intoTemplate = chunk5DBKW7F3_js.isTemplateElementId(group.id);
6714
+ const intoTemplate = chunkP2COO2QO_js.isTemplateElementId(group.id);
6600
6715
  const childIds = group.children.map(
6601
- (child) => intoTemplate ? chunk5DBKW7F3_js.makeCloneId(true, child.id || group.id) : child.id || pptx.generateElementId()
6716
+ (child) => intoTemplate ? chunkP2COO2QO_js.makeCloneId(true, child.id || group.id) : child.id || pptx.generateElementId()
6602
6717
  );
6603
6718
  const { elements, childIds: usedIds } = pptx.ungroupElements(
6604
6719
  ops.activeElements,
@@ -7034,7 +7149,7 @@ function createTableMergeHandlers(input) {
7034
7149
  if (!nextCell || nextCell.hMerge || nextCell.vMerge) {
7035
7150
  return;
7036
7151
  }
7037
- const newTableData = chunk5DBKW7F3_js.mergeCells(
7152
+ const newTableData = chunkP2COO2QO_js.mergeCells(
7038
7153
  [
7039
7154
  { row: rowIndex, col: columnIndex },
7040
7155
  { row: rowIndex, col: nextColIdx }
@@ -7042,7 +7157,7 @@ function createTableMergeHandlers(input) {
7042
7157
  td
7043
7158
  );
7044
7159
  const updates = { tableData: newTableData };
7045
- const newRawXml = chunk5DBKW7F3_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7160
+ const newRawXml = chunkP2COO2QO_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7046
7161
  if (newRawXml) {
7047
7162
  updates.rawXml = newRawXml;
7048
7163
  }
@@ -7068,7 +7183,7 @@ function createTableMergeHandlers(input) {
7068
7183
  if (!targetNextCell || targetNextCell.hMerge || targetNextCell.vMerge) {
7069
7184
  return;
7070
7185
  }
7071
- const newTableData = chunk5DBKW7F3_js.mergeCells(
7186
+ const newTableData = chunkP2COO2QO_js.mergeCells(
7072
7187
  [
7073
7188
  { row: rowIndex, col: columnIndex },
7074
7189
  { row: targetNextRowIdx, col: columnIndex }
@@ -7076,7 +7191,7 @@ function createTableMergeHandlers(input) {
7076
7191
  td
7077
7192
  );
7078
7193
  const updates = { tableData: newTableData };
7079
- const newRawXml = chunk5DBKW7F3_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7194
+ const newRawXml = chunkP2COO2QO_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7080
7195
  if (newRawXml) {
7081
7196
  updates.rawXml = newRawXml;
7082
7197
  }
@@ -7091,9 +7206,9 @@ function createTableMergeHandlers(input) {
7091
7206
  return;
7092
7207
  }
7093
7208
  const td = selectedElement.tableData;
7094
- const newTableData = chunk5DBKW7F3_js.mergeCells(ts.selectedCells, td);
7209
+ const newTableData = chunkP2COO2QO_js.mergeCells(ts.selectedCells, td);
7095
7210
  const updates = { tableData: newTableData };
7096
- const newRawXml = chunk5DBKW7F3_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7211
+ const newRawXml = chunkP2COO2QO_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7097
7212
  if (newRawXml) {
7098
7213
  updates.rawXml = newRawXml;
7099
7214
  }
@@ -7110,9 +7225,9 @@ function createTableMergeHandlers(input) {
7110
7225
  }
7111
7226
  const { rowIndex, columnIndex } = ts;
7112
7227
  const td = selectedElement.tableData;
7113
- const newTableData = chunk5DBKW7F3_js.splitCell(rowIndex, columnIndex, td);
7228
+ const newTableData = chunkP2COO2QO_js.splitCell(rowIndex, columnIndex, td);
7114
7229
  const updates = { tableData: newTableData };
7115
- const newRawXml = chunk5DBKW7F3_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7230
+ const newRawXml = chunkP2COO2QO_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
7116
7231
  if (newRawXml) {
7117
7232
  updates.rawXml = newRawXml;
7118
7233
  }
@@ -7147,7 +7262,7 @@ function createTableStructHandlers(input) {
7147
7262
  updates.tableData = pptx.setCellText(el, rowIndex, colIndex, text).tableData;
7148
7263
  }
7149
7264
  if (el.rawXml) {
7150
- const newRawXml = chunk5DBKW7F3_js.updateCellTextInRawXml(el, rowIndex, colIndex, text);
7265
+ const newRawXml = chunkP2COO2QO_js.updateCellTextInRawXml(el, rowIndex, colIndex, text);
7151
7266
  if (newRawXml) {
7152
7267
  updates.rawXml = newRawXml;
7153
7268
  }
@@ -7171,7 +7286,7 @@ function createTableStructHandlers(input) {
7171
7286
  const { rowIndex, columnIndex: colIndex } = ts;
7172
7287
  const updates = {};
7173
7288
  if (selectedElement.rawXml) {
7174
- const newRawXml = chunk5DBKW7F3_js.updateCellTextStyleInRawXml(
7289
+ const newRawXml = chunkP2COO2QO_js.updateCellTextStyleInRawXml(
7175
7290
  selectedElement,
7176
7291
  rowIndex,
7177
7292
  colIndex,
@@ -7349,7 +7464,7 @@ function useExportSaveAs(input) {
7349
7464
  const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
7350
7465
  const slideSize = pptx.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
7351
7466
  const data = {
7352
- slides: chunk5DBKW7F3_js.buildSaveSlides(slides, templateElementsBySlideId),
7467
+ slides: chunkP2COO2QO_js.buildSaveSlides(slides, templateElementsBySlideId),
7353
7468
  width: canvasSize.width,
7354
7469
  height: canvasSize.height,
7355
7470
  widthEmu: slideSize.widthEmu,
@@ -7512,7 +7627,7 @@ async function captureSlidesAsPngDataUrls(slideStageRef, slideIndices, setActive
7512
7627
  }
7513
7628
  function tilesToPdfPage(tilesResult) {
7514
7629
  return tilesResult.tiles.map((tile) => ({
7515
- image: chunk5DBKW7F3_js.canvasToJpegData(tile.canvas),
7630
+ image: chunkP2COO2QO_js.canvasToJpegData(tile.canvas),
7516
7631
  placement: pptx.placeTileOnPage(
7517
7632
  tile,
7518
7633
  tilesResult.fullWidth,
@@ -7545,7 +7660,7 @@ async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide,
7545
7660
  if (pages.length === 0) {
7546
7661
  throw new Error(i18n.translationsEn["pptx.export.errorNoSlidesPdf"]);
7547
7662
  }
7548
- const pdfBlobUrl = chunk5DBKW7F3_js.buildPdfFromTiledImageData(pages);
7663
+ const pdfBlobUrl = chunkP2COO2QO_js.buildPdfFromTiledImageData(pages);
7549
7664
  pptx.downloadDataUrl(pdfBlobUrl, filename);
7550
7665
  }
7551
7666
  async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, slideNotes, filename = "presentation-notes.pdf", options = {}) {
@@ -7575,7 +7690,7 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
7575
7690
  if (pages.length === 0) {
7576
7691
  throw new Error(i18n.translationsEn["pptx.export.errorNoSlidesNotesPdf"]);
7577
7692
  }
7578
- const pdfDataUrl = chunk5DBKW7F3_js.buildNotesPdf(pages);
7693
+ const pdfDataUrl = chunkP2COO2QO_js.buildNotesPdf(pages);
7579
7694
  pptx.downloadDataUrl(pdfDataUrl, filename);
7580
7695
  }
7581
7696
  async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
@@ -8153,13 +8268,13 @@ function usePrintHandlers(input) {
8153
8268
  const { slides, activeSlideIndex, canvasStageRef, setActiveSlideIndex, canvasSize } = input;
8154
8269
  const handoutMaster = input.handoutMaster ?? input.pptxData?.handoutMaster;
8155
8270
  const [isPrintDialogOpen, setIsPrintDialogOpen] = React17.useState(false);
8156
- const { t } = chunk5DBKW7F3_js.useTranslation();
8271
+ const { t } = chunkP2COO2QO_js.useTranslation();
8157
8272
  const viewerOptions = useViewerOptionsContext();
8158
8273
  const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * pptx.resolveImageResolutionScale(viewerOptions);
8159
8274
  const handlePrint = () => {
8160
8275
  setIsPrintDialogOpen(true);
8161
8276
  };
8162
- const deckSlides = () => input.templateElementsBySlideId ? chunk5DBKW7F3_js.buildSaveSlides(slides, input.templateElementsBySlideId) : slides;
8277
+ const deckSlides = () => input.templateElementsBySlideId ? chunkP2COO2QO_js.buildSaveSlides(slides, input.templateElementsBySlideId) : slides;
8163
8278
  const plan = (settings, deck) => pptx.planPrintJob(settings, {
8164
8279
  slides: deck,
8165
8280
  activeSlideIndex,
@@ -8574,7 +8689,7 @@ function usePropertyHandlers(input) {
8574
8689
  width: canvasSize.width,
8575
8690
  height: canvasSize.height
8576
8691
  };
8577
- setCompareResult(chunk5DBKW7F3_js.comparePresentation(cur, other));
8692
+ setCompareResult(chunkP2COO2QO_js.comparePresentation(cur, other));
8578
8693
  setIsComparePanelOpen(true);
8579
8694
  } catch (err) {
8580
8695
  console.warn("Compare failed:", err);
@@ -8627,7 +8742,7 @@ function usePropertyHandlers(input) {
8627
8742
  };
8628
8743
  }
8629
8744
  function useDialogCustomShows(input) {
8630
- const { t } = chunk5DBKW7F3_js.useTranslation();
8745
+ const { t } = chunkP2COO2QO_js.useTranslation();
8631
8746
  const {
8632
8747
  activeSlide,
8633
8748
  customShows,
@@ -8952,7 +9067,7 @@ function useViewerDialogs(input) {
8952
9067
  };
8953
9068
  }
8954
9069
  function computeGridSpacingPx(documentGridSpacing) {
8955
- return pptx.computeGridSpacingPx(documentGridSpacing, chunk5DBKW7F3_js.GRID_SIZE);
9070
+ return pptx.computeGridSpacingPx(documentGridSpacing, chunkP2COO2QO_js.GRID_SIZE);
8956
9071
  }
8957
9072
  function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, presentationProperties) {
8958
9073
  const activeShow = activeCustomShowId ? customShows.find((show) => show.id === activeCustomShowId) : void 0;
@@ -8961,7 +9076,7 @@ function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, pre
8961
9076
  }
8962
9077
  function computeSlideSectionGroups(slides, sections) {
8963
9078
  return pptx.groupSlidesBySection(sections, slides).map((group) => ({
8964
- id: group.section?.id ?? (sections.length > 0 ? chunk5DBKW7F3_js.UNGROUPED_SECTION_ID : chunk5DBKW7F3_js.DEFAULT_SECTION_GROUP_ID),
9079
+ id: group.section?.id ?? (sections.length > 0 ? chunkP2COO2QO_js.UNGROUPED_SECTION_ID : chunkP2COO2QO_js.DEFAULT_SECTION_GROUP_ID),
8965
9080
  label: group.section?.name ?? (sections.length > 0 ? "Ungrouped Slides" : "Slides"),
8966
9081
  slideIndexes: group.slideIndexes,
8967
9082
  ...group.section?.color !== void 0 ? { color: group.section.color } : {},
@@ -8980,7 +9095,7 @@ function computeMasterPseudoSlide(mode, activeLayout, activeMaster) {
8980
9095
  });
8981
9096
  }
8982
9097
  function useDerivedSlideState(input) {
8983
- const { t } = chunk5DBKW7F3_js.useTranslation();
9098
+ const { t } = chunkP2COO2QO_js.useTranslation();
8984
9099
  const {
8985
9100
  slides,
8986
9101
  sections,
@@ -9006,10 +9121,10 @@ function useDerivedSlideState(input) {
9006
9121
  );
9007
9122
  const slideSectionGroups = React17.useMemo(
9008
9123
  () => computeSlideSectionGroups(slides, sections).map((group) => {
9009
- if (group.id === chunk5DBKW7F3_js.UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
9124
+ if (group.id === chunkP2COO2QO_js.UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
9010
9125
  return { ...group, label: t("pptx.slides.ungroupedSlides") };
9011
9126
  }
9012
- if (group.id === chunk5DBKW7F3_js.DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
9127
+ if (group.id === chunkP2COO2QO_js.DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
9013
9128
  return { ...group, label: t("pptx.sections.slides") };
9014
9129
  }
9015
9130
  return group;
@@ -9116,7 +9231,7 @@ function useAnnotationHandlers(input) {
9116
9231
  if (nextMode === "present") {
9117
9232
  presentation.enterPresentMode();
9118
9233
  } else if (mode === "present" && annotations.hasAnyAnnotations) {
9119
- chunk5DBKW7F3_js.stopAllPersistentAudio();
9234
+ chunkP2COO2QO_js.stopAllPersistentAudio();
9120
9235
  if (promptKeepInkAnnotations) {
9121
9236
  pendingModeAfterAnnotationsRef.current = nextMode;
9122
9237
  setShowKeepAnnotationsDialog(true);
@@ -9126,7 +9241,7 @@ function useAnnotationHandlers(input) {
9126
9241
  }
9127
9242
  } else {
9128
9243
  if (mode === "present") {
9129
- chunk5DBKW7F3_js.stopAllPersistentAudio();
9244
+ chunkP2COO2QO_js.stopAllPersistentAudio();
9130
9245
  }
9131
9246
  setMode(nextMode);
9132
9247
  }
@@ -9294,7 +9409,7 @@ function useSerialize(input) {
9294
9409
  guides: pptxGuides.length > 0 ? pptxGuides : void 0
9295
9410
  };
9296
9411
  });
9297
- const slidesToSave = chunk5DBKW7F3_js.buildSaveSlides(slidesWithGuides, pending.templateElementsBySlideId);
9412
+ const slidesToSave = chunkP2COO2QO_js.buildSaveSlides(slidesWithGuides, pending.templateElementsBySlideId);
9298
9413
  const saveOptions = pptx.buildDeckSaveOptions({
9299
9414
  // Without this the Slide Size card edited a viewer-only pixel value and
9300
9415
  // the saved `p:sldSz` never moved: passing `slideSize` is the only way a
@@ -9439,7 +9554,7 @@ function usePresentationSetup(input) {
9439
9554
  return;
9440
9555
  }
9441
9556
  if (mode === "present" && nextMode !== "present") {
9442
- chunk5DBKW7F3_js.stopAllPersistentAudio();
9557
+ chunkP2COO2QO_js.stopAllPersistentAudio();
9443
9558
  stopAnimationSound();
9444
9559
  const exitHandler = exitModeHandlerRef.current;
9445
9560
  if (exitHandler) {
@@ -9560,7 +9675,7 @@ function useCanvasImagePaste(input) {
9560
9675
  );
9561
9676
  }
9562
9677
  function formatPatchFor(element, format) {
9563
- const updated = chunk5DBKW7F3_js.applyFormatToElement(element, format);
9678
+ const updated = chunkP2COO2QO_js.applyFormatToElement(element, format);
9564
9679
  const updates = {};
9565
9680
  if (pptx$1.hasShapeProperties(updated)) {
9566
9681
  updates.shapeStyle = updated.shapeStyle;
@@ -9583,7 +9698,7 @@ function useFormatPainterEditing(input) {
9583
9698
  const prevFormatPainterRef = React17.useRef(false);
9584
9699
  React17.useEffect(() => {
9585
9700
  if (formatPainterActive && !prevFormatPainterRef.current && selectedElement) {
9586
- copiedFormatRef.current = chunk5DBKW7F3_js.copyFormatFromElement(selectedElement);
9701
+ copiedFormatRef.current = chunkP2COO2QO_js.copyFormatFromElement(selectedElement);
9587
9702
  } else if (!formatPainterActive) {
9588
9703
  copiedFormatRef.current = null;
9589
9704
  }
@@ -10110,173 +10225,6 @@ function useIOHandlers(input) {
10110
10225
  });
10111
10226
  return { exportHandlers, printHandlers, themeHandlers, propertyHandlers };
10112
10227
  }
10113
- var EMBEDDED_FONTS_STYLE_ID = "pptx-embedded-fonts";
10114
- var GOOGLE_FONTS_LINK_ID = "pptx-google-fonts";
10115
- var SYMBOL_FONTS_STYLE_ID = "pptx-symbol-font-fallback";
10116
- var SYMBOL_FONT_FAMILIES = [
10117
- "Wingdings",
10118
- "Wingdings 2",
10119
- "Wingdings 3",
10120
- "Symbol",
10121
- "Webdings"
10122
- ];
10123
- var FONT_NAME_UNSAFE_CHARS = /["\\\n\r;}<>]/u;
10124
- var FONT_FORMAT_ALLOWED = /* @__PURE__ */ new Set([
10125
- "truetype",
10126
- "opentype",
10127
- "woff",
10128
- "woff2",
10129
- "svg",
10130
- "embedded-opentype"
10131
- ]);
10132
- var FONT_DATA_URL_PATTERN = /^data:font\/[a-z0-9+.-]+(?:;charset=[a-z0-9-]+)?;base64,[A-Za-z0-9+/=]+$/iu;
10133
- function isFontDataUrlSafe(url) {
10134
- if (typeof url !== "string" || url.length === 0) {
10135
- return false;
10136
- }
10137
- if (url.startsWith("blob:")) {
10138
- return true;
10139
- }
10140
- return FONT_DATA_URL_PATTERN.test(url);
10141
- }
10142
- function useFontInjection({
10143
- embeddedFonts,
10144
- slides,
10145
- googleFonts
10146
- }) {
10147
- const googleFontsBase = pptx.resolveGoogleFontsCss2Base(googleFonts);
10148
- React17.useEffect(() => {
10149
- if (!embeddedFonts.length) {
10150
- return;
10151
- }
10152
- const styleEl = document.createElement("style");
10153
- styleEl.id = EMBEDDED_FONTS_STYLE_ID;
10154
- const cssRules = pptx.selectTrustedEmbeddedFonts(embeddedFonts).flatMap((font) => {
10155
- if (typeof font.name !== "string" || font.name.length === 0 || FONT_NAME_UNSAFE_CHARS.test(font.name)) {
10156
- return [];
10157
- }
10158
- if (!isFontDataUrlSafe(font.dataUrl)) {
10159
- return [];
10160
- }
10161
- const fontFormat = font.format ?? "truetype";
10162
- if (!FONT_FORMAT_ALLOWED.has(fontFormat)) {
10163
- return [];
10164
- }
10165
- const fontWeight = String(pptx.resolveFontWeight(font.name, font.bold));
10166
- const fontStyleCss = pptx.resolveFontItalic(font.name, font.italic) ? "italic" : "normal";
10167
- return [
10168
- `@font-face {
10169
- font-family: "${font.name}";
10170
- src: url("${font.dataUrl}") format("${fontFormat}");
10171
- font-weight: ${fontWeight};
10172
- font-style: ${fontStyleCss};
10173
- font-display: swap;
10174
- }`
10175
- ];
10176
- }).join("\n");
10177
- styleEl.textContent = cssRules;
10178
- document.head.appendChild(styleEl);
10179
- return () => {
10180
- const existing = document.getElementById(EMBEDDED_FONTS_STYLE_ID);
10181
- if (existing) {
10182
- document.head.removeChild(existing);
10183
- }
10184
- };
10185
- }, [embeddedFonts]);
10186
- const referencedFamilies = React17.useMemo(() => pptx.collectReferencedFontFamilies(slides), [slides]);
10187
- React17.useEffect(() => {
10188
- let cancelled = false;
10189
- void pptx.resolveGoogleWebfontHref(slides, embeddedFonts, void 0, googleFontsBase).then(
10190
- (href) => {
10191
- if (cancelled) {
10192
- return null;
10193
- }
10194
- pptx.syncGoogleWebfontStylesheet(document, GOOGLE_FONTS_LINK_ID, href);
10195
- return href;
10196
- }
10197
- );
10198
- return () => {
10199
- cancelled = true;
10200
- };
10201
- }, [embeddedFonts, slides, googleFontsBase]);
10202
- React17.useEffect(() => () => document.getElementById(GOOGLE_FONTS_LINK_ID)?.remove(), []);
10203
- const [, setOutlineFontsTick] = React17.useState(0);
10204
- React17.useEffect(() => {
10205
- let cancelled = false;
10206
- const referenced = pptx.collectReferencedFontFamilies(slides);
10207
- const candidates = pptx.selectGoogleWebfontFamilies(
10208
- referenced,
10209
- pptx.selectTrustedEmbeddedFonts(embeddedFonts).map((font) => font.name)
10210
- );
10211
- if (candidates.length === 0) {
10212
- return;
10213
- }
10214
- void pptx.resolveGoogleWebfontHref(slides, embeddedFonts, void 0, googleFontsBase).then(
10215
- async (href) => {
10216
- if (cancelled || !href) {
10217
- return;
10218
- }
10219
- const boldItalicVariants = [
10220
- { bold: false, italic: false },
10221
- { bold: true, italic: false }
10222
- ];
10223
- let registeredAny = false;
10224
- for (const family of candidates) {
10225
- for (const variant of boldItalicVariants) {
10226
- if (cancelled) {
10227
- return;
10228
- }
10229
- const bytes = await pptx.fetchGoogleWebfontOutlineBytes(
10230
- href,
10231
- family,
10232
- variant.bold,
10233
- variant.italic,
10234
- fetch
10235
- );
10236
- if (bytes && glyphOutlineFontCache.registerFontBytes(family, variant.bold, variant.italic, bytes)) {
10237
- registeredAny = true;
10238
- }
10239
- }
10240
- }
10241
- if (registeredAny && !cancelled) {
10242
- setOutlineFontsTick((tick) => tick + 1);
10243
- }
10244
- return void 0;
10245
- }
10246
- );
10247
- return () => {
10248
- cancelled = true;
10249
- };
10250
- }, [embeddedFonts, slides, googleFontsBase]);
10251
- React17.useEffect(() => {
10252
- const neededSymbolFonts = SYMBOL_FONT_FAMILIES.filter((f) => referencedFamilies.has(f));
10253
- if (neededSymbolFonts.length === 0) {
10254
- return;
10255
- }
10256
- const styleEl = document.createElement("style");
10257
- styleEl.id = SYMBOL_FONTS_STYLE_ID;
10258
- const rules = neededSymbolFonts.flatMap((font) => {
10259
- if (typeof font !== "string" || FONT_NAME_UNSAFE_CHARS.test(font)) {
10260
- return [];
10261
- }
10262
- return [
10263
- `@font-face {
10264
- font-family: "${font}";
10265
- src: local("${font}"), local("${font} Regular");
10266
- font-display: swap;
10267
- }`
10268
- ];
10269
- }).join("\n");
10270
- styleEl.textContent = rules;
10271
- document.head.appendChild(styleEl);
10272
- return () => {
10273
- const existing = document.getElementById(SYMBOL_FONTS_STYLE_ID);
10274
- if (existing) {
10275
- document.head.removeChild(existing);
10276
- }
10277
- };
10278
- }, [referencedFamilies]);
10279
- }
10280
10228
  function useContentLifecycle(input) {
10281
10229
  const {
10282
10230
  content,
@@ -10343,6 +10291,8 @@ function useContentLifecycle(input) {
10343
10291
  setModifyVerifier,
10344
10292
  setCompatToasts,
10345
10293
  setLoading: state.setLoading,
10294
+ setFontProgress: state.setFontProgress,
10295
+ googleFonts,
10346
10296
  setError: state.setError,
10347
10297
  setIsDirty: state.setIsDirty,
10348
10298
  setIsEncrypted: setIsEncryptedDialogOpen,
@@ -11220,7 +11170,7 @@ function useCollaborationWriteBack(input) {
11220
11170
  getSourceBytes: () => latest.current.getSourceBytes?.() ?? null,
11221
11171
  getSaveOptions: () => latest.current.getSaveOptions?.(),
11222
11172
  getTemplateElements: () => latest.current.templateElementsBySlideId,
11223
- mergeTemplateElements: chunk5DBKW7F3_js.buildSaveSlides,
11173
+ mergeTemplateElements: chunkP2COO2QO_js.buildSaveSlides,
11224
11174
  onWriteBackStatus: () => latest.current.onWriteBackStatus?.(
11225
11175
  pptx.writeBackReport(latest.current.config, created.getState())
11226
11176
  )
@@ -11777,8 +11727,8 @@ function useTouchGestures(input) {
11777
11727
  }
11778
11728
  const recognizer = pptx.createTouchGestureRecognizer({
11779
11729
  getScale: () => scaleRef.current,
11780
- minScale: chunk5DBKW7F3_js.MIN_ZOOM_SCALE,
11781
- maxScale: chunk5DBKW7F3_js.MAX_ZOOM_SCALE,
11730
+ minScale: chunkP2COO2QO_js.MIN_ZOOM_SCALE,
11731
+ maxScale: chunkP2COO2QO_js.MAX_ZOOM_SCALE,
11782
11732
  callbacks: {
11783
11733
  onPinchZoom: (newScale) => callbacksRef.current.onPinchZoom?.(newScale),
11784
11734
  onSwipe: (direction) => callbacksRef.current.onSwipe?.(direction),
@@ -11914,9 +11864,9 @@ function buildCanvasProps(input) {
11914
11864
  }
11915
11865
  };
11916
11866
  const handleHyperlinkClick = (url, target) => {
11917
- if (chunk5DBKW7F3_js.isPpactionUrl(url)) {
11867
+ if (chunkP2COO2QO_js.isPpactionUrl(url)) {
11918
11868
  if (mode === "present") {
11919
- const parsed = chunk5DBKW7F3_js.parsePpactionUrl(url);
11869
+ const parsed = chunkP2COO2QO_js.parsePpactionUrl(url);
11920
11870
  if (parsed) {
11921
11871
  presentation.handlePresentationAction({
11922
11872
  action: parsed.action,
@@ -12408,7 +12358,7 @@ function buildToolbarProps(input) {
12408
12358
  markDirty: history.markDirty
12409
12359
  }),
12410
12360
  formatPainterActive: s.formatPainterActive,
12411
- canActivateFormatPainter: chunk5DBKW7F3_js.hasCopyableFormat(selectedElement),
12361
+ canActivateFormatPainter: chunkP2COO2QO_js.hasCopyableFormat(selectedElement),
12412
12362
  onToggleFormatPainter: () => s.setFormatPainterActive((p) => !p),
12413
12363
  isSelectionPaneOpen: s.isSelectionPaneOpen,
12414
12364
  onToggleSelectionPane: () => s.setIsSelectionPaneOpen((p) => !p),
@@ -12933,17 +12883,20 @@ function useViewPreferencesSync(input) {
12933
12883
  function useViewerBuildingBlocksState(input) {
12934
12884
  const { core, content, canEdit, filePath, autosaveEnabled, userName, handle, setContent } = input;
12935
12885
  const { initialSlide, googleFonts, listConversionScope, allowExternalContent, limits } = input;
12936
- const externalContentLockedRef = React17.useRef(false);
12886
+ const hostLockedRef = React17.useRef(false);
12937
12887
  const { optionsStore } = core;
12888
+ const fontDownloadLock = pptx.hostFontDownloadLock(googleFonts);
12938
12889
  React17.useLayoutEffect(() => {
12939
- if (allowExternalContent === void 0 && !externalContentLockedRef.current) {
12890
+ const anyLock = allowExternalContent !== void 0 || fontDownloadLock !== void 0;
12891
+ if (!anyLock && !hostLockedRef.current) {
12940
12892
  return;
12941
12893
  }
12942
- externalContentLockedRef.current = allowExternalContent !== void 0;
12894
+ hostLockedRef.current = anyLock;
12895
+ const locked = pptx.lockExternalContentSetting({}, allowExternalContent);
12943
12896
  optionsStore.setConstraints({
12944
- locked: pptx.lockExternalContentSetting({}, allowExternalContent)
12897
+ locked: fontDownloadLock === void 0 ? locked : { ...locked, [pptx.FONT_DOWNLOAD_SETTING_ID]: fontDownloadLock }
12945
12898
  });
12946
- }, [optionsStore, allowExternalContent]);
12899
+ }, [optionsStore, allowExternalContent, fontDownloadLock]);
12947
12900
  const {
12948
12901
  onContentChange,
12949
12902
  onDirtyChange,
@@ -13045,7 +12998,8 @@ function useViewerBuildingBlocksState(input) {
13045
12998
  filePath,
13046
12999
  autosaveEnabled,
13047
13000
  initialSlide,
13048
- googleFonts,
13001
+ // Host `googleFonts` first, else Trust Center > "Download fonts", as in `PowerPointViewer`.
13002
+ googleFonts: pptx.resolveEffectiveGoogleFonts(googleFonts, viewerOptions),
13049
13003
  limits,
13050
13004
  // Trust Center > "Allow external content": same gate `PowerPointViewer`
13051
13005
  // applies, so the headless building-blocks API loads http(s) images
@@ -13133,7 +13087,7 @@ function useViewerBuildingBlocks(input) {
13133
13087
  } = input;
13134
13088
  const collaborationConfig = pptx.resolveCollaborationConfig(input.collaboration);
13135
13089
  const [collaborationReadOnly, setCollaborationReadOnly] = React17.useState(Boolean(collaborationConfig));
13136
- const { t } = chunk5DBKW7F3_js.useTranslation();
13090
+ const { t } = chunkP2COO2QO_js.useTranslation();
13137
13091
  const [content, setContent] = React17.useState(incomingContent ?? null);
13138
13092
  const [loadOrigin, setLoadOrigin] = React17.useState("bootstrap");
13139
13093
  React17.useEffect(() => {
@@ -13335,23 +13289,23 @@ function ColorChangedImage({
13335
13289
  className,
13336
13290
  alt
13337
13291
  }) {
13338
- const tolerance = tolerancePct ?? chunk5DBKW7F3_js.DEFAULT_COLOR_CHANGE_TOLERANCE;
13339
- const cacheKey = chunk5DBKW7F3_js.buildCacheKey(
13292
+ const tolerance = tolerancePct ?? chunkP2COO2QO_js.DEFAULT_COLOR_CHANGE_TOLERANCE;
13293
+ const cacheKey = chunkP2COO2QO_js.buildCacheKey(
13340
13294
  src,
13341
13295
  clrChange.clrFrom,
13342
13296
  clrChange.clrTo,
13343
13297
  tolerance,
13344
13298
  Boolean(clrChange.clrToTransparent)
13345
13299
  );
13346
- const cached = chunk5DBKW7F3_js.getCachedResult(cacheKey);
13300
+ const cached = chunkP2COO2QO_js.getCachedResult(cacheKey);
13347
13301
  const [processedSrc, setProcessedSrc] = React17.useState(cached ?? null);
13348
13302
  React17.useEffect(() => {
13349
- if (chunk5DBKW7F3_js.getCachedResult(cacheKey)) {
13350
- setProcessedSrc(chunk5DBKW7F3_js.getCachedResult(cacheKey) ?? null);
13303
+ if (chunkP2COO2QO_js.getCachedResult(cacheKey)) {
13304
+ setProcessedSrc(chunkP2COO2QO_js.getCachedResult(cacheKey) ?? null);
13351
13305
  return;
13352
13306
  }
13353
13307
  let cancelled = false;
13354
- chunk5DBKW7F3_js.applyColorChange(
13308
+ chunkP2COO2QO_js.applyColorChange(
13355
13309
  src,
13356
13310
  clrChange.clrFrom,
13357
13311
  clrChange.clrTo,
@@ -13359,7 +13313,7 @@ function ColorChangedImage({
13359
13313
  Boolean(clrChange.clrToTransparent)
13360
13314
  ).then((result) => {
13361
13315
  if (!cancelled) {
13362
- chunk5DBKW7F3_js.setCachedResult(cacheKey, result.dataUrl);
13316
+ chunkP2COO2QO_js.setCachedResult(cacheKey, result.dataUrl);
13363
13317
  setProcessedSrc(result.dataUrl);
13364
13318
  }
13365
13319
  return void 0;
@@ -13451,7 +13405,7 @@ function TiledImageLayer({
13451
13405
  cancelled = true;
13452
13406
  };
13453
13407
  }, [src]);
13454
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...chunk5DBKW7F3_js.getImageTilingStyle(element, nativeSize), ...style } });
13408
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...chunkP2COO2QO_js.getImageTilingStyle(element, nativeSize), ...style } });
13455
13409
  }
13456
13410
  function renderImageEffectDefinitions(element, excludeDuotone = false) {
13457
13411
  return pptx.getImageSvgFilters(element).filter((definition) => !excludeDuotone || definition.id !== `duotone-${element.id}`).map((definition) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -13520,7 +13474,7 @@ function renderImg(el, style, filter, alt, opacity) {
13520
13474
  ...filter ? { filter } : {},
13521
13475
  ...opacity !== void 0 ? { opacity } : {}
13522
13476
  };
13523
- if (chunk5DBKW7F3_js.isImageTiled(el)) {
13477
+ if (chunkP2COO2QO_js.isImageTiled(el)) {
13524
13478
  const tileSrc = imgSrc(el);
13525
13479
  if (!tileSrc) {
13526
13480
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-gray-500 bg-gray-100", children: "Image" });
@@ -13542,9 +13496,9 @@ function renderImg(el, style, filter, alt, opacity) {
13542
13496
  pptx$1.isImageLikeElement(el) ? el.imageEffects?.colorWash : void 0
13543
13497
  );
13544
13498
  const clrChange = "imageEffects" in el ? el.imageEffects?.clrChange : void 0;
13545
- const duotoneColors = chunk5DBKW7F3_js.getDuotoneColors(el);
13499
+ const duotoneColors = chunkP2COO2QO_js.getDuotoneColors(el);
13546
13500
  const useDuotoneCanvas = Boolean(duotoneColors && !clrChange);
13547
- const filterForImg = useDuotoneCanvas ? chunk5DBKW7F3_js.getImageEffectsFilter(el, { excludeDuotone: true }) : filter;
13501
+ const filterForImg = useDuotoneCanvas ? chunkP2COO2QO_js.getImageEffectsFilter(el, { excludeDuotone: true }) : filter;
13548
13502
  const canvasEffectStyles = {
13549
13503
  ...filterForImg ? { filter: filterForImg } : {},
13550
13504
  ...opacity !== void 0 ? { opacity } : {}
@@ -13620,10 +13574,10 @@ function SlideBackgroundImageLayer({
13620
13574
  style: { zIndex: 0 },
13621
13575
  children: renderImg(
13622
13576
  backgroundElement,
13623
- chunk5DBKW7F3_js.getImageRenderStyle(backgroundElement),
13624
- chunk5DBKW7F3_js.getImageEffectsFilter(backgroundElement),
13577
+ chunkP2COO2QO_js.getImageRenderStyle(backgroundElement),
13578
+ chunkP2COO2QO_js.getImageEffectsFilter(backgroundElement),
13625
13579
  "",
13626
- chunk5DBKW7F3_js.getImageEffectsOpacity(backgroundElement)
13580
+ chunkP2COO2QO_js.getImageEffectsOpacity(backgroundElement)
13627
13581
  )
13628
13582
  }
13629
13583
  );
@@ -13894,7 +13848,7 @@ function ChartElementView({
13894
13848
  onUpdateElement,
13895
13849
  animationState
13896
13850
  }) {
13897
- const { t } = chunk5DBKW7F3_js.useTranslation();
13851
+ const { t } = chunkP2COO2QO_js.useTranslation();
13898
13852
  const wrapperRef = React17.useRef(null);
13899
13853
  const { selection, setSelection } = useChartPartSelection();
13900
13854
  const [titleDraft, setTitleDraft] = React17.useState(null);
@@ -13909,7 +13863,7 @@ function ChartElementView({
13909
13863
  pptx.getBarFacePicturePixelSampleVersion
13910
13864
  );
13911
13865
  const viewModel = React17.useMemo(() => {
13912
- return canEdit ? chunk5DBKW7F3_js.buildReactChartViewModel(element) : null;
13866
+ return canEdit ? chunkP2COO2QO_js.buildReactChartViewModel(element) : null;
13913
13867
  }, [canEdit, element, barFacePictureSampleVersion]);
13914
13868
  React17.useEffect(pptx.ensureChartInteractionStyles, []);
13915
13869
  React17.useEffect(() => {
@@ -14014,9 +13968,9 @@ function ChartElementView({
14014
13968
  textStyle: animationState?.textStyle,
14015
13969
  onSelect: chart3D.onSelect,
14016
13970
  onDrag: chart3D.onDrag,
14017
- children: chunk5DBKW7F3_js.renderChartElement(renderedElement, (key) => t(key))
13971
+ children: chunkP2COO2QO_js.renderChartElement(renderedElement, (key) => t(key))
14018
13972
  }
14019
- ) : chunk5DBKW7F3_js.renderChartElement(renderedElement, (key) => t(key)),
13973
+ ) : chunkP2COO2QO_js.renderChartElement(renderedElement, (key) => t(key)),
14020
13974
  dragValue !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-1 right-1 z-10 rounded bg-primary/90 px-1.5 py-0.5 text-[10px] font-medium text-white pointer-events-none", children: pptx.formatAxisValue(dragValue) }),
14021
13975
  titleDraft !== null && /* @__PURE__ */ jsxRuntime.jsx(
14022
13976
  "input",
@@ -14044,7 +13998,7 @@ function ChartElementView({
14044
13998
  );
14045
13999
  }
14046
14000
  function useActionAffordance(element, canInteract) {
14047
- const { t } = chunk5DBKW7F3_js.useTranslation();
14001
+ const { t } = chunkP2COO2QO_js.useTranslation();
14048
14002
  pptx.ensureActionAffordanceStyles();
14049
14003
  return React17.useMemo(
14050
14004
  () => pptx.resolveElementActionAffordance(element, {
@@ -14322,7 +14276,7 @@ function ResizeHandles({
14322
14276
  nonRotationTransform,
14323
14277
  onRotate
14324
14278
  }) {
14325
- const { t } = chunk5DBKW7F3_js.useTranslation();
14279
+ const { t } = chunkP2COO2QO_js.useTranslation();
14326
14280
  const rotateRef = useRotateHandlePlacement(elementId, Boolean(onRotate));
14327
14281
  const peStyle = forcePointerEvents ? { ...HANDLE_TOUCH_ACTION, pointerEvents: "auto" } : HANDLE_TOUCH_ACTION;
14328
14282
  const resizeStyle = { ...HANDLE_TOUCH_ACTION, pointerEvents: "none" };
@@ -14355,7 +14309,7 @@ function ResizeHandles({
14355
14309
  "aria-label": t("pptx.selectionOverlay.resize", { handle }),
14356
14310
  "data-pptx-handle-kind": "resize",
14357
14311
  "data-pptx-compact": true,
14358
- className: chunk5DBKW7F3_js.cn(
14312
+ className: chunkP2COO2QO_js.cn(
14359
14313
  "absolute z-10 group border-0 bg-transparent p-0",
14360
14314
  RESIZE_DEFAULT_CLASSES,
14361
14315
  posClass,
@@ -14381,7 +14335,7 @@ function ResizeHandles({
14381
14335
  "div",
14382
14336
  {
14383
14337
  "data-pptx-handle-hit": true,
14384
- className: chunk5DBKW7F3_js.cn(
14338
+ className: chunkP2COO2QO_js.cn(
14385
14339
  "absolute -inset-px pointer-events-auto [--pptx-handle-hit-inset:-1px]",
14386
14340
  corner ? "max-md:-inset-1.5 max-md:[--pptx-handle-hit-inset:-6px]" : "max-md:-inset-2 max-md:[--pptx-handle-hit-inset:-8px]"
14387
14341
  ),
@@ -14402,7 +14356,7 @@ function ResizeHandles({
14402
14356
  "aria-label": t("pptx.selectionOverlay.rotate"),
14403
14357
  "data-pptx-handle-kind": "rotate",
14404
14358
  "data-pptx-compact": true,
14405
- className: chunk5DBKW7F3_js.cn(
14359
+ className: chunkP2COO2QO_js.cn(
14406
14360
  "absolute left-1/2 top-0 -translate-x-1/2 -translate-y-1/2 z-20 border-0 bg-transparent p-0 cursor-grab active:cursor-grabbing",
14407
14361
  ROTATE_DEFAULT_CLASSES
14408
14362
  ),
@@ -14479,13 +14433,14 @@ var ConnectorElementRendererMemo = /* @__PURE__ */ React17__default.default.memo
14479
14433
  const svgHeight = Math.max(el.height, 1);
14480
14434
  const ss = shapeEl?.shapeStyle;
14481
14435
  const strokeWidth = Math.max(0, ss?.strokeWidth ?? 2);
14482
- const strokeColor = chunk5DBKW7F3_js.normalizeHexColor(ss?.strokeColor, chunk5DBKW7F3_js.DEFAULT_STROKE_COLOR);
14483
- const strokePaint = chunk5DBKW7F3_js.colorWithOpacity(strokeColor, ss?.strokeOpacity);
14484
- const dashType = chunk5DBKW7F3_js.normalizeStrokeDashType(ss?.strokeDash);
14485
- const dashArray = chunk5DBKW7F3_js.getSvgStrokeDasharray(
14436
+ const strokeColor = chunkP2COO2QO_js.normalizeHexColor(ss?.strokeColor, chunkP2COO2QO_js.DEFAULT_STROKE_COLOR);
14437
+ const strokePaint = chunkP2COO2QO_js.colorWithOpacity(strokeColor, ss?.strokeOpacity);
14438
+ const dashType = chunkP2COO2QO_js.normalizeStrokeDashType(ss?.strokeDash);
14439
+ const dashArray = chunkP2COO2QO_js.getSvgStrokeDasharray(
14486
14440
  dashType,
14487
14441
  Math.max(strokeWidth, 1),
14488
- ss?.customDashSegments
14442
+ ss?.customDashSegments,
14443
+ ss?.lineCap
14489
14444
  );
14490
14445
  const startArrow = ss?.connectorStartArrow;
14491
14446
  const endArrow = ss?.connectorEndArrow;
@@ -14493,14 +14448,14 @@ var ConnectorElementRendererMemo = /* @__PURE__ */ React17__default.default.memo
14493
14448
  const markerSeed = el.id.replace(/[^a-zA-Z0-9_-]/gu, "_");
14494
14449
  const startMarkerId = `${markerSeed}-sel-start`;
14495
14450
  const endMarkerId = `${markerSeed}-sel-end`;
14496
- const compoundOffsets = chunk5DBKW7F3_js.getCompoundLineOffsets(compoundLine, strokeWidth);
14497
- const compoundWidths = chunk5DBKW7F3_js.getCompoundLineWidths(compoundLine, strokeWidth);
14498
- const strokeCap = pptx.svgLineCap(ss?.lineCap);
14451
+ const compoundOffsets = chunkP2COO2QO_js.getCompoundLineOffsets(compoundLine, strokeWidth);
14452
+ const compoundWidths = chunkP2COO2QO_js.getCompoundLineWidths(compoundLine, strokeWidth);
14453
+ const strokeCap = pptx.svgLineCap(ss?.lineCap, dashArray !== void 0);
14499
14454
  const textEl = pptx$1.hasTextProperties(el) ? el : void 0;
14500
14455
  const connectorText = textEl?.text?.trim() ?? "";
14501
14456
  const connectorTextSegments = textEl?.textSegments;
14502
14457
  const connectorTextStyle = textEl?.textStyle;
14503
- const pathGeometry = shapeEl ? chunk5DBKW7F3_js.getConnectorPathGeometry(shapeEl) : {
14458
+ const pathGeometry = shapeEl ? chunkP2COO2QO_js.getConnectorPathGeometry(shapeEl) : {
14504
14459
  pathData: `M 0 0 L ${viewWidth} ${viewHeight}`,
14505
14460
  startX: 0,
14506
14461
  startY: 0,
@@ -14508,6 +14463,12 @@ var ConnectorElementRendererMemo = /* @__PURE__ */ React17__default.default.memo
14508
14463
  endY: viewHeight
14509
14464
  };
14510
14465
  const hitTargetWidth = Math.max(strokeWidth * 3, 14);
14466
+ const paintPathData = pptx.connectorSquareCapPath(
14467
+ pathGeometry.pathData,
14468
+ ss,
14469
+ strokeWidth,
14470
+ compoundOffsets.length > 1 || !!startArrow && startArrow !== "none" || !!endArrow && endArrow !== "none"
14471
+ ) ?? pathGeometry.pathData;
14511
14472
  const snapTransform = pptx.connectorSnapTransform(
14512
14473
  el,
14513
14474
  !pptx.connectorNeedsPath(shapeEl?.shapeType),
@@ -14515,16 +14476,16 @@ var ConnectorElementRendererMemo = /* @__PURE__ */ React17__default.default.memo
14515
14476
  strokeWidth
14516
14477
  );
14517
14478
  const selColor = selClr === "blue-400" ? "#60a5fa" : "#3b82f6";
14518
- const lineShadow = chunk5DBKW7F3_js.buildLineShadowCss(el);
14519
- const lineGlow = chunk5DBKW7F3_js.buildLineGlowFilter(el);
14479
+ const lineShadow = chunkP2COO2QO_js.buildLineShadowCss(el);
14480
+ const lineGlow = chunkP2COO2QO_js.buildLineGlowFilter(el);
14520
14481
  return /* @__PURE__ */ jsxRuntime.jsxs(
14521
14482
  "div",
14522
14483
  {
14523
14484
  "data-pptx-element": "true",
14524
14485
  "data-element-id": el.id,
14525
- role: chunk5DBKW7F3_js.getAriaRole(el, { actionable: false }),
14526
- "aria-label": chunk5DBKW7F3_js.getAriaLabel(el),
14527
- "aria-roledescription": chunk5DBKW7F3_js.getAriaRoleDescription(el),
14486
+ role: chunkP2COO2QO_js.getAriaRole(el, { actionable: false }),
14487
+ "aria-label": chunkP2COO2QO_js.getAriaLabel(el),
14488
+ "aria-roledescription": chunkP2COO2QO_js.getAriaRoleDescription(el),
14528
14489
  "aria-selected": isSelected ? true : void 0,
14529
14490
  className: "absolute",
14530
14491
  style: {
@@ -14557,14 +14518,14 @@ var ConnectorElementRendererMemo = /* @__PURE__ */ React17__default.default.memo
14557
14518
  style: { overflow: "visible", pointerEvents: "none" },
14558
14519
  children: [
14559
14520
  /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
14560
- chunk5DBKW7F3_js.renderConnectorMarker(
14521
+ chunkP2COO2QO_js.renderConnectorMarker(
14561
14522
  startMarkerId,
14562
14523
  startArrow,
14563
14524
  strokePaint,
14564
14525
  ss?.connectorStartArrowWidth,
14565
14526
  ss?.connectorStartArrowLength
14566
14527
  ),
14567
- chunk5DBKW7F3_js.renderConnectorMarker(
14528
+ chunkP2COO2QO_js.renderConnectorMarker(
14568
14529
  endMarkerId,
14569
14530
  endArrow,
14570
14531
  strokePaint,
@@ -14632,7 +14593,7 @@ var ConnectorElementRendererMemo = /* @__PURE__ */ React17__default.default.memo
14632
14593
  "path",
14633
14594
  {
14634
14595
  "data-pptx-line": "",
14635
- d: pathGeometry.pathData,
14596
+ d: paintPathData,
14636
14597
  fill: "none",
14637
14598
  stroke: strokePaint,
14638
14599
  strokeWidth: Math.max(compoundWidths[idx] ?? strokeWidth, 1),
@@ -14774,14 +14735,14 @@ function getElementInteractionProps({
14774
14735
  };
14775
14736
  }
14776
14737
  function renderDagDuotoneFilterForElement(el) {
14777
- if (!chunk5DBKW7F3_js.hasDagDuotoneEffect(el)) {
14738
+ if (!chunkP2COO2QO_js.hasDagDuotoneEffect(el)) {
14778
14739
  return null;
14779
14740
  }
14780
14741
  const duotone = el.shapeStyle?.dagDuotone;
14781
14742
  if (!duotone) {
14782
14743
  return null;
14783
14744
  }
14784
- return chunk5DBKW7F3_js.renderDagDuotoneSvgFilter(el.id, duotone.color1, duotone.color2);
14745
+ return chunkP2COO2QO_js.renderDagDuotoneSvgFilter(el.id, duotone.color1, duotone.color2);
14785
14746
  }
14786
14747
  function getContainerStyle({
14787
14748
  el,
@@ -14809,10 +14770,10 @@ function getContainerStyle({
14809
14770
  top: isFullscreenMedia ? fs.top : el.y,
14810
14771
  width: isFullscreenMedia ? fs.width : painted.width,
14811
14772
  ...heightStyle,
14812
- transform: isFullscreenMedia ? fs.transform : chunk5DBKW7F3_js.getElementTransform(el),
14773
+ transform: isFullscreenMedia ? fs.transform : chunkP2COO2QO_js.getElementTransform(el),
14813
14774
  transformOrigin: "center",
14814
14775
  overflow: overflowValue,
14815
- clipPath: isPicture ? void 0 : isImg && !has3DExtrusion ? chunk5DBKW7F3_js.getCropShapeClipPath(el) : void 0,
14776
+ clipPath: isPicture ? void 0 : isImg && !has3DExtrusion ? chunkP2COO2QO_js.getCropShapeClipPath(el) : void 0,
14816
14777
  zIndex: isFullscreenMedia ? fs.zIndex : zIndex,
14817
14778
  visibility: animationState?.visible === false ? "hidden" : "visible",
14818
14779
  animation: animationState?.cssAnimation,
@@ -14857,9 +14818,9 @@ function getContainerStyle({
14857
14818
  function shapeParams(element) {
14858
14819
  const style = pptx$1.hasShapeProperties(element) ? element.shapeStyle : void 0;
14859
14820
  const strokeWidth = pptx.paintedStrokeWidth(style);
14860
- const strokeColor = chunk5DBKW7F3_js.normalizeHexColor(style?.strokeColor, chunk5DBKW7F3_js.DEFAULT_STROKE_COLOR);
14861
- const fillColor = chunk5DBKW7F3_js.normalizeHexColor(style?.fillColor, chunk5DBKW7F3_js.DEFAULT_FILL_COLOR);
14862
- const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(chunk5DBKW7F3_js.buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
14821
+ const strokeColor = chunkP2COO2QO_js.normalizeHexColor(style?.strokeColor, chunkP2COO2QO_js.DEFAULT_STROKE_COLOR);
14822
+ const fillColor = chunkP2COO2QO_js.normalizeHexColor(style?.fillColor, chunkP2COO2QO_js.DEFAULT_FILL_COLOR);
14823
+ const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(chunkP2COO2QO_js.buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
14863
14824
  return { hf: hasFill, fc: fillColor, sw: strokeWidth, sc: strokeColor };
14864
14825
  }
14865
14826
  var Extrusion3DOverlayMemo = /* @__PURE__ */ React17__default.default.memo(
@@ -14931,7 +14892,17 @@ function renderOutlinePaint(paint) {
14931
14892
  );
14932
14893
  }
14933
14894
  if (paint.kind === "rectPath") {
14934
- return /* @__PURE__ */ jsxRuntime.jsx("pattern", { id: paint.id, patternUnits: "objectBoundingBox", width: 1, height: 1, children: /* @__PURE__ */ jsxRuntime.jsx("image", { href: paint.href, x: 0, y: 0, width: 1, height: 1, preserveAspectRatio: "none" }) });
14895
+ return /* @__PURE__ */ jsxRuntime.jsx(
14896
+ "pattern",
14897
+ {
14898
+ id: paint.id,
14899
+ patternUnits: "objectBoundingBox",
14900
+ patternContentUnits: "objectBoundingBox",
14901
+ width: 1,
14902
+ height: 1,
14903
+ children: /* @__PURE__ */ jsxRuntime.jsx("image", { href: paint.href, x: 0, y: 0, width: 1, height: 1, preserveAspectRatio: "none" })
14904
+ }
14905
+ );
14935
14906
  }
14936
14907
  const stops = paint.stops.map((stop, idx) => /* @__PURE__ */ jsxRuntime.jsx(
14937
14908
  "stop",
@@ -14956,27 +14927,38 @@ function ShapeEffectOverlay({
14956
14927
  const fx = pptx.getComputedEffectStyle(element);
14957
14928
  const overlay = fx.fillOverlay;
14958
14929
  const reflection = suppressReflection ? void 0 : fx.reflection;
14959
- const softEdge = pptx.getSoftEdgeSvgFilter(pptx.getEffectStyleSource(element), element.id);
14930
+ const softEdge = pptx.getShapeEffectFilterDefs(element);
14960
14931
  const bevelLightingFilter = pptx.getBevelLightingSvgFilter(element);
14961
14932
  const strokeOutline = pptx.buildStrokeOutline(element);
14962
14933
  const hollowHit = pptx.buildHollowHitOutline(element);
14963
- const subpathFill = pptx.buildSubpathFillOverlay(element);
14964
- if (!overlay && !softEdge && !bevelLightingFilter && !strokeOutline && !hollowHit && !subpathFill && !reflection) {
14934
+ const fillLayer = pptx.getSilhouetteFillLayer(element);
14935
+ const overlayFill = pptx.buildSubpathFillOverlay(element);
14936
+ const subpathFill = overlayFill?.silhouette && (chunkP2COO2QO_js.rendersCustomVectorPath(element) || chunkP2COO2QO_js.rendersWedgeCalloutVector(element)) ? void 0 : overlayFill;
14937
+ if (!overlay && !softEdge && !bevelLightingFilter && !strokeOutline && !hollowHit && !subpathFill && !fillLayer && !reflection) {
14965
14938
  return null;
14966
14939
  }
14967
14940
  const fillOverlayStyle = overlay ? {
14968
14941
  position: "absolute",
14969
14942
  inset: 0,
14970
- ...pptx$1.isImageLikeElement(element) ? chunk5DBKW7F3_js.getImageSurfaceMaskStyle(element) : {},
14943
+ ...pptx$1.isImageLikeElement(element) ? chunkP2COO2QO_js.getImageSurfaceMaskStyle(element) : {},
14971
14944
  background: overlay.color,
14972
14945
  mixBlendMode: overlay.blendMode,
14973
14946
  pointerEvents: "none"
14974
14947
  } : void 0;
14975
14948
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14949
+ fillLayer ? /* @__PURE__ */ jsxRuntime.jsx(
14950
+ "div",
14951
+ {
14952
+ className: "pptx-react-silhouette-fill",
14953
+ "aria-hidden": "true",
14954
+ style: fillLayer.style
14955
+ }
14956
+ ) : null,
14976
14957
  subpathFill ? /* @__PURE__ */ jsxRuntime.jsx(
14977
14958
  "svg",
14978
14959
  {
14979
14960
  className: "pptx-react-subpath-fill",
14961
+ "data-pptx-silhouette-fill": subpathFill.silhouette ? "" : void 0,
14980
14962
  "aria-hidden": "true",
14981
14963
  viewBox: `0 0 ${subpathFill.viewBoxWidth} ${subpathFill.viewBoxHeight}`,
14982
14964
  preserveAspectRatio: "none",
@@ -15072,6 +15054,7 @@ function ShapeEffectOverlay({
15072
15054
  ]
15073
15055
  }
15074
15056
  ) : null,
15057
+ hollowHit?.textCss ? /* @__PURE__ */ jsxRuntime.jsx("style", { children: hollowHit.textCss }) : null,
15075
15058
  hollowHit ? /* @__PURE__ */ jsxRuntime.jsx(
15076
15059
  "svg",
15077
15060
  {
@@ -15092,10 +15075,10 @@ function ShapeEffectOverlay({
15092
15075
  "path",
15093
15076
  {
15094
15077
  d: hollowHit.d,
15095
- fill: "none",
15096
- stroke: "transparent",
15078
+ fill: hollowHit.fill,
15079
+ stroke: hollowHit.stroke,
15097
15080
  strokeWidth: hollowHit.strokeWidth,
15098
- style: { pointerEvents: "stroke" }
15081
+ style: { pointerEvents: hollowHit.pointerEvents }
15099
15082
  }
15100
15083
  )
15101
15084
  }
@@ -15176,10 +15159,10 @@ var ElementRenderer = /* @__PURE__ */ React17__default.default.memo(
15176
15159
  const backgroundAnimationState = pptx.getBackgroundAnimationState(el, presentationElementStates);
15177
15160
  const effectPlacement = pptx.getShapeEffectLayerPlacement(el);
15178
15161
  const visualAnimationState = backgroundAnimationState ?? animationState;
15179
- const isTxt = chunk5DBKW7F3_js.isEditableTextElement(el) && allow.textEditable;
15162
+ const isTxt = chunkP2COO2QO_js.isEditableTextElement(el) && allow.textEditable;
15180
15163
  const txtSE = pptx$1.hasTextProperties(el) ? el.textStyle : void 0;
15181
15164
  const textStyleOverrideCss = pptx.buildTextStyleOverrideCss(el.id, visualAnimationState?.textStyle);
15182
- const ss = chunk5DBKW7F3_js.getShapeVisualStyle(
15165
+ const ss = chunkP2COO2QO_js.getShapeVisualStyle(
15183
15166
  el,
15184
15167
  hf,
15185
15168
  fc,
@@ -15188,9 +15171,9 @@ var ElementRenderer = /* @__PURE__ */ React17__default.default.memo(
15188
15171
  visualAnimationState?.animatesFill,
15189
15172
  visualAnimationState?.animatesStroke
15190
15173
  );
15191
- const ts = chunk5DBKW7F3_js.getTextStyleForElement(el, chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR);
15174
+ const ts = chunkP2COO2QO_js.getTextStyleForElement(el, chunkP2COO2QO_js.DEFAULT_TEXT_COLOR);
15192
15175
  const isImg = el.type === "picture" || el.type === "image";
15193
- const vs = chunk5DBKW7F3_js.renderVectorShape(
15176
+ const vs = chunkP2COO2QO_js.renderVectorShape(
15194
15177
  el,
15195
15178
  isImg ? false : hf,
15196
15179
  fc,
@@ -15200,10 +15183,10 @@ var ElementRenderer = /* @__PURE__ */ React17__default.default.memo(
15200
15183
  visualAnimationState?.animatesStroke
15201
15184
  );
15202
15185
  const isModel3D = el.type === "model3d";
15203
- const isConn = chunk5DBKW7F3_js.isConnectorOrLineElement(el);
15186
+ const isConn = chunkP2COO2QO_js.isConnectorOrLineElement(el);
15204
15187
  const shapeStyle3d = pptx$1.hasShapeProperties(el) ? el.shapeStyle : void 0;
15205
15188
  const extrusionData = React17.useMemo(
15206
- () => chunk5DBKW7F3_js.build3DExtrusionData(shapeStyle3d?.shape3d, shapeStyle3d?.scene3d, fc, el.width, el.height),
15189
+ () => chunkP2COO2QO_js.build3DExtrusionData(shapeStyle3d?.shape3d, shapeStyle3d?.scene3d, fc, el.width, el.height),
15207
15190
  [shapeStyle3d?.shape3d, shapeStyle3d?.scene3d, fc, el.width, el.height]
15208
15191
  );
15209
15192
  const actionAffordance = useActionAffordance(el, canInteract);
@@ -15294,7 +15277,7 @@ var ElementRenderer = /* @__PURE__ */ React17__default.default.memo(
15294
15277
  "aria-hidden": aria.hidden ? true : void 0,
15295
15278
  "aria-selected": isSelected ? true : void 0,
15296
15279
  tabIndex: isFocusable ? 0 : -1,
15297
- className: chunk5DBKW7F3_js.cn(
15280
+ className: chunkP2COO2QO_js.cn(
15298
15281
  "absolute",
15299
15282
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500",
15300
15283
  cur,
@@ -15312,7 +15295,7 @@ var ElementRenderer = /* @__PURE__ */ React17__default.default.memo(
15312
15295
  // outline only, so its interior must not swallow clicks meant for what it
15313
15296
  // is drawn over. ShapeEffectOverlay paints a transparent
15314
15297
  // pointer-events:stroke band that opts the outline back in.
15315
- pptx.isHollowShapeElement(el) ? "pointer-events-none" : "",
15298
+ pptx.passesClicksThroughBox(el) ? "pointer-events-none" : "",
15316
15299
  isFullscreenMedia ? "pointer-events-auto" : "",
15317
15300
  selB,
15318
15301
  // Shared class the tooltip's `:hover` rule keys off (see
@@ -15321,6 +15304,13 @@ var ElementRenderer = /* @__PURE__ */ React17__default.default.memo(
15321
15304
  actionAffordance.showLinkTooltip && pptx.LINK_TOOLTIP_HOST_CLASS
15322
15305
  ),
15323
15306
  style: {
15307
+ // The table style's drop shadow (Themed Style 1/2) sits on the clipping frame.
15308
+ ...el.type === "table" ? pptx.tableFrameCss(el.tableData, {
15309
+ tableStyleMap: tableStyleContext?.tableStyleMap,
15310
+ colorScheme: tableStyleContext?.theme?.colorScheme,
15311
+ fontScheme: tableStyleContext?.theme?.fontScheme,
15312
+ formatScheme: tableStyleContext?.theme?.formatScheme
15313
+ }) : {},
15324
15314
  ...containerStyle,
15325
15315
  ...isSelected ? selectionOutlineStyle(selClr) : {}
15326
15316
  },
@@ -15367,9 +15357,9 @@ var ElementRenderer = /* @__PURE__ */ React17__default.default.memo(
15367
15357
  txtSE,
15368
15358
  txtS: ts,
15369
15359
  vecShape: backgroundAnimationState && !isImg ? null : vs,
15370
- imgStyle: chunk5DBKW7F3_js.getImageRenderStyle(el),
15371
- imgFilter: chunk5DBKW7F3_js.getImageEffectsFilter(el),
15372
- imgOpacity: chunk5DBKW7F3_js.getImageEffectsOpacity(el),
15360
+ imgStyle: chunkP2COO2QO_js.getImageRenderStyle(el),
15361
+ imgFilter: chunkP2COO2QO_js.getImageEffectsFilter(el),
15362
+ imgOpacity: chunkP2COO2QO_js.getImageEffectsOpacity(el),
15373
15363
  imgAlt: imageAltText,
15374
15364
  isTxtEl: isTxt,
15375
15365
  media: mediaDataUrls,
@@ -15506,10 +15496,10 @@ function renderStrokeView(view, pressureSensitive, replayStyle, key) {
15506
15496
  }
15507
15497
  function renderInk(el, options) {
15508
15498
  const replay = options?.replay ?? false;
15509
- const strokes = chunk5DBKW7F3_js.buildInkGroupStrokes(el, { color: "#000", width: 3 });
15499
+ const strokes = chunkP2COO2QO_js.buildInkGroupStrokes(el, { color: "#000", width: 3 });
15510
15500
  strokes.some((s) => s.circles || s.nibMarks);
15511
15501
  const pressureSensitive = options?.pressureSensitive;
15512
- const replayStyles = replay ? chunk5DBKW7F3_js.getInkReplayStyles(el, options?.replayConfig) : null;
15502
+ const replayStyles = replay ? chunkP2COO2QO_js.getInkReplayStyles(el, options?.replayConfig) : null;
15513
15503
  return /* @__PURE__ */ jsxRuntime.jsxs(
15514
15504
  "svg",
15515
15505
  {
@@ -15517,7 +15507,7 @@ function renderInk(el, options) {
15517
15507
  viewBox: `0 0 ${Math.max(el.width, 1)} ${Math.max(el.height, 1)}`,
15518
15508
  preserveAspectRatio: "none",
15519
15509
  children: [
15520
- replay && /* @__PURE__ */ jsxRuntime.jsx("style", { children: chunk5DBKW7F3_js.INK_REPLAY_KEYFRAMES }),
15510
+ replay && /* @__PURE__ */ jsxRuntime.jsx("style", { children: chunkP2COO2QO_js.INK_REPLAY_KEYFRAMES }),
15521
15511
  strokes.map(
15522
15512
  (s, i) => renderStrokeView(s, pressureSensitive, replayStyles?.[i], `${el.id}-ink-${i}`)
15523
15513
  )
@@ -15528,7 +15518,7 @@ function renderInk(el, options) {
15528
15518
  function renderGroup(children, parentGroupFill) {
15529
15519
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full h-full pointer-events-none", children: pptx.filterRenderedElements(children).map((c, childIndex) => {
15530
15520
  const { hf, fc, sw, sc } = shapeParams(c);
15531
- const baseSs = chunk5DBKW7F3_js.getShapeVisualStyle(c, hf, fc, sw, sc);
15521
+ const baseSs = chunkP2COO2QO_js.getShapeVisualStyle(c, hf, fc, sw, sc);
15532
15522
  const inheritedFill = pptx.resolveGroupChildFill(c, parentGroupFill);
15533
15523
  const ss = inheritedFill ? {
15534
15524
  ...baseSs,
@@ -15539,9 +15529,9 @@ function renderGroup(children, parentGroupFill) {
15539
15529
  backgroundPosition: inheritedFill.backgroundPosition
15540
15530
  } : baseSs;
15541
15531
  const isI = c.type === "picture" || c.type === "image";
15542
- const vs = chunk5DBKW7F3_js.renderVectorShape(c, isI ? false : hf, fc, sw, sc);
15543
- const ts = chunk5DBKW7F3_js.getTextStyleForElement(c, chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR);
15544
- const isTxt = chunk5DBKW7F3_js.isEditableTextElement(c);
15532
+ const vs = chunkP2COO2QO_js.renderVectorShape(c, isI ? false : hf, fc, sw, sc);
15533
+ const ts = chunkP2COO2QO_js.getTextStyleForElement(c, chunkP2COO2QO_js.DEFAULT_TEXT_COLOR);
15534
+ const isTxt = chunkP2COO2QO_js.isEditableTextElement(c);
15545
15535
  return /* @__PURE__ */ jsxRuntime.jsxs(
15546
15536
  "div",
15547
15537
  {
@@ -15550,9 +15540,9 @@ function renderGroup(children, parentGroupFill) {
15550
15540
  style: {
15551
15541
  left: c.x,
15552
15542
  top: c.y,
15553
- width: Math.max(c.width, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE),
15554
- height: Math.max(c.height, chunk5DBKW7F3_js.MIN_ELEMENT_SIZE),
15555
- transform: chunk5DBKW7F3_js.getElementTransform(c),
15543
+ width: Math.max(c.width, chunkP2COO2QO_js.MIN_ELEMENT_SIZE),
15544
+ height: Math.max(c.height, chunkP2COO2QO_js.MIN_ELEMENT_SIZE),
15545
+ transform: chunkP2COO2QO_js.getElementTransform(c),
15556
15546
  transformOrigin: "center",
15557
15547
  ...ss,
15558
15548
  ...isI ? {
@@ -15577,8 +15567,8 @@ function renderGroup(children, parentGroupFill) {
15577
15567
  // A nested group: recurse, chaining the inherited fill so a
15578
15568
  // `grpFill` shape under a fill-less sub-group still paints.
15579
15569
  renderGroup(c.children, pptx.getGroupChildParentFill(c, parentGroupFill))
15580
- ) : isI && ("svgData" in c && c.svgData || "imageData" in c && c.imageData) ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 pointer-events-none", style: chunk5DBKW7F3_js.getImageSurfaceStyle(c), children: [
15581
- chunk5DBKW7F3_js.isImageTiled(c) ? /* @__PURE__ */ jsxRuntime.jsx(
15570
+ ) : isI && ("svgData" in c && c.svgData || "imageData" in c && c.imageData) ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 pointer-events-none", style: chunkP2COO2QO_js.getImageSurfaceStyle(c), children: [
15571
+ chunkP2COO2QO_js.isImageTiled(c) ? /* @__PURE__ */ jsxRuntime.jsx(
15582
15572
  TiledImageLayer,
15583
15573
  {
15584
15574
  element: c,
@@ -15591,7 +15581,7 @@ function renderGroup(children, parentGroupFill) {
15591
15581
  src: "svgData" in c && c.svgData ? c.svgData : c.imageData,
15592
15582
  alt: i18n.translationsEn["pptx.ink.groupChildAlt"],
15593
15583
  className: "pointer-events-none select-none",
15594
- style: chunk5DBKW7F3_js.getImageRenderStyle(c),
15584
+ style: chunkP2COO2QO_js.getImageRenderStyle(c),
15595
15585
  draggable: false
15596
15586
  }
15597
15587
  ),
@@ -15603,7 +15593,7 @@ function renderGroup(children, parentGroupFill) {
15603
15593
  {
15604
15594
  className: "relative z-10 w-full h-full pointer-events-none whitespace-pre-wrap break-words leading-[1.3]",
15605
15595
  style: ts,
15606
- children: chunk5DBKW7F3_js.renderTextSegments(c, chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR)
15596
+ children: chunkP2COO2QO_js.renderTextSegments(c, chunkP2COO2QO_js.DEFAULT_TEXT_COLOR)
15607
15597
  }
15608
15598
  ) : null
15609
15599
  ] })
@@ -15617,8 +15607,8 @@ function renderContentPart(el, options) {
15617
15607
  if (el.inkStrokes && el.inkStrokes.length > 0) {
15618
15608
  const replay = options?.replay ?? false;
15619
15609
  const pressureSensitive = options?.pressureSensitive ?? true;
15620
- const strokes = chunk5DBKW7F3_js.buildContentPartStrokes(el);
15621
- const replayStyles = replay ? chunk5DBKW7F3_js.getContentPartReplayStyles(el.inkStrokes, options?.replayConfig) : null;
15610
+ const strokes = chunkP2COO2QO_js.buildContentPartStrokes(el);
15611
+ const replayStyles = replay ? chunkP2COO2QO_js.getContentPartReplayStyles(el.inkStrokes, options?.replayConfig) : null;
15622
15612
  return /* @__PURE__ */ jsxRuntime.jsxs(
15623
15613
  "svg",
15624
15614
  {
@@ -15626,7 +15616,7 @@ function renderContentPart(el, options) {
15626
15616
  viewBox: `0 0 ${Math.max(el.width, 1)} ${Math.max(el.height, 1)}`,
15627
15617
  preserveAspectRatio: "none",
15628
15618
  children: [
15629
- replay && /* @__PURE__ */ jsxRuntime.jsx("style", { children: chunk5DBKW7F3_js.INK_REPLAY_KEYFRAMES }),
15619
+ replay && /* @__PURE__ */ jsxRuntime.jsx("style", { children: chunkP2COO2QO_js.INK_REPLAY_KEYFRAMES }),
15630
15620
  strokes.map(
15631
15621
  (s, i) => renderStrokeView(s, pressureSensitive, replayStyles?.[i], `${el.id}-cp-ink-${i}`)
15632
15622
  )
@@ -15853,9 +15843,9 @@ function useInlineListEditor(element, rootRef, onChange, onModelReplacement) {
15853
15843
  collaboration: connected,
15854
15844
  model: pptx.createInlineListModelObserver(element),
15855
15845
  activationSelection,
15856
- children: seed && !connected ? chunk5DBKW7F3_js.renderTextSegments(
15846
+ children: seed && !connected ? chunkP2COO2QO_js.renderTextSegments(
15857
15847
  element,
15858
- chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR,
15848
+ chunkP2COO2QO_js.DEFAULT_TEXT_COLOR,
15859
15849
  void 0,
15860
15850
  void 0,
15861
15851
  void 0,
@@ -16091,8 +16081,8 @@ function InlineTextEditor({
16091
16081
  pending.endOffset
16092
16082
  );
16093
16083
  });
16094
- const warpStyle = chunk5DBKW7F3_js.getTextWarpStyle(textStyleRaw);
16095
- const compensationTransform = chunk5DBKW7F3_js.getTextCompensationTransform(element);
16084
+ const warpStyle = chunkP2COO2QO_js.getTextWarpStyle(textStyleRaw);
16085
+ const compensationTransform = chunkP2COO2QO_js.getTextCompensationTransform(element);
16096
16086
  const warpTransform = warpStyle?.transform;
16097
16087
  const mergedTransform = [compensationTransform, warpTransform].filter(Boolean).join(" ") || void 0;
16098
16088
  const wrapperStyle = {
@@ -16100,7 +16090,7 @@ function InlineTextEditor({
16100
16090
  ...textStyle,
16101
16091
  ...warpStyle,
16102
16092
  transform: mergedTransform,
16103
- transformOrigin: warpStyle?.transformOrigin || (compensationTransform ? chunk5DBKW7F3_js.getTextCompensationOrigin(element) : "center")
16093
+ transformOrigin: warpStyle?.transformOrigin || (compensationTransform ? chunkP2COO2QO_js.getTextCompensationOrigin(element) : "center")
16104
16094
  };
16105
16095
  const nextInlineStyleValue = (property) => {
16106
16096
  if (!pptx$1.hasTextProperties(element)) {
@@ -16175,7 +16165,7 @@ function InlineTextEditor({
16175
16165
  const text = e.clipboardData.getData("text/plain");
16176
16166
  document.execCommand("insertText", false, text);
16177
16167
  },
16178
- children: list.seed ? list.children : seed.hasRichSegments ? chunk5DBKW7F3_js.renderTextSegments(element, chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR) : seed.initialText
16168
+ children: list.seed ? list.children : seed.hasRichSegments ? chunkP2COO2QO_js.renderTextSegments(element, chunkP2COO2QO_js.DEFAULT_TEXT_COLOR) : seed.initialText
16179
16169
  },
16180
16170
  list.seed?.paragraphs[0].token ?? "plain"
16181
16171
  );
@@ -16340,7 +16330,7 @@ function OleActionFooter({
16340
16330
  info,
16341
16331
  showActions
16342
16332
  }) {
16343
- const { t } = chunk5DBKW7F3_js.useTranslation();
16333
+ const { t } = chunkP2COO2QO_js.useTranslation();
16344
16334
  if (!showActions || !info.canDownload || !el.oleEmbeddedData) {
16345
16335
  return null;
16346
16336
  }
@@ -16449,7 +16439,7 @@ function SmartArtInlineNodeEditor({
16449
16439
  onCommit,
16450
16440
  onCancel
16451
16441
  }) {
16452
- const { t } = chunk5DBKW7F3_js.useTranslation();
16442
+ const { t } = chunkP2COO2QO_js.useTranslation();
16453
16443
  const ref = React17__default.default.useRef(null);
16454
16444
  const [value, setValue] = React17__default.default.useState(initialText);
16455
16445
  const settled = React17__default.default.useRef(false);
@@ -17077,7 +17067,7 @@ function SmartArtRendererImpl({
17077
17067
  onUpdateElement,
17078
17068
  animationState
17079
17069
  }) {
17080
- const { t } = chunk5DBKW7F3_js.useTranslation();
17070
+ const { t } = chunkP2COO2QO_js.useTranslation();
17081
17071
  if (element.type !== "smartArt" || !element.smartArtData) {
17082
17072
  return /* @__PURE__ */ jsxRuntime.jsx(
17083
17073
  "div",
@@ -17323,7 +17313,7 @@ function groupIntoParagraphs(element, fieldContext) {
17323
17313
  element,
17324
17314
  fieldContext ? (seg) => {
17325
17315
  if (seg.fieldType) {
17326
- const substituted = chunk5DBKW7F3_js.substituteFieldText(
17316
+ const substituted = chunkP2COO2QO_js.substituteFieldText(
17327
17317
  seg.text,
17328
17318
  seg.fieldType,
17329
17319
  fieldContext,
@@ -17349,31 +17339,28 @@ function getAlignmentProps(align) {
17349
17339
  return { startOffset: "0%", textAnchor: "start" };
17350
17340
  }
17351
17341
  }
17352
- function getSegmentTspanProps(segment, element, fallbackColor) {
17353
- const s = segment.style || {};
17354
- const decos = [];
17355
- if (s.underline || s.hyperlink) {
17356
- decos.push("underline");
17357
- }
17358
- if (s.strikethrough) {
17359
- decos.push("line-through");
17360
- }
17361
- const fill = s.hyperlink ? chunk5DBKW7F3_js.normalizeHexColor(s.color || element.textStyle?.color, chunk5DBKW7F3_js.HYPERLINK_COLOR) : chunk5DBKW7F3_js.normalizeHexColor(s.color || element.textStyle?.color, fallbackColor);
17342
+ function getSegmentTspanProps(segment, element, fallbackColor, fitScale = 1) {
17343
+ const paint = pptx.resolveWarpRunPaint(
17344
+ segment,
17345
+ element.textStyle,
17346
+ fallbackColor,
17347
+ chunkP2COO2QO_js.DEFAULT_TEXT_FONT_SIZE
17348
+ );
17362
17349
  return {
17363
- fill,
17364
- fontSize: s.fontSize ?? element.textStyle?.fontSize ?? chunk5DBKW7F3_js.DEFAULT_TEXT_FONT_SIZE,
17365
- fontWeight: pptx.resolveFontWeight(s.fontFamily || element.textStyle?.fontFamily, s.bold),
17366
- fontStyle: pptx.resolveFontItalic(s.fontFamily || element.textStyle?.fontFamily, s.italic) ? "italic" : void 0,
17367
- fontFamily: s.fontFamily || element.textStyle?.fontFamily ? pptx$1.getSubstituteFontFamily(s.fontFamily || element.textStyle?.fontFamily || "") : chunk5DBKW7F3_js.DEFAULT_FONT_FAMILY,
17368
- textDecoration: decos.length > 0 ? decos.join(" ") : void 0
17350
+ fill: paint.fill,
17351
+ fontSize: paint.fontSizePx * fitScale,
17352
+ fontWeight: paint.fontWeight ?? "normal",
17353
+ fontStyle: paint.fontStyle ?? "normal",
17354
+ fontFamily: paint.fontFamily,
17355
+ textDecoration: paint.textDecoration
17369
17356
  };
17370
17357
  }
17371
17358
  function resolveSegmentFont(segment, element) {
17372
17359
  const s = segment.style || {};
17373
17360
  const family = s.fontFamily || element.textStyle?.fontFamily;
17374
17361
  return {
17375
- fontFamily: family ? pptx$1.getSubstituteFontFamily(family) : chunk5DBKW7F3_js.DEFAULT_FONT_FAMILY,
17376
- fontSizePx: s.fontSize ?? element.textStyle?.fontSize ?? chunk5DBKW7F3_js.DEFAULT_TEXT_FONT_SIZE,
17362
+ fontFamily: family ? pptx$1.getSubstituteFontFamily(family) : chunkP2COO2QO_js.DEFAULT_FONT_FAMILY,
17363
+ fontSizePx: s.fontSize ?? element.textStyle?.fontSize ?? chunkP2COO2QO_js.DEFAULT_TEXT_FONT_SIZE,
17377
17364
  bold: s.bold ?? element.textStyle?.bold,
17378
17365
  italic: s.italic ?? element.textStyle?.italic
17379
17366
  };
@@ -17456,15 +17443,14 @@ function WarpedText({
17456
17443
  if (paragraphs.length === 0) {
17457
17444
  return null;
17458
17445
  }
17459
- const lineCount = paragraphs.length;
17460
17446
  const pathIdPrefix = `warp-${element.id}`;
17461
17447
  const warpAdj = textEl.textStyle?.textWarpAdj;
17462
17448
  const warpAdj2 = textEl.textStyle?.textWarpAdj2;
17463
17449
  const align = textEl.textStyle?.align ?? "center";
17464
17450
  const { startOffset, textAnchor } = getAlignmentProps(align);
17465
- const baseFontSize = textEl.textStyle?.fontSize ?? chunk5DBKW7F3_js.DEFAULT_TEXT_FONT_SIZE;
17466
- const baseFontFamily = textEl.textStyle?.fontFamily ? pptx$1.getSubstituteFontFamily(textEl.textStyle.fontFamily) : chunk5DBKW7F3_js.DEFAULT_FONT_FAMILY;
17467
- const baseFill = chunk5DBKW7F3_js.normalizeHexColor(textEl.textStyle?.color, fallbackColor);
17451
+ const baseFontSize = textEl.textStyle?.fontSize ?? chunkP2COO2QO_js.DEFAULT_TEXT_FONT_SIZE;
17452
+ const baseFontFamily = textEl.textStyle?.fontFamily ? pptx$1.getSubstituteFontFamily(textEl.textStyle.fontFamily) : chunkP2COO2QO_js.DEFAULT_FONT_FAMILY;
17453
+ const baseFill = chunkP2COO2QO_js.normalizeHexColor(textEl.textStyle?.color, fallbackColor);
17468
17454
  if (pptx.hasGlyphEnvelope(preset)) {
17469
17455
  const perLine = pptx.buildGlyphEnvelopeBlock(
17470
17456
  preset,
@@ -17509,6 +17495,15 @@ function WarpedText({
17509
17495
  }
17510
17496
  );
17511
17497
  }
17498
+ const layouts = pptx.warpParagraphLayouts(
17499
+ preset,
17500
+ width,
17501
+ height,
17502
+ paragraphs,
17503
+ warpAdj,
17504
+ warpAdj2,
17505
+ textEl.textStyle
17506
+ );
17512
17507
  return /* @__PURE__ */ jsxRuntime.jsxs(
17513
17508
  "svg",
17514
17509
  {
@@ -17528,7 +17523,7 @@ function WarpedText({
17528
17523
  "path",
17529
17524
  {
17530
17525
  id: `${pathIdPrefix}-${i}`,
17531
- d: pptx.getWarpPath(preset, width, height, i, lineCount, warpAdj, warpAdj2),
17526
+ d: layouts[i]?.d,
17532
17527
  fill: "none"
17533
17528
  },
17534
17529
  `${pathIdPrefix}-def-${i}`
@@ -17550,7 +17545,12 @@ function WarpedText({
17550
17545
  children: para.segments.map((seg, segIdx) => /* @__PURE__ */ jsxRuntime.jsx(
17551
17546
  "tspan",
17552
17547
  {
17553
- ...getSegmentTspanProps(seg, textEl, fallbackColor),
17548
+ ...getSegmentTspanProps(
17549
+ seg,
17550
+ textEl,
17551
+ fallbackColor,
17552
+ layouts[paraIdx]?.fitScale ?? 1
17553
+ ),
17554
17554
  children: seg.text
17555
17555
  },
17556
17556
  `${pathIdPrefix}-ts-${paraIdx}-${segIdx}`
@@ -17564,60 +17564,66 @@ function WarpedText({
17564
17564
  }
17565
17565
  );
17566
17566
  }
17567
- var GLYPH_BY_SHAPE = /* @__PURE__ */ buildGlyphByShape();
17568
- function buildGlyphByShape() {
17569
- const glyphs = Object.fromEntries(
17570
- chunk5DBKW7F3_js.ACTION_BUTTON_PRESETS.map((p) => [p.shapeType, p.iconPath])
17571
- );
17572
- glyphs["actionButtonForwardOrNext"] = glyphs["actionButtonForwardNext"];
17573
- glyphs["actionButtonBackOrPrevious"] = glyphs["actionButtonBackPrevious"];
17574
- return glyphs;
17575
- }
17576
- function isActionButtonShape(shapeType) {
17577
- return Boolean(shapeType && shapeType in GLYPH_BY_SHAPE);
17578
- }
17579
- function getActionButtonGlyphPath(shapeType) {
17580
- if (!shapeType) {
17581
- return void 0;
17567
+ function renderEquationBox(el, interactive) {
17568
+ if (!pptx$1.hasTextProperties(el) || !pptx.isEquationOnlyText(el.textSegments)) {
17569
+ return null;
17582
17570
  }
17583
- const path = GLYPH_BY_SHAPE[shapeType];
17584
- return path && path.length > 0 ? path : void 0;
17585
- }
17586
- function ActionButtonGlyphOverlay({
17587
- element,
17588
- color
17589
- }) {
17590
- const shapeType = "shapeType" in element ? element.shapeType : void 0;
17591
- const path = getActionButtonGlyphPath(shapeType);
17592
- if (!path) {
17571
+ const equations = (el.textSegments ?? []).flatMap((segment, index) => {
17572
+ const mathml = segment.equationXml ? pptx.convertOmmlToMathMl(segment.equationXml) : "";
17573
+ if (!mathml) {
17574
+ return [];
17575
+ }
17576
+ const math = /* @__PURE__ */ jsxRuntime.jsx(
17577
+ "span",
17578
+ {
17579
+ style: {
17580
+ display: "inline-block",
17581
+ verticalAlign: "middle",
17582
+ fontFamily: pptx.EQUATION_FONT_FAMILY
17583
+ },
17584
+ dangerouslySetInnerHTML: { __html: pptx.sanitizeMathMl(mathml) }
17585
+ }
17586
+ );
17587
+ if (!segment.equationNumber) {
17588
+ return [/* @__PURE__ */ jsxRuntime.jsx(React17__default.default.Fragment, { children: math }, `${el.id}-eq-${index}`)];
17589
+ }
17590
+ const label = `(${segment.equationNumber})`;
17591
+ return [
17592
+ /* @__PURE__ */ jsxRuntime.jsxs(
17593
+ "span",
17594
+ {
17595
+ style: {
17596
+ display: "flex",
17597
+ justifyContent: "space-between",
17598
+ alignItems: "center",
17599
+ width: "100%"
17600
+ },
17601
+ children: [
17602
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { visibility: "hidden", whiteSpace: "nowrap" }, children: label }),
17603
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1, textAlign: "center" }, children: math }),
17604
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { whiteSpace: "nowrap", fontFamily: pptx.EQUATION_FONT_FAMILY }, children: label })
17605
+ ]
17606
+ },
17607
+ `${el.id}-eq-${index}`
17608
+ )
17609
+ ];
17610
+ });
17611
+ if (equations.length === 0) {
17593
17612
  return null;
17594
17613
  }
17595
- const stroke = color ?? ("textStyle" in element && element.textStyle?.color || "#ffffff");
17614
+ const style = pptx.buildEquationBlockStyle(
17615
+ pptx.buildTextBlockStyle(el, {
17616
+ fallbackColor: chunkP2COO2QO_js.DEFAULT_TEXT_COLOR,
17617
+ bodyLayout: true,
17618
+ pxLengths: true
17619
+ })
17620
+ );
17596
17621
  return /* @__PURE__ */ jsxRuntime.jsx(
17597
- "svg",
17622
+ "div",
17598
17623
  {
17599
- viewBox: "0 0 24 24",
17600
- width: "100%",
17601
- height: "100%",
17602
- preserveAspectRatio: "xMidYMid meet",
17603
- style: {
17604
- position: "absolute",
17605
- inset: 0,
17606
- pointerEvents: "none",
17607
- padding: "20%"
17608
- },
17609
- "aria-hidden": "true",
17610
- children: /* @__PURE__ */ jsxRuntime.jsx(
17611
- "path",
17612
- {
17613
- d: path,
17614
- fill: "none",
17615
- stroke,
17616
- strokeWidth: 2,
17617
- strokeLinecap: "round",
17618
- strokeLinejoin: "round"
17619
- }
17620
- )
17624
+ className: chunkP2COO2QO_js.cn("relative z-10 w-full h-full", interactive ? "" : "pointer-events-none"),
17625
+ style,
17626
+ children: equations
17621
17627
  }
17622
17628
  );
17623
17629
  }
@@ -17641,7 +17647,7 @@ function renderTextElementBody(options) {
17641
17647
  const useSvgWarp = pptx.shouldUseSvgWarp(
17642
17648
  pptx$1.hasTextProperties(el) ? el.textStyle?.textWarpPreset : void 0
17643
17649
  );
17644
- const scene3dStyle = pptx$1.hasTextProperties(el) ? chunk5DBKW7F3_js.buildTextBody3DSceneStyle(el.textStyle, { width: el.width, height: el.height }) : void 0;
17650
+ const scene3dStyle = pptx$1.hasTextProperties(el) ? chunkP2COO2QO_js.buildTextBody3DSceneStyle(el.textStyle, { width: el.width, height: el.height }) : void 0;
17645
17651
  const rotationTransform = pptx.getTextBodyRotationTransform(el);
17646
17652
  const compensation = pptx.getTextCompensationStyle(el);
17647
17653
  const composedTransform = [rotationTransform, compensation?.transform, scene3dStyle?.transform].filter(Boolean).join(" ") || void 0;
@@ -17665,27 +17671,27 @@ function renderTextElementBody(options) {
17665
17671
  ...scene3dStyle?.transformStyle ? { transformStyle: scene3dStyle.transformStyle } : {},
17666
17672
  ...isLinkedTextBox ? { overflow: "hidden" } : {}
17667
17673
  };
17668
- const shapeType = "shapeType" in el ? el.shapeType : void 0;
17669
17674
  const placeholderPrompt = pptx.placeholderPromptDescriptor(el, placeholderPromptMode);
17670
17675
  const shouldRenderText = isTxtEl || placeholderPrompt !== null;
17676
+ const equationBox = shouldRenderText ? renderEquationBox(el, Boolean(onHyperlinkClick)) : null;
17671
17677
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17672
17678
  vecShape,
17673
- isActionButtonShape(shapeType) && /* @__PURE__ */ jsxRuntime.jsx(ActionButtonGlyphOverlay, { element: el }),
17674
- shouldRenderText && (useSvgWarp ? /* @__PURE__ */ jsxRuntime.jsx(
17679
+ equationBox,
17680
+ shouldRenderText && !equationBox && (useSvgWarp ? /* @__PURE__ */ jsxRuntime.jsx(
17675
17681
  "div",
17676
17682
  {
17677
- className: chunk5DBKW7F3_js.cn(
17683
+ className: chunkP2COO2QO_js.cn(
17678
17684
  "relative z-10 w-full h-full",
17679
17685
  onHyperlinkClick ? "" : "pointer-events-none"
17680
17686
  ),
17681
- style: { ...chunk5DBKW7F3_js.getTextLayoutStyle(el), ...transformStyle },
17687
+ style: { ...chunkP2COO2QO_js.getTextLayoutStyle(el), ...transformStyle },
17682
17688
  children: /* @__PURE__ */ jsxRuntime.jsx(
17683
17689
  WarpedText,
17684
17690
  {
17685
17691
  element: el,
17686
17692
  width: el.width,
17687
17693
  height: el.height,
17688
- fallbackColor: chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR,
17694
+ fallbackColor: chunkP2COO2QO_js.DEFAULT_TEXT_COLOR,
17689
17695
  findHighlights: findHl,
17690
17696
  fieldContext
17691
17697
  }
@@ -17694,19 +17700,19 @@ function renderTextElementBody(options) {
17694
17700
  ) : /* @__PURE__ */ jsxRuntime.jsx(
17695
17701
  "div",
17696
17702
  {
17697
- className: chunk5DBKW7F3_js.cn(
17703
+ className: chunkP2COO2QO_js.cn(
17698
17704
  "relative z-10 w-full h-full whitespace-pre-wrap break-words leading-[1.3]",
17699
17705
  onHyperlinkClick ? "" : "pointer-events-none"
17700
17706
  ),
17701
17707
  style: {
17702
- ...chunk5DBKW7F3_js.getTextLayoutStyle(el),
17708
+ ...chunkP2COO2QO_js.getTextLayoutStyle(el),
17703
17709
  ...txtS,
17704
- ...chunk5DBKW7F3_js.getTextWarpStyle(txtSE),
17710
+ ...chunkP2COO2QO_js.getTextWarpStyle(txtSE),
17705
17711
  ...transformStyle
17706
17712
  },
17707
- children: chunk5DBKW7F3_js.renderTextSegments(
17713
+ children: chunkP2COO2QO_js.renderTextSegments(
17708
17714
  el,
17709
- chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR,
17715
+ chunkP2COO2QO_js.DEFAULT_TEXT_COLOR,
17710
17716
  void 0,
17711
17717
  findHl,
17712
17718
  onHyperlinkClick,
@@ -17727,7 +17733,7 @@ function ZoomElementRenderer({
17727
17733
  onZoomClick,
17728
17734
  sourceSlideIndex
17729
17735
  }) {
17730
- const { t } = chunk5DBKW7F3_js.useTranslation();
17736
+ const { t } = chunkP2COO2QO_js.useTranslation();
17731
17737
  const summaryView = pptx.buildSummaryZoomView(
17732
17738
  element,
17733
17739
  (index) => {
@@ -18025,7 +18031,7 @@ function renderBody(options) {
18025
18031
  );
18026
18032
  }
18027
18033
  if (isImg) {
18028
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 pointer-events-none", style: chunk5DBKW7F3_js.getImageSurfaceStyle(el), children: [
18034
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 pointer-events-none", style: chunkP2COO2QO_js.getImageSurfaceStyle(el), children: [
18029
18035
  renderImg(el, imgStyle, imgFilter, imgAlt, imgOpacity),
18030
18036
  vecShape ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-0", children: vecShape }) : null
18031
18037
  ] });
@@ -18042,7 +18048,7 @@ function renderBody(options) {
18042
18048
  textDirection: txtSE?.textDirection,
18043
18049
  textStyle: txtS,
18044
18050
  textStyleRaw: txtSE,
18045
- layoutStyle: chunk5DBKW7F3_js.getTextLayoutStyle(el),
18051
+ layoutStyle: chunkP2COO2QO_js.getTextLayoutStyle(el),
18046
18052
  element: el,
18047
18053
  onCommit,
18048
18054
  onCancel,
@@ -18053,7 +18059,7 @@ function renderBody(options) {
18053
18059
  ] });
18054
18060
  }
18055
18061
  if (el.type === "table") {
18056
- return chunk5DBKW7F3_js.renderTableElement(el, txtS, {
18062
+ return chunkP2COO2QO_js.renderTableElement(el, txtS, {
18057
18063
  editable: isSel,
18058
18064
  selectedCell: isSel ? tableSt : null,
18059
18065
  onSelectCell: onCellSel,
@@ -18086,7 +18092,7 @@ function renderBody(options) {
18086
18092
  );
18087
18093
  }
18088
18094
  if (el.type === "media") {
18089
- return chunk5DBKW7F3_js.renderMediaElement(el, media, {
18095
+ return chunkP2COO2QO_js.renderMediaElement(el, media, {
18090
18096
  // Present mode autoplays every media element on the active slide,
18091
18097
  // not only ones persisted with their own `autoPlay` flag (matching
18092
18098
  // the other four bindings' unconditional `presenting`-gated
@@ -18100,13 +18106,17 @@ function renderBody(options) {
18100
18106
  // does. The rule is shared so the five bindings cannot drift on it.
18101
18107
  showTransport: pptx.mediaTransportVisible({
18102
18108
  presenting: isPresentationPassive === true,
18103
- preview: isStaticSurface === true,
18104
- canvasTransport: true
18109
+ preview: isStaticSurface === true
18105
18110
  }),
18106
18111
  // ...and never the play badge / placeholder box either: a still is
18107
18112
  // slide content, and the transition overlay paints one (issue #147).
18108
18113
  preview: isStaticSurface === true,
18109
- onPlayStateChange: handleMediaPlayStateChange
18114
+ onPlayStateChange: handleMediaPlayStateChange,
18115
+ // PowerPoint's Normal view: a control bar while selected or hovered.
18116
+ ...pptx.mediaControlBarEnabled({
18117
+ presenting: isPresentationPassive === true,
18118
+ preview: isStaticSurface === true
18119
+ }) ? { controlBar: { selected: isSel === true } } : {}
18110
18120
  });
18111
18121
  }
18112
18122
  if (doInk && pptx$1.isInkElement(el)) {
@@ -18138,27 +18148,27 @@ function renderBody(options) {
18138
18148
  }
18139
18149
  return renderGroup(el.children, pptx.getGroupChildParentFill(el));
18140
18150
  }
18141
- if (chunk5DBKW7F3_js.shouldRenderFallbackLabel(el, isTxtEl)) {
18142
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: chunk5DBKW7F3_js.getElementLabel(el) });
18151
+ if (chunkP2COO2QO_js.shouldRenderFallbackLabel(el, isTxtEl)) {
18152
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: chunkP2COO2QO_js.getElementLabel(el) });
18143
18153
  }
18144
18154
  return renderTextElementBody(options);
18145
18155
  }
18146
18156
  function defaultTextColorForFill(fillColor) {
18147
18157
  const hex = String(fillColor ?? "").replace(/^#/u, "");
18148
18158
  if (!/^[0-9a-f]{6}$/iu.test(hex)) {
18149
- return chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR;
18159
+ return chunkP2COO2QO_js.DEFAULT_TEXT_COLOR;
18150
18160
  }
18151
18161
  const channels = [0, 2, 4].map((offset) => Number.parseInt(hex.slice(offset, offset + 2), 16) / 255).map((channel) => channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4);
18152
18162
  const luminance = channels[0] * 0.2126 + channels[1] * 0.7152 + channels[2] * 0.0722;
18153
- return luminance > 0.179 ? chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR : "#ffffff";
18163
+ return luminance > 0.179 ? chunkP2COO2QO_js.DEFAULT_TEXT_COLOR : "#ffffff";
18154
18164
  }
18155
18165
  function getStaticElementVisualState(element, parentGroupFill) {
18156
18166
  const style = pptx$1.hasShapeProperties(element) ? element.shapeStyle : void 0;
18157
- const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(chunk5DBKW7F3_js.buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
18158
- const fill = chunk5DBKW7F3_js.normalizeHexColor(style?.fillColor, chunk5DBKW7F3_js.DEFAULT_FILL_COLOR);
18167
+ const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(chunkP2COO2QO_js.buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
18168
+ const fill = chunkP2COO2QO_js.normalizeHexColor(style?.fillColor, chunkP2COO2QO_js.DEFAULT_FILL_COLOR);
18159
18169
  const strokeWidth = pptx.paintedStrokeWidth(style);
18160
- const stroke = chunk5DBKW7F3_js.normalizeHexColor(style?.strokeColor, chunk5DBKW7F3_js.DEFAULT_STROKE_COLOR);
18161
- const baseVisualStyle = chunk5DBKW7F3_js.getShapeVisualStyle(element, hasFill, fill, strokeWidth, stroke);
18170
+ const stroke = chunkP2COO2QO_js.normalizeHexColor(style?.strokeColor, chunkP2COO2QO_js.DEFAULT_STROKE_COLOR);
18171
+ const baseVisualStyle = chunkP2COO2QO_js.getShapeVisualStyle(element, hasFill, fill, strokeWidth, stroke);
18162
18172
  const inheritedFill = pptx.resolveGroupChildFill(element, parentGroupFill);
18163
18173
  const visualStyle = inheritedFill ? {
18164
18174
  ...baseVisualStyle,
@@ -18168,9 +18178,9 @@ function getStaticElementVisualState(element, parentGroupFill) {
18168
18178
  backgroundSize: inheritedFill.backgroundSize,
18169
18179
  backgroundPosition: inheritedFill.backgroundPosition
18170
18180
  } : baseVisualStyle;
18171
- const textStyle = chunk5DBKW7F3_js.getTextStyleForElement(
18181
+ const textStyle = chunkP2COO2QO_js.getTextStyleForElement(
18172
18182
  element,
18173
- element.type === "shape" && hasFill ? defaultTextColorForFill(fill) : chunk5DBKW7F3_js.DEFAULT_TEXT_COLOR
18183
+ element.type === "shape" && hasFill ? defaultTextColorForFill(fill) : chunkP2COO2QO_js.DEFAULT_TEXT_COLOR
18174
18184
  );
18175
18185
  const isImage = element.type === "picture" || element.type === "image";
18176
18186
  const letsTextOverflow = pptx$1.hasTextProperties(element) && Boolean(element.text?.trim());
@@ -18195,7 +18205,7 @@ function getStaticElementInteractionState(element, hasActionHandler, exposeEleme
18195
18205
  return { action, isActionable, contractRole };
18196
18206
  }
18197
18207
  function getStaticElementWrapperClassName(element, visual, positioned, isActionable) {
18198
- const overflowClass = visual.isImage || visual.strokeWidth > 0 || element.type === "group" || chunk5DBKW7F3_js.isConnectorOrLineElement(element) || visual.isCallout || visual.letsTextOverflow ? "" : "overflow-hidden";
18208
+ const overflowClass = visual.isImage || visual.strokeWidth > 0 || element.type === "group" || chunkP2COO2QO_js.isConnectorOrLineElement(element) || visual.isCallout || visual.letsTextOverflow ? "" : "overflow-hidden";
18199
18209
  const pointerClass = isActionable ? "pointer-events-auto cursor-pointer" : "pointer-events-none";
18200
18210
  return `${positioned ? "absolute" : "relative"} ${overflowClass} ${pointerClass}`;
18201
18211
  }
@@ -18278,7 +18288,7 @@ function StaticElementRendererImpl({
18278
18288
  top: positioned ? element.y : void 0,
18279
18289
  width: positioned ? Math.max(element.width, 1) : "100%",
18280
18290
  height: positioned ? Math.max(element.height, 1) : "100%",
18281
- transform: positioned ? chunk5DBKW7F3_js.getElementTransform(element) : void 0,
18291
+ transform: positioned ? chunkP2COO2QO_js.getElementTransform(element) : void 0,
18282
18292
  transformOrigin: "center",
18283
18293
  zIndex,
18284
18294
  ...visualStyle,
@@ -18321,18 +18331,18 @@ function StaticElementRendererImpl({
18321
18331
  spellCheck: false,
18322
18332
  txtSE: pptx$1.hasTextProperties(element) ? element.textStyle : void 0,
18323
18333
  txtS: textStyle,
18324
- vecShape: chunk5DBKW7F3_js.renderVectorShape(
18334
+ vecShape: chunkP2COO2QO_js.renderVectorShape(
18325
18335
  element,
18326
18336
  isImage ? false : hasFill,
18327
18337
  fill,
18328
18338
  strokeWidth,
18329
18339
  stroke
18330
18340
  ),
18331
- imgStyle: imageAnimation ? { ...chunk5DBKW7F3_js.getImageRenderStyle(element), animation: imageAnimation } : chunk5DBKW7F3_js.getImageRenderStyle(element),
18332
- imgFilter: chunk5DBKW7F3_js.getImageEffectsFilter(element),
18333
- imgOpacity: chunk5DBKW7F3_js.getImageEffectsOpacity(element),
18341
+ imgStyle: imageAnimation ? { ...chunkP2COO2QO_js.getImageRenderStyle(element), animation: imageAnimation } : chunkP2COO2QO_js.getImageRenderStyle(element),
18342
+ imgFilter: chunkP2COO2QO_js.getImageEffectsFilter(element),
18343
+ imgOpacity: chunkP2COO2QO_js.getImageEffectsOpacity(element),
18334
18344
  imgAlt: "",
18335
- isTxtEl: chunk5DBKW7F3_js.isEditableTextElement(element),
18345
+ isTxtEl: chunkP2COO2QO_js.isEditableTextElement(element),
18336
18346
  media: mediaDataUrls,
18337
18347
  tableSt: null,
18338
18348
  isSel: false,
@@ -18380,7 +18390,7 @@ function SlideLayer({
18380
18390
  style: {
18381
18391
  width: safeWidth,
18382
18392
  height: safeHeight,
18383
- backgroundColor: slide.backgroundColor ? chunk5DBKW7F3_js.normalizeHexColor(slide.backgroundColor, "#ffffff") : "#ffffff",
18393
+ backgroundColor: slide.backgroundColor ? chunkP2COO2QO_js.normalizeHexColor(slide.backgroundColor, "#ffffff") : "#ffffff",
18384
18394
  backgroundImage: slide.backgroundImage ? `url(${slide.backgroundImage})` : slide.backgroundGradient ? slide.backgroundGradient : void 0,
18385
18395
  backgroundSize: slide.backgroundImage ? "cover" : void 0,
18386
18396
  backgroundPosition: slide.backgroundImage ? "center" : void 0