pptx-react-viewer 4.74.0 → 4.76.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 (126) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +1 -1
  3. package/dist/{AiChatPanel-PLQ3NBTK.js → AiChatPanel-4V7QB5Z3.js} +19 -19
  4. package/dist/AiChatPanel-4V7QB5Z3.js.br +0 -0
  5. package/dist/AiChatPanel-4V7QB5Z3.js.gz +0 -0
  6. package/dist/{AiChatPanel-E7CJSTW7.mjs → AiChatPanel-6ML3VLIX.mjs} +1 -1
  7. package/dist/AiChatPanel-6ML3VLIX.mjs.br +0 -0
  8. package/dist/AiChatPanel-6ML3VLIX.mjs.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-P2COO2QO.js → chunk-6GFSF2ML.js} +65 -13
  16. package/dist/chunk-6GFSF2ML.js.br +0 -0
  17. package/dist/chunk-6GFSF2ML.js.gz +0 -0
  18. package/dist/chunk-FFTZYNL4.mjs +2 -0
  19. package/dist/chunk-FFTZYNL4.mjs.br +6 -0
  20. package/dist/chunk-FFTZYNL4.mjs.gz +0 -0
  21. package/dist/chunk-LWGPHJHC.js +151 -0
  22. package/dist/chunk-LWGPHJHC.js.br +0 -0
  23. package/dist/chunk-LWGPHJHC.js.gz +0 -0
  24. package/dist/{chunk-LVEFHZ76.js → chunk-MU3BIZ2U.js} +1 -1
  25. package/dist/chunk-MU3BIZ2U.js.br +0 -0
  26. package/dist/chunk-MU3BIZ2U.js.gz +0 -0
  27. package/dist/{chunk-FBSPQYRE.mjs → chunk-N3YK2BCA.mjs} +61 -14
  28. package/dist/chunk-N3YK2BCA.mjs.br +0 -0
  29. package/dist/chunk-N3YK2BCA.mjs.gz +0 -0
  30. package/dist/{chunk-SQ7OASDY.mjs → chunk-OC4RP2CB.mjs} +590 -392
  31. package/dist/chunk-OC4RP2CB.mjs.br +0 -0
  32. package/dist/chunk-OC4RP2CB.mjs.gz +0 -0
  33. package/dist/chunk-P2IEKYVG.js +29 -0
  34. package/dist/chunk-P2IEKYVG.js.br +0 -0
  35. package/dist/chunk-P2IEKYVG.js.gz +0 -0
  36. package/dist/{chunk-CRC3V4UG.mjs → chunk-PPOGAZ53.mjs} +646 -263
  37. package/dist/chunk-PPOGAZ53.mjs.br +0 -0
  38. package/dist/chunk-PPOGAZ53.mjs.gz +0 -0
  39. package/dist/{chunk-JZE6BORE.mjs → chunk-RMEWSJZU.mjs} +1 -1
  40. package/dist/chunk-RMEWSJZU.mjs.br +0 -0
  41. package/dist/chunk-RMEWSJZU.mjs.gz +0 -0
  42. package/dist/{chunk-XG4WSJ4O.js → chunk-SEIVQGH5.js} +1632 -1240
  43. package/dist/chunk-SEIVQGH5.js.br +0 -0
  44. package/dist/chunk-SEIVQGH5.js.gz +0 -0
  45. package/dist/{chunk-D4WC35PL.js → chunk-XTYBIJ2S.js} +1136 -939
  46. package/dist/chunk-XTYBIJ2S.js.br +0 -0
  47. package/dist/chunk-XTYBIJ2S.js.gz +0 -0
  48. package/dist/chunk-Y53EC3JU.mjs +27 -0
  49. package/dist/chunk-Y53EC3JU.mjs.br +0 -0
  50. package/dist/chunk-Y53EC3JU.mjs.gz +0 -0
  51. package/dist/i18n/de.cjs +5 -0
  52. package/dist/i18n/de.cjs.br +0 -0
  53. package/dist/i18n/de.cjs.gz +0 -0
  54. package/dist/i18n/de.mjs +5 -0
  55. package/dist/i18n/de.mjs.br +0 -0
  56. package/dist/i18n/de.mjs.gz +0 -0
  57. package/dist/i18n/es.cjs +5 -0
  58. package/dist/i18n/es.cjs.br +0 -0
  59. package/dist/i18n/es.cjs.gz +0 -0
  60. package/dist/i18n/es.mjs +5 -0
  61. package/dist/i18n/es.mjs.br +0 -0
  62. package/dist/i18n/es.mjs.gz +0 -0
  63. package/dist/i18n/fr.cjs +5 -0
  64. package/dist/i18n/fr.cjs.br +0 -0
  65. package/dist/i18n/fr.cjs.gz +0 -0
  66. package/dist/i18n/fr.mjs +5 -0
  67. package/dist/i18n/fr.mjs.br +0 -0
  68. package/dist/i18n/fr.mjs.gz +0 -0
  69. package/dist/i18n/zh-CN.cjs +5 -0
  70. package/dist/i18n/zh-CN.cjs.br +0 -0
  71. package/dist/i18n/zh-CN.cjs.gz +0 -0
  72. package/dist/i18n/zh-CN.mjs +5 -0
  73. package/dist/i18n/zh-CN.mjs.br +0 -0
  74. package/dist/i18n/zh-CN.mjs.gz +0 -0
  75. package/dist/index.d.ts +76 -26
  76. package/dist/index.js +126 -126
  77. package/dist/index.js.br +0 -0
  78. package/dist/index.js.gz +0 -0
  79. package/dist/index.mjs +6 -6
  80. package/dist/index.mjs.br +0 -0
  81. package/dist/index.mjs.gz +0 -0
  82. package/dist/internals.d.ts +52 -24
  83. package/dist/internals.js +82 -81
  84. package/dist/internals.js.br +0 -0
  85. package/dist/internals.js.gz +0 -0
  86. package/dist/internals.mjs +3 -2
  87. package/dist/internals.mjs.br +0 -0
  88. package/dist/internals.mjs.gz +0 -0
  89. package/dist/no-i18next.d.ts +1343 -0
  90. package/dist/no-i18next.js +251 -0
  91. package/dist/no-i18next.js.br +0 -0
  92. package/dist/no-i18next.js.gz +0 -0
  93. package/dist/no-i18next.mjs +6 -0
  94. package/dist/no-i18next.mjs.br +0 -0
  95. package/dist/no-i18next.mjs.gz +0 -0
  96. package/dist/pptx-viewer.css +1 -1
  97. package/dist/pptx-viewer.css.br +0 -0
  98. package/dist/pptx-viewer.css.gz +0 -0
  99. package/dist/viewer/index.d.ts +37 -18
  100. package/dist/viewer/index.js +25 -24
  101. package/dist/viewer/index.js.br +0 -0
  102. package/dist/viewer/index.js.gz +0 -0
  103. package/dist/viewer/index.mjs +5 -4
  104. package/dist/viewer/index.mjs.br +0 -0
  105. package/dist/viewer/index.mjs.gz +0 -0
  106. package/package.json +9 -4
  107. package/dist/AiChatPanel-E7CJSTW7.mjs.br +0 -0
  108. package/dist/AiChatPanel-E7CJSTW7.mjs.gz +0 -0
  109. package/dist/AiChatPanel-PLQ3NBTK.js.br +0 -0
  110. package/dist/AiChatPanel-PLQ3NBTK.js.gz +0 -0
  111. package/dist/chunk-CRC3V4UG.mjs.br +0 -0
  112. package/dist/chunk-CRC3V4UG.mjs.gz +0 -0
  113. package/dist/chunk-D4WC35PL.js.br +0 -0
  114. package/dist/chunk-D4WC35PL.js.gz +0 -0
  115. package/dist/chunk-FBSPQYRE.mjs.br +0 -0
  116. package/dist/chunk-FBSPQYRE.mjs.gz +0 -0
  117. package/dist/chunk-JZE6BORE.mjs.br +0 -0
  118. package/dist/chunk-JZE6BORE.mjs.gz +0 -0
  119. package/dist/chunk-LVEFHZ76.js.br +0 -0
  120. package/dist/chunk-LVEFHZ76.js.gz +0 -0
  121. package/dist/chunk-P2COO2QO.js.br +0 -0
  122. package/dist/chunk-P2COO2QO.js.gz +0 -0
  123. package/dist/chunk-SQ7OASDY.mjs.br +0 -0
  124. package/dist/chunk-SQ7OASDY.mjs.gz +0 -0
  125. package/dist/chunk-XG4WSJ4O.js.br +0 -0
  126. package/dist/chunk-XG4WSJ4O.js.gz +0 -0
