pptx-react-viewer 4.14.0 → 4.16.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 (136) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/{AiChatPanel-WQUOEVQB.mjs → AiChatPanel-5Z4BYP7S.mjs} +4 -4
  3. package/dist/AiChatPanel-5Z4BYP7S.mjs.br +0 -0
  4. package/dist/AiChatPanel-5Z4BYP7S.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-PULXQTFJ.js → AiChatPanel-DHLJ6LKF.js} +28 -28
  6. package/dist/AiChatPanel-DHLJ6LKF.js.br +0 -0
  7. package/dist/AiChatPanel-DHLJ6LKF.js.gz +0 -0
  8. package/dist/{Model3DScene-6MYHPE5N.js → Model3DScene-AXT5KCUX.js} +2 -2
  9. package/dist/Model3DScene-AXT5KCUX.js.br +0 -0
  10. package/dist/Model3DScene-AXT5KCUX.js.gz +0 -0
  11. package/dist/{Model3DScene-HZG33BWN.mjs → Model3DScene-N36X5Z2Z.mjs} +1 -1
  12. package/dist/Model3DScene-N36X5Z2Z.mjs.br +0 -0
  13. package/dist/Model3DScene-N36X5Z2Z.mjs.gz +0 -0
  14. package/dist/{chunk-WSYKEPW6.mjs → chunk-BTTAYCGK.mjs} +904 -1201
  15. package/dist/chunk-BTTAYCGK.mjs.br +0 -0
  16. package/dist/chunk-BTTAYCGK.mjs.gz +0 -0
  17. package/dist/{chunk-E6VYR3GM.js → chunk-BZNYI5U6.js} +866 -820
  18. package/dist/chunk-BZNYI5U6.js.br +0 -0
  19. package/dist/chunk-BZNYI5U6.js.gz +0 -0
  20. package/dist/{chunk-55OLQ7HS.mjs → chunk-CJSIEITL.mjs} +3 -0
  21. package/dist/chunk-CJSIEITL.mjs.br +0 -0
  22. package/dist/chunk-CJSIEITL.mjs.gz +0 -0
  23. package/dist/{chunk-XWO367ZG.js → chunk-FVLBN45Z.js} +5 -5
  24. package/dist/chunk-FVLBN45Z.js.br +0 -0
  25. package/dist/chunk-FVLBN45Z.js.gz +0 -0
  26. package/dist/{chunk-AJTFPTSN.mjs → chunk-MFGRRONU.mjs} +2 -2
  27. package/dist/chunk-MFGRRONU.mjs.br +0 -0
  28. package/dist/chunk-MFGRRONU.mjs.gz +0 -0
  29. package/dist/{chunk-UWVRB4Z5.mjs → chunk-MJ6LTUJ3.mjs} +3437 -1237
  30. package/dist/chunk-MJ6LTUJ3.mjs.br +0 -0
  31. package/dist/chunk-MJ6LTUJ3.mjs.gz +0 -0
  32. package/dist/{chunk-DI4YTG3J.js → chunk-QAVJDYB2.js} +197 -197
  33. package/dist/chunk-QAVJDYB2.js.br +0 -0
  34. package/dist/chunk-QAVJDYB2.js.gz +0 -0
  35. package/dist/{chunk-EPMT65EN.mjs → chunk-QLUA63T3.mjs} +54 -9
  36. package/dist/chunk-QLUA63T3.mjs.br +0 -0
  37. package/dist/chunk-QLUA63T3.mjs.gz +0 -0
  38. package/dist/{chunk-RK5UV5HL.js → chunk-UVK2WBCU.js} +2047 -2344
  39. package/dist/chunk-UVK2WBCU.js.br +0 -0
  40. package/dist/chunk-UVK2WBCU.js.gz +0 -0
  41. package/dist/{chunk-ECKXYCP3.mjs → chunk-WRQ7K3DG.mjs} +1 -1
  42. package/dist/chunk-WRQ7K3DG.mjs.br +0 -0
  43. package/dist/chunk-WRQ7K3DG.mjs.gz +0 -0
  44. package/dist/{chunk-HIYK7HPX.js → chunk-XEYB25ZT.js} +3 -0
  45. package/dist/chunk-XEYB25ZT.js.br +0 -0
  46. package/dist/chunk-XEYB25ZT.js.gz +0 -0
  47. package/dist/{chunk-6ZR27XTL.js → chunk-XZUIS3VB.js} +3454 -1242
  48. package/dist/chunk-XZUIS3VB.js.br +0 -0
  49. package/dist/chunk-XZUIS3VB.js.gz +0 -0
  50. package/dist/i18n/de.cjs +3 -0
  51. package/dist/i18n/de.cjs.br +0 -0
  52. package/dist/i18n/de.cjs.gz +0 -0
  53. package/dist/i18n/de.mjs +3 -0
  54. package/dist/i18n/de.mjs.br +0 -0
  55. package/dist/i18n/de.mjs.gz +0 -0
  56. package/dist/i18n/es.cjs +3 -0
  57. package/dist/i18n/es.cjs.br +0 -0
  58. package/dist/i18n/es.cjs.gz +0 -0
  59. package/dist/i18n/es.mjs +3 -0
  60. package/dist/i18n/es.mjs.br +0 -0
  61. package/dist/i18n/es.mjs.gz +0 -0
  62. package/dist/i18n/fr.cjs +3 -0
  63. package/dist/i18n/fr.cjs.br +0 -0
  64. package/dist/i18n/fr.cjs.gz +0 -0
  65. package/dist/i18n/fr.mjs +3 -0
  66. package/dist/i18n/fr.mjs.br +0 -0
  67. package/dist/i18n/fr.mjs.gz +0 -0
  68. package/dist/i18n/zh-CN.cjs +3 -0
  69. package/dist/i18n/zh-CN.cjs.br +0 -0
  70. package/dist/i18n/zh-CN.cjs.gz +0 -0
  71. package/dist/i18n/zh-CN.mjs +3 -0
  72. package/dist/i18n/zh-CN.mjs.br +0 -0
  73. package/dist/i18n/zh-CN.mjs.gz +0 -0
  74. package/dist/i18n.js +4 -4
  75. package/dist/i18n.js.br +0 -0
  76. package/dist/i18n.js.gz +0 -0
  77. package/dist/i18n.mjs +1 -1
  78. package/dist/i18n.mjs.br +0 -0
  79. package/dist/i18n.mjs.gz +0 -0
  80. package/dist/index.d.ts +329 -267
  81. package/dist/index.js +63 -63
  82. package/dist/index.js.br +0 -0
  83. package/dist/index.js.gz +0 -0
  84. package/dist/index.mjs +6 -6
  85. package/dist/index.mjs.br +0 -0
  86. package/dist/index.mjs.gz +0 -0
  87. package/dist/internals.d.ts +643 -573
  88. package/dist/internals.js +105 -105
  89. package/dist/internals.js.br +0 -0
  90. package/dist/internals.js.gz +0 -0
  91. package/dist/internals.mjs +4 -4
  92. package/dist/internals.mjs.br +0 -0
  93. package/dist/internals.mjs.gz +0 -0
  94. package/dist/pptx-viewer.css +1 -1
  95. package/dist/pptx-viewer.css.br +0 -0
  96. package/dist/pptx-viewer.css.gz +0 -0
  97. package/dist/viewer/index.d.ts +196 -136
  98. package/dist/viewer/index.js +27 -27
  99. package/dist/viewer/index.js.br +0 -0
  100. package/dist/viewer/index.js.gz +0 -0
  101. package/dist/viewer/index.mjs +6 -6
  102. package/dist/viewer/index.mjs.br +0 -0
  103. package/dist/viewer/index.mjs.gz +0 -0
  104. package/package.json +2 -2
  105. package/dist/AiChatPanel-PULXQTFJ.js.br +0 -0
  106. package/dist/AiChatPanel-PULXQTFJ.js.gz +0 -0
  107. package/dist/AiChatPanel-WQUOEVQB.mjs.br +0 -0
  108. package/dist/AiChatPanel-WQUOEVQB.mjs.gz +0 -0
  109. package/dist/Model3DScene-6MYHPE5N.js.br +0 -0
  110. package/dist/Model3DScene-6MYHPE5N.js.gz +0 -0
  111. package/dist/Model3DScene-HZG33BWN.mjs.br +0 -0
  112. package/dist/Model3DScene-HZG33BWN.mjs.gz +0 -0
  113. package/dist/chunk-55OLQ7HS.mjs.br +0 -0
  114. package/dist/chunk-55OLQ7HS.mjs.gz +0 -0
  115. package/dist/chunk-6ZR27XTL.js.br +0 -0
  116. package/dist/chunk-6ZR27XTL.js.gz +0 -0
  117. package/dist/chunk-AJTFPTSN.mjs.br +0 -0
  118. package/dist/chunk-AJTFPTSN.mjs.gz +0 -0
  119. package/dist/chunk-DI4YTG3J.js.br +0 -0
  120. package/dist/chunk-DI4YTG3J.js.gz +0 -0
  121. package/dist/chunk-E6VYR3GM.js.br +0 -0
  122. package/dist/chunk-E6VYR3GM.js.gz +0 -0
  123. package/dist/chunk-ECKXYCP3.mjs.br +0 -0
  124. package/dist/chunk-ECKXYCP3.mjs.gz +0 -0
  125. package/dist/chunk-EPMT65EN.mjs.br +0 -0
  126. package/dist/chunk-EPMT65EN.mjs.gz +0 -0
  127. package/dist/chunk-HIYK7HPX.js.br +0 -0
  128. package/dist/chunk-HIYK7HPX.js.gz +0 -0
  129. package/dist/chunk-RK5UV5HL.js.br +0 -0
  130. package/dist/chunk-RK5UV5HL.js.gz +0 -0
  131. package/dist/chunk-UWVRB4Z5.mjs.br +0 -0
  132. package/dist/chunk-UWVRB4Z5.mjs.gz +0 -0
  133. package/dist/chunk-WSYKEPW6.mjs.br +0 -0
  134. package/dist/chunk-WSYKEPW6.mjs.gz +0 -0
  135. package/dist/chunk-XWO367ZG.js.br +0 -0
  136. package/dist/chunk-XWO367ZG.js.gz +0 -0
