@pixerate/editor 0.124.1 → 0.126.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/agent/index.cjs +3 -3
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.js +3 -3
  4. package/dist/animation-editor/index.cjs +422 -85
  5. package/dist/animation-editor/index.cjs.map +1 -1
  6. package/dist/animation-editor/index.d.cts +174 -7
  7. package/dist/animation-editor/index.d.ts +174 -7
  8. package/dist/animation-editor/index.js +346 -9
  9. package/dist/animation-editor/index.js.map +1 -1
  10. package/dist/{chunk-ORHMVUR6.js → chunk-FICSDDDF.js} +5 -3
  11. package/dist/{chunk-ORHMVUR6.js.map → chunk-FICSDDDF.js.map} +1 -1
  12. package/dist/chunk-FJ3324TZ.js +59 -0
  13. package/dist/chunk-FJ3324TZ.js.map +1 -0
  14. package/dist/{chunk-5EO2IXQE.js → chunk-FPRIUR4T.js} +1 -1
  15. package/dist/chunk-FPRIUR4T.js.map +1 -0
  16. package/dist/{chunk-FHYDQOPC.cjs → chunk-JODTP4DP.cjs} +178 -7
  17. package/dist/chunk-JODTP4DP.cjs.map +1 -0
  18. package/dist/{chunk-NGYD3AMN.js → chunk-MPQAO33O.js} +2 -2
  19. package/dist/{chunk-PEHYWUVV.cjs → chunk-O5RVCDEC.cjs} +82 -82
  20. package/dist/{chunk-PEHYWUVV.cjs.map → chunk-O5RVCDEC.cjs.map} +1 -1
  21. package/dist/{chunk-JRXJTPES.js → chunk-QFSTQHZY.js} +176 -5
  22. package/dist/chunk-QFSTQHZY.js.map +1 -0
  23. package/dist/{chunk-5XXMLBH4.cjs → chunk-QQKTOA4U.cjs} +1 -1
  24. package/dist/chunk-QQKTOA4U.cjs.map +1 -0
  25. package/dist/{chunk-4QQZV5Y5.cjs → chunk-SFCPGMCT.cjs} +11 -9
  26. package/dist/chunk-SFCPGMCT.cjs.map +1 -0
  27. package/dist/{chunk-WE25VLCO.cjs → chunk-V5YGPRCZ.cjs} +36 -36
  28. package/dist/{chunk-WE25VLCO.cjs.map → chunk-V5YGPRCZ.cjs.map} +1 -1
  29. package/dist/chunk-W6QTLHZ3.cjs +59 -0
  30. package/dist/chunk-W6QTLHZ3.cjs.map +1 -0
  31. package/dist/{chunk-WATAQ2Z2.js → chunk-WUDPFWAN.js} +2 -2
  32. package/dist/effects/index.cjs +59 -33
  33. package/dist/effects/index.cjs.map +1 -1
  34. package/dist/effects/index.d.cts +4 -5
  35. package/dist/effects/index.d.ts +4 -5
  36. package/dist/effects/index.js +33 -7
  37. package/dist/effects/index.js.map +1 -1
  38. package/dist/{export-WmYoWmLM.d.cts → export-Bp7ji2r4.d.cts} +1 -2
  39. package/dist/{export-BdfY_lH0.d.ts → export-C1s4eolZ.d.ts} +1 -1
  40. package/dist/{export-BGtXgMJ3.d.ts → export-DAyPY94f.d.ts} +1 -2
  41. package/dist/{export-CbpjwxaI.d.cts → export-DVl4fWy5.d.cts} +1 -1
  42. package/dist/generation/index.cjs +3 -3
  43. package/dist/generation/index.cjs.map +1 -1
  44. package/dist/generation/index.js +3 -3
  45. package/dist/helpers-BBLlekuM.d.ts +2009 -0
  46. package/dist/helpers-i95Ob6Vi.d.cts +2009 -0
  47. package/dist/image-editor/index.cjs +627 -627
  48. package/dist/image-editor/index.cjs.map +1 -1
  49. package/dist/image-editor/index.d.cts +5 -7
  50. package/dist/image-editor/index.d.ts +5 -7
  51. package/dist/image-editor/index.js +13 -13
  52. package/dist/paint-editor/index.cjs +736 -115
  53. package/dist/paint-editor/index.cjs.map +1 -1
  54. package/dist/paint-editor/index.d.cts +248 -13
  55. package/dist/paint-editor/index.d.ts +248 -13
  56. package/dist/paint-editor/index.js +634 -13
  57. package/dist/paint-editor/index.js.map +1 -1
  58. package/dist/{svg-BDrjRnL1.d.cts → svg-BkRL-fZJ.d.cts} +1 -1
  59. package/dist/{svg-C-vZ3q50.d.ts → svg-DJKriJ4A.d.ts} +1 -1
  60. package/dist/tools/index.cjs +2 -2
  61. package/dist/tools/index.cjs.map +1 -1
  62. package/dist/tools/index.js +3 -3
  63. package/dist/{tools-C7JtLYzo.d.ts → tools-CM8Oe8F3.d.ts} +1 -1
  64. package/dist/{tools-DHKGHiSK.d.cts → tools-DZCv2kX1.d.cts} +1 -1
  65. package/dist/vector/index.cjs +1030 -883
  66. package/dist/vector/index.cjs.map +1 -1
  67. package/dist/vector/index.d.cts +61 -6
  68. package/dist/vector/index.d.ts +61 -6
  69. package/dist/vector/index.js +153 -6
  70. package/dist/vector/index.js.map +1 -1
  71. package/dist/video-editor/index.cjs +272 -273
  72. package/dist/video-editor/index.cjs.map +1 -1
  73. package/dist/video-editor/index.d.cts +4 -6
  74. package/dist/video-editor/index.d.ts +4 -6
  75. package/dist/video-editor/index.js +6 -7
  76. package/dist/video-editor/index.js.map +1 -1
  77. package/package.json +1 -1
  78. package/skills/pixerate-animation-editor/SKILL.md +24 -1
  79. package/skills/pixerate-paint-editor/SKILL.md +40 -1
  80. package/skills/pixerate-vector/SKILL.md +15 -0
  81. package/dist/chunk-4QQZV5Y5.cjs.map +0 -1
  82. package/dist/chunk-5EO2IXQE.js.map +0 -1
  83. package/dist/chunk-5XXMLBH4.cjs.map +0 -1
  84. package/dist/chunk-CN4PJHUG.cjs +0 -234
  85. package/dist/chunk-CN4PJHUG.cjs.map +0 -1
  86. package/dist/chunk-FHYDQOPC.cjs.map +0 -1
  87. package/dist/chunk-JRXJTPES.js.map +0 -1
  88. package/dist/chunk-QEG3GRN2.js +0 -234
  89. package/dist/chunk-QEG3GRN2.js.map +0 -1
  90. package/dist/flair-CxB3fOcU.d.ts +0 -739
  91. package/dist/flair-D7BxyBwL.d.cts +0 -739
  92. package/dist/helpers-777mC6dc.d.cts +0 -253
  93. package/dist/helpers-DX2_7L5t.d.ts +0 -253
  94. package/dist/types-BcX7sCsn.d.ts +0 -993
  95. package/dist/types-CznabG7m.d.cts +0 -993
  96. /package/dist/{chunk-NGYD3AMN.js.map → chunk-MPQAO33O.js.map} +0 -0
  97. /package/dist/{chunk-WATAQ2Z2.js.map → chunk-WUDPFWAN.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
2
2
 
3
- var _chunkWE25VLCOcjs = require('../chunk-WE25VLCO.cjs');
3
+ var _chunkV5YGPRCZcjs = require('../chunk-V5YGPRCZ.cjs');
4
4
 
5
5
 
6
6
 
@@ -31,7 +31,14 @@ var _chunkWAJQKWQUcjs = require('../chunk-WAJQKWQU.cjs');
31
31
 
32
32
 
33
33
 
34
- var _chunk5XXMLBH4cjs = require('../chunk-5XXMLBH4.cjs');
34
+ var _chunkQQKTOA4Ucjs = require('../chunk-QQKTOA4U.cjs');
35
+
36
+
37
+
38
+
39
+
40
+
41
+ var _chunkJODTP4DPcjs = require('../chunk-JODTP4DP.cjs');
35
42
 
36
43
 
37
44
 
@@ -40,6 +47,7 @@ var _chunk5XXMLBH4cjs = require('../chunk-5XXMLBH4.cjs');
40
47
 
41
48
  var _chunkN3FVUOZDcjs = require('../chunk-N3FVUOZD.cjs');
42
49
  require('../chunk-GUZ47CJM.cjs');
50
+ require('../chunk-RIWPYSKU.cjs');
43
51
 
44
52
 
45
53
  var _chunkEMQWJA3Gcjs = require('../chunk-EMQWJA3G.cjs');
@@ -166,7 +174,7 @@ ${problems.map((p) => `- ${p}`).join("\n")}`);
166
174
  var SCENE_KEYS = ["version", "name", "description", "artwork", "shots", "clips", "drivers", "motionBlur", "loop", "trigger", "fps", "steps", "beat", "narration", "target", "controls", "presets"];
167
175
  var SHOT_KEYS = ["id", "label", "camera", "at", "run", "hold", "speed"];
168
176
  var CAMERA_KEYS = ["x", "y", "width", "height", "frame", "padding", "ease", "ms", "geometric"];
169
- var BASE_KEYS = ["type", "targets", "duration", "delay", "stagger", "with", "ease", "note", "repeat", "repeatMode", "steps", "split", "cascade"];
177
+ var BASE_KEYS = ["type", "targets", "duration", "delay", "stagger", "with", "ease", "note", "repeat", "repeatMode", "steps", "split", "cascade", "source"];
170
178
  var DRAW_ORDER_KEYS = ["order", "pace", "align", "sortBy", "origin"];
171
179
  var COMMAND_KEYS = {
172
180
  enter: [...BASE_KEYS, ...DRAW_ORDER_KEYS, "style", "direction", "distance", "scale", "shape", "orientation"],
@@ -224,6 +232,11 @@ function commandShapeProblems(command3, where) {
224
232
  if (command3.origin !== void 0 && !isPoint(command3.origin)) p(`"origin" must be { "x": number, "y": number } (document units).`);
225
233
  }
226
234
  if (command3.note !== void 0 && typeof command3.note !== "string") p(`"note" must be a string.`);
235
+ if (command3.source !== void 0) {
236
+ const src = command3.source;
237
+ if (!isObject(src) || typeof src.instance !== "string" || !src.instance || typeof src.effect !== "string" || !src.effect) p(`"source" must be { instance, effect, provider?, name?, values? } (set by applyMotionEffect).`);
238
+ else unknownKeys(src, ["instance", "effect", "provider", "name", "values"], `${where} (${type}) source`, problems);
239
+ }
227
240
  if (type === "wait") {
228
241
  if (!isNum(command3.duration) || command3.duration < 0) p(`"duration" must be a number of milliseconds \u2265 0.`);
229
242
  return problems;
@@ -560,7 +573,7 @@ function smoothMotionTimes(points, start, duration, pacing = "even") {
560
573
  function motionTextLayout(nodes, id) {
561
574
  const group = _optionalChain([nodes, 'access', _5 => _5.get, 'call', _6 => _6(id), 'optionalAccess', _7 => _7.node]);
562
575
  if (!group || group.type !== "group") return null;
563
- const letters = _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, group).map((p) => ({ id: p.id, b: _optionalChain([nodes, 'access', _8 => _8.get, 'call', _9 => _9(p.id), 'optionalAccess', _10 => _10.bounds]) })).filter((l) => !!l.b && l.b.width + l.b.height > 0);
576
+ const letters = _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, group).map((p) => ({ id: p.id, b: _optionalChain([nodes, 'access', _8 => _8.get, 'call', _9 => _9(p.id), 'optionalAccess', _10 => _10.bounds]) })).filter((l) => !!l.b && l.b.width + l.b.height > 0);
564
577
  if (!letters.length) return null;
565
578
  const lines = [];
566
579
  for (const l of [...letters].sort((a, c) => a.b.y + a.b.height / 2 - (c.b.y + c.b.height / 2))) {
@@ -645,21 +658,21 @@ function indexMotionNodes(nodes) {
645
658
  const out = /* @__PURE__ */ new Map();
646
659
  const walk = (list, parentWorld, ancestors) => {
647
660
  for (const node of list) {
648
- const local = _chunk5XXMLBH4cjs.vectorNodeBounds.call(void 0, node);
649
- const bounds = _chunk5XXMLBH4cjs.vectorNodeBounds.call(void 0, node, parentWorld);
661
+ const local = _chunkQQKTOA4Ucjs.vectorNodeBounds.call(void 0, node);
662
+ const bounds = _chunkQQKTOA4Ucjs.vectorNodeBounds.call(void 0, node, parentWorld);
650
663
  const center = local ? { x: local.x + local.width / 2, y: local.y + local.height / 2 } : { x: 0, y: 0 };
651
664
  if (!out.has(node.id)) out.set(node.id, { node, ancestors, parentWorld, center, bounds, box: local });
652
- if (node.type === "group") walk(node.children, _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, node), parentWorld), [...ancestors, node.id]);
665
+ if (node.type === "group") walk(node.children, _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, node), parentWorld), [...ancestors, node.id]);
653
666
  }
654
667
  };
655
- walk(nodes, _chunk5XXMLBH4cjs.IDENTITY_MATRIX, []);
668
+ walk(nodes, _chunkQQKTOA4Ucjs.IDENTITY_MATRIX, []);
656
669
  indexCache.set(nodes, out);
657
670
  return out;
658
671
  }
659
672
  var solid = (paint) => typeof paint === "string" && paint !== "none" ? paint : void 0;
660
673
  function firstPaint(node, key) {
661
674
  if (node.type === "path") return solid(node[key]);
662
- for (const p of _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node)) {
675
+ for (const p of _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node)) {
663
676
  const s = solid(p[key]);
664
677
  if (s) return s;
665
678
  }
@@ -667,7 +680,7 @@ function firstPaint(node, key) {
667
680
  }
668
681
  function strokeReach(node) {
669
682
  let reach = 0;
670
- for (const p of node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node)) {
683
+ for (const p of node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node)) {
671
684
  if (p.stroke == null || p.stroke === "none") continue;
672
685
  const width = _nullishCoalesce(p.strokeWidth, () => ( 1));
673
686
  reach = Math.max(reach, p.strokeAlign === "outside" ? width : p.strokeAlign === "inside" ? 0 : width / 2);
@@ -737,7 +750,7 @@ function motionRestValue(entry, property, artwork) {
737
750
  case "stroke":
738
751
  return _nullishCoalesce((node && firstPaint(node, property)), () => ( "transparent"));
739
752
  case "strokeWidth": {
740
- const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ? _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node)[0] : void 0;
753
+ const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ? _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node)[0] : void 0;
741
754
  return _nullishCoalesce(_optionalChain([path, 'optionalAccess', _14 => _14.strokeWidth]), () => ( 1));
742
755
  }
743
756
  case "shape":
@@ -848,12 +861,12 @@ function resolveMotionCamera(camera, scene) {
848
861
  const r = camera;
849
862
  return { x: r.x, y: r.y, width: r.width, height: r.height };
850
863
  }
851
- function motionPathLength(node, parentWorld = _chunk5XXMLBH4cjs.IDENTITY_MATRIX) {
864
+ function motionPathLength(node, parentWorld = _chunkQQKTOA4Ucjs.IDENTITY_MATRIX) {
852
865
  let longest = 0;
853
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
866
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
854
867
  for (const p of paths) {
855
868
  try {
856
- longest = Math.max(longest, _chunkN3FVUOZDcjs.bezierPathLength.call(void 0, _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, p, parentWorld, { effects: false })));
869
+ longest = Math.max(longest, _chunkN3FVUOZDcjs.bezierPathLength.call(void 0, _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, p, parentWorld, { effects: false })));
857
870
  } catch (e2) {
858
871
  }
859
872
  }
@@ -1106,12 +1119,12 @@ function compileMotionScene(scene) {
1106
1119
  const order2 = _nullishCoalesce(o.order, () => ( "together"));
1107
1120
  const pace = _nullishCoalesce(o.pace, () => ( "time"));
1108
1121
  if (order2 === "together" && pace === "time") return null;
1109
- const paths = entry.node.type === "path" ? [entry.node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, entry.node);
1122
+ const paths = entry.node.type === "path" ? [entry.node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, entry.node);
1110
1123
  let list = paths.map((p) => {
1111
1124
  const at = nodes.get(p.id);
1112
1125
  let first = { x: 0, y: 0 };
1113
1126
  try {
1114
- const m = _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, p, _nullishCoalesce(_optionalChain([at, 'optionalAccess', _41 => _41.parentWorld]), () => ( _chunk5XXMLBH4cjs.IDENTITY_MATRIX)), { effects: false })[0];
1127
+ const m = _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, p, _nullishCoalesce(_optionalChain([at, 'optionalAccess', _41 => _41.parentWorld]), () => ( _chunkQQKTOA4Ucjs.IDENTITY_MATRIX)), { effects: false })[0];
1115
1128
  if (m && m.type === "M") first = { x: m.x, y: m.y };
1116
1129
  } catch (e3) {
1117
1130
  }
@@ -1223,17 +1236,17 @@ function compileMotionScene(scene) {
1223
1236
  let dx = _nullishCoalesce(_optionalChain([command3, 'access', _44 => _44.by, 'optionalAccess', _45 => _45.x]), () => ( 0));
1224
1237
  let dy = _nullishCoalesce(_optionalChain([command3, 'access', _46 => _46.by, 'optionalAccess', _47 => _47.y]), () => ( 0));
1225
1238
  if (command3.to) {
1226
- const inv = _chunk5XXMLBH4cjs.invertMatrix.call(void 0, entry.parentWorld);
1227
- const target = _chunk5XXMLBH4cjs.applyMatrix.call(void 0, inv, command3.to);
1239
+ const inv = _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, entry.parentWorld);
1240
+ const target = _chunkQQKTOA4Ucjs.applyMatrix.call(void 0, inv, command3.to);
1228
1241
  dx = target.x - (entry.center.x + num2("x"));
1229
1242
  dy = target.y - (entry.center.y + num2("y"));
1230
1243
  }
1231
1244
  if (_optionalChain([command3, 'access', _48 => _48.via, 'optionalAccess', _49 => _49.length])) {
1232
- const inv = _chunk5XXMLBH4cjs.invertMatrix.call(void 0, entry.parentWorld);
1245
+ const inv = _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, entry.parentWorld);
1233
1246
  const x0 = num2("x");
1234
1247
  const y0 = num2("y");
1235
1248
  const add = command3.blend === "add";
1236
- const offsets = [{ x: 0, y: 0 }, ...command3.via.map((p) => _chunk5XXMLBH4cjs.applyMatrix.call(void 0, inv, p)).map((p) => ({ x: p.x - entry.center.x - x0, y: p.y - entry.center.y - y0 })), { x: dx, y: dy }];
1249
+ const offsets = [{ x: 0, y: 0 }, ...command3.via.map((p) => _chunkQQKTOA4Ucjs.applyMatrix.call(void 0, inv, p)).map((p) => ({ x: p.x - entry.center.x - x0, y: p.y - entry.center.y - y0 })), { x: dx, y: dy }];
1237
1250
  const times = smoothMotionTimes(offsets, start, end - start, _nullishCoalesce(command3.pacing, () => ( "even")));
1238
1251
  for (const axis of ["x", "y"]) {
1239
1252
  const base = add ? 0 : axis === "x" ? x0 : y0;
@@ -1376,13 +1389,13 @@ function morphBetween(a, b) {
1376
1389
  let inner = morphCache.get(a);
1377
1390
  if (!inner) morphCache.set(a, inner = /* @__PURE__ */ new WeakMap());
1378
1391
  let morph = inner.get(b);
1379
- if (!morph) inner.set(b, morph = _chunkWE25VLCOcjs.createVectorMorph.call(void 0, a, b, { id: a.id }));
1392
+ if (!morph) inner.set(b, morph = _chunkV5YGPRCZcjs.createVectorMorph.call(void 0, a, b, { id: a.id }));
1380
1393
  return morph;
1381
1394
  }
1382
1395
  function shapeIn(entry, shape) {
1383
1396
  if (shape === entry) return entry.node;
1384
- const m = _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, shape.node), shape.parentWorld), _chunk5XXMLBH4cjs.invertMatrix.call(void 0, entry.parentWorld));
1385
- return { ...shape.node, ..._chunk5XXMLBH4cjs.isIdentityMatrix.call(void 0, m) ? { transform: void 0 } : { transform: m } };
1397
+ const m = _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, shape.node), shape.parentWorld), _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, entry.parentWorld));
1398
+ return { ...shape.node, ..._chunkQQKTOA4Ucjs.isIdentityMatrix.call(void 0, m) ? { transform: void 0 } : { transform: m } };
1386
1399
  }
1387
1400
  function shapeAt(entry, timeline, nodes, time) {
1388
1401
  const track = timeline.tracks.get(motionTrackKey(entry.node.id, "shape"));
@@ -1402,7 +1415,7 @@ function shapeAt(entry, timeline, nodes, time) {
1402
1415
  function motionFollowRoute(entry, path) {
1403
1416
  if (!path || path.node.type !== "path") return null;
1404
1417
  try {
1405
- return _chunkN3FVUOZDcjs.transformBezierPath.call(void 0, _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, path.node, path.parentWorld, { effects: false }), _chunk5XXMLBH4cjs.invertMatrix.call(void 0, entry.parentWorld));
1418
+ return _chunkN3FVUOZDcjs.transformBezierPath.call(void 0, _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, path.node, path.parentWorld, { effects: false }), _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, entry.parentWorld));
1406
1419
  } catch (e4) {
1407
1420
  return null;
1408
1421
  }
@@ -1436,9 +1449,9 @@ function motionNodeOffset(entry, timeline, time, nodes = indexMotionNodes([entry
1436
1449
  const scaleX = read("scaleX", 1);
1437
1450
  const scaleY = read("scaleY", 1);
1438
1451
  const c = entry.center;
1439
- let matrix = _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.scaleMatrix.call(void 0, scaleX, scaleY, c), _chunk5XXMLBH4cjs.rotateMatrix.call(void 0, rotation, c)), _chunk5XXMLBH4cjs.translateMatrix.call(void 0, dx, dy));
1452
+ let matrix = _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.scaleMatrix.call(void 0, scaleX, scaleY, c), _chunkQQKTOA4Ucjs.rotateMatrix.call(void 0, rotation, c)), _chunkQQKTOA4Ucjs.translateMatrix.call(void 0, dx, dy));
1440
1453
  const along = follow ? followAt(entry, timeline, nodes, time) : null;
1441
- if (along) matrix = _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, matrix, _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.translateMatrix.call(void 0, -c.x, -c.y), _chunk5XXMLBH4cjs.rotateMatrix.call(void 0, along.angle)), _chunk5XXMLBH4cjs.translateMatrix.call(void 0, along.x, along.y)));
1454
+ if (along) matrix = _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, matrix, _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.translateMatrix.call(void 0, -c.x, -c.y), _chunkQQKTOA4Ucjs.rotateMatrix.call(void 0, along.angle)), _chunkQQKTOA4Ucjs.translateMatrix.call(void 0, along.x, along.y)));
1442
1455
  return { matrix, dx, dy, rotation, scaleX, scaleY, follow: along };
1443
1456
  }
1444
1457
  function motionNodeClips(id, timeline, time) {
@@ -1505,7 +1518,7 @@ function motionFrameAt(scene, time, options = {}) {
1505
1518
  const start = Math.min(1, Math.max(0, typeof drawStart === "number" ? drawStart : 0));
1506
1519
  const end = Math.min(1, Math.max(0, typeof drawEnd === "number" ? drawEnd : 1));
1507
1520
  if (start > 0 || end < 1) {
1508
- const trim = _chunk5XXMLBH4cjs.createVectorEffect.call(void 0, "trim", MOTION_DRAW_EFFECT_ID, { start: tidy(start * 100), end: tidy(end * 100) });
1521
+ const trim = _chunkQQKTOA4Ucjs.createVectorEffect.call(void 0, "trim", MOTION_DRAW_EFFECT_ID, { start: tidy(start * 100), end: tidy(end * 100) });
1509
1522
  p = { ...p, effects: [trim, ...(_nullishCoalesce(p.effects, () => ( []))).filter((e) => e.id !== MOTION_DRAW_EFFECT_ID)] };
1510
1523
  }
1511
1524
  }
@@ -1519,8 +1532,8 @@ function motionFrameAt(scene, time, options = {}) {
1519
1532
  if (o >= 1) delete out.opacity;
1520
1533
  }
1521
1534
  const offset = options.offsets === false ? null : motionNodeOffset(entry, timeline, time, nodes);
1522
- if (offset && !_chunk5XXMLBH4cjs.isIdentityMatrix.call(void 0, offset.matrix)) {
1523
- const m = _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, out), offset.matrix).map(tidy);
1535
+ if (offset && !_chunkQQKTOA4Ucjs.isIdentityMatrix.call(void 0, offset.matrix)) {
1536
+ const m = _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, out), offset.matrix).map(tidy);
1524
1537
  out = { ...out, transform: m };
1525
1538
  }
1526
1539
  return out;
@@ -1540,7 +1553,7 @@ function motionFrameToSvg(scene, time, options = {}) {
1540
1553
  const wrap = { ...options.wrap };
1541
1554
  for (const [id, clips] of Object.entries(frame.clips))
1542
1555
  wrap[id] = [..._nullishCoalesce(wrap[id], () => ( [])), ...clips.map((clip, i) => ({ clip: { id: `${prefix}reveal-${id}-${i}`, shape: clip.shape, attrs: motionClipAttrs(clip) } }))];
1543
- return withViewBox(_chunk5XXMLBH4cjs.vectorDocumentToSvg.call(void 0, frame.document, { ...options, wrap }), frame.camera);
1556
+ return withViewBox(_chunkQQKTOA4Ucjs.vectorDocumentToSvg.call(void 0, frame.document, { ...options, wrap }), frame.camera);
1544
1557
  }
1545
1558
  function withViewBox(svg, box) {
1546
1559
  const f = (n) => String(Math.round(n * 1e3) / 1e3);
@@ -1723,8 +1736,8 @@ function visibleAt(timeline, id, time, node) {
1723
1736
  if (Array.isArray(rect) && (rect[2] <= 1e-4 || rect[3] <= 1e-4)) return false;
1724
1737
  const circle = clip("clipCircle");
1725
1738
  if (Array.isArray(circle) && circle[2] <= 1e-4) return false;
1726
- const hasFill = node.type === "path" ? !!node.fill && node.fill !== "none" : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node).some((p) => p.fill && p.fill !== "none");
1727
- const drawn = num2("drawEnd", 1) > 0.01 && (node.type === "path" || _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node).length === 0 || _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node).some((p) => {
1739
+ const hasFill = node.type === "path" ? !!node.fill && node.fill !== "none" : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node).some((p) => p.fill && p.fill !== "none");
1740
+ const drawn = num2("drawEnd", 1) > 0.01 && (node.type === "path" || _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node).length === 0 || _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node).some((p) => {
1728
1741
  const v = trackValue(timeline.tracks.get(motionTrackKey(p.id, "drawEnd")), time);
1729
1742
  return typeof v !== "number" || v > 0.01;
1730
1743
  }));
@@ -1810,7 +1823,7 @@ function checkMotionScene(scene) {
1810
1823
  }
1811
1824
  for (const id of targets) {
1812
1825
  const node = nodes.get(id).node;
1813
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
1826
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
1814
1827
  if (paths.some((p) => p[key] !== void 0 && p[key] !== null && typeof p[key] !== "string"))
1815
1828
  issues.push(_chunkWAJQKWQUcjs.motionIssue.call(void 0, "paint-not-color", `"${id}" has a gradient ${key}; it switches to ${color} at the end instead of blending.`, { ...where, ids: [id] }));
1816
1829
  }
@@ -1823,7 +1836,7 @@ function checkMotionScene(scene) {
1823
1836
  else
1824
1837
  for (const id of targets) {
1825
1838
  const node = nodes.get(id).node;
1826
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
1839
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
1827
1840
  if (paths.some((p) => typeof p[key] !== "string"))
1828
1841
  issues.push(_chunkWAJQKWQUcjs.motionIssue.call(void 0, "paint-not-color", `"${id}" has a gradient or no ${key}, so a colour pulse cannot tint it; give it a solid ${key} or pulse the ${key === "fill" ? "stroke" : "fill"}.`, { ...where, ids: [id] }));
1829
1842
  }
@@ -2407,7 +2420,7 @@ function toFlairSvgMotion(scene, options = {}) {
2407
2420
  raw: (t) => transformAt(t, true)
2408
2421
  });
2409
2422
  }
2410
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
2423
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
2411
2424
  for (const path of paths) {
2412
2425
  if (pathsSeen.has(path.id)) continue;
2413
2426
  pathsSeen.add(path.id);
@@ -2429,7 +2442,7 @@ function toFlairSvgMotion(scene, options = {}) {
2429
2442
  if (shapeSegments.length) {
2430
2443
  if (node.type !== "path") notes.push(`"${id}" is a group: its morph or effect animation is not exported (Flair tweens one path's "d").`);
2431
2444
  else {
2432
- const inverse = _chunk5XXMLBH4cjs.invertMatrix.call(void 0, _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, node));
2445
+ const inverse = _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, node));
2433
2446
  channels.push({
2434
2447
  id,
2435
2448
  kind: "attr",
@@ -2438,9 +2451,9 @@ function toFlairSvgMotion(scene, options = {}) {
2438
2451
  exact: () => false,
2439
2452
  value: (t) => {
2440
2453
  const frame = motionFrameAt(scene, t, { draw: false, offsets: false });
2441
- const now = _chunk5XXMLBH4cjs.expandVectorAppearance.call(void 0, _optionalChain([indexMotionNodes, 'call', _108 => _108(frame.document.nodes), 'access', _109 => _109.get, 'call', _110 => _110(id), 'optionalAccess', _111 => _111.node]));
2454
+ const now = _chunkQQKTOA4Ucjs.expandVectorAppearance.call(void 0, _optionalChain([indexMotionNodes, 'call', _108 => _108(frame.document.nodes), 'access', _109 => _109.get, 'call', _110 => _110(id), 'optionalAccess', _111 => _111.node]));
2442
2455
  if (!now || now.type !== "path") return "";
2443
- const bezier = _chunkN3FVUOZDcjs.transformBezierPath.call(void 0, _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, now, _chunk5XXMLBH4cjs.IDENTITY_MATRIX, { effects: false }), inverse);
2456
+ const bezier = _chunkN3FVUOZDcjs.transformBezierPath.call(void 0, _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, now, _chunkQQKTOA4Ucjs.IDENTITY_MATRIX, { effects: false }), inverse);
2444
2457
  return _chunkN3FVUOZDcjs.bezierPathToSvg.call(void 0, bezier, { precision: Math.min(precision, 2) });
2445
2458
  }
2446
2459
  });
