@pixerate/editor-svelte 0.65.0 → 0.67.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.
@@ -7,7 +7,8 @@
7
7
  normalizeVideoGrade,
8
8
  VIDEO_GRADE_CONTROLS,
9
9
  VIDEO_GRADE_PRESET_NAMES,
10
- videoGradePreset,
10
+ videoGradeLook,
11
+ videoLutEdits,
11
12
  VIDEO_BLEND_MODE_LABELS,
12
13
  VIDEO_BLEND_MODES,
13
14
  VIDEO_FADE_CURVE_LABELS,
@@ -27,6 +28,7 @@
27
28
  type VideoEditorController,
28
29
  type VideoFadeCurve,
29
30
  type VideoGradeControl,
31
+ type VideoGradeLut,
30
32
  type VideoGradePreset,
31
33
  type VideoKeyframeRow,
32
34
  type VideoTransitionType,
@@ -119,9 +121,46 @@
119
121
  set('grade', normalizeVideoGrade({ ...clip.grade, [c.key]: n }), `Change ${c.label.toLowerCase()}`);
120
122
  }
121
123
  function gradePreset(name: string) {
122
- const grade = clip && name ? videoGradePreset(name as VideoGradePreset) : undefined;
124
+ const grade = clip && name ? videoGradeLook(clip.grade, name as VideoGradePreset) : undefined;
123
125
  if (clip && grade) apply({ op: 'update_clip', clip: clip.id, set: { grade } }, `Apply ${name} look`);
124
126
  }