@@ -1,12 +1,12 @@
1
- import { computeFocusTargets, deckDataFieldChanged, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, collectStoredChats, exportAiChatLogs, applyElementUpdate } from './chunk-ECKXYCP3.mjs';
2
- import { useViewerOptions, useReadOnlyRecommendationState, useCompatibilityToastsState, useReducedMotion, useViewerState, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useViewPreferencesSync, useLayoutSwitching, ViewerOptionsContext, Rendering3DFlagsContext, CollaborationProvider, useCollaboration, useCollaborationDocumentSync, useFollowMode, useBroadcastFollower, SlideBackgroundImageLayer, StaticElementRenderer, safePrompt, scopeLayoutOptionsToActiveSlide, ChartPartSelectionProvider, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, useViewerOptionsContext, useVirtualizedSlides, useSwipeNavigation, PresentationTransitionOverlay, RemoteSelectionOverlay, CollaborationCursorOverlay, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, ElementRenderer, InlineCollaborationContext, SmartArtRenderer, playAnimationSound, ResizeHandles, imgSrc, renderStrokeView, useChartPartSelection, resolveSmartArtDataPalette } from './chunk-EPMT65EN.mjs';
3
- import { SHAPE_PRESETS, ANIMATION_PRESET_OPTIONS, cn, SLIDE_NAV_THUMBNAIL_WIDTH, DEFAULT_SECTION_GROUP_ID, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, TOOLBAR_SECTIONS, isConnectorOrLineElement, GRID_SIZE, MIN_ELEMENT_SIZE, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, DEFAULT_FILL_COLOR, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation, DEFAULT_STROKE_COLOR, STROKE_DASH_OPTIONS } from './chunk-AJTFPTSN.mjs';
4
- import { FIXED_TAB_GALLERIES, EMPTY_RESOLVED_CUSTOMIZATION, ANIMATION_DIRECTION_LABEL_KEYS, SWITCHABLE_LAYOUT_TYPES, compileEquationTemplateMathMl, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, isFeatureEnabled, isDialogAvailable, resolveAutosaveActivation, buildThemeColorMap, viewerOptionsToPreferences, applyPreferenceToOptions, resolveHistoryDepth, applyAutoCorrect, resolveImageResolutionScale, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, isPanelVisible, shouldShowAutosaveRecoveryPrompt, resolveOptionRootClasses, RIBBON_SCOPE_ATTR, resolve3DRenderingFlags, resolveSlideSizeSelection, RULER_THICKNESS, RULER_FONT_SIZE, buildPreviewElements, deriveSlideFieldContext, SLIDE_TRANSITION_OPTIONS, hiddenSlideCue, HIDDEN_SLIDE_SLASH_GRADIENT, HIDDEN_SLIDE_LABEL_KEY, visibleTemplateElements, normalizeHexColor, themeToCssVars, createCustomizationController, resolveEffectiveHiddenActions, listAutosaveSnapshots, resolveExpiredAutosaveSnapshots, deleteAutosaveSnapshot, masterViewCrudActions, applyMasterViewCrudAction, masterViewCrudFailureKey, ribbonCustomizationCss, applyMotionPathPreset, resetSlideLayoutPath, DEFAULT_INSERT_CHART_KIND, hasCopyableFormat, templateSchemeFromTheme, createBackstagePresentation, playFeedbackSound, shouldDiscardAutosaveOnSuccessfulSave, setMasterViewBackgroundColor, resolveEditPointsAvailability, canUseClipboard, runProgramNoticeStackStyle, compatToastStackStyle, printPropertiesFrameSlides, printPropertiesSlidesPerPage, PASTE_SPECIAL_OPTIONS, getDensePanelTouchTargetPx, shouldStickyActionRow, customizeOptionsTabs, VIEWER_OPTIONS_TABS, isOptionsPageVisible, DEFAULT_QUICK_ACCESS_COMMAND_IDS, isHeaderFooterDateTextVisible, isHeaderFooterHeaderTextVisible, isHeaderFooterFooterTextVisible, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, getSlideBackgroundStyle, pushRecentColor, mruColorsPatch, shouldClearAutosaveCacheOnClose, canCropElement, cropSessionChanged, cancelCropUpdate, startCropSession, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, masterViewBackgroundColor, buildFieldSubstitutionContext, shouldConfirmExternalHyperlink, safeOpenUrl, resolvePresentationAction, isPpactionUrl, parsePpactionUrl, isPresentationAdvanceClick, toggleBlackboard, PRESENT_TOOLBAR_CLASSES, customizeContextMenuEntries, buildContextMenuEntries, customizeCanvasContextMenuEntries, buildCanvasContextMenuEntries, isCurrentLayout, themeColorSchemesEqual, observeElementHeight, EXPANDED_MAX_HEIGHT, STATUS_BAR_CLASSES, buildBarActions, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, compileLatexEquation, convertLatexToOmml, EQUATION_TEMPLATES, clampPercent2, resolveDefaultPrintSettings, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, CUSTOM_FONT_ACCEPT, activateModalFocus, buildCollaborationShareUrl, buildActiveSessionUsers, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, SORTER_MAX_ZOOM, canGoPrevious, formatSlideCounter, READING_VIEW_COUNTER_ATTR, canGoNext, READING_VIEW_ATTR, OUTLINE_LEVEL_ATTR, OUTLINE_SLIDE_ATTR, OUTLINE_ROW_ATTR, OUTLINE_VIEW_ATTR, mobileElapsedSince, nextPresentedSlide, presenterPrevDisabled, presenterNextDisabled, formatMobileElapsed, mobileSlideCounter, presenterPaneAdvancesOnClick, presenterTimerProgress, PRESENTER_CONSOLE_CLASSES, formatElapsed, cropModeKeyAction, extraQuickAccessCommands, visibleContextualTabs, resolveActiveRibbonTab, resolveScreenTip, contextualTabLabelKey, RIBBON_CONTEXTUAL_TAB_ATTR, TAB_ROW_ACTION_CLASSES, customizeBackstageNav, BACKSTAGE_NAV, listBackstageRecentFiles, BACKSTAGE_BACK_CLASSES, BACKSTAGE_NAV_CLASSES, hasTextProperties, COMMON_FONT_SIZES, textFontSizePtToPx, INSERT_CHART_TYPES, ACTION_BUTTON_PRESETS, hasShapeProperties, shapeFillChange, shapeOutlineChange, CONTEXTUAL_TAB_GROUPS, resolveSlidePaneClick, SLIDE_VIRTUALIZATION_THRESHOLD, buildSlidePaneContextMenuEntries, isEditPointsEnabled, PRESENTATION_HIT_TEST_CSS, PRESENTATION_STAGE_ATTRIBUTE, buildStrokePathD, cursorForTool, annotationOverlayZIndex, presentationInkPath, resolveNotesSchematicBodyFontSizePx, PRESENTER_NAVIGATOR_LABEL_KEYS, PEN_COLORS, HIGHLIGHTER_COLORS, isBlackboardActive, clampFlyoutPosition, buildLayoutPreviewGeometry, scaleSlidesForSizeChange, slideSizeToCanvasPx, resolveSelectionPaneRename, PRESET_THEMES, resolveNotesSegments, segmentsToEditorHtml, DEBOUNCE_MS, createPlainNotesSegments, parseSegmentsFromRichEditor, segmentsToPlainText, getCurrentParagraphIndex, segmentsToParagraphs, paragraphsToSegments, MAX_INDENT_LEVEL, INDENT_PX, isUrlSafe, buildNotesPrintHtml, MIN_TOUCH_TARGET_PX, toggleSheet, SMARTART_PREVIEW_ELEMENT_HEIGHT, SMARTART_PREVIEW_ELEMENT_WIDTH, buildSmartArtPreviewElement, sanitizeMathMl, computeHandoutLayout, getPrintableArea, generateNoteLineCount, computeAllNotesPages, getNotesPrintableArea, downloadBlob, clampOptionNumber, QUICK_ACCESS_COMMAND_CATALOG, registerCustomFont, openReadingView, applyReadingViewCommand, createPresentationKeyBuffer, readingViewFitScale, READING_VIEW_STAGE_ATTR, buildOutline, applyOutlineEdit, mapOutlineKey, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, PRESENTER_CONSOLE_CONTROLS, NOTES_FONT_SIZE_DEFAULT, formatTime, NOTES_FONT_SIZE_MIN, clampNotesFontSize, NOTES_FONT_SIZE_STEP, NOTES_FONT_SIZE_MAX, BACKSTAGE_TEMPLATES, formatBackstageDate, formatBackstageSize, customizeBackstageCards, backstageCardsFor, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, resolveDefaultFontFamily, textFontSizePxToPt, buildFontCatalog, RIBBON_CONTROL_ATTR, RIBBON_GROUP_ATTR, FREEFORM_TOOL_IDS, isDrawingToolVisible, FREEFORM_TOOL_LABEL_KEYS, getSelectionTextStyleFlags, getInlineEditorSelectionResult, selectedParagraphBulletKind, elementBulletKind, selectionBulletKind, TEXT_DECORATION_FLAGS, nextToggleValue, CHARACTER_SPACING_OPTIONS, OFFICE_COLOR_SWATCHES, RIBBON_SHAPE_SWATCHES, buildRibbonGallery, galleryHasItems, inlineGalleryItems, canGroupSelection, canUngroupSelection, canSetStrokeWidth, strokeWidthOf, readRibbonTransitionDraft, ribbonTransitionUpdates, playSlideTransitionPreview, RIBBON_TRANSITION_PRESETS, transitionSoundOptions, transitionSoundSelectedValue, DEFAULT_MOTION_PATH_PRESET_ID, SLIDE_SHOW_OPTIONS, slideShowOptionChange, readSlideShowOption, masterViewPseudoSlide, motionPathFor, setMotionPath, getShapeAdjustmentHandleDescriptors, shouldShowElementHandles, MERGE_SHAPES_MENU_ITEMS, hasMultipleSelectedTableCells, computeAnchoredPopupPosition, applyTableStyleDelete, applyTableStyleMapChange, themeColorLabel, buildThemeColorGrid, THEME_COLOR_SCHEME_KEYS, COMMON_FONTS, handleReadingViewKey, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, SLIDE_TEMPLATES, buildThemeColorSwatchGrid, themeColorSwatchRows, findSelectedThemeSwatch, themeSwatchCommit, RIBBON_GALLERY_POPUP_ATTR, applyRibbonGalleryItem, galleryItemLabel, RIBBON_GALLERY_ITEM_ATTR, RIBBON_GALLERY_ATTR, MERGE_SHAPES_LABEL_KEY, MERGE_SHAPES_HINT_KEY, CROP_LABEL_KEY, CROP_ASPECT_LABEL_KEY, CROP_ASPECT_GROUP_LABEL_KEYS, CROP_ASPECT_PRESETS, CROP_FILL_LABEL_KEY, CROP_FIT_LABEL_KEY, readSoundFileAsDataUrl, applyTransitionSoundFile, TRANSITION_SOUND_OTHER_VALUE, TRANSITION_SOUND_NONE_VALUE, clearTransitionSound, applyTransitionStockSound, transitionStockSoundId, getEffectSoundAsset, playAnimationRibbonPreview, ENTRANCE_PRESET_VALUES, EMPHASIS_PRESET_VALUES, EXIT_PRESET_VALUES, MOTION_PATH_FAMILIES, motionPathFamilyLabelKey, motionPathPresetsByFamily, motionPathPresetLabelKey, attachEditorImagePaste, authorConnectorBetweenSites, findEraserHitElementId, generateTicks, rulerDragToGuidePosition, resolveElementInteractivity, getElementTransformWithoutRotation, getElementTransform, buildChartQuickActionsDescriptor, applyChartElementToggle, CHART_QUICK_ACTION_BUTTON_SIZE, applyChartStylePreset, hideChartSeries, restoreFilteredSeries, buildCropOverlay, CROP_HANDLE_ARIA_KEY, getActiveXControlOverlayView, buildCommentMarkers, COMMENT_MARKER_SIZE, collectConnectorSiteCandidates, getConnectorEndpointHandles, findConnectorSiteNear, motionPathToSvgD, motionPathEndPixel, isEditableMotionPath, setMotionPathEnd, canEditElementPoints, isElementLocked, isImageLikeElement, mergeSlideTransition, getElementLabel, effectiveDirection, TRIGGER_OPTIONS, effectiveTimingCurve, mapSlideSorterKey, isEditorTextInputTarget, clampSorterZoom, buildSlideTemplateContent, buildFreeformShapeElement, buildLiveInkStrokeView, beginCropDrag, CONNECTOR_SITE_SNAP_PX, resolveConnectorEndpointUpdate, withConnectorEndpointUpdate, getShapeConnectionSites, FreeformToolSession, attachOverlayKeyboard, EditPointsSession, EDIT_POINTS_STYLE, elementLockTogglePatch, buildTableDataGrid, getDenseGridLayoutPlan, appendTableElementRow, removeLastTableElementRow, appendTableElementColumn, removeLastTableElementColumn, removeTableElementColumn, removeTableElementRow, setTableElementCellText, TABLE_STYLE_PRESETS, applyTableStylePreset, tableStyleAssignmentUpdate, evenColumnWidths, redistributeColumnWidth, evenRowHeights, patchChartData, collapseChartTitleRunsForEdit, chartGridlinesState, chartGridlinesPatch, seriesSecondaryAxisPatch, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setDataLabelsRangeCache, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, describeSmartArtBounds, canAddTopLevelNode, classifyExtraConnections, siblingIndex, siblingCount, canRemoveTopLevelNode, canInteractWithElement, buildOleObjectNamePatch, getOleObjectTypeLabel, sanitizeGradientStops, shouldShowAccessibilitySection, pptxActionToElementAction, withFrameSlides, withSlidesPerPage, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, schemaLabel, THEME_COLOR_SLOT_LABEL_KEYS, SLIDE_SIZE_PRESETS, TRANSITION_VALID_DIRECTIONS, TRANSITION_ORIENTATION_TYPES, TRANSITION_PATTERN_OPTIONS, TRANSITION_THRUBLK_TYPES, clampTransitionNumber, TRANSITION_SPEED_OPTIONS, TRANSITION_MORPH_OPTIONS, flattenTagCollections, resolveTemplateBackgroundRows, formatCommentTimestamp, commentMentionQuery, matchCommentMentionAuthors, buildAnimationTimelineRows, clearMotionPath, setTrigger, setTriggerBookmark, getEffectSoundState, setEffectSound, setEffectStockSound, setAfterAnimation, setAfterAnimationColor, directionValuesFor, buildAnimationTimelineBars, motionPathPresetIdForPath, EFFECT_SOUND_CATALOGUE, listMediaBookmarkOptions, selectedBookmarkOptionValue, hasTiltData, toElementAxes, dragCropHandle, panCropImage, clientToSlidePoint, EDIT_POINTS_TARGET_ATTR, normalizeTableStyleGuid, describeTableStyleEditor, TABLE_STYLE_EDITOR_PARTS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, updateMergeAttrsInRawXml, resolveDisplayedChartType, CHART_TYPE_OPTIONS, chartDataLabelsTogglePatch, BAR3D_SHAPE_OPTIONS, bar3DShapePatch, RADAR_STYLE_OPTIONS, radarStylePatch, SURFACE_WIREFRAME_OPTIONS, surfaceWireframePatch, isSeriesUsingSecondaryAxis, listChartUserShapeRows, withChartUserShapeAdded, createDefaultChartUserShape, withChartUserShapeRowRemoved, withChartUserShapeRowTextUpdated, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, addSmartArtNodeAsChild, setSmartArtNodeStyle, removeSmartArtNode, addSiblingAfter, removeEmptyNode, demote, promote, updateSmartArtNodeText, reorder, clampCropValue, DUOTONE_PRESETS, ARTISTIC_EFFECTS, mediaTrimEndSeconds, trimmedMediaDurationMs, mediaTrimEndAbsoluteMs, mediaTrimEndMsFromAbsoluteMs, buildOleEditDialogDescriptor, buildOleContentUpdatePatch, applyOleSheetCellEdit, getOleSheetGrid, applyOleDocumentParagraphEdit, getOleDocumentParagraphs, applyOleNestedDeckElementTextEdit, getOleNestedDeckDetail, replaceOleFile, getNonVisualDescriptionFields, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, elementActionToPptxAction, canCommitActionType, slideSizeFromPreset, withSlideSizeOrientation, TRANSITION_DIR_ARROWS, buildDirectionGrid, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, updateTagInCollections, deleteTagFromCollections, addTagToCollections, commentTextSegments, COMMENT_MENTION_CLASS, COMMENT_MENTION_ATTRIBUTE, insertCommentMention, reorderAnimationTimelineRows, applyAnimationTimelineOrder, animationEffectLabel, overlayPointerInput, TABLE_STYLE_BORDER_SIDES, applyTableStyleFieldEdit, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, getChartUserShapeGroupTransform, withChartUserShapeGroupChildAdded, createDefaultChartUserShapeGroupChild, withChartUserShapeRowUpdated, getChartUserShapeRowChartBox, withChartUserShapeRowFlipUpdated, withChartUserShapeRowRotationUpdated, withChartUserShapeRowChartBoxUpdated, switchSmartArtLayout, rebuildDrawingShapesIfCleared, mediaTrimEndMsFromSeconds, validateMediaTrimRange, SHAPE_QUICK_STYLES, quickStyleSwatchCss, PATTERN_PRESET_OPTIONS, getPatternSvg, COMPOUND_LINE_OPTIONS, LINE_JOIN_OPTIONS, LINE_CAP_OPTIONS, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, toSlideIndex, TABLE_STYLE_BORDER_SIDE_LABEL_KEYS, TABLE_STYLE_DASH_PRESETS, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS, FILL_PATTERN_LABEL_KEYS, openNativeEyeDropper, toggleText3dExtrusion, BEVEL_PRESETS, cropFit, cropFill, cropToAspectRatio } from './chunk-UWVRB4Z5.mjs';
5
- import { LOCALE_CATALOG, ALIGNMENT_LABEL_KEYS } from './chunk-55OLQ7HS.mjs';
6
- import React6, { createContext, lazy, forwardRef, useEffect, useState, useCallback, useMemo, useRef, useLayoutEffect, useSyncExternalStore, useId, useContext, Fragment as Fragment$1, useDeferredValue, Suspense, useReducer } from 'react';
1
+ import { computeFocusTargets, deckDataFieldChanged, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, collectStoredChats, exportAiChatLogs, applyElementUpdate } from './chunk-WRQ7K3DG.mjs';
2
+ import { useViewerOptions, useReadOnlyRecommendationState, useCompatibilityToastsState, useReducedMotion, useViewerState, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useViewPreferencesSync, useLayoutSwitching, Rendering3DFlagsContext, CollaborationProvider, useCollaboration, useCollaborationDocumentSync, useFollowMode, useBroadcastFollower, SlideBackgroundImageLayer, StaticElementRenderer, safePrompt, scopeLayoutOptionsToActiveSlide, ChartPartSelectionProvider, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, ViewerOptionsStoreContext, ViewerOptionsContext, useViewerOptionsContext, useVirtualizedSlides, useSwipeNavigation, PresentationTransitionOverlay, RemoteSelectionOverlay, CollaborationCursorOverlay, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, ElementRenderer, InlineCollaborationContext, SmartArtRenderer, playAnimationSound, ResizeHandles, imgSrc, renderStrokeView, useChartPartSelection, resolveSmartArtDataPalette } from './chunk-QLUA63T3.mjs';
3
+ import { SHAPE_PRESETS, ANIMATION_PRESET_OPTIONS, cn, SLIDE_NAV_THUMBNAIL_WIDTH, DEFAULT_SECTION_GROUP_ID, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, TOOLBAR_SECTIONS, isConnectorOrLineElement, GRID_SIZE, MIN_ELEMENT_SIZE, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, DEFAULT_FILL_COLOR, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation, DEFAULT_STROKE_COLOR, STROKE_DASH_OPTIONS } from './chunk-MFGRRONU.mjs';
4
+ import { FIXED_TAB_GALLERIES, EMPTY_RESOLVED_CUSTOMIZATION, ANIMATION_DIRECTION_LABEL_KEYS, SWITCHABLE_LAYOUT_TYPES, compileEquationTemplateMathMl, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, isFeatureEnabled, isDialogAvailable, resolveAutosaveActivation, buildThemeColorMap, viewerOptionsToPreferences, applyPreferenceToOptions, resolveHistoryDepth, applyAutoCorrect, resolveImageResolutionScale, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, isPanelVisible, shouldShowAutosaveRecoveryPrompt, resolveOptionRootClasses, RIBBON_SCOPE_ATTR, resolve3DRenderingFlags, resolveSlideSizeSelection, RULER_THICKNESS, RULER_FONT_SIZE, editorThumbnailHeight, buildPreviewElements, deriveSlideFieldContext, SLIDE_TRANSITION_OPTIONS, hiddenSlideCue, EDITOR_THUMBNAIL_WIDTH, HIDDEN_SLIDE_SLASH_GRADIENT, HIDDEN_SLIDE_LABEL_KEY, visibleTemplateElements, normalizeHexColor, themeToCssVars, createCustomizationController, resolveEffectiveHiddenActions, listAutosaveSnapshots, resolveExpiredAutosaveSnapshots, deleteAutosaveSnapshot, masterViewCrudActions, applyMasterViewCrudAction, masterViewCrudFailureKey, EDITOR_CHROME_CSS, ribbonCustomizationCss, applyMotionPathPreset, resetSlideLayoutPath, DEFAULT_INSERT_CHART_KIND, hasCopyableFormat, templateSchemeFromTheme, createBackstagePresentation, playFeedbackSound, shouldDiscardAutosaveOnSuccessfulSave, setMasterViewBackgroundColor, canUseClipboard, runProgramNoticeStackStyle, compatToastStackStyle, printPropertiesFrameSlides, printPropertiesSlidesPerPage, PASTE_SPECIAL_OPTIONS, getDensePanelTouchTargetPx, shouldStickyActionRow, customizeOptionsTabs, VIEWER_OPTIONS_TABS, isOptionsPageVisible, DEFAULT_QUICK_ACCESS_COMMAND_IDS, isHeaderFooterDateTextVisible, isHeaderFooterHeaderTextVisible, isHeaderFooterFooterTextVisible, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, getSlideBackgroundStyle, pushRecentColor, mruColorsPatch, shouldClearAutosaveCacheOnClose, canCropElement, cropSessionChanged, cancelCropUpdate, startCropSession, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, editorThumbnailWidth, masterViewBackgroundColor, buildFieldSubstitutionContext, shouldConfirmExternalHyperlink, safeOpenUrl, resolvePresentationAction, isPpactionUrl, parsePpactionUrl, isPresentationAdvanceClick, toggleBlackboard, PRESENT_TOOLBAR_CLASSES, resolveEditPointsAvailability, isCurrentLayout, themeColorSchemesEqual, observeElementHeight, EXPANDED_MAX_HEIGHT, STATUS_BAR_CLASSES, buildBarActions, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, compileLatexEquation, convertLatexToOmml, EQUATION_TEMPLATES, clampPercent2, resolveDefaultPrintSettings, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, CUSTOM_FONT_ACCEPT, activateModalFocus, buildCollaborationShareUrl, buildActiveSessionUsers, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, SORTER_MAX_ZOOM, canGoPrevious, formatSlideCounter, READING_VIEW_COUNTER_ATTR, canGoNext, READING_VIEW_ATTR, OUTLINE_LEVEL_ATTR, OUTLINE_SLIDE_ATTR, OUTLINE_ROW_ATTR, OUTLINE_VIEW_ATTR, mobileElapsedSince, nextPresentedSlide, presenterPrevDisabled, presenterNextDisabled, formatMobileElapsed, mobileSlideCounter, presenterPaneAdvancesOnClick, presenterTimerProgress, PRESENTER_CONSOLE_CLASSES, formatElapsed, cropModeKeyAction, extraQuickAccessCommands, visibleContextualTabs, resolveActiveRibbonTab, resolveScreenTip, contextualTabLabelKey, RIBBON_CONTEXTUAL_TAB_ATTR, TAB_ROW_ACTION_CLASSES, customizeBackstageNav, BACKSTAGE_NAV, listBackstageRecentFiles, BACKSTAGE_BACK_CLASSES, BACKSTAGE_NAV_CLASSES, hasTextProperties, textFontSizePtToPx, INSERT_CHART_TYPES, ACTION_BUTTON_PRESETS, hasShapeProperties, shapeFillChange, shapeOutlineChange, CONTEXTUAL_TAB_GROUPS, editorThumbnailStep, resolveSlidePaneClick, SLIDE_VIRTUALIZATION_THRESHOLD, buildSlidePaneContextMenuEntries, isEditPointsEnabled, PRESENTATION_HIT_TEST_CSS, PRESENTATION_STAGE_ATTRIBUTE, buildStrokePathD, cursorForTool, annotationOverlayZIndex, presentationInkPath, resolveNotesSchematicBodyFontSizePx, PRESENTER_NAVIGATOR_LABEL_KEYS, subtitleRecognitionLanguage, subtitleSettingsFromOptions, getSpeechRecognitionCtor, mergeCaptionResults, PEN_COLORS, HIGHLIGHTER_COLORS, isBlackboardActive, customizeContextMenuEntries, buildContextMenuEntries, customizeCanvasContextMenuEntries, buildCanvasContextMenuEntries, buildLayoutPreviewGeometry, scaleSlidesForSizeChange, slideSizeToCanvasPx, resolveSelectionPaneRename, themeEditorLabels, resolveNotesSegments, segmentsToEditorHtml, DEBOUNCE_MS, createPlainNotesSegments, parseSegmentsFromRichEditor, segmentsToPlainText, getCurrentParagraphIndex, segmentsToParagraphs, paragraphsToSegments, MAX_INDENT_LEVEL, INDENT_PX, isUrlSafe, buildNotesPrintHtml, MIN_TOUCH_TARGET_PX, toggleSheet, SMARTART_PREVIEW_ELEMENT_HEIGHT, SMARTART_PREVIEW_ELEMENT_WIDTH, buildSmartArtPreviewElement, sanitizeMathMl, computeHandoutLayout, getPrintableArea, generateNoteLineCount, computeAllNotesPages, getNotesPrintableArea, downloadBlob, clampOptionNumber, QUICK_ACCESS_COMMAND_CATALOG, registerCustomFont, openReadingView, applyReadingViewCommand, createPresentationKeyBuffer, readingViewFitScale, READING_VIEW_STAGE_ATTR, buildOutline, applyOutlineEdit, mapOutlineKey, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, PRESENTER_CONSOLE_CONTROLS, NOTES_FONT_SIZE_DEFAULT, formatTime, NOTES_FONT_SIZE_MIN, clampNotesFontSize, NOTES_FONT_SIZE_STEP, NOTES_FONT_SIZE_MAX, BACKSTAGE_TEMPLATES, formatBackstageDate, formatBackstageSize, customizeBackstageCards, backstageCardsFor, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, resolveDefaultFontFamily, textFontSizePxToPt, buildFontCatalog, COMMON_FONT_SIZES, RIBBON_CONTROL_ATTR, FREEFORM_TOOL_IDS, isDrawingToolVisible, FREEFORM_TOOL_LABEL_KEYS, getSelectionTextStyleFlags, getInlineEditorSelectionResult, selectedParagraphBulletKind, elementBulletKind, selectionBulletKind, TEXT_DECORATION_FLAGS, nextToggleValue, CHARACTER_SPACING_OPTIONS, OFFICE_COLOR_SWATCHES, RIBBON_GROUP_ATTR, RIBBON_SHAPE_SWATCHES, buildRibbonGallery, galleryHasItems, inlineGalleryItems, canGroupSelection, canUngroupSelection, canSetStrokeWidth, strokeWidthOf, readRibbonTransitionDraft, ribbonTransitionUpdates, playSlideTransitionPreview, RIBBON_TRANSITION_PRESETS, transitionSoundOptions, transitionSoundSelectedValue, DEFAULT_MOTION_PATH_PRESET_ID, SLIDE_SHOW_COMMAND_GROUPS, RECORD_COMMAND_GROUPS, HELP_RIBBON_COMMANDS, masterViewPseudoSlide, PRESENTATION_ANIM_TRIGGER_ATTRIBUTE, motionPathFor, setMotionPath, getShapeAdjustmentHandleDescriptors, shouldShowElementHandles, clampFlyoutPosition, computeAnchoredPopupPosition, applyTableStyleDelete, applyTableStyleMapChange, handleReadingViewKey, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, SLIDE_TEMPLATES, buildThemeColorSwatchGrid, themeColorSwatchRows, findSelectedThemeSwatch, themeSwatchCommit, RIBBON_GALLERY_POPUP_ATTR, applyRibbonGalleryItem, galleryItemLabel, RIBBON_GALLERY_ITEM_ATTR, RIBBON_GALLERY_ATTR, MERGE_SHAPES_LABEL_KEY, MERGE_SHAPES_HINT_KEY, MERGE_SHAPES_MENU_ITEMS, CROP_LABEL_KEY, CROP_ASPECT_LABEL_KEY, CROP_ASPECT_GROUP_LABEL_KEYS, CROP_ASPECT_PRESETS, CROP_FILL_LABEL_KEY, CROP_FIT_LABEL_KEY, readSoundFileAsDataUrl, applyTransitionSoundFile, TRANSITION_SOUND_OTHER_VALUE, TRANSITION_SOUND_NONE_VALUE, clearTransitionSound, applyTransitionStockSound, transitionStockSoundId, getEffectSoundAsset, playAnimationRibbonPreview, ENTRANCE_PRESET_VALUES, EMPHASIS_PRESET_VALUES, EXIT_PRESET_VALUES, MOTION_PATH_FAMILIES, motionPathFamilyLabelKey, motionPathPresetsByFamily, motionPathPresetLabelKey, SLIDE_SHOW_OPTIONS, createViewerOptionsStore, subtitleSettingsLabels, attachEditorImagePaste, authorConnectorBetweenSites, findEraserHitElementId, generateTicks, rulerDragToGuidePosition, resolveElementInteractivity, getElementTransformWithoutRotation, getElementTransform, buildChartQuickActionsDescriptor, applyChartElementToggle, CHART_QUICK_ACTION_BUTTON_SIZE, applyChartStylePreset, hideChartSeries, restoreFilteredSeries, buildCropOverlay, CROP_HANDLE_ARIA_KEY, getActiveXControlOverlayView, buildCommentMarkers, COMMENT_MARKER_SIZE, collectConnectorSiteCandidates, getConnectorEndpointHandles, findConnectorSiteNear, motionPathToSvgD, motionPathEndPixel, isEditableMotionPath, setMotionPathEnd, canEditElementPoints, hasMultipleSelectedTableCells, isElementLocked, isImageLikeElement, mergeSlideTransition, getElementLabel, effectiveDirection, TRIGGER_OPTIONS, effectiveTimingCurve, mapSlideSorterKey, isEditorTextInputTarget, clampSorterZoom, buildSlideTemplateContent, updateSubtitleSettings, buildFreeformShapeElement, buildLiveInkStrokeView, beginCropDrag, CONNECTOR_SITE_SNAP_PX, resolveConnectorEndpointUpdate, withConnectorEndpointUpdate, getShapeConnectionSites, FreeformToolSession, attachOverlayKeyboard, EditPointsSession, EDIT_POINTS_STYLE, elementLockTogglePatch, buildTableDataGrid, getDenseGridLayoutPlan, appendTableElementRow, removeLastTableElementRow, appendTableElementColumn, removeLastTableElementColumn, removeTableElementColumn, removeTableElementRow, setTableElementCellText, TABLE_STYLE_PRESETS, applyTableStylePreset, tableStyleAssignmentUpdate, evenColumnWidths, redistributeColumnWidth, evenRowHeights, patchChartData, collapseChartTitleRunsForEdit, chartGridlinesState, chartGridlinesPatch, seriesSecondaryAxisPatch, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setDataLabelsRangeCache, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, describeSmartArtBounds, canAddTopLevelNode, classifyExtraConnections, siblingIndex, siblingCount, canRemoveTopLevelNode, canInteractWithElement, buildOleObjectNamePatch, getOleObjectTypeLabel, sanitizeGradientStops, shouldShowAccessibilitySection, pptxActionToElementAction, withFrameSlides, withSlidesPerPage, THEME_COLOR_SCHEME_KEYS, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, schemaLabel, THEME_COLOR_SLOT_LABEL_KEYS, SLIDE_SIZE_PRESETS, TRANSITION_VALID_DIRECTIONS, TRANSITION_ORIENTATION_TYPES, TRANSITION_PATTERN_OPTIONS, TRANSITION_THRUBLK_TYPES, clampTransitionNumber, TRANSITION_SPEED_OPTIONS, TRANSITION_MORPH_OPTIONS, flattenTagCollections, resolveTemplateBackgroundRows, formatCommentTimestamp, commentMentionQuery, matchCommentMentionAuthors, buildAnimationTimelineRows, clearMotionPath, setTrigger, setTriggerBookmark, getEffectSoundState, setEffectSound, setEffectStockSound, setAfterAnimation, setAfterAnimationColor, directionValuesFor, buildAnimationTimelineBars, motionPathPresetIdForPath, EFFECT_SOUND_CATALOGUE, listMediaBookmarkOptions, selectedBookmarkOptionValue, hasTiltData, toElementAxes, dragCropHandle, panCropImage, clientToSlidePoint, EDIT_POINTS_TARGET_ATTR, normalizeTableStyleGuid, describeTableStyleEditor, TABLE_STYLE_EDITOR_PARTS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, updateMergeAttrsInRawXml, resolveDisplayedChartType, CHART_TYPE_OPTIONS, chartDataLabelsTogglePatch, BAR3D_SHAPE_OPTIONS, bar3DShapePatch, RADAR_STYLE_OPTIONS, radarStylePatch, SURFACE_WIREFRAME_OPTIONS, surfaceWireframePatch, isSeriesUsingSecondaryAxis, listChartUserShapeRows, withChartUserShapeAdded, createDefaultChartUserShape, withChartUserShapeRowRemoved, withChartUserShapeRowTextUpdated, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, addSmartArtNodeAsChild, setSmartArtNodeStyle, removeSmartArtNode, addSiblingAfter, removeEmptyNode, demote, promote, updateSmartArtNodeText, reorder, clampCropValue, DUOTONE_PRESETS, ARTISTIC_EFFECTS, mediaTrimEndSeconds, trimmedMediaDurationMs, mediaTrimEndAbsoluteMs, mediaTrimEndMsFromAbsoluteMs, buildOleEditDialogDescriptor, buildOleContentUpdatePatch, applyOleSheetCellEdit, getOleSheetGrid, applyOleDocumentParagraphEdit, getOleDocumentParagraphs, applyOleNestedDeckElementTextEdit, getOleNestedDeckDetail, replaceOleFile, getNonVisualDescriptionFields, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, elementActionToPptxAction, canCommitActionType, slideSizeFromPreset, withSlideSizeOrientation, TRANSITION_DIR_ARROWS, buildDirectionGrid, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, updateTagInCollections, deleteTagFromCollections, addTagToCollections, commentTextSegments, COMMENT_MENTION_CLASS, COMMENT_MENTION_ATTRIBUTE, insertCommentMention, reorderAnimationTimelineRows, applyAnimationTimelineOrder, animationEffectLabel, overlayPointerInput, TABLE_STYLE_BORDER_SIDES, applyTableStyleFieldEdit, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, getChartUserShapeGroupTransform, withChartUserShapeGroupChildAdded, createDefaultChartUserShapeGroupChild, withChartUserShapeRowUpdated, getChartUserShapeRowChartBox, withChartUserShapeRowFlipUpdated, withChartUserShapeRowRotationUpdated, withChartUserShapeRowChartBoxUpdated, switchSmartArtLayout, rebuildDrawingShapesIfCleared, mediaTrimEndMsFromSeconds, validateMediaTrimRange, SHAPE_QUICK_STYLES, quickStyleSwatchCss, PATTERN_PRESET_OPTIONS, getPatternSvg, COMPOUND_LINE_OPTIONS, LINE_JOIN_OPTIONS, LINE_CAP_OPTIONS, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, toSlideIndex, TABLE_STYLE_BORDER_SIDE_LABEL_KEYS, TABLE_STYLE_DASH_PRESETS, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS, FILL_PATTERN_LABEL_KEYS, openNativeEyeDropper, toggleText3dExtrusion, BEVEL_PRESETS, cropFit, cropFill, cropToAspectRatio } from './chunk-MJ6LTUJ3.mjs';
5
+ import { LOCALE_CATALOG, ALIGNMENT_LABEL_KEYS } from './chunk-CJSIEITL.mjs';
6
+ import React6, { createContext, lazy, forwardRef, useEffect, useState, useCallback, useMemo, useRef, useLayoutEffect, useSyncExternalStore, useId, useContext, useDeferredValue, Fragment as Fragment$1, Suspense, useReducer } from 'react';
7
7
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
8
  import { useTranslation } from 'react-i18next';
