pptx-react-viewer 1.25.4 → 2.0.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 (230) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +1 -1
  3. package/dist/AiChatPanel-BRGQCYZM.mjs +1087 -0
  4. package/dist/AiChatPanel-BRGQCYZM.mjs.br +0 -0
  5. package/dist/AiChatPanel-BRGQCYZM.mjs.gz +0 -0
  6. package/dist/AiChatPanel-PW5OT25Z.js +1089 -0
  7. package/dist/AiChatPanel-PW5OT25Z.js.br +0 -0
  8. package/dist/AiChatPanel-PW5OT25Z.js.gz +0 -0
  9. package/dist/{GLTFLoader-NMAS6VRH.mjs → GLTFLoader-374ZNTXW.mjs} +1 -1
  10. package/dist/GLTFLoader-374ZNTXW.mjs.br +0 -0
  11. package/dist/GLTFLoader-374ZNTXW.mjs.gz +0 -0
  12. package/dist/{GLTFLoader-GP55DVVS.js → GLTFLoader-Q7BHCGAW.js} +1 -1
  13. package/dist/GLTFLoader-Q7BHCGAW.js.br +0 -0
  14. package/dist/GLTFLoader-Q7BHCGAW.js.gz +0 -0
  15. package/dist/{Model3DScene-SP6WOKSX.js → Model3DScene-JCGYRKXM.js} +4 -4
  16. package/dist/{Model3DScene-SP6WOKSX.js.br → Model3DScene-JCGYRKXM.js.br} +0 -0
  17. package/dist/Model3DScene-JCGYRKXM.js.gz +0 -0
  18. package/dist/{Model3DScene-DZFYJPUH.mjs → Model3DScene-TEF362W2.mjs} +3 -3
  19. package/dist/Model3DScene-TEF362W2.mjs.br +0 -0
  20. package/dist/Model3DScene-TEF362W2.mjs.gz +0 -0
  21. package/dist/{OrbitControls-VH6KILH7.js → OrbitControls-SMYCPLXO.js} +1 -1
  22. package/dist/OrbitControls-SMYCPLXO.js.br +3 -0
  23. package/dist/OrbitControls-SMYCPLXO.js.gz +0 -0
  24. package/dist/{OrbitControls-F5XPYD2Z.mjs → OrbitControls-ZTGHPI5G.mjs} +1 -1
  25. package/dist/OrbitControls-ZTGHPI5G.mjs.br +0 -0
  26. package/dist/{OrbitControls-F5XPYD2Z.mjs.gz → OrbitControls-ZTGHPI5G.mjs.gz} +0 -0
  27. package/dist/{PowerPointViewer-CnADroqZ.d.ts → PowerPointViewer-gmU5rc7K.d.ts} +2 -2
  28. package/dist/PowerPointViewer-gmU5rc7K.d.ts.map +1 -0
  29. package/dist/{SmartArt3DScene-WQIDFZ7X.mjs → SmartArt3DScene-XCFVGCXE.mjs} +1 -1
  30. package/dist/SmartArt3DScene-XCFVGCXE.mjs.br +0 -0
  31. package/dist/SmartArt3DScene-XCFVGCXE.mjs.gz +0 -0
  32. package/dist/{SmartArt3DScene-HCQBDRAM.js → SmartArt3DScene-ZO3KFDI2.js} +1 -1
  33. package/dist/SmartArt3DScene-ZO3KFDI2.js.br +0 -0
  34. package/dist/SmartArt3DScene-ZO3KFDI2.js.gz +0 -0
  35. package/dist/{SurfaceChart3DScene-GISPZ4C2.js → SurfaceChart3DScene-2SHCYZVC.js} +4 -4
  36. package/dist/SurfaceChart3DScene-2SHCYZVC.js.br +0 -0
  37. package/dist/SurfaceChart3DScene-2SHCYZVC.js.gz +0 -0
  38. package/dist/{SurfaceChart3DScene-54BRNPQ5.mjs → SurfaceChart3DScene-UPDCIMJM.mjs} +3 -3
  39. package/dist/{SurfaceChart3DScene-54BRNPQ5.mjs.br → SurfaceChart3DScene-UPDCIMJM.mjs.br} +0 -0
  40. package/dist/SurfaceChart3DScene-UPDCIMJM.mjs.gz +0 -0
  41. package/dist/{animation-timeline-CEJJLFqK.d.ts → animation-timeline-eb5z0SHW.d.ts} +250 -8
  42. package/dist/animation-timeline-eb5z0SHW.d.ts.map +1 -0
  43. package/dist/{chunk-M3SIFXWD.mjs → chunk-2X72MOPZ.mjs} +65 -0
  44. package/dist/chunk-2X72MOPZ.mjs.br +0 -0
  45. package/dist/chunk-2X72MOPZ.mjs.gz +0 -0
  46. package/dist/{chunk-QGM4M3NI.js → chunk-4VNS5WPM.js} +5 -0
  47. package/dist/chunk-4VNS5WPM.js.br +0 -0
  48. package/dist/chunk-4VNS5WPM.js.gz +0 -0
  49. package/dist/{chunk-P72VQ7WE.mjs → chunk-5XLLRPMV.mjs} +8966 -16340
  50. package/dist/chunk-5XLLRPMV.mjs.br +0 -0
  51. package/dist/chunk-5XLLRPMV.mjs.gz +0 -0
  52. package/dist/{chunk-UYNOPUSG.mjs → chunk-6YXLGMTN.mjs} +4137 -1927
  53. package/dist/chunk-6YXLGMTN.mjs.br +0 -0
  54. package/dist/chunk-6YXLGMTN.mjs.gz +0 -0
  55. package/dist/chunk-B6NRDUHJ.mjs +8029 -0
  56. package/dist/chunk-B6NRDUHJ.mjs.br +0 -0
  57. package/dist/chunk-B6NRDUHJ.mjs.gz +0 -0
  58. package/dist/chunk-BHVCED34.mjs +16664 -0
  59. package/dist/chunk-BHVCED34.mjs.br +0 -0
  60. package/dist/chunk-BHVCED34.mjs.gz +0 -0
  61. package/dist/{chunk-FWF2SP6N.js → chunk-CLNGAVNH.js} +4142 -1926
  62. package/dist/chunk-CLNGAVNH.js.br +0 -0
  63. package/dist/chunk-CLNGAVNH.js.gz +0 -0
  64. package/dist/{chunk-2EFVXYNA.js → chunk-CUUYYYC5.js} +65 -0
  65. package/dist/chunk-CUUYYYC5.js.br +0 -0
  66. package/dist/chunk-CUUYYYC5.js.gz +0 -0
  67. package/dist/{chunk-TPG2WKHQ.mjs → chunk-L63RAVM7.mjs} +1286 -151
  68. package/dist/chunk-L63RAVM7.mjs.br +0 -0
  69. package/dist/chunk-L63RAVM7.mjs.gz +0 -0
  70. package/dist/{chunk-5VYVKFMS.js → chunk-LFXG7SGG.js} +2074 -939
  71. package/dist/chunk-LFXG7SGG.js.br +0 -0
  72. package/dist/chunk-LFXG7SGG.js.gz +0 -0
  73. package/dist/{chunk-6F4WVHS3.js → chunk-OKOJVSKJ.js} +4701 -656
  74. package/dist/chunk-OKOJVSKJ.js.br +0 -0
  75. package/dist/chunk-OKOJVSKJ.js.gz +0 -0
  76. package/dist/{chunk-VUC3UPLM.mjs → chunk-R2N2UYT7.mjs} +4647 -618
  77. package/dist/chunk-R2N2UYT7.mjs.br +0 -0
  78. package/dist/chunk-R2N2UYT7.mjs.gz +0 -0
  79. package/dist/chunk-SYPHGLIB.js +16701 -0
  80. package/dist/chunk-SYPHGLIB.js.br +0 -0
  81. package/dist/chunk-SYPHGLIB.js.gz +0 -0
  82. package/dist/{chunk-6DZX6EAA.mjs → chunk-XGB3TDIC.mjs} +5 -1
  83. package/dist/chunk-XGB3TDIC.mjs.br +0 -0
  84. package/dist/chunk-XGB3TDIC.mjs.gz +0 -0
  85. package/dist/chunk-ZB4NZRCI.js +11111 -0
  86. package/dist/chunk-ZB4NZRCI.js.br +0 -0
  87. package/dist/chunk-ZB4NZRCI.js.gz +0 -0
  88. package/dist/chunk-ZKDE3HJI.js +8121 -0
  89. package/dist/chunk-ZKDE3HJI.js.br +0 -0
  90. package/dist/chunk-ZKDE3HJI.js.gz +0 -0
  91. package/dist/{dist-QU6JIDAF.js → dist-4LUVI3SW.js} +587 -563
  92. package/dist/dist-4LUVI3SW.js.br +0 -0
  93. package/dist/dist-4LUVI3SW.js.gz +0 -0
  94. package/dist/dist-J6PC54PZ.mjs +2 -0
  95. package/dist/dist-J6PC54PZ.mjs.br +0 -0
  96. package/dist/dist-J6PC54PZ.mjs.gz +0 -0
  97. package/dist/i18n.js +5 -5
  98. package/dist/i18n.js.br +0 -0
  99. package/dist/i18n.js.gz +0 -0
  100. package/dist/i18n.mjs +2 -2
  101. package/dist/i18n.mjs.br +0 -0
  102. package/dist/i18n.mjs.gz +0 -0
  103. package/dist/{index-DWvM1PBB.d.ts → index-a8wcFjRJ.d.ts} +24 -7
  104. package/dist/index-a8wcFjRJ.d.ts.map +1 -0
  105. package/dist/index.d.ts +3333 -301
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +41 -39
  108. package/dist/index.js.br +0 -0
  109. package/dist/index.js.gz +0 -0
  110. package/dist/index.mjs +8 -6
  111. package/dist/index.mjs.br +0 -0
  112. package/dist/index.mjs.gz +0 -0
  113. package/dist/{hooks-unstable.d.ts → internals.d.ts} +1298 -795
  114. package/dist/internals.d.ts.map +1 -0
  115. package/dist/{hooks-unstable.js → internals.js} +81 -80
  116. package/dist/internals.js.br +0 -0
  117. package/dist/internals.js.gz +0 -0
  118. package/dist/{hooks-unstable.mjs → internals.mjs} +6 -5
  119. package/dist/internals.mjs.br +0 -0
  120. package/dist/internals.mjs.gz +0 -0
  121. package/dist/pptx-viewer.css +1 -1
  122. package/dist/pptx-viewer.css.br +0 -0
  123. package/dist/pptx-viewer.css.gz +0 -0
  124. package/dist/{three.module-7CXEVRKB.mjs → three.module-AC7ESV4W.mjs} +1 -1
  125. package/dist/three.module-AC7ESV4W.mjs.br +0 -0
  126. package/dist/three.module-AC7ESV4W.mjs.gz +0 -0
  127. package/dist/{three.module-CPZZFD2Q.js → three.module-GNNNRIMK.js} +1 -1
  128. package/dist/three.module-GNNNRIMK.js.br +0 -0
  129. package/dist/three.module-GNNNRIMK.js.gz +0 -0
  130. package/dist/{useViewerBuildingBlocks-ll3_ncCH.d.ts → useViewerBuildingBlocks-CjureTRf.d.ts} +185 -174
  131. package/dist/useViewerBuildingBlocks-CjureTRf.d.ts.map +1 -0
  132. package/dist/viewer/index.d.ts +692 -53
  133. package/dist/viewer/index.d.ts.map +1 -1
  134. package/dist/viewer/index.js +35 -33
  135. package/dist/viewer/index.js.br +0 -0
  136. package/dist/viewer/index.js.gz +0 -0
  137. package/dist/viewer/index.mjs +8 -6
  138. package/dist/viewer/index.mjs.br +0 -0
  139. package/dist/viewer/index.mjs.gz +0 -0
  140. package/dist/{y-webrtc-6CRYHAXH.mjs → y-webrtc-DGVURJIF.mjs} +1 -1
  141. package/dist/y-webrtc-DGVURJIF.mjs.br +0 -0
  142. package/dist/y-webrtc-DGVURJIF.mjs.gz +0 -0
  143. package/dist/{y-webrtc-QCZF75JW.js → y-webrtc-YN53KW3J.js} +5 -5
  144. package/dist/y-webrtc-YN53KW3J.js.br +0 -0
  145. package/dist/y-webrtc-YN53KW3J.js.gz +0 -0
  146. package/dist/{y-websocket-QJEM6VOB.js → y-websocket-HZCIQLM6.js} +1 -1
  147. package/dist/y-websocket-HZCIQLM6.js.br +0 -0
  148. package/dist/y-websocket-HZCIQLM6.js.gz +0 -0
  149. package/dist/{y-websocket-57Q3RNHC.mjs → y-websocket-P5LTAJ5T.mjs} +1 -1
  150. package/dist/y-websocket-P5LTAJ5T.mjs.br +0 -0
  151. package/dist/y-websocket-P5LTAJ5T.mjs.gz +0 -0
  152. package/dist/{yjs-Y7IYUWOG.mjs → yjs-FKGX4QHS.mjs} +1 -1
  153. package/dist/yjs-FKGX4QHS.mjs.br +0 -0
  154. package/dist/yjs-FKGX4QHS.mjs.gz +0 -0
  155. package/dist/{yjs-UH3EPF3C.js → yjs-HBLSEMHP.js} +1 -1
  156. package/dist/yjs-HBLSEMHP.js.br +0 -0
  157. package/dist/yjs-HBLSEMHP.js.gz +0 -0
  158. package/package.json +19 -7
  159. package/dist/GLTFLoader-GP55DVVS.js.br +0 -0
  160. package/dist/GLTFLoader-GP55DVVS.js.gz +0 -0
  161. package/dist/GLTFLoader-NMAS6VRH.mjs.br +0 -0
  162. package/dist/GLTFLoader-NMAS6VRH.mjs.gz +0 -0
  163. package/dist/Model3DScene-DZFYJPUH.mjs.br +0 -0
  164. package/dist/Model3DScene-DZFYJPUH.mjs.gz +0 -0
  165. package/dist/Model3DScene-SP6WOKSX.js.gz +0 -0
  166. package/dist/OrbitControls-F5XPYD2Z.mjs.br +0 -0
  167. package/dist/OrbitControls-VH6KILH7.js.br +0 -2
  168. package/dist/OrbitControls-VH6KILH7.js.gz +0 -0
  169. package/dist/PowerPointViewer-CnADroqZ.d.ts.map +0 -1
  170. package/dist/SmartArt3DScene-HCQBDRAM.js.br +0 -0
  171. package/dist/SmartArt3DScene-HCQBDRAM.js.gz +0 -0
  172. package/dist/SmartArt3DScene-WQIDFZ7X.mjs.br +0 -0
  173. package/dist/SmartArt3DScene-WQIDFZ7X.mjs.gz +0 -0
  174. package/dist/SurfaceChart3DScene-54BRNPQ5.mjs.gz +0 -0
  175. package/dist/SurfaceChart3DScene-GISPZ4C2.js.br +0 -0
  176. package/dist/SurfaceChart3DScene-GISPZ4C2.js.gz +0 -0
  177. package/dist/animation-timeline-CEJJLFqK.d.ts.map +0 -1
  178. package/dist/chunk-2EFVXYNA.js.br +0 -0
  179. package/dist/chunk-2EFVXYNA.js.gz +0 -0
  180. package/dist/chunk-5VYVKFMS.js.br +0 -0
  181. package/dist/chunk-5VYVKFMS.js.gz +0 -0
  182. package/dist/chunk-6DZX6EAA.mjs.br +0 -0
  183. package/dist/chunk-6DZX6EAA.mjs.gz +0 -0
  184. package/dist/chunk-6F4WVHS3.js.br +0 -0
  185. package/dist/chunk-6F4WVHS3.js.gz +0 -0
  186. package/dist/chunk-7FE27DDH.js +0 -18559
  187. package/dist/chunk-7FE27DDH.js.br +0 -0
  188. package/dist/chunk-7FE27DDH.js.gz +0 -0
  189. package/dist/chunk-FWF2SP6N.js.br +0 -0
  190. package/dist/chunk-FWF2SP6N.js.gz +0 -0
  191. package/dist/chunk-M3SIFXWD.mjs.br +0 -0
  192. package/dist/chunk-M3SIFXWD.mjs.gz +0 -0
  193. package/dist/chunk-P72VQ7WE.mjs.br +0 -0
  194. package/dist/chunk-P72VQ7WE.mjs.gz +0 -0
  195. package/dist/chunk-QGM4M3NI.js.br +0 -0
  196. package/dist/chunk-QGM4M3NI.js.gz +0 -0
  197. package/dist/chunk-TPG2WKHQ.mjs.br +0 -0
  198. package/dist/chunk-TPG2WKHQ.mjs.gz +0 -0
  199. package/dist/chunk-UYNOPUSG.mjs.br +0 -0
  200. package/dist/chunk-UYNOPUSG.mjs.gz +0 -0
  201. package/dist/chunk-VUC3UPLM.mjs.br +0 -0
  202. package/dist/chunk-VUC3UPLM.mjs.gz +0 -0
  203. package/dist/dist-QNYKM7YS.mjs +0 -2
  204. package/dist/dist-QNYKM7YS.mjs.br +0 -0
  205. package/dist/dist-QNYKM7YS.mjs.gz +0 -0
  206. package/dist/dist-QU6JIDAF.js.br +0 -0
  207. package/dist/dist-QU6JIDAF.js.gz +0 -0
  208. package/dist/hooks-unstable.d.ts.map +0 -1
  209. package/dist/hooks-unstable.js.br +0 -0
  210. package/dist/hooks-unstable.js.gz +0 -0
  211. package/dist/hooks-unstable.mjs.br +0 -0
  212. package/dist/hooks-unstable.mjs.gz +0 -0
  213. package/dist/index-DWvM1PBB.d.ts.map +0 -1
  214. package/dist/three.module-7CXEVRKB.mjs.br +0 -0
  215. package/dist/three.module-7CXEVRKB.mjs.gz +0 -0
  216. package/dist/three.module-CPZZFD2Q.js.br +0 -0
  217. package/dist/three.module-CPZZFD2Q.js.gz +0 -0
  218. package/dist/useViewerBuildingBlocks-ll3_ncCH.d.ts.map +0 -1
  219. package/dist/y-webrtc-6CRYHAXH.mjs.br +0 -0
  220. package/dist/y-webrtc-6CRYHAXH.mjs.gz +0 -0
  221. package/dist/y-webrtc-QCZF75JW.js.br +0 -0
  222. package/dist/y-webrtc-QCZF75JW.js.gz +0 -0
  223. package/dist/y-websocket-57Q3RNHC.mjs.br +0 -0
  224. package/dist/y-websocket-57Q3RNHC.mjs.gz +0 -0
  225. package/dist/y-websocket-QJEM6VOB.js.br +0 -0
  226. package/dist/y-websocket-QJEM6VOB.js.gz +0 -0
  227. package/dist/yjs-UH3EPF3C.js.br +0 -0
  228. package/dist/yjs-UH3EPF3C.js.gz +0 -0
  229. package/dist/yjs-Y7IYUWOG.mjs.br +0 -0
  230. package/dist/yjs-Y7IYUWOG.mjs.gz +0 -0
