pptx-react-viewer 2.9.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/{AiChatPanel-6W6ZBAGU.mjs → AiChatPanel-EX2TBRJM.mjs} +4 -4
  3. package/dist/AiChatPanel-EX2TBRJM.mjs.br +0 -0
  4. package/dist/AiChatPanel-EX2TBRJM.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-MALC32TM.js → AiChatPanel-PJPSDMN4.js} +23 -23
  6. package/dist/AiChatPanel-PJPSDMN4.js.br +0 -0
  7. package/dist/AiChatPanel-PJPSDMN4.js.gz +0 -0
  8. package/dist/{Model3DScene-57HZ4NVD.mjs → Model3DScene-TTQFV7OS.mjs} +1 -1
  9. package/dist/Model3DScene-TTQFV7OS.mjs.br +0 -0
  10. package/dist/Model3DScene-TTQFV7OS.mjs.gz +0 -0
  11. package/dist/{Model3DScene-76R2YXSO.js → Model3DScene-UCBPTEAY.js} +2 -2
  12. package/dist/Model3DScene-UCBPTEAY.js.br +0 -0
  13. package/dist/Model3DScene-UCBPTEAY.js.gz +0 -0
  14. package/dist/{SurfaceChart3DScene-JGOQNHSU.mjs → SurfaceChart3DScene-5SZCRHZI.mjs} +1 -1
  15. package/dist/{SurfaceChart3DScene-JGOQNHSU.mjs.br → SurfaceChart3DScene-5SZCRHZI.mjs.br} +0 -0
  16. package/dist/SurfaceChart3DScene-5SZCRHZI.mjs.gz +0 -0
  17. package/dist/{SurfaceChart3DScene-2QZZTBV4.js → SurfaceChart3DScene-ADKCYYOQ.js} +2 -2
  18. package/dist/SurfaceChart3DScene-ADKCYYOQ.js.br +0 -0
  19. package/dist/SurfaceChart3DScene-ADKCYYOQ.js.gz +0 -0
  20. package/dist/{chunk-D6SHCB4V.js → chunk-4J7SPY64.js} +338 -324
  21. package/dist/chunk-4J7SPY64.js.br +0 -0
  22. package/dist/chunk-4J7SPY64.js.gz +0 -0
  23. package/dist/{chunk-CD434OFE.mjs → chunk-53NXKDMZ.mjs} +48 -0
  24. package/dist/chunk-53NXKDMZ.mjs.br +0 -0
  25. package/dist/chunk-53NXKDMZ.mjs.gz +0 -0
  26. package/dist/{chunk-L47Y62L6.mjs → chunk-C2UWTH42.mjs} +1168 -118
  27. package/dist/chunk-C2UWTH42.mjs.br +0 -0
  28. package/dist/chunk-C2UWTH42.mjs.gz +0 -0
  29. package/dist/{chunk-6UXRNLHD.js → chunk-E367QIKR.js} +2526 -1738
  30. package/dist/chunk-E367QIKR.js.br +0 -0
  31. package/dist/chunk-E367QIKR.js.gz +0 -0
  32. package/dist/{chunk-4FO4JMTN.mjs → chunk-HK2UERUX.mjs} +17 -3
  33. package/dist/chunk-HK2UERUX.mjs.br +0 -0
  34. package/dist/chunk-HK2UERUX.mjs.gz +0 -0
  35. package/dist/{chunk-IKISUZKE.js → chunk-HMQVOPQH.js} +1210 -118
  36. package/dist/chunk-HMQVOPQH.js.br +0 -0
  37. package/dist/chunk-HMQVOPQH.js.gz +0 -0
  38. package/dist/{chunk-NQLVK23T.mjs → chunk-L2CM5EUD.mjs} +885 -97
  39. package/dist/chunk-L2CM5EUD.mjs.br +0 -0
  40. package/dist/chunk-L2CM5EUD.mjs.gz +0 -0
  41. package/dist/{chunk-34BUZNKO.js → chunk-MM5RMRSP.js} +278 -291
  42. package/dist/chunk-MM5RMRSP.js.br +0 -0
  43. package/dist/chunk-MM5RMRSP.js.gz +0 -0
  44. package/dist/{chunk-2JDWFMIK.js → chunk-N6IHR6PS.js} +48 -0
  45. package/dist/chunk-N6IHR6PS.js.br +0 -0
  46. package/dist/chunk-N6IHR6PS.js.gz +0 -0
  47. package/dist/{chunk-JPTO6P5K.mjs → chunk-RJEY2KZH.mjs} +34 -48
  48. package/dist/chunk-RJEY2KZH.mjs.br +0 -0
  49. package/dist/chunk-RJEY2KZH.mjs.gz +0 -0
  50. package/dist/{chunk-6OLS3EJW.mjs → chunk-UZVRM6LD.mjs} +1 -1
  51. package/dist/chunk-UZVRM6LD.mjs.br +0 -0
  52. package/dist/chunk-UZVRM6LD.mjs.gz +0 -0
  53. package/dist/{chunk-YEM2VOAP.js → chunk-VNP627O5.js} +3 -3
  54. package/dist/chunk-VNP627O5.js.br +0 -0
  55. package/dist/chunk-VNP627O5.js.gz +0 -0
  56. package/dist/i18n.js +4 -4
  57. package/dist/i18n.js.br +0 -0
  58. package/dist/i18n.js.gz +0 -0
  59. package/dist/i18n.mjs +1 -1
  60. package/dist/i18n.mjs.br +0 -0
  61. package/dist/i18n.mjs.gz +0 -0
  62. package/dist/index.d.ts +26 -3
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +36 -36
  65. package/dist/index.js.br +0 -0
  66. package/dist/index.js.gz +0 -0
  67. package/dist/index.mjs +6 -6
  68. package/dist/index.mjs.br +0 -0
  69. package/dist/index.mjs.gz +0 -0
  70. package/dist/internals.d.ts +30 -2
  71. package/dist/internals.d.ts.map +1 -1
  72. package/dist/internals.js +79 -79
  73. package/dist/internals.js.br +0 -0
  74. package/dist/internals.js.gz +0 -0
  75. package/dist/internals.mjs +4 -4
  76. package/dist/internals.mjs.br +0 -0
  77. package/dist/internals.mjs.gz +0 -0
  78. package/dist/pptx-viewer.css +1 -1
  79. package/dist/pptx-viewer.css.br +0 -0
  80. package/dist/pptx-viewer.css.gz +0 -0
  81. package/dist/{useViewerBuildingBlocks-C59NY1qZ.d.ts → useViewerBuildingBlocks-Rqxm0pRS.d.ts} +19 -5
  82. package/dist/useViewerBuildingBlocks-Rqxm0pRS.d.ts.map +1 -0
  83. package/dist/viewer/index.js +22 -22
  84. package/dist/viewer/index.js.br +0 -0
  85. package/dist/viewer/index.js.gz +0 -0
  86. package/dist/viewer/index.mjs +6 -6
  87. package/dist/viewer/index.mjs.br +0 -0
  88. package/dist/viewer/index.mjs.gz +0 -0
  89. package/package.json +1 -1
  90. package/dist/AiChatPanel-6W6ZBAGU.mjs.br +0 -0
  91. package/dist/AiChatPanel-6W6ZBAGU.mjs.gz +0 -0
  92. package/dist/AiChatPanel-MALC32TM.js.br +0 -0
  93. package/dist/AiChatPanel-MALC32TM.js.gz +0 -0
  94. package/dist/Model3DScene-57HZ4NVD.mjs.br +0 -0
  95. package/dist/Model3DScene-57HZ4NVD.mjs.gz +0 -0
  96. package/dist/Model3DScene-76R2YXSO.js.br +0 -0
  97. package/dist/Model3DScene-76R2YXSO.js.gz +0 -0
  98. package/dist/SurfaceChart3DScene-2QZZTBV4.js.br +0 -0
  99. package/dist/SurfaceChart3DScene-2QZZTBV4.js.gz +0 -0
  100. package/dist/SurfaceChart3DScene-JGOQNHSU.mjs.gz +0 -0
  101. package/dist/chunk-2JDWFMIK.js.br +0 -0
  102. package/dist/chunk-2JDWFMIK.js.gz +0 -0
  103. package/dist/chunk-34BUZNKO.js.br +0 -0
  104. package/dist/chunk-34BUZNKO.js.gz +0 -0
  105. package/dist/chunk-4FO4JMTN.mjs.br +0 -0
  106. package/dist/chunk-4FO4JMTN.mjs.gz +0 -0
  107. package/dist/chunk-6OLS3EJW.mjs.br +0 -0
  108. package/dist/chunk-6OLS3EJW.mjs.gz +0 -0
  109. package/dist/chunk-6UXRNLHD.js.br +0 -0
  110. package/dist/chunk-6UXRNLHD.js.gz +0 -0
  111. package/dist/chunk-CD434OFE.mjs.br +0 -0
  112. package/dist/chunk-CD434OFE.mjs.gz +0 -0
  113. package/dist/chunk-D6SHCB4V.js.br +0 -0
  114. package/dist/chunk-D6SHCB4V.js.gz +0 -0
  115. package/dist/chunk-IKISUZKE.js.br +0 -0
  116. package/dist/chunk-IKISUZKE.js.gz +0 -0
  117. package/dist/chunk-JPTO6P5K.mjs.br +0 -0
  118. package/dist/chunk-JPTO6P5K.mjs.gz +0 -0
  119. package/dist/chunk-L47Y62L6.mjs.br +0 -0
  120. package/dist/chunk-L47Y62L6.mjs.gz +0 -0
  121. package/dist/chunk-NQLVK23T.mjs.br +0 -0
  122. package/dist/chunk-NQLVK23T.mjs.gz +0 -0
  123. package/dist/chunk-YEM2VOAP.js.br +0 -0
  124. package/dist/chunk-YEM2VOAP.js.gz +0 -0
  125. package/dist/useViewerBuildingBlocks-C59NY1qZ.d.ts.map +0 -1