9
- import { LuArrowDown, LuArrowUp, LuArrowRight, LuArrowLeft, LuArrowDownRight, LuArrowDownLeft, LuArrowUpRight, LuArrowUpLeft, LuMessageSquare, LuEyeOff, LuHistory, LuTrash2, LuSettings, LuX, LuCalendarDays, LuClock, LuHash, LuFileText, LuText, LuCast, LuSave, LuUndo, LuRedo, LuSearch, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuSettings2, LuLayers, LuDownload, LuCheck, LuLock, LuEye, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuBug, LuChevronUp, LuChevronDown, LuUpload, LuWifi, LuWifiOff, LuUsers, LuCopy, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuZoomOut, LuZoomIn, LuSpellCheck, LuFileDown, LuMenu, LuSparkles, LuShare2, LuPanelLeft, LuPanelRight, LuFolderOpen, LuSquare, LuImage, LuVideo, LuDatabase, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuReplace, LuMousePointer2, LuShapes, LuPaintBucket, LuPenLine, LuPalette, LuPaintbrush, LuPencil, LuCaseSensitive, LuTimer, LuHighlighter, LuEraser, LuGripVertical, LuLoaderCircle, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuList, LuListOrdered, LuIndentIncrease, LuIndentDecrease, LuLink, LuGrid2X2, LuClipboardPaste, LuCopyPlus, LuScan, LuRotateCcw, LuMonitorOff, LuCirclePlay, LuCirclePause, LuCaptions, LuArrowLeftRight, LuClipboardCopy, LuLayoutGrid, LuWand, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuFilePlus2, LuHouse, LuFileJson, LuBox, LuFileImage, LuClock3, LuUser, LuHardDrive, LuLogIn, LuScissors, LuLayoutTemplate, LuFolderPlus, LuSpline, LuMoveRight, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignHorizontalSpaceAround, LuAlignVerticalSpaceAround, LuGroup, LuUngroup, LuStar, LuMousePointerClick, LuMonitorPlay, LuListVideo, LuCamera, LuCircleHelp, LuBookOpen, LuLanguages, LuGlobe, LuGitCompare, LuMessageSquarePlus, LuLockKeyhole, LuPanelTop, LuGrid3X3, LuPipette, LuRuler, LuMaximize2, LuCode, LuMove, LuRadio, LuAlignJustify, LuColumns3, LuCombine, LuCrop, LuFilter, LuLockOpen, LuReply, LuRotateCw, LuBookmark } from 'react-icons/lu';
9
+ import { LuArrowDown, LuArrowUp, LuArrowRight, LuArrowLeft, LuArrowDownRight, LuArrowDownLeft, LuArrowUpRight, LuArrowUpLeft, LuMessageSquare, LuEyeOff, LuHistory, LuTrash2, LuSettings, LuX, LuCalendarDays, LuClock, LuHash, LuFileText, LuText, LuCast, LuSave, LuUndo, LuRedo, LuSearch, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuSettings2, LuLayers, LuDownload, LuCheck, LuLock, LuEye, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuBug, LuChevronUp, LuChevronDown, LuUpload, LuWifi, LuWifiOff, LuUsers, LuCopy, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuZoomOut, LuZoomIn, LuSpellCheck, LuFileDown, LuMenu, LuSparkles, LuShare2, LuPanelLeft, LuPanelRight, LuFolderOpen, LuSquare, LuImage, LuVideo, LuDatabase, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuReplace, LuMousePointer2, LuShapes, LuPaintBucket, LuPenLine, LuPalette, LuPaintbrush, LuPencil, LuCaseSensitive, LuTimer, LuHighlighter, LuEraser, LuGripVertical, LuLoaderCircle, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuList, LuListOrdered, LuIndentIncrease, LuIndentDecrease, LuLink, LuGrid2X2, LuClipboardPaste, LuCopyPlus, LuScan, LuRotateCcw, LuMonitorOff, LuCirclePlay, LuCirclePause, LuCaptions, LuArrowLeftRight, LuClipboardCopy, LuLayoutGrid, LuWand, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuFilePlus2, LuHouse, LuFileJson, LuBox, LuFileImage, LuClock3, LuUser, LuHardDrive, LuLogIn, LuScissors, LuLayoutTemplate, LuFolderPlus, LuSpline, LuMoveRight, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignHorizontalSpaceAround, LuAlignVerticalSpaceAround, LuGroup, LuUngroup, LuStar, LuMousePointerClick, LuBookOpen, LuLanguages, LuGlobe, LuGitCompare, LuMessageSquarePlus, LuLockKeyhole, LuPanelTop, LuGrid3X3, LuPipette, LuRuler, LuMaximize2, LuCode, LuMove, LuRadio, LuAlignJustify, LuColumns3, LuCombine, LuCrop, LuFilter, LuLockOpen, LuReply, LuRotateCw, LuBookmark } from 'react-icons/lu';
10
10
 
11
11
  var ViewerThemeContext = createContext(void 0);