@@ -1,11 +1,13 @@
1
- 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, useReducedMotion, useViewerState, useViewerOptions, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useYjsDocumentSync, useFollowMode, useBroadcastFollower, resolvePalette, resolveStyle, layoutToCategory, wrapChrome, DEFAULT_FILL_COLOR, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getCropShapeClipPath, SLIDE_TRANSITION_OPTIONS, SLIDE_NAV_THUMBNAIL_WIDTH, scopeLayoutOptionsToActiveSlide, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, useCollaborativeState, 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, useVirtualizedSlides, useSwipeNavigation, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, 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, startPreviewAnimation, stopPreviewAnimation } from './chunk-P72VQ7WE.mjs';
2
- import { RULER_THICKNESS, RULER_FONT_SIZE, normalizeHexColor, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, svgLineCap, getElementTransform, ACTION_BUTTON_PRESETS, isEditableTextElement, getAriaRole, getAriaLabel, getAriaRoleDescription, getImageEffectsOpacity, getImageEffectsFilter, getElementTransformWithoutRotation, EQUATION_TEMPLATES, convertLatexToOmml, convertOmmlToMathMl, sanitizeMathMl, DEFAULT_VIEWER_OPTIONS, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, viewerOptionsToPreferences, applyPreferenceToOptions, listAutosaveSnapshots, deleteAutosaveSnapshot, buildSmartArtA11y, buildCssGradientFromShapeStyle, getElementLabel, themeToCssVars, DEFAULT_INSERT_CHART_TYPE, hasCopyableFormat, createBackstagePresentation, VIEWER_OPTIONS_TABS, DEFAULT_QUICK_ACCESS_COMMAND_IDS, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, resolveDrawingShapeNodeId, buildSummaryZoomView, getImageColorWashStyle, getPendingSelectionRestore, restoreSegmentSelection, getTextCompensationTransform, formatAxisValue, hasPressureVariation, getInkReplayStyles, INK_REPLAY_KEYFRAMES, resolveInkColor, resolveInkWidth, resolveInkOpacity, pressuresToWidths, getContentPartReplayStyles, resolveOleType, getOleTypeColor, getOleTypeLabel, shouldUseSvgWarp, getSlideBackgroundStyle, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, shouldConfirmExternalHyperlink, safeOpenUrl, isPpactionUrl, parsePpactionUrl, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, clampPercent, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, activateModalFocus, buildCollaborationShareUrl, presentationInkPath, mobileElapsedSince, isFirstSlide, isLastSlide, formatMobileElapsed, mobileSlideCounter, formatElapsed, computeInlineEditorRect, findSmartArtNodeText, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, 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, getWarpPath, TAB_ROW_ACTION_CLASSES, listBackstageRecentFiles, BACKSTAGE_NAV, INSERT_CHART_TYPES, SLIDE_VIRTUALIZATION_THRESHOLD, getShapeAdjustmentHandleDescriptor, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, formatSlideCounter, 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, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, getConnectionSites, generateTicks, getCommentMarkerPosition, buildThemeColorGrid, THEME_COLOR_LABELS, buildSmartArtPresetData, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, TABLE_STYLE_PRESETS, formatCommentTimestamp, DIRECTIONAL_PRESETS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, DUOTONE_PRESETS, ARTISTIC_EFFECTS, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS } from './chunk-VUC3UPLM.mjs';
3
- import { LOCALE_CATALOG, translationsEn } from './chunk-M3SIFXWD.mjs';
4
- import { hasShapeProperties, hasTextProperties, SWITCHABLE_LAYOUT_TYPES, isInkElement, isImageLikeElement, getLinkedTextBoxSegments, themeColorSchemesEqual, setSmartArtNodeStyle, updateSmartArtNodeText, getSubstituteFontFamily, THEME_COLOR_SCHEME_KEYS, chartDataChangeType, chartDataUpdatePoint, chartDataAddCategory, chartDataRemoveCategory, chartDataAddSeries, chartDataRemoveSeries, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, getOleObjectTypeLabel, pptxActionToElementAction, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, addSmartArtNodeAsChild, removeSmartArtNode, elementActionToPptxAction, switchSmartArtLayout, addSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode } from './chunk-UYNOPUSG.mjs';
5
- import React32, { createContext, useMemo, useState, useCallback, forwardRef, useEffect, useRef, useContext, Suspense, useLayoutEffect, useDeferredValue } from 'react';
1
+ import { computeFocusTargets, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, toRenderableParts } from './chunk-BHVCED34.mjs';
2
+ import { useReducedMotion, useViewerState, useViewerOptions, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useYjsDocumentSync, useFollowMode, useBroadcastFollower, scopeLayoutOptionsToActiveSlide, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, useCollaborativeState, useVirtualizedSlides, useSwipeNavigation, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, downloadBlob } from './chunk-5XLLRPMV.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_TRANSITION_OPTIONS, 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, startPreviewAnimation, stopPreviewAnimation } from './chunk-B6NRDUHJ.mjs';
4
+ import { RULER_THICKNESS, RULER_FONT_SIZE, normalizeHexColor, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, svgLineCap, getElementTransform, ACTION_BUTTON_PRESETS, isEditableTextElement, getAriaRole, getAriaLabel, getAriaRoleDescription, getImageEffectsOpacity, getImageEffectsFilter, getElementTransformWithoutRotation, EQUATION_TEMPLATES, convertLatexToOmml, convertOmmlToMathMl, sanitizeMathMl, DEFAULT_VIEWER_OPTIONS, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, viewerOptionsToPreferences, applyPreferenceToOptions, listAutosaveSnapshots, deleteAutosaveSnapshot, revealedSmartArtNodeCount, buildSmartArtA11y, buildCssGradientFromShapeStyle, resolveGroupChildFill, getGroupChildParentFill, getComputedEffectStyle, getSoftEdgeSvgFilter, getElementLabel, buildPreviewElements, 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, getPendingSelectionRestore, restoreSegmentSelection, getTextCompensationTransform, applyChartBuildReveal, formatAxisValue, hasPressureVariation, getInkReplayStyles, INK_REPLAY_KEYFRAMES, resolveInkColor, resolveInkWidth, resolveInkOpacity, pressuresToWidths, getContentPartReplayStyles, resolveOleType, getOleTypeColor, getOleTypeLabel, shouldUseSvgWarp, getSlideBackgroundStyle, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, shouldConfirmExternalHyperlink, safeOpenUrl, isPpactionUrl, parsePpactionUrl, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, clampPercent, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, activateModalFocus, buildCollaborationShareUrl, presentationInkPath, mobileElapsedSince, isFirstSlide, isLastSlide, formatMobileElapsed, mobileSlideCounter, formatElapsed, computeInlineEditorRect, findSmartArtNodeText, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, 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, getWarpPath, TAB_ROW_ACTION_CLASSES, listBackstageRecentFiles, BACKSTAGE_NAV, INSERT_CHART_TYPES, SLIDE_VIRTUALIZATION_THRESHOLD, getShapeAdjustmentHandleDescriptor, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, formatSlideCounter, 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, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, getConnectionSites, generateTicks, getCommentMarkerPosition, buildThemeColorGrid, THEME_COLOR_LABELS, buildSmartArtPresetData, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, TABLE_STYLE_PRESETS, withFrameSlides, withSlidesPerPage, formatCommentTimestamp, DIRECTIONAL_PRESETS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, DUOTONE_PRESETS, ARTISTIC_EFFECTS, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS } from './chunk-R2N2UYT7.mjs';
5
+ import { LOCALE_CATALOG, translationsEn } from './chunk-2X72MOPZ.mjs';
6
+ import { hasShapeProperties, hasTextProperties, SWITCHABLE_LAYOUT_TYPES, isInkElement, isImageLikeElement, getLinkedTextBoxSegments, themeColorSchemesEqual, setSmartArtNodeStyle, updateSmartArtNodeText, getSubstituteFontFamily, THEME_COLOR_SCHEME_KEYS, chartDataChangeType, chartDataUpdatePoint, chartDataAddCategory, chartDataRemoveCategory, chartDataAddSeries, chartDataRemoveSeries, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, getOleObjectTypeLabel, pptxActionToElementAction, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, addSmartArtNodeAsChild, removeSmartArtNode, elementActionToPptxAction, switchSmartArtLayout, addSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode } from './chunk-6YXLGMTN.mjs';
7
+ import React32, { createContext, useMemo, useState, useCallback, lazy, forwardRef, useEffect, useRef, useContext, Suspense, useLayoutEffect, useDeferredValue } from 'react';
6
8
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
9
  import { useTranslation } from 'react-i18next';
8
- 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, LuChevronUp, LuChevronDown, LuWifi, LuWifiOff, LuUsers, LuCopy, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuMenu, LuShare2, LuPanelLeft, LuPanelRight, LuArrowLeft, LuFolderOpen, LuPackage, LuFileImage, LuVideo, LuBox, LuClipboardPaste, LuScissors, LuPaintbrush, LuSquare, LuImage, LuDatabase, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuHighlighter, LuList, LuListOrdered, LuIndentDecrease, LuIndentIncrease, LuReplace, LuMousePointer2, LuShapes, LuPaintBucket, LuPenLine, LuSparkles, LuPalette, LuPencil, LuStar, LuMoveRight, LuMousePointerClick, LuClock3, LuMonitorPlay, LuListVideo, LuCaptions, LuCamera, LuEraser, LuRotateCcw, LuCircleHelp, LuSpellCheck, LuBookOpen, LuLanguages, LuGlobe, LuGitCompare, LuMessageSquarePlus, LuLockKeyhole, LuPanelTop, LuLayoutGrid, LuGrid3X3, LuPipette, LuRuler, LuZoomIn, LuMaximize2, LuCode, LuCaseSensitive, LuTimer, LuGripVertical, LuUpload, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuLink, LuGrid2X2, LuCopyPlus, LuCirclePlay, LuCirclePause, LuZoomOut, LuScan, LuMonitorOff, LuClipboardCopy, LuWand, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuFilePlus2, LuHouse, LuUser, LuHardDrive, LuLogIn, LuFolderPlus, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignJustify, LuColumns3, LuSpline, LuAlignHorizontalSpaceAround, LuAlignVerticalSpaceAround, LuMove, LuRadio, LuLockOpen, LuArrowDown, LuArrowUp, LuArrowRight, LuReply, LuBookmark } from 'react-icons/lu';
10
+ 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, LuMenu, LuSparkles, LuShare2, LuPanelLeft, LuPanelRight, LuArrowLeft, LuFolderOpen, LuPackage, LuFileImage, LuVideo, LuBox, LuClipboardPaste, LuScissors, LuPaintbrush, LuSquare, LuImage, 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, LuSpellCheck, LuBookOpen, LuLanguages, LuGlobe, LuGitCompare, LuMessageSquarePlus, LuLockKeyhole, LuPanelTop, LuLayoutGrid, LuGrid3X3, LuPipette, LuRuler, LuZoomIn, LuMaximize2, LuCode, LuCaseSensitive, LuTimer, LuGripVertical, LuLoaderCircle, LuUpload, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuLink, LuGrid2X2, LuCopyPlus, LuCirclePlay, LuCirclePause, LuZoomOut, LuScan, LuMonitorOff, LuClipboardCopy, LuWand, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuFilePlus2, LuHouse, LuUser, LuHardDrive, LuLogIn, LuFolderPlus, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignJustify, LuColumns3, LuSpline, LuAlignHorizontalSpaceAround, LuAlignVerticalSpaceAround, LuMove, LuRadio, LuLockOpen, LuArrowDown, LuArrowUp, LuArrowRight, LuReply, LuBookmark } from 'react-icons/lu';
9
11
 
10
12
  var ViewerThemeContext = createContext(void 0);
11
13
  function ViewerThemeProvider({ theme, children }) {
@@ -1334,7 +1336,7 @@ function AccountPage() {
1334
1336
  return void 0;
1335
1337
  });
1336
1338
  };
