@editframe/elements 0.33.0-beta → 0.34.6-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/dist/EF_FRAMEGEN.js +5 -3
  2. package/dist/EF_FRAMEGEN.js.map +1 -1
  3. package/dist/_virtual/{_@oxc-project_runtime@0.94.0 → _@oxc-project_runtime@0.95.0}/helpers/decorate.js +1 -1
  4. package/dist/canvas/EFCanvas.d.ts +7 -4
  5. package/dist/canvas/EFCanvas.js +1 -1
  6. package/dist/canvas/EFCanvasItem.d.ts +4 -4
  7. package/dist/canvas/EFCanvasItem.js +1 -1
  8. package/dist/canvas/overlays/SelectionOverlay.d.ts +95 -0
  9. package/dist/canvas/overlays/SelectionOverlay.js +1 -1
  10. package/dist/canvas/selection/SelectionController.js +7 -11
  11. package/dist/canvas/selection/SelectionController.js.map +1 -1
  12. package/dist/elements/EFAudio.d.ts +25 -7
  13. package/dist/elements/EFAudio.js +31 -61
  14. package/dist/elements/EFAudio.js.map +1 -1
  15. package/dist/elements/EFCaptions.d.ts +65 -52
  16. package/dist/elements/EFCaptions.js +186 -400
  17. package/dist/elements/EFCaptions.js.map +1 -1
  18. package/dist/elements/EFImage.d.ts +34 -6
  19. package/dist/elements/EFImage.js +114 -79
  20. package/dist/elements/EFImage.js.map +1 -1
  21. package/dist/elements/EFMedia/AssetIdMediaEngine.js +17 -17
  22. package/dist/elements/EFMedia/AssetIdMediaEngine.js.map +1 -1
  23. package/dist/elements/EFMedia/AssetMediaEngine.js +41 -25
  24. package/dist/elements/EFMedia/AssetMediaEngine.js.map +1 -1
  25. package/dist/elements/EFMedia/BaseMediaEngine.js +4 -4
  26. package/dist/elements/EFMedia/BaseMediaEngine.js.map +1 -1
  27. package/dist/elements/EFMedia/BufferedSeekingInput.js +1 -1
  28. package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -1
  29. package/dist/elements/EFMedia/JitMediaEngine.js +31 -17
  30. package/dist/elements/EFMedia/JitMediaEngine.js.map +1 -1
  31. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +3 -3
  32. package/dist/elements/EFMedia/shared/AudioSpanUtils.js.map +1 -1
  33. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +17 -9
  34. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -1
  35. package/dist/elements/EFMedia.d.ts +66 -20
  36. package/dist/elements/EFMedia.js +412 -30
  37. package/dist/elements/EFMedia.js.map +1 -1
  38. package/dist/elements/EFPanZoom.d.ts +4 -4
  39. package/dist/elements/EFPanZoom.js +1 -1
  40. package/dist/elements/EFSourceMixin.js +43 -15
  41. package/dist/elements/EFSourceMixin.js.map +1 -1
  42. package/dist/elements/EFSurface.d.ts +23 -10
  43. package/dist/elements/EFSurface.js +64 -22
  44. package/dist/elements/EFSurface.js.map +1 -1
  45. package/dist/elements/EFTemporal.d.ts +8 -2
  46. package/dist/elements/EFTemporal.js +42 -31
  47. package/dist/elements/EFTemporal.js.map +1 -1
  48. package/dist/elements/EFText.d.ts +5 -4
  49. package/dist/elements/EFText.js +11 -2
  50. package/dist/elements/EFText.js.map +1 -1
  51. package/dist/elements/EFTextSegment.d.ts +4 -4
  52. package/dist/elements/EFTextSegment.js +1 -1
  53. package/dist/elements/EFThumbnailStrip.d.ts +4 -4
  54. package/dist/elements/EFThumbnailStrip.js +1 -1
  55. package/dist/elements/EFTimegroup.d.ts +22 -8
  56. package/dist/elements/EFTimegroup.js +203 -115
  57. package/dist/elements/EFTimegroup.js.map +1 -1
  58. package/dist/elements/EFVideo.d.ts +57 -20
  59. package/dist/elements/EFVideo.js +324 -72
  60. package/dist/elements/EFVideo.js.map +1 -1
  61. package/dist/elements/EFWaveform.d.ts +33 -7
  62. package/dist/elements/EFWaveform.js +103 -59
  63. package/dist/elements/EFWaveform.js.map +1 -1
  64. package/dist/elements/renderTemporalAudio.js +14 -3
  65. package/dist/elements/renderTemporalAudio.js.map +1 -1
  66. package/dist/getRenderInfo.d.ts +2 -2
  67. package/dist/gui/ContextMixin.js +1 -1
  68. package/dist/gui/Controllable.d.ts +2 -0
  69. package/dist/gui/EFActiveRootTemporal.d.ts +4 -4
  70. package/dist/gui/EFActiveRootTemporal.js +1 -1
  71. package/dist/gui/EFConfiguration.d.ts +4 -4
  72. package/dist/gui/EFConfiguration.js +1 -1
  73. package/dist/gui/EFControls.d.ts +2 -2
  74. package/dist/gui/EFControls.js +1 -1
  75. package/dist/gui/EFDial.d.ts +4 -4
  76. package/dist/gui/EFDial.js +1 -1
  77. package/dist/gui/EFFilmstrip.d.ts +3 -2
  78. package/dist/gui/EFFilmstrip.js +1 -1
  79. package/dist/gui/EFFitScale.js +1 -1
  80. package/dist/gui/EFFocusOverlay.d.ts +4 -4
  81. package/dist/gui/EFFocusOverlay.js +1 -1
  82. package/dist/gui/EFOverlayItem.d.ts +4 -4
  83. package/dist/gui/EFOverlayItem.js +1 -1
  84. package/dist/gui/EFOverlayLayer.d.ts +4 -4
  85. package/dist/gui/EFOverlayLayer.js +1 -1
  86. package/dist/gui/EFPause.d.ts +4 -4
  87. package/dist/gui/EFPause.js +1 -1
  88. package/dist/gui/EFPlay.d.ts +4 -4
  89. package/dist/gui/EFPlay.js +1 -1
  90. package/dist/gui/EFPreview.d.ts +4 -4
  91. package/dist/gui/EFPreview.js +1 -1
  92. package/dist/gui/EFResizableBox.d.ts +4 -4
  93. package/dist/gui/EFResizableBox.js +1 -1
  94. package/dist/gui/EFScrubber.d.ts +4 -4
  95. package/dist/gui/EFScrubber.js +1 -1
  96. package/dist/gui/EFTimeDisplay.d.ts +4 -4
  97. package/dist/gui/EFTimeDisplay.js +1 -1
  98. package/dist/gui/EFTimelineRuler.d.ts +4 -4
  99. package/dist/gui/EFTimelineRuler.js +1 -1
  100. package/dist/gui/EFToggleLoop.d.ts +4 -4
  101. package/dist/gui/EFToggleLoop.js +1 -1
  102. package/dist/gui/EFTogglePlay.d.ts +4 -4
  103. package/dist/gui/EFTogglePlay.js +1 -1
  104. package/dist/gui/EFTransformHandles.d.ts +4 -4
  105. package/dist/gui/EFTransformHandles.js +1 -1
  106. package/dist/gui/EFWorkbench.d.ts +5 -4
  107. package/dist/gui/EFWorkbench.js +1 -1
  108. package/dist/gui/PlaybackController.d.ts +10 -2
  109. package/dist/gui/PlaybackController.js +52 -30
  110. package/dist/gui/PlaybackController.js.map +1 -1
  111. package/dist/gui/TWMixin.js +1 -1
  112. package/dist/gui/TWMixin.js.map +1 -1
  113. package/dist/gui/TargetOrContextMixin.js +1 -1
  114. package/dist/gui/hierarchy/EFHierarchy.d.ts +4 -4
  115. package/dist/gui/hierarchy/EFHierarchy.js +1 -1
  116. package/dist/gui/hierarchy/EFHierarchyItem.d.ts +3 -3
  117. package/dist/gui/hierarchy/EFHierarchyItem.js +1 -1
  118. package/dist/gui/timeline/EFTimeline.d.ts +6 -2
  119. package/dist/gui/timeline/EFTimeline.js +1 -1
  120. package/dist/gui/timeline/EFTimelineRow.d.ts +57 -0
  121. package/dist/gui/timeline/EFTimelineRow.js +1 -1
  122. package/dist/gui/timeline/TrimHandles.d.ts +4 -4
  123. package/dist/gui/timeline/TrimHandles.js +1 -1
  124. package/dist/gui/timeline/tracks/AudioTrack.d.ts +2 -0
  125. package/dist/gui/timeline/tracks/AudioTrack.js +1 -1
  126. package/dist/gui/timeline/tracks/CaptionsTrack.d.ts +58 -0
  127. package/dist/gui/timeline/tracks/CaptionsTrack.js +1 -1
  128. package/dist/gui/timeline/tracks/HTMLTrack.d.ts +13 -0
  129. package/dist/gui/timeline/tracks/HTMLTrack.js +1 -1
  130. package/dist/gui/timeline/tracks/ImageTrack.d.ts +14 -0
  131. package/dist/gui/timeline/tracks/ImageTrack.js +1 -1
  132. package/dist/gui/timeline/tracks/TextTrack.d.ts +26 -0
  133. package/dist/gui/timeline/tracks/TextTrack.js +1 -1
  134. package/dist/gui/timeline/tracks/TimegroupTrack.d.ts +47 -0
  135. package/dist/gui/timeline/tracks/TimegroupTrack.js +4 -12
  136. package/dist/gui/timeline/tracks/TimegroupTrack.js.map +1 -1
  137. package/dist/gui/timeline/tracks/TrackItem.d.ts +81 -0
  138. package/dist/gui/timeline/tracks/TrackItem.js +1 -1
  139. package/dist/gui/timeline/tracks/VideoTrack.d.ts +25 -0
  140. package/dist/gui/timeline/tracks/VideoTrack.js +1 -1
  141. package/dist/gui/timeline/tracks/WaveformTrack.d.ts +14 -0
  142. package/dist/gui/timeline/tracks/WaveformTrack.js +1 -1
  143. package/dist/gui/timeline/tracks/ensureTrackItemInit.d.ts +1 -0
  144. package/dist/gui/timeline/tracks/preloadTracks.d.ts +9 -0
  145. package/dist/gui/tree/EFTree.d.ts +5 -4
  146. package/dist/gui/tree/EFTree.js +1 -1
  147. package/dist/gui/tree/EFTreeItem.d.ts +4 -4
  148. package/dist/gui/tree/EFTreeItem.js +1 -1
  149. package/dist/index.d.ts +4 -1
  150. package/dist/preview/AdaptiveResolutionTracker.js +6 -14
  151. package/dist/preview/AdaptiveResolutionTracker.js.map +1 -1
  152. package/dist/preview/FrameController.d.ts +123 -0
  153. package/dist/preview/FrameController.js +216 -0
  154. package/dist/preview/FrameController.js.map +1 -0
  155. package/dist/preview/RenderContext.d.ts +1 -0
  156. package/dist/preview/RenderContext.js +193 -0
  157. package/dist/preview/RenderContext.js.map +1 -0
  158. package/dist/preview/encoding/canvasEncoder.js +166 -0
  159. package/dist/preview/encoding/canvasEncoder.js.map +1 -0
  160. package/dist/preview/encoding/mainThreadEncoder.js +39 -0
  161. package/dist/preview/encoding/mainThreadEncoder.js.map +1 -0
  162. package/dist/preview/encoding/types.d.ts +1 -0
  163. package/dist/preview/encoding/workerEncoder.js +58 -0
  164. package/dist/preview/encoding/workerEncoder.js.map +1 -0
  165. package/dist/preview/logger.js +41 -0
  166. package/dist/preview/logger.js.map +1 -0
  167. package/dist/preview/previewTypes.js +11 -10
  168. package/dist/preview/previewTypes.js.map +1 -1
  169. package/dist/preview/renderTimegroupPreview.js +259 -236
  170. package/dist/preview/renderTimegroupPreview.js.map +1 -1
  171. package/dist/preview/renderTimegroupToCanvas.d.ts +5 -0
  172. package/dist/preview/renderTimegroupToCanvas.js +100 -489
  173. package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
  174. package/dist/preview/renderTimegroupToVideo.d.ts +1 -0
  175. package/dist/preview/renderTimegroupToVideo.js +80 -22
  176. package/dist/preview/renderTimegroupToVideo.js.map +1 -1
  177. package/dist/preview/renderers.js.map +1 -1
  178. package/dist/preview/rendering/inlineImages.js +56 -0
  179. package/dist/preview/rendering/inlineImages.js.map +1 -0
  180. package/dist/preview/rendering/renderToImage.d.ts +1 -0
  181. package/dist/preview/rendering/renderToImage.js +120 -0
  182. package/dist/preview/rendering/renderToImage.js.map +1 -0
  183. package/dist/preview/rendering/renderToImageForeignObject.js +135 -0
  184. package/dist/preview/rendering/renderToImageForeignObject.js.map +1 -0
  185. package/dist/preview/rendering/renderToImageNative.d.ts +1 -0
  186. package/dist/preview/rendering/renderToImageNative.js +129 -0
  187. package/dist/preview/rendering/renderToImageNative.js.map +1 -0
  188. package/dist/preview/rendering/svgSerializer.js +43 -0
  189. package/dist/preview/rendering/svgSerializer.js.map +1 -0
  190. package/dist/preview/rendering/types.d.ts +2 -0
  191. package/dist/preview/statsTrackingStrategy.js +3 -1
  192. package/dist/preview/statsTrackingStrategy.js.map +1 -1
  193. package/dist/preview/workers/WorkerPool.js +8 -57
  194. package/dist/preview/workers/WorkerPool.js.map +1 -1
  195. package/dist/render/EFRenderAPI.d.ts +35 -0
  196. package/dist/render/EFRenderAPI.js +1 -0
  197. package/dist/render/EFRenderAPI.js.map +1 -1
  198. package/dist/sandbox/PlaybackControls.d.ts +1 -0
  199. package/dist/sandbox/ScenarioRunner.d.ts +1 -0
  200. package/dist/sandbox/defineSandbox.d.ts +1 -0
  201. package/dist/sandbox/index.d.ts +3 -0
  202. package/dist/style.css +3 -0
  203. package/dist/transcoding/types/index.d.ts +6 -3
  204. package/package.json +2 -3
  205. package/test/EFVideo.framegen.browsertest.ts +8 -1
  206. package/test/profilingPlugin.ts +1 -3
  207. package/test/setup.ts +23 -1
  208. package/dist/EF_INTERACTIVE.js +0 -7
  209. package/dist/EF_INTERACTIVE.js.map +0 -1
  210. package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +0 -50
  211. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +0 -12
  212. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +0 -104
  213. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js.map +0 -1
  214. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +0 -168
  215. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js.map +0 -1
  216. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +0 -46
  217. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js.map +0 -1
  218. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +0 -49
  219. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js.map +0 -1
  220. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +0 -30
  221. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js.map +0 -1
  222. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +0 -49
  223. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js.map +0 -1
  224. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +0 -47
  225. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js.map +0 -1
  226. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +0 -140
  227. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js.map +0 -1
  228. package/dist/elements/EFMedia/shared/BufferUtils.d.ts +0 -13
  229. package/dist/elements/EFMedia/shared/BufferUtils.js +0 -86
  230. package/dist/elements/EFMedia/shared/BufferUtils.js.map +0 -1
  231. package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +0 -17
  232. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +0 -90
  233. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js.map +0 -1
  234. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +0 -80
  235. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js.map +0 -1
  236. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js +0 -49
  237. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js.map +0 -1
  238. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +0 -58
  239. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js.map +0 -1
  240. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +0 -71
  241. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js.map +0 -1
  242. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js +0 -52
  243. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js.map +0 -1
  244. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +0 -50
  245. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js.map +0 -1
  246. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +0 -109
  247. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js.map +0 -1
  248. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +0 -12
  249. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +0 -97
  250. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js.map +0 -1
  251. package/dist/elements/SampleBuffer.d.ts +0 -19