127
+ /** Gives the clip a LUT (keeping its other grade settings), or takes it off with `null`. */
128
+ function setLut(setting: VideoGradeLut | null, label: string) {
129
+ if (!clip) return;
130
+ localError = null;
131
+ const r = controller.apply(videoLutEdits(editor.project, [clip.id], setting), label);
132
+ if (!r.ok) localError = { text: r.error, revision: editor.revision };
133
+ }
134
+ /** A `.cube` path or URL, checked by loading it; empty removes the LUT. */
135
+ async function chooseLut(src: string) {
136
+ if (!clip) return;
137
+ const strength = clip.grade?.lut?.strength;
138
+ if (!src) return clip.grade?.lut && setLut(null, 'Remove LUT');
139
+ try {
140
+ const table = await controller.luts.load(src);
141
+ setLut({ src, ...(strength !== undefined ? { strength } : {}), ...(table.title ? { name: table.title } : {}) }, 'Apply LUT');
142
+ } catch (e) {
143
+ localError = { text: e instanceof Error ? e.message : String(e), revision: editor.revision };
144
+ }
145
+ }
146
+ /** A `.cube` file read in place: its name becomes the `src`, so keep the file beside the export. */
147
+ async function loadLutFile(file: File | undefined) {
148
+ if (!file || !clip) return;
149
+ const strength = clip.grade?.lut?.strength;
150
+ try {
151
+ const table = controller.luts.set(file.name, await file.text());
152
+ setLut({ src: file.name, ...(strength !== undefined ? { strength } : {}), ...(table.title ? { name: table.title } : {}) }, 'Apply LUT');
153
+ } catch (e) {
154
+ localError = { text: `${file.name}: ${e instanceof Error ? e.message : String(e)}`, revision: editor.revision };
155
+ }
156
+ }
157
+ function lutStrength(raw: string) {
158
+ const lut = clip?.grade?.lut;
159
+ const n = Number(raw);
160
+ if (!lut || !raw.trim() || !Number.isFinite(n)) return;
161
+ // A strength of 0 changes nothing, so it takes the LUT off.
162
+ setLut(n > 0 ? { ...lut, strength: Math.min(1, n) } : null, n > 0 ? 'Change LUT strength' : 'Remove LUT');
163
+ }
125
164
  function transitionAudioCurve(curve: string) {
126
165
  if (!clip?.transition) return;
127
166
  const { audioCurve: _, ...rest } = clip.transition;
@@ -186,6 +225,21 @@
186
225
  <span class="text-muted-foreground">{c.label}</span>
187
226
  <input class={input} type="number" min={c.min} max={c.max} step={c.step} placeholder="0" aria-label={c.label} {disabled} value={clip.grade?.[c.key] ?? ''} onchange={(e) => gradeValue(c, e.currentTarget.value)} data-field="grade.{c.key}" />
188
227
  {/each}
228
+ <span class="text-muted-foreground">LUT</span>
229
+ <div class="flex min-w-0 gap-1" data-field="grade.lut">
230
+ <input class={input} placeholder="look.cube" aria-label="LUT file" {disabled} value={clip.grade?.lut?.src ?? ''} onchange={(e) => chooseLut(e.currentTarget.value.trim())} />
231
+ <label class="{btn} cursor-pointer whitespace-nowrap" title="Load a .cube file">
232
+ Load
233
+ <input type="file" accept=".cube" class="sr-only" {disabled} aria-label="Load a .cube LUT" onchange={(e) => loadLutFile(e.currentTarget.files?.[0])} />
234
+ </label>
235
+ {#if clip.grade?.lut}
236
+ <button type="button" class={btn} {disabled} aria-label="Remove LUT" onclick={() => setLut(null, 'Remove LUT')}>✕</button>
237
+ {/if}
238
+ </div>
239
+ {#if clip.grade?.lut}
240
+ <span class="text-muted-foreground">LUT strength</span>
241
+ <input class={input} type="number" min="0" max="1" step="0.05" aria-label="LUT strength" {disabled} value={clip.grade.lut.strength ?? 1} onchange={(e) => lutStrength(e.currentTarget.value)} data-field="grade.lut.strength" />
242
+ {/if}
189
243
  {/if}
190
244
  {#if at?.track.kind === 'video'}
191
245
  {#each [{ key: 'animateIn', label: 'Animate in', change: 'Change entrance' }, { key: 'animateOut', label: 'Animate out', change: 'Change exit' }] as const as row (row.key)}
@@ -1 +1 @@
1
- {"version":3,"file":"ClipInspector.svelte.d.ts","sourceRoot":"","sources":["../../src/video-editor/ClipInspector.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAyBH,KAAK,qBAAqB,EAO3B,MAAM,+BAA+B,CAAC;AAIvC,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2PH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ClipInspector.svelte.d.ts","sourceRoot":"","sources":["../../src/video-editor/ClipInspector.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EA0BH,KAAK,qBAAqB,EAQ3B,MAAM,+BAA+B,CAAC;AAIvC,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA+SH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -5,6 +5,7 @@
5
5
  import MediaBin from './MediaBin.svelte';
6
6
  import TranscriptPanel from './TranscriptPanel.svelte';
7
7
  import VideoPreview from './VideoPreview.svelte';
8
+ import VideoScopes from './VideoScopes.svelte';
8
9
  import VideoTimeline from './VideoTimeline.svelte';
9
10
  import VideoTransport from './VideoTransport.svelte';
10
11
  import { videoEditorStateOf } from './createVideoEditor.svelte.js';
@@ -25,10 +26,12 @@
25
26
  showIssues?: boolean;
26
27
  /** Show the transcript panel for editing by text (default true). */
27
28
  showTranscript?: boolean;
29
+ /** Show colour scopes (histogram, luma waveform, vectorscope) of the preview under it (default false). */
30
+ showScopes?: boolean;
28
31
  class?: string;
29
32
  }
30
33
 
31
- let { controller, options, editable = true, pxPerSecond = $bindable(100), showIssues = true, showTranscript = true, class: className = '' }: Props = $props();
34
+ let { controller, options, editable = true, pxPerSecond = $bindable(100), showIssues = true, showTranscript = true, showScopes = false, class: className = '' }: Props = $props();
32
35
  let owned: VideoEditorController | null = null;
33
36
  // A controller is made only when none is passed, and kept for the component's lifetime.
34
37
  const ctl = $derived(controller ?? (owned ??= new VideoEditorController(options)));
@@ -56,6 +59,7 @@
56
59
  <div class="flex flex-col gap-2 {className}" data-video-editor="">
57
60
  <VideoPreview controller={ctl} class="rounded-md" />
58
61
  <VideoTransport controller={ctl} editable={false} />
62
+ {#if showScopes}<VideoScopes controller={ctl} />{/if}
59
63
  <VideoTimeline controller={ctl} bind:pxPerSecond editable={false} />
60
64
  {#if showTranscript}<TranscriptPanel controller={ctl} editable={false} />{/if}
61
65
  {@render issueList()}
@@ -66,6 +70,7 @@
66
70
  <div class="flex min-w-0 flex-col gap-2">
67
71
  <VideoPreview controller={ctl} class="rounded-md" />
68
72
  <VideoTransport controller={ctl} />
73
+ {#if showScopes}<VideoScopes controller={ctl} />{/if}
69
74
  </div>
70
75
  <ClipInspector controller={ctl} class="min-w-0" />
71
76
  <div class="flex min-w-0 flex-col gap-2 lg:col-span-3">
@@ -15,6 +15,8 @@ interface Props {
15
15
  showIssues?: boolean;
16
16
  /** Show the transcript panel for editing by text (default true). */
17
17
  showTranscript?: boolean;
18
+ /** Show colour scopes (histogram, luma waveform, vectorscope) of the preview under it (default false). */
19
+ showScopes?: boolean;
18
20
  class?: string;
19
21
  }
20
22
  declare const VideoEditor: import("svelte").Component<Props, {}, "pxPerSecond">;
@@ -1 +1 @@
1
- {"version":3,"file":"VideoEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/video-editor/VideoEditor.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAU7F,UAAU,KAAK;IACb,2FAA2F;IAC3F,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oEAAoE;IACpE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2DH,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"VideoEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/video-editor/VideoEditor.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAW7F,UAAU,KAAK;IACb,2FAA2F;IAC3F,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oEAAoE;IACpE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8DH,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,77 @@
1
+ <script lang="ts">
2
+ import { readVideoScopesPanel, VIDEO_SCOPE_KINDS, type VideoEditorController, type VideoScopeKind, type VideoScopesPanelReading } from '@pixerate/editor/video-editor';
3
+
4
+ interface Props {
5
+ controller: VideoEditorController;
6
+ /** Which scopes to show, in order (default histogram, waveform and vectorscope). */
7
+ scopes?: readonly VideoScopeKind[];
8
+ /** Size of the histogram and waveform in pixels (default 256 × 128); the vectorscope is square, `height` a side. */
9
+ width?: number;
10
+ height?: number;
11
+ class?: string;
12
+ }
13
+
14
+ let { controller, scopes = VIDEO_SCOPE_KINDS, width = 256, height = 128, class: className = '' }: Props = $props();
15
+ const LABELS: Record<VideoScopeKind, string> = { histogram: 'Histogram', waveform: 'Luma waveform', vectorscope: 'Vectorscope' };
16
+ const pct = (v: number) => `${Math.round(v * 1000) / 10}%`;
17
+ const canvases: Partial<Record<VideoScopeKind, HTMLCanvasElement>> = $state({});
18
+ let reading: VideoScopesPanelReading = $state.raw({ ok: false, message: 'Show the preview to see its scopes.' });
19
+
20
+ // Redraw after each preview frame, at most once an animation frame.
21
+ $effect(() => {
22
+ const feed = controller.previewPixels;
23
+ const kinds = scopes;
24
+ const size = { width, height };
25
+ let frame = 0;
26
+ const raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : (fn: () => void) => setTimeout(fn, 16) as unknown as number;
27
+ const caf = typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame : (id: number) => clearTimeout(id);
28
+ const draw = () => {
29
+ frame = 0;
30
+ const next = readVideoScopesPanel(feed, kinds, size);
31
+ reading = next;
32
+ if (!next.ok) return;
33
+ for (const kind of kinds) {
34
+ const img = next.images[kind];
35
+ const ctx = canvases[kind]?.getContext('2d');
36
+ if (img && ctx && typeof ImageData !== 'undefined') ctx.putImageData(new ImageData(img.data, img.width, img.height), 0, 0);
37
+ }
38
+ };
39
+ const schedule = () => {
40
+ if (!frame) frame = raf(draw);
41
+ };
42
+ schedule();
43
+ const off = feed.subscribe(schedule);
44
+ return () => {
45
+ off();
46
+ if (frame) caf(frame);
47
+ };
48
+ });
49
+ </script>
50
+
51
+ <!-- Colour scopes of what this controller's <VideoPreview> draws, with exposure figures and notes. -->
52
+ <div class="flex flex-col gap-2 text-xs {className}" data-video-scopes="">
53
+ <div class="flex flex-wrap gap-2">
54
+ {#each scopes as kind (kind)}
55
+ {@const w = kind === 'vectorscope' ? height : width}
56
+ <figure class="m-0 flex min-w-0 max-w-full flex-col gap-1">
57
+ <canvas bind:this={canvases[kind]} width={w} height={height} class="rounded border border-border bg-black" style="width:{w}px;max-width:100%;height:auto;aspect-ratio:{w} / {height}" aria-label={LABELS[kind]} data-scope={kind}></canvas>
58
+ <figcaption class="text-[11px] text-muted-foreground">{LABELS[kind]}</figcaption>
59
+ </figure>
60
+ {/each}
61
+ </div>
62
+ {#if reading.ok}
63
+ <div class="flex flex-col gap-0.5" data-scope-stats="">
64
+ <div class="tabular-nums">
65
+ Luma {reading.stats.luma.mean.toFixed(2)} mean · {reading.stats.luma.p1.toFixed(2)}–{reading.stats.luma.p99.toFixed(2)} · crushed {pct(reading.stats.clipped.shadows)} · blown {pct(reading.stats.clipped.highlights)} · average
66
+ <span class="inline-block h-2.5 w-2.5 rounded-sm align-middle" style="background:{reading.stats.average}"></span>
67
+ {reading.stats.average}
68
+ {#if !reading.complete}<span class="text-muted-foreground"> · loading</span>{/if}
69
+ </div>
70
+ {#each reading.notes as note (note)}
71
+ <div class="text-amber-500">{note}</div>
72
+ {/each}
73
+ </div>
74
+ {:else}
75
+ <div class="text-muted-foreground" data-scope-message="">{reading.message}</div>
76
+ {/if}
77
+ </div>
@@ -0,0 +1,14 @@
1
+ import { type VideoEditorController, type VideoScopeKind } from '@pixerate/editor/video-editor';
2
+ interface Props {
3
+ controller: VideoEditorController;
4
+ /** Which scopes to show, in order (default histogram, waveform and vectorscope). */
5
+ scopes?: readonly VideoScopeKind[];
6
+ /** Size of the histogram and waveform in pixels (default 256 × 128); the vectorscope is square, `height` a side. */
7
+ width?: number;
8
+ height?: number;
9
+ class?: string;
10
+ }
11
+ declare const VideoScopes: import("svelte").Component<Props, {}, "">;
12
+ type VideoScopes = ReturnType<typeof VideoScopes>;
13
+ export default VideoScopes;
14
+ //# sourceMappingURL=VideoScopes.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoScopes.svelte.d.ts","sourceRoot":"","sources":["../../src/video-editor/VideoScopes.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2C,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAgC,MAAM,+BAA+B,CAAC;AAGrK,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,oFAAoF;IACpF,MAAM,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,oHAAoH;IACpH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwEH,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import type { ComponentProps } from "svelte";
2
2
  import type VideoEditorComponent from "./VideoEditor.svelte";
3
3
  import type VideoPreviewComponent from "./VideoPreview.svelte";
4
+ import type VideoScopesComponent from "./VideoScopes.svelte";
4
5
  import type VideoTransportComponent from "./VideoTransport.svelte";
5
6
  import type VideoTimelineComponent from "./VideoTimeline.svelte";
6
7
  import type ClipInspectorComponent from "./ClipInspector.svelte";
@@ -8,6 +9,7 @@ import type MediaBinComponent from "./MediaBin.svelte";
8
9
  import type TranscriptPanelComponent from "./TranscriptPanel.svelte";
9
10
  export { default as VideoEditor } from "./VideoEditor.svelte";
10
11
  export { default as VideoPreview } from "./VideoPreview.svelte";
12
+ export { default as VideoScopes } from "./VideoScopes.svelte";
11
13
  export { default as VideoTransport } from "./VideoTransport.svelte";
12
14
  export { default as VideoTimeline } from "./VideoTimeline.svelte";
13
15
  export { default as ClipInspector } from "./ClipInspector.svelte";
@@ -16,6 +18,7 @@ export { default as TranscriptPanel } from "./TranscriptPanel.svelte";
16
18
  export * from "./createVideoEditor.svelte.js";
17
19
  export type VideoEditorProps = ComponentProps<typeof VideoEditorComponent>;
18
20
  export type VideoPreviewProps = ComponentProps<typeof VideoPreviewComponent>;
21
+ export type VideoScopesProps = ComponentProps<typeof VideoScopesComponent>;
19
22
  export type VideoTransportProps = ComponentProps<typeof VideoTransportComponent>;
20
23
  export type VideoTimelineProps = ComponentProps<typeof VideoTimelineComponent>;
21
24
  export type ClipInspectorProps = ComponentProps<typeof ClipInspectorComponent>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/video-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,uBAAuB,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,iBAAiB,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,wBAAwB,MAAM,0BAA0B,CAAC;AAErE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,cAAc,+BAA+B,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACjF,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACrE,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/video-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,uBAAuB,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,iBAAiB,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,wBAAwB,MAAM,0BAA0B,CAAC;AAErE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,cAAc,+BAA+B,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACjF,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACrE,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { default as VideoEditor } from "./VideoEditor.svelte";
2
2
  export { default as VideoPreview } from "./VideoPreview.svelte";
3
+ export { default as VideoScopes } from "./VideoScopes.svelte";
3
4
  export { default as VideoTransport } from "./VideoTransport.svelte";
4
5
  export { default as VideoTimeline } from "./VideoTimeline.svelte";
5
6
  export { default as ClipInspector } from "./ClipInspector.svelte";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor-svelte",
3
- "version": "0.65.0",
3
+ "version": "0.67.0",
4
4
  "description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -131,7 +131,7 @@
131
131
  "@tiptap/extension-bubble-menu": "^2.11.5",
132
132
  "@tiptap/extension-placeholder": "^2.11.5",
133
133
  "@tiptap/starter-kit": "^2.11.5",
134
- "@pixerate/editor": "0.86.0"
134
+ "@pixerate/editor": "0.88.0"
135
135
  },
136
136
  "peerDependencies": {
137
137
  "@dagrejs/dagre": "^1.1.4",