pptx-react-viewer 3.1.1 → 3.1.2

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 (167) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{AiChatPanel-6PERJN7M.js → AiChatPanel-4EYZDQXM.js} +24 -24
  3. package/dist/AiChatPanel-4EYZDQXM.js.br +0 -0
  4. package/dist/AiChatPanel-4EYZDQXM.js.gz +0 -0
  5. package/dist/{AiChatPanel-EIENGCKW.mjs → AiChatPanel-UCFQIWOQ.mjs} +4 -4
  6. package/dist/AiChatPanel-UCFQIWOQ.mjs.br +0 -0
  7. package/dist/AiChatPanel-UCFQIWOQ.mjs.gz +0 -0
  8. package/dist/{Area3DChartScene-W6SVC235.mjs → Area3DChartScene-PMYXO4MR.mjs} +1 -1
  9. package/dist/Area3DChartScene-PMYXO4MR.mjs.br +0 -0
  10. package/dist/Area3DChartScene-PMYXO4MR.mjs.gz +0 -0
  11. package/dist/{Area3DChartScene-TXCLQLBQ.js → Area3DChartScene-YBMC6NKY.js} +2 -2
  12. package/dist/Area3DChartScene-YBMC6NKY.js.br +0 -0
  13. package/dist/Area3DChartScene-YBMC6NKY.js.gz +0 -0
  14. package/dist/{Bar3DChartScene-6RHPFLZT.js → Bar3DChartScene-75DCA2ZA.js} +2 -2
  15. package/dist/Bar3DChartScene-75DCA2ZA.js.br +0 -0
  16. package/dist/Bar3DChartScene-75DCA2ZA.js.gz +0 -0
  17. package/dist/{Bar3DChartScene-FCVUZIJ3.mjs → Bar3DChartScene-CEOI6SU6.mjs} +1 -1
  18. package/dist/Bar3DChartScene-CEOI6SU6.mjs.br +0 -0
  19. package/dist/Bar3DChartScene-CEOI6SU6.mjs.gz +0 -0
  20. package/dist/{Line3DChartScene-MJXFXSPW.mjs → Line3DChartScene-EZZKWUZR.mjs} +1 -1
  21. package/dist/Line3DChartScene-EZZKWUZR.mjs.br +0 -0
  22. package/dist/Line3DChartScene-EZZKWUZR.mjs.gz +0 -0
  23. package/dist/{Line3DChartScene-2ZFE53KO.js → Line3DChartScene-STGX6N6V.js} +2 -2
  24. package/dist/Line3DChartScene-STGX6N6V.js.br +0 -0
  25. package/dist/Line3DChartScene-STGX6N6V.js.gz +0 -0
  26. package/dist/{Model3DScene-7VQNRY5B.js → Model3DScene-DWRD63FH.js} +2 -2
  27. package/dist/Model3DScene-DWRD63FH.js.br +0 -0
  28. package/dist/Model3DScene-DWRD63FH.js.gz +0 -0
  29. package/dist/{Model3DScene-A5RV3KNJ.mjs → Model3DScene-FGQJKWL6.mjs} +1 -1
  30. package/dist/Model3DScene-FGQJKWL6.mjs.br +0 -0
  31. package/dist/Model3DScene-FGQJKWL6.mjs.gz +0 -0
  32. package/dist/{PieChart3DScene-UEVFZZVW.mjs → PieChart3DScene-DH6RSJO6.mjs} +1 -1
  33. package/dist/PieChart3DScene-DH6RSJO6.mjs.br +0 -0
  34. package/dist/PieChart3DScene-DH6RSJO6.mjs.gz +0 -0
  35. package/dist/{PieChart3DScene-JTHZESS3.js → PieChart3DScene-R3Y7OVVO.js} +2 -2
  36. package/dist/PieChart3DScene-R3Y7OVVO.js.br +0 -0
  37. package/dist/PieChart3DScene-R3Y7OVVO.js.gz +0 -0
  38. package/dist/PowerPointViewer-Cl6jBPNw.d.ts.map +1 -1
  39. package/dist/{SurfaceChart3DScene-WD65PAG4.mjs → SurfaceChart3DScene-BMBU5RKI.mjs} +1 -1
  40. package/dist/SurfaceChart3DScene-BMBU5RKI.mjs.br +0 -0
  41. package/dist/SurfaceChart3DScene-BMBU5RKI.mjs.gz +0 -0
  42. package/dist/{SurfaceChart3DScene-FXUNT5OK.js → SurfaceChart3DScene-UM5HA3VO.js} +2 -2
  43. package/dist/SurfaceChart3DScene-UM5HA3VO.js.br +0 -0
  44. package/dist/SurfaceChart3DScene-UM5HA3VO.js.gz +0 -0
  45. package/dist/{chunk-GCE2TYHF.js → chunk-2HLDBQH7.js} +157 -157
  46. package/dist/chunk-2HLDBQH7.js.br +0 -0
  47. package/dist/chunk-2HLDBQH7.js.gz +0 -0
  48. package/dist/{chunk-MAOUVROK.mjs → chunk-4VVOTEQ4.mjs} +359 -336
  49. package/dist/chunk-4VVOTEQ4.mjs.br +0 -0
  50. package/dist/chunk-4VVOTEQ4.mjs.gz +0 -0
  51. package/dist/{chunk-IDTNKL4S.js → chunk-7ZQ2FZXE.js} +300 -45
  52. package/dist/chunk-7ZQ2FZXE.js.br +0 -0
  53. package/dist/chunk-7ZQ2FZXE.js.gz +0 -0
  54. package/dist/{chunk-MKPSUHUH.mjs → chunk-ARJE3V6V.mjs} +5 -6
  55. package/dist/chunk-ARJE3V6V.mjs.br +0 -0
  56. package/dist/chunk-ARJE3V6V.mjs.gz +0 -0
  57. package/dist/{chunk-GIFQWIW5.js → chunk-MQEG5GOV.js} +1339 -1212
  58. package/dist/chunk-MQEG5GOV.js.br +0 -0
  59. package/dist/chunk-MQEG5GOV.js.gz +0 -0
  60. package/dist/{chunk-5ERW2B25.mjs → chunk-O5DKWJDK.mjs} +1 -1
  61. package/dist/chunk-O5DKWJDK.mjs.br +0 -0
  62. package/dist/chunk-O5DKWJDK.mjs.gz +0 -0
  63. package/dist/{chunk-ISDTM2V3.mjs → chunk-S546O4W2.mjs} +286 -45
  64. package/dist/chunk-S546O4W2.mjs.br +0 -0
  65. package/dist/chunk-S546O4W2.mjs.gz +0 -0
  66. package/dist/{chunk-PIUB7R2K.js → chunk-SWRY3SI5.js} +5 -6
  67. package/dist/chunk-SWRY3SI5.js.br +0 -0
  68. package/dist/chunk-SWRY3SI5.js.gz +0 -0
  69. package/dist/{chunk-ICAYXQVJ.mjs → chunk-VLLZ3QL2.mjs} +260 -133
  70. package/dist/chunk-VLLZ3QL2.mjs.br +0 -0
  71. package/dist/chunk-VLLZ3QL2.mjs.gz +0 -0
  72. package/dist/{chunk-OUX4O5XK.mjs → chunk-W3J6SNVE.mjs} +2 -2
  73. package/dist/chunk-W3J6SNVE.mjs.br +0 -0
  74. package/dist/chunk-W3J6SNVE.mjs.gz +0 -0
  75. package/dist/{chunk-OTBQBTTQ.js → chunk-WVIKFMNS.js} +725 -704
  76. package/dist/chunk-WVIKFMNS.js.br +0 -0
  77. package/dist/chunk-WVIKFMNS.js.gz +0 -0
  78. package/dist/{chunk-OZGFMZEX.js → chunk-YNUYFR2T.js} +3 -3
  79. package/dist/chunk-YNUYFR2T.js.br +0 -0
  80. package/dist/chunk-YNUYFR2T.js.gz +0 -0
  81. package/dist/i18n.js +4 -4
  82. package/dist/i18n.js.br +0 -0
  83. package/dist/i18n.js.gz +0 -0
  84. package/dist/i18n.mjs +1 -1
  85. package/dist/i18n.mjs.br +0 -0
  86. package/dist/i18n.mjs.gz +0 -0
  87. package/dist/index.d.ts +27 -1
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +47 -47
  90. package/dist/index.js.br +0 -0
  91. package/dist/index.js.gz +0 -0
  92. package/dist/index.mjs +6 -6
  93. package/dist/index.mjs.br +0 -0
  94. package/dist/index.mjs.gz +0 -0
  95. package/dist/internals.d.ts +99 -22
  96. package/dist/internals.d.ts.map +1 -1
  97. package/dist/internals.js +79 -79
  98. package/dist/internals.js.br +0 -0
  99. package/dist/internals.js.gz +0 -0
  100. package/dist/internals.mjs +4 -4
  101. package/dist/internals.mjs.br +0 -0
  102. package/dist/internals.mjs.gz +0 -0
  103. package/dist/pptx-viewer.css +1 -1
  104. package/dist/pptx-viewer.css.br +0 -0
  105. package/dist/pptx-viewer.css.gz +0 -0
  106. package/dist/{useViewerBuildingBlocks-DC1O_op4.d.ts → useViewerBuildingBlocks-X1L8BjsQ.d.ts} +19 -2
  107. package/dist/useViewerBuildingBlocks-X1L8BjsQ.d.ts.map +1 -0
  108. package/dist/viewer/index.js +27 -27
  109. package/dist/viewer/index.js.br +0 -0
  110. package/dist/viewer/index.js.gz +0 -0
  111. package/dist/viewer/index.mjs +6 -6
  112. package/dist/viewer/index.mjs.br +0 -0
  113. package/dist/viewer/index.mjs.gz +0 -0
  114. package/package.json +1 -1
  115. package/dist/AiChatPanel-6PERJN7M.js.br +0 -0
  116. package/dist/AiChatPanel-6PERJN7M.js.gz +0 -0
  117. package/dist/AiChatPanel-EIENGCKW.mjs.br +0 -0
  118. package/dist/AiChatPanel-EIENGCKW.mjs.gz +0 -0
  119. package/dist/Area3DChartScene-TXCLQLBQ.js.br +0 -0
  120. package/dist/Area3DChartScene-TXCLQLBQ.js.gz +0 -0
  121. package/dist/Area3DChartScene-W6SVC235.mjs.br +0 -0
  122. package/dist/Area3DChartScene-W6SVC235.mjs.gz +0 -0
  123. package/dist/Bar3DChartScene-6RHPFLZT.js.br +0 -0
  124. package/dist/Bar3DChartScene-6RHPFLZT.js.gz +0 -0
  125. package/dist/Bar3DChartScene-FCVUZIJ3.mjs.br +0 -0
  126. package/dist/Bar3DChartScene-FCVUZIJ3.mjs.gz +0 -0
  127. package/dist/Line3DChartScene-2ZFE53KO.js.br +0 -0
  128. package/dist/Line3DChartScene-2ZFE53KO.js.gz +0 -0
  129. package/dist/Line3DChartScene-MJXFXSPW.mjs.br +0 -0
  130. package/dist/Line3DChartScene-MJXFXSPW.mjs.gz +0 -0
  131. package/dist/Model3DScene-7VQNRY5B.js.br +0 -0
  132. package/dist/Model3DScene-7VQNRY5B.js.gz +0 -0
  133. package/dist/Model3DScene-A5RV3KNJ.mjs.br +0 -0
  134. package/dist/Model3DScene-A5RV3KNJ.mjs.gz +0 -0
  135. package/dist/PieChart3DScene-JTHZESS3.js.br +0 -0
  136. package/dist/PieChart3DScene-JTHZESS3.js.gz +0 -0
  137. package/dist/PieChart3DScene-UEVFZZVW.mjs.br +0 -0
  138. package/dist/PieChart3DScene-UEVFZZVW.mjs.gz +0 -0
  139. package/dist/SurfaceChart3DScene-FXUNT5OK.js.br +0 -0
  140. package/dist/SurfaceChart3DScene-FXUNT5OK.js.gz +0 -0
  141. package/dist/SurfaceChart3DScene-WD65PAG4.mjs.br +0 -0
  142. package/dist/SurfaceChart3DScene-WD65PAG4.mjs.gz +0 -0
  143. package/dist/chunk-5ERW2B25.mjs.br +0 -0
  144. package/dist/chunk-5ERW2B25.mjs.gz +0 -0
  145. package/dist/chunk-GCE2TYHF.js.br +0 -0
  146. package/dist/chunk-GCE2TYHF.js.gz +0 -0
  147. package/dist/chunk-GIFQWIW5.js.br +0 -0
  148. package/dist/chunk-GIFQWIW5.js.gz +0 -0
  149. package/dist/chunk-ICAYXQVJ.mjs.br +0 -0
  150. package/dist/chunk-ICAYXQVJ.mjs.gz +0 -0
  151. package/dist/chunk-IDTNKL4S.js.br +0 -0
  152. package/dist/chunk-IDTNKL4S.js.gz +0 -0
  153. package/dist/chunk-ISDTM2V3.mjs.br +0 -0
  154. package/dist/chunk-ISDTM2V3.mjs.gz +0 -0
  155. package/dist/chunk-MAOUVROK.mjs.br +0 -0
  156. package/dist/chunk-MAOUVROK.mjs.gz +0 -0
  157. package/dist/chunk-MKPSUHUH.mjs.br +0 -0
  158. package/dist/chunk-MKPSUHUH.mjs.gz +0 -0
  159. package/dist/chunk-OTBQBTTQ.js.br +0 -0
  160. package/dist/chunk-OTBQBTTQ.js.gz +0 -0
  161. package/dist/chunk-OUX4O5XK.mjs.br +0 -0
  162. package/dist/chunk-OUX4O5XK.mjs.gz +0 -0
  163. package/dist/chunk-OZGFMZEX.js.br +0 -0
  164. package/dist/chunk-OZGFMZEX.js.gz +0 -0
  165. package/dist/chunk-PIUB7R2K.js.br +0 -0
  166. package/dist/chunk-PIUB7R2K.js.gz +0 -0
  167. package/dist/useViewerBuildingBlocks-DC1O_op4.d.ts.map +0 -1
