@clipkit/editor 1.0.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 (248) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +51 -0
  3. package/dist/Editor.d.ts +3 -0
  4. package/dist/Editor.d.ts.map +1 -0
  5. package/dist/Editor.js +73 -0
  6. package/dist/Editor.js.map +1 -0
  7. package/dist/ExportDialog.d.ts +12 -0
  8. package/dist/ExportDialog.d.ts.map +1 -0
  9. package/dist/ExportDialog.js +30 -0
  10. package/dist/ExportDialog.js.map +1 -0
  11. package/dist/MotionPathOverlay.d.ts +5 -0
  12. package/dist/MotionPathOverlay.d.ts.map +1 -0
  13. package/dist/MotionPathOverlay.js +156 -0
  14. package/dist/MotionPathOverlay.js.map +1 -0
  15. package/dist/PerfHud.d.ts +2 -0
  16. package/dist/PerfHud.d.ts.map +1 -0
  17. package/dist/PerfHud.js +85 -0
  18. package/dist/PerfHud.js.map +1 -0
  19. package/dist/Stage.d.ts +2 -0
  20. package/dist/Stage.d.ts.map +1 -0
  21. package/dist/Stage.js +406 -0
  22. package/dist/Stage.js.map +1 -0
  23. package/dist/StageOverlay.d.ts +7 -0
  24. package/dist/StageOverlay.d.ts.map +1 -0
  25. package/dist/StageOverlay.js +508 -0
  26. package/dist/StageOverlay.js.map +1 -0
  27. package/dist/commands.d.ts +18 -0
  28. package/dist/commands.d.ts.map +1 -0
  29. package/dist/commands.js +103 -0
  30. package/dist/commands.js.map +1 -0
  31. package/dist/configuration.d.ts +9 -0
  32. package/dist/configuration.d.ts.map +1 -0
  33. package/dist/configuration.js +21 -0
  34. package/dist/configuration.js.map +1 -0
  35. package/dist/controls/AnimationsStack.d.ts +8 -0
  36. package/dist/controls/AnimationsStack.d.ts.map +1 -0
  37. package/dist/controls/AnimationsStack.js +188 -0
  38. package/dist/controls/AnimationsStack.js.map +1 -0
  39. package/dist/controls/CameraControl.d.ts +19 -0
  40. package/dist/controls/CameraControl.d.ts.map +1 -0
  41. package/dist/controls/CameraControl.js +47 -0
  42. package/dist/controls/CameraControl.js.map +1 -0
  43. package/dist/controls/CaptionLengthControl.d.ts +5 -0
  44. package/dist/controls/CaptionLengthControl.d.ts.map +1 -0
  45. package/dist/controls/CaptionLengthControl.js +11 -0
  46. package/dist/controls/CaptionLengthControl.js.map +1 -0
  47. package/dist/controls/CaptionTranscribe.d.ts +2 -0
  48. package/dist/controls/CaptionTranscribe.d.ts.map +1 -0
  49. package/dist/controls/CaptionTranscribe.js +95 -0
  50. package/dist/controls/CaptionTranscribe.js.map +1 -0
  51. package/dist/controls/ColorPicker.d.ts +17 -0
  52. package/dist/controls/ColorPicker.d.ts.map +1 -0
  53. package/dist/controls/ColorPicker.js +354 -0
  54. package/dist/controls/ColorPicker.js.map +1 -0
  55. package/dist/controls/ControlRenderer.d.ts +20 -0
  56. package/dist/controls/ControlRenderer.d.ts.map +1 -0
  57. package/dist/controls/ControlRenderer.js +106 -0
  58. package/dist/controls/ControlRenderer.js.map +1 -0
  59. package/dist/controls/CropControl.d.ts +2 -0
  60. package/dist/controls/CropControl.d.ts.map +1 -0
  61. package/dist/controls/CropControl.js +177 -0
  62. package/dist/controls/CropControl.js.map +1 -0
  63. package/dist/controls/EffectsStack.d.ts +8 -0
  64. package/dist/controls/EffectsStack.d.ts.map +1 -0
  65. package/dist/controls/EffectsStack.js +89 -0
  66. package/dist/controls/EffectsStack.js.map +1 -0
  67. package/dist/controls/GradeControl.d.ts +2 -0
  68. package/dist/controls/GradeControl.d.ts.map +1 -0
  69. package/dist/controls/GradeControl.js +120 -0
  70. package/dist/controls/GradeControl.js.map +1 -0
  71. package/dist/controls/KeyframeDiamond.d.ts +11 -0
  72. package/dist/controls/KeyframeDiamond.d.ts.map +1 -0
  73. package/dist/controls/KeyframeDiamond.js +87 -0
  74. package/dist/controls/KeyframeDiamond.js.map +1 -0
  75. package/dist/controls/LightingControls.d.ts +24 -0
  76. package/dist/controls/LightingControls.d.ts.map +1 -0
  77. package/dist/controls/LightingControls.js +108 -0
  78. package/dist/controls/LightingControls.js.map +1 -0
  79. package/dist/controls/ShapePresetControl.d.ts +4 -0
  80. package/dist/controls/ShapePresetControl.d.ts.map +1 -0
  81. package/dist/controls/ShapePresetControl.js +30 -0
  82. package/dist/controls/ShapePresetControl.js.map +1 -0
  83. package/dist/controls/ValueField.d.ts +10 -0
  84. package/dist/controls/ValueField.d.ts.map +1 -0
  85. package/dist/controls/ValueField.js +158 -0
  86. package/dist/controls/ValueField.js.map +1 -0
  87. package/dist/controls/VolumeControl.d.ts +10 -0
  88. package/dist/controls/VolumeControl.d.ts.map +1 -0
  89. package/dist/controls/VolumeControl.js +75 -0
  90. package/dist/controls/VolumeControl.js.map +1 -0
  91. package/dist/controls/compound.d.ts +46 -0
  92. package/dist/controls/compound.d.ts.map +1 -0
  93. package/dist/controls/compound.js +160 -0
  94. package/dist/controls/compound.js.map +1 -0
  95. package/dist/controls/layout.d.ts +38 -0
  96. package/dist/controls/layout.d.ts.map +1 -0
  97. package/dist/controls/layout.js +162 -0
  98. package/dist/controls/layout.js.map +1 -0
  99. package/dist/controls/primitives.d.ts +83 -0
  100. package/dist/controls/primitives.d.ts.map +1 -0
  101. package/dist/controls/primitives.js +194 -0
  102. package/dist/controls/primitives.js.map +1 -0
  103. package/dist/controls/transcribe.worker.d.ts +2 -0
  104. package/dist/controls/transcribe.worker.d.ts.map +1 -0
  105. package/dist/controls/transcribe.worker.js +22 -0
  106. package/dist/controls/transcribe.worker.js.map +1 -0
  107. package/dist/frame/AddElementBar.d.ts +2 -0
  108. package/dist/frame/AddElementBar.d.ts.map +1 -0
  109. package/dist/frame/AddElementBar.js +103 -0
  110. package/dist/frame/AddElementBar.js.map +1 -0
  111. package/dist/frame/Breadcrumbs.d.ts +2 -0
  112. package/dist/frame/Breadcrumbs.d.ts.map +1 -0
  113. package/dist/frame/Breadcrumbs.js +32 -0
  114. package/dist/frame/Breadcrumbs.js.map +1 -0
  115. package/dist/frame/GroupFlash.d.ts +2 -0
  116. package/dist/frame/GroupFlash.d.ts.map +1 -0
  117. package/dist/frame/GroupFlash.js +65 -0
  118. package/dist/frame/GroupFlash.js.map +1 -0
  119. package/dist/frame/Resizable.d.ts +12 -0
  120. package/dist/frame/Resizable.d.ts.map +1 -0
  121. package/dist/frame/Resizable.js +37 -0
  122. package/dist/frame/Resizable.js.map +1 -0
  123. package/dist/frame/Section.d.ts +23 -0
  124. package/dist/frame/Section.d.ts.map +1 -0
  125. package/dist/frame/Section.js +23 -0
  126. package/dist/frame/Section.js.map +1 -0
  127. package/dist/frame/ZoomControl.d.ts +9 -0
  128. package/dist/frame/ZoomControl.d.ts.map +1 -0
  129. package/dist/frame/ZoomControl.js +15 -0
  130. package/dist/frame/ZoomControl.js.map +1 -0
  131. package/dist/index.d.ts +9 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +13 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/lib/camera-gizmo.d.ts +15 -0
  136. package/dist/lib/camera-gizmo.d.ts.map +1 -0
  137. package/dist/lib/camera-gizmo.js +57 -0
  138. package/dist/lib/camera-gizmo.js.map +1 -0
  139. package/dist/lib/camera-tool.d.ts +43 -0
  140. package/dist/lib/camera-tool.d.ts.map +1 -0
  141. package/dist/lib/camera-tool.js +80 -0
  142. package/dist/lib/camera-tool.js.map +1 -0
  143. package/dist/lib/caption-segments.d.ts +17 -0
  144. package/dist/lib/caption-segments.d.ts.map +1 -0
  145. package/dist/lib/caption-segments.js +50 -0
  146. package/dist/lib/caption-segments.js.map +1 -0
  147. package/dist/lib/group.d.ts +12 -0
  148. package/dist/lib/group.d.ts.map +1 -0
  149. package/dist/lib/group.js +61 -0
  150. package/dist/lib/group.js.map +1 -0
  151. package/dist/lib/keyframes.d.ts +29 -0
  152. package/dist/lib/keyframes.d.ts.map +1 -0
  153. package/dist/lib/keyframes.js +92 -0
  154. package/dist/lib/keyframes.js.map +1 -0
  155. package/dist/lib/sfx-preview.d.ts +18 -0
  156. package/dist/lib/sfx-preview.d.ts.map +1 -0
  157. package/dist/lib/sfx-preview.js +74 -0
  158. package/dist/lib/sfx-preview.js.map +1 -0
  159. package/dist/lib/shape-presets.d.ts +35 -0
  160. package/dist/lib/shape-presets.d.ts.map +1 -0
  161. package/dist/lib/shape-presets.js +81 -0
  162. package/dist/lib/shape-presets.js.map +1 -0
  163. package/dist/lib/ungroup.d.ts +12 -0
  164. package/dist/lib/ungroup.d.ts.map +1 -0
  165. package/dist/lib/ungroup.js +40 -0
  166. package/dist/lib/ungroup.js.map +1 -0
  167. package/dist/lib/utils.d.ts +3 -0
  168. package/dist/lib/utils.d.ts.map +1 -0
  169. package/dist/lib/utils.js +9 -0
  170. package/dist/lib/utils.js.map +1 -0
  171. package/dist/panels/AssetsPanel.d.ts +2 -0
  172. package/dist/panels/AssetsPanel.d.ts.map +1 -0
  173. package/dist/panels/AssetsPanel.js +108 -0
  174. package/dist/panels/AssetsPanel.js.map +1 -0
  175. package/dist/panels/InspectorPanel.d.ts +2 -0
  176. package/dist/panels/InspectorPanel.d.ts.map +1 -0
  177. package/dist/panels/InspectorPanel.js +286 -0
  178. package/dist/panels/InspectorPanel.js.map +1 -0
  179. package/dist/panels/InterpolationPanel.d.ts +2 -0
  180. package/dist/panels/InterpolationPanel.d.ts.map +1 -0
  181. package/dist/panels/InterpolationPanel.js +226 -0
  182. package/dist/panels/InterpolationPanel.js.map +1 -0
  183. package/dist/panels/LayersTree.d.ts +4 -0
  184. package/dist/panels/LayersTree.d.ts.map +1 -0
  185. package/dist/panels/LayersTree.js +137 -0
  186. package/dist/panels/LayersTree.js.map +1 -0
  187. package/dist/panels/LeftRail.d.ts +6 -0
  188. package/dist/panels/LeftRail.d.ts.map +1 -0
  189. package/dist/panels/LeftRail.js +35 -0
  190. package/dist/panels/LeftRail.js.map +1 -0
  191. package/dist/panels/SourcePanel.d.ts +2 -0
  192. package/dist/panels/SourcePanel.d.ts.map +1 -0
  193. package/dist/panels/SourcePanel.js +470 -0
  194. package/dist/panels/SourcePanel.js.map +1 -0
  195. package/dist/panels/TimelinePanel.d.ts +11 -0
  196. package/dist/panels/TimelinePanel.d.ts.map +1 -0
  197. package/dist/panels/TimelinePanel.js +98 -0
  198. package/dist/panels/TimelinePanel.js.map +1 -0
  199. package/dist/panels/assets/SfxBrowser.d.ts +2 -0
  200. package/dist/panels/assets/SfxBrowser.d.ts.map +1 -0
  201. package/dist/panels/assets/SfxBrowser.js +49 -0
  202. package/dist/panels/assets/SfxBrowser.js.map +1 -0
  203. package/dist/panels/assets/use-assets.d.ts +11 -0
  204. package/dist/panels/assets/use-assets.d.ts.map +1 -0
  205. package/dist/panels/assets/use-assets.js +84 -0
  206. package/dist/panels/assets/use-assets.js.map +1 -0
  207. package/dist/panels/assets/use-sfx.d.ts +6 -0
  208. package/dist/panels/assets/use-sfx.d.ts.map +1 -0
  209. package/dist/panels/assets/use-sfx.js +47 -0
  210. package/dist/panels/assets/use-sfx.js.map +1 -0
  211. package/dist/panels/timeline/CanvasTimeline.d.ts +7 -0
  212. package/dist/panels/timeline/CanvasTimeline.d.ts.map +1 -0
  213. package/dist/panels/timeline/CanvasTimeline.js +1536 -0
  214. package/dist/panels/timeline/CanvasTimeline.js.map +1 -0
  215. package/dist/panels/timeline/Clip.d.ts +37 -0
  216. package/dist/panels/timeline/Clip.d.ts.map +1 -0
  217. package/dist/panels/timeline/Clip.js +176 -0
  218. package/dist/panels/timeline/Clip.js.map +1 -0
  219. package/dist/panels/timeline/CurveEditor.d.ts +2 -0
  220. package/dist/panels/timeline/CurveEditor.d.ts.map +1 -0
  221. package/dist/panels/timeline/CurveEditor.js +233 -0
  222. package/dist/panels/timeline/CurveEditor.js.map +1 -0
  223. package/dist/panels/timeline/MixerRail.d.ts +7 -0
  224. package/dist/panels/timeline/MixerRail.d.ts.map +1 -0
  225. package/dist/panels/timeline/MixerRail.js +295 -0
  226. package/dist/panels/timeline/MixerRail.js.map +1 -0
  227. package/dist/panels/timeline/Waveform.d.ts +11 -0
  228. package/dist/panels/timeline/Waveform.d.ts.map +1 -0
  229. package/dist/panels/timeline/Waveform.js +63 -0
  230. package/dist/panels/timeline/Waveform.js.map +1 -0
  231. package/dist/panels/timeline/clip-style.d.ts +10 -0
  232. package/dist/panels/timeline/clip-style.d.ts.map +1 -0
  233. package/dist/panels/timeline/clip-style.js +20 -0
  234. package/dist/panels/timeline/clip-style.js.map +1 -0
  235. package/dist/panels/timeline/filmstrip.d.ts +7 -0
  236. package/dist/panels/timeline/filmstrip.d.ts.map +1 -0
  237. package/dist/panels/timeline/filmstrip.js +135 -0
  238. package/dist/panels/timeline/filmstrip.js.map +1 -0
  239. package/dist/panels/timeline/timeline-layout.d.ts +65 -0
  240. package/dist/panels/timeline/timeline-layout.d.ts.map +1 -0
  241. package/dist/panels/timeline/timeline-layout.js +118 -0
  242. package/dist/panels/timeline/timeline-layout.js.map +1 -0
  243. package/dist/types.d.ts +68 -0
  244. package/dist/types.d.ts.map +1 -0
  245. package/dist/types.js +3 -0
  246. package/dist/types.js.map +1 -0
  247. package/package.json +56 -0
  248. package/src/styles.css +185 -0
