@pixerate/editor 0.124.1 → 0.125.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 +424 -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 +348 -9
  9. package/dist/animation-editor/index.js.map +1 -1
  10. package/dist/chunk-FJ3324TZ.js +59 -0
  11. package/dist/chunk-FJ3324TZ.js.map +1 -0
  12. package/dist/{chunk-5EO2IXQE.js → chunk-FPRIUR4T.js} +1 -1
  13. package/dist/chunk-FPRIUR4T.js.map +1 -0
  14. package/dist/{chunk-ORHMVUR6.js → chunk-G6WXWS4Y.js} +5 -3
  15. package/dist/{chunk-ORHMVUR6.js.map → chunk-G6WXWS4Y.js.map} +1 -1
  16. package/dist/{chunk-CN4PJHUG.cjs → chunk-IOXKXQNW.cjs} +3 -59
  17. package/dist/chunk-IOXKXQNW.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-FHYDQOPC.cjs → chunk-QDJKUBWE.cjs} +5 -5
  22. package/dist/{chunk-FHYDQOPC.cjs.map → chunk-QDJKUBWE.cjs.map} +1 -1
  23. package/dist/{chunk-5XXMLBH4.cjs → chunk-QQKTOA4U.cjs} +1 -1
  24. package/dist/chunk-QQKTOA4U.cjs.map +1 -0
  25. package/dist/{chunk-QEG3GRN2.js → chunk-TGKT5QAB.js} +2 -58
  26. package/dist/chunk-TGKT5QAB.js.map +1 -0
  27. package/dist/{chunk-4QQZV5Y5.cjs → chunk-UXFI3CDZ.cjs} +11 -9
  28. package/dist/chunk-UXFI3CDZ.cjs.map +1 -0
  29. package/dist/{chunk-WE25VLCO.cjs → chunk-V5YGPRCZ.cjs} +36 -36
  30. package/dist/{chunk-WE25VLCO.cjs.map → chunk-V5YGPRCZ.cjs.map} +1 -1
  31. package/dist/chunk-W6QTLHZ3.cjs +59 -0
  32. package/dist/chunk-W6QTLHZ3.cjs.map +1 -0
  33. package/dist/{chunk-WATAQ2Z2.js → chunk-WUDPFWAN.js} +2 -2
  34. package/dist/{chunk-JRXJTPES.js → chunk-XZWOLXWA.js} +4 -4
  35. package/dist/{chunk-JRXJTPES.js.map → chunk-XZWOLXWA.js.map} +1 -1
  36. package/dist/effects/index.cjs +61 -33
  37. package/dist/effects/index.cjs.map +1 -1
  38. package/dist/effects/index.d.cts +4 -5
  39. package/dist/effects/index.d.ts +4 -5
  40. package/dist/effects/index.js +32 -4
  41. package/dist/effects/index.js.map +1 -1
  42. package/dist/{export-WmYoWmLM.d.cts → export-Bp7ji2r4.d.cts} +1 -2
  43. package/dist/{export-BdfY_lH0.d.ts → export-C1s4eolZ.d.ts} +1 -1
  44. package/dist/{export-BGtXgMJ3.d.ts → export-DAyPY94f.d.ts} +1 -2
  45. package/dist/{export-CbpjwxaI.d.cts → export-DVl4fWy5.d.cts} +1 -1
  46. package/dist/generation/index.cjs +3 -3
  47. package/dist/generation/index.cjs.map +1 -1
  48. package/dist/generation/index.js +3 -3
  49. package/dist/helpers-BBLlekuM.d.ts +2009 -0
  50. package/dist/helpers-i95Ob6Vi.d.cts +2009 -0
  51. package/dist/image-editor/index.cjs +629 -627
  52. package/dist/image-editor/index.cjs.map +1 -1
  53. package/dist/image-editor/index.d.cts +5 -7
  54. package/dist/image-editor/index.d.ts +5 -7
  55. package/dist/image-editor/index.js +15 -13
  56. package/dist/image-editor/index.js.map +1 -1
  57. package/dist/paint-editor/index.cjs +12 -11
  58. package/dist/paint-editor/index.cjs.map +1 -1
  59. package/dist/paint-editor/index.d.cts +3 -5
  60. package/dist/paint-editor/index.d.ts +3 -5
  61. package/dist/paint-editor/index.js +6 -5
  62. package/dist/paint-editor/index.js.map +1 -1
  63. package/dist/{svg-BDrjRnL1.d.cts → svg-BkRL-fZJ.d.cts} +1 -1
  64. package/dist/{svg-C-vZ3q50.d.ts → svg-DJKriJ4A.d.ts} +1 -1
  65. package/dist/tools/index.cjs +2 -2
  66. package/dist/tools/index.cjs.map +1 -1
  67. package/dist/tools/index.js +3 -3
  68. package/dist/{tools-C7JtLYzo.d.ts → tools-CM8Oe8F3.d.ts} +1 -1
  69. package/dist/{tools-DHKGHiSK.d.cts → tools-DZCv2kX1.d.cts} +1 -1
  70. package/dist/vector/index.cjs +1032 -883
  71. package/dist/vector/index.cjs.map +1 -1
  72. package/dist/vector/index.d.cts +61 -6
  73. package/dist/vector/index.d.ts +61 -6
  74. package/dist/vector/index.js +155 -6
  75. package/dist/vector/index.js.map +1 -1
  76. package/dist/video-editor/index.cjs +273 -272
  77. package/dist/video-editor/index.cjs.map +1 -1
  78. package/dist/video-editor/index.d.cts +4 -6
  79. package/dist/video-editor/index.d.ts +4 -6
  80. package/dist/video-editor/index.js +7 -6
  81. package/dist/video-editor/index.js.map +1 -1
  82. package/package.json +1 -1
  83. package/skills/pixerate-animation-editor/SKILL.md +24 -1
  84. package/skills/pixerate-vector/SKILL.md +15 -0
  85. package/dist/chunk-4QQZV5Y5.cjs.map +0 -1
  86. package/dist/chunk-5EO2IXQE.js.map +0 -1
  87. package/dist/chunk-5XXMLBH4.cjs.map +0 -1
  88. package/dist/chunk-CN4PJHUG.cjs.map +0 -1
  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,16 @@ 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
+ var _chunkQDJKUBWEcjs = require('../chunk-QDJKUBWE.cjs');
38
+
39
+
40
+
41
+
42
+
43
+ var _chunkIOXKXQNWcjs = require('../chunk-IOXKXQNW.cjs');
35
44
 
36
45
 
37
46
 
@@ -40,6 +49,7 @@ var _chunk5XXMLBH4cjs = require('../chunk-5XXMLBH4.cjs');
40
49
 
41
50
  var _chunkN3FVUOZDcjs = require('../chunk-N3FVUOZD.cjs');
42
51
  require('../chunk-GUZ47CJM.cjs');
52
+ require('../chunk-RIWPYSKU.cjs');
43
53
 
44
54
 
45
55
  var _chunkEMQWJA3Gcjs = require('../chunk-EMQWJA3G.cjs');
