@editframe/elements 0.37.2-beta → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. package/dist/EF_FRAMEGEN.js +17 -14
  2. package/dist/EF_FRAMEGEN.js.map +1 -1
  3. package/dist/EF_RENDERING.js.map +1 -1
  4. package/dist/canvas/EFCanvas.d.ts +9 -2
  5. package/dist/canvas/EFCanvas.js +14 -4
  6. package/dist/canvas/EFCanvas.js.map +1 -1
  7. package/dist/canvas/EFCanvasItem.d.ts +4 -4
  8. package/dist/canvas/overlays/SelectionOverlay.d.ts +10 -2
  9. package/dist/canvas/overlays/SelectionOverlay.js +5 -12
  10. package/dist/canvas/overlays/SelectionOverlay.js.map +1 -1
  11. package/dist/canvas/overlays/overlayState.js.map +1 -1
  12. package/dist/canvas/selection/SelectionController.js.map +1 -1
  13. package/dist/elements/EFAudio.d.ts +1 -11
  14. package/dist/elements/EFAudio.js +2 -10
  15. package/dist/elements/EFAudio.js.map +1 -1
  16. package/dist/elements/EFCaptions.d.ts +5 -9
  17. package/dist/elements/EFCaptions.js +34 -11
  18. package/dist/elements/EFCaptions.js.map +1 -1
  19. package/dist/elements/EFImage.d.ts +10 -8
  20. package/dist/elements/EFImage.js +117 -32
  21. package/dist/elements/EFImage.js.map +1 -1
  22. package/dist/elements/EFMedia/AssetMediaEngine.js +2 -2
  23. package/dist/elements/EFMedia/AssetMediaEngine.js.map +1 -1
  24. package/dist/elements/EFMedia/BaseMediaEngine.js +15 -92
  25. package/dist/elements/EFMedia/BaseMediaEngine.js.map +1 -1
  26. package/dist/elements/EFMedia/BufferedSeekingInput.js +10 -11
  27. package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -1
  28. package/dist/elements/EFMedia/{AssetIdMediaEngine.js → FileMediaEngine.js} +44 -24
  29. package/dist/elements/EFMedia/FileMediaEngine.js.map +1 -0
  30. package/dist/elements/EFMedia/JitMediaEngine.js +14 -13
  31. package/dist/elements/EFMedia/JitMediaEngine.js.map +1 -1
  32. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +3 -3
  33. package/dist/elements/EFMedia/shared/AudioSpanUtils.js.map +1 -1
  34. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +12 -7
  35. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js.map +1 -1
  36. package/dist/elements/EFMedia/shared/timeoutUtils.js +44 -0
  37. package/dist/elements/EFMedia/shared/timeoutUtils.js.map +1 -0
  38. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +1 -1
  39. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js.map +1 -1
  40. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +4 -4
  41. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -1
  42. package/dist/elements/EFMedia.d.ts +14 -8
  43. package/dist/elements/EFMedia.js +52 -19
  44. package/dist/elements/EFMedia.js.map +1 -1
  45. package/dist/elements/EFPanZoom.d.ts +2 -2
  46. package/dist/elements/EFPanZoom.js +1 -1
  47. package/dist/elements/EFPanZoom.js.map +1 -1
  48. package/dist/elements/EFSourceMixin.js +16 -8
  49. package/dist/elements/EFSourceMixin.js.map +1 -1
  50. package/dist/elements/EFSurface.d.ts +7 -10
  51. package/dist/elements/EFSurface.js +4 -43
  52. package/dist/elements/EFSurface.js.map +1 -1
  53. package/dist/elements/EFTemporal.d.ts +33 -8
  54. package/dist/elements/EFTemporal.js +92 -40
  55. package/dist/elements/EFTemporal.js.map +1 -1
  56. package/dist/elements/EFText.d.ts +3 -0
  57. package/dist/elements/EFText.js +54 -21
  58. package/dist/elements/EFText.js.map +1 -1
  59. package/dist/elements/EFTextSegment.js +8 -4
  60. package/dist/elements/EFTextSegment.js.map +1 -1
  61. package/dist/elements/EFTimegroup.d.ts +26 -43
  62. package/dist/elements/EFTimegroup.js +295 -314
  63. package/dist/elements/EFTimegroup.js.map +1 -1
  64. package/dist/elements/EFVideo.d.ts +44 -42
  65. package/dist/elements/EFVideo.js +259 -172
  66. package/dist/elements/EFVideo.js.map +1 -1
  67. package/dist/elements/EFWaveform.d.ts +3 -8
  68. package/dist/elements/EFWaveform.js +18 -13
  69. package/dist/elements/EFWaveform.js.map +1 -1
  70. package/dist/elements/ElementPositionInfo.js.map +1 -1
  71. package/dist/elements/FetchMixin.js.map +1 -1
  72. package/dist/elements/TargetController.d.ts +0 -3
  73. package/dist/elements/TargetController.js +12 -35
  74. package/dist/elements/TargetController.js.map +1 -1
  75. package/dist/elements/TimegroupController.js.map +1 -1
  76. package/dist/elements/cloneFactoryRegistry.d.ts +14 -0
  77. package/dist/elements/cloneFactoryRegistry.js +15 -0
  78. package/dist/elements/cloneFactoryRegistry.js.map +1 -0
  79. package/dist/elements/renderTemporalAudio.js +8 -6
  80. package/dist/elements/renderTemporalAudio.js.map +1 -1
  81. package/dist/elements/setupTemporalHierarchy.js +62 -0
  82. package/dist/elements/setupTemporalHierarchy.js.map +1 -0
  83. package/dist/elements/updateAnimations.js +62 -87
  84. package/dist/elements/updateAnimations.js.map +1 -1
  85. package/dist/getRenderInfo.d.ts +3 -2
  86. package/dist/getRenderInfo.js +20 -4
  87. package/dist/getRenderInfo.js.map +1 -1
  88. package/dist/gui/ContextMixin.js +68 -12
  89. package/dist/gui/ContextMixin.js.map +1 -1
  90. package/dist/gui/Controllable.js +1 -1
  91. package/dist/gui/Controllable.js.map +1 -1
  92. package/dist/gui/EFActiveRootTemporal.d.ts +4 -4
  93. package/dist/gui/EFActiveRootTemporal.js.map +1 -1
  94. package/dist/gui/EFControls.d.ts +2 -2
  95. package/dist/gui/EFControls.js +2 -2
  96. package/dist/gui/EFControls.js.map +1 -1
  97. package/dist/gui/EFDial.d.ts +4 -4
  98. package/dist/gui/EFDial.js +12 -9
  99. package/dist/gui/EFDial.js.map +1 -1
  100. package/dist/gui/EFFilmstrip.d.ts +2 -0
  101. package/dist/gui/EFFilmstrip.js +18 -10
  102. package/dist/gui/EFFilmstrip.js.map +1 -1
  103. package/dist/gui/EFFitScale.d.ts +28 -4
  104. package/dist/gui/EFFitScale.js +88 -26
  105. package/dist/gui/EFFitScale.js.map +1 -1
  106. package/dist/gui/EFFocusOverlay.d.ts +4 -4
  107. package/dist/gui/EFFocusOverlay.js +3 -3
  108. package/dist/gui/EFFocusOverlay.js.map +1 -1
  109. package/dist/gui/EFOverlayItem.d.ts +4 -4
  110. package/dist/gui/EFOverlayLayer.d.ts +4 -4
  111. package/dist/gui/EFPause.d.ts +4 -4
  112. package/dist/gui/EFPause.js +1 -1
  113. package/dist/gui/EFPlay.d.ts +4 -4
  114. package/dist/gui/EFPlay.js +1 -1
  115. package/dist/gui/EFPreview.js +1 -1
  116. package/dist/gui/EFResizableBox.d.ts +4 -4
  117. package/dist/gui/EFResizableBox.js +5 -5
  118. package/dist/gui/EFResizableBox.js.map +1 -1
  119. package/dist/gui/EFScrubber.d.ts +4 -4
  120. package/dist/gui/EFScrubber.js +8 -13
  121. package/dist/gui/EFScrubber.js.map +1 -1
  122. package/dist/gui/EFTimeDisplay.d.ts +8 -4
  123. package/dist/gui/EFTimeDisplay.js +25 -7
  124. package/dist/gui/EFTimeDisplay.js.map +1 -1
  125. package/dist/gui/EFTimelineRuler.d.ts +4 -4
  126. package/dist/gui/EFTimelineRuler.js +3 -3
  127. package/dist/gui/EFTimelineRuler.js.map +1 -1
  128. package/dist/gui/EFToggleLoop.d.ts +4 -4
  129. package/dist/gui/EFToggleLoop.js +1 -1
  130. package/dist/gui/EFTogglePlay.d.ts +4 -4
  131. package/dist/gui/EFTogglePlay.js +1 -1
  132. package/dist/gui/EFTransformHandles.d.ts +4 -4
  133. package/dist/gui/EFTransformHandles.js +6 -6
  134. package/dist/gui/EFTransformHandles.js.map +1 -1
  135. package/dist/gui/EFWorkbench.d.ts +40 -36
  136. package/dist/gui/EFWorkbench.js +436 -822
  137. package/dist/gui/EFWorkbench.js.map +1 -1
  138. package/dist/gui/FitScaleHelpers.js.map +1 -1
  139. package/dist/gui/PlaybackController.d.ts +3 -8
  140. package/dist/gui/PlaybackController.js +59 -56
  141. package/dist/gui/PlaybackController.js.map +1 -1
  142. package/dist/gui/TWMixin.js +1 -1
  143. package/dist/gui/TWMixin.js.map +1 -1
  144. package/dist/gui/TargetOrContextMixin.js +43 -6
  145. package/dist/gui/TargetOrContextMixin.js.map +1 -1
  146. package/dist/gui/ef-theme.css +136 -0
  147. package/dist/gui/hierarchy/EFHierarchy.d.ts +2 -2
  148. package/dist/gui/hierarchy/EFHierarchy.js +14 -24
  149. package/dist/gui/hierarchy/EFHierarchy.js.map +1 -1
  150. package/dist/gui/hierarchy/EFHierarchyItem.d.ts +3 -3
  151. package/dist/gui/hierarchy/EFHierarchyItem.js +22 -10
  152. package/dist/gui/hierarchy/EFHierarchyItem.js.map +1 -1
  153. package/dist/gui/icons.js.map +1 -1
  154. package/dist/gui/previewSettingsContext.d.ts +18 -0
  155. package/dist/gui/previewSettingsContext.js.map +1 -1
  156. package/dist/gui/theme.js +34 -0
  157. package/dist/gui/theme.js.map +1 -0
  158. package/dist/gui/timeline/EFTimeline.d.ts +2 -2
  159. package/dist/gui/timeline/EFTimeline.js +70 -52
  160. package/dist/gui/timeline/EFTimeline.js.map +1 -1
  161. package/dist/gui/timeline/EFTimelineRow.d.ts +3 -1
  162. package/dist/gui/timeline/EFTimelineRow.js +55 -32
  163. package/dist/gui/timeline/EFTimelineRow.js.map +1 -1
  164. package/dist/gui/timeline/TrimHandles.d.ts +23 -9
  165. package/dist/gui/timeline/TrimHandles.js +224 -51
  166. package/dist/gui/timeline/TrimHandles.js.map +1 -1
  167. package/dist/gui/timeline/flattenHierarchy.js.map +1 -1
  168. package/dist/gui/timeline/timelineEditingContext.d.ts +34 -0
  169. package/dist/gui/timeline/timelineEditingContext.js +24 -0
  170. package/dist/gui/timeline/timelineEditingContext.js.map +1 -0
  171. package/dist/gui/timeline/timelineStateContext.js.map +1 -1
  172. package/dist/gui/timeline/tracks/AudioTrack.js +1 -1
  173. package/dist/gui/timeline/tracks/AudioTrack.js.map +1 -1
  174. package/dist/gui/timeline/tracks/CaptionsTrack.d.ts +2 -3
  175. package/dist/gui/timeline/tracks/CaptionsTrack.js +17 -75
  176. package/dist/gui/timeline/tracks/CaptionsTrack.js.map +1 -1
  177. package/dist/gui/timeline/tracks/EFThumbnailStrip.d.ts +52 -0
  178. package/dist/gui/timeline/tracks/EFThumbnailStrip.js +596 -0
  179. package/dist/gui/timeline/tracks/EFThumbnailStrip.js.map +1 -0
  180. package/dist/gui/timeline/tracks/HTMLTrack.js.map +1 -1
  181. package/dist/gui/timeline/tracks/ImageTrack.js.map +1 -1
  182. package/dist/gui/timeline/tracks/TextTrack.d.ts +3 -2
  183. package/dist/gui/timeline/tracks/TextTrack.js +17 -43
  184. package/dist/gui/timeline/tracks/TextTrack.js.map +1 -1
  185. package/dist/gui/timeline/tracks/TimegroupTrack.d.ts +5 -6
  186. package/dist/gui/timeline/tracks/TimegroupTrack.js +33 -23
  187. package/dist/gui/timeline/tracks/TimegroupTrack.js.map +1 -1
  188. package/dist/gui/timeline/tracks/TrackItem.d.ts +7 -9
  189. package/dist/gui/timeline/tracks/TrackItem.js +18 -17
  190. package/dist/gui/timeline/tracks/TrackItem.js.map +1 -1
  191. package/dist/gui/timeline/tracks/VideoTrack.d.ts +3 -3
  192. package/dist/gui/timeline/tracks/VideoTrack.js +11 -14
  193. package/dist/gui/timeline/tracks/VideoTrack.js.map +1 -1
  194. package/dist/gui/timeline/tracks/WaveformTrack.js.map +1 -1
  195. package/dist/gui/timeline/tracks/renderTrackChildren.js.map +1 -1
  196. package/dist/gui/timeline/tracks/waveformUtils.js +1 -1
  197. package/dist/gui/timeline/tracks/waveformUtils.js.map +1 -1
  198. package/dist/gui/tree/EFTree.d.ts +4 -4
  199. package/dist/gui/tree/EFTree.js +8 -14
  200. package/dist/gui/tree/EFTree.js.map +1 -1
  201. package/dist/gui/tree/EFTreeItem.d.ts +4 -4
  202. package/dist/gui/tree/EFTreeItem.js +3 -3
  203. package/dist/gui/tree/EFTreeItem.js.map +1 -1
  204. package/dist/gui/tree/treeContext.js.map +1 -1
  205. package/dist/index.d.ts +10 -8
  206. package/dist/index.js +6 -5
  207. package/dist/index.js.map +1 -1
  208. package/dist/node.d.ts +2 -2
  209. package/dist/node.js +2 -2
  210. package/dist/preview/AdaptiveResolutionTracker.js +3 -3
  211. package/dist/preview/AdaptiveResolutionTracker.js.map +1 -1
  212. package/dist/preview/FrameController.d.ts +2 -17
  213. package/dist/preview/FrameController.js +40 -63
  214. package/dist/preview/FrameController.js.map +1 -1
  215. package/dist/preview/QualityUpgradeScheduler.d.ts +76 -0
  216. package/dist/preview/QualityUpgradeScheduler.js +158 -0
  217. package/dist/preview/QualityUpgradeScheduler.js.map +1 -0
  218. package/dist/preview/RenderContext.d.ts +119 -1
  219. package/dist/preview/RenderContext.js +21 -3
  220. package/dist/preview/RenderContext.js.map +1 -1
  221. package/dist/preview/RenderProfiler.js.map +1 -1
  222. package/dist/preview/RenderStats.js +85 -0
  223. package/dist/preview/RenderStats.js.map +1 -0
  224. package/dist/preview/encoding/canvasEncoder.js +2 -52
  225. package/dist/preview/encoding/canvasEncoder.js.map +1 -1
  226. package/dist/preview/encoding/mainThreadEncoder.js.map +1 -1
  227. package/dist/preview/encoding/workerEncoder.js.map +1 -1
  228. package/dist/preview/logger.js.map +1 -1
  229. package/dist/preview/previewSettings.d.ts +34 -0
  230. package/dist/preview/previewSettings.js +29 -17
  231. package/dist/preview/previewSettings.js.map +1 -1
  232. package/dist/preview/previewTypes.js +4 -4
  233. package/dist/preview/previewTypes.js.map +1 -1
  234. package/dist/preview/renderElementToCanvas.d.ts +44 -0
  235. package/dist/preview/renderElementToCanvas.js +72 -0
  236. package/dist/preview/renderElementToCanvas.js.map +1 -0
  237. package/dist/preview/renderTimegroupToCanvas.js +267 -145
  238. package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
  239. package/dist/preview/renderTimegroupToCanvas.types.d.ts +30 -0
  240. package/dist/preview/renderTimegroupToVideo.js +85 -105
  241. package/dist/preview/renderTimegroupToVideo.js.map +1 -1
  242. package/dist/preview/{renderTimegroupToVideo.d.ts → renderTimegroupToVideo.types.d.ts} +9 -9
  243. package/dist/preview/renderVideoToVideo.js +286 -0
  244. package/dist/preview/renderVideoToVideo.js.map +1 -0
  245. package/dist/preview/renderers.js.map +1 -1
  246. package/dist/preview/rendering/ScaleConfig.js +74 -0
  247. package/dist/preview/rendering/ScaleConfig.js.map +1 -0
  248. package/dist/preview/rendering/inlineImages.js +1 -44
  249. package/dist/preview/rendering/inlineImages.js.map +1 -1
  250. package/dist/preview/rendering/loadImage.js +22 -0
  251. package/dist/preview/rendering/loadImage.js.map +1 -0
  252. package/dist/preview/rendering/renderToImageNative.js +3 -3
  253. package/dist/preview/rendering/renderToImageNative.js.map +1 -1
  254. package/dist/preview/rendering/serializeTimelineDirect.js +224 -68
  255. package/dist/preview/rendering/serializeTimelineDirect.js.map +1 -1
  256. package/dist/preview/statsTrackingStrategy.js +1 -101
  257. package/dist/preview/statsTrackingStrategy.js.map +1 -1
  258. package/dist/preview/workers/WorkerPool.js +0 -1
  259. package/dist/preview/workers/WorkerPool.js.map +1 -1
  260. package/dist/preview/workers/encoderWorkerInline.js +21 -54
  261. package/dist/preview/workers/encoderWorkerInline.js.map +1 -1
  262. package/dist/render/EFRenderAPI.d.ts +2 -1
  263. package/dist/render/EFRenderAPI.js +12 -36
  264. package/dist/render/EFRenderAPI.js.map +1 -1
  265. package/dist/render/getRenderData.js +4 -4
  266. package/dist/render/getRenderData.js.map +1 -1
  267. package/dist/style.css +114 -163
  268. package/dist/transcoding/cache/RequestDeduplicator.js +1 -0
  269. package/dist/transcoding/cache/RequestDeduplicator.js.map +1 -1
  270. package/dist/transcoding/types/index.d.ts +1 -1
  271. package/dist/transcoding/utils/UrlGenerator.js +10 -3
  272. package/dist/transcoding/utils/UrlGenerator.js.map +1 -1
  273. package/dist/utils/LRUCache.js +1 -0
  274. package/dist/utils/LRUCache.js.map +1 -1
  275. package/dist/utils/frameTime.js +23 -1
  276. package/dist/utils/frameTime.js.map +1 -1
  277. package/package.json +21 -8
  278. package/scripts/build-css.js +8 -1
  279. package/test/setup.ts +0 -1
  280. package/test/useAssetMSW.ts +50 -0
  281. package/test/visualRegressionUtils.ts +23 -9
  282. package/dist/_virtual/rolldown_runtime.js +0 -27
  283. package/dist/elements/EFMedia/AssetIdMediaEngine.js.map +0 -1
  284. package/dist/elements/EFThumbnailStrip.d.ts +0 -167
  285. package/dist/elements/EFThumbnailStrip.js +0 -731
  286. package/dist/elements/EFThumbnailStrip.js.map +0 -1
  287. package/dist/elements/SessionThumbnailCache.js +0 -154
  288. package/dist/elements/SessionThumbnailCache.js.map +0 -1
  289. package/dist/node_modules/react/cjs/react-jsx-runtime.development.js +0 -688
  290. package/dist/node_modules/react/cjs/react-jsx-runtime.development.js.map +0 -1
  291. package/dist/node_modules/react/cjs/react.development.js +0 -1521
  292. package/dist/node_modules/react/cjs/react.development.js.map +0 -1
  293. package/dist/node_modules/react/index.js +0 -13
  294. package/dist/node_modules/react/index.js.map +0 -1
  295. package/dist/node_modules/react/jsx-runtime.js +0 -13
  296. package/dist/node_modules/react/jsx-runtime.js.map +0 -1
  297. package/dist/preview/encoding/types.d.ts +0 -1
  298. package/dist/preview/renderTimegroupPreview.js +0 -686
  299. package/dist/preview/renderTimegroupPreview.js.map +0 -1
  300. package/dist/preview/renderTimegroupToCanvas.d.ts +0 -42
  301. package/dist/preview/rendering/renderToImage.d.ts +0 -2
  302. package/dist/preview/rendering/renderToImage.js +0 -95
  303. package/dist/preview/rendering/renderToImage.js.map +0 -1
  304. package/dist/preview/rendering/renderToImageForeignObject.js +0 -163
  305. package/dist/preview/rendering/renderToImageForeignObject.js.map +0 -1
  306. package/dist/preview/rendering/renderToImageNative.d.ts +0 -1
  307. package/dist/preview/rendering/svgSerializer.js +0 -43
  308. package/dist/preview/rendering/svgSerializer.js.map +0 -1
  309. package/dist/preview/rendering/types.d.ts +0 -2
  310. package/dist/preview/thumbnailCacheSettings.js +0 -52
  311. package/dist/preview/thumbnailCacheSettings.js.map +0 -1
  312. package/dist/sandbox/PlaybackControls.d.ts +0 -1
  313. package/dist/sandbox/PlaybackControls.js +0 -10
  314. package/dist/sandbox/PlaybackControls.js.map +0 -1
  315. package/dist/sandbox/ScenarioRunner.d.ts +0 -1
  316. package/dist/sandbox/ScenarioRunner.js +0 -1
  317. package/dist/sandbox/defineSandbox.d.ts +0 -1
  318. package/dist/sandbox/index.d.ts +0 -3
  319. package/dist/sandbox/index.js +0 -2
  320. package/test/EFVideo.framegen.browsertest.ts +0 -80
  321. package/test/thumbnail-performance-test.html +0 -116