@@ -1,7 +1,7 @@
1
- import { cloneTemplateElementsBySlideId, cloneSlide, cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, useTranslation, partitionTemplateElements, isTemplateElementId, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, comparePresentation, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, stopAllPersistentAudio, buildSaveSlides, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, getImageEffectsOpacity, getImageEffectsFilter, getImageRenderStyle, cn, isEditableTextElement, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getElementLabel, normalizeHexColor, makeCloneId, DEFAULT_TEXT_FONT_SIZE, buildPdfFromTiledImageData, GRID_SIZE, copyFormatFromElement, hasCopyableFormat, isImageTiled, getDuotoneColors, DEFAULT_STROKE_COLOR, DEFAULT_FILL_COLOR, buildCssGradientFromShapeStyle, getCropShapeClipPath, getElementTransform, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, rendersCustomVectorPath, rendersWedgeCalloutVector, getImageSurfaceMaskStyle, getTextWarpStyle, getTextCompensationTransform, getTextCompensationOrigin, renderTextSegments, buildReactChartViewModel, renderChartElement, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, buildTextBody3DSceneStyle, rerouteConnectorsForMovedElements, applyReroutedConnectors, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, buildNotesPdf, canvasToJpegData, applyFormatToElement, isPpactionUrl, parsePpactionUrl, getImageTilingStyle, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getAriaRoleDescription as getAriaRoleDescription$1, getAriaLabel as getAriaLabel$1, getAriaRole, DEFAULT_FONT_FAMILY, ACTION_BUTTON_PRESETS, isUrlSafe, substituteFieldText } from './chunk-FBSPQYRE.mjs';
2
- import { defineThreeViewElement, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createCollaborationSessionController, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, createEditorHistoryController, historyTheme, crossedHistoryTheme, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, resolveMediaBookmarkTimesMs, advanceMainSequence, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, resolveShowBackward, resolveShowForward, beginZoomExcursion, buildZoomTransitionOverride, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, INITIAL_FIND_REPLACE_SESSION, findReplaceSessionActions, visibleTemplateElements, createCollaborationLivePatcher, reportInlineTextDraft, initialInspectorOpen, resolveGoogleFontsCss2Base, createEmbeddedFontsSheet, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, loadDeckWebfontOutlines, GlyphOutlineFontCache, createPresentationLoadResources, prepareDeckWebfonts, prefetchDeckWebfonts, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, resolveTextFillBlipUrls, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, resolveInitialSlideIndex, pptxLoadErrorMessage, resolveAutosaveIntervalMs, createAutosaveController, saveAutosaveSnapshot, updateMasterViewElement, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canMergeShapes, canInteractWithElement, prepareHtml2CanvasClone, html2canvasCaptureScope, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, DEFAULT_VIEWER_OPTIONS, resolveImageResolutionScale, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, createAutosaveRecoveryController, discardAutosaveRecovery, probeAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, rasterResultToPngBlob, downloadBlob, elementPictureFilename, canEditElementPoints, dispatchEditorKey, isFeatureEnabled, parentSelection, textFontSizePtToPx, stepFontSizePt, textFontSizePxToPt, cycleSelectableElement, createCustomizationController, gateViewerEdits, prepareElementForInsertion, slideSpaceElement, resolveReportedViewerMode, autosaveStatusKind, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, isKeyboardOpen, scopeLayoutOptionsToSlide, collaborationHistoryReady, bindCollaborationHistory, INITIAL_READ_ONLY_SESSION, readOnlySessionActions, applyReadOnlySessionEvent, readOnlyBannerVisible, readOnlyLocked, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, resolveCollaborationConfig, openPptxFile, readBackstageRecentFile, resolveCollaborationShellEditability, resolveCollaborationShellState, getResizeHandleHitAreaStyle, resolveElementInteractivity, getBackgroundAnimationState, getShapeEffectLayerPlacement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, isMediaFullscreenActive, shouldRenderHitTarget, elementHitTargetStyle, getShapeEffectAnimationLayerStyle, tableFrameCss, inlineElementPointerEvents, passesClicksThroughBox, LINK_TOOLTIP_HOST_CLASS, resolvePalette as resolvePalette$1, mediaControlBarEnabled, mediaTransportVisible, oleActionsVisible, getGroupChildParentFill, deviceStrokeStageStyle, morphOverlayElementSlots, buildMorphOutlineRules, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, setPendingCaretPoint, resolveGroupDoubleClickTarget, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, promptNameDialog, generateCustomShowId, confirmDeleteDialog, contextMenuInspectorAnchor, savedPresentationFileName, deliverSavedPresentation, exportDeckJson, mapCustomizedEditorKey, isEditorTextInputTarget, groupElements, generateElementId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, planMergeShapes, applyMergeShapesPlan, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, createBlankSlide, insertSlidePaste, applySlidePasteTemplates, makeSlideId, insertedLayoutCompletion, buildSlideTemplateSlide, templateSchemeFromTheme, queueThemeWrite, needsOwnedSession, openOwnedCollaboration, resolveViewportFitOptions, editorViewportFitFor, calculateViewportFit, observeViewportClientSize, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, slideSpaceMembers, remapTextToSegments, getInlineEditorSelectionResult, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, createGestureController, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx as computeGridSpacingPx$1, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, rasterizeElement, cloneElementForPaste, applyPasteSpecialFormat, buildRasterPictureElement, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createWriteBackScheduler, writeBackReport, createSyncGate, observeExternalCollaborationReadiness, resolveHistoryDepth, hostFontDownloadLock, lockExternalContentSetting, FONT_DOWNLOAD_SETTING_ID, resolveAllowExternalContent, resolveEffectiveGoogleFonts, createBackstagePresentation, buildFieldSubstitutionContext, buildSlidesPaneFieldContext, buildSlidesPaneTableStyleContext, slidesPaneRehearsalTimings, openSlidesPaneLayoutGallery, getImageColorWashStyle, attachRotateHandlePlacement, getSelectionControlArtworkStyle, getSelectionOutlineColor, paintedStrokeWidth, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, MEDIA_FULLSCREEN_OVERLAY_STYLE, elementContainerHeightStyle, getAnimationOpacity, abuttingEdgeBleedStyle, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getShapeEffectFilterDefs, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, getSilhouetteFillLayer, buildSubpathFillOverlay, strokeOutlineViewBox, buildSummaryZoomView, readEditableText, spaceBeforeCaretRange, placeCaretAt, takePendingCaretPoint, getPendingSelectionRestore, restoreSegmentSelection, mapInlineTextFormatKey, mapInlineEditorChord, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, chartFormatTargetFromEvent, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, getTextCompensationStyle, placeholderPromptDescriptor, getAriaRoleDescription, getAriaLabel, elementIdSelector, TOOLBAR_TABS, resolveGroupPressTarget, scrollInspectorSectionIntoView, computeScrollDelta, buildOutlinePrintJobDocument, printJobRasterFallback, applyThemeByPath, withHistoryTheme, withHistoryMasterThemes, writeThemeParts, loadedThemeName, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, withCellStyle, getCellText, setCellText, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, createSnapshotTextPositions, resolvePresentationAction, getImageSvgFilters, getCachedNativeImageSize, probeNativeImageSize, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, svgLineCap, connectorSquareCapPath, connectorSnapTransform, connectorNeedsPath, connectorStrandScreenWidth, connectorWrapperTransform, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, modelDataToBlobUrl, resolveZoomNavigationTarget, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, isBulletMarkerSegment, resolveChartThreeViewSpec, applyChart3DDrag, applyChart3DSelect, canDrillDown, findChartPartTarget, withChartTitle, resolveSmartArtThreeViewSpec, measureSvgViewportRect, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, isEquationOnlyText, convertOmmlToMathMl, EQUATION_FONT_FAMILY, sanitizeMathMl, buildEquationBlockStyle, buildTextBlockStyle, hasGlyphEnvelope, buildGlyphEnvelopeBlock, warpParagraphLayouts, resolveFontItalic, resolveFontWeight, isWedgeCalloutPresetShape, getAriaRole as getAriaRole$1, isElementActionable, buildSmartArtPresetData, classifyMediaType, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, planPrintJob, openPrintWindow, buildVectorPrintJobDocument, openPendingPrintWindow, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, publishLiveGeometry, rasterizeElementTiledToCanvas, clampGifDimensions, rasterResultToPngDataUrl, openExternalHyperlinkConfirmed, advanceChartMarkDrag, advanceChartValueDrag, resolveChartKind, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, findSmartArtNodeText, commitSmartArtNodeFill, commitSmartArtNodeText, groupIntoParagraphs as groupIntoParagraphs$1, createGlyphOutlineLookup, resolveWarpRunPaint, finishPrintWindow, buildRasterPrintJobDocument, applyMotionPathPreset, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, computeSmartArtElementLayout, flattenNodes, computeInlineEditorRect, smartArtNodeAtPoint, SMARTART_DEFAULT_PALETTE, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, refreshSmartArtPictureImage, centeredSvgTextLines, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, bringForward, sendBackward, bringToFront, sendToBack } from 'ooxml-ui/pptx';
3
- export { DUOTONE_PRESETS, MOBILE_BREAKPOINT, SLIDE_TRANSITION_KEYFRAMES, TABLET_BREAKPOINT, clearAudienceContent, computeVirtualRange, downloadBlob, getSlideTransitionAnimations, loadAudienceContent, storeAudienceContent } from 'ooxml-ui/pptx';
4
- import React17, { useRef, useState, useCallback, useEffect, useSyncExternalStore, useMemo, useContext, useLayoutEffect, createContext, useImperativeHandle, Suspense } from 'react';
1
+ import { cloneTemplateElementsBySlideId, cloneSlide, cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, useTranslation, partitionTemplateElements, isTemplateElementId, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, comparePresentation, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, stopAllPersistentAudio, buildSaveSlides, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, getImageEffectsOpacity, getImageEffectsFilter, getImageRenderStyle, cn, isEditableTextElement, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getElementLabel, normalizeHexColor, makeCloneId, DEFAULT_TEXT_FONT_SIZE, buildPdfFromTiledImageData, GRID_SIZE, copyFormatFromElement, hasCopyableFormat, isImageTiled, getDuotoneColors, DEFAULT_STROKE_COLOR, DEFAULT_FILL_COLOR, buildCssGradientFromShapeStyle, getCropShapeClipPath, getElementTransform, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, rendersCustomVectorPath, rendersWedgeCalloutVector, getImageSurfaceMaskStyle, getTextWarpStyle, getTextCompensationTransform, getTextCompensationOrigin, renderTextSegments, buildReactChartViewModel, renderChartElement, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, buildTextBody3DSceneStyle, rerouteConnectorsForMovedElements, applyReroutedConnectors, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, buildNotesPdf, canvasToJpegData, applyFormatToElement, isPpactionUrl, parsePpactionUrl, getImageTilingStyle, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getAriaRoleDescription as getAriaRoleDescription$1, getAriaLabel as getAriaLabel$1, getAriaRole, DEFAULT_FONT_FAMILY, ACTION_BUTTON_PRESETS, isUrlSafe, substituteFieldText } from './chunk-N3YK2BCA.mjs';
2
+ import { defineThreeViewElement, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createCollaborationSessionController, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, createEditorHistoryController, historyTheme, crossedHistoryTheme, createViewerZoomStore, clampZoomScale, resetViewportScroll, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, resolveMediaBookmarkTimesMs, advanceMainSequence, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createWheelStepBuffer, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, resolveShowBackward, resolveShowForward, beginZoomExcursion, buildZoomTransitionOverride, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, INITIAL_FIND_REPLACE_SESSION, findReplaceSessionActions, visibleTemplateElements, createCollaborationLivePatcher, reportInlineTextDraft, initialInspectorOpen, resolveGoogleFontsCss2Base, createEmbeddedFontsSheet, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, loadDeckWebfontOutlines, GlyphOutlineFontCache, createPresentationLoadResources, prepareDeckWebfonts, prefetchDeckWebfonts, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, resolveTextFillBlipUrls, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, resolveInitialSlideIndex, pptxLoadErrorMessage, resolveAutosaveIntervalMs, createAutosaveController, saveAutosaveSnapshot, updateMasterViewElement, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canMergeShapes, canInteractWithElement, prepareHtml2CanvasClone, html2canvasCaptureScope, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, DEFAULT_VIEWER_OPTIONS, resolveImageResolutionScale, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, createAutosaveRecoveryController, discardAutosaveRecovery, probeAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, rasterResultToPngBlob, downloadBlob, elementPictureFilename, canEditElementPoints, dispatchEditorKey, isFeatureEnabled, parentSelection, textFontSizePtToPx, stepFontSizePt, textFontSizePxToPt, cycleSelectableElement, createCustomizationController, gateViewerEdits, prepareElementForInsertion, slideSpaceElement, resolveReportedViewerMode, autosaveStatusKind, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, isKeyboardOpen, scopeLayoutOptionsToSlide, collaborationHistoryReady, bindCollaborationHistory, INITIAL_READ_ONLY_SESSION, readOnlySessionActions, applyReadOnlySessionEvent, readOnlyBannerVisible, readOnlyLocked, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, resolveCollaborationConfig, openPptxFile, readBackstageRecentFile, resolveCollaborationShellEditability, resolveCollaborationShellState, resolveBuildingBlockMode, getResizeHandleHitAreaStyle, resolveElementInteractivity, getBackgroundAnimationState, getShapeEffectLayerPlacement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, isMediaFullscreenActive, shouldRenderHitTarget, elementHitTargetStyle, getShapeEffectAnimationLayerStyle, tableFrameCss, inlineElementPointerEvents, passesClicksThroughBox, LINK_TOOLTIP_HOST_CLASS, resolvePalette as resolvePalette$1, mediaControlBarEnabled, mediaTransportVisible, oleActionsVisible, getGroupChildParentFill, deviceStrokeStageStyle, morphOverlayElementSlots, buildMorphOutlineRules, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, setPendingCaretPoint, resolveGroupDoubleClickTarget, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, promptNameDialog, generateCustomShowId, confirmDeleteDialog, contextMenuInspectorAnchor, savedPresentationFileName, deliverSavedPresentation, exportDeckJson, mapCustomizedEditorKey, isEditorTextInputTarget, groupElements, generateElementId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, planMergeShapes, applyMergeShapesPlan, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, createBlankSlide, insertSlidePaste, applySlidePasteTemplates, makeSlideId, insertedLayoutCompletion, buildSlideTemplateSlide, templateSchemeFromTheme, queueThemeWrite, attachViewportNavigation, needsOwnedSession, openOwnedCollaboration, resolveViewportFitOptions, editorViewportFitFor, calculateViewportFit, observeViewportClientSize, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, slideSpaceMembers, remapTextToSegments, getInlineEditorSelectionResult, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, createGestureController, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx as computeGridSpacingPx$1, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, rasterizeElement, cloneElementForPaste, applyPasteSpecialFormat, buildRasterPictureElement, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createSaveRevisionController, createWriteBackScheduler, writeBackReport, createSyncGate, observeExternalCollaborationReadiness, resolveHistoryDepth, hostFontDownloadLock, lockExternalContentSetting, FONT_DOWNLOAD_SETTING_ID, resolveAllowExternalContent, resolveEffectiveGoogleFonts, resetSlideLayoutPath, selectionEquation, createPptxBuildingBlockSession, registerBuildingBlockGroups, createBackstagePresentation, buildFieldSubstitutionContext, buildSlidesPaneFieldContext, buildSlidesPaneTableStyleContext, slidesPaneRehearsalTimings, openSlidesPaneLayoutGallery, getImageColorWashStyle, attachRotateHandlePlacement, getSelectionControlArtworkStyle, getSelectionOutlineColor, paintedStrokeWidth, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, MEDIA_FULLSCREEN_OVERLAY_STYLE, elementContainerHeightStyle, getAnimationOpacity, abuttingEdgeBleedStyle, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getShapeEffectFilterDefs, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, getSilhouetteFillLayer, buildSubpathFillOverlay, strokeOutlineViewBox, buildSummaryZoomView, readEditableText, spaceBeforeCaretRange, placeCaretAt, takePendingCaretPoint, getPendingSelectionRestore, restoreSegmentSelection, mapInlineTextFormatKey, mapInlineEditorChord, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, chartFormatTargetFromEvent, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, getTextCompensationStyle, placeholderPromptDescriptor, getAriaRoleDescription, getAriaLabel, elementIdSelector, TOOLBAR_TABS, resolveGroupPressTarget, scrollInspectorSectionIntoView, computeScrollDelta, buildOutlinePrintJobDocument, printJobRasterFallback, applyThemeByPath, withHistoryTheme, withHistoryMasterThemes, writeThemeParts, loadedThemeName, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, withCellStyle, getCellText, setCellText, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, createSnapshotTextPositions, resolvePresentationAction, getImageSvgFilters, getCachedNativeImageSize, probeNativeImageSize, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, svgLineCap, connectorSquareCapPath, connectorSnapTransform, connectorNeedsPath, connectorStrandScreenWidth, connectorWrapperTransform, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, modelDataToBlobUrl, resolveZoomNavigationTarget, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, isBulletMarkerSegment, resolveChartThreeViewSpec, applyChart3DDrag, applyChart3DSelect, canDrillDown, findChartPartTarget, withChartTitle, resolveSmartArtThreeViewSpec, measureSvgViewportRect, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, isEquationOnlyText, convertOmmlToMathMl, EQUATION_FONT_FAMILY, sanitizeMathMl, buildEquationBlockStyle, buildTextBlockStyle, hasGlyphEnvelope, buildGlyphEnvelopeBlock, warpParagraphLayouts, resolveFontItalic, resolveFontWeight, isWedgeCalloutPresetShape, getAriaRole as getAriaRole$1, isElementActionable, buildingBlockFailure, BUILDING_BLOCK_OK, resolveHyperlinkEditResult, buildSmartArtPresetData, classifyMediaType, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, planPrintJob, openPrintWindow, buildVectorPrintJobDocument, openPendingPrintWindow, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, publishLiveGeometry, rasterizeElementTiledToCanvas, clampGifDimensions, rasterResultToPngDataUrl, openExternalHyperlinkConfirmed, advanceChartMarkDrag, advanceChartValueDrag, resolveChartKind, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, findSmartArtNodeText, commitSmartArtNodeFill, commitSmartArtNodeText, groupIntoParagraphs as groupIntoParagraphs$1, createGlyphOutlineLookup, resolveWarpRunPaint, finishPrintWindow, buildRasterPrintJobDocument, applyMotionPathPreset, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, computeSmartArtElementLayout, flattenNodes, computeInlineEditorRect, smartArtNodeAtPoint, SMARTART_DEFAULT_PALETTE, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, refreshSmartArtPictureImage, centeredSvgTextLines, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, bringForward, sendBackward, bringToFront, sendToBack } from 'ooxml-ui/pptx';
3
+ export { DUOTONE_PRESETS, MOBILE_BREAKPOINT, SLIDE_TRANSITION_KEYFRAMES, TABLET_BREAKPOINT, clearAudienceContent, computeVirtualRange, detectHyperlinkTargetType, downloadBlob, getSlideTransitionAnimations, loadAudienceContent, parseHyperlinkEmailUrl, parseHyperlinkSlideNumber, storeAudienceContent } from 'ooxml-ui/pptx';
4
+ import React18, { createContext, useRef, useState, useCallback, useEffect, useSyncExternalStore, useMemo, useContext, useLayoutEffect, useImperativeHandle, Suspense } from 'react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { PptxHandler, EncryptedFileError, hasShapeProperties, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, guidePxToEmu, hasTextProperties, isInkElement, duplicateSlide, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, reResolveSlideFonts, reResolveElementFonts, isImageLikeElement, getSubstituteFontFamily, elementActionToPptxAction, SvgExporter, setSmartArtNodeStyle, updateSmartArtNodeText } from 'ooxml-core/pptx';
7
7
  import { translationsEn } from 'ooxml-ui/pptx/i18n';
