markdown-flow-ui 0.2.26-dev.6 → 0.2.26-dev.7
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slide.es.js","sources":["../../../src/components/Slide/Slide.tsx"],"sourcesContent":["import React, {\n memo,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ChevronLeft, GripHorizontal } from \"lucide-react\";\n\nimport { isSandboxInteractionMessage } from \"../../lib/sandboxInteraction\";\nimport { cn } from \"../../lib/utils\";\nimport { useResolvedDirection } from \"../../lib/useResolvedDirection\";\nimport {\n getMarkdownFlowDirection,\n getMarkdownFlowLanguage,\n type MarkdownFlowLocale,\n} from \"../../lib/locale\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport ContentRender from \"../ContentRender\";\nimport type { ContentRenderProps } from \"../ContentRender/ContentRender\";\nimport IframeSandbox from \"../ContentRender/IframeSandbox\";\nimport type { OnSendContentParams } from \"../types\";\nimport type { InteractionDefaultValueOptions } from \"../../lib/interaction-defaults\";\nimport {\n isLandscapeViewport as getIsFullscreenPreferredViewport,\n isMobileDevice as getIsMobileDevice,\n subscribeMobileDeviceChange,\n} from \"../../lib/mobileDevice\";\nimport Player from \"./Player\";\nimport MarkdownSlideScaling from \"./MarkdownSlideScaling\";\nimport SubtitleOverlay from \"./SubtitleOverlay\";\nimport type {\n PlayerProps,\n SlidePlayerNavigationContext,\n SlidePlayerSubtitleJumpTarget,\n SlidePlayerSubtitleSeekRequest,\n SlidePlayerTexts,\n} from \"./Player\";\nimport type { SlidePlayerLoadingReason } from \"./Player\";\nimport type { Element } from \"./types\";\nimport useSlide from \"./useSlide\";\nimport useWakePlayerFromIframe from \"./useWakePlayerFromIframe\";\nimport { PlayerKeyboardShortcutContext } from \"./utils/playerKeyboardShortcutContext\";\nimport { activatePlayerKeyboardShortcutOwner } from \"./utils/playerKeyboardShortcuts\";\nimport {\n DEFAULT_MOBILE_VIEW_MODE,\n resolveMobileViewModeState,\n type MobileViewMode,\n} from \"./utils/mobileScreenMode\";\nimport {\n clampInteractionOverlayDragOffset,\n shouldPresentInteractionOverlay,\n shouldRenderInteractionOverlay,\n type InteractionOverlayDragBounds,\n type InteractionOverlayDragOffset,\n} from \"./utils/interactionPlayback\";\nimport { resolveMarkdownScalingMode } from \"./utils/markdownScaling\";\nimport { shouldWakePlayerControlsAfterNavigation } from \"./utils/playerNavigationContext\";\nimport { shouldAutoAdvanceIntoAppendedMarker } from \"./utils/appendedMarkerAdvance\";\nimport {\n hasUnplayedStepAudio,\n resolvePendingStepAudioKey,\n} from \"./utils/stepAudioProgress\";\nimport {\n getPlaybackSequenceTransition,\n shouldStartDefaultAudioSequence,\n} from \"./utils/playbackSequence\";\nimport {\n canReachSubtitleJumpTarget,\n hasResolvedInteractionElement,\n} from \"./utils/subtitleJumpNavigation\";\nimport {\n getPlayerCustomActionCount,\n resolvePlayerCustomActionElement,\n} from \"./utils/playerCustomActions\";\nimport { createPlaybackTimeStore } from \"./utils/playbackTimeStore\";\nimport { resolveSlideInteractionState } from \"./utils/interactionResolution\";\nimport { shouldUseAutoAdvanceToggle } from \"./utils/playerToggleMode\";\nimport {\n areImageOnlyStepIframeVisualsReady,\n DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS,\n} from \"./utils/imageOnlyStepVisualReady\";\nimport { resolveSilentStepAutoAdvanceBehavior } from \"./utils/silentStepAutoAdvance\";\nimport {\n resolveSlidePlayerLayoutState,\n resolveSlidePlayerVisibility,\n type SlidePlayerControlsVisibility,\n} from \"./utils/playerVisibility\";\nimport {\n DEFAULT_SLIDE_BUFFERING_TEXTS,\n getSlideLocaleTexts,\n type SlideBufferingReason,\n} from \"./slideI18n\";\nimport \"./slide.css\";\nexport type {\n Element,\n ElementAudioSegment,\n ElementSubtitleCue,\n SlidePlayerCustomActionContext,\n SlidePlayerCustomActions,\n} from \"./types\";\nexport type { SlidePlayerControlsVisibility } from \"./utils/playerVisibility\";\n\nconst DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS = 2000;\nconst DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS = 300;\nconst DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX = 160;\nconst DEFAULT_INTERACTION_SUBTITLE_GAP_PX = 16;\nconst DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS = 3000;\nconst DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET: InteractionOverlayDragOffset = {\n x: 0,\n y: 0,\n};\nconst INTERACTION_OVERLAY_LAYOUT_EPSILON_PX = 0.5;\ntype InteractionOverlayLayoutRect = Pick<DOMRect, \"left\" | \"top\">;\nconst useIsomorphicLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\nconst INTERACTION_ACTIVITY_SELECTOR = [\n \"button\",\n \"input\",\n \"textarea\",\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\"]',\n '[contenteditable=\"plaintext-only\"]',\n].join(\", \");\nconst DEFAULT_BUFFERING_REASON: SlideBufferingReason = \"waitingForAudio\";\n\nconst normalizeInteractionOverlayDragOffset = ({\n x,\n y,\n}: InteractionOverlayDragOffset): InteractionOverlayDragOffset => ({\n x: Number(x.toFixed(2)),\n y: Number(y.toFixed(2)),\n});\n\nconst hasMeaningfulInteractionOverlayLayoutDelta = (delta: number) =>\n Math.abs(delta) >= INTERACTION_OVERLAY_LAYOUT_EPSILON_PX;\n\nconst areInteractionOverlayDragOffsetsEqual = (\n first: InteractionOverlayDragOffset,\n second: InteractionOverlayDragOffset\n) =>\n Math.abs(first.x - second.x) < INTERACTION_OVERLAY_LAYOUT_EPSILON_PX &&\n Math.abs(first.y - second.y) < INTERACTION_OVERLAY_LAYOUT_EPSILON_PX;\n\nexport type { SlideBufferingReason } from \"./slideI18n\";\n\nexport type SlideBufferingTextConfig =\n | string\n | Partial<Record<SlideBufferingReason, string>>;\n\nconst resolveBufferingTextByReason = (\n bufferingText: SlideBufferingTextConfig,\n reason: SlideBufferingReason\n) => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return (\n bufferingText[reason] ??\n bufferingText[DEFAULT_BUFFERING_REASON] ??\n DEFAULT_SLIDE_BUFFERING_TEXTS[reason]\n );\n};\n\nconst mergeBufferingTextWithLocaleDefaults = (\n bufferingText: SlideBufferingTextConfig | undefined,\n localeBufferingText: Record<string, string>\n): SlideBufferingTextConfig => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return {\n ...localeBufferingText,\n ...bufferingText,\n };\n};\n\nconst shouldShowBufferingOverlay = (\n reason: SlideBufferingReason | null,\n loading: boolean\n) => {\n if (!loading) {\n return false;\n }\n\n // Keep the silent preload/loading phase invisible until audio is actually playable.\n return reason !== \"loadingAudio\";\n};\n\ntype RenderSlideElementOptions = {\n replaceRootScreenHeightWithFull?: boolean;\n};\n\ninterface InteractionOverlayCardProps {\n dir?: ContentRenderProps[\"dir\"];\n lang?: string;\n content: string;\n title: string;\n dragHandleAriaLabel: string;\n locale?: MarkdownFlowLocale;\n defaultButtonText?: string;\n defaultInputText?: string;\n defaultSelectedValues?: string[];\n confirmButtonText?: string;\n copyButtonText?: string;\n copiedButtonText?: string;\n onSend?: (content: OnSendContentParams) => void;\n onDragHandlePointerCancel?: React.PointerEventHandler<HTMLButtonElement>;\n onDragHandlePointerDown?: React.PointerEventHandler<HTMLButtonElement>;\n onDragHandlePointerMove?: React.PointerEventHandler<HTMLButtonElement>;\n onDragHandlePointerUp?: React.PointerEventHandler<HTMLButtonElement>;\n readonly?: boolean;\n}\n\nexport interface SlideInteractionTexts\n extends Pick<\n ContentRenderProps,\n \"confirmButtonText\" | \"copyButtonText\" | \"copiedButtonText\"\n > {\n title?: string;\n /** Accessible label for the interaction panel drag handle. */\n dragHandleAriaLabel?: string;\n}\n\nexport type SlideFullscreenHeader = {\n content?: React.ReactNode;\n backAriaLabel?: string;\n onBack?: () => void;\n};\n\nconst InteractionOverlayCard = memo(\n ({\n content,\n title,\n dragHandleAriaLabel,\n locale,\n dir,\n lang,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n onSend,\n onDragHandlePointerCancel,\n onDragHandlePointerDown,\n onDragHandlePointerMove,\n onDragHandlePointerUp,\n readonly = false,\n }: InteractionOverlayCardProps) => (\n <div className=\"slide-player__interaction-card\">\n <button\n type=\"button\"\n className=\"slide-player__interaction-drag-handle\"\n aria-label={dragHandleAriaLabel}\n onPointerCancel={onDragHandlePointerCancel}\n onPointerDown={onDragHandlePointerDown}\n onPointerMove={onDragHandlePointerMove}\n onPointerUp={onDragHandlePointerUp}\n >\n <span className=\"slide-player__interaction-drag-handle-icon\">\n <GripHorizontal aria-hidden=\"true\" />\n <GripHorizontal aria-hidden=\"true\" />\n <GripHorizontal aria-hidden=\"true\" />\n </span>\n </button>\n <div className=\"slide-player__interaction-header\">\n <p className=\"slide-player__interaction-title\">{title}</p>\n </div>\n <div className=\"slide-player__interaction-body\">\n <ContentRender\n content={content}\n locale={locale}\n dir={dir}\n lang={lang}\n defaultButtonText={defaultButtonText}\n defaultInputText={defaultInputText}\n defaultSelectedValues={defaultSelectedValues}\n confirmButtonText={confirmButtonText}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n onSend={onSend}\n readonly={readonly}\n sandboxMode=\"content\"\n />\n </div>\n </div>\n )\n);\n\nInteractionOverlayCard.displayName = \"InteractionOverlayCard\";\n\nconst areStepElementListsEqual = (\n prevElementList: Element[],\n nextElementList: Element[]\n) =>\n prevElementList.length === nextElementList.length &&\n prevElementList.every((element, index) => {\n const nextElement = nextElementList[index];\n\n return (\n element.sequence_number === nextElement?.sequence_number &&\n element.type === nextElement?.type &&\n element.content === nextElement?.content\n );\n });\n\nconst isInteractionActivityTarget = (\n target: EventTarget | null\n): target is HTMLElement =>\n target instanceof HTMLElement &&\n Boolean(target.closest(INTERACTION_ACTIVITY_SELECTOR));\nexport interface SlideProps extends React.ComponentProps<\"section\"> {\n elementList?: Element[];\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /** Enables the player runtime, including audio playback and keyboard shortcuts. */\n playerEnabled?: boolean;\n /**\n * Controls whether the player controls are always visible, always hidden, or auto-hidden.\n *\n * Use `\"hidden\"` to keep audio playback and keyboard shortcuts active while\n * hiding the visual controls.\n *\n * @example\n * ```tsx\n * <Slide playerControlsVisibility=\"hidden\" enableKeyboardShortcuts />\n * ```\n */\n playerControlsVisibility?: SlidePlayerControlsVisibility;\n playerClassName?: string;\n fullscreenHeader?: SlideFullscreenHeader;\n playerCustomActions?: PlayerProps[\"customActions\"];\n playerCustomActionPauseOnActive?: boolean;\n bufferingText?: SlideBufferingTextConfig;\n interactionTitle?: string;\n interactionTexts?: SlideInteractionTexts;\n playerTexts?: SlidePlayerTexts;\n playerAutoHideDelay?: number;\n markerAutoAdvanceDelay?: number;\n /** Shows an interactive navigation timeline for generated slide steps. */\n showSlideProgress?: boolean;\n /** Indicates that more generated slide steps may still be appended. */\n isSlideProgressGenerating?: boolean;\n /** Fired when a generated slide is selected from the progress navigation. */\n onSlideProgressNavigate?: (\n element: Element | undefined,\n index: number\n ) => void;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n onSend?: (content: OnSendContentParams, element?: Element) => void;\n onPlayerVisibilityChange?: (visible: boolean) => void;\n onMobileViewModeChange?: (viewMode: MobileViewMode) => void;\n onStepChange?: (element: Element | undefined, index: number) => void;\n /** Emits a low-frequency checkpoint for the active logical audio item. */\n onPlaybackCheckpoint?: (checkpoint: SlidePlaybackCheckpoint) => void;\n /** Restores one logical audio item and continues its normal playback. */\n playbackRestoreRequest?: SlidePlaybackRestoreRequest | null;\n /**\n * Enables keyboard shortcuts for existing player actions.\n *\n * Defaults to `true`. The active slide responds after users click, touch, or\n * focus the slide/player surface; ignored targets include form controls and\n * interaction overlays.\n *\n * @example\n * ```tsx\n * <Slide elementList={slides} enableKeyboardShortcuts={false} />\n * ```\n */\n enableKeyboardShortcuts?: boolean;\n enableIframeScaling?: boolean;\n /**\n * Fits Markdown-only slides to the available presentation viewport.\n *\n * Defaults to `true`. Disable this to preserve the fixed 16px article\n * typography used by standalone ContentRender.\n */\n enableMarkdownScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nexport interface SlidePlaybackCheckpoint {\n audioKey: string;\n element: Element;\n isComplete: boolean;\n stepIndex: number;\n timeMs: number;\n}\n\nexport interface SlidePlaybackRestoreRequest {\n audioKey: string;\n id: number | string;\n timeMs: number;\n}\n\nconst Slide: React.FC<SlideProps> = ({\n elementList = [],\n locale,\n playerEnabled,\n playerControlsVisibility,\n playerClassName,\n fullscreenHeader,\n playerCustomActions,\n playerCustomActionPauseOnActive = true,\n bufferingText,\n interactionTitle,\n interactionTexts,\n playerTexts,\n playerAutoHideDelay = 3000,\n markerAutoAdvanceDelay = DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS,\n showSlideProgress = false,\n isSlideProgressGenerating = false,\n onSlideProgressNavigate,\n interactionDefaultValueOptions,\n onSend,\n onPlayerVisibilityChange,\n onMobileViewModeChange,\n onStepChange,\n onPlaybackCheckpoint,\n playbackRestoreRequest = null,\n enableKeyboardShortcuts = true,\n enableIframeScaling = true,\n enableMarkdownScaling = true,\n disableLoadingOverlay = false,\n className,\n dir,\n lang,\n onPointerDown,\n onFocusCapture,\n ...props\n}) => {\n const direction = dir ?? getMarkdownFlowDirection(locale);\n const language = lang ?? getMarkdownFlowLanguage(locale);\n const localeTexts = useMemo(() => getSlideLocaleTexts(locale), [locale]);\n const resolvedBufferingText = useMemo(\n () =>\n mergeBufferingTextWithLocaleDefaults(\n bufferingText,\n localeTexts.bufferingText\n ),\n [bufferingText, localeTexts.bufferingText]\n );\n const {\n playerEnabled: resolvedPlayerEnabled,\n playerControlsVisibility: resolvedPlayerControlsVisibility,\n } = resolveSlidePlayerVisibility({\n playerEnabled,\n playerControlsVisibility,\n });\n const keyboardShortcutOwnerId = useId();\n const sectionRef = useRef<HTMLElement | null>(null);\n const { resolvedDirection } = useResolvedDirection(sectionRef, direction);\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const stageLayerRef = useRef<HTMLDivElement | null>(null);\n const lastElementRef = useRef<HTMLDivElement | null>(null);\n const playerHideTimerRef = useRef<number | null>(null);\n const isPointerInsidePlayerControlsRef = useRef(false);\n const autoAdvanceTimerRef = useRef<number | null>(null);\n const imageOnlyStepReadyTimeoutRef = useRef<number | null>(null);\n const interactionAutoCloseTimerRef = useRef<number | null>(null);\n const interactionOverlayOpenTimerRef = useRef<number | null>(null);\n const interactionOverlayRef = useRef<HTMLDivElement | null>(null);\n const interactionOverlayLayoutRectRef =\n useRef<InteractionOverlayLayoutRect | null>(null);\n const interactionOverlayDragRef = useRef<{\n pointerId: number;\n startClientX: number;\n startClientY: number;\n startOffset: InteractionOverlayDragOffset;\n bounds: InteractionOverlayDragBounds;\n } | null>(null);\n const prevRenderElementKeysRef = useRef<string[]>([]);\n const shouldScrollToBottomRef = useRef(false);\n const pendingInteractionOverlayStepIndexRef = useRef<number | null>(null);\n const pendingSubtitleJumpRef = useRef<{\n audioIndex: number;\n audioKey: string;\n slideIndex: number;\n timeMs: number;\n } | null>(null);\n const subtitleSeekRequestIdRef = useRef(0);\n const playbackResetKeyRef = useRef<string | null>(null);\n const appendedMarkerAdvanceStateRef = useRef({\n markerCount: 0,\n currentIndex: -1,\n canGoNext: false,\n });\n const shouldSkipDefaultAudioStartForSubtitleJumpRef = useRef(false);\n const {\n currentElementList,\n stepElementLists,\n slideElementList,\n currentIndex,\n audioList,\n audioSlideIndexes,\n currentAudioSequenceIndexes,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n canGoPrev,\n canGoNext,\n handlePrev: goPrev,\n handleNext: goNext,\n handleGoTo: goTo,\n } = useSlide(elementList);\n const currentStepElement = useMemo(() => {\n if (currentIndex < 0) {\n return undefined;\n }\n\n return slideElementList[currentIndex];\n }, [currentIndex, slideElementList]);\n const currentRenderElementKeys = useMemo(\n () =>\n currentElementList.map(\n (element, index) =>\n `${element.sequence_number ?? `${element.type}-${index}`}:${String(element.is_new ?? \"\")}`\n ),\n [currentElementList]\n );\n const generatedSlideCount = slideElementList.length;\n const isSingleSlide = generatedSlideCount === 1;\n const shouldMountPlayer =\n resolvedPlayerEnabled &&\n (slideElementList.length > 0 ||\n audioList.length > 0 ||\n Boolean(currentInteractionElement));\n const keyboardShortcutContextValue = useMemo(\n () => ({\n enabled: enableKeyboardShortcuts,\n ownerId: keyboardShortcutOwnerId,\n }),\n [enableKeyboardShortcuts, keyboardShortcutOwnerId]\n );\n const activateKeyboardShortcutOwner = useCallback(() => {\n if (!enableKeyboardShortcuts || !shouldMountPlayer) {\n return;\n }\n\n activatePlayerKeyboardShortcutOwner(keyboardShortcutOwnerId);\n }, [enableKeyboardShortcuts, keyboardShortcutOwnerId, shouldMountPlayer]);\n const currentAudioSequenceKeys = useMemo(\n () =>\n currentAudioSequenceIndexes\n .map((audioIndex) => audioList[audioIndex]?.audioKey)\n .filter((audioKey): audioKey is string => Boolean(audioKey)),\n [audioList, currentAudioSequenceIndexes]\n );\n const [isPlayerVisible, setIsPlayerVisible] = useState(true);\n const [hasPlayerInteracted, setHasPlayerInteracted] = useState(false);\n const [isPlaybackRequested, setIsPlaybackRequested] = useState(true);\n const [isAutoAdvanceEnabled, setIsAutoAdvanceEnabled] = useState(true);\n const [currentAudioKey, setCurrentAudioKey] = useState<string | null>(null);\n const [pendingPlaybackRestore, setPendingPlaybackRestore] =\n useState<SlidePlaybackRestoreRequest | null>(null);\n const pendingPlaybackRestoreRef = useRef<SlidePlaybackRestoreRequest | null>(\n null\n );\n const lastPlaybackRestoreRequestIdRef = useRef<number | string | null>(null);\n const [subtitleSeekRequest, setSubtitleSeekRequest] =\n useState<SlidePlayerSubtitleSeekRequest | null>(null);\n const [isAudioLoadingVisible, setIsAudioLoadingVisible] = useState(false);\n const [audioLoadingReason, setAudioLoadingReason] =\n useState<SlideBufferingReason>(DEFAULT_BUFFERING_REASON);\n const [hasCompletedCurrentStepAudio, setHasCompletedCurrentStepAudio] =\n useState(false);\n // Audio keys already played within the current step. A step's audio arrives\n // progressively while content is still being generated, so \"completed\" has to\n // mean \"every key played\" rather than \"reached the end of the list once\".\n const playedAudioKeysRef = useRef<Set<string>>(new Set());\n const [hasCurrentAudioPlaybackStarted, setHasCurrentAudioPlaybackStarted] =\n useState(false);\n const [isSubtitleEnabled, setIsSubtitleEnabled] = useState(true);\n const [isPlayerCustomActionActive, setIsPlayerCustomActionActive] =\n useState(false);\n const [activeInteractionElement, setActiveInteractionElement] = useState<\n Element | undefined\n >();\n const [isInteractionOverlayOpen, setIsInteractionOverlayOpen] =\n useState(false);\n const [hasInteractionOverlayActivity, setHasInteractionOverlayActivity] =\n useState(false);\n const [interactionOverlayDragOffset, setInteractionOverlayDragOffset] =\n useState<InteractionOverlayDragOffset>(\n DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET\n );\n const [isInteractionOverlayDragging, setIsInteractionOverlayDragging] =\n useState(false);\n const [\n interactionOverlaySubtitleOffset,\n setInteractionOverlaySubtitleOffset,\n ] = useState(0);\n const [isBrowserFullscreen, setIsBrowserFullscreen] = useState(false);\n const isMobileDevice = useMemo(() => getIsMobileDevice(), []);\n const [mobileViewMode, setMobileViewMode] = useState<MobileViewMode>(\n DEFAULT_MOBILE_VIEW_MODE\n );\n const [hasManualMobileViewMode, setHasManualMobileViewMode] = useState(false);\n const [isViewportFullscreenPreferred, setIsViewportFullscreenPreferred] =\n useState(() =>\n isMobileDevice ? getIsFullscreenPreferredViewport() : false\n );\n const playbackTimeStore = useMemo(() => createPlaybackTimeStore(), []);\n const {\n effectiveMobileViewMode,\n isImmersiveMobileFullscreen,\n isNativeMobileFullscreen,\n shouldRotateFullscreenViewport,\n } = useMemo(\n () =>\n resolveMobileViewModeState({\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n }),\n [\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n ]\n );\n const previousEffectiveMobileViewModeRef = useRef(effectiveMobileViewMode);\n const {\n controlsVisible: playerControlsVisible,\n layoutReserved: playerLayoutReserved,\n } = resolveSlidePlayerLayoutState({\n isAutoVisible: isPlayerVisible,\n playerControlsVisibility: resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n });\n const shouldShowFullscreenHeader =\n isImmersiveMobileFullscreen && playerControlsVisible;\n const shouldApplyFullscreenViewportPadding =\n isImmersiveMobileFullscreen && playerLayoutReserved;\n const shouldShowMobileFullscreenMask =\n isImmersiveMobileFullscreen || isNativeMobileFullscreen;\n const isDesktopBrowserFullscreen = isBrowserFullscreen && !isMobileDevice;\n const handleMobileViewModeSelect = useCallback(\n (nextViewMode: MobileViewMode) => {\n setHasManualMobileViewMode(true);\n setMobileViewMode(nextViewMode);\n },\n []\n );\n const handleMobileViewModeReset = useCallback(() => {\n // Clear manual override so the effective mode returns to the default non-fullscreen state.\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, []);\n const handleFullscreenHeaderBack = useCallback(() => {\n handleMobileViewModeReset();\n fullscreenHeader?.onBack?.();\n }, [fullscreenHeader, handleMobileViewModeReset]);\n\n const clearInteractionAutoCloseTimer = useCallback(() => {\n if (interactionAutoCloseTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionAutoCloseTimerRef.current);\n interactionAutoCloseTimerRef.current = null;\n }, []);\n\n const clearInteractionOverlayOpenTimer = useCallback(() => {\n if (interactionOverlayOpenTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionOverlayOpenTimerRef.current);\n interactionOverlayOpenTimerRef.current = null;\n }, []);\n\n const closeInteractionOverlayForCustomAction = useCallback(() => {\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n }, [clearInteractionAutoCloseTimer, clearInteractionOverlayOpenTimer]);\n\n const setPlayerCustomActionActive = useCallback(\n (active: boolean) => {\n if (active) {\n closeInteractionOverlayForCustomAction();\n }\n\n setIsPlayerCustomActionActive(active);\n },\n [closeInteractionOverlayForCustomAction]\n );\n const togglePlayerCustomActionActive = useCallback(() => {\n closeInteractionOverlayForCustomAction();\n setIsPlayerCustomActionActive((previousActive) => !previousActive);\n }, [closeInteractionOverlayForCustomAction]);\n const resetInteractionOverlayDragState = useCallback(() => {\n setInteractionOverlayDragOffset((previousOffset) =>\n previousOffset.x === DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET.x &&\n previousOffset.y === DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET.y\n ? previousOffset\n : DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET\n );\n setIsInteractionOverlayDragging(false);\n interactionOverlayDragRef.current = null;\n interactionOverlayLayoutRectRef.current = null;\n }, []);\n const { mountedStepStates, currentMountedStateIndex } = useMemo(() => {\n const nextMountedStepStates: Array<{\n elementList: Element[];\n sourceStepIndexes: number[];\n }> = [];\n const mountedStateIndexByStep = new Map<number, number>();\n\n stepElementLists.forEach((stepElementList, stepIndex) => {\n const existingMountedStateIndex = nextMountedStepStates.findIndex(\n (mountedStepState) =>\n areStepElementListsEqual(\n mountedStepState.elementList,\n stepElementList\n )\n );\n\n if (existingMountedStateIndex >= 0) {\n nextMountedStepStates[\n existingMountedStateIndex\n ]?.sourceStepIndexes.push(stepIndex);\n mountedStateIndexByStep.set(stepIndex, existingMountedStateIndex);\n return;\n }\n\n nextMountedStepStates.push({\n elementList: stepElementList,\n sourceStepIndexes: [stepIndex],\n });\n mountedStateIndexByStep.set(stepIndex, nextMountedStepStates.length - 1);\n });\n\n return {\n mountedStepStates: nextMountedStepStates,\n currentMountedStateIndex:\n currentIndex >= 0\n ? (mountedStateIndexByStep.get(currentIndex) ?? -1)\n : -1,\n };\n }, [currentIndex, stepElementLists]);\n const currentStepKey = useMemo(() => String(currentIndex), [currentIndex]);\n const currentAudioIndex = useMemo(() => {\n if (!currentAudioKey) {\n return -1;\n }\n\n return audioList.findIndex(\n (audioItem) => (audioItem.audioKey ?? \"\") === currentAudioKey\n );\n }, [audioList, currentAudioKey]);\n const currentAudioItem = useMemo(\n () => (currentAudioIndex >= 0 ? audioList[currentAudioIndex] : undefined),\n [audioList, currentAudioIndex]\n );\n\n useEffect(() => {\n if (\n !playbackRestoreRequest ||\n playbackRestoreRequest.id === lastPlaybackRestoreRequestIdRef.current\n ) {\n return;\n }\n\n const targetAudioIndex = audioList.findIndex(\n (audioItem) => audioItem.audioKey === playbackRestoreRequest.audioKey\n );\n if (targetAudioIndex < 0) {\n return;\n }\n\n const targetStepIndex = audioSlideIndexes[targetAudioIndex];\n if (targetStepIndex == null) {\n return;\n }\n\n lastPlaybackRestoreRequestIdRef.current = playbackRestoreRequest.id;\n setIsPlaybackRequested(true);\n setCurrentAudioKey(playbackRestoreRequest.audioKey);\n pendingPlaybackRestoreRef.current = playbackRestoreRequest;\n setPendingPlaybackRestore(playbackRestoreRequest);\n if (currentIndex !== targetStepIndex) {\n goTo(targetStepIndex);\n }\n }, [\n audioList,\n audioSlideIndexes,\n currentIndex,\n goTo,\n playbackRestoreRequest,\n ]);\n const currentSubtitleCues = currentAudioItem?.element?.subtitle_cues ?? [];\n const currentAudioSequenceStartKey = useMemo(\n () => currentAudioSequenceKeys[0] ?? \"none\",\n [currentAudioSequenceKeys]\n );\n const playerCustomActionContext = useMemo(\n () => ({\n currentElement: resolvePlayerCustomActionElement({\n currentAudioIndex,\n currentAudioSequenceIndexes,\n audioList,\n currentInteractionElement: activeInteractionElement,\n currentStepElement,\n }),\n currentIndex,\n currentStepElement,\n isActive: isPlayerCustomActionActive,\n setActive: setPlayerCustomActionActive,\n toggleActive: togglePlayerCustomActionActive,\n }),\n [\n activeInteractionElement,\n audioList,\n currentAudioIndex,\n currentAudioSequenceIndexes,\n currentIndex,\n currentStepElement,\n isPlayerCustomActionActive,\n setPlayerCustomActionActive,\n togglePlayerCustomActionActive,\n ]\n );\n const playerCustomActionCount = useMemo(\n () =>\n getPlayerCustomActionCount(\n playerCustomActions,\n playerCustomActionContext\n ),\n [playerCustomActionContext, playerCustomActions]\n );\n const hasPlayerCustomActions = playerCustomActionCount > 0;\n const isPlayerCustomActionEffectivelyActive =\n hasPlayerCustomActions && isPlayerCustomActionActive;\n const interactionOverlayStyle = useMemo(\n () =>\n ({\n \"--slide-player-custom-action-count\": String(playerCustomActionCount),\n \"--slide-player-mobile-control-count\": String(\n playerCustomActionCount + 4\n ),\n \"--slide-interaction-drag-x\": `${interactionOverlayDragOffset.x}px`,\n \"--slide-interaction-drag-y\": `${interactionOverlayDragOffset.y}px`,\n }) as React.CSSProperties,\n [\n interactionOverlayDragOffset.x,\n interactionOverlayDragOffset.y,\n playerCustomActionCount,\n ]\n );\n const hasAvailableStepAudio = currentAudioSequenceKeys.length > 0;\n const currentInteractionResetKey = useMemo(() => {\n if (!currentInteractionElement) {\n return \"none\";\n }\n\n return `${currentInteractionElement.sequence_number ?? \"none\"}:${String(\n currentInteractionElement.content ?? \"\"\n )}`;\n }, [currentInteractionElement]);\n const currentPlaybackResetKey = useMemo(\n () => [currentStepKey, currentInteractionResetKey].join(\"|\"),\n [currentInteractionResetKey, currentStepKey]\n );\n const currentPlaybackStartedResetKey = useMemo(\n () =>\n [\n currentPlaybackResetKey,\n currentAudioItem?.audioKey ?? \"none\",\n String(currentAudioIndex),\n ].join(\"|\"),\n [currentAudioIndex, currentAudioItem?.audioKey, currentPlaybackResetKey]\n );\n const currentStepAudioUrl = useMemo(() => {\n if (\n !currentAudioSequenceStartKey ||\n currentAudioSequenceStartKey === \"none\"\n ) {\n return \"\";\n }\n\n const currentStepAudioItem = audioList.find(\n (audioItem) => audioItem.audioKey === currentAudioSequenceStartKey\n );\n\n return currentStepAudioItem?.audioUrl?.trim() ?? \"\";\n }, [audioList, currentAudioSequenceStartKey]);\n const hasCurrentStepAudioUrl = Boolean(currentStepAudioUrl);\n const shouldPausePlaybackForCustomAction =\n playerCustomActionPauseOnActive && isPlayerCustomActionEffectivelyActive;\n const shouldUseSilentStepAutoAdvanceToggle = useMemo(\n () =>\n shouldUseAutoAdvanceToggle({\n canGoNext,\n currentAudioIndex,\n currentStepHasSpeakableElement,\n hasInteraction: Boolean(currentInteractionElement),\n }),\n [\n canGoNext,\n currentAudioIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n ]\n );\n const silentStepAutoAdvanceBehavior = useMemo(\n () =>\n resolveSilentStepAutoAdvanceBehavior({\n currentElementList,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n markerAutoAdvanceDelay,\n }),\n [\n currentElementList,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n markerAutoAdvanceDelay,\n ]\n );\n const silentStepAutoAdvanceDelay = silentStepAutoAdvanceBehavior.delayMs;\n const isImageOnlySilentStep =\n silentStepAutoAdvanceBehavior.usesImageOnlyDelay;\n const imageOnlyStepVisualReadyKey = useMemo(\n () => `${currentIndex}:${currentRenderElementKeys.join(\"|\")}`,\n [currentIndex, currentRenderElementKeys]\n );\n const [readyImageOnlyStepKey, setReadyImageOnlyStepKey] = useState<\n string | null\n >(null);\n const isImageOnlyStepVisualReady =\n !isImageOnlySilentStep ||\n readyImageOnlyStepKey === imageOnlyStepVisualReadyKey;\n\n const clearPlayerHideTimer = useCallback(() => {\n if (playerHideTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(playerHideTimerRef.current);\n playerHideTimerRef.current = null;\n }, []);\n\n const clearAutoAdvanceTimer = useCallback(() => {\n if (autoAdvanceTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(autoAdvanceTimerRef.current);\n autoAdvanceTimerRef.current = null;\n }, []);\n\n const clearImageOnlyStepReadyTimeout = useCallback(() => {\n if (imageOnlyStepReadyTimeoutRef.current === null) {\n return;\n }\n\n window.clearTimeout(imageOnlyStepReadyTimeoutRef.current);\n imageOnlyStepReadyTimeoutRef.current = null;\n }, []);\n\n const resetAudioSequence = useCallback(\n (\n options: {\n preservePendingSubtitleJump?: boolean;\n } = {}\n ) => {\n clearAutoAdvanceTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n clearImageOnlyStepReadyTimeout();\n setCurrentAudioKey(null);\n playbackTimeStore.reset();\n setIsAudioLoadingVisible(false);\n setAudioLoadingReason(DEFAULT_BUFFERING_REASON);\n setHasCompletedCurrentStepAudio(false);\n playedAudioKeysRef.current = new Set();\n setHasCurrentAudioPlaybackStarted(false);\n setSubtitleSeekRequest(null);\n if (!options.preservePendingSubtitleJump) {\n pendingSubtitleJumpRef.current = null;\n }\n setActiveInteractionElement(undefined);\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n },\n [\n clearAutoAdvanceTimer,\n clearImageOnlyStepReadyTimeout,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n playbackTimeStore,\n ]\n );\n\n const requestSubtitleCueSeek = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) => {\n subtitleSeekRequestIdRef.current += 1;\n setSubtitleSeekRequest({\n ...target,\n id: subtitleSeekRequestIdRef.current,\n });\n },\n []\n );\n\n const startCurrentAudioSequence = useCallback(() => {\n // Resume at the first key that has not played yet. Falling back to index 0\n // unconditionally would replay the opening segment every time late audio\n // extends the current step.\n const nextAudioKey = resolvePendingStepAudioKey(\n currentAudioSequenceKeys,\n playedAudioKeysRef.current\n );\n\n if (!nextAudioKey) {\n return false;\n }\n\n // Start the first pending audio segment for the current step immediately.\n setCurrentAudioKey(nextAudioKey);\n return true;\n }, [currentAudioSequenceKeys]);\n\n const continueAfterInteraction = useCallback(() => {\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (canGoNext) {\n goNext();\n }\n }, [\n canGoNext,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n goNext,\n startCurrentAudioSequence,\n ]);\n\n const scheduleInteractionOverlayOpen = useCallback(\n (interactionElement?: Element) => {\n clearInteractionOverlayOpenTimer();\n\n if (!interactionElement) {\n return;\n }\n\n const openOverlay = () => {\n interactionOverlayOpenTimerRef.current = null;\n setInteractionOverlaySubtitleOffset(\n DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX\n );\n setIsInteractionOverlayOpen(true);\n pendingInteractionOverlayStepIndexRef.current = null;\n };\n\n interactionOverlayOpenTimerRef.current = window.setTimeout(\n openOverlay,\n DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS\n );\n },\n [clearInteractionOverlayOpenTimer]\n );\n\n const isPlayerControlsHovered = useCallback(\n () =>\n isPointerInsidePlayerControlsRef.current ||\n Boolean(\n sectionRef.current?.querySelector(\".slide-player__controls:hover\")\n ),\n []\n );\n\n const revealPlayerControls = useCallback(\n (enableAutoHide = hasPlayerInteracted) => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n return;\n }\n\n setIsPlayerVisible(true);\n clearPlayerHideTimer();\n\n if (\n resolvedPlayerControlsVisibility === \"visible\" ||\n !enableAutoHide ||\n playerAutoHideDelay <= 0 ||\n isPlayerControlsHovered()\n ) {\n return;\n }\n\n playerHideTimerRef.current = window.setTimeout(() => {\n if (isPlayerControlsHovered()) {\n playerHideTimerRef.current = null;\n return;\n }\n\n setIsPlayerVisible(false);\n playerHideTimerRef.current = null;\n }, playerAutoHideDelay);\n },\n [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n isPlayerControlsHovered,\n playerAutoHideDelay,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n ]\n );\n\n const hasResolvedCurrentInteraction = Boolean(\n hasResolvedInteractionElement(currentInteractionElement)\n );\n\n const shouldBlockPlaybackForInteraction =\n Boolean(currentInteractionElement) && !hasResolvedCurrentInteraction;\n\n const handlePlaybackPreferenceChange = useCallback((playing: boolean) => {\n setIsPlaybackRequested(playing);\n }, []);\n\n const syncPlaybackPreferenceBeforeNavigation = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n if (context) {\n setIsPlaybackRequested(context.shouldContinuePlayback);\n }\n },\n []\n );\n\n useEffect(() => {\n // Keep silent-step autoplay aligned with the same play/pause preference as audio.\n setIsAutoAdvanceEnabled(isPlaybackRequested);\n }, [currentIndex, isPlaybackRequested, playerCustomActionPauseOnActive]);\n\n useEffect(() => {\n if (playerCustomActionPauseOnActive) {\n setPlayerCustomActionActive(false);\n }\n }, [\n currentIndex,\n playerCustomActionPauseOnActive,\n setPlayerCustomActionActive,\n ]);\n\n useEffect(() => {\n if (!hasPlayerCustomActions) {\n setIsPlayerCustomActionActive(false);\n }\n }, [hasPlayerCustomActions]);\n\n useEffect(() => {\n return () => {\n clearAutoAdvanceTimer();\n clearImageOnlyStepReadyTimeout();\n clearPlayerHideTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n };\n }, [\n clearAutoAdvanceTimer,\n clearImageOnlyStepReadyTimeout,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n clearPlayerHideTimer,\n ]);\n\n useEffect(() => {\n if (!isImageOnlySilentStep) {\n clearImageOnlyStepReadyTimeout();\n return;\n }\n\n let cancelled = false;\n let rafId: number | null = null;\n let cleanupListeners: (() => void) | null = null;\n\n const detachListeners = () => {\n cleanupListeners?.();\n cleanupListeners = null;\n };\n\n const finishVisualReady = () => {\n if (cancelled) {\n return;\n }\n\n detachListeners();\n clearImageOnlyStepReadyTimeout();\n setReadyImageOnlyStepKey(imageOnlyStepVisualReadyKey);\n };\n\n const evaluateVisualReady = () => {\n if (cancelled) {\n return;\n }\n\n detachListeners();\n\n const activeStepContainer = stageLayerRef.current?.querySelector(\n '[data-active-step=\"true\"]'\n ) as HTMLElement | null;\n\n if (!activeStepContainer) {\n return;\n }\n\n const iframeElements = Array.from(\n activeStepContainer.querySelectorAll(\"iframe\")\n ) as HTMLIFrameElement[];\n\n if (\n iframeElements.length === 0 ||\n areImageOnlyStepIframeVisualsReady(iframeElements)\n ) {\n finishVisualReady();\n return;\n }\n\n const cleanupCallbacks: Array<() => void> = [];\n const queueRecheck = () => {\n if (cancelled) {\n return;\n }\n\n if (rafId !== null) {\n window.cancelAnimationFrame(rafId);\n }\n\n rafId = window.requestAnimationFrame(() => {\n rafId = null;\n evaluateVisualReady();\n });\n };\n const registerEvent = (\n target: EventTarget,\n eventName: string,\n listener: EventListener\n ) => {\n target.addEventListener(eventName, listener, { once: true });\n cleanupCallbacks.push(() =>\n target.removeEventListener(eventName, listener)\n );\n };\n\n iframeElements.forEach((iframeElement) => {\n const iframeDocument = iframeElement.contentDocument;\n\n if (!iframeDocument || iframeDocument.readyState !== \"complete\") {\n registerEvent(iframeElement, \"load\", queueRecheck);\n return;\n }\n\n Array.from(iframeDocument.images)\n .filter((image) => !image.complete)\n .forEach((image) => {\n registerEvent(image, \"load\", queueRecheck);\n registerEvent(image, \"error\", queueRecheck);\n });\n });\n\n cleanupListeners = () => {\n cleanupCallbacks.forEach((cleanup) => cleanup());\n };\n };\n\n rafId = window.requestAnimationFrame(() => {\n rafId = null;\n evaluateVisualReady();\n });\n\n imageOnlyStepReadyTimeoutRef.current = window.setTimeout(() => {\n finishVisualReady();\n }, DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS);\n\n return () => {\n cancelled = true;\n detachListeners();\n clearImageOnlyStepReadyTimeout();\n if (rafId !== null) {\n window.cancelAnimationFrame(rafId);\n }\n };\n }, [\n clearImageOnlyStepReadyTimeout,\n currentElementList,\n currentIndex,\n imageOnlyStepVisualReadyKey,\n isImageOnlySilentStep,\n ]);\n\n useEffect(() => {\n onPlayerVisibilityChange?.(playerControlsVisible);\n\n return () => {\n onPlayerVisibilityChange?.(false);\n };\n }, [onPlayerVisibilityChange, playerControlsVisible]);\n\n useEffect(() => {\n if (playerControlsVisible) {\n return;\n }\n\n isPointerInsidePlayerControlsRef.current = false;\n }, [playerControlsVisible]);\n\n useEffect(() => {\n if (isMobileDevice || mobileViewMode === DEFAULT_MOBILE_VIEW_MODE) {\n return;\n }\n\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, [isMobileDevice, mobileViewMode]);\n\n useEffect(() => {\n if (!isMobileDevice) {\n setIsViewportFullscreenPreferred(false);\n return;\n }\n\n const syncViewportFullscreenPreference = () => {\n setIsViewportFullscreenPreferred(getIsFullscreenPreferredViewport());\n resetInteractionOverlayDragState();\n };\n const handleOrientationChange = () => {\n resetInteractionOverlayDragState();\n };\n\n syncViewportFullscreenPreference();\n window.addEventListener(\"orientationchange\", handleOrientationChange);\n window.screen?.orientation?.addEventListener?.(\n \"change\",\n handleOrientationChange\n );\n const unsubscribeMobileDeviceChange = subscribeMobileDeviceChange(\n syncViewportFullscreenPreference\n );\n\n return () => {\n unsubscribeMobileDeviceChange();\n window.removeEventListener(\"orientationchange\", handleOrientationChange);\n window.screen?.orientation?.removeEventListener?.(\n \"change\",\n handleOrientationChange\n );\n };\n }, [isMobileDevice, resetInteractionOverlayDragState]);\n\n useEffect(() => {\n onMobileViewModeChange?.(effectiveMobileViewMode);\n }, [effectiveMobileViewMode, onMobileViewModeChange]);\n\n useEffect(() => {\n if (\n previousEffectiveMobileViewModeRef.current !== effectiveMobileViewMode\n ) {\n resetInteractionOverlayDragState();\n }\n previousEffectiveMobileViewModeRef.current = effectiveMobileViewMode;\n }, [effectiveMobileViewMode, resetInteractionOverlayDragState]);\n\n useEffect(() => {\n onStepChange?.(currentStepElement, currentIndex);\n }, [currentIndex, currentStepElement, onStepChange]);\n\n useEffect(() => {\n const previousState = appendedMarkerAdvanceStateRef.current;\n const shouldAdvanceIntoAppendedMarker = shouldAutoAdvanceIntoAppendedMarker(\n {\n previousMarkerCount: previousState.markerCount,\n nextMarkerCount: slideElementList.length,\n previousIndex: previousState.currentIndex,\n previousCanGoNext: previousState.canGoNext,\n nextCanGoNext: canGoNext,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n }\n );\n\n appendedMarkerAdvanceStateRef.current = {\n markerCount: slideElementList.length,\n currentIndex,\n canGoNext,\n };\n\n if (!shouldAdvanceIntoAppendedMarker) {\n return;\n }\n\n goNext();\n }, [\n canGoNext,\n currentAudioKey,\n currentIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n goNext,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n slideElementList.length,\n ]);\n\n useEffect(() => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(false);\n return;\n }\n\n if (resolvedPlayerControlsVisibility === \"visible\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(true);\n return;\n }\n\n if (!hasPlayerInteracted) {\n // Keep the initial player visible briefly, then hide it automatically.\n revealPlayerControls(true);\n }\n }, [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n revealPlayerControls,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleSandboxInteraction = (event: MessageEvent) => {\n if (event.origin !== window.location.origin) {\n return;\n }\n\n if (!isSandboxInteractionMessage(event.data)) {\n return;\n }\n\n if (event.data.eventType !== \"click\") {\n return;\n }\n\n if (!shouldMountPlayer) {\n return;\n }\n\n // Restore player controls on explicit click/tap without waking on scroll start.\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n };\n\n window.addEventListener(\"message\", handleSandboxInteraction);\n\n return () => {\n window.removeEventListener(\"message\", handleSandboxInteraction);\n };\n }, [activateKeyboardShortcutOwner, shouldMountPlayer, revealPlayerControls]);\n\n useWakePlayerFromIframe({\n sectionRef,\n enabled: shouldMountPlayer,\n keyboardShortcutsEnabled: enableKeyboardShortcuts,\n onKeyboardShortcut: activateKeyboardShortcutOwner,\n onWake: () => {\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n },\n });\n\n useEffect(() => {\n if (!shouldMountPlayer) {\n resetAudioSequence();\n return;\n }\n\n // A restore request sets the target audio in an earlier effect. Without\n // this guard, the normal first-audio initializer in this same commit can\n // overwrite that target before Player receives the restore request.\n if (pendingPlaybackRestoreRef.current) {\n // Record the target context before Player finishes its restore callback.\n // The next sequence effect then sees this step as initialized instead of\n // resetting it back to the default first audio item.\n playbackResetKeyRef.current = currentPlaybackResetKey;\n return;\n }\n\n const { hasPlaybackContextChanged, shouldInitializeAudioSequence } =\n getPlaybackSequenceTransition({\n previousResetKey: playbackResetKeyRef.current,\n nextResetKey: currentPlaybackResetKey,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n });\n\n playbackResetKeyRef.current = currentPlaybackResetKey;\n\n const shouldOpenInteractionOverlayAfterAudio =\n pendingInteractionOverlayStepIndexRef.current === currentIndex &&\n Boolean(currentInteractionElement);\n const shouldPresentOverlay = shouldPresentInteractionOverlay({\n hasInteraction: Boolean(currentInteractionElement),\n shouldBlockPlaybackForInteraction,\n shouldOpenInteractionOverlayAfterAudio,\n hasPlaybackContextChanged,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n isPlayerCustomActionActive: isPlayerCustomActionEffectivelyActive,\n });\n\n const pendingSubtitleJump = pendingSubtitleJumpRef.current;\n const shouldPreservePendingSubtitleJump =\n pendingSubtitleJump?.slideIndex === currentIndex;\n\n if (hasPlaybackContextChanged) {\n resetAudioSequence({\n preservePendingSubtitleJump: shouldPreservePendingSubtitleJump,\n });\n }\n\n if (currentElementList.length === 0 && !currentInteractionElement) {\n return;\n }\n\n if (shouldPausePlaybackForCustomAction) {\n return;\n }\n\n if (pendingSubtitleJump?.slideIndex === currentIndex) {\n if (\n !canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: pendingSubtitleJump.slideIndex,\n })\n ) {\n // Keep the pending seek queued while the interaction overlay gates playback.\n } else {\n pendingSubtitleJumpRef.current = null;\n // The default audio-start effect still sees the pre-seek render state.\n // Skip it once so it does not replace the subtitle target audio.\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = true;\n setCurrentAudioKey(pendingSubtitleJump.audioKey);\n requestSubtitleCueSeek({\n audioIndex: pendingSubtitleJump.audioIndex,\n timeMs: pendingSubtitleJump.timeMs,\n });\n return;\n }\n }\n\n if (currentInteractionElement) {\n setActiveInteractionElement(currentInteractionElement);\n }\n\n if (shouldPresentOverlay) {\n // Delay auto-presenting the overlay so subtitles can settle above it.\n scheduleInteractionOverlayOpen(currentInteractionElement);\n return;\n }\n\n clearInteractionOverlayOpenTimer();\n pendingInteractionOverlayStepIndexRef.current = null;\n\n // A custom action may intentionally remain active without pausing ordinary\n // playback. Unresolved interactions still gate progression even while that\n // action temporarily owns the visible overlay surface.\n if (shouldBlockPlaybackForInteraction) {\n return;\n }\n\n if (!shouldInitializeAudioSequence) {\n return;\n }\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (currentStepHasSpeakableElement) {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setIsAudioLoadingVisible(true);\n return;\n }\n\n if (!canGoNext) {\n return;\n }\n\n if (shouldUseSilentStepAutoAdvanceToggle && !isAutoAdvanceEnabled) {\n return;\n }\n\n if (isImageOnlySilentStep && !isImageOnlyStepVisualReady) {\n return;\n }\n\n // Auto-advance silent marker-only steps so playback flow does not stall.\n autoAdvanceTimerRef.current = window.setTimeout(() => {\n autoAdvanceTimerRef.current = null;\n goNext();\n }, silentStepAutoAdvanceDelay);\n\n return () => {\n clearAutoAdvanceTimer();\n };\n }, [\n activeInteractionElement,\n canGoNext,\n clearAutoAdvanceTimer,\n currentElementList.length,\n currentIndex,\n currentInteractionElement,\n currentAudioKey,\n currentPlaybackResetKey,\n currentStepHasSpeakableElement,\n isImageOnlySilentStep,\n isImageOnlyStepVisualReady,\n silentStepAutoAdvanceDelay,\n goNext,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n isAutoAdvanceEnabled,\n hasResolvedCurrentInteraction,\n isPlayerCustomActionEffectivelyActive,\n shouldBlockPlaybackForInteraction,\n clearInteractionOverlayOpenTimer,\n resetAudioSequence,\n requestSubtitleCueSeek,\n scheduleInteractionOverlayOpen,\n shouldMountPlayer,\n slideElementList,\n startCurrentAudioSequence,\n shouldPausePlaybackForCustomAction,\n shouldUseSilentStepAutoAdvanceToggle,\n ]);\n\n useEffect(() => {\n if (\n disableLoadingOverlay ||\n shouldPausePlaybackForCustomAction ||\n !currentStepHasSpeakableElement ||\n shouldBlockPlaybackForInteraction\n ) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasAvailableStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setAudioLoadingReason(\"waitingForAudio\");\n setIsAudioLoadingVisible(true);\n }, [\n hasAvailableStepAudio,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n ]);\n\n // A step's audio can keep arriving after the last available segment finished,\n // because narration is synthesized while the lesson is still streaming. The\n // step-completed flag is otherwise only cleared when the reset key changes -\n // which tracks the step index and the interaction content, neither of which\n // moves while new audio is appended to the step the learner is already on.\n // Without this, everything synthesized after that first gap stays silent.\n useEffect(() => {\n if (!hasCompletedCurrentStepAudio) {\n return;\n }\n\n if (\n !hasUnplayedStepAudio(\n currentAudioSequenceKeys,\n playedAudioKeysRef.current\n )\n ) {\n return;\n }\n\n setHasCompletedCurrentStepAudio(false);\n }, [currentAudioSequenceKeys, hasCompletedCurrentStepAudio]);\n\n useEffect(() => {\n // A restore request may arrive after the slide itself mounts. Do not let\n // this independent default-start path select the first audio item while\n // the restore target is still being applied.\n if (pendingPlaybackRestoreRef.current) {\n return;\n }\n\n const shouldSkipDefaultAudioStart =\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current;\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = false;\n\n if (\n !shouldStartDefaultAudioSequence({\n currentAudioKey,\n currentAudioSequenceLength: currentAudioSequenceKeys.length,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldBlockPlaybackForInteraction,\n shouldPausePlaybackForCustomAction,\n shouldSkipDefaultAudioStart,\n })\n ) {\n return;\n }\n\n startCurrentAudioSequence();\n }, [\n currentAudioKey,\n currentAudioSequenceKeys,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n startCurrentAudioSequence,\n ]);\n\n useEffect(() => {\n if (!currentAudioKey || currentAudioIndex >= 0) {\n return;\n }\n\n setCurrentAudioKey(null);\n }, [currentAudioIndex, currentAudioKey]);\n\n useEffect(() => {\n if (currentAudioIndex >= 0) {\n return;\n }\n\n playbackTimeStore.reset();\n }, [currentAudioIndex, playbackTimeStore]);\n\n useEffect(() => {\n setHasCurrentAudioPlaybackStarted(false);\n }, [currentPlaybackStartedResetKey]);\n\n const {\n interactionDefaults,\n interactionDefaultSelectedValues,\n hasResolvedInteractionInput,\n isInteractionReadonly: resolvedInteractionReadonly,\n shouldAutoContinueInteraction,\n } = useMemo(\n () =>\n resolveSlideInteractionState(activeInteractionElement, {\n interactionDefaultValueOptions,\n }),\n [activeInteractionElement, interactionDefaultValueOptions]\n );\n\n const isInteractionReadonly =\n Boolean(activeInteractionElement?.readonly) || resolvedInteractionReadonly;\n const shouldShowInteractionOverlay = shouldRenderInteractionOverlay({\n hasActiveInteraction: Boolean(activeInteractionElement),\n isInteractionOverlayOpen,\n });\n\n const handleInteractionSend = useCallback(\n (content: OnSendContentParams) => {\n const submittedValues = [\n ...(content.selectedValues ?? []),\n content.inputText?.trim() ?? \"\",\n content.buttonText?.trim() ?? \"\",\n ].filter(Boolean);\n const resolvedUserInput = submittedValues.join(\", \");\n\n setActiveInteractionElement((prevElement) => {\n if (!prevElement || !resolvedUserInput) {\n return prevElement;\n }\n\n return {\n ...prevElement,\n user_input: resolvedUserInput,\n };\n });\n\n onSend?.(content, activeInteractionElement);\n continueAfterInteraction();\n },\n [activeInteractionElement, continueAfterInteraction, onSend]\n );\n\n useEffect(() => {\n // Keep the player icon in sync with the actual fullscreen owner.\n const syncFullscreenState = () => {\n setIsBrowserFullscreen(document.fullscreenElement === sectionRef.current);\n };\n\n syncFullscreenState();\n document.addEventListener(\"fullscreenchange\", syncFullscreenState);\n\n return () => {\n document.removeEventListener(\"fullscreenchange\", syncFullscreenState);\n };\n }, []);\n\n useEffect(() => {\n if (activeInteractionElement && isInteractionOverlayOpen) {\n return;\n }\n\n setHasInteractionOverlayActivity(false);\n }, [activeInteractionElement, isInteractionOverlayOpen]);\n\n useEffect(() => {\n resetInteractionOverlayDragState();\n }, [activeInteractionElement, resetInteractionOverlayDragState]);\n\n useEffect(() => {\n if (!shouldShowInteractionOverlay) {\n setInteractionOverlaySubtitleOffset(0);\n return;\n }\n\n const interactionOverlayElement = interactionOverlayRef.current;\n\n if (!interactionOverlayElement) {\n return;\n }\n\n const updateSubtitleOffset = () => {\n const overlayHeight = Math.ceil(\n interactionOverlayElement.getBoundingClientRect().height\n );\n\n setInteractionOverlaySubtitleOffset(\n overlayHeight + DEFAULT_INTERACTION_SUBTITLE_GAP_PX\n );\n };\n\n updateSubtitleOffset();\n\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateSubtitleOffset();\n });\n\n resizeObserver.observe(interactionOverlayElement);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [shouldShowInteractionOverlay]);\n\n useEffect(() => {\n clearInteractionAutoCloseTimer();\n\n if (!isInteractionOverlayOpen) {\n return;\n }\n\n if (shouldAutoContinueInteraction) {\n // Auto-close passive interaction markers to keep playback moving.\n interactionAutoCloseTimerRef.current = window.setTimeout(() => {\n interactionAutoCloseTimerRef.current = null;\n\n continueAfterInteraction();\n }, DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS);\n return () => {\n clearInteractionAutoCloseTimer();\n };\n }\n\n if (hasInteractionOverlayActivity || !hasResolvedInteractionInput) {\n return;\n }\n\n // Give resolved history interactions a short revisit window before\n // playback resumes, but stop auto-closing once the learner starts editing.\n interactionAutoCloseTimerRef.current = window.setTimeout(() => {\n interactionAutoCloseTimerRef.current = null;\n\n continueAfterInteraction();\n }, DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS);\n\n return () => {\n clearInteractionAutoCloseTimer();\n };\n }, [\n clearInteractionAutoCloseTimer,\n continueAfterInteraction,\n hasInteractionOverlayActivity,\n hasResolvedInteractionInput,\n isInteractionOverlayOpen,\n shouldAutoContinueInteraction,\n ]);\n\n const renderSlideElement = (\n element?: Element,\n options: RenderSlideElementOptions = {}\n ) => {\n if (!element) {\n return null;\n }\n\n if (element.type === \"slot\") {\n return <>{element.content}</>;\n }\n\n if (element.type === \"html\") {\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n dir={direction}\n lang={language}\n mode=\"blackboard\"\n replaceRootScreenHeightWithFull={\n options.replaceRootScreenHeightWithFull\n }\n type=\"sandbox\"\n content={element.content as string}\n enableScaling={enableIframeScaling}\n />\n );\n }\n\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n dir={direction}\n lang={language}\n mode=\"blackboard\"\n type=\"markdown\"\n content={element.content as string}\n />\n );\n };\n\n const renderSlideElementList = (\n elementList: Element[] = [],\n isActiveStep = false\n ) => {\n if (elementList.length === 0) {\n return null;\n }\n\n const visibleElementCount = elementList.filter(\n (element) => element.is_renderable !== false\n ).length;\n const markdownScalingMode =\n isActiveStep && enableMarkdownScaling\n ? resolveMarkdownScalingMode(elementList)\n : \"disabled\";\n const lastVisibleElementIndex = elementList.reduce(\n (lastVisibleIndex, element, index) =>\n element.is_renderable !== false ? index : lastVisibleIndex,\n -1\n );\n\n return (\n <MarkdownSlideScaling\n className=\"slide-stage__content flex w-full flex-col gap-4\"\n mode={markdownScalingMode}\n >\n {elementList.map((element, index) => {\n const isPreRenderedHtml =\n element.type === \"html\" && element.is_renderable === false;\n\n return (\n <div\n key={element.sequence_number ?? `${element.type}-${index}`}\n ref={\n isActiveStep && index === lastVisibleElementIndex\n ? lastElementRef\n : null\n }\n aria-hidden={isPreRenderedHtml || undefined}\n className={cn(\n \"w-full shrink-0\",\n visibleElementCount === 1 &&\n element.is_renderable !== false &&\n \"slide-element--single\",\n isPreRenderedHtml\n ? \"pointer-events-none fixed left-[-200vw] top-0 -z-10 h-[100dvh] w-[100vw] overflow-hidden opacity-0\"\n : element.is_renderable === false && \"hidden\"\n )}\n >\n {renderSlideElement(element, {\n replaceRootScreenHeightWithFull:\n visibleElementCount === 1 &&\n element.type === \"html\" &&\n element.is_renderable !== false,\n })}\n </div>\n );\n })}\n </MarkdownSlideScaling>\n );\n };\n\n const handleFullscreen = useCallback(() => {\n const target = sectionRef.current;\n if (!target) {\n return;\n }\n\n if (document.fullscreenElement === target) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n\n target.requestFullscreen?.().catch(() => {});\n }, []);\n\n const scrollStageToBottom = useCallback(() => {\n const stageLayerElement = stageLayerRef.current;\n\n if (!stageLayerElement) {\n return;\n }\n\n // Keep the latest content visible after manual player navigation.\n stageLayerElement.scrollTo({\n top: stageLayerElement.scrollHeight,\n behavior: \"smooth\",\n });\n }, []);\n\n const canJumpToSubtitleTarget = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) =>\n canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: audioSlideIndexes[target.audioIndex],\n }),\n [\n activeInteractionElement,\n audioSlideIndexes,\n currentIndex,\n slideElementList,\n ]\n );\n\n const handleSubtitleJump = useCallback(\n (\n target: SlidePlayerSubtitleJumpTarget,\n context: SlidePlayerNavigationContext\n ) => {\n const targetAudio = audioList[target.audioIndex];\n const targetAudioKey = targetAudio?.audioKey;\n const targetSlideIndex = audioSlideIndexes[target.audioIndex];\n\n if (!targetAudioKey || targetSlideIndex == null) {\n return false;\n }\n\n if (!canJumpToSubtitleTarget(target)) {\n return false;\n }\n\n syncPlaybackPreferenceBeforeNavigation(context);\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n setHasCompletedCurrentStepAudio(false);\n setHasCurrentAudioPlaybackStarted(false);\n\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n\n if (targetSlideIndex === currentIndex) {\n pendingSubtitleJumpRef.current = null;\n resetAudioSequence();\n setCurrentAudioKey(targetAudioKey);\n requestSubtitleCueSeek(target);\n return true;\n }\n\n shouldScrollToBottomRef.current = true;\n resetAudioSequence();\n pendingSubtitleJumpRef.current = {\n audioIndex: target.audioIndex,\n audioKey: targetAudioKey,\n slideIndex: targetSlideIndex,\n timeMs: target.timeMs,\n };\n goTo(targetSlideIndex);\n\n return true;\n },\n [\n audioList,\n audioSlideIndexes,\n canJumpToSubtitleTarget,\n currentIndex,\n goTo,\n requestSubtitleCueSeek,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePrev = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goPrev();\n },\n [\n goPrev,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handleNext = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goNext();\n },\n [\n goNext,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handleSlideProgressNavigate = useCallback(\n (targetIndex: number, context: SlidePlayerNavigationContext) => {\n if (\n targetIndex < 0 ||\n targetIndex >= slideElementList.length ||\n targetIndex === currentIndex\n ) {\n return;\n }\n\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n resetAudioSequence();\n goTo(targetIndex);\n onSlideProgressNavigate?.(slideElementList[targetIndex], targetIndex);\n },\n [\n currentIndex,\n goTo,\n onSlideProgressNavigate,\n resetAudioSequence,\n revealPlayerControls,\n slideElementList,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePlayerLoadingChange = useCallback(\n ({\n loading,\n reason,\n }: {\n loading: boolean;\n reason: SlidePlayerLoadingReason | null;\n }) => {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (!currentStepHasSpeakableElement || hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (loading && reason) {\n setAudioLoadingReason(reason);\n }\n setIsAudioLoadingVisible(shouldShowBufferingOverlay(reason, loading));\n },\n [\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n ]\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n setIsAudioLoadingVisible(false);\n }, [disableLoadingOverlay]);\n\n const handlePlayerEnded = useCallback(\n (audioIndex: number) => {\n const endedAudioKey = audioList[audioIndex]?.audioKey;\n\n if (!endedAudioKey || !currentAudioKey) {\n return;\n }\n\n if (endedAudioKey !== currentAudioKey) {\n return;\n }\n\n playedAudioKeysRef.current.add(endedAudioKey);\n\n const activeSequencePosition = currentAudioSequenceKeys.findIndex(\n (audioSequenceKey) => audioSequenceKey === endedAudioKey\n );\n if (activeSequencePosition < 0) {\n setCurrentAudioKey(null);\n return;\n }\n\n const nextSequencePosition = activeSequencePosition + 1;\n const nextAudioKey = currentAudioSequenceKeys[nextSequencePosition];\n\n if (nextAudioKey) {\n setCurrentAudioKey(nextAudioKey);\n return;\n }\n\n setCurrentAudioKey(null);\n setHasCompletedCurrentStepAudio(true);\n setIsAudioLoadingVisible(false);\n\n if (canGoNext) {\n const nextStepIndex = currentIndex + 1;\n const nextStepElement = slideElementList[nextStepIndex];\n\n if (hasCurrentStepAudioUrl && nextStepElement?.type === \"interaction\") {\n pendingInteractionOverlayStepIndexRef.current = nextStepIndex;\n }\n\n goNext();\n return;\n }\n },\n [\n audioList,\n canGoNext,\n currentIndex,\n currentAudioKey,\n currentAudioSequenceKeys,\n goNext,\n hasCurrentStepAudioUrl,\n slideElementList,\n ]\n );\n\n const handlePlayerControlsPointerEnter = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = true;\n clearPlayerHideTimer();\n\n if (shouldMountPlayer) {\n setIsPlayerVisible(true);\n }\n }, [clearPlayerHideTimer, shouldMountPlayer]);\n\n const handlePlayerControlsPointerLeave = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = false;\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n\n const stopOverlayPropagation = useCallback(\n (\n event: React.PointerEvent<HTMLElement> | React.MouseEvent<HTMLElement>\n ) => {\n event.stopPropagation();\n\n // Keep the player visible a bit longer when users interact with the overlay.\n if (playerControlsVisible) {\n revealPlayerControls(true);\n }\n },\n [playerControlsVisible, revealPlayerControls]\n );\n\n const getInteractionOverlayDragBounds = useCallback(\n (\n overlayElement: HTMLElement,\n startOffset: InteractionOverlayDragOffset\n ): InteractionOverlayDragBounds | null => {\n const viewportElement = viewportRef.current;\n\n if (!viewportElement) {\n return null;\n }\n\n const overlayRect = overlayElement.getBoundingClientRect();\n const viewportRect = viewportElement.getBoundingClientRect();\n\n return {\n minX: startOffset.x + viewportRect.left - overlayRect.left,\n maxX: startOffset.x + viewportRect.right - overlayRect.right,\n minY: startOffset.y + viewportRect.top - overlayRect.top,\n maxY: startOffset.y + viewportRect.bottom - overlayRect.bottom,\n };\n },\n []\n );\n\n useIsomorphicLayoutEffect(() => {\n const overlayElement = interactionOverlayRef.current;\n\n if (!shouldShowInteractionOverlay || !overlayElement) {\n interactionOverlayLayoutRectRef.current = null;\n return;\n }\n\n const previousRect = interactionOverlayLayoutRectRef.current;\n const currentRect = overlayElement.getBoundingClientRect();\n\n if (!previousRect || isInteractionOverlayDragging) {\n interactionOverlayLayoutRectRef.current = {\n left: currentRect.left,\n top: currentRect.top,\n };\n return;\n }\n\n const deltaX = previousRect.left - currentRect.left;\n const deltaY = previousRect.top - currentRect.top;\n\n if (\n !hasMeaningfulInteractionOverlayLayoutDelta(deltaX) &&\n !hasMeaningfulInteractionOverlayLayoutDelta(deltaY)\n ) {\n interactionOverlayLayoutRectRef.current = {\n left: currentRect.left,\n top: currentRect.top,\n };\n return;\n }\n\n const nextOffset = {\n x: interactionOverlayDragOffset.x + deltaX,\n y: interactionOverlayDragOffset.y + deltaY,\n };\n const bounds = getInteractionOverlayDragBounds(\n overlayElement,\n interactionOverlayDragOffset\n );\n const clampedOffset = normalizeInteractionOverlayDragOffset(\n bounds\n ? clampInteractionOverlayDragOffset(nextOffset, bounds)\n : nextOffset\n );\n\n interactionOverlayLayoutRectRef.current = {\n left: currentRect.left + clampedOffset.x - interactionOverlayDragOffset.x,\n top: currentRect.top + clampedOffset.y - interactionOverlayDragOffset.y,\n };\n\n if (\n !areInteractionOverlayDragOffsetsEqual(\n clampedOffset,\n interactionOverlayDragOffset\n )\n ) {\n setInteractionOverlayDragOffset((previousOffset) =>\n areInteractionOverlayDragOffsetsEqual(previousOffset, clampedOffset)\n ? previousOffset\n : clampedOffset\n );\n }\n }, [\n getInteractionOverlayDragBounds,\n interactionOverlayDragOffset,\n isInteractionOverlayDragging,\n playerLayoutReserved,\n shouldShowInteractionOverlay,\n ]);\n\n const handleInteractionOverlayPointerDown = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n stopOverlayPropagation(event);\n\n if (\n event.button !== 0 ||\n !event.currentTarget.isConnected ||\n !interactionOverlayRef.current\n ) {\n return;\n }\n\n const bounds = getInteractionOverlayDragBounds(\n interactionOverlayRef.current,\n interactionOverlayDragOffset\n );\n\n if (!bounds) {\n return;\n }\n\n event.preventDefault();\n if (event.currentTarget.hasPointerCapture?.(event.pointerId) !== true) {\n event.currentTarget.setPointerCapture(event.pointerId);\n }\n interactionOverlayDragRef.current = {\n pointerId: event.pointerId,\n startClientX: event.clientX,\n startClientY: event.clientY,\n startOffset: interactionOverlayDragOffset,\n bounds,\n };\n setIsInteractionOverlayDragging(true);\n },\n [\n getInteractionOverlayDragBounds,\n interactionOverlayDragOffset,\n stopOverlayPropagation,\n ]\n );\n\n const handleInteractionOverlayPointerMove = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n const dragState = interactionOverlayDragRef.current;\n\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n setInteractionOverlayDragOffset(\n clampInteractionOverlayDragOffset(\n {\n x: dragState.startOffset.x + event.clientX - dragState.startClientX,\n y: dragState.startOffset.y + event.clientY - dragState.startClientY,\n },\n dragState.bounds\n )\n );\n },\n []\n );\n\n const endInteractionOverlayDrag = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n const dragState = interactionOverlayDragRef.current;\n\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n\n event.stopPropagation();\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n interactionOverlayDragRef.current = null;\n setIsInteractionOverlayDragging(false);\n },\n []\n );\n\n const handleSurfacePointerDown = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onPointerDown?.(event);\n },\n [activateKeyboardShortcutOwner, onPointerDown]\n );\n\n const handleSurfaceFocusCapture = useCallback(\n (event: React.FocusEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onFocusCapture?.(event);\n },\n [activateKeyboardShortcutOwner, onFocusCapture]\n );\n\n const handleSurfaceClick = useCallback(() => {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n useEffect(() => {\n const prevKeys = prevRenderElementKeysRef.current;\n const hasStablePrefix =\n prevKeys.length > 0 &&\n prevKeys.length < currentRenderElementKeys.length &&\n prevKeys.every((key, index) => key === currentRenderElementKeys[index]);\n const appendedElements = hasStablePrefix\n ? currentElementList.slice(prevKeys.length)\n : [];\n const shouldAutoScrollToAppend = appendedElements.some(\n (element) => element.is_new === false\n );\n\n prevRenderElementKeysRef.current = currentRenderElementKeys;\n\n if (!shouldAutoScrollToAppend) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n const stageLayerElement = stageLayerRef.current;\n const targetElement = lastElementRef.current;\n\n if (!stageLayerElement || !targetElement) {\n return;\n }\n\n const stageLayerRect = stageLayerElement.getBoundingClientRect();\n const targetRect = targetElement.getBoundingClientRect();\n const nextScrollTop =\n stageLayerElement.scrollTop + (targetRect.top - stageLayerRect.top);\n\n // Keep newly appended content visible when the current slide grows downward.\n stageLayerElement.scrollTo({\n top: Math.max(nextScrollTop, 0),\n behavior: \"smooth\",\n });\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, currentRenderElementKeys]);\n\n useEffect(() => {\n if (!shouldScrollToBottomRef.current) {\n return;\n }\n\n shouldScrollToBottomRef.current = false;\n\n if (currentElementList.length === 0) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n scrollStageToBottom();\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, scrollStageToBottom]);\n\n return (\n <section\n ref={sectionRef}\n className={cn(\n \"relative h-full w-full\",\n isMobileDevice && \"slide--mobile-device\",\n isDesktopBrowserFullscreen && \"slide--browser-fullscreen\",\n isImmersiveMobileFullscreen && \"slide--mobile-landscape\",\n isNativeMobileFullscreen && \"slide--mobile-landscape-native\",\n className\n )}\n dir={direction}\n lang={language}\n onClick={handleSurfaceClick}\n onFocusCapture={handleSurfaceFocusCapture}\n onPointerDown={handleSurfacePointerDown}\n {...props}\n >\n {shouldShowMobileFullscreenMask ? (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none fixed left-0 top-0 z-[9999] h-[100vh] max-h-[100vh] w-[100vw]\"\n />\n ) : null}\n\n <div\n ref={viewportRef}\n className={cn(\n \"slide__viewport relative h-full min-h-0 w-full\",\n isImmersiveMobileFullscreen && \"slide__viewport--mobile-landscape\",\n isImmersiveMobileFullscreen &&\n !shouldRotateFullscreenViewport &&\n \"slide__viewport--mobile-landscape-native\"\n )}\n >\n {shouldShowFullscreenHeader ? (\n <div className=\"slide-landscape-header\">\n <button\n aria-label={\n fullscreenHeader?.backAriaLabel ??\n localeTexts.fullscreenBackAriaLabel\n }\n className=\"slide-landscape-header__back\"\n onClick={handleFullscreenHeaderBack}\n type=\"button\"\n >\n <ChevronLeft\n className=\"slide-landscape-header__icon h-6 w-6\"\n strokeWidth={2.25}\n />\n </button>\n\n {fullscreenHeader?.content ? (\n <div className=\"min-w-0 flex-1 overflow-hidden\">\n {fullscreenHeader.content}\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div\n className={cn(\n \"h-full min-h-0 w-full\",\n shouldApplyFullscreenViewportPadding &&\n \"slide__viewport-content--with-header\",\n isSingleSlide ? \"slide-content--single\" : \"grid gap-4\"\n )}\n >\n {currentElementList.length > 0 ? (\n <div className=\"slide-stage\">\n <div ref={stageLayerRef} className=\"slide-stage__layer w-full\">\n {mountedStepStates.map(\n (mountedStepState, mountedStepStateIndex) => {\n const isActiveStep =\n mountedStepStateIndex === currentMountedStateIndex;\n\n return (\n <div\n key={\n mountedStepState.sourceStepIndexes[0] ??\n mountedStepStateIndex\n }\n data-active-step={isActiveStep ? \"true\" : undefined}\n aria-hidden={!isActiveStep || undefined}\n className=\"w-full h-full\"\n style={{ display: isActiveStep ? undefined : \"none\" }}\n >\n {renderSlideElementList(\n mountedStepState.elementList,\n isActiveStep\n )}\n </div>\n );\n }\n )}\n </div>\n </div>\n ) : null}\n </div>\n\n {isAudioLoadingVisible ? (\n <LoadingOverlayCard\n message={resolveBufferingTextByReason(\n resolvedBufferingText,\n audioLoadingReason\n )}\n className=\"absolute left-1/2 top-1/2 z-[3] -translate-x-1/2 -translate-y-1/2\"\n />\n ) : null}\n\n <SubtitleOverlay\n extraBottomOffset={interactionOverlaySubtitleOffset}\n hasPlayerGap={playerLayoutReserved}\n isEnabled={isSubtitleEnabled && hasCurrentAudioPlaybackStarted}\n playbackTimeStore={playbackTimeStore}\n subtitleCues={currentSubtitleCues}\n />\n\n {shouldShowInteractionOverlay ? (\n <div\n ref={interactionOverlayRef}\n data-player-keyboard-shortcuts-ignore=\"true\"\n className={cn(\n \"slide-interaction-overlay\",\n playerLayoutReserved\n ? \"slide-interaction-overlay--with-player\"\n : \"slide-interaction-overlay--standalone\",\n isInteractionOverlayDragging &&\n \"slide-interaction-overlay--dragging\"\n )}\n onClick={stopOverlayPropagation}\n onPointerDownCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n onFocusCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n onInputCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n style={interactionOverlayStyle}\n >\n <InteractionOverlayCard\n dir={direction}\n lang={language}\n content={String(activeInteractionElement?.content ?? \"\")}\n dragHandleAriaLabel={\n interactionTexts?.dragHandleAriaLabel ??\n localeTexts.interactionTexts.dragHandleAriaLabel\n }\n locale={locale}\n defaultButtonText={interactionDefaults.buttonText ?? \"\"}\n defaultInputText={interactionDefaults.inputText ?? \"\"}\n defaultSelectedValues={interactionDefaultSelectedValues}\n confirmButtonText={\n interactionTexts?.confirmButtonText ??\n localeTexts.interactionTexts.confirmButtonText\n }\n copyButtonText={\n interactionTexts?.copyButtonText ??\n localeTexts.interactionTexts.copyButtonText\n }\n copiedButtonText={\n interactionTexts?.copiedButtonText ??\n localeTexts.interactionTexts.copiedButtonText\n }\n onSend={handleInteractionSend}\n onDragHandlePointerCancel={endInteractionOverlayDrag}\n onDragHandlePointerDown={handleInteractionOverlayPointerDown}\n onDragHandlePointerMove={handleInteractionOverlayPointerMove}\n onDragHandlePointerUp={endInteractionOverlayDrag}\n readonly={isInteractionReadonly}\n title={\n interactionTexts?.title ??\n interactionTitle ??\n localeTexts.interactionTexts.title\n }\n />\n </div>\n ) : null}\n\n {shouldMountPlayer ? (\n <PlayerKeyboardShortcutContext.Provider\n value={keyboardShortcutContextValue}\n >\n <Player\n dir={direction === \"auto\" ? resolvedDirection : direction}\n lang={language}\n audioList={audioList}\n className={cn(\n \"absolute left-1/2 z-[2] -translate-x-1/2\",\n isDesktopBrowserFullscreen ? \"bottom-3\" : \"-bottom-3\",\n playerClassName,\n !playerControlsVisible && \"pointer-events-none opacity-0\"\n )}\n currentAudioIndex={currentAudioIndex}\n defaultPlaying={isPlaybackRequested}\n enableKeyboardShortcuts={enableKeyboardShortcuts}\n isPlaybackPaused={shouldPausePlaybackForCustomAction}\n isAutoAdvanceEnabled={isAutoAdvanceEnabled}\n locale={locale}\n isInteractionOpen={isInteractionOverlayOpen}\n isSubtitleEnabled={isSubtitleEnabled}\n onAutoAdvanceToggle={setIsAutoAdvanceEnabled}\n onLoadingChange={handlePlayerLoadingChange}\n onPlaybackStarted={() => {\n setHasCurrentAudioPlaybackStarted(true);\n }}\n onPlaybackCheckpoint={({ audioKey, isComplete, timeMs }) => {\n const checkpointAudioIndex = audioList.findIndex(\n (audioItem) => audioItem.audioKey === audioKey\n );\n const checkpointAudioItem =\n checkpointAudioIndex >= 0\n ? audioList[checkpointAudioIndex]\n : undefined;\n\n if (\n !checkpointAudioItem?.audioKey ||\n !checkpointAudioItem.element\n ) {\n return;\n }\n\n onPlaybackCheckpoint?.({\n audioKey: checkpointAudioItem.audioKey,\n element: checkpointAudioItem.element,\n isComplete,\n stepIndex:\n audioSlideIndexes[checkpointAudioIndex] ?? currentIndex,\n timeMs,\n });\n }}\n onPlaybackPreferenceChange={handlePlaybackPreferenceChange}\n onPlaybackTimeChange={playbackTimeStore.setTime}\n onSubtitleToggle={() => {\n setIsSubtitleEnabled((previousEnabled) => !previousEnabled);\n }}\n nextDisabled={!canGoNext}\n onEnded={handlePlayerEnded}\n onFullscreen={handleFullscreen}\n isFullscreen={isBrowserFullscreen}\n mobileViewMode={effectiveMobileViewMode}\n settingsPortalContainer={viewportRef.current}\n onMobileViewModeChange={handleMobileViewModeSelect}\n onControlsPointerEnter={handlePlayerControlsPointerEnter}\n onControlsPointerLeave={handlePlayerControlsPointerLeave}\n onNext={handleNext}\n onPrev={handlePrev}\n onSubtitleJump={handleSubtitleJump}\n canJumpToSubtitleTarget={canJumpToSubtitleTarget}\n prevDisabled={!canGoPrev}\n showControls={playerControlsVisible}\n slideProgress={\n showSlideProgress\n ? {\n ariaLabel: localeTexts.slideProgressAriaLabel,\n currentIndex,\n generatingLabel: localeTexts.slideProgressGeneratingLabel,\n isGenerating: isSlideProgressGenerating,\n onNavigate: handleSlideProgressNavigate,\n totalSteps: generatedSlideCount,\n }\n : null\n }\n subtitleSeekRequest={subtitleSeekRequest}\n playbackRestoreRequest={\n pendingPlaybackRestore &&\n pendingPlaybackRestore.audioKey === currentAudioItem?.audioKey\n ? {\n id: pendingPlaybackRestore.id,\n timeMs: pendingPlaybackRestore.timeMs,\n }\n : null\n }\n onPlaybackRestoreComplete={(requestId) => {\n if (pendingPlaybackRestoreRef.current?.id !== requestId) {\n return;\n }\n\n pendingPlaybackRestoreRef.current = null;\n setPendingPlaybackRestore(null);\n }}\n texts={playerTexts}\n customActionContext={playerCustomActionContext}\n customActions={playerCustomActions}\n useAutoAdvanceToggle={shouldUseSilentStepAutoAdvanceToggle}\n />\n </PlayerKeyboardShortcutContext.Provider>\n ) : null}\n </div>\n </section>\n );\n};\n\nexport default Slide;\n"],"names":["DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX","DEFAULT_INTERACTION_SUBTITLE_GAP_PX","DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET","INTERACTION_OVERLAY_LAYOUT_EPSILON_PX","useIsomorphicLayoutEffect","useEffect","useLayoutEffect","INTERACTION_ACTIVITY_SELECTOR","DEFAULT_BUFFERING_REASON","normalizeInteractionOverlayDragOffset","x","y","hasMeaningfulInteractionOverlayLayoutDelta","delta","areInteractionOverlayDragOffsetsEqual","first","second","resolveBufferingTextByReason","bufferingText","reason","DEFAULT_SLIDE_BUFFERING_TEXTS","mergeBufferingTextWithLocaleDefaults","localeBufferingText","shouldShowBufferingOverlay","loading","InteractionOverlayCard","memo","content","title","dragHandleAriaLabel","locale","dir","lang","defaultButtonText","defaultInputText","defaultSelectedValues","confirmButtonText","copyButtonText","copiedButtonText","onSend","onDragHandlePointerCancel","onDragHandlePointerDown","onDragHandlePointerMove","onDragHandlePointerUp","readonly","jsxs","jsx","GripHorizontal","ContentRender","areStepElementListsEqual","prevElementList","nextElementList","element","index","nextElement","isInteractionActivityTarget","target","Slide","elementList","playerEnabled","playerControlsVisibility","playerClassName","fullscreenHeader","playerCustomActions","playerCustomActionPauseOnActive","interactionTitle","interactionTexts","playerTexts","playerAutoHideDelay","markerAutoAdvanceDelay","showSlideProgress","isSlideProgressGenerating","onSlideProgressNavigate","interactionDefaultValueOptions","onPlayerVisibilityChange","onMobileViewModeChange","onStepChange","onPlaybackCheckpoint","playbackRestoreRequest","enableKeyboardShortcuts","enableIframeScaling","enableMarkdownScaling","disableLoadingOverlay","className","onPointerDown","onFocusCapture","props","direction","getMarkdownFlowDirection","language","getMarkdownFlowLanguage","localeTexts","useMemo","getSlideLocaleTexts","resolvedBufferingText","resolvedPlayerEnabled","resolvedPlayerControlsVisibility","resolveSlidePlayerVisibility","keyboardShortcutOwnerId","useId","sectionRef","useRef","resolvedDirection","useResolvedDirection","viewportRef","stageLayerRef","lastElementRef","playerHideTimerRef","isPointerInsidePlayerControlsRef","autoAdvanceTimerRef","imageOnlyStepReadyTimeoutRef","interactionAutoCloseTimerRef","interactionOverlayOpenTimerRef","interactionOverlayRef","interactionOverlayLayoutRectRef","interactionOverlayDragRef","prevRenderElementKeysRef","shouldScrollToBottomRef","pendingInteractionOverlayStepIndexRef","pendingSubtitleJumpRef","subtitleSeekRequestIdRef","playbackResetKeyRef","appendedMarkerAdvanceStateRef","shouldSkipDefaultAudioStartForSubtitleJumpRef","currentElementList","stepElementLists","slideElementList","currentIndex","audioList","audioSlideIndexes","currentAudioSequenceIndexes","currentStepHasSpeakableElement","currentInteractionElement","canGoPrev","canGoNext","goPrev","goNext","goTo","useSlide","currentStepElement","currentRenderElementKeys","generatedSlideCount","isSingleSlide","shouldMountPlayer","keyboardShortcutContextValue","activateKeyboardShortcutOwner","useCallback","activatePlayerKeyboardShortcutOwner","currentAudioSequenceKeys","audioIndex","audioKey","isPlayerVisible","setIsPlayerVisible","useState","hasPlayerInteracted","setHasPlayerInteracted","isPlaybackRequested","setIsPlaybackRequested","isAutoAdvanceEnabled","setIsAutoAdvanceEnabled","currentAudioKey","setCurrentAudioKey","pendingPlaybackRestore","setPendingPlaybackRestore","pendingPlaybackRestoreRef","lastPlaybackRestoreRequestIdRef","subtitleSeekRequest","setSubtitleSeekRequest","isAudioLoadingVisible","setIsAudioLoadingVisible","audioLoadingReason","setAudioLoadingReason","hasCompletedCurrentStepAudio","setHasCompletedCurrentStepAudio","playedAudioKeysRef","hasCurrentAudioPlaybackStarted","setHasCurrentAudioPlaybackStarted","isSubtitleEnabled","setIsSubtitleEnabled","isPlayerCustomActionActive","setIsPlayerCustomActionActive","activeInteractionElement","setActiveInteractionElement","isInteractionOverlayOpen","setIsInteractionOverlayOpen","hasInteractionOverlayActivity","setHasInteractionOverlayActivity","interactionOverlayDragOffset","setInteractionOverlayDragOffset","isInteractionOverlayDragging","setIsInteractionOverlayDragging","interactionOverlaySubtitleOffset","setInteractionOverlaySubtitleOffset","isBrowserFullscreen","setIsBrowserFullscreen","isMobileDevice","getIsMobileDevice","mobileViewMode","setMobileViewMode","DEFAULT_MOBILE_VIEW_MODE","hasManualMobileViewMode","setHasManualMobileViewMode","isViewportFullscreenPreferred","setIsViewportFullscreenPreferred","getIsFullscreenPreferredViewport","playbackTimeStore","createPlaybackTimeStore","effectiveMobileViewMode","isImmersiveMobileFullscreen","isNativeMobileFullscreen","shouldRotateFullscreenViewport","resolveMobileViewModeState","previousEffectiveMobileViewModeRef","playerControlsVisible","playerLayoutReserved","resolveSlidePlayerLayoutState","shouldShowFullscreenHeader","shouldApplyFullscreenViewportPadding","shouldShowMobileFullscreenMask","isDesktopBrowserFullscreen","handleMobileViewModeSelect","nextViewMode","handleMobileViewModeReset","handleFullscreenHeaderBack","clearInteractionAutoCloseTimer","clearInteractionOverlayOpenTimer","closeInteractionOverlayForCustomAction","setPlayerCustomActionActive","active","togglePlayerCustomActionActive","previousActive","resetInteractionOverlayDragState","previousOffset","mountedStepStates","currentMountedStateIndex","nextMountedStepStates","mountedStateIndexByStep","stepElementList","stepIndex","existingMountedStateIndex","mountedStepState","currentStepKey","currentAudioIndex","audioItem","currentAudioItem","targetAudioIndex","targetStepIndex","currentSubtitleCues","currentAudioSequenceStartKey","playerCustomActionContext","resolvePlayerCustomActionElement","playerCustomActionCount","getPlayerCustomActionCount","hasPlayerCustomActions","isPlayerCustomActionEffectivelyActive","interactionOverlayStyle","hasAvailableStepAudio","currentInteractionResetKey","currentPlaybackResetKey","currentPlaybackStartedResetKey","hasCurrentStepAudioUrl","shouldPausePlaybackForCustomAction","shouldUseSilentStepAutoAdvanceToggle","shouldUseAutoAdvanceToggle","silentStepAutoAdvanceBehavior","resolveSilentStepAutoAdvanceBehavior","silentStepAutoAdvanceDelay","isImageOnlySilentStep","imageOnlyStepVisualReadyKey","readyImageOnlyStepKey","setReadyImageOnlyStepKey","isImageOnlyStepVisualReady","clearPlayerHideTimer","clearAutoAdvanceTimer","clearImageOnlyStepReadyTimeout","resetAudioSequence","options","requestSubtitleCueSeek","startCurrentAudioSequence","nextAudioKey","resolvePendingStepAudioKey","continueAfterInteraction","scheduleInteractionOverlayOpen","interactionElement","openOverlay","isPlayerControlsHovered","revealPlayerControls","enableAutoHide","hasResolvedCurrentInteraction","hasResolvedInteractionElement","shouldBlockPlaybackForInteraction","handlePlaybackPreferenceChange","playing","syncPlaybackPreferenceBeforeNavigation","context","cancelled","rafId","cleanupListeners","detachListeners","finishVisualReady","evaluateVisualReady","activeStepContainer","iframeElements","areImageOnlyStepIframeVisualsReady","cleanupCallbacks","queueRecheck","registerEvent","eventName","listener","iframeElement","iframeDocument","image","cleanup","DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS","syncViewportFullscreenPreference","handleOrientationChange","unsubscribeMobileDeviceChange","subscribeMobileDeviceChange","previousState","shouldAdvanceIntoAppendedMarker","shouldAutoAdvanceIntoAppendedMarker","handleSandboxInteraction","event","isSandboxInteractionMessage","useWakePlayerFromIframe","hasPlaybackContextChanged","shouldInitializeAudioSequence","getPlaybackSequenceTransition","shouldOpenInteractionOverlayAfterAudio","shouldPresentOverlay","shouldPresentInteractionOverlay","pendingSubtitleJump","shouldPreservePendingSubtitleJump","canReachSubtitleJumpTarget","hasUnplayedStepAudio","shouldSkipDefaultAudioStart","shouldStartDefaultAudioSequence","interactionDefaults","interactionDefaultSelectedValues","hasResolvedInteractionInput","resolvedInteractionReadonly","shouldAutoContinueInteraction","resolveSlideInteractionState","isInteractionReadonly","shouldShowInteractionOverlay","shouldRenderInteractionOverlay","handleInteractionSend","resolvedUserInput","prevElement","syncFullscreenState","interactionOverlayElement","updateSubtitleOffset","overlayHeight","resizeObserver","renderSlideElement","Fragment","IframeSandbox","renderSlideElementList","isActiveStep","visibleElementCount","markdownScalingMode","resolveMarkdownScalingMode","lastVisibleElementIndex","lastVisibleIndex","MarkdownSlideScaling","isPreRenderedHtml","cn","handleFullscreen","scrollStageToBottom","stageLayerElement","canJumpToSubtitleTarget","handleSubtitleJump","targetAudioKey","targetSlideIndex","shouldWakePlayerControlsAfterNavigation","handlePrev","handleNext","handleSlideProgressNavigate","targetIndex","handlePlayerLoadingChange","handlePlayerEnded","endedAudioKey","activeSequencePosition","audioSequenceKey","nextSequencePosition","nextStepIndex","nextStepElement","handlePlayerControlsPointerEnter","handlePlayerControlsPointerLeave","stopOverlayPropagation","getInteractionOverlayDragBounds","overlayElement","startOffset","viewportElement","overlayRect","viewportRect","previousRect","currentRect","deltaX","deltaY","nextOffset","bounds","clampedOffset","clampInteractionOverlayDragOffset","handleInteractionOverlayPointerDown","handleInteractionOverlayPointerMove","dragState","endInteractionOverlayDrag","handleSurfacePointerDown","handleSurfaceFocusCapture","handleSurfaceClick","prevKeys","shouldAutoScrollToAppend","key","animationFrameId","targetElement","stageLayerRect","targetRect","nextScrollTop","ChevronLeft","mountedStepStateIndex","LoadingOverlayCard","SubtitleOverlay","PlayerKeyboardShortcutContext","Player","isComplete","timeMs","checkpointAudioIndex","checkpointAudioItem","previousEnabled","requestId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Slide.es.js","sources":["../../../src/components/Slide/Slide.tsx"],"sourcesContent":["import React, {\n memo,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ChevronLeft, GripHorizontal } from \"lucide-react\";\n\nimport { isSandboxInteractionMessage } from \"../../lib/sandboxInteraction\";\nimport { cn } from \"../../lib/utils\";\nimport { useResolvedDirection } from \"../../lib/useResolvedDirection\";\nimport {\n getMarkdownFlowDirection,\n getMarkdownFlowLanguage,\n type MarkdownFlowLocale,\n} from \"../../lib/locale\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport ContentRender from \"../ContentRender\";\nimport type { ContentRenderProps } from \"../ContentRender/ContentRender\";\nimport IframeSandbox from \"../ContentRender/IframeSandbox\";\nimport type { OnSendContentParams } from \"../types\";\nimport type { InteractionDefaultValueOptions } from \"../../lib/interaction-defaults\";\nimport {\n isLandscapeViewport as getIsFullscreenPreferredViewport,\n isMobileDevice as getIsMobileDevice,\n subscribeMobileDeviceChange,\n} from \"../../lib/mobileDevice\";\nimport Player from \"./Player\";\nimport MarkdownSlideScaling from \"./MarkdownSlideScaling\";\nimport SubtitleOverlay from \"./SubtitleOverlay\";\nimport type {\n PlayerProps,\n SlidePlayerNavigationContext,\n SlidePlayerSubtitleJumpTarget,\n SlidePlayerSubtitleSeekRequest,\n SlidePlayerTexts,\n} from \"./Player\";\nimport type { SlidePlayerLoadingReason } from \"./Player\";\nimport type { Element } from \"./types\";\nimport useSlide from \"./useSlide\";\nimport useWakePlayerFromIframe from \"./useWakePlayerFromIframe\";\nimport { PlayerKeyboardShortcutContext } from \"./utils/playerKeyboardShortcutContext\";\nimport { activatePlayerKeyboardShortcutOwner } from \"./utils/playerKeyboardShortcuts\";\nimport {\n DEFAULT_MOBILE_VIEW_MODE,\n resolveMobileViewModeState,\n type MobileViewMode,\n} from \"./utils/mobileScreenMode\";\nimport {\n clampInteractionOverlayDragOffset,\n shouldPresentInteractionOverlay,\n shouldRenderInteractionOverlay,\n type InteractionOverlayDragBounds,\n type InteractionOverlayDragOffset,\n} from \"./utils/interactionPlayback\";\nimport { resolveMarkdownScalingMode } from \"./utils/markdownScaling\";\nimport { shouldWakePlayerControlsAfterNavigation } from \"./utils/playerNavigationContext\";\nimport { shouldAutoAdvanceIntoAppendedMarker } from \"./utils/appendedMarkerAdvance\";\nimport {\n hasUnplayedStepAudio,\n resolvePendingStepAudioKey,\n} from \"./utils/stepAudioProgress\";\nimport {\n getPlaybackSequenceTransition,\n shouldStartDefaultAudioSequence,\n} from \"./utils/playbackSequence\";\nimport {\n canReachSubtitleJumpTarget,\n hasResolvedInteractionElement,\n} from \"./utils/subtitleJumpNavigation\";\nimport {\n getPlayerCustomActionCount,\n resolvePlayerCustomActionElement,\n} from \"./utils/playerCustomActions\";\nimport { createPlaybackTimeStore } from \"./utils/playbackTimeStore\";\nimport { resolveSlideInteractionState } from \"./utils/interactionResolution\";\nimport { shouldUseAutoAdvanceToggle } from \"./utils/playerToggleMode\";\nimport {\n areImageOnlyStepIframeVisualsReady,\n DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS,\n} from \"./utils/imageOnlyStepVisualReady\";\nimport { resolveSilentStepAutoAdvanceBehavior } from \"./utils/silentStepAutoAdvance\";\nimport {\n resolveSlidePlayerLayoutState,\n resolveSlidePlayerVisibility,\n type SlidePlayerControlsVisibility,\n} from \"./utils/playerVisibility\";\nimport {\n DEFAULT_SLIDE_BUFFERING_TEXTS,\n getSlideLocaleTexts,\n type SlideBufferingReason,\n} from \"./slideI18n\";\nimport \"./slide.css\";\nexport type {\n Element,\n ElementAudioSegment,\n ElementSubtitleCue,\n SlidePlayerCustomActionContext,\n SlidePlayerCustomActions,\n} from \"./types\";\nexport type { SlidePlayerControlsVisibility } from \"./utils/playerVisibility\";\n\nconst DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS = 2000;\nconst DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS = 300;\nconst DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX = 160;\nconst DEFAULT_INTERACTION_SUBTITLE_GAP_PX = 16;\nconst DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS = 3000;\nconst DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET: InteractionOverlayDragOffset = {\n x: 0,\n y: 0,\n};\nconst INTERACTION_OVERLAY_LAYOUT_EPSILON_PX = 0.5;\ntype InteractionOverlayLayoutRect = Pick<DOMRect, \"left\" | \"top\">;\nconst useIsomorphicLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\nconst INTERACTION_ACTIVITY_SELECTOR = [\n \"button\",\n \"input\",\n \"textarea\",\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\"]',\n '[contenteditable=\"plaintext-only\"]',\n].join(\", \");\nconst DEFAULT_BUFFERING_REASON: SlideBufferingReason = \"waitingForAudio\";\n\nconst normalizeInteractionOverlayDragOffset = ({\n x,\n y,\n}: InteractionOverlayDragOffset): InteractionOverlayDragOffset => ({\n x: Number(x.toFixed(2)),\n y: Number(y.toFixed(2)),\n});\n\nconst hasMeaningfulInteractionOverlayLayoutDelta = (delta: number) =>\n Math.abs(delta) >= INTERACTION_OVERLAY_LAYOUT_EPSILON_PX;\n\nconst areInteractionOverlayDragOffsetsEqual = (\n first: InteractionOverlayDragOffset,\n second: InteractionOverlayDragOffset\n) =>\n Math.abs(first.x - second.x) < INTERACTION_OVERLAY_LAYOUT_EPSILON_PX &&\n Math.abs(first.y - second.y) < INTERACTION_OVERLAY_LAYOUT_EPSILON_PX;\n\nexport type { SlideBufferingReason } from \"./slideI18n\";\n\nexport type SlideBufferingTextConfig =\n | string\n | Partial<Record<SlideBufferingReason, string>>;\n\nconst resolveBufferingTextByReason = (\n bufferingText: SlideBufferingTextConfig,\n reason: SlideBufferingReason\n) => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return (\n bufferingText[reason] ??\n bufferingText[DEFAULT_BUFFERING_REASON] ??\n DEFAULT_SLIDE_BUFFERING_TEXTS[reason]\n );\n};\n\nconst mergeBufferingTextWithLocaleDefaults = (\n bufferingText: SlideBufferingTextConfig | undefined,\n localeBufferingText: Record<string, string>\n): SlideBufferingTextConfig => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return {\n ...localeBufferingText,\n ...bufferingText,\n };\n};\n\nconst shouldShowBufferingOverlay = (\n reason: SlideBufferingReason | null,\n loading: boolean\n) => {\n if (!loading) {\n return false;\n }\n\n // Keep the silent preload/loading phase invisible until audio is actually playable.\n return reason !== \"loadingAudio\";\n};\n\ntype RenderSlideElementOptions = {\n replaceRootScreenHeightWithFull?: boolean;\n};\n\ninterface InteractionOverlayCardProps {\n dir?: ContentRenderProps[\"dir\"];\n lang?: string;\n content: string;\n title: string;\n dragHandleAriaLabel: string;\n locale?: MarkdownFlowLocale;\n defaultButtonText?: string;\n defaultInputText?: string;\n defaultSelectedValues?: string[];\n confirmButtonText?: string;\n copyButtonText?: string;\n copiedButtonText?: string;\n onSend?: (content: OnSendContentParams) => void;\n onDragHandlePointerCancel?: React.PointerEventHandler<HTMLButtonElement>;\n onDragHandlePointerDown?: React.PointerEventHandler<HTMLButtonElement>;\n onDragHandlePointerMove?: React.PointerEventHandler<HTMLButtonElement>;\n onDragHandlePointerUp?: React.PointerEventHandler<HTMLButtonElement>;\n readonly?: boolean;\n}\n\nexport interface SlideInteractionTexts\n extends Pick<\n ContentRenderProps,\n \"confirmButtonText\" | \"copyButtonText\" | \"copiedButtonText\"\n > {\n title?: string;\n /** Accessible label for the interaction panel drag handle. */\n dragHandleAriaLabel?: string;\n}\n\nexport type SlideFullscreenHeader = {\n content?: React.ReactNode;\n backAriaLabel?: string;\n onBack?: () => void;\n};\n\nconst InteractionOverlayCard = memo(\n ({\n content,\n title,\n dragHandleAriaLabel,\n locale,\n dir,\n lang,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n onSend,\n onDragHandlePointerCancel,\n onDragHandlePointerDown,\n onDragHandlePointerMove,\n onDragHandlePointerUp,\n readonly = false,\n }: InteractionOverlayCardProps) => (\n <div className=\"slide-player__interaction-card\">\n <button\n type=\"button\"\n className=\"slide-player__interaction-drag-handle\"\n aria-label={dragHandleAriaLabel}\n onPointerCancel={onDragHandlePointerCancel}\n onPointerDown={onDragHandlePointerDown}\n onPointerMove={onDragHandlePointerMove}\n onPointerUp={onDragHandlePointerUp}\n >\n <span className=\"slide-player__interaction-drag-handle-icon\">\n <GripHorizontal aria-hidden=\"true\" />\n <GripHorizontal aria-hidden=\"true\" />\n <GripHorizontal aria-hidden=\"true\" />\n </span>\n </button>\n <div className=\"slide-player__interaction-header\">\n <p className=\"slide-player__interaction-title\">{title}</p>\n </div>\n <div className=\"slide-player__interaction-body\">\n <ContentRender\n content={content}\n locale={locale}\n dir={dir}\n lang={lang}\n defaultButtonText={defaultButtonText}\n defaultInputText={defaultInputText}\n defaultSelectedValues={defaultSelectedValues}\n confirmButtonText={confirmButtonText}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n onSend={onSend}\n readonly={readonly}\n sandboxMode=\"content\"\n />\n </div>\n </div>\n )\n);\n\nInteractionOverlayCard.displayName = \"InteractionOverlayCard\";\n\nconst areStepElementListsEqual = (\n prevElementList: Element[],\n nextElementList: Element[]\n) =>\n prevElementList.length === nextElementList.length &&\n prevElementList.every((element, index) => {\n const nextElement = nextElementList[index];\n\n return (\n element.sequence_number === nextElement?.sequence_number &&\n element.type === nextElement?.type &&\n element.content === nextElement?.content\n );\n });\n\nconst isInteractionActivityTarget = (\n target: EventTarget | null\n): target is HTMLElement =>\n target instanceof HTMLElement &&\n Boolean(target.closest(INTERACTION_ACTIVITY_SELECTOR));\nexport interface SlideProps extends React.ComponentProps<\"section\"> {\n elementList?: Element[];\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /** Enables the player runtime, including audio playback and keyboard shortcuts. */\n playerEnabled?: boolean;\n /**\n * Controls whether the player controls are always visible, always hidden, or auto-hidden.\n *\n * Use `\"hidden\"` to keep audio playback and keyboard shortcuts active while\n * hiding the visual controls.\n *\n * @example\n * ```tsx\n * <Slide playerControlsVisibility=\"hidden\" enableKeyboardShortcuts />\n * ```\n */\n playerControlsVisibility?: SlidePlayerControlsVisibility;\n playerClassName?: string;\n fullscreenHeader?: SlideFullscreenHeader;\n playerCustomActions?: PlayerProps[\"customActions\"];\n playerCustomActionPauseOnActive?: boolean;\n bufferingText?: SlideBufferingTextConfig;\n interactionTitle?: string;\n interactionTexts?: SlideInteractionTexts;\n playerTexts?: SlidePlayerTexts;\n playerAutoHideDelay?: number;\n markerAutoAdvanceDelay?: number;\n /** Shows an interactive navigation timeline for generated slide steps. */\n showSlideProgress?: boolean;\n /** Indicates that more generated slide steps may still be appended. */\n isSlideProgressGenerating?: boolean;\n /** Fired when a generated slide is selected from the progress navigation. */\n onSlideProgressNavigate?: (\n element: Element | undefined,\n index: number\n ) => void;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n onSend?: (content: OnSendContentParams, element?: Element) => void;\n onPlayerVisibilityChange?: (visible: boolean) => void;\n onMobileViewModeChange?: (viewMode: MobileViewMode) => void;\n onStepChange?: (element: Element | undefined, index: number) => void;\n /** Emits a low-frequency checkpoint for the active logical audio item. */\n onPlaybackCheckpoint?: (checkpoint: SlidePlaybackCheckpoint) => void;\n /** Restores one logical audio item and continues its normal playback. */\n playbackRestoreRequest?: SlidePlaybackRestoreRequest | null;\n /**\n * Enables keyboard shortcuts for existing player actions.\n *\n * Defaults to `true`. The active slide responds after users click, touch, or\n * focus the slide/player surface; ignored targets include form controls and\n * interaction overlays.\n *\n * @example\n * ```tsx\n * <Slide elementList={slides} enableKeyboardShortcuts={false} />\n * ```\n */\n enableKeyboardShortcuts?: boolean;\n enableIframeScaling?: boolean;\n /**\n * Fits Markdown-only slides to the available presentation viewport.\n *\n * Defaults to `true`. Disable this to preserve the fixed 16px article\n * typography used by standalone ContentRender.\n */\n enableMarkdownScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nexport interface SlidePlaybackCheckpoint {\n audioKey: string;\n element: Element;\n isComplete: boolean;\n stepIndex: number;\n timeMs: number;\n}\n\nexport interface SlidePlaybackRestoreRequest {\n audioKey: string;\n id: number | string;\n timeMs: number;\n}\n\nconst Slide: React.FC<SlideProps> = ({\n elementList = [],\n locale,\n playerEnabled,\n playerControlsVisibility,\n playerClassName,\n fullscreenHeader,\n playerCustomActions,\n playerCustomActionPauseOnActive = true,\n bufferingText,\n interactionTitle,\n interactionTexts,\n playerTexts,\n playerAutoHideDelay = 3000,\n markerAutoAdvanceDelay = DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS,\n showSlideProgress = false,\n isSlideProgressGenerating = false,\n onSlideProgressNavigate,\n interactionDefaultValueOptions,\n onSend,\n onPlayerVisibilityChange,\n onMobileViewModeChange,\n onStepChange,\n onPlaybackCheckpoint,\n playbackRestoreRequest = null,\n enableKeyboardShortcuts = true,\n enableIframeScaling = true,\n enableMarkdownScaling = true,\n disableLoadingOverlay = false,\n className,\n dir,\n lang,\n onPointerDown,\n onFocusCapture,\n ...props\n}) => {\n const direction = dir ?? getMarkdownFlowDirection(locale);\n const language = lang ?? getMarkdownFlowLanguage(locale);\n const localeTexts = useMemo(() => getSlideLocaleTexts(locale), [locale]);\n const resolvedBufferingText = useMemo(\n () =>\n mergeBufferingTextWithLocaleDefaults(\n bufferingText,\n localeTexts.bufferingText\n ),\n [bufferingText, localeTexts.bufferingText]\n );\n const {\n playerEnabled: resolvedPlayerEnabled,\n playerControlsVisibility: resolvedPlayerControlsVisibility,\n } = resolveSlidePlayerVisibility({\n playerEnabled,\n playerControlsVisibility,\n });\n const keyboardShortcutOwnerId = useId();\n const sectionRef = useRef<HTMLElement | null>(null);\n const { resolvedDirection } = useResolvedDirection(sectionRef, direction);\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const stageLayerRef = useRef<HTMLDivElement | null>(null);\n const lastElementRef = useRef<HTMLDivElement | null>(null);\n const playerHideTimerRef = useRef<number | null>(null);\n const isPointerInsidePlayerControlsRef = useRef(false);\n const autoAdvanceTimerRef = useRef<number | null>(null);\n const imageOnlyStepReadyTimeoutRef = useRef<number | null>(null);\n const interactionAutoCloseTimerRef = useRef<number | null>(null);\n const interactionOverlayOpenTimerRef = useRef<number | null>(null);\n const interactionOverlayRef = useRef<HTMLDivElement | null>(null);\n const interactionOverlayLayoutRectRef =\n useRef<InteractionOverlayLayoutRect | null>(null);\n const interactionOverlayDragRef = useRef<{\n pointerId: number;\n startClientX: number;\n startClientY: number;\n startOffset: InteractionOverlayDragOffset;\n bounds: InteractionOverlayDragBounds;\n } | null>(null);\n const prevRenderElementKeysRef = useRef<string[]>([]);\n const shouldScrollToBottomRef = useRef(false);\n const pendingInteractionOverlayStepIndexRef = useRef<number | null>(null);\n const pendingSubtitleJumpRef = useRef<{\n audioIndex: number;\n audioKey: string;\n slideIndex: number;\n timeMs: number;\n } | null>(null);\n const subtitleSeekRequestIdRef = useRef(0);\n const playbackResetKeyRef = useRef<string | null>(null);\n const appendedMarkerAdvanceStateRef = useRef({\n markerCount: 0,\n currentIndex: -1,\n canGoNext: false,\n });\n const shouldSkipDefaultAudioStartForSubtitleJumpRef = useRef(false);\n const {\n currentElementList,\n stepElementLists,\n slideElementList,\n currentIndex,\n audioList,\n audioSlideIndexes,\n currentAudioSequenceIndexes,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n canGoPrev,\n canGoNext,\n handlePrev: goPrev,\n handleNext: goNext,\n handleGoTo: goTo,\n } = useSlide(elementList);\n const currentStepElement = useMemo(() => {\n if (currentIndex < 0) {\n return undefined;\n }\n\n return slideElementList[currentIndex];\n }, [currentIndex, slideElementList]);\n const currentRenderElementKeys = useMemo(\n () =>\n currentElementList.map(\n (element, index) =>\n `${element.sequence_number ?? `${element.type}-${index}`}:${String(element.is_new ?? \"\")}`\n ),\n [currentElementList]\n );\n const generatedSlideCount = slideElementList.length;\n const isSingleSlide = generatedSlideCount === 1;\n const shouldMountPlayer =\n resolvedPlayerEnabled &&\n (slideElementList.length > 0 ||\n audioList.length > 0 ||\n Boolean(currentInteractionElement));\n const keyboardShortcutContextValue = useMemo(\n () => ({\n enabled: enableKeyboardShortcuts,\n ownerId: keyboardShortcutOwnerId,\n }),\n [enableKeyboardShortcuts, keyboardShortcutOwnerId]\n );\n const activateKeyboardShortcutOwner = useCallback(() => {\n if (!enableKeyboardShortcuts || !shouldMountPlayer) {\n return;\n }\n\n activatePlayerKeyboardShortcutOwner(keyboardShortcutOwnerId);\n }, [enableKeyboardShortcuts, keyboardShortcutOwnerId, shouldMountPlayer]);\n const currentAudioSequenceKeys = useMemo(\n () =>\n currentAudioSequenceIndexes\n .map((audioIndex) => audioList[audioIndex]?.audioKey)\n .filter((audioKey): audioKey is string => Boolean(audioKey)),\n [audioList, currentAudioSequenceIndexes]\n );\n const [isPlayerVisible, setIsPlayerVisible] = useState(true);\n const [hasPlayerInteracted, setHasPlayerInteracted] = useState(false);\n const [isPlaybackRequested, setIsPlaybackRequested] = useState(true);\n const [isAutoAdvanceEnabled, setIsAutoAdvanceEnabled] = useState(true);\n const [currentAudioKey, setCurrentAudioKey] = useState<string | null>(null);\n const [pendingPlaybackRestore, setPendingPlaybackRestore] =\n useState<SlidePlaybackRestoreRequest | null>(null);\n const pendingPlaybackRestoreRef = useRef<SlidePlaybackRestoreRequest | null>(\n null\n );\n const lastPlaybackRestoreRequestIdRef = useRef<number | string | null>(null);\n const [subtitleSeekRequest, setSubtitleSeekRequest] =\n useState<SlidePlayerSubtitleSeekRequest | null>(null);\n const [isAudioLoadingVisible, setIsAudioLoadingVisible] = useState(false);\n const [audioLoadingReason, setAudioLoadingReason] =\n useState<SlideBufferingReason>(DEFAULT_BUFFERING_REASON);\n const [hasCompletedCurrentStepAudio, setHasCompletedCurrentStepAudio] =\n useState(false);\n // Audio keys already played within the current step. A step's audio arrives\n // progressively while content is still being generated, so \"completed\" has to\n // mean \"every key played\" rather than \"reached the end of the list once\".\n const playedAudioKeysRef = useRef<Set<string>>(new Set());\n const [hasCurrentAudioPlaybackStarted, setHasCurrentAudioPlaybackStarted] =\n useState(false);\n const [isSubtitleEnabled, setIsSubtitleEnabled] = useState(true);\n const [isPlayerCustomActionActive, setIsPlayerCustomActionActive] =\n useState(false);\n const [activeInteractionElement, setActiveInteractionElement] = useState<\n Element | undefined\n >();\n const [isInteractionOverlayOpen, setIsInteractionOverlayOpen] =\n useState(false);\n const [hasInteractionOverlayActivity, setHasInteractionOverlayActivity] =\n useState(false);\n const [interactionOverlayDragOffset, setInteractionOverlayDragOffset] =\n useState<InteractionOverlayDragOffset>(\n DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET\n );\n const [isInteractionOverlayDragging, setIsInteractionOverlayDragging] =\n useState(false);\n const [\n interactionOverlaySubtitleOffset,\n setInteractionOverlaySubtitleOffset,\n ] = useState(0);\n const [isBrowserFullscreen, setIsBrowserFullscreen] = useState(false);\n const isMobileDevice = useMemo(() => getIsMobileDevice(), []);\n const [mobileViewMode, setMobileViewMode] = useState<MobileViewMode>(\n DEFAULT_MOBILE_VIEW_MODE\n );\n const [hasManualMobileViewMode, setHasManualMobileViewMode] = useState(false);\n const [isViewportFullscreenPreferred, setIsViewportFullscreenPreferred] =\n useState(() =>\n isMobileDevice ? getIsFullscreenPreferredViewport() : false\n );\n const playbackTimeStore = useMemo(() => createPlaybackTimeStore(), []);\n const {\n effectiveMobileViewMode,\n isImmersiveMobileFullscreen,\n isNativeMobileFullscreen,\n shouldRotateFullscreenViewport,\n } = useMemo(\n () =>\n resolveMobileViewModeState({\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n }),\n [\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n ]\n );\n const previousEffectiveMobileViewModeRef = useRef(effectiveMobileViewMode);\n const {\n controlsVisible: playerControlsVisible,\n layoutReserved: playerLayoutReserved,\n } = resolveSlidePlayerLayoutState({\n isAutoVisible: isPlayerVisible,\n playerControlsVisibility: resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n });\n const shouldShowFullscreenHeader =\n isImmersiveMobileFullscreen && playerControlsVisible;\n const shouldApplyFullscreenViewportPadding =\n isImmersiveMobileFullscreen && playerLayoutReserved;\n const shouldShowMobileFullscreenMask =\n isImmersiveMobileFullscreen || isNativeMobileFullscreen;\n const isDesktopBrowserFullscreen = isBrowserFullscreen && !isMobileDevice;\n const handleMobileViewModeSelect = useCallback(\n (nextViewMode: MobileViewMode) => {\n setHasManualMobileViewMode(true);\n setMobileViewMode(nextViewMode);\n },\n []\n );\n const handleMobileViewModeReset = useCallback(() => {\n // Clear manual override so the effective mode returns to the default non-fullscreen state.\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, []);\n const handleFullscreenHeaderBack = useCallback(() => {\n handleMobileViewModeReset();\n fullscreenHeader?.onBack?.();\n }, [fullscreenHeader, handleMobileViewModeReset]);\n\n const clearInteractionAutoCloseTimer = useCallback(() => {\n if (interactionAutoCloseTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionAutoCloseTimerRef.current);\n interactionAutoCloseTimerRef.current = null;\n }, []);\n\n const clearInteractionOverlayOpenTimer = useCallback(() => {\n if (interactionOverlayOpenTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionOverlayOpenTimerRef.current);\n interactionOverlayOpenTimerRef.current = null;\n }, []);\n\n const closeInteractionOverlayForCustomAction = useCallback(() => {\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n }, [clearInteractionAutoCloseTimer, clearInteractionOverlayOpenTimer]);\n\n const setPlayerCustomActionActive = useCallback(\n (active: boolean) => {\n if (active) {\n closeInteractionOverlayForCustomAction();\n }\n\n setIsPlayerCustomActionActive(active);\n },\n [closeInteractionOverlayForCustomAction]\n );\n const togglePlayerCustomActionActive = useCallback(() => {\n closeInteractionOverlayForCustomAction();\n setIsPlayerCustomActionActive((previousActive) => !previousActive);\n }, [closeInteractionOverlayForCustomAction]);\n const resetInteractionOverlayDragState = useCallback(() => {\n setInteractionOverlayDragOffset((previousOffset) =>\n previousOffset.x === DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET.x &&\n previousOffset.y === DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET.y\n ? previousOffset\n : DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET\n );\n setIsInteractionOverlayDragging(false);\n interactionOverlayDragRef.current = null;\n interactionOverlayLayoutRectRef.current = null;\n }, []);\n const { mountedStepStates, currentMountedStateIndex } = useMemo(() => {\n const nextMountedStepStates: Array<{\n elementList: Element[];\n sourceStepIndexes: number[];\n }> = [];\n const mountedStateIndexByStep = new Map<number, number>();\n\n stepElementLists.forEach((stepElementList, stepIndex) => {\n const existingMountedStateIndex = nextMountedStepStates.findIndex(\n (mountedStepState) =>\n areStepElementListsEqual(\n mountedStepState.elementList,\n stepElementList\n )\n );\n\n if (existingMountedStateIndex >= 0) {\n nextMountedStepStates[\n existingMountedStateIndex\n ]?.sourceStepIndexes.push(stepIndex);\n mountedStateIndexByStep.set(stepIndex, existingMountedStateIndex);\n return;\n }\n\n nextMountedStepStates.push({\n elementList: stepElementList,\n sourceStepIndexes: [stepIndex],\n });\n mountedStateIndexByStep.set(stepIndex, nextMountedStepStates.length - 1);\n });\n\n return {\n mountedStepStates: nextMountedStepStates,\n currentMountedStateIndex:\n currentIndex >= 0\n ? (mountedStateIndexByStep.get(currentIndex) ?? -1)\n : -1,\n };\n }, [currentIndex, stepElementLists]);\n const currentStepKey = useMemo(() => String(currentIndex), [currentIndex]);\n const currentAudioIndex = useMemo(() => {\n if (!currentAudioKey) {\n return -1;\n }\n\n return audioList.findIndex(\n (audioItem) => (audioItem.audioKey ?? \"\") === currentAudioKey\n );\n }, [audioList, currentAudioKey]);\n const currentAudioItem = useMemo(\n () => (currentAudioIndex >= 0 ? audioList[currentAudioIndex] : undefined),\n [audioList, currentAudioIndex]\n );\n\n useEffect(() => {\n if (\n !playbackRestoreRequest ||\n playbackRestoreRequest.id === lastPlaybackRestoreRequestIdRef.current\n ) {\n return;\n }\n\n const targetAudioIndex = audioList.findIndex(\n (audioItem) => audioItem.audioKey === playbackRestoreRequest.audioKey\n );\n if (targetAudioIndex < 0) {\n return;\n }\n\n const targetStepIndex = audioSlideIndexes[targetAudioIndex];\n if (targetStepIndex == null) {\n return;\n }\n\n lastPlaybackRestoreRequestIdRef.current = playbackRestoreRequest.id;\n setIsPlaybackRequested(true);\n setCurrentAudioKey(playbackRestoreRequest.audioKey);\n pendingPlaybackRestoreRef.current = playbackRestoreRequest;\n setPendingPlaybackRestore(playbackRestoreRequest);\n if (currentIndex !== targetStepIndex) {\n goTo(targetStepIndex);\n }\n }, [\n audioList,\n audioSlideIndexes,\n currentIndex,\n goTo,\n playbackRestoreRequest,\n ]);\n const currentSubtitleCues = currentAudioItem?.element?.subtitle_cues ?? [];\n const currentAudioSequenceStartKey = useMemo(\n () => currentAudioSequenceKeys[0] ?? \"none\",\n [currentAudioSequenceKeys]\n );\n const playerCustomActionContext = useMemo(\n () => ({\n currentElement: resolvePlayerCustomActionElement({\n currentAudioIndex,\n currentAudioSequenceIndexes,\n audioList,\n currentInteractionElement: activeInteractionElement,\n currentStepElement,\n }),\n currentIndex,\n currentStepElement,\n isActive: isPlayerCustomActionActive,\n setActive: setPlayerCustomActionActive,\n toggleActive: togglePlayerCustomActionActive,\n }),\n [\n activeInteractionElement,\n audioList,\n currentAudioIndex,\n currentAudioSequenceIndexes,\n currentIndex,\n currentStepElement,\n isPlayerCustomActionActive,\n setPlayerCustomActionActive,\n togglePlayerCustomActionActive,\n ]\n );\n const playerCustomActionCount = useMemo(\n () =>\n getPlayerCustomActionCount(\n playerCustomActions,\n playerCustomActionContext\n ),\n [playerCustomActionContext, playerCustomActions]\n );\n const hasPlayerCustomActions = playerCustomActionCount > 0;\n const isPlayerCustomActionEffectivelyActive =\n hasPlayerCustomActions && isPlayerCustomActionActive;\n const interactionOverlayStyle = useMemo(\n () =>\n ({\n \"--slide-player-custom-action-count\": String(playerCustomActionCount),\n \"--slide-player-mobile-control-count\": String(\n playerCustomActionCount + 4\n ),\n \"--slide-interaction-drag-x\": `${interactionOverlayDragOffset.x}px`,\n \"--slide-interaction-drag-y\": `${interactionOverlayDragOffset.y}px`,\n }) as React.CSSProperties,\n [\n interactionOverlayDragOffset.x,\n interactionOverlayDragOffset.y,\n playerCustomActionCount,\n ]\n );\n const hasAvailableStepAudio = currentAudioSequenceKeys.length > 0;\n const currentInteractionResetKey = useMemo(() => {\n if (!currentInteractionElement) {\n return \"none\";\n }\n\n return `${currentInteractionElement.sequence_number ?? \"none\"}:${String(\n currentInteractionElement.content ?? \"\"\n )}`;\n }, [currentInteractionElement]);\n const currentPlaybackResetKey = useMemo(\n () => [currentStepKey, currentInteractionResetKey].join(\"|\"),\n [currentInteractionResetKey, currentStepKey]\n );\n const currentPlaybackStartedResetKey = useMemo(\n () =>\n [\n currentPlaybackResetKey,\n currentAudioItem?.audioKey ?? \"none\",\n String(currentAudioIndex),\n ].join(\"|\"),\n [currentAudioIndex, currentAudioItem?.audioKey, currentPlaybackResetKey]\n );\n const currentStepAudioUrl = useMemo(() => {\n if (\n !currentAudioSequenceStartKey ||\n currentAudioSequenceStartKey === \"none\"\n ) {\n return \"\";\n }\n\n const currentStepAudioItem = audioList.find(\n (audioItem) => audioItem.audioKey === currentAudioSequenceStartKey\n );\n\n return currentStepAudioItem?.audioUrl?.trim() ?? \"\";\n }, [audioList, currentAudioSequenceStartKey]);\n const hasCurrentStepAudioUrl = Boolean(currentStepAudioUrl);\n const shouldPausePlaybackForCustomAction =\n playerCustomActionPauseOnActive && isPlayerCustomActionEffectivelyActive;\n const shouldUseSilentStepAutoAdvanceToggle = useMemo(\n () =>\n shouldUseAutoAdvanceToggle({\n canGoNext,\n currentAudioIndex,\n currentStepHasSpeakableElement,\n hasInteraction: Boolean(currentInteractionElement),\n }),\n [\n canGoNext,\n currentAudioIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n ]\n );\n const silentStepAutoAdvanceBehavior = useMemo(\n () =>\n resolveSilentStepAutoAdvanceBehavior({\n currentElementList,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n markerAutoAdvanceDelay,\n }),\n [\n currentElementList,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n markerAutoAdvanceDelay,\n ]\n );\n const silentStepAutoAdvanceDelay = silentStepAutoAdvanceBehavior.delayMs;\n const isImageOnlySilentStep =\n silentStepAutoAdvanceBehavior.usesImageOnlyDelay;\n const imageOnlyStepVisualReadyKey = useMemo(\n () => `${currentIndex}:${currentRenderElementKeys.join(\"|\")}`,\n [currentIndex, currentRenderElementKeys]\n );\n const [readyImageOnlyStepKey, setReadyImageOnlyStepKey] = useState<\n string | null\n >(null);\n const isImageOnlyStepVisualReady =\n !isImageOnlySilentStep ||\n readyImageOnlyStepKey === imageOnlyStepVisualReadyKey;\n\n const clearPlayerHideTimer = useCallback(() => {\n if (playerHideTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(playerHideTimerRef.current);\n playerHideTimerRef.current = null;\n }, []);\n\n const clearAutoAdvanceTimer = useCallback(() => {\n if (autoAdvanceTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(autoAdvanceTimerRef.current);\n autoAdvanceTimerRef.current = null;\n }, []);\n\n const clearImageOnlyStepReadyTimeout = useCallback(() => {\n if (imageOnlyStepReadyTimeoutRef.current === null) {\n return;\n }\n\n window.clearTimeout(imageOnlyStepReadyTimeoutRef.current);\n imageOnlyStepReadyTimeoutRef.current = null;\n }, []);\n\n const resetAudioSequence = useCallback(\n (\n options: {\n preservePendingSubtitleJump?: boolean;\n } = {}\n ) => {\n clearAutoAdvanceTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n clearImageOnlyStepReadyTimeout();\n setCurrentAudioKey(null);\n playbackTimeStore.reset();\n setIsAudioLoadingVisible(false);\n setAudioLoadingReason(DEFAULT_BUFFERING_REASON);\n setHasCompletedCurrentStepAudio(false);\n playedAudioKeysRef.current = new Set();\n setHasCurrentAudioPlaybackStarted(false);\n setSubtitleSeekRequest(null);\n if (!options.preservePendingSubtitleJump) {\n pendingSubtitleJumpRef.current = null;\n }\n setActiveInteractionElement(undefined);\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n },\n [\n clearAutoAdvanceTimer,\n clearImageOnlyStepReadyTimeout,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n playbackTimeStore,\n ]\n );\n\n const requestSubtitleCueSeek = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) => {\n subtitleSeekRequestIdRef.current += 1;\n setSubtitleSeekRequest({\n ...target,\n id: subtitleSeekRequestIdRef.current,\n });\n },\n []\n );\n\n const startCurrentAudioSequence = useCallback(() => {\n // Resume at the first key that has not played yet. Falling back to index 0\n // unconditionally would replay the opening segment every time late audio\n // extends the current step.\n const nextAudioKey = resolvePendingStepAudioKey(\n currentAudioSequenceKeys,\n playedAudioKeysRef.current\n );\n\n if (!nextAudioKey) {\n return false;\n }\n\n // Start the first pending audio segment for the current step immediately.\n setCurrentAudioKey(nextAudioKey);\n return true;\n }, [currentAudioSequenceKeys]);\n\n const continueAfterInteraction = useCallback(() => {\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (canGoNext) {\n goNext();\n }\n }, [\n canGoNext,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n goNext,\n startCurrentAudioSequence,\n ]);\n\n const scheduleInteractionOverlayOpen = useCallback(\n (interactionElement?: Element) => {\n clearInteractionOverlayOpenTimer();\n\n if (!interactionElement) {\n return;\n }\n\n const openOverlay = () => {\n interactionOverlayOpenTimerRef.current = null;\n setInteractionOverlaySubtitleOffset(\n DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX\n );\n setIsInteractionOverlayOpen(true);\n pendingInteractionOverlayStepIndexRef.current = null;\n };\n\n interactionOverlayOpenTimerRef.current = window.setTimeout(\n openOverlay,\n DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS\n );\n },\n [clearInteractionOverlayOpenTimer]\n );\n\n const isPlayerControlsHovered = useCallback(\n () =>\n isPointerInsidePlayerControlsRef.current ||\n Boolean(\n sectionRef.current?.querySelector(\".slide-player__controls:hover\")\n ),\n []\n );\n\n const revealPlayerControls = useCallback(\n (enableAutoHide = hasPlayerInteracted) => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n return;\n }\n\n setIsPlayerVisible(true);\n clearPlayerHideTimer();\n\n if (\n resolvedPlayerControlsVisibility === \"visible\" ||\n !enableAutoHide ||\n playerAutoHideDelay <= 0 ||\n isPlayerControlsHovered()\n ) {\n return;\n }\n\n playerHideTimerRef.current = window.setTimeout(() => {\n if (isPlayerControlsHovered()) {\n playerHideTimerRef.current = null;\n return;\n }\n\n setIsPlayerVisible(false);\n playerHideTimerRef.current = null;\n }, playerAutoHideDelay);\n },\n [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n isPlayerControlsHovered,\n playerAutoHideDelay,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n ]\n );\n\n const hasResolvedCurrentInteraction = Boolean(\n hasResolvedInteractionElement(currentInteractionElement)\n );\n\n const shouldBlockPlaybackForInteraction =\n Boolean(currentInteractionElement) && !hasResolvedCurrentInteraction;\n\n const handlePlaybackPreferenceChange = useCallback((playing: boolean) => {\n setIsPlaybackRequested(playing);\n }, []);\n\n const syncPlaybackPreferenceBeforeNavigation = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n if (context) {\n setIsPlaybackRequested(context.shouldContinuePlayback);\n }\n },\n []\n );\n\n useEffect(() => {\n // Keep silent-step autoplay aligned with the same play/pause preference as audio.\n setIsAutoAdvanceEnabled(isPlaybackRequested);\n }, [currentIndex, isPlaybackRequested, playerCustomActionPauseOnActive]);\n\n useEffect(() => {\n if (playerCustomActionPauseOnActive) {\n setPlayerCustomActionActive(false);\n }\n }, [\n currentIndex,\n playerCustomActionPauseOnActive,\n setPlayerCustomActionActive,\n ]);\n\n useEffect(() => {\n if (!hasPlayerCustomActions) {\n setIsPlayerCustomActionActive(false);\n }\n }, [hasPlayerCustomActions]);\n\n useEffect(() => {\n return () => {\n clearAutoAdvanceTimer();\n clearImageOnlyStepReadyTimeout();\n clearPlayerHideTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n };\n }, [\n clearAutoAdvanceTimer,\n clearImageOnlyStepReadyTimeout,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n clearPlayerHideTimer,\n ]);\n\n useEffect(() => {\n if (!isImageOnlySilentStep) {\n clearImageOnlyStepReadyTimeout();\n return;\n }\n\n let cancelled = false;\n let rafId: number | null = null;\n let cleanupListeners: (() => void) | null = null;\n\n const detachListeners = () => {\n cleanupListeners?.();\n cleanupListeners = null;\n };\n\n const finishVisualReady = () => {\n if (cancelled) {\n return;\n }\n\n detachListeners();\n clearImageOnlyStepReadyTimeout();\n setReadyImageOnlyStepKey(imageOnlyStepVisualReadyKey);\n };\n\n const evaluateVisualReady = () => {\n if (cancelled) {\n return;\n }\n\n detachListeners();\n\n const activeStepContainer = stageLayerRef.current?.querySelector(\n '[data-active-step=\"true\"]'\n ) as HTMLElement | null;\n\n if (!activeStepContainer) {\n return;\n }\n\n const iframeElements = Array.from(\n activeStepContainer.querySelectorAll(\"iframe\")\n ) as HTMLIFrameElement[];\n\n if (\n iframeElements.length === 0 ||\n areImageOnlyStepIframeVisualsReady(iframeElements)\n ) {\n finishVisualReady();\n return;\n }\n\n const cleanupCallbacks: Array<() => void> = [];\n const queueRecheck = () => {\n if (cancelled) {\n return;\n }\n\n if (rafId !== null) {\n window.cancelAnimationFrame(rafId);\n }\n\n rafId = window.requestAnimationFrame(() => {\n rafId = null;\n evaluateVisualReady();\n });\n };\n const registerEvent = (\n target: EventTarget,\n eventName: string,\n listener: EventListener\n ) => {\n target.addEventListener(eventName, listener, { once: true });\n cleanupCallbacks.push(() =>\n target.removeEventListener(eventName, listener)\n );\n };\n\n iframeElements.forEach((iframeElement) => {\n const iframeDocument = iframeElement.contentDocument;\n\n if (!iframeDocument || iframeDocument.readyState !== \"complete\") {\n registerEvent(iframeElement, \"load\", queueRecheck);\n return;\n }\n\n Array.from(iframeDocument.images)\n .filter((image) => !image.complete)\n .forEach((image) => {\n registerEvent(image, \"load\", queueRecheck);\n registerEvent(image, \"error\", queueRecheck);\n });\n });\n\n cleanupListeners = () => {\n cleanupCallbacks.forEach((cleanup) => cleanup());\n };\n };\n\n rafId = window.requestAnimationFrame(() => {\n rafId = null;\n evaluateVisualReady();\n });\n\n imageOnlyStepReadyTimeoutRef.current = window.setTimeout(() => {\n finishVisualReady();\n }, DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS);\n\n return () => {\n cancelled = true;\n detachListeners();\n clearImageOnlyStepReadyTimeout();\n if (rafId !== null) {\n window.cancelAnimationFrame(rafId);\n }\n };\n }, [\n clearImageOnlyStepReadyTimeout,\n currentElementList,\n currentIndex,\n imageOnlyStepVisualReadyKey,\n isImageOnlySilentStep,\n ]);\n\n useEffect(() => {\n onPlayerVisibilityChange?.(playerControlsVisible);\n\n return () => {\n onPlayerVisibilityChange?.(false);\n };\n }, [onPlayerVisibilityChange, playerControlsVisible]);\n\n useEffect(() => {\n if (playerControlsVisible) {\n return;\n }\n\n isPointerInsidePlayerControlsRef.current = false;\n }, [playerControlsVisible]);\n\n useEffect(() => {\n if (isMobileDevice || mobileViewMode === DEFAULT_MOBILE_VIEW_MODE) {\n return;\n }\n\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, [isMobileDevice, mobileViewMode]);\n\n useEffect(() => {\n if (!isMobileDevice) {\n setIsViewportFullscreenPreferred(false);\n return;\n }\n\n const syncViewportFullscreenPreference = () => {\n setIsViewportFullscreenPreferred(getIsFullscreenPreferredViewport());\n resetInteractionOverlayDragState();\n };\n const handleOrientationChange = () => {\n resetInteractionOverlayDragState();\n };\n\n syncViewportFullscreenPreference();\n window.addEventListener(\"orientationchange\", handleOrientationChange);\n window.screen?.orientation?.addEventListener?.(\n \"change\",\n handleOrientationChange\n );\n const unsubscribeMobileDeviceChange = subscribeMobileDeviceChange(\n syncViewportFullscreenPreference\n );\n\n return () => {\n unsubscribeMobileDeviceChange();\n window.removeEventListener(\"orientationchange\", handleOrientationChange);\n window.screen?.orientation?.removeEventListener?.(\n \"change\",\n handleOrientationChange\n );\n };\n }, [isMobileDevice, resetInteractionOverlayDragState]);\n\n useEffect(() => {\n onMobileViewModeChange?.(effectiveMobileViewMode);\n }, [effectiveMobileViewMode, onMobileViewModeChange]);\n\n useEffect(() => {\n if (\n previousEffectiveMobileViewModeRef.current !== effectiveMobileViewMode\n ) {\n resetInteractionOverlayDragState();\n }\n previousEffectiveMobileViewModeRef.current = effectiveMobileViewMode;\n }, [effectiveMobileViewMode, resetInteractionOverlayDragState]);\n\n useEffect(() => {\n onStepChange?.(currentStepElement, currentIndex);\n }, [currentIndex, currentStepElement, onStepChange]);\n\n useEffect(() => {\n const previousState = appendedMarkerAdvanceStateRef.current;\n const shouldAdvanceIntoAppendedMarker = shouldAutoAdvanceIntoAppendedMarker(\n {\n previousMarkerCount: previousState.markerCount,\n nextMarkerCount: slideElementList.length,\n previousIndex: previousState.currentIndex,\n previousCanGoNext: previousState.canGoNext,\n nextCanGoNext: canGoNext,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n }\n );\n\n appendedMarkerAdvanceStateRef.current = {\n markerCount: slideElementList.length,\n currentIndex,\n canGoNext,\n };\n\n if (!shouldAdvanceIntoAppendedMarker) {\n return;\n }\n\n goNext();\n }, [\n canGoNext,\n currentAudioKey,\n currentIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n goNext,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n slideElementList.length,\n ]);\n\n useEffect(() => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(false);\n return;\n }\n\n if (resolvedPlayerControlsVisibility === \"visible\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(true);\n return;\n }\n\n if (!hasPlayerInteracted) {\n // Keep the initial player visible briefly, then hide it automatically.\n revealPlayerControls(true);\n }\n }, [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n revealPlayerControls,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleSandboxInteraction = (event: MessageEvent) => {\n if (event.origin !== window.location.origin) {\n return;\n }\n\n if (!isSandboxInteractionMessage(event.data)) {\n return;\n }\n\n if (event.data.eventType !== \"click\") {\n return;\n }\n\n if (!shouldMountPlayer) {\n return;\n }\n\n // Restore player controls on explicit click/tap without waking on scroll start.\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n };\n\n window.addEventListener(\"message\", handleSandboxInteraction);\n\n return () => {\n window.removeEventListener(\"message\", handleSandboxInteraction);\n };\n }, [activateKeyboardShortcutOwner, shouldMountPlayer, revealPlayerControls]);\n\n useWakePlayerFromIframe({\n sectionRef,\n enabled: shouldMountPlayer,\n keyboardShortcutsEnabled: enableKeyboardShortcuts,\n onKeyboardShortcut: activateKeyboardShortcutOwner,\n onWake: () => {\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n },\n });\n\n useEffect(() => {\n if (!shouldMountPlayer) {\n resetAudioSequence();\n return;\n }\n\n // A restore request sets the target audio in an earlier effect. Without\n // this guard, the normal first-audio initializer in this same commit can\n // overwrite that target before Player receives the restore request.\n if (pendingPlaybackRestoreRef.current) {\n // Record the target context before Player finishes its restore callback.\n // The next sequence effect then sees this step as initialized instead of\n // resetting it back to the default first audio item.\n playbackResetKeyRef.current = currentPlaybackResetKey;\n return;\n }\n\n const { hasPlaybackContextChanged, shouldInitializeAudioSequence } =\n getPlaybackSequenceTransition({\n previousResetKey: playbackResetKeyRef.current,\n nextResetKey: currentPlaybackResetKey,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n });\n\n playbackResetKeyRef.current = currentPlaybackResetKey;\n\n const shouldOpenInteractionOverlayAfterAudio =\n pendingInteractionOverlayStepIndexRef.current === currentIndex &&\n Boolean(currentInteractionElement);\n const shouldPresentOverlay = shouldPresentInteractionOverlay({\n hasInteraction: Boolean(currentInteractionElement),\n shouldBlockPlaybackForInteraction,\n shouldOpenInteractionOverlayAfterAudio,\n hasPlaybackContextChanged,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n isPlayerCustomActionActive: isPlayerCustomActionEffectivelyActive,\n });\n\n const pendingSubtitleJump = pendingSubtitleJumpRef.current;\n const shouldPreservePendingSubtitleJump =\n pendingSubtitleJump?.slideIndex === currentIndex;\n\n if (hasPlaybackContextChanged) {\n resetAudioSequence({\n preservePendingSubtitleJump: shouldPreservePendingSubtitleJump,\n });\n }\n\n if (currentElementList.length === 0 && !currentInteractionElement) {\n return;\n }\n\n if (shouldPausePlaybackForCustomAction) {\n return;\n }\n\n if (pendingSubtitleJump?.slideIndex === currentIndex) {\n if (\n !canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: pendingSubtitleJump.slideIndex,\n })\n ) {\n // Keep the pending seek queued while the interaction overlay gates playback.\n } else {\n pendingSubtitleJumpRef.current = null;\n // The default audio-start effect still sees the pre-seek render state.\n // Skip it once so it does not replace the subtitle target audio.\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = true;\n setCurrentAudioKey(pendingSubtitleJump.audioKey);\n requestSubtitleCueSeek({\n audioIndex: pendingSubtitleJump.audioIndex,\n timeMs: pendingSubtitleJump.timeMs,\n });\n return;\n }\n }\n\n if (currentInteractionElement) {\n setActiveInteractionElement(currentInteractionElement);\n }\n\n if (shouldPresentOverlay) {\n // Delay auto-presenting the overlay so subtitles can settle above it.\n scheduleInteractionOverlayOpen(currentInteractionElement);\n return;\n }\n\n clearInteractionOverlayOpenTimer();\n pendingInteractionOverlayStepIndexRef.current = null;\n\n // A custom action may intentionally remain active without pausing ordinary\n // playback. Unresolved interactions still gate progression even while that\n // action temporarily owns the visible overlay surface.\n if (shouldBlockPlaybackForInteraction) {\n return;\n }\n\n if (!shouldInitializeAudioSequence) {\n return;\n }\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (currentStepHasSpeakableElement) {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setIsAudioLoadingVisible(true);\n return;\n }\n\n if (!canGoNext) {\n return;\n }\n\n if (shouldUseSilentStepAutoAdvanceToggle && !isAutoAdvanceEnabled) {\n return;\n }\n\n if (isImageOnlySilentStep && !isImageOnlyStepVisualReady) {\n return;\n }\n\n // Auto-advance silent marker-only steps so playback flow does not stall.\n autoAdvanceTimerRef.current = window.setTimeout(() => {\n autoAdvanceTimerRef.current = null;\n goNext();\n }, silentStepAutoAdvanceDelay);\n\n return () => {\n clearAutoAdvanceTimer();\n };\n }, [\n activeInteractionElement,\n canGoNext,\n clearAutoAdvanceTimer,\n currentElementList.length,\n currentIndex,\n currentInteractionElement,\n currentAudioKey,\n currentPlaybackResetKey,\n currentStepHasSpeakableElement,\n isImageOnlySilentStep,\n isImageOnlyStepVisualReady,\n silentStepAutoAdvanceDelay,\n goNext,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n isAutoAdvanceEnabled,\n hasResolvedCurrentInteraction,\n isPlayerCustomActionEffectivelyActive,\n shouldBlockPlaybackForInteraction,\n clearInteractionOverlayOpenTimer,\n resetAudioSequence,\n requestSubtitleCueSeek,\n scheduleInteractionOverlayOpen,\n shouldMountPlayer,\n slideElementList,\n startCurrentAudioSequence,\n shouldPausePlaybackForCustomAction,\n shouldUseSilentStepAutoAdvanceToggle,\n ]);\n\n useEffect(() => {\n if (\n disableLoadingOverlay ||\n shouldPausePlaybackForCustomAction ||\n !currentStepHasSpeakableElement ||\n shouldBlockPlaybackForInteraction\n ) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasAvailableStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setAudioLoadingReason(\"waitingForAudio\");\n setIsAudioLoadingVisible(true);\n }, [\n hasAvailableStepAudio,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n ]);\n\n // A step's audio can keep arriving after the last available segment finished,\n // because narration is synthesized while the lesson is still streaming. The\n // step-completed flag is otherwise only cleared when the reset key changes -\n // which tracks the step index and the interaction content, neither of which\n // moves while new audio is appended to the step the learner is already on.\n // Without this, everything synthesized after that first gap stays silent.\n useEffect(() => {\n if (!hasCompletedCurrentStepAudio) {\n return;\n }\n\n if (\n !hasUnplayedStepAudio(\n currentAudioSequenceKeys,\n playedAudioKeysRef.current\n )\n ) {\n return;\n }\n\n setHasCompletedCurrentStepAudio(false);\n }, [currentAudioSequenceKeys, hasCompletedCurrentStepAudio]);\n\n useEffect(() => {\n // A restore request may arrive after the slide itself mounts. Do not let\n // this independent default-start path select the first audio item while\n // the restore target is still being applied.\n if (pendingPlaybackRestoreRef.current) {\n return;\n }\n\n const shouldSkipDefaultAudioStart =\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current;\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = false;\n\n if (\n !shouldStartDefaultAudioSequence({\n currentAudioKey,\n currentAudioSequenceLength: currentAudioSequenceKeys.length,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldBlockPlaybackForInteraction,\n shouldPausePlaybackForCustomAction,\n shouldSkipDefaultAudioStart,\n })\n ) {\n return;\n }\n\n startCurrentAudioSequence();\n }, [\n currentAudioKey,\n currentAudioSequenceKeys,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n startCurrentAudioSequence,\n ]);\n\n useEffect(() => {\n if (!currentAudioKey || currentAudioIndex >= 0) {\n return;\n }\n\n setCurrentAudioKey(null);\n }, [currentAudioIndex, currentAudioKey]);\n\n useEffect(() => {\n if (currentAudioIndex >= 0) {\n return;\n }\n\n playbackTimeStore.reset();\n }, [currentAudioIndex, playbackTimeStore]);\n\n useEffect(() => {\n setHasCurrentAudioPlaybackStarted(false);\n }, [currentPlaybackStartedResetKey]);\n\n const {\n interactionDefaults,\n interactionDefaultSelectedValues,\n hasResolvedInteractionInput,\n isInteractionReadonly: resolvedInteractionReadonly,\n shouldAutoContinueInteraction,\n } = useMemo(\n () =>\n resolveSlideInteractionState(activeInteractionElement, {\n interactionDefaultValueOptions,\n }),\n [activeInteractionElement, interactionDefaultValueOptions]\n );\n\n const isInteractionReadonly =\n Boolean(activeInteractionElement?.readonly) || resolvedInteractionReadonly;\n const shouldShowInteractionOverlay = shouldRenderInteractionOverlay({\n hasActiveInteraction: Boolean(activeInteractionElement),\n isInteractionOverlayOpen,\n });\n\n const handleInteractionSend = useCallback(\n (content: OnSendContentParams) => {\n const submittedValues = [\n ...(content.selectedValues ?? []),\n content.inputText?.trim() ?? \"\",\n content.buttonText?.trim() ?? \"\",\n ].filter(Boolean);\n const resolvedUserInput = submittedValues.join(\", \");\n\n setActiveInteractionElement((prevElement) => {\n if (!prevElement || !resolvedUserInput) {\n return prevElement;\n }\n\n return {\n ...prevElement,\n user_input: resolvedUserInput,\n };\n });\n\n onSend?.(content, activeInteractionElement);\n continueAfterInteraction();\n },\n [activeInteractionElement, continueAfterInteraction, onSend]\n );\n\n useEffect(() => {\n // Keep the player icon in sync with the actual fullscreen owner.\n const syncFullscreenState = () => {\n setIsBrowserFullscreen(document.fullscreenElement === sectionRef.current);\n };\n\n syncFullscreenState();\n document.addEventListener(\"fullscreenchange\", syncFullscreenState);\n\n return () => {\n document.removeEventListener(\"fullscreenchange\", syncFullscreenState);\n };\n }, []);\n\n useEffect(() => {\n if (activeInteractionElement && isInteractionOverlayOpen) {\n return;\n }\n\n setHasInteractionOverlayActivity(false);\n }, [activeInteractionElement, isInteractionOverlayOpen]);\n\n useEffect(() => {\n resetInteractionOverlayDragState();\n }, [activeInteractionElement, resetInteractionOverlayDragState]);\n\n useEffect(() => {\n if (!shouldShowInteractionOverlay) {\n setInteractionOverlaySubtitleOffset(0);\n return;\n }\n\n const interactionOverlayElement = interactionOverlayRef.current;\n\n if (!interactionOverlayElement) {\n return;\n }\n\n const updateSubtitleOffset = () => {\n const overlayHeight = Math.ceil(\n interactionOverlayElement.getBoundingClientRect().height\n );\n\n setInteractionOverlaySubtitleOffset(\n overlayHeight + DEFAULT_INTERACTION_SUBTITLE_GAP_PX\n );\n };\n\n updateSubtitleOffset();\n\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateSubtitleOffset();\n });\n\n resizeObserver.observe(interactionOverlayElement);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [shouldShowInteractionOverlay]);\n\n useEffect(() => {\n clearInteractionAutoCloseTimer();\n\n if (!isInteractionOverlayOpen) {\n return;\n }\n\n if (shouldAutoContinueInteraction) {\n // Auto-close passive interaction markers to keep playback moving.\n interactionAutoCloseTimerRef.current = window.setTimeout(() => {\n interactionAutoCloseTimerRef.current = null;\n\n continueAfterInteraction();\n }, DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS);\n return () => {\n clearInteractionAutoCloseTimer();\n };\n }\n\n if (hasInteractionOverlayActivity || !hasResolvedInteractionInput) {\n return;\n }\n\n // Give resolved history interactions a short revisit window before\n // playback resumes, but stop auto-closing once the learner starts editing.\n interactionAutoCloseTimerRef.current = window.setTimeout(() => {\n interactionAutoCloseTimerRef.current = null;\n\n continueAfterInteraction();\n }, DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS);\n\n return () => {\n clearInteractionAutoCloseTimer();\n };\n }, [\n clearInteractionAutoCloseTimer,\n continueAfterInteraction,\n hasInteractionOverlayActivity,\n hasResolvedInteractionInput,\n isInteractionOverlayOpen,\n shouldAutoContinueInteraction,\n ]);\n\n const renderSlideElement = (\n element?: Element,\n options: RenderSlideElementOptions = {}\n ) => {\n if (!element) {\n return null;\n }\n\n if (element.type === \"slot\") {\n return <>{element.content}</>;\n }\n\n if (element.type === \"html\") {\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n dir={direction}\n lang={language}\n mode=\"blackboard\"\n replaceRootScreenHeightWithFull={\n options.replaceRootScreenHeightWithFull\n }\n type=\"sandbox\"\n content={element.content as string}\n enableScaling={enableIframeScaling}\n />\n );\n }\n\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n dir={direction}\n lang={language}\n mode=\"blackboard\"\n type=\"markdown\"\n content={element.content as string}\n />\n );\n };\n\n const renderSlideElementList = (\n elementList: Element[] = [],\n isActiveStep = false\n ) => {\n if (elementList.length === 0) {\n return null;\n }\n\n const visibleElementCount = elementList.filter(\n (element) => element.is_renderable !== false\n ).length;\n const markdownScalingMode =\n isActiveStep && enableMarkdownScaling\n ? resolveMarkdownScalingMode(elementList)\n : \"disabled\";\n const lastVisibleElementIndex = elementList.reduce(\n (lastVisibleIndex, element, index) =>\n element.is_renderable !== false ? index : lastVisibleIndex,\n -1\n );\n\n return (\n <MarkdownSlideScaling\n className=\"slide-stage__content flex w-full flex-col gap-4\"\n mode={markdownScalingMode}\n >\n {elementList.map((element, index) => {\n const isPreRenderedHtml =\n element.type === \"html\" && element.is_renderable === false;\n\n return (\n <div\n key={element.sequence_number ?? `${element.type}-${index}`}\n ref={\n isActiveStep && index === lastVisibleElementIndex\n ? lastElementRef\n : null\n }\n aria-hidden={isPreRenderedHtml || undefined}\n className={cn(\n \"w-full shrink-0\",\n visibleElementCount === 1 &&\n element.is_renderable !== false &&\n \"slide-element--single\",\n isPreRenderedHtml\n ? \"pointer-events-none fixed left-[-200vw] top-0 -z-10 h-[100dvh] w-[100vw] overflow-hidden opacity-0\"\n : element.is_renderable === false && \"hidden\"\n )}\n >\n {renderSlideElement(element, {\n replaceRootScreenHeightWithFull:\n visibleElementCount === 1 &&\n element.type === \"html\" &&\n element.is_renderable !== false,\n })}\n </div>\n );\n })}\n </MarkdownSlideScaling>\n );\n };\n\n const handleFullscreen = useCallback(() => {\n const target = sectionRef.current;\n if (!target) {\n return;\n }\n\n if (document.fullscreenElement === target) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n\n target.requestFullscreen?.().catch(() => {});\n }, []);\n\n const scrollStageToBottom = useCallback(() => {\n const stageLayerElement = stageLayerRef.current;\n\n if (!stageLayerElement) {\n return;\n }\n\n // Keep the latest content visible after manual player navigation.\n stageLayerElement.scrollTo({\n top: stageLayerElement.scrollHeight,\n behavior: \"smooth\",\n });\n }, []);\n\n const canJumpToSubtitleTarget = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) =>\n canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: audioSlideIndexes[target.audioIndex],\n }),\n [\n activeInteractionElement,\n audioSlideIndexes,\n currentIndex,\n slideElementList,\n ]\n );\n\n const handleSubtitleJump = useCallback(\n (\n target: SlidePlayerSubtitleJumpTarget,\n context: SlidePlayerNavigationContext\n ) => {\n const targetAudio = audioList[target.audioIndex];\n const targetAudioKey = targetAudio?.audioKey;\n const targetSlideIndex = audioSlideIndexes[target.audioIndex];\n\n if (!targetAudioKey || targetSlideIndex == null) {\n return false;\n }\n\n if (!canJumpToSubtitleTarget(target)) {\n return false;\n }\n\n syncPlaybackPreferenceBeforeNavigation(context);\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n setHasCompletedCurrentStepAudio(false);\n setHasCurrentAudioPlaybackStarted(false);\n\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n\n if (targetSlideIndex === currentIndex) {\n pendingSubtitleJumpRef.current = null;\n resetAudioSequence();\n setCurrentAudioKey(targetAudioKey);\n requestSubtitleCueSeek(target);\n return true;\n }\n\n shouldScrollToBottomRef.current = true;\n resetAudioSequence();\n pendingSubtitleJumpRef.current = {\n audioIndex: target.audioIndex,\n audioKey: targetAudioKey,\n slideIndex: targetSlideIndex,\n timeMs: target.timeMs,\n };\n goTo(targetSlideIndex);\n\n return true;\n },\n [\n audioList,\n audioSlideIndexes,\n canJumpToSubtitleTarget,\n currentIndex,\n goTo,\n requestSubtitleCueSeek,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePrev = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goPrev();\n },\n [\n goPrev,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handleNext = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goNext();\n },\n [\n goNext,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handleSlideProgressNavigate = useCallback(\n (targetIndex: number, context: SlidePlayerNavigationContext) => {\n if (\n targetIndex < 0 ||\n targetIndex >= slideElementList.length ||\n targetIndex === currentIndex\n ) {\n return;\n }\n\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n resetAudioSequence();\n goTo(targetIndex);\n onSlideProgressNavigate?.(slideElementList[targetIndex], targetIndex);\n },\n [\n currentIndex,\n goTo,\n onSlideProgressNavigate,\n resetAudioSequence,\n revealPlayerControls,\n slideElementList,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePlayerLoadingChange = useCallback(\n ({\n loading,\n reason,\n }: {\n loading: boolean;\n reason: SlidePlayerLoadingReason | null;\n }) => {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (!currentStepHasSpeakableElement || hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (loading && reason) {\n setAudioLoadingReason(reason);\n }\n setIsAudioLoadingVisible(shouldShowBufferingOverlay(reason, loading));\n },\n [\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n ]\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n setIsAudioLoadingVisible(false);\n }, [disableLoadingOverlay]);\n\n const handlePlayerEnded = useCallback(\n (audioIndex: number) => {\n const endedAudioKey = audioList[audioIndex]?.audioKey;\n\n if (!endedAudioKey || !currentAudioKey) {\n return;\n }\n\n if (endedAudioKey !== currentAudioKey) {\n return;\n }\n\n playedAudioKeysRef.current.add(endedAudioKey);\n\n const activeSequencePosition = currentAudioSequenceKeys.findIndex(\n (audioSequenceKey) => audioSequenceKey === endedAudioKey\n );\n if (activeSequencePosition < 0) {\n setCurrentAudioKey(null);\n return;\n }\n\n const nextSequencePosition = activeSequencePosition + 1;\n const nextAudioKey = currentAudioSequenceKeys[nextSequencePosition];\n\n if (nextAudioKey) {\n setCurrentAudioKey(nextAudioKey);\n return;\n }\n\n setCurrentAudioKey(null);\n setHasCompletedCurrentStepAudio(true);\n setIsAudioLoadingVisible(false);\n\n if (canGoNext) {\n const nextStepIndex = currentIndex + 1;\n const nextStepElement = slideElementList[nextStepIndex];\n\n if (hasCurrentStepAudioUrl && nextStepElement?.type === \"interaction\") {\n pendingInteractionOverlayStepIndexRef.current = nextStepIndex;\n }\n\n goNext();\n return;\n }\n },\n [\n audioList,\n canGoNext,\n currentIndex,\n currentAudioKey,\n currentAudioSequenceKeys,\n goNext,\n hasCurrentStepAudioUrl,\n slideElementList,\n ]\n );\n\n const handlePlayerControlsPointerEnter = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = true;\n clearPlayerHideTimer();\n\n if (shouldMountPlayer) {\n setIsPlayerVisible(true);\n }\n }, [clearPlayerHideTimer, shouldMountPlayer]);\n\n const handlePlayerControlsPointerLeave = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = false;\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n\n const stopOverlayPropagation = useCallback(\n (\n event: React.PointerEvent<HTMLElement> | React.MouseEvent<HTMLElement>\n ) => {\n event.stopPropagation();\n\n // Keep the player visible a bit longer when users interact with the overlay.\n if (playerControlsVisible) {\n revealPlayerControls(true);\n }\n },\n [playerControlsVisible, revealPlayerControls]\n );\n\n const getInteractionOverlayDragBounds = useCallback(\n (\n overlayElement: HTMLElement,\n startOffset: InteractionOverlayDragOffset\n ): InteractionOverlayDragBounds | null => {\n const viewportElement = viewportRef.current;\n\n if (!viewportElement) {\n return null;\n }\n\n const overlayRect = overlayElement.getBoundingClientRect();\n const viewportRect = viewportElement.getBoundingClientRect();\n\n return {\n minX: startOffset.x + viewportRect.left - overlayRect.left,\n maxX: startOffset.x + viewportRect.right - overlayRect.right,\n minY: startOffset.y + viewportRect.top - overlayRect.top,\n maxY: startOffset.y + viewportRect.bottom - overlayRect.bottom,\n };\n },\n []\n );\n\n useIsomorphicLayoutEffect(() => {\n const overlayElement = interactionOverlayRef.current;\n\n if (!shouldShowInteractionOverlay || !overlayElement) {\n interactionOverlayLayoutRectRef.current = null;\n return;\n }\n\n const previousRect = interactionOverlayLayoutRectRef.current;\n const currentRect = overlayElement.getBoundingClientRect();\n\n if (!previousRect || isInteractionOverlayDragging) {\n interactionOverlayLayoutRectRef.current = {\n left: currentRect.left,\n top: currentRect.top,\n };\n return;\n }\n\n const deltaX = previousRect.left - currentRect.left;\n const deltaY = previousRect.top - currentRect.top;\n\n if (\n !hasMeaningfulInteractionOverlayLayoutDelta(deltaX) &&\n !hasMeaningfulInteractionOverlayLayoutDelta(deltaY)\n ) {\n interactionOverlayLayoutRectRef.current = {\n left: currentRect.left,\n top: currentRect.top,\n };\n return;\n }\n\n const nextOffset = {\n x: interactionOverlayDragOffset.x + deltaX,\n y: interactionOverlayDragOffset.y + deltaY,\n };\n const bounds = getInteractionOverlayDragBounds(\n overlayElement,\n interactionOverlayDragOffset\n );\n const clampedOffset = normalizeInteractionOverlayDragOffset(\n bounds\n ? clampInteractionOverlayDragOffset(nextOffset, bounds)\n : nextOffset\n );\n\n interactionOverlayLayoutRectRef.current = {\n left: currentRect.left + clampedOffset.x - interactionOverlayDragOffset.x,\n top: currentRect.top + clampedOffset.y - interactionOverlayDragOffset.y,\n };\n\n if (\n !areInteractionOverlayDragOffsetsEqual(\n clampedOffset,\n interactionOverlayDragOffset\n )\n ) {\n setInteractionOverlayDragOffset((previousOffset) =>\n areInteractionOverlayDragOffsetsEqual(previousOffset, clampedOffset)\n ? previousOffset\n : clampedOffset\n );\n }\n }, [\n getInteractionOverlayDragBounds,\n interactionOverlayDragOffset,\n isInteractionOverlayDragging,\n playerLayoutReserved,\n shouldShowInteractionOverlay,\n ]);\n\n const handleInteractionOverlayPointerDown = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n stopOverlayPropagation(event);\n\n if (\n event.button !== 0 ||\n !event.currentTarget.isConnected ||\n !interactionOverlayRef.current\n ) {\n return;\n }\n\n const bounds = getInteractionOverlayDragBounds(\n interactionOverlayRef.current,\n interactionOverlayDragOffset\n );\n\n if (!bounds) {\n return;\n }\n\n event.preventDefault();\n if (event.currentTarget.hasPointerCapture?.(event.pointerId) !== true) {\n event.currentTarget.setPointerCapture(event.pointerId);\n }\n interactionOverlayDragRef.current = {\n pointerId: event.pointerId,\n startClientX: event.clientX,\n startClientY: event.clientY,\n startOffset: interactionOverlayDragOffset,\n bounds,\n };\n setIsInteractionOverlayDragging(true);\n },\n [\n getInteractionOverlayDragBounds,\n interactionOverlayDragOffset,\n stopOverlayPropagation,\n ]\n );\n\n const handleInteractionOverlayPointerMove = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n const dragState = interactionOverlayDragRef.current;\n\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n setInteractionOverlayDragOffset(\n clampInteractionOverlayDragOffset(\n {\n x: dragState.startOffset.x + event.clientX - dragState.startClientX,\n y: dragState.startOffset.y + event.clientY - dragState.startClientY,\n },\n dragState.bounds\n )\n );\n },\n []\n );\n\n const endInteractionOverlayDrag = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n const dragState = interactionOverlayDragRef.current;\n\n if (!dragState || dragState.pointerId !== event.pointerId) {\n return;\n }\n\n event.stopPropagation();\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n interactionOverlayDragRef.current = null;\n setIsInteractionOverlayDragging(false);\n },\n []\n );\n\n const handleSurfacePointerDown = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onPointerDown?.(event);\n },\n [activateKeyboardShortcutOwner, onPointerDown]\n );\n\n const handleSurfaceFocusCapture = useCallback(\n (event: React.FocusEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onFocusCapture?.(event);\n },\n [activateKeyboardShortcutOwner, onFocusCapture]\n );\n\n const handleSurfaceClick = useCallback(() => {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n useEffect(() => {\n const prevKeys = prevRenderElementKeysRef.current;\n const hasStablePrefix =\n prevKeys.length > 0 &&\n prevKeys.length < currentRenderElementKeys.length &&\n prevKeys.every((key, index) => key === currentRenderElementKeys[index]);\n const appendedElements = hasStablePrefix\n ? currentElementList.slice(prevKeys.length)\n : [];\n const shouldAutoScrollToAppend = appendedElements.some(\n (element) => element.is_new === false\n );\n\n prevRenderElementKeysRef.current = currentRenderElementKeys;\n\n if (!shouldAutoScrollToAppend) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n const stageLayerElement = stageLayerRef.current;\n const targetElement = lastElementRef.current;\n\n if (!stageLayerElement || !targetElement) {\n return;\n }\n\n const stageLayerRect = stageLayerElement.getBoundingClientRect();\n const targetRect = targetElement.getBoundingClientRect();\n const nextScrollTop =\n stageLayerElement.scrollTop + (targetRect.top - stageLayerRect.top);\n\n // Keep newly appended content visible when the current slide grows downward.\n stageLayerElement.scrollTo({\n top: Math.max(nextScrollTop, 0),\n behavior: \"smooth\",\n });\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, currentRenderElementKeys]);\n\n useEffect(() => {\n if (!shouldScrollToBottomRef.current) {\n return;\n }\n\n shouldScrollToBottomRef.current = false;\n\n if (currentElementList.length === 0) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n scrollStageToBottom();\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, scrollStageToBottom]);\n\n return (\n <section\n ref={sectionRef}\n className={cn(\n \"relative h-full w-full\",\n isMobileDevice && \"slide--mobile-device\",\n isDesktopBrowserFullscreen && \"slide--browser-fullscreen\",\n isImmersiveMobileFullscreen && \"slide--mobile-landscape\",\n isNativeMobileFullscreen && \"slide--mobile-landscape-native\",\n className\n )}\n dir={direction}\n lang={language}\n onClick={handleSurfaceClick}\n onFocusCapture={handleSurfaceFocusCapture}\n onPointerDown={handleSurfacePointerDown}\n {...props}\n >\n {shouldShowMobileFullscreenMask ? (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none fixed left-0 top-0 z-[9999] h-[100vh] max-h-[100vh] w-[100vw]\"\n />\n ) : null}\n\n <div\n ref={viewportRef}\n className={cn(\n \"slide__viewport relative h-full min-h-0 w-full\",\n isImmersiveMobileFullscreen && \"slide__viewport--mobile-landscape\",\n isImmersiveMobileFullscreen &&\n !shouldRotateFullscreenViewport &&\n \"slide__viewport--mobile-landscape-native\"\n )}\n >\n {shouldShowFullscreenHeader ? (\n <div className=\"slide-landscape-header\">\n <button\n aria-label={\n fullscreenHeader?.backAriaLabel ??\n localeTexts.fullscreenBackAriaLabel\n }\n className=\"slide-landscape-header__back\"\n onClick={handleFullscreenHeaderBack}\n type=\"button\"\n >\n <ChevronLeft\n className=\"slide-landscape-header__icon h-6 w-6\"\n strokeWidth={2.25}\n />\n </button>\n\n {fullscreenHeader?.content ? (\n <div className=\"min-w-0 flex-1 overflow-hidden\">\n {fullscreenHeader.content}\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div\n className={cn(\n \"h-full min-h-0 w-full\",\n shouldApplyFullscreenViewportPadding &&\n \"slide__viewport-content--with-header\",\n isSingleSlide ? \"slide-content--single\" : \"grid gap-4\"\n )}\n >\n {currentElementList.length > 0 ? (\n <div className=\"slide-stage\">\n <div ref={stageLayerRef} className=\"slide-stage__layer w-full\">\n {mountedStepStates.map(\n (mountedStepState, mountedStepStateIndex) => {\n const isActiveStep =\n mountedStepStateIndex === currentMountedStateIndex;\n\n return (\n <div\n key={\n mountedStepState.sourceStepIndexes[0] ??\n mountedStepStateIndex\n }\n data-active-step={isActiveStep ? \"true\" : undefined}\n aria-hidden={!isActiveStep || undefined}\n className=\"w-full h-full\"\n style={{ display: isActiveStep ? undefined : \"none\" }}\n >\n {renderSlideElementList(\n mountedStepState.elementList,\n isActiveStep\n )}\n </div>\n );\n }\n )}\n </div>\n </div>\n ) : null}\n </div>\n\n {isAudioLoadingVisible ? (\n <LoadingOverlayCard\n message={resolveBufferingTextByReason(\n resolvedBufferingText,\n audioLoadingReason\n )}\n className=\"absolute left-1/2 top-1/2 z-[3] -translate-x-1/2 -translate-y-1/2\"\n />\n ) : null}\n\n <SubtitleOverlay\n extraBottomOffset={interactionOverlaySubtitleOffset}\n hasPlayerGap={playerLayoutReserved}\n isEnabled={isSubtitleEnabled && hasCurrentAudioPlaybackStarted}\n playbackTimeStore={playbackTimeStore}\n subtitleCues={currentSubtitleCues}\n />\n\n {shouldShowInteractionOverlay ? (\n <div\n ref={interactionOverlayRef}\n data-player-keyboard-shortcuts-ignore=\"true\"\n className={cn(\n \"slide-interaction-overlay\",\n playerLayoutReserved\n ? \"slide-interaction-overlay--with-player\"\n : \"slide-interaction-overlay--standalone\",\n isInteractionOverlayDragging &&\n \"slide-interaction-overlay--dragging\"\n )}\n onClick={stopOverlayPropagation}\n onPointerDownCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n onFocusCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n onInputCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n style={interactionOverlayStyle}\n >\n <InteractionOverlayCard\n dir={direction}\n lang={language}\n content={String(activeInteractionElement?.content ?? \"\")}\n dragHandleAriaLabel={\n interactionTexts?.dragHandleAriaLabel ??\n localeTexts.interactionTexts.dragHandleAriaLabel\n }\n locale={locale}\n defaultButtonText={interactionDefaults.buttonText ?? \"\"}\n defaultInputText={interactionDefaults.inputText ?? \"\"}\n defaultSelectedValues={interactionDefaultSelectedValues}\n confirmButtonText={\n interactionTexts?.confirmButtonText ??\n localeTexts.interactionTexts.confirmButtonText\n }\n copyButtonText={\n interactionTexts?.copyButtonText ??\n localeTexts.interactionTexts.copyButtonText\n }\n copiedButtonText={\n interactionTexts?.copiedButtonText ??\n localeTexts.interactionTexts.copiedButtonText\n }\n onSend={handleInteractionSend}\n onDragHandlePointerCancel={endInteractionOverlayDrag}\n onDragHandlePointerDown={handleInteractionOverlayPointerDown}\n onDragHandlePointerMove={handleInteractionOverlayPointerMove}\n onDragHandlePointerUp={endInteractionOverlayDrag}\n readonly={isInteractionReadonly}\n title={\n interactionTexts?.title ??\n interactionTitle ??\n localeTexts.interactionTexts.title\n }\n />\n </div>\n ) : null}\n\n {shouldMountPlayer ? (\n <PlayerKeyboardShortcutContext.Provider\n value={keyboardShortcutContextValue}\n >\n <Player\n dir={direction === \"auto\" ? resolvedDirection : direction}\n lang={language}\n audioList={audioList}\n className={cn(\n \"absolute left-1/2 z-[2] -translate-x-1/2\",\n showSlideProgress\n ? \"bottom-9\"\n : isDesktopBrowserFullscreen\n ? \"bottom-3\"\n : \"-bottom-3\",\n playerClassName,\n !playerControlsVisible && \"pointer-events-none opacity-0\"\n )}\n currentAudioIndex={currentAudioIndex}\n defaultPlaying={isPlaybackRequested}\n enableKeyboardShortcuts={enableKeyboardShortcuts}\n isPlaybackPaused={shouldPausePlaybackForCustomAction}\n isAutoAdvanceEnabled={isAutoAdvanceEnabled}\n locale={locale}\n isInteractionOpen={isInteractionOverlayOpen}\n isSubtitleEnabled={isSubtitleEnabled}\n onAutoAdvanceToggle={setIsAutoAdvanceEnabled}\n onLoadingChange={handlePlayerLoadingChange}\n onPlaybackStarted={() => {\n setHasCurrentAudioPlaybackStarted(true);\n }}\n onPlaybackCheckpoint={({ audioKey, isComplete, timeMs }) => {\n const checkpointAudioIndex = audioList.findIndex(\n (audioItem) => audioItem.audioKey === audioKey\n );\n const checkpointAudioItem =\n checkpointAudioIndex >= 0\n ? audioList[checkpointAudioIndex]\n : undefined;\n\n if (\n !checkpointAudioItem?.audioKey ||\n !checkpointAudioItem.element\n ) {\n return;\n }\n\n onPlaybackCheckpoint?.({\n audioKey: checkpointAudioItem.audioKey,\n element: checkpointAudioItem.element,\n isComplete,\n stepIndex:\n audioSlideIndexes[checkpointAudioIndex] ?? currentIndex,\n timeMs,\n });\n }}\n onPlaybackPreferenceChange={handlePlaybackPreferenceChange}\n onPlaybackTimeChange={playbackTimeStore.setTime}\n onSubtitleToggle={() => {\n setIsSubtitleEnabled((previousEnabled) => !previousEnabled);\n }}\n nextDisabled={!canGoNext}\n onEnded={handlePlayerEnded}\n onFullscreen={handleFullscreen}\n isFullscreen={isBrowserFullscreen}\n mobileViewMode={effectiveMobileViewMode}\n settingsPortalContainer={viewportRef.current}\n onMobileViewModeChange={handleMobileViewModeSelect}\n onControlsPointerEnter={handlePlayerControlsPointerEnter}\n onControlsPointerLeave={handlePlayerControlsPointerLeave}\n onNext={handleNext}\n onPrev={handlePrev}\n onSubtitleJump={handleSubtitleJump}\n canJumpToSubtitleTarget={canJumpToSubtitleTarget}\n prevDisabled={!canGoPrev}\n showControls={playerControlsVisible}\n slideProgress={\n showSlideProgress\n ? {\n ariaLabel: localeTexts.slideProgressAriaLabel,\n currentIndex,\n generatingLabel: localeTexts.slideProgressGeneratingLabel,\n isGenerating: isSlideProgressGenerating,\n onNavigate: handleSlideProgressNavigate,\n totalSteps: generatedSlideCount,\n }\n : null\n }\n subtitleSeekRequest={subtitleSeekRequest}\n playbackRestoreRequest={\n pendingPlaybackRestore &&\n pendingPlaybackRestore.audioKey === currentAudioItem?.audioKey\n ? {\n id: pendingPlaybackRestore.id,\n timeMs: pendingPlaybackRestore.timeMs,\n }\n : null\n }\n onPlaybackRestoreComplete={(requestId) => {\n if (pendingPlaybackRestoreRef.current?.id !== requestId) {\n return;\n }\n\n pendingPlaybackRestoreRef.current = null;\n setPendingPlaybackRestore(null);\n }}\n texts={playerTexts}\n customActionContext={playerCustomActionContext}\n customActions={playerCustomActions}\n useAutoAdvanceToggle={shouldUseSilentStepAutoAdvanceToggle}\n />\n </PlayerKeyboardShortcutContext.Provider>\n ) : null}\n </div>\n </section>\n );\n};\n\nexport default Slide;\n"],"names":["DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX","DEFAULT_INTERACTION_SUBTITLE_GAP_PX","DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_DRAG_OFFSET","INTERACTION_OVERLAY_LAYOUT_EPSILON_PX","useIsomorphicLayoutEffect","useEffect","useLayoutEffect","INTERACTION_ACTIVITY_SELECTOR","DEFAULT_BUFFERING_REASON","normalizeInteractionOverlayDragOffset","x","y","hasMeaningfulInteractionOverlayLayoutDelta","delta","areInteractionOverlayDragOffsetsEqual","first","second","resolveBufferingTextByReason","bufferingText","reason","DEFAULT_SLIDE_BUFFERING_TEXTS","mergeBufferingTextWithLocaleDefaults","localeBufferingText","shouldShowBufferingOverlay","loading","InteractionOverlayCard","memo","content","title","dragHandleAriaLabel","locale","dir","lang","defaultButtonText","defaultInputText","defaultSelectedValues","confirmButtonText","copyButtonText","copiedButtonText","onSend","onDragHandlePointerCancel","onDragHandlePointerDown","onDragHandlePointerMove","onDragHandlePointerUp","readonly","jsxs","jsx","GripHorizontal","ContentRender","areStepElementListsEqual","prevElementList","nextElementList","element","index","nextElement","isInteractionActivityTarget","target","Slide","elementList","playerEnabled","playerControlsVisibility","playerClassName","fullscreenHeader","playerCustomActions","playerCustomActionPauseOnActive","interactionTitle","interactionTexts","playerTexts","playerAutoHideDelay","markerAutoAdvanceDelay","showSlideProgress","isSlideProgressGenerating","onSlideProgressNavigate","interactionDefaultValueOptions","onPlayerVisibilityChange","onMobileViewModeChange","onStepChange","onPlaybackCheckpoint","playbackRestoreRequest","enableKeyboardShortcuts","enableIframeScaling","enableMarkdownScaling","disableLoadingOverlay","className","onPointerDown","onFocusCapture","props","direction","getMarkdownFlowDirection","language","getMarkdownFlowLanguage","localeTexts","useMemo","getSlideLocaleTexts","resolvedBufferingText","resolvedPlayerEnabled","resolvedPlayerControlsVisibility","resolveSlidePlayerVisibility","keyboardShortcutOwnerId","useId","sectionRef","useRef","resolvedDirection","useResolvedDirection","viewportRef","stageLayerRef","lastElementRef","playerHideTimerRef","isPointerInsidePlayerControlsRef","autoAdvanceTimerRef","imageOnlyStepReadyTimeoutRef","interactionAutoCloseTimerRef","interactionOverlayOpenTimerRef","interactionOverlayRef","interactionOverlayLayoutRectRef","interactionOverlayDragRef","prevRenderElementKeysRef","shouldScrollToBottomRef","pendingInteractionOverlayStepIndexRef","pendingSubtitleJumpRef","subtitleSeekRequestIdRef","playbackResetKeyRef","appendedMarkerAdvanceStateRef","shouldSkipDefaultAudioStartForSubtitleJumpRef","currentElementList","stepElementLists","slideElementList","currentIndex","audioList","audioSlideIndexes","currentAudioSequenceIndexes","currentStepHasSpeakableElement","currentInteractionElement","canGoPrev","canGoNext","goPrev","goNext","goTo","useSlide","currentStepElement","currentRenderElementKeys","generatedSlideCount","isSingleSlide","shouldMountPlayer","keyboardShortcutContextValue","activateKeyboardShortcutOwner","useCallback","activatePlayerKeyboardShortcutOwner","currentAudioSequenceKeys","audioIndex","audioKey","isPlayerVisible","setIsPlayerVisible","useState","hasPlayerInteracted","setHasPlayerInteracted","isPlaybackRequested","setIsPlaybackRequested","isAutoAdvanceEnabled","setIsAutoAdvanceEnabled","currentAudioKey","setCurrentAudioKey","pendingPlaybackRestore","setPendingPlaybackRestore","pendingPlaybackRestoreRef","lastPlaybackRestoreRequestIdRef","subtitleSeekRequest","setSubtitleSeekRequest","isAudioLoadingVisible","setIsAudioLoadingVisible","audioLoadingReason","setAudioLoadingReason","hasCompletedCurrentStepAudio","setHasCompletedCurrentStepAudio","playedAudioKeysRef","hasCurrentAudioPlaybackStarted","setHasCurrentAudioPlaybackStarted","isSubtitleEnabled","setIsSubtitleEnabled","isPlayerCustomActionActive","setIsPlayerCustomActionActive","activeInteractionElement","setActiveInteractionElement","isInteractionOverlayOpen","setIsInteractionOverlayOpen","hasInteractionOverlayActivity","setHasInteractionOverlayActivity","interactionOverlayDragOffset","setInteractionOverlayDragOffset","isInteractionOverlayDragging","setIsInteractionOverlayDragging","interactionOverlaySubtitleOffset","setInteractionOverlaySubtitleOffset","isBrowserFullscreen","setIsBrowserFullscreen","isMobileDevice","getIsMobileDevice","mobileViewMode","setMobileViewMode","DEFAULT_MOBILE_VIEW_MODE","hasManualMobileViewMode","setHasManualMobileViewMode","isViewportFullscreenPreferred","setIsViewportFullscreenPreferred","getIsFullscreenPreferredViewport","playbackTimeStore","createPlaybackTimeStore","effectiveMobileViewMode","isImmersiveMobileFullscreen","isNativeMobileFullscreen","shouldRotateFullscreenViewport","resolveMobileViewModeState","previousEffectiveMobileViewModeRef","playerControlsVisible","playerLayoutReserved","resolveSlidePlayerLayoutState","shouldShowFullscreenHeader","shouldApplyFullscreenViewportPadding","shouldShowMobileFullscreenMask","isDesktopBrowserFullscreen","handleMobileViewModeSelect","nextViewMode","handleMobileViewModeReset","handleFullscreenHeaderBack","clearInteractionAutoCloseTimer","clearInteractionOverlayOpenTimer","closeInteractionOverlayForCustomAction","setPlayerCustomActionActive","active","togglePlayerCustomActionActive","previousActive","resetInteractionOverlayDragState","previousOffset","mountedStepStates","currentMountedStateIndex","nextMountedStepStates","mountedStateIndexByStep","stepElementList","stepIndex","existingMountedStateIndex","mountedStepState","currentStepKey","currentAudioIndex","audioItem","currentAudioItem","targetAudioIndex","targetStepIndex","currentSubtitleCues","currentAudioSequenceStartKey","playerCustomActionContext","resolvePlayerCustomActionElement","playerCustomActionCount","getPlayerCustomActionCount","hasPlayerCustomActions","isPlayerCustomActionEffectivelyActive","interactionOverlayStyle","hasAvailableStepAudio","currentInteractionResetKey","currentPlaybackResetKey","currentPlaybackStartedResetKey","hasCurrentStepAudioUrl","shouldPausePlaybackForCustomAction","shouldUseSilentStepAutoAdvanceToggle","shouldUseAutoAdvanceToggle","silentStepAutoAdvanceBehavior","resolveSilentStepAutoAdvanceBehavior","silentStepAutoAdvanceDelay","isImageOnlySilentStep","imageOnlyStepVisualReadyKey","readyImageOnlyStepKey","setReadyImageOnlyStepKey","isImageOnlyStepVisualReady","clearPlayerHideTimer","clearAutoAdvanceTimer","clearImageOnlyStepReadyTimeout","resetAudioSequence","options","requestSubtitleCueSeek","startCurrentAudioSequence","nextAudioKey","resolvePendingStepAudioKey","continueAfterInteraction","scheduleInteractionOverlayOpen","interactionElement","openOverlay","isPlayerControlsHovered","revealPlayerControls","enableAutoHide","hasResolvedCurrentInteraction","hasResolvedInteractionElement","shouldBlockPlaybackForInteraction","handlePlaybackPreferenceChange","playing","syncPlaybackPreferenceBeforeNavigation","context","cancelled","rafId","cleanupListeners","detachListeners","finishVisualReady","evaluateVisualReady","activeStepContainer","iframeElements","areImageOnlyStepIframeVisualsReady","cleanupCallbacks","queueRecheck","registerEvent","eventName","listener","iframeElement","iframeDocument","image","cleanup","DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS","syncViewportFullscreenPreference","handleOrientationChange","unsubscribeMobileDeviceChange","subscribeMobileDeviceChange","previousState","shouldAdvanceIntoAppendedMarker","shouldAutoAdvanceIntoAppendedMarker","handleSandboxInteraction","event","isSandboxInteractionMessage","useWakePlayerFromIframe","hasPlaybackContextChanged","shouldInitializeAudioSequence","getPlaybackSequenceTransition","shouldOpenInteractionOverlayAfterAudio","shouldPresentOverlay","shouldPresentInteractionOverlay","pendingSubtitleJump","shouldPreservePendingSubtitleJump","canReachSubtitleJumpTarget","hasUnplayedStepAudio","shouldSkipDefaultAudioStart","shouldStartDefaultAudioSequence","interactionDefaults","interactionDefaultSelectedValues","hasResolvedInteractionInput","resolvedInteractionReadonly","shouldAutoContinueInteraction","resolveSlideInteractionState","isInteractionReadonly","shouldShowInteractionOverlay","shouldRenderInteractionOverlay","handleInteractionSend","resolvedUserInput","prevElement","syncFullscreenState","interactionOverlayElement","updateSubtitleOffset","overlayHeight","resizeObserver","renderSlideElement","Fragment","IframeSandbox","renderSlideElementList","isActiveStep","visibleElementCount","markdownScalingMode","resolveMarkdownScalingMode","lastVisibleElementIndex","lastVisibleIndex","MarkdownSlideScaling","isPreRenderedHtml","cn","handleFullscreen","scrollStageToBottom","stageLayerElement","canJumpToSubtitleTarget","handleSubtitleJump","targetAudioKey","targetSlideIndex","shouldWakePlayerControlsAfterNavigation","handlePrev","handleNext","handleSlideProgressNavigate","targetIndex","handlePlayerLoadingChange","handlePlayerEnded","endedAudioKey","activeSequencePosition","audioSequenceKey","nextSequencePosition","nextStepIndex","nextStepElement","handlePlayerControlsPointerEnter","handlePlayerControlsPointerLeave","stopOverlayPropagation","getInteractionOverlayDragBounds","overlayElement","startOffset","viewportElement","overlayRect","viewportRect","previousRect","currentRect","deltaX","deltaY","nextOffset","bounds","clampedOffset","clampInteractionOverlayDragOffset","handleInteractionOverlayPointerDown","handleInteractionOverlayPointerMove","dragState","endInteractionOverlayDrag","handleSurfacePointerDown","handleSurfaceFocusCapture","handleSurfaceClick","prevKeys","shouldAutoScrollToAppend","key","animationFrameId","targetElement","stageLayerRect","targetRect","nextScrollTop","ChevronLeft","mountedStepStateIndex","LoadingOverlayCard","SubtitleOverlay","PlayerKeyboardShortcutContext","Player","isComplete","timeMs","checkpointAudioIndex","checkpointAudioItem","previousEnabled","requestId"],"mappings":"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"}
|