@@ -1,9 +1,9 @@
1
- import { computeFocusTargets, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, toRenderableParts } from './chunk-6OLS3EJW.mjs';
2
- import { useReducedMotion, useViewerState, useViewerOptions, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useYjsDocumentSync, useCollaborationLivePatch, useFollowMode, useBroadcastFollower, scopeLayoutOptionsToActiveSlide, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, useCollaborativeState, useVirtualizedSlides, useSwipeNavigation, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, downloadBlob } from './chunk-4FO4JMTN.mjs';
3
- import { SHAPE_PRESETS, DEFAULT_STROKE_COLOR, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, MIN_ELEMENT_SIZE, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageRenderStyle, cn, ANIMATION_PRESET_OPTIONS, resolvePalette, resolveStyle, layoutToCategory, wrapChrome, DEFAULT_FILL_COLOR, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getCropShapeClipPath, SLIDE_NAV_THUMBNAIL_WIDTH, styleShadow, styleStroke, colour, fitFontSize, smartArtNodeGroupProps, chevronPoints, SmartArtNodeText, truncate, renderStepDownProcess, renderAlternatingFlow, renderDescendingProcess, renderPictureAccentList, renderVerticalBlockList, renderGroupedList, renderPyramidList, renderHorizontalPictureList, renderAccentProcess, renderVerticalChevronList, isImageTiled, getImageTilingStyle, getDuotoneColors, getTextWarpStyle, renderTextSegments, buildReactChartViewModel, renderChartElement, buildTextBody3DSceneStyle, TOOLBAR_SECTIONS, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, buildTree, treeWidth, treeDepth, nodeOpacity, gearPath, resolveSmartArtDataPalette, DEFAULT_TEXT_FONT_SIZE, DEFAULT_FONT_FAMILY, HYPERLINK_COLOR, GRID_SIZE, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, startPreviewAnimation, stopPreviewAnimation, THEME_COLOR_SWATCHES, STROKE_DASH_OPTIONS } from './chunk-JPTO6P5K.mjs';
4
- import { LOCALE_CATALOG, translationsEn } from './chunk-CD434OFE.mjs';
5
- import { hasShapeProperties, normalizeHexColor, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, svgLineCap, hasTextProperties, getElementTransform, ACTION_BUTTON_PRESETS, isEditableTextElement, isElementRendered, isElementActionable, getAriaRole, getAriaLabel, getAriaRoleDescription, getImageEffectsOpacity, getImageEffectsFilter, getElementTransformWithoutRotation, SWITCHABLE_LAYOUT_TYPES, DEFAULT_VIEWER_OPTIONS, EQUATION_TEMPLATES, convertLatexToOmml, convertOmmlToMathMl, sanitizeMathMl, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, viewerOptionsToPreferences, applyPreferenceToOptions, listAutosaveSnapshots, deleteAutosaveSnapshot, RULER_THICKNESS, RULER_FONT_SIZE, revealedSmartArtNodeCount, buildSmartArtA11y, buildCssGradientFromShapeStyle, resolveGroupChildFill, getGroupChildParentFill, getComputedEffectStyle, getSoftEdgeSvgFilter, buildStrokeOutline, svgGradientFillRef, isInkElement, getElementLabel, buildPreviewElements, deriveSlideFieldContext, SLIDE_TRANSITION_OPTIONS, themeToCssVars, DEFAULT_INSERT_CHART_TYPE, hasCopyableFormat, createBackstagePresentation, printPropertiesFrameSlides, printPropertiesSlidesPerPage, VIEWER_OPTIONS_TABS, DEFAULT_QUICK_ACCESS_COMMAND_IDS, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, resolveDrawingShapeNodeId, buildSummaryZoomView, getImageColorWashStyle, isImageLikeElement, getPendingSelectionRestore, restoreSegmentSelection, getTextCompensationTransform, applyChartBuildReveal, formatAxisValue, hasPressureVariation, getInkReplayStyles, INK_REPLAY_KEYFRAMES, resolveInkColor, resolveInkWidth, resolveInkOpacity, pressuresToWidths, getContentPartReplayStyles, resolveOleType, getOleTypeColor, getOleTypeLabel, filterRenderedElements, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getSlideBackgroundStyle, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, buildFieldSubstitutionContext, shouldConfirmExternalHyperlink, safeOpenUrl, isPpactionUrl, parsePpactionUrl, isPresentationAdvanceClick, buildContextMenuEntries, themeColorSchemesEqual, STATUS_BAR_CLASSES, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, clampPercent, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, activateModalFocus, buildCollaborationShareUrl, mobileElapsedSince, isFirstSlide, isLastSlide, formatMobileElapsed, mobileSlideCounter, presenterPaneAdvancesOnClick, formatElapsed, computeInlineEditorRect, findSmartArtNodeText, setSmartArtNodeStyle, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, updateSmartArtNodeText, getImageSvgFilters, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, findChartPartTarget, dragValueForPart, withChartPointValue, dragAnchorViewY, withChartTitle, computeSmartArtLayout, buildSmartArt3DModel, extractPathPoints, generatePressureCircles, isBrowserOpenableMime, formatBytes, getOleBadgeLabel, openUrlInNewTab, getSubstituteFontFamily, getWarpPath, extraQuickAccessCommands, TAB_ROW_ACTION_CLASSES, listBackstageRecentFiles, BACKSTAGE_NAV, INSERT_CHART_TYPES, SLIDE_VIRTUALIZATION_THRESHOLD, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, presentationInkPath, getShapeAdjustmentHandleDescriptor, formatSlideCounter, PRESET_THEMES, isUrlSafe, computeHandoutLayout, getPrintableArea, generateNoteLineCount, computeAllNotesPages, getNotesPrintableArea, QUICK_ACCESS_COMMAND_CATALOG, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, NOTES_FONT_SIZE_DEFAULT, formatTime, NOTES_FONT_SIZE_MIN, clampNotesFontSize, NOTES_FONT_SIZE_STEP, NOTES_FONT_SIZE_MAX, groupIntoParagraphs, substituteFieldText, BACKSTAGE_TEMPLATES, formatBackstageDate, formatBackstageSize, backstageCardsFor, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, ENTRANCE_PRESET_VALUES, EMPHASIS_PRESET_VALUES, EXIT_PRESET_VALUES, getConnectionSites, generateTicks, rulerDragToGuidePosition, getCommentMarkerPosition, buildThemeColorGrid, THEME_COLOR_SCHEME_KEYS, THEME_COLOR_LABELS, COMMON_FONTS, buildSmartArtPresetData, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, mergeSlideTransition, TABLE_STYLE_PRESETS, chartDataChangeType, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, getOleObjectTypeLabel, sanitizeGradientStops, pptxActionToElementAction, withFrameSlides, withSlidesPerPage, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, TRANSITION_VALID_DIRECTIONS, TRANSITION_ORIENTATION_TYPES, clampTransitionNumber, flattenTagCollections, formatCommentTimestamp, DIRECTIONAL_PRESETS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, addSmartArtNodeAsChild, removeSmartArtNode, clampCropValue, DUOTONE_PRESETS, ARTISTIC_EFFECTS, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, toSlideIndex, elementActionToPptxAction, canCommitActionType, TRANSITION_DIR_ARROWS, buildDirectionGrid, updateTagInCollections, deleteTagFromCollections, addTagToCollections, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, switchSmartArtLayout, addSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, SHAPE_QUICK_STYLES, quickStyleSwatchCss, getPatternSvg, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS, openNativeEyeDropper, toggleText3dExtrusion, BEVEL_PRESETS } from './chunk-L47Y62L6.mjs';
6
- import React33, { createContext, useMemo, useState, useCallback, lazy, forwardRef, useEffect, useRef, useContext, Suspense, useLayoutEffect, Fragment as Fragment$1, useDeferredValue } from 'react';
1
+ import { computeFocusTargets, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, toRenderableParts } from './chunk-UZVRM6LD.mjs';
2
+ import { useReducedMotion, useViewerState, useViewerOptions, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useYjsDocumentSync, useCollaborationLivePatch, useFollowMode, useBroadcastFollower, scopeLayoutOptionsToActiveSlide, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, useCollaborativeState, useVirtualizedSlides, useSwipeNavigation, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, downloadBlob } from './chunk-HK2UERUX.mjs';
3
+ import { SHAPE_PRESETS, DEFAULT_STROKE_COLOR, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, MIN_ELEMENT_SIZE, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageRenderStyle, cn, ANIMATION_PRESET_OPTIONS, resolvePalette, resolveStyle, layoutToCategory, wrapChrome, DEFAULT_FILL_COLOR, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getCropShapeClipPath, SLIDE_NAV_THUMBNAIL_WIDTH, styleShadow, styleStroke, colour, fitFontSize, smartArtNodeGroupProps, chevronPoints, SmartArtNodeText, truncate, renderStepDownProcess, renderAlternatingFlow, renderDescendingProcess, renderPictureAccentList, renderVerticalBlockList, renderGroupedList, renderPyramidList, renderHorizontalPictureList, renderAccentProcess, renderVerticalChevronList, isImageTiled, getImageTilingStyle, getDuotoneColors, getTextWarpStyle, renderTextSegments, buildReactChartViewModel, renderChartElement, buildTextBody3DSceneStyle, TOOLBAR_SECTIONS, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, buildTree, treeWidth, treeDepth, nodeOpacity, gearPath, resolveSmartArtDataPalette, DEFAULT_TEXT_FONT_SIZE, DEFAULT_FONT_FAMILY, HYPERLINK_COLOR, GRID_SIZE, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation, THEME_COLOR_SWATCHES, STROKE_DASH_OPTIONS } from './chunk-RJEY2KZH.mjs';
4
+ import { LOCALE_CATALOG, translationsEn } from './chunk-53NXKDMZ.mjs';
5
+ import { hasShapeProperties, normalizeHexColor, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, svgLineCap, hasTextProperties, getElementTransform, ACTION_BUTTON_PRESETS, isEditableTextElement, isElementRendered, isElementActionable, getAriaRole, getAriaLabel, getAriaRoleDescription, getImageEffectsOpacity, getImageEffectsFilter, getElementTransformWithoutRotation, SWITCHABLE_LAYOUT_TYPES, DEFAULT_VIEWER_OPTIONS, compileEquationTemplateMathMl, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, viewerOptionsToPreferences, applyPreferenceToOptions, listAutosaveSnapshots, deleteAutosaveSnapshot, RULER_THICKNESS, RULER_FONT_SIZE, revealedSmartArtNodeCount, buildSmartArtA11y, buildCssGradientFromShapeStyle, resolveGroupChildFill, getGroupChildParentFill, getComputedEffectStyle, getSoftEdgeSvgFilter, buildStrokeOutline, svgGradientFillRef, isInkElement, getElementLabel, buildPreviewElements, deriveSlideFieldContext, SLIDE_TRANSITION_OPTIONS, themeToCssVars, applyMotionPathPreset, DEFAULT_INSERT_CHART_TYPE, hasCopyableFormat, createBackstagePresentation, printPropertiesFrameSlides, printPropertiesSlidesPerPage, VIEWER_OPTIONS_TABS, DEFAULT_QUICK_ACCESS_COMMAND_IDS, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, resolveDrawingShapeNodeId, buildSummaryZoomView, getImageColorWashStyle, isImageLikeElement, getPendingSelectionRestore, restoreSegmentSelection, getTextCompensationTransform, applyChartBuildReveal, formatAxisValue, hasPressureVariation, getInkReplayStyles, INK_REPLAY_KEYFRAMES, resolveInkColor, resolveInkWidth, resolveInkOpacity, pressuresToWidths, getContentPartReplayStyles, resolveOleType, getOleTypeColor, getOleTypeLabel, filterRenderedElements, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getSlideBackgroundStyle, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, buildFieldSubstitutionContext, shouldConfirmExternalHyperlink, safeOpenUrl, isPpactionUrl, parsePpactionUrl, isPresentationAdvanceClick, buildContextMenuEntries, themeColorSchemesEqual, STATUS_BAR_CLASSES, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, compileLatexEquation, convertLatexToOmml, EQUATION_TEMPLATES, clampPercent, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, activateModalFocus, buildCollaborationShareUrl, canGoPrevious, formatSlideCounter, READING_VIEW_COUNTER_ATTR, canGoNext, READING_VIEW_ATTR, OUTLINE_LEVEL_ATTR, OUTLINE_SLIDE_ATTR, OUTLINE_ROW_ATTR, OUTLINE_VIEW_ATTR, mobileElapsedSince, isFirstSlide, isLastSlide, formatMobileElapsed, mobileSlideCounter, presenterPaneAdvancesOnClick, formatElapsed, computeInlineEditorRect, findSmartArtNodeText, setSmartArtNodeStyle, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, updateSmartArtNodeText, getImageSvgFilters, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, findChartPartTarget, dragValueForPart, withChartPointValue, dragAnchorViewY, withChartTitle, computeSmartArtLayout, buildSmartArt3DModel, extractPathPoints, generatePressureCircles, isBrowserOpenableMime, formatBytes, getOleBadgeLabel, openUrlInNewTab, getSubstituteFontFamily, getWarpPath, extraQuickAccessCommands, TAB_ROW_ACTION_CLASSES, listBackstageRecentFiles, BACKSTAGE_NAV, INSERT_CHART_TYPES, DEFAULT_MOTION_PATH_PRESET_ID, SLIDE_VIRTUALIZATION_THRESHOLD, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, presentationInkPath, motionPathFor, setMotionPath, getShapeAdjustmentHandleDescriptor, PRESET_THEMES, isUrlSafe, sanitizeMathMl, computeHandoutLayout, getPrintableArea, generateNoteLineCount, computeAllNotesPages, getNotesPrintableArea, QUICK_ACCESS_COMMAND_CATALOG, openReadingView, applyReadingViewCommand, createPresentationKeyBuffer, readingViewFitScale, READING_VIEW_STAGE_ATTR, buildOutline, applyOutlineEdit, mapOutlineKey, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, NOTES_FONT_SIZE_DEFAULT, formatTime, NOTES_FONT_SIZE_MIN, clampNotesFontSize, NOTES_FONT_SIZE_STEP, NOTES_FONT_SIZE_MAX, groupIntoParagraphs, substituteFieldText, BACKSTAGE_TEMPLATES, formatBackstageDate, formatBackstageSize, backstageCardsFor, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, ENTRANCE_PRESET_VALUES, EMPHASIS_PRESET_VALUES, EXIT_PRESET_VALUES, MOTION_PATH_FAMILIES, motionPathFamilyLabelKey, motionPathPresetsByFamily, motionPathPresetLabelKey, getConnectionSites, generateTicks, rulerDragToGuidePosition, getCommentMarkerPosition, motionPathToSvgD, motionPathEndPixel, isEditableMotionPath, setMotionPathEnd, buildThemeColorGrid, THEME_COLOR_SCHEME_KEYS, THEME_COLOR_LABELS, COMMON_FONTS, buildSmartArtPresetData, handleReadingViewKey, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, mergeSlideTransition, buildTableDataGrid, appendTableElementRow, removeLastTableElementRow, appendTableElementColumn, removeLastTableElementColumn, removeTableElementColumn, removeTableElementRow, setTableElementCellText, TABLE_STYLE_PRESETS, chartDataChangeType, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, getOleObjectTypeLabel, sanitizeGradientStops, pptxActionToElementAction, withFrameSlides, withSlidesPerPage, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, TRANSITION_VALID_DIRECTIONS, TRANSITION_ORIENTATION_TYPES, clampTransitionNumber, flattenTagCollections, formatCommentTimestamp, clearMotionPath, DIRECTIONAL_PRESETS, motionPathPresetIdForPath, computeMergeCellRight, computeMergeCellDown, computeSplitCell, addSmartArtNodeAsChild, removeSmartArtNode, clampCropValue, DUOTONE_PRESETS, ARTISTIC_EFFECTS, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, toSlideIndex, elementActionToPptxAction, canCommitActionType, TRANSITION_DIR_ARROWS, buildDirectionGrid, updateTagInCollections, deleteTagFromCollections, addTagToCollections, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, switchSmartArtLayout, addSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, SHAPE_QUICK_STYLES, quickStyleSwatchCss, getPatternSvg, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS, openNativeEyeDropper, toggleText3dExtrusion, BEVEL_PRESETS } from './chunk-C2UWTH42.mjs';
6
+ import React34, { createContext, useMemo, useState, useCallback, lazy, forwardRef, useEffect, useRef, useContext, Suspense, useLayoutEffect, Fragment as Fragment$1, useDeferredValue } from 'react';
7
7
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { LuRotateCw, LuMessageSquare, LuEyeOff, LuSettings, LuX, LuCalendarDays, LuHash, LuText, LuCast, LuSave, LuUndo, LuRedo, LuSearch, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuLayers, LuSettings2, LuClock, LuDownload, LuTrash2, LuCheck, LuLock, LuEye, LuFileText, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuBug, LuChevronUp, LuChevronDown, LuWifi, LuWifiOff, LuUsers, LuCopy, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuZoomOut, LuZoomIn, LuSpellCheck, LuFileDown, LuMenu, LuSparkles, LuShare2, LuPanelLeft, LuPanelRight, LuArrowLeft, LuFolderOpen, LuClipboardPaste, LuScissors, LuPaintbrush, LuSquare, LuImage, LuVideo, LuDatabase, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuHighlighter, LuList, LuListOrdered, LuIndentDecrease, LuIndentIncrease, LuReplace, LuMousePointer2, LuShapes, LuPaintBucket, LuPenLine, LuPalette, LuPencil, LuStar, LuMoveRight, LuMousePointerClick, LuClock3, LuMonitorPlay, LuListVideo, LuCaptions, LuCamera, LuEraser, LuRotateCcw, LuCircleHelp, LuBookOpen, LuLanguages, LuGlobe, LuGitCompare, LuMessageSquarePlus, LuLockKeyhole, LuPanelTop, LuLayoutGrid, LuGrid3X3, LuPipette, LuRuler, LuMaximize2, LuCode, LuCaseSensitive, LuTimer, LuGripVertical, LuLoaderCircle, LuUpload, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuLink, LuGrid2X2, LuCopyPlus, LuCirclePlay, LuCirclePause, LuScan, LuMonitorOff, LuClipboardCopy, LuWand, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuFilePlus2, LuHouse, LuPackage, LuBox, LuFileImage, LuUser, LuHardDrive, LuLogIn, LuFolderPlus, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignJustify, LuColumns3, LuSpline, LuAlignHorizontalSpaceAround, LuAlignVerticalSpaceAround, LuGroup, LuUngroup, LuMove, LuRadio, LuLockOpen, LuArrowDown, LuArrowUp, LuArrowRight, LuReply, LuBookmark } from 'react-icons/lu';
@@ -523,6 +523,40 @@ function AnimationPresetGallery({
523
523
  }
524
524
  );