@@ -166,7 +176,7 @@ ${problems.map((p) => `- ${p}`).join("\n")}`);
166
176
  var SCENE_KEYS = ["version", "name", "description", "artwork", "shots", "clips", "drivers", "motionBlur", "loop", "trigger", "fps", "steps", "beat", "narration", "target", "controls", "presets"];
167
177
  var SHOT_KEYS = ["id", "label", "camera", "at", "run", "hold", "speed"];
168
178
  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"];
179
+ var BASE_KEYS = ["type", "targets", "duration", "delay", "stagger", "with", "ease", "note", "repeat", "repeatMode", "steps", "split", "cascade", "source"];
170
180
  var DRAW_ORDER_KEYS = ["order", "pace", "align", "sortBy", "origin"];
171
181
  var COMMAND_KEYS = {
172
182
  enter: [...BASE_KEYS, ...DRAW_ORDER_KEYS, "style", "direction", "distance", "scale", "shape", "orientation"],
@@ -224,6 +234,11 @@ function commandShapeProblems(command3, where) {
224
234
  if (command3.origin !== void 0 && !isPoint(command3.origin)) p(`"origin" must be { "x": number, "y": number } (document units).`);
225
235
  }
226
236
  if (command3.note !== void 0 && typeof command3.note !== "string") p(`"note" must be a string.`);
237
+ if (command3.source !== void 0) {
238
+ const src = command3.source;
239
+ 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).`);
240
+ else unknownKeys(src, ["instance", "effect", "provider", "name", "values"], `${where} (${type}) source`, problems);
241
+ }
227
242
  if (type === "wait") {
228
243
  if (!isNum(command3.duration) || command3.duration < 0) p(`"duration" must be a number of milliseconds \u2265 0.`);
229
244
  return problems;
@@ -560,7 +575,7 @@ function smoothMotionTimes(points, start, duration, pacing = "even") {
560
575
  function motionTextLayout(nodes, id) {
561
576
  const group = _optionalChain([nodes, 'access', _5 => _5.get, 'call', _6 => _6(id), 'optionalAccess', _7 => _7.node]);
562
577
  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);
578
+ 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
579
  if (!letters.length) return null;
565
580
  const lines = [];
566
581
  for (const l of [...letters].sort((a, c) => a.b.y + a.b.height / 2 - (c.b.y + c.b.height / 2))) {
@@ -645,21 +660,21 @@ function indexMotionNodes(nodes) {
645
660
  const out = /* @__PURE__ */ new Map();
646
661
  const walk = (list, parentWorld, ancestors) => {
647
662
  for (const node of list) {
648
- const local = _chunk5XXMLBH4cjs.vectorNodeBounds.call(void 0, node);
649
- const bounds = _chunk5XXMLBH4cjs.vectorNodeBounds.call(void 0, node, parentWorld);
663
+ const local = _chunkQQKTOA4Ucjs.vectorNodeBounds.call(void 0, node);
664
+ const bounds = _chunkQQKTOA4Ucjs.vectorNodeBounds.call(void 0, node, parentWorld);
650
665
  const center = local ? { x: local.x + local.width / 2, y: local.y + local.height / 2 } : { x: 0, y: 0 };
651
666
  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]);
667
+ if (node.type === "group") walk(node.children, _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, node), parentWorld), [...ancestors, node.id]);
653
668
  }
654
669
  };
655
- walk(nodes, _chunk5XXMLBH4cjs.IDENTITY_MATRIX, []);
670
+ walk(nodes, _chunkQQKTOA4Ucjs.IDENTITY_MATRIX, []);
656
671
  indexCache.set(nodes, out);
657
672
  return out;
658
673
  }
659
674
  var solid = (paint) => typeof paint === "string" && paint !== "none" ? paint : void 0;
660
675
  function firstPaint(node, key) {
661
676
  if (node.type === "path") return solid(node[key]);
662
- for (const p of _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node)) {
677
+ for (const p of _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node)) {
663
678
  const s = solid(p[key]);
664
679
  if (s) return s;
665
680
  }
@@ -667,7 +682,7 @@ function firstPaint(node, key) {
667
682
  }
668
683
  function strokeReach(node) {
669
684
  let reach = 0;
670
- for (const p of node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node)) {
685
+ for (const p of node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node)) {
671
686
  if (p.stroke == null || p.stroke === "none") continue;
672
687
  const width = _nullishCoalesce(p.strokeWidth, () => ( 1));
673
688
  reach = Math.max(reach, p.strokeAlign === "outside" ? width : p.strokeAlign === "inside" ? 0 : width / 2);
@@ -737,7 +752,7 @@ function motionRestValue(entry, property, artwork) {
737
752
  case "stroke":
738
753
  return _nullishCoalesce((node && firstPaint(node, property)), () => ( "transparent"));
739
754
  case "strokeWidth": {
740
- const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ? _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node)[0] : void 0;
755
+ const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ? _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node)[0] : void 0;
741
756
  return _nullishCoalesce(_optionalChain([path, 'optionalAccess', _14 => _14.strokeWidth]), () => ( 1));
742
757
  }
743
758
  case "shape":
@@ -848,12 +863,12 @@ function resolveMotionCamera(camera, scene) {
848
863
  const r = camera;
849
864
  return { x: r.x, y: r.y, width: r.width, height: r.height };
850
865
  }
851
- function motionPathLength(node, parentWorld = _chunk5XXMLBH4cjs.IDENTITY_MATRIX) {
866
+ function motionPathLength(node, parentWorld = _chunkQQKTOA4Ucjs.IDENTITY_MATRIX) {
852
867
  let longest = 0;
853
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
868
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
854
869
  for (const p of paths) {
855
870
  try {
856
- longest = Math.max(longest, _chunkN3FVUOZDcjs.bezierPathLength.call(void 0, _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, p, parentWorld, { effects: false })));
871
+ longest = Math.max(longest, _chunkN3FVUOZDcjs.bezierPathLength.call(void 0, _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, p, parentWorld, { effects: false })));
857
872
  } catch (e2) {
858
873
  }
859
874
  }
@@ -1106,12 +1121,12 @@ function compileMotionScene(scene) {
1106
1121
  const order2 = _nullishCoalesce(o.order, () => ( "together"));
1107
1122
  const pace = _nullishCoalesce(o.pace, () => ( "time"));
1108
1123
  if (order2 === "together" && pace === "time") return null;
1109
- const paths = entry.node.type === "path" ? [entry.node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, entry.node);
1124
+ const paths = entry.node.type === "path" ? [entry.node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, entry.node);
1110
1125
  let list = paths.map((p) => {
1111
1126
  const at = nodes.get(p.id);
1112
1127
  let first = { x: 0, y: 0 };
1113
1128
  try {
1114
- const m = _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, p, _nullishCoalesce(_optionalChain([at, 'optionalAccess', _41 => _41.parentWorld]), () => ( _chunk5XXMLBH4cjs.IDENTITY_MATRIX)), { effects: false })[0];
1129
+ const m = _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, p, _nullishCoalesce(_optionalChain([at, 'optionalAccess', _41 => _41.parentWorld]), () => ( _chunkQQKTOA4Ucjs.IDENTITY_MATRIX)), { effects: false })[0];
1115
1130
  if (m && m.type === "M") first = { x: m.x, y: m.y };
1116
1131
  } catch (e3) {
1117
1132
  }
@@ -1223,17 +1238,17 @@ function compileMotionScene(scene) {
1223
1238
  let dx = _nullishCoalesce(_optionalChain([command3, 'access', _44 => _44.by, 'optionalAccess', _45 => _45.x]), () => ( 0));
1224
1239
  let dy = _nullishCoalesce(_optionalChain([command3, 'access', _46 => _46.by, 'optionalAccess', _47 => _47.y]), () => ( 0));
1225
1240
  if (command3.to) {
1226
- const inv = _chunk5XXMLBH4cjs.invertMatrix.call(void 0, entry.parentWorld);
1227
- const target = _chunk5XXMLBH4cjs.applyMatrix.call(void 0, inv, command3.to);
1241
+ const inv = _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, entry.parentWorld);
1242
+ const target = _chunkQQKTOA4Ucjs.applyMatrix.call(void 0, inv, command3.to);
1228
1243
  dx = target.x - (entry.center.x + num2("x"));
1229
1244
  dy = target.y - (entry.center.y + num2("y"));
1230
1245
  }
1231
1246
  if (_optionalChain([command3, 'access', _48 => _48.via, 'optionalAccess', _49 => _49.length])) {
1232
- const inv = _chunk5XXMLBH4cjs.invertMatrix.call(void 0, entry.parentWorld);
1247
+ const inv = _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, entry.parentWorld);
1233
1248
  const x0 = num2("x");
1234
1249
  const y0 = num2("y");
1235
1250
  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 }];
1251
+ 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
1252
  const times = smoothMotionTimes(offsets, start, end - start, _nullishCoalesce(command3.pacing, () => ( "even")));
1238
1253
  for (const axis of ["x", "y"]) {
1239
1254
  const base = add ? 0 : axis === "x" ? x0 : y0;
@@ -1376,13 +1391,13 @@ function morphBetween(a, b) {
1376
1391
  let inner = morphCache.get(a);
1377
1392
  if (!inner) morphCache.set(a, inner = /* @__PURE__ */ new WeakMap());
1378
1393
  let morph = inner.get(b);
1379
- if (!morph) inner.set(b, morph = _chunkWE25VLCOcjs.createVectorMorph.call(void 0, a, b, { id: a.id }));
1394
+ if (!morph) inner.set(b, morph = _chunkV5YGPRCZcjs.createVectorMorph.call(void 0, a, b, { id: a.id }));
1380
1395
  return morph;
1381
1396
  }
1382
1397
  function shapeIn(entry, shape) {
1383
1398
  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 } };
1399
+ 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));
1400
+ return { ...shape.node, ..._chunkQQKTOA4Ucjs.isIdentityMatrix.call(void 0, m) ? { transform: void 0 } : { transform: m } };
1386
1401
  }
1387
1402
  function shapeAt(entry, timeline, nodes, time) {
1388
1403
  const track = timeline.tracks.get(motionTrackKey(entry.node.id, "shape"));
@@ -1402,7 +1417,7 @@ function shapeAt(entry, timeline, nodes, time) {
1402
1417
  function motionFollowRoute(entry, path) {
1403
1418
  if (!path || path.node.type !== "path") return null;
1404
1419
  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));
1420
+ 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
1421
  } catch (e4) {
1407
1422
  return null;
1408
1423
  }
@@ -1436,9 +1451,9 @@ function motionNodeOffset(entry, timeline, time, nodes = indexMotionNodes([entry
1436
1451
  const scaleX = read("scaleX", 1);
1437
1452
  const scaleY = read("scaleY", 1);
1438
1453
  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));
1454
+ 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
1455
  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)));
1456
+ 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
1457
  return { matrix, dx, dy, rotation, scaleX, scaleY, follow: along };
1443
1458
  }
1444
1459
  function motionNodeClips(id, timeline, time) {
@@ -1505,7 +1520,7 @@ function motionFrameAt(scene, time, options = {}) {
1505
1520
  const start = Math.min(1, Math.max(0, typeof drawStart === "number" ? drawStart : 0));
1506
1521
  const end = Math.min(1, Math.max(0, typeof drawEnd === "number" ? drawEnd : 1));
1507
1522
  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) });
1523
+ const trim = _chunkQQKTOA4Ucjs.createVectorEffect.call(void 0, "trim", MOTION_DRAW_EFFECT_ID, { start: tidy(start * 100), end: tidy(end * 100) });
1509
1524
  p = { ...p, effects: [trim, ...(_nullishCoalesce(p.effects, () => ( []))).filter((e) => e.id !== MOTION_DRAW_EFFECT_ID)] };
1510
1525
  }
1511
1526
  }
@@ -1519,8 +1534,8 @@ function motionFrameAt(scene, time, options = {}) {
1519
1534
  if (o >= 1) delete out.opacity;
1520
1535
  }
1521
1536
  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);
1537
+ if (offset && !_chunkQQKTOA4Ucjs.isIdentityMatrix.call(void 0, offset.matrix)) {
1538
+ const m = _chunkQQKTOA4Ucjs.multiplyMatrices.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, out), offset.matrix).map(tidy);
1524
1539
  out = { ...out, transform: m };
1525
1540
  }
1526
1541
  return out;
@@ -1540,7 +1555,7 @@ function motionFrameToSvg(scene, time, options = {}) {
1540
1555
  const wrap = { ...options.wrap };
1541
1556
  for (const [id, clips] of Object.entries(frame.clips))
1542
1557
  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);
1558
+ return withViewBox(_chunkQQKTOA4Ucjs.vectorDocumentToSvg.call(void 0, frame.document, { ...options, wrap }), frame.camera);
1544
1559
  }
1545
1560
  function withViewBox(svg, box) {
1546
1561
  const f = (n) => String(Math.round(n * 1e3) / 1e3);
@@ -1723,8 +1738,8 @@ function visibleAt(timeline, id, time, node) {
1723
1738
  if (Array.isArray(rect) && (rect[2] <= 1e-4 || rect[3] <= 1e-4)) return false;
1724
1739
  const circle = clip("clipCircle");
1725
1740
  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) => {
1741
+ const hasFill = node.type === "path" ? !!node.fill && node.fill !== "none" : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node).some((p) => p.fill && p.fill !== "none");
1742
+ 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
1743
  const v = trackValue(timeline.tracks.get(motionTrackKey(p.id, "drawEnd")), time);
1729
1744
  return typeof v !== "number" || v > 0.01;
1730
1745
  }));
@@ -1810,7 +1825,7 @@ function checkMotionScene(scene) {
1810
1825
  }
1811
1826
  for (const id of targets) {
1812
1827
  const node = nodes.get(id).node;
1813
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
1828
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
1814
1829
  if (paths.some((p) => p[key] !== void 0 && p[key] !== null && typeof p[key] !== "string"))
1815
1830
  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
1831
  }
@@ -1823,7 +1838,7 @@ function checkMotionScene(scene) {
1823
1838
  else
1824
1839
  for (const id of targets) {
1825
1840
  const node = nodes.get(id).node;
1826
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
1841
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
1827
1842
  if (paths.some((p) => typeof p[key] !== "string"))
1828
1843
  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
1844
  }
@@ -2407,7 +2422,7 @@ function toFlairSvgMotion(scene, options = {}) {
2407
2422
  raw: (t) => transformAt(t, true)
2408
2423
  });
2409
2424
  }
2410
- const paths = node.type === "path" ? [node] : _chunk5XXMLBH4cjs.collectPathNodes.call(void 0, node);
2425
+ const paths = node.type === "path" ? [node] : _chunkQQKTOA4Ucjs.collectPathNodes.call(void 0, node);
2411
2426
  for (const path of paths) {
2412
2427
  if (pathsSeen.has(path.id)) continue;
2413
2428
  pathsSeen.add(path.id);
@@ -2429,7 +2444,7 @@ function toFlairSvgMotion(scene, options = {}) {
2429
2444
  if (shapeSegments.length) {
2430
2445
  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
2446
  else {
2432
- const inverse = _chunk5XXMLBH4cjs.invertMatrix.call(void 0, _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, node));
2447
+ const inverse = _chunkQQKTOA4Ucjs.invertMatrix.call(void 0, _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, node));
2433
2448
  channels.push({
2434
2449
  id,
2435
2450
  kind: "attr",
@@ -2438,9 +2453,9 @@ function toFlairSvgMotion(scene, options = {}) {
2438
2453
  exact: () => false,
2439
2454
  value: (t) => {
2440
2455
  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]));
2456
+ 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
2457
  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);
2458
+ const bezier = _chunkN3FVUOZDcjs.transformBezierPath.call(void 0, _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, now, _chunkQQKTOA4Ucjs.IDENTITY_MATRIX, { effects: false }), inverse);
2444
2459
  return _chunkN3FVUOZDcjs.bezierPathToSvg.call(void 0, bezier, { precision: Math.min(precision, 2) });
2445
2460
  }
2446
2461
  });
@@ -2547,7 +2562,7 @@ function toFlairSvgMotion(scene, options = {}) {
2547
2562
  }
2548
2563
  if (scene.motionBlur) notes.push("Motion blur is drawn on the stage only; Flair plays the scene sharp.");
2549
2564
  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 });
2565
+ let svg = _chunkQQKTOA4Ucjs.vectorDocumentToSvg.call(void 0, { ...scene.artwork, nodes: _chunkQQKTOA4Ucjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) }, { pretty: false, precision, wrap });
2551
2566
  if (routes.length) svg = svg.replace(/^(<svg[^>]*>)/, `$1<defs>${routes.join("")}</defs>`);
2552
2567
  let motion = { svg, animate };
2553
2568
  if (_optionalChain([scene, 'access', _114 => _114.controls, 'optionalAccess', _115 => _115.length])) {
@@ -2631,14 +2646,14 @@ function easingOf(ease, fallback) {
2631
2646
  return fallback;
2632
2647
  }
2633
2648
  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);
2649
+ const t = _chunkQQKTOA4Ucjs.parseSvgTransform.call(void 0, String(value));
2650
+ 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
2651
  const sx = Math.hypot(o[0], o[1]);
2637
2652
  if (!(sx > 1e-9)) return null;
2638
2653
  const sy = (o[0] * o[3] - o[1] * o[2]) / sx;
2639
2654
  if (Math.abs(o[2] + o[1] / sx * sy) > 1e-6 || Math.abs(o[3] - o[0] / sx * sy) > 1e-6) return null;
2640
2655
  const c = entry.center;
2641
- const moved = _chunk5XXMLBH4cjs.applyMatrix.call(void 0, o, c);
2656
+ const moved = _chunkQQKTOA4Ucjs.applyMatrix.call(void 0, o, c);
2642
2657
  return { dx: moved.x - c.x, dy: moved.y - c.y, rotation: Math.atan2(o[1], o[0]) * 180 / Math.PI, sx, sy };
2643
2658
  }
2644
2659
  var near = (a, b, eps = 1e-6) => Math.abs(a - b) < eps;
@@ -2723,7 +2738,7 @@ function fromFlairSvgMotion(input, options = {}) {
2723
2738
  const notes = [];
2724
2739
  if (!input || typeof input.svg !== "string") throw new Error('Give a Flair SvgMotion: { svg: "<svg \u2026>", animate: [ \u2026 ] }.');
2725
2740
  const { motion, controls } = resolvePlaceholders(input, notes);
2726
- const artwork = _chunk5XXMLBH4cjs.parseVectorSvg.call(void 0, motion.svg);
2741
+ const artwork = _chunkQQKTOA4Ucjs.parseVectorSvg.call(void 0, motion.svg);
2727
2742
  const nodes = indexMotionNodes(artwork.nodes);
2728
2743
  const byStep = /* @__PURE__ */ new Map();
2729
2744
  for (const anim of _nullishCoalesce(motion.animate, () => ( []))) {
@@ -2970,9 +2985,9 @@ function toLottie(scene, options = {}) {
2970
2985
  const items = [];
2971
2986
  const shapeSegments = [...timeline.tracks.entries()].filter(([k]) => k.startsWith(`${path.id}\0`) && (k.endsWith("\0shape") || k.includes("\0effect:"))).flatMap(([, v]) => v);
2972
2987
  const geometryAt = (t) => {
2973
- if (!shapeSegments.length) return _chunk5XXMLBH4cjs.vectorPathWorldBezier.call(void 0, path);
2988
+ if (!shapeSegments.length) return _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, path);
2974
2989
  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);
2990
+ return now && now.type === "path" ? _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, _chunkQQKTOA4Ucjs.expandVectorAppearances.call(void 0, [now])[0]) : _chunkQQKTOA4Ucjs.vectorPathWorldBezier.call(void 0, path);
2976
2991
  };
2977
2992
  const rest = lottieContours(_chunkN3FVUOZDcjs.toBezierPath.call(void 0, geometryAt(0)), round2);
