@pixerate/editor 0.124.0 → 0.124.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/{chunk-IWSMDQE5.cjs → chunk-4QQZV5Y5.cjs} +18 -29
  2. package/dist/chunk-4QQZV5Y5.cjs.map +1 -0
  3. package/dist/{chunk-IOXKXQNW.cjs → chunk-CN4PJHUG.cjs} +59 -3
  4. package/dist/chunk-CN4PJHUG.cjs.map +1 -0
  5. package/dist/{chunk-TK53AB4Q.cjs → chunk-FHYDQOPC.cjs} +3 -3
  6. package/dist/{chunk-TK53AB4Q.cjs.map → chunk-FHYDQOPC.cjs.map} +1 -1
  7. package/dist/{chunk-VFAKN46Z.js → chunk-JRXJTPES.js} +2 -2
  8. package/dist/{chunk-YVVSTD3B.js → chunk-ORHMVUR6.js} +8 -19
  9. package/dist/chunk-ORHMVUR6.js.map +1 -0
  10. package/dist/{chunk-TGKT5QAB.js → chunk-QEG3GRN2.js} +58 -2
  11. package/dist/chunk-QEG3GRN2.js.map +1 -0
  12. package/dist/effects/index.cjs +51 -34
  13. package/dist/effects/index.cjs.map +1 -1
  14. package/dist/effects/index.d.cts +35 -3
  15. package/dist/effects/index.d.ts +35 -3
  16. package/dist/effects/index.js +20 -3
  17. package/dist/effects/index.js.map +1 -1
  18. package/dist/{export-8RnlngAv.d.ts → export-BGtXgMJ3.d.ts} +3 -1
  19. package/dist/{export-DM3h7QEI.d.ts → export-BdfY_lH0.d.ts} +4 -2
  20. package/dist/{export-BzSRXyH6.d.cts → export-CbpjwxaI.d.cts} +4 -2
  21. package/dist/{export-TqXMOlDt.d.cts → export-WmYoWmLM.d.cts} +3 -1
  22. package/dist/image-editor/index.cjs +110 -121
  23. package/dist/image-editor/index.cjs.map +1 -1
  24. package/dist/image-editor/index.d.cts +2 -2
  25. package/dist/image-editor/index.d.ts +2 -2
  26. package/dist/image-editor/index.js +7 -18
  27. package/dist/image-editor/index.js.map +1 -1
  28. package/dist/paint-editor/index.cjs +3 -3
  29. package/dist/paint-editor/index.d.cts +2 -2
  30. package/dist/paint-editor/index.d.ts +2 -2
  31. package/dist/paint-editor/index.js +2 -2
  32. package/dist/video-editor/index.cjs +270 -270
  33. package/dist/video-editor/index.d.cts +2 -2
  34. package/dist/video-editor/index.d.ts +2 -2
  35. package/dist/video-editor/index.js +3 -3
  36. package/package.json +1 -1
  37. package/dist/chunk-IOXKXQNW.cjs.map +0 -1
  38. package/dist/chunk-IWSMDQE5.cjs.map +0 -1
  39. package/dist/chunk-TGKT5QAB.js.map +0 -1
  40. package/dist/chunk-YVVSTD3B.js.map +0 -1
  41. /package/dist/{chunk-VFAKN46Z.js.map → chunk-JRXJTPES.js.map} +0 -0
@@ -134,14 +134,14 @@
134
134
 
135
135
 
136
136
 
137
- var _chunkIWSMDQE5cjs = require('../chunk-IWSMDQE5.cjs');
137
+ var _chunk4QQZV5Y5cjs = require('../chunk-4QQZV5Y5.cjs');
138
138
 
139
139
 
140
- var _chunkTK53AB4Qcjs = require('../chunk-TK53AB4Q.cjs');
140
+ var _chunkFHYDQOPCcjs = require('../chunk-FHYDQOPC.cjs');
141
141
 
142
142
 
143
143
 
144
- var _chunkIOXKXQNWcjs = require('../chunk-IOXKXQNW.cjs');
144
+ var _chunkCN4PJHUGcjs = require('../chunk-CN4PJHUG.cjs');
145
145
  require('../chunk-RIWPYSKU.cjs');
146
146
 
147
147
 
@@ -192,7 +192,7 @@ function parseVideoEase(v, path) {
192
192
  if (v[0] < 0 || v[0] > 1 || v[2] < 0 || v[2] > 1) fail(path, "must have x1 and x2 between 0 and 1");
193
193
  return [v[0], v[1], v[2], v[3]];
194
194
  }
195
- return oneOf(v, _chunkIWSMDQE5cjs.VIDEO_EASE_NAMES, path);
195
+ return oneOf(v, _chunk4QQZV5Y5cjs.VIDEO_EASE_NAMES, path);
196
196
  }
197
197
  function parseVideoKeyframes(v, path, { min, max } = {}) {
198
198
  if (!isObject(v)) return fail(path, "must be a number or keyframes { keys: [{ t, v, ease }] }");
@@ -230,7 +230,7 @@ function parseVideoTimeRemap(v, speed, path) {
230
230
  if (typeof remap === "number" || remap === void 0) return fail(path, "must be keyframes { keys: [{ t, v, ease }] } (v: ms of source after the in point)");
231
231
  if (speed !== void 0 && speed !== 1) fail(path, 'cannot be used with a speed; a ramp sets the speed itself (remove "speed")');
232
232
  try {
233
- _chunkIWSMDQE5cjs.checkVideoTimeRemap.call(void 0, remap, path);
233
+ _chunk4QQZV5Y5cjs.checkVideoTimeRemap.call(void 0, remap, path);
234
234
  } catch (e) {
235
235
  throw new Error(e.message.replace(/\.?$/, "."));
236
236
  }
@@ -240,17 +240,17 @@ function parseVideoClipAnimation(v, path) {
240
240
  if (v === void 0) return void 0;
241
241
  if (!isObject(v)) return fail(path, "must be an object { effect, duration }");
242
242
  return compact({
243
- effect: oneOf(v.effect, _chunkIWSMDQE5cjs.VIDEO_CLIP_ANIMATION_EFFECTS, `${path}.effect`, false),
243
+ effect: oneOf(v.effect, _chunk4QQZV5Y5cjs.VIDEO_CLIP_ANIMATION_EFFECTS, `${path}.effect`, false),
244
244
  duration: num(v.duration, `${path}.duration`, { optional: true, positive: true })
245
245
  });
246
246
  }
247
247
  function parseVideoGrade(v, path) {
248
248
  if (v === void 0) return void 0;
249
249
  if (!isObject(v)) return fail(path, "must be an object such as { exposure, contrast, saturation }");
250
- const known = /* @__PURE__ */ new Set([..._chunkIWSMDQE5cjs.VIDEO_GRADE_CONTROLS.map((c) => c.key), "lut"]);
250
+ const known = /* @__PURE__ */ new Set([..._chunk4QQZV5Y5cjs.VIDEO_GRADE_CONTROLS.map((c) => c.key), "lut"]);
251
251
  const unknown = Object.keys(v).find((k) => !known.has(k));
252
252
  if (unknown) fail(`${path}.${unknown}`, `is not a grade setting; use ${[...known].join(", ")}`);
253
- return compact({ ...Object.fromEntries(_chunkIWSMDQE5cjs.VIDEO_GRADE_CONTROLS.map((c) => [c.key, num(v[c.key], `${path}.${c.key}`, { optional: true, min: c.min, max: c.max })])), lut: parseVideoGradeLut(v.lut, `${path}.lut`) });
253
+ return compact({ ...Object.fromEntries(_chunk4QQZV5Y5cjs.VIDEO_GRADE_CONTROLS.map((c) => [c.key, num(v[c.key], `${path}.${c.key}`, { optional: true, min: c.min, max: c.max })])), lut: parseVideoGradeLut(v.lut, `${path}.lut`) });
254
254
  }
255
255
  function parseVideoGradeLut(v, path) {
256
256
  if (v === void 0) return void 0;
@@ -262,15 +262,15 @@ function parseVideoGradeLut(v, path) {
262
262
  function parseVideoTransition(v, path) {
263
263
  if (v === void 0) return void 0;
264
264
  if (!isObject(v)) return fail(path, "must be an object { type, duration }");
265
- const type = oneOf(v.type, _chunkIWSMDQE5cjs.VIDEO_TRANSITION_TYPES, `${path}.type`, false);
265
+ const type = oneOf(v.type, _chunk4QQZV5Y5cjs.VIDEO_TRANSITION_TYPES, `${path}.type`, false);
266
266
  if (type === "effect" && v.effect === void 0) fail(`${path}.effect`, 'is required for an effect transition: { effect: "<effect id>", values }');
267
267
  if (type !== "effect" && v.effect !== void 0) fail(`${path}.effect`, 'is only for transitions of type "effect"');
268
268
  return compact({
269
269
  type,
270
270
  duration: num(v.duration, `${path}.duration`, { positive: true }),
271
271
  color: str(v.color, `${path}.color`, true),
272
- direction: oneOf(v.direction, _chunkIWSMDQE5cjs.VIDEO_WIPE_DIRECTIONS, `${path}.direction`),
273
- audioCurve: oneOf(v.audioCurve, _chunkIWSMDQE5cjs.VIDEO_FADE_CURVES, `${path}.audioCurve`),
272
+ direction: oneOf(v.direction, _chunk4QQZV5Y5cjs.VIDEO_WIPE_DIRECTIONS, `${path}.direction`),
273
+ audioCurve: oneOf(v.audioCurve, _chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES, `${path}.audioCurve`),
274
274
  effect: v.effect === void 0 ? void 0 : parseVideoEffectRef(v.effect, `${path}.effect`, false)
275
275
  });
276
276
  }
@@ -363,7 +363,7 @@ function parseVideoAssetProxies(v, path) {
363
363
  }
364
364
  function parseVideoClip(v, path = "clip") {
365
365
  if (!isObject(v)) return fail(path, "must be an object");
366
- const type = oneOf(_nullishCoalesce(v.type, () => ( "media")), _chunkIWSMDQE5cjs.VIDEO_CLIP_TYPES, `${path}.type`, false);
366
+ const type = oneOf(_nullishCoalesce(v.type, () => ( "media")), _chunk4QQZV5Y5cjs.VIDEO_CLIP_TYPES, `${path}.type`, false);
367
367
  const base = {
368
368
  id: str(v.id, `${path}.id`),
369
369
  name: str(v.name, `${path}.name`, true),
@@ -371,8 +371,8 @@ function parseVideoClip(v, path = "clip") {
371
371
  duration: num(v.duration, `${path}.duration`, { positive: true }),
372
372
  opacity: parseVideoAnimatable(v.opacity, `${path}.opacity`, { optional: true, min: 0, max: 1 }),
373
373
  transform: parseVideoTransform(v.transform, `${path}.transform`),
374
- fit: oneOf(v.fit, _chunkIWSMDQE5cjs.VIDEO_FITS, `${path}.fit`),
375
- blend: oneOf(v.blend, _chunkIWSMDQE5cjs.VIDEO_BLEND_MODES, `${path}.blend`),
374
+ fit: oneOf(v.fit, _chunk4QQZV5Y5cjs.VIDEO_FITS, `${path}.fit`),
375
+ blend: oneOf(v.blend, _chunk4QQZV5Y5cjs.VIDEO_BLEND_MODES, `${path}.blend`),
376
376
  grade: parseVideoGrade(v.grade, `${path}.grade`),
377
377
  animateIn: parseVideoClipAnimation(v.animateIn, `${path}.animateIn`),
378
378
  animateOut: parseVideoClipAnimation(v.animateOut, `${path}.animateOut`),
@@ -391,8 +391,8 @@ function parseVideoClip(v, path = "clip") {
391
391
  volume: parseVideoAnimatable(v.volume, `${path}.volume`, { optional: true, min: 0, max: 4 }),
392
392
  muted: bool(v.muted, `${path}.muted`),
393
393
  timeRemap: parseVideoTimeRemap(v.timeRemap, v.speed, `${path}.timeRemap`),
394
- fadeInCurve: oneOf(v.fadeInCurve, _chunkIWSMDQE5cjs.VIDEO_FADE_CURVES, `${path}.fadeInCurve`),
395
- fadeOutCurve: oneOf(v.fadeOutCurve, _chunkIWSMDQE5cjs.VIDEO_FADE_CURVES, `${path}.fadeOutCurve`)
394
+ fadeInCurve: oneOf(v.fadeInCurve, _chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES, `${path}.fadeInCurve`),
395
+ fadeOutCurve: oneOf(v.fadeOutCurve, _chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES, `${path}.fadeOutCurve`)
396
396
  });
397
397
  if (type === "sequence") {
398
398
  for (const key of ["speed", "timeRemap"])
@@ -404,8 +404,8 @@ function parseVideoClip(v, path = "clip") {
404
404
  in: num(v.in, `${path}.in`, { optional: true, min: 0 }),
405
405
  volume: parseVideoAnimatable(v.volume, `${path}.volume`, { optional: true, min: 0, max: 4 }),
406
406
  muted: bool(v.muted, `${path}.muted`),
407
- fadeInCurve: oneOf(v.fadeInCurve, _chunkIWSMDQE5cjs.VIDEO_FADE_CURVES, `${path}.fadeInCurve`),
408
- fadeOutCurve: oneOf(v.fadeOutCurve, _chunkIWSMDQE5cjs.VIDEO_FADE_CURVES, `${path}.fadeOutCurve`)
407
+ fadeInCurve: oneOf(v.fadeInCurve, _chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES, `${path}.fadeInCurve`),
408
+ fadeOutCurve: oneOf(v.fadeOutCurve, _chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES, `${path}.fadeOutCurve`)
409
409
  });
410
410
  }
411
411
  if (type === "text")
@@ -516,9 +516,9 @@ function createVideoProject(options = {}) {
516
516
  // src/video-editor/check.ts
517
517
  function videoClipKeyframes(clip) {
518
518
  const out = [
519
- { property: "opacity", keys: _chunkIWSMDQE5cjs.videoKeysOf.call(void 0, clip.opacity) },
520
- { property: "volume", keys: clip.type === "media" || clip.type === "sequence" ? _chunkIWSMDQE5cjs.videoKeysOf.call(void 0, clip.volume) : [] },
521
- ..._chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES.map((p) => ({ property: p, keys: _chunkIWSMDQE5cjs.videoKeysOf.call(void 0, _optionalChain([clip, 'access', _2 => _2.transform, 'optionalAccess', _3 => _3[p]])) }))
519
+ { property: "opacity", keys: _chunk4QQZV5Y5cjs.videoKeysOf.call(void 0, clip.opacity) },
520
+ { property: "volume", keys: clip.type === "media" || clip.type === "sequence" ? _chunk4QQZV5Y5cjs.videoKeysOf.call(void 0, clip.volume) : [] },
521
+ ..._chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES.map((p) => ({ property: p, keys: _chunk4QQZV5Y5cjs.videoKeysOf.call(void 0, _optionalChain([clip, 'access', _2 => _2.transform, 'optionalAccess', _3 => _3[p]])) }))
522
522
  ];
523
523
  return out.filter((o) => o.keys.length);
524
524
  }
@@ -545,8 +545,8 @@ var VIDEO_ISSUE_CODES = [
545
545
  var videoIssueKey = (i) => [i.code, _nullishCoalesce(i.sequence, () => ( "")), _nullishCoalesce(i.track, () => ( "")), _nullishCoalesce(i.clip, () => ( "")), _nullishCoalesce(i.asset, () => ( "")), _nullishCoalesce(i.marker, () => ( ""))].join("|");
546
546
  function checkVideoProject(project) {
547
547
  const issues = [];
548
- const assets = _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, project);
549
- const sequences = _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, project);
548
+ const assets = _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, project);
549
+ const sequences = _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, project);
550
550
  const used = /* @__PURE__ */ new Set();
551
551
  const usedSequences = /* @__PURE__ */ new Set();
552
552
  const cycles = /* @__PURE__ */ new Map();
@@ -554,7 +554,7 @@ function checkVideoProject(project) {
554
554
  if ((asset.kind === "video" || asset.kind === "audio") && asset.duration === void 0)
555
555
  issues.push({ code: "unknown-duration", severity: "warning", asset: asset.id, message: `Asset "${asset.id}" has no duration, so clips of it cannot be checked against its length; set "duration" in ms.` });
556
556
  const checkTrack = (track, sequence) => {
557
- const clips = _chunkIWSMDQE5cjs.sortedVideoClips.call(void 0, track);
557
+ const clips = _chunk4QQZV5Y5cjs.sortedVideoClips.call(void 0, track);
558
558
  const where = sequence ? ` in sequence "${sequence}"` : "";
559
559
  for (let i = 0; i < clips.length; i++) {
560
560
  const clip = clips[i];
@@ -564,13 +564,13 @@ function checkVideoProject(project) {
564
564
  const seq = sequences.get(clip.sequence);
565
565
  if (!seq) issues.push({ code: "missing-sequence", severity: "error", ...at, message: `Compound clip "${clip.id}" plays sequence "${clip.sequence}", which is not in the project; add the sequence or delete the clip.` });
566
566
  else {
567
- if (!cycles.has(seq.id)) cycles.set(seq.id, _chunkIWSMDQE5cjs.findVideoSequenceCycle.call(void 0, project, seq.id));
567
+ if (!cycles.has(seq.id)) cycles.set(seq.id, _chunk4QQZV5Y5cjs.findVideoSequenceCycle.call(void 0, project, seq.id));
568
568
  const cycle = cycles.get(seq.id);
569
569
  if (cycle) issues.push({ code: "sequence-cycle", severity: "error", ...at, message: `Compound clip "${clip.id}" plays sequence "${seq.id}", which contains itself (${cycle.join(" \u2192 ")}), so it is left out of the picture and sound; remove the compound clip that closes the loop.` });
570
- const length = _chunkIWSMDQE5cjs.videoSequenceDuration.call(void 0, seq);
571
- const range = _chunkIWSMDQE5cjs.videoClipSourceRange.call(void 0, clip);
572
- if (range.out > length + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
573
- issues.push({ code: "source-overrun", severity: "error", ...at, message: `Compound clip "${clip.id}" plays to ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, range.out)} of sequence "${seq.id}", which is only ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, length)} long; shorten the clip or move its in point.` });
570
+ const length = _chunk4QQZV5Y5cjs.videoSequenceDuration.call(void 0, seq);
571
+ const range = _chunk4QQZV5Y5cjs.videoClipSourceRange.call(void 0, clip);
572
+ if (range.out > length + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
573
+ issues.push({ code: "source-overrun", severity: "error", ...at, message: `Compound clip "${clip.id}" plays to ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, range.out)} of sequence "${seq.id}", which is only ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, length)} long; shorten the clip or move its in point.` });
574
574
  }
575
575
  } else if (clip.type === "media") {
576
576
  used.add(clip.asset);
@@ -579,28 +579,28 @@ function checkVideoProject(project) {
579
579
  else {
580
580
  if (track.kind === "audio" && asset.kind === "image") issues.push({ code: "wrong-track", severity: "error", ...at, message: `Clip "${clip.id}" is an image on audio track "${track.id}"; move it to a video track.` });
581
581
  if (track.kind === "video" && asset.kind === "audio") issues.push({ code: "wrong-track", severity: "error", ...at, message: `Clip "${clip.id}" is audio on video track "${track.id}"; move it to an audio track.` });
582
- const range = _chunkIWSMDQE5cjs.videoClipSourceRange.call(void 0, clip);
583
- if (asset.duration !== void 0 && range.out > asset.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
584
- issues.push({ code: "source-overrun", severity: "error", ...at, message: `Clip "${clip.id}" plays to ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, range.out)} of "${asset.id}", which is only ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, asset.duration)} long; shorten the clip or move its in point.` });
582
+ const range = _chunk4QQZV5Y5cjs.videoClipSourceRange.call(void 0, clip);
583
+ if (asset.duration !== void 0 && range.out > asset.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
584
+ issues.push({ code: "source-overrun", severity: "error", ...at, message: `Clip "${clip.id}" plays to ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, range.out)} of "${asset.id}", which is only ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, asset.duration)} long; shorten the clip or move its in point.` });
585
585
  }
586
586
  } else if (track.kind === "audio") issues.push({ code: "wrong-track", severity: "error", ...at, message: `Clip "${clip.id}" is a ${clip.type} clip on audio track "${track.id}"; move it to a video track.` });
587
587
  const next = clips[i + 1];
588
- if (next && next.start < _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip) - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
589
- issues.push({ code: "overlap", severity: "error", ...at, message: `Clips "${clip.id}" and "${next.id}" overlap on track "${track.id}"${where} from ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, next.start)}; move one of them.` });
590
- if ((_nullishCoalesce(clip.fadeIn, () => ( 0))) + (_nullishCoalesce(clip.fadeOut, () => ( 0))) > clip.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
588
+ if (next && next.start < _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip) - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
589
+ issues.push({ code: "overlap", severity: "error", ...at, message: `Clips "${clip.id}" and "${next.id}" overlap on track "${track.id}"${where} from ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, next.start)}; move one of them.` });
590
+ if ((_nullishCoalesce(clip.fadeIn, () => ( 0))) + (_nullishCoalesce(clip.fadeOut, () => ( 0))) > clip.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
591
591
  issues.push({ code: "fades-too-long", severity: "warning", ...at, message: `Clip "${clip.id}"'s fades (${_nullishCoalesce(clip.fadeIn, () => ( 0))} + ${_nullishCoalesce(clip.fadeOut, () => ( 0))} ms) are longer than the clip (${clip.duration} ms); shorten them.` });
592
- const anim = (clip.animateIn ? _nullishCoalesce(clip.animateIn.duration, () => ( _chunkIWSMDQE5cjs.VIDEO_CLIP_ANIMATION_DURATION)) : 0) + (clip.animateOut ? _nullishCoalesce(clip.animateOut.duration, () => ( _chunkIWSMDQE5cjs.VIDEO_CLIP_ANIMATION_DURATION)) : 0);
593
- if (anim > clip.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
592
+ const anim = (clip.animateIn ? _nullishCoalesce(clip.animateIn.duration, () => ( _chunk4QQZV5Y5cjs.VIDEO_CLIP_ANIMATION_DURATION)) : 0) + (clip.animateOut ? _nullishCoalesce(clip.animateOut.duration, () => ( _chunk4QQZV5Y5cjs.VIDEO_CLIP_ANIMATION_DURATION)) : 0);
593
+ if (anim > clip.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
594
594
  issues.push({ code: "animations-too-long", severity: "warning", ...at, message: `Clip "${clip.id}"'s entrance and exit (${anim} ms together) are longer than the clip (${clip.duration} ms), so both are shortened; give them shorter durations.` });
595
595
  for (const which of ["animateIn", "animateOut"]) {
596
596
  const a = clip[which];
597
597
  if (!a) continue;
598
- const keyed = _chunkIWSMDQE5cjs.videoClipAnimationProperties.call(void 0, a).filter((p) => _chunkIWSMDQE5cjs.videoKeysOf.call(void 0, p === "opacity" ? clip.opacity : _optionalChain([clip, 'access', _4 => _4.transform, 'optionalAccess', _5 => _5[p]])).length);
598
+ const keyed = _chunk4QQZV5Y5cjs.videoClipAnimationProperties.call(void 0, a).filter((p) => _chunk4QQZV5Y5cjs.videoKeysOf.call(void 0, p === "opacity" ? clip.opacity : _optionalChain([clip, 'access', _4 => _4.transform, 'optionalAccess', _5 => _5[p]])).length);
599
599
  if (keyed.length)
600
600
  issues.push({ code: "animation-keyed", severity: "note", ...at, message: `Clip "${clip.id}"'s ${a.effect} ${which === "animateIn" ? "entrance" : "exit"} leaves ${keyed.join(", ")} alone, because the clip keys ${keyed.length > 1 ? "them" : "it"} itself; remove those keyframes or the animation.` });
601
601
  }
602
602
  for (const { property, keys } of videoClipKeyframes(clip)) {
603
- const outside = keys.filter((k) => k.t < -_chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON || k.t > clip.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON);
603
+ const outside = keys.filter((k) => k.t < -_chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON || k.t > clip.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON);
604
604
  if (outside.length)
605
605
  issues.push({
606
606
  code: "keyframes-outside-clip",
@@ -611,20 +611,20 @@ function checkVideoProject(project) {
611
611
  }
612
612
  if (clip.transition) {
613
613
  const d = clip.transition.duration;
614
- const before = _chunkIWSMDQE5cjs.videoClipBefore.call(void 0, track, clip);
614
+ const before = _chunk4QQZV5Y5cjs.videoClipBefore.call(void 0, track, clip);
615
615
  if (!before) {
616
616
  issues.push({ code: "transition-without-cut", severity: "warning", ...at, message: `Clip "${clip.id}" has a transition but no clip ends where it starts on track "${track.id}", so it plays as nothing; butt a clip up against it or remove the transition.` });
617
617
  continue;
618
618
  }
619
- if (d > clip.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON || d > before.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) {
619
+ if (d > clip.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON || d > before.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) {
620
620
  issues.push({ code: "transition-too-long", severity: "error", ...at, message: `The ${d} ms transition into "${clip.id}" is longer than "${clip.id}" (${clip.duration} ms) or "${before.id}" (${before.duration} ms); make it at most ${Math.min(clip.duration, before.duration)} ms.` });
621
621
  continue;
622
622
  }
623
623
  if (clip.transition.type === "dip") continue;
624
- const outgoing = _chunkIWSMDQE5cjs.videoClipHandles.call(void 0, before, assets, sequences).after;
625
- const incoming = _chunkIWSMDQE5cjs.videoClipHandles.call(void 0, clip, assets, sequences).before;
624
+ const outgoing = _chunk4QQZV5Y5cjs.videoClipHandles.call(void 0, before, assets, sequences).after;
625
+ const incoming = _chunk4QQZV5Y5cjs.videoClipHandles.call(void 0, clip, assets, sequences).before;
626
626
  const half = d / 2;
627
- if (outgoing < half - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON || incoming < half - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) {
627
+ if (outgoing < half - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON || incoming < half - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) {
628
628
  const fits = 2 * Math.min(outgoing, incoming);
629
629
  issues.push({
630
630
  code: "transition-handles",
@@ -641,9 +641,9 @@ function checkVideoProject(project) {
641
641
  for (const sequence of _nullishCoalesce(project.sequences, () => ( [])))
642
642
  if (!usedSequences.has(sequence.id)) issues.push({ code: "unused-sequence", severity: "note", sequence: sequence.id, message: `Sequence "${sequence.id}" is not played by any compound clip.` });
643
643
  for (const asset of project.assets) if (!used.has(asset.id)) issues.push({ code: "unused-asset", severity: "note", asset: asset.id, message: `Asset "${asset.id}" is not used by any clip.` });
644
- const end = _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, project);
644
+ const end = _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, project);
645
645
  for (const marker of _nullishCoalesce(project.markers, () => ( [])))
646
- if (marker.time > end + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) issues.push({ code: "marker-past-end", severity: "note", marker: marker.id, message: `Marker "${marker.id}" at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, marker.time)} is past the end (${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, end)}).` });
646
+ if (marker.time > end + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) issues.push({ code: "marker-past-end", severity: "note", marker: marker.id, message: `Marker "${marker.id}" at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, marker.time)} is past the end (${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, end)}).` });
647
647
  if (!project.tracks.some((t) => t.clips.length)) issues.push({ code: "empty", severity: "note", message: "The project has no clips yet; add assets and then clips." });
648
648
  const rank = { error: 0, warning: 1, note: 2 };
649
649
  return issues.sort((a, b) => rank[a.severity] - rank[b.severity]);
@@ -697,7 +697,7 @@ function mergeSpans(spans) {
697
697
  const out = [];
698
698
  for (const [from, to] of [...spans].sort((a, b) => a[0] - b[0])) {
699
699
  const last = out[out.length - 1];
700
- if (last && from <= last[1] + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) last[1] = Math.max(last[1], to);
700
+ if (last && from <= last[1] + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) last[1] = Math.max(last[1], to);
701
701
  else out.push([from, to]);
702
702
  }
703
703
  return out;
@@ -711,13 +711,13 @@ function clipAnimatables(clip) {
711
711
  // A speed ramp is keys in clip time too, so trims and splits keep it on the same frames of source.
712
712
  { get: () => c.timeRemap, set: (v) => c.timeRemap = v }
713
713
  ];
714
- for (const p of _chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES) out.push({ get: () => _optionalChain([c, 'access', _6 => _6.transform, 'optionalAccess', _7 => _7[p]]), set: (v) => c.transform && (c.transform[p] = v) });
714
+ for (const p of _chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES) out.push({ get: () => _optionalChain([c, 'access', _6 => _6.transform, 'optionalAccess', _7 => _7[p]]), set: (v) => c.transform && (c.transform[p] = v) });
715
715
  return out;
716
716
  }
717
717
  function retimeClipKeys(clip, fn) {
718
718
  for (const a of clipAnimatables(clip)) {
719
719
  const v = a.get();
720
- if (_chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, v)) a.set(fn(v));
720
+ if (_chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, v)) a.set(fn(v));
721
721
  }
722
722
  }
723
723
  var OPTIONAL_CLIP_FIELDS = ["name", "effects", "values", "provider", "opacity", "transform", "fit", "blend", "grade", "animateIn", "animateOut", "fadeIn", "fadeOut", "fadeInCurve", "fadeOutCurve", "transition", "in", "speed", "timeRemap", "volume", "muted", "color", "fontSize", "fontFamily", "fontWeight", "background"];
@@ -734,8 +734,8 @@ var Editor = (_class = class {
734
734
  return t;
735
735
  }
736
736
  clip(id) {
737
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, this.p, id);
738
- const nested = at ? null : _chunkIWSMDQE5cjs.findVideoSequenceClip.call(void 0, this.p, id);
737
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, this.p, id);
738
+ const nested = at ? null : _chunk4QQZV5Y5cjs.findVideoSequenceClip.call(void 0, this.p, id);
739
739
  if (nested) refuse(`Clip "${id}" is inside sequence "${nested.sequence.id}", and clips inside sequences cannot be edited yet; edit the compound clip that plays the sequence instead (list_video_sequences shows which).`);
740
740
  if (!at) {
741
741
  const ids = this.p.tracks.flatMap((t) => t.clips.map((c) => c.id));
@@ -752,10 +752,10 @@ var Editor = (_class = class {
752
752
  return a;
753
753
  }
754
754
  fits(track, start, duration, ignore, what) {
755
- const hit = _chunkIWSMDQE5cjs.videoOverlap.call(void 0, track, start, start + duration, ignore);
755
+ const hit = _chunk4QQZV5Y5cjs.videoOverlap.call(void 0, track, start, start + duration, ignore);
756
756
  if (hit) {
757
- const free = _chunkIWSMDQE5cjs.nextFreeVideoSlot.call(void 0, track, start, duration, ignore);
758
- refuse(`${what} at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, start)}\u2013${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, start + duration)} would overlap clip "${hit.id}" (${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, hit.start)}\u2013${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, hit))}) on track "${track.id}"; the next free place is ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, free)}, or use mode "insert" to push later clips along or "overwrite" to replace what is there.`);
757
+ const free = _chunk4QQZV5Y5cjs.nextFreeVideoSlot.call(void 0, track, start, duration, ignore);
758
+ refuse(`${what} at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, start)}\u2013${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, start + duration)} would overlap clip "${hit.id}" (${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, hit.start)}\u2013${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, hit))}) on track "${track.id}"; the next free place is ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, free)}, or use mode "insert" to push later clips along or "overwrite" to replace what is there.`);
759
759
  }
760
760
  }
761
761
  kindFits(track, clip) {
@@ -771,14 +771,14 @@ var Editor = (_class = class {
771
771
  /** Moves every clip on `track` starting at or after `from` by `delta`. */
772
772
  shift(track, from, delta, except = /* @__PURE__ */ new Set()) {
773
773
  if (!delta) return;
774
- for (const c of track.clips) if (!except.has(c.id) && c.start >= from - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) c.start = Math.max(0, c.start + delta);
774
+ for (const c of track.clips) if (!except.has(c.id) && c.start >= from - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) c.start = Math.max(0, c.start + delta);
775
775
  track.clips.sort((a, b) => a.start - b.start);
776
776
  }
777
777
  get frame() {
778
778
  return 1e3 / this.p.fps;
779
779
  }
780
780
  ids() {
781
- return _chunkIWSMDQE5cjs.allVideoClipIds.call(void 0, this.p);
781
+ return _chunk4QQZV5Y5cjs.allVideoClipIds.call(void 0, this.p);
782
782
  }
783
783
  /**
784
784
  * The tracks a ripple on `sources` moves, top to bottom: the sources, and every unlocked
@@ -786,8 +786,8 @@ var Editor = (_class = class {
786
786
  */
787
787
  rippleTracks(sources) {
788
788
  const set = new Set(sources);
789
- if ([...set].some(_chunkIWSMDQE5cjs.videoTrackSyncLocked)) {
790
- for (const t of this.p.tracks) if (_chunkIWSMDQE5cjs.videoTrackSyncLocked.call(void 0, t) && !t.locked) set.add(t);
789
+ if ([...set].some(_chunk4QQZV5Y5cjs.videoTrackSyncLocked)) {
790
+ for (const t of this.p.tracks) if (_chunk4QQZV5Y5cjs.videoTrackSyncLocked.call(void 0, t) && !t.locked) set.add(t);
791
791
  }
792
792
  return this.p.tracks.filter((t) => set.has(t));
793
793
  }
@@ -804,7 +804,7 @@ var Editor = (_class = class {
804
804
  return open;
805
805
  }
806
806
  range(from, to) {
807
- if (!(to - from > _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)) refuse(`"to" (${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, to)}) must be after "from" (${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, from)}).`);
807
+ if (!(to - from > _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)) refuse(`"to" (${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, to)}) must be after "from" (${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, from)}).`);
808
808
  }
809
809
  /** Moves a media or compound clip's in point by `delta` of timeline time (stills, titles and colours have none). */
810
810
  moveIn(clip, delta) {
@@ -813,18 +813,18 @@ var Editor = (_class = class {
813
813
  if (clip.in < 1e-9) delete clip.in;
814
814
  return;
815
815
  }
816
- if (clip.type !== "media" || _optionalChain([_chunkIWSMDQE5cjs.videoAssetMap.call(void 0, this.p), 'access', _9 => _9.get, 'call', _10 => _10(clip.asset), 'optionalAccess', _11 => _11.kind]) === "image") return;
817
- clip.in = Math.max(0, (_nullishCoalesce(clip.in, () => ( 0))) + delta * _chunkIWSMDQE5cjs.videoClipSpeed.call(void 0, clip));
816
+ if (clip.type !== "media" || _optionalChain([_chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, this.p), 'access', _9 => _9.get, 'call', _10 => _10(clip.asset), 'optionalAccess', _11 => _11.kind]) === "image") return;
817
+ clip.in = Math.max(0, (_nullishCoalesce(clip.in, () => ( 0))) + delta * _chunk4QQZV5Y5cjs.videoClipSpeed.call(void 0, clip));
818
818
  if (clip.in < 1e-9) delete clip.in;
819
819
  }
820
820
  /** Moves a clip's head `delta` later in time (start, in point and keys); the caller sets start and duration. */
821
821
  trimHead(clip, delta) {
822
822
  if (!isRamped(clip)) this.moveIn(clip, delta);
823
- retimeClipKeys(clip, (v) => _chunkIWSMDQE5cjs.retimeVideoAnimatable.call(void 0, v, -delta));
823
+ retimeClipKeys(clip, (v) => _chunk4QQZV5Y5cjs.retimeVideoAnimatable.call(void 0, v, -delta));
824
824
  }
825
825
  /** Cuts `clip` at `at` (inside it): the left part keeps the id, the right part is returned. */
826
826
  cut(track, clip, at, id) {
827
- const end = _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip);
827
+ const end = _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip);
828
828
  const right = { ...structuredClone(clip), id: _nullishCoalesce(id, () => ( freshId(`${clip.id}-`, this.ids()))), start: at, duration: end - at };
829
829
  delete right.transition;
830
830
  delete right.fadeIn;
@@ -832,9 +832,9 @@ var Editor = (_class = class {
832
832
  delete right.animateIn;
833
833
  const leftValues = clipAnimatables(clip);
834
834
  clipAnimatables(right).forEach((r, i) => {
835
- const [l, rr] = _chunkIWSMDQE5cjs.splitVideoAnimatable.call(void 0, leftValues[i].get(), at - clip.start);
836
- if (_chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, l)) leftValues[i].set(l);
837
- if (_chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, rr)) r.set(rr);
835
+ const [l, rr] = _chunk4QQZV5Y5cjs.splitVideoAnimatable.call(void 0, leftValues[i].get(), at - clip.start);
836
+ if (_chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, l)) leftValues[i].set(l);
837
+ if (_chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, rr)) r.set(rr);
838
838
  });
839
839
  if (!isRamped(right)) this.moveIn(right, at - clip.start);
840
840
  clip.duration = at - clip.start;
@@ -848,7 +848,7 @@ var Editor = (_class = class {
848
848
  /** Cuts every clip on `tracks` that runs across `at`; returns the new right-hand parts. */
849
849
  cutAcross(tracks, at) {
850
850
  const made = [];
851
- for (const t of tracks) for (const c of [...t.clips]) if (c.start < at - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON && _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c) > at + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) made.push(this.cut(t, c, at));
851
+ for (const t of tracks) for (const c of [...t.clips]) if (c.start < at - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON && _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c) > at + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) made.push(this.cut(t, c, at));
852
852
  return made;
853
853
  }
854
854
  /**
@@ -866,10 +866,10 @@ var Editor = (_class = class {
866
866
  */
867
867
  close(tracks, from, to) {
868
868
  for (const t of tracks) {
869
- const hit = _chunkIWSMDQE5cjs.videoOverlap.call(void 0, t, from, to);
869
+ const hit = _chunk4QQZV5Y5cjs.videoOverlap.call(void 0, t, from, to);
870
870
  if (hit)
871
871
  refuse(
872
- `Rippling out ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, from)}\u2013${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, to)} would pull track "${t.id}" out of sync: clip "${hit.id}" (${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, hit.start)}\u2013${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, hit))}) is in that stretch. Extract the range across "${t.id}" too (extract_range with its id in "tracks"), turn its sync lock off (update_track with syncLocked false) or lock it, or lift instead of rippling.`
872
+ `Rippling out ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, from)}\u2013${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, to)} would pull track "${t.id}" out of sync: clip "${hit.id}" (${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, hit.start)}\u2013${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, hit))}) is in that stretch. Extract the range across "${t.id}" too (extract_range with its id in "tracks"), turn its sync lock off (update_track with syncLocked false) or lock it, or lift instead of rippling.`
873
873
  );
874
874
  }
875
875
  for (const t of tracks) this.shift(t, to, from - to);
@@ -881,10 +881,10 @@ var Editor = (_class = class {
881
881
  clear(track, from, to, report) {
882
882
  for (const c of [...track.clips]) {
883
883
  const start = c.start;
884
- const end = _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c);
885
- if (end <= from + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON || start >= to - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) continue;
886
- const coversHead = start >= from - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON;
887
- const coversTail = end <= to + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON;
884
+ const end = _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c);
885
+ if (end <= from + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON || start >= to - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) continue;
886
+ const coversHead = start >= from - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON;
887
+ const coversTail = end <= to + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON;
888
888
  if (coversHead && coversTail) {
889
889
  track.clips = track.clips.filter((x) => x !== c);
890
890
  report.removed.push(c.id);
@@ -907,8 +907,8 @@ var Editor = (_class = class {
907
907
  /** Clamps a slip, roll or slide to `[lo, hi]`, refusing when it cannot move that way at all. */
908
908
  clamp(delta, lo, hi, why) {
909
909
  const applied = Math.min(Math.max(delta, Math.min(0, lo)), Math.max(0, hi));
910
- if (Math.abs(delta) > _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON && Math.abs(applied) <= _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) refuse(why());
911
- return Math.abs(applied) <= _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON ? 0 : applied;
910
+ if (Math.abs(delta) > _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON && Math.abs(applied) <= _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) refuse(why());
911
+ return Math.abs(applied) <= _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON ? 0 : applied;
912
912
  }
913
913
  /** Places a clip on a track by `mode`, returning what it cut, trimmed, removed and rippled. */
914
914
  place(track, clip, mode, outcome) {
@@ -918,14 +918,14 @@ var Editor = (_class = class {
918
918
  outcome.rippled = tracks.map((t) => t.id);
919
919
  } else if (mode === "overwrite") {
920
920
  const report = { removed: [], trimmed: [], created: [] };
921
- this.clear(track, clip.start, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip), report);
921
+ this.clear(track, clip.start, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip), report);
922
922
  Object.assign(outcome, report);
923
923
  } else this.fits(track, clip.start, clip.duration, /* @__PURE__ */ new Set([clip.id]), `Clip "${clip.id}"`);
924
924
  track.clips.push(clip);
925
925
  track.clips.sort((a, b) => a.start - b.start);
926
926
  }
927
927
  placement(mode, ripple) {
928
- if (mode !== void 0 && !_chunkIWSMDQE5cjs.VIDEO_PLACEMENT_MODES.includes(mode)) refuse(`"mode" must be ${_chunkIWSMDQE5cjs.VIDEO_PLACEMENT_MODES.map((m) => `"${m}"`).join(", ")}.`);
928
+ if (mode !== void 0 && !_chunk4QQZV5Y5cjs.VIDEO_PLACEMENT_MODES.includes(mode)) refuse(`"mode" must be ${_chunk4QQZV5Y5cjs.VIDEO_PLACEMENT_MODES.map((m) => `"${m}"`).join(", ")}.`);
929
929
  if (ripple && mode !== void 0 && mode !== "insert") refuse(`"ripple" means mode "insert", so it cannot go with mode "${mode}"; pass one or the other.`);
930
930
  return _nullishCoalesce(mode, () => ( (ripple ? "insert" : "refuse")));
931
931
  }
@@ -962,7 +962,7 @@ var Editor = (_class = class {
962
962
  }
963
963
  case "remove_asset": {
964
964
  const asset = this.asset(e.asset);
965
- const users = _chunkIWSMDQE5cjs.allVideoTracks.call(void 0, this.p).flatMap(({ track: t }) => t.clips.filter((c) => c.type === "media" && c.asset === asset.id).map((c) => c.id));
965
+ const users = _chunk4QQZV5Y5cjs.allVideoTracks.call(void 0, this.p).flatMap(({ track: t }) => t.clips.filter((c) => c.type === "media" && c.asset === asset.id).map((c) => c.id));
966
966
  if (users.length) refuse(`Asset "${asset.id}" is used by clip${users.length > 1 ? "s" : ""} ${users.map((u) => `"${u}"`).join(", ")}; delete ${users.length > 1 ? "them" : "it"} first.`);
967
967
  this.p.assets = this.p.assets.filter((a) => a !== asset);
968
968
  return this.outcomes.push({ op: e.op, asset: asset.id });
@@ -1015,12 +1015,12 @@ var Editor = (_class = class {
1015
1015
  else draft.duration = (asset.duration - (_nullishCoalesce(draft.in, () => ( 0)))) / (_nullishCoalesce(draft.speed, () => ( 1)));
1016
1016
  if (!(draft.duration > 0)) refuse(`"in" (${draft.in} ms) is at or past the end of "${asset.id}" (${asset.duration} ms).`);
1017
1017
  } else if (draft.type === "sequence") {
1018
- const length = _chunkIWSMDQE5cjs.videoSequenceDuration.call(void 0, _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, this.p).get(draft.sequence)) - (_nullishCoalesce(draft.in, () => ( 0)));
1018
+ const length = _chunk4QQZV5Y5cjs.videoSequenceDuration.call(void 0, _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, this.p).get(draft.sequence)) - (_nullishCoalesce(draft.in, () => ( 0)));
1019
1019
  if (!(length > 0)) refuse(`"in" (${_nullishCoalesce(draft.in, () => ( 0))} ms) is at or past the end of sequence "${draft.sequence}".`);
1020
1020
  draft.duration = length;
1021
1021
  } else draft.duration = VIDEO_DEFAULT_TITLE_DURATION;
1022
1022
  }
1023
- const end = _chunkIWSMDQE5cjs.sortedVideoClips.call(void 0, track).reduce((m, c) => Math.max(m, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c)), 0);
1023
+ const end = _chunk4QQZV5Y5cjs.sortedVideoClips.call(void 0, track).reduce((m, c) => Math.max(m, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c)), 0);
1024
1024
  draft.start ??= end;
1025
1025
  const clip = parseVideoClip(draft, "clip");
1026
1026
  const outcome = { op: e.op, clip: clip.id, track: track.id };
@@ -1045,20 +1045,20 @@ var Editor = (_class = class {
1045
1045
  case "trim_clip": {
1046
1046
  const { track, clip } = this.clip(e.clip);
1047
1047
  this.unlocked(track);
1048
- const speed = _chunkIWSMDQE5cjs.videoClipSpeed.call(void 0, clip);
1049
- const end = _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip);
1048
+ const speed = _chunk4QQZV5Y5cjs.videoClipSpeed.call(void 0, clip);
1049
+ const end = _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip);
1050
1050
  const minimum = 1e3 / this.p.fps;
1051
- const assets = _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, this.p);
1051
+ const assets = _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, this.p);
1052
1052
  if (e.edge === "start") {
1053
1053
  const delta = e.to - clip.start;
1054
- if (clip.duration - delta < minimum - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) refuse(`Trimming the start to ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, e.to)} would leave "${clip.id}" shorter than a frame; it ends at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, end)}.`);
1054
+ if (clip.duration - delta < minimum - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) refuse(`Trimming the start to ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, e.to)} would leave "${clip.id}" shorter than a frame; it ends at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, end)}.`);
1055
1055
  if (clip.type === "media" && !isRamped(clip) || clip.type === "sequence") {
1056
1056
  const sourceIn = (_nullishCoalesce(clip.in, () => ( 0))) + delta * speed;
1057
- if (sourceIn < -_chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) refuse(`"${clip.id}" starts ${Math.round((_nullishCoalesce(clip.in, () => ( 0))) / speed)} ms into its source, so its start can move at most that far earlier (to ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, clip.start - (_nullishCoalesce(clip.in, () => ( 0))) / speed)}).`);
1057
+ if (sourceIn < -_chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) refuse(`"${clip.id}" starts ${Math.round((_nullishCoalesce(clip.in, () => ( 0))) / speed)} ms into its source, so its start can move at most that far earlier (to ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, clip.start - (_nullishCoalesce(clip.in, () => ( 0))) / speed)}).`);
1058
1058
  clip.in = Math.max(0, sourceIn);
1059
1059
  if (clip.in === 0) delete clip.in;
1060
1060
  }
1061
- retimeClipKeys(clip, (v) => _chunkIWSMDQE5cjs.retimeVideoAnimatable.call(void 0, v, -delta));
1061
+ retimeClipKeys(clip, (v) => _chunk4QQZV5Y5cjs.retimeVideoAnimatable.call(void 0, v, -delta));
1062
1062
  if (e.ripple) {
1063
1063
  const tracks = this.rippleTracks([track]);
1064
1064
  if (delta > 0) {
@@ -1079,17 +1079,17 @@ var Editor = (_class = class {
1079
1079
  }
1080
1080
  } else {
1081
1081
  const duration = e.to - clip.start;
1082
- if (duration < minimum - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) refuse(`Trimming the end to ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, e.to)} would leave "${clip.id}" shorter than a frame; it starts at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, clip.start)}.`);
1082
+ if (duration < minimum - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) refuse(`Trimming the end to ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, e.to)} would leave "${clip.id}" shorter than a frame; it starts at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, clip.start)}.`);
1083
1083
  if (clip.type === "media" && !isRamped(clip)) {
1084
1084
  const asset = assets.get(clip.asset);
1085
1085
  const out = (_nullishCoalesce(clip.in, () => ( 0))) + duration * speed;
1086
- if (_optionalChain([asset, 'optionalAccess', _12 => _12.duration]) !== void 0 && out > asset.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
1087
- refuse(`"${clip.id}" can end at most at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, clip.start + (asset.duration - (_nullishCoalesce(clip.in, () => ( 0)))) / speed)}, where "${asset.id}" runs out.`);
1086
+ if (_optionalChain([asset, 'optionalAccess', _12 => _12.duration]) !== void 0 && out > asset.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
1087
+ refuse(`"${clip.id}" can end at most at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, clip.start + (asset.duration - (_nullishCoalesce(clip.in, () => ( 0)))) / speed)}, where "${asset.id}" runs out.`);
1088
1088
  }
1089
1089
  if (clip.type === "sequence") {
1090
- const seq = _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, this.p).get(clip.sequence);
1091
- const length = seq ? _chunkIWSMDQE5cjs.videoSequenceDuration.call(void 0, seq) : Infinity;
1092
- if ((_nullishCoalesce(clip.in, () => ( 0))) + duration > length + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) refuse(`"${clip.id}" can end at most at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, clip.start + length - (_nullishCoalesce(clip.in, () => ( 0))))}, where sequence "${clip.sequence}" ends.`);
1090
+ const seq = _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, this.p).get(clip.sequence);
1091
+ const length = seq ? _chunk4QQZV5Y5cjs.videoSequenceDuration.call(void 0, seq) : Infinity;
1092
+ if ((_nullishCoalesce(clip.in, () => ( 0))) + duration > length + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) refuse(`"${clip.id}" can end at most at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, clip.start + length - (_nullishCoalesce(clip.in, () => ( 0))))}, where sequence "${clip.sequence}" ends.`);
1093
1093
  }
1094
1094
  if (e.ripple) {
1095
1095
  const tracks = this.rippleTracks([track]);
@@ -1111,9 +1111,9 @@ var Editor = (_class = class {
1111
1111
  case "split_clip": {
1112
1112
  const { track, clip } = this.clip(e.clip);
1113
1113
  this.unlocked(track);
1114
- const end = _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip);
1114
+ const end = _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip);
1115
1115
  const minimum = 1e3 / this.p.fps;
1116
- if (e.at < clip.start + minimum - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON || e.at > end - minimum + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) refuse(`${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, e.at)} is not inside "${clip.id}" (${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, clip.start)}\u2013${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, end)}), at least a frame from either end.`);
1116
+ if (e.at < clip.start + minimum - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON || e.at > end - minimum + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) refuse(`${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, e.at)} is not inside "${clip.id}" (${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, clip.start)}\u2013${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, end)}), at least a frame from either end.`);
1117
1117
  if (e.id !== void 0 && this.ids().includes(e.id)) refuse(`There is already a clip "${e.id}".`);
1118
1118
  const right = this.cut(track, clip, e.at, e.id);
1119
1119
  return this.outcomes.push({ op: e.op, clips: [clip.id, right.id], clip: right.id, track: track.id });
@@ -1124,12 +1124,12 @@ var Editor = (_class = class {
1124
1124
  for (const track of new Set(found.map((f) => f.track))) track.clips = track.clips.filter((c) => !found.some((f) => f.clip === c));
1125
1125
  if (!e.ripple) return this.outcomes.push({ op: e.op, clips: found.map((f) => f.clip.id) });
1126
1126
  const rippled = /* @__PURE__ */ new Set();
1127
- const groups = [...new Set(found.map((f) => f.track))].filter((t) => !_chunkIWSMDQE5cjs.videoTrackSyncLocked.call(void 0, t)).map((t) => [t]);
1128
- if (found.some((f) => _chunkIWSMDQE5cjs.videoTrackSyncLocked.call(void 0, f.track))) groups.push(found.filter((f) => _chunkIWSMDQE5cjs.videoTrackSyncLocked.call(void 0, f.track)).map((f) => f.track));
1127
+ const groups = [...new Set(found.map((f) => f.track))].filter((t) => !_chunk4QQZV5Y5cjs.videoTrackSyncLocked.call(void 0, t)).map((t) => [t]);
1128
+ if (found.some((f) => _chunk4QQZV5Y5cjs.videoTrackSyncLocked.call(void 0, f.track))) groups.push(found.filter((f) => _chunk4QQZV5Y5cjs.videoTrackSyncLocked.call(void 0, f.track)).map((f) => f.track));
1129
1129
  for (const sources of groups) {
1130
1130
  const tracks = this.rippleTracks(sources);
1131
1131
  tracks.forEach((t) => rippled.add(t));
1132
- const spans = mergeSpans(found.filter((f) => sources.includes(f.track)).map((f) => [f.clip.start, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, f.clip)]));
1132
+ const spans = mergeSpans(found.filter((f) => sources.includes(f.track)).map((f) => [f.clip.start, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, f.clip)]));
1133
1133
  for (const [from, to] of spans.reverse()) this.close(tracks, from, to);
1134
1134
  }
1135
1135
  return this.outcomes.push({ op: e.op, clips: found.map((f) => f.clip.id), rippled: this.p.tracks.filter((t) => rippled.has(t)).map((t) => t.id) });
@@ -1145,7 +1145,7 @@ var Editor = (_class = class {
1145
1145
  if ("timeRemap" in set) refuse("Set a speed ramp with set_time_remap, which checks it against the media and moves later clips if asked.");
1146
1146
  let stretch = 1;
1147
1147
  if (at.clip.type === "media" && !("duration" in set)) {
1148
- const was = _chunkIWSMDQE5cjs.videoClipSpeed.call(void 0, at.clip);
1148
+ const was = _chunk4QQZV5Y5cjs.videoClipSpeed.call(void 0, at.clip);
1149
1149
  const now = "speed" in set ? set.speed : _optionalChain([e, 'access', _13 => _13.remove, 'optionalAccess', _14 => _14.includes, 'call', _15 => _15("speed")]) ? 1 : was;
1150
1150
  if (now !== was) {
1151
1151
  set.duration = at.clip.duration * was / now;
@@ -1153,7 +1153,7 @@ var Editor = (_class = class {
1153
1153
  }
1154
1154
  }
1155
1155
  const next = { ...structuredClone(at.clip), ...set };
1156
- if (stretch !== 1) retimeClipKeys(next, (v) => _chunkIWSMDQE5cjs.retimeVideoAnimatable.call(void 0, v, 0, stretch));
1156
+ if (stretch !== 1) retimeClipKeys(next, (v) => _chunk4QQZV5Y5cjs.retimeVideoAnimatable.call(void 0, v, 0, stretch));
1157
1157
  for (const k of _nullishCoalesce(e.remove, () => ( []))) delete next[k];
1158
1158
  const clip = parseVideoClip(next, "set");
1159
1159
  if (clip.type === "media" && clip.asset !== at.clip.asset) this.kindFits(at.track, clip);
@@ -1170,13 +1170,13 @@ var Editor = (_class = class {
1170
1170
  const asset = this.asset(clip.asset);
1171
1171
  if (asset.kind === "image") refuse(`Clip "${clip.id}" is a still ("${asset.id}"), so it has no motion to ramp.`);
1172
1172
  const media = clip;
1173
- const end = _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, media);
1173
+ const end = _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, media);
1174
1174
  const duration = _nullishCoalesce(e.duration, () => ( media.duration));
1175
- if (!(duration >= 1e3 / this.p.fps - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)) refuse(`"duration" must be at least a frame (${Math.ceil(1e3 / this.p.fps)} ms).`);
1175
+ if (!(duration >= 1e3 / this.p.fps - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)) refuse(`"duration" must be at least a frame (${Math.ceil(1e3 / this.p.fps)} ms).`);
1176
1176
  if (e.keys === null) {
1177
1177
  if (!media.timeRemap) refuse(`Clip "${clip.id}" has no speed ramp to remove.`);
1178
1178
  const from = (_nullishCoalesce(media.in, () => ( 0))) + media.timeRemap.keys[0].v;
1179
- if (asset.duration !== void 0 && from + duration > asset.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
1179
+ if (asset.duration !== void 0 && from + duration > asset.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
1180
1180
  refuse(`At normal speed from ${Math.round(from)} ms, "${clip.id}" would run past the end of "${asset.id}" (${asset.duration} ms); give a duration of at most ${Math.floor(asset.duration - from)} ms.`);
1181
1181
  delete media.timeRemap;
1182
1182
  media.in = from;
@@ -1184,17 +1184,17 @@ var Editor = (_class = class {
1184
1184
  } else {
1185
1185
  if (!Array.isArray(e.keys) || !e.keys.length) refuse('"keys" must be a list of at least one { t, v, ease } (or null to remove the ramp).');
1186
1186
  const remap = parseVideoTimeRemap({ keys: e.keys }, void 0, "keys");
1187
- remap.keys = _chunkIWSMDQE5cjs.sortVideoKeys.call(void 0, remap.keys);
1188
- _chunkIWSMDQE5cjs.checkVideoTimeRemap.call(void 0, remap, "keys");
1189
- const span = _chunkIWSMDQE5cjs.videoTimeRemapSpan.call(void 0, remap);
1190
- if (asset.duration !== void 0 && (_nullishCoalesce(media.in, () => ( 0))) + span.to > asset.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON)
1187
+ remap.keys = _chunk4QQZV5Y5cjs.sortVideoKeys.call(void 0, remap.keys);
1188
+ _chunk4QQZV5Y5cjs.checkVideoTimeRemap.call(void 0, remap, "keys");
1189
+ const span = _chunk4QQZV5Y5cjs.videoTimeRemapSpan.call(void 0, remap);
1190
+ if (asset.duration !== void 0 && (_nullishCoalesce(media.in, () => ( 0))) + span.to > asset.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON)
1191
1191
  refuse(`The ramp plays ${Math.round(span.to)} ms of source from the in point (${_nullishCoalesce(media.in, () => ( 0))} ms), past the end of "${asset.id}" (${asset.duration} ms); it can use at most ${Math.floor(asset.duration - (_nullishCoalesce(media.in, () => ( 0))))} ms.`);
1192
1192
  media.timeRemap = remap;
1193
1193
  delete media.speed;
1194
1194
  }
1195
1195
  const newEnd = media.start + duration;
1196
1196
  const outcome = { op: e.op, clip: clip.id, track: track.id };
1197
- if (Math.abs(newEnd - end) > _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) {
1197
+ if (Math.abs(newEnd - end) > _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) {
1198
1198
  if (e.ripple) {
1199
1199
  const tracks = this.rippleTracks([track]);
1200
1200
  if (newEnd < end) {
@@ -1226,8 +1226,8 @@ var Editor = (_class = class {
1226
1226
  if (clip.type !== "media" && clip.type !== "sequence") refuse(`Clip "${clip.id}" is a ${clip.type === "text" ? "title" : clip.type === "effect" ? "effect clip" : "colour"}, so it has no source to slip; only video, audio and compound clips slip.`);
1227
1227
  const source = clip.type === "sequence" ? `sequence "${clip.sequence}"` : `"${this.asset(clip.asset).id}"`;
1228
1228
  if (clip.type === "media" && this.asset(clip.asset).kind === "image") refuse(`Clip "${clip.id}" is a still ("${clip.asset}"), so it has no source to slip; only video and audio clips slip.`);
1229
- const handles = _chunkIWSMDQE5cjs.videoClipHandles.call(void 0, clip, _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, this.p), _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, this.p));
1230
- const { lead, tail } = _chunkIWSMDQE5cjs.videoClipOverhang.call(void 0, track, clip);
1229
+ const handles = _chunk4QQZV5Y5cjs.videoClipHandles.call(void 0, clip, _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, this.p), _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, this.p));
1230
+ const { lead, tail } = _chunk4QQZV5Y5cjs.videoClipOverhang.call(void 0, track, clip);
1231
1231
  const delta = this.clamp(
1232
1232
  e.delta,
1233
1233
  lead - handles.before,
@@ -1245,13 +1245,13 @@ var Editor = (_class = class {
1245
1245
  this.unlocked(track);
1246
1246
  const L = left.clip;
1247
1247
  const R = right.clip;
1248
- if (Math.abs(_chunkIWSMDQE5cjs.videoClipEnd.call(void 0, L) - R.start) > _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) {
1249
- if (Math.abs(_chunkIWSMDQE5cjs.videoClipEnd.call(void 0, R) - L.start) <= _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) refuse(`"${R.id}" comes before "${L.id}"; pass left "${R.id}" and right "${L.id}".`);
1250
- refuse(`"${L.id}" ends at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, L))} but "${R.id}" starts at ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, R.start)}; a roll needs two clips that meet at a cut (use trim_clip to move one edge).`);
1248
+ if (Math.abs(_chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, L) - R.start) > _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) {
1249
+ if (Math.abs(_chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, R) - L.start) <= _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) refuse(`"${R.id}" comes before "${L.id}"; pass left "${R.id}" and right "${L.id}".`);
1250
+ refuse(`"${L.id}" ends at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, L))} but "${R.id}" starts at ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, R.start)}; a roll needs two clips that meet at a cut (use trim_clip to move one edge).`);
1251
1251
  }
1252
- const assets = _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, this.p);
1253
- const lo = Math.max(-(L.duration - this.frame), -(_chunkIWSMDQE5cjs.videoClipHandles.call(void 0, R, assets, _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, this.p)).before - _chunkIWSMDQE5cjs.videoClipOverhang.call(void 0, track, R).lead));
1254
- const hi = Math.min(R.duration - this.frame, _chunkIWSMDQE5cjs.videoClipHandles.call(void 0, L, assets, _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, this.p)).after - _chunkIWSMDQE5cjs.videoClipOverhang.call(void 0, track, L).tail);
1252
+ const assets = _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, this.p);
1253
+ const lo = Math.max(-(L.duration - this.frame), -(_chunk4QQZV5Y5cjs.videoClipHandles.call(void 0, R, assets, _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, this.p)).before - _chunk4QQZV5Y5cjs.videoClipOverhang.call(void 0, track, R).lead));
1254
+ const hi = Math.min(R.duration - this.frame, _chunk4QQZV5Y5cjs.videoClipHandles.call(void 0, L, assets, _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, this.p)).after - _chunk4QQZV5Y5cjs.videoClipOverhang.call(void 0, track, L).tail);
1255
1255
  const delta = this.clamp(
1256
1256
  e.delta,
1257
1257
  lo,
@@ -1267,18 +1267,18 @@ var Editor = (_class = class {
1267
1267
  case "slide_clip": {
1268
1268
  const { track, clip } = this.clip(e.clip);
1269
1269
  this.unlocked(track);
1270
- const before = _chunkIWSMDQE5cjs.videoClipBefore.call(void 0, track, clip);
1271
- const after = _chunkIWSMDQE5cjs.videoClipAfter.call(void 0, track, clip);
1270
+ const before = _chunk4QQZV5Y5cjs.videoClipBefore.call(void 0, track, clip);
1271
+ const after = _chunk4QQZV5Y5cjs.videoClipAfter.call(void 0, track, clip);
1272
1272
  if (!before && !after) refuse(`"${clip.id}" has no clip right before or after it on track "${track.id}", so there is nothing to slide against; use move_clip.`);
1273
- const assets = _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, this.p);
1274
- const end = _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip);
1273
+ const assets = _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, this.p);
1274
+ const end = _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip);
1275
1275
  const others = track.clips.filter((c) => c !== clip);
1276
1276
  const room = {
1277
- earlier: before ? before.duration - this.frame : clip.start - others.filter((c) => _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c) <= clip.start + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON).reduce((m, c) => Math.max(m, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c)), 0),
1278
- later: after ? after.duration - this.frame : others.filter((c) => c.start >= end - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON).reduce((m, c) => Math.min(m, c.start - end), Infinity)
1277
+ earlier: before ? before.duration - this.frame : clip.start - others.filter((c) => _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c) <= clip.start + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON).reduce((m, c) => Math.max(m, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c)), 0),
1278
+ later: after ? after.duration - this.frame : others.filter((c) => c.start >= end - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON).reduce((m, c) => Math.min(m, c.start - end), Infinity)
1279
1279
  };
1280
- const lo = -Math.min(room.earlier, after ? _chunkIWSMDQE5cjs.videoClipHandles.call(void 0, after, assets, _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, this.p)).before - _chunkIWSMDQE5cjs.videoClipOverhang.call(void 0, track, after).lead : Infinity);
1281
- const hi = Math.min(room.later, before ? _chunkIWSMDQE5cjs.videoClipHandles.call(void 0, before, assets, _chunkIWSMDQE5cjs.videoSequenceMap.call(void 0, this.p)).after - _chunkIWSMDQE5cjs.videoClipOverhang.call(void 0, track, before).tail : Infinity);
1280
+ const lo = -Math.min(room.earlier, after ? _chunk4QQZV5Y5cjs.videoClipHandles.call(void 0, after, assets, _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, this.p)).before - _chunk4QQZV5Y5cjs.videoClipOverhang.call(void 0, track, after).lead : Infinity);
1281
+ const hi = Math.min(room.later, before ? _chunk4QQZV5Y5cjs.videoClipHandles.call(void 0, before, assets, _chunk4QQZV5Y5cjs.videoSequenceMap.call(void 0, this.p)).after - _chunk4QQZV5Y5cjs.videoClipOverhang.call(void 0, track, before).tail : Infinity);
1282
1282
  const delta = this.clamp(
1283
1283
  e.delta,
1284
1284
  lo,
@@ -1311,29 +1311,29 @@ var Editor = (_class = class {
1311
1311
  }
1312
1312
  case "split_at": {
1313
1313
  const tracks = this.rangeTracks(e.tracks);
1314
- const lefts = tracks.flatMap((t) => t.clips.filter((c) => c.start < e.at - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON && _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c) > e.at + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON).map((c) => c.id));
1315
- if (!lefts.length) refuse(`No clip runs across ${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, e.at)} on ${e.tracks ? `track${tracks.length > 1 ? "s" : ""} ${tracks.map((t) => `"${t.id}"`).join(", ")}` : "the unlocked tracks"}, so there is nothing to split there.`);
1314
+ const lefts = tracks.flatMap((t) => t.clips.filter((c) => c.start < e.at - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON && _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c) > e.at + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON).map((c) => c.id));
1315
+ if (!lefts.length) refuse(`No clip runs across ${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, e.at)} on ${e.tracks ? `track${tracks.length > 1 ? "s" : ""} ${tracks.map((t) => `"${t.id}"`).join(", ")}` : "the unlocked tracks"}, so there is nothing to split there.`);
1316
1316
  const created = this.cutAcross(tracks, e.at).map((c) => c.id);
1317
1317
  return this.outcomes.push({ op: e.op, clips: lefts, created });
1318
1318
  }
1319
1319
  case "set_keyframes": {
1320
1320
  const { track, clip } = this.clip(e.clip);
1321
1321
  this.unlocked(track);
1322
- if (!_chunkIWSMDQE5cjs.VIDEO_KEYFRAME_PROPERTIES.includes(e.property)) refuse(`"${e.property}" cannot be keyframed; use one of ${_chunkIWSMDQE5cjs.VIDEO_KEYFRAME_PROPERTIES.join(", ")}.`);
1322
+ if (!_chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_PROPERTIES.includes(e.property)) refuse(`"${e.property}" cannot be keyframed; use one of ${_chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_PROPERTIES.join(", ")}.`);
1323
1323
  if (e.property === "volume" && clip.type !== "media" && clip.type !== "sequence") refuse(`Clip "${clip.id}" is a ${clip.type} clip and has no volume; volume keys go on media and compound clips.`);
1324
- const limits = _chunkIWSMDQE5cjs.VIDEO_KEYFRAME_LIMITS[e.property];
1325
- const transform = _chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(e.property);
1324
+ const limits = _chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_LIMITS[e.property];
1325
+ const transform = _chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(e.property);
1326
1326
  const c = clip;
1327
1327
  const current = transform ? _optionalChain([c, 'access', _18 => _18.transform, 'optionalAccess', _19 => _19[e.property]]) : c[e.property];
1328
1328
  let value;
1329
1329
  if (e.keys === null) {
1330
- const v = _chunkIWSMDQE5cjs.videoValueAt.call(void 0, current, 0, limits.default);
1331
- value = _chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, current) ? v === limits.default ? void 0 : v : current;
1330
+ const v = _chunk4QQZV5Y5cjs.videoValueAt.call(void 0, current, 0, limits.default);
1331
+ value = _chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, current) ? v === limits.default ? void 0 : v : current;
1332
1332
  } else {
1333
1333
  if (!Array.isArray(e.keys) || !e.keys.length) refuse('"keys" must list at least one key { t, v }; pass null to remove the keyframes.');
1334
1334
  let sorted = [];
1335
1335
  try {
1336
- sorted = _chunkIWSMDQE5cjs.sortVideoKeys.call(void 0, e.keys);
1336
+ sorted = _chunk4QQZV5Y5cjs.sortVideoKeys.call(void 0, e.keys);
1337
1337
  } catch (error) {
1338
1338
  refuse(error.message);
1339
1339
  }
@@ -1352,12 +1352,12 @@ var Editor = (_class = class {
1352
1352
  this.unlocked(track);
1353
1353
  let at = 0;
1354
1354
  const moved = [];
1355
- for (const clip of _chunkIWSMDQE5cjs.sortedVideoClips.call(void 0, track)) {
1356
- if (clip.start >= (_nullishCoalesce(e.from, () => ( 0))) - _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON && clip.start > at + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) {
1355
+ for (const clip of _chunk4QQZV5Y5cjs.sortedVideoClips.call(void 0, track)) {
1356
+ if (clip.start >= (_nullishCoalesce(e.from, () => ( 0))) - _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON && clip.start > at + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) {
1357
1357
  clip.start = Math.max(at, _nullishCoalesce(e.from, () => ( 0)));
1358
1358
  moved.push(clip.id);
1359
1359
  }
1360
- at = Math.max(at, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip));
1360
+ at = Math.max(at, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip));
1361
1361
  }
1362
1362
  return this.outcomes.push({ op: e.op, track: track.id, clips: moved });
1363
1363
  }
@@ -1512,7 +1512,7 @@ function videoClipWaveform(clip, peaks, columns) {
1512
1512
  const step = clip.duration / Math.max(1, n);
1513
1513
  for (let c = 0; c < n; c++) {
1514
1514
  const { min, max } = videoAudioPeakRange(peaks, start + c * step * speed, start + (c + 1) * step * speed);
1515
- const gain = _chunkIWSMDQE5cjs.videoClipSoundGain.call(void 0, clip, (c + 0.5) * step);
1515
+ const gain = _chunk4QQZV5Y5cjs.videoClipSoundGain.call(void 0, clip, (c + 0.5) * step);
1516
1516
  out[2 * c] = min * gain;
1517
1517
  out[2 * c + 1] = max * gain;
1518
1518
  }
@@ -2077,7 +2077,7 @@ function videoTranscriptTrack(project, track) {
2077
2077
  if (!project.tracks.some((t) => t.id === track)) throw new Error(`There is no track "${track}"; the tracks are ${project.tracks.map((t) => `"${t.id}"`).join(", ")}.`);
2078
2078
  return track;
2079
2079
  }
2080
- const assets = _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, project);
2080
+ const assets = _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, project);
2081
2081
  const transcribed = (t) => t.clips.some((c) => c.type === "media" && _optionalChain([assets, 'access', _21 => _21.get, 'call', _22 => _22(c.asset), 'optionalAccess', _23 => _23.transcript, 'optionalAccess', _24 => _24.length]));
2082
2082
  return _nullishCoalesce(_optionalChain([(_nullishCoalesce(project.tracks.find((t) => t.kind === "audio" && transcribed(t)), () => ( project.tracks.find(transcribed)))), 'optionalAccess', _25 => _25.id]), () => ( null));
2083
2083
  }
@@ -2085,16 +2085,16 @@ function videoTimelineTranscript(project, options = {}) {
2085
2085
  const id = videoTranscriptTrack(project, options.track);
2086
2086
  if (!id) return [];
2087
2087
  const track = project.tracks.find((t) => t.id === id);
2088
- const assets = _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, project);
2088
+ const assets = _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, project);
2089
2089
  const out = [];
2090
- for (const clip of _chunkIWSMDQE5cjs.sortedVideoClips.call(void 0, track)) {
2090
+ for (const clip of _chunk4QQZV5Y5cjs.sortedVideoClips.call(void 0, track)) {
2091
2091
  if (clip.type !== "media") continue;
2092
2092
  const words = _optionalChain([assets, 'access', _26 => _26.get, 'call', _27 => _27(clip.asset), 'optionalAccess', _28 => _28.transcript]);
2093
2093
  if (!_optionalChain([words, 'optionalAccess', _29 => _29.length])) continue;
2094
- const speed = _chunkIWSMDQE5cjs.videoClipSpeed.call(void 0, clip);
2094
+ const speed = _chunk4QQZV5Y5cjs.videoClipSpeed.call(void 0, clip);
2095
2095
  const from = _nullishCoalesce(clip.in, () => ( 0));
2096
2096
  const to = from + clip.duration * speed;
2097
- const toTimeline = (s) => Math.min(_chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip), Math.max(clip.start, clip.start + (s - from) / speed));
2097
+ const toTimeline = (s) => Math.min(_chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip), Math.max(clip.start, clip.start + (s - from) / speed));
2098
2098
  words.forEach((w, index) => {
2099
2099
  const mid = (w.start + w.end) / 2;
2100
2100
  if (mid < from || mid >= to) return;
@@ -2139,19 +2139,19 @@ function findVideoTranscriptPauses(words, options = {}) {
2139
2139
  let to = b.start - keep;
2140
2140
  if (options.fps) {
2141
2141
  const f = 1e3 / options.fps;
2142
- from = _chunkIWSMDQE5cjs.snapToVideoFrame.call(void 0, Math.ceil(from / f - 1e-9) * f, options.fps);
2143
- to = _chunkIWSMDQE5cjs.snapToVideoFrame.call(void 0, Math.floor(to / f + 1e-9) * f, options.fps);
2142
+ from = _chunk4QQZV5Y5cjs.snapToVideoFrame.call(void 0, Math.ceil(from / f - 1e-9) * f, options.fps);
2143
+ to = _chunk4QQZV5Y5cjs.snapToVideoFrame.call(void 0, Math.floor(to / f + 1e-9) * f, options.fps);
2144
2144
  }
2145
- if (to - from > _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) out.push({ from, to, text: `(pause after "${a.word}")` });
2145
+ if (to - from > _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) out.push({ from, to, text: `(pause after "${a.word}")` });
2146
2146
  }
2147
2147
  return out;
2148
2148
  }
2149
2149
  function mergeVideoRanges(ranges) {
2150
- const sorted = ranges.filter((r) => r.to - r.from > _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON).map((r) => ({ from: r.from, to: r.to })).sort((a, b) => a.from - b.from);
2150
+ const sorted = ranges.filter((r) => r.to - r.from > _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON).map((r) => ({ from: r.from, to: r.to })).sort((a, b) => a.from - b.from);
2151
2151
  const out = [];
2152
2152
  for (const r of sorted) {
2153
2153
  const last = out[out.length - 1];
2154
- if (last && r.from <= last.to + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON) last.to = Math.max(last.to, r.to);
2154
+ if (last && r.from <= last.to + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON) last.to = Math.max(last.to, r.to);
2155
2155
  else out.push(r);
2156
2156
  }
2157
2157
  return out;
@@ -2235,7 +2235,7 @@ function videoProxyFfmpeg(asset, options = {}) {
2235
2235
  output
2236
2236
  ];
2237
2237
  const proxy = { scale, src: output, ...asset.width && asset.height ? { width: Math.trunc(asset.width * scale / 2) * 2, height: Math.trunc(asset.height * scale / 2) * 2 } : {} };
2238
- return { asset: asset.id, args, command: ["ffmpeg", ...args].map(_chunkIWSMDQE5cjs.videoShellQuote).join(" "), proxy };
2238
+ return { asset: asset.id, args, command: ["ffmpeg", ...args].map(_chunk4QQZV5Y5cjs.videoShellQuote).join(" "), proxy };
2239
2239
  }
2240
2240
  function videoProxyPlan(project, options = {}) {
2241
2241
  const scale = _nullishCoalesce(options.scale, () => ( 0.5));
@@ -2261,7 +2261,7 @@ var videoSourceFrameTime = (frame, fps) => (frame + 0.5) * 1e3 / fps;
2261
2261
  var videoFrameCacheKey = (src, frame) => `${frame}@${src}`;
2262
2262
  function videoFrameRequestsAt(project, time, srcFor = (l) => l.src) {
2263
2263
  const out = [];
2264
- for (const layer of _chunkIWSMDQE5cjs.videoFrameLeafLayers.call(void 0, _chunkIWSMDQE5cjs.videoFrameAt.call(void 0, project, time).layers)) {
2264
+ for (const layer of _chunk4QQZV5Y5cjs.videoFrameLeafLayers.call(void 0, _chunk4QQZV5Y5cjs.videoFrameAt.call(void 0, project, time).layers)) {
2265
2265
  if (layer.type !== "media" || layer.assetKind !== "video") continue;
2266
2266
  const src = srcFor(layer);
2267
2267
  if (!src) continue;
@@ -2602,7 +2602,7 @@ var VideoPreviewEngine = (_class5 = class {
2602
2602
  if (this.destroyed) return;
2603
2603
  const state = this.source.getState();
2604
2604
  const { project, time, playing } = state;
2605
- const frame = _chunkIWSMDQE5cjs.videoFrameAt.call(void 0, project, time);
2605
+ const frame = _chunk4QQZV5Y5cjs.videoFrameAt.call(void 0, project, time);
2606
2606
  const scale = resolveVideoPreviewScale(_nullishCoalesce(this.options.previewScale, () => ( state.previewScale)), this.resolutionFor(project.width));
2607
2607
  const assets = new Map(project.assets.map((a) => [a.id, a]));
2608
2608
  this.srcFor = (layer) => videoPreviewSrc(assets.get(_nullishCoalesce(layer.asset, () => ( ""))), scale, layer.src);
@@ -2632,7 +2632,7 @@ var VideoPreviewEngine = (_class5 = class {
2632
2632
  }
2633
2633
  };
2634
2634
  const sounding = new Map(frame.audio.map((a) => [a.clip, a]));
2635
- for (const layer of _chunkIWSMDQE5cjs.videoFrameLeafLayers.call(void 0, frame.layers)) {
2635
+ for (const layer of _chunk4QQZV5Y5cjs.videoFrameLeafLayers.call(void 0, frame.layers)) {
2636
2636
  if (layer.type !== "media" || layer.assetKind !== "video" || !layer.src) continue;
2637
2637
  const sound = sounding.get(layer.clip);
2638
2638
  sync(layer.clip, this.srcFor(layer), "video", _nullishCoalesce(layer.sourceTime, () => ( 0)), _nullishCoalesce(_optionalChain([sound, 'optionalAccess', _71 => _71.speed]), () => ( 1)), sound ? sound.gain : null);
@@ -2644,9 +2644,9 @@ var VideoPreviewEngine = (_class5 = class {
2644
2644
  }
2645
2645
  /** With effects, the frame is drawn at the start of its frame, so effect pictures are cached once per frame. */
2646
2646
  drawable(project, frame) {
2647
- if (!_optionalChain([this, 'access', _72 => _72.effects, 'optionalAccess', _73 => _73.available]) || !_chunkIWSMDQE5cjs.videoLayersUseEffects.call(void 0, frame.layers)) return frame;
2648
- const at = _chunkIWSMDQE5cjs.videoEffectFrameTime.call(void 0, frame.time, project.fps);
2649
- return at === frame.time ? frame : { ..._chunkIWSMDQE5cjs.videoFrameAt.call(void 0, project, at), time: frame.time };
2647
+ if (!_optionalChain([this, 'access', _72 => _72.effects, 'optionalAccess', _73 => _73.available]) || !_chunk4QQZV5Y5cjs.videoLayersUseEffects.call(void 0, frame.layers)) return frame;
2648
+ const at = _chunk4QQZV5Y5cjs.videoEffectFrameTime.call(void 0, frame.time, project.fps);
2649
+ return at === frame.time ? frame : { ..._chunk4QQZV5Y5cjs.videoFrameAt.call(void 0, project, at), time: frame.time };
2650
2650
  }
2651
2651
  redraw() {
2652
2652
  if (this.scheduled || this.destroyed) return;
@@ -2655,7 +2655,7 @@ var VideoPreviewEngine = (_class5 = class {
2655
2655
  this.scheduled = false;
2656
2656
  if (this.destroyed) return;
2657
2657
  const { project, time } = this.source.getState();
2658
- this.draw(this.drawable(project, _chunkIWSMDQE5cjs.videoFrameAt.call(void 0, project, time)));
2658
+ this.draw(this.drawable(project, _chunk4QQZV5Y5cjs.videoFrameAt.call(void 0, project, time)));
2659
2659
  });
2660
2660
  }
2661
2661
  __init33() {this.sourceFor = (layer) => {
@@ -2698,7 +2698,7 @@ var VideoPreviewEngine = (_class5 = class {
2698
2698
  if (!source) this.complete = false;
2699
2699
  return source;
2700
2700
  };
2701
- _chunkIWSMDQE5cjs.drawVideoFrame.call(void 0, this.ctx, frame, sourceFor, resolution, {
2701
+ _chunk4QQZV5Y5cjs.drawVideoFrame.call(void 0, this.ctx, frame, sourceFor, resolution, {
2702
2702
  defineSvgFilter: this.defineSvgFilter,
2703
2703
  lutFor: this.lutFor,
2704
2704
  scratch: this.scratch,
@@ -2798,17 +2798,17 @@ var VideoEditorController = (_class6 = class {
2798
2798
  constructor(options = {}) {;_class6.prototype.__init37.call(this);_class6.prototype.__init38.call(this);_class6.prototype.__init39.call(this);_class6.prototype.__init40.call(this);_class6.prototype.__init41.call(this);_class6.prototype.__init42.call(this);_class6.prototype.__init43.call(this);_class6.prototype.__init44.call(this);_class6.prototype.__init45.call(this);
2799
2799
  this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkQKLRAA4Tcjs.HistoryManager)()));
2800
2800
  this.audioPeaks = options.audioPeaks instanceof VideoAudioPeaksCache ? options.audioPeaks : new VideoAudioPeaksCache(options.audioPeaks);
2801
- this.luts = options.luts instanceof _chunkIWSMDQE5cjs.VideoLutCache ? options.luts : new (0, _chunkIWSMDQE5cjs.VideoLutCache)(options.luts);
2801
+ this.luts = options.luts instanceof _chunk4QQZV5Y5cjs.VideoLutCache ? options.luts : new (0, _chunk4QQZV5Y5cjs.VideoLutCache)(options.luts);
2802
2802
  this.frameCache = _nullishCoalesce(options.frameCache, () => ( null));
2803
- this.effects = new (0, _chunkIOXKXQNWcjs.EffectsSlot)();
2803
+ this.effects = new (0, _chunkCN4PJHUGcjs.EffectsSlot)();
2804
2804
  if (options.effects) this.effects.set(options.effects);
2805
- this.effectsEngine = new (0, _chunkIWSMDQE5cjs.VideoEffectsEngine)({ slot: this.effects });
2805
+ this.effectsEngine = new (0, _chunk4QQZV5Y5cjs.VideoEffectsEngine)({ slot: this.effects });
2806
2806
  this.project = options.project ? parseVideoProject(options.project) : createVideoProject();
2807
2807
  this.issues = checkVideoProject(this.project);
2808
2808
  this.readOnly = _nullishCoalesce(options.readOnly, () => ( false));
2809
2809
  this.previewScale = checkPreviewScale(_nullishCoalesce(options.previewScale, () => ( "auto")));
2810
2810
  this.onChange = options.onChange;
2811
- this.player = new (0, _chunk477UVMNRcjs.AnimationPlayer)({ clock: options.clock, duration: () => _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, this.project), loop: "none" });
2811
+ this.player = new (0, _chunk477UVMNRcjs.AnimationPlayer)({ clock: options.clock, duration: () => _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, this.project), loop: "none" });
2812
2812
  this.state = this.computeState();
2813
2813
  this.connect();
2814
2814
  }
@@ -2845,12 +2845,12 @@ var VideoEditorController = (_class6 = class {
2845
2845
  const h = this.history.getState();
2846
2846
  return {
2847
2847
  project: this.project,
2848
- duration: _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, this.project),
2848
+ duration: _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, this.project),
2849
2849
  time: p.time,
2850
2850
  playing: p.playing,
2851
2851
  loop: p.loop,
2852
2852
  selection: this.selection,
2853
- current: _chunkIWSMDQE5cjs.videoClipsAt.call(void 0, this.project, p.time).map((c) => c.clip.id),
2853
+ current: _chunk4QQZV5Y5cjs.videoClipsAt.call(void 0, this.project, p.time).map((c) => c.clip.id),
2854
2854
  issues: this.issues,
2855
2855
  readOnly: this.readOnly,
2856
2856
  error: this.error,
@@ -2882,7 +2882,7 @@ var VideoEditorController = (_class6 = class {
2882
2882
  this.issues = checkVideoProject(project);
2883
2883
  const ids = new Set(project.tracks.flatMap((t) => t.clips.map((c) => c.id)));
2884
2884
  if (this.selection.some((id) => !ids.has(id))) this.selection = this.selection.filter((id) => ids.has(id));
2885
- this.player.setDuration(() => _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, this.project));
2885
+ this.player.setDuration(() => _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, this.project));
2886
2886
  } finally {
2887
2887
  this.applying = false;
2888
2888
  }
@@ -2964,7 +2964,7 @@ var VideoEditorController = (_class6 = class {
2964
2964
  }
2965
2965
  /** Selects clips (unknown ids are dropped). `add` toggles them into the current selection. */
2966
2966
  select(clips, options = {}) {
2967
- const known = _nullishCoalesce(_optionalChain([clips, 'optionalAccess', _89 => _89.filter, 'call', _90 => _90((id) => _chunkIWSMDQE5cjs.findVideoClip.call(void 0, this.project, id))]), () => ( []));
2967
+ const known = _nullishCoalesce(_optionalChain([clips, 'optionalAccess', _89 => _89.filter, 'call', _90 => _90((id) => _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, this.project, id))]), () => ( []));
2968
2968
  let next;
2969
2969
  if (options.add) {
2970
2970
  next = [...this.selection];
@@ -2991,7 +2991,7 @@ var VideoEditorController = (_class6 = class {
2991
2991
  step(frames) {
2992
2992
  this.player.pause();
2993
2993
  const fps = this.project.fps;
2994
- this.player.seek(Math.max(0, _chunkIWSMDQE5cjs.snapToVideoFrame.call(void 0, this.player.currentTime, fps) + frames * 1e3 / fps));
2994
+ this.player.seek(Math.max(0, _chunk4QQZV5Y5cjs.snapToVideoFrame.call(void 0, this.player.currentTime, fps) + frames * 1e3 / fps));
2995
2995
  }
2996
2996
  setLoop(loop) {
2997
2997
  this.player.setLoop(loop);
@@ -3008,14 +3008,14 @@ var VideoEditorController = (_class6 = class {
3008
3008
  */
3009
3009
  snap(time, options = {}) {
3010
3010
  const threshold = _nullishCoalesce(options.threshold, () => ( 8 * 1e3 / this.project.fps));
3011
- const points = _chunkIWSMDQE5cjs.videoSnapPoints.call(void 0, this.project, { exclude: options.exclude, playhead: options.playhead === false ? void 0 : this.player.currentTime });
3012
- const hit = _chunkIWSMDQE5cjs.snapVideoTime.call(void 0, time, points, threshold);
3013
- return hit.snapped !== null ? hit : { time: Math.max(0, _chunkIWSMDQE5cjs.snapToVideoFrame.call(void 0, time, this.project.fps)), snapped: null };
3011
+ const points = _chunk4QQZV5Y5cjs.videoSnapPoints.call(void 0, this.project, { exclude: options.exclude, playhead: options.playhead === false ? void 0 : this.player.currentTime });
3012
+ const hit = _chunk4QQZV5Y5cjs.snapVideoTime.call(void 0, time, points, threshold);
3013
+ return hit.snapped !== null ? hit : { time: Math.max(0, _chunk4QQZV5Y5cjs.snapToVideoFrame.call(void 0, time, this.project.fps)), snapped: null };
3014
3014
  }
3015
3015
  /** Splits the selected clips (or every clip) under the playhead there, as one undo step. */
3016
3016
  splitAtPlayhead() {
3017
- const t = _chunkIWSMDQE5cjs.snapToVideoFrame.call(void 0, this.player.currentTime, this.project.fps);
3018
- const under = _chunkIWSMDQE5cjs.videoClipsAt.call(void 0, this.project, t).filter(({ clip }) => t > clip.start && t < _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip));
3017
+ const t = _chunk4QQZV5Y5cjs.snapToVideoFrame.call(void 0, this.player.currentTime, this.project.fps);
3018
+ const under = _chunk4QQZV5Y5cjs.videoClipsAt.call(void 0, this.project, t).filter(({ clip }) => t > clip.start && t < _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip));
3019
3019
  const chosen = this.selection.length ? under.filter(({ clip }) => this.selection.includes(clip.id)) : under;
3020
3020
  if (!chosen.length) return this.refuse("No clip is under the playhead to split.");
3021
3021
  return this.apply(chosen.map(({ clip }) => ({ op: "split_clip", clip: clip.id, at: t })), "Split");
@@ -3043,7 +3043,7 @@ var VideoEditorController = (_class6 = class {
3043
3043
  /** The provider's description of an effect, checked for `place` (rejects without a provider or for an unknown id). */
3044
3044
  async describeEffect(effect, place) {
3045
3045
  const d = await this.effects.require().describe(effect);
3046
- if (place) _chunkIWSMDQE5cjs.checkVideoEffectPlace.call(void 0, d, place);
3046
+ if (place) _chunk4QQZV5Y5cjs.checkVideoEffectPlace.call(void 0, d, place);
3047
3047
  return d;
3048
3048
  }
3049
3049
  refused(message) {
@@ -3056,7 +3056,7 @@ var VideoEditorController = (_class6 = class {
3056
3056
  try {
3057
3057
  plan = await run();
3058
3058
  } catch (error) {
3059
- if (_chunkIOXKXQNWcjs.isEffectError.call(void 0, error) || error instanceof Error) return this.refused(error.message);
3059
+ if (_chunkCN4PJHUGcjs.isEffectError.call(void 0, error) || error instanceof Error) return this.refused(error.message);
3060
3060
  throw error;
3061
3061
  }
3062
3062
  const result = this.apply(plan.edit, plan.label, { merge });
@@ -3064,7 +3064,7 @@ var VideoEditorController = (_class6 = class {
3064
3064
  return { ...result, clip: plan.clip, ...plan.effect ? { effect: plan.effect() } : {} };
3065
3065
  }
3066
3066
  clipOrThrow(id) {
3067
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, this.project, id);
3067
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, this.project, id);
3068
3068
  if (!at) throw new Error(`There is no clip "${id}"; list_applied_effects or get_video_project lists the clips.`);
3069
3069
  return at.clip;
3070
3070
  }
@@ -3077,7 +3077,7 @@ var VideoEditorController = (_class6 = class {
3077
3077
  return this.effectEdit(async () => {
3078
3078
  const current = this.clipOrThrow(clip);
3079
3079
  const d = await this.describeEffect(effect, "clip");
3080
- const values = _chunkIWSMDQE5cjs.checkVideoEffectValues.call(void 0, d, options.values, { keyframes: true });
3080
+ const values = _chunk4QQZV5Y5cjs.checkVideoEffectValues.call(void 0, d, options.values, { keyframes: true });
3081
3081
  const stack = [..._nullishCoalesce(current.effects, () => ( []))];
3082
3082
  const taken = new Set(stack.map((e) => e.id));
3083
3083
  let n = 1;
@@ -3113,7 +3113,7 @@ var VideoEditorController = (_class6 = class {
3113
3113
  if (!(k in d.controls.properties)) throw new Error(`"${k}" is not a control of "${d.id}"; its controls are ${Object.keys(d.controls.properties).join(", ")}.`);
3114
3114
  base[k] = d.defaults[k];
3115
3115
  }
3116
- next.values = _chunkIWSMDQE5cjs.checkVideoEffectValues.call(void 0, d, given, { base, keyframes: true });
3116
+ next.values = _chunk4QQZV5Y5cjs.checkVideoEffectValues.call(void 0, d, given, { base, keyframes: true });
3117
3117
  }
3118
3118
  if (changes.enabled !== void 0) {
3119
3119
  if (changes.enabled) delete next.enabled;
@@ -3131,7 +3131,7 @@ var VideoEditorController = (_class6 = class {
3131
3131
  removeClipEffect(clip, instance) {
3132
3132
  const reason = this.readOnlyReason();
3133
3133
  if (reason) return this.refused(reason);
3134
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, this.project, clip);
3134
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, this.project, clip);
3135
3135
  if (!at) return this.refused(`There is no clip "${clip}".`);
3136
3136
  const stack = _nullishCoalesce(at.clip.effects, () => ( []));
3137
3137
  const was = stack.find((e) => e.id === instance);
@@ -3148,7 +3148,7 @@ var VideoEditorController = (_class6 = class {
3148
3148
  return this.effectEdit(async () => {
3149
3149
  this.clipOrThrow(clip);
3150
3150
  const d = await this.describeEffect(effect, "transition");
3151
- const values = _chunkIWSMDQE5cjs.checkVideoEffectValues.call(void 0, d, options.values);
3151
+ const values = _chunk4QQZV5Y5cjs.checkVideoEffectValues.call(void 0, d, options.values);
3152
3152
  const duration = _nullishCoalesce(_nullishCoalesce(options.duration, () => ( d.duration)), () => ( 1e3));
3153
3153
  return { edit: { op: "set_transition", clip, transition: { type: "effect", duration, effect: { effect: d.id, provider: this.effects.require().id, name: d.name, values } } }, label: `Transition ${d.name}`, clip };
3154
3154
  });
@@ -3161,7 +3161,7 @@ var VideoEditorController = (_class6 = class {
3161
3161
  addEffectClip(track, effect, options = {}) {
3162
3162
  return this.effectEdit(async () => {
3163
3163
  const d = await this.describeEffect(effect, "generator");
3164
- const values = _chunkIWSMDQE5cjs.checkVideoEffectValues.call(void 0, d, options.values, { keyframes: true });
3164
+ const values = _chunk4QQZV5Y5cjs.checkVideoEffectValues.call(void 0, d, options.values, { keyframes: true });
3165
3165
  const duration = _nullishCoalesce(_nullishCoalesce(options.duration, () => ( d.duration)), () => ( 5e3));
3166
3166
  const label = `Add ${d.name}`;
3167
3167
  const clipId = _nullishCoalesce(options.id, () => ( ""));
@@ -3183,42 +3183,42 @@ var VideoEditorController = (_class6 = class {
3183
3183
  if (part === "generator") {
3184
3184
  if (current.type !== "effect") throw new Error(`Clip "${clip}" is not an effect clip.`);
3185
3185
  const d2 = await this.describeEffect(current.effect);
3186
- return { edit: { op: "update_clip", clip, set: { values: _chunkIWSMDQE5cjs.checkVideoEffectValues.call(void 0, d2, values, { base: _nullishCoalesce(current.values, () => ( {})), keyframes: true }) } }, label: `Change ${_nullishCoalesce(current.name, () => ( d2.name))}`, clip };
3186
+ return { edit: { op: "update_clip", clip, set: { values: _chunk4QQZV5Y5cjs.checkVideoEffectValues.call(void 0, d2, values, { base: _nullishCoalesce(current.values, () => ( {})), keyframes: true }) } }, label: `Change ${_nullishCoalesce(current.name, () => ( d2.name))}`, clip };
3187
3187
  }
3188
3188
  const t = current.transition;
3189
3189
  if (_optionalChain([t, 'optionalAccess', _94 => _94.type]) !== "effect" || !t.effect) throw new Error(`Clip "${clip}" has no effect transition.`);
3190
3190
  const d = await this.describeEffect(t.effect.effect);
3191
- const merged = _chunkIWSMDQE5cjs.checkVideoEffectValues.call(void 0, d, values, { base: _nullishCoalesce(t.effect.values, () => ( {})) });
3191
+ const merged = _chunk4QQZV5Y5cjs.checkVideoEffectValues.call(void 0, d, values, { base: _nullishCoalesce(t.effect.values, () => ( {})) });
3192
3192
  return { edit: { op: "set_transition", clip, transition: { ...t, effect: { ...t.effect, values: merged } } }, label: `Change transition ${d.name}`, clip };
3193
3193
  }, options.merge);
3194
3194
  }
3195
3195
  /** Keys for one numeric control of a clip effect (clip-relative ms), or `null` to stop animating it (keeping its value at the clip's start). */
3196
3196
  setClipEffectKeyframes(clip, instance, control, keys) {
3197
- const current = _optionalChain([_chunkIWSMDQE5cjs.findVideoClip.call(void 0, this.project, clip), 'optionalAccess', _95 => _95.clip]);
3197
+ const current = _optionalChain([_chunk4QQZV5Y5cjs.findVideoClip.call(void 0, this.project, clip), 'optionalAccess', _95 => _95.clip]);
3198
3198
  const was = _optionalChain([current, 'optionalAccess', _96 => _96.effects, 'optionalAccess', _97 => _97.find, 'call', _98 => _98((e) => e.id === instance)]);
3199
3199
  const value = _optionalChain([was, 'optionalAccess', _99 => _99.values, 'optionalAccess', _100 => _100[control]]);
3200
- const plain = keys === null ? _chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, value) ? _optionalChain([value, 'access', _101 => _101.keys, 'access', _102 => _102[0], 'optionalAccess', _103 => _103.v]) : value : { keys: [...keys].sort((a, b) => a.t - b.t) };
3200
+ const plain = keys === null ? _chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, value) ? _optionalChain([value, 'access', _101 => _101.keys, 'access', _102 => _102[0], 'optionalAccess', _103 => _103.v]) : value : { keys: [...keys].sort((a, b) => a.t - b.t) };
3201
3201
  return this.updateClipEffect(clip, instance, { values: { [control]: _nullishCoalesce(plain, () => ( null)) } });
3202
3202
  }
3203
3203
  /** What plays at `time` (default: the playhead). */
3204
3204
  frame(time = this.player.currentTime) {
3205
- return _chunkIWSMDQE5cjs.videoFrameAt.call(void 0, this.project, time);
3205
+ return _chunk4QQZV5Y5cjs.videoFrameAt.call(void 0, this.project, time);
3206
3206
  }
3207
3207
  /** The frame at `time` (default: the playhead) as SVG. */
3208
3208
  toSvg(time = this.player.currentTime, options = {}) {
3209
- return _chunkIWSMDQE5cjs.videoProjectSvg.call(void 0, this.project, time, { lutFor: (src) => this.luts.peek(src), ...options });
3209
+ return _chunk4QQZV5Y5cjs.videoProjectSvg.call(void 0, this.project, time, { lutFor: (src) => this.luts.peek(src), ...options });
3210
3210
  }
3211
3211
  /** The project as an ffmpeg command. */
3212
3212
  toFfmpeg(options = {}) {
3213
- return _chunkIWSMDQE5cjs.toVideoFfmpeg.call(void 0, this.project, options);
3213
+ return _chunk4QQZV5Y5cjs.toVideoFfmpeg.call(void 0, this.project, options);
3214
3214
  }
3215
3215
  /** The ffmpeg command that measures the mix's loudness (see `toVideoLoudnessMeasure`). */
3216
3216
  toLoudnessMeasure(options = {}) {
3217
- return _chunkIWSMDQE5cjs.toVideoLoudnessMeasure.call(void 0, this.project, options);
3217
+ return _chunk4QQZV5Y5cjs.toVideoLoudnessMeasure.call(void 0, this.project, options);
3218
3218
  }
3219
3219
  /** One track as a CMX 3600 EDL. */
3220
3220
  toEdl(options = {}) {
3221
- return _chunkIWSMDQE5cjs.toVideoEdl.call(void 0, this.project, options);
3221
+ return _chunk4QQZV5Y5cjs.toVideoEdl.call(void 0, this.project, options);
3222
3222
  }
3223
3223
  }, _class6);
3224
3224
  function checkPreviewScale(scale) {
@@ -3237,12 +3237,12 @@ function videoRulerTicks(duration, pxPerSecond, fps) {
3237
3237
  const ticks = [];
3238
3238
  for (let t = 0; t <= duration + 1e-6; t += step) {
3239
3239
  const isMajor = Math.abs(t / major - Math.round(t / major)) < 1e-9;
3240
- ticks.push({ time: t, x: t * pxPerMs, major: isMajor, ...isMajor ? { label: _chunkIWSMDQE5cjs.formatVideoTimecode.call(void 0, t, fps).replace(/^00:/, "") } : {} });
3240
+ ticks.push({ time: t, x: t * pxPerMs, major: isMajor, ...isMajor ? { label: _chunk4QQZV5Y5cjs.formatVideoTimecode.call(void 0, t, fps).replace(/^00:/, "") } : {} });
3241
3241
  }
3242
3242
  return ticks;
3243
3243
  }
3244
3244
  function videoClipShowsWaveform(clip, asset, mode = "audio") {
3245
- if (clip.type !== "media" || mode === "none" || !_chunkIWSMDQE5cjs.videoAssetHasSound.call(void 0, asset)) return false;
3245
+ if (clip.type !== "media" || mode === "none" || !_chunk4QQZV5Y5cjs.videoAssetHasSound.call(void 0, asset)) return false;
3246
3246
  return mode === "all" || asset.kind === "audio";
3247
3247
  }
3248
3248
  var VIDEO_CLIP_ANIMATION_LABELS = {
@@ -3301,11 +3301,11 @@ function videoClipLabel(clip, asset, sequence) {
3301
3301
  if (clip.type === "sequence") return `Compound: ${_nullishCoalesce(_optionalChain([sequence, 'optionalAccess', _104 => _104.name]), () => ( clip.sequence))}`;
3302
3302
  if (clip.type === "effect") return `Effect: ${clip.effect}`;
3303
3303
  const base = _nullishCoalesce(_nullishCoalesce(_optionalChain([asset, 'optionalAccess', _105 => _105.name]), () => ( _optionalChain([asset, 'optionalAccess', _106 => _106.src, 'access', _107 => _107.replace, 'call', _108 => _108(/^.*[\\/]/, "")]))), () => ( clip.asset));
3304
- const speed = _chunkIWSMDQE5cjs.videoClipSpeed.call(void 0, clip);
3304
+ const speed = _chunk4QQZV5Y5cjs.videoClipSpeed.call(void 0, clip);
3305
3305
  return speed !== 1 ? `${base} (${Math.round(speed * 100)}%)` : base;
3306
3306
  }
3307
3307
  function planVideoClipDrag(project, input) {
3308
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project, input.clip);
3308
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project, input.clip);
3309
3309
  if (!at) return null;
3310
3310
  const { clip, track } = at;
3311
3311
  const snap = _nullishCoalesce(input.snap, () => ( ((t) => t)));
@@ -3322,17 +3322,17 @@ function planVideoClipDrag(project, input) {
3322
3322
  }
3323
3323
  const minimum = 1e3 / project.fps;
3324
3324
  if (input.mode === "trim-start") {
3325
- const to2 = Math.min(snap(Math.max(0, clip.start + input.delta)), _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip) - minimum);
3325
+ const to2 = Math.min(snap(Math.max(0, clip.start + input.delta)), _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip) - minimum);
3326
3326
  const changed2 = Math.abs(to2 - clip.start) > 1e-6;
3327
- const plan = input.ripple ? { start: clip.start, duration: clip.duration - (to2 - clip.start) } : { start: to2, duration: _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip) - to2 };
3327
+ const plan = input.ripple ? { start: clip.start, duration: clip.duration - (to2 - clip.start) } : { start: to2, duration: _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip) - to2 };
3328
3328
  return { ...plan, track: track.id, edit: changed2 ? { op: "trim_clip", clip: clip.id, edge: "start", to: to2, ...input.ripple ? { ripple: true } : {} } : null };
3329
3329
  }
3330
- const to = Math.max(snap(_chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip) + input.delta), clip.start + minimum);
3331
- const changed = Math.abs(to - _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, clip)) > 1e-6;
3330
+ const to = Math.max(snap(_chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip) + input.delta), clip.start + minimum);
3331
+ const changed = Math.abs(to - _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, clip)) > 1e-6;
3332
3332
  return { start: clip.start, duration: to - clip.start, track: track.id, edit: changed ? { op: "trim_clip", clip: clip.id, edge: "end", to, ...input.ripple ? { ripple: true } : {} } : null };
3333
3333
  }
3334
3334
  function videoDropTracks(project, clipId) {
3335
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project, clipId);
3335
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project, clipId);
3336
3336
  if (!at) return [];
3337
3337
  return project.tracks.filter((t) => t.kind === at.track.kind && !t.locked).map((t) => t.id);
3338
3338
  }
@@ -3341,7 +3341,7 @@ function videoDragLabel(edit) {
3341
3341
  return edit.op === "trim_clip" && edit.ripple ? "Ripple trim" : "Trim clip";
3342
3342
  }
3343
3343
  function videoAssetDropEdit(project, assetId, options = {}) {
3344
- const asset = _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, project).get(assetId);
3344
+ const asset = _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, project).get(assetId);
3345
3345
  if (!asset) return null;
3346
3346
  const kind = asset.kind === "audio" ? "audio" : "video";
3347
3347
  const track = _nullishCoalesce(options.track, () => ( _optionalChain([project, 'access', _109 => _109.tracks, 'access', _110 => _110.find, 'call', _111 => _111((t) => t.kind === kind && !t.locked), 'optionalAccess', _112 => _112.id])));
@@ -3393,25 +3393,25 @@ var KEY_LABELS = {
3393
3393
  scale: { label: "Scale", step: 0.05 },
3394
3394
  rotation: { label: "Rotation", step: 1 }
3395
3395
  };
3396
- var animatableOf = (clip, property) => _chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(property) ? _optionalChain([clip, 'access', _113 => _113.transform, 'optionalAccess', _114 => _114[property]]) : property === "volume" ? clip.type === "media" || clip.type === "sequence" ? clip.volume : void 0 : clip.opacity;
3396
+ var animatableOf = (clip, property) => _chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(property) ? _optionalChain([clip, 'access', _113 => _113.transform, 'optionalAccess', _114 => _114[property]]) : property === "volume" ? clip.type === "media" || clip.type === "sequence" ? clip.volume : void 0 : clip.opacity;
3397
3397
  var playheadInClip = (clip, time) => Math.round(Math.min(clip.duration, Math.max(0, time - clip.start)));
3398
3398
  function videoKeyframeRows(project, clipId, time) {
3399
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project, clipId);
3399
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project, clipId);
3400
3400
  if (!at) return [];
3401
3401
  const { clip } = at;
3402
- const asset = clip.type === "media" ? _chunkIWSMDQE5cjs.videoAssetMap.call(void 0, project).get(clip.asset) : void 0;
3402
+ const asset = clip.type === "media" ? _chunk4QQZV5Y5cjs.videoAssetMap.call(void 0, project).get(clip.asset) : void 0;
3403
3403
  const visual = !(_optionalChain([asset, 'optionalAccess', _115 => _115.kind]) === "audio" || at.track.kind === "audio");
3404
- const audible = clip.type === "media" && _chunkIWSMDQE5cjs.videoAssetHasSound.call(void 0, asset) || clip.type === "sequence";
3405
- const properties = [...visual ? ["opacity"] : [], ...audible ? ["volume"] : [], ...visual ? _chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES : []];
3404
+ const audible = clip.type === "media" && _chunk4QQZV5Y5cjs.videoAssetHasSound.call(void 0, asset) || clip.type === "sequence";
3405
+ const properties = [...visual ? ["opacity"] : [], ...audible ? ["volume"] : [], ...visual ? _chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES : []];
3406
3406
  const clipTime = playheadInClip(clip, time);
3407
3407
  return properties.map((property) => {
3408
3408
  const prop = animatableOf(clip, property);
3409
- const keys = _chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, prop) ? prop.keys : [];
3410
- const limits = _chunkIWSMDQE5cjs.VIDEO_KEYFRAME_LIMITS[property];
3409
+ const keys = _chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, prop) ? prop.keys : [];
3410
+ const limits = _chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_LIMITS[property];
3411
3411
  return {
3412
3412
  property,
3413
3413
  ...KEY_LABELS[property],
3414
- value: Math.round(_chunkIWSMDQE5cjs.videoValueAt.call(void 0, prop, clipTime, limits.default) * 1e3) / 1e3,
3414
+ value: Math.round(_chunk4QQZV5Y5cjs.videoValueAt.call(void 0, prop, clipTime, limits.default) * 1e3) / 1e3,
3415
3415
  keyed: keys.length > 0,
3416
3416
  keys: keys.length,
3417
3417
  onKey: keys.some((k) => Math.abs(k.t - clipTime) < 0.5),
@@ -3422,44 +3422,44 @@ function videoKeyframeRows(project, clipId, time) {
3422
3422
  });
3423
3423
  }
3424
3424
  function plainValueEdit(clip, property, value) {
3425
- if (!_chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(property))
3425
+ if (!_chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(property))
3426
3426
  return value === void 0 ? { op: "update_clip", clip: clip.id, remove: [property] } : { op: "update_clip", clip: clip.id, set: { [property]: value } };
3427
3427
  const transform = { ...clip.transform, [property]: value };
3428
3428
  if (value === void 0) delete transform[property];
3429
3429
  return Object.keys(transform).length ? { op: "update_clip", clip: clip.id, set: { transform } } : { op: "update_clip", clip: clip.id, remove: ["transform"] };
3430
3430
  }
3431
3431
  function videoKeyframeValueEdit(project, clipId, property, time, value) {
3432
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project, clipId);
3432
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project, clipId);
3433
3433
  if (!at) return null;
3434
3434
  const prop = animatableOf(at.clip, property);
3435
- if (!_chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, prop)) return plainValueEdit(at.clip, property, value);
3435
+ if (!_chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, prop)) return plainValueEdit(at.clip, property, value);
3436
3436
  if (value === void 0) return null;
3437
- return { op: "set_keyframes", clip: clipId, property, keys: _chunkIWSMDQE5cjs.setVideoKey.call(void 0, prop, { t: playheadInClip(at.clip, time), v: value }, _chunkIWSMDQE5cjs.VIDEO_KEYFRAME_LIMITS[property].default).keys };
3437
+ return { op: "set_keyframes", clip: clipId, property, keys: _chunk4QQZV5Y5cjs.setVideoKey.call(void 0, prop, { t: playheadInClip(at.clip, time), v: value }, _chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_LIMITS[property].default).keys };
3438
3438
  }
3439
3439
  function videoKeyframeToggleEdit(project, clipId, property, time) {
3440
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project, clipId);
3440
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project, clipId);
3441
3441
  if (!at) return null;
3442
3442
  const prop = animatableOf(at.clip, property);
3443
3443
  const t = playheadInClip(at.clip, time);
3444
- const fallback = _chunkIWSMDQE5cjs.VIDEO_KEYFRAME_LIMITS[property].default;
3445
- if (_chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, prop)) {
3444
+ const fallback = _chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_LIMITS[property].default;
3445
+ if (_chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, prop)) {
3446
3446
  const key = prop.keys.find((k) => Math.abs(k.t - t) < 0.5);
3447
3447
  if (key) {
3448
- const rest = _chunkIWSMDQE5cjs.removeVideoKey.call(void 0, prop, key.t);
3449
- return _chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, rest) ? { op: "set_keyframes", clip: clipId, property, keys: rest.keys } : plainValueEdit(at.clip, property, rest === fallback ? void 0 : rest);
3448
+ const rest = _chunk4QQZV5Y5cjs.removeVideoKey.call(void 0, prop, key.t);
3449
+ return _chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, rest) ? { op: "set_keyframes", clip: clipId, property, keys: rest.keys } : plainValueEdit(at.clip, property, rest === fallback ? void 0 : rest);
3450
3450
  }
3451
3451
  }
3452
- const v = _chunkIWSMDQE5cjs.videoValueAt.call(void 0, prop, t, fallback);
3453
- return { op: "set_keyframes", clip: clipId, property, keys: _chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, prop) ? _chunkIWSMDQE5cjs.setVideoKey.call(void 0, prop, { t, v }, fallback).keys : [{ t, v }] };
3452
+ const v = _chunk4QQZV5Y5cjs.videoValueAt.call(void 0, prop, t, fallback);
3453
+ return { op: "set_keyframes", clip: clipId, property, keys: _chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, prop) ? _chunk4QQZV5Y5cjs.setVideoKey.call(void 0, prop, { t, v }, fallback).keys : [{ t, v }] };
3454
3454
  }
3455
3455
  function videoLutEdits(project, clips, lut) {
3456
3456
  const edits = [];
3457
3457
  for (const id of clips) {
3458
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project, id);
3458
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project, id);
3459
3459
  if (!at) continue;
3460
3460
  const { lut: current, ...rest } = _nullishCoalesce(at.clip.grade, () => ( {}));
3461
3461
  if (!lut && !current) continue;
3462
- const grade = _chunkIWSMDQE5cjs.normalizeVideoGrade.call(void 0, lut ? { ...rest, lut } : rest);
3462
+ const grade = _chunk4QQZV5Y5cjs.normalizeVideoGrade.call(void 0, lut ? { ...rest, lut } : rest);
3463
3463
  edits.push(grade ? { op: "update_clip", clip: id, set: { grade } } : { op: "update_clip", clip: id, remove: ["grade"] });
3464
3464
  }
3465
3465
  return edits;
@@ -3489,7 +3489,7 @@ var RIPPLE = {
3489
3489
  };
3490
3490
  var MODE = {
3491
3491
  type: "string",
3492
- enum: [..._chunkIWSMDQE5cjs.VIDEO_PLACEMENT_MODES],
3492
+ enum: [..._chunk4QQZV5Y5cjs.VIDEO_PLACEMENT_MODES],
3493
3493
  description: 'What to do with clips already where it lands: "refuse" (default) fails with the next free place; "overwrite" cuts, trims or removes what is underneath on that track; "insert" cuts everything across the start and pushes later material along by its length on this track and every sync-locked track.'
3494
3494
  };
3495
3495
  var DELTA = (what) => ({ type: "number", description: `${what}, in milliseconds of timeline time: positive is later, negative earlier. It is clamped to what the media and neighbours allow; the result says how far it went.` });
@@ -3506,11 +3506,11 @@ var TRANSFORM = object(
3506
3506
  );
3507
3507
  var TRANSITION = object(
3508
3508
  {
3509
- type: { type: "string", enum: _chunkIWSMDQE5cjs.VIDEO_TRANSITION_TYPES.filter((t) => t !== "effect"), description: "crossfade (this clip fades up over the one before), dip (down into a colour and up out of it), wipe (an edge travels across revealing this clip), push (this clip slides in and pushes the one before out), slide (this clip slides in over the one before) or iris (a circle opens from the centre). For a transition effect from the effects provider use set_video_effect_transition." },
3509
+ type: { type: "string", enum: _chunk4QQZV5Y5cjs.VIDEO_TRANSITION_TYPES.filter((t) => t !== "effect"), description: "crossfade (this clip fades up over the one before), dip (down into a colour and up out of it), wipe (an edge travels across revealing this clip), push (this clip slides in and pushes the one before out), slide (this clip slides in over the one before) or iris (a circle opens from the centre). For a transition effect from the effects provider use set_video_effect_transition." },
3510
3510
  duration: { type: "number", exclusiveMinimum: 0, description: "Length in ms, centred on the cut. Every type but dip needs half of it in media past the cut on both sides (handles); a dip needs none." },
3511
3511
  color: COLOR("For dip: the colour passed through (default black)"),
3512
- direction: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_WIPE_DIRECTIONS], description: "For wipe, push and slide: the way the edge or picture travels (default right, coming in from the left)." },
3513
- audioCurve: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_FADE_CURVES], description: "Shape of the sound's fades through it: default equal-power for every type but dip (steady loudness while the two sounds overlap), linear for dip; or s-curve, exponential, logarithmic." }
3512
+ direction: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_WIPE_DIRECTIONS], description: "For wipe, push and slide: the way the edge or picture travels (default right, coming in from the left)." },
3513
+ audioCurve: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES], description: "Shape of the sound's fades through it: default equal-power for every type but dip (steady loudness while the two sounds overlap), linear for dip; or s-curve, exponential, logarithmic." }
3514
3514
  },
3515
3515
  ["type", "duration"],
3516
3516
  "A transition from the clip that ends where this one starts on the same track."
@@ -3519,7 +3519,7 @@ var LUT_SRC = { type: "string", minLength: 1, description: 'A .cube 3D LUT file
3519
3519
  var LUT_STRENGTH = { type: "number", minimum: 0, maximum: 1, description: "How much of the LUT's change to apply, 0 (none) to 1 (full, the default); 0.3-0.7 for a subtler look." };
3520
3520
  var GRADE = object(
3521
3521
  {
3522
- ...Object.fromEntries(_chunkIWSMDQE5cjs.VIDEO_GRADE_CONTROLS.map((c) => [c.key, { type: "number", minimum: c.min, maximum: c.max, description: c.description }])),
3522
+ ...Object.fromEntries(_chunk4QQZV5Y5cjs.VIDEO_GRADE_CONTROLS.map((c) => [c.key, { type: "number", minimum: c.min, maximum: c.max, description: c.description }])),
3523
3523
  lut: object({ src: LUT_SRC, strength: LUT_STRENGTH, name: { type: "string", minLength: 1, description: "A label for the look." } }, ["src"], "A 3D LUT applied after the other settings (set_video_lut checks the file first).")
3524
3524
  },
3525
3525
  [],
@@ -3527,7 +3527,7 @@ var GRADE = object(
3527
3527
  );
3528
3528
  var ANIMATION = (when) => object(
3529
3529
  {
3530
- effect: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_CLIP_ANIMATION_EFFECTS], description: "fade; rise (up into place) or drop (down into place); slide-left / slide-right (moving that way); zoom (grows into place); pop (grows past its size and settles). Each also fades; an exit plays the movement backwards." },
3530
+ effect: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_CLIP_ANIMATION_EFFECTS], description: "fade; rise (up into place) or drop (down into place); slide-left / slide-right (moving that way); zoom (grows into place); pop (grows past its size and settles). Each also fades; an exit plays the movement backwards." },
3531
3531
  duration: { type: "number", exclusiveMinimum: 0, description: "Length in ms (default 500)." }
3532
3532
  },
3533
3533
  ["effect"],
@@ -3537,11 +3537,11 @@ var CLIP_COMMON = {
3537
3537
  name: { type: "string", description: "A label for the clip." },
3538
3538
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Opacity 0\u20131 (default 1). A number replaces any keyframes; set_video_keyframes animates it." },
3539
3539
  transform: TRANSFORM,
3540
- fit: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_FITS], description: "How the picture fits the frame before the transform, as CSS object-fit (default contain for media, fill for colours)." },
3540
+ fit: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_FITS], description: "How the picture fits the frame before the transform, as CSS object-fit (default contain for media, fill for colours)." },
3541
3541
  grade: GRADE,
3542
3542
  animateIn: ANIMATION("How the picture enters, from the clip's start (on top of any fade in). Titles usually rise, pop or fade in."),
3543
3543
  animateOut: ANIMATION("How the picture leaves, ending at the clip's end."),
3544
- blend: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_BLEND_MODES], description: "How the picture mixes with what is beneath it, as CSS mix-blend-mode (default normal): multiply darkens (shadows, textures), screen and add lighten (light leaks, flares, glows), overlay and soft-light add contrast, difference and exclusion invert." },
3544
+ blend: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_BLEND_MODES], description: "How the picture mixes with what is beneath it, as CSS mix-blend-mode (default normal): multiply darkens (shadows, textures), screen and add lighten (light leaks, flares, glows), overlay and soft-light add contrast, difference and exclusion invert." },
3545
3545
  fadeIn: MS("Fade up from nothing (picture and sound) over this long"),
3546
3546
  fadeOut: MS("Fade down to nothing over this long")
3547
3547
  };
@@ -3550,8 +3550,8 @@ var MEDIA_FIELDS = {
3550
3550
  speed: { type: "number", minimum: 0.05, maximum: 20, description: "Playback speed (default 1). Changing it keeps the stretch of source, so the clip gets shorter or longer." },
3551
3551
  volume: { type: "number", minimum: 0, maximum: 4, description: "Gain (1 = unchanged, default 1). A number replaces any keyframes; set_video_keyframes animates it." },
3552
3552
  muted: { type: "boolean", description: "Silence this clip (default false)." },
3553
- fadeInCurve: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_FADE_CURVES], description: "Shape of the sound's fade in (default linear; the picture always fades linearly): linear, equal-power (steady loudness, best for crossfades), s-curve (gentle at both ends), exponential (slow start, natural from silence) or logarithmic (fast start)." },
3554
- fadeOutCurve: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_FADE_CURVES], description: "Shape of the sound's fade out (default linear), the same choices as fadeInCurve; exponential sounds natural fading to silence." }
3553
+ fadeInCurve: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES], description: "Shape of the sound's fade in (default linear; the picture always fades linearly): linear, equal-power (steady loudness, best for crossfades), s-curve (gentle at both ends), exponential (slow start, natural from silence) or logarithmic (fast start)." },
3554
+ fadeOutCurve: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES], description: "Shape of the sound's fade out (default linear), the same choices as fadeInCurve; exponential sounds natural fading to silence." }
3555
3555
  };
3556
3556
  var TEXT_FIELDS = {
3557
3557
  text: { type: "string", minLength: 1, description: `The title's text ("\\n" breaks lines).` },
@@ -3600,7 +3600,7 @@ var ASSET_FIELDS = {
3600
3600
  };
3601
3601
  var KEY_PROPERTY = {
3602
3602
  type: "string",
3603
- enum: [..._chunkIWSMDQE5cjs.VIDEO_KEYFRAME_PROPERTIES],
3603
+ enum: [..._chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_PROPERTIES],
3604
3604
  description: "Which property: opacity (0\u20131), volume (media only, 0\u20134 gain), x / y (pixels from the frame's centre, right / down), scale (1 = fitted size) or rotation (degrees clockwise)."
3605
3605
  };
3606
3606
  var KEYS = {
@@ -3615,7 +3615,7 @@ var KEYS = {
3615
3615
  ease: {
3616
3616
  description: "How the value moves from this key to the next (default linear): linear, hold (stays, then jumps at the next key), ease-in, ease-out, ease-in-out, or CSS cubic-bezier points [x1, y1, x2, y2] with x1 and x2 in 0\u20131.",
3617
3617
  anyOf: [
3618
- { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_EASE_NAMES] },
3618
+ { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_EASE_NAMES] },
3619
3619
  { type: "array", items: { type: "number" }, minItems: 4, maxItems: 4 }
3620
3620
  ]
3621
3621
  }
@@ -3644,19 +3644,19 @@ var describeVideoTracks = (tracks) => tracks.map((t, index) => ({
3644
3644
  ...t.locked ? { locked: true } : {},
3645
3645
  ...t.syncLocked === false ? { syncLocked: false } : {},
3646
3646
  ...t.volume !== void 0 ? { volume: t.volume } : {},
3647
- clips: _chunkIWSMDQE5cjs.sortedVideoClips.call(void 0, t).map((c) => ({ ...c, end: _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c), ...c.type === "media" || c.type === "sequence" ? { source: _chunkIWSMDQE5cjs.videoClipSourceRange.call(void 0, c) } : {} }))
3647
+ clips: _chunk4QQZV5Y5cjs.sortedVideoClips.call(void 0, t).map((c) => ({ ...c, end: _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c), ...c.type === "media" || c.type === "sequence" ? { source: _chunk4QQZV5Y5cjs.videoClipSourceRange.call(void 0, c) } : {} }))
3648
3648
  }));
3649
- var videoSequenceUsers = (project, id) => _chunkIWSMDQE5cjs.allVideoTracks.call(void 0, project).flatMap(
3650
- ({ sequence, track }) => track.clips.flatMap((c) => c.type === "sequence" && c.sequence === id ? [{ clip: c.id, ...sequence ? { inSequence: sequence } : {}, track: track.id, start: c.start, end: _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c), source: _chunkIWSMDQE5cjs.videoClipSourceRange.call(void 0, c) }] : [])
3649
+ var videoSequenceUsers = (project, id) => _chunk4QQZV5Y5cjs.allVideoTracks.call(void 0, project).flatMap(
3650
+ ({ sequence, track }) => track.clips.flatMap((c) => c.type === "sequence" && c.sequence === id ? [{ clip: c.id, ...sequence ? { inSequence: sequence } : {}, track: track.id, start: c.start, end: _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c), source: _chunk4QQZV5Y5cjs.videoClipSourceRange.call(void 0, c) }] : [])
3651
3651
  );
3652
3652
  function describeVideoSequence(project, sequence, tracks = true) {
3653
- const cycle = _chunkIWSMDQE5cjs.findVideoSequenceCycle.call(void 0, project, sequence.id);
3653
+ const cycle = _chunk4QQZV5Y5cjs.findVideoSequenceCycle.call(void 0, project, sequence.id);
3654
3654
  return {
3655
3655
  id: sequence.id,
3656
3656
  ...sequence.name ? { name: sequence.name } : {},
3657
- duration: _chunkIWSMDQE5cjs.videoSequenceDuration.call(void 0, sequence),
3657
+ duration: _chunk4QQZV5Y5cjs.videoSequenceDuration.call(void 0, sequence),
3658
3658
  clipCount: sequence.tracks.reduce((n, t) => n + t.clips.length, 0),
3659
- nests: _chunkIWSMDQE5cjs.videoSequenceChildren.call(void 0, sequence),
3659
+ nests: _chunk4QQZV5Y5cjs.videoSequenceChildren.call(void 0, sequence),
3660
3660
  usedBy: videoSequenceUsers(project, sequence.id),
3661
3661
  ...cycle ? { cycle } : {},
3662
3662
  ...tracks ? { tracks: describeVideoTracks(sequence.tracks) } : { trackCount: sequence.tracks.length }
@@ -3668,7 +3668,7 @@ function describeVideoProject(project) {
3668
3668
  width: project.width,
3669
3669
  height: project.height,
3670
3670
  fps: project.fps,
3671
- duration: _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, project),
3671
+ duration: _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, project),
3672
3672
  ...project.background ? { background: project.background } : {},
3673
3673
  assets: project.assets.map(videoAssetOut),
3674
3674
  tracks: describeVideoTracks(project.tracks),
@@ -3685,7 +3685,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
3685
3685
  const project = () => controller.getProject();
3686
3686
  const outcome = (result, extra = {}) => {
3687
3687
  if (!result.ok) throw new Error(result.error);
3688
- return { ...extra, duration: _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, result.project), issues: issueSummary(result.issues) };
3688
+ return { ...extra, duration: _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, result.project), issues: issueSummary(result.issues) };
3689
3689
  };
3690
3690
  const apply = (edits, label, extra) => {
3691
3691
  const result = controller.apply(edits, label);
@@ -3694,7 +3694,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
3694
3694
  const clipOut = (p, id) => {
3695
3695
  for (const t of p.tracks) {
3696
3696
  const c = t.clips.find((x) => x.id === id);
3697
- if (c) return { track: t.id, ...c, end: _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c), ...c.type === "media" || c.type === "sequence" ? { source: _chunkIWSMDQE5cjs.videoClipSourceRange.call(void 0, c) } : {} };
3697
+ if (c) return { track: t.id, ...c, end: _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c), ...c.type === "media" || c.type === "sequence" ? { source: _chunk4QQZV5Y5cjs.videoClipSourceRange.call(void 0, c) } : {} };
3698
3698
  }
3699
3699
  return null;
3700
3700
  };
@@ -3706,7 +3706,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
3706
3706
  });
3707
3707
  const keysOut = (p, clip, property) => {
3708
3708
  const c = clipOut(p, clip);
3709
- const value = _chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(property) ? _optionalChain([c, 'optionalAccess', _124 => _124.transform, 'optionalAccess', _125 => _125[property]]) : _optionalChain([c, 'optionalAccess', _126 => _126[property]]);
3709
+ const value = _chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES.includes(property) ? _optionalChain([c, 'optionalAccess', _124 => _124.transform, 'optionalAccess', _125 => _125[property]]) : _optionalChain([c, 'optionalAccess', _126 => _126[property]]);
3710
3710
  return typeof value === "object" ? { keys: value.keys } : { keys: [], value: _nullishCoalesce(value, () => ( null)) };
3711
3711
  };
3712
3712
  const getProject = {
@@ -3728,8 +3728,8 @@ function createVideoEditorToolProvider(controller, options = {}) {
3728
3728
  inputSchema: object({ time: MS("Time from the start (default: the playhead)") }),
3729
3729
  annotations: { title: "What plays at a moment", ...READ },
3730
3730
  handler: ({ time }) => {
3731
- const frame = _chunkIWSMDQE5cjs.videoFrameAt.call(void 0, project(), _nullishCoalesce(time, () => ( controller.getState().time)));
3732
- return { ...frame, timecode: _chunkIWSMDQE5cjs.formatVideoTimecode.call(void 0, frame.time, project().fps) };
3731
+ const frame = _chunk4QQZV5Y5cjs.videoFrameAt.call(void 0, project(), _nullishCoalesce(time, () => ( controller.getState().time)));
3732
+ return { ...frame, timecode: _chunk4QQZV5Y5cjs.formatVideoTimecode.call(void 0, frame.time, project().fps) };
3733
3733
  }
3734
3734
  };
3735
3735
  const listSequences = {
@@ -3757,7 +3757,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
3757
3757
  annotations: { title: "Find gaps", ...READ },
3758
3758
  handler: ({ track }) => {
3759
3759
  if (track !== void 0 && !project().tracks.some((t) => t.id === track)) throw new Error(`There is no track "${track}"; the tracks are ${project().tracks.map((t) => `"${t.id}"`).join(", ")}.`);
3760
- return { gaps: _chunkIWSMDQE5cjs.findVideoGaps.call(void 0, project(), track) };
3760
+ return { gaps: _chunk4QQZV5Y5cjs.findVideoGaps.call(void 0, project(), track) };
3761
3761
  }
3762
3762
  };
3763
3763
  const checkProject = {
@@ -3787,7 +3787,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
3787
3787
  const lutSrcs = [...new Set(p.tracks.flatMap((t) => t.clips.map((c) => _optionalChain([c, 'access', _127 => _127.grade, 'optionalAccess', _128 => _128.lut, 'optionalAccess', _129 => _129.src])).filter((x) => !!x)))];
3788
3788
  const missing = (await Promise.all(lutSrcs.map((src) => controller.luts.load(src).then(() => null, (e) => e.message)))).filter((m) => !!m);
3789
3789
  const svgOptions = { lutFor: (src) => controller.luts.peek(src), ...columns ? { columns } : {} };
3790
- const svg = times ? _chunkIWSMDQE5cjs.videoContactSheetSvg.call(void 0, p, times, svgOptions) : _chunkIWSMDQE5cjs.videoProjectSvg.call(void 0, p, _nullishCoalesce(time, () => ( controller.getState().time)), svgOptions);
3790
+ const svg = times ? _chunk4QQZV5Y5cjs.videoContactSheetSvg.call(void 0, p, times, svgOptions) : _chunk4QQZV5Y5cjs.videoProjectSvg.call(void 0, p, _nullishCoalesce(time, () => ( controller.getState().time)), svgOptions);
3791
3791
  const notes = [...missing.map((m) => `${m}; that LUT is left out of the picture.`), ...lutSrcs.length > missing.length ? ["LUTs are drawn approximately in SVG (curves and a colour matrix); the preview and export apply them exactly."] : []];
3792
3792
  if (format === "png") {
3793
3793
  if (!options.rasterize) throw new Error('This host cannot make PNG images; call render_video_frame with format "svg".');
@@ -3877,7 +3877,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
3877
3877
  if (play === true) controller.play();
3878
3878
  if (play === false) controller.pause();
3879
3879
  const state = controller.getState();
3880
- return { time: state.time, timecode: _chunkIWSMDQE5cjs.formatVideoTimecode.call(void 0, state.time, p.fps), playing: state.playing, clips: state.current };
3880
+ return { time: state.time, timecode: _chunk4QQZV5Y5cjs.formatVideoTimecode.call(void 0, state.time, p.fps), playing: state.playing, clips: state.current };
3881
3881
  }
3882
3882
  };
3883
3883
  const setSettings = {
@@ -4022,7 +4022,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4022
4022
  const gradeTargets = (ids) => {
4023
4023
  const p = project();
4024
4024
  for (const id of ids) {
4025
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, p, id);
4025
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, p, id);
4026
4026
  if (!at) throw new Error(`There is no clip "${id}"; get_video_project lists the clips.`);
4027
4027
  const { clip } = at;
4028
4028
  if (at.track.kind !== "video" || clip.type === "media" && _optionalChain([p, 'access', _130 => _130.assets, 'access', _131 => _131.find, 'call', _132 => _132((a) => a.id === clip.asset), 'optionalAccess', _133 => _133.kind]) === "audio")
@@ -4036,7 +4036,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4036
4036
  inputSchema: object(
4037
4037
  {
4038
4038
  clips: { type: "array", items: CLIP_ID, minItems: 1, description: "Clips on video tracks to grade." },
4039
- preset: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_GRADE_PRESET_NAMES], description: "The look." },
4039
+ preset: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_GRADE_PRESET_NAMES], description: "The look." },
4040
4040
  amount: { type: "number", minimum: 0, maximum: 1, description: "Strength, 0 (none) to 1 (full, the default); 0.5 is a subtler version." }
4041
4041
  },
4042
4042
  ["clips", "preset"]
@@ -4045,10 +4045,10 @@ function createVideoEditorToolProvider(controller, options = {}) {
4045
4045
  handler: ({ clips, preset, amount }) => {
4046
4046
  gradeTargets(clips);
4047
4047
  const edits = clips.map((clip) => {
4048
- const grade = _chunkIWSMDQE5cjs.videoGradeLook.call(void 0, _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project(), clip).clip.grade, preset, _nullishCoalesce(amount, () => ( 1)));
4048
+ const grade = _chunk4QQZV5Y5cjs.videoGradeLook.call(void 0, _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project(), clip).clip.grade, preset, _nullishCoalesce(amount, () => ( 1)));
4049
4049
  return grade ? { op: "update_clip", clip, set: { grade } } : { op: "update_clip", clip, remove: ["grade"] };
4050
4050
  });
4051
- return apply(edits, `Apply ${preset} look`, (r) => ({ clips: clips.map((id) => ({ id, grade: _nullishCoalesce(_optionalChain([_chunkIWSMDQE5cjs.findVideoClip.call(void 0, r.project, id), 'optionalAccess', _134 => _134.clip, 'access', _135 => _135.grade]), () => ( null)) })) }));
4051
+ return apply(edits, `Apply ${preset} look`, (r) => ({ clips: clips.map((id) => ({ id, grade: _nullishCoalesce(_optionalChain([_chunk4QQZV5Y5cjs.findVideoClip.call(void 0, r.project, id), 'optionalAccess', _134 => _134.clip, 'access', _135 => _135.grade]), () => ( null)) })) }));
4052
4052
  }
4053
4053
  };
4054
4054
  const copyGrade = {
@@ -4059,7 +4059,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4059
4059
  annotations: { title: "Copy a colour grade", ...WRITE_IDEMPOTENT },
4060
4060
  handler: ({ from, to }) => {
4061
4061
  gradeTargets([from, ...to]);
4062
- const grade = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project(), from).clip.grade;
4062
+ const grade = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project(), from).clip.grade;
4063
4063
  const edits = to.map((clip) => grade ? { op: "update_clip", clip, set: { grade: { ...grade } } } : { op: "update_clip", clip, remove: ["grade"] });
4064
4064
  return apply(edits, "Copy grade", () => ({ grade: _nullishCoalesce(grade, () => ( null)), clips: to }));
4065
4065
  }
@@ -4084,7 +4084,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4084
4084
  const lut = await controller.luts.load(src);
4085
4085
  const label = _nullishCoalesce(name, () => ( lut.title));
4086
4086
  const setting = { src, ...strength !== void 0 && strength !== 1 ? { strength } : {}, ...label ? { name: label } : {} };
4087
- return apply(videoLutEdits(project(), clips, setting), "Apply LUT", (r) => ({ lut: { src, ...lut.title ? { title: lut.title } : {}, size: lut.size }, clips: clips.map((id) => ({ id, grade: _nullishCoalesce(_optionalChain([_chunkIWSMDQE5cjs.findVideoClip.call(void 0, r.project, id), 'optionalAccess', _136 => _136.clip, 'access', _137 => _137.grade]), () => ( null)) })) }));
4087
+ return apply(videoLutEdits(project(), clips, setting), "Apply LUT", (r) => ({ lut: { src, ...lut.title ? { title: lut.title } : {}, size: lut.size }, clips: clips.map((id) => ({ id, grade: _nullishCoalesce(_optionalChain([_chunk4QQZV5Y5cjs.findVideoClip.call(void 0, r.project, id), 'optionalAccess', _136 => _136.clip, 'access', _137 => _137.grade]), () => ( null)) })) }));
4088
4088
  }
4089
4089
  };
4090
4090
  const removeLut = {
@@ -4096,9 +4096,9 @@ function createVideoEditorToolProvider(controller, options = {}) {
4096
4096
  handler: ({ clips }) => {
4097
4097
  gradeTargets(clips);
4098
4098
  const p = project();
4099
- const withLut = clips.filter((id) => _optionalChain([_chunkIWSMDQE5cjs.findVideoClip.call(void 0, p, id), 'access', _138 => _138.clip, 'access', _139 => _139.grade, 'optionalAccess', _140 => _140.lut]));
4099
+ const withLut = clips.filter((id) => _optionalChain([_chunk4QQZV5Y5cjs.findVideoClip.call(void 0, p, id), 'access', _138 => _138.clip, 'access', _139 => _139.grade, 'optionalAccess', _140 => _140.lut]));
4100
4100
  if (!withLut.length) throw new Error(`None of ${clips.map((c) => `"${c}"`).join(", ")} has a LUT; get_video_project shows each clip's grade.`);
4101
- return apply(videoLutEdits(p, withLut, null), "Remove LUT", (r) => ({ clips: clips.map((id) => ({ id, grade: _nullishCoalesce(_optionalChain([_chunkIWSMDQE5cjs.findVideoClip.call(void 0, r.project, id), 'optionalAccess', _141 => _141.clip, 'access', _142 => _142.grade]), () => ( null)) })) }));
4101
+ return apply(videoLutEdits(p, withLut, null), "Remove LUT", (r) => ({ clips: clips.map((id) => ({ id, grade: _nullishCoalesce(_optionalChain([_chunk4QQZV5Y5cjs.findVideoClip.call(void 0, r.project, id), 'optionalAccess', _141 => _141.clip, 'access', _142 => _142.grade]), () => ( null)) })) }));
4102
4102
  }
4103
4103
  };
4104
4104
  const PROXY_SCALE = { type: "number", exclusiveMinimum: 0, exclusiveMaximum: 1, description: "Proxy size as a fraction of the original: 0.5 (half width and height, the default) or 0.25 for very large footage." };
@@ -4207,7 +4207,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4207
4207
  approximate: parsed.approximate,
4208
4208
  first: list[0],
4209
4209
  last: list[list.length - 1],
4210
- ...a.duration !== void 0 && list[list.length - 1].end > a.duration + _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON ? { warning: `The transcript runs to ${list[list.length - 1].end} ms, past the asset's ${a.duration} ms: is it for this asset?` } : {}
4210
+ ...a.duration !== void 0 && list[list.length - 1].end > a.duration + _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON ? { warning: `The transcript runs to ${list[list.length - 1].end} ms, past the asset's ${a.duration} ms: is it for this asset?` } : {}
4211
4211
  }));
4212
4212
  }
4213
4213
  };
@@ -4278,12 +4278,12 @@ function createVideoEditorToolProvider(controller, options = {}) {
4278
4278
  const bad = ranges.findIndex((r) => !(r.to > r.from));
4279
4279
  if (bad >= 0) throw new Error(`Range ${bad + 1} is empty or backwards (${ranges[bad].from}\u2013${ranges[bad].to} ms); "to" must be after "from".`);
4280
4280
  const merged = mergeVideoRanges(ranges);
4281
- const before = _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, project());
4282
- return apply(videoRemoveRangesEdits(merged, tracks), merged.length > 1 ? `Cut ${merged.length} stretches` : "Cut stretch", (r) => ({ removed: merged.length, time: round(before - _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, r.project)), duration: _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, r.project) }));
4281
+ const before = _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, project());
4282
+ return apply(videoRemoveRangesEdits(merged, tracks), merged.length > 1 ? `Cut ${merged.length} stretches` : "Cut stretch", (r) => ({ removed: merged.length, time: round(before - _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, r.project)), duration: _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, r.project) }));
4283
4283
  }
4284
4284
  };
4285
4285
  const rampTarget = (id) => {
4286
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, project(), id);
4286
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, project(), id);
4287
4287
  if (!at) throw new Error(`There is no clip "${id}"; get_video_project lists the clips.`);
4288
4288
  const { clip } = at;
4289
4289
  if (clip.type === "sequence") throw new Error(`Clip "${id}" is a compound clip, which plays its sequence at normal speed; change the speed of the clips inside the sequence instead.`);
@@ -4293,7 +4293,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4293
4293
  };
4294
4294
  const rampOut = (r, id) => {
4295
4295
  const outcome2 = r.outcomes[r.outcomes.length - 1];
4296
- return { clip: clipOut(r.project, id), ...outcome2.rippled ? { rippled: outcome2.rippled } : {}, duration: _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, r.project) };
4296
+ return { clip: clipOut(r.project, id), ...outcome2.rippled ? { rippled: outcome2.rippled } : {}, duration: _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, r.project) };
4297
4297
  };
4298
4298
  const RIPPLE_RAMP = { type: "boolean", description: "Move later material on every sync-locked track by the change in length (default true); false refuses if the clip would overlap the next one." };
4299
4299
  const setSpeedRamp = {
@@ -4324,8 +4324,8 @@ function createVideoEditorToolProvider(controller, options = {}) {
4324
4324
  ),
4325
4325
  annotations: { title: "Ramp the speed", ...WRITE_IDEMPOTENT },
4326
4326
  handler: ({ clip, segments, ripple }) => {
4327
- const edit = _chunkIWSMDQE5cjs.videoSpeedRampEdit.call(void 0, rampTarget(clip), segments, _nullishCoalesce(ripple, () => ( true)));
4328
- return apply(edit, "Speed ramp", (r) => ({ ...rampOut(r, clip), source: Math.round(_chunkIWSMDQE5cjs.videoSpeedRampKeys.call(void 0, segments).source) }));
4327
+ const edit = _chunk4QQZV5Y5cjs.videoSpeedRampEdit.call(void 0, rampTarget(clip), segments, _nullishCoalesce(ripple, () => ( true)));
4328
+ return apply(edit, "Speed ramp", (r) => ({ ...rampOut(r, clip), source: Math.round(_chunk4QQZV5Y5cjs.videoSpeedRampKeys.call(void 0, segments).source) }));
4329
4329
  }
4330
4330
  };
4331
4331
  const addFreeze = {
@@ -4345,8 +4345,8 @@ function createVideoEditorToolProvider(controller, options = {}) {
4345
4345
  handler: ({ clip, at, duration, ripple }) => {
4346
4346
  const c = rampTarget(clip);
4347
4347
  const t = at - c.start;
4348
- if (t < 0 || t > c.duration) throw new Error(`${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, at)} is outside clip "${clip}" (${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, c.start)}\u2013${_chunkIWSMDQE5cjs.formatVideoSeconds.call(void 0, _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c))}); pick a time inside it.`);
4349
- return apply(_chunkIWSMDQE5cjs.videoFreezeFrameEdit.call(void 0, c, t, duration, _nullishCoalesce(ripple, () => ( true))), "Freeze frame", (r) => rampOut(r, clip));
4348
+ if (t < 0 || t > c.duration) throw new Error(`${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, at)} is outside clip "${clip}" (${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, c.start)}\u2013${_chunk4QQZV5Y5cjs.formatVideoSeconds.call(void 0, _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c))}); pick a time inside it.`);
4349
+ return apply(_chunk4QQZV5Y5cjs.videoFreezeFrameEdit.call(void 0, c, t, duration, _nullishCoalesce(ripple, () => ( true))), "Freeze frame", (r) => rampOut(r, clip));
4350
4350
  }
4351
4351
  };
4352
4352
  const removeRamp = {
@@ -4519,7 +4519,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4519
4519
  let from;
4520
4520
  let to;
4521
4521
  if (args.clip !== void 0) {
4522
- const found = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, p, args.clip);
4522
+ const found = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, p, args.clip);
4523
4523
  if (!found) throw new Error(`There is no clip "${args.clip}"; get_video_project lists the clips.`);
4524
4524
  const c = found.clip;
4525
4525
  if (c.type === "sequence") throw new Error(`Clip "${c.id}" is a compound clip; its sound is the mix of its sequence "${c.sequence}", so read the levels of the media in it (list_video_sequences lists its clips and assets).`);
@@ -4529,7 +4529,7 @@ function createVideoEditorToolProvider(controller, options = {}) {
4529
4529
  toSource = (t) => (_nullishCoalesce(c.in, () => ( 0))) + (t - c.start) * speed;
4530
4530
  toOut = (s) => c.start + (s - (_nullishCoalesce(c.in, () => ( 0)))) / speed;
4531
4531
  from = Math.max(c.start, _nullishCoalesce(args.from, () => ( c.start)));
4532
- to = Math.min(_chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c), _nullishCoalesce(args.to, () => ( _chunkIWSMDQE5cjs.videoClipEnd.call(void 0, c))));
4532
+ to = Math.min(_chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c), _nullishCoalesce(args.to, () => ( _chunk4QQZV5Y5cjs.videoClipEnd.call(void 0, c))));
4533
4533
  } else {
4534
4534
  asset = p.assets.find((a) => a.id === args.asset);
4535
4535
  if (!asset) throw new Error(`There is no asset "${args.asset}"; the assets are ${p.assets.map((a) => `"${a.id}"`).join(", ") || "none"}.`);
@@ -4610,11 +4610,11 @@ function createVideoEditorToolProvider(controller, options = {}) {
4610
4610
  annotations: { title: "Measure a frame with scopes", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
4611
4611
  handler: async ({ time, bins, columns }) => {
4612
4612
  const p = project();
4613
- const end = _chunkIWSMDQE5cjs.videoProjectDuration.call(void 0, p);
4613
+ const end = _chunk4QQZV5Y5cjs.videoProjectDuration.call(void 0, p);
4614
4614
  const t = _nullishCoalesce(time, () => ( controller.getState().time));
4615
4615
  if (time !== void 0 && time > end) throw new Error(`Time ${time} ms is past the end of the project (${end} ms).`);
4616
4616
  const pixels = await pixelsAt(t);
4617
- return { time: t, timecode: _chunkIWSMDQE5cjs.formatVideoTimecode.call(void 0, t, p.fps), width: pixels.width, height: pixels.height, ...summarizeVideoScopes(pixels, { bins, columns }) };
4617
+ return { time: t, timecode: _chunk4QQZV5Y5cjs.formatVideoTimecode.call(void 0, t, p.fps), width: pixels.width, height: pixels.height, ...summarizeVideoScopes(pixels, { bins, columns }) };
4618
4618
  }
4619
4619
  };
4620
4620
  const reads = [getProject, listSequences, getFrame, getTranscript, findText, findFillers, findPauses, findGaps, checkProject, renderFrame, getScopes, previewCache, planProxies, exportFfmpeg, exportLoudnessMeasure, exportEdl, audioLevels, findSilences, seek, setPreviewScale];
@@ -4654,7 +4654,7 @@ var KEYS2 = {
4654
4654
  properties: {
4655
4655
  t: { type: "number", description: "Clip-relative time in ms (0 = the clip's start)." },
4656
4656
  v: { type: "number", description: "The control's value at t, within its range from describe_effect." },
4657
- ease: { anyOf: [{ type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_EASE_NAMES] }, { type: "array", items: { type: "number" }, minItems: 4, maxItems: 4 }], description: "How the value moves to the next key: linear (default), hold, ease-in, ease-out, ease-in-out, or CSS cubic-bezier [x1, y1, x2, y2]." }
4657
+ ease: { anyOf: [{ type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_EASE_NAMES] }, { type: "array", items: { type: "number" }, minItems: 4, maxItems: 4 }], description: "How the value moves to the next key: linear (default), hold, ease-in, ease-out, ease-in-out, or CSS cubic-bezier [x1, y1, x2, y2]." }
4658
4658
  },
4659
4659
  required: ["t", "v"],
4660
4660
  additionalProperties: false
@@ -4668,7 +4668,7 @@ function createVideoEffectsToolProvider(controller, options = {}) {
4668
4668
  return controller.readOnlyReason();
4669
4669
  };
4670
4670
  const clipOf = (id) => {
4671
- const at = _chunkIWSMDQE5cjs.findVideoClip.call(void 0, controller.getProject(), id);
4671
+ const at = _chunk4QQZV5Y5cjs.findVideoClip.call(void 0, controller.getProject(), id);
4672
4672
  if (!at) {
4673
4673
  const ids = controller.getProject().tracks.flatMap((t) => t.clips.map((c) => c.id));
4674
4674
  throw new Error(`There is no clip "${id}"; the clips are ${ids.map((c) => `"${c}"`).join(", ") || "none"} (get_video_project lists them).`);
@@ -4681,7 +4681,7 @@ function createVideoEffectsToolProvider(controller, options = {}) {
4681
4681
  const effect = _nullishCoalesce(effects.find((e) => e.id === (_nullishCoalesce(instance, () => ( _optionalChain([r, 'access', _154 => _154.effect, 'optionalAccess', _155 => _155.id]))))), () => ( (r.effect ? { id: r.effect.id, effect: r.effect.effect, role: "clip effect", enabled: r.effect.enabled !== false, values: _nullishCoalesce(r.effect.values, () => ( {})) } : effects[0])));
4682
4682
  return { target, effect, effects, ...extra };
4683
4683
  };
4684
- return _chunkTK53AB4Qcjs.createEffectToolProvider.call(void 0, {
4684
+ return _chunkFHYDQOPCcjs.createEffectToolProvider.call(void 0, {
4685
4685
  id: _nullishCoalesce(options.id, () => ( "video-effects")),
4686
4686
  namespace: options.namespace,
4687
4687
  target: { noun: "clip", id: 'A clip id from get_video_project (e.g. "c1").' },
@@ -4736,7 +4736,7 @@ function createVideoEffectsToolProvider(controller, options = {}) {
4736
4736
  duration: { type: "number", exclusiveMinimum: 0, description: "Length in ms (default: the effect's own length, else 5000)." },
4737
4737
  values: ctx.valuesSchema("Control values over the effect's defaults", true),
4738
4738
  name: { type: "string", minLength: 1, description: "A label for the clip (default: the effect's name)." },
4739
- mode: { type: "string", enum: [..._chunkIWSMDQE5cjs.VIDEO_PLACEMENT_MODES], description: "What to do with clips already there: refuse (default), overwrite or insert." }
4739
+ mode: { type: "string", enum: [..._chunk4QQZV5Y5cjs.VIDEO_PLACEMENT_MODES], description: "What to do with clips already there: refuse (default), overwrite or insert." }
4740
4740
  },
4741
4741
  required: ["track", "effect"],
4742
4742
  additionalProperties: false
@@ -4796,7 +4796,7 @@ function createVideoEffectsToolProvider(controller, options = {}) {
4796
4796
  const clip = clipOf(args.clip);
4797
4797
  if (clip.type !== "effect") throw new Error(`Clip "${args.clip}" is not an effect clip; give the id of one of its effects (list_applied_effects).`);
4798
4798
  const was = _optionalChain([clip, 'access', _156 => _156.values, 'optionalAccess', _157 => _157[args.control]]);
4799
- const plain = keys === null ? _chunkIWSMDQE5cjs.isVideoKeyframes.call(void 0, was) ? _optionalChain([was, 'access', _158 => _158.keys, 'access', _159 => _159[0], 'optionalAccess', _160 => _160.v]) : was : { keys: [...keys].sort((a, b) => a.t - b.t) };
4799
+ const plain = keys === null ? _chunk4QQZV5Y5cjs.isVideoKeyframes.call(void 0, was) ? _optionalChain([was, 'access', _158 => _158.keys, 'access', _159 => _159[0], 'optionalAccess', _160 => _160.v]) : was : { keys: [...keys].sort((a, b) => a.t - b.t) };
4800
4800
  if (plain === void 0) throw new Error(`"${args.control}" has no value to keep; give keys instead.`);
4801
4801
  r = await controller.updateEffectValues(args.clip, "generator", { [args.control]: plain });
4802
4802
  } else r = await controller.setClipEffectKeyframes(args.clip, args.effect, args.control, keys);
@@ -5059,5 +5059,5 @@ function createVideoEffectsToolProvider(controller, options = {}) {
5059
5059
 
5060
5060
 
5061
5061
 
5062
- exports.VIDEO_BLEND_MODES = _chunkIWSMDQE5cjs.VIDEO_BLEND_MODES; exports.VIDEO_BLEND_MODE_LABELS = VIDEO_BLEND_MODE_LABELS; exports.VIDEO_CLIP_ANIMATION_DURATION = _chunkIWSMDQE5cjs.VIDEO_CLIP_ANIMATION_DURATION; exports.VIDEO_CLIP_ANIMATION_EFFECTS = _chunkIWSMDQE5cjs.VIDEO_CLIP_ANIMATION_EFFECTS; exports.VIDEO_CLIP_ANIMATION_LABELS = VIDEO_CLIP_ANIMATION_LABELS; exports.VIDEO_CLIP_TYPES = _chunkIWSMDQE5cjs.VIDEO_CLIP_TYPES; exports.VIDEO_DEFAULT_FILLERS = VIDEO_DEFAULT_FILLERS; exports.VIDEO_DEFAULT_STILL_DURATION = VIDEO_DEFAULT_STILL_DURATION; exports.VIDEO_DEFAULT_TITLE_DURATION = VIDEO_DEFAULT_TITLE_DURATION; exports.VIDEO_EASE_NAMES = _chunkIWSMDQE5cjs.VIDEO_EASE_NAMES; exports.VIDEO_EDIT_OPS = VIDEO_EDIT_OPS; exports.VIDEO_EFFECT_PLACES = _chunkIWSMDQE5cjs.VIDEO_EFFECT_PLACES; exports.VIDEO_FADE_CURVES = _chunkIWSMDQE5cjs.VIDEO_FADE_CURVES; exports.VIDEO_FADE_CURVE_LABELS = VIDEO_FADE_CURVE_LABELS; exports.VIDEO_FITS = _chunkIWSMDQE5cjs.VIDEO_FITS; exports.VIDEO_GRADE_CONTROLS = _chunkIWSMDQE5cjs.VIDEO_GRADE_CONTROLS; exports.VIDEO_GRADE_PRESETS = _chunkIWSMDQE5cjs.VIDEO_GRADE_PRESETS; exports.VIDEO_GRADE_PRESET_NAMES = _chunkIWSMDQE5cjs.VIDEO_GRADE_PRESET_NAMES; exports.VIDEO_ISSUE_CODES = VIDEO_ISSUE_CODES; exports.VIDEO_KEYFRAME_LIMITS = _chunkIWSMDQE5cjs.VIDEO_KEYFRAME_LIMITS; exports.VIDEO_KEYFRAME_PROPERTIES = _chunkIWSMDQE5cjs.VIDEO_KEYFRAME_PROPERTIES; exports.VIDEO_LUT_MAX_SIZE = _chunkIWSMDQE5cjs.VIDEO_LUT_MAX_SIZE; exports.VIDEO_PEAK_BLOCK = VIDEO_PEAK_BLOCK; exports.VIDEO_PLACEMENT_MODES = _chunkIWSMDQE5cjs.VIDEO_PLACEMENT_MODES; exports.VIDEO_PREVIEW_SCALE_OPTIONS = VIDEO_PREVIEW_SCALE_OPTIONS; exports.VIDEO_PROXY_SCALES = VIDEO_PROXY_SCALES; exports.VIDEO_SCOPE_KINDS = VIDEO_SCOPE_KINDS; exports.VIDEO_TIME_EPSILON = _chunkIWSMDQE5cjs.VIDEO_TIME_EPSILON; exports.VIDEO_TRANSFORM_PROPERTIES = _chunkIWSMDQE5cjs.VIDEO_TRANSFORM_PROPERTIES; exports.VIDEO_TRANSITION_LABELS = VIDEO_TRANSITION_LABELS; exports.VIDEO_TRANSITION_TYPES = _chunkIWSMDQE5cjs.VIDEO_TRANSITION_TYPES; exports.VIDEO_VECTORSCOPE_TARGETS = VIDEO_VECTORSCOPE_TARGETS; exports.VIDEO_WIPE_DIRECTIONS = _chunkIWSMDQE5cjs.VIDEO_WIPE_DIRECTIONS; exports.VideoAudioPeaksCache = VideoAudioPeaksCache; exports.VideoEditorController = VideoEditorController; exports.VideoEffectsEngine = _chunkIWSMDQE5cjs.VideoEffectsEngine; exports.VideoFrameCache = VideoFrameCache; exports.VideoLutCache = _chunkIWSMDQE5cjs.VideoLutCache; exports.VideoPreviewEngine = VideoPreviewEngine; exports.VideoPreviewPixels = VideoPreviewPixels; exports.allVideoClipIds = _chunkIWSMDQE5cjs.allVideoClipIds; exports.allVideoTracks = _chunkIWSMDQE5cjs.allVideoTracks; exports.applyVideoEdits = applyVideoEdits; exports.applyVideoGrade = _chunkIWSMDQE5cjs.applyVideoGrade; exports.applyVideoLut = _chunkIWSMDQE5cjs.applyVideoLut; exports.applyVideoLutToPixels = _chunkIWSMDQE5cjs.applyVideoLutToPixels; exports.buildVideoAudioPeaks = buildVideoAudioPeaks; exports.checkVideoEffectPlace = _chunkIWSMDQE5cjs.checkVideoEffectPlace; exports.checkVideoEffectValues = _chunkIWSMDQE5cjs.checkVideoEffectValues; exports.checkVideoProject = checkVideoProject; exports.checkVideoTimeRemap = _chunkIWSMDQE5cjs.checkVideoTimeRemap; exports.createVideoEditorToolProvider = createVideoEditorToolProvider; exports.createVideoEffectsToolProvider = createVideoEffectsToolProvider; exports.createVideoElementDecoder = createVideoElementDecoder; exports.createVideoProject = createVideoProject; exports.decodeVideoAudioPeaks = decodeVideoAudioPeaks; exports.describeVideoProject = describeVideoProject; exports.describeVideoSequence = describeVideoSequence; exports.drawVideoFrame = _chunkIWSMDQE5cjs.drawVideoFrame; exports.ffmpegFilterValue = _chunkIWSMDQE5cjs.ffmpegFilterValue; exports.findVideoAudioSilences = findVideoAudioSilences; exports.findVideoClip = _chunkIWSMDQE5cjs.findVideoClip; exports.findVideoFillers = findVideoFillers; exports.findVideoGaps = _chunkIWSMDQE5cjs.findVideoGaps; exports.findVideoSequenceClip = _chunkIWSMDQE5cjs.findVideoSequenceClip; exports.findVideoSequenceCycle = _chunkIWSMDQE5cjs.findVideoSequenceCycle; exports.findVideoTranscriptPauses = findVideoTranscriptPauses; exports.findVideoTranscriptText = findVideoTranscriptText; exports.formatVideoSeconds = _chunkIWSMDQE5cjs.formatVideoSeconds; exports.formatVideoTimecode = _chunkIWSMDQE5cjs.formatVideoTimecode; exports.formatVideoTimecodeFrames = _chunkIWSMDQE5cjs.formatVideoTimecodeFrames; exports.isVideoDropFrameRate = _chunkIWSMDQE5cjs.isVideoDropFrameRate; exports.isVideoKeyframes = _chunkIWSMDQE5cjs.isVideoKeyframes; exports.mergeVideoRanges = mergeVideoRanges; exports.mixEffectPixels = _chunkIWSMDQE5cjs.mixEffectPixels; exports.nextFreeVideoSlot = _chunkIWSMDQE5cjs.nextFreeVideoSlot; exports.normalizeVideoGrade = _chunkIWSMDQE5cjs.normalizeVideoGrade; exports.normalizeVideoGradeLut = _chunkIWSMDQE5cjs.normalizeVideoGradeLut; exports.normalizeVideoWord = normalizeVideoWord; exports.overEffectPixels = _chunkIWSMDQE5cjs.overEffectPixels; exports.parseVideoAnimatable = parseVideoAnimatable; exports.parseVideoAsset = parseVideoAsset; exports.parseVideoAssetProxies = parseVideoAssetProxies; exports.parseVideoClip = parseVideoClip; exports.parseVideoClipAnimation = parseVideoClipAnimation; exports.parseVideoClipEffects = parseVideoClipEffects; exports.parseVideoCubeLut = _chunkIWSMDQE5cjs.parseVideoCubeLut; exports.parseVideoEffectRef = parseVideoEffectRef; exports.parseVideoEffectValues = parseVideoEffectValues; exports.parseVideoGrade = parseVideoGrade; exports.parseVideoGradeLut = parseVideoGradeLut; exports.parseVideoKeyframes = parseVideoKeyframes; exports.parseVideoLoudnessMeasurement = _chunkIWSMDQE5cjs.parseVideoLoudnessMeasurement; exports.parseVideoMarker = parseVideoMarker; exports.parseVideoPreviewScale = parseVideoPreviewScale; exports.parseVideoProject = parseVideoProject; exports.parseVideoSequence = parseVideoSequence; exports.parseVideoTimeRemap = parseVideoTimeRemap; exports.parseVideoTrack = parseVideoTrack; exports.parseVideoTranscript = parseVideoTranscript; exports.parseVideoTranscriptWords = parseVideoTranscriptWords; exports.parseVideoTransform = parseVideoTransform; exports.parseVideoTransition = parseVideoTransition; exports.placeVideoRect = _chunkIWSMDQE5cjs.placeVideoRect; exports.planVideoClipDrag = planVideoClipDrag; exports.planVideoPrefetch = planVideoPrefetch; exports.probeVideoMedia = probeVideoMedia; exports.readVideoScopesPanel = readVideoScopesPanel; exports.removeVideoKey = _chunkIWSMDQE5cjs.removeVideoKey; exports.renderVideoFrameExact = _chunkIWSMDQE5cjs.renderVideoFrameExact; exports.resolveVideoPreviewScale = resolveVideoPreviewScale; exports.retimeVideoAnimatable = _chunkIWSMDQE5cjs.retimeVideoAnimatable; exports.setVideoKey = _chunkIWSMDQE5cjs.setVideoKey; exports.snapToVideoFrame = _chunkIWSMDQE5cjs.snapToVideoFrame; exports.snapVideoTime = _chunkIWSMDQE5cjs.snapVideoTime; exports.sortVideoKeys = _chunkIWSMDQE5cjs.sortVideoKeys; exports.sortedVideoClips = _chunkIWSMDQE5cjs.sortedVideoClips; exports.splitVideoAnimatable = _chunkIWSMDQE5cjs.splitVideoAnimatable; exports.summarizeVideoScopes = summarizeVideoScopes; exports.toVideoEdl = _chunkIWSMDQE5cjs.toVideoEdl; exports.toVideoFfmpeg = _chunkIWSMDQE5cjs.toVideoFfmpeg; exports.toVideoLoudnessMeasure = _chunkIWSMDQE5cjs.toVideoLoudnessMeasure; exports.videoAssetDropEdit = videoAssetDropEdit; exports.videoAssetHasSound = _chunkIWSMDQE5cjs.videoAssetHasSound; exports.videoAssetKindOf = videoAssetKindOf; exports.videoAssetMap = _chunkIWSMDQE5cjs.videoAssetMap; exports.videoAssetProxy = videoAssetProxy; exports.videoAudioLevels = videoAudioLevels; exports.videoAudioPeakRange = videoAudioPeakRange; exports.videoAudioPeakSpans = videoAudioPeakSpans; exports.videoAudioPeaksDuration = videoAudioPeaksDuration; exports.videoCacheEvictions = videoCacheEvictions; exports.videoChroma = videoChroma; exports.videoClipAfter = _chunkIWSMDQE5cjs.videoClipAfter; exports.videoClipAnimated = _chunkIWSMDQE5cjs.videoClipAnimated; exports.videoClipAnimationProperties = _chunkIWSMDQE5cjs.videoClipAnimationProperties; exports.videoClipAnimationSpans = _chunkIWSMDQE5cjs.videoClipAnimationSpans; exports.videoClipAppliedEffects = videoClipAppliedEffects; exports.videoClipBefore = _chunkIWSMDQE5cjs.videoClipBefore; exports.videoClipEffectUses = _chunkIWSMDQE5cjs.videoClipEffectUses; exports.videoClipEnd = _chunkIWSMDQE5cjs.videoClipEnd; exports.videoClipHandles = _chunkIWSMDQE5cjs.videoClipHandles; exports.videoClipKeyframes = videoClipKeyframes; exports.videoClipLabel = videoClipLabel; exports.videoClipOverhang = _chunkIWSMDQE5cjs.videoClipOverhang; exports.videoClipShowsWaveform = videoClipShowsWaveform; exports.videoClipSoundGain = _chunkIWSMDQE5cjs.videoClipSoundGain; exports.videoClipSourceRange = _chunkIWSMDQE5cjs.videoClipSourceRange; exports.videoClipSourceTime = _chunkIWSMDQE5cjs.videoClipSourceTime; exports.videoClipSpeed = _chunkIWSMDQE5cjs.videoClipSpeed; exports.videoClipSpeedAt = _chunkIWSMDQE5cjs.videoClipSpeedAt; exports.videoClipTint = videoClipTint; exports.videoClipWaveform = videoClipWaveform; exports.videoClipWaveformPath = videoClipWaveformPath; exports.videoClipsAt = _chunkIWSMDQE5cjs.videoClipsAt; exports.videoContactSheetSvg = _chunkIWSMDQE5cjs.videoContactSheetSvg; exports.videoDragLabel = videoDragLabel; exports.videoDropTracks = videoDropTracks; exports.videoEaseBezier = _chunkIWSMDQE5cjs.videoEaseBezier; exports.videoEaseProgress = _chunkIWSMDQE5cjs.videoEaseProgress; exports.videoEffectFrameTime = _chunkIWSMDQE5cjs.videoEffectFrameTime; exports.videoEffectLayerKey = _chunkIWSMDQE5cjs.videoEffectLayerKey; exports.videoEffectValuesAt = _chunkIWSMDQE5cjs.videoEffectValuesAt; exports.videoExposureNotes = videoExposureNotes; exports.videoExposureStats = videoExposureStats; exports.videoFadeCurveGain = _chunkIWSMDQE5cjs.videoFadeCurveGain; exports.videoFfmpegUnsupportedEffects = _chunkIWSMDQE5cjs.videoFfmpegUnsupportedEffects; exports.videoFrameAt = _chunkIWSMDQE5cjs.videoFrameAt; exports.videoFrameCacheKey = videoFrameCacheKey; exports.videoFrameDuration = _chunkIWSMDQE5cjs.videoFrameDuration; exports.videoFrameLeafLayers = _chunkIWSMDQE5cjs.videoFrameLeafLayers; exports.videoFrameRequestsAt = videoFrameRequestsAt; exports.videoFrameToSvg = _chunkIWSMDQE5cjs.videoFrameToSvg; exports.videoFrames = _chunkIWSMDQE5cjs.videoFrames; exports.videoFreezeFrameEdit = _chunkIWSMDQE5cjs.videoFreezeFrameEdit; exports.videoGradeCssFilter = _chunkIWSMDQE5cjs.videoGradeCssFilter; exports.videoGradeFfmpegFilters = _chunkIWSMDQE5cjs.videoGradeFfmpegFilters; exports.videoGradeGainsFilterId = _chunkIWSMDQE5cjs.videoGradeGainsFilterId; exports.videoGradeLook = _chunkIWSMDQE5cjs.videoGradeLook; exports.videoGradePreset = _chunkIWSMDQE5cjs.videoGradePreset; exports.videoGradeStepMatrix = _chunkIWSMDQE5cjs.videoGradeStepMatrix; exports.videoGradeStepSvgValues = _chunkIWSMDQE5cjs.videoGradeStepSvgValues; exports.videoGradeSteps = _chunkIWSMDQE5cjs.videoGradeSteps; exports.videoGradeSvgDefs = _chunkIWSMDQE5cjs.videoGradeSvgDefs; exports.videoGradeSvgFilter = _chunkIWSMDQE5cjs.videoGradeSvgFilter; exports.videoHistogram = videoHistogram; exports.videoHistogramImage = videoHistogramImage; exports.videoHourFrames = _chunkIWSMDQE5cjs.videoHourFrames; exports.videoIrisRadius = _chunkIWSMDQE5cjs.videoIrisRadius; exports.videoIssueKey = videoIssueKey; exports.videoKeyframeBreakpoints = _chunkIWSMDQE5cjs.videoKeyframeBreakpoints; exports.videoKeyframeFfmpegExpr = _chunkIWSMDQE5cjs.videoKeyframeFfmpegExpr; exports.videoKeyframeRows = videoKeyframeRows; exports.videoKeyframeToggleEdit = videoKeyframeToggleEdit; exports.videoKeyframeValueEdit = videoKeyframeValueEdit; exports.videoKeysOf = _chunkIWSMDQE5cjs.videoKeysOf; exports.videoLayersUseEffects = _chunkIWSMDQE5cjs.videoLayersUseEffects; exports.videoLayersWithoutTransitionEffects = _chunkIWSMDQE5cjs.videoLayersWithoutTransitionEffects; exports.videoLuma = videoLuma; exports.videoLumaWaveform = videoLumaWaveform; exports.videoLutEdits = videoLutEdits; exports.videoLutFromFunction = _chunkIWSMDQE5cjs.videoLutFromFunction; exports.videoLutSvgApproximation = _chunkIWSMDQE5cjs.videoLutSvgApproximation; exports.videoLutSvgPrimitives = _chunkIWSMDQE5cjs.videoLutSvgPrimitives; exports.videoLutToCube = _chunkIWSMDQE5cjs.videoLutToCube; exports.videoOverlap = _chunkIWSMDQE5cjs.videoOverlap; exports.videoPeakDb = videoPeakDb; exports.videoPreviewSrc = videoPreviewSrc; exports.videoProjectDuration = _chunkIWSMDQE5cjs.videoProjectDuration; exports.videoProjectEffects = _chunkIWSMDQE5cjs.videoProjectEffects; exports.videoProjectHasProxies = videoProjectHasProxies; exports.videoProjectSvg = _chunkIWSMDQE5cjs.videoProjectSvg; exports.videoProxyFfmpeg = videoProxyFfmpeg; exports.videoProxyName = videoProxyName; exports.videoProxyPlan = videoProxyPlan; exports.videoRemoveRangesEdits = videoRemoveRangesEdits; exports.videoRulerTicks = videoRulerTicks; exports.videoScopeImage = videoScopeImage; exports.videoSequenceChildren = _chunkIWSMDQE5cjs.videoSequenceChildren; exports.videoSequenceDuration = _chunkIWSMDQE5cjs.videoSequenceDuration; exports.videoSequenceMap = _chunkIWSMDQE5cjs.videoSequenceMap; exports.videoShellQuote = _chunkIWSMDQE5cjs.videoShellQuote; exports.videoSlowMotionRamp = _chunkIWSMDQE5cjs.videoSlowMotionRamp; exports.videoSnapPoints = _chunkIWSMDQE5cjs.videoSnapPoints; exports.videoSourceFrame = videoSourceFrame; exports.videoSourceFrameTime = videoSourceFrameTime; exports.videoSpeedRampEdit = _chunkIWSMDQE5cjs.videoSpeedRampEdit; exports.videoSpeedRampKeys = _chunkIWSMDQE5cjs.videoSpeedRampKeys; exports.videoTextStyle = _chunkIWSMDQE5cjs.videoTextStyle; exports.videoTimeRemapBreakpoints = _chunkIWSMDQE5cjs.videoTimeRemapBreakpoints; exports.videoTimeRemapSpan = _chunkIWSMDQE5cjs.videoTimeRemapSpan; exports.videoTimecodeFrames = _chunkIWSMDQE5cjs.videoTimecodeFrames; exports.videoTimelineTranscript = videoTimelineTranscript; exports.videoTitleFrame = _chunkIWSMDQE5cjs.videoTitleFrame; exports.videoTrackSyncLocked = _chunkIWSMDQE5cjs.videoTrackSyncLocked; exports.videoTranscriptEdit = videoTranscriptEdit; exports.videoTranscriptTrack = videoTranscriptTrack; exports.videoTransformAt = _chunkIWSMDQE5cjs.videoTransformAt; exports.videoTransitionAudioCurve = _chunkIWSMDQE5cjs.videoTransitionAudioCurve; exports.videoTransitionEase = _chunkIWSMDQE5cjs.videoTransitionEase; exports.videoTransitionHasDirection = videoTransitionHasDirection; exports.videoValueAt = _chunkIWSMDQE5cjs.videoValueAt; exports.videoVectorscope = videoVectorscope; exports.videoVectorscopeAngle = videoVectorscopeAngle; exports.videoVectorscopeImage = videoVectorscopeImage; exports.videoVectorscopePoint = videoVectorscopePoint; exports.videoWaveformImage = videoWaveformImage; exports.videoWaveformPath = videoWaveformPath; exports.videoWipeRect = _chunkIWSMDQE5cjs.videoWipeRect; exports.videoWordAt = videoWordAt; exports.videoWordsRange = videoWordsRange;
5062
+ exports.VIDEO_BLEND_MODES = _chunk4QQZV5Y5cjs.VIDEO_BLEND_MODES; exports.VIDEO_BLEND_MODE_LABELS = VIDEO_BLEND_MODE_LABELS; exports.VIDEO_CLIP_ANIMATION_DURATION = _chunk4QQZV5Y5cjs.VIDEO_CLIP_ANIMATION_DURATION; exports.VIDEO_CLIP_ANIMATION_EFFECTS = _chunk4QQZV5Y5cjs.VIDEO_CLIP_ANIMATION_EFFECTS; exports.VIDEO_CLIP_ANIMATION_LABELS = VIDEO_CLIP_ANIMATION_LABELS; exports.VIDEO_CLIP_TYPES = _chunk4QQZV5Y5cjs.VIDEO_CLIP_TYPES; exports.VIDEO_DEFAULT_FILLERS = VIDEO_DEFAULT_FILLERS; exports.VIDEO_DEFAULT_STILL_DURATION = VIDEO_DEFAULT_STILL_DURATION; exports.VIDEO_DEFAULT_TITLE_DURATION = VIDEO_DEFAULT_TITLE_DURATION; exports.VIDEO_EASE_NAMES = _chunk4QQZV5Y5cjs.VIDEO_EASE_NAMES; exports.VIDEO_EDIT_OPS = VIDEO_EDIT_OPS; exports.VIDEO_EFFECT_PLACES = _chunk4QQZV5Y5cjs.VIDEO_EFFECT_PLACES; exports.VIDEO_FADE_CURVES = _chunk4QQZV5Y5cjs.VIDEO_FADE_CURVES; exports.VIDEO_FADE_CURVE_LABELS = VIDEO_FADE_CURVE_LABELS; exports.VIDEO_FITS = _chunk4QQZV5Y5cjs.VIDEO_FITS; exports.VIDEO_GRADE_CONTROLS = _chunk4QQZV5Y5cjs.VIDEO_GRADE_CONTROLS; exports.VIDEO_GRADE_PRESETS = _chunk4QQZV5Y5cjs.VIDEO_GRADE_PRESETS; exports.VIDEO_GRADE_PRESET_NAMES = _chunk4QQZV5Y5cjs.VIDEO_GRADE_PRESET_NAMES; exports.VIDEO_ISSUE_CODES = VIDEO_ISSUE_CODES; exports.VIDEO_KEYFRAME_LIMITS = _chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_LIMITS; exports.VIDEO_KEYFRAME_PROPERTIES = _chunk4QQZV5Y5cjs.VIDEO_KEYFRAME_PROPERTIES; exports.VIDEO_LUT_MAX_SIZE = _chunk4QQZV5Y5cjs.VIDEO_LUT_MAX_SIZE; exports.VIDEO_PEAK_BLOCK = VIDEO_PEAK_BLOCK; exports.VIDEO_PLACEMENT_MODES = _chunk4QQZV5Y5cjs.VIDEO_PLACEMENT_MODES; exports.VIDEO_PREVIEW_SCALE_OPTIONS = VIDEO_PREVIEW_SCALE_OPTIONS; exports.VIDEO_PROXY_SCALES = VIDEO_PROXY_SCALES; exports.VIDEO_SCOPE_KINDS = VIDEO_SCOPE_KINDS; exports.VIDEO_TIME_EPSILON = _chunk4QQZV5Y5cjs.VIDEO_TIME_EPSILON; exports.VIDEO_TRANSFORM_PROPERTIES = _chunk4QQZV5Y5cjs.VIDEO_TRANSFORM_PROPERTIES; exports.VIDEO_TRANSITION_LABELS = VIDEO_TRANSITION_LABELS; exports.VIDEO_TRANSITION_TYPES = _chunk4QQZV5Y5cjs.VIDEO_TRANSITION_TYPES; exports.VIDEO_VECTORSCOPE_TARGETS = VIDEO_VECTORSCOPE_TARGETS; exports.VIDEO_WIPE_DIRECTIONS = _chunk4QQZV5Y5cjs.VIDEO_WIPE_DIRECTIONS; exports.VideoAudioPeaksCache = VideoAudioPeaksCache; exports.VideoEditorController = VideoEditorController; exports.VideoEffectsEngine = _chunk4QQZV5Y5cjs.VideoEffectsEngine; exports.VideoFrameCache = VideoFrameCache; exports.VideoLutCache = _chunk4QQZV5Y5cjs.VideoLutCache; exports.VideoPreviewEngine = VideoPreviewEngine; exports.VideoPreviewPixels = VideoPreviewPixels; exports.allVideoClipIds = _chunk4QQZV5Y5cjs.allVideoClipIds; exports.allVideoTracks = _chunk4QQZV5Y5cjs.allVideoTracks; exports.applyVideoEdits = applyVideoEdits; exports.applyVideoGrade = _chunk4QQZV5Y5cjs.applyVideoGrade; exports.applyVideoLut = _chunk4QQZV5Y5cjs.applyVideoLut; exports.applyVideoLutToPixels = _chunk4QQZV5Y5cjs.applyVideoLutToPixels; exports.buildVideoAudioPeaks = buildVideoAudioPeaks; exports.checkVideoEffectPlace = _chunk4QQZV5Y5cjs.checkVideoEffectPlace; exports.checkVideoEffectValues = _chunk4QQZV5Y5cjs.checkVideoEffectValues; exports.checkVideoProject = checkVideoProject; exports.checkVideoTimeRemap = _chunk4QQZV5Y5cjs.checkVideoTimeRemap; exports.createVideoEditorToolProvider = createVideoEditorToolProvider; exports.createVideoEffectsToolProvider = createVideoEffectsToolProvider; exports.createVideoElementDecoder = createVideoElementDecoder; exports.createVideoProject = createVideoProject; exports.decodeVideoAudioPeaks = decodeVideoAudioPeaks; exports.describeVideoProject = describeVideoProject; exports.describeVideoSequence = describeVideoSequence; exports.drawVideoFrame = _chunk4QQZV5Y5cjs.drawVideoFrame; exports.ffmpegFilterValue = _chunk4QQZV5Y5cjs.ffmpegFilterValue; exports.findVideoAudioSilences = findVideoAudioSilences; exports.findVideoClip = _chunk4QQZV5Y5cjs.findVideoClip; exports.findVideoFillers = findVideoFillers; exports.findVideoGaps = _chunk4QQZV5Y5cjs.findVideoGaps; exports.findVideoSequenceClip = _chunk4QQZV5Y5cjs.findVideoSequenceClip; exports.findVideoSequenceCycle = _chunk4QQZV5Y5cjs.findVideoSequenceCycle; exports.findVideoTranscriptPauses = findVideoTranscriptPauses; exports.findVideoTranscriptText = findVideoTranscriptText; exports.formatVideoSeconds = _chunk4QQZV5Y5cjs.formatVideoSeconds; exports.formatVideoTimecode = _chunk4QQZV5Y5cjs.formatVideoTimecode; exports.formatVideoTimecodeFrames = _chunk4QQZV5Y5cjs.formatVideoTimecodeFrames; exports.isVideoDropFrameRate = _chunk4QQZV5Y5cjs.isVideoDropFrameRate; exports.isVideoKeyframes = _chunk4QQZV5Y5cjs.isVideoKeyframes; exports.mergeVideoRanges = mergeVideoRanges; exports.mixEffectPixels = _chunk4QQZV5Y5cjs.mixEffectPixels; exports.nextFreeVideoSlot = _chunk4QQZV5Y5cjs.nextFreeVideoSlot; exports.normalizeVideoGrade = _chunk4QQZV5Y5cjs.normalizeVideoGrade; exports.normalizeVideoGradeLut = _chunk4QQZV5Y5cjs.normalizeVideoGradeLut; exports.normalizeVideoWord = normalizeVideoWord; exports.overEffectPixels = _chunk4QQZV5Y5cjs.overEffectPixels; exports.parseVideoAnimatable = parseVideoAnimatable; exports.parseVideoAsset = parseVideoAsset; exports.parseVideoAssetProxies = parseVideoAssetProxies; exports.parseVideoClip = parseVideoClip; exports.parseVideoClipAnimation = parseVideoClipAnimation; exports.parseVideoClipEffects = parseVideoClipEffects; exports.parseVideoCubeLut = _chunk4QQZV5Y5cjs.parseVideoCubeLut; exports.parseVideoEffectRef = parseVideoEffectRef; exports.parseVideoEffectValues = parseVideoEffectValues; exports.parseVideoGrade = parseVideoGrade; exports.parseVideoGradeLut = parseVideoGradeLut; exports.parseVideoKeyframes = parseVideoKeyframes; exports.parseVideoLoudnessMeasurement = _chunk4QQZV5Y5cjs.parseVideoLoudnessMeasurement; exports.parseVideoMarker = parseVideoMarker; exports.parseVideoPreviewScale = parseVideoPreviewScale; exports.parseVideoProject = parseVideoProject; exports.parseVideoSequence = parseVideoSequence; exports.parseVideoTimeRemap = parseVideoTimeRemap; exports.parseVideoTrack = parseVideoTrack; exports.parseVideoTranscript = parseVideoTranscript; exports.parseVideoTranscriptWords = parseVideoTranscriptWords; exports.parseVideoTransform = parseVideoTransform; exports.parseVideoTransition = parseVideoTransition; exports.placeVideoRect = _chunk4QQZV5Y5cjs.placeVideoRect; exports.planVideoClipDrag = planVideoClipDrag; exports.planVideoPrefetch = planVideoPrefetch; exports.probeVideoMedia = probeVideoMedia; exports.readVideoScopesPanel = readVideoScopesPanel; exports.removeVideoKey = _chunk4QQZV5Y5cjs.removeVideoKey; exports.renderVideoFrameExact = _chunk4QQZV5Y5cjs.renderVideoFrameExact; exports.resolveVideoPreviewScale = resolveVideoPreviewScale; exports.retimeVideoAnimatable = _chunk4QQZV5Y5cjs.retimeVideoAnimatable; exports.setVideoKey = _chunk4QQZV5Y5cjs.setVideoKey; exports.snapToVideoFrame = _chunk4QQZV5Y5cjs.snapToVideoFrame; exports.snapVideoTime = _chunk4QQZV5Y5cjs.snapVideoTime; exports.sortVideoKeys = _chunk4QQZV5Y5cjs.sortVideoKeys; exports.sortedVideoClips = _chunk4QQZV5Y5cjs.sortedVideoClips; exports.splitVideoAnimatable = _chunk4QQZV5Y5cjs.splitVideoAnimatable; exports.summarizeVideoScopes = summarizeVideoScopes; exports.toVideoEdl = _chunk4QQZV5Y5cjs.toVideoEdl; exports.toVideoFfmpeg = _chunk4QQZV5Y5cjs.toVideoFfmpeg; exports.toVideoLoudnessMeasure = _chunk4QQZV5Y5cjs.toVideoLoudnessMeasure; exports.videoAssetDropEdit = videoAssetDropEdit; exports.videoAssetHasSound = _chunk4QQZV5Y5cjs.videoAssetHasSound; exports.videoAssetKindOf = videoAssetKindOf; exports.videoAssetMap = _chunk4QQZV5Y5cjs.videoAssetMap; exports.videoAssetProxy = videoAssetProxy; exports.videoAudioLevels = videoAudioLevels; exports.videoAudioPeakRange = videoAudioPeakRange; exports.videoAudioPeakSpans = videoAudioPeakSpans; exports.videoAudioPeaksDuration = videoAudioPeaksDuration; exports.videoCacheEvictions = videoCacheEvictions; exports.videoChroma = videoChroma; exports.videoClipAfter = _chunk4QQZV5Y5cjs.videoClipAfter; exports.videoClipAnimated = _chunk4QQZV5Y5cjs.videoClipAnimated; exports.videoClipAnimationProperties = _chunk4QQZV5Y5cjs.videoClipAnimationProperties; exports.videoClipAnimationSpans = _chunk4QQZV5Y5cjs.videoClipAnimationSpans; exports.videoClipAppliedEffects = videoClipAppliedEffects; exports.videoClipBefore = _chunk4QQZV5Y5cjs.videoClipBefore; exports.videoClipEffectUses = _chunk4QQZV5Y5cjs.videoClipEffectUses; exports.videoClipEnd = _chunk4QQZV5Y5cjs.videoClipEnd; exports.videoClipHandles = _chunk4QQZV5Y5cjs.videoClipHandles; exports.videoClipKeyframes = videoClipKeyframes; exports.videoClipLabel = videoClipLabel; exports.videoClipOverhang = _chunk4QQZV5Y5cjs.videoClipOverhang; exports.videoClipShowsWaveform = videoClipShowsWaveform; exports.videoClipSoundGain = _chunk4QQZV5Y5cjs.videoClipSoundGain; exports.videoClipSourceRange = _chunk4QQZV5Y5cjs.videoClipSourceRange; exports.videoClipSourceTime = _chunk4QQZV5Y5cjs.videoClipSourceTime; exports.videoClipSpeed = _chunk4QQZV5Y5cjs.videoClipSpeed; exports.videoClipSpeedAt = _chunk4QQZV5Y5cjs.videoClipSpeedAt; exports.videoClipTint = videoClipTint; exports.videoClipWaveform = videoClipWaveform; exports.videoClipWaveformPath = videoClipWaveformPath; exports.videoClipsAt = _chunk4QQZV5Y5cjs.videoClipsAt; exports.videoContactSheetSvg = _chunk4QQZV5Y5cjs.videoContactSheetSvg; exports.videoDragLabel = videoDragLabel; exports.videoDropTracks = videoDropTracks; exports.videoEaseBezier = _chunk4QQZV5Y5cjs.videoEaseBezier; exports.videoEaseProgress = _chunk4QQZV5Y5cjs.videoEaseProgress; exports.videoEffectFrameTime = _chunk4QQZV5Y5cjs.videoEffectFrameTime; exports.videoEffectLayerKey = _chunk4QQZV5Y5cjs.videoEffectLayerKey; exports.videoEffectValuesAt = _chunk4QQZV5Y5cjs.videoEffectValuesAt; exports.videoExposureNotes = videoExposureNotes; exports.videoExposureStats = videoExposureStats; exports.videoFadeCurveGain = _chunk4QQZV5Y5cjs.videoFadeCurveGain; exports.videoFfmpegUnsupportedEffects = _chunk4QQZV5Y5cjs.videoFfmpegUnsupportedEffects; exports.videoFrameAt = _chunk4QQZV5Y5cjs.videoFrameAt; exports.videoFrameCacheKey = videoFrameCacheKey; exports.videoFrameDuration = _chunk4QQZV5Y5cjs.videoFrameDuration; exports.videoFrameLeafLayers = _chunk4QQZV5Y5cjs.videoFrameLeafLayers; exports.videoFrameRequestsAt = videoFrameRequestsAt; exports.videoFrameToSvg = _chunk4QQZV5Y5cjs.videoFrameToSvg; exports.videoFrames = _chunk4QQZV5Y5cjs.videoFrames; exports.videoFreezeFrameEdit = _chunk4QQZV5Y5cjs.videoFreezeFrameEdit; exports.videoGradeCssFilter = _chunk4QQZV5Y5cjs.videoGradeCssFilter; exports.videoGradeFfmpegFilters = _chunk4QQZV5Y5cjs.videoGradeFfmpegFilters; exports.videoGradeGainsFilterId = _chunk4QQZV5Y5cjs.videoGradeGainsFilterId; exports.videoGradeLook = _chunk4QQZV5Y5cjs.videoGradeLook; exports.videoGradePreset = _chunk4QQZV5Y5cjs.videoGradePreset; exports.videoGradeStepMatrix = _chunk4QQZV5Y5cjs.videoGradeStepMatrix; exports.videoGradeStepSvgValues = _chunk4QQZV5Y5cjs.videoGradeStepSvgValues; exports.videoGradeSteps = _chunk4QQZV5Y5cjs.videoGradeSteps; exports.videoGradeSvgDefs = _chunk4QQZV5Y5cjs.videoGradeSvgDefs; exports.videoGradeSvgFilter = _chunk4QQZV5Y5cjs.videoGradeSvgFilter; exports.videoHistogram = videoHistogram; exports.videoHistogramImage = videoHistogramImage; exports.videoHourFrames = _chunk4QQZV5Y5cjs.videoHourFrames; exports.videoIrisRadius = _chunk4QQZV5Y5cjs.videoIrisRadius; exports.videoIssueKey = videoIssueKey; exports.videoKeyframeBreakpoints = _chunk4QQZV5Y5cjs.videoKeyframeBreakpoints; exports.videoKeyframeFfmpegExpr = _chunk4QQZV5Y5cjs.videoKeyframeFfmpegExpr; exports.videoKeyframeRows = videoKeyframeRows; exports.videoKeyframeToggleEdit = videoKeyframeToggleEdit; exports.videoKeyframeValueEdit = videoKeyframeValueEdit; exports.videoKeysOf = _chunk4QQZV5Y5cjs.videoKeysOf; exports.videoLayersUseEffects = _chunk4QQZV5Y5cjs.videoLayersUseEffects; exports.videoLayersWithoutTransitionEffects = _chunk4QQZV5Y5cjs.videoLayersWithoutTransitionEffects; exports.videoLuma = videoLuma; exports.videoLumaWaveform = videoLumaWaveform; exports.videoLutEdits = videoLutEdits; exports.videoLutFromFunction = _chunk4QQZV5Y5cjs.videoLutFromFunction; exports.videoLutSvgApproximation = _chunk4QQZV5Y5cjs.videoLutSvgApproximation; exports.videoLutSvgPrimitives = _chunk4QQZV5Y5cjs.videoLutSvgPrimitives; exports.videoLutToCube = _chunk4QQZV5Y5cjs.videoLutToCube; exports.videoOverlap = _chunk4QQZV5Y5cjs.videoOverlap; exports.videoPeakDb = videoPeakDb; exports.videoPreviewSrc = videoPreviewSrc; exports.videoProjectDuration = _chunk4QQZV5Y5cjs.videoProjectDuration; exports.videoProjectEffects = _chunk4QQZV5Y5cjs.videoProjectEffects; exports.videoProjectHasProxies = videoProjectHasProxies; exports.videoProjectSvg = _chunk4QQZV5Y5cjs.videoProjectSvg; exports.videoProxyFfmpeg = videoProxyFfmpeg; exports.videoProxyName = videoProxyName; exports.videoProxyPlan = videoProxyPlan; exports.videoRemoveRangesEdits = videoRemoveRangesEdits; exports.videoRulerTicks = videoRulerTicks; exports.videoScopeImage = videoScopeImage; exports.videoSequenceChildren = _chunk4QQZV5Y5cjs.videoSequenceChildren; exports.videoSequenceDuration = _chunk4QQZV5Y5cjs.videoSequenceDuration; exports.videoSequenceMap = _chunk4QQZV5Y5cjs.videoSequenceMap; exports.videoShellQuote = _chunk4QQZV5Y5cjs.videoShellQuote; exports.videoSlowMotionRamp = _chunk4QQZV5Y5cjs.videoSlowMotionRamp; exports.videoSnapPoints = _chunk4QQZV5Y5cjs.videoSnapPoints; exports.videoSourceFrame = videoSourceFrame; exports.videoSourceFrameTime = videoSourceFrameTime; exports.videoSpeedRampEdit = _chunk4QQZV5Y5cjs.videoSpeedRampEdit; exports.videoSpeedRampKeys = _chunk4QQZV5Y5cjs.videoSpeedRampKeys; exports.videoTextStyle = _chunk4QQZV5Y5cjs.videoTextStyle; exports.videoTimeRemapBreakpoints = _chunk4QQZV5Y5cjs.videoTimeRemapBreakpoints; exports.videoTimeRemapSpan = _chunk4QQZV5Y5cjs.videoTimeRemapSpan; exports.videoTimecodeFrames = _chunk4QQZV5Y5cjs.videoTimecodeFrames; exports.videoTimelineTranscript = videoTimelineTranscript; exports.videoTitleFrame = _chunk4QQZV5Y5cjs.videoTitleFrame; exports.videoTrackSyncLocked = _chunk4QQZV5Y5cjs.videoTrackSyncLocked; exports.videoTranscriptEdit = videoTranscriptEdit; exports.videoTranscriptTrack = videoTranscriptTrack; exports.videoTransformAt = _chunk4QQZV5Y5cjs.videoTransformAt; exports.videoTransitionAudioCurve = _chunk4QQZV5Y5cjs.videoTransitionAudioCurve; exports.videoTransitionEase = _chunk4QQZV5Y5cjs.videoTransitionEase; exports.videoTransitionHasDirection = videoTransitionHasDirection; exports.videoValueAt = _chunk4QQZV5Y5cjs.videoValueAt; exports.videoVectorscope = videoVectorscope; exports.videoVectorscopeAngle = videoVectorscopeAngle; exports.videoVectorscopeImage = videoVectorscopeImage; exports.videoVectorscopePoint = videoVectorscopePoint; exports.videoWaveformImage = videoWaveformImage; exports.videoWaveformPath = videoWaveformPath; exports.videoWipeRect = _chunk4QQZV5Y5cjs.videoWipeRect; exports.videoWordAt = videoWordAt; exports.videoWordsRange = videoWordsRange;
5063
5063
  //# sourceMappingURL=index.cjs.map