@@ -1,8 +1,7 @@
1
- import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-OUX4O5XK.mjs';
2
- import { translationsEn } from './chunk-MKPSUHUH.mjs';
3
- import { TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, PresentationAnimationController, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, attachPresentationVisibilityPause, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, collectTableCellImagePaths, applyTableCellImagePatches, collectTableStyleImagePaths, applyTableStyleImagePatches, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, downloadBlob, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, resolveInlineEditAutoFitHeight, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, generatePackageReadme, presentationBaseName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, firstShowSlideIndex, mapPresentationWheel, computeColorFilter, computeSlideIndices, buildPrintDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, replyToCommentInList, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, computeGridSpacingPx, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, buildPrintHtmlDocument, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, safeOpenUrl, ACTION_BUTTON_PRESETS, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, classifyMediaType, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, applyResize, snapBoxToGrid, applyMotionPathPreset } from './chunk-ISDTM2V3.mjs';
4
- import { useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useImperativeHandle, useSyncExternalStore } from 'react';
5
- import JSZip from 'jszip';
1
+ import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-W3J6SNVE.mjs';
2
+ import { translationsEn } from './chunk-ARJE3V6V.mjs';
3
+ import { DEFAULT_VIEWER_OPTIONS, TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, PresentationAnimationController, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, attachPresentationVisibilityPause, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, collectTableCellImagePaths, applyTableCellImagePatches, collectTableStyleImagePaths, applyTableStyleImagePatches, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, downloadBlob, resolveImageResolutionScale, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, resolveInlineEditAutoFitHeight, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, firstShowSlideIndex, mapPresentationWheel, openPendingPrintWindow, computeColorFilter, filterHiddenSlideIndices, computeSlideIndices, buildPrintDocument, finishPrintWindow, buildPrintHtmlDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, replyToCommentInList, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, computeGridSpacingPx, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, resolveHistoryDepth, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, resolvePresentationAction, ACTION_BUTTON_PRESETS, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, classifyMediaType, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, shouldConfirmExternalHyperlink, safeOpenUrl, applyResize, snapBoxToGrid, applyMotionPathPreset } from './chunk-S546O4W2.mjs';
4
+ import { createContext, useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useContext, useImperativeHandle, useSyncExternalStore } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
8
7
  function useVirtualizedSlides({
@@ -3792,7 +3791,8 @@ function useLoadContent({
3792
3791
  setError,
3793
3792
  setIsDirty,
3794
3793
  setIsEncrypted,
3795
- onContentApplied
3794
+ onContentApplied,
3795
+ allowExternalImages
3796
3796
  }) {
3797
3797
  const handlerRef = useRef(null);
3798
3798
  const originalBufferRef = useRef(null);
@@ -3818,7 +3818,7 @@ function useLoadContent({
3818
3818
  }
3819
3819
  const previousHandler = handlerRef.current;
3820
3820
  const handler = new PptxHandler();
3821
- const parsed = await handler.load(buffer);
3821
+ const parsed = await handler.load(buffer, { allowExternalImages });
3822
3822
  if (cancelled || token !== renderTokenRef.current) {
3823
3823
  handler.dispose();
3824
3824
  return;
@@ -6546,13 +6546,15 @@ function createTableStructHandlers(input) {
6546
6546
  elementLookup,
6547
6547
  setTableEditorState,
6548
6548
  ops,
6549
- history
6549
+ history,
6550
+ transformCommittedText
6550
6551
  } = input;
6551
- const handleCommitCellEdit = (elementId, rowIndex, colIndex, text) => {
6552
+ const handleCommitCellEdit = (elementId, rowIndex, colIndex, rawText) => {
6552
6553
  const el = elementLookup.get(elementId);
6553
6554
  if (!el || el.type !== "table") {
6554
6555
  return;
6555
6556
  }
6557
+ const text = transformCommittedText ? transformCommittedText(rawText) : rawText;
6556
6558
  const updates = {};
6557
6559
  if (el.tableData) {
6558
6560
  updates.tableData = setCellText(el, rowIndex, colIndex, text).tableData;
@@ -6743,6 +6745,144 @@ async function renderToCanvas(element, options = {}) {
6743
6745
  });
6744
6746
  }
6745
6747
 
6748
+ // src/viewer/hooks/useExportSaveAs.ts
6749
+ function useExportSaveAs(input) {
6750
+ const {
6751
+ slides,
6752
+ templateElementsBySlideId,
6753
+ filePath,
6754
+ handlerRef,
6755
+ headerFooter,
6756
+ presentationProperties,
6757
+ customShows,
6758
+ sections,
6759
+ coreProperties,
6760
+ appProperties,
6761
+ customProperties,
6762
+ tagCollections,
6763
+ slideMasters,
6764
+ notesMaster,
6765
+ handoutMaster,
6766
+ guides,
6767
+ activeSlideIndexForGuides,
6768
+ theme,
6769
+ canvasSize,
6770
+ slideSizeEmu,
6771
+ password
6772
+ } = input;
6773
+ const handleSaveAsFormat = async (format) => {
6774
+ const handler = handlerRef.current;
6775
+ if (!handler) {
6776
+ return;
6777
+ }
6778
+ const downloadName = savedPresentationFileName(filePath, format);
6779
+ try {
6780
+ const data = await buildSaveAsData(handler, format);
6781
+ const blob = new Blob([data], {
6782
+ type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
6783
+ });
6784
+ downloadBlob(blob, downloadName);
6785
+ } catch (err) {
6786
+ console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
6787
+ }
6788
+ };
6789
+ const buildSaveAsData = async (handler, format) => {
6790
+ const slidesWithGuides = slides.map((slide, idx) => {
6791
+ if (idx !== activeSlideIndexForGuides) {
6792
+ return slide;
6793
+ }
6794
+ const pptxGuides = guides.map((g) => ({
6795
+ id: g.id,
6796
+ orientation: g.axis === "h" ? "horz" : "vert",
6797
+ positionEmu: guidePxToEmu(g.position)
6798
+ }));
6799
+ return {
6800
+ ...slide,
6801
+ guides: pptxGuides.length > 0 ? pptxGuides : void 0
6802
+ };
6803
+ });
6804
+ const slidesToSave = buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
6805
+ const saveOptions = {
6806
+ // Save As shares Save's slide-size decision; leaving it out here is how
6807
+ // a preset picked in the inspector reached one save path and not the other.
6808
+ slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
6809
+ headerFooter,
6810
+ presentationProperties,
6811
+ customShows: customShows.length > 0 ? customShows : void 0,
6812
+ sections: sections.length > 0 ? sections : void 0,
6813
+ coreProperties: coreProperties ?? void 0,
6814
+ appProperties: appProperties ?? void 0,
6815
+ customProperties: customProperties.length > 0 ? customProperties : void 0,
6816
+ tags: tagCollections.length > 0 ? tagCollections : void 0,
6817
+ slideMasters,
6818
+ notesMaster,
6819
+ handoutMaster,
6820
+ outputFormat: format
6821
+ };
6822
+ return saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
6823
+ };
6824
+ const handleExportJson = () => {
6825
+ const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
6826
+ const slideSize = resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
6827
+ const data = {
6828
+ slides: buildSaveSlides(slides, templateElementsBySlideId),
6829
+ width: canvasSize.width,
6830
+ height: canvasSize.height,
6831
+ widthEmu: slideSize.widthEmu,
6832
+ heightEmu: slideSize.heightEmu,
6833
+ slideSizeType: slideSize.type === "" ? void 0 : slideSize.type,
6834
+ theme,
6835
+ headerFooter,
6836
+ presentationProperties,
6837
+ customShows: customShows.length > 0 ? customShows : void 0,
6838
+ sections: sections.length > 0 ? sections : void 0,
6839
+ coreProperties: coreProperties ?? void 0,
6840
+ appProperties: appProperties ?? void 0,
6841
+ customProperties: customProperties.length > 0 ? customProperties : void 0,
6842
+ tags: tagCollections.length > 0 ? tagCollections : void 0,
6843
+ notesMaster,
6844
+ handoutMaster
6845
+ };
6846
+ try {
6847
+ exportDeckJson(data, sourceName);
6848
+ } catch (err) {
6849
+ console.error("[PowerPointViewer] JSON export failed:", err);
6850
+ }
6851
+ };
6852
+ const handleSaveAsPptx = () => {
6853
+ void handleSaveAsFormat("pptx");
6854
+ };
6855
+ const handleSaveAsPpsx = () => {
6856
+ void handleSaveAsFormat("ppsx");
6857
+ };
6858
+ const handleSaveAsPptm = () => {
6859
+ void handleSaveAsFormat("pptm");
6860
+ };
6861
+ return {
6862
+ handleExportJson,
6863
+ handleSaveAsFormat,
6864
+ handleSaveAsPptx,
6865
+ handleSaveAsPpsx,
6866
+ handleSaveAsPptm
6867
+ };
6868
+ }
6869
+
6870
+ // src/viewer/utils/dom-helpers.ts
6871
+ function safePrompt(message, defaultValue) {
6872
+ try {
6873
+ return window.prompt(message, defaultValue);
6874
+ } catch {
6875
+ return null;
6876
+ }
6877
+ }
6878
+ function safeConfirm(message) {
6879
+ try {
6880
+ return window.confirm(message);
6881
+ } catch {
6882
+ return false;
6883
+ }
6884
+ }
6885
+
6746
6886
  // src/viewer/utils/export-helpers.ts
6747
6887
  async function renderElementToCanvas(element, scale = 2, backgroundColor) {
6748
6888
  const canvas = await renderToCanvas(element, {
@@ -7052,194 +7192,6 @@ function exportAllSlidesToSvg(data, options = {}) {
7052
7192
  return results;
7053
7193
  }
7054
7194
 
7055
- // src/viewer/hooks/useExportSaveAs.ts
7056
- function useExportSaveAs(input) {
7057
- const {
7058
- slides,
7059
- templateElementsBySlideId,
7060
- filePath,
7061
- handlerRef,
7062
- serializeSlides,
7063
- headerFooter,
7064
- presentationProperties,
7065
- customShows,
7066
- sections,
7067
- coreProperties,
7068
- appProperties,
7069
- customProperties,
7070
- tagCollections,
7071
- slideMasters,
7072
- notesMaster,
7073
- handoutMaster,
7074
- guides,
7075
- activeSlideIndexForGuides,
7076
- theme,
7077
- canvasSize,
7078
- slideSizeEmu,
7079
- modalControls,
7080
- password
7081
- } = input;
7082
- const {
7083
- setExportModalOpen,
7084
- setExportModalTitle,
7085
- setExportProgress,
7086
- setExportStatusMessage,
7087
- exportAbortRef
7088
- } = modalControls;
7089
- const handlePackageForSharing = async () => {
7090
- const abortCtrl = new AbortController();
7091
- exportAbortRef.current = abortCtrl;
7092
- setExportModalTitle("Package for Sharing");
7093
- setExportStatusMessage("Preparing package...");
7094
- setExportProgress(0);
7095
- setExportModalOpen(true);
7096
- try {
7097
- const zip = new JSZip();
7098
- const pkgFolder = zip.folder("presentation-package");
7099
- setExportProgress(10);
7100
- setExportStatusMessage("Adding presentation...");
7101
- const pptxData = await serializeSlides();
7102
- const pptxFilename = savedPresentationFileName(filePath);
7103
- if (pptxData) {
7104
- pkgFolder.file(pptxFilename, pptxData);
7105
- }
7106
- setExportProgress(70);
7107
- setExportStatusMessage("Writing README...");
7108
- const readme = generatePackageReadme(pptxFilename);
7109
- pkgFolder.file("README.txt", readme);
7110
- if (abortCtrl.signal.aborted) {
7111
- throw new DOMException("Export cancelled", "AbortError");
7112
- }
7113
- setExportProgress(85);
7114
- setExportStatusMessage("Generating ZIP...");
7115
- const zipBlob = await zip.generateAsync({ type: "blob" });
7116
- setExportProgress(95);
7117
- setExportStatusMessage("Downloading...");
7118
- downloadBlob(zipBlob, `${presentationBaseName(pptxFilename)}-package.zip`);
7119
- setExportProgress(100);
7120
- } catch (err) {
7121
- if (err.name !== "AbortError") {
7122
- console.error("[PowerPointViewer] Package export failed:", err);
7123
- }
7124
- } finally {
7125
- exportAbortRef.current = null;
7126
- setExportModalOpen(false);
7127
- }
7128
- };
7129
- const handleSaveAsFormat = async (format) => {
7130
- const handler = handlerRef.current;
7131
- if (!handler) {
7132
- return;
7133
- }
7134
- const downloadName = savedPresentationFileName(filePath, format);
7135
- try {
7136
- const data = await buildSaveAsData(handler, format);
7137
- const blob = new Blob([data], {
7138
- type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
7139
- });
7140
- downloadBlob(blob, downloadName);
7141
- } catch (err) {
7142
- console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
7143
- }
7144
- };
7145
- const buildSaveAsData = async (handler, format) => {
7146
- const slidesWithGuides = slides.map((slide, idx) => {
7147
- if (idx !== activeSlideIndexForGuides) {
7148
- return slide;
7149
- }
7150
- const pptxGuides = guides.map((g) => ({
7151
- id: g.id,
7152
- orientation: g.axis === "h" ? "horz" : "vert",
7153
- positionEmu: guidePxToEmu(g.position)
7154
- }));
7155
- return {
7156
- ...slide,
7157
- guides: pptxGuides.length > 0 ? pptxGuides : void 0
7158
- };
7159
- });
7160
- const slidesToSave = buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
7161
- const saveOptions = {
7162
- // Save As shares Save's slide-size decision; leaving it out here is how
7163
- // a preset picked in the inspector reached one save path and not the other.
7164
- slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
7165
- headerFooter,
7166
- presentationProperties,
7167
- customShows: customShows.length > 0 ? customShows : void 0,
7168
- sections: sections.length > 0 ? sections : void 0,
7169
- coreProperties: coreProperties ?? void 0,
7170
- appProperties: appProperties ?? void 0,
7171
- customProperties: customProperties.length > 0 ? customProperties : void 0,
7172
- tags: tagCollections.length > 0 ? tagCollections : void 0,
7173
- slideMasters,
7174
- notesMaster,
7175
- handoutMaster,
7176
- outputFormat: format
7177
- };
7178
- return saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
7179
- };
7180
- const handleExportJson = () => {
7181
- const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
7182
- const slideSize = resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
7183
- const data = {
7184
- slides: buildSaveSlides(slides, templateElementsBySlideId),
7185
- width: canvasSize.width,
7186
- height: canvasSize.height,
7187
- widthEmu: slideSize.widthEmu,
7188
- heightEmu: slideSize.heightEmu,
7189
- slideSizeType: slideSize.type === "" ? void 0 : slideSize.type,
7190
- theme,
7191
- headerFooter,
7192
- presentationProperties,
7193
- customShows: customShows.length > 0 ? customShows : void 0,
7194
- sections: sections.length > 0 ? sections : void 0,
7195
- coreProperties: coreProperties ?? void 0,
7196
- appProperties: appProperties ?? void 0,
7197
- customProperties: customProperties.length > 0 ? customProperties : void 0,
7198
- tags: tagCollections.length > 0 ? tagCollections : void 0,
7199
- notesMaster,
7200
- handoutMaster
7201
- };
7202
- try {
7203
- exportDeckJson(data, sourceName);
7204
- } catch (err) {
7205
- console.error("[PowerPointViewer] JSON export failed:", err);
7206
- }
7207
- };
7208
- const handleSaveAsPptx = () => {
7209
- void handleSaveAsFormat("pptx");
7210
- };
7211
- const handleSaveAsPpsx = () => {
7212
- void handleSaveAsFormat("ppsx");
7213
- };
7214
- const handleSaveAsPptm = () => {
7215
- void handleSaveAsFormat("pptm");
7216
- };
7217
- return {
7218
- handleExportJson,
7219
- handlePackageForSharing,
7220
- handleSaveAsFormat,
7221
- handleSaveAsPptx,
7222
- handleSaveAsPpsx,
7223
- handleSaveAsPptm
7224
- };
7225
- }
7226
-
7227
- // src/viewer/utils/dom-helpers.ts
7228
- function safePrompt(message, defaultValue) {
7229
- try {
7230
- return window.prompt(message, defaultValue);
7231
- } catch {
7232
- return null;
7233
- }
7234
- }
7235
- function safeConfirm(message) {
7236
- try {
7237
- return window.confirm(message);
7238
- } catch {
7239
- return false;
7240
- }
7241
- }
7242
-
7243
7195
  // src/viewer/hooks/useExportHandlers.ts
7244
7196
  function useExportHandlers(input) {
7245
7197
  const {
@@ -7251,7 +7203,6 @@ function useExportHandlers(input) {
7251
7203
  canvasStageRef,
7252
7204
  setActiveSlideIndex,
7253
7205
  handlerRef,
7254
- serializeSlides,
7255
7206
  headerFooter,
7256
7207
  presentationProperties,
7257
7208
  customShows,
@@ -7268,23 +7219,16 @@ function useExportHandlers(input) {
7268
7219
  theme,
7269
7220
  canvasSize,
7270
7221
  slideSizeEmu,
7271
- password
7222
+ password,
7223
+ imageExportScale
7272
7224
  } = input;
7273
7225
  const [exportModalOpen, setExportModalOpen] = useState(false);
7274
7226
  const [exportModalTitle, setExportModalTitle] = useState("");
7275
7227
  const [exportProgress, setExportProgress] = useState(0);
7276
7228
  const [exportStatusMessage, setExportStatusMessage] = useState("");
7277
7229
  const exportAbortRef = useRef(null);
7278
- const modalControls = {
7279
- setExportModalOpen,
7280
- setExportModalTitle,
7281
- setExportProgress,
7282
- setExportStatusMessage,
7283
- exportAbortRef
7284
- };
7285
7230
  const {
7286
7231
  handleExportJson,
7287
- handlePackageForSharing,
7288
7232
  handleSaveAsFormat,
7289
7233
  handleSaveAsPptx,
7290
7234
  handleSaveAsPpsx,
@@ -7294,7 +7238,6 @@ function useExportHandlers(input) {
7294
7238
  templateElementsBySlideId,
7295
7239
  filePath,
7296
7240
  handlerRef,
7297
- serializeSlides,
7298
7241
  headerFooter,
7299
7242
  presentationProperties,
7300
7243
  customShows,
@@ -7311,7 +7254,6 @@ function useExportHandlers(input) {
7311
7254
  theme,
7312
7255
  canvasSize,
7313
7256
  slideSizeEmu,
7314
- modalControls,
7315
7257
  password
7316
7258
  });
7317
7259
  const handleExportPng = useCallback(async () => {
@@ -7321,12 +7263,13 @@ function useExportHandlers(input) {
7321
7263
  }
7322
7264
  try {
7323
7265
  await exportSlideAsPng(stageEl, activeSlideIndex, {
7324
- backgroundColor: activeSlide?.backgroundColor
7266
+ backgroundColor: activeSlide?.backgroundColor,
7267
+ scale: imageExportScale
7325
7268
  });
7326
7269
  } catch (err) {
7327
7270
  console.error("[PowerPointViewer] PNG export failed:", err);
7328
7271
  }
7329
- }, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor]);
7272
+ }, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor, imageExportScale]);
7330
7273
  const handleExportPdf = useCallback(async () => {
7331
7274
  if (!canvasStageRef.current) {
7332
7275
  return;
@@ -7345,7 +7288,7 @@ function useExportHandlers(input) {
7345
7288
  activeSlideIndex,
7346
7289
  "presentation.pdf",
7347
7290
  {
7348
- scale: 2,
7291
+ scale: imageExportScale,
7349
7292
  onProgress: (current, total) => {
7350
7293
  setExportProgress(slideProgressPercent(current, total));
7351
7294
  setExportStatusMessage(slideStatusLabel("Rendering", current, total));
@@ -7368,7 +7311,7 @@ function useExportHandlers(input) {
7368
7311
  exportAbortRef.current = null;
7369
7312
  setExportModalOpen(false);
7370
7313
  }
7371
- }, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
7314
+ }, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
7372
7315
  const handleExportNotesPdf = useCallback(async () => {
7373
7316
  if (!canvasStageRef.current) {
7374
7317
  return;
@@ -7389,7 +7332,7 @@ function useExportHandlers(input) {
7389
7332
  slideNotes,
7390
7333
  "presentation-notes.pdf",
7391
7334
  {
7392
- scale: 2,
7335
+ scale: imageExportScale,
7393
7336
  onProgress: (current, total) => {
7394
7337
  setExportProgress(slideProgressPercent(current, total));
7395
7338
  setExportStatusMessage(slideStatusLabel("Rendering", current, total));
@@ -7412,7 +7355,7 @@ function useExportHandlers(input) {
7412
7355
  exportAbortRef.current = null;
7413
7356
  setExportModalOpen(false);
7414
7357
  }
7415
- }, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex]);
7358
+ }, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
7416
7359
  const handleCopySlideAsImage = useCallback(async () => {
7417
7360
  const stageEl = canvasStageRef.current;
7418
7361
  if (!stageEl) {
@@ -7420,12 +7363,13 @@ function useExportHandlers(input) {
7420
7363
  }
7421
7364
  try {
7422
7365
  await copySlideToClipboard(stageEl, {
7423
- backgroundColor: activeSlide?.backgroundColor
7366
+ backgroundColor: activeSlide?.backgroundColor,
7367
+ scale: imageExportScale
7424
7368
  });
7425
7369
  } catch (err) {
7426
7370
  console.error("[PowerPointViewer] Copy slide as image failed:", err);
7427
7371
  }
7428
- }, [canvasStageRef, activeSlide?.backgroundColor]);
7372
+ }, [canvasStageRef, activeSlide?.backgroundColor, imageExportScale]);
7429
7373
  const handleExportVideo = useCallback(async () => {
7430
7374
  if (!canvasStageRef.current) {
7431
7375
  return;
@@ -7522,7 +7466,6 @@ function useExportHandlers(input) {
7522
7466
  handleExportVideo,
7523
7467
  handleExportGif,
7524
7468
  handleExportJson,
7525
- handlePackageForSharing,
7526
7469
  handleSaveAsFormat,
7527
7470
  handleSaveAsPptx,
7528
7471
  handleSaveAsPpsx,
@@ -7534,95 +7477,96 @@ function useExportHandlers(input) {
7534
7477
  exportStatusMessage
7535
7478
  };
7536
7479
  }
7537
- function openPrintWindow(title, bodyHtml, orientation, colorFilter, frameSlides) {
7538
- const printWindow = window.open("", "_blank", "noopener,noreferrer");
7539
- if (!printWindow) {
7540
- return false;
7541
- }
7542
- printWindow.document.open();
7543
- printWindow.document.write(
7544
- buildPrintHtmlDocument({ title, bodyHtml, orientation, colorFilter, frameSlides })
7545
- );
7546
- printWindow.document.close();
7547
- printWindow.focus();
7548
- setTimeout(() => {
7549
- printWindow.print();
7550
- }, 300);
7551
- return true;
7552
- }
7553
- function openPrintWindowWithDocument(htmlDocument) {
7554
- const printWindow = window.open("", "_blank", "noopener,noreferrer");
7555
- if (!printWindow) {
7556
- return false;
7557
- }
7558
- printWindow.document.open();
7559
- printWindow.document.write(htmlDocument);
7560
- printWindow.document.close();
7561
- printWindow.focus();
7562
- setTimeout(() => {
7563
- printWindow.print();
7564
- }, 300);
7565
- return true;
7480
+ var ViewerOptionsContext = createContext(DEFAULT_VIEWER_OPTIONS);
7481
+ function useViewerOptionsContext() {
7482
+ return useContext(ViewerOptionsContext);
7566
7483
  }
7484
+
7485
+ // src/viewer/hooks/usePrintHandlers.ts
7567
7486
  function usePrintHandlers(input) {
7568
7487
  const { slides, activeSlideIndex, canvasStageRef, setActiveSlideIndex, pptxData } = input;
7569
7488
  const [isPrintDialogOpen, setIsPrintDialogOpen] = useState(false);
7489
+ const { t } = useTranslation();
7490
+ const viewerOptions = useViewerOptionsContext();
7491
+ const includeHiddenSlides = viewerOptions.advanced.printHiddenSlides;
7492
+ const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * resolveImageResolutionScale(viewerOptions);
7570
7493
  const handlePrint = () => {
7571
7494
  setIsPrintDialogOpen(true);
7572
7495
  };
7573
7496
  const handlePrintSvg = async (settings) => {
7574
7497
  setIsPrintDialogOpen(false);
7498
+ const printWindow = openPendingPrintWindow(t("pptx.print.preparingToPrint"));
7499
+ if (!printWindow) {
7500
+ console.warn(
7501
+ "[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
7502
+ );
7503
+ return;
7504
+ }
7575
7505
  if (!pptxData || settings.printWhat !== "slides") {
7576
- return handlePrintWithSettings(settings);
7506
+ return runRasterPrint(printWindow, settings);
7577
7507
  }
7578
7508
  const colorFilter = computeColorFilter(settings.colorMode);
7579
- const slideIndices = computeSlideIndices(
7580
- settings.slideRange,
7581
- activeSlideIndex,
7582
- slides.length,
7583
- settings.customRangeFrom,
7584
- settings.customRangeTo
7509
+ const slideIndices = filterHiddenSlideIndices(
7510
+ computeSlideIndices(
7511
+ settings.slideRange,
7512
+ activeSlideIndex,
7513
+ slides.length,
7514
+ settings.customRangeFrom,
7515
+ settings.customRangeTo
7516
+ ),
7517
+ slides,
7518
+ includeHiddenSlides
7585
7519
  );
7586
7520
  try {
7587
7521
  const svgs = exportAllSlidesToSvg(pptxData, {
7588
7522
  slideIndices
7589
7523
  });
7590
7524
  if (svgs.length === 0) {
7525
+ printWindow.close();
7591
7526
  return;
7592
7527
  }
7593
7528
  const printDoc = buildPrintDocument(svgs, pptxData.width, pptxData.height, {
7594
7529
  title: "Slides (Vector)",
7595
7530
  orientation: settings.orientation,
7596
- colorFilter
7531
+ colorFilter,
7532
+ scaleToFit: settings.scaleToFit
7597
7533
  });
7598
- openPrintWindowWithDocument(printDoc);
7534
+ finishPrintWindow(printWindow, printDoc);
7599
7535
  } catch (err) {
7600
7536
  console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
7601
- return handlePrintWithSettings(settings);
7537
+ return runRasterPrint(printWindow, settings);
7602
7538
  }
7603
7539
  };
7604
- const handlePrintWithSettings = async (settings) => {
7605
- setIsPrintDialogOpen(false);
7540
+ const runRasterPrint = async (printWindow, settings) => {
7606
7541
  const colorFilter = computeColorFilter(settings.colorMode);
7607
- const slideIndices = computeSlideIndices(
7608
- settings.slideRange,
7609
- activeSlideIndex,
7610
- slides.length,
7611
- settings.customRangeFrom,
7612
- settings.customRangeTo
7542
+ const slideIndices = filterHiddenSlideIndices(
7543
+ computeSlideIndices(
7544
+ settings.slideRange,
7545
+ activeSlideIndex,
7546
+ slides.length,
7547
+ settings.customRangeFrom,
7548
+ settings.customRangeTo
7549
+ ),
7550
+ slides,
7551
+ includeHiddenSlides
7613
7552
  );
7614
7553
  if (settings.printWhat === "outline") {
7615
- openPrintWindow(
7616
- "Outline",
7617
- `<div class="outline-page">${buildOutlineHtml(slideIndices, slides)}</div>`,
7618
- settings.orientation,
7619
- colorFilter,
7620
- settings.frameSlides
7554
+ finishPrintWindow(
7555
+ printWindow,
7556
+ buildPrintHtmlDocument({
7557
+ title: "Outline",
7558
+ bodyHtml: `<div class="outline-page">${buildOutlineHtml(slideIndices, slides)}</div>`,
7559
+ orientation: settings.orientation,
7560
+ colorFilter,
7561
+ frameSlides: settings.frameSlides,
7562
+ scaleToFit: settings.scaleToFit
7563
+ })
7621
7564
  );
7622
7565
  return;
7623
7566
  }
7624
7567
  try {
7625
7568
  if (!canvasStageRef.current) {
7569
+ printWindow.close();
7626
7570
  return;
7627
7571
  }
7628
7572
  const allImages = await captureAllSlidesAsPngDataUrls(
@@ -7630,46 +7574,70 @@ function usePrintHandlers(input) {
7630
7574
  slides.length,
7631
7575
  setActiveSlideIndex,
7632
7576
  activeSlideIndex,
7633
- { scale: 3 }
7577
+ { scale: printRasterScale }
7634
7578
  );
7635
7579
  if (allImages.length === 0) {
7580
+ printWindow.close();
7636
7581
  return;
7637
7582
  }
7638
7583
  const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
7639
7584
  if (settings.printWhat === "slides") {
7640
- openPrintWindow(
7641
- "Slides",
7642
- buildSlidesHtml(slideImages, slideIndices),
7643
- settings.orientation,
7644
- colorFilter,
7645
- settings.frameSlides
7585
+ finishPrintWindow(
7586
+ printWindow,
7587
+ buildPrintHtmlDocument({
7588
+ title: "Slides",
7589
+ bodyHtml: buildSlidesHtml(slideImages, slideIndices),
7590
+ orientation: settings.orientation,
7591
+ colorFilter,
7592
+ frameSlides: settings.frameSlides,
7593
+ scaleToFit: settings.scaleToFit
7594
+ })
7646
7595
  );
7647
7596
  return;
7648
7597
  }
7649
7598
  if (settings.printWhat === "notes") {
7650
- openPrintWindow(
7651
- "Notes Pages",
7652
- buildNotesHtml(slideImages, slideIndices, slides),
7653
- "portrait",
7654
- colorFilter,
7655
- settings.frameSlides
7599
+ finishPrintWindow(
7600
+ printWindow,
7601
+ buildPrintHtmlDocument({
7602
+ title: "Notes Pages",
7603
+ bodyHtml: buildNotesHtml(slideImages, slideIndices, slides),
7604
+ orientation: "portrait",
7605
+ colorFilter,
7606
+ frameSlides: settings.frameSlides,
7607
+ scaleToFit: settings.scaleToFit
7608
+ })
7656
7609
  );
7657
7610
  return;
7658
7611
  }
7659
7612
  if (settings.printWhat === "handouts") {
7660
7613
  const spp = settings.slidesPerPage;
7661
- openPrintWindow(
7662
- `Handout ${spp} per page`,
7663
- buildHandoutsHtml(slideImages, slideIndices, spp),
7664
- "portrait",
7665
- colorFilter,
7666
- settings.frameSlides
7614
+ finishPrintWindow(
7615
+ printWindow,
7616
+ buildPrintHtmlDocument({
7617
+ title: `Handout ${spp} per page`,
7618
+ bodyHtml: buildHandoutsHtml(slideImages, slideIndices, spp),
7619
+ orientation: "portrait",
7620
+ colorFilter,
7621
+ frameSlides: settings.frameSlides,
7622
+ scaleToFit: settings.scaleToFit
7623
+ })
7667
7624
  );
7668
7625
  }
7669
7626
  } catch (err) {
7670
7627
  console.error("[PowerPointViewer] Print layout failed:", err);
7671
7628
  }
7672
7629
  };
7630
+ const handlePrintWithSettings = async (settings) => {
7631
+ setIsPrintDialogOpen(false);
7632
+ const printWindow = openPendingPrintWindow(t("pptx.print.preparingToPrint"));
7633
+ if (!printWindow) {
7634
+ console.warn(
7635
+ "[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
7636
+ );
7637
+ return;
7638
+ }
7639
+ return runRasterPrint(printWindow, settings);
7640
+ };
7673
7641
  return {
7674
7642
  handlePrint,
7675
7643
  handlePrintWithSettings,
@@ -8460,11 +8428,12 @@ function useAnnotationHandlers(input) {
8460
8428
  presentation.enterPresentMode();
8461
8429
  } else if (mode === "present" && annotations.hasAnyAnnotations) {
8462
8430
  stopAllPersistentAudio();
8463
- pendingModeAfterAnnotationsRef.current = nextMode;
8464
8431
  if (promptKeepInkAnnotations) {
8432
+ pendingModeAfterAnnotationsRef.current = nextMode;
8465
8433
  setShowKeepAnnotationsDialog(true);
8466
8434
  } else {
8467
- handleKeepAnnotations();
8435
+ annotations.clearAllAnnotations();
8436
+ setMode(nextMode);
8468
8437
  }
8469
8438
  } else {
8470
8439
  if (mode === "present") {
@@ -8473,14 +8442,7 @@ function useAnnotationHandlers(input) {
8473
8442
  setMode(nextMode);
8474
8443
  }
8475
8444
  },
8476
- [
8477
- presentation,
8478
- mode,
8479
- annotations.hasAnyAnnotations,
8480
- promptKeepInkAnnotations,
8481
- handleKeepAnnotations,
8482
- setMode
8483
- ]
8445
+ [presentation, mode, annotations, promptKeepInkAnnotations, setMode]
8484
8446
  );
8485
8447
  const handleDiscardAnnotations = useCallback(() => {
8486
8448
  annotations.clearAllAnnotations();
@@ -8678,8 +8640,7 @@ function usePresentationSetup(input) {
8678
8640
  onToggleSubtitles
8679
8641
  } = input;
8680
8642
  const actionSoundHandlerRef = useRef(null);
8681
- const [, setShowKeepAnnotationsDialog] = useState(false);
8682
- const pendingModeRef = useRef("edit");
8643
+ const exitModeHandlerRef = useRef(null);
8683
8644
  const annotations = usePresentationAnnotations({
8684
8645
  isActive: mode === "present",
8685
8646
  activeSlideIndex,
@@ -8696,16 +8657,19 @@ function usePresentationSetup(input) {
8696
8657
  if (mode === "present" && nextMode !== "present" && !mayLeaveSlideShow()) {
8697
8658
  return;
8698
8659
  }
8699
- if (mode === "present" && nextMode !== "present" && annotations.hasAnyAnnotations && promptKeepInkAnnotations) {
8700
- pendingModeRef.current = nextMode;
8701
- setShowKeepAnnotationsDialog(true);
8702
- } else {
8703
- if (mode === "present" && nextMode !== "present") {
8704
- stopAllPersistentAudio();
8705
- stopAnimationSound();
8660
+ if (mode === "present" && nextMode !== "present") {
8661
+ stopAllPersistentAudio();
8662
+ stopAnimationSound();
8663
+ const exitHandler = exitModeHandlerRef.current;
8664
+ if (exitHandler) {
8665
+ exitHandler(nextMode);
8666
+ return;
8667
+ }
8668
+ if (annotations.hasAnyAnnotations && !promptKeepInkAnnotations) {
8669
+ annotations.clearAllAnnotations();
8706
8670
  }
8707
- setMode(nextMode);
8708
8671
  }
8672
+ setMode(nextMode);
8709
8673
  },
8710
8674
  onSetActiveSlideIndex: setActiveSlideIndex,
8711
8675
  onPlayActionSound: (soundPath, options) => {
@@ -8764,7 +8728,14 @@ function usePresentationSetup(input) {
8764
8728
  useTimings: presentationProperties.advanceMode !== "manual",
8765
8729
  endWithBlackSlide
8766
8730
  });
8767
- return { presentation, annotations, actionSoundHandlerRef };
8731
+ return {
8732
+ presentation,
8733
+ annotations,
8734
+ actionSoundHandlerRef,
8735
+ setExitModeHandler: (handler) => {
8736
+ exitModeHandlerRef.current = handler;
8737
+ }
8738
+ };
8768
8739
  }
8769
8740
  function useEditorOperations(input) {
8770
8741
  const {
@@ -8928,7 +8899,8 @@ function useEditorOperations(input) {
8928
8899
  tableEditorState: state.tableEditorState,
8929
8900
  setTableEditorState: state.setTableEditorState,
8930
8901
  ops,
8931
- history
8902
+ history,
8903
+ transformCommittedText
8932
8904
  });
8933
8905
  const combinedUpdateTextStyle = useCallback(
8934
8906
  (updates) => {
@@ -9030,11 +9002,11 @@ function useIOHandlers(input) {
9030
9002
  ops,
9031
9003
  zoom,
9032
9004
  handlerRef,
9033
- serializeSlides,
9034
9005
  serializeForRecovery,
9035
9006
  setContent,
9036
9007
  onContentChange,
9037
- password
9008
+ password,
9009
+ imageExportScale
9038
9010
  } = input;
9039
9011
  const exportHandlers = useExportHandlers({
9040
9012
  slides,
@@ -9045,7 +9017,6 @@ function useIOHandlers(input) {
9045
9017
  canvasStageRef: zoom.canvasStageRef,
9046
9018
  setActiveSlideIndex: state.setActiveSlideIndex,
9047
9019
  handlerRef,
9048
- serializeSlides,
9049
9020
  headerFooter: state.headerFooter,
9050
9021
  presentationProperties: state.presentationProperties,
9051
9022
  customShows: state.customShows,
@@ -9062,7 +9033,8 @@ function useIOHandlers(input) {
9062
9033
  theme: state.theme,
9063
9034
  canvasSize,
9064
9035
  slideSizeEmu: state.slideSizeEmu,
9065
- password
9036
+ password,
9037
+ imageExportScale
9066
9038
  });
9067
9039
  const printHandlers = usePrintHandlers({
9068
9040
  slides,
@@ -9276,7 +9248,8 @@ function useContentLifecycle(input) {
9276
9248
  actionSoundHandlerRef,
9277
9249
  setIsEncryptedDialogOpen,
9278
9250
  password,
9279
- onContentApplied
9251
+ onContentApplied,
9252
+ allowExternalImages
9280
9253
  } = input;
9281
9254
  const { handlerRef } = useLoadContent({
9282
9255
  content,
@@ -9315,7 +9288,8 @@ function useContentLifecycle(input) {
9315
9288
  setError: state.setError,
9316
9289
  setIsDirty: state.setIsDirty,
9317
9290
  setIsEncrypted: setIsEncryptedDialogOpen,
9318
- onContentApplied
9291
+ onContentApplied,
9292
+ allowExternalImages
9319
9293
  });
9320
9294
  useEffect(() => {
9321
9295
  actionSoundHandlerRef.current = handlerRef.current;
@@ -9554,7 +9528,10 @@ function useViewerIntegration(input) {
9554
9528
  autosaveEnabled,
9555
9529
  autosaveAllowed = true,
9556
9530
  autosaveIntervalMs,
9531
+ allowExternalImages,
9557
9532
  canEdit,
9533
+ promptKeepInkAnnotations,
9534
+ imageExportScale,
9558
9535
  mode,
9559
9536
  slides,
9560
9537
  activeSlide,
@@ -9619,7 +9596,8 @@ function useViewerIntegration(input) {
9619
9596
  actionSoundHandlerRef,
9620
9597
  setIsEncryptedDialogOpen,
9621
9598
  password: dialogs.presentationPassword ?? void 0,
9622
- onContentApplied: () => setLoadVersion((v) => v + 1)
9599
+ onContentApplied: () => setLoadVersion((v) => v + 1),
9600
+ allowExternalImages
9623
9601
  }
9624
9602
  );
9625
9603
  const { exportHandlers, printHandlers, themeHandlers, propertyHandlers } = useIOHandlers({
@@ -9632,11 +9610,11 @@ function useViewerIntegration(input) {
9632
9610
  ops: editorOps.ops,
9633
9611
  zoom,
9634
9612
  handlerRef,
9635
- serializeSlides,
9636
9613
  serializeForRecovery,
9637
9614
  setContent,
9638
9615
  onContentChange,
9639
- password: dialogs.presentationPassword ?? void 0
9616
+ password: dialogs.presentationPassword ?? void 0,
9617
+ imageExportScale
9640
9618
  });
9641
9619
  const {
9642
9620
  showKeepAnnotationsDialog,
@@ -9651,7 +9629,8 @@ function useViewerIntegration(input) {
9651
9629
  annotations,
9652
9630
  history,
9653
9631
  setMode: state.setMode,
9654
- setSlides: state.setSlides
9632
+ setSlides: state.setSlides,
9633
+ promptKeepInkAnnotations
9655
9634
  });
9656
9635
  const recovery = useRecoveryDetection({
9657
9636
  filePath,
@@ -9930,13 +9909,19 @@ function useViewerOptions() {
9930
9909
  return { optionsStore: store, options };
9931
9910
  }
9932
9911
  var KNOWN_TAB_IDS = new Set(TOOLBAR_TABS.map((tab) => tab.id));
9933
- function computeToolbarVisibility(hiddenActions) {
9912
+ function computeToolbarVisibility(hiddenActions, hiddenTabIds = []) {
9934
9913
  const isHidden = (id) => isActionHidden(id, hiddenActions);
9935
- const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id);
9914
+ const userHidden = new Set(hiddenTabIds);
9915
+ userHidden.delete("file");
9916
+ const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id) && !userHidden.has(id);
9936
9917
  return { isHidden, isTabVisible };
9937
9918
  }
9938
9919
  function useToolbarVisibility(hiddenActions) {
9939
- return useMemo(() => computeToolbarVisibility(hiddenActions), [hiddenActions]);
9920
+ const hiddenTabIds = useViewerOptionsContext().ribbon.hiddenTabIds;
9921
+ return useMemo(
9922
+ () => computeToolbarVisibility(hiddenActions, hiddenTabIds),
9923
+ [hiddenActions, hiddenTabIds]
9924
+ );
9940
9925
  }
9941
9926
  function useCollaborativeHistory({
9942
9927
  localClientId: _localClientId,
@@ -10509,7 +10494,9 @@ function buildCanvasProps(input) {
10509
10494
  tableOps,
10510
10495
  presentation,
10511
10496
  findResults,
10512
- findResultIndex
10497
+ findResultIndex,
10498
+ viewerOptions,
10499
+ buildHyperlinkConfirmMessage
10513
10500
  } = input;
10514
10501
  const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
10515
10502
  const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
@@ -10519,11 +10506,22 @@ function buildCanvasProps(input) {
10519
10506
  slide: activeSlide
10520
10507
  });
10521
10508
  const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
10509
+ const openExternalUrl = (url) => {
10510
+ if (shouldConfirmExternalHyperlink(viewerOptions, url) && !window.confirm(buildHyperlinkConfirmMessage(url))) {
10511
+ return;
10512
+ }
10513
+ safeOpenUrl(url);
10514
+ };
10522
10515
  const handleActionClick = (_elementId, action) => {
10523
10516
  if (mode === "present") {
10517
+ const resolved = resolvePresentationAction(action, { slideCount: slides.length });
10518
+ if (resolved.intent.kind === "openUrl") {
10519
+ openExternalUrl(resolved.intent.url);
10520
+ return;
10521
+ }
10524
10522
  presentation.handlePresentationAction(action);
10525
10523
  } else if (action.url) {
10526
- safeOpenUrl(action.url);
10524
+ openExternalUrl(action.url);
10527
10525
  }
10528
10526
  };
10529
10527
  const handleHyperlinkClick = (url) => {
@@ -10539,7 +10537,7 @@ function buildCanvasProps(input) {
10539
10537
  }
10540
10538
  return;
10541
10539
  }
10542
- safeOpenUrl(url);
10540
+ openExternalUrl(url);
10543
10541
  };
10544
10542
  return {
10545
10543
  activeSlide: effectiveSlide,
@@ -10839,7 +10837,6 @@ function buildToolbarProps(input) {
10839
10837
  onExportVideo: exportHandlers.handleExportVideo,
10840
10838
  onExportGif: exportHandlers.handleExportGif,
10841
10839
  onExportJson: exportHandlers.handleExportJson,
10842
- onPackageForSharing: exportHandlers.handlePackageForSharing,
10843
10840
  onOpenFile,
10844
10841
  onOpenRecentFile,
10845
10842
  onCreatePresentation: (templateId) => {
@@ -10977,6 +10974,7 @@ function useViewerBuildingBlocksCore(input) {
10977
10974
  ]
10978
10975
  );
10979
10976
  const zoom = useZoomViewport({ canvasSize, selectedElements: state.selectedElements });
10977
+ const { options: viewerOptions } = useViewerOptions();
10980
10978
  const history = useEditorHistory({
10981
10979
  slides,
10982
10980
  canvasSize,
@@ -10986,6 +10984,7 @@ function useViewerBuildingBlocksCore(input) {
10986
10984
  headerFooter: state.headerFooter,
10987
10985
  loading,
10988
10986
  error,
10987
+ maxHistoryEntries: resolveHistoryDepth(viewerOptions),
10989
10988
  hasActivePointerInteraction,
10990
10989
  pointerCommitNonce: state.pointerCommitNonce,
10991
10990
  setSlides: state.setSlides,
@@ -11007,12 +11006,15 @@ function useViewerBuildingBlocksCore(input) {
11007
11006
  activeMaster: state.activeMaster,
11008
11007
  documentGridSpacing: state.viewProperties?.gridSpacing
11009
11008
  });
11010
- const { options: viewerOptions } = useViewerOptions();
11011
- const { presentation, annotations, actionSoundHandlerRef } = usePresentationSetup({
11009
+ const { presentation, annotations, actionSoundHandlerRef, setExitModeHandler } = usePresentationSetup({
11012
11010
  mode,
11013
11011
  slides,
11014
11012
  visibleSlideIndexes,
11015
11013
  endWithBlackSlide: viewerOptions.advanced.slideShowEndWithBlackSlide,
11014
+ // File > Options > Advanced > "Prompt to keep ink annotations when
11015
+ // exiting" / "Show popup toolbar" while presenting.
11016
+ promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
11017
+ popupToolbarEnabled: viewerOptions.advanced.slideShowShowPopupToolbar,
11016
11018
  activeSlideIndex,
11017
11019
  containerRef,
11018
11020
  content,
@@ -11042,8 +11044,13 @@ function useViewerBuildingBlocksCore(input) {
11042
11044
  presentation,
11043
11045
  annotations,
11044
11046
  actionSoundHandlerRef,
11047
+ setExitModeHandler,
11045
11048
  masterPseudoSlide,
11046
- gridSpacingPx
11049
+ gridSpacingPx,
11050
+ // Multiplied against the pre-existing 2x baseline; see the matching
11051
+ // comment in `PowerPointViewer.tsx`.
11052
+ imageExportScale: 2 * resolveImageResolutionScale(viewerOptions),
11053
+ viewerOptions
11047
11054
  };
11048
11055
  }
11049
11056
  function useViewerBuildingBlocksState(input) {
@@ -11071,7 +11078,10 @@ function useViewerBuildingBlocksState(input) {
11071
11078
  presentation,
11072
11079
  annotations,
11073
11080
  actionSoundHandlerRef,
11074
- gridSpacingPx
11081
+ gridSpacingPx,
11082
+ imageExportScale,
11083
+ setExitModeHandler,
11084
+ viewerOptions
11075
11085
  } = core;
11076
11086
  const dialogs = useViewerDialogs({
11077
11087
  mode,
@@ -11142,7 +11152,13 @@ function useViewerBuildingBlocksState(input) {
11142
11152
  content,
11143
11153
  filePath,
11144
11154
  autosaveEnabled,
11155
+ // Trust Center > "Allow external content": same gate `PowerPointViewer`
11156
+ // applies, so the headless building-blocks API loads http(s) images
11157
+ // under the same default-off, core-side SSRF/privacy guard.
11158
+ allowExternalImages: viewerOptions.trust.allowExternalContent,
11145
11159
  canEdit,
11160
+ promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
11161
+ imageExportScale,
11146
11162
  mode,
11147
11163
  slides,
11148
11164
  activeSlide,
@@ -11160,6 +11176,7 @@ function useViewerBuildingBlocksState(input) {
11160
11176
  onSelectionChange,
11161
11177
  onSlideCountChange
11162
11178
  });
11179
+ setExitModeHandler(handleSetMode);
11163
11180
  return {
11164
11181
  dialogs,
11165
11182
  editorOps,
@@ -11195,6 +11212,7 @@ function useViewerBuildingBlocks(input) {
11195
11212
  onOpenHeaderFooter,
11196
11213
  onOpenShareDialog
11197
11214
  } = input;
11215
+ const { t } = useTranslation();
11198
11216
  const [content, setContent] = useState(incomingContent ?? null);
11199
11217
  useEffect(() => {
11200
11218
  setContent(incomingContent ?? null);
@@ -11229,7 +11247,8 @@ function useViewerBuildingBlocks(input) {
11229
11247
  history,
11230
11248
  presentation,
11231
11249
  masterPseudoSlide,
11232
- gridSpacingPx
11250
+ gridSpacingPx,
11251
+ viewerOptions
11233
11252
  } = core;
11234
11253
  const {
11235
11254
  dialogs,
@@ -11305,7 +11324,11 @@ function useViewerBuildingBlocks(input) {
11305
11324
  tableOps: editorOps.tableOps,
11306
11325
  presentation,
11307
11326
  findResults: editorOps.findReplace.findResults,
11308
- findResultIndex: editorOps.findReplace.findResultIndex
11327
+ findResultIndex: editorOps.findReplace.findResultIndex,
11328
+ viewerOptions,
11329
+ buildHyperlinkConfirmMessage: (url) => `${t("pptx.options.trust.confirmHyperlinks")}
11330
+
11331
+ ${url}`
11309
11332
  });
11310
11333
  return { toolbarProps, canvasProps, mode, loading, error, autosaveStatus };
11311
11334
  }
@@ -11379,4 +11402,4 @@ function useResizablePanels() {
11379
11402
  };
11380
11403
  }
11381
11404
 
11382
- export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, renderToCanvas, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
11405
+ export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, renderToCanvas, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };