pptx-react-viewer 4.37.0 → 4.39.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 (70) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/dist/{chunk-L4E5A5DE.js → chunk-2LNWGZPT.js} +2157 -2013
  3. package/dist/chunk-2LNWGZPT.js.br +0 -0
  4. package/dist/chunk-2LNWGZPT.js.gz +0 -0
  5. package/dist/{chunk-RZIXD6X7.mjs → chunk-5XBS7MCX.mjs} +53 -13
  6. package/dist/chunk-5XBS7MCX.mjs.br +0 -0
  7. package/dist/chunk-5XBS7MCX.mjs.gz +0 -0
  8. package/dist/{chunk-YAODOVJY.js → chunk-HOKZJLT5.js} +52 -10
  9. package/dist/chunk-HOKZJLT5.js.br +0 -0
  10. package/dist/chunk-HOKZJLT5.js.gz +0 -0
  11. package/dist/{chunk-RXN5Q6CJ.mjs → chunk-TYULCCA6.mjs} +1183 -1039
  12. package/dist/chunk-TYULCCA6.mjs.br +0 -0
  13. package/dist/chunk-TYULCCA6.mjs.gz +0 -0
  14. package/dist/i18n/de.cjs +629 -42
  15. package/dist/i18n/de.cjs.br +0 -0
  16. package/dist/i18n/de.cjs.gz +0 -0
  17. package/dist/i18n/de.mjs +629 -42
  18. package/dist/i18n/de.mjs.br +0 -0
  19. package/dist/i18n/de.mjs.gz +0 -0
  20. package/dist/i18n/es.cjs +629 -42
  21. package/dist/i18n/es.cjs.br +0 -0
  22. package/dist/i18n/es.cjs.gz +0 -0
  23. package/dist/i18n/es.mjs +629 -42
  24. package/dist/i18n/es.mjs.br +0 -0
  25. package/dist/i18n/es.mjs.gz +0 -0
  26. package/dist/i18n/fr.cjs +632 -42
  27. package/dist/i18n/fr.cjs.br +0 -0
  28. package/dist/i18n/fr.cjs.gz +0 -0
  29. package/dist/i18n/fr.mjs +632 -42
  30. package/dist/i18n/fr.mjs.br +0 -0
  31. package/dist/i18n/fr.mjs.gz +0 -0
  32. package/dist/i18n/zh-CN.cjs +640 -53
  33. package/dist/i18n/zh-CN.cjs.br +0 -0
  34. package/dist/i18n/zh-CN.cjs.gz +0 -0
  35. package/dist/i18n/zh-CN.mjs +640 -53
  36. package/dist/i18n/zh-CN.mjs.br +0 -0
  37. package/dist/i18n/zh-CN.mjs.gz +0 -0
  38. package/dist/index.d.ts +22 -5
  39. package/dist/index.js +22 -22
  40. package/dist/index.js.br +0 -0
  41. package/dist/index.js.gz +0 -0
  42. package/dist/index.mjs +2 -2
  43. package/dist/index.mjs.br +0 -0
  44. package/dist/index.mjs.gz +0 -0
  45. package/dist/internals.d.ts +37 -29
  46. package/dist/internals.js +80 -80
  47. package/dist/internals.js.br +0 -0
  48. package/dist/internals.js.gz +0 -0
  49. package/dist/internals.mjs +1 -1
  50. package/dist/internals.mjs.br +0 -0
  51. package/dist/internals.mjs.gz +0 -0
  52. package/dist/pptx-viewer.css +1 -1
  53. package/dist/pptx-viewer.css.br +0 -0
  54. package/dist/pptx-viewer.css.gz +0 -0
  55. package/dist/viewer/index.d.ts +17 -3
  56. package/dist/viewer/index.js +17 -17
  57. package/dist/viewer/index.js.br +0 -0
  58. package/dist/viewer/index.js.gz +0 -0
  59. package/dist/viewer/index.mjs +2 -2
  60. package/dist/viewer/index.mjs.br +0 -0
  61. package/dist/viewer/index.mjs.gz +0 -0
  62. package/package.json +3 -3
  63. package/dist/chunk-L4E5A5DE.js.br +0 -0
  64. package/dist/chunk-L4E5A5DE.js.gz +0 -0
  65. package/dist/chunk-RXN5Q6CJ.mjs.br +0 -0
  66. package/dist/chunk-RXN5Q6CJ.mjs.gz +0 -0
  67. package/dist/chunk-RZIXD6X7.mjs.br +0 -0
  68. package/dist/chunk-RZIXD6X7.mjs.gz +0 -0
  69. package/dist/chunk-YAODOVJY.js.br +0 -0
  70. package/dist/chunk-YAODOVJY.js.gz +0 -0
@@ -1,11 +1,11 @@
1
- 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, createReviewCommentsHost, ChartPartSelectionProvider, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, ViewerOptionsStoreContext, ViewerOptionsContext, useViewerOptionsContext, useVirtualizedSlides, useSwipeNavigation, PresentationTransitionOverlay, RemoteSelectionOverlay, CollaborationCursorOverlay, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, ElementRenderer, InlineCollaborationContext, SmartArtRenderer, downloadBlob, playAnimationSound, ResizeHandles, imgSrc, renderStrokeView, useChartPartSelection, DUOTONE_PRESETS, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, resolveSmartArtDataPalette } from './chunk-RZIXD6X7.mjs';
2
- import { ANIMATION_PRESET_OPTIONS, dist_exports, cn, SLIDE_NAV_THUMBNAIL_WIDTH, SLIDE_TRANSITION_OPTIONS, normalizeHexColor, hasCopyableFormat, DEFAULT_SECTION_GROUP_ID, safeOpenUrl, isPpactionUrl, parsePpactionUrl, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, TOOLBAR_SECTIONS, isUrlSafe, computeHandoutLayout, getPrintableArea, generateNoteLineCount, UNGROUPED_SECTION_ID, getShapeAdjustmentHandleDescriptors, isConnectorOrLineElement, GRID_SIZE, getElementTransformWithoutRotation, getElementTransform, MIN_ELEMENT_SIZE, getElementLabel, TABLE_STYLE_PRESETS, SHAPE_PRESETS, sanitizeGradientStops, formatCommentTimestamp, clampCropValue, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, DEFAULT_FILL_COLOR, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation, SHAPE_QUICK_STYLES, getPatternSvg, DEFAULT_STROKE_COLOR, STROKE_DASH_OPTIONS, openNativeEyeDropper } from './chunk-UC2VQORY.mjs';
3
- import { EMPTY_RESOLVED_CUSTOMIZATION, ANIMATION_DIRECTION_LABEL_KEYS, compileEquationTemplateMathMl, resolveViewerRootOptions, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, isFeatureEnabled, isDialogAvailable, resolveAutosaveActivation, viewerOptionsToPreferences, applyPreferenceToOptions, resolveHistoryDepth, attachViewerHyperlinks, shouldConfirmExternalHyperlink, applyAutoCorrect, resolveImageResolutionScale, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, createSlidePackageClipboard, isPanelVisible, shouldShowAutosaveRecoveryPrompt, resolveOptionRootClasses, RIBBON_SCOPE_ATTR, resolve3DRenderingFlags, resolveSlideSizeSelection, RULER_THICKNESS, RULER_FONT_SIZE, editorThumbnailHeight, buildPreviewElements, deriveSlideFieldContext, deviceStrokeStageStyle, hiddenSlideCue, EDITOR_THUMBNAIL_WIDTH, HIDDEN_SLIDE_SLASH_GRADIENT, HIDDEN_SLIDE_LABEL_KEY, visibleTemplateElements, themeToCssVars, createCustomizationController, resolveEffectiveHiddenActions, listAutosaveSnapshots, resolveExpiredAutosaveSnapshots, deleteAutosaveSnapshot, tableLayoutCells, masterViewCrudActions, applyMasterViewCrudAction, masterViewCrudFailureKey, EDITOR_CHROME_CSS, ribbonCustomizationCss, applyMotionPathPreset, resetSlideLayoutPath, DEFAULT_INSERT_CHART_KIND, templateSchemeFromTheme, createBackstagePresentation, playFeedbackSound, shouldDiscardAutosaveOnSuccessfulSave, buildFieldSubstitutionContext, setMasterViewBackgroundColor, canUseClipboard, runProgramNoticeStackStyle, printPropertiesFrameSlides, printPropertiesSlidesPerPage, PASTE_SPECIAL_OPTIONS, findCanvasElementNode, 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, homeLaunchers, attachRibbonOverflow, editorThumbnailWidth, masterViewBackgroundColor, resolvePresentationAction, isPresentationAdvanceClick, toggleBlackboard, PRESENT_TOOLBAR_CLASSES, resolveEditPointsAvailability, isCurrentLayout, observeElementHeight, EXPANDED_MAX_HEIGHT, resolveStatusBarSave, statusBarViewMode, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, compileLatexEquation, convertLatexToOmml, EQUATION_TEMPLATES, clampPercent, resolveDefaultPrintSettings, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, CUSTOM_FONT_ACCEPT, activateModalFocus, buildCollaborationShareUrl, buildActiveSessionUsers, slideClipboardLabels, sorterPasteInsertAt, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, SORTER_MAX_ZOOM, canGoPrevious, formatSlideCounter, READING_VIEW_COUNTER_ATTR, canGoNext, READING_VIEW_ATTR, listenForOutlineViewDismiss, 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, buildTitleBarState, resolveScreenTip, visibleContextualTabs, resolveActiveRibbonTab, visibleRibbonAddIns, RIBBON_ADD_IN_TAB_ATTR, contextualTabLabelKey, RIBBON_CONTEXTUAL_TAB_ATTR, buildTabRowActionsState, TAB_ROW_ACTION_CLASSES, tabRowActionsAttributes, customizeBackstageNav, BACKSTAGE_NAV, listBackstageRecentFiles, BACKSTAGE_BACK_CLASSES, BACKSTAGE_NAV_CLASSES, FREEFORM_TOOL_IDS, isDrawingToolVisible, textFontSizePtToPx, withHomeGalleries, drawingHomeControls, homeGalleryControls, homeGalleryApply, shapeOutlineChange, shapeFillChange, editingHomeControls, arrangeHomeControls, arrangePainterHomeControls, arrangeAlignAction, DESIGN_RIBBON_GROUPS, DESIGN_RIBBON_COMMANDS, designCommandState, FIXED_TAB_GALLERIES, CONTEXTUAL_TAB_GROUPS, editorThumbnailStep, resolveSlidePaneClick, SLIDE_VIRTUALIZATION_THRESHOLD, buildSectionContextMenuEntries, buildSlidePaneContextMenuEntries, slidePaneViewItems, isEditPointsEnabled, findReplacementAvailability, PRESENTATION_HIT_TEST_CSS, PRESENTATION_STAGE_ATTRIBUTE, buildStrokePathD, cursorForTool, annotationOverlayZIndex, presentationInkPath, resolveNotesSchematicBodyFontSizePx, PRESENTER_NAVIGATOR_LABEL_KEYS, getPresentationContextMenuSections, CONTEXT_MENU_PRESENTATION_LAYER, presentationViewItems, subtitleRecognitionLanguage, subtitleSettingsFromOptions, getSpeechRecognitionCtor, mergeCaptionResults, customizeContextMenuEntries, buildContextMenuEntries, contextMenuViewItems, customizeCanvasContextMenuEntries, buildCanvasContextMenuEntries, buildLayoutPreviewGeometry, scaleSlidesForSizeChange, slideSizeToCanvasPx, resolveSelectionPaneRename, themeEditorLabels, resolveNotesSegments, defaultRichEnabled, segmentsToEditorHtml, DEBOUNCE_MS, createPlainNotesSegments, parseSegmentsFromRichEditor, segmentsToPlainText, getCurrentParagraphIndex, segmentsToParagraphs, paragraphsToSegments, MAX_INDENT_LEVEL, INDENT_PX as INDENT_PX$1, buildNotesPrintHtml, MIN_TOUCH_TARGET_PX, toggleSheet, SMARTART_PREVIEW_ELEMENT_HEIGHT, SMARTART_PREVIEW_ELEMENT_WIDTH, buildSmartArtPreviewElement, sanitizeMathMl, computeAllNotesPages, getNotesPrintableArea, clampOptionNumber, QUICK_ACCESS_COMMAND_CATALOG, registerCustomFont, createSlideSorterState, sorterSelectionIndexes, selectSorterSlide, applySorterAction, sorterGridColumns, sorterMenuContext, buildSlideSorterContextMenuEntries, slideSorterContextMenuLabel, openReadingView, applyReadingViewCommand, createPresentationKeyBuffer, readingViewFitScale, READING_VIEW_STAGE_ATTR, buildOutline, applyOutlineEdit, mapOutlineKey, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, presenterConsoleAction, presenterConsoleViewState, 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, clipboardHomeControls, slidesHomeControls, resolveDefaultFontFamily, textFontSizePxToPt, getInlineEditorSelectionResult, selectedParagraphBulletKind, elementBulletKind, selectionBulletKind, fontPickerHomeControls, fontHomeControls, nextToggleValue, RIBBON_GROUP_ATTR, paragraphHomeAlign, paragraphHomeControls, paragraphHomeAction, arrangeShapeHomeControls, strokeWidthOf, canSetStrokeWidth, canUngroupSelection, canGroupSelection, buildRibbonGallery, readRibbonTransitionDraft, SLIDE_SHOW_COMMAND_GROUPS, RECORD_COMMAND_GROUPS, trackActiveComment, commentCounts, findCommentLocation, buildReviewRibbon, HELP_RIBBON_COMMANDS, galleryTextLabel, pictureSizeHomeControls, sectionAddAfterSlideIndex, masterViewPseudoSlide, PRESENTATION_ANIM_TRIGGER_ATTRIBUTE, parentSelection, slideSpaceElement, isGroupMember, motionPathFor, setMotionPath, shouldShowElementHandles, computeAnchoredPopupPosition, applyTableStyleDelete, applyTableStyleMapChange, handleReadingViewKey, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, SLIDE_TEMPLATES, getSelectionTextStyleFlags, TEXT_DECORATION_FLAGS, dispatchCropRequest, applyRibbonGalleryItem, ribbonTransitionsDraftPatch, ribbonTransitionUpdates, ribbonTransitionsSoundChange, ribbonTransitionStockSoundUrl, playSlideTransitionPreview, playAnimationRibbonPreview, SLIDE_SHOW_OPTIONS, createViewerOptionsStore, subtitleSettingsLabels, isReviewCommentCommand, runReviewCommentCommand, attachEditorImagePaste, authorConnectorBetweenSites, findEraserHitElementId, generateTicks, rulerDragToGuidePosition, resolveElementInteractivity, 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, MERGE_SHAPES_MENU_ITEMS, hasMultipleSelectedTableCells, isElementLocked, mergeSlideTransition, slideBackgroundClearState, slideBackgroundClearPatch, effectiveDirection, TRIGGER_OPTIONS, effectiveTimingCurve, getAfterAnimationState, 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, applyTableStylePreset, tableStyleAssignmentUpdate, evenColumnWidths, redistributeColumnWidth, evenRowHeights, inspectorNumber, patchChartData, collapseChartTitleRunsForEdit, chartGridlinesState, chartGridlinesPatch, seriesSecondaryAxisPatch, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setDataLabelsRangeCache, describeSmartArtBounds, canAddTopLevelNode, classifyExtraConnections, siblingIndex, siblingCount, canRemoveTopLevelNode, imageResetPatch, imageResetState, canInteractWithElement, buildOleObjectNamePatch, shouldShowAccessibilitySection, withFrameSlides, withSlidesPerPage, schemaLabel, THEME_COLOR_SLOT_LABEL_KEYS, SLIDE_SIZE_PRESETS, TRANSITION_ORIENTATION_TYPES, clampTransitionNumber, TRANSITION_SPEED_OPTIONS, TRANSITION_MORPH_OPTIONS, flattenTagCollections, resolveTemplateBackgroundRows, commentMentionQuery, matchCommentMentionAuthors, buildAnimationTimelineRows, clearMotionPath, setTrigger, setTriggerBookmark, getEffectSoundState, setEffectSound, setEffectStockSound, setAfterAnimation, setAfterAnimationColor, directionValuesFor, buildAnimationTimelineBars, motionPathPresetIdForPath, MOTION_PATH_FAMILIES, motionPathPresetsByFamily, motionPathPresetLabelKey, motionPathFamilyLabelKey, EFFECT_SOUND_CATALOGUE, listMediaBookmarkOptions, selectedBookmarkOptionValue, hasTiltData, toElementAxes, dragCropHandle, panCropImage, clientToSlidePoint, EDIT_POINTS_TARGET_ATTR, describeTableStyleEditor, TABLE_STYLE_EDITOR_PARTS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, resolveDisplayedChartType, CHART_TYPE_OPTIONS, chartDataLabelsTogglePatch, BAR3D_SHAPE_OPTIONS, bar3DShapePatch, RADAR_STYLE_OPTIONS, radarStylePatch, SURFACE_WIREFRAME_OPTIONS, surfaceWireframePatch, isSeriesUsingSecondaryAxis, seriesColorClearState, listChartUserShapeRows, withChartUserShapeAdded, createDefaultChartUserShape, withChartUserShapeRowRemoved, withChartUserShapeRowTextUpdated, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, addSiblingAfter, removeEmptyNode, demote, promote, reorder, cropResetState, cropResetPatch, ARTISTIC_EFFECTS, mediaTrimEndSeconds, trimmedMediaDurationMs, mediaTrimEndAbsoluteMs, mediaTrimResetState, mediaTrimEndMsFromAbsoluteMs, mediaTrimResetPatch, buildOleEditDialogDescriptor, buildOleContentUpdatePatch, buildThemeColorSwatchGrid, themeColorSwatchRows, findSelectedThemeSwatch, themeSwatchCommit, getNonVisualDescriptionFields, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, canCommitActionType, slideSizeFromPreset, withSlideSizeOrientation, TRANSITION_DIR_ARROWS, buildDirectionGrid, updateTagInCollections, deleteTagFromCollections, addTagToCollections, commentTextSegments, COMMENT_MENTION_CLASS, COMMENT_MENTION_ATTRIBUTE, insertCommentMention, reorderAnimationTimelineRows, applyAnimationTimelineOrder, getEffectSoundAsset, animationEffectLabel, overlayPointerInput, TABLE_STYLE_BORDER_SIDES, applyTableStyleFieldEdit, withCellStyle, LBL as LBL$1, SEL as SEL$1, FILL_MODE_OPTIONS as FILL_MODE_OPTIONS$1, SECTION_HEADING, NUM as NUM$1, getChartUserShapeGroupTransform, withChartUserShapeGroupChildAdded, createDefaultChartUserShapeGroupChild, withChartUserShapeRowUpdated, getChartUserShapeRowChartBox, withChartUserShapeRowFlipUpdated, withChartUserShapeRowRotationUpdated, withChartUserShapeRowChartBoxUpdated, smartArtLayoutSwitchPatch, rebuildDrawingShapesIfCleared, mediaTrimEndMsFromSeconds, validateMediaTrimRange, quickStyleSwatchCss, shapeQuickStyleLabel, OFFICE_COLOR_SWATCHES, officeColorSwatchLabel, PATTERN_PRESET_OPTIONS as PATTERN_PRESET_OPTIONS$1, COMPOUND_LINE_OPTIONS as COMPOUND_LINE_OPTIONS$1, LINE_JOIN_OPTIONS as LINE_JOIN_OPTIONS$1, LINE_CAP_OPTIONS as LINE_CAP_OPTIONS$1, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, toSlideIndex, TABLE_STYLE_BORDER_SIDE_LABEL_KEYS, TABLE_STYLE_DASH_PRESETS, GRADIENT_TYPE_OPTIONS as GRADIENT_TYPE_OPTIONS$1, PATTERN_OPTIONS, FILL_PATTERN_LABEL_KEYS, toggleText3dExtrusion, BEVEL_PRESETS, cropFit, cropFill, cropToAspectRatio } from 'ooxml-ui/pptx';
1
+ import { useViewerOptions, useReadOnlyRecommendationState, useCompatibilityToastsState, useReducedMotion, useViewerState, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useViewPreferencesSync, useLayoutSwitching, Rendering3DFlagsContext, CollaborationProvider, ChartFormatContext, useCollaboration, useCollaborationDocumentSync, useFollowMode, useBroadcastFollower, SlideBackgroundImageLayer, StaticElementRenderer, safePrompt, scopeLayoutOptionsToActiveSlide, createReviewCommentsHost, ChartPartSelectionProvider, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, ViewerOptionsStoreContext, ViewerOptionsContext, useViewerOptionsContext, useVirtualizedSlides, useSwipeNavigation, PresentationTransitionOverlay, RemoteSelectionOverlay, CollaborationCursorOverlay, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, ElementRenderer, InlineCollaborationContext, useChartFormatContext, SmartArtRenderer, downloadBlob, playAnimationSound, ResizeHandles, imgSrc, renderStrokeView, useChartPartSelection, DUOTONE_PRESETS, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, resolveSmartArtDataPalette } from './chunk-5XBS7MCX.mjs';
2
+ import { ANIMATION_PRESET_OPTIONS, dist_exports, cn, SLIDE_NAV_THUMBNAIL_WIDTH, SLIDE_TRANSITION_OPTIONS, normalizeHexColor, hasCopyableFormat, DEFAULT_SECTION_GROUP_ID, safeOpenUrl, isPpactionUrl, parsePpactionUrl, SHORTCUT_REFERENCE_ITEMS, TOOLBAR_SECTIONS, isUrlSafe, computeHandoutLayout, getPrintableArea, generateNoteLineCount, UNGROUPED_SECTION_ID, getShapeAdjustmentHandleDescriptors, isConnectorOrLineElement, GRID_SIZE, getElementTransformWithoutRotation, getElementTransform, MIN_ELEMENT_SIZE, getElementLabel, TABLE_STYLE_PRESETS, SHAPE_PRESETS, sanitizeGradientStops, formatCommentTimestamp, clampCropValue, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, DEFAULT_FILL_COLOR, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation, SHAPE_QUICK_STYLES, getPatternSvg, DEFAULT_STROKE_COLOR, STROKE_DASH_OPTIONS, openNativeEyeDropper } from './chunk-UC2VQORY.mjs';
3
+ import { EMPTY_RESOLVED_CUSTOMIZATION, ANIMATION_DIRECTION_LABEL_KEYS, compileEquationTemplateMathMl, resolveViewerRootOptions, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, isFeatureEnabled, isDialogAvailable, isEditingAllowed, resolveAutosaveActivation, viewerOptionsToPreferences, applyPreferenceToOptions, resolveHistoryDepth, attachViewerHyperlinks, shouldConfirmExternalHyperlink, applyAutoCorrect, resolveImageResolutionScale, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, createSlidePackageClipboard, isPanelVisible, shouldShowAutosaveRecoveryPrompt, resolveOptionRootClasses, RIBBON_SCOPE_ATTR, resolve3DRenderingFlags, resolveSlideSizeSelection, RULER_THICKNESS, RULER_FONT_SIZE, editorThumbnailHeight, buildPreviewElements, deriveSlideFieldContext, deviceStrokeStageStyle, hiddenSlideCue, EDITOR_THUMBNAIL_WIDTH, HIDDEN_SLIDE_SLASH_GRADIENT, HIDDEN_SLIDE_LABEL_KEY, visibleTemplateElements, themeToCssVars, createCustomizationController, resolveEffectiveHiddenActions, listAutosaveSnapshots, resolveExpiredAutosaveSnapshots, deleteAutosaveSnapshot, tableLayoutCells, resetChartFormatTarget, masterViewCrudActions, applyMasterViewCrudAction, masterViewCrudFailureKey, EDITOR_CHROME_CSS, ribbonCustomizationCss, applyMotionPathPreset, resetSlideLayoutPath, DEFAULT_INSERT_CHART_KIND, templateSchemeFromTheme, createBackstagePresentation, playFeedbackSound, shouldDiscardAutosaveOnSuccessfulSave, buildFieldSubstitutionContext, setMasterViewBackgroundColor, canUseClipboard, runProgramNoticeStackStyle, observeElementHeight, printPropertiesFrameSlides, printPropertiesSlidesPerPage, PASTE_SPECIAL_OPTIONS, findCanvasElementNode, isHeaderFooterDateTextVisible, isHeaderFooterHeaderTextVisible, isHeaderFooterFooterTextVisible, getDensePanelTouchTargetPx, shouldStickyActionRow, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, getSlideBackgroundStyle, pushRecentColor, mruColorsPatch, shouldClearAutosaveCacheOnClose, canCropElement, cropSessionChanged, cancelCropUpdate, startCropSession, homeLaunchers, attachRibbonOverflow, getRegionRenderer, ViewerRegionHost, editorThumbnailWidth, masterViewBackgroundColor, resolvePresentationAction, isPresentationAdvanceClick, toggleBlackboard, PRESENT_TOOLBAR_CLASSES, resolveEditPointsAvailability, isCurrentLayout, EXPANDED_MAX_HEIGHT, resolveStatusBarSave, statusBarViewMode, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, compileLatexEquation, convertLatexToOmml, EQUATION_TEMPLATES, clampPercent, resolveDefaultPrintSettings, HANDOUT_OPTIONS, bindPptxOptionsDialog, optionsBlockSlot, optionsPaneSlot, DEFAULT_QUICK_ACCESS_COMMAND_IDS, AI_OPTIONS_CATEGORY, activateModalFocus, buildCollaborationShareUrl, buildActiveSessionUsers, slideClipboardLabels, sorterPasteInsertAt, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, SORTER_MAX_ZOOM, canGoPrevious, formatSlideCounter, READING_VIEW_COUNTER_ATTR, canGoNext, READING_VIEW_ATTR, listenForOutlineViewDismiss, 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, buildTitleBarState, resolveScreenTip, visibleContextualTabs, resolveActiveRibbonTab, visibleRibbonAddIns, RIBBON_ADD_IN_TAB_ATTR, contextualTabLabelKey, RIBBON_CONTEXTUAL_TAB_ATTR, buildTabRowActionsState, TAB_ROW_ACTION_CLASSES, tabRowActionsAttributes, backstageNavEntries, BACKSTAGE_NAV, listBackstageRecentFiles, BACKSTAGE_BACK_CLASSES, BACKSTAGE_NAV_CLASSES, FREEFORM_TOOL_IDS, isDrawingToolVisible, textFontSizePtToPx, withHomeGalleries, drawingHomeControls, homeGalleryControls, homeGalleryApply, shapeOutlineChange, shapeFillChange, editingHomeControls, arrangeHomeControls, arrangePainterHomeControls, arrangeAlignAction, DESIGN_RIBBON_GROUPS, FIXED_TAB_GALLERIES, DESIGN_RIBBON_COMMANDS, designCommandState, CONTEXTUAL_TAB_GROUPS, editorThumbnailStep, resolveSlidePaneClick, SLIDE_VIRTUALIZATION_THRESHOLD, buildSectionContextMenuEntries, buildSlidePaneContextMenuEntries, slidePaneViewItems, isEditPointsEnabled, findReplacementAvailability, PRESENTATION_HIT_TEST_CSS, PRESENTATION_STAGE_ATTRIBUTE, buildStrokePathD, cursorForTool, annotationOverlayZIndex, presentationInkPath, resolveNotesSchematicBodyFontSizePx, PRESENTER_NAVIGATOR_LABEL_KEYS, getPresentationContextMenuSections, CONTEXT_MENU_PRESENTATION_LAYER, presentationViewItems, subtitleRecognitionLanguage, subtitleSettingsFromOptions, getSpeechRecognitionCtor, mergeCaptionResults, customizeContextMenuEntries, buildContextMenuEntries, contextMenuViewItems, customizeCanvasContextMenuEntries, buildCanvasContextMenuEntries, buildLayoutPreviewGeometry, scaleSlidesForSizeChange, slideSizeToCanvasPx, resolveSelectionPaneRename, themeEditorLabels, resolveNotesSegments, defaultRichEnabled, segmentsToEditorHtml, DEBOUNCE_MS, createPlainNotesSegments, parseSegmentsFromRichEditor, segmentsToPlainText, getCurrentParagraphIndex, segmentsToParagraphs, paragraphsToSegments, MAX_INDENT_LEVEL, INDENT_PX as INDENT_PX$1, buildNotesPrintHtml, MIN_TOUCH_TARGET_PX, toggleSheet, SMARTART_PREVIEW_ELEMENT_HEIGHT, SMARTART_PREVIEW_ELEMENT_WIDTH, buildSmartArtPreviewElement, sanitizeMathMl, computeAllNotesPages, getNotesPrintableArea, CUSTOM_FONT_ACCEPT, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, resolveViewerAddinRows, createSlideSorterState, sorterSelectionIndexes, selectSorterSlide, applySorterAction, sorterGridColumns, sorterMenuContext, buildSlideSorterContextMenuEntries, slideSorterContextMenuLabel, openReadingView, applyReadingViewCommand, createPresentationKeyBuffer, readingViewFitScale, READING_VIEW_STAGE_ATTR, buildOutline, applyOutlineEdit, mapOutlineKey, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, presenterConsoleAction, presenterConsoleViewState, 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, clipboardHomeControls, slidesHomeControls, resolveInsertSlideLayout, SLIDE_TEMPLATES, resolveDefaultFontFamily, textFontSizePxToPt, getInlineEditorSelectionResult, selectedParagraphBulletKind, elementBulletKind, selectionBulletKind, fontPickerHomeControls, fontHomeControls, nextToggleValue, RIBBON_GROUP_ATTR, paragraphHomeAlign, paragraphHomeControls, paragraphHomeAction, arrangeShapeHomeControls, strokeWidthOf, canSetStrokeWidth, canUngroupSelection, canGroupSelection, buildRibbonGallery, readRibbonTransitionDraft, SLIDE_SHOW_COMMAND_GROUPS, RECORD_COMMAND_GROUPS, trackActiveComment, commentCounts, findCommentLocation, buildReviewRibbon, HELP_RIBBON_COMMANDS, galleryTextLabel, pictureSizeHomeControls, chartSelectionHomeControls, dispatchChartSelectionRequest, sectionAddAfterSlideIndex, masterViewPseudoSlide, PRESENTATION_ANIM_TRIGGER_ATTRIBUTE, parentSelection, slideSpaceElement, isGroupMember, motionPathFor, setMotionPath, shouldShowElementHandles, computeAnchoredPopupPosition, applyTableStyleDelete, applyTableStyleMapChange, registerCustomFont, QUICK_ACCESS_COMMAND_CATALOG, handleReadingViewKey, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, buildSlideTemplateContent, getSelectionTextStyleFlags, TEXT_DECORATION_FLAGS, dispatchCropRequest, applyRibbonGalleryItem, ribbonTransitionsDraftPatch, ribbonTransitionUpdates, ribbonTransitionsSoundChange, ribbonTransitionStockSoundUrl, playSlideTransitionPreview, playAnimationRibbonPreview, SLIDE_SHOW_OPTIONS, createViewerOptionsStore, subtitleSettingsLabels, isReviewCommentCommand, runReviewCommentCommand, attachEditorImagePaste, authorConnectorBetweenSites, findEraserHitElementId, generateTicks, rulerDragToGuidePosition, resolveElementInteractivity, 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, MERGE_SHAPES_MENU_ITEMS, hasMultipleSelectedTableCells, isElementLocked, mergeSlideTransition, slideBackgroundClearState, slideBackgroundClearPatch, effectiveDirection, TRIGGER_OPTIONS, effectiveTimingCurve, getAfterAnimationState, mapSlideSorterKey, isEditorTextInputTarget, clampSorterZoom, 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, applyTableStylePreset, tableStyleAssignmentUpdate, evenColumnWidths, redistributeColumnWidth, evenRowHeights, inspectorNumber, patchChartData, collapseChartTitleRunsForEdit, chartGridlinesState, chartGridlinesPatch, seriesSecondaryAxisPatch, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setDataLabelsRangeCache, describeSmartArtBounds, canAddTopLevelNode, classifyExtraConnections, siblingIndex, siblingCount, canRemoveTopLevelNode, imageResetPatch, imageResetState, canInteractWithElement, buildOleObjectNamePatch, shouldShowAccessibilitySection, withFrameSlides, withSlidesPerPage, schemaLabel, THEME_COLOR_SLOT_LABEL_KEYS, SLIDE_SIZE_PRESETS, TRANSITION_ORIENTATION_TYPES, clampTransitionNumber, TRANSITION_SPEED_OPTIONS, TRANSITION_MORPH_OPTIONS, flattenTagCollections, resolveTemplateBackgroundRows, commentMentionQuery, matchCommentMentionAuthors, buildAnimationTimelineRows, clearMotionPath, setTrigger, setTriggerBookmark, getEffectSoundState, setEffectSound, setEffectStockSound, setAfterAnimation, setAfterAnimationColor, directionValuesFor, buildAnimationTimelineBars, motionPathPresetIdForPath, MOTION_PATH_FAMILIES, motionPathPresetsByFamily, motionPathPresetLabelKey, motionPathFamilyLabelKey, EFFECT_SOUND_CATALOGUE, listMediaBookmarkOptions, selectedBookmarkOptionValue, hasTiltData, toElementAxes, dragCropHandle, panCropImage, clientToSlidePoint, EDIT_POINTS_TARGET_ATTR, describeTableStyleEditor, TABLE_STYLE_EDITOR_PARTS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, resolveDisplayedChartType, CHART_TYPE_OPTIONS, chartDataLabelsTogglePatch, BAR3D_SHAPE_OPTIONS, bar3DShapePatch, RADAR_STYLE_OPTIONS, radarStylePatch, SURFACE_WIREFRAME_OPTIONS, surfaceWireframePatch, isSeriesUsingSecondaryAxis, seriesColorClearState, listChartUserShapeRows, withChartUserShapeAdded, createDefaultChartUserShape, withChartUserShapeRowRemoved, withChartUserShapeRowTextUpdated, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, addSiblingAfter, removeEmptyNode, demote, promote, reorder, cropResetState, cropResetPatch, ARTISTIC_EFFECTS, mediaTrimEndSeconds, trimmedMediaDurationMs, mediaTrimEndAbsoluteMs, mediaTrimResetState, mediaTrimEndMsFromAbsoluteMs, mediaTrimResetPatch, buildOleEditDialogDescriptor, buildOleContentUpdatePatch, buildThemeColorSwatchGrid, themeColorSwatchRows, findSelectedThemeSwatch, themeSwatchCommit, getNonVisualDescriptionFields, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, canCommitActionType, slideSizeFromPreset, withSlideSizeOrientation, TRANSITION_DIR_ARROWS, buildDirectionGrid, updateTagInCollections, deleteTagFromCollections, addTagToCollections, commentTextSegments, COMMENT_MENTION_CLASS, COMMENT_MENTION_ATTRIBUTE, insertCommentMention, reorderAnimationTimelineRows, applyAnimationTimelineOrder, getEffectSoundAsset, animationEffectLabel, overlayPointerInput, TABLE_STYLE_BORDER_SIDES, applyTableStyleFieldEdit, withCellStyle, LBL as LBL$1, SEL as SEL$1, FILL_MODE_OPTIONS as FILL_MODE_OPTIONS$1, SECTION_HEADING, NUM as NUM$1, getChartUserShapeGroupTransform, withChartUserShapeGroupChildAdded, createDefaultChartUserShapeGroupChild, withChartUserShapeRowUpdated, getChartUserShapeRowChartBox, withChartUserShapeRowFlipUpdated, withChartUserShapeRowRotationUpdated, withChartUserShapeRowChartBoxUpdated, smartArtLayoutSwitchPatch, rebuildDrawingShapesIfCleared, mediaTrimEndMsFromSeconds, validateMediaTrimRange, quickStyleSwatchCss, shapeQuickStyleLabel, OFFICE_COLOR_SWATCHES, officeColorSwatchLabel, PATTERN_PRESET_OPTIONS as PATTERN_PRESET_OPTIONS$1, COMPOUND_LINE_OPTIONS as COMPOUND_LINE_OPTIONS$1, LINE_JOIN_OPTIONS as LINE_JOIN_OPTIONS$1, LINE_CAP_OPTIONS as LINE_CAP_OPTIONS$1, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, toSlideIndex, TABLE_STYLE_BORDER_SIDE_LABEL_KEYS, TABLE_STYLE_DASH_PRESETS, GRADIENT_TYPE_OPTIONS as GRADIENT_TYPE_OPTIONS$1, PATTERN_OPTIONS, FILL_PATTERN_LABEL_KEYS, toggleText3dExtrusion, BEVEL_PRESETS, cropFit, cropFill, cropToAspectRatio } from 'ooxml-ui/pptx';
4
4
  export { THEME_CATALOG, defaultCssVars, defaultRadius, defaultThemeColors, resolveThemeCatalogEntry, themeToCssVars, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius } from 'ooxml-ui/pptx';
5
- import React103, { createContext, lazy, forwardRef, useEffect, useState, useCallback, useMemo, useRef, useLayoutEffect, useSyncExternalStore, useId, useContext, useDeferredValue, Suspense, useReducer, Fragment as Fragment$1 } from 'react';
5
+ import React104, { createContext, lazy, forwardRef, useEffect, useState, useCallback, useMemo, useRef, useLayoutEffect, useSyncExternalStore, useId, useContext, useDeferredValue, Suspense, useReducer, Fragment as Fragment$1 } from 'react';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
  import { useTranslation } from 'react-i18next';
8
- import { LuArrowDown, LuArrowUp, LuArrowRight, LuArrowLeft, LuArrowDownRight, LuArrowDownLeft, LuArrowUpRight, LuArrowUpLeft, LuMessageSquare, LuEyeOff, LuHistory, LuSettings, LuX, LuCalendarDays, LuClock, LuHash, LuFileText, LuText, LuCast, LuShieldCheck, LuPlus, LuPanelLeftClose, LuDownload, LuTrash2, LuCheck, LuLock, LuEye, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuBug, LuChevronUp, LuChevronDown, LuUpload, LuWifi, LuWifiOff, LuUsers, LuCopy, LuMinus, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuPanelLeft, LuPanelRight, LuSparkles, LuFolderOpen, LuPalette, LuSearch, LuCaseSensitive, LuReplace, LuGripVertical, LuLoaderCircle, LuGrid2X2, LuStickyNote, LuList, LuClipboardCopy, LuPaintbrush, LuShapes, LuLayoutGrid, LuWand, LuPresentation, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuShare2, LuSave, LuFilePlus2, LuHouse, LuFileJson, LuBox, LuVideo, LuFileImage, LuDatabase, LuClock3, LuUser, LuHardDrive, LuLogIn, LuMove, LuCopyPlus, LuClipboardPaste, LuMonitor, LuRadio, LuCaptions, LuImage, LuFilter, LuLayers, LuSettings2, LuLockOpen, LuPencil, LuReply, LuMoveRight, LuRotateCw, LuScissors, LuBookmark, LuPipette } from 'react-icons/lu';
8
+ import { LuArrowDown, LuArrowUp, LuArrowRight, LuArrowLeft, LuArrowDownRight, LuArrowDownLeft, LuArrowUpRight, LuArrowUpLeft, LuMessageSquare, LuEyeOff, LuHistory, LuX, LuCalendarDays, LuClock, LuHash, LuFileText, LuText, LuCast, LuShieldCheck, LuPlus, LuPanelLeftClose, LuDownload, LuTrash2, LuCheck, LuLock, LuEye, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuWifi, LuWifiOff, LuUsers, LuCopy, LuMinus, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuPanelLeft, LuPanelRight, LuSparkles, LuSettings, LuFolderOpen, LuPalette, LuSearch, LuCaseSensitive, LuChevronUp, LuChevronDown, LuReplace, LuGripVertical, LuLoaderCircle, LuUpload, LuGrid2X2, LuStickyNote, LuList, LuBug, LuClipboardCopy, LuPaintbrush, LuShapes, LuLayoutGrid, LuWand, LuPresentation, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuShare2, LuSave, LuFilePlus2, LuHouse, LuFileJson, LuBox, LuVideo, LuFileImage, LuDatabase, LuClock3, LuUser, LuHardDrive, LuLogIn, LuMove, LuCopyPlus, LuClipboardPaste, LuMonitor, LuRadio, LuCaptions, LuImage, LuFilter, LuLayers, LuSettings2, LuLockOpen, LuPencil, LuReply, LuMoveRight, LuRotateCw, LuScissors, LuBookmark, LuPipette } from 'react-icons/lu';
9
9
  import { createPortal } from 'react-dom';
10
10
  import { LOCALE_CATALOG } from 'ooxml-ui/pptx/i18n';
11
11
  import { computeFocusTargets, deckDataFieldChanged, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, collectStoredChats, exportAiChatLogs as exportAiChatLogs$1, applyElementUpdate } from 'ooxml-ui/pptx/ai';
@@ -489,57 +489,11 @@ function SlideTemplateGalleryDialog({
489
489
  )
490
490
  ] });
491
491
  }
492
- function AnimationsSection(p) {
493
- const { t } = useTranslation();
494
- const ref = useRef(null);
495
- const [previewActive, setPreviewActive] = useState(false);
496
- const timer = useRef(void 0);
497
- const disabled = !p.canEdit || p.selectedElement === null;
498
- const selectedAnimation = useMemo(
499
- () => p.selectedElement ? (p.activeSlide?.animations ?? []).find((a) => a.elementId === p.selectedElement?.id) : void 0,
500
- [p.activeSlide?.animations, p.selectedElement]
501
- );
502
- useEffect(() => () => clearTimeout(timer.current), []);
503
- useEffect(() => {
504
- const host = ref.current;
505
- if (!host) {
506
- return;
507
- }
508
- host.state = {
509
- editable: p.canEdit,
510
- hasSelection: p.selectedElement !== null,
511
- paneOpen: p.isInspectorPaneOpen,
512
- previewActive,
513
- translate: t
514
- };
515
- }, [p.canEdit, p.selectedElement, p.isInspectorPaneOpen, previewActive, t]);
516
- useEffect(() => {
517
- const host = ref.current;
518
- if (!host) {
519
- return;
520
- }
521
- const request = (event) => {
522
- const intent = event.detail;
523
- if (intent.kind === "add") {
524
- p.onAddAnimation?.(intent.preset, intent.group);
525
- } else if (intent.value === "remove") {
526
- p.onRemoveAnimation?.();
527
- } else if (intent.value === "preview") {
528
- if (disabled) {
529
- return;
530
- }
531
- setPreviewActive(true);
532
- clearTimeout(timer.current);
533
- timer.current = setTimeout(() => setPreviewActive(false), 1200);
534
- playAnimationRibbonPreview(document, selectedAnimation);
535
- } else {
536
- (p.onOpenAnimationPanel ?? p.onToggleInspector)();
537
- }
538
- };
539
- host.addEventListener("animations-request", request);
540
- return () => host.removeEventListener("animations-request", request);
541
- }, [p, disabled, selectedAnimation]);
542
- return /* @__PURE__ */ jsx("pptx-ui-ribbon-animations", { ref });
492
+ var ViewerCustomizationContext = createContext(
493
+ EMPTY_RESOLVED_CUSTOMIZATION
494
+ );
495
+ function useViewerCustomizationContext() {
496
+ return useContext(ViewerCustomizationContext);
543
497
  }
544
498
  function useHostEvent(ref, type, handler) {
545
499
  useEffect(() => {
@@ -657,6 +611,412 @@ function WebRadio({
657
611
  }
658
612
  );
659
613
  }
614
+ function nowLocalInputValue() {
615
+ const now = /* @__PURE__ */ new Date();
616
+ const pad = (n) => String(n).padStart(2, "0");
617
+ return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`;
618
+ }
619
+ function DateTimeFieldDialog(p) {
620
+ const { t } = useTranslation();
621
+ const [datePickerValue, setDatePickerValue] = useState(nowLocalInputValue);
622
+ const [dateFormat, setDateFormat] = useState("locale");
623
+ const confirmDatePicker = useCallback(() => {
624
+ const d = new Date(datePickerValue);
625
+ if (isNaN(d.getTime())) {
626
+ return;
627
+ }
628
+ let formatted;
629
+ switch (dateFormat) {
630
+ case "iso":
631
+ formatted = d.toISOString().slice(0, 10);
632
+ break;
633
+ case "long":
634
+ formatted = d.toLocaleDateString(void 0, {
635
+ weekday: "long",
636
+ year: "numeric",
637
+ month: "long",
638
+ day: "numeric"
639
+ });
640
+ break;
641
+ case "short":
642
+ formatted = d.toLocaleDateString(void 0, {
643
+ year: "numeric",
644
+ month: "short",
645
+ day: "numeric"
646
+ });
647
+ break;
648
+ case "time":
649
+ formatted = d.toLocaleString();
650
+ break;
651
+ default:
652
+ formatted = d.toLocaleDateString();
653
+ break;
654
+ }
655
+ p.onInsert(formatted);
656
+ }, [datePickerValue, dateFormat, p]);
657
+ return /* @__PURE__ */ jsx(
658
+ "div",
659
+ {
660
+ className: "fixed inset-0 z-[9999] flex items-center justify-center bg-black/30",
661
+ onMouseDown: (e) => {
662
+ if (e.target === e.currentTarget) {
663
+ p.onClose();
664
+ }
665
+ },
666
+ children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-popover shadow-2xl p-4 w-72 space-y-3", children: [
667
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-foreground", children: t("pptx.field.dateTime") }),
668
+ /* @__PURE__ */ jsx(
669
+ "input",
670
+ {
671
+ type: "datetime-local",
672
+ className: "w-full text-xs",
673
+ "aria-label": t("pptx.field.format", "Format"),
674
+ value: datePickerValue,
675
+ onChange: (e) => setDatePickerValue(e.target.value)
676
+ }
677
+ ),
678
+ /* @__PURE__ */ jsxs("div", { children: [
679
+ /* @__PURE__ */ jsx("label", { className: "block text-[11px] text-muted-foreground mb-1", children: t("pptx.field.format", "Format") }),
680
+ /* @__PURE__ */ jsxs(
681
+ WebSelect,
682
+ {
683
+ className: "w-full rounded border border-border bg-muted px-2.5 py-1.5 text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary outline-none",
684
+ value: dateFormat,
685
+ onChange: (e) => setDateFormat(e.target.value),
686
+ children: [
687
+ /* @__PURE__ */ jsx("option", { value: "locale", children: new Date(datePickerValue || Date.now()).toLocaleDateString() }),
688
+ /* @__PURE__ */ jsx("option", { value: "long", children: new Date(datePickerValue || Date.now()).toLocaleDateString(void 0, {
689
+ weekday: "long",
690
+ year: "numeric",
691
+ month: "long",
692
+ day: "numeric"
693
+ }) }),
694
+ /* @__PURE__ */ jsx("option", { value: "short", children: new Date(datePickerValue || Date.now()).toLocaleDateString(void 0, {
695
+ year: "numeric",
696
+ month: "short",
697
+ day: "numeric"
698
+ }) }),
699
+ /* @__PURE__ */ jsx("option", { value: "iso", children: new Date(datePickerValue || Date.now()).toISOString().slice(0, 10) }),
700
+ /* @__PURE__ */ jsx("option", { value: "time", children: new Date(datePickerValue || Date.now()).toLocaleString() })
701
+ ]
702
+ }
703
+ )
704
+ ] }),
705
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 pt-1", children: /* @__PURE__ */ jsx(
706
+ DialogFooter,
707
+ {
708
+ actions: [
709
+ { id: "cancel", label: t("pptx.common.cancel", "Cancel") },
710
+ { id: "insert", label: t("pptx.common.insert", "Insert"), variant: "primary" }
711
+ ],
712
+ onAction: (id) => id === "insert" ? confirmDatePicker() : p.onClose()
713
+ }
714
+ ) })
715
+ ] })
716
+ }
717
+ );
718
+ }
719
+ function InsertSection(p) {
720
+ const { t } = useTranslation();
721
+ const customization = useViewerCustomizationContext();
722
+ const ref = useRef(null);
723
+ const [datePickerOpen, setDatePickerOpen] = useState(false);
724
+ const [templatesOpen, setTemplatesOpen] = useState(false);
725
+ const templatesAvailable = Boolean(p.onInsertSlideFromTemplate) && isDialogAvailable(customization, "slideTemplates");
726
+ const [chartKind, setChartKind] = useState(DEFAULT_INSERT_CHART_KIND);
727
+ useEffect(() => {
728
+ const host = ref.current;
729
+ if (!host) {
730
+ return;
731
+ }
732
+ host.state = {
733
+ editable: p.canEdit,
734
+ hasSelection: p.hasSelection,
735
+ shapeType: p.newShapeType,
736
+ chartKind,
737
+ activeFreeformTool: p.activeFreeformTool ?? null,
738
+ freeformTools: p.onArmFreeformTool ? FREEFORM_TOOL_IDS.filter((tool) => isDrawingToolVisible(customization, tool)) : [],
739
+ chartAvailable: Boolean(p.onAddChart),
740
+ fieldAvailable: Boolean(p.onInsertField),
741
+ headerFooterAvailable: Boolean(p.onOpenHeaderFooter),
742
+ newSlideAvailable: Boolean(p.onInsertSlideFromLayout && p.layoutOptions?.length),
743
+ commentAvailable: Boolean(p.onToggleComments),
744
+ slideTemplatesAvailable: templatesAvailable,
745
+ layouts: p.layoutOptions ?? [],
746
+ ...p.currentLayoutPath ? { currentLayoutPath: p.currentLayoutPath } : {},
747
+ translate: t
748
+ };
749
+ }, [p, chartKind, customization, t, templatesAvailable]);
750
+ useEffect(() => {
751
+ const host = ref.current;
752
+ if (!host) {
753
+ return;
754
+ }
755
+ const request = (event) => {
756
+ const intent = event.detail;
757
+ switch (intent.kind) {
758
+ case "command": {
759
+ const commands = {
760
+ textBox: p.onAddTextBox,
761
+ table: p.onAddTable,
762
+ image: p.onOpenImagePicker,
763
+ media: p.onOpenMediaPicker,
764
+ smartArt: p.onAddSmartArt,
765
+ equation: p.onAddEquation,
766
+ link: p.onOpenHyperlinkDialog,
767
+ headerFooter: p.onOpenHeaderFooter,
768
+ // Opening an already open pane would toggle it shut.
769
+ comment: p.isCommentsPanelOpen ? void 0 : p.onToggleComments
770
+ };
771
+ commands[intent.value]?.();
772
+ break;
773
+ }
774
+ case "table":
775
+ p.onAddTable(intent.rows, intent.columns);
776
+ break;
777
+ case "newSlide": {
778
+ const layout = resolveInsertSlideLayout(
779
+ p.layoutOptions ?? [],
780
+ intent.value,
781
+ p.currentLayoutPath
782
+ );
783
+ if (layout) {
784
+ p.onInsertSlideFromLayout?.(layout.path, layout.name);
785
+ }
786
+ break;
787
+ }
788
+ case "slideTemplates":
789
+ setTemplatesOpen(true);
790
+ break;
791
+ case "shapeType":
792
+ p.onSetNewShapeType(intent.value);
793
+ break;
794
+ case "shape":
795
+ p.onAddShape();
796
+ break;
797
+ case "chartType":
798
+ setChartKind(intent.value);
799
+ break;
800
+ case "chart":
801
+ p.onAddChart?.(intent.value);
802
+ break;
803
+ case "freeform":
804
+ p.onArmFreeformTool?.(intent.value);
805
+ break;
806
+ case "actionButton":
807
+ p.onAddActionButton(intent.value);
808
+ break;
809
+ case "field":
810
+ if (intent.value === "datetime") {
811
+ setDatePickerOpen(true);
812
+ } else {
813
+ p.onInsertField?.(intent.value);
814
+ }
815
+ }
816
+ p.onRequestHandled?.();
817
+ };
818
+ host.addEventListener("insert-request", request);
819
+ return () => host.removeEventListener("insert-request", request);
820
+ }, [p]);
821
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
822
+ p.phone ? /* @__PURE__ */ jsx("pptx-ui-mobile-insert", { ref }) : /* @__PURE__ */ jsx("pptx-ui-ribbon-insert", { ref }),
823
+ templatesAvailable && /* @__PURE__ */ jsx(
824
+ SlideTemplateGalleryDialog,
825
+ {
826
+ isOpen: templatesOpen,
827
+ onClose: () => setTemplatesOpen(false),
828
+ onInsert: (templateId) => p.onInsertSlideFromTemplate?.(templateId),
829
+ scheme: p.templateScheme
830
+ }
831
+ ),
832
+ datePickerOpen && p.onInsertField && /* @__PURE__ */ jsx(
833
+ DateTimeFieldDialog,
834
+ {
835
+ onClose: () => setDatePickerOpen(false),
836
+ onInsert: (formatted) => {
837
+ p.onInsertField?.("datetime", formatted);
838
+ setDatePickerOpen(false);
839
+ }
840
+ }
841
+ )
842
+ ] });
843
+ }
844
+ function MobileSheet({
845
+ open,
846
+ onClose,
847
+ title,
848
+ children,
849
+ heightFraction = 0.6,
850
+ fullScreen = false,
851
+ autoHeight = false,
852
+ className,
853
+ headerRight
854
+ }) {
855
+ const sheetRef = useRef(null);
856
+ const { t } = useTranslation();
857
+ const { dragY, dragging, handlers } = useSheetDismissDrag(onClose);
858
+ useModalFocus(open, sheetRef, onClose);
859
+ if (!open) {
860
+ return null;
861
+ }
862
+ const heightStyle = autoHeight ? { maxHeight: "calc(85dvh - env(safe-area-inset-top))" } : fullScreen ? { height: "calc(100dvh - env(safe-area-inset-top))" } : { height: `${Math.round(heightFraction * 100)}dvh` };
863
+ return /* @__PURE__ */ jsxs("div", { className: "fixed inset-x-0 top-0 bottom-14 z-[69] flex flex-col justify-end", children: [
864
+ /* @__PURE__ */ jsx(
865
+ "button",
866
+ {
867
+ type: "button",
868
+ "aria-label": t("pptx.mobileSheet.close"),
869
+ className: "absolute inset-0 bg-black/40 backdrop-blur-[2px] animate-in fade-in duration-150",
870
+ onClick: onClose
871
+ }
872
+ ),
873
+ /* @__PURE__ */ jsxs(
874
+ "div",
875
+ {
876
+ ref: sheetRef,
877
+ role: "dialog",
878
+ "aria-modal": "true",
879
+ "aria-label": typeof title === "string" ? title : t("pptx.mobileSheet.ariaLabel"),
880
+ tabIndex: -1,
881
+ className: cn(
882
+ "relative bg-background border-t border-border rounded-t-2xl shadow-2xl flex flex-col overflow-hidden",
883
+ "animate-in slide-in-from-bottom duration-200",
884
+ className
885
+ ),
886
+ style: {
887
+ ...heightStyle,
888
+ transform: dragY > 0 ? `translateY(${dragY}px)` : void 0,
889
+ transition: dragging ? "none" : "transform 150ms ease-out"
890
+ },
891
+ children: [
892
+ /* @__PURE__ */ jsxs(
893
+ "div",
894
+ {
895
+ className: "cursor-grab active:cursor-grabbing touch-none",
896
+ onPointerDown: handlers.onPointerDown,
897
+ onPointerMove: handlers.onPointerMove,
898
+ onPointerUp: handlers.onPointerUp,
899
+ onPointerCancel: handlers.onPointerCancel,
900
+ children: [
901
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center pt-2 pb-1", children: /* @__PURE__ */ jsx("div", { className: "h-1 w-10 rounded-full bg-muted-foreground/40" }) }),
902
+ (title || headerRight) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-4 pb-2 border-b border-border/60", children: [
903
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-foreground truncate", children: title }),
904
+ headerRight,
905
+ /* @__PURE__ */ jsx(
906
+ "button",
907
+ {
908
+ type: "button",
909
+ "aria-label": t("pptx.mobileSheet.close"),
910
+ onPointerDown: (event) => event.stopPropagation(),
911
+ onClick: onClose,
912
+ style: { minWidth: MIN_TOUCH_TARGET_PX, minHeight: MIN_TOUCH_TARGET_PX },
913
+ className: "inline-flex items-center justify-center rounded text-xl text-muted-foreground hover:bg-accent hover:text-foreground",
914
+ children: "\xD7"
915
+ }
916
+ )
917
+ ] })
918
+ ]
919
+ }
920
+ ),
921
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto overscroll-contain", children })
922
+ ]
923
+ }
924
+ )
925
+ ] });
926
+ }
927
+ function MobileInsertSheet(p) {
928
+ const { t } = useTranslation();
929
+ const close = () => p.onCloseMobileInsert?.();
930
+ return /* @__PURE__ */ jsx(
931
+ MobileSheet,
932
+ {
933
+ open: Boolean(p.isMobileInsertOpen) && !p.isThemeEditorOpen,
934
+ onClose: close,
935
+ autoHeight: true,
936
+ title: t("pptx.mobileBar.insert"),
937
+ children: /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx(
938
+ InsertSection,
939
+ {
940
+ phone: true,
941
+ onRequestHandled: close,
942
+ canEdit: p.canEdit,
943
+ newShapeType: p.newShapeType,
944
+ onSetNewShapeType: p.onSetNewShapeType,
945
+ onAddTextBox: p.onAddTextBox,
946
+ onAddShape: p.onAddShape,
947
+ onAddTable: p.onAddTable,
948
+ onAddChart: p.onAddChart,
949
+ onAddSmartArt: p.onAddSmartArt,
950
+ onAddEquation: p.onAddEquation,
951
+ onAddActionButton: p.onAddActionButton,
952
+ onInsertField: p.onInsertField,
953
+ onOpenHeaderFooter: p.onOpenHeaderFooter,
954
+ onOpenImagePicker: p.onOpenImagePicker,
955
+ onOpenMediaPicker: p.onOpenMediaPicker,
956
+ hasSelection: Boolean(p.selectedElement),
957
+ onOpenHyperlinkDialog: p.onOpenHyperlinkDialog,
958
+ layoutOptions: p.layoutOptions,
959
+ currentLayoutPath: p.currentLayoutPath,
960
+ onInsertSlideFromLayout: p.onInsertSlideFromLayout,
961
+ onToggleComments: p.onToggleComments,
962
+ isCommentsPanelOpen: p.isCommentsPanelOpen
963
+ }
964
+ ) })
965
+ }
966
+ );
967
+ }
968
+ function AnimationsSection(p) {
969
+ const { t } = useTranslation();
970
+ const ref = useRef(null);
971
+ const [previewActive, setPreviewActive] = useState(false);
972
+ const timer = useRef(void 0);
973
+ const disabled = !p.canEdit || p.selectedElement === null;
974
+ const selectedAnimation = useMemo(
975
+ () => p.selectedElement ? (p.activeSlide?.animations ?? []).find((a) => a.elementId === p.selectedElement?.id) : void 0,
976
+ [p.activeSlide?.animations, p.selectedElement]
977
+ );
978
+ useEffect(() => () => clearTimeout(timer.current), []);
979
+ useEffect(() => {
980
+ const host = ref.current;
981
+ if (!host) {
982
+ return;
983
+ }
984
+ host.state = {
985
+ editable: p.canEdit,
986
+ hasSelection: p.selectedElement !== null,
987
+ paneOpen: p.isInspectorPaneOpen,
988
+ previewActive,
989
+ translate: t
990
+ };
991
+ }, [p.canEdit, p.selectedElement, p.isInspectorPaneOpen, previewActive, t]);
992
+ useEffect(() => {
993
+ const host = ref.current;
994
+ if (!host) {
995
+ return;
996
+ }
997
+ const request = (event) => {
998
+ const intent = event.detail;
999
+ if (intent.kind === "add") {
1000
+ p.onAddAnimation?.(intent.preset, intent.group);
1001
+ } else if (intent.value === "remove") {
1002
+ p.onRemoveAnimation?.();
1003
+ } else if (intent.value === "preview") {
1004
+ if (disabled) {
1005
+ return;
1006
+ }
1007
+ setPreviewActive(true);
1008
+ clearTimeout(timer.current);
1009
+ timer.current = setTimeout(() => setPreviewActive(false), 1200);
1010
+ playAnimationRibbonPreview(document, selectedAnimation);
1011
+ } else {
1012
+ (p.onOpenAnimationPanel ?? p.onToggleInspector)();
1013
+ }
1014
+ };
1015
+ host.addEventListener("animations-request", request);
1016
+ return () => host.removeEventListener("animations-request", request);
1017
+ }, [p, disabled, selectedAnimation]);
1018
+ return /* @__PURE__ */ jsx("pptx-ui-ribbon-animations", { ref });
1019
+ }
660
1020
  function groupAttr(id) {
661
1021
  return id ? { [RIBBON_GROUP_ATTR]: id } : {};
662
1022
  }
@@ -723,7 +1083,7 @@ function WebHomeControls({
723
1083
  host.addEventListener("home-popup", listener);
724
1084
  return () => host.removeEventListener("home-popup", listener);
725
1085
  }, [onPopup]);
726
- return React103.createElement(`pptx-ui-ribbon-home-${family}`, { ref });
1086
+ return React104.createElement(`pptx-ui-ribbon-home-${family}`, { ref });
727
1087
  }
728
1088
  function ShapeArrangeExtras(p) {
729
1089
  const commands = useShapeFormatContext();
@@ -1086,6 +1446,16 @@ function DesignSection(p) {
1086
1446
  hasBackground: Boolean(p.onToggleInspector)
1087
1447
  };
1088
1448
  return /* @__PURE__ */ jsx(Fragment, { children: DESIGN_RIBBON_GROUPS.map((group) => /* @__PURE__ */ jsxs(WebRibbonGroup, { groupId: group.id, label: t(group.labelKey), children: [
1449
+ FIXED_TAB_GALLERIES.filter(
1450
+ (placement) => placement.control.startsWith(`${group.id}.`)
1451
+ ).map((placement) => /* @__PURE__ */ jsx(
1452
+ RibbonGallery,
1453
+ {
1454
+ placement,
1455
+ icon: placement.gallery === "themeFonts" ? /* @__PURE__ */ jsx(LuType, {}) : /* @__PURE__ */ jsx(LuPalette, {})
1456
+ },
1457
+ placement.control
1458
+ )),
1089
1459
  DESIGN_RIBBON_COMMANDS.filter((command) => command.id.startsWith(`${group.id}.`)).map(
1090
1460
  (command) => {
1091
1461
  const view = designCommandState(command.id, state);
@@ -1104,17 +1474,7 @@ function DesignSection(p) {
1104
1474
  command.id
1105
1475
  );
1106
1476
  }
1107
- ),
1108
- FIXED_TAB_GALLERIES.filter(
1109
- (placement) => placement.control.startsWith(`${group.id}.`)
1110
- ).map((placement) => /* @__PURE__ */ jsx(
1111
- RibbonGallery,
1112
- {
1113
- placement,
1114
- icon: placement.gallery === "themeFonts" ? /* @__PURE__ */ jsx(LuType, {}) : /* @__PURE__ */ jsx(LuPalette, {})
1115
- },
1116
- placement.control
1117
- ))
1477
+ )
1118
1478
  ] }, group.id)) });
1119
1479
  }
1120
1480
  var DEFAULT_VALUE = {
@@ -1174,11 +1534,43 @@ function DrawSection(p) {
1174
1534
  }, [p, pushColor]);
1175
1535
  return /* @__PURE__ */ jsx("pptx-ui-ribbon-draw", { ref });
1176
1536
  }
1177
- var ViewerCustomizationContext = createContext(
1178
- EMPTY_RESOLVED_CUSTOMIZATION
1179
- );
1180
- function useViewerCustomizationContext() {
1181
- return useContext(ViewerCustomizationContext);
1537
+ var ViewerRegionBaseContext = createContext(null);
1538
+ function useRegionRenderer(id) {
1539
+ const customization = useViewerCustomizationContext();
1540
+ const base = useContext(ViewerRegionBaseContext);
1541
+ return base ? getRegionRenderer(customization, id) : void 0;
1542
+ }
1543
+ var FILL = { width: "100%", height: "100%" };
1544
+ var NOOP = () => {
1545
+ };
1546
+ function ViewerRegion(props) {
1547
+ const { region, renderer, close = NOOP, extra, className, style } = props;
1548
+ const base = useContext(ViewerRegionBaseContext);
1549
+ const containerRef = useRef(null);
1550
+ const hostRef = useRef(null);
1551
+ useLayoutEffect(() => {
1552
+ const host = new ViewerRegionHost(containerRef.current);
1553
+ hostRef.current = host;
1554
+ return () => {
1555
+ host.destroy();
1556
+ hostRef.current = null;
1557
+ };
1558
+ }, []);
1559
+ useLayoutEffect(() => {
1560
+ if (!base) {
1561
+ return;
1562
+ }
1563
+ const context = { ...base, ...extra, region, close };
1564
+ hostRef.current?.render(renderer, context);
1565
+ });
1566
+ return /* @__PURE__ */ jsx(
1567
+ "div",
1568
+ {
1569
+ ref: containerRef,
1570
+ className: className ? `pptx-region-host ${className}` : "pptx-region-host",
1571
+ style: style ?? FILL
1572
+ }
1573
+ );
1182
1574
  }
1183
1575
  var AccountAuthContext = createContext(void 0);
1184
1576
  var cardClass = "border border-border bg-card p-6 text-card-foreground";
@@ -1210,7 +1602,7 @@ function AccountPage() {
1210
1602
  return void 0;
1211
1603
  });
1212
1604
  };
1213
- const version = "4.37.0" ;
1605
+ const version = "4.39.0" ;
1214
1606
  return /* @__PURE__ */ jsxs("div", { className: "mt-8 max-w-[700px] space-y-6", children: [
1215
1607
  /* @__PURE__ */ jsxs("section", { className: cardClass, children: [
1216
1608
  /* @__PURE__ */ jsxs("h2", { className: "flex items-center gap-2 text-sm font-semibold", children: [
@@ -1468,7 +1860,8 @@ function BackstageNavIcon({ page }) {
1468
1860
  function FileSection(p) {
1469
1861
  const { t } = useTranslation();
1470
1862
  const [requestedPage, setRequestedPage] = useState("home");
1471
- const nav = customizeBackstageNav(BACKSTAGE_NAV, useViewerCustomizationContext());
1863
+ const customization = useViewerCustomizationContext();
1864
+ const nav = backstageNavEntries(BACKSTAGE_NAV, customization);
1472
1865
  const offered = (id) => nav.some((item) => item.id === id);
1473
1866
  const page = offered(requestedPage) ? requestedPage : offered("home") ? "home" : nav.find((item) => item.id !== "save" && item.id !== "close")?.id ?? "home";
1474
1867
  const [query, setQuery] = useState("");
@@ -1489,7 +1882,12 @@ function FileSection(p) {
1489
1882
  }
1490
1883
  };
1491
1884
  const current = nav.find((item) => item.id === page);
1492
- const title = current ? t(current.labelKey, { defaultValue: current.label }) : t("pptx.backstage.nav.home");
1885
+ const hostPage = current?.host;
1886
+ const builtInPage = hostPage ? void 0 : page;
1887
+ const title = current ? current.labelKey ? t(current.labelKey, { defaultValue: current.label }) : current.label : t("pptx.backstage.nav.home");
1888
+ const regionId = hostPage ? `backstage.host.${hostPage.id}` : `backstage.${page}`;
1889
+ const builtInRegionRenderer = useRegionRenderer(regionId);
1890
+ const regionRenderer = hostPage ? hostPage.render : builtInRegionRenderer;
1493
1891
  return /* @__PURE__ */ jsxs(
1494
1892
  "div",
1495
1893
  {
@@ -1510,7 +1908,7 @@ function FileSection(p) {
1510
1908
  }
1511
1909
  ) }),
1512
1910
  /* @__PURE__ */ jsxs("nav", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto pb-2 max-md:flex-row max-md:items-center max-md:overflow-y-visible max-md:pb-0", children: [
1513
- nav.filter((item) => !item.group && !(item.id === "export" && exportHidden)).map((item) => /* @__PURE__ */ jsxs(
1911
+ nav.filter((item) => item.group !== "footer" && !(item.id === "export" && exportHidden)).map((item) => /* @__PURE__ */ jsxs(
1514
1912
  "button",
1515
1913
  {
1516
1914
  type: "button",
@@ -1519,14 +1917,14 @@ function FileSection(p) {
1519
1917
  onClick: () => item.id === "close" ? p.onClose() : item.id === "save" ? run(p.onSaveAsPptx) : setRequestedPage(item.id),
1520
1918
  className: `${BACKSTAGE_NAV_CLASSES.row} ${page === item.id ? BACKSTAGE_NAV_CLASSES.active : BACKSTAGE_NAV_CLASSES.inactive}`,
1521
1919
  children: [
1522
- /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
1523
- t(item.labelKey, { defaultValue: item.label })
1920
+ !item.host && /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
1921
+ item.labelKey ? t(item.labelKey, { defaultValue: item.label }) : item.label
1524
1922
  ]
1525
1923
  },
1526
1924
  item.id
1527
1925
  )),
1528
1926
  /* @__PURE__ */ jsx("div", { className: "flex-1 max-md:hidden" }),
1529
- nav.filter((item) => item.group).map((item) => /* @__PURE__ */ jsxs(
1927
+ nav.filter((item) => item.group === "footer").map((item) => /* @__PURE__ */ jsxs(
1530
1928
  "button",
1531
1929
  {
1532
1930
  type: "button",
@@ -1535,8 +1933,8 @@ function FileSection(p) {
1535
1933
  onClick: () => item.id === "options" && p.onOpenSettings ? run(p.onOpenSettings) : setRequestedPage(item.id),
1536
1934
  className: `${BACKSTAGE_NAV_CLASSES.row} ${page === item.id ? BACKSTAGE_NAV_CLASSES.active : BACKSTAGE_NAV_CLASSES.inactive}`,
1537
1935
  children: [
1538
- /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
1539
- t(item.labelKey, { defaultValue: item.label })
1936
+ !item.host && /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
1937
+ item.labelKey ? t(item.labelKey, { defaultValue: item.label }) : item.label
1540
1938
  ]
1541
1939
  },
1542
1940
  item.id
@@ -1545,63 +1943,76 @@ function FileSection(p) {
1545
1943
  ] }),
1546
1944
  /* @__PURE__ */ jsxs("main", { className: "min-w-0 flex-1 overflow-y-auto bg-background px-[clamp(32px,4vw,72px)] py-5 max-md:px-4 max-md:py-4", children: [
1547
1945
  /* @__PURE__ */ jsx("h1", { className: "text-[24px] font-semibold", children: page === "home" ? t("pptx.backstage.greeting") : title }),
1548
- (page === "home" || page === "new") && /* @__PURE__ */ jsx(
1549
- BackstageNewGallery,
1550
- {
1551
- onCreate: (templateId) => run(() => p.onCreatePresentation(templateId))
1552
- }
1553
- ),
1554
- (page === "home" || page === "open") && /* @__PURE__ */ jsxs(Fragment, { children: [
1555
- /* @__PURE__ */ jsx(
1556
- WebSearch,
1946
+ regionRenderer ? (
1947
+ // The nav, title and back button stay the viewer's; the host fills the page body.
1948
+ /* @__PURE__ */ jsx("div", { className: "mt-6", children: /* @__PURE__ */ jsx(
1949
+ ViewerRegion,
1557
1950
  {
1558
- "data-pptx-search-surface": true,
1559
- "data-pptx-search-input": true,
1560
- className: "mt-8 w-full max-w-[540px]",
1561
- value: query,
1562
- onInput: (event) => setQuery(event.currentTarget.value),
1563
- placeholder: t("pptx.backstage.searchPlaceholder"),
1564
- "aria-label": t("pptx.backstage.searchPlaceholder")
1951
+ region: regionId,
1952
+ renderer: regionRenderer,
1953
+ close: p.onClose,
1954
+ style: { width: "100%", minHeight: "12rem" }
1565
1955
  }
1566
- ),
1567
- page === "open" && /* @__PURE__ */ jsxs(
1568
- "button",
1956
+ ) })
1957
+ ) : builtInPage ? /* @__PURE__ */ jsxs(Fragment, { children: [
1958
+ (page === "home" || page === "new") && /* @__PURE__ */ jsx(
1959
+ BackstageNewGallery,
1569
1960
  {
1570
- type: "button",
1571
- className: "mt-4 inline-flex items-center gap-2 bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:opacity-90",
1572
- onClick: () => run(p.onOpenFile),
1573
- children: [
1574
- /* @__PURE__ */ jsx(LuFolderOpen, {}),
1575
- " ",
1576
- t("pptx.backstage.browseDevice")
1577
- ]
1961
+ onCreate: (templateId) => run(() => p.onCreatePresentation(templateId))
1578
1962
  }
1579
1963
  ),
1580
- /* @__PURE__ */ jsx("h2", { className: "mt-6 text-[16px] font-semibold", children: t("pptx.backstage.recentHeading") }),
1581
- /* @__PURE__ */ jsx(
1582
- BackstageRecentList,
1583
- {
1584
- files: visibleRecent,
1585
- onOpen: (key) => run(() => p.onOpenRecentFile?.(key))
1586
- }
1587
- )
1588
- ] }),
1589
- !(page === "export" && exportHidden) && /* @__PURE__ */ jsx(BackstageCards, { page, props: p, run }),
1590
- page === "account" && /* @__PURE__ */ jsx(AccountPage, {}),
1591
- page === "options" && /* @__PURE__ */ jsxs("div", { className: "mt-8 max-w-[760px] border border-border bg-card p-7 text-card-foreground", children: [
1592
- /* @__PURE__ */ jsx(LuSettings, { className: "text-3xl text-primary" }),
1593
- /* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold", children: t("pptx.backstage.optionsTitle") }),
1594
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: t("pptx.backstage.optionsBody") }),
1595
- /* @__PURE__ */ jsx(
1596
- "button",
1597
- {
1598
- type: "button",
1599
- className: "mt-6 bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:opacity-90",
1600
- onClick: () => run(p.onOpenSettings),
1601
- children: t("pptx.backstage.openOptions")
1602
- }
1603
- )
1604
- ] }),
1964
+ (page === "home" || page === "open") && /* @__PURE__ */ jsxs(Fragment, { children: [
1965
+ /* @__PURE__ */ jsx(
1966
+ WebSearch,
1967
+ {
1968
+ "data-pptx-search-surface": true,
1969
+ "data-pptx-search-input": true,
1970
+ className: "mt-8 w-full max-w-[540px]",
1971
+ value: query,
1972
+ onInput: (event) => setQuery(event.currentTarget.value),
1973
+ placeholder: t("pptx.backstage.searchPlaceholder"),
1974
+ "aria-label": t("pptx.backstage.searchPlaceholder")
1975
+ }
1976
+ ),
1977
+ page === "open" && /* @__PURE__ */ jsxs(
1978
+ "button",
1979
+ {
1980
+ type: "button",
1981
+ className: "mt-4 inline-flex items-center gap-2 bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:opacity-90",
1982
+ onClick: () => run(p.onOpenFile),
1983
+ children: [
1984
+ /* @__PURE__ */ jsx(LuFolderOpen, {}),
1985
+ " ",
1986
+ t("pptx.backstage.browseDevice")
1987
+ ]
1988
+ }
1989
+ ),
1990
+ /* @__PURE__ */ jsx("h2", { className: "mt-6 text-[16px] font-semibold", children: t("pptx.backstage.recentHeading") }),
1991
+ /* @__PURE__ */ jsx(
1992
+ BackstageRecentList,
1993
+ {
1994
+ files: visibleRecent,
1995
+ onOpen: (key) => run(() => p.onOpenRecentFile?.(key))
1996
+ }
1997
+ )
1998
+ ] }),
1999
+ !(page === "export" && exportHidden) && /* @__PURE__ */ jsx(BackstageCards, { page, props: p, run }),
2000
+ page === "account" && /* @__PURE__ */ jsx(AccountPage, {}),
2001
+ page === "options" && /* @__PURE__ */ jsxs("div", { className: "mt-8 max-w-[760px] border border-border bg-card p-7 text-card-foreground", children: [
2002
+ /* @__PURE__ */ jsx(LuSettings, { className: "text-3xl text-primary" }),
2003
+ /* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold", children: t("pptx.backstage.optionsTitle") }),
2004
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: t("pptx.backstage.optionsBody") }),
2005
+ /* @__PURE__ */ jsx(
2006
+ "button",
2007
+ {
2008
+ type: "button",
2009
+ className: "mt-6 bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:opacity-90",
2010
+ onClick: () => run(p.onOpenSettings),
2011
+ children: t("pptx.backstage.openOptions")
2012
+ }
2013
+ )
2014
+ ] })
2015
+ ] }) : null,
1605
2016
  /* @__PURE__ */ jsxs("p", { className: "mt-12 text-[11px] text-muted-foreground", children: [
1606
2017
  p.fileName || t("pptx.backstage.untitled"),
1607
2018
  " \xB7 ",
@@ -1915,6 +2326,7 @@ var OV = [
1915
2326
  ];
1916
2327
  var nextTile = 0;
1917
2328
  function SlidesGroup(p) {
2329
+ const customization = useViewerCustomizationContext();
1918
2330
  const [templateGalleryOpen, setTemplateGalleryOpen] = useState(false);
1919
2331
  const [galleryOpen, setGalleryOpen] = useState(false);
1920
2332
  const [tiles, setTiles] = useState([]);
@@ -1925,7 +2337,7 @@ function SlidesGroup(p) {
1925
2337
  editable: p.canEdit,
1926
2338
  hasLayouts: layoutOptions.length > 0,
1927
2339
  hasSlides: true,
1928
- showTemplates: Boolean(p.onInsertSlideFromTemplate),
2340
+ showTemplates: Boolean(p.onInsertSlideFromTemplate) && isDialogAvailable(customization, "slideTemplates"),
1929
2341
  newSlideNeedsLayout: true,
1930
2342
  resetNeedsSlide: false,
1931
2343
  layouts: {
@@ -1934,7 +2346,14 @@ function SlidesGroup(p) {
1934
2346
  previews
1935
2347
  }
1936
2348
  }),
1937
- [p.canEdit, layoutOptions, p.onInsertSlideFromTemplate, p.currentLayoutPath, previews]
2349
+ [
2350
+ p.canEdit,
2351
+ layoutOptions,
2352
+ p.onInsertSlideFromTemplate,
2353
+ customization,
2354
+ p.currentLayoutPath,
2355
+ previews
2356
+ ]
1938
2357
  );
1939
2358
  const request = useCallback(
1940
2359
  (id, _part, intent) => {
@@ -2002,7 +2421,7 @@ function SlidesGroup(p) {
2002
2421
  )
2003
2422
  ),
2004
2423
  sep,
2005
- p.onInsertSlideFromTemplate && /* @__PURE__ */ jsx(
2424
+ p.onInsertSlideFromTemplate && isDialogAvailable(customization, "slideTemplates") && /* @__PURE__ */ jsx(
2006
2425
  SlideTemplateGalleryDialog,
2007
2426
  {
2008
2427
  isOpen: templateGalleryOpen,
@@ -2048,200 +2467,6 @@ function HomeSection(p) {
2048
2467
  )
2049
2468
  ] });
2050
2469
  }
2051
- function nowLocalInputValue() {
2052
- const now = /* @__PURE__ */ new Date();
2053
- const pad = (n) => String(n).padStart(2, "0");
2054
- return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`;
2055
- }
2056
- function DateTimeFieldDialog(p) {
2057
- const { t } = useTranslation();
2058
- const [datePickerValue, setDatePickerValue] = useState(nowLocalInputValue);
2059
- const [dateFormat, setDateFormat] = useState("locale");
2060
- const confirmDatePicker = useCallback(() => {
2061
- const d = new Date(datePickerValue);
2062
- if (isNaN(d.getTime())) {
2063
- return;
2064
- }
2065
- let formatted;
2066
- switch (dateFormat) {
2067
- case "iso":
2068
- formatted = d.toISOString().slice(0, 10);
2069
- break;
2070
- case "long":
2071
- formatted = d.toLocaleDateString(void 0, {
2072
- weekday: "long",
2073
- year: "numeric",
2074
- month: "long",
2075
- day: "numeric"
2076
- });
2077
- break;
2078
- case "short":
2079
- formatted = d.toLocaleDateString(void 0, {
2080
- year: "numeric",
2081
- month: "short",
2082
- day: "numeric"
2083
- });
2084
- break;
2085
- case "time":
2086
- formatted = d.toLocaleString();
2087
- break;
2088
- default:
2089
- formatted = d.toLocaleDateString();
2090
- break;
2091
- }
2092
- p.onInsert(formatted);
2093
- }, [datePickerValue, dateFormat, p]);
2094
- return /* @__PURE__ */ jsx(
2095
- "div",
2096
- {
2097
- className: "fixed inset-0 z-[9999] flex items-center justify-center bg-black/30",
2098
- onMouseDown: (e) => {
2099
- if (e.target === e.currentTarget) {
2100
- p.onClose();
2101
- }
2102
- },
2103
- children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-popover shadow-2xl p-4 w-72 space-y-3", children: [
2104
- /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-foreground", children: t("pptx.field.dateTime") }),
2105
- /* @__PURE__ */ jsx(
2106
- "input",
2107
- {
2108
- type: "datetime-local",
2109
- className: "w-full text-xs",
2110
- "aria-label": t("pptx.field.format", "Format"),
2111
- value: datePickerValue,
2112
- onChange: (e) => setDatePickerValue(e.target.value)
2113
- }
2114
- ),
2115
- /* @__PURE__ */ jsxs("div", { children: [
2116
- /* @__PURE__ */ jsx("label", { className: "block text-[11px] text-muted-foreground mb-1", children: t("pptx.field.format", "Format") }),
2117
- /* @__PURE__ */ jsxs(
2118
- WebSelect,
2119
- {
2120
- className: "w-full rounded border border-border bg-muted px-2.5 py-1.5 text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary outline-none",
2121
- value: dateFormat,
2122
- onChange: (e) => setDateFormat(e.target.value),
2123
- children: [
2124
- /* @__PURE__ */ jsx("option", { value: "locale", children: new Date(datePickerValue || Date.now()).toLocaleDateString() }),
2125
- /* @__PURE__ */ jsx("option", { value: "long", children: new Date(datePickerValue || Date.now()).toLocaleDateString(void 0, {
2126
- weekday: "long",
2127
- year: "numeric",
2128
- month: "long",
2129
- day: "numeric"
2130
- }) }),
2131
- /* @__PURE__ */ jsx("option", { value: "short", children: new Date(datePickerValue || Date.now()).toLocaleDateString(void 0, {
2132
- year: "numeric",
2133
- month: "short",
2134
- day: "numeric"
2135
- }) }),
2136
- /* @__PURE__ */ jsx("option", { value: "iso", children: new Date(datePickerValue || Date.now()).toISOString().slice(0, 10) }),
2137
- /* @__PURE__ */ jsx("option", { value: "time", children: new Date(datePickerValue || Date.now()).toLocaleString() })
2138
- ]
2139
- }
2140
- )
2141
- ] }),
2142
- /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 pt-1", children: /* @__PURE__ */ jsx(
2143
- DialogFooter,
2144
- {
2145
- actions: [
2146
- { id: "cancel", label: t("pptx.common.cancel", "Cancel") },
2147
- { id: "insert", label: t("pptx.common.insert", "Insert"), variant: "primary" }
2148
- ],
2149
- onAction: (id) => id === "insert" ? confirmDatePicker() : p.onClose()
2150
- }
2151
- ) })
2152
- ] })
2153
- }
2154
- );
2155
- }
2156
- function InsertSection(p) {
2157
- const { t } = useTranslation();
2158
- const customization = useViewerCustomizationContext();
2159
- const ref = useRef(null);
2160
- const [datePickerOpen, setDatePickerOpen] = useState(false);
2161
- const [chartKind, setChartKind] = useState(DEFAULT_INSERT_CHART_KIND);
2162
- useEffect(() => {
2163
- const host = ref.current;
2164
- if (!host) {
2165
- return;
2166
- }
2167
- host.state = {
2168
- editable: p.canEdit,
2169
- hasSelection: p.hasSelection,
2170
- shapeType: p.newShapeType,
2171
- chartKind,
2172
- activeFreeformTool: p.activeFreeformTool ?? null,
2173
- freeformTools: p.onArmFreeformTool ? FREEFORM_TOOL_IDS.filter((tool) => isDrawingToolVisible(customization, tool)) : [],
2174
- chartAvailable: Boolean(p.onAddChart),
2175
- fieldAvailable: Boolean(p.onInsertField),
2176
- headerFooterAvailable: Boolean(p.onOpenHeaderFooter),
2177
- translate: t
2178
- };
2179
- }, [p, chartKind, customization, t]);
2180
- useEffect(() => {
2181
- const host = ref.current;
2182
- if (!host) {
2183
- return;
2184
- }
2185
- const request = (event) => {
2186
- const intent = event.detail;
2187
- switch (intent.kind) {
2188
- case "command": {
2189
- const commands = {
2190
- textBox: p.onAddTextBox,
2191
- table: p.onAddTable,
2192
- image: p.onOpenImagePicker,
2193
- media: p.onOpenMediaPicker,
2194
- smartArt: p.onAddSmartArt,
2195
- equation: p.onAddEquation,
2196
- link: p.onOpenHyperlinkDialog,
2197
- headerFooter: p.onOpenHeaderFooter
2198
- };
2199
- commands[intent.value]?.();
2200
- break;
2201
- }
2202
- case "shapeType":
2203
- p.onSetNewShapeType(intent.value);
2204
- break;
2205
- case "shape":
2206
- p.onAddShape();
2207
- break;
2208
- case "chartType":
2209
- setChartKind(intent.value);
2210
- break;
2211
- case "chart":
2212
- p.onAddChart?.(intent.value);
2213
- break;
2214
- case "freeform":
2215
- p.onArmFreeformTool?.(intent.value);
2216
- break;
2217
- case "actionButton":
2218
- p.onAddActionButton(intent.value);
2219
- break;
2220
- case "field":
2221
- if (intent.value === "datetime") {
2222
- setDatePickerOpen(true);
2223
- } else {
2224
- p.onInsertField?.(intent.value);
2225
- }
2226
- }
2227
- };
2228
- host.addEventListener("insert-request", request);
2229
- return () => host.removeEventListener("insert-request", request);
2230
- }, [p]);
2231
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2232
- /* @__PURE__ */ jsx("pptx-ui-ribbon-insert", { ref }),
2233
- datePickerOpen && p.onInsertField && /* @__PURE__ */ jsx(
2234
- DateTimeFieldDialog,
2235
- {
2236
- onClose: () => setDatePickerOpen(false),
2237
- onInsert: (formatted) => {
2238
- p.onInsertField?.("datetime", formatted);
2239
- setDatePickerOpen(false);
2240
- }
2241
- }
2242
- )
2243
- ] });
2244
- }
2245
2470
  function WebRibbonSection({
2246
2471
  groups,
2247
2472
  onCommand
@@ -2994,89 +3219,6 @@ function ViewSection(p) {
2994
3219
  }, [p]);
2995
3220
  return /* @__PURE__ */ jsx("pptx-ui-ribbon-view", { ref });
2996
3221
  }
2997
- function MobileSheet({
2998
- open,
2999
- onClose,
3000
- title,
3001
- children,
3002
- heightFraction = 0.6,
3003
- fullScreen = false,
3004
- autoHeight = false,
3005
- className,
3006
- headerRight
3007
- }) {
3008
- const sheetRef = useRef(null);
3009
- const { t } = useTranslation();
3010
- const { dragY, dragging, handlers } = useSheetDismissDrag(onClose);
3011
- useModalFocus(open, sheetRef, onClose);
3012
- if (!open) {
3013
- return null;
3014
- }
3015
- const heightStyle = autoHeight ? { maxHeight: "calc(85dvh - env(safe-area-inset-top))" } : fullScreen ? { height: "calc(100dvh - env(safe-area-inset-top))" } : { height: `${Math.round(heightFraction * 100)}dvh` };
3016
- return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex flex-col justify-end", children: [
3017
- /* @__PURE__ */ jsx(
3018
- "button",
3019
- {
3020
- type: "button",
3021
- "aria-label": t("pptx.mobileSheet.close"),
3022
- className: "absolute inset-0 bg-black/40 backdrop-blur-[2px] animate-in fade-in duration-150",
3023
- onClick: onClose
3024
- }
3025
- ),
3026
- /* @__PURE__ */ jsxs(
3027
- "div",
3028
- {
3029
- ref: sheetRef,
3030
- role: "dialog",
3031
- "aria-modal": "true",
3032
- "aria-label": typeof title === "string" ? title : t("pptx.mobileSheet.ariaLabel"),
3033
- tabIndex: -1,
3034
- className: cn(
3035
- "relative bg-background border-t border-border rounded-t-2xl shadow-2xl flex flex-col overflow-hidden",
3036
- "animate-in slide-in-from-bottom duration-200",
3037
- className
3038
- ),
3039
- style: {
3040
- ...heightStyle,
3041
- transform: dragY > 0 ? `translateY(${dragY}px)` : void 0,
3042
- transition: dragging ? "none" : "transform 150ms ease-out"
3043
- },
3044
- children: [
3045
- /* @__PURE__ */ jsxs(
3046
- "div",
3047
- {
3048
- className: "cursor-grab active:cursor-grabbing touch-none",
3049
- onPointerDown: handlers.onPointerDown,
3050
- onPointerMove: handlers.onPointerMove,
3051
- onPointerUp: handlers.onPointerUp,
3052
- onPointerCancel: handlers.onPointerCancel,
3053
- children: [
3054
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center pt-2 pb-1", children: /* @__PURE__ */ jsx("div", { className: "h-1 w-10 rounded-full bg-muted-foreground/40" }) }),
3055
- (title || headerRight) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-4 pb-2 border-b border-border/60", children: [
3056
- /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-foreground truncate", children: title }),
3057
- headerRight,
3058
- /* @__PURE__ */ jsx(
3059
- "button",
3060
- {
3061
- type: "button",
3062
- "aria-label": t("pptx.mobileSheet.close"),
3063
- onPointerDown: (event) => event.stopPropagation(),
3064
- onClick: onClose,
3065
- style: { minWidth: MIN_TOUCH_TARGET_PX, minHeight: MIN_TOUCH_TARGET_PX },
3066
- className: "inline-flex items-center justify-center rounded text-xl text-muted-foreground hover:bg-accent hover:text-foreground",
3067
- children: "\xD7"
3068
- }
3069
- )
3070
- ] })
3071
- ]
3072
- }
3073
- ),
3074
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto overscroll-contain", children })
3075
- ]
3076
- }
3077
- )
3078
- ] });
3079
- }
3080
3222
  var MENU_ITEMS = [
3081
3223
  { key: "home", label: "pptx.ribbon.tab.home", icon: LuClipboardCopy },
3082
3224
  { key: "insert", label: "pptx.ribbon.tab.insert", icon: LuPlus },
@@ -3155,6 +3297,8 @@ function MobileSectionBody({
3155
3297
  InsertSection,
3156
3298
  {
3157
3299
  canEdit: p.canEdit,
3300
+ onInsertSlideFromTemplate: p.onInsertSlideFromTemplate,
3301
+ templateScheme: p.templateScheme,
3158
3302
  newShapeType: p.newShapeType,
3159
3303
  onSetNewShapeType: p.onSetNewShapeType,
3160
3304
  onAddTextBox: p.onAddTextBox,
@@ -3168,7 +3312,12 @@ function MobileSectionBody({
3168
3312
  onOpenImagePicker: p.onOpenImagePicker,
3169
3313
  onOpenMediaPicker: p.onOpenMediaPicker,
3170
3314
  hasSelection: Boolean(p.selectedElement),
3171
- onOpenHyperlinkDialog: p.onOpenHyperlinkDialog
3315
+ onOpenHyperlinkDialog: p.onOpenHyperlinkDialog,
3316
+ layoutOptions: p.layoutOptions,
3317
+ currentLayoutPath: p.currentLayoutPath,
3318
+ onInsertSlideFromLayout: p.onInsertSlideFromLayout,
3319
+ onToggleComments: p.onToggleComments,
3320
+ isCommentsPanelOpen: p.isCommentsPanelOpen
3172
3321
  }
3173
3322
  ) });
3174
3323
  case "text":
@@ -3418,9 +3567,39 @@ function MobileToolbar(props) {
3418
3567
  );
3419
3568
  return /* @__PURE__ */ jsxs("div", { className: "relative z-20", children: [
3420
3569
  /* @__PURE__ */ jsx("pptx-ui-mobile-toolbar", { ref }),
3421
- /* @__PURE__ */ jsx(MobileMenuSheet, { open: menuOpen, onClose: () => setMenuOpen(false), ...props })
3570
+ /* @__PURE__ */ jsx(MobileMenuSheet, { open: menuOpen, onClose: () => setMenuOpen(false), ...props }),
3571
+ /* @__PURE__ */ jsx(MobileInsertSheet, { ...props })
3422
3572
  ] });
3423
3573
  }
3574
+ function ChartSelectionStrip() {
3575
+ const { t } = useTranslation();
3576
+ const commands = useChartFormatContext();
3577
+ const chart = commands?.chart;
3578
+ const chartData = chart?.type === "chart" ? chart.chartData : void 0;
3579
+ const controls = useMemo(
3580
+ () => chartSelectionHomeControls({
3581
+ chartData,
3582
+ targetKey: commands?.target,
3583
+ editable: Boolean(commands?.editable),
3584
+ translate: t
3585
+ }),
3586
+ [chartData, commands?.target, commands?.editable, t]
3587
+ );
3588
+ const request = useCallback(
3589
+ (_id, _part, intent) => {
3590
+ if (!commands || !intent) {
3591
+ return;
3592
+ }
3593
+ dispatchChartSelectionRequest(intent, {
3594
+ select: commands.setTarget,
3595
+ formatSelection: () => commands.openPane(),
3596
+ reset: commands.reset
3597
+ });
3598
+ },
3599
+ [commands]
3600
+ );
3601
+ return /* @__PURE__ */ jsx(WebHomeControls, { family: "chart-selection", controls, onRequest: request });
3602
+ }
3424
3603
  function PictureSizeStrip({
3425
3604
  hiddenActions
3426
3605
  }) {
@@ -3457,7 +3636,8 @@ function ContextualTabSection({
3457
3636
  label: translateOr(group.labelKey, group.label),
3458
3637
  children: [
3459
3638
  group.galleries.map((placement) => /* @__PURE__ */ jsx(RibbonGallery, { placement }, placement.control)),
3460
- group.strip === "picture-size" && /* @__PURE__ */ jsx(PictureSizeStrip, { hiddenActions })
3639
+ group.strip === "picture-size" && /* @__PURE__ */ jsx(PictureSizeStrip, { hiddenActions }),
3640
+ group.strip === "chart-selection" && /* @__PURE__ */ jsx(ChartSelectionStrip, {})
3461
3641
  ]
3462
3642
  },
3463
3643
  group.group
@@ -4557,6 +4737,8 @@ function Toolbar(p) {
4557
4737
  InsertSection,
4558
4738
  {
4559
4739
  canEdit: p.canEdit,
4740
+ onInsertSlideFromTemplate: p.onInsertSlideFromTemplate,
4741
+ templateScheme: p.templateScheme,
4560
4742
  newShapeType: p.newShapeType,
4561
4743
  onSetNewShapeType: p.onSetNewShapeType,
4562
4744
  activeFreeformTool: p.activeFreeformTool,
@@ -4573,7 +4755,12 @@ function Toolbar(p) {
4573
4755
  onOpenImagePicker: p.onOpenImagePicker,
4574
4756
  onOpenMediaPicker: p.onOpenMediaPicker,
4575
4757
  hasSelection: Boolean(p.selectedElement),
4576
- onOpenHyperlinkDialog: p.onOpenHyperlinkDialog
4758
+ onOpenHyperlinkDialog: p.onOpenHyperlinkDialog,
4759
+ layoutOptions: p.layoutOptions,
4760
+ currentLayoutPath: p.currentLayoutPath,
4761
+ onInsertSlideFromLayout: p.onInsertSlideFromLayout,
4762
+ onToggleComments: p.onToggleComments,
4763
+ isCommentsPanelOpen: p.isCommentsPanelOpen
4577
4764
  }
4578
4765
  ),
4579
4766
  sTxt && /* @__PURE__ */ jsx(
@@ -4933,7 +5120,7 @@ function ChartQuickActionsOverlay({
4933
5120
  "data-export-ignore": "true",
4934
5121
  style: { position: "absolute", left: 0, top: 0, zIndex: 59 },
4935
5122
  onMouseDown: (e) => e.stopPropagation(),
4936
- children: descriptor.buttons.map((button) => /* @__PURE__ */ jsxs(React103.Fragment, { children: [
5123
+ children: descriptor.buttons.map((button) => /* @__PURE__ */ jsxs(React104.Fragment, { children: [
4937
5124
  /* @__PURE__ */ jsx(
4938
5125
  "button",
4939
5126
  {
@@ -4953,7 +5140,7 @@ function ChartQuickActionsOverlay({
4953
5140
  transformOrigin: "top left"
4954
5141
  },
4955
5142
  className: "flex items-center justify-center rounded bg-white border border-gray-300 shadow-sm hover:bg-gray-100 text-gray-700",
4956
- children: React103.createElement(ICONS3[button.id], { className: "size-3.5" })
5143
+ children: React104.createElement(ICONS3[button.id], { className: "size-3.5" })
4957
5144
  }
4958
5145
  ),
4959
5146
  open === button.id && button.id === "elements" && /* @__PURE__ */ jsxs(
@@ -6099,7 +6286,7 @@ function HorizontalRulerView({ ticks, widthPx, highlight }) {
6099
6286
  }
6100
6287
  );
6101
6288
  }
6102
- var HorizontalRuler = React103.memo(HorizontalRulerView);
6289
+ var HorizontalRuler = React104.memo(HorizontalRulerView);
6103
6290
  HorizontalRuler.displayName = "HorizontalRuler";
6104
6291
  function VerticalRulerView({ ticks, heightPx, highlight }) {
6105
6292
  return /* @__PURE__ */ jsxs(
@@ -6171,7 +6358,7 @@ function VerticalRulerView({ ticks, heightPx, highlight }) {
6171
6358
  }
6172
6359
  );
6173
6360
  }
6174
- var VerticalRuler = React103.memo(VerticalRulerView);
6361
+ var VerticalRuler = React104.memo(VerticalRulerView);
6175
6362
  VerticalRuler.displayName = "VerticalRuler";
6176
6363
  function Ruler({
6177
6364
  canvasSize,
@@ -7672,7 +7859,7 @@ function ShortcutPanel({ isOpen, onClose }) {
7672
7859
  }
7673
7860
  )
7674
7861
  ] }),
7675
- /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto p-2 space-y-1", children: SHORTCUT_REFERENCE_ITEMS$1.map((shortcut) => /* @__PURE__ */ jsxs(
7862
+ /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto p-2 space-y-1", children: SHORTCUT_REFERENCE_ITEMS.map((shortcut) => /* @__PURE__ */ jsxs(
7676
7863
  "div",
7677
7864
  {
7678
7865
  className: "flex items-center justify-between gap-3 rounded bg-muted/80 px-2 py-1.5",
@@ -8053,7 +8240,7 @@ function slideThumbnailPropsEqual(prev, next) {
8053
8240
  }
8054
8241
  return true;
8055
8242
  }
8056
- var SlideThumbnail = React103.memo(SlideThumbnailImpl, slideThumbnailPropsEqual);
8243
+ var SlideThumbnail = React104.memo(SlideThumbnailImpl, slideThumbnailPropsEqual);
8057
8244
  function tableCell(props) {
8058
8245
  const { selectedElement, tableEditorState } = props;
8059
8246
  if (selectedElement?.type !== "table" || tableEditorState === null) {
@@ -8166,10 +8353,21 @@ function ContextMenu(props) {
8166
8353
  const { t } = useTranslation();
8167
8354
  const customization = useViewerCustomizationContext();
8168
8355
  const shapeFormat = useShapeFormatContext();
8356
+ const chartFormat = useChartFormatContext();
8169
8357
  const open = Boolean(contextMenuState) && mode === "edit";
8170
- const handlers = contextMenuHandlers(props, shapeFormat);
8358
+ const handlers = {
8359
+ ...contextMenuHandlers(props, shapeFormat),
8360
+ // "Format Chart Area..." and its siblings open the chart Format pane.
8361
+ "format-chart-element": chartFormat ? () => {
8362
+ chartFormat.openPane();
8363
+ onClose();
8364
+ } : void 0
8365
+ };
8171
8366
  const entries = customizeContextMenuEntries(
8172
- buildContextMenuEntries(contextMenuContext(props, shapeFormat)),
8367
+ buildContextMenuEntries({
8368
+ ...contextMenuContext(props, shapeFormat),
8369
+ chartFormatTarget: chartFormat?.target ?? null
8370
+ }),
8173
8371
  customization,
8174
8372
  {
8175
8373
  slideIndex: props.slideIndex ?? 0,
@@ -8739,7 +8937,7 @@ function LazyThumbnailInner({
8739
8937
  }
8740
8938
  ) });
8741
8939
  }
8742
- var LazyThumbnail = React103.memo(LazyThumbnailInner);
8940
+ var LazyThumbnail = React104.memo(LazyThumbnailInner);
8743
8941
  function declaredSectionFacts(groups, sectionId) {
8744
8942
  const declared = groups.filter((group) => group.id !== DEFAULT_SECTION_GROUP_ID && group.id !== UNGROUPED_SECTION_ID).map((group) => group.id);
8745
8943
  return {
@@ -8907,7 +9105,7 @@ function SlideItemInner({
8907
9105
  }
8908
9106
  );
8909
9107
  }
8910
- var SlideItem = React103.memo(SlideItemInner);
9108
+ var SlideItem = React104.memo(SlideItemInner);
8911
9109
  function useSlidePaneCallbacks(onMoveSlide, onRenameSection, onToggleSectionCollapse) {
8912
9110
  const [collapsedSections, setCollapsedSections] = useState({});
8913
9111
  const [renamingSectionId, setRenamingSectionId] = useState(null);
@@ -10320,7 +10518,7 @@ function arePropsEqual(prev, next) {
10320
10518
  }
10321
10519
  return true;
10322
10520
  }
10323
- var SlideCard = React103.memo(SlideCardImpl, arePropsEqual);
10521
+ var SlideCard = React104.memo(SlideCardImpl, arePropsEqual);
10324
10522
  var ICON_CLASS = "h-3.5 w-3.5 text-muted-foreground";
10325
10523
  function SorterContextMenu({
10326
10524
  x,
@@ -10745,7 +10943,7 @@ function SlideSorterOverlay({
10745
10943
  count: state.selectedSlideIds.length
10746
10944
  }) })
10747
10945
  ] }),
10748
- React103.createElement("pptx-ui-slide-clipboard", {
10946
+ React104.createElement("pptx-ui-slide-clipboard", {
10749
10947
  ref: (node) => {
10750
10948
  if (!node) {
10751
10949
  return;
@@ -11661,8 +11859,8 @@ function SlideNotesPanel({
11661
11859
  onHeightChange
11662
11860
  }) {
11663
11861
  const { t } = useTranslation();
11664
- const rootRef = React103.useRef(null);
11665
- React103.useEffect(() => {
11862
+ const rootRef = React104.useRef(null);
11863
+ React104.useEffect(() => {
11666
11864
  const el = rootRef.current;
11667
11865
  if (!el || !onHeightChange) {
11668
11866
  return void 0;
@@ -13505,9 +13703,9 @@ function PresentationSubtitleBar({
13505
13703
  function renderNotesSegments(segments) {
13506
13704
  return notesSegmentsToSpans(segments).map((span) => {
13507
13705
  if (span.kind === "break") {
13508
- return React103.createElement("br", { key: span.key });
13706
+ return React104.createElement("br", { key: span.key });
13509
13707
  }
13510
- return React103.createElement(
13708
+ return React104.createElement(
13511
13709
  "span",
13512
13710
  { key: span.key, style: span.style },
13513
13711
  span.text
@@ -13683,7 +13881,7 @@ function scaledSlidePreviewPropsEqual(prev, next) {
13683
13881
  }
13684
13882
  return true;
13685
13883
  }
13686
- var ScaledSlidePreview = React103.memo(ScaledSlidePreviewImpl, scaledSlidePreviewPropsEqual);
13884
+ var ScaledSlidePreview = React104.memo(ScaledSlidePreviewImpl, scaledSlidePreviewPropsEqual);
13687
13885
  function PresenterNotesRail({
13688
13886
  slides,
13689
13887
  current,
@@ -14912,7 +15110,7 @@ function EffectSoundRow({
14912
15110
  onPickStock
14913
15111
  }) {
14914
15112
  const { t } = useTranslation();
14915
- const fileInputRef = React103.useRef(null);
15113
+ const fileInputRef = React104.useRef(null);
14916
15114
  const selectedValue = soundState.catalogueId ?? (soundState.hasSound ? CURRENT_VALUE : NONE_VALUE);
14917
15115
  const handleSelectChange = (event) => {
14918
15116
  const value = event.target.value;
@@ -16476,7 +16674,7 @@ function ChartDataGrid({
16476
16674
  "input",
16477
16675
  {
16478
16676
  type: "number",
16479
- "aria-label": `${s.name} value ${ci + 1}`,
16677
+ "aria-label": t("pptx.chart.seriesValueCell", { name: s.name, number: ci + 1 }),
16480
16678
  disabled: !canEdit,
16481
16679
  ref: isValueHighlight(si, ci) ? highlightRef : null,
16482
16680
  className: `${CELL_INPUT}${isValueHighlight(si, ci) ? highlightClass : ""}`,
@@ -18483,7 +18681,7 @@ function ConnectorArrowsSection({
18483
18681
  ["Start", "End"].map((end) => {
18484
18682
  const widthKey = end === "Start" ? "connectorStartArrowWidth" : "connectorEndArrowWidth";
18485
18683
  const lengthKey = end === "Start" ? "connectorStartArrowLength" : "connectorEndArrowLength";
18486
- return /* @__PURE__ */ jsxs(React103.Fragment, { children: [
18684
+ return /* @__PURE__ */ jsxs(React104.Fragment, { children: [
18487
18685
  /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
18488
18686
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t(END_LABEL_KEYS[end].width) }),
18489
18687
  /* @__PURE__ */ jsx(
@@ -21411,7 +21609,7 @@ function StrokeEffectsSection({
21411
21609
  ] }),
21412
21610
  EFFECT_CONFIGS.map((cfg) => {
21413
21611
  const on = cfg.isOn(style);
21414
- return /* @__PURE__ */ jsxs(React103.Fragment, { children: [
21612
+ return /* @__PURE__ */ jsxs(React104.Fragment, { children: [
21415
21613
  /* @__PURE__ */ jsxs("label", { className: `inline-flex items-center gap-2 text-foreground ${COL2}`, children: [
21416
21614
  /* @__PURE__ */ jsx(
21417
21615
  WebCheckbox,
@@ -21666,7 +21864,7 @@ function Text3DProperties({
21666
21864
  });
21667
21865
  },
21668
21866
  className: INPUT_CLS2,
21669
- children: MATERIAL_PRESETS.map(({ value, label }) => /* @__PURE__ */ jsx("option", { value, children: label }, value))
21867
+ children: MATERIAL_PRESETS.map(({ value, labelKey }) => /* @__PURE__ */ jsx("option", { value, children: t(labelKey) }, value))
21670
21868
  }
21671
21869
  )
21672
21870
  ] })
@@ -21694,7 +21892,7 @@ function BevelSection({
21694
21892
  value: bevelType ?? "none",
21695
21893
  onChange: (e) => onTypeChange(e.target.value),
21696
21894
  className: INPUT_CLS2,
21697
- children: BEVEL_PRESETS.map(({ value, label: l }) => /* @__PURE__ */ jsx("option", { value, children: l }, value))
21895
+ children: BEVEL_PRESETS.map(({ value, labelKey }) => /* @__PURE__ */ jsx("option", { value, children: t(labelKey) }, value))
21698
21896
  }
21699
21897
  )
21700
21898
  ] }),
@@ -22266,7 +22464,7 @@ function TextWarpGallery({
22266
22464
  onUpdateTextStyle
22267
22465
  }) {
22268
22466
  const { t } = useTranslation();
22269
- const [expanded, setExpanded] = React103.useState(false);
22467
+ const [expanded, setExpanded] = React104.useState(false);
22270
22468
  const currentPreset = ts?.textWarpPreset || "textNoShape";
22271
22469
  return /* @__PURE__ */ jsxs("div", { className: "mt-2 rounded border border-border bg-card p-2 space-y-2", children: [
22272
22470
  /* @__PURE__ */ jsxs(
@@ -22281,13 +22479,16 @@ function TextWarpGallery({
22281
22479
  ]
22282
22480
  }
22283
22481
  ),
22284
- !expanded && /* @__PURE__ */ jsx("div", { className: "text-[11px] text-muted-foreground", children: TEXT_WARP_PRESETS.find((p) => p.value === currentPreset)?.label || currentPreset }),
22285
- expanded && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1", children: TEXT_WARP_PRESETS.map(({ value, label }) => /* @__PURE__ */ jsx(
22482
+ !expanded && /* @__PURE__ */ jsx("div", { className: "text-[11px] text-muted-foreground", children: (() => {
22483
+ const current = TEXT_WARP_PRESETS.find((p) => p.value === currentPreset);
22484
+ return current ? t(current.labelKey) : currentPreset;
22485
+ })() }),
22486
+ expanded && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1", children: TEXT_WARP_PRESETS.map(({ value, labelKey }) => /* @__PURE__ */ jsx(
22286
22487
  "button",
22287
22488
  {
22288
22489
  type: "button",
22289
- title: label,
22290
- "aria-label": label,
22490
+ title: t(labelKey),
22491
+ "aria-label": t(labelKey),
22291
22492
  className: `flex items-center justify-center rounded p-1 ${currentPreset === value ? "bg-primary ring-1 ring-primary" : "bg-muted hover:bg-accent"}`,
22292
22493
  onClick: () => onUpdateTextStyle({
22293
22494
  textWarpPreset: value === "textNoShape" ? void 0 : value
@@ -22909,7 +23110,7 @@ function SmartArtStyleControls({
22909
23110
  onChangeStyle
22910
23111
  }) {
22911
23112
  const { t } = useTranslation();
22912
- const translate = React103.useCallback((key) => t(key), [t]);
23113
+ const translate = React104.useCallback((key) => t(key), [t]);
22913
23114
  return /* @__PURE__ */ jsxs(Fragment, { children: [
22914
23115
  /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1 text-[11px]", children: [
22915
23116
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("pptx.smartart.colorScheme") }),
@@ -22964,9 +23165,9 @@ function SmartArtPropertiesPanel({
22964
23165
  const nodes = smartArtData.nodes ?? [];
22965
23166
  const layout = smartArtData.resolvedLayoutType;
22966
23167
  const topLevelCount = nodes.filter((n) => !n.parentId).length;
22967
- const inputRefs = React103.useRef(/* @__PURE__ */ new Map());
22968
- const pendingFocusId = React103.useRef(null);
22969
- React103.useEffect(() => {
23168
+ const inputRefs = React104.useRef(/* @__PURE__ */ new Map());
23169
+ const pendingFocusId = React104.useRef(null);
23170
+ React104.useEffect(() => {
22970
23171
  const id = pendingFocusId.current;
22971
23172
  if (id) {
22972
23173
  inputRefs.current.get(id)?.focus();
@@ -24151,8 +24352,8 @@ function TablePropertiesPanel({
24151
24352
  {
24152
24353
  type: "button",
24153
24354
  disabled: !canEdit,
24154
- title: preset.label,
24155
- "aria-label": preset.label,
24355
+ title: t(preset.labelKey),
24356
+ "aria-label": t(preset.labelKey),
24156
24357
  className: "rounded border border-border hover:border-primary overflow-hidden h-10 max-md:h-11 transition-colors",
24157
24358
  onClick: () => {
24158
24359
  updateTableData({ rows: applyTableStylePreset(td, preset) });
@@ -24572,7 +24773,7 @@ function CommentBody({ text, mentions, className }) {
24572
24773
  index
24573
24774
  ) : (
24574
24775
  // eslint-disable-next-line react/no-array-index-key -- segments are positional
24575
- /* @__PURE__ */ jsx(React103.Fragment, { children: segment.text }, index)
24776
+ /* @__PURE__ */ jsx(React104.Fragment, { children: segment.text }, index)
24576
24777
  )
24577
24778
  ) });
24578
24779
  }
@@ -26089,7 +26290,7 @@ function PresentationPropertiesPanel({
26089
26290
  onUpdateTagCollections
26090
26291
  }) {
26091
26292
  const { t } = useTranslation();
26092
- const handleTransitionChange = React103.useCallback(
26293
+ const handleTransitionChange = React104.useCallback(
26093
26294
  (updates) => {
26094
26295
  onUpdateSlide({
26095
26296
  transition: mergeSlideTransition(activeSlide?.transition, updates)
@@ -27509,6 +27710,7 @@ function PrintDialog({
27509
27710
  defaultFrameSlides
27510
27711
  }) {
27511
27712
  const { t } = useTranslation();
27713
+ const regionRenderer = useRegionRenderer("dialog.print");
27512
27714
  const { panelStyle, handlers: dragHandlers } = useModalDismissDrag(onClose);
27513
27715
  const { viewportWidth } = useIsMobile();
27514
27716
  const touchTargetPx = getDensePanelTouchTargetPx(viewportWidth);
@@ -27638,68 +27840,81 @@ function PrintDialog({
27638
27840
  ]
27639
27841
  }
27640
27842
  ),
27641
- /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-5 py-4 flex gap-5 max-md:flex-col", children: [
27642
- /* @__PURE__ */ jsx(
27643
- PrintSettingsPanel,
27644
- {
27645
- printWhat,
27646
- onPrintWhatChange: setPrintWhat,
27647
- orientation,
27648
- onOrientationChange: setOrientation,
27649
- colorMode,
27650
- onColorModeChange: setColorMode,
27651
- frameSlides,
27652
- onFrameSlidesChange: setFrameSlides,
27653
- slidesPerPage,
27654
- onSlidesPerPageChange: setSlidesPerPage,
27655
- slideRange,
27656
- onSlideRangeChange: setSlideRange,
27657
- customFrom,
27658
- onCustomFromChange: setCustomFrom,
27659
- customTo,
27660
- onCustomToChange: setCustomTo,
27661
- totalSlides: slides.length,
27662
- activeSlideIndex
27663
- }
27664
- ),
27665
- printWhat === "handouts" && /* @__PURE__ */ jsx("div", { className: "w-[230px] shrink-0 border-l border-border pl-4 overflow-y-auto max-md:w-full max-md:border-l-0 max-md:border-t max-md:pl-0 max-md:pt-3", children: /* @__PURE__ */ jsx(
27666
- PrintPreview,
27843
+ regionRenderer ? (
27844
+ // The frame (backdrop, title bar, close, dismiss) stays the viewer's; the host replaces the body.
27845
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx(
27846
+ ViewerRegion,
27667
27847
  {
27668
- slideIndices: previewSlideIndices,
27669
- slidesPerPage,
27670
- orientation: effectiveOrientation,
27671
- frameSlides
27672
- }
27673
- ) }),
27674
- printWhat === "notes" && /* @__PURE__ */ jsx("div", { className: "w-[230px] shrink-0 border-l border-border pl-4 overflow-y-auto max-md:w-full max-md:border-l-0 max-md:border-t max-md:pl-0 max-md:pt-3", children: /* @__PURE__ */ jsx(
27675
- NotesPagePreview,
27676
- {
27677
- slideIndices: previewSlideIndices,
27678
- slides,
27679
- frameSlides
27680
- }
27681
- ) })
27682
- ] }),
27683
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-t border-border", children: [
27684
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t("pptx.print.pageEstimate", {
27685
- pages: pageCount,
27686
- slides: slideCount
27687
- }) }),
27688
- /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx(
27689
- DialogFooter,
27690
- {
27691
- actions: [
27692
- { id: "cancel", label: t("pptx.common.cancel") },
27693
- {
27694
- id: "print",
27695
- label: t("pptx.print.printButton"),
27696
- variant: "primary",
27697
- icon: "print"
27698
- }
27699
- ],
27700
- onAction: (id) => id === "print" ? handlePrint() : onClose()
27848
+ region: "dialog.print",
27849
+ renderer: regionRenderer,
27850
+ close: onClose,
27851
+ style: { width: "100%", minHeight: "8rem" }
27701
27852
  }
27702
27853
  ) })
27854
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
27855
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-5 py-4 flex gap-5 max-md:flex-col", children: [
27856
+ /* @__PURE__ */ jsx(
27857
+ PrintSettingsPanel,
27858
+ {
27859
+ printWhat,
27860
+ onPrintWhatChange: setPrintWhat,
27861
+ orientation,
27862
+ onOrientationChange: setOrientation,
27863
+ colorMode,
27864
+ onColorModeChange: setColorMode,
27865
+ frameSlides,
27866
+ onFrameSlidesChange: setFrameSlides,
27867
+ slidesPerPage,
27868
+ onSlidesPerPageChange: setSlidesPerPage,
27869
+ slideRange,
27870
+ onSlideRangeChange: setSlideRange,
27871
+ customFrom,
27872
+ onCustomFromChange: setCustomFrom,
27873
+ customTo,
27874
+ onCustomToChange: setCustomTo,
27875
+ totalSlides: slides.length,
27876
+ activeSlideIndex
27877
+ }
27878
+ ),
27879
+ printWhat === "handouts" && /* @__PURE__ */ jsx("div", { className: "w-[230px] shrink-0 border-l border-border pl-4 overflow-y-auto max-md:w-full max-md:border-l-0 max-md:border-t max-md:pl-0 max-md:pt-3", children: /* @__PURE__ */ jsx(
27880
+ PrintPreview,
27881
+ {
27882
+ slideIndices: previewSlideIndices,
27883
+ slidesPerPage,
27884
+ orientation: effectiveOrientation,
27885
+ frameSlides
27886
+ }
27887
+ ) }),
27888
+ printWhat === "notes" && /* @__PURE__ */ jsx("div", { className: "w-[230px] shrink-0 border-l border-border pl-4 overflow-y-auto max-md:w-full max-md:border-l-0 max-md:border-t max-md:pl-0 max-md:pt-3", children: /* @__PURE__ */ jsx(
27889
+ NotesPagePreview,
27890
+ {
27891
+ slideIndices: previewSlideIndices,
27892
+ slides,
27893
+ frameSlides
27894
+ }
27895
+ ) })
27896
+ ] }),
27897
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-t border-border", children: [
27898
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t("pptx.print.pageEstimate", {
27899
+ pages: pageCount,
27900
+ slides: slideCount
27901
+ }) }),
27902
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx(
27903
+ DialogFooter,
27904
+ {
27905
+ actions: [
27906
+ { id: "cancel", label: t("pptx.common.cancel") },
27907
+ {
27908
+ id: "print",
27909
+ label: t("pptx.print.printButton"),
27910
+ variant: "primary",
27911
+ icon: "print"
27912
+ }
27913
+ ],
27914
+ onAction: (id) => id === "print" ? handlePrint() : onClose()
27915
+ }
27916
+ ) })
27917
+ ] })
27703
27918
  ] })
27704
27919
  ]
27705
27920
  }
@@ -28016,6 +28231,7 @@ function BroadcastDialog({
28016
28231
  defaultServerUrl
28017
28232
  }) {
28018
28233
  const { t } = useTranslation();
28234
+ const regionRenderer = useRegionRenderer("dialog.broadcast");
28019
28235
  const collab = useCollaboration();
28020
28236
  const isBroadcasting = collab !== null && collab.status !== "disconnected" && collab.status !== "error" && collab.config.role === "owner";
28021
28237
  const [roomId, setRoomId] = useState("");
@@ -28119,41 +28335,54 @@ function BroadcastDialog({
28119
28335
  ]
28120
28336
  }
28121
28337
  ),
28122
- /* @__PURE__ */ jsx("div", { className: "px-5 py-4", children: isBroadcasting ? /* @__PURE__ */ jsx(
28123
- ActiveBroadcastView,
28124
- {
28125
- collab,
28126
- broadcastUrl,
28127
- copied,
28128
- onCopyUrl: handleCopyUrl,
28129
- onStopBroadcast: handleStopBroadcast
28130
- }
28131
- ) : /* @__PURE__ */ jsx(
28132
- StartBroadcastForm,
28133
- {
28134
- roomId,
28135
- userName,
28136
- serverUrl,
28137
- onRoomIdChange: setRoomId,
28138
- onUserNameChange: setUserName,
28139
- onServerUrlChange: setServerUrl
28140
- }
28141
- ) }),
28142
- !isBroadcasting && /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 px-5 py-3 border-t border-border", children: /* @__PURE__ */ jsx(
28143
- DialogFooter,
28144
- {
28145
- actions: [
28146
- { id: "close", label: t("pptx.common.close") },
28147
- {
28148
- id: "start",
28149
- label: t("pptx.broadcast.startBroadcast"),
28150
- variant: "primary",
28151
- disabled: !canStart
28152
- }
28153
- ],
28154
- onAction: (id) => id === "start" ? handleStartBroadcast() : onClose()
28155
- }
28156
- ) })
28338
+ regionRenderer ? (
28339
+ // The frame (backdrop, title bar, close, dismiss) stays the viewer's; the host replaces the body.
28340
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx(
28341
+ ViewerRegion,
28342
+ {
28343
+ region: "dialog.broadcast",
28344
+ renderer: regionRenderer,
28345
+ close: onClose,
28346
+ style: { width: "100%", minHeight: "8rem" }
28347
+ }
28348
+ ) })
28349
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
28350
+ /* @__PURE__ */ jsx("div", { className: "px-5 py-4", children: isBroadcasting ? /* @__PURE__ */ jsx(
28351
+ ActiveBroadcastView,
28352
+ {
28353
+ collab,
28354
+ broadcastUrl,
28355
+ copied,
28356
+ onCopyUrl: handleCopyUrl,
28357
+ onStopBroadcast: handleStopBroadcast
28358
+ }
28359
+ ) : /* @__PURE__ */ jsx(
28360
+ StartBroadcastForm,
28361
+ {
28362
+ roomId,
28363
+ userName,
28364
+ serverUrl,
28365
+ onRoomIdChange: setRoomId,
28366
+ onUserNameChange: setUserName,
28367
+ onServerUrlChange: setServerUrl
28368
+ }
28369
+ ) }),
28370
+ !isBroadcasting && /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 px-5 py-3 border-t border-border", children: /* @__PURE__ */ jsx(
28371
+ DialogFooter,
28372
+ {
28373
+ actions: [
28374
+ { id: "close", label: t("pptx.common.close") },
28375
+ {
28376
+ id: "start",
28377
+ label: t("pptx.broadcast.startBroadcast"),
28378
+ variant: "primary",
28379
+ disabled: !canStart
28380
+ }
28381
+ ],
28382
+ onAction: (id) => id === "start" ? handleStartBroadcast() : onClose()
28383
+ }
28384
+ ) })
28385
+ ] })
28157
28386
  ]
28158
28387
  }
28159
28388
  )
@@ -28562,6 +28791,7 @@ function ShareDialog({
28562
28791
  const collab = useCollaboration();
28563
28792
  const isActive = collab !== null && collab.status !== "disconnected" && collab.status !== "error";
28564
28793
  const { t } = useTranslation();
28794
+ const regionRenderer = useRegionRenderer("dialog.share");
28565
28795
  const [roomId, setRoomId] = useState(defaultRoomId ?? "");
28566
28796
  const [userName, setUserName] = useState(defaultUserName ?? "");
28567
28797
  const [serverUrl, setServerUrl] = useState(defaultServerUrl ?? "");
@@ -28648,58 +28878,74 @@ function ShareDialog({
28648
28878
  ]
28649
28879
  }
28650
28880
  ),
28651
- /* @__PURE__ */ jsx("div", { className: "px-5 py-4", children: isActive ? /* @__PURE__ */ jsx(
28652
- ActiveSessionView,
28653
- {
28654
- collab,
28655
- activeCollaboration,
28656
- copied,
28657
- onCopyRoomId: handleCopyRoomId,
28658
- onStopCollaboration
28659
- }
28660
- ) : /* @__PURE__ */ jsx(
28661
- StartSessionForm,
28662
- {
28663
- mode,
28664
- invitation,
28665
- roomId,
28666
- userName,
28667
- serverUrl,
28668
- onRoomIdChange: setRoomId,
28669
- onUserNameChange: setUserName,
28670
- onServerUrlChange: setServerUrl,
28671
- onModeChange: setMode,
28672
- onInvitationChange: setInvitation,
28673
- preconfigured,
28674
- connectionFailed: collab?.status === "error",
28675
- onRetry: collab?.retry
28676
- }
28677
- ) }),
28678
- /* @__PURE__ */ jsx(
28679
- "div",
28680
- {
28681
- className: `flex justify-end gap-2 px-5 py-3 border-t border-border ${stickyFooterClass}`,
28682
- children: /* @__PURE__ */ jsx(
28683
- DialogFooter,
28684
- {
28685
- actions: [
28686
- { id: "cancel", label: isActive ? t("pptx.share.close") : t("pptx.share.cancel") },
28687
- ...isActive ? [] : [
28881
+ regionRenderer ? (
28882
+ // The frame (backdrop, title bar, close, dismiss) stays the viewer's; the host replaces the body.
28883
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx(
28884
+ ViewerRegion,
28885
+ {
28886
+ region: "dialog.share",
28887
+ renderer: regionRenderer,
28888
+ close: onClose,
28889
+ style: { width: "100%", minHeight: "8rem" }
28890
+ }
28891
+ ) })
28892
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
28893
+ /* @__PURE__ */ jsx("div", { className: "px-5 py-4", children: isActive ? /* @__PURE__ */ jsx(
28894
+ ActiveSessionView,
28895
+ {
28896
+ collab,
28897
+ activeCollaboration,
28898
+ copied,
28899
+ onCopyRoomId: handleCopyRoomId,
28900
+ onStopCollaboration
28901
+ }
28902
+ ) : /* @__PURE__ */ jsx(
28903
+ StartSessionForm,
28904
+ {
28905
+ mode,
28906
+ invitation,
28907
+ roomId,
28908
+ userName,
28909
+ serverUrl,
28910
+ onRoomIdChange: setRoomId,
28911
+ onUserNameChange: setUserName,
28912
+ onServerUrlChange: setServerUrl,
28913
+ onModeChange: setMode,
28914
+ onInvitationChange: setInvitation,
28915
+ preconfigured,
28916
+ connectionFailed: collab?.status === "error",
28917
+ onRetry: collab?.retry
28918
+ }
28919
+ ) }),
28920
+ /* @__PURE__ */ jsx(
28921
+ "div",
28922
+ {
28923
+ className: `flex justify-end gap-2 px-5 py-3 border-t border-border ${stickyFooterClass}`,
28924
+ children: /* @__PURE__ */ jsx(
28925
+ DialogFooter,
28926
+ {
28927
+ actions: [
28688
28928
  {
28689
- id: "start",
28690
- label: t(
28691
- mode === "join" ? "pptx.share.joinSession" : "pptx.share.startSharing"
28692
- ),
28693
- variant: "primary",
28694
- disabled: !canStart
28695
- }
28696
- ]
28697
- ],
28698
- onAction: (id) => id === "start" ? handleStartSharing() : onClose()
28699
- }
28700
- )
28701
- }
28702
- )
28929
+ id: "cancel",
28930
+ label: isActive ? t("pptx.share.close") : t("pptx.share.cancel")
28931
+ },
28932
+ ...isActive ? [] : [
28933
+ {
28934
+ id: "start",
28935
+ label: t(
28936
+ mode === "join" ? "pptx.share.joinSession" : "pptx.share.startSharing"
28937
+ ),
28938
+ variant: "primary",
28939
+ disabled: !canStart
28940
+ }
28941
+ ]
28942
+ ],
28943
+ onAction: (id) => id === "start" ? handleStartSharing() : onClose()
28944
+ }
28945
+ )
28946
+ }
28947
+ )
28948
+ ] })
28703
28949
  ]
28704
28950
  }
28705
28951
  )
@@ -29049,13 +29295,14 @@ function ViewerOverlays({
29049
29295
  reducedMotion,
29050
29296
  onToggleReducedMotion
29051
29297
  }) {
29298
+ const customization = useViewerCustomizationContext();
29052
29299
  const hasOverlay = isShortcutHelpOpen || isAccessibilityPanelOpen || showSlideSorter || showReadingView || showOutlineView;
29053
29300
  if (!hasOverlay) {
29054
29301
  return null;
29055
29302
  }
29056
29303
  return /* @__PURE__ */ jsxs(Fragment, { children: [
29057
29304
  isShortcutHelpOpen && /* @__PURE__ */ jsx(ShortcutPanel, { isOpen: isShortcutHelpOpen, onClose: onCloseShortcuts }),
29058
- isAccessibilityPanelOpen && /* @__PURE__ */ jsx(
29305
+ isAccessibilityPanelOpen && isPanelVisible(customization, "accessibilityPane") && /* @__PURE__ */ jsx(
29059
29306
  AccessibilityPanel,
29060
29307
  {
29061
29308
  isOpen: isAccessibilityPanelOpen,
@@ -29138,9 +29385,38 @@ function ViewerBottomPanels({
29138
29385
  const { isHidden } = useToolbarVisibility(hiddenActions);
29139
29386
  const customization = useViewerCustomizationContext();
29140
29387
  const showNotes = isPanelVisible(customization, "notes");
29388
+ const notesRenderer = useRegionRenderer("notes");
29389
+ const statusBarRenderer = useRegionRenderer("statusBar");
29390
+ const [notesSlot, setNotesSlot] = useState(null);
29391
+ const reportsNotesHeight = Boolean(showNotes && notesRenderer);
29392
+ useEffect(() => {
29393
+ if (!notesSlot || !reportsNotesHeight || !onNotesHeightChange) {
29394
+ return void 0;
29395
+ }
29396
+ const stop2 = observeElementHeight(notesSlot, onNotesHeightChange);
29397
+ return () => {
29398
+ stop2();
29399
+ onNotesHeightChange(0);
29400
+ };
29401
+ }, [notesSlot, reportsNotesHeight, onNotesHeightChange]);
29141
29402
  return /* @__PURE__ */ jsxs(Fragment, { children: [
29142
29403
  showNotes && onResizeBottom && !isSlideNotesCollapsed && /* @__PURE__ */ jsx(ResizeHandle, { direction: "vertical", onResize: onResizeBottom }),
29143
- showNotes && /* @__PURE__ */ jsx(
29404
+ showNotes && notesRenderer && // The slot (height, resize handle, collapse) stays the viewer's; a
29405
+ // collapsed strip is hidden, not unmounted, so the host keeps its state.
29406
+ /* @__PURE__ */ jsx(
29407
+ "div",
29408
+ {
29409
+ ref: setNotesSlot,
29410
+ "data-pptx-chrome": "notes",
29411
+ className: "flex-shrink-0 overflow-hidden border-t border-border/60 bg-background",
29412
+ style: {
29413
+ height: notesPanelHeight ?? 120,
29414
+ display: isSlideNotesCollapsed ? "none" : void 0
29415
+ },
29416
+ children: /* @__PURE__ */ jsx(ViewerRegion, { region: "notes", renderer: notesRenderer })
29417
+ }
29418
+ ),
29419
+ showNotes && !notesRenderer && /* @__PURE__ */ jsx(
29144
29420
  SlideNotesPanel,
29145
29421
  {
29146
29422
  activeSlide,
@@ -29154,7 +29430,8 @@ function ViewerBottomPanels({
29154
29430
  onHeightChange: onNotesHeightChange
29155
29431
  }
29156
29432
  ),
29157
- !hideStatusBar && isPanelVisible(customization, "statusBar") && /* @__PURE__ */ jsx(
29433
+ !hideStatusBar && isPanelVisible(customization, "statusBar") && statusBarRenderer && /* @__PURE__ */ jsx("div", { "data-pptx-chrome": "status-bar", className: "flex-shrink-0", children: /* @__PURE__ */ jsx(ViewerRegion, { region: "statusBar", renderer: statusBarRenderer }) }),
29434
+ !hideStatusBar && isPanelVisible(customization, "statusBar") && !statusBarRenderer && /* @__PURE__ */ jsx(
29158
29435
  StatusBar,
29159
29436
  {
29160
29437
  slideCount,
@@ -29233,9 +29510,23 @@ function ViewerInspector({
29233
29510
  panelWidth
29234
29511
  }) {
29235
29512
  const { t } = useTranslation();
29513
+ const regionRenderer = useRegionRenderer("inspector");
29236
29514
  if (!isOpen) {
29237
29515
  return null;
29238
29516
  }
29517
+ if (regionRenderer) {
29518
+ return /* @__PURE__ */ jsx(
29519
+ "div",
29520
+ {
29521
+ "data-pptx-inspector": true,
29522
+ role: "complementary",
29523
+ "aria-label": t("pptx.inspector.properties"),
29524
+ className: "h-full flex-shrink-0 max-md:absolute max-md:inset-x-0 max-md:bottom-0 max-md:top-auto max-md:z-30",
29525
+ style: panelWidth ? { width: panelWidth } : void 0,
29526
+ children: /* @__PURE__ */ jsx(ViewerRegion, { region: "inspector", renderer: regionRenderer, close: onClose })
29527
+ }
29528
+ );
29529
+ }
29239
29530
  const slideId = activeSlide?.id ?? "";
29240
29531
  const commentDraft = comments.commentDraftBySlideId[slideId] ?? "";
29241
29532
  const editingCommentId = comments.editingCommentIdBySlideId[slideId] ?? null;
@@ -29480,7 +29771,7 @@ function ViewerToolbarSection(props) {
29480
29771
  },
29481
29772
  [activeSlide, propertyHandlers]
29482
29773
  );
29483
- const scopedLayoutOptions = React103.useMemo(
29774
+ const scopedLayoutOptions = React104.useMemo(
29484
29775
  () => scopeLayoutOptionsToActiveSlide(s.layoutOptions, activeSlide),
29485
29776
  [s.layoutOptions, activeSlide]
29486
29777
  );
@@ -29883,6 +30174,8 @@ function ViewerToolbarSection(props) {
29883
30174
  }
29884
30175
  },
29885
30176
  isCommentsPanelOpen: s.isInspectorPaneOpen,
30177
+ isMobileInsertOpen: s.isMobileInsertOpen,
30178
+ onCloseMobileInsert: () => s.setIsMobileInsertOpen(false),
29886
30179
  slideCommentCount: activeSlide?.comments?.length ?? 0,
29887
30180
  reviewComments: createReviewCommentsHost({
29888
30181
  state: s,
@@ -30350,7 +30643,8 @@ function ViewerDialogGroup(props) {
30350
30643
  onKeepAnnotations,
30351
30644
  onDiscardAnnotations
30352
30645
  } = props;
30353
- const printAvailable = isDialogAvailable(useViewerCustomizationContext(), "print");
30646
+ const customization = useViewerCustomizationContext();
30647
+ const printAvailable = isDialogAvailable(customization, "print");
30354
30648
  return /* @__PURE__ */ jsxs(Fragment, { children: [
30355
30649
  /* @__PURE__ */ jsx(
30356
30650
  VersionHistoryPanel,
@@ -30364,7 +30658,7 @@ function ViewerDialogGroup(props) {
30364
30658
  /* @__PURE__ */ jsx(
30365
30659
  ComparePanel,
30366
30660
  {
30367
- isOpen: propertyHandlers.isComparePanelOpen,
30661
+ isOpen: propertyHandlers.isComparePanelOpen && isPanelVisible(customization, "comparePane"),
30368
30662
  compareResult: propertyHandlers.compareResult,
30369
30663
  canvasSize,
30370
30664
  onClose: () => propertyHandlers.setIsComparePanelOpen(false),
@@ -30376,7 +30670,7 @@ function ViewerDialogGroup(props) {
30376
30670
  /* @__PURE__ */ jsx(
30377
30671
  PasswordProtectionDialog,
30378
30672
  {
30379
- isOpen: dialogs.isPasswordDialogOpen,
30673
+ isOpen: dialogs.isPasswordDialogOpen && isDialogAvailable(customization, "passwordProtection"),
30380
30674
  isCurrentlyProtected: dialogs.isPasswordProtected,
30381
30675
  onClose: () => dialogs.setIsPasswordDialogOpen(false),
30382
30676
  onSetPassword: dialogs.handleSetPassword,
@@ -30416,7 +30710,7 @@ function ViewerDialogGroup(props) {
30416
30710
  /* @__PURE__ */ jsx(
30417
30711
  DigitalSignaturesDialog,
30418
30712
  {
30419
- isOpen: dialogs.isDigitalSigDialogOpen,
30713
+ isOpen: dialogs.isDigitalSigDialogOpen && isDialogAvailable(customization, "signatures"),
30420
30714
  onClose: () => dialogs.setIsDigitalSigDialogOpen(false),
30421
30715
  hasSignatures: hasDigitalSignatures,
30422
30716
  signatureCount: digitalSignatureCount
@@ -30449,7 +30743,7 @@ function ViewerDialogGroup(props) {
30449
30743
  /* @__PURE__ */ jsx(
30450
30744
  EquationEditorDialog,
30451
30745
  {
30452
- isOpen: dialogs.isEquationDialogOpen,
30746
+ isOpen: dialogs.isEquationDialogOpen && isDialogAvailable(customization, "equation"),
30453
30747
  onClose: () => dialogs.setIsEquationDialogOpen(false),
30454
30748
  onInsert: dialogs.editingEquationOmml ? insertHandlers.handleUpdateEquation : insertHandlers.handleInsertEquation,
30455
30749
  existingOmml: dialogs.editingEquationOmml
@@ -30458,7 +30752,7 @@ function ViewerDialogGroup(props) {
30458
30752
  /* @__PURE__ */ jsx(
30459
30753
  HyperlinkEditDialog,
30460
30754
  {
30461
- open: dialogs.isHyperlinkDialogOpen,
30755
+ open: dialogs.isHyperlinkDialogOpen && isDialogAvailable(customization, "hyperlink"),
30462
30756
  initialUrl: selectedElements[0]?.actionClick?.url,
30463
30757
  initialTooltip: selectedElements[0]?.actionClick?.tooltip,
30464
30758
  initialAction: selectedElements[0]?.actionClick?.action,
@@ -30918,6 +31212,7 @@ function PresentationContextMenu(p) {
30918
31212
  );
30919
31213
  }
30920
31214
  function ViewerCanvasArea(props) {
31215
+ const customization = useViewerCustomizationContext();
30921
31216
  const {
30922
31217
  mode,
30923
31218
  canEdit,
@@ -31110,7 +31405,7 @@ ${url}`)) {
31110
31405
  onTouchEnd: swipe.onTouchEnd,
31111
31406
  onContextMenu: mode === "present" ? handlePresentationContextMenu : void 0,
31112
31407
  children: [
31113
- findReplace.findReplaceOpen && /* @__PURE__ */ jsx(
31408
+ findReplace.findReplaceOpen && isPanelVisible(customization, "findReplace") && /* @__PURE__ */ jsx(
31114
31409
  FindReplacePanel,
31115
31410
  {
31116
31411
  findQuery: findReplace.findQuery,
@@ -31545,6 +31840,42 @@ function AiChangeOverlay({ batch, activeSlideIndex }) {
31545
31840
  ))
31546
31841
  ] });
31547
31842
  }
31843
+ function ChartFormatPanel() {
31844
+ const { t } = useTranslation();
31845
+ const commands = useChartFormatContext();
31846
+ const ref = useRef(null);
31847
+ const chart = commands?.chart;
31848
+ const chartData = chart?.type === "chart" ? chart.chartData : void 0;
31849
+ useEffect(() => {
31850
+ const node = ref.current;
31851
+ if (node && commands) {
31852
+ node.translateLabel = t;
31853
+ node.chartData = chartData;
31854
+ node.target = commands.target;
31855
+ node.disabled = !commands.editable;
31856
+ }
31857
+ }, [chartData, commands, t]);
31858
+ useEffect(() => {
31859
+ const node = ref.current;
31860
+ if (!node || !commands) {
31861
+ return;
31862
+ }
31863
+ const change = (event) => commands.applyChartData(event.detail.chartData);
31864
+ const retarget = (event) => commands.setTarget(event.detail.target);
31865
+ node.addEventListener("chart-format-change", change);
31866
+ node.addEventListener("chart-format-target", retarget);
31867
+ node.addEventListener("chart-format-close", commands.closePane);
31868
+ return () => {
31869
+ node.removeEventListener("chart-format-change", change);
31870
+ node.removeEventListener("chart-format-target", retarget);
31871
+ node.removeEventListener("chart-format-close", commands.closePane);
31872
+ };
31873
+ }, [commands]);
31874
+ if (!commands?.paneOpen || !chartData) {
31875
+ return null;
31876
+ }
31877
+ return /* @__PURE__ */ jsx("pptx-ui-chart-format-pane", { ref, "data-testid": "chart-format-pane" });
31878
+ }
31548
31879
  function ThemeEditorPanel({ theme, canEdit, onApply, onClose }) {
31549
31880
  const { t } = useTranslation();
31550
31881
  const ref = useRef(null);
@@ -32100,7 +32431,7 @@ function ViewerSidePanels(props) {
32100
32431
  panelWidth
32101
32432
  }
32102
32433
  ),
32103
- s.isSelectionPaneOpen && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
32434
+ s.isSelectionPaneOpen && isPanelVisible(customization, "selectionPane") && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
32104
32435
  MobileDismissSheet,
32105
32436
  {
32106
32437
  onClose: () => s.setIsSelectionPaneOpen(false),
@@ -32134,6 +32465,7 @@ function ViewerSidePanels(props) {
32134
32465
  onClose: () => s.setIsThemeEditorOpen(false)
32135
32466
  }
32136
32467
  ),
32468
+ (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(ChartFormatPanel, {}),
32137
32469
  aiPanel?.isOpen && aiConfig && aiBridge && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
32138
32470
  AiChatPanelLazy,
32139
32471
  {
@@ -32295,6 +32627,7 @@ function ViewerMainContent(props) {
32295
32627
  onApplyLayout,
32296
32628
  loadLayoutPreviews
32297
32629
  } = props;
32630
+ const slidesPaneRenderer = useRegionRenderer("slidesPane");
32298
32631
  const {
32299
32632
  ops,
32300
32633
  sectionOps,
@@ -32324,7 +32657,22 @@ function ViewerMainContent(props) {
32324
32657
  const layoutGalleryPreviews = useLayoutPreviews(loadLayoutPreviews, layoutGalleryAnchor !== null);
32325
32658
  return /* @__PURE__ */ jsx(ChartPartSelectionProvider, { children: /* @__PURE__ */ jsxs("div", { "data-pptx-chrome": "body", className: "relative z-10 flex flex-1 min-h-0", children: [
32326
32659
  showSlidesPane && /* @__PURE__ */ jsxs(Fragment, { children: [
32327
- /* @__PURE__ */ jsx(
32660
+ slidesPaneRenderer ? (
32661
+ // The rail's slot (width, collapse, resize handle) stays the viewer's.
32662
+ /* @__PURE__ */ jsx(
32663
+ "div",
32664
+ {
32665
+ "data-pptx-chrome": "slides",
32666
+ className: "h-full flex-shrink-0 overflow-hidden border-r border-border bg-secondary/30",
32667
+ style: {
32668
+ width: leftPanelWidth ?? 220,
32669
+ // Same collapse rule as the built-in rail; hidden, not unmounted.
32670
+ display: state.isSlidesPaneOpen ? void 0 : "none"
32671
+ },
32672
+ children: /* @__PURE__ */ jsx(ViewerRegion, { region: "slidesPane", renderer: slidesPaneRenderer })
32673
+ }
32674
+ )
32675
+ ) : /* @__PURE__ */ jsx(
32328
32676
  SlidesPaneSidebar,
32329
32677
  {
32330
32678
  slides,
@@ -32812,8 +33160,9 @@ function MobileChromeOverlay(props) {
32812
33160
  slideSectionGroups,
32813
33161
  canEdit,
32814
33162
  commentCount
32815
- } = props, { keyboardInset, isKeyboardOpen } = useKeyboardInsets(), activeSheet = s.isSlidesPaneOpen ? "slides" : s.isInspectorPaneOpen ? s.sidebarPanelMode === "comments" ? "comments" : "inspector" : !s.isSlideNotesCollapsed ? "notes" : null, closeAllSheets = () => {
33163
+ } = props, { keyboardInset, isKeyboardOpen } = useKeyboardInsets(), activeSheet = s.isMobileInsertOpen ? "insert" : s.isSlidesPaneOpen ? "slides" : s.isInspectorPaneOpen ? s.sidebarPanelMode === "comments" ? "comments" : "inspector" : !s.isSlideNotesCollapsed ? "notes" : null, closeAllSheets = () => {
32816
33164
  s.setIsSlidesPaneOpen(false);
33165
+ s.setIsMobileInsertOpen(false);
32817
33166
  s.setIsInspectorPaneOpen(false);
32818
33167
  s.setIsSlideNotesCollapsed(true);
32819
33168
  }, openSheet = (which) => {
@@ -32822,6 +33171,9 @@ function MobileChromeOverlay(props) {
32822
33171
  case "slides":
32823
33172
  s.setIsSlidesPaneOpen(true);
32824
33173
  break;
33174
+ case "insert":
33175
+ s.setIsMobileInsertOpen(true);
33176
+ break;
32825
33177
  case "inspector":
32826
33178
  s.setSidebarPanelMode("properties");
32827
33179
  s.setIsInspectorPaneOpen(true);
@@ -32897,9 +33249,7 @@ function MobileChromeOverlay(props) {
32897
33249
  activeSheet,
32898
33250
  commentCount,
32899
33251
  onOpenSlides: () => applySheetTap("slides"),
32900
- onOpenInsert: () => {
32901
- editorOps.insertHandlers.handleAddTextBox();
32902
- },
33252
+ onOpenInsert: () => applySheetTap("insert"),
32903
33253
  onOpenInspector: () => applySheetTap("inspector"),
32904
33254
  onOpenComments: () => applySheetTap("comments"),
32905
33255
  onToggleNotes: () => applySheetTap("notes")
@@ -33070,157 +33420,6 @@ function OptionsAddInsPane({ addinStatus }) {
33070
33420
  ] })
33071
33421
  ] });
33072
33422
  }
33073
- function readValue(options, control) {
33074
- const group = options[control.group];
33075
- const value = group[control.key];
33076
- return typeof value === "boolean" || typeof value === "number" || typeof value === "string" ? value : void 0;
33077
- }
33078
- function InfoTip({ text }) {
33079
- return /* @__PURE__ */ jsx("span", { title: text, className: "inline-flex cursor-help align-middle", children: /* @__PURE__ */ jsx(LuInfo, { className: "ml-1 h-3.5 w-3.5 text-primary/70", "aria-label": text }) });
33080
- }
33081
- var IGNORE_CHANGE = () => void 0;
33082
- function ControlRow({
33083
- control,
33084
- options,
33085
- onOptionChange: emitChange
33086
- }) {
33087
- const { t } = useTranslation();
33088
- const { viewportWidth } = useIsMobile();
33089
- const fieldMinHeight = getDensePanelTouchTargetPx(viewportWidth);
33090
- const value = readValue(options, control);
33091
- const label = t(control.labelKey);
33092
- const info = control.infoKey ? /* @__PURE__ */ jsx(InfoTip, { text: t(control.infoKey) }) : null;
33093
- const rowClass = cn("flex items-center justify-between gap-3 py-1.5", control.indent && "pl-6");
33094
- const rowStyle = { minHeight: fieldMinHeight };
33095
- const locked = control.readOnly === true;
33096
- const lockedTitle = locked ? t("pptx.options.lockedByHost") : void 0;
33097
- const onOptionChange = locked ? IGNORE_CHANGE : emitChange;
33098
- if (control.kind === "toggle") {
33099
- return /* @__PURE__ */ jsxs("label", { className: cn(rowClass, "cursor-pointer select-none"), style: rowStyle, children: [
33100
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-foreground", children: [
33101
- label,
33102
- info
33103
- ] }),
33104
- /* @__PURE__ */ jsx(
33105
- WebCheckbox,
33106
- {
33107
- checked: value === true,
33108
- "aria-label": label,
33109
- disabled: locked,
33110
- title: lockedTitle,
33111
- onChange: (event) => onOptionChange(
33112
- control.group,
33113
- control.key,
33114
- event.currentTarget.checked
33115
- )
33116
- }
33117
- )
33118
- ] });
33119
- }
33120
- if (control.kind === "select") {
33121
- return /* @__PURE__ */ jsxs("div", { className: rowClass, style: rowStyle, children: [
33122
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-foreground", children: [
33123
- label,
33124
- info
33125
- ] }),
33126
- /* @__PURE__ */ jsx(
33127
- WebSelect,
33128
- {
33129
- "aria-label": label,
33130
- disabled: locked,
33131
- title: lockedTitle,
33132
- style: { minHeight: fieldMinHeight },
33133
- value: typeof value === "string" ? value : "",
33134
- onChange: (event) => onOptionChange(
33135
- control.group,
33136
- control.key,
33137
- event.currentTarget.value
33138
- ),
33139
- children: control.choices.map((choice) => /* @__PURE__ */ jsx("option", { value: choice.value, children: t(choice.labelKey) }, choice.value))
33140
- }
33141
- )
33142
- ] });
33143
- }
33144
- if (control.kind === "number") {
33145
- return /* @__PURE__ */ jsxs("div", { className: rowClass, style: rowStyle, children: [
33146
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-foreground", children: [
33147
- label,
33148
- info
33149
- ] }),
33150
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
33151
- /* @__PURE__ */ jsx(
33152
- "input",
33153
- {
33154
- type: "number",
33155
- "aria-label": label,
33156
- disabled: locked,
33157
- title: lockedTitle,
33158
- style: { minHeight: fieldMinHeight },
33159
- className: "w-20 rounded border border-border bg-background px-2 py-1 text-right text-xs text-foreground",
33160
- min: control.min,
33161
- max: control.max,
33162
- step: control.step ?? 1,
33163
- value: typeof value === "number" ? value : control.min,
33164
- onChange: (event) => {
33165
- const clamped = clampOptionNumber(event.target.value, control.min, control.max);
33166
- if (clamped !== void 0) {
33167
- onOptionChange(control.group, control.key, clamped);
33168
- }
33169
- }
33170
- }
33171
- ),
33172
- control.unitKey && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t(control.unitKey) })
33173
- ] })
33174
- ] });
33175
- }
33176
- return /* @__PURE__ */ jsxs("div", { className: rowClass, style: rowStyle, children: [
33177
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-foreground", children: [
33178
- label,
33179
- info
33180
- ] }),
33181
- /* @__PURE__ */ jsx(
33182
- "input",
33183
- {
33184
- type: "text",
33185
- "aria-label": label,
33186
- disabled: locked,
33187
- title: lockedTitle,
33188
- style: { minHeight: fieldMinHeight },
33189
- className: "w-48 max-w-[55%] rounded border border-border bg-background px-2 py-1 text-xs text-foreground",
33190
- maxLength: control.maxLength,
33191
- value: typeof value === "string" ? value : "",
33192
- onChange: (event) => onOptionChange(control.group, control.key, event.target.value)
33193
- }
33194
- )
33195
- ] });
33196
- }
33197
- function OptionsPane({
33198
- tab,
33199
- options,
33200
- onOptionChange,
33201
- renderSpecial,
33202
- children
33203
- }) {
33204
- const { t } = useTranslation();
33205
- return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
33206
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t(tab.descriptionKey) }),
33207
- tab.sections.map((section) => /* @__PURE__ */ jsxs("section", { children: [
33208
- /* @__PURE__ */ jsx("h3", { className: "mb-1 border-b border-border/60 pb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: t(section.titleKey) }),
33209
- section.descriptionKey && /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs text-muted-foreground", children: t(section.descriptionKey) }),
33210
- /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: section.controls.map((control) => /* @__PURE__ */ jsx(
33211
- ControlRow,
33212
- {
33213
- control,
33214
- options,
33215
- onOptionChange
33216
- },
33217
- `${control.group}.${control.key}.${section.id}`
33218
- )) }),
33219
- section.special && renderSpecial?.(section)
33220
- ] }, section.id)),
33221
- children
33222
- ] });
33223
- }
33224
33423
  function CommandList({
33225
33424
  title,
33226
33425
  commandIds,
@@ -33423,7 +33622,7 @@ function OptionsRibbonPane({
33423
33622
  ] }),
33424
33623
  /* @__PURE__ */ jsxs("section", { children: [
33425
33624
  /* @__PURE__ */ jsx("h3", { className: "mb-1 border-b border-border/60 pb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: t("pptx.settings.keyboardShortcuts") }),
33426
- /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: SHORTCUT_REFERENCE_ITEMS.map((shortcut, i) => /* @__PURE__ */ jsxs(
33625
+ /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: SHORTCUT_REFERENCE_ITEMS$1.map((shortcut, i) => /* @__PURE__ */ jsxs(
33427
33626
  "div",
33428
33627
  {
33429
33628
  className: cn(
@@ -33665,10 +33864,11 @@ function SettingsLanguageTab({
33665
33864
  );
33666
33865
  }) });
33667
33866
  }
33668
- var AI_TAB_ID = "ai";
33669
33867
  var NO_CUSTOM_FONT_FAMILIES = [];
33670
- function SettingsDialog({
33671
- isOpen,
33868
+ function SettingsDialog(props) {
33869
+ return props.isOpen ? /* @__PURE__ */ jsx(OpenSettingsDialog, { ...props }) : null;
33870
+ }
33871
+ function OpenSettingsDialog({
33672
33872
  onClose,
33673
33873
  options,
33674
33874
  onOptionChange,
@@ -33689,272 +33889,98 @@ function SettingsDialog({
33689
33889
  customFontFamilies = NO_CUSTOM_FONT_FAMILIES,
33690
33890
  onCustomFontRegistered
33691
33891
  }) {
33692
- const [activeTabId, setActiveTabId] = useState("general");
33693
33892
  const { t } = useTranslation();
33694
33893
  const customization = useViewerCustomizationContext();
33695
- const { panelStyle, handlers: dragHandlers } = useModalDismissDrag(onClose);
33696
- const { viewportWidth, viewportHeight } = useIsMobile();
33697
- const touchTargetPx = getDensePanelTouchTargetPx(viewportWidth);
33698
- const navBtnStyle = { minHeight: touchTargetPx, minWidth: touchTargetPx };
33699
- const closeBtnStyle = { minWidth: touchTargetPx, minHeight: touchTargetPx };
33700
- const footerBtnStyle = { minHeight: touchTargetPx };
33701
- const stickyFooterClass = shouldStickyActionRow(viewportWidth, viewportHeight) ? "sticky bottom-0 bg-popover" : "";
33702
- const snapshotRef = useRef(null);
33703
- const wasOpenRef = useRef(false);
33704
- useEffect(() => {
33705
- if (isOpen && !wasOpenRef.current) {
33706
- snapshotRef.current = options;
33707
- }
33708
- wasOpenRef.current = isOpen;
33709
- }, [isOpen, options]);
33710
- const handleCancel = useCallback(() => {
33711
- if (snapshotRef.current) {
33712
- onRestoreOptions(snapshotRef.current);
33713
- }
33714
- onClose();
33715
- }, [onClose, onRestoreOptions]);
33716
- const handleKeyDown = useCallback(
33717
- (e) => {
33718
- if (e.key === "Escape") {
33719
- onClose();
33720
- }
33721
- },
33722
- [onClose]
33894
+ const regionBase = useContext(ViewerRegionBaseContext);
33895
+ const regionContext = useMemo(
33896
+ () => regionBase ? { ...regionBase, region: "dialog.options", close: onClose } : null,
33897
+ [regionBase, onClose]
33723
33898
  );
33724
- useEffect(() => {
33725
- if (isOpen) {
33726
- document.addEventListener("keydown", handleKeyDown);
33727
- return () => document.removeEventListener("keydown", handleKeyDown);
33728
- }
33729
- }, [isOpen, handleKeyDown]);
33730
- if (!isOpen) {
33731
- return null;
33732
- }
33733
- const tabs = customizeOptionsTabs(VIEWER_OPTIONS_TABS, customization);
33734
- const showAiTab = Boolean(aiEnabled) && isOptionsPageVisible(customization, AI_TAB_ID);
33735
- const activeTab = tabs.find((tab) => tab.id === activeTabId) ?? tabs[0];
33736
- const aiActive = activeTabId === AI_TAB_ID && showAiTab;
33737
- if (!activeTab) {
33738
- return null;
33739
- }
33740
- const currentTabId = aiActive ? AI_TAB_ID : activeTab.id;
33741
- return /* @__PURE__ */ jsxs(Fragment, { children: [
33742
- /* @__PURE__ */ jsx(
33743
- "button",
33899
+ const dialogRef = useRef(null);
33900
+ const bindingRef = useRef(null);
33901
+ const [category, setCategory] = useState("general");
33902
+ const latest = useRef({ onClose, onOptionChange, onRestoreOptions, onResetOptions });
33903
+ latest.current = { onClose, onOptionChange, onRestoreOptions, onResetOptions };
33904
+ useLayoutEffect(() => {
33905
+ const binding = bindPptxOptionsDialog(dialogRef.current, {
33906
+ setOption: (group, key, value) => latest.current.onOptionChange(group, key, value),
33907
+ restoreOptions: (snapshot) => latest.current.onRestoreOptions(snapshot),
33908
+ resetOptions: () => latest.current.onResetOptions(),
33909
+ close: () => latest.current.onClose(),
33910
+ categoryChanged: setCategory
33911
+ });
33912
+ bindingRef.current = binding;
33913
+ return () => {
33914
+ binding.dispose();
33915
+ bindingRef.current = null;
33916
+ };
33917
+ }, []);
33918
+ useLayoutEffect(() => {
33919
+ bindingRef.current?.sync({
33920
+ options,
33921
+ t,
33922
+ customization,
33923
+ aiEnabled: Boolean(aiEnabled),
33924
+ regionContext
33925
+ });
33926
+ }, [options, t, customization, aiEnabled, regionContext]);
33927
+ return /* @__PURE__ */ jsxs("pptx-ui-options-dialog", { ref: dialogRef, children: [
33928
+ category === "general" && /* @__PURE__ */ jsxs(Fragment, { children: [
33929
+ /* @__PURE__ */ jsx("div", { slot: optionsBlockSlot("themePicker"), className: "mt-2", children: /* @__PURE__ */ jsx(
33930
+ SettingsAppearanceTab,
33931
+ {
33932
+ activeThemeKey: themeKey,
33933
+ themes: availableThemes,
33934
+ onSelectTheme
33935
+ }
33936
+ ) }),
33937
+ /* @__PURE__ */ jsx("div", { slot: optionsBlockSlot("customFonts"), children: /* @__PURE__ */ jsx(
33938
+ SettingsCustomFontsSection,
33939
+ {
33940
+ enabled: options.general.enableCustomFontUpload,
33941
+ families: customFontFamilies,
33942
+ onRegistered: (family) => onCustomFontRegistered?.(family)
33943
+ }
33944
+ ) })
33945
+ ] }),
33946
+ category === "save" && /* @__PURE__ */ jsxs("div", { slot: optionsBlockSlot("clearCache"), className: "mt-2", children: [
33947
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs text-muted-foreground", children: t("pptx.options.save.clearCacheDescription") }),
33948
+ /* @__PURE__ */ jsx(
33949
+ "button",
33950
+ {
33951
+ type: "button",
33952
+ onClick: onClearCache,
33953
+ className: "rounded border border-border px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-accent",
33954
+ children: t("pptx.options.save.clearCacheNow")
33955
+ }
33956
+ )
33957
+ ] }),
33958
+ category === "language" && /* @__PURE__ */ jsx("div", { slot: optionsBlockSlot("language"), children: /* @__PURE__ */ jsx(
33959
+ SettingsLanguageTab,
33744
33960
  {
33745
- type: "button",
33746
- style: { zIndex: 1200 },
33747
- className: "fixed inset-0 bg-black/60",
33748
- "aria-label": t("pptx.settings.closeSettings"),
33749
- onClick: onClose
33961
+ activeLocale: localeCode,
33962
+ locales: availableLocales,
33963
+ onSelectLocale
33750
33964
  }
33751
- ),
33752
- /* @__PURE__ */ jsx(
33753
- "div",
33965
+ ) }),
33966
+ category === "ribbon" && /* @__PURE__ */ jsx("div", { slot: optionsPaneSlot("ribbon"), children: /* @__PURE__ */ jsx(
33967
+ OptionsRibbonPane,
33754
33968
  {
33755
- style: { zIndex: 1201 },
33756
- className: "fixed inset-0 flex items-center justify-center pointer-events-none",
33757
- children: /* @__PURE__ */ jsxs(
33758
- "div",
33759
- {
33760
- style: panelStyle,
33761
- role: "dialog",
33762
- "aria-modal": "true",
33763
- "aria-label": t("pptx.options.title"),
33764
- className: "pointer-events-auto flex max-h-[85vh] w-[min(56rem,calc(100%-2rem))] flex-col rounded-xl border border-border bg-popover shadow-2xl backdrop-blur-xl max-md:fixed max-md:inset-x-0 max-md:bottom-0 max-md:top-auto max-md:max-h-[88dvh] max-md:w-full max-md:rounded-t-2xl max-md:rounded-b-none max-md:border-x-0 max-md:border-b-0 max-md:pb-[max(env(safe-area-inset-bottom),0px)]",
33765
- children: [
33766
- /* @__PURE__ */ jsxs(
33767
- "div",
33768
- {
33769
- ...dragHandlers,
33770
- className: "flex items-center justify-between border-b border-border/60 px-5 py-4 touch-none",
33771
- children: [
33772
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
33773
- /* @__PURE__ */ jsx(LuSettings, { className: "h-5 w-5 text-primary" }),
33774
- /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("pptx.options.title") })
33775
- ] }),
33776
- /* @__PURE__ */ jsx(
33777
- "button",
33778
- {
33779
- type: "button",
33780
- onClick: onClose,
33781
- style: closeBtnStyle,
33782
- className: "rounded p-1 transition-colors hover:bg-accent inline-flex items-center justify-center",
33783
- "aria-label": t("pptx.settings.close"),
33784
- children: /* @__PURE__ */ jsx(LuX, { className: "h-4 w-4 text-muted-foreground" })
33785
- }
33786
- )
33787
- ]
33788
- }
33789
- ),
33790
- /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 max-md:flex-col", children: [
33791
- /* @__PURE__ */ jsxs(
33792
- "nav",
33793
- {
33794
- "aria-label": t("pptx.options.title"),
33795
- className: "w-44 shrink-0 space-y-0.5 overflow-y-auto border-r border-border/60 p-2 max-md:flex max-md:w-full max-md:space-y-0 max-md:gap-1 max-md:overflow-x-auto max-md:border-b max-md:border-r-0",
33796
- children: [
33797
- tabs.map((tab) => /* @__PURE__ */ jsx(
33798
- "button",
33799
- {
33800
- type: "button",
33801
- onClick: () => setActiveTabId(tab.id),
33802
- "aria-current": currentTabId === tab.id,
33803
- style: navBtnStyle,
33804
- className: cn(
33805
- "flex w-full items-center whitespace-nowrap rounded px-3 py-2 text-left text-sm transition-colors max-md:w-auto",
33806
- currentTabId === tab.id ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
33807
- ),
33808
- children: t(tab.labelKey)
33809
- },
33810
- tab.id
33811
- )),
33812
- showAiTab && /* @__PURE__ */ jsx(
33813
- "button",
33814
- {
33815
- type: "button",
33816
- onClick: () => setActiveTabId(AI_TAB_ID),
33817
- "aria-current": aiActive,
33818
- style: navBtnStyle,
33819
- className: cn(
33820
- "flex w-full items-center whitespace-nowrap rounded px-3 py-2 text-left text-sm transition-colors max-md:w-auto",
33821
- aiActive ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
33822
- ),
33823
- children: t("pptx.ai.settingsSectionTitle")
33824
- }
33825
- )
33826
- ]
33827
- }
33828
- ),
33829
- /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-5 py-4", children: aiActive ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33830
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t("pptx.ai.settingsSectionTitle") }),
33831
- /* @__PURE__ */ jsx(SettingsAiTab, { store: chatStore })
33832
- ] }) : activeTab.custom === "language" ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33833
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t(activeTab.descriptionKey) }),
33834
- /* @__PURE__ */ jsxs("section", { children: [
33835
- /* @__PURE__ */ jsx("h3", { className: "mb-1 border-b border-border/60 pb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: t("pptx.options.language.displayLanguage") }),
33836
- /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs text-muted-foreground", children: t("pptx.options.language.displayLanguageDescription") }),
33837
- /* @__PURE__ */ jsx(
33838
- SettingsLanguageTab,
33839
- {
33840
- activeLocale: localeCode,
33841
- locales: availableLocales,
33842
- onSelectLocale
33843
- }
33844
- )
33845
- ] })
33846
- ] }) : activeTab.custom === "ribbon" ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33847
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t(activeTab.descriptionKey) }),
33848
- /* @__PURE__ */ jsx(
33849
- OptionsRibbonPane,
33850
- {
33851
- options,
33852
- onRibbonTabHiddenChange,
33853
- onResetRibbon: () => onResetOptions("ribbon")
33854
- }
33855
- )
33856
- ] }) : activeTab.custom === "addIns" ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
33857
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t(activeTab.descriptionKey) }),
33858
- /* @__PURE__ */ jsx(OptionsAddInsPane, { addinStatus })
33859
- ] }) : /* @__PURE__ */ jsx(
33860
- OptionsPane,
33861
- {
33862
- tab: activeTab,
33863
- options,
33864
- onOptionChange,
33865
- renderSpecial: (section) => {
33866
- if (section.special === "themePicker") {
33867
- return /* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsx(
33868
- SettingsAppearanceTab,
33869
- {
33870
- activeThemeKey: themeKey,
33871
- themes: availableThemes,
33872
- onSelectTheme
33873
- }
33874
- ) });
33875
- }
33876
- if (section.special === "customFonts") {
33877
- return /* @__PURE__ */ jsx(
33878
- SettingsCustomFontsSection,
33879
- {
33880
- enabled: options.general.enableCustomFontUpload,
33881
- families: customFontFamilies,
33882
- onRegistered: (family) => onCustomFontRegistered?.(family)
33883
- }
33884
- );
33885
- }
33886
- if (section.special === "clearCache") {
33887
- return /* @__PURE__ */ jsxs("div", { className: "mt-2", children: [
33888
- /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs text-muted-foreground", children: t("pptx.options.save.clearCacheDescription") }),
33889
- /* @__PURE__ */ jsx(
33890
- "button",
33891
- {
33892
- type: "button",
33893
- onClick: onClearCache,
33894
- className: "rounded border border-border px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-accent",
33895
- children: t("pptx.options.save.clearCacheNow")
33896
- }
33897
- )
33898
- ] });
33899
- }
33900
- return null;
33901
- },
33902
- children: activeTab.custom === "quickAccess" && /* @__PURE__ */ jsx(
33903
- OptionsQuickAccessPane,
33904
- {
33905
- options,
33906
- onQuickAccessCommandsChange,
33907
- onResetQuickAccess: () => onQuickAccessCommandsChange([...DEFAULT_QUICK_ACCESS_COMMAND_IDS])
33908
- }
33909
- )
33910
- }
33911
- ) })
33912
- ] }),
33913
- /* @__PURE__ */ jsxs(
33914
- "div",
33915
- {
33916
- className: `flex items-center justify-between gap-2 border-t border-border/60 px-5 py-3 ${stickyFooterClass}`,
33917
- children: [
33918
- /* @__PURE__ */ jsx(
33919
- "button",
33920
- {
33921
- type: "button",
33922
- onClick: () => onResetOptions(),
33923
- style: footerBtnStyle,
33924
- className: "rounded border border-border px-3 py-1.5 text-xs text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
33925
- children: t("pptx.options.resetAll")
33926
- }
33927
- ),
33928
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
33929
- /* @__PURE__ */ jsx(
33930
- "button",
33931
- {
33932
- type: "button",
33933
- onClick: handleCancel,
33934
- style: footerBtnStyle,
33935
- className: "rounded border border-border px-4 py-1.5 text-xs text-foreground transition-colors hover:bg-accent",
33936
- children: t("pptx.common.cancel")
33937
- }
33938
- ),
33939
- /* @__PURE__ */ jsx(
33940
- "button",
33941
- {
33942
- type: "button",
33943
- onClick: onClose,
33944
- style: footerBtnStyle,
33945
- className: "rounded bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90",
33946
- children: t("pptx.common.ok")
33947
- }
33948
- )
33949
- ] })
33950
- ]
33951
- }
33952
- )
33953
- ]
33954
- }
33955
- )
33969
+ options,
33970
+ onRibbonTabHiddenChange,
33971
+ onResetRibbon: () => onResetOptions("ribbon")
33956
33972
  }
33957
- )
33973
+ ) }),
33974
+ category === "quickAccess" && /* @__PURE__ */ jsx("div", { slot: optionsPaneSlot("quickAccess"), children: /* @__PURE__ */ jsx(
33975
+ OptionsQuickAccessPane,
33976
+ {
33977
+ options,
33978
+ onQuickAccessCommandsChange,
33979
+ onResetQuickAccess: () => onQuickAccessCommandsChange([...DEFAULT_QUICK_ACCESS_COMMAND_IDS])
33980
+ }
33981
+ ) }),
33982
+ category === "addIns" && /* @__PURE__ */ jsx("div", { slot: optionsPaneSlot("addIns"), children: /* @__PURE__ */ jsx(OptionsAddInsPane, { addinStatus }) }),
33983
+ category === AI_OPTIONS_CATEGORY && /* @__PURE__ */ jsx("div", { slot: optionsPaneSlot(AI_OPTIONS_CATEGORY), children: /* @__PURE__ */ jsx(SettingsAiTab, { store: chatStore }) })
33958
33984
  ] });
33959
33985
  }
33960
33986
  function ViewerOptionsProvider({
@@ -34250,6 +34276,89 @@ function useAutosaveCacheMaintenance(viewerOptions) {
34250
34276
  }, [viewerOptions]);
34251
34277
  return handleClearOptionsCache;
34252
34278
  }
34279
+ function useChartFormatCommands(input) {
34280
+ const { selectedElement, editable, updateElementById } = input;
34281
+ const chart = selectedElement?.type === "chart" ? selectedElement : null;
34282
+ const chartId = chart?.id ?? null;
34283
+ const [picked, setPicked] = useState({
34284
+ chartId: null,
34285
+ target: "chartArea"
34286
+ });
34287
+ const [paneOpen, setPaneOpen] = useState(false);
34288
+ const target = picked.chartId === chartId ? picked.target : "chartArea";
34289
+ useEffect(() => {
34290
+ if (!chartId) {
34291
+ setPaneOpen(false);
34292
+ }
34293
+ }, [chartId]);
34294
+ const setTarget = useCallback(
34295
+ (next, forChartId) => setPicked({ chartId: forChartId ?? chartId, target: next }),
34296
+ [chartId]
34297
+ );
34298
+ const openPane = useCallback(
34299
+ (next) => {
34300
+ if (next) {
34301
+ setTarget(next);
34302
+ }
34303
+ setPaneOpen(true);
34304
+ },
34305
+ [setTarget]
34306
+ );
34307
+ const closePane = useCallback(() => setPaneOpen(false), []);
34308
+ const applyChartData = useCallback(
34309
+ (chartData2) => {
34310
+ if (editable && chartId) {
34311
+ updateElementById(chartId, { chartData: chartData2 });
34312
+ }
34313
+ },
34314
+ [editable, chartId, updateElementById]
34315
+ );
34316
+ const chartData = chart?.type === "chart" ? chart.chartData : void 0;
34317
+ const reset = useCallback(() => {
34318
+ if (chartData) {
34319
+ applyChartData(resetChartFormatTarget(chartData, target));
34320
+ }
34321
+ }, [chartData, target, applyChartData]);
34322
+ return useMemo(
34323
+ () => ({
34324
+ chart,
34325
+ editable,
34326
+ target,
34327
+ paneOpen: paneOpen && Boolean(chart),
34328
+ setTarget,
34329
+ openPane,
34330
+ closePane,
34331
+ applyChartData,
34332
+ reset
34333
+ }),
34334
+ [chart, editable, target, paneOpen, setTarget, openPane, closePane, applyChartData, reset]
34335
+ );
34336
+ }
34337
+ function useLoadNotifications(input) {
34338
+ const { loading, error } = input;
34339
+ const latest = useRef(input);
34340
+ latest.current = input;
34341
+ const wasLoading = useRef(loading);
34342
+ const announcedError = useRef(null);
34343
+ useEffect(() => {
34344
+ const finished = wasLoading.current && !loading;
34345
+ wasLoading.current = loading;
34346
+ if (finished && !latest.current.error) {
34347
+ latest.current.onLoad?.({
34348
+ slideCount: latest.current.slideCount,
34349
+ canvasSize: latest.current.canvasSize
34350
+ });
34351
+ }
34352
+ }, [loading]);
34353
+ useEffect(() => {
34354
+ if (error && error !== announcedError.current) {
34355
+ announcedError.current = error;
34356
+ latest.current.onError?.(error);
34357
+ } else if (!error) {
34358
+ announcedError.current = null;
34359
+ }
34360
+ }, [error]);
34361
+ }
34253
34362
  function useMasterViewCrud(input) {
34254
34363
  const {
34255
34364
  handlerRef,
@@ -34363,7 +34472,8 @@ function useRibbonGalleryCommands2(input) {
34363
34472
  tableEditorState,
34364
34473
  updateElementById,
34365
34474
  updateThemeColorScheme,
34366
- updateThemeFontScheme
34475
+ updateThemeFontScheme,
34476
+ applyThemeData
34367
34477
  } = input;
34368
34478
  const handler = handlerRef.current;
34369
34479
  const context = useMemo(
@@ -34385,6 +34495,9 @@ function useRibbonGalleryCommands2(input) {
34385
34495
  case "element":
34386
34496
  updateElementById(result.elementId, result.patch);
34387
34497
  return;
34498
+ case "theme":
34499
+ void applyThemeData?.(result.colorScheme, result.fontScheme, result.name);
34500
+ return;
34388
34501
  case "themeColorScheme":
34389
34502
  void updateThemeColorScheme(result.colorScheme);
34390
34503
  return;
@@ -34392,7 +34505,7 @@ function useRibbonGalleryCommands2(input) {
34392
34505
  void updateThemeFontScheme(result.fontScheme);
34393
34506
  }
34394
34507
  },
34395
- [editable, updateElementById, updateThemeColorScheme, updateThemeFontScheme]
34508
+ [editable, updateElementById, updateThemeColorScheme, updateThemeFontScheme, applyThemeData]
34396
34509
  );
34397
34510
  return useMemo(() => ({ context, editable, dispatch }), [context, editable, dispatch]);
34398
34511
  }
@@ -34623,6 +34736,8 @@ var PowerPointViewer = forwardRef(
34623
34736
  onZoomChange,
34624
34737
  onSelectionChange,
34625
34738
  onSlideCountChange,
34739
+ onLoad,
34740
+ onError,
34626
34741
  onOpenFile: hostOpenFile,
34627
34742
  theme,
34628
34743
  defaultThemeKey,
@@ -34765,7 +34880,7 @@ var PowerPointViewer = forwardRef(
34765
34880
  const [notesBarHeight, setNotesBarHeight] = useState(0);
34766
34881
  const runProgramNoticesState = useRunProgramNoticesState();
34767
34882
  const [collaborationReadOnly, setCollaborationReadOnly] = useState(Boolean(collaboration));
34768
- const canEdit = hostCanEdit && !collaborationReadOnly && !isProtectedView && !readOnlyRec.locked;
34883
+ const canEdit = hostCanEdit && isEditingAllowed(customizationResolved) && !collaborationReadOnly && !isProtectedView && !readOnlyRec.locked;
34769
34884
  const [isSettingsOpen, setIsSettingsOpen] = useState(false);
34770
34885
  const [isHeaderFooterOpen, setIsHeaderFooterOpen] = useState(false);
34771
34886
  const [autosaveEnabled, setAutosaveEnabled] = useState(true);
@@ -34797,6 +34912,14 @@ var PowerPointViewer = forwardRef(
34797
34912
  activeSlide,
34798
34913
  selectedElement
34799
34914
  } = state;
34915
+ useLoadNotifications({
34916
+ loading,
34917
+ error,
34918
+ slideCount: slides.length,
34919
+ canvasSize,
34920
+ onLoad,
34921
+ onError
34922
+ });
34800
34923
  const { pushColor } = useRecentColorsSync({
34801
34924
  setRecentColors: state.setRecentColors,
34802
34925
  setPresentationProperties: state.setPresentationProperties
@@ -35150,6 +35273,7 @@ ${url}`)
35150
35273
  isEncryptedDialogOpen,
35151
35274
  setIsEncryptedDialogOpen,
35152
35275
  handlerRef,
35276
+ viewerApi,
35153
35277
  loadVersion
35154
35278
  } = useViewerIntegration({
35155
35279
  transformCommittedText: (text) => applyAutoCorrect(text, viewerOptions.proofing),
@@ -35252,7 +35376,13 @@ ${url}`)
35252
35376
  tableEditorState: state.tableEditorState,
35253
35377
  updateElementById: editorOps.ops.updateElementById,
35254
35378
  updateThemeColorScheme: themeHandlers.handleUpdateThemeColorScheme,
35255
- updateThemeFontScheme: themeHandlers.handleUpdateThemeFontScheme
35379
+ updateThemeFontScheme: themeHandlers.handleUpdateThemeFontScheme,
35380
+ applyThemeData: themeHandlers.handleApplyThemeData
35381
+ });
35382
+ const chartFormat = useChartFormatCommands({
35383
+ selectedElement,
35384
+ editable: canEdit && (mode === "edit" || mode === "master"),
35385
+ updateElementById: editorOps.ops.updateElementById
35256
35386
  });
35257
35387
  const ribbonScope = useRibbonScopeToken();
35258
35388
  const viewPreferencesSync = useViewPreferencesSync({
@@ -35381,6 +35511,20 @@ ${url}`)
35381
35511
  collaboration: Boolean(collaboration),
35382
35512
  locales: resolvedLocales.length > 1
35383
35513
  };
35514
+ const selectionKey = state.effectiveSelectedIds.join("\0");
35515
+ const regionBase = useMemo(
35516
+ () => ({
35517
+ viewer: viewerApi,
35518
+ mode,
35519
+ canEdit,
35520
+ activeSlideIndex,
35521
+ slideCount: slides.length,
35522
+ selectedElementIds: [...state.effectiveSelectedIds],
35523
+ locale: localeCode
35524
+ }),
35525
+ // oxlint-disable-next-line react-hooks/exhaustive-deps -- selectionKey stands for the ids
35526
+ [viewerApi, mode, canEdit, activeSlideIndex, slides.length, selectionKey, localeCode]
35527
+ );
35384
35528
  const viewerContent = /* @__PURE__ */ jsxs(
35385
35529
  "div",
35386
35530
  {
@@ -35451,7 +35595,7 @@ ${url}`)
35451
35595
  isAiPanelOpen: aiPanel.isOpen,
35452
35596
  onToggleAiPanel: aiPanel.toggle,
35453
35597
  isProtectedView,
35454
- onEnableEditing: hostCanEdit ? handleEnableEditing : void 0,
35598
+ onEnableEditing: hostCanEdit && isEditingAllowed(customizationResolved) ? handleEnableEditing : void 0,
35455
35599
  onSetSnapToGrid: viewPreferencesSync.handleSetSnapToGrid,
35456
35600
  onSetSnapToShape: viewPreferencesSync.handleSetSnapToShape,
35457
35601
  onSetShowGuides: viewPreferencesSync.handleSetShowGuides
@@ -35615,7 +35759,7 @@ ${url}`)
35615
35759
  /* @__PURE__ */ jsx(
35616
35760
  PasteSpecialDialog,
35617
35761
  {
35618
- isOpen: editorOps.pasteSpecial.isPasteSpecialDialogOpen,
35762
+ isOpen: editorOps.pasteSpecial.isPasteSpecialDialogOpen && isDialogAvailable(customizationResolved, "pasteSpecial"),
35619
35763
  onCancel: editorOps.pasteSpecial.closePasteSpecialDialog,
35620
35764
  onConfirm: (format) => {
35621
35765
  void editorOps.pasteSpecial.pasteWithFormat(format);
@@ -35784,7 +35928,7 @@ ${url}`)
35784
35928
  // Nothing previously provided it, so every one of those consumers was
35785
35929
  // silently reading `DEFAULT_VIEWER_OPTIONS` forever, no matter what
35786
35930
  // the user changed in the Options dialog.
35787
- /* @__PURE__ */ jsx(ViewerOptionsProvider, { options: viewerOptions, store: optionsStore, children: /* @__PURE__ */ jsx(ViewerCustomizationContext.Provider, { value: customizationResolved, children: /* @__PURE__ */ jsx(RibbonAddInsContext.Provider, { value: ribbonAddIns ?? NO_RIBBON_ADD_INS, children: /* @__PURE__ */ jsx(AccountAuthContext.Provider, { value: accountAuth, children: /* @__PURE__ */ jsx(Rendering3DFlagsContext.Provider, { value: effective3D, children: /* @__PURE__ */ jsx(ViewerThemeProvider, { theme: effectiveTheme, children: /* @__PURE__ */ jsxs(
35931
+ /* @__PURE__ */ jsx(ViewerOptionsProvider, { options: viewerOptions, store: optionsStore, children: /* @__PURE__ */ jsx(ViewerCustomizationContext.Provider, { value: customizationResolved, children: /* @__PURE__ */ jsx(ViewerRegionBaseContext.Provider, { value: regionBase, children: /* @__PURE__ */ jsx(RibbonAddInsContext.Provider, { value: ribbonAddIns ?? NO_RIBBON_ADD_INS, children: /* @__PURE__ */ jsx(AccountAuthContext.Provider, { value: accountAuth, children: /* @__PURE__ */ jsx(Rendering3DFlagsContext.Provider, { value: effective3D, children: /* @__PURE__ */ jsx(ViewerThemeProvider, { theme: effectiveTheme, children: /* @__PURE__ */ jsxs(
35788
35932
  CollaborationProvider,
35789
35933
  {
35790
35934
  config: collaboration,
@@ -35834,10 +35978,10 @@ ${url}`)
35834
35978
  slideCount: slides.length
35835
35979
  }
35836
35980
  ),
35837
- /* @__PURE__ */ jsx(ShapeFormatContext.Provider, { value: shapeFormat, children: /* @__PURE__ */ jsx(RibbonGalleryCommandsContext.Provider, { value: ribbonGalleries, children: viewerContent }) })
35981
+ /* @__PURE__ */ jsx(ShapeFormatContext.Provider, { value: shapeFormat, children: /* @__PURE__ */ jsx(RibbonGalleryCommandsContext.Provider, { value: ribbonGalleries, children: /* @__PURE__ */ jsx(ChartFormatContext.Provider, { value: chartFormat, children: viewerContent }) }) })
35838
35982
  ]
35839
35983
  }
35840
- ) }) }) }) }) }) })
35984
+ ) }) }) }) }) }) }) })
35841
35985
  );
35842
35986
  }
35843
35987
  );