@@ -1020,13 +1020,14 @@ function useZoomViewport({
1020
1020
  canvasSize,
1021
1021
  selectedElements,
1022
1022
  fitPadding,
1023
- maxFitScale
1023
+ maxFitScale,
1024
+ dragPans = false,
1025
+ activeSlideId
1024
1026
  }) {
1025
1027
  const editWrapperRef = useRef(null);
1026
1028
  const canvasStageRef = useRef(null);
1027
1029
  const { viewportRef: canvasViewportRef, viewportNode, setCanvasViewportNode } = useViewportNode();
1028
1030
  const renderScaleRef = useRef(1);
1029
- const wheelBufferRef = useRef(createWheelStepBuffer());
1030
1031
  const storeRef = useRef(null);
1031
1032
  storeRef.current ??= createViewerZoomStore();
1032
1033
  const store = storeRef.current;
@@ -1124,41 +1125,40 @@ function useZoomViewport({
1124
1125
  selectedElements,
1125
1126
  setScale
1126
1127
  ]);
1127
- const handleWheel = useCallback(
1128
- (event) => {
1129
- const mapped = mapEditingWheel(event, wheelBufferRef.current, true);
1130
- if (mapped.intent !== "zoom") {
1131
- return;
1132
- }
1133
- event.preventDefault();
1134
- store.dispatch({
1135
- type: "set-zoom",
1136
- zoom: clampZoomScale(store.getState().zoom + mapped.deltaScale)
1137
- });
1138
- },
1139
- [store]
1140
- );
1128
+ const dragPansRef = useRef(dragPans);
1129
+ useEffect(() => {
1130
+ dragPansRef.current = dragPans;
1131
+ }, [dragPans]);
1141
1132
  useEffect(() => {
1142
1133
  if (viewportNode === null) {
1143
1134
  return;
1144
1135
  }
1145
1136
  let raf = 0;
1146
- let attached = null;
1137
+ let detach = null;
1147
1138
  const attach = () => {
1148
1139
  const viewport = viewportNode ?? canvasViewportRef.current;
1149
1140
  if (!viewport) {
1150
1141
  raf = requestAnimationFrame(attach);
1151
1142
  return;
1152
1143
  }
1153
- attached = viewport;
1154
- viewport.addEventListener("wheel", handleWheel, { passive: false });
1144
+ detach = attachViewportNavigation(viewport, {
1145
+ getZoom: () => store.getState().zoom,
1146
+ setZoom: (zoom) => store.dispatch({ type: "set-zoom", zoom }),
1147
+ dragPans: () => dragPansRef.current
1148
+ });
1155
1149
  };
1156
1150
  attach();
1157
1151
  return () => {
1158
1152
  cancelAnimationFrame(raf);
1159
- attached?.removeEventListener("wheel", handleWheel);
1153
+ detach?.();
1160
1154
  };
1161
- }, [canvasViewportRef, viewportNode, handleWheel]);
1155
+ }, [canvasViewportRef, viewportNode, store]);
1156
+ useEffect(() => {
1157
+ const viewport = viewportNode ?? canvasViewportRef.current;
1158
+ if (viewport) {
1159
+ resetViewportScroll(viewport);
1160
+ }
1161
+ }, [activeSlideId]);
1162
1162
  const getCanvasPointFromClient = useCallback(
1163
1163
  (clientX, clientY) => {
1164
1164
  const canvasStage = canvasStageRef.current;
@@ -1195,7 +1195,6 @@ function useZoomViewport({
1195
1195
  handleResetZoom,
1196
1196
  handleZoomToFit,
1197
1197
  handleZoomToSelection,
1198
- handleWheel,
1199
1198
  centerBoundsInViewport,
1200
1199
  getCanvasPointFromClient
1201
1200
  };
@@ -6116,184 +6115,95 @@ function createFileHandlers(deps) {
6116
6115
  };
6117
6116
  reader.readAsDataURL(file);
6118
6117
  };
6119
- const handleMediaFileChange = (e) => {
6120
- const file = e.target.files?.[0];
6121
- if (!file || !activeSlide) {
6122
- return;
6118
+ const insertMediaFile = (file, shouldInsert) => {
6119
+ if (!activeSlide) {
6120
+ return Promise.resolve(buildingBlockFailure("no-slide"));
6123
6121
  }
6124
- e.target.value = "";
6125
6122
  const mediaType = classifyMediaType(file.type);
6126
6123
  if (!mediaType) {
6127
- return;
6124
+ return Promise.resolve(buildingBlockFailure("unsupported-type"));
6128
6125
  }
6129
6126
  const elFilePath = file.path;
6130
- const insertMediaElement = (mediaSourceUrl, width, height) => {
6131
- addElement({
6132
- id: generateElementId(),
6133
- type: "media",
6134
- mediaType,
6135
- mediaMimeType: file.type || void 0,
6136
- mediaData: mediaSourceUrl,
6137
- x: Math.round((canvasSize.width - width) / 2),
6138
- y: Math.round((canvasSize.height - height) / 2),
6139
- width,
6140
- height
6141
- });
6142
- };
6143
- if (elFilePath) {
6144
- let normalized = elFilePath.replace(/\\/gu, "/");
6145
- if (!normalized.startsWith("/")) {
6146
- normalized = `/${normalized}`;
6147
- }
6148
- const mediaUrl = `pptx-resource://media${encodeURI(normalized)}`;
6149
- if (mediaType === "audio") {
6150
- insertMediaElement(mediaUrl, 420, 64);
6151
- return;
6152
- }
6153
- const probeUrl = URL.createObjectURL(file);
6154
- const probeVideo = document.createElement("video");
6155
- probeVideo.preload = "metadata";
6156
- probeVideo.onloadedmetadata = () => {
6157
- URL.revokeObjectURL(probeUrl);
6158
- const mW = 640, mH = 360;
6159
- let w = probeVideo.videoWidth || mW, h = probeVideo.videoHeight || mH;
6160
- if (w > mW || h > mH) {
6161
- const sc = Math.min(mW / w, mH / h);
6162
- w = Math.round(w * sc);
6163
- h = Math.round(h * sc);
6127
+ return new Promise((resolve) => {
6128
+ const insertMediaElement = (mediaSourceUrl, width, height) => {
6129
+ if (shouldInsert && !shouldInsert()) {
6130
+ resolve(buildingBlockFailure("stale-target"));
6131
+ return;
6164
6132
  }
6165
- insertMediaElement(mediaUrl, w, h);
6133
+ addElement({
6134
+ id: generateElementId(),
6135
+ type: "media",
6136
+ mediaType,
6137
+ mediaMimeType: file.type || void 0,
6138
+ mediaData: mediaSourceUrl,
6139
+ x: Math.round((canvasSize.width - width) / 2),
6140
+ y: Math.round((canvasSize.height - height) / 2),
6141
+ width,
6142
+ height
6143
+ });
6144
+ resolve(BUILDING_BLOCK_OK);
6166
6145
  };
6167
- probeVideo.onerror = () => {
6168
- URL.revokeObjectURL(probeUrl);
6169
- insertMediaElement(mediaUrl, 640, 360);
6146
+ const probeVideoSize = (probeSrc, mediaSourceUrl, release) => {
6147
+ const probeVideo = document.createElement("video");
6148
+ probeVideo.preload = "metadata";
6149
+ probeVideo.onloadedmetadata = () => {
6150
+ release();
6151
+ const mW = 640, mH = 360;
6152
+ let w = probeVideo.videoWidth || mW, h = probeVideo.videoHeight || mH;
6153
+ if (w > mW || h > mH) {
6154
+ const sc = Math.min(mW / w, mH / h);
6155
+ w = Math.round(w * sc);
6156
+ h = Math.round(h * sc);
6157
+ }
6158
+ insertMediaElement(mediaSourceUrl, w, h);
6159
+ };
6160
+ probeVideo.onerror = () => {
6161
+ release();
6162
+ insertMediaElement(mediaSourceUrl, 640, 360);
6163
+ };
6164
+ probeVideo.src = probeSrc;
6170
6165
  };
6171
- probeVideo.src = probeUrl;
6172
- return;
6173
- }
6174
- const reader = new FileReader();
6175
- reader.onload = () => {
6176
- const dataUrl = reader.result;
6177
- if (!dataUrl) {
6178
- return;
6179
- }
6180
- if (mediaType === "audio") {
6181
- insertMediaElement(dataUrl, 420, 64);
6166
+ if (elFilePath) {
6167
+ let normalized = elFilePath.replace(/\\/gu, "/");
6168
+ if (!normalized.startsWith("/")) {
6169
+ normalized = `/${normalized}`;
6170
+ }
6171
+ const mediaUrl = `pptx-resource://media${encodeURI(normalized)}`;
6172
+ if (mediaType === "audio") {
6173
+ insertMediaElement(mediaUrl, 420, 64);
6174
+ return;
6175
+ }
6176
+ const probeUrl = URL.createObjectURL(file);
6177
+ probeVideoSize(probeUrl, mediaUrl, () => URL.revokeObjectURL(probeUrl));
6182
6178
  return;
6183
6179
  }
6184
- const probeVideo = document.createElement("video");
6185
- probeVideo.preload = "metadata";
6186
- probeVideo.onloadedmetadata = () => {
6187
- const mW = 640, mH = 360;
6188
- let w = probeVideo.videoWidth || mW, h = probeVideo.videoHeight || mH;
6189
- if (w > mW || h > mH) {
6190
- const sc = Math.min(mW / w, mH / h);
6191
- w = Math.round(w * sc);
6192
- h = Math.round(h * sc);
6180
+ const reader = new FileReader();
6181
+ reader.onerror = () => resolve(buildingBlockFailure("decode-failed"));
6182
+ reader.onload = () => {
6183
+ const dataUrl = reader.result;
6184
+ if (!dataUrl) {
6185
+ resolve(buildingBlockFailure("decode-failed"));
6186
+ return;
6193
6187
  }
6194
- insertMediaElement(dataUrl, w, h);
6195
- };
6196
- probeVideo.onerror = () => {
6197
- insertMediaElement(dataUrl, 640, 360);
6188
+ if (mediaType === "audio") {
6189
+ insertMediaElement(dataUrl, 420, 64);
6190
+ return;
6191
+ }
6192
+ probeVideoSize(dataUrl, dataUrl, () => {
6193
+ });
6198
6194
  };
6199
- probeVideo.src = dataUrl;
6200
- };
6201
- reader.readAsDataURL(file);
6195
+ reader.readAsDataURL(file);
6196
+ });
6202
6197
  };
6203
- return { handleImageFileChange, handleMediaFileChange };
6204
- }
6205
-
6206
- // src/viewer/components/hyperlink-edit-types.ts
6207
- var ACTION_VERB_MAP = {
6208
- "ppaction://hlinkshowjump?jump=nextslide": "nextSlide",
6209
- "ppaction://hlinkshowjump?jump=previousslide": "prevSlide",
6210
- "ppaction://hlinkshowjump?jump=firstslide": "firstSlide",
6211
- "ppaction://hlinkshowjump?jump=lastslide": "lastSlide",
6212
- "ppaction://hlinkshowjump?jump=endshow": "endShow"
6213
- };
6214
- var ACTION_VERB_TO_PPACTION = {
6215
- nextSlide: "ppaction://hlinkshowjump?jump=nextslide",
6216
- prevSlide: "ppaction://hlinkshowjump?jump=previousslide",
6217
- firstSlide: "ppaction://hlinkshowjump?jump=firstslide",
6218
- lastSlide: "ppaction://hlinkshowjump?jump=lastslide",
6219
- endShow: "ppaction://hlinkshowjump?jump=endshow"
6220
- };
6221
-
6222
- // src/viewer/components/hyperlink-edit-utils.ts
6223
- function detectTargetType(url, action) {
6224
- if (action && action.startsWith("ppaction://")) {
6225
- if (action.includes("hlinksldjump")) {
6226
- return "slide";
6227
- }
6228
- if (ACTION_VERB_MAP[action.toLowerCase()]) {
6229
- return "action";
6230
- }
6231
- return "action";
6232
- }
6233
- if (!url) {
6234
- return "url";
6235
- }
6236
- if (url.startsWith("mailto:")) {
6237
- return "email";
6238
- }
6239
- if (/^[a-zA-Z]:\\|^\.\.?[/\\]|^file:/i.test(url)) {
6240
- return "file";
6241
- }
6242
- return "url";
6243
- }
6244
- function parseEmailUrl(url) {
6245
- if (!url.startsWith("mailto:")) {
6246
- return { address: url, subject: "" };
6247
- }
6248
- const withoutScheme = url.slice(7);
6249
- const qIdx = withoutScheme.indexOf("?");
6250
- if (qIdx < 0) {
6251
- return { address: withoutScheme, subject: "" };
6252
- }
6253
- const address = withoutScheme.slice(0, qIdx);
6254
- const params = new URLSearchParams(withoutScheme.slice(qIdx + 1));
6255
- return { address, subject: params.get("subject") || "" };
6256
- }
6257
- function parseSlideFromUrl(url, action) {
6258
- if (action === "ppaction://hlinksldjump" && url) {
6259
- const match = url.match(/slide(\d+)\.xml$/i);
6260
- if (match) {
6261
- return parseInt(match[1], 10);
6262
- }
6263
- }
6264
- if (url) {
6265
- const hashMatch = url.match(/#\s*Slide\s+(\d+)/i);
6266
- if (hashMatch) {
6267
- return parseInt(hashMatch[1], 10);
6268
- }
6269
- }
6270
- return 1;
6271
- }
6272
- function resolveHyperlinkEditResult(data) {
6273
- const tooltip = data.tooltip.trim() || void 0;
6274
- switch (data.targetType) {
6275
- case "email": {
6276
- const mailto = data.emailSubject ? `mailto:${data.emailAddress}?subject=${encodeURIComponent(data.emailSubject)}` : `mailto:${data.emailAddress}`;
6277
- return { url: mailto, tooltip };
6198
+ const handleMediaFileChange = (e) => {
6199
+ const file = e.target.files?.[0];
6200
+ if (!file || !activeSlide) {
6201
+ return;
6278
6202
  }
6279
- case "slide":
6280
- return {
6281
- url: `slide${data.slideNumber}.xml`,
6282
- action: "ppaction://hlinksldjump",
6283
- tooltip
6284
- };
6285
- case "file":
6286
- return { url: data.filePath, tooltip };
6287
- case "action":
6288
- return {
6289
- url: "",
6290
- action: ACTION_VERB_TO_PPACTION[data.actionVerb],
6291
- tooltip
6292
- };
6293
- case "url":
6294
- default:
6295
- return { url: data.url, tooltip };
6296
- }
6203
+ e.target.value = "";
6204
+ void insertMediaFile(file);
6205
+ };
6206
+ return { handleImageFileChange, handleMediaFileChange, insertMediaFile };
6297
6207
  }
6298
6208
 
6299
6209
  // src/viewer/hooks/insert-structured-elements.ts
@@ -6354,14 +6264,14 @@ function createStructuredElementHandlers(deps) {
6354
6264
  ops.updateElementById(sel.id, { textSegments: updatedSegments });
6355
6265
  history.markDirty();
6356
6266
  };
6357
- const handleHyperlinkConfirm = (data) => {
6267
+ const applyHyperlink = (data) => {
6358
6268
  const sel = selectedElements[0];
6359
6269
  if (!sel) {
6360
- return;
6270
+ return buildingBlockFailure("no-selection");
6361
6271
  }
6362
6272
  const resolved = resolveHyperlinkEditResult(data);
6363
6273
  if (resolved.url && !isUrlSafe(resolved.url)) {
6364
- return;
6274
+ return buildingBlockFailure("unsafe-url");
6365
6275
  }
6366
6276
  const actionClick = {
6367
6277
  url: resolved.url || void 0,
@@ -6370,6 +6280,22 @@ function createStructuredElementHandlers(deps) {
6370
6280
  };
6371
6281
  ops.updateElementById(sel.id, { actionClick });
6372
6282
  history.markDirty();
6283
+ return BUILDING_BLOCK_OK;
6284
+ };
6285
+ const handleHyperlinkConfirm = (data) => {
6286
+ applyHyperlink(data);
6287
+ };
6288
+ const removeHyperlink = () => {
6289
+ const sel = selectedElements[0];
6290
+ if (!sel) {
6291
+ return buildingBlockFailure("no-selection");
6292
+ }
6293
+ if (!sel.actionClick) {
6294
+ return buildingBlockFailure("no-hyperlink");
6295
+ }
6296
+ ops.updateElementById(sel.id, { actionClick: void 0 });
6297
+ history.markDirty();
6298
+ return BUILDING_BLOCK_OK;
6373
6299
  };
6374
6300
  const handleInsertField = (fieldType, value) => {
6375
6301
  if (!activeSlide) {
@@ -6456,6 +6382,8 @@ function createStructuredElementHandlers(deps) {
6456
6382
  handleInsertEquation,
6457
6383
  handleUpdateEquation,
6458
6384
  handleHyperlinkConfirm,
6385
+ applyHyperlink,
6386
+ removeHyperlink,
6459
6387
  handleInsertField,
6460
6388
  handleAddActionButton
6461
6389
  };
@@ -10647,6 +10575,18 @@ function useReportOnChange(value, report, initial = value) {
10647
10575
  callback.current?.(value);
10648
10576
  }, [value]);
10649
10577
  }
10578
+ function useSaveRevision(deps) {
10579
+ const depsRef = useRef(deps);
10580
+ depsRef.current = deps;
10581
+ const controllerRef = useRef(null);
10582
+ controllerRef.current ??= createSaveRevisionController({
10583
+ getSources: () => depsRef.current.getSources(),
10584
+ serialize: () => depsRef.current.serialize(),
10585
+ markClean: () => depsRef.current.markClean(),
10586
+ discardRecovery: () => depsRef.current.discardRecovery()
10587
+ });
10588
+ return controllerRef.current;
10589
+ }
10650
10590
 
10651
10591
  // src/viewer/hooks/useViewerIntegration.ts
10652
10592
  function useViewerIntegration(input) {
@@ -10811,6 +10751,16 @@ function useViewerIntegration(input) {
10811
10751
  const updateElements = useElementUpdateBatch(input);
10812
10752
  const fallbackCustomizationRef = useRef(null);
10813
10753
  const customizationApi = input.customizationApi ?? (fallbackCustomizationRef.current ??= createCustomizationController().api);
10754
+ const saveRevision = useSaveRevision({
10755
+ getSources: getChangeSources,
10756
+ // Not `getContent`: that one announces `onContentChange`; a host save is not an edit feed.
10757
+ serialize: async () => await serializeSlides() ?? new Uint8Array(0),
10758
+ markClean: () => {
10759
+ history.markSaved();
10760
+ state.setIsDirty(false);
10761
+ },
10762
+ discardRecovery: input.discardRecoveryOnHostSave ?? (() => void 0)
10763
+ });
10814
10764
  const latestHandleRef = useRef(null);
10815
10765
  const viewerApiRef = useRef(null);
10816
10766
  viewerApiRef.current ??= new Proxy({}, {
@@ -10887,6 +10837,9 @@ function useViewerIntegration(input) {
10887
10837
  isDirty() {
10888
10838
  return state.isDirty;
10889
10839
  },
10840
+ getSaveRevision: () => saveRevision.getRevision(),
10841
+ getSaveSnapshot: () => saveRevision.snapshot(),
10842
+ acknowledgeSave: (revision) => saveRevision.acknowledge(revision),
10890
10843
  getSelectedElementIds() {
10891
10844
  return state.effectiveSelectedIds;
10892
10845
  },
@@ -12239,8 +12192,8 @@ function buildToolbarProps(input) {
12239
12192
  onAddActionButton: insertHandlers.handleAddActionButton,
12240
12193
  onInsertField: insertHandlers.handleInsertField,
12241
12194
  onOpenHeaderFooter,
12242
- onOpenImagePicker: () => s.imageInputRef.current?.click(),
12243
- onOpenMediaPicker: () => s.mediaInputRef.current?.click(),
12195
+ onOpenImagePicker: input.onOpenImagePicker ?? (() => s.imageInputRef.current?.click()),
12196
+ onOpenMediaPicker: input.onOpenMediaPicker ?? (() => s.mediaInputRef.current?.click()),
12244
12197
  onSetActiveTool: s.setActiveTool,
12245
12198
  onSetDrawingColor: s.setDrawingColor,
12246
12199
  onSetDrawingWidth: s.setDrawingWidth,
@@ -12388,9 +12341,8 @@ function buildToolbarProps(input) {
12388
12341
  activeSlide,
12389
12342
  onTransitionChange: handleTransitionChange,
12390
12343
  onApplyTransitionToAll: handleApplyTransitionToAll,
12391
- // No `onResetSlide` here: this building-blocks surface supplies no
12392
- // `onApplyLayout` either, so there is no layout to reset to. The mounted
12393
- // viewer (`ViewerToolbarSection`) wires both.
12344
+ onApplyLayout: input.onApplyLayout,
12345
+ onResetSlide: input.onResetSlide,
12394
12346
  onSelectAll: () => {
12395
12347
  const allIds = activeSlide?.elements.map((element) => element.id) ?? [];
12396
12348
  if (allIds.length > 0) {
@@ -12405,6 +12357,312 @@ function buildToolbarProps(input) {
12405
12357
  hiddenActions
12406
12358
  };
12407
12359
  }
12360
+ function useDialogFlagRequest(isOpen2, handle) {
12361
+ const handleRef = useRef(handle);
12362
+ handleRef.current = handle;
12363
+ useEffect(() => {
12364
+ if (isOpen2) {
12365
+ handleRef.current();
12366
+ }
12367
+ }, [isOpen2]);
12368
+ }
12369
+ function useFileDialogPorts(input) {
12370
+ const latest = useRef(input);
12371
+ latest.current = input;
12372
+ const { dialogs, request } = input;
12373
+ useDialogFlagRequest(dialogs.isPasswordDialogOpen, () => {
12374
+ dialogs.setIsPasswordDialogOpen(false);
12375
+ request({ kind: "passwordProtection" });
12376
+ });
12377
+ useDialogFlagRequest(dialogs.isDocPropsDialogOpen, () => {
12378
+ dialogs.setIsDocPropsDialogOpen(false);
12379
+ request({ kind: "documentProperties" });
12380
+ });
12381
+ useDialogFlagRequest(dialogs.isFontEmbeddingOpen, () => {
12382
+ dialogs.setIsFontEmbeddingOpen(false);
12383
+ request({ kind: "fontEmbedding" });
12384
+ });
12385
+ useDialogFlagRequest(dialogs.isDigitalSigDialogOpen, () => {
12386
+ dialogs.setIsDigitalSigDialogOpen(false);
12387
+ request({ kind: "digitalSignatures" });
12388
+ });
12389
+ const ports = useRef(null);
12390
+ ports.current ??= /* @__PURE__ */ (() => {
12391
+ const now = () => latest.current;
12392
+ const markDirty = () => now().history.markDirty();
12393
+ return {
12394
+ passwordProtection: {
12395
+ input: () => ({
12396
+ openPasswordSet: now().dialogs.isPasswordProtected,
12397
+ recommendation: now().recommendation,
12398
+ hasModifyVerifier: now().hasModifyVerifier,
12399
+ customProperties: now().state.customProperties
12400
+ }),
12401
+ customProperties: () => now().state.customProperties,
12402
+ applyOpenPassword: (password) => password === null ? now().dialogs.handleRemovePassword() : now().dialogs.handleSetPassword(password),
12403
+ applyCustomProperties: (next) => now().propertyHandlers.handleUpdateCustomProperties(next),
12404
+ markDirty
12405
+ },
12406
+ documentProperties: {
12407
+ current: () => ({
12408
+ core: now().state.coreProperties ?? {},
12409
+ custom: now().state.customProperties,
12410
+ app: now().state.appProperties ?? {}
12411
+ }),
12412
+ applyUpdate: (update) => {
12413
+ const handlers = now().propertyHandlers;
12414
+ if (update.core) {
12415
+ handlers.handleUpdateCoreProperties(update.core);
12416
+ }
12417
+ if (update.custom) {
12418
+ handlers.handleUpdateCustomProperties(update.custom);
12419
+ }
12420
+ if (update.app) {
12421
+ handlers.handleUpdateAppProperties(update.app);
12422
+ }
12423
+ }
12424
+ },
12425
+ fontEmbedding: {
12426
+ input: () => ({
12427
+ embedFonts: now().dialogs.embedFontsEnabled,
12428
+ embeddedFamilies: now().state.embeddedFonts.map((font) => font.name),
12429
+ usedFamilies: now().propertyHandlers.usedFontFamilies,
12430
+ descriptor: now().dialogs.fontEmbedding
12431
+ }),
12432
+ apply: (enabled) => now().dialogs.setEmbedFontsEnabled(enabled),
12433
+ markDirty
12434
+ },
12435
+ digitalSignatures: {
12436
+ signed: () => now().state.hasDigitalSignatures,
12437
+ count: () => now().state.digitalSignatureCount,
12438
+ content: () => now().content,
12439
+ markDirty
12440
+ }
12441
+ };
12442
+ })();
12443
+ return ports.current;
12444
+ }
12445
+
12446
+ // src/viewer/hooks/useViewerBuildingBlocks-find-layout-actions.ts
12447
+ function findReplacePort(findReplace) {
12448
+ return {
12449
+ open: findReplace.findReplaceOpen,
12450
+ setOpen: findReplace.setFindReplaceOpen,
12451
+ query: findReplace.findQuery,
12452
+ replacement: findReplace.replaceQuery,
12453
+ options: {
12454
+ matchCase: findReplace.findMatchCase,
12455
+ includeNotes: findReplace.findIncludeNotes,
12456
+ includeChartTitles: findReplace.findIncludeChartTitles,
12457
+ includeChartData: findReplace.findIncludeChartData
12458
+ },
12459
+ matches: findReplace.findResults,
12460
+ currentIndex: findReplace.findResultIndex,
12461
+ setQuery: findReplace.setFindQuery,
12462
+ setReplacement: findReplace.setReplaceQuery,
12463
+ setOptions: (change) => {
12464
+ if (change.matchCase !== void 0) {
12465
+ findReplace.setFindMatchCase(change.matchCase);
12466
+ }
12467
+ if (change.includeNotes !== void 0) {
12468
+ findReplace.setFindIncludeNotes(change.includeNotes);
12469
+ }
12470
+ if (change.includeChartTitles !== void 0) {
12471
+ findReplace.setFindIncludeChartTitles(change.includeChartTitles);
12472
+ }
12473
+ if (change.includeChartData !== void 0) {
12474
+ findReplace.setFindIncludeChartData(change.includeChartData);
12475
+ }
12476
+ },
12477
+ find: findReplace.performFind,
12478
+ navigate: (delta) => findReplace.navigateFindResult(delta),
12479
+ replaceCurrent: findReplace.handleReplace,
12480
+ replaceAll: findReplace.handleReplaceAll
12481
+ };
12482
+ }
12483
+ function useShowDialogPorts(input) {
12484
+ const { state, dialogs, presentation, session } = input;
12485
+ const { t } = useTranslation();
12486
+ const latest = useRef({ ...input, t });
12487
+ latest.current = { ...input, t };
12488
+ const showsRef = useRef(state.customShows);
12489
+ showsRef.current = state.customShows;
12490
+ const [startRequest, setStartRequest] = useState(0);
12491
+ useDialogFlagRequest(dialogs.isSetUpSlideShowOpen, () => {
12492
+ dialogs.setIsSetUpSlideShowOpen(false);
12493
+ session.request({ kind: "setUpSlideShow" });
12494
+ });
12495
+ useDialogFlagRequest(dialogs.isCustomShowsOpen, () => {
12496
+ dialogs.setIsCustomShowsOpen(false);
12497
+ session.request({ kind: "customShows" });
12498
+ });
12499
+ useDialogFlagRequest(
12500
+ dialogs.isBroadcastDialogOpen,
12501
+ () => dialogs.setIsBroadcastDialogOpen(false)
12502
+ );
12503
+ const shortcutsOpen = state.isShortcutHelpOpen;
12504
+ const firstShortcutsRender = useRef(true);
12505
+ useEffect(() => {
12506
+ if (firstShortcutsRender.current) {
12507
+ firstShortcutsRender.current = false;
12508
+ return;
12509
+ }
12510
+ session.announce({ kind: "shortcuts", open: shortcutsOpen }, shortcutsOpen);
12511
+ }, [shortcutsOpen, session]);
12512
+ useEffect(() => {
12513
+ if (startRequest > 0) {
12514
+ presentation.enterPresentModeFromBeginning();
12515
+ }
12516
+ }, [startRequest]);
12517
+ const ports = useRef(null);
12518
+ ports.current ??= /* @__PURE__ */ (() => {
12519
+ const now = () => latest.current;
12520
+ return {
12521
+ setUpSlideShow: {
12522
+ presentationProperties: () => now().state.presentationProperties,
12523
+ slideCount: () => now().slides.length,
12524
+ customShows: () => now().state.customShows,
12525
+ save: (settings) => now().dialogs.handleSaveSlideShowSettings(settings)
12526
+ },
12527
+ customShows: {
12528
+ customShows: () => showsRef.current,
12529
+ slides: () => now().slides,
12530
+ activeId: () => now().state.activeCustomShowId,
12531
+ commit: (shows, slides) => {
12532
+ showsRef.current = shows;
12533
+ now().dialogs.handleCommitCustomShows(shows, slides);
12534
+ },
12535
+ start: (id) => {
12536
+ now().state.setActiveCustomShowId(id);
12537
+ setStartRequest((count) => count + 1);
12538
+ }
12539
+ },
12540
+ shortcuts: {
12541
+ open: () => now().state.isShortcutHelpOpen,
12542
+ setOpen: (open) => now().state.setIsShortcutHelpOpen(open),
12543
+ toggle: () => now().state.setIsShortcutHelpOpen((open) => !open),
12544
+ translate: (key) => now().t(key)
12545
+ }
12546
+ };
12547
+ })();
12548
+ return ports.current;
12549
+ }
12550
+
12551
+ // src/viewer/hooks/useViewerBuildingBlocksActions.ts
12552
+ function useViewerBuildingBlocksActions(input) {
12553
+ const { state, dialogs, activeSlide, handlerRef } = input;
12554
+ const selectedElement = state.selectedElements[0] ?? null;
12555
+ const scopedLayouts = useMemo(
12556
+ () => scopeLayoutOptionsToActiveSlide(state.layoutOptions, activeSlide),
12557
+ [state.layoutOptions, activeSlide]
12558
+ );
12559
+ const layoutSwitching = useLayoutSwitching({
12560
+ handler: handlerRef.current,
12561
+ slides: input.slides,
12562
+ activeSlideIndex: input.activeSlideIndex,
12563
+ ops: input.editorOps.ops,
12564
+ history: input.history,
12565
+ onTemplateElementsChanged: (slideId, elements) => state.setTemplateElementsBySlideId((prev) => ({ ...prev, [slideId]: elements }))
12566
+ });
12567
+ const availabilityInput = {
12568
+ ready: !state.loading && !state.error,
12569
+ hasActiveSlide: Boolean(activeSlide),
12570
+ canEdit: input.canEdit,
12571
+ editing: input.mode === "edit",
12572
+ canInsert: input.canInsert,
12573
+ hasSelection: selectedElement !== null,
12574
+ selectionHasHyperlink: Boolean(selectedElement?.actionClick),
12575
+ selectionHasEquation: selectionEquation(selectedElement) !== null,
12576
+ layoutCount: scopedLayouts.length,
12577
+ hasCurrentLayout: resetSlideLayoutPath(activeSlide) !== void 0,
12578
+ hasHandler: handlerRef.current !== null
12579
+ };
12580
+ const next = { ...input, availabilityInput, scopedLayouts, layoutSwitching, selectedElement };
12581
+ const latest = useRef(next);
12582
+ latest.current = next;
12583
+ const sessionRef = useRef(null);
12584
+ sessionRef.current ??= createPptxBuildingBlockSession(createReactPort(latest));
12585
+ const session = sessionRef.current;
12586
+ useController(session.requests);
12587
+ const fileDialogPorts = useFileDialogPorts({
12588
+ state,
12589
+ dialogs,
12590
+ propertyHandlers: input.propertyHandlers,
12591
+ history: input.history,
12592
+ content: input.content,
12593
+ recommendation: input.readOnlyRecommendation,
12594
+ hasModifyVerifier: input.hasModifyVerifier,
12595
+ request: (request) => void session.request(request)
12596
+ });
12597
+ const showDialogPorts = useShowDialogPorts({
12598
+ state,
12599
+ dialogs,
12600
+ presentation: input.presentation,
12601
+ slides: input.slides,
12602
+ session
12603
+ });
12604
+ const registered = useRef(false);
12605
+ if (!registered.current) {
12606
+ registered.current = true;
12607
+ registerBuildingBlockGroups(session, { ...fileDialogPorts, ...showDialogPorts });
12608
+ }
12609
+ useDialogFlagRequest(dialogs.isHyperlinkDialogOpen, () => {
12610
+ dialogs.setIsHyperlinkDialogOpen(false);
12611
+ session.request({ kind: "hyperlink" });
12612
+ });
12613
+ useDialogFlagRequest(dialogs.isSmartArtDialogOpen, () => {
12614
+ dialogs.setIsSmartArtDialogOpen(false);
12615
+ session.request({ kind: "smartArt" });
12616
+ });
12617
+ useDialogFlagRequest(dialogs.isEquationDialogOpen, () => {
12618
+ const existingOmml = dialogs.editingEquationOmml;
12619
+ dialogs.setIsEquationDialogOpen(false);
12620
+ dialogs.setEditingEquationOmml(null);
12621
+ session.request({ kind: "equation", existingOmml });
12622
+ });
12623
+ useDialogFlagRequest(dialogs.isChartDialogOpen, () => {
12624
+ dialogs.setIsChartDialogOpen(false);
12625
+ session.request({ kind: "chart" });
12626
+ });
12627
+ return {
12628
+ actions: session.actions(),
12629
+ session,
12630
+ requestImagePicker: () => void session.request({ kind: "image" }),
12631
+ requestMediaPicker: () => void session.request({ kind: "media" }),
12632
+ applyLayout: (path) => void session.applyLayout(path),
12633
+ resetSlide: () => void session.resetSlide(),
12634
+ loadLayoutPreviews: layoutSwitching.loadLayoutPreviews
12635
+ };
12636
+ }
12637
+ function createReactPort(latest) {
12638
+ const insert = () => latest.current.editorOps.insertHandlers;
12639
+ return {
12640
+ availabilityInput: () => latest.current.availabilityInput,
12641
+ fileLimits: () => latest.current.fileLimits,
12642
+ onRequest: (request) => latest.current.onRequest?.(request),
12643
+ onCancel: () => latest.current.state.setIsShortcutHelpOpen(false),
12644
+ target: () => ({
12645
+ deck: latest.current.handlerRef.current,
12646
+ slideId: latest.current.activeSlide?.id,
12647
+ slideIndex: latest.current.activeSlideIndex
12648
+ }),
12649
+ canvasSize: () => latest.current.state.canvasSize,
12650
+ selectedElement: () => latest.current.selectedElement,
12651
+ slideCount: () => latest.current.slides.length,
12652
+ activeSlide: () => latest.current.activeSlide,
12653
+ scopedLayouts: () => latest.current.scopedLayouts,
12654
+ addElement: (element) => insert().addElement(element),
12655
+ insertMediaFile: (file, sameTarget) => insert().insertMediaFile(file, sameTarget),
12656
+ applyHyperlink: (data) => insert().applyHyperlink(data),
12657
+ removeHyperlink: () => insert().removeHyperlink(),
12658
+ insertSmartArt: (layout, items) => insert().handleInsertSmartArt(layout, items),
12659
+ insertChart: (kind, options) => insert().handleAddChart(kind, options),
12660
+ insertEquation: (omml) => insert().handleInsertEquation(omml),
12661
+ updateEquation: (omml) => insert().handleUpdateEquation(omml),
12662
+ findReplace: () => findReplacePort(latest.current.editorOps.findReplace),
12663
+ applyLayout: (path) => latest.current.layoutSwitching.applyLayout(path)
12664
+ };
12665
+ }
12408
12666
  function CollaborationCursorOverlay({
12409
12667
  collaboration,
12410
12668
  activeSlideIndex,
@@ -12669,7 +12927,10 @@ function useViewerBuildingBlocksCore(input) {
12669
12927
  canvasSize,
12670
12928
  selectedElements: state.selectedElements,
12671
12929
  fitPadding: input.fitPadding,
12672
- maxFitScale: input.maxFitScale
12930
+ maxFitScale: input.maxFitScale,
12931
+ // Nothing to select in a read-only view, so a plain drag pans instead.
12932
+ dragPans: mode === "preview",
12933
+ activeSlideId: activeSlide?.id
12673
12934
  });
12674
12935
  const { options: viewerOptions, optionsStore } = useViewerOptions();
12675
12936
  const { setIsDirty } = state;
@@ -12807,6 +13068,8 @@ function useReadOnlyRecommendationState(content) {
12807
13068
  recommendation,
12808
13069
  setRecommendation,
12809
13070
  setModifyVerifier,
13071
+ /** The deck's raw `p:modifyVerifier`, for reporting protection state. */
13072
+ modifyVerifier,
12810
13073
  /** Whether the viewer's `canEdit` should be forced off. */
12811
13074
  locked: readOnlyLocked(recommendation, session),
12812
13075
  bannerVisible: readOnlyBannerVisible(recommendation, session),
@@ -12987,6 +13250,7 @@ function useViewerBuildingBlocksState(input) {
12987
13250
  handlerRef: actionSoundHandlerRef,
12988
13251
  listConversionScope
12989
13252
  });
13253
+ const canInsertElement = !readOnlyRec.locked && !viewerOptions.trust.openInProtectedView;
12990
13254
  const {
12991
13255
  exportHandlers,
12992
13256
  printHandlers,
@@ -12995,7 +13259,8 @@ function useViewerBuildingBlocksState(input) {
12995
13259
  handleEnterPresenterView,
12996
13260
  handleEnterRehearsalMode,
12997
13261
  autosaveStatus,
12998
- loadVersion
13262
+ loadVersion,
13263
+ handlerRef: integrationHandlerRef
12999
13264
  } = useViewerIntegration({
13000
13265
  state,
13001
13266
  zoom,
@@ -13019,7 +13284,7 @@ function useViewerBuildingBlocksState(input) {
13019
13284
  allowExternalImages: resolveAllowExternalContent(allowExternalContent, viewerOptions),
13020
13285
  setReadOnlyRecommendation: readOnlyRec.setRecommendation,
13021
13286
  setModifyVerifier: readOnlyRec.setModifyVerifier,
13022
- canInsertElement: !readOnlyRec.locked && !viewerOptions.trust.openInProtectedView,
13287
+ canInsertElement,
13023
13288
  setCompatToasts: compatToastsState.setToasts,
13024
13289
  canEdit,
13025
13290
  promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
@@ -13056,6 +13321,10 @@ function useViewerBuildingBlocksState(input) {
13056
13321
  });
13057
13322
  return {
13058
13323
  loadVersion,
13324
+ canInsertElement,
13325
+ readOnlyRecommendation: readOnlyRec.recommendation,
13326
+ hasModifyVerifier: readOnlyRec.modifyVerifier !== void 0,
13327
+ handlerRef: integrationHandlerRef,
13059
13328
  dialogs,
13060
13329
  editorOps,
13061
13330
  exportHandlers,
@@ -13156,6 +13425,10 @@ function useViewerBuildingBlocks(input) {
13156
13425
  const {
13157
13426
  dialogs,
13158
13427
  loadVersion,
13428
+ canInsertElement,
13429
+ readOnlyRecommendation: readOnlyRecommendation3,
13430
+ hasModifyVerifier,
13431
+ handlerRef,
13159
13432
  editorOps,
13160
13433
  exportHandlers,
13161
13434
  printHandlers,
@@ -13196,6 +13469,26 @@ function useViewerBuildingBlocks(input) {
13196
13469
  embedFonts: dialogs.embedFontsEnabled,
13197
13470
  onReadOnlyChange: setCollaborationReadOnly
13198
13471
  });
13472
+ const blockActions = useViewerBuildingBlocksActions({
13473
+ state,
13474
+ canEdit,
13475
+ canInsert: canInsertElement,
13476
+ mode,
13477
+ slides,
13478
+ activeSlide,
13479
+ activeSlideIndex,
13480
+ dialogs,
13481
+ editorOps,
13482
+ history,
13483
+ handlerRef,
13484
+ propertyHandlers,
13485
+ content,
13486
+ readOnlyRecommendation: readOnlyRecommendation3,
13487
+ hasModifyVerifier,
13488
+ presentation,
13489
+ onRequest: input.onRequest,
13490
+ fileLimits: input.fileLimits
13491
+ });
13199
13492
  const toolbarProps = buildToolbarProps({
13200
13493
  mode,
13201
13494
  canEdit,
@@ -13224,7 +13517,12 @@ function useViewerBuildingBlocks(input) {
13224
13517
  onOpenRecentFile,
13225
13518
  fileName,
13226
13519
  hiddenActions,
13227
- viewPreferencesSync
13520
+ viewPreferencesSync,
13521
+ onOpenImagePicker: blockActions.requestImagePicker,
13522
+ onOpenMediaPicker: blockActions.requestMediaPicker,
13523
+ onApplyLayout: blockActions.applyLayout,
13524
+ onResetSlide: blockActions.resetSlide,
13525
+ loadLayoutPreviews: blockActions.loadLayoutPreviews
13228
13526
  });
13229
13527
  const canvasProps = buildCanvasProps({
13230
13528
  mode,
@@ -13249,6 +13547,7 @@ function useViewerBuildingBlocks(input) {
13249
13547
  t
13250
13548
  });
13251
13549
  canvasProps.collaborationOverlay = overlay;
13550
+ canvasProps.onElementRenderError = input.onElementRenderError;
13252
13551
  const slidesPaneProps = useSlidesPaneProps({
13253
13552
  state,
13254
13553
  slides,
@@ -13260,6 +13559,7 @@ function useViewerBuildingBlocks(input) {
13260
13559
  recordedTimings: presentation.recordedTimings,
13261
13560
  onOpenLayoutGallery
13262
13561
  });
13562
+ slidesPaneProps.onElementRenderError = input.onElementRenderError;
13263
13563
  const shellState = useMemo(
13264
13564
  () => resolveCollaborationShellState({
13265
13565
  authorizedCanEdit: requestedCanEdit,
@@ -13285,12 +13585,15 @@ function useViewerBuildingBlocks(input) {
13285
13585
  toolbarProps,
13286
13586
  canvasProps,
13287
13587
  slidesPaneProps,
13288
- mode,
13588
+ // The effective mode: `preview` while the blocks may not edit, as in every binding.
13589
+ mode: resolveBuildingBlockMode(mode, canEdit),
13289
13590
  loading,
13290
13591
  error,
13291
13592
  autosaveStatus,
13292
13593
  collaboration,
13293
- shellState
13594
+ shellState,
13595
+ // Read last, so action groups registered by the hooks above are included.
13596
+ actions: blockActions.session.actions()
13294
13597
  };
13295
13598
  }
13296
13599
  function ColorChangedImage({
@@ -13600,6 +13903,61 @@ function withDisplayName(component, displayName) {
13600
13903
  component.displayName = displayName;
13601
13904
  return component;
13602
13905
  }
13906
+ var ElementRenderErrorReportingContext = createContext(
13907
+ void 0
13908
+ );
13909
+ var ElementErrorBoundaryState = class extends React18.Component {
13910
+ state = { element: this.props.element, failed: false };
13911
+ static getDerivedStateFromProps(props, state) {
13912
+ return props.element !== state.element ? { element: props.element, failed: false } : null;
13913
+ }
13914
+ static getDerivedStateFromError() {
13915
+ return { failed: true };
13916
+ }
13917
+ componentDidCatch(error) {
13918
+ const { element, slideId, onElementRenderError } = this.props;
13919
+ const context = {
13920
+ elementId: element.id,
13921
+ elementType: element.type,
13922
+ ...slideId === void 0 ? {} : { slideId }
13923
+ };
13924
+ if (onElementRenderError) {
13925
+ try {
13926
+ onElementRenderError(error, context);
13927
+ return;
13928
+ } catch {
13929
+ }
13930
+ }
13931
+ console.error(error, context);
13932
+ }
13933
+ render() {
13934
+ return this.state.failed ? null : this.props.children;
13935
+ }
13936
+ };
13937
+ function ElementErrorBoundary({
13938
+ element,
13939
+ slideId,
13940
+ onElementRenderError,
13941
+ children
13942
+ }) {
13943
+ const inherited = useContext(ElementRenderErrorReportingContext);
13944
+ const effectiveSlideId = slideId ?? inherited?.slideId;
13945
+ const reporter = onElementRenderError ?? inherited?.onElementRenderError;
13946
+ const scope = useMemo(
13947
+ () => ({ slideId: effectiveSlideId, onElementRenderError: reporter }),
13948
+ [effectiveSlideId, reporter]
13949
+ );
13950
+ return /* @__PURE__ */ jsx(ElementRenderErrorReportingContext.Provider, { value: scope, children: /* @__PURE__ */ jsx(
13951
+ ElementErrorBoundaryState,
13952
+ {
13953
+ element,
13954
+ slideId: effectiveSlideId,
13955
+ onElementRenderError: reporter,
13956
+ children
13957
+ },
13958
+ element.id
13959
+ ) });
13960
+ }
13603
13961
  var ChartFormatContext = /* @__PURE__ */ createContext(null);
13604
13962
  function useChartFormatContext() {
13605
13963
  return useContext(ChartFormatContext);
@@ -14421,7 +14779,7 @@ function ResizeHandles({
14421
14779
  ))
14422
14780
  ] });
14423
14781
  }
14424
- var ConnectorElementRendererMemo = /* @__PURE__ */ React17.memo(
14782
+ var ConnectorElementRendererMemo = /* @__PURE__ */ React18.memo(
14425
14783
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
14426
14784
  function ConnectorElementRendererInner({
14427
14785
  el,
@@ -14835,7 +15193,7 @@ function shapeParams(element) {
14835
15193
  const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
14836
15194
  return { hf: hasFill, fc: fillColor, sw: strokeWidth, sc: strokeColor };
14837
15195
  }
14838
- var Extrusion3DOverlayMemo = /* @__PURE__ */ React17.memo(
15196
+ var Extrusion3DOverlayMemo = /* @__PURE__ */ React18.memo(
14839
15197
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
14840
15198
  function Extrusion3DOverlayInner({ data }) {
14841
15199
  if (!data.hasExtrusion || data.panels.length === 0) {
@@ -15106,9 +15464,24 @@ function ShapeEffectOverlay({
15106
15464
  ) : null
15107
15465
  ] });
15108
15466
  }
15109
- var ElementRenderer = /* @__PURE__ */ React17.memo(
15467
+ var ElementRenderer = /* @__PURE__ */ React18.memo(
15110
15468
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
15111
- function ElementRendererInner({
15469
+ function ElementRendererInner(props) {
15470
+ return /* @__PURE__ */ jsx(
15471
+ ElementErrorBoundary,
15472
+ {
15473
+ element: props.element,
15474
+ slideId: props.activeSlide?.id,
15475
+ onElementRenderError: props.onElementRenderError,
15476
+ children: /* @__PURE__ */ jsx(ElementRendererImpl, { ...props })
15477
+ },
15478
+ props.element.id
15479
+ );
15480
+ }
15481
+ );
15482
+ var ElementRendererImpl = /* @__PURE__ */ React18.memo(
15483
+ // oxlint-disable-next-line prefer-arrow-callback -- keep the implementation named in React stacks
15484
+ function ElementRendererImpl2({
15112
15485
  element: el,
15113
15486
  activeSlide,
15114
15487
  isSelected,
@@ -16170,18 +16543,7 @@ function InlineTextEditor({
16170
16543
  list.seed?.paragraphs[0].token ?? "plain"
16171
16544
  );
16172
16545
  }
16173
- function FailedToLoad() {
16174
- return null;
16175
- }
16176
- var LazyModel3DScene = /* @__PURE__ */ React17.lazy(
16177
- async () => {
16178
- try {
16179
- return await import('./Model3DScene-NUJH2UKM.mjs');
16180
- } catch {
16181
- return { default: FailedToLoad };
16182
- }
16183
- }
16184
- );
16546
+ var LazyModel3DScene = /* @__PURE__ */ React18.lazy(() => import('./Model3DScene-NUJH2UKM.mjs'));
16185
16547
  function dataUrlToBlobUrl(dataUrl, mimeType) {
16186
16548
  return modelDataToBlobUrl(dataUrl, mimeType);
16187
16549
  }
@@ -16238,21 +16600,6 @@ function PosterFallback({
16238
16600
  }
16239
16601
  );
16240
16602
  }
16241
- var Model3DErrorBoundary = class extends React17.Component {
16242
- constructor(props) {
16243
- super(props);
16244
- this.state = { hasError: false };
16245
- }
16246
- static getDerivedStateFromError() {
16247
- return { hasError: true };
16248
- }
16249
- render() {
16250
- if (this.state.hasError) {
16251
- return this.props.fallback;
16252
- }
16253
- return this.props.children;
16254
- }
16255
- };
16256
16603
  function Model3DRenderer({ element, width, height, interactive }) {
16257
16604
  const [threeAvailable, setThreeAvailable] = useState(null);
16258
16605
  useEffect(() => {
@@ -16289,7 +16636,7 @@ function Model3DRenderer({ element, width, height, interactive }) {
16289
16636
  if (!threeAvailable || !blobUrl) {
16290
16637
  return posterFallback;
16291
16638
  }
16292
- return /* @__PURE__ */ jsx(Model3DErrorBoundary, { fallback: posterFallback, children: /* @__PURE__ */ jsx(Suspense, { fallback: posterFallback, children: /* @__PURE__ */ jsx(
16639
+ return /* @__PURE__ */ jsx(Suspense, { fallback: posterFallback, children: /* @__PURE__ */ jsx(
16293
16640
  LazyModel3DScene,
16294
16641
  {
16295
16642
  modelUrl: blobUrl,
@@ -16298,7 +16645,7 @@ function Model3DRenderer({ element, width, height, interactive }) {
16298
16645
  height,
16299
16646
  scene: element.scene
16300
16647
  }
16301
- ) }) });
16648
+ ) });
16302
16649
  }
16303
16650
  function buildEmbedInfo(el) {
16304
16651
  const canDownload = Boolean(el.oleEmbeddedData);
@@ -16440,10 +16787,10 @@ function SmartArtInlineNodeEditor({
16440
16787
  onCancel
16441
16788
  }) {
16442
16789
  const { t } = useTranslation();
16443
- const ref = React17.useRef(null);
16444
- const [value, setValue] = React17.useState(initialText);
16445
- const settled = React17.useRef(false);
16446
- React17.useEffect(() => {
16790
+ const ref = React18.useRef(null);
16791
+ const [value, setValue] = React18.useState(initialText);
16792
+ const settled = React18.useRef(false);
16793
+ React18.useEffect(() => {
16447
16794
  const el = ref.current;
16448
16795
  if (el) {
16449
16796
  el.focus();
@@ -16539,16 +16886,16 @@ function findNodeFromMouseEvent(e, host) {
16539
16886
  return (host ? smartArtNodeAtPoint(host, e.clientX, e.clientY) : null) ?? findNodeIdFromEvent(e.target);
16540
16887
  }
16541
16888
  function useSmartArtHoverState(containerRef, measureNodeRect = measureScreenNodeRect) {
16542
- const [hoveredNodeId, setHoveredNodeId] = React17.useState(null);
16543
- const [hoveredNodeRect, setHoveredNodeRect] = React17.useState(null);
16544
- const hideTimeoutRef = React17.useRef(null);
16545
- const cancelPendingHide = React17.useCallback(() => {
16889
+ const [hoveredNodeId, setHoveredNodeId] = React18.useState(null);
16890
+ const [hoveredNodeRect, setHoveredNodeRect] = React18.useState(null);
16891
+ const hideTimeoutRef = React18.useRef(null);
16892
+ const cancelPendingHide = React18.useCallback(() => {
16546
16893
  if (hideTimeoutRef.current !== null) {
16547
16894
  window.clearTimeout(hideTimeoutRef.current);
16548
16895
  hideTimeoutRef.current = null;
16549
16896
  }
16550
16897
  }, []);
16551
- const handleMouseMove = React17.useCallback(
16898
+ const handleMouseMove = React18.useCallback(
16552
16899
  (e, ignoreRef) => {
16553
16900
  const nodeEl = findNodeFromMouseEvent(e, containerRef.current);
16554
16901
  const container = containerRef.current;
@@ -16571,12 +16918,12 @@ function useSmartArtHoverState(containerRef, measureNodeRect = measureScreenNode
16571
16918
  },
16572
16919
  [containerRef, cancelPendingHide, measureNodeRect]
16573
16920
  );
16574
- const clearHover = React17.useCallback(() => {
16921
+ const clearHover = React18.useCallback(() => {
16575
16922
  cancelPendingHide();
16576
16923
  setHoveredNodeId(null);
16577
16924
  setHoveredNodeRect(null);
16578
16925
  }, [cancelPendingHide]);
16579
- React17.useEffect(() => cancelPendingHide, [cancelPendingHide]);
16926
+ React18.useEffect(() => cancelPendingHide, [cancelPendingHide]);
16580
16927
  return { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover };
16581
16928
  }
16582
16929
  var EDITOR_PADDING = 4;
@@ -16592,14 +16939,14 @@ function SmartArtEditableLayer({
16592
16939
  measureNodeRect = measureScreenNodeRect,
16593
16940
  children
16594
16941
  }) {
16595
- const containerRef = React17.useRef(null);
16596
- const styleBarRef = React17.useRef(null);
16597
- const [edit, setEdit] = React17.useState(null);
16942
+ const containerRef = React18.useRef(null);
16943
+ const styleBarRef = React18.useRef(null);
16944
+ const [edit, setEdit] = React18.useState(null);
16598
16945
  const { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover } = useSmartArtHoverState(
16599
16946
  containerRef,
16600
16947
  measureNodeRect
16601
16948
  );
16602
- const openEditor = React17.useCallback(
16949
+ const openEditor = React18.useCallback(
16603
16950
  (nodeEl) => {
16604
16951
  const container = containerRef.current;
16605
16952
  if (!nodeEl || !container) {
@@ -17229,7 +17576,7 @@ function sameDiagramReveal(prev, next) {
17229
17576
  }
17230
17577
  return true;
17231
17578
  }
17232
- var SmartArtRenderer = /* @__PURE__ */ React17.memo(SmartArtRendererImpl, arePropsEqual);
17579
+ var SmartArtRenderer = /* @__PURE__ */ React18.memo(SmartArtRendererImpl, arePropsEqual);
17233
17580
  function SmartArt3DView({
17234
17581
  element,
17235
17582
  className,
@@ -17378,7 +17725,7 @@ function EnvelopeGlyph({
17378
17725
  }
17379
17726
  return /* @__PURE__ */ jsx("g", { "data-glyph-slices": glyph.slices.length, children: glyph.slices.map((slice, si) => {
17380
17727
  const clipId = `${glyphKey}-s${si}`;
17381
- return /* @__PURE__ */ jsxs(React17.Fragment, { children: [
17728
+ return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
17382
17729
  /* @__PURE__ */ jsx("clipPath", { id: clipId, clipPathUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
17383
17730
  "rect",
17384
17731
  {
@@ -17585,7 +17932,7 @@ function renderEquationBox(el, interactive) {
17585
17932
  }
17586
17933
  );
17587
17934
  if (!segment.equationNumber) {
17588
- return [/* @__PURE__ */ jsx(React17.Fragment, { children: math }, `${el.id}-eq-${index}`)];
17935
+ return [/* @__PURE__ */ jsx(React18.Fragment, { children: math }, `${el.id}-eq-${index}`)];
17589
17936
  }
17590
17937
  const label = `(${segment.equationNumber})`;
17591
17938
  return [
@@ -18372,13 +18719,28 @@ function StaticElementRendererImpl({
18372
18719
  );
18373
18720
  }
18374
18721
  var StaticElementRenderer = /* @__PURE__ */ withDisplayName(
18375
- /* @__PURE__ */ React17.memo(StaticElementRendererImpl),
18722
+ /* @__PURE__ */ React18.memo(
18723
+ // oxlint-disable-next-line prefer-arrow-callback -- keep the wrapper named in React stacks
18724
+ function StaticElementRendererBoundary(props) {
18725
+ return /* @__PURE__ */ jsx(
18726
+ ElementErrorBoundary,
18727
+ {
18728
+ element: props.element,
18729
+ slideId: props.activeSlide?.id,
18730
+ onElementRenderError: props.onElementRenderError,
18731
+ children: /* @__PURE__ */ jsx(StaticElementRendererImpl, { ...props })
18732
+ },
18733
+ props.element.id
18734
+ );
18735
+ }
18736
+ ),
18376
18737
  "StaticElementRenderer"
18377
18738
  );
18378
18739
  function SlideLayer({
18379
18740
  slide,
18380
18741
  templateElements,
18381
- canvasSize
18742
+ canvasSize,
18743
+ onElementRenderError
18382
18744
  }) {
18383
18745
  const safeWidth = Math.max(canvasSize.width, 1);
18384
18746
  const safeHeight = Math.max(canvasSize.height, 1);
@@ -18403,7 +18765,8 @@ function SlideLayer({
18403
18765
  element,
18404
18766
  activeSlide: slide,
18405
18767
  allSlides: [slide],
18406
- zIndex: index
18768
+ zIndex: index,
18769
+ onElementRenderError
18407
18770
  },
18408
18771
  element.id
18409
18772
  ))
@@ -18418,7 +18781,8 @@ function FragmentedTransitionLayer({
18418
18781
  canvasSize,
18419
18782
  scale,
18420
18783
  zIndex,
18421
- layerName
18784
+ layerName,
18785
+ onElementRenderError
18422
18786
  }) {
18423
18787
  return /* @__PURE__ */ jsx(
18424
18788
  "div",
@@ -18454,7 +18818,15 @@ function FragmentedTransitionLayer({
18454
18818
  transformOrigin: "center",
18455
18819
  ...deviceStrokeStageStyle(scale)
18456
18820
  },
18457
- children: /* @__PURE__ */ jsx(SlideLayer, { slide, templateElements, canvasSize })
18821
+ children: /* @__PURE__ */ jsx(
18822
+ SlideLayer,
18823
+ {
18824
+ slide,
18825
+ templateElements,
18826
+ canvasSize,
18827
+ onElementRenderError
18828
+ }
18829
+ )
18458
18830
  }
18459
18831
  )
18460
18832
  },
@@ -18473,7 +18845,8 @@ function MorphTransitionOverlay({
18473
18845
  morphPlan,
18474
18846
  outgoingSlide,
18475
18847
  incomingSlide,
18476
- containerRef
18848
+ containerRef,
18849
+ onElementRenderError
18477
18850
  }) {
18478
18851
  const groupSlots = morphOverlayElementSlots(morphPlan).groups;
18479
18852
  return /* @__PURE__ */ jsxs(
@@ -18521,6 +18894,7 @@ function MorphTransitionOverlay({
18521
18894
  StaticElementRenderer,
18522
18895
  {
18523
18896
  element,
18897
+ onElementRenderError,
18524
18898
  activeSlide: outgoingSlide,
18525
18899
  allSlides: [outgoingSlide],
18526
18900
  zIndex,
@@ -18539,6 +18913,7 @@ function MorphTransitionOverlay({
18539
18913
  StaticElementRenderer,
18540
18914
  {
18541
18915
  element,
18916
+ onElementRenderError,
18542
18917
  activeSlide: incomingSlide,
18543
18918
  allSlides: [incomingSlide],
18544
18919
  zIndex,
@@ -18567,6 +18942,7 @@ function MorphTransitionOverlay({
18567
18942
  StaticElementRenderer,
18568
18943
  {
18569
18944
  element: group.outgoing,
18945
+ onElementRenderError,
18570
18946
  activeSlide: outgoingSlide,
18571
18947
  allSlides: [outgoingSlide],
18572
18948
  zIndex: 0,
@@ -18585,6 +18961,7 @@ function MorphTransitionOverlay({
18585
18961
  StaticElementRenderer,
18586
18962
  {
18587
18963
  element: group.incoming,
18964
+ onElementRenderError,
18588
18965
  activeSlide: incomingSlide,
18589
18966
  allSlides: [incomingSlide],
18590
18967
  zIndex: 0,
@@ -18604,7 +18981,13 @@ function MorphTransitionOverlay({
18604
18981
  }
18605
18982
  );
18606
18983
  }
18607
- function PresentationTransitionOverlay({
18984
+ function PresentationTransitionOverlay(props) {
18985
+ const inherited = React18.useContext(ElementRenderErrorReportingContext);
18986
+ const reporter = props.onElementRenderError ?? inherited?.onElementRenderError;
18987
+ const errorReporting = useMemo(() => ({ onElementRenderError: reporter }), [reporter]);
18988
+ return /* @__PURE__ */ jsx(ElementRenderErrorReportingContext.Provider, { value: errorReporting, children: /* @__PURE__ */ jsx(PresentationTransitionOverlayContent, { ...props }) });
18989
+ }
18990
+ function PresentationTransitionOverlayContent({
18608
18991
  outgoingSlide,
18609
18992
  templateElements,
18610
18993
  canvasSize,
@@ -18861,4 +19244,4 @@ function useResizablePanels() {
18861
19244
  };
18862
19245
  }
18863
19246
 
18864
- export { ACTION_VERB_MAP, ChartFormatContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, MIN_TOUCH_TARGET, MorphTransitionOverlay, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, Rendering3DFlagsContext, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, StaticElementRenderer, ViewerOptionsContext, ViewerOptionsStoreContext, computeToolbarVisibility, createReviewCommentsHost, detectTargetType, imgSrc, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartFormatContext, useChartPartSelection, useClearSelectionOnSlideChange, useClipboardHandlers, useCollaboration, useCollaborationDocumentSync, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useController, 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, useReadOnlyRecommendationState, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useReportOnChange, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewPreferencesSync, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport, withDisplayName };
19247
+ export { ChartFormatContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderErrorReportingContext, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, MIN_TOUCH_TARGET, MorphTransitionOverlay, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, Rendering3DFlagsContext, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, StaticElementRenderer, ViewerOptionsContext, ViewerOptionsStoreContext, computeToolbarVisibility, createReviewCommentsHost, imgSrc, isAudienceTab, parseAudienceNonce, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartFormatContext, useChartPartSelection, useClearSelectionOnSlideChange, useClipboardHandlers, useCollaboration, useCollaborationDocumentSync, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useController, 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, useReadOnlyRecommendationState, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useReportOnChange, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewPreferencesSync, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport, withDisplayName };