@editframe/elements 0.47.2 → 0.48.1
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.
- package/dist/DelayedLoadingState.js +1 -1
- package/dist/DelayedLoadingState.js.map +1 -1
- package/dist/EF_FRAMEGEN.js +1 -2
- package/dist/EF_FRAMEGEN.js.map +1 -1
- package/dist/EF_RENDERING.js +1 -1
- package/dist/EF_RENDERING.js.map +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.95.0 → _@oxc-project_runtime@0.122.0}/helpers/decorate.js +2 -3
- package/dist/attachContextRoot.js +1 -2
- package/dist/attachContextRoot.js.map +1 -1
- package/dist/canvas/EFCanvas.d.ts +4 -7
- package/dist/canvas/EFCanvas.js +20 -21
- package/dist/canvas/EFCanvas.js.map +1 -1
- package/dist/canvas/EFCanvasItem.d.ts +4 -5
- package/dist/canvas/EFCanvasItem.js +3 -4
- package/dist/canvas/EFCanvasItem.js.map +1 -1
- package/dist/canvas/api/CanvasAPI.d.ts +0 -1
- package/dist/canvas/api/CanvasAPI.js +1 -1
- package/dist/canvas/api/CanvasAPI.js.map +1 -1
- package/dist/canvas/coordinateTransform.js +1 -1
- package/dist/canvas/coordinateTransform.js.map +1 -1
- package/dist/canvas/getElementBounds.js +1 -1
- package/dist/canvas/getElementBounds.js.map +1 -1
- package/dist/canvas/overlays/SelectionOverlay.d.ts +4 -4
- package/dist/canvas/overlays/SelectionOverlay.js +6 -7
- package/dist/canvas/overlays/SelectionOverlay.js.map +1 -1
- package/dist/canvas/overlays/overlayState.js +1 -2
- package/dist/canvas/overlays/overlayState.js.map +1 -1
- package/dist/canvas/selection/SelectionController.js +1 -2
- package/dist/canvas/selection/SelectionController.js.map +1 -1
- package/dist/canvas/selection/SelectionModel.d.ts +0 -1
- package/dist/canvas/selection/SelectionModel.js +1 -1
- package/dist/canvas/selection/SelectionModel.js.map +1 -1
- package/dist/canvas/selection/selectionContext.d.ts +0 -1
- package/dist/canvas/selection/selectionContext.js +1 -2
- package/dist/canvas/selection/selectionContext.js.map +1 -1
- package/dist/elements/ContainerInfo.js +1 -1
- package/dist/elements/ContainerInfo.js.map +1 -1
- package/dist/elements/CrossUpdateController.js +1 -1
- package/dist/elements/CrossUpdateController.js.map +1 -1
- package/dist/elements/EFAudio.d.ts +4 -4
- package/dist/elements/EFAudio.js +4 -6
- package/dist/elements/EFAudio.js.map +1 -1
- package/dist/elements/EFCaptions.d.ts +4 -4
- package/dist/elements/EFCaptions.js +8 -10
- package/dist/elements/EFCaptions.js.map +1 -1
- package/dist/elements/EFImage.d.ts +7 -7
- package/dist/elements/EFImage.js +4 -6
- package/dist/elements/EFImage.js.map +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +2 -2
- package/dist/elements/EFMedia/BufferedSeekingInput.js +8 -9
- package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -1
- package/dist/elements/EFMedia/CachedFetcher.js +1 -2
- package/dist/elements/EFMedia/CachedFetcher.js.map +1 -1
- package/dist/elements/EFMedia/MediaEngine.d.ts +0 -2
- package/dist/elements/EFMedia/MediaEngine.js +1 -2
- package/dist/elements/EFMedia/MediaEngine.js.map +1 -1
- package/dist/elements/EFMedia/SegmentIndex.d.ts +0 -3
- package/dist/elements/EFMedia/SegmentIndex.js +1 -2
- package/dist/elements/EFMedia/SegmentIndex.js.map +1 -1
- package/dist/elements/EFMedia/SegmentTransport.d.ts +0 -2
- package/dist/elements/EFMedia/SegmentTransport.js +1 -1
- package/dist/elements/EFMedia/SegmentTransport.js.map +1 -1
- package/dist/elements/EFMedia/TimingModel.d.ts +0 -2
- package/dist/elements/EFMedia/TimingModel.js +1 -1
- package/dist/elements/EFMedia/TimingModel.js.map +1 -1
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +1 -1
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js.map +1 -1
- package/dist/elements/EFMedia/shared/GlobalInputCache.js +1 -2
- package/dist/elements/EFMedia/shared/GlobalInputCache.js.map +1 -1
- package/dist/elements/EFMedia/shared/PrecisionUtils.js +1 -1
- package/dist/elements/EFMedia/shared/PrecisionUtils.js.map +1 -1
- package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +1 -2
- package/dist/elements/EFMedia/shared/ThumbnailExtractor.js.map +1 -1
- package/dist/elements/EFMedia/shared/timeoutUtils.js +1 -2
- package/dist/elements/EFMedia/shared/timeoutUtils.js.map +1 -1
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +1 -1
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js.map +1 -1
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.d.ts +0 -1
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +12 -12
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -1
- package/dist/elements/EFMedia.d.ts +2 -2
- package/dist/elements/EFMedia.js +2 -3
- package/dist/elements/EFMedia.js.map +1 -1
- package/dist/elements/EFMotionBlur.d.ts +0 -1
- package/dist/elements/EFMotionBlur.js +8 -15
- package/dist/elements/EFMotionBlur.js.map +1 -1
- package/dist/elements/EFPanZoom.d.ts +4 -4
- package/dist/elements/EFPanZoom.js +3 -4
- package/dist/elements/EFPanZoom.js.map +1 -1
- package/dist/elements/EFSourceMixin.js +2 -3
- package/dist/elements/EFSourceMixin.js.map +1 -1
- package/dist/elements/EFSurface.d.ts +6 -6
- package/dist/elements/EFSurface.js +3 -4
- package/dist/elements/EFSurface.js.map +1 -1
- package/dist/elements/EFTemporal.d.ts +0 -1
- package/dist/elements/EFTemporal.js +12 -9
- package/dist/elements/EFTemporal.js.map +1 -1
- package/dist/elements/EFText.d.ts +4 -4
- package/dist/elements/EFText.js +6 -7
- package/dist/elements/EFText.js.map +1 -1
- package/dist/elements/EFTextSegment.d.ts +4 -4
- package/dist/elements/EFTextSegment.js +3 -4
- package/dist/elements/EFTextSegment.js.map +1 -1
- package/dist/elements/EFTimegroup.d.ts +4 -10
- package/dist/elements/EFTimegroup.js +11 -12
- package/dist/elements/EFTimegroup.js.map +1 -1
- package/dist/elements/EFVideo.d.ts +6 -7
- package/dist/elements/EFVideo.js +7 -9
- package/dist/elements/EFVideo.js.map +1 -1
- package/dist/elements/EFWaveform.d.ts +4 -4
- package/dist/elements/EFWaveform.js +4 -6
- package/dist/elements/EFWaveform.js.map +1 -1
- package/dist/elements/ElementPositionInfo.js +1 -1
- package/dist/elements/ElementPositionInfo.js.map +1 -1
- package/dist/elements/FetchMixin.js +1 -1
- package/dist/elements/FetchMixin.js.map +1 -1
- package/dist/elements/SampleBuffer.js +1 -2
- package/dist/elements/SampleBuffer.js.map +1 -1
- package/dist/elements/TargetController.d.ts +0 -1
- package/dist/elements/TargetController.js +1 -1
- package/dist/elements/TargetController.js.map +1 -1
- package/dist/elements/TimegroupController.js +1 -1
- package/dist/elements/TimegroupController.js.map +1 -1
- package/dist/elements/cloneFactoryRegistry.js +1 -1
- package/dist/elements/cloneFactoryRegistry.js.map +1 -1
- package/dist/elements/durationConverter.js +4 -5
- package/dist/elements/durationConverter.js.map +1 -1
- package/dist/elements/easingUtils.js +1 -1
- package/dist/elements/easingUtils.js.map +1 -1
- package/dist/elements/findRootTemporal.js +1 -2
- package/dist/elements/findRootTemporal.js.map +1 -1
- package/dist/elements/parseTimeToMs.js +1 -1
- package/dist/elements/parseTimeToMs.js.map +1 -1
- package/dist/elements/renderTemporalAudio.js +1 -2
- package/dist/elements/renderTemporalAudio.js.map +1 -1
- package/dist/elements/setupTemporalHierarchy.js +1 -1
- package/dist/elements/setupTemporalHierarchy.js.map +1 -1
- package/dist/elements/updateAnimations.js +1 -2
- package/dist/elements/updateAnimations.js.map +1 -1
- package/dist/getRenderInfo.d.ts +0 -1
- package/dist/getRenderInfo.js +1 -2
- package/dist/getRenderInfo.js.map +1 -1
- package/dist/gui/ContextMixin.d.ts +0 -1
- package/dist/gui/ContextMixin.js +2 -3
- package/dist/gui/ContextMixin.js.map +1 -1
- package/dist/gui/Controllable.d.ts +0 -2
- package/dist/gui/Controllable.js +1 -2
- package/dist/gui/Controllable.js.map +1 -1
- package/dist/gui/EFActiveRootTemporal.d.ts +4 -5
- package/dist/gui/EFActiveRootTemporal.js +3 -4
- package/dist/gui/EFActiveRootTemporal.js.map +1 -1
- package/dist/gui/EFConfiguration.d.ts +4 -4
- package/dist/gui/EFConfiguration.js +3 -4
- package/dist/gui/EFConfiguration.js.map +1 -1
- package/dist/gui/EFControls.d.ts +2 -3
- package/dist/gui/EFControls.js +4 -5
- package/dist/gui/EFControls.js.map +1 -1
- package/dist/gui/EFDial.d.ts +4 -4
- package/dist/gui/EFDial.js +3 -4
- package/dist/gui/EFDial.js.map +1 -1
- package/dist/gui/EFFilmstrip.d.ts +6 -7
- package/dist/gui/EFFilmstrip.js +3 -4
- package/dist/gui/EFFilmstrip.js.map +1 -1
- package/dist/gui/EFFitScale.d.ts +3 -3
- package/dist/gui/EFFitScale.js +6 -7
- package/dist/gui/EFFitScale.js.map +1 -1
- package/dist/gui/EFFocusOverlay.d.ts +6 -6
- package/dist/gui/EFFocusOverlay.js +3 -4
- package/dist/gui/EFFocusOverlay.js.map +1 -1
- package/dist/gui/EFOverlayItem.d.ts +4 -4
- package/dist/gui/EFOverlayItem.js +3 -4
- package/dist/gui/EFOverlayItem.js.map +1 -1
- package/dist/gui/EFOverlayLayer.d.ts +4 -5
- package/dist/gui/EFOverlayLayer.js +3 -4
- package/dist/gui/EFOverlayLayer.js.map +1 -1
- package/dist/gui/EFPause.d.ts +4 -4
- package/dist/gui/EFPause.js +3 -4
- package/dist/gui/EFPause.js.map +1 -1
- package/dist/gui/EFPlay.d.ts +4 -4
- package/dist/gui/EFPlay.js +3 -4
- package/dist/gui/EFPlay.js.map +1 -1
- package/dist/gui/EFPreview.d.ts +4 -4
- package/dist/gui/EFPreview.js +3 -4
- package/dist/gui/EFPreview.js.map +1 -1
- package/dist/gui/EFResizableBox.d.ts +4 -4
- package/dist/gui/EFResizableBox.js +3 -4
- package/dist/gui/EFResizableBox.js.map +1 -1
- package/dist/gui/EFScrubber.d.ts +4 -4
- package/dist/gui/EFScrubber.js +3 -4
- package/dist/gui/EFScrubber.js.map +1 -1
- package/dist/gui/EFTimeDisplay.d.ts +4 -4
- package/dist/gui/EFTimeDisplay.js +3 -4
- package/dist/gui/EFTimeDisplay.js.map +1 -1
- package/dist/gui/EFTimelineRuler.d.ts +4 -4
- package/dist/gui/EFTimelineRuler.js +5 -6
- package/dist/gui/EFTimelineRuler.js.map +1 -1
- package/dist/gui/EFToggleLoop.d.ts +4 -4
- package/dist/gui/EFToggleLoop.js +3 -4
- package/dist/gui/EFToggleLoop.js.map +1 -1
- package/dist/gui/EFTogglePlay.d.ts +4 -4
- package/dist/gui/EFTogglePlay.js +3 -4
- package/dist/gui/EFTogglePlay.js.map +1 -1
- package/dist/gui/EFTransformHandles.d.ts +4 -4
- package/dist/gui/EFTransformHandles.js +3 -4
- package/dist/gui/EFTransformHandles.js.map +1 -1
- package/dist/gui/EFWorkbench.d.ts +6 -7
- package/dist/gui/EFWorkbench.js +13 -15
- package/dist/gui/EFWorkbench.js.map +1 -1
- package/dist/gui/EFWorkbench.spacebar.js +1 -1
- package/dist/gui/EFWorkbench.spacebar.js.map +1 -1
- package/dist/gui/FitScaleHelpers.js +1 -2
- package/dist/gui/FitScaleHelpers.js.map +1 -1
- package/dist/gui/PlaybackController.js +3 -4
- package/dist/gui/PlaybackController.js.map +1 -1
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/TWMixin.js.map +1 -1
- package/dist/gui/TWMixin2.js +1 -2
- package/dist/gui/TWMixin2.js.map +1 -1
- package/dist/gui/TargetOrContextMixin.js +2 -3
- package/dist/gui/TargetOrContextMixin.js.map +1 -1
- package/dist/gui/currentTimeContext.js +1 -2
- package/dist/gui/currentTimeContext.js.map +1 -1
- package/dist/gui/durationContext.js +1 -2
- package/dist/gui/durationContext.js.map +1 -1
- package/dist/gui/efContext.js +1 -2
- package/dist/gui/efContext.js.map +1 -1
- package/dist/gui/fetchContext.js +1 -2
- package/dist/gui/fetchContext.js.map +1 -1
- package/dist/gui/focusContext.js +1 -2
- package/dist/gui/focusContext.js.map +1 -1
- package/dist/gui/focusedElementContext.js +1 -2
- package/dist/gui/focusedElementContext.js.map +1 -1
- package/dist/gui/hierarchy/EFHierarchy.d.ts +4 -4
- package/dist/gui/hierarchy/EFHierarchy.js +3 -4
- package/dist/gui/hierarchy/EFHierarchy.js.map +1 -1
- package/dist/gui/hierarchy/EFHierarchyItem.d.ts +2 -2
- package/dist/gui/hierarchy/EFHierarchyItem.js +13 -14
- package/dist/gui/hierarchy/EFHierarchyItem.js.map +1 -1
- package/dist/gui/hierarchy/hierarchyContext.js +1 -2
- package/dist/gui/hierarchy/hierarchyContext.js.map +1 -1
- package/dist/gui/icons.js +1 -2
- package/dist/gui/icons.js.map +1 -1
- package/dist/gui/panZoomTransformContext.js +1 -2
- package/dist/gui/panZoomTransformContext.js.map +1 -1
- package/dist/gui/playingContext.js +1 -2
- package/dist/gui/playingContext.js.map +1 -1
- package/dist/gui/previewSettingsContext.d.ts +0 -1
- package/dist/gui/previewSettingsContext.js +1 -2
- package/dist/gui/previewSettingsContext.js.map +1 -1
- package/dist/gui/shouldSignUrl.js +1 -1
- package/dist/gui/shouldSignUrl.js.map +1 -1
- package/dist/gui/theme.js +1 -1
- package/dist/gui/theme.js.map +1 -1
- package/dist/gui/timeline/EFTimeline.d.ts +2 -5
- package/dist/gui/timeline/EFTimeline.js +19 -20
- package/dist/gui/timeline/EFTimeline.js.map +1 -1
- package/dist/gui/timeline/EFTimelineRow.d.ts +2 -2
- package/dist/gui/timeline/EFTimelineRow.js +3 -4
- package/dist/gui/timeline/EFTimelineRow.js.map +1 -1
- package/dist/gui/timeline/TrimHandles.d.ts +4 -4
- package/dist/gui/timeline/TrimHandles.js +3 -4
- package/dist/gui/timeline/TrimHandles.js.map +1 -1
- package/dist/gui/timeline/flattenHierarchy.js +1 -2
- package/dist/gui/timeline/flattenHierarchy.js.map +1 -1
- package/dist/gui/timeline/timelineEditingContext.js +1 -2
- package/dist/gui/timeline/timelineEditingContext.js.map +1 -1
- package/dist/gui/timeline/timelineStateContext.js +1 -14
- package/dist/gui/timeline/timelineStateContext.js.map +1 -1
- package/dist/gui/timeline/tracks/AudioTrack.d.ts +0 -1
- package/dist/gui/timeline/tracks/AudioTrack.js +3 -4
- package/dist/gui/timeline/tracks/AudioTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/CaptionsTrack.d.ts +2 -2
- package/dist/gui/timeline/tracks/CaptionsTrack.js +9 -9
- package/dist/gui/timeline/tracks/CaptionsTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/EFThumbnailStrip.d.ts +4 -4
- package/dist/gui/timeline/tracks/EFThumbnailStrip.js +3 -4
- package/dist/gui/timeline/tracks/EFThumbnailStrip.js.map +1 -1
- package/dist/gui/timeline/tracks/HTMLTrack.d.ts +2 -2
- package/dist/gui/timeline/tracks/HTMLTrack.js +3 -4
- package/dist/gui/timeline/tracks/HTMLTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/ImageTrack.d.ts +2 -2
- package/dist/gui/timeline/tracks/ImageTrack.js +3 -4
- package/dist/gui/timeline/tracks/ImageTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/TextTrack.d.ts +2 -2
- package/dist/gui/timeline/tracks/TextTrack.js +4 -5
- package/dist/gui/timeline/tracks/TextTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/TimegroupTrack.d.ts +5 -6
- package/dist/gui/timeline/tracks/TimegroupTrack.js +3 -4
- package/dist/gui/timeline/tracks/TimegroupTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/TrackItem.d.ts +2 -2
- package/dist/gui/timeline/tracks/TrackItem.js +3 -4
- package/dist/gui/timeline/tracks/TrackItem.js.map +1 -1
- package/dist/gui/timeline/tracks/VideoTrack.d.ts +6 -7
- package/dist/gui/timeline/tracks/VideoTrack.js +3 -4
- package/dist/gui/timeline/tracks/VideoTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/WaveformTrack.js +3 -4
- package/dist/gui/timeline/tracks/WaveformTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/ensureTrackItemInit.js +1 -1
- package/dist/gui/timeline/tracks/preloadTracks.d.ts +1 -9
- package/dist/gui/timeline/tracks/renderTrackChildren.js +1 -2
- package/dist/gui/timeline/tracks/renderTrackChildren.js.map +1 -1
- package/dist/gui/timeline/tracks/waveformUtils.js +3 -6
- package/dist/gui/timeline/tracks/waveformUtils.js.map +1 -1
- package/dist/gui/transformCalculations.js +1 -2
- package/dist/gui/transformCalculations.js.map +1 -1
- package/dist/gui/transformUtils.js +1 -1
- package/dist/gui/transformUtils.js.map +1 -1
- package/dist/gui/tree/EFTree.d.ts +4 -6
- package/dist/gui/tree/EFTree.js +3 -4
- package/dist/gui/tree/EFTree.js.map +1 -1
- package/dist/gui/tree/EFTreeItem.d.ts +4 -5
- package/dist/gui/tree/EFTreeItem.js +3 -4
- package/dist/gui/tree/EFTreeItem.js.map +1 -1
- package/dist/gui/tree/treeContext.d.ts +0 -1
- package/dist/gui/tree/treeContext.js +1 -2
- package/dist/gui/tree/treeContext.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/node.js +1 -2
- package/dist/node_modules/lit-html/development/directives/ref.d.ts +14 -0
- package/dist/node_modules/lit-html/development/lit-html.d.ts +46 -0
- package/dist/otel/BridgeSpanExporter.js +1 -2
- package/dist/otel/BridgeSpanExporter.js.map +1 -1
- package/dist/otel/setupBrowserTracing.js +1 -2
- package/dist/otel/setupBrowserTracing.js.map +1 -1
- package/dist/otel/tracingHelpers.d.ts +0 -2
- package/dist/otel/tracingHelpers.js +1 -2
- package/dist/otel/tracingHelpers.js.map +1 -1
- package/dist/preview/AdaptiveResolutionTracker.js +11 -2
- package/dist/preview/AdaptiveResolutionTracker.js.map +1 -1
- package/dist/preview/FrameController.d.ts +0 -1
- package/dist/preview/FrameController.js +8 -33
- package/dist/preview/FrameController.js.map +1 -1
- package/dist/preview/QualityUpgradeScheduler.js +1 -1
- package/dist/preview/QualityUpgradeScheduler.js.map +1 -1
- package/dist/preview/RenderContext.d.ts +0 -1
- package/dist/preview/RenderContext.js +11 -2
- package/dist/preview/RenderContext.js.map +1 -1
- package/dist/preview/RenderProfiler.js +1 -1
- package/dist/preview/RenderProfiler.js.map +1 -1
- package/dist/preview/RenderStats.js +1 -1
- package/dist/preview/RenderStats.js.map +1 -1
- package/dist/preview/encoding/canvasEncoder.js +7 -2
- package/dist/preview/encoding/canvasEncoder.js.map +1 -1
- package/dist/preview/encoding/mainThreadEncoder.js +1 -1
- package/dist/preview/encoding/mainThreadEncoder.js.map +1 -1
- package/dist/preview/encoding/workerEncoder.js +1 -1
- package/dist/preview/encoding/workerEncoder.js.map +1 -1
- package/dist/preview/logger.js +1 -1
- package/dist/preview/logger.js.map +1 -1
- package/dist/preview/previewSettings.js +1 -1
- package/dist/preview/previewSettings.js.map +1 -1
- package/dist/preview/previewTypes.js +1 -1
- package/dist/preview/previewTypes.js.map +1 -1
- package/dist/preview/renderElementToCanvas.d.ts +0 -1
- package/dist/preview/renderElementToCanvas.js +12 -5
- package/dist/preview/renderElementToCanvas.js.map +1 -1
- package/dist/preview/renderTimegroupToCanvas.d.ts +0 -1
- package/dist/preview/renderTimegroupToCanvas.js +6 -7
- package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
- package/dist/preview/renderTimegroupToVideo.d.ts +0 -1
- package/dist/preview/renderTimegroupToVideo.js +20 -8
- package/dist/preview/renderTimegroupToVideo.js.map +1 -1
- package/dist/preview/renderVideoToVideo.js +11 -2
- package/dist/preview/renderVideoToVideo.js.map +1 -1
- package/dist/preview/renderers.d.ts +0 -1
- package/dist/preview/renderers.js +5 -2
- package/dist/preview/renderers.js.map +1 -1
- package/dist/preview/rendering/ScaleConfig.js +2 -3
- package/dist/preview/rendering/ScaleConfig.js.map +1 -1
- package/dist/preview/rendering/inlineImages.d.ts +0 -1
- package/dist/preview/rendering/inlineImages.js +1 -1
- package/dist/preview/rendering/inlineImages.js.map +1 -1
- package/dist/preview/rendering/loadImage.js +1 -2
- package/dist/preview/rendering/loadImage.js.map +1 -1
- package/dist/preview/rendering/renderToImageNative.js +4 -5
- package/dist/preview/rendering/renderToImageNative.js.map +1 -1
- package/dist/preview/rendering/serializeTimelineDirect.js +16 -4
- package/dist/preview/rendering/serializeTimelineDirect.js.map +1 -1
- package/dist/preview/statsTrackingStrategy.js +1 -1
- package/dist/preview/statsTrackingStrategy.js.map +1 -1
- package/dist/preview/workers/WorkerPool.js +5 -2
- package/dist/preview/workers/WorkerPool.js.map +1 -1
- package/dist/preview/workers/encoderWorkerInline.js +1 -1
- package/dist/preview/workers/encoderWorkerInline.js.map +1 -1
- package/dist/render/EFRenderAPI.d.ts +0 -1
- package/dist/render/EFRenderAPI.js +1 -2
- package/dist/render/EFRenderAPI.js.map +1 -1
- package/dist/render/getRenderData.js +1 -1
- package/dist/render/getRenderData.js.map +1 -1
- package/dist/transcoding/cache/RequestDeduplicator.js +1 -1
- package/dist/transcoding/cache/RequestDeduplicator.js.map +1 -1
- package/dist/transcoding/cache/URLTokenDeduplicator.js +1 -1
- package/dist/transcoding/cache/URLTokenDeduplicator.js.map +1 -1
- package/dist/transcoding/types/index.d.ts +0 -1
- package/dist/transcoding/utils/UrlGenerator.js +1 -1
- package/dist/transcoding/utils/UrlGenerator.js.map +1 -1
- package/dist/utils/LRUCache.js +1 -1
- package/dist/utils/LRUCache.js.map +1 -1
- package/dist/utils/frameTime.js +2 -9
- package/dist/utils/frameTime.js.map +1 -1
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region ../../node_modules/lit-html/development/lit-html.d.ts
|
|
2
|
+
/** TemplateResult types */
|
|
3
|
+
declare const HTML_RESULT = 1;
|
|
4
|
+
declare const SVG_RESULT = 2;
|
|
5
|
+
declare const MATHML_RESULT = 3;
|
|
6
|
+
type ResultType = typeof HTML_RESULT | typeof SVG_RESULT | typeof MATHML_RESULT;
|
|
7
|
+
/**
|
|
8
|
+
* The return type of the template tag functions, {@linkcode html} and
|
|
9
|
+
* {@linkcode svg} when it hasn't been compiled by @lit-labs/compiler.
|
|
10
|
+
*
|
|
11
|
+
* A `TemplateResult` object holds all the information about a template
|
|
12
|
+
* expression required to render it: the template strings, expression values,
|
|
13
|
+
* and type of template (html or svg).
|
|
14
|
+
*
|
|
15
|
+
* `TemplateResult` objects do not create any DOM on their own. To create or
|
|
16
|
+
* update DOM you need to render the `TemplateResult`. See
|
|
17
|
+
* [Rendering](https://lit.dev/docs/components/rendering) for more information.
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
type UncompiledTemplateResult<T extends ResultType = ResultType> = {
|
|
21
|
+
['_$litType$']: T;
|
|
22
|
+
strings: TemplateStringsArray;
|
|
23
|
+
values: unknown[];
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The return type of the template tag functions, {@linkcode html} and
|
|
27
|
+
* {@linkcode svg}.
|
|
28
|
+
*
|
|
29
|
+
* A `TemplateResult` object holds all the information about a template
|
|
30
|
+
* expression required to render it: the template strings, expression values,
|
|
31
|
+
* and type of template (html or svg).
|
|
32
|
+
*
|
|
33
|
+
* `TemplateResult` objects do not create any DOM on their own. To create or
|
|
34
|
+
* update DOM you need to render the `TemplateResult`. See
|
|
35
|
+
* [Rendering](https://lit.dev/docs/components/rendering) for more information.
|
|
36
|
+
*
|
|
37
|
+
* In Lit 4, this type will be an alias of
|
|
38
|
+
* MaybeCompiledTemplateResult, so that code will get type errors if it assumes
|
|
39
|
+
* that Lit templates are not compiled. When deliberately working with only
|
|
40
|
+
* one, use either {@linkcode CompiledTemplateResult} or
|
|
41
|
+
* {@linkcode UncompiledTemplateResult} explicitly.
|
|
42
|
+
*/
|
|
43
|
+
type TemplateResult<T extends ResultType = ResultType> = UncompiledTemplateResult<T>;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { TemplateResult };
|
|
46
|
+
//# sourceMappingURL=lit-html.d.ts.map
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ExportResultCode } from "@opentelemetry/core";
|
|
2
|
-
|
|
3
2
|
//#region src/otel/BridgeSpanExporter.ts
|
|
4
3
|
function toHex(value) {
|
|
5
4
|
if (typeof value === "string") return value;
|
|
@@ -86,7 +85,7 @@ var BridgeSpanExporter = class {
|
|
|
86
85
|
return Promise.resolve();
|
|
87
86
|
}
|
|
88
87
|
};
|
|
89
|
-
|
|
90
88
|
//#endregion
|
|
91
89
|
export { BridgeSpanExporter };
|
|
90
|
+
|
|
92
91
|
//# sourceMappingURL=BridgeSpanExporter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BridgeSpanExporter.js","names":[],"sources":["../../src/otel/BridgeSpanExporter.ts"],"
|
|
1
|
+
{"version":3,"file":"BridgeSpanExporter.js","names":[],"sources":["../../src/otel/BridgeSpanExporter.ts"],"mappings":"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"}
|
|
@@ -3,7 +3,6 @@ import { Resource } from "@opentelemetry/resources";
|
|
|
3
3
|
import { BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
4
4
|
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
|
|
5
5
|
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
6
|
-
|
|
7
6
|
//#region src/otel/setupBrowserTracing.ts
|
|
8
7
|
let isInitialized = false;
|
|
9
8
|
let provider = null;
|
|
@@ -31,7 +30,7 @@ async function setupBrowserTracing(config) {
|
|
|
31
30
|
throw error;
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
|
-
|
|
35
33
|
//#endregion
|
|
36
34
|
export { setupBrowserTracing };
|
|
35
|
+
|
|
37
36
|
//# sourceMappingURL=setupBrowserTracing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupBrowserTracing.js","names":[
|
|
1
|
+
{"version":3,"file":"setupBrowserTracing.js","names":[],"sources":["../../src/otel/setupBrowserTracing.ts"],"mappings":";;;;;;AAMA,IAAI,gBAAgB;AACpB,IAAI,WAAqC;AAazC,eAAsB,oBAAoB,QAA6C;AACrF,KAAI,cACF;AAGF,KAAI;AACF,MAAI,CAAC,OAAO,OACV,OAAM,IAAI,MAAM,yCAAyC;EAG3D,MAAM,WAAW,IAAI,mBAAmB,OAAO,QAAQ,OAAO,aAAa;EAE3E,IAAI;AACJ,MAAI,OAAO,YACT,iBAAgB,IAAI,mBAAmB,UAAU;GAC/C,cAAc;GACd,oBAAoB;GACpB,sBAAsB;GACvB,CAAC;MAEF,iBAAgB,IAAI,oBAAoB,SAAS;AAGnD,aAAW,IAAI,kBAAkB;GAC/B,UAAU,IAAI,SAAS,GACpB,oBAAoB,OAAO,eAAe,oBAC5C,CAAC;GACF,gBAAgB,CAAC,cAAc;GAChC,CAAC;EAIF,MAAM,EAAE,uBAAuB,MAAM,OAAO;AAE5C,WAAS,SAAS,EAChB,gBAAgB,IAAI,oBAAoB,EACzC,CAAC;AAEF,kBAAgB;UACT,OAAO;AACd,UAAQ,MAAM,yCAAyC,MAAM;AAC7D,QAAM"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { context, propagation, trace } from "@opentelemetry/api";
|
|
2
|
-
|
|
3
2
|
//#region src/otel/tracingHelpers.ts
|
|
4
3
|
/**
|
|
5
4
|
* Global flag to enable/disable tracing.
|
|
@@ -138,7 +137,7 @@ function withSpanSync(name, attributes, parentContext, fn) {
|
|
|
138
137
|
throw error;
|
|
139
138
|
}
|
|
140
139
|
}
|
|
141
|
-
|
|
142
140
|
//#endregion
|
|
143
141
|
export { clearCurrentFrameSpan, enableTracing, extractParentContext, isTracingEnabled, setCurrentFrameSpan, withSpan, withSpanAndContext, withSpanSync };
|
|
142
|
+
|
|
144
143
|
//# sourceMappingURL=tracingHelpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracingHelpers.js","names":[
|
|
1
|
+
{"version":3,"file":"tracingHelpers.js","names":[],"sources":["../../src/otel/tracingHelpers.ts"],"mappings":"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"}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { logger } from "./logger.js";
|
|
2
|
-
|
|
3
2
|
//#region src/preview/AdaptiveResolutionTracker.ts
|
|
4
3
|
/**
|
|
4
|
+
* Adaptive Resolution Tracker
|
|
5
|
+
*
|
|
6
|
+
* Monitors actual render time to dynamically adjust preview resolution
|
|
7
|
+
* for smooth playback without dropped frames.
|
|
8
|
+
*
|
|
9
|
+
* Key insight: We measure how long each render() takes, not rAF timing.
|
|
10
|
+
* If renders consistently take longer than our frame budget, scale down.
|
|
11
|
+
* If renders consistently have headroom, scale up.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
5
14
|
* Available resolution scale steps for adaptive scaling.
|
|
6
15
|
* Finer-grained steps (5% increments) for smoother adaptation.
|
|
7
16
|
* Ordered from highest to lowest quality.
|
|
@@ -214,7 +223,7 @@ var AdaptiveResolutionTracker = class {
|
|
|
214
223
|
}
|
|
215
224
|
}
|
|
216
225
|
};
|
|
217
|
-
|
|
218
226
|
//#endregion
|
|
219
227
|
export { AdaptiveResolutionTracker };
|
|
228
|
+
|
|
220
229
|
//# sourceMappingURL=AdaptiveResolutionTracker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdaptiveResolutionTracker.js","names":[],"sources":["../../src/preview/AdaptiveResolutionTracker.ts"],"sourcesContent":["/**\n * Adaptive Resolution Tracker\n *\n * Monitors actual render time to dynamically adjust preview resolution\n * for smooth playback without dropped frames.\n *\n * Key insight: We measure how long each render() takes, not rAF timing.\n * If renders consistently take longer than our frame budget, scale down.\n * If renders consistently have headroom, scale up.\n */\n\nimport { logger } from \"./logger.js\";\n\n/**\n * Available resolution scale steps for adaptive scaling.\n * Finer-grained steps (5% increments) for smoother adaptation.\n * Ordered from highest to lowest quality.\n */\nconst SCALE_STEPS = [\n 1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6, 0.55, 0.5, 0.45, 0.4, 0.35, 0.3, 0.25, 0.2, 0.15,\n 0.1,\n] as const;\ntype ScaleStep = (typeof SCALE_STEPS)[number];\n\n/**\n * Compute Pressure API types (not yet in TypeScript lib)\n */\ntype PressureState = \"nominal\" | \"fair\" | \"serious\" | \"critical\";\n\ninterface PressureRecord {\n state: PressureState;\n time: number;\n}\n\ninterface PressureObserverCallback {\n (records: PressureRecord[]): void;\n}\n\ninterface PressureObserverOptions {\n sampleInterval?: number;\n}\n\ndeclare class PressureObserver {\n constructor(callback: PressureObserverCallback);\n observe(source: \"cpu\", options?: PressureObserverOptions): Promise<void>;\n unobserve(source: \"cpu\"): void;\n disconnect(): void;\n}\n\n/**\n * Timing thresholds\n *\n * Target: 30fps = 33.33ms per frame\n * Tolerate down to 15fps (half target) before scaling down.\n * Scale up when we have plenty of headroom.\n */\nconst TARGET_FRAME_TIME_MS = 33.33; // 30fps target\nconst SCALE_DOWN_THRESHOLD_MS = 66.67; // 15fps (half target) - only scale down if really struggling\nconst SCALE_UP_THRESHOLD_MS = 25; // If avg render time is well below target, consider scaling up\nconst ROLLING_WINDOW_SIZE = 30; // ~1 second of samples at 30fps\nconst MIN_SCALE_CHANGE_INTERVAL_MS = 2000; // Wait 2s between any scale changes\nconst SCALE_UP_STABILITY_SAMPLES = 60; // Need 60 samples (~2s) of good performance to scale up\n\n/** Size of the pressure history for histogram display */\nconst PRESSURE_HISTORY_SIZE = 60;\n\n/**\n * Tracks render time to recommend optimal preview resolution.\n */\nexport class AdaptiveResolutionTracker {\n private renderTimes: number[] = []; // Rolling window of render times (ms)\n private currentScaleIndex = 0; // Index into SCALE_STEPS (0 = highest quality)\n private lastScaleChangeTime = 0;\n private samplesAtCurrentScale = 0; // How many samples we've collected at current scale\n\n // Compute Pressure API\n private pressureObserver: PressureObserver | null = null;\n private pressureState: PressureState = \"nominal\";\n private pressureHistory: PressureState[] = [];\n\n // For display - track frame intervals separately from render times\n private lastFrameTime = 0;\n private frameIntervals: number[] = [];\n\n // Callbacks\n private onScaleChange?: (scale: ScaleStep) => void;\n\n constructor(options?: { onScaleChange?: (scale: ScaleStep) => void }) {\n this.onScaleChange = options?.onScaleChange;\n this.initPressureObserver();\n }\n\n /**\n * Initialize Compute Pressure API observer if available.\n */\n private initPressureObserver(): void {\n if (!(\"PressureObserver\" in globalThis)) {\n return;\n }\n\n try {\n this.pressureObserver = new PressureObserver((records) => {\n if (records.length > 0) {\n const latest = records[records.length - 1]!;\n this.pressureState = latest.state;\n\n this.pressureHistory.push(latest.state);\n if (this.pressureHistory.length > PRESSURE_HISTORY_SIZE) {\n this.pressureHistory.shift();\n }\n }\n });\n\n this.pressureObserver.observe(\"cpu\", { sampleInterval: 500 }).catch(() => {\n // Ignore errors from observe (e.g., AbortError if disconnect called before observe resolves)\n });\n } catch (e) {\n logger.warn(\"[AdaptiveResolutionTracker] Failed to initialize PressureObserver:\", e);\n this.pressureObserver = null;\n }\n }\n\n /**\n * Record a frame's render time.\n * Call this AFTER each render completes with how long the render took.\n *\n * @param renderTimeMs - How long the render() call took in milliseconds\n * @param timestamp - Optional rAF timestamp for frame interval tracking (display only)\n */\n recordFrame(renderTimeMs: number, timestamp?: number): void {\n // Track render times for adaptive decisions\n this.renderTimes.push(renderTimeMs);\n if (this.renderTimes.length > ROLLING_WINDOW_SIZE) {\n this.renderTimes.shift();\n }\n this.samplesAtCurrentScale++;\n\n // Track frame intervals for FPS display (separate from render time)\n if (timestamp !== undefined && this.lastFrameTime > 0) {\n const interval = timestamp - this.lastFrameTime;\n this.frameIntervals.push(interval);\n if (this.frameIntervals.length > ROLLING_WINDOW_SIZE) {\n this.frameIntervals.shift();\n }\n }\n if (timestamp !== undefined) {\n this.lastFrameTime = timestamp;\n }\n\n // Check if we should adjust scale\n this.checkForScaleAdjustment();\n }\n\n /**\n * Check if we should scale up or down based on render time trends.\n */\n private checkForScaleAdjustment(): void {\n if (this.renderTimes.length < 10) return; // Need some samples\n\n const now = performance.now();\n if (now - this.lastScaleChangeTime < MIN_SCALE_CHANGE_INTERVAL_MS) {\n return; // Rate limit changes\n }\n\n const avgRenderTime = this.renderTimes.reduce((a, b) => a + b, 0) / this.renderTimes.length;\n\n // Scale DOWN if we're consistently slow\n if (avgRenderTime > SCALE_DOWN_THRESHOLD_MS) {\n this.scaleDown(\"slow\");\n return;\n }\n\n // Scale DOWN if CPU pressure is high (proactive)\n if (this.pressureState === \"critical\" || this.pressureState === \"serious\") {\n this.scaleDown(\"pressure\");\n return;\n }\n\n // Scale UP if we have sustained headroom and CPU isn't under pressure\n // (we already returned above if pressure is serious/critical, but check again for clarity)\n const pressureOk = this.pressureState === \"nominal\" || this.pressureState === \"fair\";\n if (\n avgRenderTime < SCALE_UP_THRESHOLD_MS &&\n this.samplesAtCurrentScale >= SCALE_UP_STABILITY_SAMPLES &&\n pressureOk\n ) {\n this.scaleUp();\n }\n }\n\n /**\n * Decrease resolution (increase scale index).\n */\n private scaleDown(reason: \"slow\" | \"pressure\"): void {\n if (this.currentScaleIndex < SCALE_STEPS.length - 1) {\n this.currentScaleIndex++;\n this.lastScaleChangeTime = performance.now();\n this.samplesAtCurrentScale = 0;\n this.renderTimes = []; // Clear history at new scale\n\n const newScale = SCALE_STEPS[this.currentScaleIndex]!;\n logger.debug(\n `[AdaptiveResolutionTracker] Scaling DOWN to ${(newScale * 100).toFixed(0)}% (reason: ${reason})`,\n );\n this.onScaleChange?.(newScale);\n }\n }\n\n /**\n * Increase resolution (decrease scale index).\n */\n private scaleUp(): void {\n if (this.currentScaleIndex > 0) {\n this.currentScaleIndex--;\n this.lastScaleChangeTime = performance.now();\n this.samplesAtCurrentScale = 0;\n this.renderTimes = []; // Clear history at new scale\n\n const newScale = SCALE_STEPS[this.currentScaleIndex]!;\n logger.debug(\n `[AdaptiveResolutionTracker] Scaling UP to ${(newScale * 100).toFixed(0)}% (reason: stable performance)`,\n );\n this.onScaleChange?.(newScale);\n }\n }\n\n /**\n * Get the current recommended scale factor.\n */\n getRecommendedScale(): ScaleStep {\n return SCALE_STEPS[this.currentScaleIndex]!;\n }\n\n /**\n * Get current statistics for display.\n */\n getStats(): {\n currentScale: ScaleStep;\n avgRenderTime: number;\n fps: number;\n pressureState: PressureState;\n pressureHistory: PressureState[];\n samplesAtCurrentScale: number;\n canScaleUp: boolean;\n canScaleDown: boolean;\n headroom: number; // How much faster than target we're rendering (negative = behind)\n } {\n const avgRenderTime =\n this.renderTimes.length > 0\n ? this.renderTimes.reduce((a, b) => a + b, 0) / this.renderTimes.length\n : 0;\n\n // FPS based on frame intervals (how often we're called), not render time\n const avgFrameInterval =\n this.frameIntervals.length > 0\n ? this.frameIntervals.reduce((a, b) => a + b, 0) / this.frameIntervals.length\n : 16.67;\n const fps = avgFrameInterval > 0 ? 1000 / avgFrameInterval : 0;\n\n const now = performance.now();\n const timeSinceLastChange = now - this.lastScaleChangeTime;\n const canChange = timeSinceLastChange >= MIN_SCALE_CHANGE_INTERVAL_MS;\n\n const pressureOk = this.pressureState === \"nominal\" || this.pressureState === \"fair\";\n const canScaleUp =\n canChange &&\n this.currentScaleIndex > 0 &&\n avgRenderTime < SCALE_UP_THRESHOLD_MS &&\n this.samplesAtCurrentScale >= SCALE_UP_STABILITY_SAMPLES &&\n pressureOk;\n\n const canScaleDown = canChange && this.currentScaleIndex < SCALE_STEPS.length - 1;\n\n // Headroom: positive = we're faster than needed, negative = we're behind\n const headroom = TARGET_FRAME_TIME_MS - avgRenderTime;\n\n return {\n currentScale: this.getRecommendedScale(),\n avgRenderTime,\n fps,\n pressureState: this.pressureState,\n pressureHistory: [...this.pressureHistory],\n samplesAtCurrentScale: this.samplesAtCurrentScale,\n canScaleUp,\n canScaleDown,\n headroom,\n };\n }\n\n /**\n * Reset the tracker state.\n */\n reset(): void {\n this.lastFrameTime = 0;\n this.frameIntervals = [];\n this.renderTimes = [];\n this.currentScaleIndex = 0;\n this.lastScaleChangeTime = 0;\n this.samplesAtCurrentScale = 0;\n }\n\n /**\n * Initialize the tracker to start at a specific scale.\n */\n initializeAtScale(targetScale: number): void {\n let bestIndex = 0;\n for (let i = 0; i < SCALE_STEPS.length; i++) {\n if (SCALE_STEPS[i]! <= targetScale) {\n bestIndex = i;\n break;\n }\n }\n\n this.currentScaleIndex = bestIndex;\n this.lastFrameTime = 0;\n this.frameIntervals = [];\n this.renderTimes = [];\n this.lastScaleChangeTime = 0;\n this.samplesAtCurrentScale = 0;\n\n logger.debug(\n `[AdaptiveResolutionTracker] Initialized at scale ${(SCALE_STEPS[bestIndex]! * 100).toFixed(0)}%`,\n );\n }\n\n /**\n * Clean up resources.\n */\n dispose(): void {\n if (this.pressureObserver) {\n try {\n this.pressureObserver.disconnect();\n } catch {\n // Ignore cleanup errors\n }\n this.pressureObserver = null;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AdaptiveResolutionTracker.js","names":[],"sources":["../../src/preview/AdaptiveResolutionTracker.ts"],"mappings":"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"}
|
|
@@ -1,35 +1,5 @@
|
|
|
1
1
|
//#region src/preview/FrameController.ts
|
|
2
2
|
/**
|
|
3
|
-
* Priority for video elements.
|
|
4
|
-
* Video renders first as other elements may depend on video frames being ready.
|
|
5
|
-
*/
|
|
6
|
-
const PRIORITY_VIDEO = 1;
|
|
7
|
-
/**
|
|
8
|
-
* Priority for captions elements.
|
|
9
|
-
* Captions render after video so they can overlay correctly.
|
|
10
|
-
*/
|
|
11
|
-
const PRIORITY_CAPTIONS = 2;
|
|
12
|
-
/**
|
|
13
|
-
* Priority for audio elements.
|
|
14
|
-
* Audio renders after captions (no visual dependency, but keeps consistent ordering).
|
|
15
|
-
*/
|
|
16
|
-
const PRIORITY_AUDIO = 3;
|
|
17
|
-
/**
|
|
18
|
-
* Priority for waveform elements.
|
|
19
|
-
* Waveform renders after audio because it depends on audio analysis data.
|
|
20
|
-
*/
|
|
21
|
-
const PRIORITY_WAVEFORM = 4;
|
|
22
|
-
/**
|
|
23
|
-
* Priority for image elements.
|
|
24
|
-
* Images render with low priority as they're typically static.
|
|
25
|
-
*/
|
|
26
|
-
const PRIORITY_IMAGE = 5;
|
|
27
|
-
/**
|
|
28
|
-
* Default priority for elements that don't specify one.
|
|
29
|
-
* High number ensures custom elements render after standard elements.
|
|
30
|
-
*/
|
|
31
|
-
const PRIORITY_DEFAULT = 100;
|
|
32
|
-
/**
|
|
33
3
|
* Type guard to check if an element implements FrameRenderable.
|
|
34
4
|
*/
|
|
35
5
|
function isFrameRenderable(element) {
|
|
@@ -166,7 +136,12 @@ var FrameController = class {
|
|
|
166
136
|
if ("startTimeMs" in element && "endTimeMs" in element) {
|
|
167
137
|
const startMs = element.startTimeMs ?? -Infinity;
|
|
168
138
|
const endMs = element.endTimeMs ?? Infinity;
|
|
169
|
-
|
|
139
|
+
let isTemporallyVisible = currentTimeMs >= startMs && currentTimeMs < endMs;
|
|
140
|
+
if (!isTemporallyVisible && currentTimeMs >= endMs && currentTimeMs <= endMs) {
|
|
141
|
+
const rootEnd = element.rootTimegroup?.endTimeMs;
|
|
142
|
+
if (rootEnd !== void 0 && Math.abs(endMs - rootEnd) < .001) isTemporallyVisible = true;
|
|
143
|
+
}
|
|
144
|
+
if (!isTemporallyVisible) return;
|
|
170
145
|
if (isFrameRenderable(element)) result.push(element);
|
|
171
146
|
} else {
|
|
172
147
|
if (element instanceof HTMLElement && element.style.display === "none") return;
|
|
@@ -202,7 +177,7 @@ var FrameController = class {
|
|
|
202
177
|
return this.#renderInProgress;
|
|
203
178
|
}
|
|
204
179
|
};
|
|
205
|
-
|
|
206
180
|
//#endregion
|
|
207
|
-
export { FrameController
|
|
181
|
+
export { FrameController };
|
|
182
|
+
|
|
208
183
|
//# sourceMappingURL=FrameController.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameController.js","names":["#rootElement","#abortController","#lastRenderedTimeMs","#renderInProgress","#pendingRenderTime","#queryVisibleElements","result: FrameRenderable[]","#getChildrenIncludingSlotted","assignedElements: Element[]"],"sources":["../../src/preview/FrameController.ts"],"sourcesContent":["/**\n * FrameController: Centralized frame rendering control\n *\n * Replaces the distributed Lit Task hierarchy with a single control loop\n * that queries elements and coordinates rendering directly.\n *\n * Benefits over the previous Task-based system:\n * - Single abort controller instead of distributed abort handling\n * - Clear prepare → render phases\n * - All coordination visible in one place\n * - No Lit Task reactivity overhead\n */\n\nimport type { LitElement } from \"lit\";\n\n// ============================================================================\n// Priority Constants\n// ============================================================================\n// Lower numbers render first. Elements with dependencies should have higher\n// priority numbers than their dependencies.\n//\n// Example: Waveform depends on audio analysis data, so it renders after audio.\n// ============================================================================\n\n/**\n * Priority for video elements.\n * Video renders first as other elements may depend on video frames being ready.\n */\nexport const PRIORITY_VIDEO = 1;\n\n/**\n * Priority for captions elements.\n * Captions render after video so they can overlay correctly.\n */\nexport const PRIORITY_CAPTIONS = 2;\n\n/**\n * Priority for audio elements.\n * Audio renders after captions (no visual dependency, but keeps consistent ordering).\n */\nexport const PRIORITY_AUDIO = 3;\n\n/**\n * Priority for waveform elements.\n * Waveform renders after audio because it depends on audio analysis data.\n */\nexport const PRIORITY_WAVEFORM = 4;\n\n/**\n * Priority for image elements.\n * Images render with low priority as they're typically static.\n */\nexport const PRIORITY_IMAGE = 5;\n\n/**\n * Default priority for elements that don't specify one.\n * High number ensures custom elements render after standard elements.\n */\nexport const PRIORITY_DEFAULT = 100;\n\n/**\n * State returned by elements describing their readiness for a given time.\n */\nexport interface FrameState {\n /**\n * Whether async preparation is needed before rendering.\n * Examples: video needs to seek, captions need to load data.\n */\n needsPreparation: boolean;\n\n /**\n * Whether the element is ready to render synchronously.\n * True when all async work is complete and renderFrame() can be called.\n */\n isReady: boolean;\n\n /**\n * Rendering priority hint. Lower numbers render first.\n * Used to order render calls for elements with dependencies.\n *\n * Standard priorities:\n * - PRIORITY_VIDEO (1): Video elements\n * - PRIORITY_CAPTIONS (2): Caption overlays\n * - PRIORITY_AUDIO (3): Audio elements\n * - PRIORITY_WAVEFORM (4): Audio visualizers (depend on audio)\n * - PRIORITY_IMAGE (5): Static images\n * - PRIORITY_DEFAULT (100): Fallback for custom elements\n */\n priority: number;\n}\n\n/**\n * Interface that elements implement to participate in centralized frame rendering.\n * Elements keep their rendering logic local but expose a standardized interface.\n */\nexport interface FrameRenderable {\n /**\n * Query the element's readiness state for a given time.\n * Must be synchronous and cheap to call.\n */\n getFrameState(timeMs: number): FrameState;\n\n /**\n * Async preparation phase. Called when getFrameState().needsPreparation is true.\n * Performs any async work needed before rendering (seeking, loading, etc.).\n *\n * @param timeMs - The time to prepare for\n * @param signal - Abort signal for cancellation\n */\n prepareFrame(timeMs: number, signal: AbortSignal): Promise<void>;\n\n /**\n * Synchronous render phase. Called after all preparation is complete.\n * Performs the actual rendering (paint to canvas, update DOM, etc.).\n *\n * @param timeMs - The time to render\n */\n renderFrame(timeMs: number): void;\n}\n\n/**\n * Type guard to check if an element implements FrameRenderable.\n */\nexport function isFrameRenderable(element: unknown): element is FrameRenderable {\n return (\n typeof element === \"object\" &&\n element !== null &&\n \"getFrameState\" in element &&\n \"prepareFrame\" in element &&\n \"renderFrame\" in element &&\n typeof (element as FrameRenderable).getFrameState === \"function\" &&\n typeof (element as FrameRenderable).prepareFrame === \"function\" &&\n typeof (element as FrameRenderable).renderFrame === \"function\"\n );\n}\n\n/**\n * Per-phase timing data returned by FrameController.renderFrame().\n * All values are in milliseconds.\n */\nexport interface RenderFrameTiming {\n queryMs: number;\n prepareMs: number;\n renderMs: number;\n animsMs: number;\n}\n\n/**\n * Options for FrameController.renderFrame()\n */\nexport interface RenderFrameOptions {\n /**\n * Whether to wait for Lit updateComplete before querying elements.\n * Default: true\n */\n waitForLitUpdate?: boolean;\n\n /**\n * Callback to update CSS animations after frame rendering completes.\n * Called with the root element after all elements have rendered.\n * This centralizes animation synchronization in one place.\n */\n onAnimationsUpdate?: (rootElement: Element) => void;\n}\n\n/**\n * Central controller for frame rendering.\n * Lives at the root timegroup and orchestrates all element rendering.\n */\nexport class FrameController {\n #rootElement: LitElement & { currentTimeMs: number };\n #abortController: AbortController | null = null;\n #renderInProgress = false;\n #pendingRenderTime: number | null = null;\n /**\n * Last successfully rendered time. Used for deduplication when multiple\n * callers (e.g., PlaybackController RAF loop and canvas render loop)\n * both try to render the same frame within one animation frame.\n */\n #lastRenderedTimeMs: number = -1;\n\n constructor(rootElement: LitElement & { currentTimeMs: number }) {\n this.#rootElement = rootElement;\n }\n\n /**\n * Cancel any in-progress render operation and mark the last frame stale.\n *\n * Use this when a user-initiated seek or time change invalidates the current\n * render and a fresh render is needed immediately.\n *\n * Do NOT call this from quality-upgrade callbacks — use markLastFrameStale()\n * instead to avoid aborting an in-progress scrub seek.\n */\n abort(): void {\n this.#abortController?.abort();\n this.#abortController = null;\n // Reset deduplication state so next render goes through even if same time\n this.#lastRenderedTimeMs = -1;\n }\n\n /**\n * Mark the last rendered frame stale WITHOUT aborting any in-progress render.\n *\n * Use this for quality-upgrade re-renders: the goal is to show a\n * higher-quality frame at the same time, but aborting the current render\n * would cancel an in-progress scrub seek. If quality-upgrade calls fire\n * faster than scrub seeks can complete, every seek would be aborted before\n * returning a sample — infinite loop, canvas stuck on first frame.\n *\n * With only the stale marker, the current render continues uninterrupted. When\n * it finishes, the queued re-render fires and can upgrade to main quality.\n *\n * Do NOT call abort() from quality-upgrade callbacks — use this method instead.\n */\n markLastFrameStale(): void {\n this.#lastRenderedTimeMs = -1;\n }\n\n /**\n * Render a frame at the specified time.\n *\n * This is the main entry point for frame rendering. It:\n * 1. Cancels any previous in-progress render\n * 2. Queries all visible FrameRenderable elements\n * 3. Runs preparation in parallel for elements that need it\n * 4. Runs render in priority order\n *\n * @param timeMs - The time in milliseconds to render\n * @param options - Optional configuration\n */\n async renderFrame(\n timeMs: number,\n options: RenderFrameOptions = {},\n ): Promise<RenderFrameTiming | null> {\n const { waitForLitUpdate = true, onAnimationsUpdate } = options;\n\n // Deduplicate: skip if we just rendered this exact time.\n // This prevents double-rendering when multiple RAF loops (e.g., PlaybackController\n // and canvas render loop) both call renderFrame() for the same frame.\n if (timeMs === this.#lastRenderedTimeMs) {\n return null;\n }\n\n // If a render is in progress, queue this one\n if (this.#renderInProgress) {\n this.#pendingRenderTime = timeMs;\n return null;\n }\n\n // Cancel any previous render operation\n this.#abortController?.abort();\n this.#abortController = new AbortController();\n const signal = this.#abortController.signal;\n\n this.#renderInProgress = true;\n\n try {\n if (waitForLitUpdate) {\n await this.#rootElement.updateComplete;\n signal.throwIfAborted();\n }\n\n const tQuery = performance.now();\n const elements = this.#queryVisibleElements(timeMs);\n const queryMs = performance.now() - tQuery;\n signal.throwIfAborted();\n\n const tPrepare = performance.now();\n const elementsNeedingPreparation = elements.filter(\n (el) => el.getFrameState(timeMs).needsPreparation,\n );\n\n if (elementsNeedingPreparation.length > 0) {\n await Promise.all(elementsNeedingPreparation.map((el) => el.prepareFrame(timeMs, signal)));\n signal.throwIfAborted();\n }\n const prepareMs = performance.now() - tPrepare;\n\n const tRender = performance.now();\n const sortedElements = [...elements].sort(\n (a, b) => a.getFrameState(timeMs).priority - b.getFrameState(timeMs).priority,\n );\n\n for (const element of sortedElements) {\n signal.throwIfAborted();\n element.renderFrame(timeMs);\n }\n const renderMs = performance.now() - tRender;\n\n const tAnims = performance.now();\n if (onAnimationsUpdate) {\n onAnimationsUpdate(this.#rootElement);\n }\n const animsMs = performance.now() - tAnims;\n\n return { queryMs, prepareMs, renderMs, animsMs };\n } finally {\n this.#renderInProgress = false;\n\n // Process any queued render. IMPORTANT: set #lastRenderedTimeMs only when\n // there is no pending follow-up render. If a pending render exists (e.g.\n // a quality-upgrade re-render queued while the scrub render was in-flight),\n // setting the dedup timestamp here would cause the pending renderFrame(T)\n // to be skipped by the dedup check (T === T). By deferring the assignment\n // we let the pending render run, and it will set #lastRenderedTimeMs itself.\n if (this.#pendingRenderTime !== null) {\n const pendingTime = this.#pendingRenderTime;\n this.#pendingRenderTime = null;\n // Don't await - fire and forget to avoid recursive waiting\n this.renderFrame(pendingTime, options).catch(() => {\n // Silently ignore errors from queued renders (likely aborted)\n });\n } else {\n this.#lastRenderedTimeMs = timeMs;\n }\n }\n }\n\n /**\n * Query all visible FrameRenderable elements in the tree.\n * Uses temporal visibility to filter out elements not visible at current time.\n *\n * IMPORTANT: For temporal elements, we use temporal visibility (startTimeMs/endTimeMs)\n * instead of CSS visibility. This is because updateAnimations sets display:none on\n * elements outside their time range, but that CSS state is from the PREVIOUS frame.\n * When seeking, we need to evaluate visibility based on the NEW time, not stale CSS.\n *\n * @param timeMs - The time to use for visibility checks. This should be the target\n * render time, not read from root element (which may be stale).\n */\n #queryVisibleElements(timeMs: number): FrameRenderable[] {\n const result: FrameRenderable[] = [];\n const currentTimeMs = timeMs;\n\n const walk = (element: Element): void => {\n // For temporal elements (ef-timegroup, ef-video, etc.), use temporal visibility\n // instead of CSS visibility. CSS display:none may be stale from previous frame.\n const isTemporal = \"startTimeMs\" in element && \"endTimeMs\" in element;\n\n if (isTemporal) {\n // Temporal element: check time-based visibility\n // Use exclusive end (< not <=) to avoid overlap at boundaries\n const startMs = (element as { startTimeMs?: number }).startTimeMs ?? -Infinity;\n const endMs = (element as { endTimeMs?: number }).endTimeMs ?? Infinity;\n const isTemporallyVisible = currentTimeMs >= startMs && currentTimeMs < endMs;\n\n if (!isTemporallyVisible) {\n // Skip this element AND its children (children's times are relative to parent)\n return;\n }\n\n // Element is temporally visible - include if it implements FrameRenderable\n if (isFrameRenderable(element)) {\n result.push(element);\n }\n } else {\n // Non-temporal element: only check inline display style (fast path).\n // Skip getComputedStyle — it forces synchronous style recalc and is\n // unnecessary because FrameRenderable elements are always temporal.\n // We only walk non-temporal elements to reach temporal children.\n if (element instanceof HTMLElement && element.style.display === \"none\") {\n return;\n }\n\n if (isFrameRenderable(element)) {\n result.push(element);\n }\n }\n\n // Walk children - handle both regular children and slotted content\n const children = this.#getChildrenIncludingSlotted(element);\n for (const child of children) {\n walk(child);\n }\n };\n\n walk(this.#rootElement);\n return result;\n }\n\n /**\n * Gets all child elements including slotted content for shadow DOM elements.\n * For elements with shadow DOM that contain slots, this returns the assigned\n * elements (slotted content) instead of just the shadow DOM children.\n */\n #getChildrenIncludingSlotted(element: Element): Iterable<Element> {\n // If element has shadowRoot with slots, get assigned elements\n if (element.shadowRoot) {\n const slots = element.shadowRoot.querySelectorAll(\"slot\");\n if (slots.length > 0) {\n const assignedElements: Element[] = [];\n for (const slot of slots) {\n assignedElements.push(...slot.assignedElements());\n }\n // Also include shadow DOM children that aren't slots (for mixed content)\n for (const child of element.shadowRoot.children) {\n if (child.tagName !== \"SLOT\") {\n assignedElements.push(child);\n }\n }\n return assignedElements;\n }\n }\n\n // Return HTMLCollection directly (iterable, no allocation)\n return element.children;\n }\n\n /**\n * Check if a render is currently in progress.\n */\n get isRendering(): boolean {\n return this.#renderInProgress;\n }\n}\n\n/**\n * Default frame state for elements that don't need special handling.\n * Use this for simple elements that are always ready.\n */\nexport const DEFAULT_FRAME_STATE: FrameState = {\n needsPreparation: false,\n isReady: true,\n priority: PRIORITY_DEFAULT,\n};\n\n/**\n * Helper to create a FrameRenderable mixin for elements.\n * Provides default implementations that can be overridden.\n */\nexport function createFrameRenderableMixin<T extends { new (...args: any[]): HTMLElement }>(\n Base: T,\n) {\n return class FrameRenderableMixin extends Base implements FrameRenderable {\n getFrameState(_timeMs: number): FrameState {\n return DEFAULT_FRAME_STATE;\n }\n\n async prepareFrame(_timeMs: number, _signal: AbortSignal): Promise<void> {\n // Default: no preparation needed\n }\n\n renderFrame(_timeMs: number): void {\n // Default: no explicit render needed\n }\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FrameController.js","names":["#rootElement","#abortController","#lastRenderedTimeMs","#renderInProgress","#pendingRenderTime","#queryVisibleElements","#getChildrenIncludingSlotted"],"sources":["../../src/preview/FrameController.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QualityUpgradeScheduler.js","names":["#requestFrameRender","#maxConcurrent","#abortController","#queue","#activeTasks","#completedTasks","#failedKeys","#processQueue","#startTask","results: UpgradeTaskStatus[]"],"sources":["../../src/preview/QualityUpgradeScheduler.ts"],"sourcesContent":["/**\n * QualityUpgradeScheduler: Centralized deadline-ordered work queue\n *\n * Coordinates main-quality segment fetching across multiple video elements.\n * Generic scheduler that doesn't understand media concepts (segments, renditions, etc.)\n * - only processes { key, deadlineMs, fetch, isCached, owner } tuples.\n *\n * Design principles:\n * - Deadline-based ordering: always process nearest deadline first\n * - Ground-truth cache validation: check cache before starting any fetch\n * - In-flight fetches never cancelled: they populate shared cache\n * - Event-driven: elements submit tasks only on state changes, not every frame\n */\n\nexport interface UpgradeTask {\n /** Opaque dedup key (e.g. \"${owner}:${segmentId}:${renditionId}\") */\n key: string;\n /** Fetch function that populates the cache */\n fetch: (signal: AbortSignal) => Promise<void>;\n /** Returns true if the segment is still present in the cache. Used to skip\n * re-queuing completed tasks whose segment is still cached, and to allow\n * re-queuing when the segment has been LRU-evicted. If absent, a completed\n * task is conservatively treated as still cached (skip re-queue). */\n isCached?: () => boolean;\n /** Timeline time when this segment will be needed */\n deadlineMs: number;\n /** Element ID, for bulk operations */\n owner: string;\n}\n\nexport interface UpgradeTaskStatus {\n key: string;\n owner: string;\n deadlineMs: number;\n status: \"queued\" | \"active\" | \"completed\" | \"failed\";\n error?: string;\n}\n\nexport interface OwnerProgress {\n queued: number;\n active: number;\n completed: number;\n failed: number;\n}\n\ninterface ActiveTask {\n task: UpgradeTask;\n startedAt: number;\n promise: Promise<void>;\n}\n\ninterface CompletedTask {\n key: string;\n owner: string;\n status: \"completed\";\n}\n\nexport class QualityUpgradeScheduler {\n #maxConcurrent: number;\n #queue: UpgradeTask[] = [];\n #activeTasks = new Map<string, ActiveTask>();\n #completedTasks = new Map<string, CompletedTask>();\n /** Keys of tasks that failed with a non-abort error, mapped to their owner.\n * Prevents enqueue() from repeatedly re-queuing the same failing segment\n * during lookahead. Cleared by replaceForOwner() (per task key) and\n * cancelForOwner() (per owner). */\n #failedKeys = new Map<string, string>(); // key → owner\n #abortController: AbortController;\n #requestFrameRender: () => void;\n\n constructor(options: { requestFrameRender: () => void; maxConcurrent?: number }) {\n this.#requestFrameRender = options.requestFrameRender;\n this.#maxConcurrent = options.maxConcurrent ?? 4;\n this.#abortController = new AbortController();\n }\n\n /**\n * Add tasks without affecting existing ones (additive).\n * Used for lookahead extension during playback.\n */\n enqueue(tasks: UpgradeTask[]): void {\n if (this.#abortController.signal.aborted) return;\n\n for (const task of tasks) {\n // Skip if already queued, active, completed, or previously failed.\n // Failed tasks are not retried via enqueue (lookahead) — only via\n // replaceForOwner (explicit seek) which clears #failedKeys for the owner.\n if (\n this.#queue.some((t) => t.key === task.key) ||\n this.#activeTasks.has(task.key) ||\n this.#completedTasks.has(task.key) ||\n this.#failedKeys.has(task.key) // previously failed — don't retry via lookahead\n ) {\n continue;\n }\n\n this.#queue.push(task);\n }\n\n // Sort queue by deadline (ascending)\n this.#queue.sort((a, b) => a.deadlineMs - b.deadlineMs);\n\n // Start processing if we have capacity\n this.#processQueue();\n }\n\n /**\n * Replace all queued tasks for an owner.\n * Used on seeks, trim changes, timeline position changes where old deadlines are stale.\n * Does NOT cancel in-flight tasks (they populate shared cache).\n */\n replaceForOwner(owner: string, tasks: UpgradeTask[]): void {\n if (this.#abortController.signal.aborted) return;\n\n // Remove queued (not active) tasks for this owner\n this.#queue = this.#queue.filter((t) => t.owner !== owner);\n\n // Add new tasks\n for (const task of tasks) {\n if (this.#activeTasks.has(task.key)) {\n continue;\n }\n\n // replaceForOwner is an explicit seek/state change — clear any prior\n // failure record so the task can be retried.\n this.#failedKeys.delete(task.key);\n\n if (this.#completedTasks.has(task.key)) {\n // If the task reports the segment is still cached, skip re-queuing.\n // When isCached is absent, conservatively treat as still cached.\n // When isCached returns false (LRU eviction), remove the stale record and re-queue.\n const segmentStillCached = task.isCached ? task.isCached() : true;\n if (segmentStillCached) continue;\n this.#completedTasks.delete(task.key);\n }\n\n this.#queue.push(task);\n }\n\n // Sort queue by deadline (ascending)\n this.#queue.sort((a, b) => a.deadlineMs - b.deadlineMs);\n\n // Start processing if we have capacity\n this.#processQueue();\n }\n\n /**\n * Cancel all tasks for an owner.\n * Removes queued tasks. Does NOT abort in-flight fetches.\n */\n cancelForOwner(owner: string): void {\n // Remove from queue\n this.#queue = this.#queue.filter((t) => t.owner !== owner);\n\n // Remove from completed and failed tracking (allows resubmission)\n for (const [key, task] of this.#completedTasks.entries()) {\n if (task.owner === owner) {\n this.#completedTasks.delete(key);\n }\n }\n for (const [key, taskOwner] of this.#failedKeys.entries()) {\n if (taskOwner === owner) {\n this.#failedKeys.delete(key);\n }\n }\n\n // Note: we do NOT cancel active tasks - they populate the shared cache\n }\n\n /**\n * Process the queue - start tasks up to maxConcurrent limit.\n */\n #processQueue(): void {\n if (this.#abortController.signal.aborted) return;\n\n while (this.#activeTasks.size < this.#maxConcurrent && this.#queue.length > 0) {\n const task = this.#queue.shift();\n if (!task) break;\n\n this.#startTask(task);\n }\n }\n\n /**\n * Start a single task.\n */\n #startTask(task: UpgradeTask): void {\n const promise = task\n .fetch(this.#abortController.signal)\n .then(() => {\n // Success\n this.#activeTasks.delete(task.key);\n this.#completedTasks.set(task.key, {\n key: task.key,\n owner: task.owner,\n status: \"completed\",\n });\n\n // Trigger re-render so upgraded quality gets displayed. Called\n // synchronously in the .then() microtask: currentTimeMs is still at\n // the position where the segment was needed, and resolvedKeys.add()\n // has already run (earlier in the microtask chain). The FrameController\n // #pendingRenderTime mechanism coalesces concurrent completions.\n this.#requestFrameRender();\n\n // Start next task if available\n this.#processQueue();\n })\n .catch((error) => {\n this.#activeTasks.delete(task.key);\n\n // Don't track AbortError as failed (intentional cancellation, not an error).\n const isAbortError = error instanceof DOMException && error.name === \"AbortError\";\n if (!isAbortError) {\n // Record as failed so enqueue() doesn't re-attempt during lookahead.\n // replaceForOwner() clears this on an explicit seek, allowing retry.\n this.#failedKeys.set(task.key, task.owner);\n }\n\n // Continue processing queue even after failure\n this.#processQueue();\n });\n\n this.#activeTasks.set(task.key, {\n task,\n startedAt: performance.now(),\n promise,\n });\n }\n\n /**\n * Check whether a task is currently in-flight (started, not yet complete).\n */\n isActive(key: string): boolean {\n return this.#activeTasks.has(key);\n }\n\n /**\n * Check whether a task is waiting in the queue (submitted but not yet started).\n */\n isPending(key: string): boolean {\n return this.#queue.some((t) => t.key === key);\n }\n\n /**\n * Get snapshot of current queue state for debugging.\n */\n getQueueSnapshot(): UpgradeTaskStatus[] {\n const results: UpgradeTaskStatus[] = [];\n\n // Queued tasks\n for (const task of this.#queue) {\n results.push({\n key: task.key,\n owner: task.owner,\n deadlineMs: task.deadlineMs,\n status: \"queued\",\n });\n }\n\n // Active tasks\n for (const [key, activeTask] of this.#activeTasks.entries()) {\n results.push({\n key,\n owner: activeTask.task.owner,\n deadlineMs: activeTask.task.deadlineMs,\n status: \"active\",\n });\n }\n\n // Completed tasks\n for (const [key, completed] of this.#completedTasks.entries()) {\n results.push({\n key,\n owner: completed.owner,\n deadlineMs: 0,\n status: completed.status,\n });\n }\n\n // Failed tasks\n for (const [key, owner] of this.#failedKeys.entries()) {\n results.push({\n key,\n owner,\n deadlineMs: 0,\n status: \"failed\",\n });\n }\n\n return results;\n }\n\n /**\n * Get progress for a specific owner.\n */\n getOwnerProgress(owner: string): OwnerProgress {\n const queued = this.#queue.filter((t) => t.owner === owner).length;\n\n let active = 0;\n for (const activeTask of this.#activeTasks.values()) {\n if (activeTask.task.owner === owner) {\n active++;\n }\n }\n\n let completed = 0;\n for (const task of this.#completedTasks.values()) {\n if (task.owner === owner) {\n completed++;\n }\n }\n\n let failed = 0;\n for (const taskOwner of this.#failedKeys.values()) {\n if (taskOwner === owner) {\n failed++;\n }\n }\n\n return { queued, active, completed, failed };\n }\n\n /**\n * Dispose the scheduler - abort all in-flight work.\n */\n dispose(): void {\n // Suppress in-flight task rejections before aborting to avoid unhandled\n // rejection events from the synchronous abort signal firing.\n for (const activeTask of this.#activeTasks.values()) {\n activeTask.promise.catch(() => {});\n }\n this.#abortController.abort();\n this.#queue = [];\n this.#activeTasks.clear();\n this.#completedTasks.clear();\n this.#failedKeys.clear();\n }\n\n /**\n * Revive a disposed scheduler so it can accept new tasks after the host\n * element is reconnected to the DOM (e.g. workbench reparenting).\n */\n revive(): void {\n if (!this.#abortController.signal.aborted) return;\n this.#abortController = new AbortController();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"QualityUpgradeScheduler.js","names":["#requestFrameRender","#maxConcurrent","#abortController","#queue","#activeTasks","#completedTasks","#failedKeys","#processQueue","#startTask"],"sources":["../../src/preview/QualityUpgradeScheduler.ts"],"mappings":"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"}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { LRUCache } from "../utils/LRUCache.js";
|
|
2
|
-
|
|
3
2
|
//#region src/preview/RenderContext.ts
|
|
4
3
|
/**
|
|
4
|
+
* RenderContext manages scoped caches for the rendering pipeline.
|
|
5
|
+
*
|
|
6
|
+
* Used during foreignObject serialization to cache:
|
|
7
|
+
* - Video frames by source timestamp (useful for freeze frames, slow-mo)
|
|
8
|
+
* - Static element canvases by element identity + renderVersion
|
|
9
|
+
*
|
|
10
|
+
* The context should be created at the start of a render operation
|
|
11
|
+
* and disposed when the render completes (success or failure).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
5
14
|
* Check if an element has a renderVersion property.
|
|
6
15
|
*/
|
|
7
16
|
function hasRenderVersion(element) {
|
|
@@ -205,7 +214,7 @@ var RenderContext = class {
|
|
|
205
214
|
return this.#videoFrameCache.size;
|
|
206
215
|
}
|
|
207
216
|
};
|
|
208
|
-
|
|
209
217
|
//#endregion
|
|
210
218
|
export { RenderContext };
|
|
219
|
+
|
|
211
220
|
//# sourceMappingURL=RenderContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderContext.js","names":["#canvasCache","#videoFrameCache","#disposed","#metrics","#getCanvasCacheKey","#getVideoFrameCacheKey","#documentStylesCache"],"sources":["../../src/preview/RenderContext.ts"],"sourcesContent":["/**\n * RenderContext manages scoped caches for the rendering pipeline.\n *\n * Used during foreignObject serialization to cache:\n * - Video frames by source timestamp (useful for freeze frames, slow-mo)\n * - Static element canvases by element identity + renderVersion\n *\n * The context should be created at the start of a render operation\n * and disposed when the render completes (success or failure).\n */\n\nimport { LRUCache } from \"../utils/LRUCache.js\";\nimport type { EFVideo } from \"../elements/EFVideo.js\";\n\n/**\n * Check if an element has a renderVersion property.\n */\nfunction hasRenderVersion(element: Element): element is Element & { renderVersion: number } {\n return \"renderVersion\" in element && typeof (element as any).renderVersion === \"number\";\n}\n\n/**\n * Module-level counter for generating unique element IDs.\n * This ensures uniqueness across all RenderContext instances.\n */\nlet nextElementId = 1;\n\n/**\n * WeakMap to store unique IDs for elements.\n * Using WeakMap ensures we don't prevent garbage collection of elements.\n * The ID is stable for the lifetime of the element.\n */\nconst elementUniqueIds = new WeakMap<Element, number>();\n\n/**\n * Get or create a unique ID for an element.\n * This guarantees uniqueness even for elements with the same id attribute\n * or no id attribute at all.\n */\nfunction getElementUniqueId(element: Element): number {\n let id = elementUniqueIds.get(element);\n if (id === undefined) {\n id = nextElementId++;\n elementUniqueIds.set(element, id);\n }\n return id;\n}\n\n/**\n * Result of capturing a video frame.\n */\nexport interface CapturedFrame {\n dataUrl: string;\n width: number;\n height: number;\n}\n\n/**\n * Options for creating a RenderContext.\n */\nexport interface RenderContextOptions {\n /** Maximum number of canvas dataURLs to cache (default: 50) */\n maxCanvasCacheSize?: number;\n /** Maximum number of video frame dataURLs to cache (default: 100) */\n maxVideoFrameCacheSize?: number;\n}\n\n/**\n * RenderContext provides scoped caching for render operations.\n *\n * Create at the start of a render, dispose when complete:\n * ```typescript\n * const context = new RenderContext();\n * try {\n * // ... render operations\n * } finally {\n * context.dispose();\n * }\n * ```\n */\nexport class RenderContext {\n /** Cache for static element canvases (ef-image, ef-waveform) */\n #canvasCache: LRUCache<string, string>;\n\n /** Cache for video frames by source timestamp */\n #videoFrameCache: LRUCache<string, CapturedFrame>;\n\n /** Cache for document styles (computed once per render session) */\n #documentStylesCache: string | null = null;\n\n /** Whether this context has been disposed */\n #disposed = false;\n\n /** Metrics for monitoring cache effectiveness */\n #metrics = {\n canvasCacheHits: 0,\n canvasCacheMisses: 0,\n videoFrameCacheHits: 0,\n videoFrameCacheMisses: 0,\n };\n\n constructor(options: RenderContextOptions = {}) {\n const { maxCanvasCacheSize = 50, maxVideoFrameCacheSize = 100 } = options;\n this.#canvasCache = new LRUCache(maxCanvasCacheSize);\n this.#videoFrameCache = new LRUCache(maxVideoFrameCacheSize);\n }\n\n /**\n * Check if the context has been disposed.\n */\n get disposed(): boolean {\n return this.#disposed;\n }\n\n /**\n * Get cache metrics for monitoring.\n */\n get metrics() {\n return { ...this.#metrics };\n }\n\n // ============================================================================\n // Static Element Cache (ef-image, ef-waveform)\n // ============================================================================\n\n /**\n * Generate a cache key for a static element.\n * Uses a unique element ID (via WeakMap) to ensure uniqueness even if\n * multiple elements have the same id attribute.\n * Returns null if the element doesn't support caching (no renderVersion).\n */\n #getCanvasCacheKey(element: Element): string | null {\n if (!hasRenderVersion(element)) {\n return null;\n }\n // Use unique element ID + render version for guaranteed uniqueness\n const uniqueId = getElementUniqueId(element);\n return `canvas:${uniqueId}:${element.renderVersion}`;\n }\n\n /**\n * Get a cached dataURL for a static element.\n * Returns undefined if not cached or element doesn't support caching.\n */\n getCachedCanvasDataUrl(element: Element): string | undefined {\n if (this.#disposed) return undefined;\n\n const key = this.#getCanvasCacheKey(element);\n if (!key) return undefined;\n\n const cached = this.#canvasCache.get(key);\n if (cached) {\n this.#metrics.canvasCacheHits++;\n } else {\n this.#metrics.canvasCacheMisses++;\n }\n return cached;\n }\n\n /**\n * Cache a dataURL for a static element.\n * Does nothing if the element doesn't support caching.\n */\n setCachedCanvasDataUrl(element: Element, dataUrl: string): void {\n if (this.#disposed) return;\n\n const key = this.#getCanvasCacheKey(element);\n if (key) {\n this.#canvasCache.set(key, dataUrl);\n }\n }\n\n // ============================================================================\n // Video Frame Cache\n // ============================================================================\n\n /**\n * Generate a cache key for a video frame.\n * Uses a unique element ID (via WeakMap) to ensure uniqueness even if\n * multiple videos have the same id attribute.\n */\n #getVideoFrameCacheKey(videoElement: Element, sourceTimeMs: number): string {\n const uniqueId = getElementUniqueId(videoElement);\n // Round to nearest ms to avoid floating point issues\n const roundedTime = Math.round(sourceTimeMs);\n return `video:${uniqueId}:${roundedTime}`;\n }\n\n /**\n * Get a cached video frame.\n * Returns undefined if not cached.\n */\n getCachedVideoFrame(videoElement: Element, sourceTimeMs: number): CapturedFrame | undefined {\n if (this.#disposed) return undefined;\n\n const key = this.#getVideoFrameCacheKey(videoElement, sourceTimeMs);\n const cached = this.#videoFrameCache.get(key);\n if (cached) {\n this.#metrics.videoFrameCacheHits++;\n } else {\n this.#metrics.videoFrameCacheMisses++;\n }\n return cached;\n }\n\n /**\n * Cache a video frame.\n */\n setCachedVideoFrame(videoElement: Element, sourceTimeMs: number, frame: CapturedFrame): void {\n if (this.#disposed) return;\n\n const key = this.#getVideoFrameCacheKey(videoElement, sourceTimeMs);\n this.#videoFrameCache.set(key, frame);\n }\n\n /**\n * Convenience method to get or capture a video frame.\n * Checks cache first, then captures if not cached.\n *\n * @param video - The ef-video element\n * @param sourceTimeMs - Source media timestamp\n * @param options - Capture options including quality and signal\n * @returns The captured frame data\n */\n async getOrCaptureVideoFrame(\n video: EFVideo,\n sourceTimeMs: number,\n options: {\n quality?: \"auto\" | \"scrub\" | \"main\";\n signal?: AbortSignal;\n } = {},\n ): Promise<CapturedFrame> {\n // Check cache first\n const cached = this.getCachedVideoFrame(video, sourceTimeMs);\n if (cached) {\n return cached;\n }\n\n // Capture frame using direct API\n const frame = await video.captureFrameAtSourceTime(sourceTimeMs, options);\n\n // Cache for future use\n this.setCachedVideoFrame(video, sourceTimeMs, frame);\n\n return frame;\n }\n\n // ============================================================================\n // Document Styles Cache\n // ============================================================================\n\n /**\n * Get cached document styles.\n * Returns undefined if not cached.\n */\n getCachedDocumentStyles(): string | undefined {\n if (this.#disposed) return undefined;\n return this.#documentStylesCache ?? undefined;\n }\n\n /**\n * Cache document styles.\n */\n setCachedDocumentStyles(styles: string): void {\n if (this.#disposed) return;\n this.#documentStylesCache = styles;\n }\n\n // ============================================================================\n // Cleanup\n // ============================================================================\n\n /**\n * Dispose the context and clear all caches.\n * Should be called when rendering is complete.\n */\n dispose(): void {\n if (this.#disposed) return;\n\n this.#canvasCache.clear();\n this.#videoFrameCache.clear();\n this.#documentStylesCache = null;\n this.#disposed = true;\n }\n\n /**\n * Symbol.dispose implementation for use with the `using` keyword.\n *\n * @example\n * ```typescript\n * using context = new RenderContext();\n * // ... render operations\n * // context is automatically disposed when scope exits\n * ```\n */\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n /**\n * Get the current size of the canvas cache.\n */\n get canvasCacheSize(): number {\n return this.#canvasCache.size;\n }\n\n /**\n * Get the current size of the video frame cache.\n */\n get videoFrameCacheSize(): number {\n return this.#videoFrameCache.size;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RenderContext.js","names":["#canvasCache","#videoFrameCache","#disposed","#metrics","#getCanvasCacheKey","#getVideoFrameCacheKey","#documentStylesCache"],"sources":["../../src/preview/RenderContext.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderProfiler.js","names":[
|
|
1
|
+
{"version":3,"file":"RenderProfiler.js","names":[],"sources":["../../src/preview/RenderProfiler.ts"],"mappings":";;;;;;AAMA,MAAM,0BAA0B;;AAGhC,MAAM,6BAA6B;;;;;AAqBnC,IAAa,iBAAb,MAA4B;;sBACH;sBACA;yBACG;kBAEQ;GAChC,OAAO;GACP,MAAM;GACN,YAAY;GACZ,cAAc;GACd,QAAQ;GACR,WAAW;GACX,QAAQ;GACR,WAAW;GACX,SAAS;GACV;;;;;CAKD,QAAc;AACZ,OAAK,eAAe;AACpB,OAAK,eAAe;AACpB,OAAK,kBAAkB;AAEvB,OAAK,MAAM,OAAO,OAAO,KAAK,KAAK,SAAS,CAC1C,MAAK,SAAS,OAAO;;;;;CAOzB,IAAI,cAAsB;AACxB,SAAO,KAAK;;;;;CAMd,uBAA6B;AAC3B,OAAK;;;;;CAMP,QAAQ,OAA4B,IAAkB;AACpD,OAAK,SAAS,UAAU;;;;;CAM1B,KAAQ,OAA4B,IAAgB;EAClD,MAAM,QAAQ,YAAY,KAAK;EAC/B,MAAM,SAAS,IAAI;AACnB,OAAK,SAAS,UAAU,YAAY,KAAK,GAAG;AAC5C,SAAO;;;;;CAMT,MAAM,UAAa,OAA4B,IAAkC;EAC/E,MAAM,QAAQ,YAAY,KAAK;EAC/B,MAAM,SAAS,MAAM,IAAI;AACzB,OAAK,SAAS,UAAU,YAAY,KAAK,GAAG;AAC5C,SAAO;;;;;CAMT,gBAAgB,aAAqB,yBAAkC;EACrE,MAAM,MAAM,YAAY,KAAK;AAC7B,MAAI,MAAM,KAAK,eAAe,YAAY;AACxC,QAAK,eAAe;AACpB,UAAO;;AAET,SAAO;;;;;CAMT,sBAAsB,WAAmB,4BAAqC;AAC5E,MAAI,KAAK,eAAe,KAAK,mBAAmB,UAAU;AACxD,QAAK,kBAAkB,KAAK;AAC5B,UAAO;;AAET,SAAO;;;;;CAMT,cAAc,YAAoB,GAAY;AAC5C,SAAO,KAAK,eAAe;;;;;CAM7B,UAAkB;EAChB,MAAM,IAAI,KAAK;EACf,MAAM,QAAkB,EAAE;AAE1B,MAAI,EAAE,QAAQ,EAAG,OAAM,KAAK,SAAS,EAAE,MAAM,QAAQ,EAAE,CAAC,IAAI;AAC5D,MAAI,EAAE,OAAO,EAAG,OAAM,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,CAAC,IAAI;AACzD,MAAI,EAAE,aAAa,EAAG,OAAM,KAAK,cAAc,EAAE,WAAW,QAAQ,EAAE,CAAC,IAAI;AAC3E,MAAI,EAAE,eAAe,EAAG,OAAM,KAAK,gBAAgB,EAAE,aAAa,QAAQ,EAAE,CAAC,IAAI;AACjF,MAAI,EAAE,SAAS,EAAG,OAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,EAAE,CAAC,IAAI;AAC/D,MAAI,EAAE,YAAY,EAAG,OAAM,KAAK,aAAa,EAAE,UAAU,QAAQ,EAAE,CAAC,IAAI;AACxE,MAAI,EAAE,SAAS,EAAG,OAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,EAAE,CAAC,IAAI;AAC/D,MAAI,EAAE,YAAY,EAAG,OAAM,KAAK,aAAa,EAAE,UAAU,QAAQ,EAAE,CAAC,IAAI;AACxE,MAAI,EAAE,UAAU,EAAG,OAAM,KAAK,WAAW,EAAE,QAAQ,QAAQ,EAAE,CAAC,IAAI;AAElE,SAAO,MAAM,KAAK,KAAK;;;;;CAMzB,aAAsC;AACpC,SAAO,EAAE,GAAG,KAAK,UAAU;;;;;;;AAQ/B,MAAa,kBAAkB,IAAI,gBAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderStats.js","names":[],"sources":["../../src/preview/RenderStats.ts"],"
|
|
1
|
+
{"version":3,"file":"RenderStats.js","names":[],"sources":["../../src/preview/RenderStats.ts"],"mappings":";;;;;;;;;;;;;;;AA8CA,IAAa,cAAb,MAAyB;CAWvB,YAAY,iBAA4C;qBAPxB,EAAE;wBACC,EAAE;uBACb;6BAEe;8BACC;AAGtC,OAAK,kBAAkB;;;;;;;;;;CAWzB,YAAY,YAAoB,WAAmB,UAAyB;AAE1E,OAAK,YAAY,KAAK,WAAW;AACjC,MAAI,KAAK,YAAY,SAAS,KAAK,oBACjC,MAAK,YAAY,OAAO;AAI1B,MAAI,KAAK,gBAAgB,GAAG;GAC1B,MAAM,WAAW,YAAY,KAAK;AAClC,QAAK,eAAe,KAAK,SAAS;AAClC,OAAI,KAAK,eAAe,SAAS,KAAK,oBACpC,MAAK,eAAe,OAAO;;AAG/B,OAAK,gBAAgB;AAGrB,MAAI,CAAC,SACH,MAAK,gBAAgB,YAAY,YAAY,UAAU;;;;;;;;;;CAY3D,SACE,aACA,cACA,kBAAiC,MAClB;EAEf,MAAM,gBACJ,KAAK,YAAY,SAAS,IACtB,KAAK,YAAY,QAAQ,GAAG,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,YAAY,SAC/D;EAGN,MAAM,mBACJ,KAAK,eAAe,SAAS,IACzB,KAAK,eAAe,QAAQ,GAAG,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,eAAe,SACrE;EACN,MAAM,MAAM,mBAAmB,IAAI,MAAO,mBAAmB;EAG7D,MAAM,WAAW,kBAAkB,OAAO,KAAK,uBAAuB,gBAAgB;EAGtF,MAAM,eAAe,KAAK,gBAAgB,UAAU;AAEpD,SAAO;GACL;GACA;GACA;GACA,eAAe,aAAa;GAC5B,iBAAiB,aAAa;GAC9B;GACA;GACA;GACA,uBAAuB,aAAa;GACpC,YAAY,aAAa;GACzB,cAAc,aAAa;GAC5B;;;;;;CAOH,QAAc;AACZ,OAAK,cAAc,EAAE;AACrB,OAAK,iBAAiB,EAAE;AACxB,OAAK,gBAAgB"}
|
|
@@ -3,8 +3,13 @@ import { WorkerPool } from "../workers/WorkerPool.js";
|
|
|
3
3
|
import { getEncoderWorkerUrl } from "../workers/encoderWorkerInline.js";
|
|
4
4
|
import { encodeCanvasOnMainThread } from "./mainThreadEncoder.js";
|
|
5
5
|
import { encodeCanvasInWorker } from "./workerEncoder.js";
|
|
6
|
-
|
|
7
6
|
//#region src/preview/encoding/canvasEncoder.ts
|
|
7
|
+
/**
|
|
8
|
+
* Canvas encoding orchestration with worker pool support.
|
|
9
|
+
*
|
|
10
|
+
* Supports caching via RenderContext:
|
|
11
|
+
* - For ef-image/ef-waveform: caches by element + renderVersion
|
|
12
|
+
*/
|
|
8
13
|
let _workerPool = null;
|
|
9
14
|
let _workerPoolWarningLogged = false;
|
|
10
15
|
/**
|
|
@@ -110,7 +115,7 @@ async function encodeCanvasesInParallel(canvases, options = {}) {
|
|
|
110
115
|
const encodingTasks = canvases.map(encodeCanvas);
|
|
111
116
|
return (await Promise.all(encodingTasks)).filter((r) => r !== null);
|
|
112
117
|
}
|
|
113
|
-
|
|
114
118
|
//#endregion
|
|
115
119
|
export { encodeCanvasesInParallel };
|
|
120
|
+
|
|
116
121
|
//# sourceMappingURL=canvasEncoder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvasEncoder.js","names":[
|
|
1
|
+
{"version":3,"file":"canvasEncoder.js","names":[],"sources":["../../../src/preview/encoding/canvasEncoder.ts"],"mappings":";;;;;;;;;;;;AAeA,IAAI,cAAiC;AACrC,IAAI,2BAA2B;;;;;AAM/B,SAAS,gBAAmC;AAC1C,KAAI,YACF,QAAO;AAIT,KACE,OAAO,WAAW,eAClB,OAAO,oBAAoB,eAC3B,OAAO,sBAAsB,aAC7B;AACA,MAAI,CAAC,0BAA0B;AAC7B,8BAA2B;AAC3B,UAAO,KACL,2FACD;;AAEH,SAAO;;AAGT,KAAI;AAKF,gBAAc,IAAI,WAFA,qBAAqB,CAEA;AAGvC,MAAI,CAAC,YAAY,aAAa,EAAE;GAC9B,MAAM,SACJ,YAAY,gBAAgB,IACxB,kDACA;AACN,iBAAc;AACd,OAAI,CAAC,0BAA0B;AAC7B,+BAA2B;AAC3B,WAAO,KACL,sDAAsD,OAAO,+BAC9D;;;UAGE,OAAO;AACd,gBAAc;AACd,MAAI,CAAC,0BAA0B;AAC7B,8BAA2B;GAC3B,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,UAAO,KACL,iDAAiD,aAAa,+BAC/D;;;AAIL,QAAO;;;;;;;;;;;;;AAcT,eAAsB,yBACpB,UACA,UAA+B,EAAE,EACF;CAC/B,MAAM,EAAE,OAAO,cAAc,GAAG,eAAe,cAAc;CAC7D,MAAM,aAAa,eAAe;CAGlC,MAAM,eAAe,OAAO,WAAkE;AAC5F,MAAI;AACF,OAAI,OAAO,UAAU,KAAK,OAAO,WAAW,EAC1C,QAAO;GAGT,MAAM,gBAAgB,OAAO,QAAQ,kBAAkB;GACvD,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAG5C,OAAI,iBAAiB,eAAe;IAClC,MAAM,gBAAgB,cAAc,uBAAuB,cAAc;AACzE,QAAI,cACF,QAAO;KAAE;KAAQ,SAAS;KAAe;KAAe;;GAK5D,IAAI,eAAe;AAGnB,OAAI,cAAc,GAAG;IACnB,MAAM,cAAc,KAAK,MAAM,OAAO,QAAQ,YAAY;IAC1D,MAAM,eAAe,KAAK,MAAM,OAAO,SAAS,YAAY;IAC5D,MAAM,eAAe,SAAS,cAAc,SAAS;AACrD,iBAAa,QAAQ;AACrB,iBAAa,SAAS;IACtB,MAAM,YAAY,aAAa,WAAW,KAAK;AAC/C,QAAI,WAAW;AACb,eAAU,UAAU,QAAQ,GAAG,GAAG,aAAa,aAAa;AAC5D,oBAAe;;;GAInB,IAAI;AAEJ,OAAI,WAEF,WAAU,MAAM,WAAW,SAAS,WAClC,qBAAqB,QAAQ,cAAc,cAAc,CAC1D;QACI;IAEL,MAAM,UAAU,yBAAyB,cAAc,YAAY;AACnE,QAAI,CAAC,QAAS,QAAO;AACrB,cAAU,QAAQ;;AAIpB,OAAI,iBAAiB,cACnB,eAAc,uBAAuB,eAAe,QAAQ;AAG9D,UAAO;IAAE;IAAQ;IAAS;IAAe;WAClC,OAAO;AAEd,UAAO,KAAK,uEAAuE,MAAM;GACzF,MAAM,UAAU,yBAAyB,QAAQ,YAAY;AAC7D,OAAI,SAAS;AACX,WAAO,KAAK,iDAAiD;AAC7D,WAAO;KAAE;KAAQ,GAAG;KAAS;;AAI/B,UAAO,KAAK,sEAAsE,MAAM;AACxF,UAAO;;;CAKX,MAAM,gBAAgB,SAAS,IAAI,aAAa;AAGhD,SAFuB,MAAM,QAAQ,IAAI,cAAc,EACnB,QAAQ,MAA+B,MAAM,KAAK"}
|