@@ -2,13 +2,36 @@ import { LitElement } from "lit";
2
2
  import * as lit_html_directives_ref1 from "lit-html/directives/ref";
3
3
 
4
4
  //#region src/gui/EFFitScale.d.ts
5
+ interface ScaleInput {
6
+ containerWidth: number;
7
+ containerHeight: number;
8
+ contentWidth: number;
9
+ contentHeight: number;
10
+ }
11
+ interface ScaleOutput {
12
+ scale: number;
13
+ translateX: number;
14
+ translateY: number;
15
+ }
16
+ /**
17
+ * Compute the scale factor and centering translation needed to fit
18
+ * content of a given size into a container while preserving aspect ratio.
19
+ *
20
+ * Returns `null` when any dimension is zero or negative (cannot compute).
21
+ */
22
+ declare function computeFitScale(input: ScaleInput): ScaleOutput | null;
5
23
  declare class EFFitScale extends LitElement {
6
24
  containerRef: lit_html_directives_ref1.Ref<HTMLDivElement>;
7
25
  contentRef: lit_html_directives_ref1.Ref<HTMLSlotElement>;
8
26
  createRenderRoot(): this;
9
27
  uniqueId: string;
10
- private scale;
11
- private animationFrameId?;
28
+ paused: boolean;
29
+ updated(changedProperties: Map<string, unknown>): void;
30
+ private containerResizeObserver?;
31
+ private contentResizeObserver?;
32
+ private childMutationObserver?;
33
+ private observedContentChild;
34
+ private hasWarnedZeroDimensions;
12
35
  get contentChild(): HTMLElement | null;
13
36
  get scaleInfo(): {
14
37
  scale: number;
@@ -18,7 +41,8 @@ declare class EFFitScale extends LitElement {
18
41
  contentHeight: number;
19
42
  };
20
43
  scaleLastSetOn: HTMLElement | null;
21
- setScale: () => void;
44
+ private updateScale;
45
+ private observeContentChild;
22
46
  removeScale: () => void;
23
47
  connectedCallback(): void;
24
48
  disconnectedCallback(): void;
@@ -29,5 +53,5 @@ declare global {
29
53
  }
30
54
  }
31
55
  //#endregion
32
- export { EFFitScale };
56
+ export { EFFitScale, ScaleInput, ScaleOutput, computeFitScale };
33
57
  //# sourceMappingURL=EFFitScale.d.ts.map
@@ -1,36 +1,64 @@
1
1
  import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
2
  import { LitElement } from "lit";
3
- import { customElement, state } from "lit/decorators.js";
3
+ import { customElement, property } from "lit/decorators.js";
4
4
  import { createRef } from "lit/directives/ref.js";
5
5
 
6
6
  //#region src/gui/EFFitScale.ts
7
+ /**
8
+ * Compute the scale factor and centering translation needed to fit
9
+ * content of a given size into a container while preserving aspect ratio.
10
+ *
11
+ * Returns `null` when any dimension is zero or negative (cannot compute).
12
+ */
13
+ function computeFitScale(input) {
14
+ const { containerWidth, containerHeight, contentWidth, contentHeight } = input;
15
+ if (containerWidth <= 0 || containerHeight <= 0 || contentWidth <= 0 || contentHeight <= 0) return null;
16
+ const scale = containerWidth / containerHeight > contentWidth / contentHeight ? containerHeight / contentHeight : containerWidth / contentWidth;
17
+ const scaledWidth = contentWidth * scale;
18
+ const scaledHeight = contentHeight * scale;
19
+ return {
20
+ scale,
21
+ translateX: (containerWidth - scaledWidth) / 2,
22
+ translateY: (containerHeight - scaledHeight) / 2
23
+ };
24
+ }
7
25
  let EFFitScale = class EFFitScale$1 extends LitElement {
8
26
  constructor(..._args) {
9
27
  super(..._args);
10
28
  this.containerRef = createRef();
11
29
  this.contentRef = createRef();
12
30
  this.uniqueId = Math.random().toString(36).substring(2, 15);
13
- this.scale = 1;
31
+ this.paused = false;
32
+ this.observedContentChild = null;
33
+ this.hasWarnedZeroDimensions = false;
14
34
  this.scaleLastSetOn = null;
15
- this.setScale = () => {
16
- if (this.isConnected) {
17
- const { scale, containerWidth, containerHeight, contentWidth, contentHeight } = this.scaleInfo;
18
- if (this.contentChild && contentWidth > 0 && contentHeight > 0) {
19
- const scaledWidth = contentWidth * scale;
20
- const scaledHeight = contentHeight * scale;
21
- const translateX = (containerWidth - scaledWidth) / 2;
22
- const translateY = (containerHeight - scaledHeight) / 2;
23
- if (this.scaleLastSetOn !== this.contentChild) this.removeScale();
24
- Object.assign(this.contentChild.style, {
25
- width: `${contentWidth}px`,
26
- height: `${contentHeight}px`,
27
- transform: `translate(${translateX.toFixed(4)}px, ${translateY.toFixed(4)}px) scale(${scale.toFixed(4)})`,
28
- transformOrigin: "top left"
29
- });
30
- this.scale = scale;
31
- this.scaleLastSetOn = this.contentChild;
35
+ this.updateScale = () => {
36
+ if (!this.isConnected || this.paused) return;
37
+ const { containerWidth, containerHeight, contentWidth, contentHeight } = this.scaleInfo;
38
+ if (containerWidth === 0 || containerHeight === 0) {
39
+ if (!this.hasWarnedZeroDimensions) {
40
+ this.hasWarnedZeroDimensions = true;
41
+ console.warn(`[ef-fit-scale] Container has zero dimensions (${containerWidth}×${containerHeight}). Content will be invisible. Ensure all ancestors have resolved height.`, this);
32
42
  }
33
- this.animationFrameId = requestAnimationFrame(this.setScale);
43
+ return;
44
+ }
45
+ this.hasWarnedZeroDimensions = false;
46
+ if (this.contentChild && contentWidth > 0 && contentHeight > 0) {
47
+ const result = computeFitScale({
48
+ containerWidth,
49
+ containerHeight,
50
+ contentWidth,
51
+ contentHeight
52
+ });
53
+ if (!result) return;
54
+ if (this.scaleLastSetOn !== this.contentChild) this.removeScale();
55
+ Object.assign(this.contentChild.style, {
56
+ width: `${contentWidth}px`,
57
+ height: `${contentHeight}px`,
58
+ transform: `translate(${result.translateX.toFixed(4)}px, ${result.translateY.toFixed(4)}px) scale(${result.scale.toFixed(4)})`,
59
+ transformOrigin: "top left"
60
+ });
61
+ this.scaleLastSetOn = this.contentChild;
34
62
  }
35
63
  };
36
64
  this.removeScale = () => {
@@ -54,12 +82,15 @@ let EFFitScale = class EFFitScale$1 extends LitElement {
54
82
  gridTemplateRows: "100%",
55
83
  overflow: "hidden",
56
84
  boxSizing: "border-box",
57
- contain: "strict",
85
+ contain: "layout paint style",
58
86
  position: "relative"
59
87
  });
60
88
  this.id = `${this.uniqueId}`;
61
89
  return this;
62
90
  }
91
+ updated(changedProperties) {
92
+ if (changedProperties.has("paused") && !this.paused) this.updateScale();
93
+ }
63
94
  get contentChild() {
64
95
  if (!this.children.length) return null;
65
96
  const isNonContentElement = (element) => {
@@ -143,26 +174,57 @@ let EFFitScale = class EFFitScale$1 extends LitElement {
143
174
  contentHeight: 0
144
175
  };
145
176
  return {
146
- scale: containerWidth / containerHeight > contentWidth / contentHeight ? containerHeight / contentHeight : containerWidth / contentWidth,
177
+ scale: computeFitScale({
178
+ containerWidth,
179
+ containerHeight,
180
+ contentWidth,
181
+ contentHeight
182
+ })?.scale ?? 1,
147
183
  containerWidth,
148
184
  containerHeight,
149
185
  contentWidth,
150
186
  contentHeight
151
187
  };
152
188
  }
189
+ observeContentChild() {
190
+ const child = this.contentChild;
191
+ if (child === this.observedContentChild) return;
192
+ this.contentResizeObserver?.disconnect();
193
+ if (child) {
194
+ this.contentResizeObserver = new ResizeObserver(() => {
195
+ this.updateScale();
196
+ });
197
+ this.contentResizeObserver.observe(child);
198
+ }
199
+ this.observedContentChild = child;
200
+ }
153
201
  connectedCallback() {
154
202
  super.connectedCallback();
155
- this.animationFrameId = requestAnimationFrame(this.setScale);
203
+ this.hasWarnedZeroDimensions = false;
204
+ this.containerResizeObserver = new ResizeObserver(() => {
205
+ this.updateScale();
206
+ });
207
+ this.containerResizeObserver.observe(this);
208
+ this.childMutationObserver = new MutationObserver(() => {
209
+ this.observeContentChild();
210
+ this.updateScale();
211
+ });
212
+ this.childMutationObserver.observe(this, { childList: true });
213
+ this.observeContentChild();
214
+ requestAnimationFrame(() => this.updateScale());
156
215
  }
157
216
  disconnectedCallback() {
158
217
  super.disconnectedCallback();
159
218
  this.removeScale();
160
- if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);
219
+ this.containerResizeObserver?.disconnect();
220
+ this.contentResizeObserver?.disconnect();
221
+ this.childMutationObserver?.disconnect();
222
+ this.observedContentChild = null;
161
223
  }
162
224
  };
163
- __decorate([state()], EFFitScale.prototype, "scale", void 0);
225
+ __decorate([property({ type: Boolean })], EFFitScale.prototype, "paused", void 0);
164
226
  EFFitScale = __decorate([customElement("ef-fit-scale")], EFFitScale);
165
227
 
166
228
  //#endregion
167
- export { EFFitScale };
229
+ export { EFFitScale, computeFitScale };
168
230
  //# sourceMappingURL=EFFitScale.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EFFitScale.js","names":["EFFitScale","results: HTMLElement[]","children","allContentElements: HTMLElement[]"],"sources":["../../src/gui/EFFitScale.ts"],"sourcesContent":["import { LitElement } from \"lit\";\nimport { customElement, state } from \"lit/decorators.js\";\nimport { createRef } from \"lit/directives/ref.js\";\n\n@customElement(\"ef-fit-scale\")\nexport class EFFitScale extends LitElement {\n containerRef = createRef<HTMLDivElement>();\n contentRef = createRef<HTMLSlotElement>();\n\n createRenderRoot() {\n Object.assign(this.style, {\n display: \"grid\",\n width: \"100%\",\n height: \"100%\",\n gridTemplateColumns: \"100%\",\n gridTemplateRows: \"100%\",\n overflow: \"hidden\",\n boxSizing: \"border-box\",\n contain: \"strict\",\n position: \"relative\",\n });\n this.id = `${this.uniqueId}`;\n return this;\n }\n\n uniqueId = Math.random().toString(36).substring(2, 15);\n\n @state()\n private scale = 1;\n\n private animationFrameId?: number;\n\n get contentChild() {\n if (!this.children.length) return null;\n\n const isNonContentElement = (element: Element): boolean => {\n const tagName = element.tagName.toLowerCase();\n const nonContentTags = [\n \"style\",\n \"script\",\n \"meta\",\n \"link\",\n \"title\",\n \"noscript\",\n ];\n if (nonContentTags.includes(tagName)) return true;\n\n try {\n const display = window.getComputedStyle(element).display;\n return display === \"none\" || display === \"contents\";\n } catch {\n return false;\n }\n };\n\n const findAllContentElements = (element: Element): HTMLElement[] => {\n const results: HTMLElement[] = [];\n\n if (element instanceof HTMLSlotElement) {\n const assigned = element.assignedElements()[0];\n if (assigned) {\n results.push(...findAllContentElements(assigned));\n }\n return results;\n }\n\n if (!isNonContentElement(element)) {\n results.push(element as HTMLElement);\n }\n\n const children = Array.from(element.children);\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child) {\n results.push(...findAllContentElements(child));\n }\n }\n\n return results;\n };\n\n const children = Array.from(this.children);\n const allContentElements: HTMLElement[] = [];\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child) {\n allContentElements.push(...findAllContentElements(child));\n }\n }\n\n if (allContentElements.length === 0) return null;\n\n return allContentElements[0] ?? null;\n }\n\n get scaleInfo() {\n if (!this.contentChild) {\n return {\n scale: 1,\n containerWidth: 0,\n containerHeight: 0,\n contentWidth: 0,\n contentHeight: 0,\n };\n }\n\n const containerWidth = this.clientWidth;\n const containerHeight = this.clientHeight;\n\n // Try to get natural dimensions from media elements (ef-video, ef-image)\n let contentWidth = 0;\n let contentHeight = 0;\n\n if (typeof (this.contentChild as any).getNaturalDimensions === \"function\") {\n const naturalDimensions = (\n this.contentChild as any\n ).getNaturalDimensions() as { width: number; height: number } | null;\n if (\n naturalDimensions &&\n naturalDimensions.width > 0 &&\n naturalDimensions.height > 0\n ) {\n contentWidth = naturalDimensions.width;\n contentHeight = naturalDimensions.height;\n\n // ESSENTIAL: For ef-video, set canvas to explicit pixel dimensions to break 100% circular dependency\n // Canvas default CSS is width:100%, height:100% which would make ef-video collapse to 0x0\n // when ef-video is set to width:auto, height:auto by ElementRenderer\n if (this.contentChild.tagName === \"EF-VIDEO\") {\n const canvas = (this.contentChild as any).canvasElement;\n if (canvas) {\n canvas.style.setProperty(\"width\", `${contentWidth}px`, \"important\");\n canvas.style.setProperty(\n \"height\",\n `${contentHeight}px`,\n \"important\",\n );\n }\n }\n } else {\n // Natural dimensions not available yet, fall back to client dimensions\n contentWidth = this.contentChild.clientWidth;\n contentHeight = this.contentChild.clientHeight;\n }\n } else {\n // For other elements, use clientWidth/Height\n contentWidth = this.contentChild.clientWidth;\n contentHeight = this.contentChild.clientHeight;\n }\n\n if (contentWidth === 0 || contentHeight === 0) {\n return {\n scale: 1,\n containerWidth,\n containerHeight,\n contentWidth: 0,\n contentHeight: 0,\n };\n }\n\n const containerRatio = containerWidth / containerHeight;\n const contentRatio = contentWidth / contentHeight;\n\n const scale =\n containerRatio > contentRatio\n ? containerHeight / contentHeight\n : containerWidth / contentWidth;\n\n return {\n scale,\n containerWidth,\n containerHeight,\n contentWidth,\n contentHeight,\n };\n }\n\n scaleLastSetOn: HTMLElement | null = null;\n\n setScale = () => {\n if (this.isConnected) {\n const scaleInfo = this.scaleInfo;\n const {\n scale,\n containerWidth,\n containerHeight,\n contentWidth,\n contentHeight,\n } = scaleInfo;\n\n if (this.contentChild && contentWidth > 0 && contentHeight > 0) {\n // Calculate scaled dimensions using natural size from scaleInfo\n const scaledWidth = contentWidth * scale;\n const scaledHeight = contentHeight * scale;\n const translateX = (containerWidth - scaledWidth) / 2;\n const translateY = (containerHeight - scaledHeight) / 2;\n\n // In the rare event that the content child is changed, we need to remove the scale\n // because we don't want to have a scale on the old content child that is somewhere else in the DOM\n if (this.scaleLastSetOn !== this.contentChild) {\n this.removeScale();\n }\n // Use toFixed to avoid floating point precision issues\n // this will update every frame with sub-pixel changes if we don't pin it down\n Object.assign(this.contentChild.style, {\n width: `${contentWidth}px`,\n height: `${contentHeight}px`,\n transform: `translate(${translateX.toFixed(4)}px, ${translateY.toFixed(4)}px) scale(${scale.toFixed(4)})`,\n transformOrigin: \"top left\",\n });\n this.scale = scale;\n this.scaleLastSetOn = this.contentChild;\n }\n this.animationFrameId = requestAnimationFrame(this.setScale);\n }\n };\n\n removeScale = () => {\n if (this.scaleLastSetOn) {\n Object.assign(this.scaleLastSetOn.style, {\n width: \"\",\n height: \"\",\n transform: \"\",\n transformOrigin: \"\",\n });\n this.scaleLastSetOn = null;\n }\n };\n\n connectedCallback(): void {\n super.connectedCallback();\n this.animationFrameId = requestAnimationFrame(this.setScale);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeScale();\n if (this.animationFrameId) {\n cancelAnimationFrame(this.animationFrameId);\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-fit-scale\": EFFitScale;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EFFitScale.js","names":["EFFitScale","results: HTMLElement[]","children","allContentElements: HTMLElement[]"],"sources":["../../src/gui/EFFitScale.ts"],"sourcesContent":["import { LitElement } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { createRef } from \"lit/directives/ref.js\";\n\n/* ━━ Pure scale calculation ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\n\nexport interface ScaleInput {\n containerWidth: number;\n containerHeight: number;\n contentWidth: number;\n contentHeight: number;\n}\n\nexport interface ScaleOutput {\n scale: number;\n translateX: number;\n translateY: number;\n}\n\n/**\n * Compute the scale factor and centering translation needed to fit\n * content of a given size into a container while preserving aspect ratio.\n *\n * Returns `null` when any dimension is zero or negative (cannot compute).\n */\nexport function computeFitScale(input: ScaleInput): ScaleOutput | null {\n const { containerWidth, containerHeight, contentWidth, contentHeight } =\n input;\n\n if (\n containerWidth <= 0 ||\n containerHeight <= 0 ||\n contentWidth <= 0 ||\n contentHeight <= 0\n ) {\n return null;\n }\n\n const containerRatio = containerWidth / containerHeight;\n const contentRatio = contentWidth / contentHeight;\n\n const scale =\n containerRatio > contentRatio\n ? containerHeight / contentHeight\n : containerWidth / contentWidth;\n\n const scaledWidth = contentWidth * scale;\n const scaledHeight = contentHeight * scale;\n const translateX = (containerWidth - scaledWidth) / 2;\n const translateY = (containerHeight - scaledHeight) / 2;\n\n return { scale, translateX, translateY };\n}\n\n/* ━━ Component ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\n\n@customElement(\"ef-fit-scale\")\nexport class EFFitScale extends LitElement {\n containerRef = createRef<HTMLDivElement>();\n contentRef = createRef<HTMLSlotElement>();\n\n createRenderRoot() {\n Object.assign(this.style, {\n display: \"grid\",\n width: \"100%\",\n height: \"100%\",\n gridTemplateColumns: \"100%\",\n gridTemplateRows: \"100%\",\n overflow: \"hidden\",\n boxSizing: \"border-box\",\n contain: \"layout paint style\",\n position: \"relative\",\n });\n this.id = `${this.uniqueId}`;\n return this;\n }\n\n uniqueId = Math.random().toString(36).substring(2, 15);\n\n @property({ type: Boolean })\n paused = false;\n\n updated(changedProperties: Map<string, unknown>): void {\n if (changedProperties.has(\"paused\") && !this.paused) {\n // When unpaused, immediately recalculate scale\n this.updateScale();\n }\n }\n\n private containerResizeObserver?: ResizeObserver;\n private contentResizeObserver?: ResizeObserver;\n private childMutationObserver?: MutationObserver;\n private observedContentChild: HTMLElement | null = null;\n private hasWarnedZeroDimensions = false;\n\n get contentChild() {\n if (!this.children.length) return null;\n\n const isNonContentElement = (element: Element): boolean => {\n const tagName = element.tagName.toLowerCase();\n const nonContentTags = [\n \"style\",\n \"script\",\n \"meta\",\n \"link\",\n \"title\",\n \"noscript\",\n ];\n if (nonContentTags.includes(tagName)) return true;\n\n try {\n const display = window.getComputedStyle(element).display;\n return display === \"none\" || display === \"contents\";\n } catch {\n return false;\n }\n };\n\n const findAllContentElements = (element: Element): HTMLElement[] => {\n const results: HTMLElement[] = [];\n\n if (element instanceof HTMLSlotElement) {\n const assigned = element.assignedElements()[0];\n if (assigned) {\n results.push(...findAllContentElements(assigned));\n }\n return results;\n }\n\n if (!isNonContentElement(element)) {\n results.push(element as HTMLElement);\n }\n\n const children = Array.from(element.children);\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child) {\n results.push(...findAllContentElements(child));\n }\n }\n\n return results;\n };\n\n const children = Array.from(this.children);\n const allContentElements: HTMLElement[] = [];\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child) {\n allContentElements.push(...findAllContentElements(child));\n }\n }\n\n if (allContentElements.length === 0) return null;\n\n return allContentElements[0] ?? null;\n }\n\n get scaleInfo() {\n if (!this.contentChild) {\n return {\n scale: 1,\n containerWidth: 0,\n containerHeight: 0,\n contentWidth: 0,\n contentHeight: 0,\n };\n }\n\n const containerWidth = this.clientWidth;\n const containerHeight = this.clientHeight;\n\n // Try to get natural dimensions from media elements (ef-video, ef-image)\n let contentWidth = 0;\n let contentHeight = 0;\n\n if (typeof (this.contentChild as any).getNaturalDimensions === \"function\") {\n const naturalDimensions = (\n this.contentChild as any\n ).getNaturalDimensions() as { width: number; height: number } | null;\n if (\n naturalDimensions &&\n naturalDimensions.width > 0 &&\n naturalDimensions.height > 0\n ) {\n contentWidth = naturalDimensions.width;\n contentHeight = naturalDimensions.height;\n\n // ESSENTIAL: For ef-video, set canvas to explicit pixel dimensions to break 100% circular dependency\n // Canvas default CSS is width:100%, height:100% which would make ef-video collapse to 0x0\n // when ef-video is set to width:auto, height:auto by ElementRenderer\n if (this.contentChild.tagName === \"EF-VIDEO\") {\n const canvas = (this.contentChild as any).canvasElement;\n if (canvas) {\n canvas.style.setProperty(\"width\", `${contentWidth}px`, \"important\");\n canvas.style.setProperty(\n \"height\",\n `${contentHeight}px`,\n \"important\",\n );\n }\n }\n } else {\n // Natural dimensions not available yet, fall back to client dimensions\n contentWidth = this.contentChild.clientWidth;\n contentHeight = this.contentChild.clientHeight;\n }\n } else {\n // For other elements, use clientWidth/Height\n contentWidth = this.contentChild.clientWidth;\n contentHeight = this.contentChild.clientHeight;\n }\n\n if (contentWidth === 0 || contentHeight === 0) {\n return {\n scale: 1,\n containerWidth,\n containerHeight,\n contentWidth: 0,\n contentHeight: 0,\n };\n }\n\n const result = computeFitScale({\n containerWidth,\n containerHeight,\n contentWidth,\n contentHeight,\n });\n\n return {\n scale: result?.scale ?? 1,\n containerWidth,\n containerHeight,\n contentWidth,\n contentHeight,\n };\n }\n\n scaleLastSetOn: HTMLElement | null = null;\n\n private updateScale = (): void => {\n if (!this.isConnected || this.paused) return;\n\n const { containerWidth, containerHeight, contentWidth, contentHeight } =\n this.scaleInfo;\n\n // Warn on zero container dimensions\n if (containerWidth === 0 || containerHeight === 0) {\n if (!this.hasWarnedZeroDimensions) {\n this.hasWarnedZeroDimensions = true;\n console.warn(\n `[ef-fit-scale] Container has zero dimensions (${containerWidth}×${containerHeight}). ` +\n `Content will be invisible. Ensure all ancestors have resolved height.`,\n this,\n );\n }\n return;\n }\n\n // Reset warning flag when dimensions become valid\n this.hasWarnedZeroDimensions = false;\n\n if (this.contentChild && contentWidth > 0 && contentHeight > 0) {\n const result = computeFitScale({\n containerWidth,\n containerHeight,\n contentWidth,\n contentHeight,\n });\n\n if (!result) return;\n\n // In the rare event that the content child is changed, we need to remove the scale\n // because we don't want to have a scale on the old content child that is somewhere else in the DOM\n if (this.scaleLastSetOn !== this.contentChild) {\n this.removeScale();\n }\n // Use toFixed to avoid floating point precision issues\n // this will update every frame with sub-pixel changes if we don't pin it down\n Object.assign(this.contentChild.style, {\n width: `${contentWidth}px`,\n height: `${contentHeight}px`,\n transform: `translate(${result.translateX.toFixed(4)}px, ${result.translateY.toFixed(4)}px) scale(${result.scale.toFixed(4)})`,\n transformOrigin: \"top left\",\n });\n this.scaleLastSetOn = this.contentChild;\n }\n };\n\n private observeContentChild(): void {\n const child = this.contentChild;\n if (child === this.observedContentChild) return;\n\n // Stop observing old child\n this.contentResizeObserver?.disconnect();\n\n // Observe new child\n if (child) {\n this.contentResizeObserver = new ResizeObserver(() => {\n this.updateScale();\n });\n this.contentResizeObserver.observe(child);\n }\n this.observedContentChild = child;\n }\n\n removeScale = () => {\n if (this.scaleLastSetOn) {\n Object.assign(this.scaleLastSetOn.style, {\n width: \"\",\n height: \"\",\n transform: \"\",\n transformOrigin: \"\",\n });\n this.scaleLastSetOn = null;\n }\n };\n\n connectedCallback(): void {\n super.connectedCallback();\n\n this.hasWarnedZeroDimensions = false;\n\n // Observe self for container size changes\n this.containerResizeObserver = new ResizeObserver(() => {\n this.updateScale();\n });\n this.containerResizeObserver.observe(this);\n\n // Observe child list for content child changes\n this.childMutationObserver = new MutationObserver(() => {\n this.observeContentChild();\n this.updateScale();\n });\n this.childMutationObserver.observe(this, { childList: true });\n\n // Initial content child observation\n this.observeContentChild();\n\n // Initial scale calculation (deferred to allow layout to settle)\n requestAnimationFrame(() => this.updateScale());\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeScale();\n this.containerResizeObserver?.disconnect();\n this.contentResizeObserver?.disconnect();\n this.childMutationObserver?.disconnect();\n this.observedContentChild = null;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-fit-scale\": EFFitScale;\n }\n}\n"],"mappings":"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"}
@@ -1,16 +1,16 @@
1
- import * as lit23 from "lit";
1
+ import * as lit25 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html22 from "lit-html";
3
+ import * as lit_html23 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: lit23.CSSResult;
8
+ static styles: lit25.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_html22.TemplateResult<1>;
13
+ render(): lit_html23.TemplateResult<1>;
14
14
  connectedCallback(): void;
15
15
  disconnectedCallback(): void;
16
16
  protected updated(): void;
@@ -36,9 +36,9 @@ let EFFocusOverlay = class EFFocusOverlay$1 extends LitElement {
36
36
  }
37
37
  .overlay {
38
38
  position: fixed;
39
- outline: 2px solid var(--ef-focus-overlay-color, rgb(59, 130, 246));
40
- background: var(--ef-focus-overlay-background, rgb(59, 130, 246));
41
- outline: 2px solid var(--ef-focus-overlay-color, rgb(59, 130, 246));
39
+ outline: 2px solid var(--ef-focus-overlay-color, var(--ef-color-primary));
40
+ background: var(--ef-focus-overlay-background, var(--ef-color-primary));
41
+ outline: 2px solid var(--ef-focus-overlay-color, var(--ef-color-primary));
42
42
  mix-blend-mode: multiply;
43
43
  opacity: 0.4;
44
44
  display: none;
@@ -1 +1 @@
1
- {"version":3,"file":"EFFocusOverlay.js","names":["EFFocusOverlay"],"sources":["../../src/gui/EFFocusOverlay.ts"],"sourcesContent":["import { consume } from \"@lit/context\";\nimport { css, html, LitElement } from \"lit\";\nimport { customElement } from \"lit/decorators.js\";\nimport { createRef, ref } from \"lit/directives/ref.js\";\nimport { focusedElementContext } from \"./focusedElementContext.js\";\n\n@customElement(\"ef-focus-overlay\")\nexport class EFFocusOverlay extends LitElement {\n static styles = css`\n :host {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n pointer-events: none;\n }\n .overlay {\n position: fixed;\n outline: 2px solid var(--ef-focus-overlay-color, rgb(59, 130, 246));\n background: var(--ef-focus-overlay-background, rgb(59, 130, 246));\n outline: 2px solid var(--ef-focus-overlay-color, rgb(59, 130, 246));\n mix-blend-mode: multiply;\n opacity: 0.4;\n display: none;\n }\n `;\n\n @consume({ context: focusedElementContext, subscribe: true })\n focusedElement?: HTMLElement | null;\n\n overlay = createRef<HTMLDivElement>();\n\n private animationFrame?: number;\n\n drawOverlay = () => {\n const overlay = this.overlay.value;\n if (overlay) {\n if (this.focusedElement) {\n overlay.style.display = \"block\";\n const rect = this.focusedElement.getBoundingClientRect();\n Object.assign(overlay.style, {\n top: `${rect.top}px`,\n left: `${rect.left}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n });\n this.animationFrame = requestAnimationFrame(this.drawOverlay);\n } else {\n overlay.style.display = \"none\";\n }\n }\n };\n\n render() {\n return html`<div ${ref(this.overlay)} class=\"overlay\"></div>`;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.drawOverlay();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame);\n }\n }\n\n protected updated(): void {\n this.drawOverlay();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-focus-overlay\": EFFocusOverlay;\n }\n}\n"],"mappings":";;;;;;;;AAOO,2BAAMA,yBAAuB,WAAW;;;iBAuBnC,WAA2B;2BAIjB;GAClB,MAAM,UAAU,KAAK,QAAQ;AAC7B,OAAI,QACF,KAAI,KAAK,gBAAgB;AACvB,YAAQ,MAAM,UAAU;IACxB,MAAM,OAAO,KAAK,eAAe,uBAAuB;AACxD,WAAO,OAAO,QAAQ,OAAO;KAC3B,KAAK,GAAG,KAAK,IAAI;KACjB,MAAM,GAAG,KAAK,KAAK;KACnB,OAAO,GAAG,KAAK,MAAM;KACrB,QAAQ,GAAG,KAAK,OAAO;KACxB,CAAC;AACF,SAAK,iBAAiB,sBAAsB,KAAK,YAAY;SAE7D,SAAQ,MAAM,UAAU;;;;gBAxCd,GAAG;;;;;;;;;;;;;;;;;;;CA6CnB,SAAS;AACP,SAAO,IAAI,QAAQ,IAAI,KAAK,QAAQ,CAAC;;CAGvC,oBAA0B;AACxB,QAAM,mBAAmB;AACzB,OAAK,aAAa;;CAGpB,uBAA6B;AAC3B,QAAM,sBAAsB;AAC5B,MAAI,KAAK,eACP,sBAAqB,KAAK,eAAe;;CAI7C,AAAU,UAAgB;AACxB,OAAK,aAAa;;;YA3CnB,QAAQ;CAAE,SAAS;CAAuB,WAAW;CAAM,CAAC;6BArB9D,cAAc,mBAAmB"}
1
+ {"version":3,"file":"EFFocusOverlay.js","names":["EFFocusOverlay"],"sources":["../../src/gui/EFFocusOverlay.ts"],"sourcesContent":["import { consume } from \"@lit/context\";\nimport { css, html, LitElement } from \"lit\";\nimport { customElement } from \"lit/decorators.js\";\nimport { createRef, ref } from \"lit/directives/ref.js\";\nimport { focusedElementContext } from \"./focusedElementContext.js\";\n\n@customElement(\"ef-focus-overlay\")\nexport class EFFocusOverlay extends LitElement {\n static styles = css`\n :host {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n pointer-events: none;\n }\n .overlay {\n position: fixed;\n outline: 2px solid var(--ef-focus-overlay-color, var(--ef-color-primary));\n background: var(--ef-focus-overlay-background, var(--ef-color-primary));\n outline: 2px solid var(--ef-focus-overlay-color, var(--ef-color-primary));\n mix-blend-mode: multiply;\n opacity: 0.4;\n display: none;\n }\n `;\n\n @consume({ context: focusedElementContext, subscribe: true })\n focusedElement?: HTMLElement | null;\n\n overlay = createRef<HTMLDivElement>();\n\n private animationFrame?: number;\n\n drawOverlay = () => {\n const overlay = this.overlay.value;\n if (overlay) {\n if (this.focusedElement) {\n overlay.style.display = \"block\";\n const rect = this.focusedElement.getBoundingClientRect();\n Object.assign(overlay.style, {\n top: `${rect.top}px`,\n left: `${rect.left}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n });\n this.animationFrame = requestAnimationFrame(this.drawOverlay);\n } else {\n overlay.style.display = \"none\";\n }\n }\n };\n\n render() {\n return html`<div ${ref(this.overlay)} class=\"overlay\"></div>`;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.drawOverlay();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame);\n }\n }\n\n protected updated(): void {\n this.drawOverlay();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-focus-overlay\": EFFocusOverlay;\n }\n}\n"],"mappings":";;;;;;;;AAOO,2BAAMA,yBAAuB,WAAW;;;iBAuBnC,WAA2B;2BAIjB;GAClB,MAAM,UAAU,KAAK,QAAQ;AAC7B,OAAI,QACF,KAAI,KAAK,gBAAgB;AACvB,YAAQ,MAAM,UAAU;IACxB,MAAM,OAAO,KAAK,eAAe,uBAAuB;AACxD,WAAO,OAAO,QAAQ,OAAO;KAC3B,KAAK,GAAG,KAAK,IAAI;KACjB,MAAM,GAAG,KAAK,KAAK;KACnB,OAAO,GAAG,KAAK,MAAM;KACrB,QAAQ,GAAG,KAAK,OAAO;KACxB,CAAC;AACF,SAAK,iBAAiB,sBAAsB,KAAK,YAAY;SAE7D,SAAQ,MAAM,UAAU;;;;gBAxCd,GAAG;;;;;;;;;;;;;;;;;;;CA6CnB,SAAS;AACP,SAAO,IAAI,QAAQ,IAAI,KAAK,QAAQ,CAAC;;CAGvC,oBAA0B;AACxB,QAAM,mBAAmB;AACzB,OAAK,aAAa;;CAGpB,uBAA6B;AAC3B,QAAM,sBAAsB;AAC5B,MAAI,KAAK,eACP,sBAAqB,KAAK,eAAe;;CAI7C,AAAU,UAAgB;AACxB,OAAK,aAAa;;;YA3CnB,QAAQ;CAAE,SAAS;CAAuB,WAAW;CAAM,CAAC;6BArB9D,cAAc,mBAAmB"}
@@ -1,6 +1,6 @@
1
- import * as lit32 from "lit";
1
+ import * as lit31 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html31 from "lit-html";
3
+ import * as lit_html29 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: lit32.CSSResult[];
26
+ static styles: lit31.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_html31.TemplateResult<1>;
39
+ render(): lit_html29.TemplateResult<1>;
40
40
  }
41
41
  declare global {
42
42
  interface HTMLElementTagNameMap {
@@ -1,8 +1,8 @@
1
1
  import { PanZoomTransform } from "../elements/EFPanZoom.js";
2
2
  import { EFOverlayItem } from "./EFOverlayItem.js";
3
- import * as lit31 from "lit";
3
+ import * as lit26 from "lit";
4
4
  import { LitElement } from "lit";
5
- import * as lit_html30 from "lit-html";
5
+ import * as lit_html24 from "lit-html";
6
6
 
7
7
  //#region src/gui/EFOverlayLayer.d.ts
8
8
 
@@ -26,7 +26,7 @@ import * as lit_html30 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: lit31.CSSResult[];
29
+ static styles: lit26.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_html30.TemplateResult<1>;
61
+ render(): lit_html24.TemplateResult<1>;
62
62
  }
63
63
  declare global {
64
64
  interface HTMLElementTagNameMap {
@@ -1,7 +1,7 @@
1
1
  import { ControllableInterface } from "./Controllable.js";
2
- import * as lit16 from "lit";
2
+ import * as lit18 from "lit";
3
3
  import { LitElement } from "lit";
4
- import * as lit_html16 from "lit-html";
4
+ import * as lit_html17 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: lit16.CSSResult[];
13
+ static styles: lit18.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_html16.TemplateResult<1>;
19
+ render(): lit_html17.TemplateResult<1>;
20
20
  handleClick: () => void;
21
21
  }
22
22
  declare global {
@@ -1,6 +1,6 @@
1
+ import { efContext } from "./efContext.js";
1
2
  import { playingContext } from "./playingContext.js";
2
3
  import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
3
- import { efContext } from "./efContext.js";
4
4
  import { attachContextRoot } from "../attachContextRoot.js";
5
5
  import { TargetOrContextMixin } from "./TargetOrContextMixin.js";
6
6
  import { consume } from "@lit/context";
@@ -1,7 +1,7 @@
1
1
  import { ControllableInterface } from "./Controllable.js";
2
- import * as lit15 from "lit";
2
+ import * as lit17 from "lit";
3
3
  import { LitElement } from "lit";
4
- import * as lit_html15 from "lit-html";
4
+ import * as lit_html16 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: lit15.CSSResult[];
13
+ static styles: lit17.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_html15.TemplateResult<1>;
19
+ render(): lit_html16.TemplateResult<1>;
20
20
  handleClick: () => void;
21
21
  }
22
22
  declare global {
@@ -1,6 +1,6 @@
1
+ import { efContext } from "./efContext.js";
1
2
  import { playingContext } from "./playingContext.js";
2
3
  import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
3
- import { efContext } from "./efContext.js";
4
4
  import { attachContextRoot } from "../attachContextRoot.js";
5
5
  import { TargetOrContextMixin } from "./TargetOrContextMixin.js";
6
6
  import { consume } from "@lit/context";
@@ -1,8 +1,8 @@
1
+ import { TWMixin } from "./TWMixin2.js";
1
2
  import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
2
3
  import { isEFTemporal } from "../elements/EFTemporal.js";
3
4
  import { focusedElementContext } from "./focusedElementContext.js";
4
5
  import { ContextMixin } from "./ContextMixin.js";
5
- import { TWMixin } from "./TWMixin2.js";
6
6
  import { EFTargetable } from "../elements/TargetController.js";
7
7
  import { provide } from "@lit/context";
8
8
  import { LitElement, css, html } from "lit";
@@ -1,6 +1,6 @@
1
- import * as lit25 from "lit";
1
+ import * as lit27 from "lit";
2
2
  import { LitElement } from "lit";
3
- import * as lit_html24 from "lit-html";
3
+ import * as lit_html25 from "lit-html";
4
4
 
5
5
  //#region src/gui/EFResizableBox.d.ts
6
6
  interface BoxBounds {
@@ -21,7 +21,7 @@ declare class EFResizableBox extends LitElement {
21
21
  private resizeStartCorner;
22
22
  private resizeStartSize;
23
23
  private resizeStartPosition;
24
- static styles: lit25.CSSResult;
24
+ static styles: lit27.CSSResult;
25
25
  private resizeObserver?;
26
26
  connectedCallback(): void;
27
27
  disconnectedCallback(): void;
@@ -30,7 +30,7 @@ declare class EFResizableBox extends LitElement {
30
30
  private handlePointerUp;
31
31
  private cleanup;
32
32
  private dispatchBoundsChange;
33
- render(): lit_html24.TemplateResult<1>;
33
+ render(): lit_html25.TemplateResult<1>;
34
34
  }
35
35
  //#endregion
36
36
  export { BoxBounds, EFResizableBox };
@@ -101,17 +101,17 @@ let EFResizableBox = class EFResizableBox$1 extends LitElement {
101
101
  this.styles = css`
102
102
  .box {
103
103
  position: absolute;
104
- border: 2px solid var(--ef-resizable-box-border-color, #3b82f6);
105
- background-color: var(--ef-resizable-box-bg-color, rgba(59, 130, 246, 0.2));
104
+ border: 2px solid var(--ef-resizable-box-border-color, var(--ef-color-primary));
105
+ background-color: var(--ef-resizable-box-bg-color, color-mix(in srgb, var(--ef-color-primary) 20%, transparent));
106
106
  cursor: grab;
107
107
  }
108
108
  .box.dragging {
109
- border-color: var(--ef-resizable-box-dragging-border-color, #2563eb);
110
- background-color: var(--ef-resizable-box-dragging-bg-color, rgba(37, 99, 235, 0.3));
109
+ border-color: var(--ef-resizable-box-dragging-border-color, var(--ef-color-primary));
110
+ background-color: var(--ef-resizable-box-dragging-bg-color, color-mix(in srgb, var(--ef-color-primary) 30%, transparent));
111
111
  }
112
112
  .handle {
113
113
  position: absolute;
114
- background-color: var(--ef-resizable-box-handle-color, #3b82f6);
114
+ background-color: var(--ef-resizable-box-handle-color, var(--ef-color-primary));
115
115
  touch-action: none;
116
116
  }
117
117
  .handle.nw { top: -4px; left: -4px; width: 8px; height: 8px; cursor: nwse-resize; }
@@ -1 +1 @@
1
- {"version":3,"file":"EFResizableBox.js","names":["EFResizableBox"],"sources":["../../src/gui/EFResizableBox.ts"],"sourcesContent":["import { css, html, LitElement } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { getCornerPoint, getOppositeCorner } from \"./transformUtils.js\";\n\nconst DEFAULT_MIN_SIZE = 10;\n\nexport interface BoxBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ntype ResizeHandle = \"nw\" | \"n\" | \"ne\" | \"e\" | \"se\" | \"s\" | \"sw\" | \"w\";\n\nfunction mapHandleToLegacy(handle: ResizeHandle): string {\n const map: Record<ResizeHandle, string> = {\n nw: \"top-left\",\n n: \"top\",\n ne: \"top-right\",\n e: \"right\",\n se: \"bottom-right\",\n s: \"bottom\",\n sw: \"bottom-left\",\n w: \"left\",\n };\n return map[handle];\n}\n\n@customElement(\"ef-resizable-box\")\nexport class EFResizableBox extends LitElement {\n @property({ type: Object })\n bounds: BoxBounds = { x: 0, y: 0, width: 100, height: 100 };\n\n @state()\n private containerWidth = 0;\n\n @state()\n private containerHeight = 0;\n\n @property({ type: Number })\n minSize = DEFAULT_MIN_SIZE;\n\n @state()\n private isDragging = false;\n\n @state()\n private isResizing: ResizeHandle | null = null;\n\n private dragStart: { x: number; y: number } | null = null;\n private dragStartPosition: { x: number; y: number } = { x: 0, y: 0 };\n private resizeStartCorner: { x: number; y: number } | null = null;\n private resizeStartSize: { width: number; height: number } | null = null;\n private resizeStartPosition: { x: number; y: number } | null = null;\n\n static styles = css`\n .box {\n position: absolute;\n border: 2px solid var(--ef-resizable-box-border-color, #3b82f6);\n background-color: var(--ef-resizable-box-bg-color, rgba(59, 130, 246, 0.2));\n cursor: grab;\n }\n .box.dragging {\n border-color: var(--ef-resizable-box-dragging-border-color, #2563eb);\n background-color: var(--ef-resizable-box-dragging-bg-color, rgba(37, 99, 235, 0.3));\n }\n .handle {\n position: absolute;\n background-color: var(--ef-resizable-box-handle-color, #3b82f6);\n touch-action: none;\n }\n .handle.nw { top: -4px; left: -4px; width: 8px; height: 8px; cursor: nwse-resize; }\n .handle.ne { top: -4px; right: -4px; width: 8px; height: 8px; cursor: nesw-resize; }\n .handle.sw { bottom: -4px; left: -4px; width: 8px; height: 8px; cursor: nesw-resize; }\n .handle.se { bottom: -4px; right: -4px; width: 8px; height: 8px; cursor: nwse-resize; }\n .handle.n { top: -4px; left: 4px; right: 4px; height: 8px; cursor: ns-resize; }\n .handle.e { top: 4px; bottom: 4px; right: -4px; width: 8px; cursor: ew-resize; }\n .handle.s { bottom: -4px; left: 4px; right: 4px; height: 8px; cursor: ns-resize; }\n .handle.w { top: 4px; bottom: 4px; left: -4px; width: 8px; cursor: ew-resize; }\n `;\n\n private resizeObserver?: ResizeObserver;\n\n connectedCallback() {\n super.connectedCallback();\n if (this.offsetParent) {\n this.containerWidth = this.offsetParent.clientWidth;\n this.containerHeight = this.offsetParent.clientHeight;\n }\n this.resizeObserver = new ResizeObserver(() => {\n if (this.offsetParent) {\n this.containerWidth = this.offsetParent.clientWidth;\n this.containerHeight = this.offsetParent.clientHeight;\n }\n });\n if (this.offsetParent) {\n this.resizeObserver.observe(this.offsetParent);\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.resizeObserver?.disconnect();\n this.cleanup();\n }\n\n private handlePointerDown = (\n e: PointerEvent,\n mode: \"move\" | \"resize\",\n handle?: ResizeHandle,\n ) => {\n e.preventDefault();\n e.stopPropagation();\n this.isDragging = true;\n this.isResizing = mode === \"resize\" ? handle || null : null;\n\n this.dragStart = { x: e.clientX, y: e.clientY };\n this.dragStartPosition = { x: this.bounds.x, y: this.bounds.y };\n\n if (mode === \"resize\" && handle) {\n const oppositeCorner = getOppositeCorner(handle);\n const rotationRadians = 0;\n const initialCorner = getCornerPoint(\n this.bounds.x,\n this.bounds.y,\n this.bounds.width,\n this.bounds.height,\n rotationRadians,\n oppositeCorner.x,\n oppositeCorner.y,\n );\n this.resizeStartCorner = initialCorner;\n this.resizeStartSize = {\n width: this.bounds.width,\n height: this.bounds.height,\n };\n this.resizeStartPosition = { x: this.bounds.x, y: this.bounds.y };\n }\n\n document.addEventListener(\"pointermove\", this.handlePointerMove, {\n passive: false,\n });\n document.addEventListener(\"pointerup\", this.handlePointerUp, {\n passive: false,\n });\n };\n\n private handlePointerMove = (e: PointerEvent) => {\n if (!this.isDragging || !this.dragStart) return;\n\n e.preventDefault();\n\n const deltaX = e.clientX - this.dragStart.x;\n const deltaY = e.clientY - this.dragStart.y;\n\n if (\n this.isResizing &&\n this.resizeStartCorner &&\n this.resizeStartSize &&\n this.resizeStartPosition\n ) {\n const oppositeCorner = getOppositeCorner(this.isResizing);\n const rotationRadians = 0;\n\n let newWidth = this.resizeStartSize.width;\n let newHeight = this.resizeStartSize.height;\n\n if (this.isResizing.includes(\"e\")) {\n newWidth = this.resizeStartSize.width + deltaX;\n } else if (this.isResizing.includes(\"w\")) {\n newWidth = this.resizeStartSize.width - deltaX;\n }\n\n if (this.isResizing.includes(\"s\")) {\n newHeight = this.resizeStartSize.height + deltaY;\n } else if (this.isResizing.includes(\"n\")) {\n newHeight = this.resizeStartSize.height - deltaY;\n }\n\n newWidth = Math.max(\n this.minSize,\n Math.min(this.containerWidth - this.bounds.x, newWidth),\n );\n newHeight = Math.max(\n this.minSize,\n Math.min(this.containerHeight - this.bounds.y, newHeight),\n );\n\n const newOppositeCorner = getCornerPoint(\n this.resizeStartPosition.x,\n this.resizeStartPosition.y,\n newWidth,\n newHeight,\n rotationRadians,\n oppositeCorner.x,\n oppositeCorner.y,\n );\n\n const offsetX = this.resizeStartCorner.x - newOppositeCorner.x;\n const offsetY = this.resizeStartCorner.y - newOppositeCorner.y;\n\n const newX = Math.max(\n 0,\n Math.min(\n this.containerWidth - newWidth,\n this.resizeStartPosition.x + offsetX,\n ),\n );\n const newY = Math.max(\n 0,\n Math.min(\n this.containerHeight - newHeight,\n this.resizeStartPosition.y + offsetY,\n ),\n );\n\n this.bounds = {\n x: newX,\n y: newY,\n width: newWidth,\n height: newHeight,\n };\n } else {\n const constrainedX = Math.max(\n 0,\n Math.min(\n this.containerWidth - this.bounds.width,\n this.dragStartPosition.x + deltaX,\n ),\n );\n const constrainedY = Math.max(\n 0,\n Math.min(\n this.containerHeight - this.bounds.height,\n this.dragStartPosition.y + deltaY,\n ),\n );\n\n this.bounds = {\n ...this.bounds,\n x: constrainedX,\n y: constrainedY,\n };\n }\n\n this.dispatchBoundsChange();\n };\n\n private handlePointerUp = (e: PointerEvent) => {\n e.preventDefault();\n this.cleanup();\n };\n\n private cleanup() {\n this.isDragging = false;\n this.isResizing = null;\n this.dragStart = null;\n this.dragStartPosition = { x: 0, y: 0 };\n this.resizeStartCorner = null;\n this.resizeStartSize = null;\n this.resizeStartPosition = null;\n document.removeEventListener(\"pointermove\", this.handlePointerMove);\n document.removeEventListener(\"pointerup\", this.handlePointerUp);\n }\n\n private dispatchBoundsChange() {\n this.dispatchEvent(\n new CustomEvent(\"bounds-change\", {\n detail: { bounds: this.bounds },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n render() {\n const boxStyles = {\n left: `${this.bounds.x}px`,\n top: `${this.bounds.y}px`,\n width: `${this.bounds.width}px`,\n height: `${this.bounds.height}px`,\n };\n\n const handles: ResizeHandle[] = [\n \"nw\",\n \"n\",\n \"ne\",\n \"e\",\n \"se\",\n \"s\",\n \"sw\",\n \"w\",\n ];\n\n return html`\n <div\n class=\"box ${this.isDragging ? \"dragging\" : \"\"}\"\n style=${styleMap(boxStyles)}\n @pointerdown=${(e: PointerEvent) => this.handlePointerDown(e, \"move\")}\n >\n ${handles.map(\n (handle) => html`\n <div\n class=\"handle ${handle}\"\n @pointerdown=${(e: PointerEvent) => {\n e.stopPropagation();\n this.handlePointerDown(e, \"resize\", handle);\n }}\n ></div>\n `,\n )}\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EFResizableBox.js","names":["EFResizableBox"],"sources":["../../src/gui/EFResizableBox.ts"],"sourcesContent":["import { css, html, LitElement } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { getCornerPoint, getOppositeCorner } from \"./transformUtils.js\";\n\nconst DEFAULT_MIN_SIZE = 10;\n\nexport interface BoxBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ntype ResizeHandle = \"nw\" | \"n\" | \"ne\" | \"e\" | \"se\" | \"s\" | \"sw\" | \"w\";\n\n@customElement(\"ef-resizable-box\")\nexport class EFResizableBox extends LitElement {\n @property({ type: Object })\n bounds: BoxBounds = { x: 0, y: 0, width: 100, height: 100 };\n\n @state()\n private containerWidth = 0;\n\n @state()\n private containerHeight = 0;\n\n @property({ type: Number })\n minSize = DEFAULT_MIN_SIZE;\n\n @state()\n private isDragging = false;\n\n @state()\n private isResizing: ResizeHandle | null = null;\n\n private dragStart: { x: number; y: number } | null = null;\n private dragStartPosition: { x: number; y: number } = { x: 0, y: 0 };\n private resizeStartCorner: { x: number; y: number } | null = null;\n private resizeStartSize: { width: number; height: number } | null = null;\n private resizeStartPosition: { x: number; y: number } | null = null;\n\n static styles = css`\n .box {\n position: absolute;\n border: 2px solid var(--ef-resizable-box-border-color, var(--ef-color-primary));\n background-color: var(--ef-resizable-box-bg-color, color-mix(in srgb, var(--ef-color-primary) 20%, transparent));\n cursor: grab;\n }\n .box.dragging {\n border-color: var(--ef-resizable-box-dragging-border-color, var(--ef-color-primary));\n background-color: var(--ef-resizable-box-dragging-bg-color, color-mix(in srgb, var(--ef-color-primary) 30%, transparent));\n }\n .handle {\n position: absolute;\n background-color: var(--ef-resizable-box-handle-color, var(--ef-color-primary));\n touch-action: none;\n }\n .handle.nw { top: -4px; left: -4px; width: 8px; height: 8px; cursor: nwse-resize; }\n .handle.ne { top: -4px; right: -4px; width: 8px; height: 8px; cursor: nesw-resize; }\n .handle.sw { bottom: -4px; left: -4px; width: 8px; height: 8px; cursor: nesw-resize; }\n .handle.se { bottom: -4px; right: -4px; width: 8px; height: 8px; cursor: nwse-resize; }\n .handle.n { top: -4px; left: 4px; right: 4px; height: 8px; cursor: ns-resize; }\n .handle.e { top: 4px; bottom: 4px; right: -4px; width: 8px; cursor: ew-resize; }\n .handle.s { bottom: -4px; left: 4px; right: 4px; height: 8px; cursor: ns-resize; }\n .handle.w { top: 4px; bottom: 4px; left: -4px; width: 8px; cursor: ew-resize; }\n `;\n\n private resizeObserver?: ResizeObserver;\n\n connectedCallback() {\n super.connectedCallback();\n if (this.offsetParent) {\n this.containerWidth = this.offsetParent.clientWidth;\n this.containerHeight = this.offsetParent.clientHeight;\n }\n this.resizeObserver = new ResizeObserver(() => {\n if (this.offsetParent) {\n this.containerWidth = this.offsetParent.clientWidth;\n this.containerHeight = this.offsetParent.clientHeight;\n }\n });\n if (this.offsetParent) {\n this.resizeObserver.observe(this.offsetParent);\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.resizeObserver?.disconnect();\n this.cleanup();\n }\n\n private handlePointerDown = (\n e: PointerEvent,\n mode: \"move\" | \"resize\",\n handle?: ResizeHandle,\n ) => {\n e.preventDefault();\n e.stopPropagation();\n this.isDragging = true;\n this.isResizing = mode === \"resize\" ? handle || null : null;\n\n this.dragStart = { x: e.clientX, y: e.clientY };\n this.dragStartPosition = { x: this.bounds.x, y: this.bounds.y };\n\n if (mode === \"resize\" && handle) {\n const oppositeCorner = getOppositeCorner(handle);\n const rotationRadians = 0;\n const initialCorner = getCornerPoint(\n this.bounds.x,\n this.bounds.y,\n this.bounds.width,\n this.bounds.height,\n rotationRadians,\n oppositeCorner.x,\n oppositeCorner.y,\n );\n this.resizeStartCorner = initialCorner;\n this.resizeStartSize = {\n width: this.bounds.width,\n height: this.bounds.height,\n };\n this.resizeStartPosition = { x: this.bounds.x, y: this.bounds.y };\n }\n\n document.addEventListener(\"pointermove\", this.handlePointerMove, {\n passive: false,\n });\n document.addEventListener(\"pointerup\", this.handlePointerUp, {\n passive: false,\n });\n };\n\n private handlePointerMove = (e: PointerEvent) => {\n if (!this.isDragging || !this.dragStart) return;\n\n e.preventDefault();\n\n const deltaX = e.clientX - this.dragStart.x;\n const deltaY = e.clientY - this.dragStart.y;\n\n if (\n this.isResizing &&\n this.resizeStartCorner &&\n this.resizeStartSize &&\n this.resizeStartPosition\n ) {\n const oppositeCorner = getOppositeCorner(this.isResizing);\n const rotationRadians = 0;\n\n let newWidth = this.resizeStartSize.width;\n let newHeight = this.resizeStartSize.height;\n\n if (this.isResizing.includes(\"e\")) {\n newWidth = this.resizeStartSize.width + deltaX;\n } else if (this.isResizing.includes(\"w\")) {\n newWidth = this.resizeStartSize.width - deltaX;\n }\n\n if (this.isResizing.includes(\"s\")) {\n newHeight = this.resizeStartSize.height + deltaY;\n } else if (this.isResizing.includes(\"n\")) {\n newHeight = this.resizeStartSize.height - deltaY;\n }\n\n newWidth = Math.max(\n this.minSize,\n Math.min(this.containerWidth - this.bounds.x, newWidth),\n );\n newHeight = Math.max(\n this.minSize,\n Math.min(this.containerHeight - this.bounds.y, newHeight),\n );\n\n const newOppositeCorner = getCornerPoint(\n this.resizeStartPosition.x,\n this.resizeStartPosition.y,\n newWidth,\n newHeight,\n rotationRadians,\n oppositeCorner.x,\n oppositeCorner.y,\n );\n\n const offsetX = this.resizeStartCorner.x - newOppositeCorner.x;\n const offsetY = this.resizeStartCorner.y - newOppositeCorner.y;\n\n const newX = Math.max(\n 0,\n Math.min(\n this.containerWidth - newWidth,\n this.resizeStartPosition.x + offsetX,\n ),\n );\n const newY = Math.max(\n 0,\n Math.min(\n this.containerHeight - newHeight,\n this.resizeStartPosition.y + offsetY,\n ),\n );\n\n this.bounds = {\n x: newX,\n y: newY,\n width: newWidth,\n height: newHeight,\n };\n } else {\n const constrainedX = Math.max(\n 0,\n Math.min(\n this.containerWidth - this.bounds.width,\n this.dragStartPosition.x + deltaX,\n ),\n );\n const constrainedY = Math.max(\n 0,\n Math.min(\n this.containerHeight - this.bounds.height,\n this.dragStartPosition.y + deltaY,\n ),\n );\n\n this.bounds = {\n ...this.bounds,\n x: constrainedX,\n y: constrainedY,\n };\n }\n\n this.dispatchBoundsChange();\n };\n\n private handlePointerUp = (e: PointerEvent) => {\n e.preventDefault();\n this.cleanup();\n };\n\n private cleanup() {\n this.isDragging = false;\n this.isResizing = null;\n this.dragStart = null;\n this.dragStartPosition = { x: 0, y: 0 };\n this.resizeStartCorner = null;\n this.resizeStartSize = null;\n this.resizeStartPosition = null;\n document.removeEventListener(\"pointermove\", this.handlePointerMove);\n document.removeEventListener(\"pointerup\", this.handlePointerUp);\n }\n\n private dispatchBoundsChange() {\n this.dispatchEvent(\n new CustomEvent(\"bounds-change\", {\n detail: { bounds: this.bounds },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n render() {\n const boxStyles = {\n left: `${this.bounds.x}px`,\n top: `${this.bounds.y}px`,\n width: `${this.bounds.width}px`,\n height: `${this.bounds.height}px`,\n };\n\n const handles: ResizeHandle[] = [\n \"nw\",\n \"n\",\n \"ne\",\n \"e\",\n \"se\",\n \"s\",\n \"sw\",\n \"w\",\n ];\n\n return html`\n <div\n class=\"box ${this.isDragging ? \"dragging\" : \"\"}\"\n style=${styleMap(boxStyles)}\n @pointerdown=${(e: PointerEvent) => this.handlePointerDown(e, \"move\")}\n >\n ${handles.map(\n (handle) => html`\n <div\n class=\"handle ${handle}\"\n @pointerdown=${(e: PointerEvent) => {\n e.stopPropagation();\n this.handlePointerDown(e, \"resize\", handle);\n }}\n ></div>\n `,\n )}\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":";;;;;;;AAKA,MAAM,mBAAmB;AAYlB,2BAAMA,yBAAuB,WAAW;;;gBAEzB;GAAE,GAAG;GAAG,GAAG;GAAG,OAAO;GAAK,QAAQ;GAAK;wBAGlC;yBAGC;iBAGhB;oBAGW;oBAGqB;mBAEW;2BACC;GAAE,GAAG;GAAG,GAAG;GAAG;2BACP;yBACO;6BACL;4BAsD7D,GACA,MACA,WACG;AACH,KAAE,gBAAgB;AAClB,KAAE,iBAAiB;AACnB,QAAK,aAAa;AAClB,QAAK,aAAa,SAAS,WAAW,UAAU,OAAO;AAEvD,QAAK,YAAY;IAAE,GAAG,EAAE;IAAS,GAAG,EAAE;IAAS;AAC/C,QAAK,oBAAoB;IAAE,GAAG,KAAK,OAAO;IAAG,GAAG,KAAK,OAAO;IAAG;AAE/D,OAAI,SAAS,YAAY,QAAQ;IAC/B,MAAM,iBAAiB,kBAAkB,OAAO;AAWhD,SAAK,oBATiB,eACpB,KAAK,OAAO,GACZ,KAAK,OAAO,GACZ,KAAK,OAAO,OACZ,KAAK,OAAO,QALU,GAOtB,eAAe,GACf,eAAe,EAChB;AAED,SAAK,kBAAkB;KACrB,OAAO,KAAK,OAAO;KACnB,QAAQ,KAAK,OAAO;KACrB;AACD,SAAK,sBAAsB;KAAE,GAAG,KAAK,OAAO;KAAG,GAAG,KAAK,OAAO;KAAG;;AAGnE,YAAS,iBAAiB,eAAe,KAAK,mBAAmB,EAC/D,SAAS,OACV,CAAC;AACF,YAAS,iBAAiB,aAAa,KAAK,iBAAiB,EAC3D,SAAS,OACV,CAAC;;4BAGyB,MAAoB;AAC/C,OAAI,CAAC,KAAK,cAAc,CAAC,KAAK,UAAW;AAEzC,KAAE,gBAAgB;GAElB,MAAM,SAAS,EAAE,UAAU,KAAK,UAAU;GAC1C,MAAM,SAAS,EAAE,UAAU,KAAK,UAAU;AAE1C,OACE,KAAK,cACL,KAAK,qBACL,KAAK,mBACL,KAAK,qBACL;IACA,MAAM,iBAAiB,kBAAkB,KAAK,WAAW;IACzD,MAAM,kBAAkB;IAExB,IAAI,WAAW,KAAK,gBAAgB;IACpC,IAAI,YAAY,KAAK,gBAAgB;AAErC,QAAI,KAAK,WAAW,SAAS,IAAI,CAC/B,YAAW,KAAK,gBAAgB,QAAQ;aAC/B,KAAK,WAAW,SAAS,IAAI,CACtC,YAAW,KAAK,gBAAgB,QAAQ;AAG1C,QAAI,KAAK,WAAW,SAAS,IAAI,CAC/B,aAAY,KAAK,gBAAgB,SAAS;aACjC,KAAK,WAAW,SAAS,IAAI,CACtC,aAAY,KAAK,gBAAgB,SAAS;AAG5C,eAAW,KAAK,IACd,KAAK,SACL,KAAK,IAAI,KAAK,iBAAiB,KAAK,OAAO,GAAG,SAAS,CACxD;AACD,gBAAY,KAAK,IACf,KAAK,SACL,KAAK,IAAI,KAAK,kBAAkB,KAAK,OAAO,GAAG,UAAU,CAC1D;IAED,MAAM,oBAAoB,eACxB,KAAK,oBAAoB,GACzB,KAAK,oBAAoB,GACzB,UACA,WACA,iBACA,eAAe,GACf,eAAe,EAChB;IAED,MAAM,UAAU,KAAK,kBAAkB,IAAI,kBAAkB;IAC7D,MAAM,UAAU,KAAK,kBAAkB,IAAI,kBAAkB;AAiB7D,SAAK,SAAS;KACZ,GAhBW,KAAK,IAChB,GACA,KAAK,IACH,KAAK,iBAAiB,UACtB,KAAK,oBAAoB,IAAI,QAC9B,CACF;KAWC,GAVW,KAAK,IAChB,GACA,KAAK,IACH,KAAK,kBAAkB,WACvB,KAAK,oBAAoB,IAAI,QAC9B,CACF;KAKC,OAAO;KACP,QAAQ;KACT;UACI;IACL,MAAM,eAAe,KAAK,IACxB,GACA,KAAK,IACH,KAAK,iBAAiB,KAAK,OAAO,OAClC,KAAK,kBAAkB,IAAI,OAC5B,CACF;IACD,MAAM,eAAe,KAAK,IACxB,GACA,KAAK,IACH,KAAK,kBAAkB,KAAK,OAAO,QACnC,KAAK,kBAAkB,IAAI,OAC5B,CACF;AAED,SAAK,SAAS;KACZ,GAAG,KAAK;KACR,GAAG;KACH,GAAG;KACJ;;AAGH,QAAK,sBAAsB;;0BAGF,MAAoB;AAC7C,KAAE,gBAAgB;AAClB,QAAK,SAAS;;;;gBAnMA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BnB,oBAAoB;AAClB,QAAM,mBAAmB;AACzB,MAAI,KAAK,cAAc;AACrB,QAAK,iBAAiB,KAAK,aAAa;AACxC,QAAK,kBAAkB,KAAK,aAAa;;AAE3C,OAAK,iBAAiB,IAAI,qBAAqB;AAC7C,OAAI,KAAK,cAAc;AACrB,SAAK,iBAAiB,KAAK,aAAa;AACxC,SAAK,kBAAkB,KAAK,aAAa;;IAE3C;AACF,MAAI,KAAK,aACP,MAAK,eAAe,QAAQ,KAAK,aAAa;;CAIlD,uBAAuB;AACrB,QAAM,sBAAsB;AAC5B,OAAK,gBAAgB,YAAY;AACjC,OAAK,SAAS;;CAsJhB,AAAQ,UAAU;AAChB,OAAK,aAAa;AAClB,OAAK,aAAa;AAClB,OAAK,YAAY;AACjB,OAAK,oBAAoB;GAAE,GAAG;GAAG,GAAG;GAAG;AACvC,OAAK,oBAAoB;AACzB,OAAK,kBAAkB;AACvB,OAAK,sBAAsB;AAC3B,WAAS,oBAAoB,eAAe,KAAK,kBAAkB;AACnE,WAAS,oBAAoB,aAAa,KAAK,gBAAgB;;CAGjE,AAAQ,uBAAuB;AAC7B,OAAK,cACH,IAAI,YAAY,iBAAiB;GAC/B,QAAQ,EAAE,QAAQ,KAAK,QAAQ;GAC/B,SAAS;GACT,UAAU;GACX,CAAC,CACH;;CAGH,SAAS;EACP,MAAM,YAAY;GAChB,MAAM,GAAG,KAAK,OAAO,EAAE;GACvB,KAAK,GAAG,KAAK,OAAO,EAAE;GACtB,OAAO,GAAG,KAAK,OAAO,MAAM;GAC5B,QAAQ,GAAG,KAAK,OAAO,OAAO;GAC/B;AAaD,SAAO,IAAI;;qBAEM,KAAK,aAAa,aAAa,GAAG;gBACvC,SAAS,UAAU,CAAC;wBACZ,MAAoB,KAAK,kBAAkB,GAAG,OAAO,CAAC;;UAf1C;GAC9B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAQa,KACP,WAAW,IAAI;;8BAEI,OAAO;8BACP,MAAoB;AAClC,KAAE,iBAAiB;AACnB,QAAK,kBAAkB,GAAG,UAAU,OAAO;IAC3C;;YAGP,CAAC;;;;;;YAvRP,SAAS,EAAE,MAAM,QAAQ,CAAC;YAG1B,OAAO;YAGP,OAAO;YAGP,SAAS,EAAE,MAAM,QAAQ,CAAC;YAG1B,OAAO;YAGP,OAAO;6BAjBT,cAAc,mBAAmB"}
@@ -1,7 +1,7 @@
1
1
  import { ControllableInterface } from "./Controllable.js";
2
- import * as lit18 from "lit";
2
+ import * as lit20 from "lit";
3
3
  import { LitElement } from "lit";
4
- import * as lit_html18 from "lit-html";
4
+ import * as lit_html19 from "lit-html";
5
5
 
6
6
  //#region src/gui/EFScrubber.d.ts
7
7
  declare const EFScrubber_base: (new (...args: any[]) => {
@@ -10,7 +10,7 @@ declare const EFScrubber_base: (new (...args: any[]) => {
10
10
  effectiveContext: ControllableInterface | null;
11
11
  }) & typeof LitElement;
12
12
  declare class EFScrubber extends EFScrubber_base {
13
- static styles: lit18.CSSResult[];
13
+ static styles: lit20.CSSResult[];
14
14
  playing: boolean;
15
15
  contextCurrentTimeMs: number;
16
16
  contextDurationMs: number;
@@ -50,7 +50,7 @@ declare class EFScrubber extends EFScrubber_base {
50
50
  private boundHandlePointerUp;
51
51
  private boundHandlePointerCancel;
52
52
  private boundHandleContextMenu;
53
- render(): lit_html18.TemplateResult<1>;
53
+ render(): lit_html19.TemplateResult<1>;
54
54
  connectedCallback(): void;
55
55
  disconnectedCallback(): void;
56
56
  }