12
12
  function ViewerThemeProvider({ theme, children }) {
@@ -1101,6 +1101,7 @@ function CropRibbonControls({ canEdit }) {
1101
1101
  "button",
1102
1102
  {
1103
1103
  type: "button",
1104
+ "data-pptx-chrome": "crop-main",
1104
1105
  "data-pptx-ribbon-control": "crop",
1105
1106
  "aria-label": label,
1106
1107
  "aria-pressed": active,
@@ -1116,6 +1117,7 @@ function CropRibbonControls({ canEdit }) {
1116
1117
  "button",
1117
1118
  {
1118
1119
  type: "button",
1120
+ "data-pptx-chrome": "crop-caret",
1119
1121
  "data-pptx-ribbon-control": "crop-menu",
1120
1122
  "aria-label": t(CROP_ASPECT_LABEL_KEY),
1121
1123
  "aria-haspopup": "menu",
@@ -1291,7 +1293,7 @@ function ArrangeSection(p) {
1291
1293
  const hasSel = Boolean(p.selectedElement);
1292
1294
  const canMut = hasSel && p.canEdit;
1293
1295
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", ...groupAttr("home.arrange"), children: [
1294
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
1296
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", "data-pptx-chrome": "arrange-controls", children: [
1295
1297
  /* @__PURE__ */ jsx("div", { className: grp, ...controlAttr("home.arrange.align"), children: ALIGN_BTNS.map((a, i, arr) => /* @__PURE__ */ jsx(
1296
1298
  "button",
1297
1299
  {
@@ -1375,7 +1377,7 @@ function ArrangeSection(p) {
1375
1377
  hiddenActions: p.hiddenActions
1376
1378
  }
1377
1379
  ),
1378
- /* @__PURE__ */ jsxs("div", { className: grp, children: [
1380
+ /* @__PURE__ */ jsxs("div", { className: grp, "data-pptx-chrome": "order-controls", children: [
1379
1381
  /* @__PURE__ */ jsx(
1380
1382
  "button",
1381
1383
  {
@@ -1612,6 +1614,7 @@ function RibbonGallery({
1612
1614
  "button",
1613
1615
  {
1614
1616
  type: "button",
1617
+ "data-pptx-chrome": chevronOnly ? "gallery-caret" : void 0,
1615
1618
  ...galleryAttrs,
1616
1619
  "aria-haspopup": "true",
1617
1620
  "aria-expanded": open,
@@ -2222,7 +2225,7 @@ function AccountPage() {
2222
2225
  return void 0;
2223
2226
  });
2224
2227
  };
2225
- const version = "4.13.0" ;
2228
+ const version = "4.15.0" ;
2226
2229
  return /* @__PURE__ */ jsxs("div", { className: "mt-8 max-w-[700px] space-y-6", children: [
2227
2230
  /* @__PURE__ */ jsxs("section", { className: cardClass, children: [
2228
2231
  /* @__PURE__ */ jsxs("h2", { className: "flex items-center gap-2 text-sm font-semibold", children: [
@@ -2695,42 +2698,50 @@ function ClipboardGroup(p) {
2695
2698
  /* @__PURE__ */ jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: t("pptx.ribbon.clipboard") })
2696
2699
  ] });
2697
2700
  }
2698
- function FontFamilyMenu(p) {
2701
+ function FontPickers(p) {
2699
2702
  const { t } = useTranslation();
2700
- const groups = buildFontCatalog({
2701
- themeFonts: p.themeFonts,
2702
- embeddedFonts: p.embeddedFonts,
2703
- customFonts: p.customFonts
2704
- });
2705
- return /* @__PURE__ */ jsx(RibbonMenu, { anchorRef: p.anchorRef, className: "flex flex-col w-64 pt-1", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1 max-h-80 overflow-y-auto", children: groups.map((group, groupIndex) => /* @__PURE__ */ jsxs(React6.Fragment, { children: [
2706
- /* @__PURE__ */ jsx(
2707
- "div",
2708
- {
2709
- className: `px-3 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground${groupIndex > 0 ? " border-t border-border/60 mt-1" : ""}`,
2710
- children: t(group.labelKey)
2711
- }
2712
- ),
2713
- group.entries.map((entry) => /* @__PURE__ */ jsx(FontRow, { entry, onSelect: p.onSelect }, `${group.id}-${entry.family}`))
2714
- ] }, group.id)) }) });
2715
- }
2716
- function FontRow({
2717
- entry,
2718
- onSelect
2719
- }) {
2720
- const { t } = useTranslation();
2721
- return /* @__PURE__ */ jsxs(
2722
- "button",
2723
- {
2724
- type: "button",
2725
- className: "flex w-full items-center justify-between gap-3 px-3 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",
2726
- style: { fontFamily: entry.family },
2727
- onClick: () => onSelect(entry.family),
2728
- children: [
2729
- /* @__PURE__ */ jsx("span", { className: "truncate", children: entry.family }),
2730
- entry.themeRole && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: t(`pptx.font.role.${entry.themeRole}`) })
2731
- ]
2732
- }
2733
- );
2703
+ const groups = buildFontCatalog(p);
2704
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", "data-ribbon-group": "home.font", children: [
2705
+ /* @__PURE__ */ jsxs("div", { "data-pptx-chrome": "font-picker-controls", children: [
2706
+ /* @__PURE__ */ jsx(
2707
+ WebSelect,
2708
+ {
2709
+ variant: "ribbon-font",
2710
+ "data-font-picker": "family",
2711
+ "data-ribbon-control": "home.font.fontFamily",
2712
+ "aria-label": t("pptx.ribbon.fontFamily"),
2713
+ value: p.fontFamily,
2714
+ disabled: !p.enabled,
2715
+ onChange: (e) => p.onFamily(e.target.value),
2716
+ children: groups.map((group) => /* @__PURE__ */ jsx("optgroup", { label: t(group.labelKey), children: group.entries.map((entry) => /* @__PURE__ */ jsx(
2717
+ "option",
2718
+ {
2719
+ value: entry.family,
2720
+ style: { fontFamily: entry.family },
2721
+ "data-display-label": entry.family,
2722
+ "data-description": entry.themeRole ? t(`pptx.font.role.${entry.themeRole}`) : void 0,
2723
+ children: entry.family
2724
+ },
2725
+ entry.family
2726
+ )) }, group.id))
2727
+ }
2728
+ ),
2729
+ /* @__PURE__ */ jsx(
2730
+ WebSelect,
2731
+ {
2732
+ variant: "ribbon-font",
2733
+ "data-font-picker": "size",
2734
+ "data-ribbon-control": "home.font.fontSize",
2735
+ "aria-label": t("pptx.ribbon.fontSize"),
2736
+ value: p.fontSize,
2737
+ disabled: !p.enabled,
2738
+ onChange: (e) => p.onSize(Number(e.target.value)),
2739
+ children: COMMON_FONT_SIZES.map((size) => /* @__PURE__ */ jsx("option", { value: size, children: size }, size))
2740
+ }
2741
+ )
2742
+ ] }),
2743
+ /* @__PURE__ */ jsx("span", { "data-pptx-chrome": "ribbon-group-label", children: t("pptx.ribbon.font") })
2744
+ ] });
2734
2745
  }
2735
2746
  function useLayoutPreviews(loadPreviews, enabled) {
2736
2747
  const [previews, setPreviews] = useState(/* @__PURE__ */ new Map());
@@ -2889,17 +2900,19 @@ function SlidesGroup(p) {
2889
2900
  }, [layoutMenuOpen]);
2890
2901
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2891
2902
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", ...groupAttr("home.slides"), children: [
2892
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
2903
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", "data-pptx-chrome": "slides-controls", children: [
2893
2904
  /* @__PURE__ */ jsxs(
2894
2905
  "div",
2895
2906
  {
2896
2907
  className: "relative inline-flex items-center",
2897
2908
  ref: newSlideMenuRef,
2898
2909
  ...controlAttr("home.slides.newSlide"),
2910
+ "data-pptx-chrome": "split-button",
2899
2911
  children: [
2900
2912
  /* @__PURE__ */ jsxs(
2901
2913
  "button",
2902
2914
  {
2915
+ "data-pptx-chrome": "split-main",
2903
2916
  type: "button",
2904
2917
  onClick: handleNewSlide,
2905
2918
  disabled: !p.canEdit || p.layoutOptions.length === 0,
@@ -2918,6 +2931,7 @@ function SlidesGroup(p) {
2918
2931
  p.layoutOptions.length > 0 && /* @__PURE__ */ jsx(
2919
2932
  "button",
2920
2933
  {
2934
+ "data-pptx-chrome": "split-caret",
2921
2935
  type: "button",
2922
2936
  disabled: !p.canEdit,
2923
2937
  className: "inline-flex items-center justify-center self-stretch px-1 rounded-r bg-muted hover:bg-accent text-xs transition-colors border-l border-border/40 active:scale-95 active:opacity-80",
@@ -3057,46 +3071,11 @@ function extractFontInfo(element, themeFonts) {
3057
3071
  };
3058
3072
  }
3059
3073
  function HomeSection(p) {
3060
- const { t } = useTranslation();
3061
- const [fontMenuOpen, setFontMenuOpen] = useState(false);
3062
- const [sizeMenuOpen, setSizeMenuOpen] = useState(false);
3063
- const fontMenuRef = useRef(null);
3064
- const sizeMenuRef = useRef(null);
3065
3074
  const { fontFamily, fontSize } = extractFontInfo(p.selectedElement, p.themeFonts);
3066
3075
  const hasSelection = Boolean(p.selectedElement);
3067
3076
  const canFormat = p.canEdit && Boolean(p.onUpdateTextStyle) && Boolean(
3068
3077
  p.selectedElement && (hasTextProperties(p.selectedElement) || p.selectedElement.type === "table" && p.tableEditorState)
3069
3078
  );
3070
- useEffect(() => {
3071
- if (!canFormat) {
3072
- setFontMenuOpen(false);
3073
- setSizeMenuOpen(false);
3074
- }
3075
- }, [canFormat]);
3076
- useEffect(() => {
3077
- if (!fontMenuOpen) {
3078
- return;
3079
- }
3080
- const handler = (e) => {
3081
- if (fontMenuRef.current && !fontMenuRef.current.contains(e.target)) {
3082
- setFontMenuOpen(false);
3083
- }
3084
- };
3085
- document.addEventListener("mousedown", handler);
3086
- return () => document.removeEventListener("mousedown", handler);
3087
- }, [fontMenuOpen]);
3088
- useEffect(() => {
3089
- if (!sizeMenuOpen) {
3090
- return;
3091
- }
3092
- const handler = (e) => {
3093
- if (sizeMenuRef.current && !sizeMenuRef.current.contains(e.target)) {
3094
- setSizeMenuOpen(false);
3095
- }
3096
- };
3097
- document.addEventListener("mousedown", handler);
3098
- return () => document.removeEventListener("mousedown", handler);
3099
- }, [sizeMenuOpen]);
3100
3079
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3101
3080
  /* @__PURE__ */ jsx(
3102
3081
  ClipboardGroup,
@@ -3128,71 +3107,21 @@ function HomeSection(p) {
3128
3107
  onAddSection: p.onAddSection
3129
3108
  }
3130
3109
  ),
3131
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", ...groupAttr("home.font"), children: [
3132
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
3133
- /* @__PURE__ */ jsxs("div", { className: "relative", ref: fontMenuRef, ...controlAttr("home.font.fontFamily"), children: [
3134
- /* @__PURE__ */ jsxs(
3135
- "button",
3136
- {
3137
- type: "button",
3138
- onClick: () => setFontMenuOpen((v) => !v),
3139
- disabled: !canFormat,
3140
- "aria-label": t("pptx.ribbon.fontFamily"),
3141
- className: "inline-flex items-center justify-between px-2 py-1 rounded-sm border border-border/60 bg-background/60 text-[11px] text-foreground min-w-[120px] truncate enabled:hover:bg-accent/40 transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed",
3142
- children: [
3143
- /* @__PURE__ */ jsx("span", { className: "truncate", children: fontFamily }),
3144
- /* @__PURE__ */ jsx(LuChevronDown, { className: "w-3 h-3 ml-1 shrink-0 text-muted-foreground" })
3145
- ]
3146
- }
3147
- ),
3148
- fontMenuOpen && canFormat && /* @__PURE__ */ jsx(
3149
- FontFamilyMenu,
3150
- {
3151
- anchorRef: fontMenuRef,
3152
- themeFonts: p.themeFonts,
3153
- embeddedFonts: p.embeddedFontFamilies,
3154
- customFonts: p.customFontFamilies,
3155
- onSelect: (family) => {
3156
- p.onUpdateTextStyle?.({ fontFamily: family });
3157
- setFontMenuOpen(false);
3158
- }
3159
- }
3160
- )
3161
- ] }),
3162
- /* @__PURE__ */ jsxs("div", { className: "relative", ref: sizeMenuRef, ...controlAttr("home.font.fontSize"), children: [
3163
- /* @__PURE__ */ jsxs(
3164
- "button",
3165
- {
3166
- type: "button",
3167
- onClick: () => setSizeMenuOpen((v) => !v),
3168
- disabled: !canFormat,
3169
- "aria-label": t("pptx.ribbon.fontSize"),
3170
- className: "inline-flex items-center justify-between px-2 py-1 rounded-sm border border-border/60 bg-background/60 text-[11px] text-foreground min-w-[50px] text-center enabled:hover:bg-accent/40 transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed",
3171
- children: [
3172
- /* @__PURE__ */ jsx("span", { className: "truncate", children: fontSize }),
3173
- /* @__PURE__ */ jsx(LuChevronDown, { className: "w-3 h-3 ml-1 shrink-0 text-muted-foreground" })
3174
- ]
3175
- }
3176
- ),
3177
- sizeMenuOpen && canFormat && /* @__PURE__ */ jsx(RibbonMenu, { anchorRef: sizeMenuRef, className: "flex flex-col w-48 pt-1", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1 max-h-60 overflow-y-auto", children: COMMON_FONT_SIZES.map((s) => /* @__PURE__ */ jsx(
3178
- "button",
3179
- {
3180
- type: "button",
3181
- className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",
3182
- onClick: () => {
3183
- p.onUpdateTextStyle?.({
3184
- fontSize: p.selectedElement && hasTextProperties(p.selectedElement) ? textFontSizePtToPx(s) : s
3185
- });
3186
- setSizeMenuOpen(false);
3187
- },
3188
- children: s
3189
- },
3190
- s
3191
- )) }) })
3192
- ] })
3193
- ] }),
3194
- /* @__PURE__ */ jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: t("pptx.ribbon.font") })
3195
- ] }),
3110
+ /* @__PURE__ */ jsx(
3111
+ FontPickers,
3112
+ {
3113
+ enabled: canFormat,
3114
+ fontFamily,
3115
+ fontSize,
3116
+ themeFonts: p.themeFonts,
3117
+ embeddedFonts: p.embeddedFontFamilies,
3118
+ customFonts: p.customFontFamilies,
3119
+ onFamily: (family) => p.onUpdateTextStyle?.({ fontFamily: family }),
3120
+ onSize: (size) => p.onUpdateTextStyle?.({
3121
+ fontSize: p.selectedElement && hasTextProperties(p.selectedElement) ? textFontSizePtToPx(size) : size
3122
+ })
3123
+ }
3124
+ ),
3196
3125
  sep
3197
3126
  ] });
3198
3127
  }
@@ -4031,6 +3960,139 @@ function CustomShowsControls({
4031
3960
  }
4032
3961
  return null;
4033
3962
  }
3963
+ function SlideShowOptions({
3964
+ presentationProperties,
3965
+ onChange,
3966
+ children
3967
+ }) {
3968
+ const ref = useRef(null);
3969
+ const { t } = useTranslation();
3970
+ useLayoutEffect(() => {
3971
+ if (!ref.current) {
3972
+ return;
3973
+ }
3974
+ ref.current.presentationProperties = presentationProperties;
3975
+ ref.current.labels = Object.fromEntries(
3976
+ SLIDE_SHOW_OPTIONS.map((option) => [option.id, t(option.labelKey)])
3977
+ );
3978
+ }, [presentationProperties, t]);
3979
+ useEffect(() => {
3980
+ const host = ref.current;
3981
+ const handler = (event) => onChange?.(event.detail);
3982
+ host?.addEventListener("show-options-change", handler);
3983
+ return () => host?.removeEventListener("show-options-change", handler);
3984
+ }, [onChange]);
3985
+ return /* @__PURE__ */ jsx("pptx-ui-slide-show-options", { ref, children });
3986
+ }
3987
+ function SubtitleSettingsControl() {
3988
+ const { t } = useTranslation();
3989
+ const supplied = useContext(ViewerOptionsStoreContext);
3990
+ const fallback = useRef(null);
3991
+ if (!supplied) {
3992
+ fallback.current ??= createViewerOptionsStore({ persist: false });
3993
+ }
3994
+ const store = supplied ?? fallback.current;
3995
+ const options = useSyncExternalStore(
3996
+ (callback) => store.subscribe(callback),
3997
+ () => store.getOptions(),
3998
+ () => store.getOptions()
3999
+ );
4000
+ const ref = useRef(null);
4001
+ useEffect(() => {
4002
+ const element = ref.current;
4003
+ element.settings = subtitleSettingsFromOptions(options);
4004
+ element.labels = subtitleSettingsLabels((key) => t(key));
4005
+ element.languageDisabled = store.isLocked("accessibility", "subtitleLanguage");
4006
+ }, [options, store, t]);
4007
+ useEffect(() => {
4008
+ const element = ref.current;
4009
+ const commit = (event) => updateSubtitleSettings(store, event.detail);
4010
+ element.addEventListener("subtitle-settings-change", commit);
4011
+ return () => element.removeEventListener("subtitle-settings-change", commit);
4012
+ }, [store]);
4013
+ return /* @__PURE__ */ jsx(
4014
+ "pptx-ui-subtitle-settings",
4015
+ {
4016
+ ref,
4017
+ "data-ribbon-control": "slideShow.captions.subtitleSettings"
4018
+ }
4019
+ );
4020
+ }
4021
+ function useIntent(ref, type, callback) {
4022
+ useEffect(() => {
4023
+ const host = ref.current;
4024
+ if (!host || !callback) {
4025
+ return;
4026
+ }
4027
+ host.addEventListener(type, callback);
4028
+ return () => host.removeEventListener(type, callback);
4029
+ }, [ref, type, callback]);
4030
+ }
4031
+ function WebRibbonGroup({
4032
+ label,
4033
+ groupId,
4034
+ children
4035
+ }) {
4036
+ return /* @__PURE__ */ jsx("pptx-ui-ribbon-group", { label, "data-ribbon-group": groupId, children });
4037
+ }
4038
+ function WebRibbonCommand({
4039
+ label,
4040
+ icon,
4041
+ controlId,
4042
+ title,
4043
+ disabled,
4044
+ active,
4045
+ pressed,
4046
+ expanded,
4047
+ compact,
4048
+ onCommand
4049
+ }) {
4050
+ const ref = useRef(null);
4051
+ useIntent(
4052
+ ref,
4053
+ "command-request",
4054
+ onCommand ? (event) => onCommand(event.detail.id) : void 0
4055
+ );
4056
+ return /* @__PURE__ */ jsx(
4057
+ "pptx-ui-ribbon-command",
4058
+ {
4059
+ ref,
4060
+ label,
4061
+ icon,
4062
+ "data-ribbon-control": controlId,
4063
+ title,
4064
+ disabled: disabled || void 0,
4065
+ active: active || void 0,
4066
+ pressed: pressed === void 0 ? void 0 : String(pressed),
4067
+ expanded: expanded === void 0 ? void 0 : String(expanded),
4068
+ compact: compact || void 0
4069
+ }
4070
+ );
4071
+ }
4072
+ function WebRibbonToggle({
4073
+ label,
4074
+ controlId,
4075
+ checked,
4076
+ title,
4077
+ onToggle
4078
+ }) {
4079
+ const ref = useRef(null);
4080
+ useIntent(
4081
+ ref,
4082
+ "toggle-request",
4083
+ onToggle ? (event) => onToggle(event.detail.checked) : void 0
4084
+ );
4085
+ return /* @__PURE__ */ jsx(
4086
+ "pptx-ui-ribbon-toggle",
4087
+ {
4088
+ ref,
4089
+ label,
4090
+ "data-ribbon-control": controlId,
4091
+ checked: checked || void 0,
4092
+ title
4093
+ }
4094
+ );
4095
+ }
4034
4096
  function SlideShowSection(p) {
4035
4097
  const { t } = useTranslation();
4036
4098
  const { isHidden } = useToolbarVisibility(p.hiddenActions);
@@ -4048,193 +4110,64 @@ function SlideShowSection(p) {
4048
4110
  document.addEventListener("mousedown", handler);
4049
4111
  return () => document.removeEventListener("mousedown", handler);
4050
4112
  }, [showsOpen]);
4113
+ const actions = {
4114
+ "slideShow.startSlideShow.fromBeginning": p.onPresentFromBeginning ?? (() => p.onSetMode("present")),
4115
+ "slideShow.startSlideShow.fromCurrent": p.onPresent,
4116
+ "slideShow.present.presenterView": p.onEnterPresenterView,
4117
+ "slideShow.startSlideShow.customShow": () => setShowsOpen((open) => !open),
4118
+ "slideShow.present.broadcast": p.onOpenBroadcastDialog,
4119
+ "slideShow.setUp.setUpSlideShow": p.onOpenSetUpSlideShow,
4120
+ "slideShow.setUp.hideSlide": p.onToggleHideSlide,
4121
+ "slideShow.setUp.rehearseTimings": p.onEnterRehearsalMode,
4122
+ "slideShow.setUp.record": p.onEnterRehearsalMode
4123
+ };
4124
+ const request = (id) => actions[id]?.();
4051
4125
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4052
- /* @__PURE__ */ jsxs(
4053
- RibbonGroup,
4054
- {
4055
- label: t("pptx.slideShow.start", { defaultValue: "Start Slide Show" }),
4056
- groupId: "slideShow.startSlideShow",
4057
- children: [
4058
- /* @__PURE__ */ jsx(
4059
- RibbonCommand,
4060
- {
4061
- controlId: "slideShow.startSlideShow.fromBeginning",
4062
- label: t("pptx.slideShow.fromBeginning"),
4063
- icon: /* @__PURE__ */ jsx(LuPlay, {}),
4064
- onClick: p.onPresentFromBeginning ?? (() => p.onSetMode("present")),
4065
- title: t("pptx.slideShow.fromBeginningTooltip")
4066
- }
4067
- ),
4068
- /* @__PURE__ */ jsx(
4069
- RibbonCommand,
4070
- {
4071
- controlId: "slideShow.startSlideShow.fromCurrent",
4072
- label: t("pptx.slideShow.fromCurrent"),
4073
- icon: /* @__PURE__ */ jsx(LuMonitorPlay, {}),
4074
- onClick: p.onPresent,
4075
- title: t("pptx.slideShow.fromCurrentTooltip")
4076
- }
4077
- )
4078
- ]
4079
- }
4080
- ),
4081
- /* @__PURE__ */ jsxs(
4082
- RibbonGroup,
4083
- {
4084
- label: t("pptx.slideShow.present", { defaultValue: "Present" }),
4085
- groupId: "slideShow.present",
4086
- children: [
4087
- /* @__PURE__ */ jsx(
4088
- RibbonCommand,
4089
- {
4090
- controlId: "slideShow.present.presenterView",
4091
- label: t("pptx.slideShow.presenterView"),
4092
- icon: /* @__PURE__ */ jsx(LuPresentation, {}),
4093
- onClick: p.onEnterPresenterView,
4094
- title: t("pptx.slideShow.presenterViewTooltip")
4095
- }
4096
- ),
4097
- /* @__PURE__ */ jsxs(
4098
- "div",
4099
- {
4100
- className: "relative",
4101
- ref: showsRef,
4102
- ...controlAttr("slideShow.startSlideShow.customShow"),
4103
- children: [
4104
- /* @__PURE__ */ jsx(
4105
- RibbonCommand,
4106
- {
4107
- label: t("pptx.slideShow.customShow", { defaultValue: "Custom Show" }),
4108
- icon: /* @__PURE__ */ jsx(LuListVideo, {}),
4109
- onClick: () => setShowsOpen((open) => !open),
4110
- active: showsOpen,
4111
- title: t("pptx.customShows.customShowTooltip")
4112
- }
4113
- ),
4114
- showsOpen && /* @__PURE__ */ jsx(RibbonMenu, { anchorRef: showsRef, className: "pt-1", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 rounded-lg border border-border bg-popover p-2 shadow-2xl", children: /* @__PURE__ */ jsx(CustomShowsControls, { ...p.customShowControls }) }) })
4115
- ]
4116
- }
4117
- ),
4118
- !isHidden("broadcast") && /* @__PURE__ */ jsx(
4119
- RibbonCommand,
4120
- {
4121
- controlId: "slideShow.present.broadcast",
4122
- label: t("pptx.slideShow.broadcast"),
4123
- icon: /* @__PURE__ */ jsx(LuCast, {}),
4124
- onClick: p.onOpenBroadcastDialog,
4125
- title: t("pptx.slideShow.broadcastTooltip")
4126
- }
4127
- )
4128
- ]
4129
- }
4130
- ),
4131
- /* @__PURE__ */ jsxs(
4132
- RibbonGroup,
4133
- {
4134
- label: t("pptx.slideShow.setUpGroup", { defaultValue: "Set Up" }),
4135
- groupId: "slideShow.setUp",
4136
- children: [
4137
- /* @__PURE__ */ jsx(
4138
- RibbonCommand,
4139
- {
4140
- controlId: "slideShow.setUp.rehearseWithCoach",
4141
- label: t("pptx.slideShow.rehearseCoach", { defaultValue: "Rehearse with Coach" }),
4142
- icon: /* @__PURE__ */ jsx(LuVideo, {}),
4143
- disabled: true
4144
- }
4145
- ),
4146
- /* @__PURE__ */ jsx(
4147
- RibbonCommand,
4148
- {
4149
- controlId: "slideShow.setUp.setUpSlideShow",
4150
- label: t("pptx.slideShow.setUp"),
4151
- icon: /* @__PURE__ */ jsx(LuSettings2, {}),
4152
- onClick: p.onOpenSetUpSlideShow,
4153
- title: t("pptx.slideShow.setUpTooltip")
4154
- }
4155
- ),
4156
- /* @__PURE__ */ jsx(
4157
- RibbonCommand,
4158
- {
4159
- controlId: "slideShow.setUp.hideSlide",
4160
- label: t("pptx.slideShow.hideSlide", { defaultValue: "Hide Slide" }),
4161
- icon: /* @__PURE__ */ jsx(LuEyeOff, {}),
4162
- onClick: p.onToggleHideSlide,
4163
- active: p.activeSlideHidden,
4164
- pressed: p.activeSlideHidden
4165
- }
4166
- ),
4167
- /* @__PURE__ */ jsx(
4168
- RibbonCommand,
4169
- {
4170
- controlId: "slideShow.setUp.rehearseTimings",
4171
- label: t("pptx.slideShow.rehearseTimings"),
4172
- icon: /* @__PURE__ */ jsx(LuClock3, {}),
4173
- onClick: p.onEnterRehearsalMode,
4174
- title: t("pptx.slideShow.rehearseTimingsTooltip")
4175
- }
4176
- ),
4177
- /* @__PURE__ */ jsx(
4178
- RibbonCommand,
4179
- {
4180
- controlId: "slideShow.setUp.record",
4181
- label: t("pptx.titleBar.record"),
4182
- icon: /* @__PURE__ */ jsx(LuVideo, {}),
4183
- onClick: p.onEnterRehearsalMode
4184
- }
4185
- )
4186
- ]
4187
- }
4188
- ),
4189
- /* @__PURE__ */ jsxs(RibbonGroup, { label: t("pptx.slideShow.options", { defaultValue: "Options" }), children: [
4190
- /* @__PURE__ */ jsx(RibbonCommandStack, { children: SLIDE_SHOW_OPTIONS.slice(0, 3).map((option) => /* @__PURE__ */ jsx(
4191
- RibbonToggle,
4192
- {
4193
- label: t(option.labelKey),
4194
- checked: readSlideShowOption(p.presentationProperties, option.id),
4195
- disabled: option.unsupported,
4196
- onChange: option.unsupported ? void 0 : (next) => {
4197
- const change = slideShowOptionChange(option.id, next);
4198
- if (change) {
4199
- p.onPresentationPropertiesChange?.(change);
4200
- }
4201
- }
4126
+ SLIDE_SHOW_COMMAND_GROUPS.map((group) => /* @__PURE__ */ jsx(WebRibbonGroup, { groupId: group.id, label: t(group.labelKey), children: group.commands.filter(
4127
+ (command) => command.id !== "slideShow.present.broadcast" || !isHidden("broadcast")
4128
+ ).map((command) => {
4129
+ const customShow = command.id === "slideShow.startSlideShow.customShow";
4130
+ const hideSlide = command.id === "slideShow.setUp.hideSlide";
4131
+ const button = /* @__PURE__ */ jsx(
4132
+ WebRibbonCommand,
4133
+ {
4134
+ controlId: command.id,
4135
+ label: t(command.labelKey),
4136
+ icon: command.icon,
4137
+ title: t(command.tooltipKey ?? command.labelKey),
4138
+ disabled: command.unsupported,
4139
+ active: hideSlide ? p.activeSlideHidden : customShow ? showsOpen : false,
4140
+ pressed: hideSlide ? p.activeSlideHidden : void 0,
4141
+ expanded: customShow ? showsOpen : void 0,
4142
+ onCommand: request
4202
4143
  },
4203
- option.id
4204
- )) }),
4205
- /* @__PURE__ */ jsxs(RibbonCommandStack, { children: [
4206
- /* @__PURE__ */ jsx(
4207
- RibbonToggle,
4208
- {
4209
- label: t(SLIDE_SHOW_OPTIONS[3].labelKey),
4210
- checked: readSlideShowOption(p.presentationProperties, SLIDE_SHOW_OPTIONS[3].id),
4211
- disabled: SLIDE_SHOW_OPTIONS[3].unsupported
4212
- }
4213
- ),
4214
- /* @__PURE__ */ jsxs(RibbonGroupScope, { id: "slideShow.captions", children: [
4144
+ command.id
4145
+ );
4146
+ return customShow ? /* @__PURE__ */ jsxs("div", { className: "relative", ref: showsRef, children: [
4147
+ button,
4148
+ showsOpen && /* @__PURE__ */ jsx(RibbonMenu, { anchorRef: showsRef, className: "pt-1", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 rounded-lg border border-border bg-popover p-2 shadow-2xl", children: /* @__PURE__ */ jsx(CustomShowsControls, { ...p.customShowControls }) }) })
4149
+ ] }, command.id) : button;
4150
+ }) }, group.id)),
4151
+ /* @__PURE__ */ jsx(WebRibbonGroup, { label: t("pptx.slideShow.options"), children: /* @__PURE__ */ jsx(
4152
+ SlideShowOptions,
4153
+ {
4154
+ presentationProperties: p.presentationProperties,
4155
+ onChange: p.onPresentationPropertiesChange,
4156
+ children: /* @__PURE__ */ jsxs(RibbonGroupScope, { id: "slideShow.captions", children: [
4215
4157
  /* @__PURE__ */ jsx(
4216
- RibbonToggle,
4158
+ WebRibbonToggle,
4217
4159
  {
4218
4160
  controlId: "slideShow.captions.subtitles",
4219
4161
  label: t("pptx.slideShow.subtitles"),
4220
4162
  checked: p.showSubtitles,
4221
- onChange: () => p.onToggleSubtitles(),
4222
- title: t("pptx.slideShow.subtitlesTooltip")
4163
+ title: t("pptx.slideShow.subtitlesTooltip"),
4164
+ onToggle: () => p.onToggleSubtitles()
4223
4165
  }
4224
4166
  ),
4225
- /* @__PURE__ */ jsx(
4226
- RibbonCommand,
4227
- {
4228
- compact: true,
4229
- controlId: "slideShow.captions.subtitleSettings",
4230
- label: t("pptx.slideShow.subtitleSettings", { defaultValue: "Subtitle Settings" }),
4231
- icon: /* @__PURE__ */ jsx(LuCaptions, {}),
4232
- onClick: p.onToggleSubtitles
4233
- }
4234
- )
4167
+ /* @__PURE__ */ jsx(SubtitleSettingsControl, {})
4235
4168
  ] })
4236
- ] })
4237
- ] })
4169
+ }
4170
+ ) })
4238
4171
  ] });
4239
4172
  }
4240
4173
  var LINE_SPACING_OPTIONS = [
@@ -5015,8 +4948,8 @@ function TextSection(p) {
5015
4948
  );
5016
4949
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5017
4950
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", ...groupAttr("home.font"), children: [
5018
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
5019
- /* @__PURE__ */ jsx("div", { className: grp, children: FMT.map((b, i, a) => {
4951
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", "data-pptx-chrome": "font-controls", children: [
4952
+ /* @__PURE__ */ jsx("div", { className: grp, "data-pptx-chrome": "control-cluster", children: FMT.map((b, i, a) => {
5020
4953
  const flag = isTextDecorationFlag(b.id) ? b.id : void 0;
5021
4954
  const handleClick = () => {
5022
4955
  if (!canFormat || !p.selectedElement || !flag) {
@@ -5101,7 +5034,7 @@ function TextSection(p) {
5101
5034
  )
5102
5035
  }
5103
5036
  ),
5104
- /* @__PURE__ */ jsxs("div", { className: grp, children: [
5037
+ /* @__PURE__ */ jsxs("div", { className: grp, "data-pptx-chrome": "control-cluster", children: [
5105
5038
  /* @__PURE__ */ jsx(
5106
5039
  "button",
5107
5040
  {
@@ -5533,25 +5466,34 @@ function MobileMenuSheet(props) {
5533
5466
  const { open, onClose } = props;
5534
5467
  const [active, setActive] = useState("home");
5535
5468
  const { isTabVisible } = useToolbarVisibility(props.hiddenActions);
5536
- return /* @__PURE__ */ jsx(MobileSheet, { open, onClose, autoHeight: true, title: t("pptx.mobileToolbar.menu"), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
5537
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-background border-b border-border", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5 px-3 py-2", children: MENU_ITEMS.filter(({ key }) => isTabVisible(key)).map(({ key, label, icon: Icon }) => /* @__PURE__ */ jsxs(
5538
- "button",
5539
- {
5540
- type: "button",
5541
- onClick: () => setActive(active === key ? null : key),
5542
- className: cn(
5543
- "inline-flex items-center gap-1.5 shrink-0 px-3 py-2 rounded-full text-[12px] font-medium border transition-colors min-h-[36px]",
5544
- active === key ? "bg-primary text-white border-primary" : "border-border text-muted-foreground hover:text-foreground hover:bg-accent/40"
5545
- ),
5546
- children: [
5547
- /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4" }),
5548
- t(label)
5549
- ]
5550
- },
5551
- key
5552
- )) }) }),
5553
- /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx(MobileSectionBody, { active, ...props }) })
5554
- ] }) });
5469
+ return /* @__PURE__ */ jsx(
5470
+ MobileSheet,
5471
+ {
5472
+ open: open && !props.isThemeEditorOpen,
5473
+ onClose,
5474
+ autoHeight: true,
5475
+ title: t("pptx.mobileToolbar.menu"),
5476
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
5477
+ /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-background border-b border-border", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5 px-3 py-2", children: MENU_ITEMS.filter(({ key }) => isTabVisible(key)).map(({ key, label, icon: Icon }) => /* @__PURE__ */ jsxs(
5478
+ "button",
5479
+ {
5480
+ type: "button",
5481
+ onClick: () => setActive(active === key ? null : key),
5482
+ className: cn(
5483
+ "inline-flex items-center gap-1.5 shrink-0 px-3 py-2 rounded-full text-[12px] font-medium border transition-colors min-h-[36px]",
5484
+ active === key ? "bg-primary text-white border-primary" : "border-border text-muted-foreground hover:text-foreground hover:bg-accent/40"
5485
+ ),
5486
+ children: [
5487
+ /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4" }),
5488
+ t(label)
5489
+ ]
5490
+ },
5491
+ key
5492
+ )) }) }),
5493
+ /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx(MobileSectionBody, { active, ...props }) })
5494
+ ] })
5495
+ }
5496
+ );
5555
5497
  }
5556
5498
  function MobileSectionBody({
5557
5499
  active,
@@ -5996,7 +5938,7 @@ function DrawingGroup(p) {
5996
5938
  const setArrangeOpen = arrange.setOpen;
5997
5939
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5998
5940
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", ...groupAttr("home.drawing"), children: [
5999
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
5941
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", "data-pptx-chrome": "drawing-controls", children: [
6000
5942
  /* @__PURE__ */ jsxs("div", { className: "relative", ref: shapes.ref, ...controlAttr("home.drawing.shapes"), children: [
6001
5943
  /* @__PURE__ */ jsxs(
6002
5944
  "button",
@@ -6241,6 +6183,7 @@ function RibbonTabBar(p) {
6241
6183
  "div",
6242
6184
  {
6243
6185
  role: "tablist",
6186
+ "data-pptx-chrome": "ribbon-tabs",
6244
6187
  className: "flex items-center border-b border-border/60 px-1 max-md:overflow-x-auto max-md:scrollbar-none",
6245
6188
  children: [
6246
6189
  TOOLBAR_SECTIONS.filter((s) => p.isTabVisible(s.id)).map((s) => {
@@ -6657,131 +6600,138 @@ function ToolbarPrimaryRow(p) {
6657
6600
  const showShare = isDialogAvailable(customization, "share");
6658
6601
  const showSettings = isDialogAvailable(customization, "options");
6659
6602
  const qab = "p-1 max-md:p-2 max-md:min-h-[40px] max-md:min-w-[40px] rounded-sm transition-colors hover:bg-accent/60 disabled:opacity-40 disabled:cursor-not-allowed active:scale-90 active:opacity-70";
6660
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 max-md:gap-0 px-1.5 py-0.5 max-md:px-1", children: [
6661
- mode !== "present" && showSlidesToggle && /* @__PURE__ */ jsx(
6662
- "button",
6663
- {
6664
- type: "button",
6665
- onClick: onToggleSidebar,
6666
- className: cn(qab, !isSidebarCollapsed ? "text-foreground" : "text-muted-foreground"),
6667
- title: t("pptx.toolbar.toggleSlidesPanel"),
6668
- "aria-label": t("pptx.toolbar.toggleSlidesPanel"),
6669
- children: /* @__PURE__ */ jsx(LuPanelLeft, { className: ic })
6670
- }
6671
- ),
6672
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-2 max-md:min-w-1" }),
6673
- (mode === "edit" || mode === "master") && showComments && /* @__PURE__ */ jsxs(
6674
- "button",
6675
- {
6676
- type: "button",
6677
- onClick: p.onToggleComments,
6678
- className: cn(
6679
- qab,
6680
- "relative max-md:hidden",
6681
- p.isCommentsPanelOpen ? "text-foreground" : "text-muted-foreground"
6603
+ return /* @__PURE__ */ jsxs(
6604
+ "div",
6605
+ {
6606
+ "data-pptx-chrome": "ribbon-primary",
6607
+ className: "flex items-center gap-0.5 max-md:gap-0 px-1.5 py-0.5 max-md:px-1",
6608
+ children: [
6609
+ mode !== "present" && showSlidesToggle && /* @__PURE__ */ jsx(
6610
+ "button",
6611
+ {
6612
+ type: "button",
6613
+ onClick: onToggleSidebar,
6614
+ className: cn(qab, !isSidebarCollapsed ? "text-foreground" : "text-muted-foreground"),
6615
+ title: t("pptx.toolbar.toggleSlidesPanel"),
6616
+ "aria-label": t("pptx.toolbar.toggleSlidesPanel"),
6617
+ children: /* @__PURE__ */ jsx(LuPanelLeft, { className: ic })
6618
+ }
6682
6619
  ),
6683
- title: t("pptx.toolbar.comments"),
6684
- "aria-label": t("pptx.toolbar.comments"),
6685
- children: [
6686
- /* @__PURE__ */ jsx(LuMessageSquare, { className: ics }),
6687
- (p.slideCommentCount ?? 0) > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-0.5 -right-0.5 flex items-center justify-center w-3.5 h-3.5 rounded-full bg-primary text-[8px] text-white leading-none", children: p.slideCommentCount })
6688
- ]
6689
- }
6690
- ),
6691
- collab && showShare && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsx(
6692
- "button",
6693
- {
6694
- type: "button",
6695
- onClick: p.onOpenShareDialog,
6696
- className: "mx-1 rounded-sm px-1 py-0.5 hover:bg-accent/60 transition-colors cursor-pointer",
6697
- title: t("pptx.toolbar.sharingUsers", { count: collab.connectedCount }),
6698
- children: /* @__PURE__ */ jsx(
6699
- UserAvatarBar,
6620
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-2 max-md:min-w-1" }),
6621
+ (mode === "edit" || mode === "master") && showComments && /* @__PURE__ */ jsxs(
6622
+ "button",
6700
6623
  {
6701
- remoteUsers: collab.remoteUsers,
6702
- localUserName: collab.config.userName,
6703
- localUserColor: collab.config.userColor ?? "#6366f1",
6704
- localUserAvatar: collab.config.userAvatar,
6705
- status: collab.status
6624
+ type: "button",
6625
+ onClick: p.onToggleComments,
6626
+ className: cn(
6627
+ qab,
6628
+ "relative max-md:hidden",
6629
+ p.isCommentsPanelOpen ? "text-foreground" : "text-muted-foreground"
6630
+ ),
6631
+ title: t("pptx.toolbar.comments"),
6632
+ "aria-label": t("pptx.toolbar.comments"),
6633
+ children: [
6634
+ /* @__PURE__ */ jsx(LuMessageSquare, { className: ics }),
6635
+ (p.slideCommentCount ?? 0) > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-0.5 -right-0.5 flex items-center justify-center w-3.5 h-3.5 rounded-full bg-primary text-[8px] text-white leading-none", children: p.slideCommentCount })
6636
+ ]
6706
6637
  }
6707
- )
6708
- }
6709
- ),
6710
- /* @__PURE__ */ jsx(
6711
- ModeSwitcher,
6712
- {
6713
- mode: p.mode,
6714
- onSetMode: p.onSetMode,
6715
- onCloseMasterView: p.onCloseMasterView,
6716
- onToggleSlideSorter: p.onToggleSlideSorter,
6717
- onEnterPresenterView: p.onEnterPresenterView,
6718
- onEnterRehearsalMode: p.onEnterRehearsalMode,
6719
- onOpenSetUpSlideShow: p.onOpenSetUpSlideShow,
6720
- onOpenBroadcastDialog: p.onOpenBroadcastDialog,
6721
- onToggleSubtitles: p.onToggleSubtitles,
6722
- showSubtitles: p.showSubtitles
6723
- }
6724
- ),
6725
- /* @__PURE__ */ jsx(
6726
- CustomShowsControls,
6727
- {
6728
- customShows: p.customShows,
6729
- activeCustomShowId: p.activeCustomShowId,
6730
- canEdit: p.canEdit,
6731
- isCurrentSlideInActiveShow: p.isCurrentSlideInActiveShow,
6732
- onSetActiveCustomShowId: p.onSetActiveCustomShowId,
6733
- onCreateCustomShow: p.onCreateCustomShow,
6734
- onRenameActiveCustomShow: p.onRenameActiveCustomShow,
6735
- onDeleteActiveCustomShow: p.onDeleteActiveCustomShow,
6736
- onToggleCurrentSlideInActiveShow: p.onToggleCurrentSlideInActiveShow
6737
- }
6738
- ),
6739
- sep,
6740
- (mode === "edit" || mode === "master") && showInspectorToggle && /* @__PURE__ */ jsx(
6741
- "button",
6742
- {
6743
- type: "button",
6744
- onClick: onToggleInspector,
6745
- className: cn(qab, isInspectorPaneOpen ? "text-foreground" : "text-muted-foreground"),
6746
- title: t("pptx.toolbar.toggleInspector"),
6747
- "aria-label": t("pptx.toolbar.toggleInspector"),
6748
- children: /* @__PURE__ */ jsx(LuPanelRight, { className: ic })
6749
- }
6750
- ),
6751
- p.aiEnabled && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
6752
- "button",
6753
- {
6754
- type: "button",
6755
- onClick: p.onToggleAiPanel,
6756
- className: cn(qab, p.isAiPanelOpen ? "text-primary" : "text-muted-foreground"),
6757
- title: t("pptx.toolbar.toggleAiAssistant"),
6758
- "aria-label": t("pptx.toolbar.toggleAiAssistant"),
6759
- children: /* @__PURE__ */ jsx(LuSparkles, { className: ic })
6760
- }
6761
- ),
6762
- showSettings && /* @__PURE__ */ jsx(
6763
- "button",
6764
- {
6765
- type: "button",
6766
- onClick: p.onOpenSettings ?? p.onToggleShortcuts,
6767
- className: cn(qab, "text-muted-foreground"),
6768
- title: t("pptx.toolbar.settingsShortcuts"),
6769
- "aria-label": t("pptx.toolbar.settings"),
6770
- children: /* @__PURE__ */ jsx(LuSettings, { className: ics })
6771
- }
6772
- ),
6773
- !canEdit && p.isProtectedView && p.onEnableEditing ? /* @__PURE__ */ jsx(
6774
- "button",
6775
- {
6776
- type: "button",
6777
- onClick: p.onEnableEditing,
6778
- className: "inline-flex items-center px-2 py-0.5 rounded-sm bg-amber-600/90 text-[10px] text-amber-50 transition-colors hover:bg-amber-600",
6779
- title: t("pptx.options.trust.protectedViewInfo"),
6780
- children: t("pptx.security.enableEditing")
6781
- }
6782
- ) : !canEdit && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded-sm bg-amber-600/90 text-[10px] text-amber-50", children: t("pptx.toolbar.readOnly") }),
6783
- /* @__PURE__ */ jsx(OverflowMenu, { ...p })
6784
- ] });
6638
+ ),
6639
+ collab && showShare && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsx(
6640
+ "button",
6641
+ {
6642
+ type: "button",
6643
+ onClick: p.onOpenShareDialog,
6644
+ className: "mx-1 rounded-sm px-1 py-0.5 hover:bg-accent/60 transition-colors cursor-pointer",
6645
+ title: t("pptx.toolbar.sharingUsers", { count: collab.connectedCount }),
6646
+ children: /* @__PURE__ */ jsx(
6647
+ UserAvatarBar,
6648
+ {
6649
+ remoteUsers: collab.remoteUsers,
6650
+ localUserName: collab.config.userName,
6651
+ localUserColor: collab.config.userColor ?? "#6366f1",
6652
+ localUserAvatar: collab.config.userAvatar,
6653
+ status: collab.status
6654
+ }
6655
+ )
6656
+ }
6657
+ ),
6658
+ /* @__PURE__ */ jsx(
6659
+ ModeSwitcher,
6660
+ {
6661
+ mode: p.mode,
6662
+ onSetMode: p.onSetMode,
6663
+ onCloseMasterView: p.onCloseMasterView,
6664
+ onToggleSlideSorter: p.onToggleSlideSorter,
6665
+ onEnterPresenterView: p.onEnterPresenterView,
6666
+ onEnterRehearsalMode: p.onEnterRehearsalMode,
6667
+ onOpenSetUpSlideShow: p.onOpenSetUpSlideShow,
6668
+ onOpenBroadcastDialog: p.onOpenBroadcastDialog,
6669
+ onToggleSubtitles: p.onToggleSubtitles,
6670
+ showSubtitles: p.showSubtitles
6671
+ }
6672
+ ),
6673
+ /* @__PURE__ */ jsx(
6674
+ CustomShowsControls,
6675
+ {
6676
+ customShows: p.customShows,
6677
+ activeCustomShowId: p.activeCustomShowId,
6678
+ canEdit: p.canEdit,
6679
+ isCurrentSlideInActiveShow: p.isCurrentSlideInActiveShow,
6680
+ onSetActiveCustomShowId: p.onSetActiveCustomShowId,
6681
+ onCreateCustomShow: p.onCreateCustomShow,
6682
+ onRenameActiveCustomShow: p.onRenameActiveCustomShow,
6683
+ onDeleteActiveCustomShow: p.onDeleteActiveCustomShow,
6684
+ onToggleCurrentSlideInActiveShow: p.onToggleCurrentSlideInActiveShow
6685
+ }
6686
+ ),
6687
+ sep,
6688
+ (mode === "edit" || mode === "master") && showInspectorToggle && /* @__PURE__ */ jsx(
6689
+ "button",
6690
+ {
6691
+ type: "button",
6692
+ onClick: onToggleInspector,
6693
+ className: cn(qab, isInspectorPaneOpen ? "text-foreground" : "text-muted-foreground"),
6694
+ title: t("pptx.toolbar.toggleInspector"),
6695
+ "aria-label": t("pptx.toolbar.toggleInspector"),
6696
+ children: /* @__PURE__ */ jsx(LuPanelRight, { className: ic })
6697
+ }
6698
+ ),
6699
+ p.aiEnabled && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
6700
+ "button",
6701
+ {
6702
+ type: "button",
6703
+ onClick: p.onToggleAiPanel,
6704
+ className: cn(qab, p.isAiPanelOpen ? "text-primary" : "text-muted-foreground"),
6705
+ title: t("pptx.toolbar.toggleAiAssistant"),
6706
+ "aria-label": t("pptx.toolbar.toggleAiAssistant"),
6707
+ children: /* @__PURE__ */ jsx(LuSparkles, { className: ic })
6708
+ }
6709
+ ),
6710
+ showSettings && /* @__PURE__ */ jsx(
6711
+ "button",
6712
+ {
6713
+ type: "button",
6714
+ onClick: p.onOpenSettings ?? p.onToggleShortcuts,
6715
+ className: cn(qab, "text-muted-foreground"),
6716
+ title: t("pptx.toolbar.settingsShortcuts"),
6717
+ "aria-label": t("pptx.toolbar.settings"),
6718
+ children: /* @__PURE__ */ jsx(LuSettings, { className: ics })
6719
+ }
6720
+ ),
6721
+ !canEdit && p.isProtectedView && p.onEnableEditing ? /* @__PURE__ */ jsx(
6722
+ "button",
6723
+ {
6724
+ type: "button",
6725
+ onClick: p.onEnableEditing,
6726
+ className: "inline-flex items-center px-2 py-0.5 rounded-sm bg-amber-600/90 text-[10px] text-amber-50 transition-colors hover:bg-amber-600",
6727
+ title: t("pptx.options.trust.protectedViewInfo"),
6728
+ children: t("pptx.security.enableEditing")
6729
+ }
6730
+ ) : !canEdit && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded-sm bg-amber-600/90 text-[10px] text-amber-50", children: t("pptx.toolbar.readOnly") }),
6731
+ /* @__PURE__ */ jsx(OverflowMenu, { ...p })
6732
+ ]
6733
+ }
6734
+ );
6785
6735
  }
6786
6736
  function useContextualRibbonTab(selectedElement, customization, onFallback) {
6787
6737
  const visible = visibleContextualTabs(selectedElement ?? null, customization);
@@ -6800,107 +6750,43 @@ function useContextualRibbonTab(selectedElement, customization, onFallback) {
6800
6750
  function HelpSection(p) {
6801
6751
  const { t } = useTranslation();
6802
6752
  const showSettings = isDialogAvailable(useViewerCustomizationContext(), "options");
6803
- return /* @__PURE__ */ jsxs(RibbonGroupScope, { id: "help.help", children: [
6804
- showSettings && /* @__PURE__ */ jsx(
6805
- "button",
6806
- {
6807
- type: "button",
6808
- onClick: p.onOpenSettings ?? p.onToggleShortcuts,
6809
- className: pill,
6810
- title: t("pptx.settings.title"),
6811
- ...controlAttr("help.help.options"),
6812
- children: t("pptx.settings.title")
6813
- }
6814
- ),
6815
- /* @__PURE__ */ jsx(
6816
- "button",
6817
- {
6818
- type: "button",
6819
- onClick: p.onToggleShortcuts,
6820
- className: pill,
6821
- title: t("pptx.settings.keyboardShortcuts"),
6822
- ...controlAttr("help.help.keyboardShortcuts"),
6823
- children: t("pptx.settings.keyboardShortcuts")
6824
- }
6825
- ),
6826
- /* @__PURE__ */ jsx(
6827
- "button",
6828
- {
6829
- type: "button",
6830
- onClick: p.onRunAccessibilityCheck,
6831
- className: pill,
6832
- title: t("pptx.ribbon.accessibilityCheck"),
6833
- ...controlAttr("help.help.accessibility"),
6834
- children: t("pptx.ribbon.accessibilityCheck")
6835
- }
6836
- )
6837
- ] });
6753
+ const actions = {
6754
+ "help.help.options": p.onOpenSettings ?? p.onToggleShortcuts,
6755
+ "help.help.keyboardShortcuts": p.onToggleShortcuts,
6756
+ "help.help.accessibility": p.onRunAccessibilityCheck
6757
+ };
6758
+ return /* @__PURE__ */ jsx(WebRibbonGroup, { label: t("pptx.ribbon.tab.help"), groupId: "help.help", children: HELP_RIBBON_COMMANDS.filter(
6759
+ (command) => command.id !== "help.help.options" || showSettings
6760
+ ).map((command) => /* @__PURE__ */ jsx(
6761
+ WebRibbonCommand,
6762
+ {
6763
+ controlId: command.id,
6764
+ label: t(command.labelKey),
6765
+ icon: command.icon,
6766
+ compact: true,
6767
+ onCommand: () => actions[command.id]()
6768
+ },
6769
+ command.id
6770
+ )) });
6838
6771
  }
6839
- function RecordSection({
6840
- onRecordFromBeginning,
6841
- onRecordFromCurrent
6842
- }) {
6772
+ function RecordSection(props) {
6843
6773
  const { t } = useTranslation();
6844
- return /* @__PURE__ */ jsxs(Fragment, { children: [
6845
- /* @__PURE__ */ jsx(RibbonGroup, { label: t("pptx.record.camera"), groupId: "record.camera", children: /* @__PURE__ */ jsx(
6846
- RibbonCommand,
6847
- {
6848
- controlId: "record.camera.cameo",
6849
- icon: /* @__PURE__ */ jsx(LuCamera, {}),
6850
- label: t("pptx.record.cameo"),
6851
- disabled: true
6852
- }
6853
- ) }),
6854
- /* @__PURE__ */ jsxs(RibbonGroup, { label: t("pptx.ribbon.tab.record"), groupId: "record.record", children: [
6855
- /* @__PURE__ */ jsx(
6856
- RibbonCommand,
6857
- {
6858
- controlId: "record.record.fromBeginning",
6859
- icon: /* @__PURE__ */ jsx(LuVideo, {}),
6860
- label: t("pptx.slideShow.fromBeginning"),
6861
- onClick: onRecordFromBeginning
6862
- }
6863
- ),
6864
- /* @__PURE__ */ jsx(
6865
- RibbonCommand,
6866
- {
6867
- icon: /* @__PURE__ */ jsx(LuPlay, {}),
6868
- controlId: "record.record.fromCurrent",
6869
- label: t("pptx.slideShow.fromCurrent"),
6870
- onClick: onRecordFromCurrent
6871
- }
6872
- )
6873
- ] }),
6874
- /* @__PURE__ */ jsxs(RibbonGroup, { label: t("pptx.record.manage"), groupId: "record.manage", children: [
6875
- /* @__PURE__ */ jsx(
6876
- RibbonCommand,
6877
- {
6878
- controlId: "record.manage.clear",
6879
- icon: /* @__PURE__ */ jsx(LuEraser, {}),
6880
- label: t("pptx.record.clear"),
6881
- disabled: true
6882
- }
6883
- ),
6884
- /* @__PURE__ */ jsx(
6885
- RibbonCommand,
6886
- {
6887
- controlId: "record.manage.reset",
6888
- icon: /* @__PURE__ */ jsx(LuRotateCcw, {}),
6889
- label: t("pptx.record.resetToCameo"),
6890
- disabled: true
6891
- }
6892
- )
6893
- ] }),
6894
- /* @__PURE__ */ jsx(RibbonGroup, { label: t("pptx.ribbon.tab.help"), groupId: "record.help", children: /* @__PURE__ */ jsx(
6895
- RibbonCommand,
6896
- {
6897
- controlId: "record.help.learnMore",
6898
- icon: /* @__PURE__ */ jsx(LuCircleHelp, {}),
6899
- label: t("pptx.record.learnMore"),
6900
- disabled: true
6901
- }
6902
- ) })
6903
- ] });
6774
+ const actions = {
6775
+ "record.record.fromBeginning": props.onRecordFromBeginning,
6776
+ "record.record.fromCurrent": props.onRecordFromCurrent
6777
+ };
6778
+ return /* @__PURE__ */ jsx(Fragment, { children: RECORD_COMMAND_GROUPS.map((group) => /* @__PURE__ */ jsx(WebRibbonGroup, { label: t(group.labelKey), groupId: group.id, children: group.commands.map((command) => /* @__PURE__ */ jsx(
6779
+ WebRibbonCommand,
6780
+ {
6781
+ controlId: command.id,
6782
+ label: t(command.labelKey),
6783
+ icon: command.icon,
6784
+ disabled: command.unsupported,
6785
+ compact: true,
6786
+ onCommand: actions[command.id]
6787
+ },
6788
+ command.id
6789
+ )) }, group.id)) });
6904
6790
  }
6905
6791
  function ToolbarLateTabs({
6906
6792
  p,
@@ -7045,6 +6931,7 @@ function Toolbar(p) {
7045
6931
  "div",
7046
6932
  {
7047
6933
  role: "toolbar",
6934
+ "data-pptx-chrome": "ribbon",
7048
6935
  "aria-label": t("pptx.toolbar.presentationToolbarAria"),
7049
6936
  className: "relative z-20 border-b border-border bg-secondary/50 overflow-visible",
7050
6937
  children: [
@@ -7098,6 +6985,7 @@ function Toolbar(p) {
7098
6985
  showRibbon && /* @__PURE__ */ jsxs(
7099
6986
  "div",
7100
6987
  {
6988
+ "data-pptx-chrome": "ribbon-content",
7101
6989
  className: cn(
7102
6990
  // Plain controls stay compact; labelled RibbonGroups opt into stretching.
7103
6991
  // `RibbonGroupScope` wraps controls in a `display: contents` div, so its
@@ -8189,13 +8077,13 @@ function EditPointsOverlay({
8189
8077
  const svgRef = useRef(null);
8190
8078
  const latest = useRef({ onCommit, onExit });
8191
8079
  latest.current = { onCommit, onExit };
8192
- const elementId = element.id;
8080
+ const elementId2 = element.id;
8193
8081
  const sessionRef = useRef(null);
8194
- if (sessionRef.current?.id !== elementId) {
8082
+ if (sessionRef.current?.id !== elementId2) {
8195
8083
  sessionRef.current = {
8196
- id: elementId,
8084
+ id: elementId2,
8197
8085
  session: new EditPointsSession(element, {
8198
- onCommit: (patch) => latest.current.onCommit(elementId, patch),
8086
+ onCommit: (patch) => latest.current.onCommit(elementId2, patch),
8199
8087
  onExit: () => latest.current.onExit(),
8200
8088
  onChange: rerender,
8201
8089
  hiddenCommands
@@ -8248,7 +8136,7 @@ function EditPointsOverlay({
8248
8136
  role: "application",
8249
8137
  "aria-label": t("pptx.editPoints.overlay"),
8250
8138
  "data-pptx-edit-points-overlay": "true",
8251
- "data-pptx-edit-points-element": elementId,
8139
+ "data-pptx-edit-points-element": elementId2,
8252
8140
  style: { touchAction: "none" },
8253
8141
  onPointerDown,
8254
8142
  onPointerMove,
@@ -9183,11 +9071,11 @@ function useConnectorCreation({
9183
9071
  }) {
9184
9072
  const [connectorDragState, setConnectorDragState] = useState(null);
9185
9073
  const handleConnectionSiteDown = useCallback(
9186
- (elementId, siteIndex, e) => {
9074
+ (elementId2, siteIndex, e) => {
9187
9075
  e.stopPropagation();
9188
9076
  e.preventDefault();
9189
9077
  setConnectorDragState({
9190
- startElementId: elementId,
9078
+ startElementId: elementId2,
9191
9079
  startSiteIndex: siteIndex,
9192
9080
  currentX: e.clientX,
9193
9081
  currentY: e.clientY
@@ -9541,15 +9429,15 @@ function useStableCallbacks(callbacks) {
9541
9429
  const cbRef = useRef(callbacks);
9542
9430
  cbRef.current = callbacks;
9543
9431
  const stableResizePointerDown = useCallback(
9544
- (elementId, e, handle) => cbRef.current.onResizePointerDown(elementId, e, handle),
9432
+ (elementId2, e, handle) => cbRef.current.onResizePointerDown(elementId2, e, handle),
9545
9433
  []
9546
9434
  );
9547
9435
  const stableAdjustmentPointerDown = useCallback(
9548
- (elementId, e, descriptor) => cbRef.current.onAdjustmentPointerDown(elementId, e, descriptor),
9436
+ (elementId2, e, descriptor) => cbRef.current.onAdjustmentPointerDown(elementId2, e, descriptor),
9549
9437
  []
9550
9438
  );
9551
9439
  const stableRotate = useCallback(
9552
- (elementId, rotationDeg) => cbRef.current.onRotate?.(elementId, rotationDeg),
9440
+ (elementId2, rotationDeg) => cbRef.current.onRotate?.(elementId2, rotationDeg),
9553
9441
  []
9554
9442
  );
9555
9443
  const stableInlineEditChange = useCallback(
@@ -9559,15 +9447,15 @@ function useStableCallbacks(callbacks) {
9559
9447
  const stableInlineEditCommit = useCallback(() => cbRef.current.onInlineEditCommit(), []);
9560
9448
  const stableInlineEditCancel = useCallback(() => cbRef.current.onInlineEditCancel(), []);
9561
9449
  const stableTableCellSelect = useCallback(
9562
- (cell, elementId) => cbRef.current.onTableCellSelect(cell, elementId),
9450
+ (cell, elementId2) => cbRef.current.onTableCellSelect(cell, elementId2),
9563
9451
  []
9564
9452
  );
9565
9453
  const stableCommitCellEdit = useCallback(
9566
- (elementId, rowIndex, colIndex, text) => cbRef.current.onCommitCellEdit?.(elementId, rowIndex, colIndex, text),
9454
+ (elementId2, rowIndex, colIndex, text) => cbRef.current.onCommitCellEdit?.(elementId2, rowIndex, colIndex, text),
9567
9455
  []
9568
9456
  );
9569
9457
  const stableUpdateSmartArtElement = useCallback(
9570
- (elementId, updates) => cbRef.current.onUpdateSmartArtElement?.(elementId, updates),
9458
+ (elementId2, updates) => cbRef.current.onUpdateSmartArtElement?.(elementId2, updates),
9571
9459
  []
9572
9460
  );
9573
9461
  const stableFormatText = useCallback(
@@ -9575,11 +9463,11 @@ function useStableCallbacks(callbacks) {
9575
9463
  []
9576
9464
  );
9577
9465
  const stableResizeTableColumns = useCallback(
9578
- (elementId, newWidths) => cbRef.current.onResizeTableColumns?.(elementId, newWidths),
9466
+ (elementId2, newWidths) => cbRef.current.onResizeTableColumns?.(elementId2, newWidths),
9579
9467
  []
9580
9468
  );
9581
9469
  const stableResizeTableRow = useCallback(
9582
- (elementId, rowIndex, newHeight) => cbRef.current.onResizeTableRow?.(elementId, rowIndex, newHeight),
9470
+ (elementId2, rowIndex, newHeight) => cbRef.current.onResizeTableRow?.(elementId2, rowIndex, newHeight),
9583
9471
  []
9584
9472
  );
9585
9473
  return {
@@ -10595,13 +10483,15 @@ function SlideThumbnailImpl({
10595
10483
  slide,
10596
10484
  templateElements,
10597
10485
  canvasSize,
10486
+ previewWidth,
10598
10487
  fieldContext,
10599
10488
  tableStyleContext
10600
10489
  }) {
10601
10490
  const safeCanvasWidth = Math.max(canvasSize.width, 1);
10602
10491
  const safeCanvasHeight = Math.max(canvasSize.height, 1);
10603
- const scale = SLIDE_NAV_THUMBNAIL_WIDTH / safeCanvasWidth;
10604
- const previewHeight = Math.max(56, Math.round(safeCanvasHeight * scale));
10492
+ const width = previewWidth ?? SLIDE_NAV_THUMBNAIL_WIDTH;
10493
+ const scale = width / safeCanvasWidth;
10494
+ const previewHeight = editorThumbnailHeight(safeCanvasWidth, safeCanvasHeight, width);
10605
10495
  const previewElements = buildPreviewElements(slide, templateElements);
10606
10496
  const slideFieldContext = deriveSlideFieldContext(fieldContext, slide);
10607
10497
  const { t } = useTranslation();
@@ -10612,7 +10502,7 @@ function SlideThumbnailImpl({
10612
10502
  return /* @__PURE__ */ jsx(
10613
10503
  "div",
10614
10504
  {
10615
- className: "relative w-full overflow-hidden rounded border border-border bg-white",
10505
+ className: previewWidth === void 0 ? "relative w-full overflow-hidden rounded border border-border bg-white" : "relative w-full overflow-hidden bg-white",
10616
10506
  style: {
10617
10507
  height: previewHeight,
10618
10508
  ...getReactSlideBackgroundStyle(slide, {
@@ -10659,6 +10549,9 @@ function SlideThumbnailImpl({
10659
10549
  );
10660
10550
  }
10661
10551
  function slideThumbnailPropsEqual(prev, next) {
10552
+ if (prev.previewWidth !== next.previewWidth) {
10553
+ return false;
10554
+ }
10662
10555
  if (prev.slide.id !== next.slide.id) {
10663
10556
  return false;
10664
10557
  }
@@ -10831,7 +10724,11 @@ function ContextMenu(props) {
10831
10724
  const handlers = contextMenuHandlers(props, shapeFormat);
10832
10725
  const entries = customizeContextMenuEntries(
10833
10726
  buildContextMenuEntries(contextMenuContext(props, shapeFormat)),
10834
- customization
10727
+ customization,
10728
+ {
10729
+ slideIndex: props.slideIndex ?? 0,
10730
+ elementIds: props.elementIds ?? (props.selectedElement ? [props.selectedElement.id] : [])
10731
+ }
10835
10732
  );
10836
10733
  if (entries.length === 0) {
10837
10734
  return null;
@@ -10861,7 +10758,10 @@ function ContextMenu(props) {
10861
10758
  top: menuPosition.top
10862
10759
  },
10863
10760
  children: entries.map((entry) => {
10864
- const run = handlers[entry.id];
10761
+ const run = "host" in entry ? () => {
10762
+ onClose();
10763
+ entry.onSelect();
10764
+ } : handlers[entry.id];
10865
10765
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
10866
10766
  entry.separatorBefore && /* @__PURE__ */ jsx(ContextMenuSeparator, {}),
10867
10767
  /* @__PURE__ */ jsx(
@@ -10870,7 +10770,7 @@ function ContextMenu(props) {
10870
10770
  danger: entry.danger,
10871
10771
  disabled: entry.disabled || !run,
10872
10772
  onSelect: () => run?.(),
10873
- children: t(entry.labelKey)
10773
+ children: "host" in entry ? entry.label : t(entry.labelKey)
10874
10774
  }
10875
10775
  )
10876
10776
  ] }, entry.id);
@@ -10931,7 +10831,8 @@ function CanvasContextMenu(props) {
10931
10831
  const handlers = canvasContextMenuHandlers(props);
10932
10832
  const entries = customizeCanvasContextMenuEntries(
10933
10833
  buildCanvasContextMenuEntries(canvasContextMenuContext(props)),
10934
- customization
10834
+ customization,
10835
+ { slideIndex: props.slideIndex ?? 0 }
10935
10836
  );
10936
10837
  if (entries.length === 0) {
10937
10838
  return null;
@@ -10961,7 +10862,10 @@ function CanvasContextMenu(props) {
10961
10862
  top: menuPosition.top
10962
10863
  },
10963
10864
  children: entries.map((entry) => {
10964
- const run = handlers[entry.id];
10865
+ const run = "host" in entry ? () => {
10866
+ onClose();
10867
+ entry.onSelect();
10868
+ } : handlers[entry.id];
10965
10869
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
10966
10870
  entry.separatorBefore && /* @__PURE__ */ jsx(ContextMenuSeparator, {}),
10967
10871
  /* @__PURE__ */ jsx(
@@ -10970,7 +10874,7 @@ function CanvasContextMenu(props) {
10970
10874
  disabled: entry.disabled || !run,
10971
10875
  checked: entry.checked,
10972
10876
  onSelect: () => run?.(),
10973
- children: t(entry.labelKey)
10877
+ children: "host" in entry ? entry.label : t(entry.labelKey)
10974
10878
  }
10975
10879
  )
10976
10880
  ] }, entry.id);
@@ -11397,6 +11301,7 @@ function LazyThumbnailInner({
11397
11301
  templateElements,
11398
11302
  canvasSize,
11399
11303
  previewHeight,
11304
+ previewWidth,
11400
11305
  fieldContext,
11401
11306
  tableStyleContext
11402
11307
  }) {
@@ -11434,6 +11339,7 @@ function LazyThumbnailInner({
11434
11339
  slide,
11435
11340
  templateElements,
11436
11341
  canvasSize,
11342
+ previewWidth,
11437
11343
  fieldContext,
11438
11344
  tableStyleContext
11439
11345
  }
@@ -11443,7 +11349,7 @@ function LazyThumbnailInner({
11443
11349
  className: "relative w-full overflow-hidden rounded border border-border bg-muted/30 animate-pulse",
11444
11350
  style: {
11445
11351
  height: previewHeight,
11446
- minWidth: SLIDE_NAV_THUMBNAIL_WIDTH
11352
+ minWidth: previewWidth
11447
11353
  }
11448
11354
  }
11449
11355
  ) });
@@ -11477,12 +11383,8 @@ function buildFlatPaneItems(sectionGroups, showSectionHeaders, collapsedSections
11477
11383
  }
11478
11384
  return items;
11479
11385
  }
11480
- function estimateSlideItemHeight(canvasWidth, canvasHeight) {
11481
- const safeW = Math.max(canvasWidth, 1);
11482
- const safeH = Math.max(canvasHeight, 1);
11483
- const scale = SLIDE_NAV_THUMBNAIL_WIDTH / safeW;
11484
- const previewHeight = Math.max(56, Math.round(safeH * scale));
11485
- return previewHeight + 30;
11386
+ function estimateSlideItemHeight(canvasWidth, canvasHeight, width = EDITOR_THUMBNAIL_WIDTH) {
11387
+ return editorThumbnailStep(canvasWidth, canvasHeight, width);
11486
11388
  }
11487
11389
  function SlideItemInner({
11488
11390
  slide,
@@ -11491,6 +11393,7 @@ function SlideItemInner({
11491
11393
  isActive,
11492
11394
  isSelected = false,
11493
11395
  canvasSize,
11396
+ previewWidth = EDITOR_THUMBNAIL_WIDTH,
11494
11397
  canEdit,
11495
11398
  rehearsalTimings,
11496
11399
  presenceUsers,
@@ -11521,8 +11424,7 @@ function SlideItemInner({
11521
11424
  );
11522
11425
  const safeCanvasWidth = Math.max(canvasSize.width, 1);
11523
11426
  const safeCanvasHeight = Math.max(canvasSize.height, 1);
11524
- const scale = SLIDE_NAV_THUMBNAIL_WIDTH / safeCanvasWidth;
11525
- const previewHeight = Math.max(56, Math.round(safeCanvasHeight * scale));
11427
+ const previewHeight = editorThumbnailHeight(safeCanvasWidth, safeCanvasHeight, previewWidth);
11526
11428
  return /* @__PURE__ */ jsxs(
11527
11429
  "button",
11528
11430
  {
@@ -11530,6 +11432,7 @@ function SlideItemInner({
11530
11432
  ref: slideRef,
11531
11433
  "aria-label": t("pptx.slidesPanel.goToSlide", { n: slideIndex + 1 }),
11532
11434
  "aria-current": isActive ? "true" : void 0,
11435
+ "data-pptx-chrome": "slide-row",
11533
11436
  "aria-describedby": cue.labelId,
11534
11437
  "data-pptx-slide-hidden": cue.marker,
11535
11438
  className: cn(
@@ -11545,28 +11448,35 @@ function SlideItemInner({
11545
11448
  onDragOver,
11546
11449
  onDrop: (e) => onDrop(e, slideIndex),
11547
11450
  children: [
11548
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5 w-5 shrink-0", children: [
11549
- /* @__PURE__ */ jsx(
11550
- "span",
11551
- {
11552
- className: cn(
11553
- "text-[10px] tabular-nums text-right select-none w-full",
11554
- isActive ? "text-primary font-medium" : "text-muted-foreground"
11451
+ /* @__PURE__ */ jsxs(
11452
+ "div",
11453
+ {
11454
+ "data-pptx-chrome": "slide-number",
11455
+ className: "flex flex-col items-center gap-0.5 w-5 shrink-0",
11456
+ children: [
11457
+ /* @__PURE__ */ jsx(
11458
+ "span",
11459
+ {
11460
+ className: cn(
11461
+ "text-[10px] tabular-nums text-right select-none w-full",
11462
+ isActive ? "text-primary font-medium" : "text-muted-foreground"
11463
+ ),
11464
+ style: isHidden ? { backgroundImage: HIDDEN_SLIDE_SLASH_GRADIENT } : void 0,
11465
+ children: slideIndex + 1
11466
+ }
11555
11467
  ),
11556
- style: isHidden ? { backgroundImage: HIDDEN_SLIDE_SLASH_GRADIENT } : void 0,
11557
- children: slideIndex + 1
11558
- }
11559
- ),
11560
- presenceUsers && presenceUsers.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-center gap-px", children: presenceUsers.slice(0, 4).map((u, i) => /* @__PURE__ */ jsx(
11561
- "span",
11562
- {
11563
- className: "w-[6px] h-[6px] rounded-full",
11564
- style: { backgroundColor: u.userColor },
11565
- title: u.userName
11566
- },
11567
- i
11568
- )) })
11569
- ] }),
11468
+ presenceUsers && presenceUsers.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-center gap-px", children: presenceUsers.slice(0, 4).map((u, i) => /* @__PURE__ */ jsx(
11469
+ "span",
11470
+ {
11471
+ className: "w-[6px] h-[6px] rounded-full",
11472
+ style: { backgroundColor: u.userColor },
11473
+ title: u.userName
11474
+ },
11475
+ i
11476
+ )) })
11477
+ ]
11478
+ }
11479
+ ),
11570
11480
  /* @__PURE__ */ jsxs(
11571
11481
  "div",
11572
11482
  {
@@ -11574,7 +11484,8 @@ function SlideItemInner({
11574
11484
  "relative shrink-0 overflow-hidden border transition-colors bg-white",
11575
11485
  isActive ? "border-primary/60" : "border-transparent group-hover:border-border/40"
11576
11486
  ),
11577
- style: { width: SLIDE_NAV_THUMBNAIL_WIDTH },
11487
+ "data-pptx-chrome": "slide-frame",
11488
+ style: { width: previewWidth, height: previewHeight },
11578
11489
  children: [
11579
11490
  isHidden && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 pointer-events-none z-10 bg-[repeating-linear-gradient(135deg,transparent,transparent_4px,rgba(255,255,255,0.04)_4px,rgba(255,255,255,0.04)_8px)]" }),
11580
11491
  /* @__PURE__ */ jsx(
@@ -11584,6 +11495,7 @@ function SlideItemInner({
11584
11495
  templateElements,
11585
11496
  canvasSize,
11586
11497
  previewHeight,
11498
+ previewWidth,
11587
11499
  fieldContext,
11588
11500
  tableStyleContext
11589
11501
  }
@@ -11787,9 +11699,10 @@ function SlidesPaneSidebar({
11787
11699
  }
11788
11700
  return map;
11789
11701
  }, [collab]);
11702
+ const previewWidth = editorThumbnailWidth(panelWidth);
11790
11703
  const estimatedItemHeight = useMemo(
11791
- () => estimateSlideItemHeight(canvasSize.width, canvasSize.height),
11792
- [canvasSize.width, canvasSize.height]
11704
+ () => estimateSlideItemHeight(canvasSize.width, canvasSize.height, previewWidth),
11705
+ [canvasSize.width, canvasSize.height, previewWidth]
11793
11706
  );
11794
11707
  const showSectionHeaders = sectionGroups.some((group) => group.id !== DEFAULT_SECTION_GROUP_ID);
11795
11708
  const {
@@ -11901,80 +11814,89 @@ function SlidesPaneSidebar({
11901
11814
  }
11902
11815
  const renderVirtualized = () => {
11903
11816
  const visibleItems = flatItems.slice(startIndex, endIndex + 1);
11904
- return /* @__PURE__ */ jsx("div", { ref: scrollContainerRef, className: "flex-1 overflow-y-auto px-1.5 pb-2", children: /* @__PURE__ */ jsx("div", { style: { height: totalHeight, position: "relative" }, children: /* @__PURE__ */ jsx(
11817
+ return /* @__PURE__ */ jsx(
11905
11818
  "div",
11906
11819
  {
11907
- style: {
11908
- position: "absolute",
11909
- top: offsetY,
11910
- left: 0,
11911
- right: 0
11912
- },
11913
- children: /* @__PURE__ */ jsx("div", { className: "space-y-1", children: visibleItems.map((item) => {
11914
- if (item.type === "section") {
11915
- const section = sectionGroups[item.sectionIndex];
11916
- if (!section) {
11917
- return null;
11918
- }
11919
- const isCollapsed = effectiveCollapsed[section.id] ?? false;
11920
- return /* @__PURE__ */ jsx(
11921
- SectionHeader,
11922
- {
11923
- sectionId: section.id,
11924
- label: section.label,
11925
- slideCount: section.slideIndexes.length,
11926
- isCollapsed,
11927
- isRenaming: renamingSectionId === section.id,
11928
- renameValue,
11929
- canEdit,
11930
- sectionIndex: item.sectionIndex,
11931
- totalSections: sectionGroups.length,
11932
- renameInputRef,
11933
- onToggle: toggleSection,
11934
- onContextMenu: handleSectionContextMenu,
11935
- onStartRename: startRename,
11936
- onRenameValueChange: setRenameValue,
11937
- onCommitRename: commitRename,
11938
- onCancelRename: cancelRename
11939
- },
11940
- `section-${section.id}`
11941
- );
11942
- }
11943
- const slide = slides[item.slideIndex];
11944
- if (!slide) {
11945
- return null;
11946
- }
11947
- return /* @__PURE__ */ jsx(
11948
- SlideItem,
11949
- {
11950
- slide,
11951
- templateElements: templateElementsBySlideId[slide.id] ?? EMPTY_TEMPLATE_ELEMENTS,
11952
- slideIndex: item.slideIndex,
11953
- isActive: item.slideIndex === activeSlideIndex,
11954
- isSelected: selectedSlideIds.includes(slide.id),
11955
- canvasSize,
11956
- canEdit,
11957
- rehearsalTimings,
11958
- presenceUsers: slidePresenceMap?.get(item.slideIndex),
11959
- fieldContext,
11960
- tableStyleContext,
11961
- onSelectSlide: selectSlide,
11962
- onSlideContextMenu,
11963
- onOpenSlideCtxMenu: openSlideCtxMenu,
11964
- onDragStart: handleDragStart,
11965
- onDragOver: handleDragOver,
11966
- onDrop: handleDrop,
11967
- slideRef: setSlideRef(item.slideIndex)
11820
+ ref: scrollContainerRef,
11821
+ "data-pptx-chrome": "slide-list",
11822
+ className: "flex-1 overflow-y-auto px-1.5 pb-2",
11823
+ children: /* @__PURE__ */ jsx("div", { style: { height: totalHeight, position: "relative" }, children: /* @__PURE__ */ jsx(
11824
+ "div",
11825
+ {
11826
+ style: {
11827
+ position: "absolute",
11828
+ top: offsetY,
11829
+ left: 0,
11830
+ right: 0
11968
11831
  },
11969
- slide.id ?? item.slideIndex
11970
- );
11971
- }) })
11832
+ children: /* @__PURE__ */ jsx("div", { className: "space-y-1", "data-pptx-chrome": "slide-window", children: visibleItems.map((item) => {
11833
+ if (item.type === "section") {
11834
+ const section = sectionGroups[item.sectionIndex];
11835
+ if (!section) {
11836
+ return null;
11837
+ }
11838
+ const isCollapsed = effectiveCollapsed[section.id] ?? false;
11839
+ return /* @__PURE__ */ jsx(
11840
+ SectionHeader,
11841
+ {
11842
+ sectionId: section.id,
11843
+ label: section.label,
11844
+ slideCount: section.slideIndexes.length,
11845
+ isCollapsed,
11846
+ isRenaming: renamingSectionId === section.id,
11847
+ renameValue,
11848
+ canEdit,
11849
+ sectionIndex: item.sectionIndex,
11850
+ totalSections: sectionGroups.length,
11851
+ renameInputRef,
11852
+ onToggle: toggleSection,
11853
+ onContextMenu: handleSectionContextMenu,
11854
+ onStartRename: startRename,
11855
+ onRenameValueChange: setRenameValue,
11856
+ onCommitRename: commitRename,
11857
+ onCancelRename: cancelRename
11858
+ },
11859
+ `section-${section.id}`
11860
+ );
11861
+ }
11862
+ const slide = slides[item.slideIndex];
11863
+ if (!slide) {
11864
+ return null;
11865
+ }
11866
+ return /* @__PURE__ */ jsx(
11867
+ SlideItem,
11868
+ {
11869
+ slide,
11870
+ templateElements: templateElementsBySlideId[slide.id] ?? EMPTY_TEMPLATE_ELEMENTS,
11871
+ slideIndex: item.slideIndex,
11872
+ isActive: item.slideIndex === activeSlideIndex,
11873
+ isSelected: selectedSlideIds.includes(slide.id),
11874
+ canvasSize,
11875
+ previewWidth,
11876
+ canEdit,
11877
+ rehearsalTimings,
11878
+ presenceUsers: slidePresenceMap?.get(item.slideIndex),
11879
+ fieldContext,
11880
+ tableStyleContext,
11881
+ onSelectSlide: selectSlide,
11882
+ onSlideContextMenu,
11883
+ onOpenSlideCtxMenu: openSlideCtxMenu,
11884
+ onDragStart: handleDragStart,
11885
+ onDragOver: handleDragOver,
11886
+ onDrop: handleDrop,
11887
+ slideRef: setSlideRef(item.slideIndex)
11888
+ },
11889
+ slide.id ?? item.slideIndex
11890
+ );
11891
+ }) })
11892
+ }
11893
+ ) })
11972
11894
  }
11973
- ) }) });
11895
+ );
11974
11896
  };
11975
- const renderNonVirtualized = () => /* @__PURE__ */ jsx("div", { className: "flex-1 space-y-1 overflow-y-auto px-1.5 pb-2", children: sectionGroups.map((section, sectionIndex) => {
11897
+ const renderNonVirtualized = () => /* @__PURE__ */ jsx("div", { "data-pptx-chrome": "slide-list", className: "flex-1 space-y-1 overflow-y-auto px-1.5 pb-2", children: sectionGroups.map((section, sectionIndex) => {
11976
11898
  const isCollapsed = effectiveCollapsed[section.id] ?? false;
11977
- return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
11899
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1", "data-pptx-chrome": "slide-window", children: [
11978
11900
  showSectionHeaders && /* @__PURE__ */ jsx(
11979
11901
  SectionHeader,
11980
11902
  {
@@ -12010,6 +11932,7 @@ function SlidesPaneSidebar({
12010
11932
  isActive: idx === activeSlideIndex,
12011
11933
  isSelected: selectedSlideIds.includes(slide.id),
12012
11934
  canvasSize,
11935
+ previewWidth,
12013
11936
  canEdit,
12014
11937
  rehearsalTimings,
12015
11938
  presenceUsers: slidePresenceMap?.get(idx),
@@ -12035,12 +11958,13 @@ function SlidesPaneSidebar({
12035
11958
  {
12036
11959
  role: "navigation",
12037
11960
  "aria-label": t("pptx.sections.slides"),
11961
+ "data-pptx-chrome": "slides",
12038
11962
  className: "flex h-full flex-col border-r border-border bg-secondary/30",
12039
11963
  style: panelWidth ? { width: panelWidth, flexShrink: 0 } : void 0,
12040
11964
  onKeyDown: onPaneKeyDown,
12041
11965
  children: [
12042
11966
  shouldVirtualize ? renderVirtualized() : renderNonVirtualized(),
12043
- canEdit && /* @__PURE__ */ jsx("div", { className: "border-t border-border/60 px-2 py-1.5", children: /* @__PURE__ */ jsxs(
11967
+ canEdit && /* @__PURE__ */ jsx("div", { "data-pptx-chrome": "slide-footer", className: "border-t border-border/60 px-2 py-1.5", children: /* @__PURE__ */ jsxs(
12044
11968
  "button",
12045
11969
  {
12046
11970
  type: "button",
@@ -14622,6 +14546,7 @@ function SlideNotesPanel({
14622
14546
  "div",
14623
14547
  {
14624
14548
  ref: rootRef,
14549
+ "data-pptx-chrome": "notes",
14625
14550
  className: cn(
14626
14551
  "flex flex-col border-t border-border/60 bg-background select-none",
14627
14552
  // On mobile, hide the entire notes strip when collapsed: the
@@ -14649,6 +14574,7 @@ function SlideNotesPanel({
14649
14574
  {
14650
14575
  type: "button",
14651
14576
  onClick: onToggle,
14577
+ "data-pptx-chrome": "notes-header",
14652
14578
  className: "flex items-center gap-1.5 px-3 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/30 transition-colors w-full text-left shrink-0 max-md:hidden",
14653
14579
  "aria-expanded": isExpanded,
14654
14580
  "aria-controls": "slide-notes-content",
@@ -16383,6 +16309,10 @@ function PresentationSubtitleBar({
16383
16309
  onCaptionChange
16384
16310
  }) {
16385
16311
  const { t } = useTranslation();
16312
+ const language = subtitleRecognitionLanguage(
16313
+ subtitleSettingsFromOptions(useViewerOptionsContext()),
16314
+ typeof navigator === "undefined" ? "en-US" : navigator.language
16315
+ );
16386
16316
  const [captionText, setCaptionText] = useState("");
16387
16317
  const [supportState, setSupportState] = useState(
16388
16318
  "unknown"
@@ -16398,8 +16328,7 @@ function PresentationSubtitleBar({
16398
16328
  return;
16399
16329
  }
16400
16330
  shouldRunRef.current = true;
16401
- const speechWindow = window;
16402
- const RecognitionCtor = speechWindow.SpeechRecognition ?? speechWindow.webkitSpeechRecognition;
16331
+ const RecognitionCtor = getSpeechRecognitionCtor();
16403
16332
  if (!RecognitionCtor) {
16404
16333
  setSupportState("unsupported");
16405
16334
  return;
@@ -16408,20 +16337,9 @@ function PresentationSubtitleBar({
16408
16337
  const recognition = new RecognitionCtor();
16409
16338
  recognition.continuous = true;
16410
16339
  recognition.interimResults = true;
16411
- recognition.lang = navigator.language || "en-US";
16340
+ recognition.lang = language;
16412
16341
  recognition.onresult = (event) => {
16413
- let finalText = "";
16414
- let interimText = "";
16415
- for (let index = event.resultIndex; index < event.results.length; index += 1) {
16416
- const result = event.results[index];
16417
- const fragment = result?.[0]?.transcript ?? "";
16418
- if (result?.isFinal) {
16419
- finalText += fragment;
16420
- } else {
16421
- interimText += fragment;
16422
- }
16423
- }
16424
- const merged = `${finalText} ${interimText}`.trim();
16342
+ const merged = mergeCaptionResults(event.resultIndex, event.results);
16425
16343
  if (merged.length > 0) {
16426
16344
  setCaptionText(merged);
16427
16345
  onCaptionChange?.(merged);
@@ -16449,7 +16367,7 @@ function PresentationSubtitleBar({
16449
16367
  recognition.stop();
16450
16368
  recognitionRef.current = null;
16451
16369
  };
16452
- }, [visible, onCaptionChange]);
16370
+ }, [visible, onCaptionChange, language]);
16453
16371
  if (!visible) {
16454
16372
  return null;
16455
16373
  }
@@ -17397,14 +17315,14 @@ function SelectionPane({
17397
17315
  const [dragIndex, setDragIndex] = useState(null);
17398
17316
  const [dragOverIndex, setDragOverIndex] = useState(null);
17399
17317
  const handleSelect = useCallback(
17400
- (elementId) => {
17401
- setSelectedElementId(elementId);
17402
- setSelectedElementIds([elementId]);
17318
+ (elementId2) => {
17319
+ setSelectedElementId(elementId2);
17320
+ setSelectedElementIds([elementId2]);
17403
17321
  },
17404
17322
  [setSelectedElementId, setSelectedElementIds]
17405
17323
  );
17406
17324
  const handleToggleVisibility = useCallback(
17407
- (elementId) => {
17325
+ (elementId2) => {
17408
17326
  setSlides((prevSlides) => {
17409
17327
  const nextSlides = [...prevSlides];
17410
17328
  const slide = nextSlides[activeSlideIndex];
@@ -17412,7 +17330,7 @@ function SelectionPane({
17412
17330
  return prevSlides;
17413
17331
  }
17414
17332
  const nextElements = [...slide.elements ?? []];
17415
- const idx = nextElements.findIndex((e) => e.id === elementId);
17333
+ const idx = nextElements.findIndex((e) => e.id === elementId2);
17416
17334
  if (idx === -1) {
17417
17335
  return prevSlides;
17418
17336
  }
@@ -17440,9 +17358,9 @@ function SelectionPane({
17440
17358
  [canEdit]
17441
17359
  );
17442
17360
  const commitRename = useCallback(() => {
17443
- const elementId = editingId;
17361
+ const elementId2 = editingId;
17444
17362
  setEditingId(null);
17445
- if (elementId === null) {
17363
+ if (elementId2 === null) {
17446
17364
  return;
17447
17365
  }
17448
17366
  const commit = resolveSelectionPaneRename(editSeedRef.current, editingName);
@@ -17456,7 +17374,7 @@ function SelectionPane({
17456
17374
  return prevSlides;
17457
17375
  }
17458
17376
  const nextElements = [...slide.elements ?? []];
17459
- const idx = nextElements.findIndex((e) => e.id === elementId);
17377
+ const idx = nextElements.findIndex((e) => e.id === elementId2);
17460
17378
  if (idx === -1) {
17461
17379
  return prevSlides;
17462
17380
  }
@@ -18798,8 +18716,8 @@ var INSPECTOR_TABS = [
18798
18716
  { key: "properties", labelKey: "pptx.inspector.properties", icon: LuSettings2 },
18799
18717
  { key: "comments", labelKey: "pptx.toolbar.comments", icon: LuMessageSquare }
18800
18718
  ];
18801
- var HEADING2 = "text-[11px] uppercase tracking-wide text-muted-foreground";
18802
- var CARD2 = "rounded border border-border bg-card p-2 space-y-2";
18719
+ var HEADING2 = "pptx-editor-heading text-[11px] uppercase tracking-wide text-muted-foreground";
18720
+ var CARD2 = "pptx-editor-card rounded border border-border bg-card p-2 space-y-2";
18803
18721
  var INPUT2 = "flex-1 bg-muted border border-border rounded px-1.5 py-0.5 w-full max-md:min-h-[44px]!";
18804
18722
  var BTN2 = "rounded bg-muted hover:bg-accent px-2 py-1 text-[11px] transition-colors max-md:min-h-[44px]! max-md:min-w-[44px]!";
18805
18723
  var POS_FIELDS = [
@@ -27962,12 +27880,12 @@ function InspectorElementsTab({
27962
27880
  onUpdateSlide
27963
27881
  }) {
27964
27882
  const { t } = useTranslation();
27965
- const toggleHidden = (elementId) => {
27883
+ const toggleHidden = (elementId2) => {
27966
27884
  const elements2 = activeSlide?.elements;
27967
27885
  if (!canEdit || !elements2) {
27968
27886
  return;
27969
27887
  }
27970
- const index = elements2.findIndex((el) => el.id === elementId);
27888
+ const index = elements2.findIndex((el) => el.id === elementId2);
27971
27889
  if (index === -1) {
27972
27890
  return;
27973
27891
  }
@@ -28031,37 +27949,54 @@ function InspectorPaneHeader({
28031
27949
  const { viewportWidth } = useIsMobile();
28032
27950
  const touchTargetPx = getDensePanelTouchTargetPx(viewportWidth);
28033
27951
  const touchBtnStyle = { minWidth: touchTargetPx, minHeight: touchTargetPx };
28034
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border", children: [
28035
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 rounded bg-muted p-0.5", children: INSPECTOR_TABS.map(({ key, labelKey, icon: Icon }) => /* @__PURE__ */ jsxs(
28036
- "button",
28037
- {
28038
- type: "button",
28039
- title: t(labelKey),
28040
- style: touchBtnStyle,
28041
- className: cn(
28042
- "flex items-center justify-center gap-1 px-2 py-1 rounded text-[11px] transition-colors",
28043
- activeTab === key ? "bg-primary text-white" : "text-muted-foreground hover:text-foreground hover:bg-accent"
27952
+ return /* @__PURE__ */ jsxs(
27953
+ "div",
27954
+ {
27955
+ "data-pptx-chrome": "inspector-header",
27956
+ className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border",
27957
+ children: [
27958
+ /* @__PURE__ */ jsx(
27959
+ "div",
27960
+ {
27961
+ "data-pptx-chrome": "inspector-tabs",
27962
+ role: "tablist",
27963
+ className: "flex items-center gap-1 rounded bg-muted p-0.5",
27964
+ children: INSPECTOR_TABS.map(({ key, labelKey, icon: Icon }) => /* @__PURE__ */ jsxs(
27965
+ "button",
27966
+ {
27967
+ role: "tab",
27968
+ "aria-selected": activeTab === key,
27969
+ type: "button",
27970
+ title: t(labelKey),
27971
+ style: touchBtnStyle,
27972
+ className: cn(
27973
+ "flex items-center justify-center gap-1 px-2 py-1 rounded text-[11px] transition-colors",
27974
+ activeTab === key ? "bg-primary text-white" : "text-muted-foreground hover:text-foreground hover:bg-accent"
27975
+ ),
27976
+ onClick: () => onSetActiveTab(key),
27977
+ children: [
27978
+ /* @__PURE__ */ jsx(Icon, { className: "w-3.5 h-3.5" }),
27979
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: t(labelKey) })
27980
+ ]
27981
+ },
27982
+ key
27983
+ ))
27984
+ }
28044
27985
  ),
28045
- onClick: () => onSetActiveTab(key),
28046
- children: [
28047
- /* @__PURE__ */ jsx(Icon, { className: "w-3.5 h-3.5" }),
28048
- /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: t(labelKey) })
28049
- ]
28050
- },
28051
- key
28052
- )) }),
28053
- /* @__PURE__ */ jsx(
28054
- "button",
28055
- {
28056
- type: "button",
28057
- onClick: onClose,
28058
- title: t("pptx.common.close"),
28059
- style: touchBtnStyle,
28060
- className: "flex items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
28061
- children: /* @__PURE__ */ jsx(LuX, { className: "w-4 h-4" })
28062
- }
28063
- )
28064
- ] });
27986
+ /* @__PURE__ */ jsx(
27987
+ "button",
27988
+ {
27989
+ type: "button",
27990
+ onClick: onClose,
27991
+ title: t("pptx.common.close"),
27992
+ style: touchBtnStyle,
27993
+ className: "flex items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
27994
+ children: /* @__PURE__ */ jsx(LuX, { className: "w-4 h-4" })
27995
+ }
27996
+ )
27997
+ ]
27998
+ }
27999
+ );
28065
28000
  }
28066
28001
  function InfoRow({ label, value }) {
28067
28002
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
@@ -28406,9 +28341,9 @@ function PresentationSettingsCard({
28406
28341
  onUpdate
28407
28342
  }) {
28408
28343
  const { t } = useTranslation();
28409
- return /* @__PURE__ */ jsxs("div", { className: CARD2, children: [
28344
+ return /* @__PURE__ */ jsxs("div", { className: `${CARD2} pptx-editor-presentation-card`, children: [
28410
28345
  /* @__PURE__ */ jsx("div", { className: HEADING2, children: t("pptx.slideInspector.presentation") }),
28411
- /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 text-[11px]", children: [
28346
+ /* @__PURE__ */ jsxs("div", { "data-pptx-chrome": "presentation-fields", className: "space-y-1.5 text-[11px]", children: [
28412
28347
  /* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-2", children: [
28413
28348
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("pptx.presentationSettings.showType") }),
28414
28349
  /* @__PURE__ */ jsxs(
@@ -29094,7 +29029,7 @@ function PresentationPropertiesPanel({
29094
29029
  },
29095
29030
  [activeSlide?.transition, onUpdateSlide]
29096
29031
  );
29097
- return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
29032
+ return /* @__PURE__ */ jsxs("div", { "data-pptx-chrome": "deck-properties", className: "space-y-3", children: [
29098
29033
  /* @__PURE__ */ jsx(
29099
29034
  PresentationSettingsCard,
29100
29035
  {
@@ -29473,6 +29408,7 @@ function InspectorPane(props) {
29473
29408
  /* @__PURE__ */ jsxs(
29474
29409
  "div",
29475
29410
  {
29411
+ "data-pptx-chrome": "inspector",
29476
29412
  className: cn(
29477
29413
  // Shared styles
29478
29414
  "bg-background flex flex-col text-xs text-foreground shadow-xl",
@@ -29509,7 +29445,7 @@ function InspectorPane(props) {
29509
29445
  onClose
29510
29446
  }
29511
29447
  ),
29512
- /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto p-3 space-y-3", children: [
29448
+ /* @__PURE__ */ jsxs("div", { "data-pptx-chrome": "inspector-body", className: "flex-1 overflow-y-auto p-3 space-y-3", children: [
29513
29449
  activeTab === "elements" && /* @__PURE__ */ jsx(
29514
29450
  InspectorElementsTab,
29515
29451
  {
@@ -30323,33 +30259,33 @@ function PasteSpecialDialog({
30323
30259
  }
30324
30260
  );
30325
30261
  }
30326
- function findElementNode(elementId) {
30262
+ function findElementNode(elementId2) {
30327
30263
  return document.querySelector(
30328
- `[data-element-id="${elementId}"][data-pptx-element="true"]`
30264
+ `[data-element-id="${elementId2}"][data-pptx-element="true"]`
30329
30265
  );
30330
30266
  }
30331
30267
  function PasteOptionsToolbar({
30332
- elementId,
30268
+ elementId: elementId2,
30333
30269
  onChoose,
30334
30270
  onDismiss
30335
30271
  }) {
30336
30272
  const { t } = useTranslation();
30337
30273
  const [rect, setRect] = useState(null);
30338
30274
  useEffect(() => {
30339
- if (!elementId) {
30275
+ if (!elementId2) {
30340
30276
  setRect(null);
30341
30277
  return;
30342
30278
  }
30343
- const node = findElementNode(elementId);
30279
+ const node = findElementNode(elementId2);
30344
30280
  if (!node) {
30345
30281
  setRect(null);
30346
30282
  return;
30347
30283
  }
30348
30284
  const box = node.getBoundingClientRect();
30349
30285
  setRect({ left: box.right, top: box.bottom });
30350
- }, [elementId]);
30286
+ }, [elementId2]);
30351
30287
  useEffect(() => {
30352
- if (!elementId) {
30288
+ if (!elementId2) {
30353
30289
  return;
30354
30290
  }
30355
30291
  const dismiss = () => onDismiss();
@@ -30362,8 +30298,8 @@ function PasteOptionsToolbar({
30362
30298
  window.removeEventListener("pointerdown", dismiss, true);
30363
30299
  window.removeEventListener("keydown", dismiss, true);
30364
30300
  };
30365
- }, [elementId, onDismiss]);
30366
- if (!elementId || !rect) {
30301
+ }, [elementId2, onDismiss]);
30302
+ if (!elementId2 || !rect) {
30367
30303
  return null;
30368
30304
  }
30369
30305
  return /* @__PURE__ */ jsx(
@@ -34144,7 +34080,7 @@ function useOutlineAuthoring({
34144
34080
  () => ({
34145
34081
  editPointsElementId: enabled ? editPointsElementId : null,
34146
34082
  hiddenEditPointsCommands: customization.hiddenEditPointsCommands,
34147
- onCommitEditPoints: (elementId, patch) => updateElement(elementId, patch),
34083
+ onCommitEditPoints: (elementId2, patch) => updateElement(elementId2, patch),
34148
34084
  onExitEditPoints,
34149
34085
  freeformTool: activeFreeformTool,
34150
34086
  onFreeformCommit: (shape) => {
@@ -34166,6 +34102,50 @@ function useOutlineAuthoring({
34166
34102
  ]
34167
34103
  );
34168
34104
  }
34105
+ function elementId(event) {
34106
+ return event.target instanceof Element ? event.target.closest("[data-element-id]")?.dataset.elementId : void 0;
34107
+ }
34108
+ function useStageAnimationTriggers(root, slide, triggers, onStageClick) {
34109
+ const hoverRef = useRef(void 0);
34110
+ useEffect(() => {
34111
+ root.current?.querySelectorAll("[data-element-id]").forEach((el) => {
34112
+ const id = el.dataset.elementId ?? "";
34113
+ const trigger = triggers?.interactiveTriggerShapeIds.has(id) || triggers?.hoverTriggerShapeIds.has(id) || false;
34114
+ el.toggleAttribute(PRESENTATION_ANIM_TRIGGER_ATTRIBUTE, trigger);
34115
+ el.style.cursor = trigger ? "pointer" : "";
34116
+ });
34117
+ hoverRef.current = void 0;
34118
+ }, [root, slide, triggers]);
34119
+ return {
34120
+ onClick(event) {
34121
+ const id = elementId(event);
34122
+ if (id && triggers?.interactiveTriggerShapeIds.has(id) && triggers.handleInteractiveShapeClick(id)) {
34123
+ return;
34124
+ }
34125
+ onStageClick?.(event);
34126
+ },
34127
+ onMouseOver(event) {
34128
+ const id = elementId(event);
34129
+ const next = id && triggers?.hoverTriggerShapeIds.has(id) ? id : void 0;
34130
+ if (next === hoverRef.current) {
34131
+ return;
34132
+ }
34133
+ if (hoverRef.current) {
34134
+ triggers?.handleHoverEnd(hoverRef.current);
34135
+ }
34136
+ hoverRef.current = next;
34137
+ if (next) {
34138
+ triggers?.handleHoverStart(next);
34139
+ }
34140
+ },
34141
+ onMouseLeave() {
34142
+ if (hoverRef.current) {
34143
+ triggers?.handleHoverEnd(hoverRef.current);
34144
+ }
34145
+ hoverRef.current = void 0;
34146
+ }
34147
+ };
34148
+ }
34169
34149
  function PresentationStage({
34170
34150
  activeSlide,
34171
34151
  templateElements,
@@ -34181,10 +34161,17 @@ function PresentationStage({
34181
34161
  fieldContext,
34182
34162
  tableStyleContext,
34183
34163
  onStageClick,
34164
+ animationTriggers,
34184
34165
  children,
34185
34166
  screenOverlay
34186
34167
  }) {
34187
34168
  const containerRef = useRef(null);
34169
+ const triggerHandlers = useStageAnimationTriggers(
34170
+ containerRef,
34171
+ activeSlide,
34172
+ animationTriggers,
34173
+ onStageClick
34174
+ );
34188
34175
  const [box, setBox] = useState(null);
34189
34176
  useEffect(() => {
34190
34177
  const el = containerRef.current;
@@ -34225,7 +34212,7 @@ function PresentationStage({
34225
34212
  ref: containerRef,
34226
34213
  "data-pptx-presentation-stage": true,
34227
34214
  className: "relative flex-1 min-h-0 overflow-hidden bg-black select-none",
34228
- onClick: onStageClick,
34215
+ ...triggerHandlers,
34229
34216
  children: [
34230
34217
  /* @__PURE__ */ jsxs(
34231
34218
  "div",
@@ -34488,14 +34475,14 @@ ${url}`)) {
34488
34475
  [viewerOptions, t]
34489
34476
  );
34490
34477
  const handleActionClick = useCallback(
34491
- (elementId, action) => {
34478
+ (elementId2, action) => {
34492
34479
  if (mode === "present") {
34493
34480
  const resolved = resolvePresentationAction(action, { slideCount: slides.length });
34494
34481
  if (resolved.intent.kind === "openUrl") {
34495
34482
  openExternalUrl(resolved.intent.url);
34496
34483
  return;
34497
34484
  }
34498
- presentation.handlePresentationAction(action, elementId);
34485
+ presentation.handlePresentationAction(action, elementId2);
34499
34486
  } else if (action.url) {
34500
34487
  openExternalUrl(action.url);
34501
34488
  }
@@ -34597,9 +34584,9 @@ ${url}`)) {
34597
34584
  onPrev: handleSwipePrev
34598
34585
  });
34599
34586
  const pickActive = aiPickMode && Boolean(onAiPickElement) && mode === "edit";
34600
- const handleElementClick = pickActive ? (elementId, e) => {
34587
+ const handleElementClick = pickActive ? (elementId2, e) => {
34601
34588
  e.stopPropagation();
34602
- onAiPickElement?.(activeSlideIndex, elementId);
34589
+ onAiPickElement?.(activeSlideIndex, elementId2);
34603
34590
  } : canvasHandlers.handleElementClick;
34604
34591
  const handleElementMouseDown = pickActive ? (_elementId, e) => {
34605
34592
  e.stopPropagation();
@@ -34637,6 +34624,7 @@ ${url}`)) {
34637
34624
  mode === "present" ? /* @__PURE__ */ jsx(
34638
34625
  PresentationStage,
34639
34626
  {
34627
+ animationTriggers: presentation,
34640
34628
  activeSlide,
34641
34629
  templateElements,
34642
34630
  canvasSize,
@@ -34751,7 +34739,7 @@ ${url}`)) {
34751
34739
  onInlineEditChange: s.setInlineEditingText,
34752
34740
  onInlineEditCommit: canvasHandlers.handleInlineEditCommit,
34753
34741
  onInlineEditCancel: () => s.setInlineEditingElementId(null),
34754
- onTableCellSelect: (cell, elementId) => s.setTableEditorState(cell ? { ...cell, elementId } : null),
34742
+ onTableCellSelect: (cell, elementId2) => s.setTableEditorState(cell ? { ...cell, elementId: elementId2 } : null),
34755
34743
  onCommitCellEdit: tableOps.handleCommitCellEdit,
34756
34744
  onUpdateSmartArtElement: canvasHandlers.handleUpdateSmartArtElement,
34757
34745
  onFormatText: canvasHandlers.handleFormatText,
@@ -34924,7 +34912,7 @@ function useTableStyleMapHandlers(input) {
34924
34912
  var AiChatPanel = lazy(async () => {
34925
34913
  const [{ useChat }, { default: Panel }] = await Promise.all([
34926
34914
  import('@ai-sdk/react'),
34927
- import('./AiChatPanel-WQUOEVQB.mjs')
34915
+ import('./AiChatPanel-5Z4BYP7S.mjs')
34928
34916
  ]);
34929
34917
  function BoundAiChatPanel(props) {
34930
34918
  return /* @__PURE__ */ jsx(Panel, { ...props, useChat });
@@ -35046,348 +35034,38 @@ function AiChangeOverlay({ batch, activeSlideIndex }) {
35046
35034
  ))
35047
35035
  ] });
35048
35036
  }
35049
-
35050
- // src/viewer/components/inspector/theme-editor-constants.ts
35051
- var THEME_EDITOR_CARD = "rounded bg-muted/50 p-2.5 space-y-2";
35052
- var THEME_EDITOR_HEADING = "text-[11px] font-medium uppercase tracking-wide text-muted-foreground mb-1.5";
35053
- var THEME_EDITOR_INPUT = "w-full rounded border border-border bg-background px-2 py-1 text-xs text-foreground focus:border-primary focus:outline-none";
35054
- var THEME_EDITOR_BTN = "rounded bg-primary px-3 py-1.5 text-xs font-medium text-white hover:bg-primary/80 disabled:opacity-40 disabled:cursor-not-allowed transition-colors";
35055
- var THEME_EDITOR_BTN_SECONDARY = "rounded bg-accent px-3 py-1.5 text-xs font-medium text-foreground hover:bg-accent/80 disabled:opacity-40 disabled:cursor-not-allowed transition-colors";
35056
- function ThemeColorSchemeEditor({
35057
- editColors,
35058
- canEdit,
35059
- activePickerKey,
35060
- majorFont,
35061
- minorFont,
35062
- onSetActivePickerKey,
35063
- onColorChange,
35064
- onMajorFontChange,
35065
- onMinorFontChange
35066
- }) {
35067
- const { t } = useTranslation();
35068
- const slotLabel = useCallback((key) => themeColorLabel(key, t), [t]);
35069
- const previewGrid = useMemo(() => buildThemeColorGrid(editColors, t), [editColors, t]);
35070
- const handleColorText = useCallback(
35071
- (val) => {
35072
- if (activePickerKey && /^#[0-9a-fA-F]{6}$/.test(val)) {
35073
- onColorChange(activePickerKey, val);
35074
- }
35075
- },
35076
- [activePickerKey, onColorChange]
35077
- );
35078
- return /* @__PURE__ */ jsxs(Fragment, { children: [
35079
- /* @__PURE__ */ jsxs("div", { className: THEME_EDITOR_CARD, children: [
35080
- /* @__PURE__ */ jsx("div", { className: THEME_EDITOR_HEADING, children: t("pptx.themeEditor.colorScheme") }),
35081
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-1.5", children: THEME_COLOR_SCHEME_KEYS.map((key) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
35082
- /* @__PURE__ */ jsx(
35083
- "button",
35084
- {
35085
- type: "button",
35086
- disabled: !canEdit,
35087
- className: `h-6 w-full rounded-sm border transition-colors ${activePickerKey === key ? "border-primary ring-1 ring-primary" : "border-border hover:border-muted-foreground"} disabled:opacity-40 disabled:cursor-not-allowed`,
35088
- style: { backgroundColor: editColors[key] },
35089
- title: `${slotLabel(key)}: ${editColors[key]}`,
35090
- "aria-label": `${slotLabel(key)}: ${editColors[key]}`,
35091
- onClick: () => onSetActivePickerKey(activePickerKey === key ? null : key)
35092
- }
35093
- ),
35094
- /* @__PURE__ */ jsx("span", { className: "text-[9px] text-muted-foreground truncate w-full text-center", children: slotLabel(key) })
35095
- ] }, key)) }),
35096
- activePickerKey && /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2 rounded bg-background p-2", children: [
35097
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground min-w-[60px]", children: slotLabel(activePickerKey) }),
35098
- /* @__PURE__ */ jsx(
35099
- "input",
35100
- {
35101
- type: "color",
35102
- disabled: !canEdit,
35103
- className: "h-6 w-8 cursor-pointer rounded border-0 bg-transparent p-0",
35104
- value: editColors[activePickerKey],
35105
- onChange: (e) => onColorChange(activePickerKey, e.target.value)
35106
- }
35107
- ),
35108
- /* @__PURE__ */ jsx(
35109
- "input",
35110
- {
35111
- type: "text",
35112
- disabled: !canEdit,
35113
- className: "flex-1 rounded border border-border bg-muted px-1.5 py-0.5 text-[10px] text-foreground font-mono",
35114
- value: editColors[activePickerKey],
35115
- onChange: (e) => handleColorText(e.target.value)
35116
- }
35117
- )
35118
- ] })
35119
- ] }),
35120
- previewGrid && /* @__PURE__ */ jsxs("div", { className: THEME_EDITOR_CARD, children: [
35121
- /* @__PURE__ */ jsx("div", { className: THEME_EDITOR_HEADING, children: t("pptx.themeEditor.preview") }),
35122
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-px", children: previewGrid.map((row, rowIdx) => /* @__PURE__ */ jsx("div", { className: "grid grid-cols-12 gap-px", children: row.map((cell) => /* @__PURE__ */ jsx(
35123
- "div",
35124
- {
35125
- className: "h-3.5 rounded-sm",
35126
- style: { backgroundColor: cell.hex },
35127
- title: `${cell.colLabel} -- ${cell.rowLabel} (${cell.hex})`
35128
- },
35129
- `${cell.schemeKey}-${rowIdx}`
35130
- )) }, rowIdx)) })
35131
- ] }),
35132
- /* @__PURE__ */ jsxs("div", { className: THEME_EDITOR_CARD, children: [
35133
- /* @__PURE__ */ jsx("div", { className: THEME_EDITOR_HEADING, children: t("pptx.themeEditor.fonts") }),
35134
- /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
35135
- /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-0.5", children: [
35136
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: t("pptx.themeEditor.headingFont") }),
35137
- /* @__PURE__ */ jsxs(
35138
- WebSelect,
35139
- {
35140
- "aria-label": t("pptx.themeEditor.headingFont"),
35141
- className: THEME_EDITOR_INPUT,
35142
- disabled: !canEdit,
35143
- value: COMMON_FONTS.includes(majorFont) ? majorFont : "__custom__",
35144
- onChange: (e) => {
35145
- if (e.target.value !== "__custom__") {
35146
- onMajorFontChange(e.target.value);
35147
- }
35148
- },
35149
- children: [
35150
- COMMON_FONTS.map((f) => /* @__PURE__ */ jsx("option", { value: f, children: f }, f)),
35151
- !COMMON_FONTS.includes(majorFont) && /* @__PURE__ */ jsx("option", { value: "__custom__", children: majorFont })
35152
- ]
35153
- }
35154
- )
35155
- ] }),
35156
- /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-0.5", children: [
35157
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: t("pptx.themeEditor.bodyFont") }),
35158
- /* @__PURE__ */ jsxs(
35159
- WebSelect,
35160
- {
35161
- "aria-label": t("pptx.themeEditor.bodyFont"),
35162
- className: THEME_EDITOR_INPUT,
35163
- disabled: !canEdit,
35164
- value: COMMON_FONTS.includes(minorFont) ? minorFont : "__custom__",
35165
- onChange: (e) => {
35166
- if (e.target.value !== "__custom__") {
35167
- onMinorFontChange(e.target.value);
35168
- }
35169
- },
35170
- children: [
35171
- COMMON_FONTS.map((f) => /* @__PURE__ */ jsx("option", { value: f, children: f }, f)),
35172
- !COMMON_FONTS.includes(minorFont) && /* @__PURE__ */ jsx("option", { value: "__custom__", children: minorFont })
35173
- ]
35174
- }
35175
- )
35176
- ] }),
35177
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-1 text-[10px] text-muted-foreground", children: [
35178
- /* @__PURE__ */ jsx("span", { style: { fontFamily: majorFont }, className: "text-foreground", children: t("pptx.themeEditor.headingSample") }),
35179
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
35180
- /* @__PURE__ */ jsx("span", { style: { fontFamily: minorFont }, className: "text-foreground", children: t("pptx.themeEditor.bodySample") })
35181
- ] })
35182
- ] })
35183
- ] })
35184
- ] });
35185
- }
35186
- var ACCENT_KEYS = ["accent1", "accent2", "accent3", "accent4", "accent5", "accent6"];
35187
- function ThemePresetGallery({
35188
- canEdit,
35189
- currentThemeName,
35190
- onSelectPreset
35191
- }) {
35192
- const { t } = useTranslation();
35193
- return /* @__PURE__ */ jsxs("div", { className: THEME_EDITOR_CARD, children: [
35194
- /* @__PURE__ */ jsx("div", { className: THEME_EDITOR_HEADING, children: t("pptx.themeEditor.presetThemes") }),
35195
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-1.5", children: PRESET_THEMES.map((preset) => /* @__PURE__ */ jsxs(
35196
- "button",
35197
- {
35198
- type: "button",
35199
- disabled: !canEdit,
35200
- className: `flex flex-col items-start gap-1 rounded border p-1.5 text-left transition-colors ${currentThemeName === preset.name ? "border-primary bg-primary/10" : "border-border hover:border-muted-foreground hover:bg-muted"} disabled:opacity-40 disabled:cursor-not-allowed`,
35201
- onClick: () => onSelectPreset(preset),
35202
- title: preset.name,
35203
- children: [
35204
- /* @__PURE__ */ jsx("div", { className: "flex gap-px w-full", children: ACCENT_KEYS.map((key) => /* @__PURE__ */ jsx(
35205
- "div",
35206
- {
35207
- className: "h-3 flex-1 first:rounded-l-sm last:rounded-r-sm",
35208
- style: { backgroundColor: preset.colorScheme[key] }
35209
- },
35210
- key
35211
- )) }),
35212
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground truncate w-full", children: preset.name })
35213
- ]
35214
- },
35215
- preset.name
35216
- )) })
35217
- ] });
35218
- }
35219
- function ThemeEditorPanel({
35220
- theme,
35221
- canEdit,
35222
- onUpdateColorScheme,
35223
- onUpdateFontScheme,
35224
- onUpdateThemeName,
35225
- onApplyToPresentation,
35226
- onClose
35227
- }) {
35037
+ function ThemeEditorPanel({ theme, canEdit, onApply, onClose }) {
35228
35038
  const { t } = useTranslation();
35229
- const [editColors, setEditColors] = useState(
35230
- () => theme?.colorScheme ?? PRESET_THEMES[0].colorScheme
35231
- );
35232
- const [majorFont, setMajorFont] = useState(
35233
- () => theme?.fontScheme?.majorFont?.latin ?? "Calibri Light"
35234
- );
35235
- const [minorFont, setMinorFont] = useState(
35236
- () => theme?.fontScheme?.minorFont?.latin ?? "Calibri"
35237
- );
35238
- const [themeName, setThemeName] = useState(() => theme?.name ?? "Custom Theme");
35239
- const [activePickerKey, setActivePickerKey] = useState(null);
35240
- const handleColorChange = useCallback(
35241
- (key, hex) => {
35242
- const next = { ...editColors, [key]: hex };
35243
- setEditColors(next);
35244
- onUpdateColorScheme(next);
35245
- },
35246
- [editColors, onUpdateColorScheme]
35247
- );
35248
- const handleSelectPreset = useCallback(
35249
- (preset) => {
35250
- setEditColors(preset.colorScheme);
35251
- setMajorFont(preset.majorFont);
35252
- setMinorFont(preset.minorFont);
35253
- setThemeName(preset.name);
35254
- onUpdateColorScheme(preset.colorScheme);
35255
- onUpdateFontScheme({
35256
- majorFont: { latin: preset.majorFont },
35257
- minorFont: { latin: preset.minorFont }
35258
- });
35259
- onUpdateThemeName(preset.name);
35260
- },
35261
- [onUpdateColorScheme, onUpdateFontScheme, onUpdateThemeName]
35262
- );
35263
- const handleReset = useCallback(() => {
35264
- if (!theme?.colorScheme) {
35039
+ const ref = useRef(null);
35040
+ useEffect(() => {
35041
+ const node = ref.current;
35042
+ if (node) {
35043
+ node.theme = theme;
35044
+ node.labels = themeEditorLabels(t);
35045
+ node.disabled = !canEdit;
35046
+ }
35047
+ }, [theme, canEdit, t]);
35048
+ useEffect(() => {
35049
+ const node = ref.current;
35050
+ if (!node) {
35265
35051
  return;
35266
35052
  }
35267
- setEditColors(theme.colorScheme);
35268
- setMajorFont(theme.fontScheme?.majorFont?.latin ?? "Calibri Light");
35269
- setMinorFont(theme.fontScheme?.minorFont?.latin ?? "Calibri");
35270
- setThemeName(theme.name ?? "Custom Theme");
35271
- onUpdateColorScheme(theme.colorScheme);
35272
- onUpdateFontScheme({
35273
- majorFont: {
35274
- latin: theme.fontScheme?.majorFont?.latin ?? "Calibri Light"
35275
- },
35276
- minorFont: { latin: theme.fontScheme?.minorFont?.latin ?? "Calibri" }
35277
- });
35278
- onUpdateThemeName(theme.name ?? "Custom Theme");
35279
- }, [theme, onUpdateColorScheme, onUpdateFontScheme, onUpdateThemeName]);
35280
- const handleMajorFontChange = useCallback(
35281
- (font) => {
35282
- setMajorFont(font);
35283
- onUpdateFontScheme({
35284
- majorFont: { latin: font },
35285
- minorFont: { latin: minorFont }
35286
- });
35287
- },
35288
- [minorFont, onUpdateFontScheme]
35289
- );
35290
- const handleMinorFontChange = useCallback(
35291
- (font) => {
35292
- setMinorFont(font);
35293
- onUpdateFontScheme({
35294
- majorFont: { latin: majorFont },
35295
- minorFont: { latin: font }
35296
- });
35297
- },
35298
- [majorFont, onUpdateFontScheme]
35299
- );
35300
- const handleNameChange = useCallback(
35301
- (name) => {
35302
- setThemeName(name);
35303
- onUpdateThemeName(name);
35304
- },
35305
- [onUpdateThemeName]
35306
- );
35307
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 overflow-y-auto max-h-[calc(100vh-120px)]", children: [
35308
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
35309
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: t("pptx.themeEditor.title") }),
35310
- /* @__PURE__ */ jsx(
35311
- "button",
35312
- {
35313
- type: "button",
35314
- onClick: onClose,
35315
- className: "rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
35316
- title: t("pptx.themeEditor.close"),
35317
- "aria-label": t("pptx.themeEditor.close"),
35318
- children: /* @__PURE__ */ jsx(
35319
- "svg",
35320
- {
35321
- className: "h-4 w-4",
35322
- fill: "none",
35323
- viewBox: "0 0 24 24",
35324
- stroke: "currentColor",
35325
- strokeWidth: 2,
35326
- children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
35327
- }
35328
- )
35329
- }
35330
- )
35331
- ] }),
35332
- /* @__PURE__ */ jsxs("div", { className: THEME_EDITOR_CARD, children: [
35333
- /* @__PURE__ */ jsx("div", { className: THEME_EDITOR_HEADING, children: t("pptx.themeEditor.themeName") }),
35334
- /* @__PURE__ */ jsx(
35335
- "input",
35336
- {
35337
- type: "text",
35338
- className: THEME_EDITOR_INPUT,
35339
- disabled: !canEdit,
35340
- value: themeName,
35341
- onChange: (e) => handleNameChange(e.target.value),
35342
- placeholder: t("pptx.themeEditor.themeNamePlaceholder")
35343
- }
35344
- )
35345
- ] }),
35346
- /* @__PURE__ */ jsx(
35347
- ThemePresetGallery,
35348
- {
35349
- canEdit,
35350
- currentThemeName: themeName,
35351
- onSelectPreset: handleSelectPreset
35352
- }
35353
- ),
35354
- /* @__PURE__ */ jsx(
35355
- ThemeColorSchemeEditor,
35356
- {
35357
- editColors,
35358
- canEdit,
35359
- activePickerKey,
35360
- majorFont,
35361
- minorFont,
35362
- onSetActivePickerKey: setActivePickerKey,
35363
- onColorChange: handleColorChange,
35364
- onMajorFontChange: handleMajorFontChange,
35365
- onMinorFontChange: handleMinorFontChange
35053
+ const apply = (event) => {
35054
+ if (!node.disabled) {
35055
+ node.disabled = true;
35056
+ void Promise.resolve(onApply(event.detail)).finally(() => {
35057
+ node.disabled = !canEdit;
35058
+ });
35366
35059
  }
35367
- ),
35368
- /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 pt-1", children: [
35369
- /* @__PURE__ */ jsx(
35370
- "button",
35371
- {
35372
- type: "button",
35373
- disabled: !canEdit,
35374
- className: THEME_EDITOR_BTN,
35375
- onClick: onApplyToPresentation,
35376
- children: t("pptx.themeEditor.applyToPresentation")
35377
- }
35378
- ),
35379
- /* @__PURE__ */ jsx(
35380
- "button",
35381
- {
35382
- type: "button",
35383
- disabled: !canEdit,
35384
- className: THEME_EDITOR_BTN_SECONDARY,
35385
- onClick: handleReset,
35386
- children: t("pptx.themeEditor.reset")
35387
- }
35388
- )
35389
- ] })
35390
- ] });
35060
+ };
35061
+ node.addEventListener("theme-editor-apply", apply);
35062
+ node.addEventListener("theme-editor-close", onClose);
35063
+ return () => {
35064
+ node.removeEventListener("theme-editor-apply", apply);
35065
+ node.removeEventListener("theme-editor-close", onClose);
35066
+ };
35067
+ }, [canEdit, onApply, onClose]);
35068
+ return /* @__PURE__ */ jsx("pptx-ui-theme-editor", { ref });
35391
35069
  }
35392
35070
  function MobileDismissSheet({
35393
35071
  onClose,
@@ -35934,22 +35612,15 @@ function ViewerSidePanels(props) {
35934
35612
  }
35935
35613
  ),
35936
35614
  s.isThemeEditorOpen && mode === "edit" && /* @__PURE__ */ jsx(
35937
- MobileDismissSheet,
35615
+ ThemeEditorPanel,
35938
35616
  {
35939
- onClose: () => s.setIsThemeEditorOpen(false),
35940
- className: "absolute right-0 top-0 z-30 h-full w-72 overflow-y-auto border-l border-border bg-card p-2.5 shadow-xl max-md:inset-x-0 max-md:bottom-0 max-md:top-auto max-md:w-full max-md:h-auto max-md:max-h-[60vh] max-md:rounded-t-xl max-md:border-t max-md:border-l-0",
35941
- children: /* @__PURE__ */ jsx(
35942
- ThemeEditorPanel,
35943
- {
35944
- theme: s.theme,
35945
- canEdit,
35946
- onUpdateColorScheme: themeHandlers.handleUpdateThemeColorScheme,
35947
- onUpdateFontScheme: themeHandlers.handleUpdateThemeFontScheme,
35948
- onUpdateThemeName: themeHandlers.handleUpdateThemeName,
35949
- onApplyToPresentation: themeHandlers.handleApplyThemeToPresentation,
35950
- onClose: () => s.setIsThemeEditorOpen(false)
35951
- }
35952
- )
35617
+ theme: s.theme,
35618
+ canEdit,
35619
+ onApply: async (edit) => {
35620
+ await themeHandlers.handleApplyThemeEdit(edit);
35621
+ s.setIsThemeEditorOpen(false);
35622
+ },
35623
+ onClose: () => s.setIsThemeEditorOpen(false)
35953
35624
  }
35954
35625
  ),
35955
35626
  aiPanel?.isOpen && aiConfig && aiBridge && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
@@ -35991,6 +35662,88 @@ function ViewerSidePanels(props) {
35991
35662
  )
35992
35663
  ] });
35993
35664
  }
35665
+ function ViewerContextMenus(props) {
35666
+ const {
35667
+ state,
35668
+ mode,
35669
+ selectedElement,
35670
+ activeSlideIndex,
35671
+ aiPanel,
35672
+ activeSlide,
35673
+ onApplyLayout,
35674
+ editorOps,
35675
+ setLayoutGalleryAnchor
35676
+ } = props;
35677
+ const { manipulation, tableOps } = editorOps;
35678
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
35679
+ state.contextMenuState && /* @__PURE__ */ jsx(
35680
+ ContextMenu,
35681
+ {
35682
+ slideIndex: activeSlideIndex,
35683
+ elementIds: state.effectiveSelectedIds,
35684
+ contextMenuState: state.contextMenuState,
35685
+ mode,
35686
+ selectedElement,
35687
+ tableEditorState: state.tableEditorState,
35688
+ hasMultiSelection: state.effectiveSelectedIds.length > 1,
35689
+ selectionGroupable: manipulation.selectionGroupable,
35690
+ hasClipboard: Boolean(state.clipboardPayload),
35691
+ editPointsAvailability: resolveEditPointsAvailability(selectedElement),
35692
+ onAction: manipulation.handleContextMenuAction,
35693
+ onInsertTableRow: tableOps.handleInsertTableRow,
35694
+ onDeleteTableRow: tableOps.handleDeleteTableRow,
35695
+ onInsertTableColumn: tableOps.handleInsertTableColumn,
35696
+ onDeleteTableColumn: tableOps.handleDeleteTableColumn,
35697
+ onMergeCellRight: tableOps.handleMergeCellRight,
35698
+ onMergeCellDown: tableOps.handleMergeCellDown,
35699
+ onMergeSelectedCells: tableOps.handleMergeSelectedCells,
35700
+ onSplitCell: tableOps.handleSplitCell,
35701
+ onAskAi: aiPanel && selectedElement ? () => {
35702
+ aiPanel.askAboutSelection();
35703
+ state.setContextMenuState(null);
35704
+ } : void 0,
35705
+ onFixAi: aiPanel && selectedElement ? () => {
35706
+ aiPanel.fixSelection();
35707
+ state.setContextMenuState(null);
35708
+ } : void 0,
35709
+ onClose: () => state.setContextMenuState(null)
35710
+ }
35711
+ ),
35712
+ state.canvasContextMenuState && /* @__PURE__ */ jsx(
35713
+ CanvasContextMenu,
35714
+ {
35715
+ slideIndex: activeSlideIndex,
35716
+ canvasContextMenuState: state.canvasContextMenuState,
35717
+ mode,
35718
+ hasClipboard: Boolean(state.clipboardPayload),
35719
+ showGrid: state.showGrid,
35720
+ showRulers: state.showRulers,
35721
+ onPaste: () => manipulation.handlePaste(),
35722
+ onOpenLayoutGallery: () => {
35723
+ const pos = state.canvasContextMenuState;
35724
+ if (pos) {
35725
+ setLayoutGalleryAnchor(pos);
35726
+ }
35727
+ },
35728
+ onResetSlide: () => {
35729
+ const path = resetSlideLayoutPath(activeSlide);
35730
+ if (path) {
35731
+ onApplyLayout?.(path);
35732
+ }
35733
+ },
35734
+ onOpenFormatBackground: () => {
35735
+ state.setSelectedElementId(null);
35736
+ state.setSelectedElementIds([]);
35737
+ state.setSidebarPanelMode("properties");
35738
+ state.setIsInspectorPaneOpen(true);
35739
+ },
35740
+ onToggleGrid: () => state.setShowGrid((v) => !v),
35741
+ onToggleRulers: () => state.setShowRulers((v) => !v),
35742
+ onClose: () => state.setCanvasContextMenuState(null)
35743
+ }
35744
+ )
35745
+ ] });
35746
+ }
35994
35747
  function ViewerMainContent(props) {
35995
35748
  const {
35996
35749
  mode,
@@ -36037,8 +35790,8 @@ function ViewerMainContent(props) {
36037
35790
  canvasHandlers,
36038
35791
  insertHandlers,
36039
35792
  manipulation,
36040
- slideOps,
36041
35793
  tableOps,
35794
+ slideOps,
36042
35795
  findReplace
36043
35796
  } = editorOps;
36044
35797
  const hf = state.headerFooter;
@@ -36061,7 +35814,7 @@ function ViewerMainContent(props) {
36061
35814
  );
36062
35815
  const layoutGalleryAnchorRef = useRef(null);
36063
35816
  const layoutGalleryPreviews = useLayoutPreviews(loadLayoutPreviews, layoutGalleryAnchor !== null);
36064
- return /* @__PURE__ */ jsx(ChartPartSelectionProvider, { children: /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-1 min-h-0", children: [
35817
+ return /* @__PURE__ */ jsx(ChartPartSelectionProvider, { children: /* @__PURE__ */ jsxs("div", { "data-pptx-chrome": "body", className: "relative z-10 flex flex-1 min-h-0", children: [
36065
35818
  showSlidesPane && /* @__PURE__ */ jsxs(Fragment, { children: [
36066
35819
  /* @__PURE__ */ jsx(
36067
35820
  SlidesPaneSidebar,
@@ -36193,69 +35946,7 @@ function ViewerMainContent(props) {
36193
35946
  ] }) : void 0
36194
35947
  }
36195
35948
  ),
36196
- state.contextMenuState && /* @__PURE__ */ jsx(
36197
- ContextMenu,
36198
- {
36199
- contextMenuState: state.contextMenuState,
36200
- mode,
36201
- selectedElement,
36202
- tableEditorState: state.tableEditorState,
36203
- hasMultiSelection: state.effectiveSelectedIds.length > 1,
36204
- selectionGroupable: manipulation.selectionGroupable,
36205
- hasClipboard: Boolean(state.clipboardPayload),
36206
- editPointsAvailability: resolveEditPointsAvailability(selectedElement),
36207
- onAction: manipulation.handleContextMenuAction,
36208
- onInsertTableRow: tableOps.handleInsertTableRow,
36209
- onDeleteTableRow: tableOps.handleDeleteTableRow,
36210
- onInsertTableColumn: tableOps.handleInsertTableColumn,
36211
- onDeleteTableColumn: tableOps.handleDeleteTableColumn,
36212
- onMergeCellRight: tableOps.handleMergeCellRight,
36213
- onMergeCellDown: tableOps.handleMergeCellDown,
36214
- onMergeSelectedCells: tableOps.handleMergeSelectedCells,
36215
- onSplitCell: tableOps.handleSplitCell,
36216
- onAskAi: aiPanel && selectedElement ? () => {
36217
- aiPanel.askAboutSelection();
36218
- state.setContextMenuState(null);
36219
- } : void 0,
36220
- onFixAi: aiPanel && selectedElement ? () => {
36221
- aiPanel.fixSelection();
36222
- state.setContextMenuState(null);
36223
- } : void 0,
36224
- onClose: () => state.setContextMenuState(null)
36225
- }
36226
- ),
36227
- state.canvasContextMenuState && /* @__PURE__ */ jsx(
36228
- CanvasContextMenu,
36229
- {
36230
- canvasContextMenuState: state.canvasContextMenuState,
36231
- mode,
36232
- hasClipboard: Boolean(state.clipboardPayload),
36233
- showGrid: state.showGrid,
36234
- showRulers: state.showRulers,
36235
- onPaste: () => manipulation.handlePaste(),
36236
- onOpenLayoutGallery: () => {
36237
- const pos = state.canvasContextMenuState;
36238
- if (pos) {
36239
- setLayoutGalleryAnchor(pos);
36240
- }
36241
- },
36242
- onResetSlide: () => {
36243
- const path = resetSlideLayoutPath(activeSlide);
36244
- if (path) {
36245
- onApplyLayout?.(path);
36246
- }
36247
- },
36248
- onOpenFormatBackground: () => {
36249
- state.setSelectedElementId(null);
36250
- state.setSelectedElementIds([]);
36251
- state.setSidebarPanelMode("properties");
36252
- state.setIsInspectorPaneOpen(true);
36253
- },
36254
- onToggleGrid: () => state.setShowGrid((v) => !v),
36255
- onToggleRulers: () => state.setShowRulers((v) => !v),
36256
- onClose: () => state.setCanvasContextMenuState(null)
36257
- }
36258
- ),
35949
+ /* @__PURE__ */ jsx(ViewerContextMenus, { ...props, setLayoutGalleryAnchor }),
36259
35950
  layoutGalleryAnchor && /* @__PURE__ */ jsxs(Fragment, { children: [
36260
35951
  /* @__PURE__ */ jsx(
36261
35952
  "div",
@@ -36439,6 +36130,9 @@ function CompatibilityToasts({
36439
36130
  }
36440
36131
  );
36441
36132
  }
36133
+ function EditorChromeStyle() {
36134
+ return /* @__PURE__ */ jsx("style", { "data-pptx-editor-styles": "", children: EDITOR_CHROME_CSS });
36135
+ }
36442
36136
  function ToggleRow({ checked, onChange, icon, label, testId }) {
36443
36137
  return /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2.5 cursor-pointer group select-none", children: [
36444
36138
  /* @__PURE__ */ jsxs("span", { className: "relative flex items-center justify-center w-4 h-4", children: [
@@ -36756,7 +36450,7 @@ function MobileChromeOverlay(props) {
36756
36450
  /* @__PURE__ */ jsx(
36757
36451
  MobileSlidesSheet,
36758
36452
  {
36759
- open: s.isSlidesPaneOpen,
36453
+ open: s.isSlidesPaneOpen && !s.isThemeEditorOpen,
36760
36454
  onClose: () => s.setIsSlidesPaneOpen(false),
36761
36455
  slides,
36762
36456
  templateElementsBySlideId: s.templateElementsBySlideId,
@@ -37951,6 +37645,13 @@ function SettingsDialog({
37951
37645
  )
37952
37646
  ] });
37953
37647
  }
37648
+ function ViewerOptionsProvider({
37649
+ options,
37650
+ store,
37651
+ children
37652
+ }) {
37653
+ return /* @__PURE__ */ jsx(ViewerOptionsStoreContext.Provider, { value: store, children: /* @__PURE__ */ jsx(ViewerOptionsContext.Provider, { value: options, children }) });
37654
+ }
37954
37655
  function useAiBridge(input) {
37955
37656
  const ref = useRef(input);
37956
37657
  ref.current = input;
@@ -38006,9 +37707,9 @@ function useAiBridge(input) {
38006
37707
  live.applySelection(elementIds[0] ?? null, elementIds);
38007
37708
  },
38008
37709
  applySlidesUpdate,
38009
- updateElement(slideIndex, elementId, updates) {
37710
+ updateElement(slideIndex, elementId2, updates) {
38010
37711
  applySlidesUpdate((slides) => {
38011
- const el = slides[slideIndex]?.elements.find((e) => e.id === elementId);
37712
+ const el = slides[slideIndex]?.elements.find((e) => e.id === elementId2);
38012
37713
  if (el) {
38013
37714
  applyElementUpdate(el, updates);
38014
37715
  }
@@ -38128,12 +37829,12 @@ function useAiPanelController(input) {
38128
37829
  setIsOpen(true);
38129
37830
  }, []);
38130
37831
  const stopPicking = useCallback(() => setPickMode(false), []);
38131
- const addPick = useCallback((slideIndex, elementId) => {
37832
+ const addPick = useCallback((slideIndex, elementId2) => {
38132
37833
  setPickTargets((prev) => {
38133
- if (prev.some((t) => t.kind === "element" && t.elementId === elementId)) {
37834
+ if (prev.some((t) => t.kind === "element" && t.elementId === elementId2)) {
38134
37835
  return prev;
38135
37836
  }
38136
- return [...prev, { kind: "element", slideIndex, elementId }];
37837
+ return [...prev, { kind: "element", slideIndex, elementId: elementId2 }];
38137
37838
  });
38138
37839
  }, []);
38139
37840
  const clearPicks = useCallback(() => {
@@ -38171,8 +37872,8 @@ function useAiPanelController(input) {
38171
37872
  }
38172
37873
  }
38173
37874
  if (toolFocus) {
38174
- for (const elementId of toolFocus.elementIds) {
38175
- out.push({ slideIndex: toolFocus.slideIndex, elementId, variant: "active" });
37875
+ for (const elementId2 of toolFocus.elementIds) {
37876
+ out.push({ slideIndex: toolFocus.slideIndex, elementId: elementId2, variant: "active" });
38176
37877
  }
38177
37878
  }
38178
37879
  return out;
@@ -38401,12 +38102,12 @@ var CROP_KEEP_SELECTOR = [
38401
38102
  "[data-pptx-crop-aspect]",
38402
38103
  "[data-pptx-crop-action]"
38403
38104
  ].join(",");
38404
- function naturalSizeOf(elementId) {
38105
+ function naturalSizeOf(elementId2) {
38405
38106
  if (typeof document === "undefined" || typeof CSS === "undefined") {
38406
38107
  return void 0;
38407
38108
  }
38408
38109
  const img = document.querySelector(
38409
- `[data-element-id="${CSS.escape(elementId)}"][data-pptx-element="true"] img`
38110
+ `[data-element-id="${CSS.escape(elementId2)}"][data-pptx-element="true"] img`
38410
38111
  );
38411
38112
  return img && img.naturalWidth > 0 && img.naturalHeight > 0 ? { width: img.naturalWidth, height: img.naturalHeight } : void 0;
38412
38113
  }
@@ -39298,6 +38999,7 @@ var PowerPointViewer = forwardRef(
39298
38999
  {
39299
39000
  style: themeStyle,
39300
39001
  "data-pptx-viewer": "",
39002
+ "data-pptx-editor-chrome": "",
39301
39003
  ...{ [RIBBON_SCOPE_ATTR]: ribbonScope },
39302
39004
  "aria-busy": loading,
39303
39005
  className: cn(
@@ -39305,6 +39007,7 @@ var PowerPointViewer = forwardRef(
39305
39007
  ...resolveOptionRootClasses(viewerOptions, "pptx")
39306
39008
  ),
39307
39009
  children: [
39010
+ /* @__PURE__ */ jsx(EditorChromeStyle, {}),
39308
39011
  /* @__PURE__ */ jsx(RibbonCustomizationStyle, { resolved: customizationResolved, scope: ribbonScope }),
39309
39012
  /* @__PURE__ */ jsx(
39310
39013
  "div",
@@ -39689,7 +39392,7 @@ var PowerPointViewer = forwardRef(
39689
39392
  // Nothing previously provided it, so every one of those consumers was
39690
39393
  // silently reading `DEFAULT_VIEWER_OPTIONS` forever, no matter what
39691
39394
  // the user changed in the Options dialog.
39692
- /* @__PURE__ */ jsx(ViewerOptionsContext.Provider, { value: viewerOptions, children: /* @__PURE__ */ jsx(ViewerCustomizationContext.Provider, { value: customizationResolved, children: /* @__PURE__ */ jsx(AccountAuthContext.Provider, { value: accountAuth, children: /* @__PURE__ */ jsx(Rendering3DFlagsContext.Provider, { value: effective3D, children: /* @__PURE__ */ jsx(ViewerThemeProvider, { theme: effectiveTheme, children: /* @__PURE__ */ jsxs(
39395
+ /* @__PURE__ */ jsx(ViewerOptionsProvider, { options: viewerOptions, store: optionsStore, children: /* @__PURE__ */ jsx(ViewerCustomizationContext.Provider, { value: customizationResolved, children: /* @__PURE__ */ jsx(AccountAuthContext.Provider, { value: accountAuth, children: /* @__PURE__ */ jsx(Rendering3DFlagsContext.Provider, { value: effective3D, children: /* @__PURE__ */ jsx(ViewerThemeProvider, { theme: effectiveTheme, children: /* @__PURE__ */ jsxs(
39693
39396
  CollaborationProvider,
39694
39397
  {
39695
39398
  config: collaboration,