1337
- const version = "1.25.3" ;
1339
+ const version = "1.25.5" ;
1338
1340
  return /* @__PURE__ */ jsxs("div", { className: "mt-8 max-w-[700px] space-y-6", children: [
1339
1341
  /* @__PURE__ */ jsxs("section", { className: cardClass, children: [
1340
1342
  /* @__PURE__ */ jsxs("h2", { className: "flex items-center gap-2 text-sm font-semibold", children: [
@@ -1543,23 +1545,23 @@ function FileSection(p) {
1543
1545
  return /* @__PURE__ */ jsxs(
1544
1546
  "div",
1545
1547
  {
1546
- className: "fixed inset-0 z-[200] flex bg-background font-[Aptos,Segoe_UI,sans-serif] text-foreground",
1548
+ className: "fixed inset-0 z-[200] flex bg-background font-[Aptos,Segoe_UI,sans-serif] text-foreground max-md:flex-col",
1547
1549
  role: "dialog",
1548
1550
  "aria-modal": "true",
1549
1551
  "aria-label": "File",
1550
1552
  children: [
1551
- /* @__PURE__ */ jsxs("aside", { className: "flex w-[148px] shrink-0 flex-col border-r border-border bg-secondary", children: [
1553
+ /* @__PURE__ */ jsxs("aside", { className: "flex w-[148px] shrink-0 flex-col border-r border-border bg-secondary max-md:w-full max-md:flex-row max-md:items-center max-md:overflow-x-auto max-md:border-r-0 max-md:border-b", children: [
1552
1554
  /* @__PURE__ */ jsx(
1553
1555
  "button",
1554
1556
  {
1555
1557
  type: "button",
1556
1558
  "aria-label": "Back to presentation",
1557
1559
  onClick: p.onClose,
1558
- className: "grid h-47px min-h-[48px] place-items-center border-b border-border text-xl hover:bg-accent",
1560
+ className: "grid h-47px min-h-[48px] place-items-center border-b border-border text-xl hover:bg-accent max-md:min-w-[48px] max-md:shrink-0 max-md:border-b-0 max-md:border-r",
1559
1561
  children: /* @__PURE__ */ jsx(LuArrowLeft, {})
1560
1562
  }
1561
1563
  ),
1562
- /* @__PURE__ */ jsxs("nav", { className: "flex min-h-0 flex-1 flex-col py-2", children: [
1564
+ /* @__PURE__ */ jsxs("nav", { className: "flex min-h-0 flex-1 flex-col py-2 max-md:flex-row max-md:items-center max-md:py-0", children: [
1563
1565
  BACKSTAGE_NAV.filter(
1564
1566
  (item) => !item.group && !(item.id === "export" && exportHidden)
1565
1567
  ).map((item) => /* @__PURE__ */ jsxs(
@@ -1567,7 +1569,7 @@ function FileSection(p) {
1567
1569
  {
1568
1570
  type: "button",
1569
1571
  onClick: () => item.id === "close" ? p.onClose() : item.id === "save" ? run(p.onSaveAsPptx) : setPage(item.id),
1570
- className: `flex min-h-10 items-center gap-3 border-l-2 px-4 text-left text-[12px] ${page === item.id ? "border-primary bg-card text-primary" : "border-transparent hover:bg-accent"}`,
1572
+ className: `flex min-h-10 items-center gap-3 border-l-2 px-4 text-left text-[12px] max-md:shrink-0 max-md:whitespace-nowrap max-md:border-l-0 max-md:border-b-2 max-md:px-3 ${page === item.id ? "border-primary bg-card text-primary" : "border-transparent hover:bg-accent"}`,
1571
1573
  children: [
1572
1574
  /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
1573
1575
  item.label
@@ -1575,13 +1577,13 @@ function FileSection(p) {
1575
1577
  },
1576
1578
  item.id
1577
1579
  )),
1578
- /* @__PURE__ */ jsx("div", { className: "flex-1" }),
1580
+ /* @__PURE__ */ jsx("div", { className: "flex-1 max-md:hidden" }),
1579
1581
  BACKSTAGE_NAV.filter((item) => item.group).map((item) => /* @__PURE__ */ jsxs(
1580
1582
  "button",
1581
1583
  {
1582
1584
  type: "button",
1583
1585
  onClick: () => item.id === "options" && p.onOpenSettings ? run(p.onOpenSettings) : setPage(item.id),
1584
- className: `flex min-h-10 items-center gap-3 border-l-2 px-4 text-left text-[12px] ${page === item.id ? "border-primary bg-card text-primary" : "border-transparent hover:bg-accent"}`,
1586
+ className: `flex min-h-10 items-center gap-3 border-l-2 px-4 text-left text-[12px] max-md:shrink-0 max-md:whitespace-nowrap max-md:border-l-0 max-md:border-b-2 max-md:px-3 ${page === item.id ? "border-primary bg-card text-primary" : "border-transparent hover:bg-accent"}`,
1585
1587
  children: [
1586
1588
  /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
1587
1589
  item.label
@@ -1591,7 +1593,7 @@ function FileSection(p) {
1591
1593
  ))
1592
1594
  ] })
1593
1595
  ] }),
1594
- /* @__PURE__ */ jsxs("main", { className: "min-w-0 flex-1 overflow-y-auto bg-background px-[clamp(32px,4vw,72px)] py-5", children: [
1596
+ /* @__PURE__ */ jsxs("main", { className: "min-w-0 flex-1 overflow-y-auto bg-background px-[clamp(32px,4vw,72px)] py-5 max-md:px-4 max-md:py-4", children: [
1595
1597
  /* @__PURE__ */ jsx("h1", { className: "text-[24px] font-semibold", children: page === "home" ? "Good evening" : title }),
1596
1598
  (page === "home" || page === "new") && /* @__PURE__ */ jsx(
1597
1599
  BackstageNewGallery,
@@ -4296,6 +4298,17 @@ function MobileToolbar(props) {
4296
4298
  }
4297
4299
  ),
4298
4300
  /* @__PURE__ */ jsx("div", { className: "flex-1" }),
4301
+ showEdit && props.aiEnabled && /* @__PURE__ */ jsx(
4302
+ "button",
4303
+ {
4304
+ type: "button",
4305
+ onClick: props.onToggleAiPanel,
4306
+ className: cn(btn, props.isAiPanelOpen ? "text-primary" : void 0),
4307
+ title: t("pptx.toolbar.toggleAiAssistant"),
4308
+ "aria-label": t("pptx.toolbar.toggleAiAssistant"),
4309
+ children: /* @__PURE__ */ jsx(LuSparkles, { className: "w-5 h-5" })
4310
+ }
4311
+ ),
4299
4312
  /* @__PURE__ */ jsx(
4300
4313
  "button",
4301
4314
  {
@@ -5172,6 +5185,17 @@ function ToolbarPrimaryRow(p) {
5172
5185
  children: /* @__PURE__ */ jsx(LuPanelRight, { className: ic })
5173
5186
  }
5174
5187
  ),
5188
+ p.aiEnabled && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
5189
+ "button",
5190
+ {
5191
+ type: "button",
5192
+ onClick: p.onToggleAiPanel,
5193
+ className: cn(qab, p.isAiPanelOpen ? "text-primary" : "text-muted-foreground"),
5194
+ title: t("pptx.toolbar.toggleAiAssistant"),
5195
+ "aria-label": t("pptx.toolbar.toggleAiAssistant"),
5196
+ children: /* @__PURE__ */ jsx(LuSparkles, { className: ic })
5197
+ }
5198
+ ),
5175
5199
  /* @__PURE__ */ jsx(
5176
5200
  "button",
5177
5201
  {
@@ -7209,7 +7233,11 @@ function getContainerStyle({
7209
7233
  has3DExtrusion,
7210
7234
  templateEditing
7211
7235
  }) {
7212
- const overflowValue = has3DExtrusion ? "visible" : isImg ? "hidden" : void 0;
7236
+ const ss = hasShapeProperties(el) ? el.shapeStyle : void 0;
7237
+ const blurGrowVisible = Boolean(
7238
+ ss?.blurGrow && typeof ss.blurRadius === "number" && ss.blurRadius > 0
7239
+ );
7240
+ const overflowValue = has3DExtrusion || blurGrowVisible ? "visible" : isImg ? "hidden" : void 0;
7213
7241
  return {
7214
7242
  left: isFullscreenMedia ? 0 : el.x,
7215
7243
  top: isFullscreenMedia ? 0 : el.y,
@@ -7293,7 +7321,8 @@ function ensureInteractionStyles() {
7293
7321
  function ChartElementView({
7294
7322
  element,
7295
7323
  editable,
7296
- onUpdateElement
7324
+ onUpdateElement,
7325
+ animationState
7297
7326
  }) {
7298
7327
  const wrapperRef = useRef(null);
7299
7328
  const dragRef = useRef(null);
@@ -7439,7 +7468,10 @@ function ChartElementView({
7439
7468
  }
7440
7469
  setTitleDraft(null);
7441
7470
  };
7442
- const renderedElement = previewData ? { ...element, chartData: previewData } : element;
7471
+ const baseChartData = previewData ?? element.chartData;
7472
+ const chartBuild = animationState?.build?.kind === "chart" ? animationState.build : void 0;
7473
+ const revealedChartData = chartBuild && baseChartData ? applyChartBuildReveal(baseChartData, chartBuild) : baseChartData;
7474
+ const renderedElement = revealedChartData === element.chartData ? element : { ...element, chartData: revealedChartData };
7443
7475
  return /* @__PURE__ */ jsxs(
7444
7476
  "div",
7445
7477
  {
@@ -7715,6 +7747,38 @@ function renderImg(el, style, filter, alt, opacity) {
7715
7747
  )
7716
7748
  ] });
7717
7749
  }
7750
+ function ShapeEffectOverlay({
7751
+ element
7752
+ }) {
7753
+ if (!hasShapeProperties(element)) {
7754
+ return null;
7755
+ }
7756
+ const overlay = getComputedEffectStyle(element).fillOverlay;
7757
+ const softEdge = getSoftEdgeSvgFilter(element.shapeStyle, element.id);
7758
+ if (!overlay && !softEdge) {
7759
+ return null;
7760
+ }
7761
+ const fillOverlayStyle = overlay ? {
7762
+ position: "absolute",
7763
+ inset: 0,
7764
+ background: overlay.color,
7765
+ mixBlendMode: overlay.blendMode,
7766
+ pointerEvents: "none"
7767
+ } : void 0;
7768
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7769
+ softEdge ? /* @__PURE__ */ jsx(
7770
+ "svg",
7771
+ {
7772
+ width: 0,
7773
+ height: 0,
7774
+ "aria-hidden": "true",
7775
+ style: { position: "absolute", width: 0, height: 0, overflow: "hidden" },
7776
+ children: /* @__PURE__ */ jsx("defs", { dangerouslySetInnerHTML: { __html: softEdge.filterMarkup } })
7777
+ }
7778
+ ) : null,
7779
+ fillOverlayStyle ? /* @__PURE__ */ jsx("div", { className: "pptx-react-fill-overlay", "aria-hidden": "true", style: fillOverlayStyle }) : null
7780
+ ] });
7781
+ }
7718
7782
  function renderPressureStroke(pathD, widths, baseWidth, color, opacity, keyPrefix) {
7719
7783
  const points = extractPathPoints(pathD);
7720
7784
  const circles = generatePressureCircles(points, widths, {
@@ -7779,15 +7843,24 @@ function renderInk(el, options) {
7779
7843
  }
7780
7844
  );
7781
7845
  }
7782
- function renderGroup(children) {
7846
+ function renderGroup(children, parentGroupFill) {
7783
7847
  return /* @__PURE__ */ jsx("div", { className: "relative w-full h-full pointer-events-none", children: children.map((c, childIndex) => {
7784
7848
  const { hf, fc, sw, sc } = shapeParams(c);
7785
- const ss = getShapeVisualStyle(c, hf, fc, sw, sc);
7849
+ const baseSs = getShapeVisualStyle(c, hf, fc, sw, sc);
7850
+ const inheritedFill = resolveGroupChildFill(c, parentGroupFill);
7851
+ const ss = inheritedFill ? {
7852
+ ...baseSs,
7853
+ backgroundColor: inheritedFill.backgroundColor,
7854
+ backgroundImage: inheritedFill.backgroundImage,
7855
+ backgroundRepeat: inheritedFill.backgroundRepeat,
7856
+ backgroundSize: inheritedFill.backgroundSize,
7857
+ backgroundPosition: inheritedFill.backgroundPosition
7858
+ } : baseSs;
7786
7859
  const vs = renderVectorShape(c, hf, fc, sw, sc);
7787
7860
  const ts = getTextStyleForElement(c, DEFAULT_TEXT_COLOR);
7788
7861
  const isTxt = isEditableTextElement(c);
7789
7862
  const isI = c.type === "picture" || c.type === "image";
7790
- return /* @__PURE__ */ jsx(
7863
+ return /* @__PURE__ */ jsxs(
7791
7864
  "div",
7792
7865
  {
7793
7866
  className: "absolute",
@@ -7807,32 +7880,35 @@ function renderGroup(children) {
7807
7880
  // Placed after ...ss to ensure it is never overwritten.
7808
7881
  zIndex: childIndex
7809
7882
  },
7810
- children: isI && ("svgData" in c && c.svgData || "imageData" in c && c.imageData) ? isImageTiled(c) ? /* @__PURE__ */ jsx(
7811
- "div",
7812
- {
7813
- className: "pointer-events-none select-none w-full h-full",
7814
- style: getImageTilingStyle(c)
7815
- }
7816
- ) : /* @__PURE__ */ jsx(
7817
- "img",
7818
- {
7819
- src: "svgData" in c && c.svgData ? c.svgData : c.imageData,
7820
- alt: translationsEn["pptx.ink.groupChildAlt"],
7821
- className: "pointer-events-none select-none",
7822
- style: getImageRenderStyle(c),
7823
- draggable: false
7824
- }
7825
- ) : /* @__PURE__ */ jsxs(Fragment, { children: [
7826
- vs,
7827
- isTxt ? /* @__PURE__ */ jsx(
7883
+ children: [
7884
+ /* @__PURE__ */ jsx(ShapeEffectOverlay, { element: c }),
7885
+ isI && ("svgData" in c && c.svgData || "imageData" in c && c.imageData) ? isImageTiled(c) ? /* @__PURE__ */ jsx(
7828
7886
  "div",
7829
7887
  {
7830
- className: "relative z-10 w-full h-full pointer-events-none whitespace-pre-wrap break-words leading-[1.3]",
7831
- style: ts,
7832
- children: renderTextSegments(c, DEFAULT_TEXT_COLOR)
7888
+ className: "pointer-events-none select-none w-full h-full",
7889
+ style: getImageTilingStyle(c)
7833
7890
  }
7834
- ) : null
7835
- ] })
7891
+ ) : /* @__PURE__ */ jsx(
7892
+ "img",
7893
+ {
7894
+ src: "svgData" in c && c.svgData ? c.svgData : c.imageData,
7895
+ alt: translationsEn["pptx.ink.groupChildAlt"],
7896
+ className: "pointer-events-none select-none",
7897
+ style: getImageRenderStyle(c),
7898
+ draggable: false
7899
+ }
7900
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
7901
+ vs,
7902
+ isTxt ? /* @__PURE__ */ jsx(
7903
+ "div",
7904
+ {
7905
+ className: "relative z-10 w-full h-full pointer-events-none whitespace-pre-wrap break-words leading-[1.3]",
7906
+ style: ts,
7907
+ children: renderTextSegments(c, DEFAULT_TEXT_COLOR)
7908
+ }
7909
+ ) : null
7910
+ ] })
7911
+ ]
7836
7912
  },
7837
7913
  c.id
7838
7914
  );
@@ -8264,7 +8340,7 @@ function FailedToLoad() {
8264
8340
  var LazyModel3DScene = React32.lazy(
8265
8341
  async () => {
8266
8342
  try {
8267
- return await import('./Model3DScene-DZFYJPUH.mjs');
8343
+ return await import('./Model3DScene-TEF362W2.mjs');
8268
8344
  } catch {
8269
8345
  return { default: FailedToLoad };
8270
8346
  }
@@ -8366,7 +8442,7 @@ function Model3DRenderer({ element, width, height, interactive }) {
8366
8442
  const [threeAvailable, setThreeAvailable] = useState(null);
8367
8443
  useEffect(() => {
8368
8444
  let cancelled = false;
8369
- import('./three.module-7CXEVRKB.mjs').then(() => {
8445
+ import('./three.module-AC7ESV4W.mjs').then(() => {
8370
8446
  if (!cancelled) {
8371
8447
  setThreeAvailable(true);
8372
8448
  }
@@ -9996,7 +10072,8 @@ function SmartArtRendererImpl({
9996
10072
  element,
9997
10073
  className = "",
9998
10074
  canEdit = false,
9999
- onUpdateElement
10075
+ onUpdateElement,
10076
+ animationState
10000
10077
  }) {
10001
10078
  const { t } = useTranslation();
10002
10079
  if (element.type !== "smartArt" || !element.smartArtData) {
@@ -10010,6 +10087,14 @@ function SmartArtRendererImpl({
10010
10087
  }
10011
10088
  const smartArtData = element.smartArtData;
10012
10089
  const { nodes, drawingShapes, chrome } = smartArtData;
10090
+ const diagramBuild = animationState?.build?.kind === "diagram" ? animationState.build : void 0;
10091
+ const shownNodeCount = diagramBuild ? revealedSmartArtNodeCount(nodes, diagramBuild) : nodes.length;
10092
+ const isPartialBuild = diagramBuild !== void 0 && shownNodeCount < nodes.length;
10093
+ const revealedNodes = isPartialBuild ? nodes.slice(0, shownNodeCount) : nodes;
10094
+ const revealedShapes = isPartialBuild && drawingShapes && drawingShapes.length > 0 ? drawingShapes.slice(
10095
+ 0,
10096
+ Math.ceil(shownNodeCount / Math.max(nodes.length, 1) * drawingShapes.length)
10097
+ ) : drawingShapes;
10013
10098
  if (nodes.length === 0) {
10014
10099
  return /* @__PURE__ */ jsx(
10015
10100
  "div",
@@ -10059,12 +10144,12 @@ function SmartArtRendererImpl({
10059
10144
  }
10060
10145
  };
10061
10146
  let content;
10062
- if (drawingShapes && drawingShapes.length > 0) {
10147
+ if (revealedShapes && revealedShapes.length > 0) {
10063
10148
  content = /* @__PURE__ */ jsx(
10064
10149
  DrawingShapeRenderer,
10065
10150
  {
10066
10151
  elementId: element.id,
10067
- shapes: drawingShapes,
10152
+ shapes: revealedShapes,
10068
10153
  style,
10069
10154
  palette,
10070
10155
  nodes,
@@ -10074,7 +10159,7 @@ function SmartArtRendererImpl({
10074
10159
  } else {
10075
10160
  const namedLayout = smartArtData.layout;
10076
10161
  const layoutType = namedLayout ? layoutToCategory(namedLayout) : (smartArtData.resolvedLayoutType ?? smartArtData.layoutType ?? "list").toLowerCase();
10077
- content = renderLayout(layoutType, element, nodes, palette, style, nodeLabels);
10162
+ content = renderLayout(layoutType, element, revealedNodes, palette, style, nodeLabels);
10078
10163
  }
10079
10164
  const body = editable ? /* @__PURE__ */ jsx(
10080
10165
  SmartArtEditableLayer,
@@ -10218,6 +10303,11 @@ function arePropsEqual(prev, next) {
10218
10303
  if (prevData !== nextData) {
10219
10304
  return false;
10220
10305
  }
10306
+ const prevBuild = prev.animationState?.build;
10307
+ const nextBuild = next.animationState?.build;
10308
+ if (prevBuild?.kind !== nextBuild?.kind || prevBuild?.mode !== nextBuild?.mode || prevBuild?.progress !== nextBuild?.progress) {
10309
+ return false;
10310
+ }
10221
10311
  return true;
10222
10312
  }
10223
10313
  var SmartArtRenderer = React32.memo(SmartArtRendererImpl, arePropsEqual);
@@ -10227,7 +10317,7 @@ function FailedToLoad2() {
10227
10317
  var LazySmartArt3DScene = React32.lazy(
10228
10318
  async () => {
10229
10319
  try {
10230
- return await import('./SmartArt3DScene-WQIDFZ7X.mjs');
10320
+ return await import('./SmartArt3DScene-XCFVGCXE.mjs');
10231
10321
  } catch {
10232
10322
  return { default: FailedToLoad2 };
10233
10323
  }
@@ -10255,7 +10345,7 @@ function SmartArt3DRenderer({
10255
10345
  const [threeAvailable, setThreeAvailable] = useState(null);
10256
10346
  useEffect(() => {
10257
10347
  let cancelled = false;
10258
- import('./three.module-7CXEVRKB.mjs').then(() => {
10348
+ import('./three.module-AC7ESV4W.mjs').then(() => {
10259
10349
  if (!cancelled) {
10260
10350
  setThreeAvailable(true);
10261
10351
  }
@@ -10339,7 +10429,8 @@ function SmartArtElement({
10339
10429
  element,
10340
10430
  className,
10341
10431
  canEdit,
10342
- onUpdateElement
10432
+ onUpdateElement,
10433
+ animationState
10343
10434
  }) {
10344
10435
  const use3D = useContext(SmartArt3DContext);
10345
10436
  if (use3D) {
@@ -10359,7 +10450,8 @@ function SmartArtElement({
10359
10450
  element,
10360
10451
  className,
10361
10452
  canEdit,
10362
- onUpdateElement
10453
+ onUpdateElement,
10454
+ animationState
10363
10455
  }
10364
10456
  );
10365
10457
  }
@@ -10564,7 +10656,9 @@ function renderTextElementBody(options) {
10564
10656
  hasTextProperties(el) ? el.textStyle?.textWarpPreset : void 0
10565
10657
  );
10566
10658
  const scene3dStyle = hasTextProperties(el) ? buildTextBody3DSceneStyle(el.textStyle) : void 0;
10567
- const composedTransform = [getTextCompensationTransform(el), scene3dStyle?.transform].filter(Boolean).join(" ") || void 0;
10659
+ const bodyRotation = hasTextProperties(el) ? el.textStyle?.textBodyRotation : void 0;
10660
+ const rotationTransform = typeof bodyRotation === "number" && Number.isFinite(bodyRotation) && bodyRotation !== 0 ? `rotate(${bodyRotation}deg)` : void 0;
10661
+ const composedTransform = [rotationTransform, getTextCompensationTransform(el), scene3dStyle?.transform].filter(Boolean).join(" ") || void 0;
10568
10662
  const transformStyle = {
10569
10663
  transform: composedTransform,
10570
10664
  transformOrigin: "center",
@@ -10872,8 +10966,10 @@ function renderBody(options) {
10872
10966
  canEditSmartArt,
10873
10967
  onUpdateSmartArtElement,
10874
10968
  canEditChart,
10875
- onUpdateChartElement
10969
+ onUpdateChartElement,
10970
+ presentationElementStates
10876
10971
  } = options;
10972
+ const animationState = presentationElementStates?.get(el.id);
10877
10973
  if (el.type === "model3d") {
10878
10974
  return /* @__PURE__ */ jsx(
10879
10975
  Model3DRenderer,
@@ -10939,7 +11035,8 @@ function renderBody(options) {
10939
11035
  {
10940
11036
  element: el,
10941
11037
  editable: Boolean(isSel && canEditChart),
10942
- onUpdateElement: onUpdateChartElement
11038
+ onUpdateElement: onUpdateChartElement,
11039
+ animationState
10943
11040
  }
10944
11041
  );
10945
11042
  }
@@ -10949,7 +11046,8 @@ function renderBody(options) {
10949
11046
  {
10950
11047
  element: el,
10951
11048
  canEdit: canEditSmartArt,
10952
- onUpdateElement: onUpdateSmartArtElement
11049
+ onUpdateElement: onUpdateSmartArtElement,
11050
+ animationState
10953
11051
  }
10954
11052
  );
10955
11053
  }
@@ -10977,7 +11075,7 @@ function renderBody(options) {
10977
11075
  if (renderGroupChild) {
10978
11076
  return /* @__PURE__ */ jsx("div", { className: "relative w-full h-full pointer-events-none", children: el.children.map(renderGroupChild) });
10979
11077
  }
10980
- return renderGroup(el.children);
11078
+ return renderGroup(el.children, el.groupFill);
10981
11079
  }
10982
11080
  if (shouldRenderFallbackLabel(el, isTxtEl)) {
10983
11081
  return /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: getElementLabel(el) });
@@ -11049,20 +11147,32 @@ function StaticElementRendererImpl({
11049
11147
  mediaDataUrls = EMPTY_MEDIA_DATA_URLS,
11050
11148
  sourceSlideIndex,
11051
11149
  zIndex,
11052
- positioned = true
11150
+ positioned = true,
11151
+ fieldContext,
11152
+ tableStyleContext,
11153
+ parentGroupFill
11053
11154
  }) {
11054
11155
  const style = hasShapeProperties(element) ? element.shapeStyle : void 0;
11055
11156
  const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
11056
11157
  const fill = normalizeHexColor(style?.fillColor, DEFAULT_FILL_COLOR);
11057
11158
  const strokeWidth = Math.max(0, style?.strokeWidth || 0);
11058
11159
  const stroke = normalizeHexColor(style?.strokeColor, DEFAULT_STROKE_COLOR);
11059
- const visualStyle = getShapeVisualStyle(element, hasFill, fill, strokeWidth, stroke);
11160
+ const baseVisualStyle = getShapeVisualStyle(element, hasFill, fill, strokeWidth, stroke);
11161
+ const inheritedFill = resolveGroupChildFill(element, parentGroupFill);
11162
+ const visualStyle = inheritedFill ? {
11163
+ ...baseVisualStyle,
11164
+ backgroundColor: inheritedFill.backgroundColor,
11165
+ backgroundImage: inheritedFill.backgroundImage,
11166
+ backgroundRepeat: inheritedFill.backgroundRepeat,
11167
+ backgroundSize: inheritedFill.backgroundSize,
11168
+ backgroundPosition: inheritedFill.backgroundPosition
11169
+ } : baseVisualStyle;
11060
11170
  const textStyle = getTextStyleForElement(
11061
11171
  element,
11062
11172
  element.type === "shape" && hasFill ? "#ffffff" : DEFAULT_TEXT_COLOR
11063
11173
  );
11064
11174
  const isImage = element.type === "picture" || element.type === "image";
11065
- return /* @__PURE__ */ jsx(
11175
+ return /* @__PURE__ */ jsxs(
11066
11176
  "div",
11067
11177
  {
11068
11178
  "data-static-element-type": element.type,
@@ -11077,46 +11187,54 @@ function StaticElementRendererImpl({
11077
11187
  zIndex,
11078
11188
  ...visualStyle
11079
11189
  },
11080
- children: element.type === "group" ? /* @__PURE__ */ jsx("div", { className: "relative w-full h-full", children: (element.children ?? []).map((child, index) => /* @__PURE__ */ jsx(
11081
- StaticElementRenderer,
11082
- {
11083
- element: child,
11084
- activeSlide,
11190
+ children: [
11191
+ /* @__PURE__ */ jsx(ShapeEffectOverlay, { element }),
11192
+ element.type === "group" ? /* @__PURE__ */ jsx("div", { className: "relative w-full h-full", children: (element.children ?? []).map((child, index) => /* @__PURE__ */ jsx(
11193
+ StaticElementRenderer,
11194
+ {
11195
+ element: child,
11196
+ activeSlide,
11197
+ allSlides,
11198
+ mediaDataUrls,
11199
+ sourceSlideIndex,
11200
+ zIndex: index,
11201
+ fieldContext,
11202
+ tableStyleContext,
11203
+ parentGroupFill: getGroupChildParentFill(element)
11204
+ },
11205
+ child.id
11206
+ )) }) : renderBody({
11207
+ el: element,
11208
+ isImg: isImage,
11209
+ isEditing: false,
11210
+ editText: "",
11211
+ spellCheck: false,
11212
+ txtSE: hasTextProperties(element) ? element.textStyle : void 0,
11213
+ txtS: textStyle,
11214
+ vecShape: renderVectorShape(element, hasFill, fill, strokeWidth, stroke),
11215
+ imgStyle: getImageRenderStyle(element),
11216
+ imgFilter: getImageEffectsFilter(element),
11217
+ imgOpacity: getImageEffectsOpacity(element),
11218
+ imgAlt: "",
11219
+ isTxtEl: isEditableTextElement(element),
11220
+ media: mediaDataUrls,
11221
+ tableSt: null,
11222
+ isSel: false,
11223
+ doInk: true,
11224
+ doGrp: false,
11225
+ onEditChange: noop,
11226
+ onCommit: noop,
11227
+ onCancel: noop,
11228
+ isPresentationPassive: false,
11229
+ slideElements: activeSlide?.elements,
11085
11230
  allSlides,
11086
- mediaDataUrls,
11087
11231
  sourceSlideIndex,
11088
- zIndex: index
11089
- },
11090
- child.id
11091
- )) }) : renderBody({
11092
- el: element,
11093
- isImg: isImage,
11094
- isEditing: false,
11095
- editText: "",
11096
- spellCheck: false,
11097
- txtSE: hasTextProperties(element) ? element.textStyle : void 0,
11098
- txtS: textStyle,
11099
- vecShape: renderVectorShape(element, hasFill, fill, strokeWidth, stroke),
11100
- imgStyle: getImageRenderStyle(element),
11101
- imgFilter: getImageEffectsFilter(element),
11102
- imgOpacity: getImageEffectsOpacity(element),
11103
- imgAlt: "",
11104
- isTxtEl: isEditableTextElement(element),
11105
- media: mediaDataUrls,
11106
- tableSt: null,
11107
- isSel: false,
11108
- doInk: true,
11109
- doGrp: false,
11110
- onEditChange: noop,
11111
- onCommit: noop,
11112
- onCancel: noop,
11113
- isPresentationPassive: false,
11114
- slideElements: activeSlide?.elements,
11115
- allSlides,
11116
- sourceSlideIndex,
11117
- canEditSmartArt: false,
11118
- canEditChart: false
11119
- })
11232
+ fieldContext,
11233
+ tableStyleContext,
11234
+ canEditSmartArt: false,
11235
+ canEditChart: false
11236
+ })
11237
+ ]
11120
11238
  }
11121
11239
  );
11122
11240
  }
@@ -11185,9 +11303,25 @@ var ElementRenderer = React32.memo(
11185
11303
  const elementLocks = el.locks;
11186
11304
  const isTxt = isEditableTextElement(el) && !elementLocks?.noTextEdit;
11187
11305
  const txtSE = hasTextProperties(el) ? el.textStyle : void 0;
11188
- const ss = getShapeVisualStyle(el, hf, fc, sw, sc);
11306
+ const ss = getShapeVisualStyle(
11307
+ el,
11308
+ hf,
11309
+ fc,
11310
+ sw,
11311
+ sc,
11312
+ animationState?.animatesFill,
11313
+ animationState?.animatesStroke
11314
+ );
11189
11315
  const ts = getTextStyleForElement(el, DEFAULT_TEXT_COLOR);
11190
- const vs = renderVectorShape(el, hf, fc, sw, sc);
11316
+ const vs = renderVectorShape(
11317
+ el,
11318
+ hf,
11319
+ fc,
11320
+ sw,
11321
+ sc,
11322
+ animationState?.animatesFill,
11323
+ animationState?.animatesStroke
11324
+ );
11191
11325
  const isImg = el.type === "picture" || el.type === "image";
11192
11326
  const isModel3D = el.type === "model3d";
11193
11327
  const isConn = isConnectorOrLineElement(el);
@@ -11280,6 +11414,7 @@ var ElementRenderer = React32.memo(
11280
11414
  ...interactionProps,
11281
11415
  children: [
11282
11416
  renderDagDuotoneFilterForElement(el),
11417
+ /* @__PURE__ */ jsx(ShapeEffectOverlay, { element: el }),
11283
11418
  extrusionData.hasExtrusion && /* @__PURE__ */ jsx(Extrusion3DOverlay, { data: extrusionData }),
11284
11419
  renderBody({
11285
11420
  el,
@@ -11308,7 +11443,8 @@ var ElementRenderer = React32.memo(
11308
11443
  allSlides,
11309
11444
  mediaDataUrls,
11310
11445
  sourceSlideIndex,
11311
- zIndex: index
11446
+ zIndex: index,
11447
+ parentGroupFill: getGroupChildParentFill(el)
11312
11448
  },
11313
11449
  child.id
11314
11450
  ),
@@ -11367,6 +11503,74 @@ var ElementRenderer = React32.memo(
11367
11503
  );
11368
11504
  }
11369
11505
  );
11506
+ var PLACEHOLDER_WIDTH = 120;
11507
+ var PLACEHOLDER_HEIGHT = 40;
11508
+ function ActiveXControlOverlay({
11509
+ controls,
11510
+ canvasSize,
11511
+ resolveFallbackImage
11512
+ }) {
11513
+ if (controls.length === 0) {
11514
+ return null;
11515
+ }
11516
+ return /* @__PURE__ */ jsx("div", { className: "absolute inset-0 pointer-events-none z-[40]", children: controls.map((control, idx) => {
11517
+ const width = control.width ?? PLACEHOLDER_WIDTH;
11518
+ const height = control.height ?? PLACEHOLDER_HEIGHT;
11519
+ const left = control.x ?? 8;
11520
+ const top = control.y ?? 8 + idx * (PLACEHOLDER_HEIGHT + 6);
11521
+ const clampedWidth = Math.min(width, canvasSize.width);
11522
+ const clampedHeight = Math.min(height, canvasSize.height);
11523
+ const imageUrl = control.fallbackImageRelId ? resolveFallbackImage?.(control.fallbackImageRelId) : void 0;
11524
+ const label = control.name || "ActiveX control";
11525
+ if (imageUrl) {
11526
+ return /* @__PURE__ */ jsx(
11527
+ "img",
11528
+ {
11529
+ src: imageUrl,
11530
+ alt: label,
11531
+ title: `ActiveX control: ${label}`,
11532
+ className: "absolute",
11533
+ style: { left, top, width: clampedWidth, height: clampedHeight }
11534
+ },
11535
+ `${control.relId}-${idx}`
11536
+ );
11537
+ }
11538
+ return /* @__PURE__ */ jsxs(
11539
+ "div",
11540
+ {
11541
+ className: "absolute",
11542
+ title: `ActiveX control: ${label} (interactive controls are not supported in the viewer)`,
11543
+ style: {
11544
+ left,
11545
+ top,
11546
+ width: clampedWidth,
11547
+ height: clampedHeight,
11548
+ display: "flex",
11549
+ alignItems: "center",
11550
+ justifyContent: "center",
11551
+ gap: 6,
11552
+ padding: "2px 6px",
11553
+ boxSizing: "border-box",
11554
+ border: "1px dashed rgba(100, 116, 139, 0.8)",
11555
+ borderRadius: 4,
11556
+ background: "rgba(148, 163, 184, 0.14)",
11557
+ color: "rgb(51, 65, 85)",
11558
+ fontSize: 11,
11559
+ fontWeight: 600,
11560
+ lineHeight: 1.2,
11561
+ overflow: "hidden",
11562
+ textOverflow: "ellipsis",
11563
+ whiteSpace: "nowrap"
11564
+ },
11565
+ children: [
11566
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2699" }),
11567
+ /* @__PURE__ */ jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: label })
11568
+ ]
11569
+ },
11570
+ `${control.relId}-${idx}`
11571
+ );
11572
+ }) });
11573
+ }
11370
11574
  function SlideCanvas({
11371
11575
  activeSlide,
11372
11576
  templateElements,
@@ -11433,7 +11637,8 @@ function SlideCanvas({
11433
11637
  sourceSlideIndex,
11434
11638
  fieldContext,
11435
11639
  tableStyleContext,
11436
- collaborationOverlay
11640
+ collaborationOverlay,
11641
+ aiActive = false
11437
11642
  }) {
11438
11643
  const isEditableCanvas = (mode === "edit" || mode === "master") && canEdit;
11439
11644
  const {
@@ -11552,6 +11757,7 @@ function SlideCanvas({
11552
11757
  role: "region",
11553
11758
  "aria-label": `Slide ${(activeSlideIndex ?? 0) + 1}`,
11554
11759
  "aria-roledescription": "slide",
11760
+ "data-pptx-ai-active": aiActive ? "true" : void 0,
11555
11761
  className: "relative shadow-2xl",
11556
11762
  style: {
11557
11763
  width: canvasSize.width,
@@ -11672,6 +11878,7 @@ function SlideCanvas({
11672
11878
  element.id
11673
11879
  )),
11674
11880
  /* @__PURE__ */ jsx(MarqueeOverlay, { marqueeSelectionState }),
11881
+ activeSlide?.activeXControls && activeSlide.activeXControls.length > 0 && /* @__PURE__ */ jsx(ActiveXControlOverlay, { controls: activeSlide.activeXControls, canvasSize }),
11675
11882
  showCommentMarkers && comments && comments.length > 0 && /* @__PURE__ */ jsx(
11676
11883
  CommentMarkersOverlay,
11677
11884
  {
@@ -12155,16 +12362,43 @@ function ResizeHandle({
12155
12362
  }
12156
12363
  );
12157
12364
  }
12365
+
12366
+ // src/viewer/components/slide-field-context.ts
12367
+ function extractSlideTitle(slide) {
12368
+ for (const el of slide.elements) {
12369
+ const phType = el.placeholderType;
12370
+ if (phType === "title" || phType === "ctrTitle") {
12371
+ const txt = el.text;
12372
+ if (txt) {
12373
+ return txt;
12374
+ }
12375
+ }
12376
+ }
12377
+ return void 0;
12378
+ }
12379
+ function deriveSlideFieldContext(base, slide) {
12380
+ if (!base) {
12381
+ return void 0;
12382
+ }
12383
+ return {
12384
+ ...base,
12385
+ slideNumber: slide.slideNumber,
12386
+ slideTitle: extractSlideTitle(slide)
12387
+ };
12388
+ }
12158
12389
  function SlideThumbnailImpl({
12159
12390
  slide,
12160
12391
  templateElements,
12161
- canvasSize
12392
+ canvasSize,
12393
+ fieldContext,
12394
+ tableStyleContext
12162
12395
  }) {
12163
12396
  const safeCanvasWidth = Math.max(canvasSize.width, 1);
12164
12397
  const safeCanvasHeight = Math.max(canvasSize.height, 1);
12165
12398
  const scale = SLIDE_NAV_THUMBNAIL_WIDTH / safeCanvasWidth;
12166
12399
  const previewHeight = Math.max(56, Math.round(safeCanvasHeight * scale));
12167
- const previewElements = [...templateElements, ...slide.elements].slice(0, 60);
12400
+ const previewElements = buildPreviewElements(slide, templateElements);
12401
+ const slideFieldContext = deriveSlideFieldContext(fieldContext, slide);
12168
12402
  const { t } = useTranslation();
12169
12403
  const transitionLabel = slide.transition ? (() => {
12170
12404
  const opt = SLIDE_TRANSITION_OPTIONS.find((o) => o.value === slide.transition?.type);
@@ -12200,7 +12434,9 @@ function SlideThumbnailImpl({
12200
12434
  element,
12201
12435
  activeSlide: slide,
12202
12436
  allSlides: [slide],
12203
- zIndex: index
12437
+ zIndex: index,
12438
+ fieldContext: slideFieldContext,
12439
+ tableStyleContext
12204
12440
  },
12205
12441
  element.id
12206
12442
  ))
@@ -12238,6 +12474,12 @@ function arePropsEqual2(prev, next) {
12238
12474
  if (prev.templateElements !== next.templateElements) {
12239
12475
  return false;
12240
12476
  }
12477
+ if (prev.fieldContext !== next.fieldContext) {
12478
+ return false;
12479
+ }
12480
+ if (prev.tableStyleContext !== next.tableStyleContext) {
12481
+ return false;
12482
+ }
12241
12483
  if (prev.canvasSize.width !== next.canvasSize.width || prev.canvasSize.height !== next.canvasSize.height) {
12242
12484
  return false;
12243
12485
  }
@@ -12259,6 +12501,8 @@ function ContextMenu({
12259
12501
  onMergeCellDown,
12260
12502
  onMergeSelectedCells,
12261
12503
  onSplitCell,
12504
+ onAskAi,
12505
+ onFixAi,
12262
12506
  onClose
12263
12507
  }) {
12264
12508
  const { t } = useTranslation();
@@ -12378,6 +12622,27 @@ function ContextMenu({
12378
12622
  }
12379
12623
  ),
12380
12624
  /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border" }),
12625
+ (onAskAi || onFixAi) && /* @__PURE__ */ jsxs(Fragment, { children: [
12626
+ onAskAi && /* @__PURE__ */ jsx(
12627
+ "button",
12628
+ {
12629
+ type: "button",
12630
+ className: "w-full px-3 py-1.5 text-left hover:bg-muted",
12631
+ onClick: onAskAi,
12632
+ children: t("pptx.ai.askAboutElement")
12633
+ }
12634
+ ),
12635
+ onFixAi && /* @__PURE__ */ jsx(
12636
+ "button",
12637
+ {
12638
+ type: "button",
12639
+ className: "w-full px-3 py-1.5 text-left hover:bg-muted",
12640
+ onClick: onFixAi,
12641
+ children: t("pptx.ai.fixElement")
12642
+ }
12643
+ ),
12644
+ /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border" })
12645
+ ] }),
12381
12646
  /* @__PURE__ */ jsx(
12382
12647
  "button",
12383
12648
  {
@@ -12926,7 +13191,9 @@ function LazyThumbnailInner({
12926
13191
  slide,
12927
13192
  templateElements,
12928
13193
  canvasSize,
12929
- previewHeight
13194
+ previewHeight,
13195
+ fieldContext,
13196
+ tableStyleContext
12930
13197
  }) {
12931
13198
  const containerRef = useRef(null);
12932
13199
  const [isVisible, setIsVisible] = useState(false);
@@ -12956,7 +13223,16 @@ function LazyThumbnailInner({
12956
13223
  observer.disconnect();
12957
13224
  };
12958
13225
  }, []);
12959
- return /* @__PURE__ */ jsx("div", { ref: containerRef, children: isVisible ? /* @__PURE__ */ jsx(SlideThumbnail, { slide, templateElements, canvasSize }) : /* @__PURE__ */ jsx(
13226
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, children: isVisible ? /* @__PURE__ */ jsx(
13227
+ SlideThumbnail,
13228
+ {
13229
+ slide,
13230
+ templateElements,
13231
+ canvasSize,
13232
+ fieldContext,
13233
+ tableStyleContext
13234
+ }
13235
+ ) : /* @__PURE__ */ jsx(
12960
13236
  "div",
12961
13237
  {
12962
13238
  className: "relative w-full overflow-hidden rounded border border-border bg-muted/30 animate-pulse",
@@ -13012,6 +13288,8 @@ function SlideItemInner({
13012
13288
  canEdit,
13013
13289
  rehearsalTimings,
13014
13290
  presenceUsers,
13291
+ fieldContext,
13292
+ tableStyleContext,
13015
13293
  onSelectSlide,
13016
13294
  onSlideContextMenu,
13017
13295
  onAddSection,
@@ -13093,7 +13371,9 @@ function SlideItemInner({
13093
13371
  slide,
13094
13372
  templateElements,
13095
13373
  canvasSize,
13096
- previewHeight
13374
+ previewHeight,
13375
+ fieldContext,
13376
+ tableStyleContext
13097
13377
  }
13098
13378
  ),
13099
13379
  (slide.comments?.length ?? 0) > 0 && /* @__PURE__ */ jsxs("div", { className: "absolute top-0.5 right-0.5 flex items-center gap-0.5 rounded bg-amber-500/90 px-1 py-0.5 text-[8px] font-medium text-white leading-none z-10", children: [
@@ -13234,7 +13514,9 @@ function SlidesPaneSidebar({
13234
13514
  onMoveSectionUp,
13235
13515
  onMoveSectionDown,
13236
13516
  rehearsalTimings,
13237
- panelWidth
13517
+ panelWidth,
13518
+ fieldContext,
13519
+ tableStyleContext
13238
13520
  }) {
13239
13521
  const { t } = useTranslation();
13240
13522
  const collab = useCollaboration();
@@ -13380,6 +13662,8 @@ function SlidesPaneSidebar({
13380
13662
  canEdit,
13381
13663
  rehearsalTimings,
13382
13664
  presenceUsers: slidePresenceMap?.get(item.slideIndex),
13665
+ fieldContext,
13666
+ tableStyleContext,
13383
13667
  onSelectSlide,
13384
13668
  onSlideContextMenu,
13385
13669
  onAddSection,
@@ -13435,6 +13719,8 @@ function SlidesPaneSidebar({
13435
13719
  canEdit,
13436
13720
  rehearsalTimings,
13437
13721
  presenceUsers: slidePresenceMap?.get(idx),
13722
+ fieldContext,
13723
+ tableStyleContext,
13438
13724
  onSelectSlide,
13439
13725
  onSlideContextMenu,
13440
13726
  onAddSection,
@@ -17079,6 +17365,9 @@ function formatFieldValue(key, value, t) {
17079
17365
  if (value === void 0 || value === null) {
17080
17366
  return t("pptx.documentProperties.statistics.notAvailable");
17081
17367
  }
17368
+ if (typeof value === "boolean") {
17369
+ return t(value ? "pptx.documentProperties.custom.yes" : "pptx.documentProperties.custom.no");
17370
+ }
17082
17371
  return String(value);
17083
17372
  }
17084
17373
  function DocumentPropertiesStatisticsTab({
@@ -25295,8 +25584,10 @@ function PresentationSettingsCard({
25295
25584
  {
25296
25585
  label: t("pptx.presentationSettings.frameSlides"),
25297
25586
  disabled: !canEdit,
25298
- checked: Boolean(presentationProperties.printFrameSlides),
25299
- onChange: (v) => onUpdate({ printFrameSlides: v })
25587
+ checked: printPropertiesFrameSlides(presentationProperties.printProperties),
25588
+ onChange: (v) => onUpdate({
25589
+ printProperties: withFrameSlides(presentationProperties.printProperties, v)
25590
+ })
25300
25591
  }
25301
25592
  ),
25302
25593
  /* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
@@ -25309,8 +25600,13 @@ function PresentationSettingsCard({
25309
25600
  max: 16,
25310
25601
  disabled: !canEdit,
25311
25602
  className: cn(INPUT, "w-20"),
25312
- value: presentationProperties.printSlidesPerPage ?? 1,
25313
- onChange: (e) => onUpdate({ printSlidesPerPage: Number(e.target.value) })
25603
+ value: printPropertiesSlidesPerPage(presentationProperties.printProperties),
25604
+ onChange: (e) => onUpdate({
25605
+ printProperties: withSlidesPerPage(
25606
+ presentationProperties.printProperties,
25607
+ Number(e.target.value)
25608
+ )
25609
+ })
25314
25610
  }
25315
25611
  )
25316
25612
  ] })
@@ -29384,7 +29680,10 @@ function ViewerToolbarSection(props) {
29384
29680
  autosaveStatus,
29385
29681
  autosaveEnabled = true,
29386
29682
  onToggleAutosave,
29387
- hiddenActions
29683
+ hiddenActions,
29684
+ aiEnabled,
29685
+ isAiPanelOpen,
29686
+ onToggleAiPanel
29388
29687
  } = props;
29389
29688
  const handleAddAnimation = useCallback(
29390
29689
  (preset, group) => {
@@ -29754,7 +30053,10 @@ function ViewerToolbarSection(props) {
29754
30053
  showSubtitles: Boolean(s.presentationProperties.showSubtitles),
29755
30054
  activeSlide,
29756
30055
  onTransitionChange: handleTransitionChange,
29757
- onApplyTransitionToAll: handleApplyTransitionToAll
30056
+ onApplyTransitionToAll: handleApplyTransitionToAll,
30057
+ aiEnabled,
30058
+ isAiPanelOpen,
30059
+ onToggleAiPanel
29758
30060
  }
29759
30061
  ),
29760
30062
  s.hasDigitalSignatures && /* @__PURE__ */ jsx("div", { className: "flex items-center px-3 py-1 z-10", children: /* @__PURE__ */ jsx(
@@ -30383,8 +30685,8 @@ function ViewerDialogGroup(props) {
30383
30685
  onPrint: printHandlers.handlePrintWithSettings,
30384
30686
  slides,
30385
30687
  activeSlideIndex,
30386
- defaultSlidesPerPage: presentationProperties.printSlidesPerPage,
30387
- defaultFrameSlides: presentationProperties.printFrameSlides
30688
+ defaultSlidesPerPage: printPropertiesSlidesPerPage(presentationProperties.printProperties),
30689
+ defaultFrameSlides: printPropertiesFrameSlides(presentationProperties.printProperties)
30388
30690
  }
30389
30691
  ),
30390
30692
  /* @__PURE__ */ jsx(
@@ -30570,7 +30872,11 @@ function ViewerCanvasArea(props) {
30570
30872
  presentation,
30571
30873
  onEndPresentation,
30572
30874
  findReplace,
30573
- hiddenActions
30875
+ hiddenActions,
30876
+ aiPickMode = false,
30877
+ onAiPickElement,
30878
+ aiHighlightOverlay,
30879
+ aiCanvasActive = false
30574
30880
  } = props;
30575
30881
  const { t } = useTranslation();
30576
30882
  const { isHidden } = useToolbarVisibility(hiddenActions);
@@ -30678,7 +30984,7 @@ ${url}`)) {
30678
30984
  const swipeEnabled = mode === "preview" || mode === "present";
30679
30985
  const handleSwipeNext = useCallback(() => {
30680
30986
  if (mode === "present") {
30681
- presentation.movePresentationSlide(1);
30987
+ presentation.movePresentationSlide(1, "click");
30682
30988
  } else {
30683
30989
  s.setActiveSlideIndex((i) => Math.min(slides.length - 1, i + 1));
30684
30990
  }
@@ -30695,13 +31001,22 @@ ${url}`)) {
30695
31001
  onNext: handleSwipeNext,
30696
31002
  onPrev: handleSwipePrev
30697
31003
  });
31004
+ const pickActive = aiPickMode && Boolean(onAiPickElement) && mode === "edit";
31005
+ const handleElementClick = pickActive ? (elementId, e) => {
31006
+ e.stopPropagation();
31007
+ onAiPickElement?.(activeSlideIndex, elementId);
31008
+ } : canvasHandlers.handleElementClick;
31009
+ const handleElementMouseDown = pickActive ? (_elementId, e) => {
31010
+ e.stopPropagation();
31011
+ } : canvasHandlers.handleElementMouseDown;
30698
31012
  return (
30699
31013
  // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- the canvas area hosts swipe navigation and the presentation-mode right-click menu; it has no interactive semantics of its own
30700
31014
  /* @__PURE__ */ jsxs(
30701
31015
  "main",
30702
31016
  {
30703
31017
  "aria-label": t("pptx.viewer.slideEditorAria"),
30704
- className: "flex-1 min-w-0 relative flex flex-col bg-background",
31018
+ "data-ai-pick-mode": pickActive ? "true" : void 0,
31019
+ className: `flex-1 min-w-0 relative flex flex-col bg-background${pickActive ? " cursor-crosshair" : ""}`,
30705
31020
  onTouchStart: swipe.onTouchStart,
30706
31021
  onTouchEnd: swipe.onTouchEnd,
30707
31022
  onContextMenu: mode === "present" ? handlePresentationContextMenu : void 0,
@@ -30763,9 +31078,9 @@ ${url}`)) {
30763
31078
  guides: s.guides,
30764
31079
  presentationElementStates: mode === "present" ? presentation.presentationElementStates : void 0,
30765
31080
  presentationKeyframesCss: mode === "present" ? presentation.presentationKeyframesCss : void 0,
30766
- onClick: canvasHandlers.handleElementClick,
31081
+ onClick: handleElementClick,
30767
31082
  onDoubleClick: canvasHandlers.handleElementDoubleClick,
30768
- onMouseDown: canvasHandlers.handleElementMouseDown,
31083
+ onMouseDown: handleElementMouseDown,
30769
31084
  onContextMenu: canvasHandlers.handleElementContextMenu,
30770
31085
  onCanvasMouseDown: canvasHandlers.handleCanvasMouseDown,
30771
31086
  onResizePointerDown: canvasHandlers.handleResizePointerDown,
@@ -30797,6 +31112,7 @@ ${url}`)) {
30797
31112
  sourceSlideIndex: mode === "present" ? activeSlideIndex : void 0,
30798
31113
  fieldContext,
30799
31114
  tableStyleContext,
31115
+ aiActive: aiCanvasActive,
30800
31116
  collaborationOverlay: /* @__PURE__ */ jsxs(Fragment, { children: [
30801
31117
  /* @__PURE__ */ jsx(
30802
31118
  RemoteSelectionOverlay,
@@ -30813,7 +31129,8 @@ ${url}`)) {
30813
31129
  canvasHeight: canvasSize.height,
30814
31130
  selectedElementId: s.selectedElementId
30815
31131
  }
30816
- )
31132
+ ),
31133
+ aiHighlightOverlay
30817
31134
  ] }),
30818
31135
  comments: activeSlide?.comments,
30819
31136
  showCommentMarkers: s.sidebarPanelMode === "comments",
@@ -30934,6 +31251,122 @@ ${url}`)) {
30934
31251
  )
30935
31252
  );
30936
31253
  }
31254
+ var AiChatPanel = lazy(() => import('./AiChatPanel-BRGQCYZM.mjs'));
31255
+ function AiChatPanelLazy(props) {
31256
+ return /* @__PURE__ */ jsx(
31257
+ Suspense,
31258
+ {
31259
+ fallback: /* @__PURE__ */ jsx(
31260
+ "div",
31261
+ {
31262
+ className: "absolute right-0 top-0 z-30 flex h-full w-80 items-center justify-center border-l border-border bg-card text-muted-foreground max-md:inset-x-0 max-md:top-auto max-md:bottom-0 max-md:h-[75dvh] max-md:w-full max-md:rounded-t-2xl max-md:border-l-0 max-md:border-t max-md:shadow-2xl",
31263
+ style: props.panelWidth ? { width: props.panelWidth } : void 0,
31264
+ children: /* @__PURE__ */ jsx(LuLoaderCircle, { className: "w-5 h-5 animate-spin" })
31265
+ }
31266
+ ),
31267
+ children: /* @__PURE__ */ jsx(AiChatPanel, { ...props })
31268
+ }
31269
+ );
31270
+ }
31271
+ var OVERLAY_CSS = `
31272
+ @keyframes pptx-ai-ring-pulse {
31273
+ 0% { box-shadow: 0 0 0 0 rgba(59,130,246,0.55), 0 0 0 0 rgba(59,130,246,0.35); }
31274
+ 70% { box-shadow: 0 0 0 6px rgba(59,130,246,0), 0 0 14px 4px rgba(59,130,246,0.28); }
31275
+ 100% { box-shadow: 0 0 0 0 rgba(59,130,246,0), 0 0 10px 2px rgba(59,130,246,0.22); }
31276
+ }
31277
+ @keyframes pptx-ai-ring-in {
31278
+ 0% { opacity: 0; transform: scale(1.04); }
31279
+ 100% { opacity: 1; transform: scale(1); }
31280
+ }
31281
+ /* While the AI is active, tween colour changes on slide elements so an edit
31282
+ fades from its old value to the new one instead of snapping. */
31283
+ [data-pptx-ai-active='true'] [data-element-id],
31284
+ [data-pptx-ai-active='true'] [data-element-id] * {
31285
+ transition: color 0.5s ease, fill 0.5s ease, stroke 0.5s ease, background-color 0.5s ease,
31286
+ border-color 0.5s ease;
31287
+ }
31288
+ `;
31289
+ function AiFocusHighlightOverlay({
31290
+ highlights,
31291
+ elements,
31292
+ activeSlideIndex
31293
+ }) {
31294
+ if (highlights.length === 0) {
31295
+ return null;
31296
+ }
31297
+ const byId = new Map(elements.map((el) => [el.id, el]));
31298
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
31299
+ /* @__PURE__ */ jsx("style", { children: OVERLAY_CSS }),
31300
+ highlights.map((hl) => {
31301
+ if (hl.slideIndex !== activeSlideIndex) {
31302
+ return null;
31303
+ }
31304
+ const el = byId.get(hl.elementId);
31305
+ if (!el) {
31306
+ return null;
31307
+ }
31308
+ const active = hl.variant === "active";
31309
+ return /* @__PURE__ */ jsx(
31310
+ "div",
31311
+ {
31312
+ "data-testid": `ai-focus-highlight-${hl.elementId}`,
31313
+ "data-ai-highlight": hl.variant,
31314
+ "data-export-ignore": "true",
31315
+ className: "absolute pointer-events-none rounded-[3px]",
31316
+ style: {
31317
+ left: el.x - 3,
31318
+ top: el.y - 3,
31319
+ width: el.width + 6,
31320
+ height: el.height + 6,
31321
+ zIndex: 9998,
31322
+ border: active ? "2px solid rgba(59,130,246,0.9)" : "2px solid rgba(59,130,246,0.55)",
31323
+ animation: active ? "pptx-ai-ring-in 0.18s ease-out, pptx-ai-ring-pulse 1s ease-out infinite" : "pptx-ai-ring-in 0.9s ease-out",
31324
+ boxShadow: active ? void 0 : "0 0 10px 2px rgba(59,130,246,0.18)"
31325
+ }
31326
+ },
31327
+ `ai-hl-${hl.variant}-${hl.elementId}`
31328
+ );
31329
+ })
31330
+ ] });
31331
+ }
31332
+ function AiChangeOverlay({ batch, activeSlideIndex }) {
31333
+ const [phase, setPhase] = useState("start");
31334
+ const nonce = batch?.nonce ?? 0;
31335
+ useEffect(() => {
31336
+ if (!batch) {
31337
+ return;
31338
+ }
31339
+ setPhase("start");
31340
+ let inner = 0;
31341
+ const outer = requestAnimationFrame(() => {
31342
+ inner = requestAnimationFrame(() => setPhase("end"));
31343
+ });
31344
+ return () => {
31345
+ cancelAnimationFrame(outer);
31346
+ cancelAnimationFrame(inner);
31347
+ };
31348
+ }, [nonce, batch]);
31349
+ if (!batch) {
31350
+ return null;
31351
+ }
31352
+ const changes = batch.changes.filter((c) => c.slideIndex === activeSlideIndex);
31353
+ if (changes.length === 0) {
31354
+ return null;
31355
+ }
31356
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
31357
+ /* @__PURE__ */ jsx("style", { children: aiChangeAnimationCss(batch.config) }),
31358
+ changes.map((change) => /* @__PURE__ */ jsx(
31359
+ "div",
31360
+ {
31361
+ "data-testid": `ai-change-${change.elementId}`,
31362
+ "data-ai-change": change.kind,
31363
+ "data-export-ignore": "true",
31364
+ style: changeGhostStyle(change, phase, batch.config)
31365
+ },
31366
+ `ai-change-${change.elementId}-${nonce}`
31367
+ ))
31368
+ ] });
31369
+ }
30937
31370
 
30938
31371
  // src/viewer/components/inspector/theme-editor-constants.ts
30939
31372
  var THEME_EDITOR_CARD = "rounded bg-muted/50 p-2.5 space-y-2";
@@ -31926,7 +32359,10 @@ function ViewerSidePanels(props) {
31926
32359
  themeHandlers,
31927
32360
  history,
31928
32361
  panelWidth,
31929
- onResizeRight
32362
+ onResizeRight,
32363
+ aiConfig,
32364
+ aiBridge,
32365
+ aiPanel
31930
32366
  } = props;
31931
32367
  const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
31932
32368
  const currentBuiltInTheme = BUILT_IN_THEMES.find(
@@ -32025,6 +32461,16 @@ function ViewerSidePanels(props) {
32025
32461
  )
32026
32462
  }
32027
32463
  ),
32464
+ aiPanel?.isOpen && aiConfig && aiBridge && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
32465
+ AiChatPanelLazy,
32466
+ {
32467
+ bridge: aiBridge,
32468
+ config: aiConfig,
32469
+ aiPanel,
32470
+ onClose: aiPanel.close,
32471
+ panelWidth
32472
+ }
32473
+ ),
32028
32474
  /* @__PURE__ */ jsx(
32029
32475
  ThemeGallery,
32030
32476
  {
@@ -32085,7 +32531,10 @@ function ViewerMainContent(props) {
32085
32531
  onResizeLeft,
32086
32532
  rightPanelWidth,
32087
32533
  onResizeRight,
32088
- hiddenActions
32534
+ hiddenActions,
32535
+ aiConfig,
32536
+ aiBridge,
32537
+ aiPanel
32089
32538
  } = props;
32090
32539
  const {
32091
32540
  ops,
@@ -32097,6 +32546,21 @@ function ViewerMainContent(props) {
32097
32546
  tableOps,
32098
32547
  findReplace
32099
32548
  } = editorOps;
32549
+ const hf = state.headerFooter;
32550
+ const thumbnailFieldContext = useMemo(
32551
+ () => ({
32552
+ dateTimeText: hf.dateTimeText,
32553
+ dateFormat: hf.dateFormat,
32554
+ footerText: hf.footerText,
32555
+ headerText: hf.headerText,
32556
+ customProperties: state.customProperties.map((p) => ({ name: p.name, value: p.value }))
32557
+ }),
32558
+ [hf.dateTimeText, hf.dateFormat, hf.footerText, hf.headerText, state.customProperties]
32559
+ );
32560
+ const thumbnailTableStyleContext = useMemo(
32561
+ () => state.theme || state.tableStyleMap ? { theme: state.theme, tableStyleMap: state.tableStyleMap } : void 0,
32562
+ [state.theme, state.tableStyleMap]
32563
+ );
32100
32564
  return /* @__PURE__ */ jsx(ChartPartSelectionProvider, { children: /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-1 min-h-0", children: [
32101
32565
  showSlidesPane && /* @__PURE__ */ jsxs(Fragment, { children: [
32102
32566
  /* @__PURE__ */ jsx(
@@ -32120,7 +32584,9 @@ function ViewerMainContent(props) {
32120
32584
  onMoveSectionUp: sectionOps.moveSectionUp,
32121
32585
  onMoveSectionDown: sectionOps.moveSectionDown,
32122
32586
  rehearsalTimings: Object.keys(presentation.recordedTimings).length > 0 ? presentation.recordedTimings : void 0,
32123
- panelWidth: leftPanelWidth
32587
+ panelWidth: leftPanelWidth,
32588
+ fieldContext: thumbnailFieldContext,
32589
+ tableStyleContext: thumbnailTableStyleContext
32124
32590
  }
32125
32591
  ),
32126
32592
  onResizeLeft && /* @__PURE__ */ jsx(ResizeHandle, { direction: "horizontal", onResize: onResizeLeft })
@@ -32181,7 +32647,21 @@ function ViewerMainContent(props) {
32181
32647
  presentation,
32182
32648
  onEndPresentation,
32183
32649
  findReplace,
32184
- hiddenActions
32650
+ hiddenActions,
32651
+ aiPickMode: aiPanel?.pickMode,
32652
+ onAiPickElement: aiPanel ? aiPanel.addPick : void 0,
32653
+ aiCanvasActive: aiPanel?.canvasAnimating,
32654
+ aiHighlightOverlay: aiPanel ? /* @__PURE__ */ jsxs(Fragment, { children: [
32655
+ /* @__PURE__ */ jsx(
32656
+ AiFocusHighlightOverlay,
32657
+ {
32658
+ highlights: aiPanel.canvasHighlights,
32659
+ elements: activeSlide?.elements ?? [],
32660
+ activeSlideIndex
32661
+ }
32662
+ ),
32663
+ /* @__PURE__ */ jsx(AiChangeOverlay, { batch: aiPanel.changeBatch, activeSlideIndex })
32664
+ ] }) : void 0
32185
32665
  }
32186
32666
  ),
32187
32667
  state.contextMenuState && /* @__PURE__ */ jsx(
@@ -32201,6 +32681,14 @@ function ViewerMainContent(props) {
32201
32681
  onMergeCellDown: tableOps.handleMergeCellDown,
32202
32682
  onMergeSelectedCells: tableOps.handleMergeSelectedCells,
32203
32683
  onSplitCell: tableOps.handleSplitCell,
32684
+ onAskAi: aiPanel && selectedElement ? () => {
32685
+ aiPanel.askAboutSelection();
32686
+ state.setContextMenuState(null);
32687
+ } : void 0,
32688
+ onFixAi: aiPanel && selectedElement ? () => {
32689
+ aiPanel.fixSelection();
32690
+ state.setContextMenuState(null);
32691
+ } : void 0,
32204
32692
  onClose: () => state.setContextMenuState(null)
32205
32693
  }
32206
32694
  ),
@@ -32223,7 +32711,10 @@ function ViewerMainContent(props) {
32223
32711
  themeHandlers,
32224
32712
  history,
32225
32713
  panelWidth: rightPanelWidth,
32226
- onResizeRight
32714
+ onResizeRight,
32715
+ aiConfig,
32716
+ aiBridge,
32717
+ aiPanel
32227
32718
  }
32228
32719
  )
32229
32720
  ] }) });
@@ -32946,6 +33437,236 @@ function OptionsRibbonPane({
32946
33437
  ] })
32947
33438
  ] });
32948
33439
  }
33440
+
33441
+ // src/viewer/utils/ai-log-export.ts
33442
+ function isoOf(ms) {
33443
+ const n = Number.isFinite(ms) ? ms : 0;
33444
+ return new Date(n).toISOString();
33445
+ }
33446
+ function toLogChat(chat, detailed) {
33447
+ const messages = chat.messages.map((message) => {
33448
+ const parts = toRenderableParts(message);
33449
+ const textRuns = [];
33450
+ const toolCalls = [];
33451
+ for (const part of parts) {
33452
+ if (part.kind === "text") {
33453
+ textRuns.push(part.text);
33454
+ continue;
33455
+ }
33456
+ toolCalls.push({
33457
+ toolName: part.toolName,
33458
+ toolCallId: part.toolCallId,
33459
+ state: part.state,
33460
+ input: detailed ? part.input : void 0,
33461
+ output: detailed ? part.output : void 0,
33462
+ errorText: part.errorText
33463
+ });
33464
+ }
33465
+ return {
33466
+ role: message.role,
33467
+ text: textRuns.join("\n\n"),
33468
+ toolCalls
33469
+ };
33470
+ });
33471
+ return {
33472
+ id: chat.id,
33473
+ title: chat.title,
33474
+ deckId: chat.deckId,
33475
+ createdAt: chat.createdAt,
33476
+ updatedAt: chat.updatedAt,
33477
+ createdAtIso: isoOf(chat.createdAt),
33478
+ updatedAtIso: isoOf(chat.updatedAt),
33479
+ messageCount: chat.messages.length,
33480
+ messages
33481
+ };
33482
+ }
33483
+ function buildChatLogExport(chats, options) {
33484
+ const detailed = options?.detailed ?? true;
33485
+ const now = options?.now ?? Date.now();
33486
+ return {
33487
+ format: "pptx-ai-chat-log",
33488
+ version: 1,
33489
+ exportedAt: isoOf(now),
33490
+ detailed,
33491
+ chatCount: chats.length,
33492
+ chats: chats.map((chat) => toLogChat(chat, detailed))
33493
+ };
33494
+ }
33495
+ function toolCallLine(call, detailed) {
33496
+ const lines = [`- Tool \`${call.toolName}\` (${call.state})`];
33497
+ if (call.errorText) {
33498
+ lines.push(` - error: ${call.errorText}`);
33499
+ }
33500
+ if (detailed) {
33501
+ lines.push(" - input:");
33502
+ lines.push(" ```json");
33503
+ lines.push(JSON.stringify(call.input ?? null, null, 2));
33504
+ lines.push(" ```");
33505
+ lines.push(" - output:");
33506
+ lines.push(" ```json");
33507
+ lines.push(JSON.stringify(call.output ?? null, null, 2));
33508
+ lines.push(" ```");
33509
+ }
33510
+ return lines.join("\n");
33511
+ }
33512
+ function buildChatLogMarkdown(doc) {
33513
+ const out = [
33514
+ `# AI chat logs`,
33515
+ "",
33516
+ `Exported: ${doc.exportedAt}`,
33517
+ `Chats: ${doc.chatCount}`,
33518
+ ""
33519
+ ];
33520
+ for (const chat of doc.chats) {
33521
+ out.push(`## ${chat.title || chat.id}`);
33522
+ out.push("");
33523
+ out.push(`- id: ${chat.id}`);
33524
+ if (chat.deckId) {
33525
+ out.push(`- deck: ${chat.deckId}`);
33526
+ }
33527
+ out.push(`- created: ${chat.createdAtIso}`);
33528
+ out.push(`- updated: ${chat.updatedAtIso}`);
33529
+ out.push(`- messages: ${chat.messageCount}`);
33530
+ out.push("");
33531
+ for (const message of chat.messages) {
33532
+ out.push(`### ${message.role}`);
33533
+ out.push("");
33534
+ if (message.text) {
33535
+ out.push(message.text);
33536
+ out.push("");
33537
+ }
33538
+ for (const call of message.toolCalls) {
33539
+ out.push(toolCallLine(call, doc.detailed));
33540
+ out.push("");
33541
+ }
33542
+ }
33543
+ }
33544
+ return out.join("\n");
33545
+ }
33546
+ async function collectStoredChats(store) {
33547
+ const summaries = await store.listChats();
33548
+ const chats = [];
33549
+ for (const summary of summaries) {
33550
+ const chat = await store.loadChat(summary.id);
33551
+ if (chat) {
33552
+ chats.push(chat);
33553
+ }
33554
+ }
33555
+ return chats;
33556
+ }
33557
+ function timestampSlug(now) {
33558
+ const d = new Date(now);
33559
+ const p = (n) => String(n).padStart(2, "0");
33560
+ return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;
33561
+ }
33562
+ async function exportAiChatLogs(options) {
33563
+ const store = options?.store ?? createChatHistoryStore();
33564
+ const format = options?.format ?? "json";
33565
+ const now = options?.now ?? Date.now();
33566
+ const chats = await collectStoredChats(store);
33567
+ if (chats.length === 0) {
33568
+ return 0;
33569
+ }
33570
+ const doc = buildChatLogExport(chats, { detailed: options?.detailed ?? true, now });
33571
+ const slug = timestampSlug(now);
33572
+ if (format === "markdown") {
33573
+ const blob = new Blob([buildChatLogMarkdown(doc)], { type: "text/markdown" });
33574
+ downloadBlob(blob, `pptx-ai-chats-${slug}.md`);
33575
+ } else {
33576
+ const blob = new Blob([JSON.stringify(doc, null, 2)], { type: "application/json" });
33577
+ downloadBlob(blob, `pptx-ai-chats-${slug}.json`);
33578
+ }
33579
+ return chats.length;
33580
+ }
33581
+ function SettingsAiTab({ store }) {
33582
+ const { t } = useTranslation();
33583
+ const activeStore = useMemo(() => store ?? createChatHistoryStore(), [store]);
33584
+ const [chatCount, setChatCount] = useState(null);
33585
+ const [detailed, setDetailed] = useState(true);
33586
+ const [status, setStatus] = useState({ kind: "idle" });
33587
+ useEffect(() => {
33588
+ let cancelled = false;
33589
+ const load = async () => {
33590
+ try {
33591
+ const chats = await activeStore.listChats();
33592
+ if (!cancelled) {
33593
+ setChatCount(chats.length);
33594
+ }
33595
+ } catch {
33596
+ if (!cancelled) {
33597
+ setChatCount(0);
33598
+ }
33599
+ }
33600
+ };
33601
+ void load();
33602
+ return () => {
33603
+ cancelled = true;
33604
+ };
33605
+ }, [activeStore]);
33606
+ const handleExport = useCallback(
33607
+ async (format) => {
33608
+ setStatus({ kind: "busy" });
33609
+ try {
33610
+ const count = await exportAiChatLogs({ store: activeStore, format, detailed });
33611
+ setStatus({ kind: "done", count });
33612
+ } catch {
33613
+ setStatus({ kind: "done", count: 0 });
33614
+ }
33615
+ },
33616
+ [activeStore, detailed]
33617
+ );
33618
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33619
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 rounded-lg border border-border/60 bg-muted/30 p-3", children: [
33620
+ /* @__PURE__ */ jsx(LuBug, { className: "mt-0.5 h-4 w-4 shrink-0 text-primary" }),
33621
+ /* @__PURE__ */ jsxs("div", { children: [
33622
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t("pptx.ai.settingsSectionTitle") }),
33623
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("pptx.ai.exportLogsHint") })
33624
+ ] })
33625
+ ] }),
33626
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: chatCount === null ? t("pptx.ai.exportLogsCounting") : t("pptx.ai.exportLogsStoredCount", { count: chatCount }) }),
33627
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
33628
+ /* @__PURE__ */ jsx(
33629
+ "input",
33630
+ {
33631
+ type: "checkbox",
33632
+ checked: detailed,
33633
+ onChange: (e) => setDetailed(e.target.checked),
33634
+ className: "h-3.5 w-3.5 rounded border-border"
33635
+ }
33636
+ ),
33637
+ t("pptx.ai.exportLogsDetailed")
33638
+ ] }),
33639
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
33640
+ /* @__PURE__ */ jsxs(
33641
+ "button",
33642
+ {
33643
+ type: "button",
33644
+ onClick: () => void handleExport("json"),
33645
+ disabled: status.kind === "busy",
33646
+ className: "inline-flex items-center gap-1.5 rounded border border-border px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-accent disabled:opacity-50",
33647
+ children: [
33648
+ /* @__PURE__ */ jsx(LuDownload, { className: "h-3.5 w-3.5" }),
33649
+ t("pptx.ai.exportLogsJson")
33650
+ ]
33651
+ }
33652
+ ),
33653
+ /* @__PURE__ */ jsxs(
33654
+ "button",
33655
+ {
33656
+ type: "button",
33657
+ onClick: () => void handleExport("markdown"),
33658
+ disabled: status.kind === "busy",
33659
+ className: "inline-flex items-center gap-1.5 rounded border border-border px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-accent disabled:opacity-50",
33660
+ children: [
33661
+ /* @__PURE__ */ jsx(LuDownload, { className: "h-3.5 w-3.5" }),
33662
+ t("pptx.ai.exportLogsMarkdown")
33663
+ ]
33664
+ }
33665
+ )
33666
+ ] }),
33667
+ status.kind === "done" && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", role: "status", children: status.count > 0 ? t("pptx.ai.exportLogsDone", { count: status.count }) : t("pptx.ai.noChatsToExport") })
33668
+ ] });
33669
+ }
32949
33670
  function SettingsAppearanceTab({
32950
33671
  activeThemeKey,
32951
33672
  themes,
@@ -33015,6 +33736,7 @@ function SettingsLanguageTab({
33015
33736
  );
33016
33737
  }) });
33017
33738
  }
33739
+ var AI_TAB_ID = "ai";
33018
33740
  function SettingsDialog({
33019
33741
  isOpen,
33020
33742
  onClose,
@@ -33031,7 +33753,9 @@ function SettingsDialog({
33031
33753
  onSelectTheme,
33032
33754
  localeCode,
33033
33755
  availableLocales,
33034
- onSelectLocale
33756
+ onSelectLocale,
33757
+ aiEnabled,
33758
+ chatStore
33035
33759
  }) {
33036
33760
  const [activeTabId, setActiveTabId] = useState("general");
33037
33761
  const { t } = useTranslation();
@@ -33120,28 +33844,46 @@ function SettingsDialog({
33120
33844
  }
33121
33845
  ),
33122
33846
  /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 max-md:flex-col", children: [
33123
- /* @__PURE__ */ jsx(
33847
+ /* @__PURE__ */ jsxs(
33124
33848
  "nav",
33125
33849
  {
33126
33850
  "aria-label": t("pptx.options.title"),
33127
33851
  className: "w-44 shrink-0 space-y-0.5 overflow-y-auto border-r border-border/60 p-2 max-md:flex max-md:w-full max-md:space-y-0 max-md:gap-1 max-md:overflow-x-auto max-md:border-b max-md:border-r-0",
33128
- children: VIEWER_OPTIONS_TABS.map((tab) => /* @__PURE__ */ jsx(
33129
- "button",
33130
- {
33131
- type: "button",
33132
- onClick: () => setActiveTabId(tab.id),
33133
- "aria-current": activeTabId === tab.id,
33134
- className: cn(
33135
- "block w-full whitespace-nowrap rounded px-3 py-2 text-left text-sm transition-colors max-md:w-auto",
33136
- activeTabId === tab.id ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
33137
- ),
33138
- children: t(tab.labelKey)
33139
- },
33140
- tab.id
33141
- ))
33852
+ children: [
33853
+ VIEWER_OPTIONS_TABS.map((tab) => /* @__PURE__ */ jsx(
33854
+ "button",
33855
+ {
33856
+ type: "button",
33857
+ onClick: () => setActiveTabId(tab.id),
33858
+ "aria-current": activeTabId === tab.id,
33859
+ className: cn(
33860
+ "block w-full whitespace-nowrap rounded px-3 py-2 text-left text-sm transition-colors max-md:w-auto",
33861
+ activeTabId === tab.id ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
33862
+ ),
33863
+ children: t(tab.labelKey)
33864
+ },
33865
+ tab.id
33866
+ )),
33867
+ aiEnabled && /* @__PURE__ */ jsx(
33868
+ "button",
33869
+ {
33870
+ type: "button",
33871
+ onClick: () => setActiveTabId(AI_TAB_ID),
33872
+ "aria-current": activeTabId === AI_TAB_ID,
33873
+ className: cn(
33874
+ "block w-full whitespace-nowrap rounded px-3 py-2 text-left text-sm transition-colors max-md:w-auto",
33875
+ activeTabId === AI_TAB_ID ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
33876
+ ),
33877
+ children: t("pptx.ai.settingsSectionTitle")
33878
+ }
33879
+ )
33880
+ ]
33142
33881
  }
33143
33882
  ),
33144
- /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-5 py-4", children: activeTab.custom === "language" ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33883
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-5 py-4", children: activeTabId === AI_TAB_ID ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33884
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t("pptx.ai.settingsSectionTitle") }),
33885
+ /* @__PURE__ */ jsx(SettingsAiTab, { store: chatStore })
33886
+ ] }) : activeTab.custom === "language" ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33145
33887
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t(activeTab.descriptionKey) }),
33146
33888
  /* @__PURE__ */ jsxs("section", { children: [
33147
33889
  /* @__PURE__ */ jsx("h3", { className: "mb-1 border-b border-border/60 pb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: t("pptx.options.language.displayLanguage") }),
@@ -33250,6 +33992,341 @@ function SettingsDialog({
33250
33992
  )
33251
33993
  ] });
33252
33994
  }
33995
+
33996
+ // src/viewer/hooks/ai/ai-element-update.ts
33997
+ function applyGeometry(el, u) {
33998
+ if (u.x !== void 0) {
33999
+ el.x = u.x;
34000
+ }
34001
+ if (u.y !== void 0) {
34002
+ el.y = u.y;
34003
+ }
34004
+ if (u.width !== void 0) {
34005
+ el.width = u.width;
34006
+ }
34007
+ if (u.height !== void 0) {
34008
+ el.height = u.height;
34009
+ }
34010
+ if (u.rotation !== void 0) {
34011
+ el.rotation = u.rotation;
34012
+ }
34013
+ if (u.opacity !== void 0) {
34014
+ el.opacity = u.opacity;
34015
+ }
34016
+ if (u.hidden !== void 0) {
34017
+ el.hidden = u.hidden;
34018
+ }
34019
+ if (u.flipHorizontal !== void 0) {
34020
+ el.flipHorizontal = u.flipHorizontal;
34021
+ }
34022
+ if (u.flipVertical !== void 0) {
34023
+ el.flipVertical = u.flipVertical;
34024
+ }
34025
+ }
34026
+ function applyText(el, u) {
34027
+ if (!hasTextProperties(el)) {
34028
+ return;
34029
+ }
34030
+ if (typeof u.text === "string") {
34031
+ el.text = u.text;
34032
+ if (el.textSegments && el.textSegments.length > 0) {
34033
+ el.textSegments = [{ text: u.text, style: el.textSegments[0].style }];
34034
+ } else {
34035
+ el.textSegments = [{ text: u.text, style: {} }];
34036
+ }
34037
+ }
34038
+ const textStyle = {};
34039
+ if (u.fontSize !== void 0) {
34040
+ textStyle.fontSize = u.fontSize;
34041
+ }
34042
+ if (u.fontFamily !== void 0) {
34043
+ textStyle.fontFamily = u.fontFamily;
34044
+ }
34045
+ if (u.fontColor !== void 0) {
34046
+ textStyle.color = u.fontColor;
34047
+ }
34048
+ if (u.bold !== void 0) {
34049
+ textStyle.bold = u.bold;
34050
+ }
34051
+ if (u.italic !== void 0) {
34052
+ textStyle.italic = u.italic;
34053
+ }
34054
+ if (u.underline !== void 0) {
34055
+ textStyle.underline = u.underline;
34056
+ }
34057
+ if (u.align !== void 0) {
34058
+ textStyle.align = u.align;
34059
+ }
34060
+ if (Object.keys(textStyle).length === 0) {
34061
+ return;
34062
+ }
34063
+ el.textStyle = { ...el.textStyle, ...textStyle };
34064
+ el.textSegments = el.textSegments?.map((seg) => ({
34065
+ ...seg,
34066
+ style: { ...seg.style, ...textStyle }
34067
+ }));
34068
+ }
34069
+ function applyShapeStyle(el, u) {
34070
+ if (!hasShapeProperties(el)) {
34071
+ return;
34072
+ }
34073
+ const shapeStyle = {};
34074
+ if (u.fillColor !== void 0) {
34075
+ shapeStyle.fillColor = u.fillColor;
34076
+ }
34077
+ if (u.strokeColor !== void 0) {
34078
+ shapeStyle.strokeColor = u.strokeColor;
34079
+ }
34080
+ if (u.strokeWidth !== void 0) {
34081
+ shapeStyle.strokeWidth = u.strokeWidth;
34082
+ }
34083
+ if (Object.keys(shapeStyle).length === 0) {
34084
+ return;
34085
+ }
34086
+ el.shapeStyle = { ...el.shapeStyle, ...shapeStyle };
34087
+ }
34088
+ function applyAiElementUpdate(el, updates) {
34089
+ applyGeometry(el, updates);
34090
+ applyText(el, updates);
34091
+ applyShapeStyle(el, updates);
34092
+ }
34093
+
34094
+ // src/viewer/hooks/ai/useAiBridge.ts
34095
+ function useAiBridge(input) {
34096
+ const ref = useRef(input);
34097
+ ref.current = input;
34098
+ return useMemo(() => {
34099
+ const applySlidesUpdate = (updater, _label) => {
34100
+ const live = ref.current;
34101
+ live.setSlides((prev) => updater(structuredClone(prev)));
34102
+ live.bumpHistory();
34103
+ live.markDirty();
34104
+ };
34105
+ const readDeckData = (live) => ({
34106
+ slides: live.slides,
34107
+ width: live.canvasSize.width,
34108
+ height: live.canvasSize.height,
34109
+ theme: live.theme,
34110
+ sections: live.sections,
34111
+ presentationProperties: live.presentationProperties,
34112
+ customProperties: live.customProperties,
34113
+ coreProperties: live.coreProperties,
34114
+ appProperties: live.appProperties
34115
+ });
34116
+ const differs = (a, b) => JSON.stringify(a) !== JSON.stringify(b);
34117
+ return {
34118
+ getDeckMeta() {
34119
+ const live = ref.current;
34120
+ const firstTitle = live.slides[0]?.elements.find(
34121
+ (el) => "text" in el && typeof el.text === "string" && el.text.trim().length > 0
34122
+ );
34123
+ return {
34124
+ slideCount: live.slides.length,
34125
+ activeSlideIndex: live.activeSlideIndex,
34126
+ title: live.fileName ?? (firstTitle && "text" in firstTitle ? String(firstTitle.text) : void 0),
34127
+ width: live.canvasSize.width,
34128
+ height: live.canvasSize.height
34129
+ };
34130
+ },
34131
+ getSlides: () => ref.current.slides,
34132
+ getActiveSlideIndex: () => ref.current.activeSlideIndex,
34133
+ getTheme: () => ref.current.theme,
34134
+ getHandler: () => ref.current.handlerRef.current ?? void 0,
34135
+ goToSlide(index) {
34136
+ ref.current.setActiveSlideIndex(index);
34137
+ },
34138
+ selectElements(slideIndex, elementIds) {
34139
+ const live = ref.current;
34140
+ if (slideIndex !== live.activeSlideIndex) {
34141
+ live.setActiveSlideIndex(slideIndex);
34142
+ }
34143
+ live.applySelection(elementIds[0] ?? null, elementIds);
34144
+ },
34145
+ applySlidesUpdate,
34146
+ updateElement(slideIndex, elementId, updates) {
34147
+ applySlidesUpdate((slides) => {
34148
+ const el = slides[slideIndex]?.elements.find((e) => e.id === elementId);
34149
+ if (el) {
34150
+ applyAiElementUpdate(el, updates);
34151
+ }
34152
+ return slides;
34153
+ });
34154
+ },
34155
+ applyTheme(updates) {
34156
+ ref.current.applyThemeUpdates(updates);
34157
+ },
34158
+ getDeckData() {
34159
+ return readDeckData(ref.current);
34160
+ },
34161
+ applyDeckData(updater, _label) {
34162
+ const live = ref.current;
34163
+ const before = readDeckData(live);
34164
+ const after = updater(structuredClone(before));
34165
+ if (differs(before.slides, after.slides)) {
34166
+ live.setSlides(() => after.slides);
34167
+ live.bumpHistory();
34168
+ }
34169
+ if (before.width !== after.width || before.height !== after.height) {
34170
+ live.setCanvasSize({ width: after.width, height: after.height });
34171
+ }
34172
+ const nextSections = after.sections ?? before.sections ?? [];
34173
+ if (differs(before.sections, nextSections)) {
34174
+ live.setSections(nextSections);
34175
+ }
34176
+ const nextPresProps = after.presentationProperties ?? live.presentationProperties;
34177
+ if (differs(before.presentationProperties, nextPresProps)) {
34178
+ live.setPresentationProperties(nextPresProps);
34179
+ }
34180
+ const nextCustomProps = after.customProperties ?? before.customProperties ?? [];
34181
+ if (differs(before.customProperties, nextCustomProps)) {
34182
+ live.setCustomProperties(nextCustomProps);
34183
+ }
34184
+ if (differs(before.coreProperties, after.coreProperties)) {
34185
+ live.setCoreProperties(after.coreProperties);
34186
+ }
34187
+ if (differs(before.appProperties, after.appProperties)) {
34188
+ live.setAppProperties(after.appProperties);
34189
+ }
34190
+ live.markDirty();
34191
+ },
34192
+ getFocusedTargets() {
34193
+ const live = ref.current;
34194
+ if (live.pickedFocus && live.pickedFocus.length > 0) {
34195
+ return live.pickedFocus;
34196
+ }
34197
+ if (live.pinnedFocus && live.pinnedFocus.length > 0) {
34198
+ return live.pinnedFocus;
34199
+ }
34200
+ return computeFocusTargets({
34201
+ activeSlideIndex: live.activeSlideIndex,
34202
+ selectedElementIds: live.selectedElementIds,
34203
+ selectedElementId: live.selectedElementId
34204
+ });
34205
+ },
34206
+ notify(message, level) {
34207
+ ref.current.notify?.(message, level);
34208
+ }
34209
+ };
34210
+ }, []);
34211
+ }
34212
+ var TOOL_FLASH_MS = 2600;
34213
+ function fixDirective(element, slideIndex) {
34214
+ return `Review and fix any issues with this ${element.type} (id=${element.id}) on slide ${slideIndex + 1}.`;
34215
+ }
34216
+ function useAiPanelController(input) {
34217
+ const { activeSlideIndex, selectedElementId, selectedElementIds, selectedElement } = input;
34218
+ const [isOpen, setIsOpen] = useState(false);
34219
+ const [pinnedFocus, setPinnedFocus] = useState(null);
34220
+ const [prefill, setPrefill] = useState({ text: "", nonce: 0 });
34221
+ const [pickMode, setPickMode] = useState(false);
34222
+ const [pickTargets, setPickTargets] = useState([]);
34223
+ const [toolFocus, setToolFocus] = useState(
34224
+ null
34225
+ );
34226
+ const [flashTick, setFlashTick] = useState(0);
34227
+ const flashTimer = useRef(null);
34228
+ const [changeBatch, setChangeBatch] = useState(null);
34229
+ const showChangeBatch = useCallback((batch) => setChangeBatch(batch), []);
34230
+ const liveFocusTargets = useMemo(
34231
+ () => computeFocusTargets({ activeSlideIndex, selectedElementIds, selectedElementId }),
34232
+ [activeSlideIndex, selectedElementIds, selectedElementId]
34233
+ );
34234
+ const open = useCallback(() => setIsOpen(true), []);
34235
+ const close = useCallback(() => setIsOpen(false), []);
34236
+ const toggle = useCallback(() => setIsOpen((p) => !p), []);
34237
+ const pinFocus = useCallback(() => setPinnedFocus(liveFocusTargets), [liveFocusTargets]);
34238
+ const clearPinnedFocus = useCallback(() => setPinnedFocus(null), []);
34239
+ const askAboutSelection = useCallback(() => {
34240
+ setPinnedFocus(liveFocusTargets);
34241
+ setPrefill((p) => ({ text: "", nonce: p.nonce + 1 }));
34242
+ setIsOpen(true);
34243
+ }, [liveFocusTargets]);
34244
+ const fixSelection = useCallback(() => {
34245
+ setPinnedFocus(liveFocusTargets);
34246
+ const text = selectedElement ? fixDirective(selectedElement, activeSlideIndex) : "";
34247
+ setPrefill((p) => ({ text, nonce: p.nonce + 1 }));
34248
+ setIsOpen(true);
34249
+ }, [liveFocusTargets, selectedElement, activeSlideIndex]);
34250
+ const startPicking = useCallback(() => {
34251
+ setPickMode(true);
34252
+ setIsOpen(true);
34253
+ }, []);
34254
+ const stopPicking = useCallback(() => setPickMode(false), []);
34255
+ const addPick = useCallback((slideIndex, elementId) => {
34256
+ setPickTargets((prev) => {
34257
+ if (prev.some((t) => t.kind === "element" && t.elementId === elementId)) {
34258
+ return prev;
34259
+ }
34260
+ return [...prev, { kind: "element", slideIndex, elementId }];
34261
+ });
34262
+ }, []);
34263
+ const clearPicks = useCallback(() => {
34264
+ setPickTargets([]);
34265
+ setPickMode(false);
34266
+ }, []);
34267
+ const flashToolTarget = useCallback((target) => {
34268
+ if (target && target.slideIndex !== void 0 && target.elementIds.length > 0) {
34269
+ setToolFocus({ slideIndex: target.slideIndex, elementIds: target.elementIds });
34270
+ } else {
34271
+ setToolFocus(null);
34272
+ }
34273
+ setFlashTick((n) => n + 1);
34274
+ if (flashTimer.current) {
34275
+ clearTimeout(flashTimer.current);
34276
+ }
34277
+ flashTimer.current = setTimeout(() => {
34278
+ setToolFocus(null);
34279
+ setFlashTick(0);
34280
+ }, TOOL_FLASH_MS);
34281
+ }, []);
34282
+ useEffect(
34283
+ () => () => {
34284
+ if (flashTimer.current) {
34285
+ clearTimeout(flashTimer.current);
34286
+ }
34287
+ },
34288
+ []
34289
+ );
34290
+ const canvasHighlights = useMemo(() => {
34291
+ const out = [];
34292
+ for (const t of pickTargets) {
34293
+ if (t.kind === "element") {
34294
+ out.push({ slideIndex: t.slideIndex, elementId: t.elementId, variant: "pick" });
34295
+ }
34296
+ }
34297
+ if (toolFocus) {
34298
+ for (const elementId of toolFocus.elementIds) {
34299
+ out.push({ slideIndex: toolFocus.slideIndex, elementId, variant: "active" });
34300
+ }
34301
+ }
34302
+ return out;
34303
+ }, [pickTargets, toolFocus]);
34304
+ const canvasAnimating = canvasHighlights.length > 0 || flashTick > 0;
34305
+ return {
34306
+ isOpen,
34307
+ open,
34308
+ close,
34309
+ toggle,
34310
+ liveFocusTargets,
34311
+ pinnedFocus,
34312
+ pinFocus,
34313
+ clearPinnedFocus,
34314
+ prefill,
34315
+ askAboutSelection,
34316
+ fixSelection,
34317
+ pickMode,
34318
+ startPicking,
34319
+ stopPicking,
34320
+ pickTargets,
34321
+ addPick,
34322
+ clearPicks,
34323
+ canvasHighlights,
34324
+ canvasAnimating,
34325
+ flashToolTarget,
34326
+ changeBatch,
34327
+ showChangeBatch
34328
+ };
34329
+ }
33253
34330
  var PowerPointViewer = forwardRef(
33254
34331
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the forwardRef component its displayName
33255
34332
  function PowerPointViewer2(props, ref) {
@@ -33281,7 +34358,8 @@ var PowerPointViewer = forwardRef(
33281
34358
  onStopCollaboration,
33282
34359
  shareDefaults,
33283
34360
  smartArt3D = false,
33284
- hiddenActions
34361
+ hiddenActions,
34362
+ ai
33285
34363
  } = props;
33286
34364
  useEffect(() => {
33287
34365
  const css = buildUserFontFaceStyles(fonts);
@@ -33637,6 +34715,7 @@ var PowerPointViewer = forwardRef(
33637
34715
  autosaveStatus,
33638
34716
  isEncryptedDialogOpen,
33639
34717
  setIsEncryptedDialogOpen,
34718
+ handlerRef,
33640
34719
  loadVersion
33641
34720
  } = useViewerIntegration({
33642
34721
  state,
@@ -33669,6 +34748,55 @@ var PowerPointViewer = forwardRef(
33669
34748
  onSelectionChange,
33670
34749
  onSlideCountChange
33671
34750
  });
34751
+ const applyAiTheme = useCallback(
34752
+ (updates) => {
34753
+ if (updates.colorScheme) {
34754
+ void themeHandlers.handleUpdateThemeColorScheme(updates.colorScheme);
34755
+ }
34756
+ if (updates.fontScheme) {
34757
+ void themeHandlers.handleUpdateThemeFontScheme(updates.fontScheme);
34758
+ }
34759
+ },
34760
+ [themeHandlers]
34761
+ );
34762
+ const bumpAiHistory = useCallback(() => {
34763
+ state.setPointerCommitNonce((n) => n + 1);
34764
+ }, [state]);
34765
+ const aiPanel = useAiPanelController({
34766
+ activeSlideIndex,
34767
+ selectedElementId,
34768
+ selectedElementIds,
34769
+ selectedElement
34770
+ });
34771
+ const aiBridge = useAiBridge({
34772
+ slides,
34773
+ activeSlideIndex,
34774
+ canvasSize,
34775
+ theme: state.theme,
34776
+ fileName,
34777
+ selectedElementId,
34778
+ selectedElementIds,
34779
+ pinnedFocus: aiPanel.pinnedFocus,
34780
+ pickedFocus: aiPanel.pickTargets.length > 0 ? aiPanel.pickTargets : null,
34781
+ handlerRef,
34782
+ sections: state.sections,
34783
+ presentationProperties: state.presentationProperties,
34784
+ customProperties: state.customProperties,
34785
+ coreProperties: state.coreProperties,
34786
+ appProperties: state.appProperties,
34787
+ setCanvasSize: state.setCanvasSize,
34788
+ setSections: state.setSections,
34789
+ setPresentationProperties: state.setPresentationProperties,
34790
+ setCustomProperties: state.setCustomProperties,
34791
+ setCoreProperties: state.setCoreProperties,
34792
+ setAppProperties: state.setAppProperties,
34793
+ setSlides: state.setSlides,
34794
+ setActiveSlideIndex: state.setActiveSlideIndex,
34795
+ applySelection: editorOps.ops.applySelection,
34796
+ bumpHistory: bumpAiHistory,
34797
+ markDirty: history.markDirty,
34798
+ applyThemeUpdates: applyAiTheme
34799
+ });
33672
34800
  const showSlidesPane = mode === "edit" && !isMobile && !dialogs.isNarrowViewport && state.isSlidesPaneOpen;
33673
34801
  const showMasterPane = mode === "master" && !isMobile && state.isSlidesPaneOpen;
33674
34802
  const viewerContent = /* @__PURE__ */ jsxs(
@@ -33717,7 +34845,10 @@ var PowerPointViewer = forwardRef(
33717
34845
  autosaveStatus,
33718
34846
  autosaveEnabled,
33719
34847
  onToggleAutosave: () => setAutosaveEnabled((p) => !p),
33720
- hiddenActions
34848
+ hiddenActions,
34849
+ aiEnabled: Boolean(ai),
34850
+ isAiPanelOpen: aiPanel.isOpen,
34851
+ onToggleAiPanel: aiPanel.toggle
33721
34852
  }
33722
34853
  ),
33723
34854
  /* @__PURE__ */ jsx(
@@ -33752,7 +34883,10 @@ var PowerPointViewer = forwardRef(
33752
34883
  onResizeLeft: isMobile ? void 0 : resizablePanels.onResizeLeft,
33753
34884
  rightPanelWidth: isMobile ? void 0 : resizablePanels.rightWidth,
33754
34885
  onResizeRight: isMobile ? void 0 : resizablePanels.onResizeRight,
33755
- hiddenActions
34886
+ hiddenActions,
34887
+ aiConfig: ai,
34888
+ aiBridge: ai ? aiBridge : void 0,
34889
+ aiPanel: ai ? aiPanel : void 0
33756
34890
  }
33757
34891
  ),
33758
34892
  mode !== "present" && (!isVirtualKeyboardOpen || !state.isSlideNotesCollapsed) && /* @__PURE__ */ jsx(
@@ -33845,7 +34979,8 @@ var PowerPointViewer = forwardRef(
33845
34979
  onSelectTheme: handleThemeChange,
33846
34980
  localeCode,
33847
34981
  availableLocales: resolvedLocales,
33848
- onSelectLocale: handleLocaleChange
34982
+ onSelectLocale: handleLocaleChange,
34983
+ aiEnabled: Boolean(ai)
33849
34984
  }
33850
34985
  ),
33851
34986
  isHeaderFooterOpen && /* @__PURE__ */ jsx(