@@ -2547,7 +2560,7 @@ function toFlairSvgMotion(scene, options = {}) {
2547
2560
  }
2548
2561
  if (scene.motionBlur) notes.push("Motion blur is drawn on the stage only; Flair plays the scene sharp.");
2549
2562
  if (trigger && (_nullishCoalesce(scene.loop, () => ( "none"))) !== "none") notes.push(`The scene plays on ${trigger}, so its loop does not apply in Flair.`);
2550
- let svg = _chunk5XXMLBH4cjs.vectorDocumentToSvg.call(void 0, { ...scene.artwork, nodes: _chunk5XXMLBH4cjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) }, { pretty: false, precision, wrap });
2563
+ let svg = _chunkQQKTOA4Ucjs.vectorDocumentToSvg.call(void 0, { ...scene.artwork, nodes: _chunkQQKTOA4Ucjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) }, { pretty: false, precision, wrap });
2551
2564
  if (routes.length) svg = svg.replace(/^(<svg[^>]*>)/, `$1<defs>${routes.join("")}</defs>`);
2552
2565
  let motion = { svg, animate };
2553
2566
  if (_optionalChain([scene, 'access', _114 => _114.controls, 'optionalAccess', _115 => _115.length])) {
@@ -2631,14 +2644,14 @@ function easingOf(ease, fallback) {
2631
2644
  return fallback;
2632
2645
  }
2633
2646
  function poseOf(value, entry) {
2634
- const t = _chunk5XXMLBH4cjs.parseSvgTransform.call(void 0, String(value));
2635
- const o = _chunk5XXMLBH4cjs.multiplyMatrices.call(void 0, _nullishCoalesce(_chunk5XXMLBH4cjs.invertMatrix.call(void 0, _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, entry.node)), () => ( [1, 0, 0, 1, 0, 0])), t);
2647
+ const t = _chunkQQKTOA4Ucjs.parseSvgTransform.call(void 0, String(value));
2648
+ const o = _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _nullishCoalesce(_chunkQQKTOA4Ucjs.invertMatrix.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, entry.node)), () => ( [1, 0, 0, 1, 0, 0])), t);
2636
2649
  const sx = Math.hypot(o[0], o[1]);