2978
2993
  rest.forEach((contour, n) => {
@@ -3045,13 +3060,13 @@ function toLottie(scene, options = {}) {
3045
3060
  const innerTr = STATIC_TR();
3046
3061
  if (node.type === "path") inner = [...pathShapes(node)];
3047
3062
  else if (node.type === "text" || node.type === "instance") {
3048
- const drawn = _chunk5XXMLBH4cjs.expandVectorAppearance.call(void 0, node);
3063
+ const drawn = _chunkQQKTOA4Ucjs.expandVectorAppearance.call(void 0, node);
3049
3064
  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)"}.`);
3065
+ 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
3066
  } else {
3052
3067
  inner = shown(node.children).reverse().map(nodeGroup);
3053
- const m = _chunk5XXMLBH4cjs.nodeMatrix.call(void 0, node);
3054
- if (m !== _chunk5XXMLBH4cjs.IDENTITY_MATRIX) {
3068
+ const m = _chunkQQKTOA4Ucjs.nodeMatrix.call(void 0, node);
3069
+ if (m !== _chunkQQKTOA4Ucjs.IDENTITY_MATRIX) {
3055
3070
  const parts = staticParts(m);
3056
3071
  if (!parts) notes.push(`"${node.id}": its transform skews, which is not exported; it is drawn without the skew.`);
3057
3072
  else {
@@ -3064,7 +3079,7 @@ function toLottie(scene, options = {}) {
3064
3079
  const body = { ty: "gr", nm: `${node.id} (own)`, it: [...inner, innerTr] };
3065
3080
  return { ty: "gr", nm: _nullishCoalesce(node.name, () => ( node.id)), it: [body, poseTransform(entry)] };
3066
3081
  };
3067
- const artwork = { ...scene.artwork, nodes: _chunk5XXMLBH4cjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) };
3082
+ const artwork = { ...scene.artwork, nodes: _chunkQQKTOA4Ucjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) };
3068
3083
  const content = shown(artwork.nodes).reverse().map(nodeGroup);
3069
3084
  if (artwork.background && rgba(artwork.background))
3070
3085
  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 +3178,11 @@ function preset(prst, w, h) {
3163
3178
  const poly = (pts) => [{ closed: true, anchors: pts.map(([x, y]) => ({ x, y })) }];
3164
3179
  switch (prst) {
3165
3180
  case "rect":
3166
- return [_chunk5XXMLBH4cjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3181
+ return [_chunkQQKTOA4Ucjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3167
3182
  case "roundRect":
3168
- return [_chunk5XXMLBH4cjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h }, Math.min(w, h) * 0.16667)];
3183
+ return [_chunkQQKTOA4Ucjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h }, Math.min(w, h) * 0.16667)];
3169
3184
  case "ellipse":
3170
- return [_chunk5XXMLBH4cjs.ellipseSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3185
+ return [_chunkQQKTOA4Ucjs.ellipseSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3171
3186
  case "triangle":
3172
3187
  return poly([[w / 2, 0], [w, h], [0, h]]);
3173
3188
  case "rtTriangle":
@@ -3275,7 +3290,7 @@ function shapes(ctx, tree, map) {
3275
3290
  let subpaths = cust ? custom(cust, w, h) : prst ? preset(prst, w, h) : null;
3276
3291
  if (!subpaths) {
3277
3292
  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 })];
3293
+ subpaths = [_chunkQQKTOA4Ucjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
3279
3294
  }
3280
3295
  const style = kid(el, "style");
3281
3296
  const fill = kid(spPr, "noFill") ? null : _nullishCoalesce(colour(ctx, kid(spPr, "solidFill")), () => ( (el.localName === "cxnSp" ? null : colour(ctx, kid(style, "fillRef")))));
@@ -3484,28 +3499,121 @@ ${problems.join("\n")}`);
3484
3499
  return { scene, notes: [...new Set(ctx.notes)], issues: checkMotionScene(scene), slides: slidePaths.length };
3485
3500
  }
3486
3501
 
3502
+ // src/animation-editor/effects.ts
3503
+ var sourceOf = (c) => c.source;
3504
+ function motionSceneEffects(scene) {
3505
+ const out = /* @__PURE__ */ new Map();
3506
+ const groups = new Set(scene.artwork.nodes.filter((n) => n.type === "group").map((n) => n.id));
3507
+ for (const shot of scene.shots) {
3508
+ for (const c of shot.run) {
3509
+ const s = sourceOf(c);
3510
+ if (!s) continue;
3511
+ let e = out.get(s.instance);
3512
+ if (!e) {
3513
+ const vector = groups.has(s.instance);
3514
+ 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 } : {} };
3515
+ out.set(s.instance, e);
3516
+ }
3517
+ if (!e.shots.includes(shot.id)) e.shots.push(shot.id);
3518
+ if (e.kind === "motion" && "targets" in c) {
3519
+ for (const t of c.targets) if (!e.targets.includes(t)) e.targets.push(t);
3520
+ }
3521
+ }
3522
+ }
3523
+ return [...out.values()];
3524
+ }
3525
+ function nextMotionEffectInstance(scene) {
3526
+ const used = /* @__PURE__ */ new Set([...motionSceneEffects(scene).map((e) => e.instance), ...scene.shots.map((s) => s.id)]);
3527
+ const walk = (nodes) => nodes.forEach((n) => (used.add(n.id), n.type === "group" && walk(n.children)));
3528
+ walk(scene.artwork.nodes);
3529
+ for (let i = 1; ; i++) if (!used.has(`fx${i}`)) return `fx${i}`;
3530
+ }
3531
+ var motionArtworkSvg = (artwork) => _chunkQQKTOA4Ucjs.vectorDocumentToSvg.call(void 0, artwork);
3532
+ var tag = (commands, source) => commands.map((c) => c.type === "wait" ? c : { ...c, source });
3533
+ function motionCommandsFromEffect(artwork, motion, source) {
3534
+ const imported = fromFlairSvgMotion({ svg: motionArtworkSvg(artwork), animate: [..._nullishCoalesce(motion.animate, () => ( []))] });
3535
+ const commands = [];
3536
+ imported.scene.shots.forEach((shot, i) => {
3537
+ shot.run.forEach((c, j) => commands.push(i > 0 && j === 0 ? { ...c, with: "after" } : c));
3538
+ });
3539
+ return { commands: tag(commands, source), notes: imported.notes };
3540
+ }
3541
+ function prefixed(nodes, shots, prefix) {
3542
+ const map = /* @__PURE__ */ new Map();
3543
+ const rename = (list) => list.map((n) => {
3544
+ map.set(n.id, prefix + n.id);
3545
+ const next = { ...n, id: prefix + n.id };
3546
+ if (next.type === "group") next.children = rename(n.children);
3547
+ return next;
3548
+ });
3549
+ const out = rename(nodes);
3550
+ const id = (v) => typeof v === "string" && map.has(v) ? map.get(v) : v;
3551
+ const remapped = shots.map((s) => ({
3552
+ ...s,
3553
+ run: s.run.map((c) => {
3554
+ const next = { ...c };
3555
+ if (Array.isArray(next.targets)) next.targets = next.targets.map((t) => id(t));
3556
+ for (const k of ["path", "into"]) if (k in next) next[k] = id(next[k]);
3557
+ return next;
3558
+ })
3559
+ }));
3560
+ return { nodes: out, shots: remapped };
3561
+ }
3562
+ function motionPartsFromVectorEffect(artwork, motion, source, box = { x: 0, y: 0, width: artwork.width, height: artwork.height }) {
3563
+ const imported = fromFlairSvgMotion({ svg: motion.svg, animate: [..._nullishCoalesce(motion.animate, () => ( []))] }, { hold: 0 });
3564
+ const art = imported.scene.artwork;
3565
+ const prefix = `${source.instance}-`;
3566
+ const { nodes, shots } = prefixed(art.nodes, imported.scene.shots, prefix);
3567
+ const k = Math.min(box.width / art.width, box.height / art.height);
3568
+ const dx = box.x + (box.width - art.width * k) / 2;
3569
+ const dy = box.y + (box.height - art.height * k) / 2;
3570
+ const group = { type: "group", id: source.instance, name: _nullishCoalesce(source.name, () => ( source.effect)), children: nodes, transform: [k, 0, 0, k, dx, dy] };
3571
+ const tagged = shots.map((s, i) => ({ ...s, id: i === 0 ? source.instance + "-shot" : `${source.instance}-shot-${i + 1}`, run: tag(s.run, source) }));
3572
+ return { group, shots: tagged.map((s) => s.hold === 0 ? (({ hold: _h, ...rest }) => rest)(s) : s), notes: imported.notes };
3573
+ }
3574
+ function withoutMotionEffect(scene, instance) {
3575
+ let place = null;
3576
+ const removedShots = [];
3577
+ const shots = [];
3578
+ for (const shot of scene.shots) {
3579
+ const run = shot.run.filter((c, i) => {
3580
+ const mine = _optionalChain([sourceOf, 'call', _152 => _152(c), 'optionalAccess', _153 => _153.instance]) === instance;
3581
+ if (mine && !place) place = { shot: shot.id, index: i };
3582
+ return !mine;
3583
+ });
3584
+ if (run.length === shot.run.length) shots.push(shot);
3585
+ else if (run.length === 0) removedShots.push(shot.id);
3586
+ else shots.push({ ...shot, run });
3587
+ }
3588
+ const artwork = { ...scene.artwork, nodes: scene.artwork.nodes.filter((n) => n.id !== instance) };
3589
+ return { scene: { ...scene, shots, artwork }, place, removedShots };
3590
+ }
3591
+
3487
3592
  // src/animation-editor/controller.ts
3488
3593
  var BLANK = { width: 800, height: 450, background: "#ffffff", nodes: [] };
3489
3594
  var AnimationEditorController = (_class = class {
3490
3595
 
3491
3596
 
3597
+ /** The effects provider slot (see `setEffectsProvider`). */
3598
+ __init() {this.effects = new (0, _chunkIOXKXQNWcjs.EffectsSlot)()}
3492
3599
 
3493
3600
 
3494
- __init() {this.selection = null}
3601
+ __init2() {this.selection = null}
3495
3602
 
3496
- __init2() {this.error = null}
3497
- __init3() {this.revision = 0}
3498
- __init4() {this.applying = false}
3603
+ __init3() {this.error = null}
3604
+ __init4() {this.revision = 0}
3605
+ __init5() {this.applying = false}
3499
3606
 
3500
- __init5() {this.listeners = /* @__PURE__ */ new Set()}
3501
- __init6() {this.unsubscribers = []}
3607
+ __init6() {this.listeners = /* @__PURE__ */ new Set()}
3608
+ __init7() {this.unsubscribers = []}
3502
3609
 
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);
3610
+ 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
3611
  this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkQKLRAA4Tcjs.HistoryManager)()));
3505
3612
  this.scene = options.scene ? parseMotionScene(options.scene) : createMotionScene(BLANK);
3506
3613
  this.issues = checkMotionScene(this.scene);
3507
3614
  this.readOnly = _nullishCoalesce(options.readOnly, () => ( false));
3508
3615
  this.onChange = options.onChange;
3616
+ if (options.effects) this.effects.set(options.effects);
3509
3617
  this.player = new (0, _chunk477UVMNRcjs.AnimationPlayer)({ clock: options.clock, duration: () => compileMotionScene(this.scene).duration, loop: _nullishCoalesce(this.scene.loop, () => ( "none")) });
3510
3618
  this.state = this.computeState();
3511
3619
  this.connect();
@@ -3516,7 +3624,8 @@ var AnimationEditorController = (_class = class {
3516
3624
  this.player.subscribe(() => this.notify()),
3517
3625
  this.history.subscribe(() => {
3518
3626
  if (!this.applying) this.notify();
3519
- })
3627
+ }),
3628
+ this.effects.subscribe(() => this.notify())
3520
3629
  );
3521
3630
  }
3522
3631
  /**
@@ -3527,8 +3636,8 @@ var AnimationEditorController = (_class = class {
3527
3636
  this.player.pause();
3528
3637
  this.unsubscribers.splice(0).forEach((u) => u());
3529
3638
  }
3530
- __init7() {this.getState = () => this.state}
3531
- __init8() {this.subscribe = (listener) => {
3639
+ __init8() {this.getState = () => this.state}
3640
+ __init9() {this.subscribe = (listener) => {
3532
3641
  this.connect();
3533
3642
  this.listeners.add(listener);
3534
3643
  return () => {
@@ -3551,7 +3660,7 @@ var AnimationEditorController = (_class = class {
3551
3660
  time: p.time,
3552
3661
  playing: p.playing,
3553
3662
  loop: p.loop,
3554
- currentShot: _nullishCoalesce(_optionalChain([motionShotAt, 'call', _152 => _152(timeline, p.time), 'optionalAccess', _153 => _153.id]), () => ( null)),
3663
+ currentShot: _nullishCoalesce(_optionalChain([motionShotAt, 'call', _154 => _154(timeline, p.time), 'optionalAccess', _155 => _155.id]), () => ( null)),
3555
3664
  selection: this.selection,
3556
3665
  readOnly: this.readOnly,
3557
3666
  error: this.error,
@@ -3559,7 +3668,8 @@ var AnimationEditorController = (_class = class {
3559
3668
  canRedo: h.canRedo,
3560
3669
  undoLabel: h.undoName,
3561
3670
  redoLabel: h.redoName,
3562
- revision: this.revision
3671
+ revision: this.revision,
3672
+ effectsProvider: this.effects.provider
3563
3673
  };
3564
3674
  }
3565
3675
  notify() {
@@ -3590,9 +3700,9 @@ var AnimationEditorController = (_class = class {
3590
3700
  this.applying = false;
3591
3701
  }
3592
3702
  this.notify();
3593
- _optionalChain([this, 'access', _154 => _154.onChange, 'optionalCall', _155 => _155(scene)]);
3703
+ _optionalChain([this, 'access', _156 => _156.onChange, 'optionalCall', _157 => _157(scene)]);
3594
3704
  }
3595
- commit(label, next) {
3705
+ commit(label, next, merge) {
3596
3706
  const before = this.scene;
3597
3707
  this.error = null;
3598
3708
  if (next === before) {
@@ -3606,7 +3716,8 @@ var AnimationEditorController = (_class = class {
3606
3716
  undo: () => this.setScene(before),
3607
3717
  redo: () => this.setScene(next)
3608
3718
  };
3609
- this.history.execute(command3);
3719
+ if (merge) this.history.executeMerged(command3, { key: merge });
3720
+ else this.history.execute(command3);
3610
3721
  }
3611
3722
  refuse(message) {
3612
3723
  this.error = message;
@@ -3626,13 +3737,155 @@ var AnimationEditorController = (_class = class {
3626
3737
  if (reason) return this.refuse(reason);
3627
3738
  const result = applyMotionEdits(this.scene, edits);
3628
3739
  if (!result.ok) return options.dryRun ? result : this.refuse(result.error);
3629
- if (!options.dryRun) this.commit(label, result.scene);
3740
+ if (!options.dryRun) this.commit(label, result.scene, options.merge);
3630
3741
  return result;
3631
3742
  }
3632
3743
  /** Replaces the artwork (e.g. from a vector editor's `onChange`), as one undo step. */
3633
3744
  setArtwork(artwork, label = "Change artwork") {
3634
3745
  return this.apply({ op: "set_artwork", artwork }, label);
3635
3746
  }
3747
+ // ---------------------------------------------------------------------------------------
3748
+ // Effects
3749
+ // ---------------------------------------------------------------------------------------
3750
+ /** The registered effects provider, or `null`. */
3751
+ get effectsProvider() {
3752
+ return this.effects.provider;
3753
+ }
3754
+ /** Registers (or with `null` removes) the effects provider. Not an edit: no undo step. */
3755
+ setEffectsProvider(provider) {
3756
+ this.effects.set(provider);
3757
+ }
3758
+ /** Registers `provider` and returns a function that removes it again (if it is still the one set). */
3759
+ useEffects(provider) {
3760
+ return this.effects.use(provider);
3761
+ }
3762
+ /** The provider effects applied in the scene. */
3763
+ appliedEffects() {
3764
+ return motionSceneEffects(this.scene);
3765
+ }
3766
+ async effectEdit(work, merge) {
3767
+ const reason = this.readOnlyReason();
3768
+ if (reason) return this.refuse(reason);
3769
+ let plan;
3770
+ try {
3771
+ plan = await work();
3772
+ } catch (error) {
3773
+ if (_chunkIOXKXQNWcjs.isEffectError.call(void 0, error) || error instanceof Error) return this.refuse(error.message);
3774
+ throw error;
3775
+ }
3776
+ const r = this.apply({ op: "replace_scene", scene: plan.scene }, plan.label, { merge });
3777
+ if (!r.ok) return r;
3778
+ const effect = motionSceneEffects(this.scene).find((e) => e.instance === plan.instance);
3779
+ if (!effect) return this.refuse("The effect made no changes the scene can play.");
3780
+ return { ok: true, effect, notes: plan.notes };
3781
+ }
3782
+ async describeFor(effect, kinds) {
3783
+ const provider = this.effects.require();
3784
+ if (!provider.applyVectorEffect) throw new (0, _chunkIOXKXQNWcjs.EffectUnsupportedError)(`${provider.name} has no vector or motion effects.`);
3785
+ const d = await provider.describe(effect);
3786
+ if (!kinds.includes(d.kind)) {
3787
+ 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";
3788
+ throw new (0, _chunkIOXKXQNWcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.kind} effect: ${hint}.`, d.id);
3789
+ }
3790
+ return d;
3791
+ }
3792
+ knownNodes(ids) {
3793
+ const all = /* @__PURE__ */ new Set();
3794
+ const walk = (nodes) => nodes.forEach((n) => (all.add(n.id), n.type === "group" && walk(n.children)));
3795
+ walk(this.scene.artwork.nodes);
3796
+ const missing = ids.filter((id) => !all.has(id));
3797
+ if (missing.length) throw new Error(`The artwork has no node ${missing.map((m) => `"${m}"`).join(", ")}; get_animation lists the node ids.`);
3798
+ if (!ids.length) throw new Error("Give at least one node to animate.");
3799
+ }
3800
+ /**
3801
+ * Applies a provider motion effect to artwork nodes: the provider animates them and the changes
3802
+ * become commands, in a new shot (default) or added to the end of `shot`. One undo step.
3803
+ * Returns the applied effect (its `instance` id changes or removes it).
3804
+ */
3805
+ applyMotionEffect(effect, targets, options = {}) {
3806
+ return this.effectEdit(async () => {
3807
+ this.knownNodes(targets);
3808
+ const d = await this.describeFor(effect, ["motion"]);
3809
+ const values = _chunkIOXKXQNWcjs.resolveEffectValues.call(void 0, d, options.values);
3810
+ const instance = _nullishCoalesce(options.instance, () => ( nextMotionEffectInstance(this.scene)));
3811
+ const motion = await this.effects.require().applyVectorEffect(d.id, { svg: motionArtworkSvg(this.scene.artwork), nodeIds: [...targets] }, values);
3812
+ const source = { instance, effect: d.id, provider: this.effects.require().id, name: d.name, values };
3813
+ const { commands, notes } = motionCommandsFromEffect(this.scene.artwork, motion, source);
3814
+ if (!commands.length) throw new Error(`"${d.name}" made no changes the scene can play${notes.length ? `: ${notes.join(" ")}` : ""}.`);
3815
+ let shots = this.scene.shots;
3816
+ if (options.shot) {
3817
+ 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(", ")}.`);
3818
+ shots = shots.map((s) => s.id === options.shot ? { ...s, run: [...s.run, ...commands] } : s);
3819
+ } else shots = [...shots, { id: instance, label: d.name, run: commands }];
3820
+ return { scene: { ...this.scene, shots }, label: `Apply ${d.name}`, instance, notes };
3821
+ });
3822
+ }
3823
+ /**
3824
+ * Adds a provider vector effect (one with its own picture: a lower third, a loader): its SVG as
3825
+ * an artwork group (id: the instance) fitted into `box` (default the whole artwork), and its
3826
+ * motion as shots after the last one. One undo step.
3827
+ */
3828
+ addVectorEffect(effect, options = {}) {
3829
+ return this.effectEdit(async () => {
3830
+ const d = await this.describeFor(effect, ["vector"]);
3831
+ const values = _chunkIOXKXQNWcjs.resolveEffectValues.call(void 0, d, options.values);
3832
+ const instance = _nullishCoalesce(options.instance, () => ( nextMotionEffectInstance(this.scene)));
3833
+ const motion = await this.effects.require().applyVectorEffect(d.id, motionArtworkSvg(this.scene.artwork), values);
3834
+ const source = { instance, effect: d.id, provider: this.effects.require().id, name: d.name, values };
3835
+ const { group, shots, notes } = motionPartsFromVectorEffect(this.scene.artwork, motion, source, options.box);
3836
+ 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 };
3837
+ });
3838
+ }
3839
+ /**
3840
+ * Makes an applied effect again with new `values` (merged over its own; `null` resets a
3841
+ * control), in the same place. One undo step.
3842
+ */
3843
+ updateMotionEffect(instance, values, options = {}) {
3844
+ return this.effectEdit(async () => {
3845
+ const was = motionSceneEffects(this.scene).find((e) => e.instance === instance);
3846
+ if (!was) throw new Error(`There is no applied effect "${instance}"; list_applied_effects lists them.`);
3847
+ const d = await this.describeFor(was.effect, [was.kind]);
3848
+ const base = { ...was.values };
3849
+ const given = {};
3850
+ for (const [k, v] of Object.entries(values)) {
3851
+ if (v !== null) given[k] = v;
3852
+ else if (k in d.controls.properties) base[k] = d.defaults[k];
3853
+ else throw new Error(`"${k}" is not a control of "${d.id}"; its controls are ${Object.keys(d.controls.properties).join(", ")}.`);
3854
+ }
3855
+ const merged = { ...base, ..._chunkIOXKXQNWcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
3856
+ const { scene: bare, place } = withoutMotionEffect(this.scene, instance);
3857
+ const provider = this.effects.require();
3858
+ const source = { instance, effect: d.id, provider: provider.id, name: d.name, values: merged };
3859
+ if (was.kind === "vector") {
3860
+ const old = this.scene.artwork.nodes.find((n) => n.id === instance);
3861
+ const motion2 = await provider.applyVectorEffect(d.id, motionArtworkSvg(bare.artwork), merged);
3862
+ const { group, shots: shots2, notes: notes2 } = motionPartsFromVectorEffect(bare.artwork, motion2, source);
3863
+ const index = this.scene.artwork.nodes.findIndex((n) => n.id === instance);
3864
+ const nodes = [...bare.artwork.nodes];
3865
+ nodes.splice(Math.max(0, index), 0, _optionalChain([old, 'optionalAccess', _158 => _158.transform]) ? { ...group, transform: old.transform } : group);
3866
+ const at = this.scene.shots.findIndex((s) => was.shots.includes(s.id));
3867
+ const kept = bare.shots;
3868
+ const nextShots = [...kept.slice(0, Math.max(0, at)), ...shots2, ...kept.slice(Math.max(0, at))];
3869
+ return { scene: { ...bare, artwork: { ...bare.artwork, nodes }, shots: nextShots }, label: `Change ${d.name}`, instance, notes: notes2 };
3870
+ }
3871
+ const motion = await provider.applyVectorEffect(d.id, { svg: motionArtworkSvg(bare.artwork), nodeIds: was.targets }, merged);
3872
+ const { commands, notes } = motionCommandsFromEffect(bare.artwork, motion, source);
3873
+ let shots = bare.shots;
3874
+ 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);
3875
+ else {
3876
+ const at = this.scene.shots.findIndex((s) => s.id === _optionalChain([place, 'optionalAccess', _159 => _159.shot]));
3877
+ shots = [...shots.slice(0, Math.max(0, at)), { id: instance, label: d.name, run: commands }, ...shots.slice(Math.max(0, at))];
3878
+ }
3879
+ return { scene: { ...bare, shots }, label: `Change ${d.name}`, instance, notes };
3880
+ }, options.merge);
3881
+ }
3882
+ /** Removes an applied effect: its commands, shots it alone filled and a vector effect's group. One undo step. Works without a provider. */
3883
+ removeMotionEffect(instance) {
3884
+ const was = motionSceneEffects(this.scene).find((e) => e.instance === instance);
3885
+ if (!was) return this.refuse(`There is no applied effect "${instance}"; list_applied_effects lists them.`);
3886
+ const r = this.apply({ op: "replace_scene", scene: withoutMotionEffect(this.scene, instance).scene }, `Remove ${_nullishCoalesce(was.name, () => ( was.effect))}`);
3887
+ return r.ok ? { ok: true, effect: was, notes: [] } : r;
3888
+ }
3636
3889
  /** Opens a scene (JSON or object). `clearHistory` drops the undo stack (opening a file); otherwise it is one undo step. */
3637
3890
  load(scene, options = {}) {
3638
3891
  let parsed;
@@ -4157,9 +4410,9 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4157
4410
  handler: ({ from = 0, to, limit = 200 }) => {
4158
4411
  const s = scene();
4159
4412
  const timeline = compileMotionScene(s);
4160
- const words = _nullishCoalesce(_optionalChain([s, 'access', _156 => _156.narration, 'optionalAccess', _157 => _157.words]), () => ( []));
4413
+ const words = _nullishCoalesce(_optionalChain([s, 'access', _160 => _160.narration, 'optionalAccess', _161 => _161.words]), () => ( []));
4161
4414
  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]);
4415
+ 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
4416
  const beats = [];
4164
4417
  if (s.beat && s.beat.bpm > 0) {
4165
4418
  const first = Math.max(0, Math.ceil(motionBeatAt(s.beat, from).beat - 1e-9));
@@ -4260,7 +4513,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4260
4513
  handler: ({ svg }) => {
4261
4514
  let artwork;
4262
4515
  try {
4263
- artwork = _chunk5XXMLBH4cjs.parseVectorSvg.call(void 0, svg);
4516
+ artwork = _chunkQQKTOA4Ucjs.parseVectorSvg.call(void 0, svg);
4264
4517
  } catch (error) {
4265
4518
  throw new Error(`The SVG could not be read: ${error.message}. Nothing was changed.`);
4266
4519
  }
@@ -4481,7 +4734,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4481
4734
  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
4735
  annotations: { title: "Add commands to a shot", ...WRITE },
4483
4736
  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));
4737
+ 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
4738
  const first = _nullishCoalesce(at, () => ( before));
4486
4739
  return apply({ op: "add_commands", shot, commands, at }, "Add commands", (s) => {
4487
4740
  const shots = describeMotionShots(s);
@@ -4677,7 +4930,7 @@ var TIMING = /* @__PURE__ */ new Set(["duration", "delay", "stagger", "with", "e
4677
4930
  var COLORS = /* @__PURE__ */ new Set(["fill", "stroke", "color"]);
4678
4931
  var NODES = /* @__PURE__ */ new Set(["into", "path"]);
4679
4932
  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);
4933
+ return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access', _172 => _172.properties, 'optionalAccess', _173 => _173.type, 'optionalAccess', _174 => _174.const]) === type);
4681
4934
  }
4682
4935
  function unitOf(type, name) {
4683
4936
  if (name === "duration" || name === "delay" || name === "stagger") return "ms";
@@ -4712,7 +4965,7 @@ function kindOf(name, schema) {
4712
4965
  }
4713
4966
  function motionCommandFields(type) {
4714
4967
  const schema = branch(type);
4715
- if (!_optionalChain([schema, 'optionalAccess', _171 => _171.properties])) return [];
4968
+ if (!_optionalChain([schema, 'optionalAccess', _175 => _175.properties])) return [];
4716
4969
  const required = new Set(_nullishCoalesce(schema.required, () => ( [])));
4717
4970
  const fields = Object.entries(schema.properties).filter(([name]) => name !== "type").map(([name, s]) => {
4718
4971
  const kind = kindOf(name, s);
@@ -4769,7 +5022,7 @@ function defaultMotionCommand(type, targets, scene) {
4769
5022
  if (type === "wait") return { type: "wait", duration: 500 };
4770
5023
  if (!targets.length) return { error: "Pick a target first: click an element on the stage." };
4771
5024
  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]);
5025
+ 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
5026
  const base = { targets: [...targets] };
4774
5027
  switch (type) {
4775
5028
  case "scale":
@@ -4800,8 +5053,8 @@ function defaultMotionCommand(type, targets, scene) {
4800
5053
  }
4801
5054
  case "effect": {
4802
5055
  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]), () => ( []))) {
5056
+ const node = _optionalChain([nodes, 'access', _180 => _180.find, 'call', _181 => _181((e) => e.node.id === id), 'optionalAccess', _182 => _182.node]);
5057
+ for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess', _183 => _183.effects]), () => ( []))) {
4805
5058
  const param = Object.entries(effect.params).find(([, v]) => typeof v === "number");
4806
5059
  if (param) return { type, ...base, effect: effect.id, param: param[0], to: param[1] + 1 };
4807
5060
  }
@@ -4826,11 +5079,11 @@ function motionCommandRows(scene, shotId) {
4826
5079
  return scene.shots[index].run.map((command3, i) => {
4827
5080
  const t = timeline.commands.find((c) => c.shotIndex === index && c.command === i);
4828
5081
  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 } : {} };
5082
+ 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
5083
  });
4831
5084
  }
4832
5085
  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]), () => ( []));
5086
+ 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
5087
  return { op: "add_commands", shot, commands: run[command3] ? [structuredClone(run[command3])] : [], at: command3 + 1 };
4835
5088
  }
4836
5089
  var MOTION_EASE_CHOICES = [
@@ -4915,7 +5168,7 @@ function motionCueFromKey(key) {
4915
5168
  function motionCueChoices(scene, limit = 256) {
4916
5169
  const choices = [];
4917
5170
  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;
5171
+ 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
5172
  if (scene.beat && scene.beat.bpm > 0) {
4920
5173
  for (let beat = 0; choices.length < limit; beat++) {
4921
5174
  const time = motionBeatTime(scene.beat, beat);
@@ -4925,7 +5178,7 @@ function motionCueChoices(scene, limit = 256) {
4925
5178
  choices.push({ value: `beat:${beat}`, label: `Beat ${beat} (bar ${at.bar}.${at.beatInBar}) \xB7 ${s(time)}`, time });
4926
5179
  }
4927
5180
  }
4928
- _optionalChain([scene, 'access', _190 => _190.narration, 'optionalAccess', _191 => _191.words, 'access', _192 => _192.forEach, 'call', _193 => _193((w, i) => {
5181
+ _optionalChain([scene, 'access', _194 => _194.narration, 'optionalAccess', _195 => _195.words, 'access', _196 => _196.forEach, 'call', _197 => _197((w, i) => {
4929
5182
  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
5183
  })]);
4931
5184
  return choices;
@@ -4934,7 +5187,7 @@ function motionShotCueTime(scene, cue) {
4934
5187
  return cue ? motionCueTime(scene, cue) : void 0;
4935
5188
  }
4936
5189
  function formatMotionNarration(narration) {
4937
- return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _194 => _194.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
5190
+ return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _198 => _198.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
4938
5191
  }
4939
5192
  function parseMotionNarration(text) {
4940
5193
  const lines = text.split("\n").map((l) => l.trim()).filter(Boolean);
@@ -4971,6 +5224,92 @@ function parseMotionDrivers(text) {
4971
5224
  return { drivers };
4972
5225
  }
4973
5226
 
5227
+ // src/animation-editor/effect-tools.ts
5228
+ 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 });
5229
+ function createAnimationEffectsToolProvider(controller, options = {}) {
5230
+ const readOnlyReason = () => {
5231
+ const ro = typeof options.readOnly === "function" ? options.readOnly() : options.readOnly;
5232
+ if (ro) return typeof ro === "string" ? ro : "The animation is read-only.";
5233
+ return controller.readOnlyReason();
5234
+ };
5235
+ const done = (r, target) => {
5236
+ if (!r.ok) throw new Error(r.error);
5237
+ return { target, effect: info(r.effect), effects: controller.appliedEffects().filter((e) => e.targets.includes(target)).map(info), ...r.notes.length ? { notes: r.notes } : {} };
5238
+ };
5239
+ return _chunkQDJKUBWEcjs.createEffectToolProvider.call(void 0, {
5240
+ id: _nullishCoalesce(options.id, () => ( "animation-effects")),
5241
+ namespace: options.namespace,
5242
+ target: { noun: "node", id: "A node id of the artwork from get_animation (a group animates as one)." },
5243
+ applyUses: ["motion"],
5244
+ 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.",
5245
+ provider: () => controller.effectsProvider,
5246
+ readOnlyReason,
5247
+ list: (target) => {
5248
+ const all = controller.appliedEffects();
5249
+ if (target) return [{ target, effects: all.filter((e) => e.targets.includes(target)).map(info) }];
5250
+ const byTarget = /* @__PURE__ */ new Map();
5251
+ for (const e of all) {
5252
+ const key = _nullishCoalesce(e.targets[0], () => ( e.instance));
5253
+ byTarget.set(key, [..._nullishCoalesce(byTarget.get(key), () => ( [])), info(e)]);
5254
+ }
5255
+ return [...byTarget].map(([t, effects]) => ({ target: t, effects }));
5256
+ },
5257
+ apply: async (target, effect, args) => {
5258
+ 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.");
5259
+ return done(await controller.applyMotionEffect(effect, [target], { values: args.values }), target);
5260
+ },
5261
+ update: async (target, instance, changes) => {
5262
+ const extra = ["enabled", "opacity", "index"].filter((k) => changes[k] !== void 0);
5263
+ 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).`);
5264
+ return done(await controller.updateMotionEffect(instance, _nullishCoalesce(changes.values, () => ( {}))), target);
5265
+ },
5266
+ remove: async (target, instance) => done(controller.removeMotionEffect(instance), target),
5267
+ subscribe: (notify) => controller.subscribe(() => notify()),
5268
+ extraTools: (ctx) => [
5269
+ {
5270
+ name: "add_vector_effect",
5271
+ title: "Add a vector effect",
5272
+ 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.",
5273
+ inputSchema: {
5274
+ type: "object",
5275
+ properties: {
5276
+ effect: { type: "string", minLength: 1, description: "A vector effect id from search_effects (kind vector)." },
5277
+ values: ctx.valuesSchema("Control values over the effect's defaults"),
5278
+ box: {
5279
+ type: "object",
5280
+ properties: {
5281
+ x: { type: "number", description: "Left edge, artwork units." },
5282
+ y: { type: "number", description: "Top edge, artwork units." },
5283
+ width: { type: "number", exclusiveMinimum: 0, description: "Width, artwork units." },
5284
+ height: { type: "number", exclusiveMinimum: 0, description: "Height, artwork units." }
5285
+ },
5286
+ required: ["x", "y", "width", "height"],
5287
+ additionalProperties: false,
5288
+ description: "Where the picture goes in the artwork, fitted keeping its proportions (default the whole artwork)."
5289
+ }
5290
+ },
5291
+ required: ["effect"],
5292
+ additionalProperties: false
5293
+ },
5294
+ annotations: { title: "Add a vector effect", ...ctx.annotations.write },
5295
+ handler: async (args) => {
5296
+ ctx.requireProvider();
5297
+ const r = await controller.addVectorEffect(args.effect, { values: args.values, box: args.box });
5298
+ if (!r.ok) throw new Error(r.error);
5299
+ return { instance: r.effect.instance, group: r.effect.group, effect: info(r.effect), ...r.notes.length ? { notes: r.notes } : {} };
5300
+ }
5301
+ }
5302
+ ]
5303
+ });
5304
+ }
5305
+
5306
+
5307
+
5308
+
5309
+
5310
+
5311
+
5312
+
4974
5313
 
4975
5314
 
4976
5315
 
@@ -5114,5 +5453,5 @@ function parseMotionDrivers(text) {
5114
5453
 
5115
5454
 
5116
5455
 
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;
5456
+ 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
5457
  //# sourceMappingURL=index.cjs.map