@@ -0,0 +1,63 @@
1
+ // Clip waveform — draws REAL min/max peaks (A3's extractWaveformPeaks,
2
+ // cached per URL) onto a canvas sized to the clip. Decode failures
3
+ // (silent video containers, CORS) just render nothing.
4
+ 'use client';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { useEffect, useRef } from 'react';
7
+ import { extractWaveformPeaks } from '@clipkit/playback';
8
+ export function Waveform({ url, trimStart = 0, mediaWindow, color, className, }) {
9
+ const canvasRef = useRef(null);
10
+ useEffect(() => {
11
+ let cancelled = false;
12
+ const canvas = canvasRef.current;
13
+ if (!canvas)
14
+ return;
15
+ extractWaveformPeaks(url)
16
+ .then((wf) => {
17
+ if (cancelled || !canvasRef.current)
18
+ return;
19
+ draw(canvasRef.current, wf, trimStart, mediaWindow, color);
20
+ })
21
+ .catch(() => {
22
+ /* no decodable audio — leave the clip body plain */
23
+ });
24
+ return () => {
25
+ cancelled = true;
26
+ };
27
+ }, [url, trimStart, mediaWindow, color]);
28
+ return (_jsx("canvas", { ref: canvasRef, className: className, style: { width: '100%', height: '100%', display: 'block' } }));
29
+ }
30
+ function draw(canvas, wf, trimStart, mediaWindow, color) {
31
+ const rect = canvas.getBoundingClientRect();
32
+ const w = Math.max(1, Math.floor(rect.width));
33
+ const h = Math.max(1, Math.floor(rect.height));
34
+ canvas.width = w;
35
+ canvas.height = h;
36
+ const ctx = canvas.getContext('2d');
37
+ if (!ctx)
38
+ return;
39
+ const windowSec = mediaWindow ?? Math.max(0, wf.duration - trimStart);
40
+ if (windowSec <= 0)
41
+ return;
42
+ const startBucket = trimStart * wf.peaksPerSecond;
43
+ const bucketsPerPx = (windowSec * wf.peaksPerSecond) / w;
44
+ const mid = h / 2;
45
+ const totalBuckets = wf.peaks.length / 2;
46
+ ctx.fillStyle = color ?? 'rgba(255, 255, 255, 0.28)';
47
+ for (let x = 0; x < w; x++) {
48
+ const b0 = Math.floor(startBucket + x * bucketsPerPx);
49
+ const b1 = Math.max(b0 + 1, Math.floor(startBucket + (x + 1) * bucketsPerPx));
50
+ let min = 0;
51
+ let max = 0;
52
+ for (let b = b0; b < b1 && b < totalBuckets; b++) {
53
+ if (b < 0)
54
+ continue;
55
+ min = Math.min(min, wf.peaks[b * 2]);
56
+ max = Math.max(max, wf.peaks[b * 2 + 1]);
57
+ }
58
+ const y0 = mid - max * (mid - 1);
59
+ const y1 = mid - min * (mid - 1);
60
+ ctx.fillRect(x, y0, 1, Math.max(1, y1 - y0));
61
+ }
62
+ }
63
+ //# sourceMappingURL=Waveform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Waveform.js","sourceRoot":"","sources":["../../../src/panels/timeline/Waveform.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface ClipStyle {
2
+ bg: string;
3
+ border: string;
4
+ /** Waveform tint (audio-carrying types). */
5
+ wave?: string;
6
+ }
7
+ export declare const CLIP_STYLES: Record<string, ClipStyle>;
8
+ export declare const DEFAULT_CLIP_STYLE: ClipStyle;
9
+ export declare function clipStyleOf(type: string): ClipStyle;
10
+ //# sourceMappingURL=clip-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clip-style.d.ts","sourceRoot":"","sources":["../../../src/panels/timeline/clip-style.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAUjD,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,SAAgD,CAAC;AAElF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAEnD"}
@@ -0,0 +1,20 @@
1
+ // Clip palette — the reference shot's type-coloring: magenta caption/
2
+ // text runs, orange images, red shapes, purple groups, blue video
3
+ // with lighter waveforms, green audio with teal waveforms. Selected
4
+ // clips lighten + ring; locked dim.
5
+ export const CLIP_STYLES = {
6
+ caption: { bg: '#a82e63', border: '#c2457a' },
7
+ text: { bg: '#9c2d74', border: '#b8478f' },
8
+ image: { bg: '#a85b1d', border: '#c27636' },
9
+ shape: { bg: '#a33b2e', border: '#bd5547' },
10
+ group: { bg: '#5d49a8', border: '#7763c2' },
11
+ video: { bg: '#2d5d9c', border: '#4777b8', wave: 'rgba(168, 205, 255, 0.55)' },
12
+ audio: { bg: '#1d7a58', border: '#36946f', wave: 'rgba(94, 230, 178, 0.65)' },
13
+ svg: { bg: '#2d8a96', border: '#47a4b0' },
14
+ particles: { bg: '#8a2d96', border: '#a447b0' },
15
+ };
16
+ export const DEFAULT_CLIP_STYLE = { bg: '#4a4a4a', border: '#5e5e5e' };
17
+ export function clipStyleOf(type) {
18
+ return CLIP_STYLES[type] ?? DEFAULT_CLIP_STYLE;
19
+ }
20
+ //# sourceMappingURL=clip-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clip-style.js","sourceRoot":"","sources":["../../../src/panels/timeline/clip-style.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,kEAAkE;AAClE,oEAAoE;AACpE,oCAAoC;AASpC,MAAM,CAAC,MAAM,WAAW,GAA8B;IACpD,OAAO,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC7C,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC1C,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC3C,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC3C,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC3C,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,2BAA2B,EAAE;IAC9E,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,0BAA0B,EAAE;IAC7E,GAAG,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IACzC,SAAS,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;CAChD,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAc,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAElF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC;AACjD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Cached filmstrip frame for `url` at `mediaTime` (seconds into the
3
+ * media), scaled to `height` px. Returns null while decoding; calls
4
+ * `onReady` when a newly-decoded frame for this URL is available.
5
+ */
6
+ export declare function filmstripFrame(url: string, mediaTime: number, height: number, onReady: () => void): ImageBitmap | null;
7
+ //# sourceMappingURL=filmstrip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filmstrip.d.ts","sourceRoot":"","sources":["../../../src/panels/timeline/filmstrip.ts"],"names":[],"mappings":"AA8HA;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,IAAI,GAClB,WAAW,GAAG,IAAI,CAUpB"}
@@ -0,0 +1,135 @@
1
+ // Filmstrip frame sampler (EDITORS — ruled by Ian 2026-06-12:
2
+ // FRONTEND ONLY, no backend, no storage). Per source URL, a hidden
3
+ // <video> seeks to requested media times and captures frames as
4
+ // ImageBitmaps held in an in-memory LRU. Nothing is persisted — the
5
+ // cache lives for the session and rebuilds on reload.
6
+ //
7
+ // Usage: filmstripFrame(url, mediaTime, height, onReady) returns the
8
+ // cached frame or null; when null, it queues a decode and calls
9
+ // onReady once the frame lands so the caller can redraw.
10
+ const MAX_FRAMES_PER_URL = 240; // LRU cap; visible clips request few.
11
+ class Sampler {
12
+ #video;
13
+ #ready = false;
14
+ #failed = false;
15
+ #aspect = 16 / 9;
16
+ #cache = new Map();
17
+ #queue = [];
18
+ #seeking = false;
19
+ #listeners = new Set();
20
+ constructor(url) {
21
+ const v = document.createElement('video');
22
+ v.muted = true;
23
+ v.crossOrigin = 'anonymous';
24
+ v.preload = 'auto';
25
+ v.playsInline = true;
26
+ v.src = url;
27
+ this.#video = v;
28
+ const onLoaded = () => {
29
+ this.#ready = true;
30
+ if (v.videoWidth && v.videoHeight)
31
+ this.#aspect = v.videoWidth / v.videoHeight;
32
+ this.#pump();
33
+ };
34
+ v.addEventListener('loadeddata', onLoaded, { once: true });
35
+ v.addEventListener('error', () => {
36
+ this.#failed = true;
37
+ this.#queue.length = 0;
38
+ });
39
+ // Some browsers need a load() nudge for metadata.
40
+ v.load();
41
+ }
42
+ get aspect() {
43
+ return this.#aspect;
44
+ }
45
+ onReady(cb) {
46
+ this.#listeners.add(cb);
47
+ }
48
+ /** Cached frame, or null (decode queued). */
49
+ frame(mediaTime, height) {
50
+ if (this.#failed)
51
+ return null;
52
+ const key = bucketKey(mediaTime, height);
53
+ const hit = this.#cache.get(key);
54
+ if (hit) {
55
+ // LRU touch.
56
+ this.#cache.delete(key);
57
+ this.#cache.set(key, hit);
58
+ return hit;
59
+ }
60
+ if (!this.#queue.some((p) => p.key === key)) {
61
+ this.#queue.push({ mediaTime, height, key });
62
+ this.#pump();
63
+ }
64
+ return null;
65
+ }
66
+ #pump() {
67
+ if (this.#seeking || !this.#ready || this.#failed)
68
+ return;
69
+ const next = this.#queue.shift();
70
+ if (!next)
71
+ return;
72
+ if (this.#cache.has(next.key)) {
73
+ this.#pump();
74
+ return;
75
+ }
76
+ this.#seeking = true;
77
+ const v = this.#video;
78
+ const onSeeked = () => {
79
+ v.removeEventListener('seeked', onSeeked);
80
+ createImageBitmap(v, { resizeHeight: Math.round(next.height * 2), resizeQuality: 'low' })
81
+ .then((bmp) => {
82
+ this.#cache.set(next.key, bmp);
83
+ while (this.#cache.size > MAX_FRAMES_PER_URL) {
84
+ const oldest = this.#cache.keys().next().value;
85
+ if (oldest === undefined)
86
+ break;
87
+ this.#cache.get(oldest)?.close();
88
+ this.#cache.delete(oldest);
89
+ }
90
+ for (const cb of this.#listeners)
91
+ cb();
92
+ })
93
+ .catch(() => {
94
+ // CORS-tainted or decode failure → give up on this URL.
95
+ this.#failed = true;
96
+ })
97
+ .finally(() => {
98
+ this.#seeking = false;
99
+ this.#pump();
100
+ });
101
+ };
102
+ v.addEventListener('seeked', onSeeked);
103
+ try {
104
+ v.currentTime = Math.max(0, next.mediaTime);
105
+ }
106
+ catch {
107
+ v.removeEventListener('seeked', onSeeked);
108
+ this.#seeking = false;
109
+ this.#failed = true;
110
+ }
111
+ }
112
+ }
113
+ const samplers = new Map();
114
+ function bucketKey(mediaTime, height) {
115
+ // Quantize to 0.5s so adjacent requests share a decode.
116
+ return `${Math.round(mediaTime * 2) / 2}:${height}`;
117
+ }
118
+ /**
119
+ * Cached filmstrip frame for `url` at `mediaTime` (seconds into the
120
+ * media), scaled to `height` px. Returns null while decoding; calls
121
+ * `onReady` when a newly-decoded frame for this URL is available.
122
+ */
123
+ export function filmstripFrame(url, mediaTime, height, onReady) {
124
+ let s = samplers.get(url);
125
+ if (!s) {
126
+ s = new Sampler(url);
127
+ s.onReady(onReady);
128
+ samplers.set(url, s);
129
+ }
130
+ else {
131
+ s.onReady(onReady);
132
+ }
133
+ return s.frame(mediaTime, height);
134
+ }
135
+ //# sourceMappingURL=filmstrip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filmstrip.js","sourceRoot":"","sources":["../../../src/panels/timeline/filmstrip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { Element } from '@clipkit/protocol';
2
+ export declare const ROW_H = 32;
3
+ export declare const LANE_H = 24;
4
+ export declare const RULER_H = 24;
5
+ export declare const HEADER_W = 116;
6
+ export declare const CLIP_INSET = 3;
7
+ export interface ClipRect {
8
+ id: string;
9
+ element: Element;
10
+ layer: number;
11
+ /** Seconds. */
12
+ time: number;
13
+ dur: number;
14
+ /** Content-space px. */
15
+ x: number;
16
+ y: number;
17
+ w: number;
18
+ h: number;
19
+ }
20
+ export interface LaneKeyframe {
21
+ animIndex: number;
22
+ kfIndex: number;
23
+ time: number;
24
+ x: number;
25
+ y: number;
26
+ }
27
+ export interface Lane {
28
+ elementId: string;
29
+ property: string;
30
+ animIndex: number;
31
+ y: number;
32
+ h: number;
33
+ keyframes: LaneKeyframe[];
34
+ }
35
+ export interface LayerRow {
36
+ layer: number;
37
+ y: number;
38
+ h: number;
39
+ /** The element whose keyframe lanes are expanded on this row, if any. */
40
+ expandedId: string | null;
41
+ /** First element on the row carrying keyframe_animations (for the chevron). */
42
+ animId: string | null;
43
+ }
44
+ export interface TimelineLayout {
45
+ layers: LayerRow[];
46
+ clips: ClipRect[];
47
+ lanes: Lane[];
48
+ contentW: number;
49
+ contentH: number;
50
+ duration: number;
51
+ pxPerSec: number;
52
+ }
53
+ /** Layers present, ascending — layer 1 (front/on top) is the first/top row. */
54
+ export declare function listLayers(source: {
55
+ elements: readonly Element[];
56
+ }): number[];
57
+ export declare function buildLayout(source: {
58
+ elements: readonly Element[];
59
+ }, duration: number, pxPerSec: number, expanded: ReadonlySet<string>): TimelineLayout;
60
+ /** Inclusive index range of layers intersecting [scrollTop, scrollTop+viewH]. */
61
+ export declare function visibleLayerRange(layers: readonly LayerRow[], scrollTop: number, viewH: number): {
62
+ start: number;
63
+ end: number;
64
+ };
65
+ //# sourceMappingURL=timeline-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline-layout.d.ts","sourceRoot":"","sources":["../../../src/panels/timeline/timeline-layout.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AAS3D,eAAO,MAAM,KAAK,KAAK,CAAC;AACxB,eAAO,MAAM,MAAM,KAAK,CAAC;AACzB,eAAO,MAAM,OAAO,KAAK,CAAC;AAC1B,eAAO,MAAM,QAAQ,MAAM,CAAC;AAI5B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,wBAAwB;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,IAAI;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,yEAAyE;IACzE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAAG,MAAM,EAAE,CAI7E;AAKD,wBAAgB,WAAW,CACzB,MAAM,EAAE;IAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,EACxC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAC5B,cAAc,CA4EhB;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,QAAQ,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAehC"}
@@ -0,0 +1,118 @@
1
+ // Timeline layout model (EDITORS D9) — the single source of truth for
2
+ // BOTH the canvas painter and the DOM hit-test overlay in the hybrid
3
+ // canvas timeline. Pure: given the source + zoom + expansion set it
4
+ // returns content-space rectangles (y grows downward from 0 at the
5
+ // first layer row, x = seconds * pxPerSec). The canvas draws these
6
+ // offset by scroll; the overlay places hit-rects at the same coords.
7
+ import { elementDuration, elementTime, elementLayer, } from '@clipkit/editor-core';
8
+ // Row/layer height. Matches the basic editor's compact 32px track — the
9
+ // representation Ian preferred. With CLIP_INSET=3 each side the clip bar is 26px.
10
+ export const ROW_H = 32;
11
+ export const LANE_H = 24;
12
+ export const RULER_H = 24;
13
+ export const HEADER_W = 116;
14
+ // px top/bottom inside the row. 3 (not 2) so the bar clears the now-visible row
15
+ // separators: the clip's centered border stroke overhangs ~0.75px, which ate
16
+ // most of a 2px gap and made the bar look like it touched the line.
17
+ export const CLIP_INSET = 3;
18
+ /** Layers present, ascending — layer 1 (front/on top) is the first/top row. */
19
+ export function listLayers(source) {
20
+ const set = new Set();
21
+ for (const el of source.elements)
22
+ set.add(elementLayer(el));
23
+ return [...set].sort((a, b) => a - b);
24
+ }
25
+ const kfTime = (k) => typeof k.time === 'number' ? k.time : parseFloat(String(k.time)) || 0;
26
+ export function buildLayout(source, duration, pxPerSec, expanded) {
27
+ const layerNums = listLayers(source);
28
+ const layers = [];
29
+ const clips = [];
30
+ const lanes = [];
31
+ let y = 0;
32
+ for (const layer of layerNums) {
33
+ const rowEls = source.elements.filter((el) => elementLayer(el) === layer);
34
+ const expandedEl = rowEls.find((el) => el.id && expanded.has(el.id)) ?? null;
35
+ const animEl = rowEls.find((el) => el.id && (el.keyframe_animations?.length ?? 0) > 0) ?? null;
36
+ const laneAnims = expandedEl?.keyframe_animations ?? [];
37
+ const rowH = ROW_H + laneAnims.length * LANE_H;
38
+ layers.push({
39
+ layer,
40
+ y,
41
+ h: rowH,
42
+ expandedId: expandedEl?.id ?? null,
43
+ animId: animEl?.id ?? null,
44
+ });
45
+ for (const el of rowEls) {
46
+ if (!el.id)
47
+ continue;
48
+ const t = elementTime(el);
49
+ const d = elementDuration(el, duration);
50
+ clips.push({
51
+ id: el.id,
52
+ element: el,
53
+ layer,
54
+ time: t,
55
+ dur: d,
56
+ x: t * pxPerSec,
57
+ y: y + CLIP_INSET,
58
+ w: Math.max(20, d * pxPerSec),
59
+ h: ROW_H - CLIP_INSET * 2,
60
+ });
61
+ }
62
+ if (expandedEl) {
63
+ const start = elementTime(expandedEl);
64
+ laneAnims.forEach((anim, ai) => {
65
+ const laneY = y + ROW_H + ai * LANE_H;
66
+ lanes.push({
67
+ elementId: expandedEl.id,
68
+ property: anim.property,
69
+ animIndex: ai,
70
+ y: laneY,
71
+ h: LANE_H,
72
+ keyframes: anim.keyframes.map((k, ki) => {
73
+ const kt = kfTime(k);
74
+ return {
75
+ animIndex: ai,
76
+ kfIndex: ki,
77
+ time: kt,
78
+ x: (start + kt) * pxPerSec,
79
+ y: laneY + LANE_H / 2,
80
+ };
81
+ }),
82
+ });
83
+ });
84
+ }
85
+ y += rowH;
86
+ }
87
+ return {
88
+ layers,
89
+ clips,
90
+ lanes,
91
+ contentW: Math.max(1, Math.ceil(duration * pxPerSec)) + 240,
92
+ contentH: y,
93
+ duration,
94
+ pxPerSec,
95
+ };
96
+ }
97
+ /** Inclusive index range of layers intersecting [scrollTop, scrollTop+viewH]. */
98
+ export function visibleLayerRange(layers, scrollTop, viewH) {
99
+ if (layers.length === 0)
100
+ return { start: 0, end: 0 };
101
+ const top = scrollTop;
102
+ const bottom = scrollTop + viewH;
103
+ let start = layers.length;
104
+ let end = 0;
105
+ for (let i = 0; i < layers.length; i++) {
106
+ const r = layers[i];
107
+ if (r.y + r.h >= top && r.y <= bottom) {
108
+ if (i < start)
109
+ start = i;
110
+ if (i + 1 > end)
111
+ end = i + 1;
112
+ }
113
+ }
114
+ if (start > end)
115
+ return { start: 0, end: 0 };
116
+ return { start, end };
117
+ }
118
+ //# sourceMappingURL=timeline-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline-layout.js","sourceRoot":"","sources":["../../../src/panels/timeline/timeline-layout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { Source } from '@clipkit/protocol';
2
+ import type { AssetStore, EditorConfiguration } from '@clipkit/editor-core';
3
+ /** A render resolution the export dialog offers. Free in-browser — WebCodecs
4
+ * upscales the canvas; no backend needed. */
5
+ export type ExportResolution = 'source' | '720p' | '1080p' | '1440p' | '4k';
6
+ /** Export quality tier — maps to encoder bitrate. */
7
+ export type ExportQuality = 'standard' | 'high';
8
+ /**
9
+ * A format the export dialog offers. The editor renders these GENERICALLY — it
10
+ * has no knowledge of codecs or how any format is produced. The default is just
11
+ * `[{ id: 'mp4', label: 'MP4' }]` (the free in-browser path). Consumers inject
12
+ * additional formats (ProRes, AV1, transparent, …) and handle them in
13
+ * `onRender`; the chosen `id` is echoed back there. Same pattern as `assetStore`.
14
+ */
15
+ export interface ExportFormatOption {
16
+ /** Stable id echoed back in `onRender`'s request (e.g. 'mp4', 'prores'). */
17
+ id: string;
18
+ /** Display label, e.g. 'MP4 (H.264)' or 'ProRes 4444'. */
19
+ label: string;
20
+ /** Optional cosmetic badge shown by the label, e.g. 'uses credits'. */
21
+ badge?: string;
22
+ }
23
+ /** What the user chose in the export dialog, passed to `onRender`. */
24
+ export interface ExportRequest {
25
+ /** The chosen `ExportFormatOption.id`. */
26
+ format: string;
27
+ resolution: ExportResolution;
28
+ quality: ExportQuality;
29
+ }
30
+ export interface EditorProps {
31
+ /** The Source the editor loads on first render. */
32
+ initialSource: Source;
33
+ /**
34
+ * Where the media bin reads and writes. Omit to use a zero-config local
35
+ * store (IndexedDB — files persist in the browser, no backend). Inject your
36
+ * own adapter (Supabase, S3, your API) to wire real storage; the editor only
37
+ * ever calls list/upload/remove, so it stays storage-agnostic.
38
+ */
39
+ assetStore?: AssetStore;
40
+ /**
41
+ * What this editor instance IS (views, dock, knob exposure).
42
+ * Defaults to ADVANCED_CONFIGURATION. Pass BASIC_CONFIGURATION — or
43
+ * your own object — to reshape the editor without forking it.
44
+ */
45
+ configuration?: EditorConfiguration;
46
+ /** Fired whenever the Source changes (mutation, undo, …). */
47
+ onSourceChange?: (source: Source) => void;
48
+ /**
49
+ * Render handler — fired with the Source and the user's export choice
50
+ * (format/resolution/quality) from the export dialog. The button is hidden
51
+ * when omitted. The editor produces nothing itself; the consumer decides how
52
+ * each format renders (browser MP4, cloud API, …).
53
+ */
54
+ onRender?: (source: Source, request: ExportRequest) => void;
55
+ /**
56
+ * Formats the export dialog offers. Defaults to `[{ id: 'mp4', label: 'MP4' }]`
57
+ * — the free in-browser path. Inject more (ProRes, AV1, transparent, …) to
58
+ * extend the dialog without the editor knowing what they are.
59
+ */
60
+ exportFormats?: ExportFormatOption[];
61
+ rendering?: boolean;
62
+ renderProgress?: number;
63
+ /** Renderer backend override; defaults to 'auto'. */
64
+ backend?: 'auto' | 'webgpu' | 'webgl2';
65
+ /** Light or dark theme. Defaults to 'dark'. */
66
+ theme?: 'light' | 'dark';
67
+ }
68
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE5E;8CAC8C;AAC9C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,CAAC;AAE5E,qDAAqD;AACrD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,4EAA4E;IAC5E,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,gBAAgB,CAAC;IAC7B,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,6DAA6D;IAC7D,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5D;;;;OAIG;IACH,aAAa,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACvC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // Public types for @clipkit/editor (the configurable editor shell).
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oEAAoE"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@clipkit/editor",
3
+ "version": "1.0.0",
4
+ "description": "The Clipkit editor — one configurable, registry-driven editor over the Source schema. BASIC and ADVANCED ship as configurations of the same component tree (<Editor configuration={…}>), powered by @clipkit/editor-core.",
5
+ "license": "Apache-2.0",
6
+ "repository": { "type": "git", "url": "git+https://github.com/clipkit-video/clipkit.git", "directory": "packages/editor" },
7
+ "homepage": "https://clipkit.dev",
8
+ "bugs": "https://github.com/clipkit-video/clipkit/issues",
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./styles.css": "./src/styles.css"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src/styles.css",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "dev": "tsc --watch",
29
+ "typecheck": "tsc --noEmit",
30
+ "clean": "rm -rf dist"
31
+ },
32
+ "dependencies": {
33
+ "@clipkit/editor-core": "^1.0.0",
34
+ "@clipkit/playback": "^1.0.0",
35
+ "@clipkit/protocol": "^1.0.0",
36
+ "@clipkit/runtime": "^1.0.0",
37
+ "@clipkit/sfx": "^1.0.0",
38
+ "@clipkit/speech-to-text": "^1.0.0",
39
+ "@codemirror/commands": "^6.10.3",
40
+ "@codemirror/lang-json": "^6.0.2",
41
+ "@codemirror/language": "^6.12.3",
42
+ "@codemirror/lint": "^6.9.7",
43
+ "@codemirror/search": "^6.7.1",
44
+ "@codemirror/state": "^6.6.0",
45
+ "@codemirror/view": "^6.43.1",
46
+ "@lezer/highlight": "^1.2.3",
47
+ "clsx": "^2.1.1",
48
+ "lucide-react": "^0.468.0",
49
+ "tailwind-merge": "^3.6.0",
50
+ "zustand": "^5.0.0"
51
+ },
52
+ "peerDependencies": {
53
+ "react": "^19.0.0",
54
+ "react-dom": "^19.0.0"
55
+ }
56
+ }