2637
2650
  if (!(sx > 1e-9)) return null;
2638
2651
  const sy = (o[0] * o[3] - o[1] * o[2]) / sx;
2639
2652
  if (Math.abs(o[2] + o[1] / sx * sy) > 1e-6 || Math.abs(o[3] - o[0] / sx * sy) > 1e-6) return null;
2640
2653
  const c = entry.center;
2641
- const moved = _chunk5XXMLBH4cjs.applyMatrix.call(void 0, o, c);
2654
+ const moved = _chunkQQKTOA4Ucjs.applyMatrix.call(void 0, o, c);
2642
2655
  return { dx: moved.x - c.x, dy: moved.y - c.y, rotation: Math.atan2(o[1], o[0]) * 180 / Math.PI, sx, sy };
2643
2656
  }
2644
2657
  var near = (a, b, eps = 1e-6) => Math.abs(a - b) < eps;
@@ -2723,7 +2736,7 @@ function fromFlairSvgMotion(input, options = {}) {
2723
2736
  const notes = [];
2724
2737
  if (!input || typeof input.svg !== "string") throw new Error('Give a Flair SvgMotion: { svg: "<svg \u2026>", animate: [ \u2026 ] }.');
2725
2738
  const { motion, controls } = resolvePlaceholders(input, notes);
2726
- const artwork = _chunk5XXMLBH4cjs.parseVectorSvg.call(void 0, motion.svg);
2739
+ const artwork = _chunkQQKTOA4Ucjs.parseVectorSvg.call(void 0, motion.svg);
2727
2740
  const nodes = indexMotionNodes(artwork.nodes);
2728
2741
  const byStep = /* @__PURE__ */ new Map();
2729
2742
  for (const anim of _nullishCoalesce(motion.animate, () => ( []))) {
@@ -2970,9 +2983,9 @@ function toLottie(scene, options = {}) {
2970
2983
  const items = [];
2971
2984
  const shapeSegments = [...timeline.tracks.entries()].filter(([k]) => k.startsWith(`${path.id}\0`) && (k.endsWith("\0shape") || k.includes("\0effect:"))).flatMap(([, v]) => v);
2972
2985
  const geometryAt = (t) => {
2973
- if (!shapeSegments.length) return _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, path);
2986
+ if (!shapeSegments.length) return _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, path);
2974
2987
  const now = _optionalChain([indexMotionNodes, 'call', _124 => _124(motionFrameAt(scene, t, { draw: false, offsets: false }).document.nodes), 'access', _125 => _125.get, 'call', _126 => _126(path.id), 'optionalAccess', _127 => _127.node]);
2975
- return now && now.type === "path" ? _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, _chunk5XXMLBH4cjs.expandVectorAppearances.call(void 0, [now])[0]) : _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, path);
2988
+ return now && now.type === "path" ? _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, _chunkQQKTOA4Ucjs.expandVectorAppearances.call(void 0, [now])[0]) : _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, path);
2976
2989
  };
2977
2990
  const rest = lottieContours(_chunkN3FVUOZDcjs.toBezierPath.call(void 0, geometryAt(0)), round2);
2978
2991
  rest.forEach((contour, n) => {
@@ -3045,13 +3058,13 @@ function toLottie(scene, options = {}) {
3045
3058
  const innerTr = STATIC_TR();
3046
3059
  if (node.type === "path") inner = [...pathShapes(node)];
3047
3060
  else if (node.type === "text" || node.type === "instance") {
3048
- const drawn = _chunk5XXMLBH4cjs.expandVectorAppearance.call(void 0, node);
3061
+ const drawn = _chunkQQKTOA4Ucjs.expandVectorAppearance.call(void 0, node);
3049
3062
  inner = drawn.type === "path" ? [...pathShapes(drawn)] : drawn.children.filter((c) => c.type === "path").reverse().flatMap((c) => [...pathShapes(c)]);
3050
- notes.push(`"${node.id}": text is exported as its outlines${_chunk5XXMLBH4cjs.vectorTextHasOutlines.call(void 0, ) ? "" : " (glyph boxes: set an outline text shaper for real glyphs)"}.`);
3063
+ notes.push(`"${node.id}": text is exported as its outlines${_chunkQQKTOA4Ucjs.vectorTextHasOutlines.call(void 0, ) ? "" : " (glyph boxes: set an outline text shaper for real glyphs)"}.`);
3051
3064
  } else {
3052
3065
  inner = shown(node.children).reverse().map(nodeGroup);
3053
- const m = _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, node);
3054
- if (m !== _chunk5XXMLBH4cjs.IDENTITY_MATRIX) {
3066
+ const m = _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, node);
3067
+ if (m !== _chunkQQKTOA4Ucjs.IDENTITY_MATRIX) {
3055
3068
  const parts = staticParts(m);
3056
3069
  if (!parts) notes.push(`"${node.id}": its transform skews, which is not exported; it is drawn without the skew.`);
3057
3070
  else {
@@ -3064,7 +3077,7 @@ function toLottie(scene, options = {}) {
3064
3077
  const body = { ty: "gr", nm: `${node.id} (own)`, it: [...inner, innerTr] };
3065
3078
  return { ty: "gr", nm: _nullishCoalesce(node.name, () => ( node.id)), it: [body, poseTransform(entry)] };
3066
3079
  };
3067
- const artwork = { ...scene.artwork, nodes: _chunk5XXMLBH4cjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) };
3080
+ const artwork = { ...scene.artwork, nodes: _chunkQQKTOA4Ucjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) };
3068
3081
  const content = shown(artwork.nodes).reverse().map(nodeGroup);
3069
3082
  if (artwork.background && rgba(artwork.background))
3070
3083
  content.push({ ty: "gr", nm: "Background", it: [{ ty: "rc", nm: "Background", p: { a: 0, k: [artwork.width / 2, artwork.height / 2] }, s: { a: 0, k: [artwork.width, artwork.height] }, r: { a: 0, k: 0 } }, { ty: "fl", c: { a: 0, k: rgba(artwork.background).map(round2) }, o: { a: 0, k: 100 }, r: 1 }, STATIC_TR()] });
@@ -3163,11 +3176,11 @@ function preset(prst, w, h) {
3163
3176
  const poly = (pts) => [{ closed: true, anchors: pts.map(([x, y]) => ({ x, y })) }];
3164
3177
  switch (prst) {
3165
3178
  case "rect":
3166
- return [_chunk5XXMLBH4cjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3179
+ return [_chunkQQKTOA4Ucjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3167
3180
  case "roundRect":
3168
- return [_chunk5XXMLBH4cjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h }, Math.min(w, h) * 0.16667)];
3181
+ return [_chunkQQKTOA4Ucjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h }, Math.min(w, h) * 0.16667)];
3169
3182
  case "ellipse":
3170
- return [_chunk5XXMLBH4cjs.ellipseSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3183
+ return [_chunkQQKTOA4Ucjs.ellipseSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3171
3184
  case "triangle":
3172
3185
  return poly([[w / 2, 0], [w, h], [0, h]]);
3173
3186
  case "rtTriangle":
@@ -3275,7 +3288,7 @@ function shapes(ctx, tree, map) {
3275
3288
  let subpaths = cust ? custom(cust, w, h) : prst ? preset(prst, w, h) : null;
3276
3289
  if (!subpaths) {
3277
3290
  if (prst) ctx.notes.push(`"${name}" is a ${prst}, drawn as its bounding rectangle.`);
3278
- subpaths = [_chunk5XXMLBH4cjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3291
+ subpaths = [_chunkQQKTOA4Ucjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3279
3292
  }
3280
3293
  const style = kid(el, "style");
3281
3294
  const fill = kid(spPr, "noFill") ? null : _nullishCoalesce(colour(ctx, kid(spPr, "solidFill")), () => ( (el.localName === "cxnSp" ? null : colour(ctx, kid(style, "fillRef")))));
@@ -3484,28 +3497,121 @@ ${problems.join("\n")}`);
3484
3497
  return { scene, notes: [...new Set(ctx.notes)], issues: checkMotionScene(scene), slides: slidePaths.length };
3485
3498
  }
3486
3499
 
3500
+ // src/animation-editor/effects.ts
3501
+ var sourceOf = (c) => c.source;
3502
+ function motionSceneEffects(scene) {
3503
+ const out = /* @__PURE__ */ new Map();
3504
+ const groups = new Set(scene.artwork.nodes.filter((n) => n.type === "group").map((n) => n.id));
3505
+ for (const shot of scene.shots) {
3506
+ for (const c of shot.run) {
3507
+ const s = sourceOf(c);
3508
+ if (!s) continue;
3509
+ let e = out.get(s.instance);
3510
+ if (!e) {
3511
+ const vector = groups.has(s.instance);
3512
+ e = { instance: s.instance, effect: s.effect, ...s.provider ? { provider: s.provider } : {}, ...s.name ? { name: s.name } : {}, values: { ..._nullishCoalesce(s.values, () => ( {})) }, kind: vector ? "vector" : "motion", targets: vector ? [s.instance] : [], shots: [], ...vector ? { group: s.instance } : {} };
3513
+ out.set(s.instance, e);
3514
+ }
3515
+ if (!e.shots.includes(shot.id)) e.shots.push(shot.id);
3516
+ if (e.kind === "motion" && "targets" in c) {
3517
+ for (const t of c.targets) if (!e.targets.includes(t)) e.targets.push(t);
3518
+ }
3519
+ }
3520
+ }
3521
+ return [...out.values()];
3522
+ }
3523
+ function nextMotionEffectInstance(scene) {
3524
+ const used = /* @__PURE__ */ new Set([...motionSceneEffects(scene).map((e) => e.instance), ...scene.shots.map((s) => s.id)]);
3525
+ const walk = (nodes) => nodes.forEach((n) => (used.add(n.id), n.type === "group" && walk(n.children)));
3526
+ walk(scene.artwork.nodes);
3527
+ for (let i = 1; ; i++) if (!used.has(`fx${i}`)) return `fx${i}`;
3528
+ }
3529
+ var motionArtworkSvg = (artwork) => _chunkQQKTOA4Ucjs.vectorDocumentToSvg.call(void 0, artwork);
3530
+ var tag = (commands, source) => commands.map((c) => c.type === "wait" ? c : { ...c, source });
3531
+ function motionCommandsFromEffect(artwork, motion, source) {
3532
+ const imported = fromFlairSvgMotion({ svg: motionArtworkSvg(artwork), animate: [..._nullishCoalesce(motion.animate, () => ( []))] });
3533
+ const commands = [];
3534
+ imported.scene.shots.forEach((shot, i) => {
3535
+ shot.run.forEach((c, j) => commands.push(i > 0 && j === 0 ? { ...c, with: "after" } : c));
3536
+ });
3537
+ return { commands: tag(commands, source), notes: imported.notes };
3538
+ }
3539
+ function prefixed(nodes, shots, prefix) {
3540
+ const map = /* @__PURE__ */ new Map();
3541
+ const rename = (list) => list.map((n) => {
3542
+ map.set(n.id, prefix + n.id);
3543
+ const next = { ...n, id: prefix + n.id };
3544
+ if (next.type === "group") next.children = rename(n.children);
3545
+ return next;
3546
+ });
3547
+ const out = rename(nodes);
3548
+ const id = (v) => typeof v === "string" && map.has(v) ? map.get(v) : v;
3549
+ const remapped = shots.map((s) => ({
3550
+ ...s,
3551
+ run: s.run.map((c) => {
3552
+ const next = { ...c };
3553
+ if (Array.isArray(next.targets)) next.targets = next.targets.map((t) => id(t));
3554
+ for (const k of ["path", "into"]) if (k in next) next[k] = id(next[k]);
3555
+ return next;
3556
+ })
3557
+ }));
3558
+ return { nodes: out, shots: remapped };
3559
+ }
3560
+ function motionPartsFromVectorEffect(artwork, motion, source, box = { x: 0, y: 0, width: artwork.width, height: artwork.height }) {
3561
+ const imported = fromFlairSvgMotion({ svg: motion.svg, animate: [..._nullishCoalesce(motion.animate, () => ( []))] }, { hold: 0 });
3562
+ const art = imported.scene.artwork;
3563
+ const prefix = `${source.instance}-`;
3564
+ const { nodes, shots } = prefixed(art.nodes, imported.scene.shots, prefix);
3565
+ const k = Math.min(box.width / art.width, box.height / art.height);
3566
+ const dx = box.x + (box.width - art.width * k) / 2;
3567
+ const dy = box.y + (box.height - art.height * k) / 2;
3568
+ const group = { type: "group", id: source.instance, name: _nullishCoalesce(source.name, () => ( source.effect)), children: nodes, transform: [k, 0, 0, k, dx, dy] };
3569
+ const tagged = shots.map((s, i) => ({ ...s, id: i === 0 ? source.instance + "-shot" : `${source.instance}-shot-${i + 1}`, run: tag(s.run, source) }));
3570
+ return { group, shots: tagged.map((s) => s.hold === 0 ? (({ hold: _h, ...rest }) => rest)(s) : s), notes: imported.notes };
3571
+ }
3572
+ function withoutMotionEffect(scene, instance) {
3573
+ let place = null;
3574
+ const removedShots = [];
3575
+ const shots = [];
3576
+ for (const shot of scene.shots) {
3577
+ const run = shot.run.filter((c, i) => {
3578
+ const mine = _optionalChain([sourceOf, 'call', _152 => _152(c), 'optionalAccess', _153 => _153.instance]) === instance;
3579
+ if (mine && !place) place = { shot: shot.id, index: i };
3580
+ return !mine;
3581
+ });
3582
+ if (run.length === shot.run.length) shots.push(shot);
3583
+ else if (run.length === 0) removedShots.push(shot.id);
3584
+ else shots.push({ ...shot, run });
3585
+ }
3586
+ const artwork = { ...scene.artwork, nodes: scene.artwork.nodes.filter((n) => n.id !== instance) };
3587
+ return { scene: { ...scene, shots, artwork }, place, removedShots };
3588
+ }
3589
+
3487
3590
  // src/animation-editor/controller.ts
3488
3591
  var BLANK = { width: 800, height: 450, background: "#ffffff", nodes: [] };
3489
3592
  var AnimationEditorController = (_class = class {
3490
3593
 
3491
3594
 
3595
+ /** The effects provider slot (see `setEffectsProvider`). */
3596
+ __init() {this.effects = new (0, _chunkJODTP4DPcjs.EffectsSlot)()}
3492
3597
 
3493
3598
 
3494
- __init() {this.selection = null}
3599
+ __init2() {this.selection = null}
3495
3600
 
3496
- __init2() {this.error = null}
3497
- __init3() {this.revision = 0}
3498
- __init4() {this.applying = false}
3601
+ __init3() {this.error = null}
3602
+ __init4() {this.revision = 0}
3603
+ __init5() {this.applying = false}
3499
3604
 
3500
- __init5() {this.listeners = /* @__PURE__ */ new Set()}
3501
- __init6() {this.unsubscribers = []}
3605
+ __init6() {this.listeners = /* @__PURE__ */ new Set()}
3606
+ __init7() {this.unsubscribers = []}
3502
3607
 
3503
- constructor(options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);
3608
+ constructor(options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);
3504
3609
  this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkQKLRAA4Tcjs.HistoryManager)()));
3505
3610
  this.scene = options.scene ? parseMotionScene(options.scene) : createMotionScene(BLANK);
3506
3611
  this.issues = checkMotionScene(this.scene);
3507
3612
  this.readOnly = _nullishCoalesce(options.readOnly, () => ( false));
3508
3613
  this.onChange = options.onChange;
3614
+ if (options.effects) this.effects.set(options.effects);
3509
3615
  this.player = new (0, _chunk477UVMNRcjs.AnimationPlayer)({ clock: options.clock, duration: () => compileMotionScene(this.scene).duration, loop: _nullishCoalesce(this.scene.loop, () => ( "none")) });
3510
3616
  this.state = this.computeState();
3511
3617
  this.connect();
@@ -3516,7 +3622,8 @@ var AnimationEditorController = (_class = class {
3516
3622
  this.player.subscribe(() => this.notify()),
3517
3623
  this.history.subscribe(() => {
3518
3624
  if (!this.applying) this.notify();
3519
- })
3625
+ }),
3626
+ this.effects.subscribe(() => this.notify())
3520
3627
  );
3521
3628
  }
3522
3629
  /**
@@ -3527,8 +3634,8 @@ var AnimationEditorController = (_class = class {
3527
3634
  this.player.pause();
3528
3635
  this.unsubscribers.splice(0).forEach((u) => u());
3529
3636
  }
3530
- __init7() {this.getState = () => this.state}
3531
- __init8() {this.subscribe = (listener) => {
3637
+ __init8() {this.getState = () => this.state}
3638
+ __init9() {this.subscribe = (listener) => {
3532
3639
  this.connect();
3533
3640
  this.listeners.add(listener);
3534
3641
  return () => {
@@ -3551,7 +3658,7 @@ var AnimationEditorController = (_class = class {
3551
3658
  time: p.time,
3552
3659
  playing: p.playing,
3553
3660
  loop: p.loop,
3554
- currentShot: _nullishCoalesce(_optionalChain([motionShotAt, 'call', _152 => _152(timeline, p.time), 'optionalAccess', _153 => _153.id]), () => ( null)),
3661
+ currentShot: _nullishCoalesce(_optionalChain([motionShotAt, 'call', _154 => _154(timeline, p.time), 'optionalAccess', _155 => _155.id]), () => ( null)),
3555
3662
  selection: this.selection,
3556
3663
  readOnly: this.readOnly,
3557
3664
  error: this.error,
@@ -3559,7 +3666,8 @@ var AnimationEditorController = (_class = class {
3559
3666
  canRedo: h.canRedo,
3560
3667
  undoLabel: h.undoName,
3561
3668
  redoLabel: h.redoName,
3562
- revision: this.revision
3669
+ revision: this.revision,
3670
+ effectsProvider: this.effects.provider
3563
3671
  };
3564
3672
  }
3565
3673
  notify() {
@@ -3590,9 +3698,9 @@ var AnimationEditorController = (_class = class {
3590
3698
  this.applying = false;
3591
3699
  }
3592
3700
  this.notify();
3593
- _optionalChain([this, 'access', _154 => _154.onChange, 'optionalCall', _155 => _155(scene)]);
3701
+ _optionalChain([this, 'access', _156 => _156.onChange, 'optionalCall', _157 => _157(scene)]);
3594
3702
  }
3595
- commit(label, next) {
3703
+ commit(label, next, merge) {
3596
3704
  const before = this.scene;
3597
3705
  this.error = null;
3598
3706
  if (next === before) {
@@ -3606,7 +3714,8 @@ var AnimationEditorController = (_class = class {
3606
3714
  undo: () => this.setScene(before),
3607
3715
  redo: () => this.setScene(next)
3608
3716
  };
3609
- this.history.execute(command3);
3717
+ if (merge) this.history.executeMerged(command3, { key: merge });
3718
+ else this.history.execute(command3);
3610
3719
  }
3611
3720
  refuse(message) {
3612
3721
  this.error = message;
@@ -3626,13 +3735,155 @@ var AnimationEditorController = (_class = class {
3626
3735
  if (reason) return this.refuse(reason);
3627
3736
  const result = applyMotionEdits(this.scene, edits);
3628
3737
  if (!result.ok) return options.dryRun ? result : this.refuse(result.error);
3629
- if (!options.dryRun) this.commit(label, result.scene);
3738
+ if (!options.dryRun) this.commit(label, result.scene, options.merge);
3630
3739
  return result;
3631
3740
  }
3632
3741
  /** Replaces the artwork (e.g. from a vector editor's `onChange`), as one undo step. */
3633
3742
  setArtwork(artwork, label = "Change artwork") {
3634
3743
  return this.apply({ op: "set_artwork", artwork }, label);
3635
3744
  }
3745
+ // ---------------------------------------------------------------------------------------
3746
+ // Effects
3747
+ // ---------------------------------------------------------------------------------------
3748
+ /** The registered effects provider, or `null`. */
3749
+ get effectsProvider() {
3750
+ return this.effects.provider;
3751
+ }
3752
+ /** Registers (or with `null` removes) the effects provider. Not an edit: no undo step. */
3753
+ setEffectsProvider(provider) {
3754
+ this.effects.set(provider);
3755
+ }
3756
+ /** Registers `provider` and returns a function that removes it again (if it is still the one set). */
3757
+ useEffects(provider) {
3758
+ return this.effects.use(provider);
3759
+ }
3760
+ /** The provider effects applied in the scene. */
3761
+ appliedEffects() {
3762
+ return motionSceneEffects(this.scene);
3763
+ }
3764
+ async effectEdit(work, merge) {
3765
+ const reason = this.readOnlyReason();
3766
+ if (reason) return this.refuse(reason);
3767
+ let plan;
3768
+ try {
3769
+ plan = await work();
3770
+ } catch (error) {
3771
+ if (_chunkJODTP4DPcjs.isEffectError.call(void 0, error) || error instanceof Error) return this.refuse(error.message);
3772
+ throw error;
3773
+ }
3774
+ const r = this.apply({ op: "replace_scene", scene: plan.scene }, plan.label, { merge });
3775
+ if (!r.ok) return r;
3776
+ const effect = motionSceneEffects(this.scene).find((e) => e.instance === plan.instance);
3777
+ if (!effect) return this.refuse("The effect made no changes the scene can play.");
3778
+ return { ok: true, effect, notes: plan.notes };
3779
+ }
3780
+ async describeFor(effect, kinds) {
3781
+ const provider = this.effects.require();
3782
+ if (!provider.applyVectorEffect) throw new (0, _chunkJODTP4DPcjs.EffectUnsupportedError)(`${provider.name} has no vector or motion effects.`);
3783
+ const d = await provider.describe(effect);
3784
+ if (!kinds.includes(d.kind)) {
3785
+ const hint = d.kind === "motion" ? "apply it to nodes with apply_effect" : d.kind === "vector" ? "add it with add_vector_effect" : "it draws pixels, which scenes cannot hold";
3786
+ throw new (0, _chunkJODTP4DPcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.kind} effect: ${hint}.`, d.id);
3787
+ }
3788
+ return d;
3789
+ }
3790
+ knownNodes(ids) {
3791
+ const all = /* @__PURE__ */ new Set();
3792
+ const walk = (nodes) => nodes.forEach((n) => (all.add(n.id), n.type === "group" && walk(n.children)));
3793
+ walk(this.scene.artwork.nodes);
3794
+ const missing = ids.filter((id) => !all.has(id));
3795
+ if (missing.length) throw new Error(`The artwork has no node ${missing.map((m) => `"${m}"`).join(", ")}; get_animation lists the node ids.`);
3796
+ if (!ids.length) throw new Error("Give at least one node to animate.");
3797
+ }
3798
+ /**
3799
+ * Applies a provider motion effect to artwork nodes: the provider animates them and the changes
3800
+ * become commands, in a new shot (default) or added to the end of `shot`. One undo step.
3801
+ * Returns the applied effect (its `instance` id changes or removes it).
3802
+ */
3803
+ applyMotionEffect(effect, targets, options = {}) {
3804
+ return this.effectEdit(async () => {
3805
+ this.knownNodes(targets);
3806
+ const d = await this.describeFor(effect, ["motion"]);
3807
+ const values = _chunkJODTP4DPcjs.resolveEffectValues.call(void 0, d, options.values);
3808
+ const instance = _nullishCoalesce(options.instance, () => ( nextMotionEffectInstance(this.scene)));
3809
+ const motion = await this.effects.require().applyVectorEffect(d.id, { svg: motionArtworkSvg(this.scene.artwork), nodeIds: [...targets] }, values);
3810
+ const source = { instance, effect: d.id, provider: this.effects.require().id, name: d.name, values };
3811
+ const { commands, notes } = motionCommandsFromEffect(this.scene.artwork, motion, source);
3812
+ if (!commands.length) throw new Error(`"${d.name}" made no changes the scene can play${notes.length ? `: ${notes.join(" ")}` : ""}.`);
3813
+ let shots = this.scene.shots;
3814
+ if (options.shot) {
3815
+ if (!shots.some((s) => s.id === options.shot)) throw new Error(`There is no shot "${options.shot}"; the shots are ${shots.map((s) => `"${s.id}"`).join(", ")}.`);
3816
+ shots = shots.map((s) => s.id === options.shot ? { ...s, run: [...s.run, ...commands] } : s);
3817
+ } else shots = [...shots, { id: instance, label: d.name, run: commands }];
3818
+ return { scene: { ...this.scene, shots }, label: `Apply ${d.name}`, instance, notes };
3819
+ });
3820
+ }
3821
+ /**
3822
+ * Adds a provider vector effect (one with its own picture: a lower third, a loader): its SVG as
3823
+ * an artwork group (id: the instance) fitted into `box` (default the whole artwork), and its
3824
+ * motion as shots after the last one. One undo step.
3825
+ */
3826
+ addVectorEffect(effect, options = {}) {
3827
+ return this.effectEdit(async () => {
3828
+ const d = await this.describeFor(effect, ["vector"]);
3829
+ const values = _chunkJODTP4DPcjs.resolveEffectValues.call(void 0, d, options.values);
3830
+ const instance = _nullishCoalesce(options.instance, () => ( nextMotionEffectInstance(this.scene)));
3831
+ const motion = await this.effects.require().applyVectorEffect(d.id, motionArtworkSvg(this.scene.artwork), values);
3832
+ const source = { instance, effect: d.id, provider: this.effects.require().id, name: d.name, values };
3833
+ const { group, shots, notes } = motionPartsFromVectorEffect(this.scene.artwork, motion, source, options.box);
3834
+ return { scene: { ...this.scene, artwork: { ...this.scene.artwork, nodes: [...this.scene.artwork.nodes, group] }, shots: [...this.scene.shots, ...shots] }, label: `Add ${d.name}`, instance, notes };
3835
+ });
3836
+ }
3837
+ /**
3838
+ * Makes an applied effect again with new `values` (merged over its own; `null` resets a
3839
+ * control), in the same place. One undo step.
3840
+ */
3841
+ updateMotionEffect(instance, values, options = {}) {
3842
+ return this.effectEdit(async () => {
3843
+ const was = motionSceneEffects(this.scene).find((e) => e.instance === instance);
3844
+ if (!was) throw new Error(`There is no applied effect "${instance}"; list_applied_effects lists them.`);
3845
+ const d = await this.describeFor(was.effect, [was.kind]);
3846
+ const base = { ...was.values };
3847
+ const given = {};
3848
+ for (const [k, v] of Object.entries(values)) {
3849
+ if (v !== null) given[k] = v;
3850
+ else if (k in d.controls.properties) base[k] = d.defaults[k];
3851
+ else throw new Error(`"${k}" is not a control of "${d.id}"; its controls are ${Object.keys(d.controls.properties).join(", ")}.`);
3852
+ }
3853
+ const merged = { ...base, ..._chunkJODTP4DPcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
3854
+ const { scene: bare, place } = withoutMotionEffect(this.scene, instance);
3855
+ const provider = this.effects.require();
3856
+ const source = { instance, effect: d.id, provider: provider.id, name: d.name, values: merged };
3857
+ if (was.kind === "vector") {
3858
+ const old = this.scene.artwork.nodes.find((n) => n.id === instance);
3859
+ const motion2 = await provider.applyVectorEffect(d.id, motionArtworkSvg(bare.artwork), merged);
3860
+ const { group, shots: shots2, notes: notes2 } = motionPartsFromVectorEffect(bare.artwork, motion2, source);
3861
+ const index = this.scene.artwork.nodes.findIndex((n) => n.id === instance);
3862
+ const nodes = [...bare.artwork.nodes];
3863
+ nodes.splice(Math.max(0, index), 0, _optionalChain([old, 'optionalAccess', _158 => _158.transform]) ? { ...group, transform: old.transform } : group);
3864
+ const at = this.scene.shots.findIndex((s) => was.shots.includes(s.id));
3865
+ const kept = bare.shots;
3866
+ const nextShots = [...kept.slice(0, Math.max(0, at)), ...shots2, ...kept.slice(Math.max(0, at))];
3867
+ return { scene: { ...bare, artwork: { ...bare.artwork, nodes }, shots: nextShots }, label: `Change ${d.name}`, instance, notes: notes2 };
3868
+ }
3869
+ const motion = await provider.applyVectorEffect(d.id, { svg: motionArtworkSvg(bare.artwork), nodeIds: was.targets }, merged);
3870
+ const { commands, notes } = motionCommandsFromEffect(bare.artwork, motion, source);
3871
+ let shots = bare.shots;
3872
+ if (place && shots.some((s) => s.id === place.shot)) shots = shots.map((s) => s.id === place.shot ? { ...s, run: [...s.run.slice(0, place.index), ...commands, ...s.run.slice(place.index)] } : s);
3873
+ else {
3874
+ const at = this.scene.shots.findIndex((s) => s.id === _optionalChain([place, 'optionalAccess', _159 => _159.shot]));
3875
+ shots = [...shots.slice(0, Math.max(0, at)), { id: instance, label: d.name, run: commands }, ...shots.slice(Math.max(0, at))];
3876
+ }
3877
+ return { scene: { ...bare, shots }, label: `Change ${d.name}`, instance, notes };
3878
+ }, options.merge);
3879
+ }
3880
+ /** Removes an applied effect: its commands, shots it alone filled and a vector effect's group. One undo step. Works without a provider. */
3881
+ removeMotionEffect(instance) {
3882
+ const was = motionSceneEffects(this.scene).find((e) => e.instance === instance);
3883
+ if (!was) return this.refuse(`There is no applied effect "${instance}"; list_applied_effects lists them.`);
3884
+ const r = this.apply({ op: "replace_scene", scene: withoutMotionEffect(this.scene, instance).scene }, `Remove ${_nullishCoalesce(was.name, () => ( was.effect))}`);
3885
+ return r.ok ? { ok: true, effect: was, notes: [] } : r;
3886
+ }
3636
3887
  /** Opens a scene (JSON or object). `clearHistory` drops the undo stack (opening a file); otherwise it is one undo step. */
3637
3888
  load(scene, options = {}) {
3638
3889
  let parsed;
@@ -4157,9 +4408,9 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4157
4408
  handler: ({ from = 0, to, limit = 200 }) => {
4158
4409
  const s = scene();
4159
4410
  const timeline = compileMotionScene(s);
4160
- const words = _nullishCoalesce(_optionalChain([s, 'access', _156 => _156.narration, 'optionalAccess', _157 => _157.words]), () => ( []));
4411
+ const words = _nullishCoalesce(_optionalChain([s, 'access', _160 => _160.narration, 'optionalAccess', _161 => _161.words]), () => ( []));
4161
4412
  const end = _nullishCoalesce(to, () => ( Math.max(timeline.duration, words.length ? _nullishCoalesce(words[words.length - 1].end, () => ( words[words.length - 1].start)) : 0)));
4162
- const shotAt = (ms) => _optionalChain([timeline, 'access', _158 => _158.shots, 'access', _159 => _159.find, 'call', _160 => _160((x) => ms >= x.start && ms < x.end), 'optionalAccess', _161 => _161.id]);
4413
+ const shotAt = (ms) => _optionalChain([timeline, 'access', _162 => _162.shots, 'access', _163 => _163.find, 'call', _164 => _164((x) => ms >= x.start && ms < x.end), 'optionalAccess', _165 => _165.id]);
4163
4414
  const beats = [];
4164
4415
  if (s.beat && s.beat.bpm > 0) {
4165
4416
  const first = Math.max(0, Math.ceil(motionBeatAt(s.beat, from).beat - 1e-9));
@@ -4260,7 +4511,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4260
4511
  handler: ({ svg }) => {
4261
4512
  let artwork;
4262
4513
  try {
4263
- artwork = _chunk5XXMLBH4cjs.parseVectorSvg.call(void 0, svg);
4514
+ artwork = _chunkQQKTOA4Ucjs.parseVectorSvg.call(void 0, svg);
4264
4515
  } catch (error) {
4265
4516
  throw new Error(`The SVG could not be read: ${error.message}. Nothing was changed.`);
4266
4517
  }
@@ -4481,7 +4732,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4481
4732
  inputSchema: object({ shot: SHOT_ID, commands: { type: "array", items: MOTION_COMMAND_SCHEMA, minItems: 1, description: "Commands to add." }, at: { type: "integer", minimum: 0, description: "Index in the run (default: the end)." } }, ["shot", "commands"]),
4482
4733
  annotations: { title: "Add commands to a shot", ...WRITE },
4483
4734
  handler: ({ shot, commands, at }) => {
4484
- const before = _nullishCoalesce(_optionalChain([scene, 'call', _162 => _162(), 'access', _163 => _163.shots, 'access', _164 => _164.find, 'call', _165 => _165((s) => s.id === shot), 'optionalAccess', _166 => _166.run, 'access', _167 => _167.length]), () => ( 0));
4735
+ const before = _nullishCoalesce(_optionalChain([scene, 'call', _166 => _166(), 'access', _167 => _167.shots, 'access', _168 => _168.find, 'call', _169 => _169((s) => s.id === shot), 'optionalAccess', _170 => _170.run, 'access', _171 => _171.length]), () => ( 0));
4485
4736
  const first = _nullishCoalesce(at, () => ( before));
4486
4737
  return apply({ op: "add_commands", shot, commands, at }, "Add commands", (s) => {
4487
4738
  const shots = describeMotionShots(s);
@@ -4677,7 +4928,7 @@ var TIMING = /* @__PURE__ */ new Set(["duration", "delay", "stagger", "with", "e
4677
4928
  var COLORS = /* @__PURE__ */ new Set(["fill", "stroke", "color"]);
4678
4929
  var NODES = /* @__PURE__ */ new Set(["into", "path"]);
4679
4930
  function branch(type) {
4680
- return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access', _168 => _168.properties, 'optionalAccess', _169 => _169.type, 'optionalAccess', _170 => _170.const]) === type);
4931
+ return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access', _172 => _172.properties, 'optionalAccess', _173 => _173.type, 'optionalAccess', _174 => _174.const]) === type);
4681
4932
  }
4682
4933
  function unitOf(type, name) {
4683
4934
  if (name === "duration" || name === "delay" || name === "stagger") return "ms";
@@ -4712,7 +4963,7 @@ function kindOf(name, schema) {
4712
4963
  }
4713
4964
  function motionCommandFields(type) {
4714
4965
  const schema = branch(type);
4715
- if (!_optionalChain([schema, 'optionalAccess', _171 => _171.properties])) return [];
4966
+ if (!_optionalChain([schema, 'optionalAccess', _175 => _175.properties])) return [];
4716
4967
  const required = new Set(_nullishCoalesce(schema.required, () => ( [])));
4717
4968
  const fields = Object.entries(schema.properties).filter(([name]) => name !== "type").map(([name, s]) => {
4718
4969
  const kind = kindOf(name, s);
@@ -4769,7 +5020,7 @@ function defaultMotionCommand(type, targets, scene) {
4769
5020
  if (type === "wait") return { type: "wait", duration: 500 };
4770
5021
  if (!targets.length) return { error: "Pick a target first: click an element on the stage." };
4771
5022
  const nodes = [...indexMotionNodes(scene.artwork.nodes).values()];
4772
- const other = (pred) => _optionalChain([nodes, 'access', _172 => _172.find, 'call', _173 => _173((e) => !targets.includes(e.node.id) && pred(e)), 'optionalAccess', _174 => _174.node, 'access', _175 => _175.id]);
5023
+ const other = (pred) => _optionalChain([nodes, 'access', _176 => _176.find, 'call', _177 => _177((e) => !targets.includes(e.node.id) && pred(e)), 'optionalAccess', _178 => _178.node, 'access', _179 => _179.id]);
4773
5024
  const base = { targets: [...targets] };
4774
5025
  switch (type) {
4775
5026
  case "scale":
@@ -4800,8 +5051,8 @@ function defaultMotionCommand(type, targets, scene) {
4800
5051
  }
4801
5052
  case "effect": {
4802
5053
  for (const id of targets) {
4803
- const node = _optionalChain([nodes, 'access', _176 => _176.find, 'call', _177 => _177((e) => e.node.id === id), 'optionalAccess', _178 => _178.node]);
4804
- for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess', _179 => _179.effects]), () => ( []))) {
5054
+ const node = _optionalChain([nodes, 'access', _180 => _180.find, 'call', _181 => _181((e) => e.node.id === id), 'optionalAccess', _182 => _182.node]);
5055
+ for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess', _183 => _183.effects]), () => ( []))) {
4805
5056
  const param = Object.entries(effect.params).find(([, v]) => typeof v === "number");
4806
5057
  if (param) return { type, ...base, effect: effect.id, param: param[0], to: param[1] + 1 };
4807
5058
  }
@@ -4826,11 +5077,11 @@ function motionCommandRows(scene, shotId) {
4826
5077
  return scene.shots[index].run.map((command3, i) => {
4827
5078
  const t = timeline.commands.find((c) => c.shotIndex === index && c.command === i);
4828
5079
  const primitive = motionFlairPrimitive(command3);
4829
- return { index: i, command: command3, summary: motionCommandSummary(command3), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _180 => _180.start]), () => ( 0)), end: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _181 => _181.end]), () => ( 0)), ...primitive ? { flairPrimitive: primitive } : {} };
5080
+ return { index: i, command: command3, summary: motionCommandSummary(command3), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _184 => _184.start]), () => ( 0)), end: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _185 => _185.end]), () => ( 0)), ...primitive ? { flairPrimitive: primitive } : {} };
4830
5081
  });
4831
5082
  }
4832
5083
  function duplicateMotionCommandEdit(scene, shot, command3) {
4833
- const run = _nullishCoalesce(_optionalChain([scene, 'access', _182 => _182.shots, 'access', _183 => _183.find, 'call', _184 => _184((s) => s.id === shot), 'optionalAccess', _185 => _185.run]), () => ( []));
5084
+ const run = _nullishCoalesce(_optionalChain([scene, 'access', _186 => _186.shots, 'access', _187 => _187.find, 'call', _188 => _188((s) => s.id === shot), 'optionalAccess', _189 => _189.run]), () => ( []));
4834
5085
  return { op: "add_commands", shot, commands: run[command3] ? [structuredClone(run[command3])] : [], at: command3 + 1 };
4835
5086
  }
4836
5087
  var MOTION_EASE_CHOICES = [
@@ -4915,7 +5166,7 @@ function motionCueFromKey(key) {
4915
5166
  function motionCueChoices(scene, limit = 256) {
4916
5167
  const choices = [];
4917
5168
  const s = (ms) => `${(ms / 1e3).toFixed(2)} s`;
4918
- const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access', _186 => _186.narration, 'optionalAccess', _187 => _187.words, 'access', _188 => _188.map, 'call', _189 => _189((w) => _nullishCoalesce(w.end, () => ( w.start)))]), () => ( [0]))) + 2e3;
5169
+ const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access', _190 => _190.narration, 'optionalAccess', _191 => _191.words, 'access', _192 => _192.map, 'call', _193 => _193((w) => _nullishCoalesce(w.end, () => ( w.start)))]), () => ( [0]))) + 2e3;
4919
5170
  if (scene.beat && scene.beat.bpm > 0) {
4920
5171
  for (let beat = 0; choices.length < limit; beat++) {
4921
5172
  const time = motionBeatTime(scene.beat, beat);
@@ -4925,7 +5176,7 @@ function motionCueChoices(scene, limit = 256) {
4925
5176
  choices.push({ value: `beat:${beat}`, label: `Beat ${beat} (bar ${at.bar}.${at.beatInBar}) \xB7 ${s(time)}`, time });
4926
5177
  }
4927
5178
  }
4928
- _optionalChain([scene, 'access', _190 => _190.narration, 'optionalAccess', _191 => _191.words, 'access', _192 => _192.forEach, 'call', _193 => _193((w, i) => {
5179
+ _optionalChain([scene, 'access', _194 => _194.narration, 'optionalAccess', _195 => _195.words, 'access', _196 => _196.forEach, 'call', _197 => _197((w, i) => {
4929
5180
  if (choices.length < limit * 2) choices.push({ value: `word:${i}`, label: `Word ${i} \u201C${w.text}\u201D \xB7 ${s(w.start)}`, time: w.start });
4930
5181
  })]);
4931
5182
  return choices;
@@ -4934,7 +5185,7 @@ function motionShotCueTime(scene, cue) {
4934
5185
  return cue ? motionCueTime(scene, cue) : void 0;
4935
5186
  }
4936
5187
  function formatMotionNarration(narration) {
4937
- return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _194 => _194.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
5188
+ return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _198 => _198.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
4938
5189
  }
4939
5190
  function parseMotionNarration(text) {
4940
5191
  const lines = text.split("\n").map((l) => l.trim()).filter(Boolean);
@@ -4971,6 +5222,92 @@ function parseMotionDrivers(text) {
4971
5222
  return { drivers };
4972
5223
  }
4973
5224
 
5225
+ // src/animation-editor/effect-tools.ts
5226
+ var info = (e) => ({ id: e.instance, effect: e.effect, ...e.name ? { name: e.name } : {}, ...e.provider ? { provider: e.provider } : {}, role: e.kind === "vector" ? "vector picture" : "motion", enabled: true, values: e.values, targets: e.targets, shots: e.shots });
5227
+ function createAnimationEffectsToolProvider(controller, options = {}) {
5228
+ const readOnlyReason = () => {
5229
+ const ro = typeof options.readOnly === "function" ? options.readOnly() : options.readOnly;
5230
+ if (ro) return typeof ro === "string" ? ro : "The animation is read-only.";
5231
+ return controller.readOnlyReason();
5232
+ };
5233
+ const done = (r, target) => {
5234
+ if (!r.ok) throw new Error(r.error);
5235
+ return { target, effect: info(r.effect), effects: controller.appliedEffects().filter((e) => e.targets.includes(target)).map(info), ...r.notes.length ? { notes: r.notes } : {} };
5236
+ };
5237
+ return _chunkJODTP4DPcjs.createEffectToolProvider.call(void 0, {
5238
+ id: _nullishCoalesce(options.id, () => ( "animation-effects")),
5239
+ namespace: options.namespace,
5240
+ target: { noun: "node", id: "A node id of the artwork from get_animation (a group animates as one)." },
5241
+ applyUses: ["motion"],
5242
+ applyDetails: "The provider animates the node and its changes become ordinary commands (enter, fade, move, pulse\u2026), in a new shot after the last one, tagged with the effect so it can be changed or removed as a whole. They preview, play and export to Flair like any command. Vector effects with their own picture go through add_vector_effect. index, enabled and opacity do not apply here.",
5243
+ provider: () => controller.effectsProvider,
5244
+ readOnlyReason,
5245
+ list: (target) => {
5246
+ const all = controller.appliedEffects();
5247
+ if (target) return [{ target, effects: all.filter((e) => e.targets.includes(target)).map(info) }];
5248
+ const byTarget = /* @__PURE__ */ new Map();
5249
+ for (const e of all) {
5250
+ const key = _nullishCoalesce(e.targets[0], () => ( e.instance));
5251
+ byTarget.set(key, [..._nullishCoalesce(byTarget.get(key), () => ( [])), info(e)]);
5252
+ }
5253
+ return [...byTarget].map(([t, effects]) => ({ target: t, effects }));
5254
+ },
5255
+ apply: async (target, effect, args) => {
5256
+ if (args.index !== void 0 || args.opacity !== void 0 || args.enabled === false) throw new Error("index, opacity and enabled do not apply to motion effects; the effect becomes commands in a new shot.");
5257
+ return done(await controller.applyMotionEffect(effect, [target], { values: args.values }), target);
5258
+ },
5259
+ update: async (target, instance, changes) => {
5260
+ const extra = ["enabled", "opacity", "index"].filter((k) => changes[k] !== void 0);
5261
+ if (extra.length) throw new Error(`A motion effect only takes values; ${extra.join(", ")} do not apply (move or delete its commands with edit_animation).`);
5262
+ return done(await controller.updateMotionEffect(instance, _nullishCoalesce(changes.values, () => ( {}))), target);
5263
+ },
5264
+ remove: async (target, instance) => done(controller.removeMotionEffect(instance), target),
5265
+ subscribe: (notify) => controller.subscribe(() => notify()),
5266
+ extraTools: (ctx) => [
5267
+ {
5268
+ name: "add_vector_effect",
5269
+ title: "Add a vector effect",
5270
+ description: "Adds a provider vector effect that brings its own picture (search_effects with kind vector: lower thirds, loaders, stickers): its SVG becomes an artwork group, fitted into box (default the whole artwork), and its motion becomes shots after the last one. Change it with update_effect (target and effect: the returned instance) or remove it with remove_effect. One undo step. Returns the instance, the group id and any notes on what could not be carried over.",
5271
+ inputSchema: {
5272
+ type: "object",
5273
+ properties: {
5274
+ effect: { type: "string", minLength: 1, description: "A vector effect id from search_effects (kind vector)." },
5275
+ values: ctx.valuesSchema("Control values over the effect's defaults"),
5276
+ box: {
5277
+ type: "object",
5278
+ properties: {
5279
+ x: { type: "number", description: "Left edge, artwork units." },
5280
+ y: { type: "number", description: "Top edge, artwork units." },
5281
+ width: { type: "number", exclusiveMinimum: 0, description: "Width, artwork units." },
5282
+ height: { type: "number", exclusiveMinimum: 0, description: "Height, artwork units." }
5283
+ },
5284
+ required: ["x", "y", "width", "height"],
5285
+ additionalProperties: false,
5286
+ description: "Where the picture goes in the artwork, fitted keeping its proportions (default the whole artwork)."
5287
+ }
5288
+ },
5289
+ required: ["effect"],
5290
+ additionalProperties: false
5291
+ },
5292
+ annotations: { title: "Add a vector effect", ...ctx.annotations.write },
5293
+ handler: async (args) => {
5294
+ ctx.requireProvider();
5295
+ const r = await controller.addVectorEffect(args.effect, { values: args.values, box: args.box });
5296
+ if (!r.ok) throw new Error(r.error);
5297
+ return { instance: r.effect.instance, group: r.effect.group, effect: info(r.effect), ...r.notes.length ? { notes: r.notes } : {} };
5298
+ }
5299
+ }
5300
+ ]
5301
+ });
5302
+ }
5303
+
5304
+
5305
+
5306
+
5307
+
5308
+
5309
+
5310
+
4974
5311
 
4975
5312
 
4976
5313
 
@@ -5114,5 +5451,5 @@ function parseMotionDrivers(text) {
5114
5451
 
5115
5452
 
5116
5453
 
5117
- exports.ANIMATION_EDITOR_AGENT_INSTRUCTIONS = ANIMATION_EDITOR_AGENT_INSTRUCTIONS; exports.AnimationEditorController = AnimationEditorController; exports.FLAIR_EASES = FLAIR_EASES; exports.FLAIR_EXPORT_VERSION = FLAIR_EXPORT_VERSION; exports.MOTION_ADDITIVE_PROPERTIES = MOTION_ADDITIVE_PROPERTIES; exports.MOTION_BLENDS = MOTION_BLENDS; exports.MOTION_CAMERA_MS = MOTION_CAMERA_MS; exports.MOTION_CASCADES = MOTION_CASCADES; exports.MOTION_CLIP_TARGET = MOTION_CLIP_TARGET; exports.MOTION_COMMAND_SCHEMA = MOTION_COMMAND_SCHEMA; exports.MOTION_COMMAND_TYPES = MOTION_COMMAND_TYPES; exports.MOTION_DEFAULT_DURATIONS = MOTION_DEFAULT_DURATIONS; exports.MOTION_DEFAULT_HOLD = MOTION_DEFAULT_HOLD; exports.MOTION_DIRECTIONS = MOTION_DIRECTIONS; exports.MOTION_DRAW_EFFECT_ID = MOTION_DRAW_EFFECT_ID; exports.MOTION_DRAW_MS_PER_UNIT = MOTION_DRAW_MS_PER_UNIT; exports.MOTION_DRAW_RANGE = MOTION_DRAW_RANGE; exports.MOTION_DRIVEN_PROPERTIES = MOTION_DRIVEN_PROPERTIES; exports.MOTION_EASE_CHOICES = MOTION_EASE_CHOICES; exports.MOTION_EASE_IN_OUT = MOTION_EASE_IN_OUT; exports.MOTION_EASE_OUT = MOTION_EASE_OUT; exports.MOTION_EDIT_OPS = MOTION_EDIT_OPS; exports.MOTION_ENTER_STYLES = MOTION_ENTER_STYLES; exports.MOTION_EXIT_STYLES = MOTION_EXIT_STYLES; exports.MOTION_IRIS_SHAPES = MOTION_IRIS_SHAPES; exports.MOTION_ISSUE_CODES = _chunkWAJQKWQUcjs.MOTION_ISSUE_CODES; exports.MOTION_MIN_CHANGE_MS = MOTION_MIN_CHANGE_MS; exports.MOTION_REPEAT_MODES = MOTION_REPEAT_MODES; exports.MOTION_SPEED_RANGE = MOTION_SPEED_RANGE; exports.MOTION_SPLIT_ORIENTATIONS = MOTION_SPLIT_ORIENTATIONS; exports.MOTION_TEXT_STAGGER = MOTION_TEXT_STAGGER; exports.MOTION_TEXT_UNITS = MOTION_TEXT_UNITS; exports.MOTION_TRIGGERS = MOTION_TRIGGERS; exports.MotionSceneFormatError = MotionSceneFormatError; exports.activeSegment = activeSegment; exports.applyMotionControlValues = applyMotionControlValues; exports.applyMotionDrivers = applyMotionDrivers; exports.applyMotionEdits = applyMotionEdits; exports.checkMotionScene = checkMotionScene; exports.clipsShapeProblems = clipsShapeProblems; exports.commandShapeProblems = commandShapeProblems; exports.compileMotionScene = compileMotionScene; exports.createAnimationEditorToolProvider = createAnimationEditorToolProvider; exports.createMotionScene = createMotionScene; exports.defaultMotionCommand = defaultMotionCommand; exports.describeMotionElements = describeMotionElements; exports.describeMotionShots = describeMotionShots; exports.driversShapeProblems = driversShapeProblems; exports.duplicateMotionCommandEdit = duplicateMotionCommandEdit; exports.fitMotionRect = fitMotionRect; exports.fitMotionScene = fitMotionScene; exports.fitMotionSceneEdits = fitMotionSceneEdits; exports.flairAtLeast = flairAtLeast; exports.flairCurveFor = flairCurveFor; exports.flairEaseFor = flairEaseFor; exports.formatMotionDrivers = formatMotionDrivers; exports.formatMotionNarration = formatMotionNarration; exports.freshShotId = freshShotId; exports.fromFlairSvgMotion = fromFlairSvgMotion; exports.fromFlairVectorEffect = fromFlairVectorEffect; exports.fromPptxAnimation = fromPptxAnimation; exports.highlightMotionSvg = highlightMotionSvg; exports.indexMotionNodes = indexMotionNodes; exports.interpolateMotionValue = interpolateMotionValue; exports.isMotionCommand = isMotionCommand; exports.isMotionShot = isMotionShot; exports.matchMotionNodes = matchMotionNodes; exports.motionAddTrackKey = motionAddTrackKey; exports.motionBeatAt = motionBeatAt; exports.motionBeatTime = motionBeatTime; exports.motionBlurTimes = motionBlurTimes; exports.motionCascade = motionCascade; exports.motionClipAttrs = motionClipAttrs; exports.motionClipLayout = motionClipLayout; exports.motionCommandDuration = motionCommandDuration; exports.motionCommandFields = motionCommandFields; exports.motionCommandRepeat = motionCommandRepeat; exports.motionCommandRows = motionCommandRows; exports.motionCommandSlots = motionCommandSlots; exports.motionCommandSummary = motionCommandSummary; exports.motionContactSheetSvg = motionContactSheetSvg; exports.motionCueChoices = motionCueChoices; exports.motionCueFromKey = motionCueFromKey; exports.motionCueKey = motionCueKey; exports.motionCueTime = motionCueTime; exports.motionCycleDuration = motionCycleDuration; exports.motionDrivenNodes = motionDrivenNodes; exports.motionDriverSources = motionDriverSources; exports.motionEaseKey = motionEaseKey; exports.motionEasingCurve = motionEasingCurve; exports.motionEasingGuides = motionEasingGuides; exports.motionEasingPath = motionEasingPath; exports.motionFieldEdit = motionFieldEdit; exports.motionFieldLabel = motionFieldLabel; exports.motionFlairPrimitive = motionFlairPrimitive; exports.motionFollowRoute = motionFollowRoute; exports.motionFrameAt = motionFrameAt; exports.motionFrameToSvg = motionFrameToSvg; exports.motionGhosts = motionGhosts; exports.motionIssue = _chunkWAJQKWQUcjs.motionIssue; exports.motionIssueKey = _chunkWAJQKWQUcjs.motionIssueKey; exports.motionIssueLine = _chunkWAJQKWQUcjs.motionIssueLine; exports.motionMovingIds = motionMovingIds; exports.motionNodeAtElement = motionNodeAtElement; exports.motionNodeClips = motionNodeClips; exports.motionNodeOffset = motionNodeOffset; exports.motionPath = motionPath; exports.motionPathLength = motionPathLength; exports.motionPathsSvg = motionPathsSvg; exports.motionPropertyValue = motionPropertyValue; exports.motionRestValue = motionRestValue; exports.motionRevealClip = motionRevealClip; exports.motionRevealPadding = motionRevealPadding; exports.motionRulerTicks = motionRulerTicks; exports.motionSceneShapeProblems = motionSceneShapeProblems; exports.motionSceneToJson = motionSceneToJson; exports.motionShotAt = motionShotAt; exports.motionShotCueTime = motionShotCueTime; exports.motionShotTimeScale = motionShotTimeScale; exports.motionStageSvg = motionStageSvg; exports.motionTextLayout = motionTextLayout; exports.motionTextUnits = motionTextUnits; exports.motionTrackKey = motionTrackKey; exports.namedWithSuggestion = _chunkWAJQKWQUcjs.namedWithSuggestion; exports.parseMotionDrivers = parseMotionDrivers; exports.parseMotionFieldInput = parseMotionFieldInput; exports.parseMotionNarration = parseMotionNarration; exports.parseMotionScene = parseMotionScene; exports.resolveMotionCamera = resolveMotionCamera; exports.resolveMotionEditRefs = resolveMotionEditRefs; exports.segmentProgress = segmentProgress; exports.segmentValue = segmentValue; exports.shotShapeProblems = shotShapeProblems; exports.smoothMotionLegs = smoothMotionLegs; exports.smoothMotionTimes = smoothMotionTimes; exports.suggestName = _chunkWAJQKWQUcjs.suggestName; exports.toFlairEffectDocument = toFlairEffectDocument; exports.toFlairSvgMotion = toFlairSvgMotion; exports.toFlairVectorEffect = toFlairVectorEffect; exports.toLottie = toLottie; exports.trackValue = trackValue; exports.withMotionLayers = withMotionLayers; exports.withViewBox = withViewBox;
5454
+ exports.ANIMATION_EDITOR_AGENT_INSTRUCTIONS = ANIMATION_EDITOR_AGENT_INSTRUCTIONS; exports.AnimationEditorController = AnimationEditorController; exports.FLAIR_EASES = FLAIR_EASES; exports.FLAIR_EXPORT_VERSION = FLAIR_EXPORT_VERSION; exports.MOTION_ADDITIVE_PROPERTIES = MOTION_ADDITIVE_PROPERTIES; exports.MOTION_BLENDS = MOTION_BLENDS; exports.MOTION_CAMERA_MS = MOTION_CAMERA_MS; exports.MOTION_CASCADES = MOTION_CASCADES; exports.MOTION_CLIP_TARGET = MOTION_CLIP_TARGET; exports.MOTION_COMMAND_SCHEMA = MOTION_COMMAND_SCHEMA; exports.MOTION_COMMAND_TYPES = MOTION_COMMAND_TYPES; exports.MOTION_DEFAULT_DURATIONS = MOTION_DEFAULT_DURATIONS; exports.MOTION_DEFAULT_HOLD = MOTION_DEFAULT_HOLD; exports.MOTION_DIRECTIONS = MOTION_DIRECTIONS; exports.MOTION_DRAW_EFFECT_ID = MOTION_DRAW_EFFECT_ID; exports.MOTION_DRAW_MS_PER_UNIT = MOTION_DRAW_MS_PER_UNIT; exports.MOTION_DRAW_RANGE = MOTION_DRAW_RANGE; exports.MOTION_DRIVEN_PROPERTIES = MOTION_DRIVEN_PROPERTIES; exports.MOTION_EASE_CHOICES = MOTION_EASE_CHOICES; exports.MOTION_EASE_IN_OUT = MOTION_EASE_IN_OUT; exports.MOTION_EASE_OUT = MOTION_EASE_OUT; exports.MOTION_EDIT_OPS = MOTION_EDIT_OPS; exports.MOTION_ENTER_STYLES = MOTION_ENTER_STYLES; exports.MOTION_EXIT_STYLES = MOTION_EXIT_STYLES; exports.MOTION_IRIS_SHAPES = MOTION_IRIS_SHAPES; exports.MOTION_ISSUE_CODES = _chunkWAJQKWQUcjs.MOTION_ISSUE_CODES; exports.MOTION_MIN_CHANGE_MS = MOTION_MIN_CHANGE_MS; exports.MOTION_REPEAT_MODES = MOTION_REPEAT_MODES; exports.MOTION_SPEED_RANGE = MOTION_SPEED_RANGE; exports.MOTION_SPLIT_ORIENTATIONS = MOTION_SPLIT_ORIENTATIONS; exports.MOTION_TEXT_STAGGER = MOTION_TEXT_STAGGER; exports.MOTION_TEXT_UNITS = MOTION_TEXT_UNITS; exports.MOTION_TRIGGERS = MOTION_TRIGGERS; exports.MotionSceneFormatError = MotionSceneFormatError; exports.activeSegment = activeSegment; exports.applyMotionControlValues = applyMotionControlValues; exports.applyMotionDrivers = applyMotionDrivers; exports.applyMotionEdits = applyMotionEdits; exports.checkMotionScene = checkMotionScene; exports.clipsShapeProblems = clipsShapeProblems; exports.commandShapeProblems = commandShapeProblems; exports.compileMotionScene = compileMotionScene; exports.createAnimationEditorToolProvider = createAnimationEditorToolProvider; exports.createAnimationEffectsToolProvider = createAnimationEffectsToolProvider; exports.createMotionScene = createMotionScene; exports.defaultMotionCommand = defaultMotionCommand; exports.describeMotionElements = describeMotionElements; exports.describeMotionShots = describeMotionShots; exports.driversShapeProblems = driversShapeProblems; exports.duplicateMotionCommandEdit = duplicateMotionCommandEdit; exports.fitMotionRect = fitMotionRect; exports.fitMotionScene = fitMotionScene; exports.fitMotionSceneEdits = fitMotionSceneEdits; exports.flairAtLeast = flairAtLeast; exports.flairCurveFor = flairCurveFor; exports.flairEaseFor = flairEaseFor; exports.formatMotionDrivers = formatMotionDrivers; exports.formatMotionNarration = formatMotionNarration; exports.freshShotId = freshShotId; exports.fromFlairSvgMotion = fromFlairSvgMotion; exports.fromFlairVectorEffect = fromFlairVectorEffect; exports.fromPptxAnimation = fromPptxAnimation; exports.highlightMotionSvg = highlightMotionSvg; exports.indexMotionNodes = indexMotionNodes; exports.interpolateMotionValue = interpolateMotionValue; exports.isMotionCommand = isMotionCommand; exports.isMotionShot = isMotionShot; exports.matchMotionNodes = matchMotionNodes; exports.motionAddTrackKey = motionAddTrackKey; exports.motionArtworkSvg = motionArtworkSvg; exports.motionBeatAt = motionBeatAt; exports.motionBeatTime = motionBeatTime; exports.motionBlurTimes = motionBlurTimes; exports.motionCascade = motionCascade; exports.motionClipAttrs = motionClipAttrs; exports.motionClipLayout = motionClipLayout; exports.motionCommandDuration = motionCommandDuration; exports.motionCommandFields = motionCommandFields; exports.motionCommandRepeat = motionCommandRepeat; exports.motionCommandRows = motionCommandRows; exports.motionCommandSlots = motionCommandSlots; exports.motionCommandSummary = motionCommandSummary; exports.motionCommandsFromEffect = motionCommandsFromEffect; exports.motionContactSheetSvg = motionContactSheetSvg; exports.motionCueChoices = motionCueChoices; exports.motionCueFromKey = motionCueFromKey; exports.motionCueKey = motionCueKey; exports.motionCueTime = motionCueTime; exports.motionCycleDuration = motionCycleDuration; exports.motionDrivenNodes = motionDrivenNodes; exports.motionDriverSources = motionDriverSources; exports.motionEaseKey = motionEaseKey; exports.motionEasingCurve = motionEasingCurve; exports.motionEasingGuides = motionEasingGuides; exports.motionEasingPath = motionEasingPath; exports.motionFieldEdit = motionFieldEdit; exports.motionFieldLabel = motionFieldLabel; exports.motionFlairPrimitive = motionFlairPrimitive; exports.motionFollowRoute = motionFollowRoute; exports.motionFrameAt = motionFrameAt; exports.motionFrameToSvg = motionFrameToSvg; exports.motionGhosts = motionGhosts; exports.motionIssue = _chunkWAJQKWQUcjs.motionIssue; exports.motionIssueKey = _chunkWAJQKWQUcjs.motionIssueKey; exports.motionIssueLine = _chunkWAJQKWQUcjs.motionIssueLine; exports.motionMovingIds = motionMovingIds; exports.motionNodeAtElement = motionNodeAtElement; exports.motionNodeClips = motionNodeClips; exports.motionNodeOffset = motionNodeOffset; exports.motionPartsFromVectorEffect = motionPartsFromVectorEffect; exports.motionPath = motionPath; exports.motionPathLength = motionPathLength; exports.motionPathsSvg = motionPathsSvg; exports.motionPropertyValue = motionPropertyValue; exports.motionRestValue = motionRestValue; exports.motionRevealClip = motionRevealClip; exports.motionRevealPadding = motionRevealPadding; exports.motionRulerTicks = motionRulerTicks; exports.motionSceneEffects = motionSceneEffects; exports.motionSceneShapeProblems = motionSceneShapeProblems; exports.motionSceneToJson = motionSceneToJson; exports.motionShotAt = motionShotAt; exports.motionShotCueTime = motionShotCueTime; exports.motionShotTimeScale = motionShotTimeScale; exports.motionStageSvg = motionStageSvg; exports.motionTextLayout = motionTextLayout; exports.motionTextUnits = motionTextUnits; exports.motionTrackKey = motionTrackKey; exports.namedWithSuggestion = _chunkWAJQKWQUcjs.namedWithSuggestion; exports.nextMotionEffectInstance = nextMotionEffectInstance; exports.parseMotionDrivers = parseMotionDrivers; exports.parseMotionFieldInput = parseMotionFieldInput; exports.parseMotionNarration = parseMotionNarration; exports.parseMotionScene = parseMotionScene; exports.resolveMotionCamera = resolveMotionCamera; exports.resolveMotionEditRefs = resolveMotionEditRefs; exports.segmentProgress = segmentProgress; exports.segmentValue = segmentValue; exports.shotShapeProblems = shotShapeProblems; exports.smoothMotionLegs = smoothMotionLegs; exports.smoothMotionTimes = smoothMotionTimes; exports.suggestName = _chunkWAJQKWQUcjs.suggestName; exports.toFlairEffectDocument = toFlairEffectDocument; exports.toFlairSvgMotion = toFlairSvgMotion; exports.toFlairVectorEffect = toFlairVectorEffect; exports.toLottie = toLottie; exports.trackValue = trackValue; exports.withMotionLayers = withMotionLayers; exports.withViewBox = withViewBox; exports.withoutMotionEffect = withoutMotionEffect;
5118
5455
  //# sourceMappingURL=index.cjs.map