525
525
  }
526
+ function MotionPathGallery({
527
+ disabled,
528
+ onApplyMotionPath
529
+ }) {
530
+ const { t } = useTranslation();
531
+ return /* @__PURE__ */ jsx(
532
+ "div",
533
+ {
534
+ className: "flex max-h-[62px] items-start gap-2 overflow-y-auto rounded-sm border border-border/60 bg-muted/30 px-1.5 py-1",
535
+ "aria-label": t("pptx.animations.motionPathGalleryAria"),
536
+ children: MOTION_PATH_FAMILIES.map((family) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
537
+ /* @__PURE__ */ jsx("span", { className: "text-[9px] font-semibold leading-3 text-muted-foreground", children: t(motionPathFamilyLabelKey(family)) }),
538
+ /* @__PURE__ */ jsx("div", { className: "flex max-w-[150px] flex-wrap gap-0.5", children: motionPathPresetsByFamily(family).map((preset) => {
539
+ const label = t(motionPathPresetLabelKey(preset.id));
540
+ return /* @__PURE__ */ jsxs(
541
+ "button",
542
+ {
543
+ type: "button",
544
+ disabled,
545
+ onClick: () => onApplyMotionPath?.(preset.id),
546
+ title: label,
547
+ className: "inline-flex items-center gap-0.5 rounded-sm px-1 py-0.5 text-[9px] leading-3 text-foreground transition-colors hover:bg-accent disabled:opacity-35",
548
+ children: [
549
+ /* @__PURE__ */ jsx(LuMoveRight, { className: "h-2.5 w-2.5 text-sky-500", "aria-hidden": "true" }),
550
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: label })
551
+ ]
552
+ },
553
+ preset.id
554
+ );
555
+ }) })
556
+ ] }, family))
557
+ }
558
+ );
559
+ }
526
560
  function RibbonGroup({
527
561
  label,
528
562
  children,
@@ -648,6 +682,13 @@ function AnimationsSection(p) {
648
682
  children: /* @__PURE__ */ jsx(AnimationPresetGallery, { disabled, onAddAnimation: p.onAddAnimation })
649
683
  }
650
684
  ),
685
+ /* @__PURE__ */ jsx(RibbonGroup, { label: t("pptx.animation.motionPath"), className: "max-w-[420px] overflow-hidden", children: /* @__PURE__ */ jsx(
686
+ MotionPathGallery,
687
+ {
688
+ disabled,
689
+ onApplyMotionPath: (presetId) => p.onAddAnimation?.(presetId, "motionPath")
690
+ }
691
+ ) }),
651
692
  /* @__PURE__ */ jsxs(RibbonGroup, { label: t("pptx.animations.advanced", { defaultValue: "Advanced Animation" }), children: [
652
693
  /* @__PURE__ */ jsx(
653
694
  RibbonCommand,
@@ -663,7 +704,7 @@ function AnimationsSection(p) {
663
704
  {
664
705
  label: t("pptx.animations.pathAnimation", { defaultValue: "Path Animation" }),
665
706
  icon: /* @__PURE__ */ jsx(LuMoveRight, {}),
666
- onClick: () => p.onAddAnimation?.("flyIn", "entrance"),
707
+ onClick: () => p.onAddAnimation?.(DEFAULT_MOTION_PATH_PRESET_ID, "motionPath"),
667
708
  disabled
668
709
  }
669
710
  ),
@@ -1203,11 +1244,11 @@ var TRANSITION_PRESETS = [
1203
1244
  ];
1204
1245
  function TransitionsSection(p) {
1205
1246
  const { t } = useTranslation();
1206
- const [selected, setSelected] = React33.useState("none");
1207
- const [duration, setDuration] = React33.useState("00.50");
1208
- const [advanceOnClick, setAdvanceOnClick] = React33.useState(true);
1209
- const [advanceAfter, setAdvanceAfter] = React33.useState(false);
1210
- const [advanceAfterSeconds, setAdvanceAfterSeconds] = React33.useState("00:00.00");
1247
+ const [selected, setSelected] = React34.useState("none");
1248
+ const [duration, setDuration] = React34.useState("00.50");
1249
+ const [advanceOnClick, setAdvanceOnClick] = React34.useState(true);
1250
+ const [advanceAfter, setAdvanceAfter] = React34.useState(false);
1251
+ const [advanceAfterSeconds, setAdvanceAfterSeconds] = React34.useState("00:00.00");
1211
1252
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1212
1253
  /* @__PURE__ */ jsxs("button", { type: "button", className: pill, title: t("pptx.ribbon.previewTransition"), children: [
1213
1254
  /* @__PURE__ */ jsx(LuPlay, { className: ics }),
@@ -1409,7 +1450,7 @@ function AccountPage() {
1409
1450
  return void 0;
1410
1451
  });
1411
1452
  };
1412
- const version = "2.8.0" ;
1453
+ const version = "2.10.0" ;
1413
1454
  return /* @__PURE__ */ jsxs("div", { className: "mt-8 max-w-[700px] space-y-6", children: [
1414
1455
  /* @__PURE__ */ jsxs("section", { className: cardClass, children: [
1415
1456
  /* @__PURE__ */ jsxs("h2", { className: "flex items-center gap-2 text-sm font-semibold", children: [
@@ -3891,12 +3932,21 @@ function ViewSection(p) {
3891
3932
  title: t("pptx.view.slideSorterTooltip")
3892
3933
  }
3893
3934
  ),
3935
+ /* @__PURE__ */ jsx(
3936
+ RibbonCommand,
3937
+ {
3938
+ label: t("pptx.view.outlineView"),
3939
+ icon: /* @__PURE__ */ jsx(LuIndentIncrease, {}),
3940
+ onClick: p.onOpenOutlineView,
3941
+ title: t("pptx.view.outlineViewTooltip")
3942
+ }
3943
+ ),
3894
3944
  /* @__PURE__ */ jsx(
3895
3945
  RibbonCommand,
3896
3946
  {
3897
3947
  label: t("pptx.view.readingView"),
3898
3948
  icon: /* @__PURE__ */ jsx(LuBookOpen, {}),
3899
- disabled: true,
3949
+ onClick: p.onOpenReadingView,
3900
3950
  title: t("pptx.view.readingView")
3901
3951
  }
3902
3952
  )
@@ -4371,7 +4421,9 @@ function MobileSectionBody({
4371
4421
  isSelectionPaneOpen: p.isSelectionPaneOpen,
4372
4422
  onToggleSelectionPane: p.onToggleSelectionPane,
4373
4423
  eyedropperActive: p.eyedropperActive,
4374
- onToggleEyedropper: p.onToggleEyedropper
4424
+ onToggleEyedropper: p.onToggleEyedropper,
4425
+ onToggleSlideSorter: p.onToggleSlideSorter,
4426
+ onOpenReadingView: p.onOpenReadingView
4375
4427
  }
4376
4428
  ) });
4377
4429
  case "file":
@@ -5623,6 +5675,9 @@ function Toolbar(p) {
5623
5675
  onToggleSelectionPane: p.onToggleSelectionPane,
5624
5676
  eyedropperActive: p.eyedropperActive,
5625
5677
  onToggleEyedropper: p.onToggleEyedropper,
5678
+ onToggleSlideSorter: p.onToggleSlideSorter,
5679
+ onOpenReadingView: p.onOpenReadingView,
5680
+ onOpenOutlineView: p.onOpenOutlineView,
5626
5681
  onZoomToFit: p.onZoomToFit
5627
5682
  }
5628
5683
  ),
@@ -5926,6 +5981,127 @@ function GridOverlay({ canvasSize, gridSpacingPx = GRID_SIZE, visible }) {
5926
5981
  }
5927
5982
  );
5928
5983
  }
5984
+ function MotionPathOverlay({
5985
+ element,
5986
+ path,
5987
+ canvasSize,
5988
+ scale,
5989
+ canEdit,
5990
+ onChangePath
5991
+ }) {
5992
+ const { t } = useTranslation();
5993
+ const dragRef = useRef(null);
5994
+ const frame = {
5995
+ originX: element.x + element.width / 2,
5996
+ originY: element.y + element.height / 2,
5997
+ slideWidth: canvasSize.width,
5998
+ slideHeight: canvasSize.height
5999
+ };
6000
+ const d = motionPathToSvgD(path, frame);
6001
+ const end = motionPathEndPixel(path, frame);
6002
+ const editable = canEdit && Boolean(onChangePath) && isEditableMotionPath(path);
6003
+ const handlePointerDown = useCallback(
6004
+ (event) => {
6005
+ if (!editable) {
6006
+ return;
6007
+ }
6008
+ event.stopPropagation();
6009
+ event.preventDefault();
6010
+ event.currentTarget.setPointerCapture(event.pointerId);
6011
+ dragRef.current = {
6012
+ pointerId: event.pointerId,
6013
+ startX: event.clientX,
6014
+ startY: event.clientY
6015
+ };
6016
+ },
6017
+ [editable]
6018
+ );
6019
+ const handlePointerMove = useCallback(
6020
+ (event) => {
6021
+ const drag = dragRef.current;
6022
+ if (!drag || drag.pointerId !== event.pointerId || !onChangePath) {
6023
+ return;
6024
+ }
6025
+ event.stopPropagation();
6026
+ const dxPx = (event.clientX - drag.startX) / (scale || 1);
6027
+ const dyPx = (event.clientY - drag.startY) / (scale || 1);
6028
+ const nextX = (end.x + dxPx - frame.originX) / frame.slideWidth;
6029
+ const nextY = (end.y + dyPx - frame.originY) / frame.slideHeight;
6030
+ const next = setMotionPathEnd(path, nextX, nextY);
6031
+ if (next !== path) {
6032
+ dragRef.current = {
6033
+ pointerId: event.pointerId,
6034
+ startX: event.clientX,
6035
+ startY: event.clientY
6036
+ };
6037
+ onChangePath(next);
6038
+ }
6039
+ },
6040
+ [
6041
+ end.x,
6042
+ end.y,
6043
+ frame.originX,
6044
+ frame.originY,
6045
+ frame.slideWidth,
6046
+ frame.slideHeight,
6047
+ onChangePath,
6048
+ path,
6049
+ scale
6050
+ ]
6051
+ );
6052
+ const handlePointerUp = useCallback((event) => {
6053
+ if (dragRef.current?.pointerId === event.pointerId) {
6054
+ event.currentTarget.releasePointerCapture(event.pointerId);
6055
+ dragRef.current = null;
6056
+ }
6057
+ }, []);
6058
+ if (!d) {
6059
+ return null;
6060
+ }
6061
+ return /* @__PURE__ */ jsxs(
6062
+ "svg",
6063
+ {
6064
+ className: "pointer-events-none absolute left-0 top-0 z-[45]",
6065
+ width: canvasSize.width,
6066
+ height: canvasSize.height,
6067
+ role: "img",
6068
+ "aria-label": t("pptx.animation.motionPath.overlay"),
6069
+ "data-pptx-motion-path-overlay": "true",
6070
+ children: [
6071
+ /* @__PURE__ */ jsx(
6072
+ "path",
6073
+ {
6074
+ d,
6075
+ fill: "none",
6076
+ stroke: "#0ea5e9",
6077
+ strokeWidth: 2,
6078
+ strokeDasharray: "6 4",
6079
+ vectorEffect: "non-scaling-stroke"
6080
+ }
6081
+ ),
6082
+ /* @__PURE__ */ jsx("circle", { cx: frame.originX, cy: frame.originY, r: 5, fill: "#0ea5e9", opacity: 0.55 }),
6083
+ /* @__PURE__ */ jsx(
6084
+ "circle",
6085
+ {
6086
+ cx: end.x,
6087
+ cy: end.y,
6088
+ r: 7,
6089
+ fill: "#ffffff",
6090
+ stroke: "#0ea5e9",
6091
+ strokeWidth: 2,
6092
+ className: editable ? "pointer-events-auto cursor-move" : "",
6093
+ "aria-label": t("pptx.animation.motionPath.endHandle"),
6094
+ "data-pptx-motion-path-handle": "end",
6095
+ onPointerDown: handlePointerDown,
6096
+ onPointerMove: handlePointerMove,
6097
+ onPointerUp: handlePointerUp,
6098
+ onPointerCancel: handlePointerUp
6099
+ }
6100
+ )
6101
+ ]
6102
+ }
6103
+ );
6104
+ }
5929
6105
  function HorizontalRulerView({ ticks, widthPx, highlight }) {
5930
6106
  return /* @__PURE__ */ jsxs(
5931
6107
  "svg",
@@ -5989,7 +6165,7 @@ function HorizontalRulerView({ ticks, widthPx, highlight }) {
5989
6165
  }
5990
6166
  );
5991
6167
  }
5992
- var HorizontalRuler = React33.memo(HorizontalRulerView);
6168
+ var HorizontalRuler = React34.memo(HorizontalRulerView);
5993
6169
  HorizontalRuler.displayName = "HorizontalRuler";
5994
6170
  function VerticalRulerView({ ticks, heightPx, highlight }) {
5995
6171
  return /* @__PURE__ */ jsxs(
@@ -6061,7 +6237,7 @@ function VerticalRulerView({ ticks, heightPx, highlight }) {
6061
6237
  }
6062
6238
  );
6063
6239
  }
6064
- var VerticalRuler = React33.memo(VerticalRulerView);
6240
+ var VerticalRuler = React34.memo(VerticalRulerView);
6065
6241
  VerticalRuler.displayName = "VerticalRuler";
6066
6242
  function Ruler({
6067
6243
  canvasSize,
@@ -7013,7 +7189,7 @@ function ResizeHandles({
7013
7189
  ) : null
7014
7190
  ] });
7015
7191
  }
7016
- var ConnectorElementRenderer = React33.memo(
7192
+ var ConnectorElementRenderer = React34.memo(
7017
7193
  ({
7018
7194
  el,
7019
7195
  isSelected,
@@ -8519,10 +8695,10 @@ function InlineTextEditor({
8519
8695
  function FailedToLoad() {
8520
8696
  return null;
8521
8697
  }
8522
- var LazyModel3DScene = React33.lazy(
8698
+ var LazyModel3DScene = React34.lazy(
8523
8699
  async () => {
8524
8700
  try {
8525
- return await import('./Model3DScene-57HZ4NVD.mjs');
8701
+ return await import('./Model3DScene-TTQFV7OS.mjs');
8526
8702
  } catch {
8527
8703
  return { default: FailedToLoad };
8528
8704
  }
@@ -8605,7 +8781,7 @@ function PosterFallback({
8605
8781
  }
8606
8782
  );
8607
8783
  }
8608
- var Model3DErrorBoundary = class extends React33.Component {
8784
+ var Model3DErrorBoundary = class extends React34.Component {
8609
8785
  constructor(props) {
8610
8786
  super(props);
8611
8787
  this.state = { hasError: false };
@@ -8796,10 +8972,10 @@ function SmartArtInlineNodeEditor({
8796
8972
  onCancel
8797
8973
  }) {
8798
8974
  const { t } = useTranslation();
8799
- const ref = React33.useRef(null);
8800
- const [value, setValue] = React33.useState(initialText);
8801
- const settled = React33.useRef(false);
8802
- React33.useEffect(() => {
8975
+ const ref = React34.useRef(null);
8976
+ const [value, setValue] = React34.useState(initialText);
8977
+ const settled = React34.useRef(false);
8978
+ React34.useEffect(() => {
8803
8979
  const el = ref.current;
8804
8980
  if (el) {
8805
8981
  el.focus();
@@ -8891,16 +9067,16 @@ function findNodeIdFromEvent(target) {
8891
9067
  return null;
8892
9068
  }
8893
9069
  function useSmartArtHoverState(containerRef) {
8894
- const [hoveredNodeId, setHoveredNodeId] = React33.useState(null);
8895
- const [hoveredNodeRect, setHoveredNodeRect] = React33.useState(null);
8896
- const hideTimeoutRef = React33.useRef(null);
8897
- const cancelPendingHide = React33.useCallback(() => {
9070
+ const [hoveredNodeId, setHoveredNodeId] = React34.useState(null);
9071
+ const [hoveredNodeRect, setHoveredNodeRect] = React34.useState(null);
9072
+ const hideTimeoutRef = React34.useRef(null);
9073
+ const cancelPendingHide = React34.useCallback(() => {
8898
9074
  if (hideTimeoutRef.current !== null) {
8899
9075
  window.clearTimeout(hideTimeoutRef.current);
8900
9076
  hideTimeoutRef.current = null;
8901
9077
  }
8902
9078
  }, []);
8903
- const handleMouseMove = React33.useCallback(
9079
+ const handleMouseMove = React34.useCallback(
8904
9080
  (e, ignoreRef) => {
8905
9081
  const nodeEl = findNodeIdFromEvent(e.target);
8906
9082
  const container = containerRef.current;
@@ -8928,12 +9104,12 @@ function useSmartArtHoverState(containerRef) {
8928
9104
  },
8929
9105
  [containerRef, cancelPendingHide]
8930
9106
  );
8931
- const clearHover = React33.useCallback(() => {
9107
+ const clearHover = React34.useCallback(() => {
8932
9108
  cancelPendingHide();
8933
9109
  setHoveredNodeId(null);
8934
9110
  setHoveredNodeRect(null);
8935
9111
  }, [cancelPendingHide]);
8936
- React33.useEffect(() => cancelPendingHide, [cancelPendingHide]);
9112
+ React34.useEffect(() => cancelPendingHide, [cancelPendingHide]);
8937
9113
  return { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover };
8938
9114
  }
8939
9115
  var EDITOR_PADDING = 4;
@@ -8948,11 +9124,11 @@ function SmartArtEditableLayer({
8948
9124
  onChangeNodeStyle,
8949
9125
  children
8950
9126
  }) {
8951
- const containerRef = React33.useRef(null);
8952
- const styleBarRef = React33.useRef(null);
8953
- const [edit, setEdit] = React33.useState(null);
9127
+ const containerRef = React34.useRef(null);
9128
+ const styleBarRef = React34.useRef(null);
9129
+ const [edit, setEdit] = React34.useState(null);
8954
9130
  const { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover } = useSmartArtHoverState(containerRef);
8955
- const openEditor = React33.useCallback(
9131
+ const openEditor = React34.useCallback(
8956
9132
  (target) => {
8957
9133
  const nodeEl = findNodeIdFromEvent(target);
8958
9134
  const container = containerRef.current;
@@ -10492,11 +10668,11 @@ function arePropsEqual(prev, next) {
10492
10668
  }
10493
10669
  return true;
10494
10670
  }
10495
- var SmartArtRenderer = React33.memo(SmartArtRendererImpl, arePropsEqual);
10671
+ var SmartArtRenderer = React34.memo(SmartArtRendererImpl, arePropsEqual);
10496
10672
  function FailedToLoad2() {
10497
10673
  return null;
10498
10674
  }
10499
- var LazySmartArt3DScene = React33.lazy(
10675
+ var LazySmartArt3DScene = React34.lazy(
10500
10676
  async () => {
10501
10677
  try {
10502
10678
  return await import('./SmartArt3DScene-XCFVGCXE.mjs');
@@ -10505,7 +10681,7 @@ var LazySmartArt3DScene = React33.lazy(
10505
10681
  }
10506
10682
  }
10507
10683
  );
10508
- var SceneErrorBoundary = class extends React33.Component {
10684
+ var SceneErrorBoundary = class extends React34.Component {
10509
10685
  constructor(props) {
10510
10686
  super(props);
10511
10687
  this.state = { hasError: false };
@@ -11264,7 +11440,7 @@ function renderBody(options) {
11264
11440
  }
11265
11441
  return renderTextElementBody(options);
11266
11442
  }
11267
- var Extrusion3DOverlay = React33.memo(({ data }) => {
11443
+ var Extrusion3DOverlay = React34.memo(({ data }) => {
11268
11444
  if (!data.hasExtrusion || data.panels.length === 0) {
11269
11445
  return null;
11270
11446
  }
@@ -11457,9 +11633,9 @@ function StaticElementRendererImpl({
11457
11633
  }
11458
11634
  );
11459
11635
  }
11460
- var StaticElementRenderer = React33.memo(StaticElementRendererImpl);
11636
+ var StaticElementRenderer = React34.memo(StaticElementRendererImpl);
11461
11637
  StaticElementRenderer.displayName = "StaticElementRenderer";
11462
- var ElementRenderer = React33.memo(
11638
+ var ElementRenderer = React34.memo(
11463
11639
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
11464
11640
  function ElementRendererInner({
11465
11641
  element: el,
@@ -11860,6 +12036,7 @@ function SlideCanvas({
11860
12036
  onCreateGuideFromRuler,
11861
12037
  connectorCreationMode = false,
11862
12038
  onCreateConnector,
12039
+ onUpdateSlideAnimations,
11863
12040
  allSlides,
11864
12041
  onZoomClick,
11865
12042
  sourceSlideIndex,
@@ -11923,6 +12100,18 @@ function SlideCanvas({
11923
12100
  zoom,
11924
12101
  onMoveGuide
11925
12102
  });
12103
+ const selectedMotionPath = selectedElement ? motionPathFor(activeSlide?.animations ?? [], selectedElement.id) : void 0;
12104
+ const handleMotionPathChange = useCallback(
12105
+ (path) => {
12106
+ if (!selectedElement || !onUpdateSlideAnimations) {
12107
+ return;
12108
+ }
12109
+ onUpdateSlideAnimations(
12110
+ setMotionPath(activeSlide?.animations ?? [], selectedElement.id, path)
12111
+ );
12112
+ },
12113
+ [activeSlide?.animations, onUpdateSlideAnimations, selectedElement]
12114
+ );
11926
12115
  const {
11927
12116
  connectorDragState,
11928
12117
  handleConnectionSiteDown,
@@ -11992,6 +12181,10 @@ function SlideCanvas({
11992
12181
  height: canvasSize.height,
11993
12182
  transform: `scale(${zoom.editorScale})`,
11994
12183
  transformOrigin: "top left",
12184
+ // Motion-path keyframes translate by a fraction of the SLIDE, so
12185
+ // the stage publishes its own size for those calc() offsets.
12186
+ ["--pptx-slide-w"]: `${canvasSize.width}px`,
12187
+ ["--pptx-slide-h"]: `${canvasSize.height}px`,
11995
12188
  marginTop: rulerOffset,
11996
12189
  marginLeft: rulerOffset,
11997
12190
  // In edit/master mode the stage must own all touch gestures so
@@ -12129,6 +12322,17 @@ function SlideCanvas({
12129
12322
  onConnectorDragEnd: handleConnectorDragEnd
12130
12323
  }
12131
12324
  ),
12325
+ isEditableCanvas && selectedElement && selectedMotionPath && /* @__PURE__ */ jsx(
12326
+ MotionPathOverlay,
12327
+ {
12328
+ element: selectedElement,
12329
+ path: selectedMotionPath,
12330
+ canvasSize,
12331
+ scale: zoom.editorScale,
12332
+ canEdit,
12333
+ onChangePath: handleMotionPathChange
12334
+ }
12335
+ ),
12132
12336
  isDrawing && /* @__PURE__ */ jsx(
12133
12337
  DrawingOverlaySvg,
12134
12338
  {
@@ -12701,7 +12905,7 @@ function arePropsEqual2(prev, next) {
12701
12905
  }
12702
12906
  return true;
12703
12907
  }
12704
- var SlideThumbnail = React33.memo(SlideThumbnailImpl, arePropsEqual2);
12908
+ var SlideThumbnail = React34.memo(SlideThumbnailImpl, arePropsEqual2);
12705
12909
 
12706
12910
  // src/viewer/components/context-menu-dispatch.ts
12707
12911
  function tableCell(props) {
@@ -13250,7 +13454,7 @@ function LazyThumbnailInner({
13250
13454
  }
13251
13455
  ) });
13252
13456
  }
13253
- var LazyThumbnail = React33.memo(LazyThumbnailInner);
13457
+ var LazyThumbnail = React34.memo(LazyThumbnailInner);
13254
13458
 
13255
13459
  // src/viewer/components/slides-pane/utils.ts
13256
13460
  function formatTimingMs(ms) {
@@ -13396,7 +13600,7 @@ function SlideItemInner({
13396
13600
  }
13397
13601
  );
13398
13602
  }
13399
- var SlideItem = React33.memo(SlideItemInner);
13603
+ var SlideItem = React34.memo(SlideItemInner);
13400
13604
  function useSlidePaneCallbacks(onMoveSlide, onRenameSection) {
13401
13605
  const [collapsedSections, setCollapsedSections] = useState({});
13402
13606
  const [renamingSectionId, setRenamingSectionId] = useState(null);
@@ -14665,7 +14869,7 @@ function arePropsEqual3(prev, next) {
14665
14869
  }
14666
14870
  return true;
14667
14871
  }
14668
- var SlideCard = React33.memo(SlideCardImpl, arePropsEqual3);
14872
+ var SlideCard = React34.memo(SlideCardImpl, arePropsEqual3);
14669
14873
  function SorterContextMenu({
14670
14874
  x,
14671
14875
  y,
@@ -15297,13 +15501,339 @@ function SlideSorterOverlay({
15297
15501
  }
15298
15502
  );
15299
15503
  }
15504
+ function useOutlineView(input) {
15505
+ const { slides, canvasSize, canEdit, setSlides, setActiveSlideIndex, bumpHistory } = input;
15506
+ const rows = useMemo(() => buildOutline(slides), [slides]);
15507
+ const containerRef = useRef(null);
15508
+ const pendingFocusRef = useRef(null);
15509
+ const run = useCallback(
15510
+ (edit) => {
15511
+ if (!canEdit) {
15512
+ return;
15513
+ }
15514
+ const result = applyOutlineEdit(slides, edit, { canvas: canvasSize });
15515
+ if (!result.changed) {
15516
+ return;
15517
+ }
15518
+ setSlides(result.slides);
15519
+ setActiveSlideIndex(result.activeSlideIndex);
15520
+ bumpHistory();
15521
+ pendingFocusRef.current = result.focusKey;
15522
+ },
15523
+ [bumpHistory, canEdit, canvasSize, setActiveSlideIndex, setSlides, slides]
15524
+ );
15525
+ const onRowKeyDown = useCallback(
15526
+ (event, rowKey) => {
15527
+ const { edit, preventDefault } = mapOutlineKey(event, rowKey);
15528
+ if (preventDefault) {
15529
+ event.preventDefault();
15530
+ }
15531
+ if (edit) {
15532
+ run(edit);
15533
+ }
15534
+ },
15535
+ [run]
15536
+ );
15537
+ useEffect(() => {
15538
+ const key = pendingFocusRef.current;
15539
+ if (!key) {
15540
+ return;
15541
+ }
15542
+ pendingFocusRef.current = null;
15543
+ const selector = `[${OUTLINE_ROW_ATTR}="${CSS.escape(key)}"]`;
15544
+ const target = containerRef.current?.querySelector(selector);
15545
+ if (target && document.activeElement !== target) {
15546
+ target.focus();
15547
+ target.setSelectionRange(target.value.length, target.value.length);
15548
+ }
15549
+ }, [rows]);
15550
+ return { rows, containerRef, run, onRowKeyDown };
15551
+ }
15552
+ var INDENT_PX = 22;
15553
+ function OutlineViewOverlay({
15554
+ slides,
15555
+ canvasSize,
15556
+ canEdit,
15557
+ setSlides,
15558
+ setActiveSlideIndex,
15559
+ bumpHistory,
15560
+ onClose
15561
+ }) {
15562
+ const { t } = useTranslation();
15563
+ const { rows, containerRef, run, onRowKeyDown } = useOutlineView({
15564
+ slides,
15565
+ canvasSize,
15566
+ canEdit,
15567
+ setSlides,
15568
+ setActiveSlideIndex,
15569
+ bumpHistory
15570
+ });
15571
+ return /* @__PURE__ */ jsxs(
15572
+ "div",
15573
+ {
15574
+ ...{ [OUTLINE_VIEW_ATTR]: "true" },
15575
+ role: "region",
15576
+ "aria-label": t("pptx.view.outlineView"),
15577
+ className: "fixed inset-0 z-[1300] flex flex-col bg-neutral-900 text-neutral-100",
15578
+ children: [
15579
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 border-b border-white/10 px-4 py-2", children: [
15580
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: t("pptx.view.outlineView") }),
15581
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-[11px] text-white/50", children: t("pptx.outline.hint") }),
15582
+ /* @__PURE__ */ jsx(
15583
+ "button",
15584
+ {
15585
+ type: "button",
15586
+ className: "inline-flex h-8 w-8 items-center justify-center rounded text-white/80 transition-colors hover:bg-white/15 hover:text-white",
15587
+ "aria-label": t("pptx.statusBar.normalView"),
15588
+ title: t("pptx.statusBar.normalView"),
15589
+ onClick: onClose,
15590
+ children: /* @__PURE__ */ jsx(LuX, {})
15591
+ }
15592
+ )
15593
+ ] }),
15594
+ /* @__PURE__ */ jsx("div", { ref: containerRef, className: "min-h-0 flex-1 overflow-auto px-4 py-3", children: rows.map((row) => /* @__PURE__ */ jsxs(
15595
+ "div",
15596
+ {
15597
+ className: "flex items-center gap-2 py-0.5",
15598
+ style: { paddingLeft: row.level * INDENT_PX },
15599
+ children: [
15600
+ /* @__PURE__ */ jsx("span", { className: "w-6 shrink-0 text-right text-[10px] tabular-nums text-white/40", children: row.kind === "title" ? row.slideIndex + 1 : "" }),
15601
+ /* @__PURE__ */ jsx(
15602
+ "input",
15603
+ {
15604
+ ...{
15605
+ [OUTLINE_ROW_ATTR]: row.key,
15606
+ [OUTLINE_SLIDE_ATTR]: String(row.slideIndex + 1),
15607
+ [OUTLINE_LEVEL_ATTR]: String(row.level)
15608
+ },
15609
+ type: "text",
15610
+ value: row.text,
15611
+ readOnly: !canEdit,
15612
+ "aria-label": t(
15613
+ row.kind === "title" ? "pptx.outline.titleLine" : "pptx.outline.bodyLine"
15614
+ ),
15615
+ className: row.kind === "title" ? "w-full rounded bg-transparent px-1 py-0.5 text-sm font-semibold outline-none focus:bg-white/10" : "w-full rounded bg-transparent px-1 py-0.5 text-[13px] text-white/80 outline-none focus:bg-white/10",
15616
+ onChange: (event) => run({ type: "setText", key: row.key, text: event.target.value }),
15617
+ onKeyDown: (event) => onRowKeyDown(event, row.key)
15618
+ }
15619
+ )
15620
+ ]
15621
+ },
15622
+ row.key
15623
+ )) })
15624
+ ]
15625
+ }
15626
+ );
15627
+ }
15628
+ function ReadingViewStage({
15629
+ slide,
15630
+ templateElements,
15631
+ canvasSize,
15632
+ scale
15633
+ }) {
15634
+ if (scale <= 0) {
15635
+ return null;
15636
+ }
15637
+ const width = Math.max(canvasSize.width, 1);
15638
+ const height = Math.max(canvasSize.height, 1);
15639
+ const elements = [...templateElements, ...slide.elements];
15640
+ return /* @__PURE__ */ jsxs(
15641
+ "div",
15642
+ {
15643
+ ...{ [READING_VIEW_STAGE_ATTR]: "true" },
15644
+ "aria-roledescription": "slide",
15645
+ className: "relative overflow-hidden bg-white shadow-2xl",
15646
+ style: { width: width * scale, height: height * scale },
15647
+ children: [
15648
+ slide.backgroundColor && slide.backgroundColor !== "transparent" && /* @__PURE__ */ jsx(
15649
+ "div",
15650
+ {
15651
+ className: "absolute inset-0",
15652
+ style: { backgroundColor: normalizeHexColor(slide.backgroundColor, "#ffffff") }
15653
+ }
15654
+ ),
15655
+ slide.backgroundImage && /* @__PURE__ */ jsx(
15656
+ "img",
15657
+ {
15658
+ src: slide.backgroundImage,
15659
+ alt: "",
15660
+ className: "absolute inset-0 h-full w-full object-cover",
15661
+ draggable: false
15662
+ }
15663
+ ),
15664
+ slide.backgroundGradient && /* @__PURE__ */ jsx("div", { className: "absolute inset-0", style: { backgroundImage: slide.backgroundGradient } }),
15665
+ /* @__PURE__ */ jsx(
15666
+ "div",
15667
+ {
15668
+ className: "absolute left-0 top-0 origin-top-left",
15669
+ style: { width, height, transform: `scale(${scale})` },
15670
+ children: elements.map((element, index) => /* @__PURE__ */ jsx(
15671
+ StaticElementRenderer,
15672
+ {
15673
+ element,
15674
+ activeSlide: slide,
15675
+ allSlides: [slide],
15676
+ zIndex: index
15677
+ },
15678
+ element.id
15679
+ ))
15680
+ }
15681
+ )
15682
+ ]
15683
+ }
15684
+ );
15685
+ }
15686
+ var READING_VIEW_PADDING = 24;
15687
+ function useReadingView(input) {
15688
+ const { slideCount, canvasSize, initialSlideIndex, onExit } = input;
15689
+ const [state, setState] = useState(
15690
+ () => openReadingView(initialSlideIndex, slideCount)
15691
+ );
15692
+ const viewportRef = useRef(null);
15693
+ const [viewport, setViewport] = useState({ width: 0, height: 0 });
15694
+ const onExitRef = useRef(onExit);
15695
+ onExitRef.current = onExit;
15696
+ const run = useCallback(
15697
+ (command) => {
15698
+ setState((previous) => {
15699
+ const next = applyReadingViewCommand(previous, command, slideCount);
15700
+ if (previous.open && !next.open) {
15701
+ onExitRef.current(previous.slideIndex);
15702
+ }
15703
+ return next;
15704
+ });
15705
+ },
15706
+ [slideCount]
15707
+ );
15708
+ useEffect(() => {
15709
+ const buffer = createPresentationKeyBuffer();
15710
+ const handle = (event) => {
15711
+ const { command, swallow, preventDefault } = handleReadingViewKey(event, buffer);
15712
+ if (swallow) {
15713
+ event.stopPropagation();
15714
+ }
15715
+ if (preventDefault) {
15716
+ event.preventDefault();
15717
+ }
15718
+ if (command.command !== "none") {
15719
+ run(command);
15720
+ }
15721
+ };
15722
+ window.addEventListener("keydown", handle, true);
15723
+ return () => window.removeEventListener("keydown", handle, true);
15724
+ }, [run]);
15725
+ useEffect(() => {
15726
+ const element = viewportRef.current;
15727
+ if (!element) {
15728
+ return;
15729
+ }
15730
+ const observer = new ResizeObserver((entries) => {
15731
+ const rect = entries[0]?.contentRect;
15732
+ if (rect) {
15733
+ setViewport({ width: rect.width, height: rect.height });
15734
+ }
15735
+ });
15736
+ observer.observe(element);
15737
+ return () => observer.disconnect();
15738
+ }, []);
15739
+ const scale = useMemo(
15740
+ () => readingViewFitScale(canvasSize, viewport, READING_VIEW_PADDING),
15741
+ [canvasSize, viewport]
15742
+ );
15743
+ return { state, viewportRef, scale, run };
15744
+ }
15745
+ function ReadingViewOverlay({
15746
+ slides,
15747
+ templateElements,
15748
+ canvasSize,
15749
+ activeSlideIndex,
15750
+ onExit
15751
+ }) {
15752
+ const { t } = useTranslation();
15753
+ const { state, viewportRef, scale, run } = useReadingView({
15754
+ slideCount: slides.length,
15755
+ canvasSize,
15756
+ initialSlideIndex: activeSlideIndex,
15757
+ onExit
15758
+ });
15759
+ const slide = slides[state.slideIndex];
15760
+ if (!state.open || !slide) {
15761
+ return null;
15762
+ }
15763
+ const control = "inline-flex h-8 w-8 items-center justify-center rounded text-white/80 transition-colors hover:bg-white/15 hover:text-white disabled:cursor-default disabled:opacity-30 disabled:hover:bg-transparent";
15764
+ return /* @__PURE__ */ jsxs(
15765
+ "div",
15766
+ {
15767
+ ...{ [READING_VIEW_ATTR]: "true" },
15768
+ role: "region",
15769
+ "aria-label": t("pptx.view.readingView"),
15770
+ className: "fixed inset-0 z-[1300] flex flex-col bg-neutral-900",
15771
+ children: [
15772
+ /* @__PURE__ */ jsx("div", { ref: viewportRef, className: "flex min-h-0 flex-1 items-center justify-center", children: /* @__PURE__ */ jsx(
15773
+ ReadingViewStage,
15774
+ {
15775
+ slide,
15776
+ templateElements,
15777
+ canvasSize,
15778
+ scale
15779
+ }
15780
+ ) }),
15781
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-3 border-t border-white/10 px-4 py-2", children: [
15782
+ /* @__PURE__ */ jsx(
15783
+ "button",
15784
+ {
15785
+ type: "button",
15786
+ className: control,
15787
+ "aria-label": t("pptx.common.previous"),
15788
+ title: t("pptx.common.previous"),
15789
+ disabled: !canGoPrevious(state),
15790
+ onClick: () => run({ command: "previous" }),
15791
+ children: /* @__PURE__ */ jsx(LuChevronLeft, {})
15792
+ }
15793
+ ),
15794
+ /* @__PURE__ */ jsx(
15795
+ "span",
15796
+ {
15797
+ ...{ [READING_VIEW_COUNTER_ATTR]: "true" },
15798
+ className: "min-w-16 text-center text-xs tabular-nums text-white/70",
15799
+ children: formatSlideCounter(state.slideIndex, slides.length)
15800
+ }
15801
+ ),
15802
+ /* @__PURE__ */ jsx(
15803
+ "button",
15804
+ {
15805
+ type: "button",
15806
+ className: control,
15807
+ "aria-label": t("pptx.common.next"),
15808
+ title: t("pptx.common.next"),
15809
+ disabled: !canGoNext(state, slides.length),
15810
+ onClick: () => run({ command: "next" }),
15811
+ children: /* @__PURE__ */ jsx(LuChevronRight, {})
15812
+ }
15813
+ ),
15814
+ /* @__PURE__ */ jsx(
15815
+ "button",
15816
+ {
15817
+ type: "button",
15818
+ className: control,
15819
+ "aria-label": t("pptx.statusBar.normalView"),
15820
+ title: t("pptx.statusBar.normalView"),
15821
+ onClick: () => run({ command: "exit" }),
15822
+ children: /* @__PURE__ */ jsx(LuX, {})
15823
+ }
15824
+ )
15825
+ ] })
15826
+ ]
15827
+ }
15828
+ );
15829
+ }
15300
15830
 
15301
15831
  // src/viewer/components/notes/notes-utils.ts
15302
15832
  var DEBOUNCE_MS = 600;
15303
15833
  var EXPANDED_MAX_HEIGHT = 200;
15304
15834
  var PX_TO_PT = 0.75;
15305
15835
  var MAX_INDENT_LEVEL = 4;
15306
- var INDENT_PX = 24;
15836
+ var INDENT_PX2 = 24;
15307
15837
  function escapeHtml(value) {
15308
15838
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
15309
15839
  }
@@ -15358,7 +15888,7 @@ function buildParagraph(segments) {
15358
15888
  if (first?.style.paragraphMarginLeft) {
15359
15889
  indentLevel = Math.min(
15360
15890
  MAX_INDENT_LEVEL,
15361
- Math.max(0, Math.round(first.style.paragraphMarginLeft / INDENT_PX))
15891
+ Math.max(0, Math.round(first.style.paragraphMarginLeft / INDENT_PX2))
15362
15892
  );
15363
15893
  }
15364
15894
  return {
@@ -15403,7 +15933,7 @@ function paragraphsToSegments(paragraphs) {
15403
15933
  para.segments.forEach((seg, sIdx) => {
15404
15934
  const updated = { ...seg, style: { ...seg.style } };
15405
15935
  if (para.indentLevel > 0) {
15406
- updated.style.paragraphMarginLeft = para.indentLevel * INDENT_PX;
15936
+ updated.style.paragraphMarginLeft = para.indentLevel * INDENT_PX2;
15407
15937
  } else {
15408
15938
  delete updated.style.paragraphMarginLeft;
15409
15939
  }
@@ -15560,7 +16090,7 @@ function parseSegmentsFromRichEditor(root) {
15560
16090
  if (paraIndent > 0) {
15561
16091
  segments[i].style = {
15562
16092
  ...segments[i].style,
15563
- paragraphMarginLeft: paraIndent * INDENT_PX
16093
+ paragraphMarginLeft: paraIndent * INDENT_PX2
15564
16094
  };
15565
16095
  }
15566
16096
  break;
@@ -15624,7 +16154,7 @@ function segmentsToEditorHtml(segments) {
15624
16154
  if (para.indentLevel > 0) {
15625
16155
  attrs.push(`data-indent-level="${para.indentLevel}"`);
15626
16156
  }
15627
- const indent = para.indentLevel * INDENT_PX;
16157
+ const indent = para.indentLevel * INDENT_PX2;
15628
16158
  const divStyles = [];
15629
16159
  if (indent > 0) {
15630
16160
  divStyles.push(`padding-left:${indent}px`);
@@ -15652,7 +16182,7 @@ function renderRichNotesSegments(segments) {
15652
16182
  }
15653
16183
  const divStyle = {};
15654
16184
  if (para.indentLevel > 0) {
15655
- divStyle.paddingLeft = para.indentLevel * INDENT_PX;
16185
+ divStyle.paddingLeft = para.indentLevel * INDENT_PX2;
15656
16186
  }
15657
16187
  const children = [];
15658
16188
  if (para.bulletType === "bullet") {
@@ -18168,9 +18698,9 @@ function PresentationSubtitleBar({
18168
18698
  function renderNotesSegments(segments) {
18169
18699
  return notesSegmentsToSpans(segments).map((span) => {
18170
18700
  if (span.kind === "break") {
18171
- return React33.createElement("br", { key: span.key });
18701
+ return React34.createElement("br", { key: span.key });
18172
18702
  }
18173
- return React33.createElement(
18703
+ return React34.createElement(
18174
18704
  "span",
18175
18705
  { key: span.key, style: span.style },
18176
18706
  span.text
@@ -18377,7 +18907,7 @@ function arePropsEqual4(prev, next) {
18377
18907
  }
18378
18908
  return true;
18379
18909
  }
18380
- var ScaledSlidePreview = React33.memo(ScaledSlidePreviewImpl, arePropsEqual4);
18910
+ var ScaledSlidePreview = React34.memo(ScaledSlidePreviewImpl, arePropsEqual4);
18381
18911
  function PresenterNotesRail({
18382
18912
  slides,
18383
18913
  current,
@@ -19408,6 +19938,33 @@ function AnimationTimelineSection({
19408
19938
  ] })
19409
19939
  ] });
19410
19940
  }
19941
+ function MotionPathRow({
19942
+ motionPath,
19943
+ canEdit,
19944
+ onChange
19945
+ }) {
19946
+ const { t } = useTranslation();
19947
+ const presetId = motionPathPresetIdForPath(motionPath);
19948
+ const isCustom = Boolean(motionPath) && !presetId;
19949
+ return /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
19950
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-[11px]", children: t("pptx.animation.motionPath.label") }),
19951
+ /* @__PURE__ */ jsxs(
19952
+ "select",
19953
+ {
19954
+ value: isCustom ? "custom" : presetId ?? "none",
19955
+ onChange: (event) => onChange(event.target.value),
19956
+ disabled: !canEdit,
19957
+ className: SELECT_CLS,
19958
+ children: [
19959
+ /* @__PURE__ */ jsx("option", { value: "none", children: t("pptx.animation.motionPath.none") }),
19960
+ isCustom && /* @__PURE__ */ jsx("option", { value: "custom", children: t("pptx.animation.motionPath.custom") }),
19961
+ MOTION_PATH_FAMILIES.map((family) => /* @__PURE__ */ jsx("optgroup", { label: t(motionPathFamilyLabelKey(family)), children: motionPathPresetsByFamily(family).map((preset) => /* @__PURE__ */ jsx("option", { value: preset.id, children: t(motionPathPresetLabelKey(preset.id)) }, preset.id)) }, family))
19962
+ ]
19963
+ }
19964
+ ),
19965
+ motionPath && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: t("pptx.animation.motionPath.editHint") })
19966
+ ] });
19967
+ }
19411
19968
  function useAnimationDragDrop({
19412
19969
  canEdit,
19413
19970
  updateAnimations
@@ -19514,6 +20071,14 @@ function useAnimationPreview({
19514
20071
  selectedElementAnimation
19515
20072
  }) {
19516
20073
  const handleAnimationHover = useCallback((anim) => {
20074
+ if (anim.motionPath) {
20075
+ startMotionPathPreview(anim.elementId, anim.motionPath, {
20076
+ durationMs: anim.durationMs,
20077
+ delayMs: anim.delayMs,
20078
+ timingCurve: anim.timingCurve
20079
+ });
20080
+ return;
20081
+ }
19517
20082
  const preset = anim.entrance ?? anim.emphasis ?? anim.exit;
19518
20083
  if (!preset || preset === "none") {
19519
20084
  return;
@@ -19529,6 +20094,14 @@ function useAnimationPreview({
19529
20094
  if (!selectedElementAnimation) {
19530
20095
  return;
19531
20096
  }
20097
+ if (selectedElementAnimation.motionPath) {
20098
+ startMotionPathPreview(selectedElementId, selectedElementAnimation.motionPath, {
20099
+ durationMs: selectedElementAnimation.durationMs,
20100
+ delayMs: selectedElementAnimation.delayMs,
20101
+ timingCurve: selectedElementAnimation.timingCurve
20102
+ });
20103
+ return;
20104
+ }
19532
20105
  const preset = selectedElementAnimation.entrance ?? selectedElementAnimation.emphasis ?? selectedElementAnimation.exit;
19533
20106
  if (!preset || preset === "none") {
19534
20107
  return;
@@ -19588,7 +20161,7 @@ function useAnimationHandlers({
19588
20161
  const idx = anims.findIndex((a) => a.elementId === selectedElement.id);
19589
20162
  const hasEffect = entrance || exit || emphasis;
19590
20163
  if (idx >= 0) {
19591
- if (!hasEffect) {
20164
+ if (!hasEffect && !anims[idx].motionPath) {
19592
20165
  return anims.filter((a) => a.elementId !== selectedElement.id);
19593
20166
  }
19594
20167
  anims[idx] = {
@@ -19646,6 +20219,20 @@ function useAnimationHandlers({
19646
20219
  },
19647
20220
  [setAnimationPreset, selectedElementAnimation]
19648
20221
  );
20222
+ const handleMotionPathChange = useCallback(
20223
+ (presetId) => {
20224
+ if (!canEdit) {
20225
+ return;
20226
+ }
20227
+ if (presetId === "custom") {
20228
+ return;
20229
+ }
20230
+ updateAnimations(
20231
+ (anims) => presetId === "none" ? clearMotionPath(anims, selectedElement.id) : applyMotionPathPreset(anims, selectedElement.id, presetId)
20232
+ );
20233
+ },
20234
+ [canEdit, updateAnimations, selectedElement.id]
20235
+ );
19649
20236
  const handleTriggerChange = useCallback(
19650
20237
  (event) => {
19651
20238
  const newTrigger = event.target.value;
@@ -19711,7 +20298,7 @@ function useAnimationHandlers({
19711
20298
  [activeSlide.elements]
19712
20299
  );
19713
20300
  const hasAnimation = Boolean(
19714
- selectedElementAnimation?.entrance || selectedElementAnimation?.exit || selectedElementAnimation?.emphasis
20301
+ selectedElementAnimation?.entrance || selectedElementAnimation?.exit || selectedElementAnimation?.emphasis || selectedElementAnimation?.motionPath
19715
20302
  );
19716
20303
  const showDirectionPicker = hasAnimation && (DIRECTIONAL_PRESETS.has(selectedElementAnimation?.entrance ?? "") || DIRECTIONAL_PRESETS.has(selectedElementAnimation?.exit ?? ""));
19717
20304
  const timelineBarData = useMemo(() => {
@@ -19753,6 +20340,7 @@ function useAnimationHandlers({
19753
20340
  handleRepeatModeChange,
19754
20341
  handleDirectionChange,
19755
20342
  handleSequenceChange,
20343
+ handleMotionPathChange,
19756
20344
  getTimelineLabel,
19757
20345
  ...preview,
19758
20346
  ...dragDrop
@@ -19787,6 +20375,7 @@ function AnimationPanel({
19787
20375
  handleRepeatModeChange,
19788
20376
  handleDirectionChange,
19789
20377
  handleSequenceChange,
20378
+ handleMotionPathChange,
19790
20379
  handlePreviewClick
19791
20380
  } = handlers;
19792
20381
  return /* @__PURE__ */ jsxs("div", { className: "rounded border border-border bg-card p-2 space-y-2", children: [
@@ -19854,6 +20443,14 @@ function AnimationPanel({
19854
20443
  }
19855
20444
  )
19856
20445
  ] }),
20446
+ /* @__PURE__ */ jsx(
20447
+ MotionPathRow,
20448
+ {
20449
+ motionPath: selectedElementAnimation?.motionPath,
20450
+ canEdit,
20451
+ onChange: handleMotionPathChange
20452
+ }
20453
+ ),
19857
20454
  hasAnimation && /* @__PURE__ */ jsxs(Fragment, { children: [
19858
20455
  showDirectionPicker && /* @__PURE__ */ jsxs("div", { className: "pt-1 border-t border-border", children: [
19859
20456
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-[11px] block mb-1", children: t("pptx.animation.direction") }),
@@ -21804,7 +22401,7 @@ function ConnectorArrowsSection({
21804
22401
  ["Start", "End"].map((end) => {
21805
22402
  const widthKey = end === "Start" ? "connectorStartArrowWidth" : "connectorEndArrowWidth";
21806
22403
  const lengthKey = end === "Start" ? "connectorStartArrowLength" : "connectorEndArrowLength";
21807
- return /* @__PURE__ */ jsxs(React33.Fragment, { children: [
22404
+ return /* @__PURE__ */ jsxs(React34.Fragment, { children: [
21808
22405
  /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
21809
22406
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t(END_LABEL_KEYS[end].width) }),
21810
22407
  /* @__PURE__ */ jsx(
@@ -24633,7 +25230,7 @@ function StrokeEffectsSection({
24633
25230
  ] }),
24634
25231
  EFFECT_CONFIGS.map((cfg) => {
24635
25232
  const on = cfg.isOn(style);
24636
- return /* @__PURE__ */ jsxs(React33.Fragment, { children: [
25233
+ return /* @__PURE__ */ jsxs(React34.Fragment, { children: [
24637
25234
  /* @__PURE__ */ jsxs("label", { className: `inline-flex items-center gap-2 text-foreground ${COL2}`, children: [
24638
25235
  /* @__PURE__ */ jsx(
24639
25236
  "input",
@@ -25470,7 +26067,7 @@ function TextWarpGallery({
25470
26067
  onUpdateTextStyle
25471
26068
  }) {
25472
26069
  const { t } = useTranslation();
25473
- const [expanded, setExpanded] = React33.useState(false);
26070
+ const [expanded, setExpanded] = React34.useState(false);
25474
26071
  const currentPreset = ts?.textWarpPreset || "textNoShape";
25475
26072
  return /* @__PURE__ */ jsxs("div", { className: "mt-2 rounded border border-border bg-card p-2 space-y-2", children: [
25476
26073
  /* @__PURE__ */ jsxs(
@@ -26195,9 +26792,9 @@ function SmartArtPropertiesPanel({
26195
26792
  const nodes = smartArtData.nodes ?? [];
26196
26793
  const layout = smartArtData.resolvedLayoutType;
26197
26794
  const topLevelCount = nodes.filter((n) => !n.parentId).length;
26198
- const inputRefs = React33.useRef(/* @__PURE__ */ new Map());
26199
- const pendingFocusId = React33.useRef(null);
26200
- React33.useEffect(() => {
26795
+ const inputRefs = React34.useRef(/* @__PURE__ */ new Map());
26796
+ const pendingFocusId = React34.useRef(null);
26797
+ React34.useEffect(() => {
26201
26798
  const id = pendingFocusId.current;
26202
26799
  if (id) {
26203
26800
  inputRefs.current.get(id)?.focus();
@@ -26413,6 +27010,151 @@ function SmartArtPropertiesPanel({
26413
27010
  ] })
26414
27011
  ] });
26415
27012
  }
27013
+ var HEADER_CELL = "flex items-center justify-center gap-0.5 bg-muted text-muted-foreground border border-border -m-px px-1 py-0.5 whitespace-nowrap";
27014
+ var CELL_INPUT2 = "w-full box-border bg-muted px-1 py-0.5 text-[11px] border-0 outline-none focus:bg-accent disabled:opacity-60";
27015
+ var REMOVE_BTN = "px-0.5 leading-none text-destructive hover:opacity-80";
27016
+ function TableDataGrid({
27017
+ tableElement,
27018
+ canEdit,
27019
+ onUpdateElement
27020
+ }) {
27021
+ const { t } = useTranslation();
27022
+ const grid = buildTableDataGrid(tableElement);
27023
+ if (grid.rowCount === 0 || grid.colCount === 0) {
27024
+ return null;
27025
+ }
27026
+ const commit = (next) => {
27027
+ if (next === tableElement) {
27028
+ return;
27029
+ }
27030
+ onUpdateElement({ tableData: next.tableData, rawXml: next.rawXml });
27031
+ };
27032
+ return /* @__PURE__ */ jsx("div", { className: CARD, children: /* @__PURE__ */ jsxs("section", { "aria-label": t("pptx.tableDataEditor.ariaLabel"), children: [
27033
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-1 mb-1.5", children: [
27034
+ /* @__PURE__ */ jsx("div", { className: HEADING, children: t("pptx.inspector.tableData") }),
27035
+ canEdit && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-0.5", children: [
27036
+ /* @__PURE__ */ jsx(
27037
+ "button",
27038
+ {
27039
+ type: "button",
27040
+ className: BTN,
27041
+ title: t("pptx.tableDataEditor.addRowTitle"),
27042
+ onClick: () => commit(appendTableElementRow(tableElement)),
27043
+ children: t("pptx.tableDataEditor.addRowLabel")
27044
+ }
27045
+ ),
27046
+ /* @__PURE__ */ jsx(
27047
+ "button",
27048
+ {
27049
+ type: "button",
27050
+ className: BTN,
27051
+ disabled: !grid.canRemoveRow,
27052
+ title: t("pptx.tableDataEditor.removeRowTitle"),
27053
+ onClick: () => commit(removeLastTableElementRow(tableElement)),
27054
+ children: t("pptx.tableDataEditor.removeRowLabel")
27055
+ }
27056
+ ),
27057
+ /* @__PURE__ */ jsx(
27058
+ "button",
27059
+ {
27060
+ type: "button",
27061
+ className: BTN,
27062
+ title: t("pptx.tableDataEditor.addColumnTitle"),
27063
+ onClick: () => commit(appendTableElementColumn(tableElement)),
27064
+ children: t("pptx.tableDataEditor.addColumnLabel")
27065
+ }
27066
+ ),
27067
+ /* @__PURE__ */ jsx(
27068
+ "button",
27069
+ {
27070
+ type: "button",
27071
+ className: BTN,
27072
+ disabled: !grid.canRemoveColumn,
27073
+ title: t("pptx.tableDataEditor.removeColumnTitle"),
27074
+ onClick: () => commit(removeLastTableElementColumn(tableElement)),
27075
+ children: t("pptx.tableDataEditor.removeColumnLabel")
27076
+ }
27077
+ )
27078
+ ] })
27079
+ ] }),
27080
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col text-[11px] w-max min-w-full", role: "grid", children: [
27081
+ /* @__PURE__ */ jsxs("div", { className: "flex", role: "row", children: [
27082
+ /* @__PURE__ */ jsx("div", { className: `${HEADER_CELL} flex-none w-10`, "aria-hidden": "true" }),
27083
+ grid.colIndices.map((colIndex) => /* @__PURE__ */ jsxs(
27084
+ "div",
27085
+ {
27086
+ className: `${HEADER_CELL} flex-1 basis-16`,
27087
+ role: "columnheader",
27088
+ children: [
27089
+ /* @__PURE__ */ jsx("span", { children: colIndex + 1 }),
27090
+ canEdit && grid.canRemoveColumn && /* @__PURE__ */ jsx(
27091
+ "button",
27092
+ {
27093
+ type: "button",
27094
+ className: REMOVE_BTN,
27095
+ "aria-label": t("pptx.tableDataEditor.removeColumnN", {
27096
+ number: colIndex + 1
27097
+ }),
27098
+ title: t("pptx.tableDataEditor.removeColumnN", { number: colIndex + 1 }),
27099
+ onClick: () => commit(removeTableElementColumn(tableElement, colIndex)),
27100
+ children: "\xD7"
27101
+ }
27102
+ )
27103
+ ]
27104
+ },
27105
+ colIndex
27106
+ ))
27107
+ ] }),
27108
+ grid.rows.map((row) => /* @__PURE__ */ jsxs("div", { className: "flex", role: "row", children: [
27109
+ /* @__PURE__ */ jsxs("div", { className: `${HEADER_CELL} flex-none w-10`, role: "rowheader", children: [
27110
+ /* @__PURE__ */ jsx("span", { children: row.rowIndex + 1 }),
27111
+ canEdit && grid.canRemoveRow && /* @__PURE__ */ jsx(
27112
+ "button",
27113
+ {
27114
+ type: "button",
27115
+ className: REMOVE_BTN,
27116
+ "aria-label": t("pptx.tableDataEditor.removeRowN", {
27117
+ number: row.rowIndex + 1
27118
+ }),
27119
+ title: t("pptx.tableDataEditor.removeRowN", { number: row.rowIndex + 1 }),
27120
+ onClick: () => commit(removeTableElementRow(tableElement, row.rowIndex)),
27121
+ children: "\xD7"
27122
+ }
27123
+ )
27124
+ ] }),
27125
+ row.cells.map((cell) => /* @__PURE__ */ jsx(
27126
+ "div",
27127
+ {
27128
+ className: "flex flex-1 basis-16 p-px border border-border -m-px",
27129
+ role: "gridcell",
27130
+ children: /* @__PURE__ */ jsx(
27131
+ "input",
27132
+ {
27133
+ type: "text",
27134
+ className: CELL_INPUT2,
27135
+ disabled: !canEdit,
27136
+ "aria-label": t("pptx.tableDataEditor.cellAriaLabel", {
27137
+ row: cell.rowIndex + 1,
27138
+ column: cell.colIndex + 1
27139
+ }),
27140
+ value: cell.text,
27141
+ onChange: (event) => commit(
27142
+ setTableElementCellText(
27143
+ tableElement,
27144
+ cell.rowIndex,
27145
+ cell.colIndex,
27146
+ event.target.value
27147
+ )
27148
+ )
27149
+ }
27150
+ )
27151
+ },
27152
+ cell.colIndex
27153
+ ))
27154
+ ] }, row.rowIndex))
27155
+ ] }) })
27156
+ ] }) });
27157
+ }
26416
27158
  function TableCellAdvancedFill({
26417
27159
  cellStyle,
26418
27160
  canEdit,
@@ -27149,15 +27891,25 @@ function ElementInspectorBody({
27149
27891
  )
27150
27892
  ] }, key)) })
27151
27893
  ] }),
27152
- selectedElement.type === "table" && /* @__PURE__ */ jsx(
27153
- TablePropertiesPanel,
27154
- {
27155
- tableElement: selectedElement,
27156
- canEdit,
27157
- onUpdateElement,
27158
- tableEditorState
27159
- }
27160
- ),
27894
+ selectedElement.type === "table" && /* @__PURE__ */ jsxs(Fragment, { children: [
27895
+ /* @__PURE__ */ jsx(
27896
+ TableDataGrid,
27897
+ {
27898
+ tableElement: selectedElement,
27899
+ canEdit,
27900
+ onUpdateElement
27901
+ }
27902
+ ),
27903
+ /* @__PURE__ */ jsx(
27904
+ TablePropertiesPanel,
27905
+ {
27906
+ tableElement: selectedElement,
27907
+ canEdit,
27908
+ onUpdateElement,
27909
+ tableEditorState
27910
+ }
27911
+ )
27912
+ ] }),
27161
27913
  selectedElement.type === "chart" && /* @__PURE__ */ jsx(
27162
27914
  ChartDataPanel,
27163
27915
  {
@@ -28509,7 +29261,7 @@ function PresentationPropertiesPanel({
28509
29261
  onUpdateTagCollections
28510
29262
  }) {
28511
29263
  const { t } = useTranslation();
28512
- const handleTransitionChange = React33.useCallback(
29264
+ const handleTransitionChange = React34.useCallback(
28513
29265
  (updates) => {
28514
29266
  onUpdateSlide({
28515
29267
  transition: mergeSlideTransition(activeSlide?.transition, updates)
@@ -31821,6 +32573,9 @@ function ViewerOverlays({
31821
32573
  isShortcutHelpOpen,
31822
32574
  isAccessibilityPanelOpen,
31823
32575
  showSlideSorter,
32576
+ showReadingView,
32577
+ showOutlineView,
32578
+ templateElements,
31824
32579
  accessibilityIssues,
31825
32580
  slides,
31826
32581
  activeSlideIndex,
@@ -31835,10 +32590,15 @@ function ViewerOverlays({
31835
32590
  onDuplicateSlides,
31836
32591
  onToggleHideSlides,
31837
32592
  onCloseSorter,
32593
+ onCloseReadingView,
32594
+ onCloseOutlineView,
32595
+ setSlides,
32596
+ setActiveSlideIndex,
32597
+ bumpHistory,
31838
32598
  reducedMotion,
31839
32599
  onToggleReducedMotion
31840
32600
  }) {
31841
- const hasOverlay = isShortcutHelpOpen || isAccessibilityPanelOpen || showSlideSorter;
32601
+ const hasOverlay = isShortcutHelpOpen || isAccessibilityPanelOpen || showSlideSorter || showReadingView || showOutlineView;
31842
32602
  if (!hasOverlay) {
31843
32603
  return null;
31844
32604
  }
@@ -31869,6 +32629,28 @@ function ViewerOverlays({
31869
32629
  onToggleHideSlides,
31870
32630
  onClose: onCloseSorter
31871
32631
  }
32632
+ ),
32633
+ showReadingView && /* @__PURE__ */ jsx(
32634
+ ReadingViewOverlay,
32635
+ {
32636
+ slides,
32637
+ templateElements,
32638
+ canvasSize,
32639
+ activeSlideIndex,
32640
+ onExit: onCloseReadingView
32641
+ }
32642
+ ),
32643
+ showOutlineView && /* @__PURE__ */ jsx(
32644
+ OutlineViewOverlay,
32645
+ {
32646
+ slides,
32647
+ canvasSize,
32648
+ canEdit,
32649
+ setSlides,
32650
+ setActiveSlideIndex,
32651
+ bumpHistory,
32652
+ onClose: onCloseOutlineView
32653
+ }
31872
32654
  )
31873
32655
  ] });
31874
32656
  }
@@ -32357,6 +33139,12 @@ function ViewerToolbarSection(props) {
32357
33139
  return;
32358
33140
  }
32359
33141
  const current = activeSlide.animations ?? [];
33142
+ if (group === "motionPath") {
33143
+ propertyHandlers.handleUpdateSlide({
33144
+ animations: applyMotionPathPreset(current, selectedElement.id, preset)
33145
+ });
33146
+ return;
33147
+ }
32360
33148
  const existing = current.find((a) => a.elementId === selectedElement.id);
32361
33149
  const presetValue = preset;
32362
33150
  if (existing) {
@@ -32395,7 +33183,7 @@ function ViewerToolbarSection(props) {
32395
33183
  },
32396
33184
  [activeSlide, propertyHandlers]
32397
33185
  );
32398
- const scopedLayoutOptions = React33.useMemo(
33186
+ const scopedLayoutOptions = React34.useMemo(
32399
33187
  () => scopeLayoutOptionsToActiveSlide(s.layoutOptions, activeSlide),
32400
33188
  [s.layoutOptions, activeSlide]
32401
33189
  );
@@ -32693,6 +33481,8 @@ function ViewerToolbarSection(props) {
32693
33481
  onOpenSettings,
32694
33482
  onRunAccessibilityCheck: dialogs.handleRunAccessibilityCheck,
32695
33483
  onToggleSlideSorter: () => s.setShowSlideSorter((p) => !p),
33484
+ onOpenReadingView: () => s.setShowReadingView(true),
33485
+ onOpenOutlineView: () => s.setShowOutlineView(true),
32696
33486
  onUpdateTextStyle: ops.updateSelectedTextStyle,
32697
33487
  onTransformTextCase: ops.updateSelectedTextCase,
32698
33488
  isOverflowMenuOpen: s.isOverflowMenuOpen,
@@ -32781,15 +33571,7 @@ function ViewerToolbarSection(props) {
32781
33571
  ] });
32782
33572
  }
32783
33573
  var TEMPLATES = EQUATION_TEMPLATES;
32784
- var TEMPLATE_MATHML = TEMPLATES.map((tmpl) => {
32785
- try {
32786
- const tmplOmml = convertLatexToOmml(tmpl.latex);
32787
- const raw = convertOmmlToMathMl(tmplOmml);
32788
- return raw ? sanitizeMathMl(raw) : "";
32789
- } catch {
32790
- return "";
32791
- }
32792
- });
33574
+ var TEMPLATE_MATHML = compileEquationTemplateMathMl();
32793
33575
  function MathMlPreview({ mathml }) {
32794
33576
  const containerRef = useRef(null);
32795
33577
  useEffect(() => {
@@ -32835,18 +33617,7 @@ function EquationEditorDialog({
32835
33617
  setLatex(initialLatex);
32836
33618
  }
32837
33619
  }, [isOpen, initialLatex]);
32838
- const { mathml, omml } = useMemo(() => {
32839
- if (!deferredLatex.trim()) {
32840
- return { mathml: "", omml: {} };
32841
- }
32842
- try {
32843
- const ommlObj = convertLatexToOmml(deferredLatex);
32844
- const mathmlStr = convertOmmlToMathMl(ommlObj);
32845
- return { mathml: mathmlStr, omml: ommlObj };
32846
- } catch {
32847
- return { mathml: "", omml: {} };
32848
- }
32849
- }, [deferredLatex]);
33620
+ const { mathml, omml } = useMemo(() => compileLatexEquation(deferredLatex), [deferredLatex]);
32850
33621
  const handleInsert = useCallback(() => {
32851
33622
  if (!latex.trim()) {
32852
33623
  return;
@@ -33553,6 +34324,10 @@ function PresentationStage({
33553
34324
  height: safeHeight,
33554
34325
  transform: `scale(${scale})`,
33555
34326
  transformOrigin: "top left",
34327
+ // Motion-path keyframes translate by a fraction of the SLIDE, so
34328
+ // the stage publishes its own size for those calc() offsets.
34329
+ "--pptx-slide-w": `${safeWidth}px`,
34330
+ "--pptx-slide-h": `${safeHeight}px`,
33556
34331
  ...getReactSlideBackgroundStyle(activeSlide)
33557
34332
  },
33558
34333
  children: [
@@ -33977,6 +34752,7 @@ ${url}`)) {
33977
34752
  ) : /* @__PURE__ */ jsx(
33978
34753
  SlideCanvas,
33979
34754
  {
34755
+ onUpdateSlideAnimations: props.onUpdateSlideAnimations,
33980
34756
  activeSlide: effectiveSlide,
33981
34757
  templateElements: effectiveTemplateElements,
33982
34758
  canvasSize,
@@ -34159,7 +34935,7 @@ ${url}`)) {
34159
34935
  )
34160
34936
  );
34161
34937
  }
34162
- var AiChatPanel = lazy(() => import('./AiChatPanel-6W6ZBAGU.mjs'));
34938
+ var AiChatPanel = lazy(() => import('./AiChatPanel-EX2TBRJM.mjs'));
34163
34939
  function AiChatPanelLazy(props) {
34164
34940
  return /* @__PURE__ */ jsx(
34165
34941
  Suspense,
@@ -35321,6 +36097,7 @@ function ViewerMainContent(props) {
35321
36097
  /* @__PURE__ */ jsx(
35322
36098
  ViewerCanvasArea,
35323
36099
  {
36100
+ onUpdateSlideAnimations: (animations) => propertyHandlers.handleUpdateSlide({ animations }),
35324
36101
  mode,
35325
36102
  canEdit,
35326
36103
  slides,
@@ -37733,6 +38510,9 @@ var PowerPointViewer = forwardRef(
37733
38510
  isShortcutHelpOpen: state.isShortcutHelpOpen,
37734
38511
  isAccessibilityPanelOpen: state.isAccessibilityPanelOpen,
37735
38512
  showSlideSorter: state.showSlideSorter,
38513
+ showReadingView: state.showReadingView,
38514
+ showOutlineView: state.showOutlineView,
38515
+ templateElements: state.templateElements,
37736
38516
  accessibilityIssues: state.accessibilityIssues,
37737
38517
  slides,
37738
38518
  activeSlideIndex,
@@ -37750,6 +38530,14 @@ var PowerPointViewer = forwardRef(
37750
38530
  onDuplicateSlides: editorOps.slideOps.handleDuplicateSlides,
37751
38531
  onToggleHideSlides: editorOps.slideOps.handleToggleHideSlides,
37752
38532
  onCloseSorter: () => state.setShowSlideSorter(false),
38533
+ onCloseReadingView: (slideIndex) => {
38534
+ state.setShowReadingView(false);
38535
+ state.setActiveSlideIndex(slideIndex);
38536
+ },
38537
+ onCloseOutlineView: () => state.setShowOutlineView(false),
38538
+ setSlides: state.setSlides,
38539
+ setActiveSlideIndex: state.setActiveSlideIndex,
38540
+ bumpHistory: () => state.setPointerCommitNonce((n) => n + 1),
37753
38541
  reducedMotion,
37754
38542
  onToggleReducedMotion: toggleReducedMotion
37755
38543
  }