@@ -1 +1 @@
1
- {"version":3,"file":"EFWaveform.js","names":["EFWaveform"],"sources":["../../src/elements/EFWaveform.ts"],"sourcesContent":["import { CSSStyleObserver } from \"@bramus/style-observer\";\nimport { Task } from \"@lit/task\";\nimport { css, html, LitElement, type PropertyValueMap } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { createRef, type Ref, ref } from \"lit/directives/ref.js\";\nimport { EF_RENDERING } from \"../EF_RENDERING.js\";\nimport { TWMixin } from \"../gui/TWMixin.js\";\nimport { CrossUpdateController } from \"./CrossUpdateController.js\";\nimport type { EFAudio } from \"./EFAudio.js\";\nimport { EFTemporal } from \"./EFTemporal.js\";\nimport type { EFVideo } from \"./EFVideo.js\";\nimport { TargetController } from \"./TargetController.ts\";\n\n@customElement(\"ef-waveform\")\nexport class EFWaveform extends EFTemporal(TWMixin(LitElement)) {\n static styles = css`\n :host {\n all: inherit;\n display: block;\n position: relative;\n }\n\n canvas {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n `;\n\n canvasRef: Ref<HTMLCanvasElement> = createRef();\n private ctx: CanvasRenderingContext2D | null = null;\n private styleObserver: CSSStyleObserver | null = null;\n\n private resizeObserver?: ResizeObserver;\n private mutationObserver?: MutationObserver;\n\n render() {\n return html`<canvas ${ref(this.canvasRef)}></canvas>`;\n }\n\n @property({\n type: String,\n attribute: \"mode\",\n })\n mode:\n | \"roundBars\"\n | \"bars\"\n | \"bricks\"\n | \"line\"\n | \"curve\"\n | \"pixel\"\n | \"wave\"\n | \"spikes\" = \"bars\";\n\n @property({ type: String })\n color = \"currentColor\";\n\n @property({ type: String, reflect: true })\n target = \"\";\n\n @property({ type: Number, attribute: \"bar-spacing\" })\n barSpacing = 0.5;\n\n @state()\n targetElement: EFAudio | EFVideo | null = null;\n\n @property({ type: Number, attribute: \"line-width\" })\n lineWidth = 4;\n\n targetController: TargetController = new TargetController(this);\n\n connectedCallback() {\n super.connectedCallback();\n try {\n if (this.targetElement) {\n new CrossUpdateController(this.targetElement, this);\n }\n } catch (_error) {\n // TODO: determine if this is a critical error, or if we should just ignore it\n // currenty evidence suggests everything still works\n // no target element, no cross update controller\n }\n\n // Initialize ResizeObserver\n this.resizeObserver = new ResizeObserver(() => {\n this.resizeCanvas();\n });\n\n // Observe the host element\n this.resizeObserver.observe(this);\n\n // Initialize MutationObserver\n this.mutationObserver = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === \"attributes\") {\n this.frameTask.run();\n }\n }\n });\n\n // Observe attribute changes on the element\n this.mutationObserver.observe(this, { attributes: true });\n\n if (!EF_RENDERING()) {\n this.styleObserver = new CSSStyleObserver([\"color\"], () => {\n this.frameTask.run();\n });\n this.styleObserver.attach(this);\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // Disconnect the observers when the element is removed from the DOM\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.styleObserver?.detach();\n }\n\n private resizeCanvas() {\n this.ctx = this.initCanvas();\n if (this.ctx) {\n this.frameTask.run(); // Redraw the canvas\n }\n }\n\n protected initCanvas() {\n const canvas = this.canvasRef.value;\n if (!canvas) return null;\n\n const rect = {\n width: this.offsetWidth,\n height: this.offsetHeight,\n };\n const dpr = window.devicePixelRatio;\n\n canvas.style.width = `${rect.width}px`;\n canvas.style.height = `${rect.height}px`;\n\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n ctx.reset();\n\n // Scale all drawing operations by dpr\n return ctx;\n }\n\n protected drawBars(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n const totalBars = frequencyData.length;\n const paddingInner = this.barSpacing;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth;\n const barWidth =\n availableWidth / (totalBars + (totalBars - 1) * paddingInner);\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const barHeight = normalizedValue * waveHeight;\n const y = (waveHeight - barHeight) / 2;\n const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));\n path.rect(x, y, barWidth, barHeight);\n });\n\n ctx.fill(path);\n }\n\n protected drawBricks(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n const columnWidth = waveWidth / frequencyData.length;\n const boxSize = columnWidth * 0.9;\n const verticalGap = boxSize * 0.2; // Add spacing between bricks\n const maxBricks = Math.floor(waveHeight / (boxSize + verticalGap)); // Account for gaps in height calculation\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const brickCount = Math.floor(normalizedValue * maxBricks);\n\n for (let j = 0; j < brickCount; j++) {\n const x = columnWidth * i;\n const y = waveHeight - (j + 1) * (boxSize + verticalGap); // Include gap in position calculation\n path.rect(x, y, boxSize, boxSize);\n }\n });\n\n ctx.fill(path);\n }\n\n protected drawRoundBars(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n // Similar padding calculation as drawBars\n const totalBars = frequencyData.length;\n const paddingInner = this.barSpacing;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth;\n const barWidth =\n availableWidth / (totalBars + (totalBars - 1) * paddingInner);\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n\n // Create a single Path2D object for all rounded bars\n const path = new Path2D();\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const height = normalizedValue * waveHeight; // Use full wave height like in drawBars\n const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));\n const y = (waveHeight - height) / 2; // Center vertically\n\n // Add rounded rectangle to path\n path.roundRect(x, y, barWidth, height, barWidth / 2);\n });\n\n // Single fill operation for all bars\n ctx.fill(path);\n }\n\n protected drawLine(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Sample fewer points to make sharp angles more visible\n const sampleRate = 1; // Only use every 4th point\n\n for (let i = 0; i < frequencyData.length; i += sampleRate) {\n const x = (i / frequencyData.length) * waveWidth;\n const y = (1 - (frequencyData[i] ?? 0) / 255) * waveHeight;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n path.lineTo(x, y);\n }\n }\n // Ensure we draw to the end\n const lastX = waveWidth;\n const lastY =\n (1 - (frequencyData[frequencyData.length - 1] ?? 0) / 255) * waveHeight;\n path.lineTo(lastX, lastY);\n\n ctx.lineWidth = this.lineWidth;\n ctx.stroke(path);\n }\n\n protected drawCurve(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Draw smooth curves between points using quadratic curves\n frequencyData.forEach((value, i) => {\n const x = (i / frequencyData.length) * waveWidth;\n const y = (1 - value / 255) * waveHeight;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n const prevX = ((i - 1) / frequencyData.length) * waveWidth;\n const prevY = (1 - (frequencyData[i - 1] ?? 0) / 255) * waveHeight;\n const xc = (prevX + x) / 2;\n const yc = (prevY + y) / 2;\n path.quadraticCurveTo(prevX, prevY, xc, yc);\n }\n });\n\n ctx.lineWidth = this.lineWidth;\n ctx.stroke(path);\n }\n\n protected drawPixel(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n const baseline = waveHeight / 2;\n const barWidth = waveWidth / frequencyData.length;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const x = i * (waveWidth / frequencyData.length);\n const barHeight = normalizedValue * (waveHeight / 2); // Half height since we extend both ways\n const y = baseline - barHeight;\n path.rect(x, y, barWidth, barHeight * 2); // Double height to extend both ways\n });\n\n ctx.fill(path);\n }\n\n protected drawWave(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth * (1 - 2 * paddingOuter);\n const startX = waveWidth * paddingOuter;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Draw top curve\n const firstValue = Math.min(((frequencyData[0] ?? 0) / 255) * 2, 1);\n const firstY = (waveHeight - firstValue * waveHeight) / 2;\n path.moveTo(startX, firstY);\n\n // Draw top half\n frequencyData.forEach((value, i) => {\n const normalizedValue = Math.min((value / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * waveHeight;\n const y = (waveHeight - barHeight) / 2;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n const prevX =\n startX + ((i - 1) / (frequencyData.length - 1)) * availableWidth;\n const prevValue = Math.min(((frequencyData[i - 1] ?? 0) / 255) * 2, 1);\n const prevBarHeight = prevValue * waveHeight;\n const prevY = (waveHeight - prevBarHeight) / 2;\n const xc = (prevX + x) / 2;\n const yc = (prevY + y) / 2;\n path.quadraticCurveTo(prevX, prevY, xc, yc);\n }\n });\n\n // Draw bottom half\n for (let i = frequencyData.length - 1; i >= 0; i--) {\n const normalizedValue = Math.min(((frequencyData[i] ?? 0) / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * waveHeight;\n const y = (waveHeight + barHeight) / 2;\n\n if (i === frequencyData.length - 1) {\n path.lineTo(x, y);\n } else {\n const nextX =\n startX + ((i + 1) / (frequencyData.length - 1)) * availableWidth;\n const nextValue = Math.min(((frequencyData[i + 1] ?? 0) / 255) * 2, 1);\n const nextBarHeight = nextValue * waveHeight;\n const nextY = (waveHeight + nextBarHeight) / 2;\n const xc = (nextX + x) / 2;\n const yc = (nextY + y) / 2;\n path.quadraticCurveTo(nextX, nextY, xc, yc);\n }\n }\n\n // Close the path with a smooth curve back to start\n const lastY = (waveHeight + firstValue * waveHeight) / 2;\n const controlX = startX;\n const controlY = (lastY + firstY) / 2;\n path.quadraticCurveTo(controlX, controlY, startX, firstY);\n\n ctx.fill(path);\n }\n\n protected drawSpikes(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth * (1 - 2 * paddingOuter);\n const startX = waveWidth * paddingOuter;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Draw top curve\n const firstValue = (frequencyData[0] ?? 0) / 255;\n const firstY = (waveHeight - firstValue * waveHeight) / 2;\n path.moveTo(startX, firstY);\n\n // Draw top half\n frequencyData.forEach((value, i) => {\n const normalizedValue = Math.min((value / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * (waveHeight / 2);\n const y = (waveHeight - barHeight * 2) / 2;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n const prevX =\n startX + ((i - 1) / (frequencyData.length - 1)) * availableWidth;\n const prevValue = (frequencyData[i - 1] ?? 0) / 255;\n const prevBarHeight = prevValue * (waveHeight / 2);\n const prevY = (waveHeight - prevBarHeight * 2) / 2;\n const xc = (prevX + x) / 2;\n const yc = (prevY + y) / 2;\n path.quadraticCurveTo(prevX, prevY, xc, yc);\n }\n });\n\n // Draw bottom half\n for (let i = frequencyData.length - 1; i >= 0; i--) {\n const normalizedValue = Math.min(((frequencyData[i] ?? 0) / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * (waveHeight / 2);\n const y = (waveHeight + barHeight * 2) / 2;\n\n if (i === frequencyData.length - 1) {\n path.lineTo(x, y);\n } else {\n const nextX =\n startX + ((i + 1) / (frequencyData.length - 1)) * availableWidth;\n const nextValue = (frequencyData[i + 1] ?? 0) / 255;\n const nextBarHeight = nextValue * (waveHeight / 2);\n const nextY = (waveHeight + nextBarHeight * 2) / 2;\n const xc = (nextX + x) / 2;\n const yc = (nextY + y) / 2;\n path.quadraticCurveTo(nextX, nextY, xc, yc);\n }\n }\n\n // Close the path with a smooth curve\n const lastY = (waveHeight + firstValue * waveHeight) / 2;\n const controlX = startX;\n const controlY = (lastY + firstY) / 2;\n path.quadraticCurveTo(controlX, controlY, startX, firstY);\n\n ctx.fill(path);\n }\n\n frameTask = new Task(this, {\n autoRun: false,\n args: () => {\n return [\n this.targetElement,\n this.targetElement?.frequencyDataTask.value,\n ] as const;\n },\n task: async ([_targetElement, _frequencyData], { signal }) => {\n if (!this.targetElement) return;\n await this.targetElement.frequencyDataTask.taskComplete;\n signal?.throwIfAborted();\n this.ctx ||= this.initCanvas();\n const ctx = this.ctx;\n if (!ctx) return;\n\n const frequencyData = this.targetElement.frequencyDataTask.value;\n const byteTimeData = this.targetElement.byteTimeDomainTask.value;\n if (!frequencyData || !byteTimeData) return;\n\n ctx.save();\n if (this.color === \"currentColor\") {\n const computedStyle = getComputedStyle(this);\n const currentColor = computedStyle.color;\n ctx.strokeStyle = currentColor;\n ctx.fillStyle = currentColor;\n } else {\n ctx.strokeStyle = this.color;\n ctx.fillStyle = this.color;\n }\n\n switch (this.mode) {\n case \"bars\":\n this.drawBars(ctx, frequencyData);\n break;\n case \"bricks\":\n this.drawBricks(ctx, frequencyData);\n break;\n case \"line\":\n this.drawLine(ctx, byteTimeData);\n break;\n case \"curve\":\n this.drawCurve(ctx, byteTimeData);\n break;\n case \"pixel\":\n this.drawPixel(ctx, frequencyData);\n break;\n case \"wave\":\n this.drawWave(ctx, frequencyData);\n break;\n case \"spikes\":\n this.drawSpikes(ctx, frequencyData);\n break;\n case \"roundBars\":\n this.drawRoundBars(ctx, frequencyData);\n break;\n }\n\n ctx.restore();\n },\n });\n\n get durationMs() {\n if (!this.targetElement) return 0;\n return this.targetElement.durationMs;\n }\n\n protected updated(changedProperties: PropertyValueMap<this>): void {\n super.updated(changedProperties);\n\n // Trigger a redraw if any property changes\n if (changedProperties.size > 0) {\n // Request a new frame\n this.frameTask.run();\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-waveform\": EFWaveform & Element;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EFWaveform.js","names":["EFWaveform","#renderVersion","#dataTimeMs","#frequencyData","#timeDomainData"],"sources":["../../src/elements/EFWaveform.ts"],"sourcesContent":["import { CSSStyleObserver } from \"@bramus/style-observer\";\nimport { css, html, LitElement, type PropertyValueMap } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { createRef, type Ref, ref } from \"lit/directives/ref.js\";\nimport { EF_RENDERING } from \"../EF_RENDERING.js\";\nimport { TWMixin } from \"../gui/TWMixin.js\";\nimport {\n type FrameRenderable,\n type FrameState,\n createFrameTaskWrapper,\n PRIORITY_WAVEFORM,\n} from \"../preview/FrameController.js\";\nimport { CrossUpdateController } from \"./CrossUpdateController.js\";\nimport type { EFAudio } from \"./EFAudio.js\";\nimport { EFTemporal } from \"./EFTemporal.js\";\nimport type { EFVideo } from \"./EFVideo.js\";\nimport { TargetController } from \"./TargetController.ts\";\n\n@customElement(\"ef-waveform\")\nexport class EFWaveform extends EFTemporal(TWMixin(LitElement)) implements FrameRenderable {\n static styles = css`\n :host {\n all: inherit;\n display: block;\n position: relative;\n }\n\n canvas {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n `;\n\n canvasRef: Ref<HTMLCanvasElement> = createRef();\n private ctx: CanvasRenderingContext2D | null = null;\n private styleObserver: CSSStyleObserver | null = null;\n\n private resizeObserver?: ResizeObserver;\n private mutationObserver?: MutationObserver;\n\n /**\n * Render version counter - increments when visual content changes.\n * Used by RenderContext to cache rendered dataURLs.\n */\n #renderVersion = 0;\n\n /**\n * Get the current render version.\n * Version increments when mode, color, barSpacing, lineWidth, or target changes.\n * @public\n */\n get renderVersion(): number {\n return this.#renderVersion;\n }\n\n render() {\n return html`<canvas ${ref(this.canvasRef)}></canvas>`;\n }\n\n @property({\n type: String,\n attribute: \"mode\",\n })\n mode:\n | \"roundBars\"\n | \"bars\"\n | \"bricks\"\n | \"line\"\n | \"curve\"\n | \"pixel\"\n | \"wave\"\n | \"spikes\" = \"bars\";\n\n @property({ type: String })\n color = \"currentColor\";\n\n @property({ type: String, reflect: true })\n target = \"\";\n\n @property({ type: Number, attribute: \"bar-spacing\" })\n barSpacing = 0.5;\n\n @state()\n targetElement: EFAudio | EFVideo | null = null;\n\n @property({ type: Number, attribute: \"line-width\" })\n lineWidth = 4;\n\n targetController: TargetController = new TargetController(this);\n\n connectedCallback() {\n super.connectedCallback();\n try {\n if (this.targetElement) {\n new CrossUpdateController(this.targetElement, this);\n }\n } catch (_error) {\n // TODO: determine if this is a critical error, or if we should just ignore it\n // currenty evidence suggests everything still works\n // no target element, no cross update controller\n }\n\n // Initialize ResizeObserver\n this.resizeObserver = new ResizeObserver(() => {\n this.resizeCanvas();\n });\n\n // Observe the host element\n this.resizeObserver.observe(this);\n\n // Initialize MutationObserver - only for non-style attributes\n // Style changes are handled by FrameController; triggering frameTask.run()\n // here would use ownCurrentTimeMs which is LOCAL time, not root time,\n // causing wrong audio data to be fetched and displayed.\n this.mutationObserver = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === \"attributes\" && mutation.attributeName !== \"style\") {\n this.frameTask.run().catch(() => {\n // AbortErrors are expected during cleanup\n });\n }\n }\n });\n\n // Observe attribute changes on the element\n this.mutationObserver.observe(this, { attributes: true });\n\n if (!EF_RENDERING()) {\n this.styleObserver = new CSSStyleObserver([\"color\"], () => {\n this.frameTask.run().catch(() => {\n // AbortErrors are expected during cleanup\n });\n });\n this.styleObserver.attach(this);\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // Disconnect the observers when the element is removed from the DOM\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.styleObserver?.detach();\n }\n\n private resizeCanvas() {\n this.ctx = this.initCanvas();\n if (this.ctx) {\n this.frameTask.run().catch(() => {\n // AbortErrors are expected during cleanup\n }); // Redraw the canvas\n }\n }\n\n protected initCanvas() {\n const canvas = this.canvasRef.value;\n if (!canvas) return null;\n\n const rect = {\n width: this.offsetWidth,\n height: this.offsetHeight,\n };\n const dpr = window.devicePixelRatio;\n\n canvas.style.width = `${rect.width}px`;\n canvas.style.height = `${rect.height}px`;\n\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n ctx.reset();\n\n // Scale all drawing operations by dpr\n return ctx;\n }\n\n protected drawBars(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n const totalBars = frequencyData.length;\n const paddingInner = this.barSpacing;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth;\n const barWidth =\n availableWidth / (totalBars + (totalBars - 1) * paddingInner);\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const barHeight = normalizedValue * waveHeight;\n const y = (waveHeight - barHeight) / 2;\n const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));\n path.rect(x, y, barWidth, barHeight);\n });\n\n ctx.fill(path);\n }\n\n protected drawBricks(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n const columnWidth = waveWidth / frequencyData.length;\n const boxSize = columnWidth * 0.9;\n const verticalGap = boxSize * 0.2; // Add spacing between bricks\n const maxBricks = Math.floor(waveHeight / (boxSize + verticalGap)); // Account for gaps in height calculation\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const brickCount = Math.floor(normalizedValue * maxBricks);\n\n for (let j = 0; j < brickCount; j++) {\n const x = columnWidth * i;\n const y = waveHeight - (j + 1) * (boxSize + verticalGap); // Include gap in position calculation\n path.rect(x, y, boxSize, boxSize);\n }\n });\n\n ctx.fill(path);\n }\n\n protected drawRoundBars(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n // Similar padding calculation as drawBars\n const totalBars = frequencyData.length;\n const paddingInner = this.barSpacing;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth;\n const barWidth =\n availableWidth / (totalBars + (totalBars - 1) * paddingInner);\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n\n // Create a single Path2D object for all rounded bars\n const path = new Path2D();\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const height = normalizedValue * waveHeight; // Use full wave height like in drawBars\n const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));\n const y = (waveHeight - height) / 2; // Center vertically\n\n // Add rounded rectangle to path\n path.roundRect(x, y, barWidth, height, barWidth / 2);\n });\n\n // Single fill operation for all bars\n ctx.fill(path);\n }\n\n protected drawLine(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Sample fewer points to make sharp angles more visible\n const sampleRate = 1; // Only use every 4th point\n\n for (let i = 0; i < frequencyData.length; i += sampleRate) {\n const x = (i / frequencyData.length) * waveWidth;\n const y = (1 - (frequencyData[i] ?? 0) / 255) * waveHeight;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n path.lineTo(x, y);\n }\n }\n // Ensure we draw to the end\n const lastX = waveWidth;\n const lastY =\n (1 - (frequencyData[frequencyData.length - 1] ?? 0) / 255) * waveHeight;\n path.lineTo(lastX, lastY);\n\n ctx.lineWidth = this.lineWidth;\n ctx.stroke(path);\n }\n\n protected drawCurve(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Draw smooth curves between points using quadratic curves\n frequencyData.forEach((value, i) => {\n const x = (i / frequencyData.length) * waveWidth;\n const y = (1 - value / 255) * waveHeight;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n const prevX = ((i - 1) / frequencyData.length) * waveWidth;\n const prevY = (1 - (frequencyData[i - 1] ?? 0) / 255) * waveHeight;\n const xc = (prevX + x) / 2;\n const yc = (prevY + y) / 2;\n path.quadraticCurveTo(prevX, prevY, xc, yc);\n }\n });\n\n ctx.lineWidth = this.lineWidth;\n ctx.stroke(path);\n }\n\n protected drawPixel(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n const baseline = waveHeight / 2;\n const barWidth = waveWidth / frequencyData.length;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n frequencyData.forEach((value, i) => {\n const normalizedValue = value / 255;\n const x = i * (waveWidth / frequencyData.length);\n const barHeight = normalizedValue * (waveHeight / 2); // Half height since we extend both ways\n const y = baseline - barHeight;\n path.rect(x, y, barWidth, barHeight * 2); // Double height to extend both ways\n });\n\n ctx.fill(path);\n }\n\n protected drawWave(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth * (1 - 2 * paddingOuter);\n const startX = waveWidth * paddingOuter;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Draw top curve\n const firstValue = Math.min(((frequencyData[0] ?? 0) / 255) * 2, 1);\n const firstY = (waveHeight - firstValue * waveHeight) / 2;\n path.moveTo(startX, firstY);\n\n // Draw top half\n frequencyData.forEach((value, i) => {\n const normalizedValue = Math.min((value / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * waveHeight;\n const y = (waveHeight - barHeight) / 2;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n const prevX =\n startX + ((i - 1) / (frequencyData.length - 1)) * availableWidth;\n const prevValue = Math.min(((frequencyData[i - 1] ?? 0) / 255) * 2, 1);\n const prevBarHeight = prevValue * waveHeight;\n const prevY = (waveHeight - prevBarHeight) / 2;\n const xc = (prevX + x) / 2;\n const yc = (prevY + y) / 2;\n path.quadraticCurveTo(prevX, prevY, xc, yc);\n }\n });\n\n // Draw bottom half\n for (let i = frequencyData.length - 1; i >= 0; i--) {\n const normalizedValue = Math.min(((frequencyData[i] ?? 0) / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * waveHeight;\n const y = (waveHeight + barHeight) / 2;\n\n if (i === frequencyData.length - 1) {\n path.lineTo(x, y);\n } else {\n const nextX =\n startX + ((i + 1) / (frequencyData.length - 1)) * availableWidth;\n const nextValue = Math.min(((frequencyData[i + 1] ?? 0) / 255) * 2, 1);\n const nextBarHeight = nextValue * waveHeight;\n const nextY = (waveHeight + nextBarHeight) / 2;\n const xc = (nextX + x) / 2;\n const yc = (nextY + y) / 2;\n path.quadraticCurveTo(nextX, nextY, xc, yc);\n }\n }\n\n // Close the path with a smooth curve back to start\n const lastY = (waveHeight + firstValue * waveHeight) / 2;\n const controlX = startX;\n const controlY = (lastY + firstY) / 2;\n path.quadraticCurveTo(controlX, controlY, startX, firstY);\n\n ctx.fill(path);\n }\n\n protected drawSpikes(\n ctx: CanvasRenderingContext2D,\n frequencyData: Uint8Array,\n ) {\n const canvas = ctx.canvas;\n const waveWidth = canvas.width;\n const waveHeight = canvas.height;\n const paddingOuter = 0.01;\n const availableWidth = waveWidth * (1 - 2 * paddingOuter);\n const startX = waveWidth * paddingOuter;\n\n ctx.clearRect(0, 0, waveWidth, waveHeight);\n const path = new Path2D();\n\n // Draw top curve\n const firstValue = (frequencyData[0] ?? 0) / 255;\n const firstY = (waveHeight - firstValue * waveHeight) / 2;\n path.moveTo(startX, firstY);\n\n // Draw top half\n frequencyData.forEach((value, i) => {\n const normalizedValue = Math.min((value / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * (waveHeight / 2);\n const y = (waveHeight - barHeight * 2) / 2;\n\n if (i === 0) {\n path.moveTo(x, y);\n } else {\n const prevX =\n startX + ((i - 1) / (frequencyData.length - 1)) * availableWidth;\n const prevValue = (frequencyData[i - 1] ?? 0) / 255;\n const prevBarHeight = prevValue * (waveHeight / 2);\n const prevY = (waveHeight - prevBarHeight * 2) / 2;\n const xc = (prevX + x) / 2;\n const yc = (prevY + y) / 2;\n path.quadraticCurveTo(prevX, prevY, xc, yc);\n }\n });\n\n // Draw bottom half\n for (let i = frequencyData.length - 1; i >= 0; i--) {\n const normalizedValue = Math.min(((frequencyData[i] ?? 0) / 255) * 2, 1);\n const x = startX + (i / (frequencyData.length - 1)) * availableWidth;\n const barHeight = normalizedValue * (waveHeight / 2);\n const y = (waveHeight + barHeight * 2) / 2;\n\n if (i === frequencyData.length - 1) {\n path.lineTo(x, y);\n } else {\n const nextX =\n startX + ((i + 1) / (frequencyData.length - 1)) * availableWidth;\n const nextValue = (frequencyData[i + 1] ?? 0) / 255;\n const nextBarHeight = nextValue * (waveHeight / 2);\n const nextY = (waveHeight + nextBarHeight * 2) / 2;\n const xc = (nextX + x) / 2;\n const yc = (nextY + y) / 2;\n path.quadraticCurveTo(nextX, nextY, xc, yc);\n }\n }\n\n // Close the path with a smooth curve\n const lastY = (waveHeight + firstValue * waveHeight) / 2;\n const controlX = startX;\n const controlY = (lastY + firstY) / 2;\n path.quadraticCurveTo(controlX, controlY, startX, firstY);\n\n ctx.fill(path);\n }\n\n /**\n * @deprecated Use FrameRenderable methods (prepareFrame, renderFrame) via FrameController instead.\n * This is a compatibility wrapper that delegates to the new system.\n */\n frameTask = createFrameTaskWrapper(this);\n\n // ============================================================================\n // FrameRenderable Implementation\n // Centralized frame control - uses direct async methods\n // ============================================================================\n\n /**\n * Cached audio analysis data\n */\n #frequencyData: Uint8Array | null = null;\n #timeDomainData: Uint8Array | null = null;\n #dataTimeMs: number | undefined = undefined;\n\n /**\n * Query readiness state for a given time.\n * @implements FrameRenderable\n */\n getFrameState(timeMs: number): FrameState {\n // Waveform is ready when we have cached data for this time\n const hasTarget = !!this.targetElement;\n const hasData = hasTarget && \n this.#dataTimeMs === timeMs &&\n this.#frequencyData !== null;\n\n return {\n needsPreparation: hasTarget && !hasData,\n isReady: hasData,\n priority: PRIORITY_WAVEFORM,\n };\n }\n\n /**\n * Async preparation - fetches frequency data from target.\n * @implements FrameRenderable\n */\n async prepareFrame(timeMs: number, signal: AbortSignal): Promise<void> {\n if (!this.targetElement) return;\n\n // Get audio analysis data directly from target\n const [frequencyData, timeDomainData] = await Promise.all([\n this.targetElement.getFrequencyData(timeMs, signal),\n this.targetElement.getTimeDomainData(timeMs, signal),\n ]);\n\n signal.throwIfAborted();\n\n // Cache results\n this.#frequencyData = frequencyData;\n this.#timeDomainData = timeDomainData;\n this.#dataTimeMs = timeMs;\n }\n\n /**\n * Synchronous render - draws waveform to canvas.\n * @implements FrameRenderable\n */\n renderFrame(_timeMs: number): void {\n if (!this.targetElement) return;\n\n this.ctx ||= this.initCanvas();\n const ctx = this.ctx;\n if (!ctx) return;\n\n const frequencyData = this.#frequencyData;\n const byteTimeData = this.#timeDomainData;\n if (!frequencyData || !byteTimeData) return;\n\n ctx.save();\n if (this.color === \"currentColor\") {\n const computedStyle = getComputedStyle(this);\n const currentColor = computedStyle.color;\n ctx.strokeStyle = currentColor;\n ctx.fillStyle = currentColor;\n } else {\n ctx.strokeStyle = this.color;\n ctx.fillStyle = this.color;\n }\n\n switch (this.mode) {\n case \"bars\":\n this.drawBars(ctx, frequencyData);\n break;\n case \"bricks\":\n this.drawBricks(ctx, frequencyData);\n break;\n case \"line\":\n this.drawLine(ctx, byteTimeData);\n break;\n case \"curve\":\n this.drawCurve(ctx, byteTimeData);\n break;\n case \"pixel\":\n this.drawPixel(ctx, frequencyData);\n break;\n case \"wave\":\n this.drawWave(ctx, frequencyData);\n break;\n case \"spikes\":\n this.drawSpikes(ctx, frequencyData);\n break;\n case \"roundBars\":\n this.drawRoundBars(ctx, frequencyData);\n break;\n }\n\n ctx.restore();\n }\n\n // ============================================================================\n // End FrameRenderable Implementation\n // ============================================================================\n\n get durationMs() {\n if (!this.targetElement) return 0;\n return this.targetElement.durationMs;\n }\n\n protected updated(changedProperties: PropertyValueMap<this>): void {\n super.updated(changedProperties);\n\n // Increment render version on any property change.\n // This is intentionally broad to avoid cache staleness - the cache is\n // per-render-session so within a render the version will be stable.\n if (changedProperties.size > 0) {\n this.#renderVersion++;\n // Request a new frame\n this.frameTask.run().catch(() => {\n // AbortErrors are expected during cleanup\n });\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-waveform\": EFWaveform & Element;\n }\n}\n"],"mappings":"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"}
@@ -9,11 +9,17 @@ async function renderTemporalAudio(host, fromMs, toMs, signal) {
9
9
  await host.waitForMediaDurations();
10
10
  signal?.throwIfAborted();
11
11
  }
12
- await Promise.all(host.getMediaElements().map(async (mediaElement) => {
12
+ const mediaElements = host.getMediaElements();
13
+ console.log(`[renderTemporalAudio] Found ${mediaElements.length} media elements, time range: ${fromMs}-${toMs}ms`);
14
+ await Promise.all(mediaElements.map(async (mediaElement) => {
15
+ console.log(`[renderTemporalAudio] Checking ${mediaElement.tagName} at ${mediaElement.startTimeMs}-${mediaElement.endTimeMs}ms, mute=${mediaElement.mute}`);
13
16
  if (mediaElement.mute) return;
14
17
  const mediaStartsBeforeEnd = mediaElement.startTimeMs <= toMs;
15
18
  const mediaEndsAfterStart = mediaElement.endTimeMs >= fromMs;
16
- if (!(mediaStartsBeforeEnd && mediaEndsAfterStart)) return;
19
+ if (!(mediaStartsBeforeEnd && mediaEndsAfterStart)) {
20
+ console.log(`[renderTemporalAudio] ${mediaElement.tagName} does not overlap`);
21
+ return;
22
+ }
17
23
  const mediaLocalFromMs = Math.max(0, fromMs - mediaElement.startTimeMs);
18
24
  const mediaLocalToMs = Math.min(mediaElement.endTimeMs - mediaElement.startTimeMs, toMs - mediaElement.startTimeMs);
19
25
  if (mediaLocalFromMs >= mediaLocalToMs) return;
@@ -21,8 +27,13 @@ async function renderTemporalAudio(host, fromMs, toMs, signal) {
21
27
  const mediaSourceFromMs = mediaLocalFromMs + sourceInMs;
22
28
  const mediaSourceToMs = mediaLocalToMs + sourceInMs;
23
29
  signal?.throwIfAborted();
30
+ console.log(`[renderTemporalAudio] Fetching audio for ${mediaElement.tagName} from ${mediaSourceFromMs}-${mediaSourceToMs}ms`);
24
31
  const audio = await mediaElement.fetchAudioSpanningTime(mediaSourceFromMs, mediaSourceToMs, signal);
25
- if (!audio) return;
32
+ if (!audio) {
33
+ console.log(`[renderTemporalAudio] No audio returned for ${mediaElement.tagName}`);
34
+ return;
35
+ }
36
+ console.log(`[renderTemporalAudio] Got audio blob size: ${audio.blob.size}, range: ${audio.startMs}-${audio.endMs}ms`);
26
37
  const bufferSource = audioContext.createBufferSource();
27
38
  let decodedBuffer;
28
39
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"renderTemporalAudio.js","names":[],"sources":["../../src/elements/renderTemporalAudio.ts"],"sourcesContent":["import type { EFMedia } from \"./EFMedia.js\";\n\ninterface TemporalAudioHost {\n startTimeMs: number;\n endTimeMs: number;\n durationMs: number;\n getMediaElements(): EFMedia[];\n waitForMediaDurations?(): Promise<void>;\n}\n\nexport async function renderTemporalAudio(\n host: TemporalAudioHost,\n fromMs: number,\n toMs: number,\n signal?: AbortSignal,\n): Promise<AudioBuffer> {\n const durationMs = toMs - fromMs;\n const duration = durationMs / 1000;\n const exactSamples = 48000 * duration;\n const aacFrames = exactSamples / 1024;\n const alignedFrames = Math.round(aacFrames);\n const contextSize = alignedFrames * 1024;\n\n if (contextSize <= 0) {\n throw new Error(\n `Duration must be greater than 0 when rendering audio. ${contextSize}ms`,\n );\n }\n\n // Check abort before starting\n signal?.throwIfAborted();\n\n const audioContext = new OfflineAudioContext(2, contextSize, 48000);\n\n if (host.waitForMediaDurations) {\n await host.waitForMediaDurations();\n // Check abort after potentially slow operation\n signal?.throwIfAborted();\n }\n\n await Promise.all(\n host.getMediaElements().map(async (mediaElement) => {\n if (mediaElement.mute) {\n return;\n }\n\n const mediaStartsBeforeEnd = mediaElement.startTimeMs <= toMs;\n const mediaEndsAfterStart = mediaElement.endTimeMs >= fromMs;\n const mediaOverlaps = mediaStartsBeforeEnd && mediaEndsAfterStart;\n if (!mediaOverlaps) {\n return;\n }\n\n const mediaLocalFromMs = Math.max(0, fromMs - mediaElement.startTimeMs);\n const mediaLocalToMs = Math.min(\n mediaElement.endTimeMs - mediaElement.startTimeMs,\n toMs - mediaElement.startTimeMs,\n );\n\n if (mediaLocalFromMs >= mediaLocalToMs) {\n return;\n }\n\n const sourceInMs =\n mediaElement.sourceInMs || mediaElement.trimStartMs || 0;\n const mediaSourceFromMs = mediaLocalFromMs + sourceInMs;\n const mediaSourceToMs = mediaLocalToMs + sourceInMs;\n\n // Check abort before processing each media element\n signal?.throwIfAborted();\n \n const audio = await mediaElement.fetchAudioSpanningTime(\n mediaSourceFromMs,\n mediaSourceToMs,\n signal,\n );\n if (!audio) {\n return;\n }\n\n const bufferSource = audioContext.createBufferSource();\n \n // Decode audio data with error handling for invalid/incomplete audio\n let decodedBuffer;\n try {\n const arrayBuffer = await audio.blob.arrayBuffer();\n // Skip if buffer is too small to be valid audio\n if (arrayBuffer.byteLength < 100) {\n return;\n }\n decodedBuffer = await audioContext.decodeAudioData(arrayBuffer);\n } catch (decodeError) {\n // Unable to decode audio data - skip this segment silently\n // This can happen with corrupted/incomplete audio segments\n if (decodeError instanceof Error && \n decodeError.message.includes(\"Unable to decode audio data\")) {\n return;\n }\n throw decodeError;\n }\n \n bufferSource.buffer = decodedBuffer;\n bufferSource.connect(audioContext.destination);\n\n const ctxStartMs = Math.max(0, mediaElement.startTimeMs - fromMs);\n\n const requestedSourceFromMs = mediaSourceFromMs;\n const actualSourceStartMs = audio.startMs;\n const offsetInBufferMs = requestedSourceFromMs - actualSourceStartMs;\n\n const safeOffsetMs = Math.max(0, offsetInBufferMs);\n\n const requestedDurationMs = mediaSourceToMs - mediaSourceFromMs;\n const availableAudioMs = audio.endMs - audio.startMs;\n const actualDurationMs = Math.min(\n requestedDurationMs,\n availableAudioMs - safeOffsetMs,\n );\n\n if (actualDurationMs <= 0) {\n return;\n }\n\n bufferSource.start(\n ctxStartMs / 1000,\n safeOffsetMs / 1000,\n actualDurationMs / 1000,\n );\n }),\n );\n\n return audioContext.startRendering();\n}\n"],"mappings":";AAUA,eAAsB,oBACpB,MACA,QACA,MACA,QACsB;CAItB,MAAM,YADe,SAFF,OAAO,UACI,OAEG;CAEjC,MAAM,cADgB,KAAK,MAAM,UAAU,GACP;AAEpC,KAAI,eAAe,EACjB,OAAM,IAAI,MACR,yDAAyD,YAAY,IACtE;AAIH,SAAQ,gBAAgB;CAExB,MAAM,eAAe,IAAI,oBAAoB,GAAG,aAAa,KAAM;AAEnE,KAAI,KAAK,uBAAuB;AAC9B,QAAM,KAAK,uBAAuB;AAElC,UAAQ,gBAAgB;;AAG1B,OAAM,QAAQ,IACZ,KAAK,kBAAkB,CAAC,IAAI,OAAO,iBAAiB;AAClD,MAAI,aAAa,KACf;EAGF,MAAM,uBAAuB,aAAa,eAAe;EACzD,MAAM,sBAAsB,aAAa,aAAa;AAEtD,MAAI,EADkB,wBAAwB,qBAE5C;EAGF,MAAM,mBAAmB,KAAK,IAAI,GAAG,SAAS,aAAa,YAAY;EACvE,MAAM,iBAAiB,KAAK,IAC1B,aAAa,YAAY,aAAa,aACtC,OAAO,aAAa,YACrB;AAED,MAAI,oBAAoB,eACtB;EAGF,MAAM,aACJ,aAAa,cAAc,aAAa,eAAe;EACzD,MAAM,oBAAoB,mBAAmB;EAC7C,MAAM,kBAAkB,iBAAiB;AAGzC,UAAQ,gBAAgB;EAExB,MAAM,QAAQ,MAAM,aAAa,uBAC/B,mBACA,iBACA,OACD;AACD,MAAI,CAAC,MACH;EAGF,MAAM,eAAe,aAAa,oBAAoB;EAGtD,IAAI;AACJ,MAAI;GACF,MAAM,cAAc,MAAM,MAAM,KAAK,aAAa;AAElD,OAAI,YAAY,aAAa,IAC3B;AAEF,mBAAgB,MAAM,aAAa,gBAAgB,YAAY;WACxD,aAAa;AAGpB,OAAI,uBAAuB,SACvB,YAAY,QAAQ,SAAS,8BAA8B,CAC7D;AAEF,SAAM;;AAGR,eAAa,SAAS;AACtB,eAAa,QAAQ,aAAa,YAAY;EAE9C,MAAM,aAAa,KAAK,IAAI,GAAG,aAAa,cAAc,OAAO;EAIjE,MAAM,mBAFwB,oBACF,MAAM;EAGlC,MAAM,eAAe,KAAK,IAAI,GAAG,iBAAiB;EAElD,MAAM,sBAAsB,kBAAkB;EAC9C,MAAM,mBAAmB,MAAM,QAAQ,MAAM;EAC7C,MAAM,mBAAmB,KAAK,IAC5B,qBACA,mBAAmB,aACpB;AAED,MAAI,oBAAoB,EACtB;AAGF,eAAa,MACX,aAAa,KACb,eAAe,KACf,mBAAmB,IACpB;GACD,CACH;AAED,QAAO,aAAa,gBAAgB"}
1
+ {"version":3,"file":"renderTemporalAudio.js","names":[],"sources":["../../src/elements/renderTemporalAudio.ts"],"sourcesContent":["import type { EFMedia } from \"./EFMedia.js\";\n\ninterface TemporalAudioHost {\n startTimeMs: number;\n endTimeMs: number;\n durationMs: number;\n getMediaElements(): EFMedia[];\n waitForMediaDurations?(): Promise<void>;\n}\n\nexport async function renderTemporalAudio(\n host: TemporalAudioHost,\n fromMs: number,\n toMs: number,\n signal?: AbortSignal,\n): Promise<AudioBuffer> {\n const durationMs = toMs - fromMs;\n const duration = durationMs / 1000;\n const exactSamples = 48000 * duration;\n const aacFrames = exactSamples / 1024;\n const alignedFrames = Math.round(aacFrames);\n const contextSize = alignedFrames * 1024;\n\n if (contextSize <= 0) {\n throw new Error(\n `Duration must be greater than 0 when rendering audio. ${contextSize}ms`,\n );\n }\n\n // Check abort before starting\n signal?.throwIfAborted();\n\n const audioContext = new OfflineAudioContext(2, contextSize, 48000);\n\n if (host.waitForMediaDurations) {\n await host.waitForMediaDurations();\n // Check abort after potentially slow operation\n signal?.throwIfAborted();\n }\n\n const mediaElements = host.getMediaElements();\n console.log(`[renderTemporalAudio] Found ${mediaElements.length} media elements, time range: ${fromMs}-${toMs}ms`);\n \n await Promise.all(\n mediaElements.map(async (mediaElement) => {\n console.log(`[renderTemporalAudio] Checking ${mediaElement.tagName} at ${mediaElement.startTimeMs}-${mediaElement.endTimeMs}ms, mute=${mediaElement.mute}`);\n \n if (mediaElement.mute) {\n return;\n }\n\n const mediaStartsBeforeEnd = mediaElement.startTimeMs <= toMs;\n const mediaEndsAfterStart = mediaElement.endTimeMs >= fromMs;\n const mediaOverlaps = mediaStartsBeforeEnd && mediaEndsAfterStart;\n if (!mediaOverlaps) {\n console.log(`[renderTemporalAudio] ${mediaElement.tagName} does not overlap`);\n return;\n }\n\n const mediaLocalFromMs = Math.max(0, fromMs - mediaElement.startTimeMs);\n const mediaLocalToMs = Math.min(\n mediaElement.endTimeMs - mediaElement.startTimeMs,\n toMs - mediaElement.startTimeMs,\n );\n\n if (mediaLocalFromMs >= mediaLocalToMs) {\n return;\n }\n\n const sourceInMs =\n mediaElement.sourceInMs || mediaElement.trimStartMs || 0;\n const mediaSourceFromMs = mediaLocalFromMs + sourceInMs;\n const mediaSourceToMs = mediaLocalToMs + sourceInMs;\n\n // Check abort before processing each media element\n signal?.throwIfAborted();\n \n console.log(`[renderTemporalAudio] Fetching audio for ${mediaElement.tagName} from ${mediaSourceFromMs}-${mediaSourceToMs}ms`);\n const audio = await mediaElement.fetchAudioSpanningTime(\n mediaSourceFromMs,\n mediaSourceToMs,\n signal,\n );\n if (!audio) {\n console.log(`[renderTemporalAudio] No audio returned for ${mediaElement.tagName}`);\n return;\n }\n console.log(`[renderTemporalAudio] Got audio blob size: ${audio.blob.size}, range: ${audio.startMs}-${audio.endMs}ms`);\n\n const bufferSource = audioContext.createBufferSource();\n \n // Decode audio data with error handling for invalid/incomplete audio\n let decodedBuffer;\n try {\n const arrayBuffer = await audio.blob.arrayBuffer();\n // Skip if buffer is too small to be valid audio\n if (arrayBuffer.byteLength < 100) {\n return;\n }\n decodedBuffer = await audioContext.decodeAudioData(arrayBuffer);\n } catch (decodeError) {\n // Unable to decode audio data - skip this segment silently\n // This can happen with corrupted/incomplete audio segments\n if (decodeError instanceof Error && \n decodeError.message.includes(\"Unable to decode audio data\")) {\n return;\n }\n throw decodeError;\n }\n \n bufferSource.buffer = decodedBuffer;\n bufferSource.connect(audioContext.destination);\n\n const ctxStartMs = Math.max(0, mediaElement.startTimeMs - fromMs);\n\n const requestedSourceFromMs = mediaSourceFromMs;\n const actualSourceStartMs = audio.startMs;\n const offsetInBufferMs = requestedSourceFromMs - actualSourceStartMs;\n\n const safeOffsetMs = Math.max(0, offsetInBufferMs);\n\n const requestedDurationMs = mediaSourceToMs - mediaSourceFromMs;\n const availableAudioMs = audio.endMs - audio.startMs;\n const actualDurationMs = Math.min(\n requestedDurationMs,\n availableAudioMs - safeOffsetMs,\n );\n\n if (actualDurationMs <= 0) {\n return;\n }\n\n bufferSource.start(\n ctxStartMs / 1000,\n safeOffsetMs / 1000,\n actualDurationMs / 1000,\n );\n }),\n );\n\n return audioContext.startRendering();\n}\n"],"mappings":";AAUA,eAAsB,oBACpB,MACA,QACA,MACA,QACsB;CAItB,MAAM,YADe,SAFF,OAAO,UACI,OAEG;CAEjC,MAAM,cADgB,KAAK,MAAM,UAAU,GACP;AAEpC,KAAI,eAAe,EACjB,OAAM,IAAI,MACR,yDAAyD,YAAY,IACtE;AAIH,SAAQ,gBAAgB;CAExB,MAAM,eAAe,IAAI,oBAAoB,GAAG,aAAa,KAAM;AAEnE,KAAI,KAAK,uBAAuB;AAC9B,QAAM,KAAK,uBAAuB;AAElC,UAAQ,gBAAgB;;CAG1B,MAAM,gBAAgB,KAAK,kBAAkB;AAC7C,SAAQ,IAAI,+BAA+B,cAAc,OAAO,+BAA+B,OAAO,GAAG,KAAK,IAAI;AAElH,OAAM,QAAQ,IACZ,cAAc,IAAI,OAAO,iBAAiB;AACxC,UAAQ,IAAI,kCAAkC,aAAa,QAAQ,MAAM,aAAa,YAAY,GAAG,aAAa,UAAU,WAAW,aAAa,OAAO;AAE3J,MAAI,aAAa,KACf;EAGF,MAAM,uBAAuB,aAAa,eAAe;EACzD,MAAM,sBAAsB,aAAa,aAAa;AAEtD,MAAI,EADkB,wBAAwB,sBAC1B;AAClB,WAAQ,IAAI,yBAAyB,aAAa,QAAQ,mBAAmB;AAC7E;;EAGF,MAAM,mBAAmB,KAAK,IAAI,GAAG,SAAS,aAAa,YAAY;EACvE,MAAM,iBAAiB,KAAK,IAC1B,aAAa,YAAY,aAAa,aACtC,OAAO,aAAa,YACrB;AAED,MAAI,oBAAoB,eACtB;EAGF,MAAM,aACJ,aAAa,cAAc,aAAa,eAAe;EACzD,MAAM,oBAAoB,mBAAmB;EAC7C,MAAM,kBAAkB,iBAAiB;AAGzC,UAAQ,gBAAgB;AAExB,UAAQ,IAAI,4CAA4C,aAAa,QAAQ,QAAQ,kBAAkB,GAAG,gBAAgB,IAAI;EAC9H,MAAM,QAAQ,MAAM,aAAa,uBAC/B,mBACA,iBACA,OACD;AACD,MAAI,CAAC,OAAO;AACV,WAAQ,IAAI,+CAA+C,aAAa,UAAU;AAClF;;AAEF,UAAQ,IAAI,8CAA8C,MAAM,KAAK,KAAK,WAAW,MAAM,QAAQ,GAAG,MAAM,MAAM,IAAI;EAEtH,MAAM,eAAe,aAAa,oBAAoB;EAGtD,IAAI;AACJ,MAAI;GACF,MAAM,cAAc,MAAM,MAAM,KAAK,aAAa;AAElD,OAAI,YAAY,aAAa,IAC3B;AAEF,mBAAgB,MAAM,aAAa,gBAAgB,YAAY;WACxD,aAAa;AAGpB,OAAI,uBAAuB,SACvB,YAAY,QAAQ,SAAS,8BAA8B,CAC7D;AAEF,SAAM;;AAGR,eAAa,SAAS;AACtB,eAAa,QAAQ,aAAa,YAAY;EAE9C,MAAM,aAAa,KAAK,IAAI,GAAG,aAAa,cAAc,OAAO;EAIjE,MAAM,mBAFwB,oBACF,MAAM;EAGlC,MAAM,eAAe,KAAK,IAAI,GAAG,iBAAiB;EAElD,MAAM,sBAAsB,kBAAkB;EAC9C,MAAM,mBAAmB,MAAM,QAAQ,MAAM;EAC7C,MAAM,mBAAmB,KAAK,IAC5B,qBACA,mBAAmB,aACpB;AAED,MAAI,oBAAoB,EACtB;AAGF,eAAa,MACX,aAAa,KACb,eAAe,KACf,mBAAmB,IACpB;GACD,CACH;AAED,QAAO,aAAa,gBAAgB"}
@@ -21,20 +21,20 @@ declare const RenderInfo: z.ZodObject<{
21
21
  efImage: string[];
22
22
  }>;
23
23
  }, "strip", z.ZodTypeAny, {
24
- durationMs: number;
25
24
  fps: number;
26
25
  width: number;
27
26
  height: number;
27
+ durationMs: number;
28
28
  assets: {
29
29
  efMedia: Record<string, any>;
30
30
  efCaptions: string[];
31
31
  efImage: string[];
32
32
  };
33
33
  }, {
34
- durationMs: number;
35
34
  fps: number;
36
35
  width: number;
37
36
  height: number;
37
+ durationMs: number;
38
38
  assets: {
39
39
  efMedia: Record<string, any>;
40
40
  efCaptions: string[];
@@ -2,7 +2,7 @@ import { EF_RENDERING } from "../EF_RENDERING.js";
2
2
  import { currentTimeContext } from "./currentTimeContext.js";
3
3
  import { durationContext } from "./durationContext.js";
4
4
  import { loopContext, playingContext } from "./playingContext.js";
5
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
5
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
6
6
  import { isEFTemporal } from "../elements/EFTemporal.js";
7
7
  import { globalURLTokenDeduplicator } from "../transcoding/cache/URLTokenDeduplicator.js";
8
8
  import { efConfigurationContext } from "./EFConfiguration.js";
@@ -1,3 +1,5 @@
1
+ import "../elements/EFTemporal.js";
2
+ import "./ContextMixin.js";
1
3
  import { LitElement } from "lit";
2
4
 
3
5
  //#region src/gui/Controllable.d.ts
@@ -1,6 +1,6 @@
1
- import * as lit24 from "lit";
1
+ import * as lit20 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html24 from "lit-html";
3
+ import * as lit_html20 from "lit-html";
4
4
 
5
5
  //#region src/gui/EFActiveRootTemporal.d.ts
6
6
 
@@ -14,7 +14,7 @@ import * as lit_html24 from "lit-html";
14
14
  * ```
15
15
  */
16
16
  declare class EFActiveRootTemporal extends LitElement {
17
- static styles: lit24.CSSResult;
17
+ static styles: lit20.CSSResult;
18
18
  /**
19
19
  * Canvas element ID or selector to bind to.
20
20
  * If not specified, will search for the nearest ef-canvas ancestor.
@@ -38,7 +38,7 @@ declare class EFActiveRootTemporal extends LitElement {
38
38
  * Remove event listener.
39
39
  */
40
40
  private removeListener;
41
- render(): lit_html24.TemplateResult<1>;
41
+ render(): lit_html20.TemplateResult<1>;
42
42
  }
43
43
  declare global {
44
44
  interface HTMLElementTagNameMap {
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { LitElement, css, html } from "lit";
3
3
  import { customElement, property, state } from "lit/decorators.js";
4
4
 
@@ -1,10 +1,10 @@
1
- import * as lit11 from "lit";
1
+ import * as lit7 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html11 from "lit-html";
3
+ import * as lit_html7 from "lit-html";
4
4
 
5
5
  //#region src/gui/EFConfiguration.d.ts
6
6
  declare class EFConfiguration extends LitElement {
7
- static styles: lit11.CSSResult[];
7
+ static styles: lit7.CSSResult[];
8
8
  efConfiguration: this;
9
9
  apiHost?: string;
10
10
  signingURL: string;
@@ -15,7 +15,7 @@ declare class EFConfiguration extends LitElement {
15
15
  * - "jit": Force JitMediaEngine for all sources (uses /api/v1/transcode/* URLs)
16
16
  */
17
17
  mediaEngine?: "cloud" | "local" | "jit";
18
- render(): lit_html11.TemplateResult<1>;
18
+ render(): lit_html7.TemplateResult<1>;
19
19
  }
20
20
  declare global {
21
21
  interface HTMLElementTagNameMap {
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { createContext, provide } from "@lit/context";
3
3
  import { LitElement, css, html } from "lit";
4
4
  import { customElement, property } from "lit/decorators.js";
@@ -1,7 +1,7 @@
1
1
  import { TemporalMixinInterface } from "../elements/EFTemporal.js";
2
2
  import { ControllableInterface } from "./Controllable.js";
3
3
  import { FocusContext } from "./focusContext.js";
4
- import * as lit26 from "lit";
4
+ import * as lit22 from "lit";
5
5
  import { LitElement, PropertyValueMap } from "lit";
6
6
 
7
7
  //#region src/gui/EFControls.d.ts
@@ -26,7 +26,7 @@ import { LitElement, PropertyValueMap } from "lit";
26
26
  */
27
27
  declare class EFControls extends LitElement {
28
28
  #private;
29
- static styles: lit26.CSSResult;
29
+ static styles: lit22.CSSResult;
30
30
  createRenderRoot(): this;
31
31
  /**
32
32
  * The ID of the ef-preview element to control
@@ -1,7 +1,7 @@
1
1
  import { currentTimeContext } from "./currentTimeContext.js";
2
2
  import { durationContext } from "./durationContext.js";
3
3
  import { loopContext, playingContext } from "./playingContext.js";
4
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
4
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
5
5
  import { isEFTemporal } from "../elements/EFTemporal.js";
6
6
  import { efContext } from "./efContext.js";
7
7
  import { focusContext } from "./focusContext.js";
@@ -1,6 +1,6 @@
1
- import * as lit25 from "lit";
1
+ import * as lit21 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html25 from "lit-html";
3
+ import * as lit_html21 from "lit-html";
4
4
 
5
5
  //#region src/gui/EFDial.d.ts
6
6
  interface DialChangeDetail {
@@ -13,12 +13,12 @@ declare class EFDial extends LitElement {
13
13
  private isDragging;
14
14
  private dragStartAngle;
15
15
  private dragStartValue;
16
- static styles: lit25.CSSResult;
16
+ static styles: lit21.CSSResult;
17
17
  private getAngleFromPoint;
18
18
  private handlePointerDown;
19
19
  private handlePointerMove;
20
20
  private handlePointerUp;
21
- render(): lit_html25.TemplateResult<1>;
21
+ render(): lit_html21.TemplateResult<1>;
22
22
  }
23
23
  //#endregion
24
24
  export { DialChangeDetail, EFDial };
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { LitElement, css, html } from "lit";
3
3
  import { customElement, property, state } from "lit/decorators.js";
4
4
  import { styleMap } from "lit/directives/style-map.js";
@@ -1,6 +1,7 @@
1
1
  import { TemporalMixinInterface } from "../elements/EFTemporal.js";
2
+ import "./timeline/EFTimeline.js";
2
3
  import { LitElement } from "lit";
3
- import * as lit_html14 from "lit-html";
4
+ import * as lit_html10 from "lit-html";
4
5
  import * as lit_html_directives_ref0 from "lit-html/directives/ref";
5
6
 
6
7
  //#region src/gui/EFFilmstrip.d.ts
@@ -21,7 +22,7 @@ declare class EFFilmstrip extends EFFilmstrip_base {
21
22
  timelineRef: lit_html_directives_ref0.Ref<HTMLElement>;
22
23
  connectedCallback(): void;
23
24
  protected willUpdate(changedProperties: Map<string | number | symbol, unknown>): void;
24
- render(): lit_html14.TemplateResult<1>;
25
+ render(): lit_html10.TemplateResult<1>;
25
26
  }
26
27
  declare global {
27
28
  interface HTMLElementTagNameMap {
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { isEFTemporal } from "../elements/EFTemporal.js";
3
3
  import { targetTemporalContext } from "./ContextMixin.js";
4
4
  import { TWMixin } from "./TWMixin2.js";
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { LitElement } from "lit";
3
3
  import { customElement, state } from "lit/decorators.js";
4
4
  import { createRef } from "lit/directives/ref.js";
@@ -1,16 +1,16 @@
1
- import * as lit27 from "lit";
1
+ import * as lit23 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html26 from "lit-html";
3
+ import * as lit_html22 from "lit-html";
4
4
  import * as lit_html_directives_ref_js3 from "lit-html/directives/ref.js";
5
5
 
6
6
  //#region src/gui/EFFocusOverlay.d.ts
7
7
  declare class EFFocusOverlay extends LitElement {
8
- static styles: lit27.CSSResult;
8
+ static styles: lit23.CSSResult;
9
9
  focusedElement?: HTMLElement | null;
10
10
  overlay: lit_html_directives_ref_js3.Ref<HTMLDivElement>;
11
11
  private animationFrame?;
12
12
  drawOverlay: () => void;
13
- render(): lit_html26.TemplateResult<1>;
13
+ render(): lit_html22.TemplateResult<1>;
14
14
  connectedCallback(): void;
15
15
  disconnectedCallback(): void;
16
16
  protected updated(): void;
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { focusedElementContext } from "./focusedElementContext.js";
3
3
  import { consume } from "@lit/context";
4
4
  import { LitElement, css, html } from "lit";
@@ -1,6 +1,6 @@
1
- import * as lit36 from "lit";
1
+ import * as lit32 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html35 from "lit-html";
3
+ import * as lit_html31 from "lit-html";
4
4
 
5
5
  //#region src/gui/EFOverlayItem.d.ts
6
6
  /**
@@ -23,7 +23,7 @@ interface OverlayItemPosition {
23
23
  * ensures transforms are applied before positions are read.
24
24
  */
25
25
  declare class EFOverlayItem extends LitElement {
26
- static styles: lit36.CSSResult[];
26
+ static styles: lit32.CSSResult[];
27
27
  elementId?: string;
28
28
  target?: HTMLElement | string;
29
29
  private currentPosition;
@@ -36,7 +36,7 @@ declare class EFOverlayItem extends LitElement {
36
36
  updatePosition(): void;
37
37
  connectedCallback(): void;
38
38
  disconnectedCallback(): void;
39
- render(): lit_html35.TemplateResult<1>;
39
+ render(): lit_html31.TemplateResult<1>;
40
40
  }
41
41
  declare global {
42
42
  interface HTMLElementTagNameMap {
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { parseRotationFromTransform } from "./transformCalculations.js";
3
3
  import { LitElement, css, html } from "lit";
4
4
  import { customElement, property } from "lit/decorators.js";
@@ -1,8 +1,8 @@
1
1
  import { PanZoomTransform } from "../elements/EFPanZoom.js";
2
2
  import { EFOverlayItem } from "./EFOverlayItem.js";
3
- import * as lit35 from "lit";
3
+ import * as lit31 from "lit";
4
4
  import { LitElement } from "lit";
5
- import * as lit_html34 from "lit-html";
5
+ import * as lit_html30 from "lit-html";
6
6
 
7
7
  //#region src/gui/EFOverlayLayer.d.ts
8
8
 
@@ -26,7 +26,7 @@ import * as lit_html34 from "lit-html";
26
26
  * 2. EFOverlayItem can use this rect for coordinate calculations
27
27
  */
28
28
  declare class EFOverlayLayer extends LitElement {
29
- static styles: lit35.CSSResult[];
29
+ static styles: lit31.CSSResult[];
30
30
  panZoomTransformFromContext?: PanZoomTransform;
31
31
  /**
32
32
  * Pan/zoom transform as fallback for when context or sibling PanZoom is not available.
@@ -58,7 +58,7 @@ declare class EFOverlayLayer extends LitElement {
58
58
  connectedCallback(): void;
59
59
  disconnectedCallback(): void;
60
60
  updated(): void;
61
- render(): lit_html34.TemplateResult<1>;
61
+ render(): lit_html30.TemplateResult<1>;
62
62
  }
63
63
  declare global {
64
64
  interface HTMLElementTagNameMap {
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { panZoomTransformContext } from "./panZoomTransformContext.js";
3
3
  import { consume } from "@lit/context";
4
4
  import { LitElement, css, html } from "lit";
@@ -1,7 +1,7 @@
1
1
  import { ControllableInterface } from "./Controllable.js";
2
- import * as lit20 from "lit";
2
+ import * as lit16 from "lit";
3
3
  import { LitElement } from "lit";
4
- import * as lit_html20 from "lit-html";
4
+ import * as lit_html16 from "lit-html";
5
5
 
6
6
  //#region src/gui/EFPause.d.ts
7
7
  declare const EFPause_base: (new (...args: any[]) => {
@@ -10,13 +10,13 @@ declare const EFPause_base: (new (...args: any[]) => {
10
10
  effectiveContext: ControllableInterface | null;
11
11
  }) & typeof LitElement;
12
12
  declare class EFPause extends EFPause_base {
13
- static styles: lit20.CSSResult[];
13
+ static styles: lit16.CSSResult[];
14
14
  playing: boolean;
15
15
  get efContext(): ControllableInterface | null;
16
16
  connectedCallback(): void;
17
17
  disconnectedCallback(): void;
18
18
  updated(changedProperties: Map<string | number | symbol, unknown>): void;
19
- render(): lit_html20.TemplateResult<1>;
19
+ render(): lit_html16.TemplateResult<1>;
20
20
  handleClick: () => void;
21
21
  }
22
22
  declare global {
@@ -1,5 +1,5 @@
1
1
  import { playingContext } from "./playingContext.js";
2
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
2
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
3
3
  import { efContext } from "./efContext.js";
4
4
  import { attachContextRoot } from "../attachContextRoot.js";
5
5
  import { TargetOrContextMixin } from "./TargetOrContextMixin.js";
@@ -1,7 +1,7 @@
1
1
  import { ControllableInterface } from "./Controllable.js";
2
- import * as lit19 from "lit";
2
+ import * as lit15 from "lit";
3
3
  import { LitElement } from "lit";
4
- import * as lit_html19 from "lit-html";
4
+ import * as lit_html15 from "lit-html";
5
5
 
6
6
  //#region src/gui/EFPlay.d.ts
7
7
  declare const EFPlay_base: (new (...args: any[]) => {
@@ -10,13 +10,13 @@ declare const EFPlay_base: (new (...args: any[]) => {
10
10
  effectiveContext: ControllableInterface | null;
11
11
  }) & typeof LitElement;
12
12
  declare class EFPlay extends EFPlay_base {
13
- static styles: lit19.CSSResult[];
13
+ static styles: lit15.CSSResult[];
14
14
  playing: boolean;
15
15
  get efContext(): ControllableInterface | null;
16
16
  connectedCallback(): void;
17
17
  disconnectedCallback(): void;
18
18
  updated(changedProperties: Map<string | number | symbol, unknown>): void;
19
- render(): lit_html19.TemplateResult<1>;
19
+ render(): lit_html15.TemplateResult<1>;
20
20
  handleClick: () => void;
21
21
  }
22
22
  declare global {
@@ -1,5 +1,5 @@
1
1
  import { playingContext } from "./playingContext.js";
2
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
2
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
3
3
  import { efContext } from "./efContext.js";
4
4
  import { attachContextRoot } from "../attachContextRoot.js";
5
5
  import { TargetOrContextMixin } from "./TargetOrContextMixin.js";
@@ -1,19 +1,19 @@
1
1
  import { ContextMixinInterface } from "./ContextMixin.js";
2
- import * as lit13 from "lit";
2
+ import * as lit9 from "lit";
3
3
  import { LitElement } from "lit";
4
- import * as lit_html13 from "lit-html";
4
+ import * as lit_html9 from "lit-html";
5
5
 
6
6
  //#region src/gui/EFPreview.d.ts
7
7
  declare const EFPreview_base: (new (...args: any[]) => ContextMixinInterface) & typeof LitElement;
8
8
  declare class EFPreview extends EFPreview_base {
9
- static styles: lit13.CSSResult[];
9
+ static styles: lit9.CSSResult[];
10
10
  focusedElement?: HTMLElement;
11
11
  /**
12
12
  * Find the closest temporal element (timegroup, video, audio, etc.)
13
13
  */
14
14
  private findClosestTemporal;
15
15
  constructor();
16
- render(): lit_html13.TemplateResult<1>;
16
+ render(): lit_html9.TemplateResult<1>;
17
17
  }
18
18
  declare global {
19
19
  interface HTMLElementTagNameMap {
@@ -1,4 +1,4 @@
1
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { isEFTemporal } from "../elements/EFTemporal.js";
3
3
  import { focusedElementContext } from "./focusedElementContext.js";
4
4
  import { ContextMixin } from "./ContextMixin.js";