@pixodesk/svg-animator-web 1.0.30 → 1.0.35

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.
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ var __objRest2 = (source, exclude) => {
64
64
  return target;
65
65
  };
66
66
  function bezierToSvgPath(path, forceCurves = false) {
67
- var _a, _b, _c, _d;
67
+ var _a2, _b, _c, _d;
68
68
  const v = path.v;
69
69
  const i = path.i;
70
70
  const o = path.o;
@@ -75,7 +75,7 @@ function bezierToSvgPath(path, forceCurves = false) {
75
75
  d.push("M" + v[0][0] + "," + v[0][1]);
76
76
  for (let idx = 1; idx < len; idx++) {
77
77
  const prevV = v[idx - 1];
78
- const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
78
+ const prevO = (_a2 = o == null ? void 0 : o[idx - 1]) != null ? _a2 : prevV;
79
79
  const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
80
80
  const currV = v[idx];
81
81
  const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
@@ -126,7 +126,7 @@ function interpolateBeziers(paths1, paths2, progress) {
126
126
  return res;
127
127
  }
128
128
  function interpolateBezier(path1, path2, progress) {
129
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
129
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
130
130
  if (!path1 || !path2) return path1 || path2 || { v: [] };
131
131
  const t = Math.min(Math.max(progress, 0), 1);
132
132
  const len = Math.min(path1.v.length, path2.v.length);
@@ -137,7 +137,7 @@ function interpolateBezier(path1, path2, progress) {
137
137
  const v1 = path1.v[idx];
138
138
  const v2 = path2.v[idx];
139
139
  v.push(interpolateVec(v1, v2, t));
140
- const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
140
+ const i1 = (_b = (_a2 = path1.i) == null ? void 0 : _a2[idx]) != null ? _b : v1;
141
141
  const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
142
142
  i.push(interpolateVec(i1, i2, t));
143
143
  const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
@@ -256,8 +256,8 @@ function toRGBA(color) {
256
256
  return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
257
257
  }
258
258
  function parseRgba(s) {
259
- var _a;
260
- const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
259
+ var _a2;
260
+ const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
261
261
  if (!inner) throw new Error("Invalid rgb/rgba format");
262
262
  const parts = inner.split(",").map((v) => +v.trim());
263
263
  return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
@@ -296,9 +296,9 @@ var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color",
296
296
  var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
297
297
  var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
298
298
  function composeTransformParts(parts, opts) {
299
- var _a;
299
+ var _a2;
300
300
  if (!parts) return "";
301
- const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
301
+ const withUnits = (_a2 = opts == null ? void 0 : opts.withUnits) != null ? _a2 : true;
302
302
  const segs = [];
303
303
  const t = parts.translate;
304
304
  const o = parts.origin;
@@ -315,6 +315,38 @@ function composeTransformParts(parts, opts) {
315
315
  if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
316
316
  return segs.join("");
317
317
  }
318
+ function parseTransformParts(str2) {
319
+ var _a2, _b;
320
+ if (!str2 || typeof str2 !== "string") return void 0;
321
+ const out = {};
322
+ const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
323
+ const order = ["translate", "rotate", "skewX", "scale"];
324
+ let lastIdx = -1;
325
+ let m;
326
+ while ((m = re.exec(str2)) !== null) {
327
+ const fn = m[1];
328
+ const idx = order.indexOf(fn);
329
+ if (idx < 0 || idx <= lastIdx) return void 0;
330
+ lastIdx = idx;
331
+ const nums = m[2].split(/[\s,]+/).filter(Boolean).map(Number);
332
+ if (nums.some((n) => Number.isNaN(n))) return void 0;
333
+ if (fn === "translate") {
334
+ if (nums.length < 1 || nums.length > 2) return void 0;
335
+ out.translate = [nums[0], (_a2 = nums[1]) != null ? _a2 : 0];
336
+ } else if (fn === "rotate") {
337
+ if (nums.length !== 1) return void 0;
338
+ out.rotate = nums[0];
339
+ } else if (fn === "skewX") {
340
+ if (nums.length !== 1) return void 0;
341
+ out.skew = nums[0];
342
+ } else {
343
+ if (nums.length < 1 || nums.length > 2) return void 0;
344
+ out.scale = [nums[0], (_b = nums[1]) != null ? _b : nums[0]];
345
+ }
346
+ }
347
+ if (str2.replace(/([a-zA-Z]+)\s*\(([^)]*)\)/g, "").replace(/[\s,]/g, "").length) return void 0;
348
+ return Object.keys(out).length ? out : void 0;
349
+ }
318
350
  var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
319
351
  var DEFAULT_DURATION_MS = 1e3;
320
352
  function kebabToCamelCaseWord(kebab) {
@@ -504,8 +536,8 @@ function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
504
536
  }
505
537
  var DEFAULT_PHASE = "cover";
506
538
  function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
507
- var _a;
508
- const [u0, u1] = scrollPhaseInterval((_a = point == null ? void 0 : point.phase) != null ? _a : DEFAULT_PHASE, subjectSize, scrollportSize);
539
+ var _a2;
540
+ const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
509
541
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
510
542
  return u0 + fraction * (u1 - u0);
511
543
  }
@@ -517,9 +549,9 @@ function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
517
549
  return clamp((u - uStart) / (uEnd - uStart), 0, 1);
518
550
  }
519
551
  function scrollOffsetProgress(offset, maxOffset, range) {
520
- var _a, _b;
552
+ var _a2, _b;
521
553
  const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
522
- const start = typeof ((_a = range == null ? void 0 : range.start) == null ? void 0 : _a.fraction) === "number" ? range.start.fraction : 0;
554
+ const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
523
555
  const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
524
556
  if (end <= start) return raw >= end ? 1 : 0;
525
557
  return clamp((raw - start) / (end - start), 0, 1);
@@ -531,6 +563,7 @@ function scrollResolveAxis(axis, writingMode) {
531
563
  if (a === "inline") return vertical ? "y" : "x";
532
564
  return vertical ? "x" : "y";
533
565
  }
566
+ var PX_UNKNOWN_KEY_ERROR = "unexpected extra key";
534
567
  function pathStr(path) {
535
568
  if (!path.length) return ".";
536
569
  let result = "";
@@ -642,6 +675,7 @@ var Union = class extends Base {
642
675
  constructor(schemas, defaultVal) {
643
676
  super();
644
677
  this.schemas = schemas;
678
+ this._kind = "union";
645
679
  this._default = defaultVal != null ? defaultVal : schemas[0]._default;
646
680
  }
647
681
  sanitize(raw) {
@@ -651,10 +685,10 @@ var Union = class extends Base {
651
685
  return this._default;
652
686
  }
653
687
  isValid(raw, ctx, path) {
654
- var _a;
688
+ var _a2;
655
689
  const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
656
690
  if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
657
- ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 240));
691
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a2 = JSON.stringify(raw)) != null ? _a2 : "").slice(0, 240));
658
692
  return false;
659
693
  }
660
694
  _canSanitize(raw) {
@@ -663,25 +697,30 @@ var Union = class extends Base {
663
697
  };
664
698
  var DiscriminatedUnion = class extends Base {
665
699
  constructor(_key, _schemas, defaultVal) {
700
+ var _a2;
666
701
  super();
667
702
  this._key = _key;
668
703
  this._schemas = _schemas;
704
+ this._kind = "discriminatedUnion";
669
705
  this._default = defaultVal != null ? defaultVal : _schemas[0]._default;
670
706
  this._map = /* @__PURE__ */ new Map();
671
707
  for (const s of _schemas) {
672
708
  const keySchema = s._shape[_key];
673
- if (keySchema) this._map.set(keySchema._default, s);
709
+ if (!keySchema) continue;
710
+ const literal = (_a2 = keySchema.inner) != null ? _a2 : keySchema;
711
+ this._map.set(literal._default, s);
712
+ if (keySchema.inner) this._absentMember = s;
674
713
  }
675
714
  }
676
715
  _findSchema(raw) {
677
716
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
678
717
  const val = raw[this._key];
679
- if (val === void 0 || val === null) return void 0;
718
+ if (val === void 0 || val === null) return this._absentMember;
680
719
  return this._map.get(val);
681
720
  }
682
721
  sanitize(raw) {
683
- var _a;
684
- return ((_a = this._findSchema(raw)) != null ? _a : this._schemas[0]).sanitize(raw);
722
+ var _a2;
723
+ return ((_a2 = this._findSchema(raw)) != null ? _a2 : this._schemas[0]).sanitize(raw);
685
724
  }
686
725
  isValid(raw, ctx, path) {
687
726
  const schema = this._findSchema(raw);
@@ -710,7 +749,8 @@ var Obj = class extends Base {
710
749
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
711
750
  const out = {};
712
751
  for (const key of Object.keys(this._shape)) {
713
- out[key] = this._shape[key].sanitize(src[key]);
752
+ const v = this._shape[key].sanitize(src[key]);
753
+ if (v !== void 0) out[key] = v;
714
754
  }
715
755
  return out;
716
756
  }
@@ -732,7 +772,7 @@ var Obj = class extends Base {
732
772
  if (key in this._shape) continue;
733
773
  if (obj[key] === void 0) continue;
734
774
  p.push(key);
735
- ctx.errors.push(pathStr(p) + ": unexpected extra key");
775
+ ctx.errors.push(pathStr(p) + ": " + PX_UNKNOWN_KEY_ERROR);
736
776
  p.pop();
737
777
  ok = false;
738
778
  }
@@ -756,7 +796,8 @@ var OpenObj = class extends Base {
756
796
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
757
797
  const out = __spreadValues2({}, src);
758
798
  for (const key of Object.keys(this._shape)) {
759
- out[key] = this._shape[key].sanitize(src[key]);
799
+ const v = this._shape[key].sanitize(src[key]);
800
+ if (v !== void 0) out[key] = v;
760
801
  }
761
802
  if (this._openSchema) {
762
803
  for (const key of Object.keys(src)) {
@@ -828,6 +869,7 @@ var Rec = class extends Base {
828
869
  constructor(value) {
829
870
  super();
830
871
  this.value = value;
872
+ this._kind = "record";
831
873
  this._default = {};
832
874
  }
833
875
  sanitize(raw) {
@@ -896,8 +938,8 @@ var Lazy = class extends Base {
896
938
  this.resolved = null;
897
939
  }
898
940
  get schema() {
899
- var _a;
900
- return (_a = this.resolved) != null ? _a : this.resolved = this.fn();
941
+ var _a2;
942
+ return (_a2 = this.resolved) != null ? _a2 : this.resolved = this.fn();
901
943
  }
902
944
  sanitize(raw) {
903
945
  return this.schema.sanitize(raw);
@@ -913,6 +955,7 @@ var Tuple = class extends Base {
913
955
  constructor(schemas) {
914
956
  super();
915
957
  this.schemas = schemas;
958
+ this._kind = "tuple";
916
959
  this._default = schemas.map((s) => s._default);
917
960
  }
918
961
  sanitize(raw) {
@@ -947,12 +990,22 @@ function schemaKeys(schema) {
947
990
  );
948
991
  }
949
992
  function describeSchema(schema) {
950
- var _a;
993
+ var _a2;
951
994
  const s = schema;
952
- if ("_shape" in s) return { kind: "shape", shape: s._shape };
995
+ switch (s._kind) {
996
+ case "union":
997
+ return { kind: "union", members: s.schemas };
998
+ case "discriminatedUnion":
999
+ return { kind: "discriminatedUnion", key: s._key, members: s._schemas };
1000
+ case "record":
1001
+ return { kind: "record", value: s.value };
1002
+ case "tuple":
1003
+ return { kind: "tuple", items: s.schemas };
1004
+ }
1005
+ if ("_shape" in s) return { kind: "shape", shape: s._shape, openValue: s._openSchema };
953
1006
  if ("item" in s) return { kind: "array", item: s.item };
954
1007
  if ("inner" in s) return { kind: "optional", inner: s.inner };
955
- if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.fn() };
1008
+ if ("fn" in s) return { kind: "lazy", resolved: (_a2 = s.resolved) != null ? _a2 : s.resolved = s.fn() };
956
1009
  return { kind: "leaf" };
957
1010
  }
958
1011
  var px = {
@@ -1006,24 +1059,49 @@ var px = {
1006
1059
  /** Defers schema creation — required for recursive types. Must supply a default value. */
1007
1060
  lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
1008
1061
  };
1062
+ var PX_PLAYER_SCHEMA_VERSION = "1.1";
1063
+ var VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?$/;
1064
+ function parseWireVersion(raw) {
1065
+ if (typeof raw !== "string") return void 0;
1066
+ const m = VERSION_RE.exec(raw.trim());
1067
+ if (!m) return void 0;
1068
+ return { a: Number(m[1]), b: Number(m[2]), c: m[3] === void 0 ? 0 : Number(m[3]) };
1069
+ }
1070
+ var _a;
1071
+ var PLAYER_WIRE_VERSION = (_a = parseWireVersion(PX_PLAYER_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
1009
1072
  var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
1010
1073
  var PX_ANIM_ATTR_NAME = "_px_animator";
1011
- var PxAnimatorMode = {
1012
- auto: "auto",
1013
- waapi: "waapi",
1014
- frames: "frames"
1074
+ var PX_TIMELINE_SHARED_KEYS = ["duration", "iterations", "engine", "frameRate"];
1075
+ var PX_TIME_ONLY_TIMELINE_KEYS = ["trigger", "delay", "fillMode", "direction"];
1076
+ var PxTimelineEngine = {
1077
+ native: "native",
1078
+ js: "js"
1015
1079
  };
1016
- var PxAnimatorEngine = {
1017
- waapi: PxAnimatorMode.waapi,
1018
- frames: PxAnimatorMode.frames
1080
+ var PxTimelineEngineExtra = __spreadProps2(__spreadValues2({}, PxTimelineEngine), {
1081
+ auto: "auto"
1082
+ });
1083
+ function resolveTimelineEngine(engine) {
1084
+ return engine === PxTimelineEngineExtra.js ? PxTimelineEngine.js : PxTimelineEngine.native;
1085
+ }
1086
+ function isNativeForced(engine) {
1087
+ return engine === PxTimelineEngineExtra.native;
1088
+ }
1089
+ function mayUseNativeScrollTimeline(engine) {
1090
+ return engine !== PxTimelineEngineExtra.js;
1091
+ }
1092
+ var PxLoopRepeatAt = {
1093
+ /** Segment from the START; the repetition runs BEFORE the first keyframe
1094
+ * (intro loops that play until the main timeline begins). */
1095
+ start: "start",
1096
+ /** DEFAULT — segment from the END; the repetition runs AFTER the last keyframe
1097
+ * (idle/outro loops that continue once the main timeline has finished). */
1098
+ end: "end"
1019
1099
  };
1020
- var PxLoopExtend = {
1021
- /** Segment from the START; the animation is extended BEFORE the first keyframe
1022
- * (intro loops that run before the main timeline begins). */
1023
- before: "before",
1024
- /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
1025
- * loops that continue once the main timeline has finished). */
1026
- after: "after"
1100
+ var PxLoopDirection = {
1101
+ /** DEFAULT — cycle: every repetition replays the segment the same way round. */
1102
+ normal: "normal",
1103
+ /** Ping-pong: repetitions alternate forward / backward. */
1104
+ alternate: "alternate"
1027
1105
  };
1028
1106
  var PxMaskType = {
1029
1107
  luminance: "luminance",
@@ -1033,8 +1111,9 @@ var PxUnits = {
1033
1111
  userSpaceOnUse: "userSpaceOnUse",
1034
1112
  objectBoundingBox: "objectBoundingBox"
1035
1113
  };
1036
- var PxCloneType = {
1037
- content: "content"
1114
+ var PxCloneWithout = {
1115
+ translate: "translate"
1116
+ // transform: 'transform', // future: drop rotate/scale too (content only)
1038
1117
  };
1039
1118
  var PxPathOverflow = {
1040
1119
  clip: "clip",
@@ -1058,6 +1137,9 @@ var PxStrokeTrimSubPaths = {
1058
1137
  };
1059
1138
  var TEXT_ATTR = "text";
1060
1139
  var TEXT_CONTENT_ATTR = "textContent";
1140
+ var CLASS_ATTR = "class";
1141
+ var TRANSFORM_ATTR = "transform";
1142
+ var OFFSET_DISTANCE_ATTR = "offsetDistance";
1061
1143
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1062
1144
  "type",
1063
1145
  "children",
@@ -1068,7 +1150,18 @@ var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1068
1150
  TEXT_ATTR,
1069
1151
  TEXT_CONTENT_ATTR
1070
1152
  ]);
1071
- var PX_TRANSFORM_PART_KEYS = ["translate", "rotate", "scale", "origin"];
1153
+ var TRANSFORM_PART = {
1154
+ translate: "translate",
1155
+ rotate: "rotate",
1156
+ scale: "scale",
1157
+ origin: "origin"
1158
+ };
1159
+ var PX_TRANSFORM_PART_KEYS = [
1160
+ TRANSFORM_PART.translate,
1161
+ TRANSFORM_PART.rotate,
1162
+ TRANSFORM_PART.scale,
1163
+ TRANSFORM_PART.origin
1164
+ ];
1072
1165
  var PxGradientUnits = {
1073
1166
  userSpaceOnUse: "userSpaceOnUse",
1074
1167
  objectBoundingBox: "objectBoundingBox"
@@ -1086,23 +1179,68 @@ function isPxElementFileFormat(fileJson) {
1086
1179
  if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
1087
1180
  return false;
1088
1181
  }
1089
- return fileJson["type"] === "svg";
1182
+ return fileJson.type === "svg";
1090
1183
  }
1091
1184
  function getAnimatorConfig(doc) {
1092
- var _a;
1093
- return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
1185
+ var _a2;
1186
+ const cfg = (doc == null ? void 0 : doc.animator) || ((_a2 = doc == null ? void 0 : doc.meta) == null ? void 0 : _a2.animator);
1187
+ return cfg ? flattenAnimatorTimeline(cfg) : void 0;
1188
+ }
1189
+ var flattenMemo = /* @__PURE__ */ new WeakMap();
1190
+ function flattenAnimatorTimeline(cfg) {
1191
+ const timeline = cfg.timeline;
1192
+ if (timeline === void 0 || timeline === null || typeof timeline !== "object") return cfg;
1193
+ const memoised = flattenMemo.get(cfg);
1194
+ if (memoised) return memoised;
1195
+ const _a2 = cfg, { timeline: _dropped } = _a2, flat = __objRest2(_a2, ["timeline"]);
1196
+ if (timeline.engine !== void 0) flat.engine = timeline.engine;
1197
+ if (timeline.frameRate !== void 0) flat.frameRate = timeline.frameRate;
1198
+ if (timeline.type === "scroll" || timeline.type === "view") {
1199
+ flat.timelineSource = "scroll";
1200
+ if (timeline.duration !== void 0) flat.duration = timeline.duration;
1201
+ if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1202
+ const scroll = __spreadValues2({}, flat.scroll || {});
1203
+ scroll.kind = timeline.type;
1204
+ if (timeline.axis !== void 0) scroll.axis = timeline.axis;
1205
+ if (timeline.source !== void 0) scroll.source = timeline.source;
1206
+ if (timeline.subject !== void 0) scroll.subject = timeline.subject;
1207
+ if (timeline.smoothing !== void 0) scroll.smoothing = timeline.smoothing;
1208
+ if (timeline.range !== void 0) scroll.range = timeline.range;
1209
+ const pin = timeline.pin;
1210
+ if (typeof pin === "boolean") scroll.pin = pin;
1211
+ else if (pin && typeof pin === "object") {
1212
+ scroll.pin = true;
1213
+ if (pin.align !== void 0) scroll.pinAlign = pin.align;
1214
+ if (pin.top !== void 0) scroll.pinTop = pin.top;
1215
+ if (pin.distance !== void 0) scroll.pinDistance = pin.distance;
1216
+ }
1217
+ flat.scroll = scroll;
1218
+ } else {
1219
+ if (timeline.duration !== void 0) flat.duration = timeline.duration;
1220
+ if (timeline.trigger !== void 0) {
1221
+ const _b = timeline.trigger, { finishAction } = _b, restTrigger = __objRest2(_b, ["finishAction"]);
1222
+ if (Object.keys(restTrigger).length) flat.trigger = restTrigger;
1223
+ if (finishAction !== void 0) flat.resetOnFinish = finishAction === "reset";
1224
+ }
1225
+ if (timeline.delay !== void 0) flat.delay = timeline.delay;
1226
+ if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1227
+ if (timeline.direction !== void 0) flat.direction = timeline.direction;
1228
+ if (timeline.fillMode !== void 0) flat.fill = timeline.fillMode;
1229
+ }
1230
+ flattenMemo.set(cfg, flat);
1231
+ return flat;
1094
1232
  }
1095
1233
  function getDefs(doc) {
1096
- var _a;
1234
+ var _a2;
1097
1235
  if (!doc) return void 0;
1098
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
1236
+ return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
1099
1237
  }
1100
1238
  function getBindings(doc) {
1101
- var _a;
1239
+ var _a2;
1102
1240
  if (!doc) return void 0;
1103
- const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
1241
+ const animateById = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.animateById;
1104
1242
  if (!animateById) return void 0;
1105
- return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
1243
+ return Object.entries(animateById).map(([id, anim]) => ({ id: id.startsWith("#") ? id.slice(1) : id, animate: anim }));
1106
1244
  }
1107
1245
  function getChildren(doc) {
1108
1246
  return doc == null ? void 0 : doc.children;
@@ -1116,39 +1254,54 @@ var PxKeyframeValueSchema = implementsInterface()(px.union([
1116
1254
  // e.g. for colors
1117
1255
  px.number(),
1118
1256
  px.array(px.number()),
1119
- px.lazy(() => PxTransformPartsSchema, {}),
1257
+ // ORDER LAW: the key-discriminated object shapes (`{path}`, `{paths}`) come BEFORE the
1258
+ // all-optional transform-parts record. In default (non-strict) mode that record accepts
1259
+ // ANY object (every key optional, unknown keys ignored), so listing it earlier made
1260
+ // Union.sanitize route `{path}`/`{paths}` values into it and strip them to `{}` —
1261
+ // silent morph-data loss (repro: the editor's keyframeValueSanitize spec). Validity is
1262
+ // order-independent (`some()`); only sanitize routing depends on this order.
1120
1263
  px.object({ path: px.string() }),
1121
1264
  px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
1122
1265
  // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
1123
- px.lazy(() => px.array(PxGradientStopSchema), [])
1266
+ px.lazy(() => px.array(PxGradientStopSchema), []),
1267
+ px.lazy(() => PxTransformPartsSchema, {})
1124
1268
  ]));
1125
1269
  var PxKeyframeSchema = implementsInterface()(px.object({
1126
1270
  time: px.number().optional(),
1127
- t: px.number().optional(),
1128
1271
  value: PxKeyframeValueSchema.optional(),
1129
- v: PxKeyframeValueSchema.optional(),
1130
1272
  easing: PxEasingOrRefSchema.optional(),
1131
- e: PxEasingOrRefSchema.optional(),
1132
1273
  tangentOut: px.tuple([px.number(), px.number()]).optional(),
1133
- to: px.tuple([px.number(), px.number()]).optional(),
1134
- // short alias
1135
- tangentIn: px.tuple([px.number(), px.number()]).optional(),
1136
- ti: px.tuple([px.number(), px.number()]).optional(),
1137
- // short alias
1138
- selected: px.boolean().optional()
1139
- // editor-side UI state (Player ignores it)
1274
+ tangentIn: px.tuple([px.number(), px.number()]).optional()
1275
+ // (`selected` — editor timeline-selection UI state — was REMOVED from the wire
1276
+ // (review §1.3): editor data lives under `meta`. The editor still carries it on
1277
+ // its internal COPY-PASTE payload, which never validates against this schema.)
1140
1278
  }));
1279
+ var anyKf = (kf) => kf;
1280
+ var kfTime = (kf) => {
1281
+ var _a2, _b;
1282
+ return (_b = (_a2 = anyKf(kf).time) != null ? _a2 : anyKf(kf).t) != null ? _b : 0;
1283
+ };
1284
+ var kfValue = (kf) => {
1285
+ var _a2;
1286
+ return (_a2 = anyKf(kf).value) != null ? _a2 : anyKf(kf).v;
1287
+ };
1288
+ var kfEasing = (kf) => {
1289
+ var _a2;
1290
+ return (_a2 = anyKf(kf).easing) != null ? _a2 : anyKf(kf).e;
1291
+ };
1292
+ var kfTangentIn = (kf) => anyKf(kf).tangentIn;
1293
+ var kfTangentOut = (kf) => anyKf(kf).tangentOut;
1141
1294
  var PxLoopSchema = implementsInterface()(px.object({
1142
1295
  segmentCount: px.number().optional(),
1143
- extend: px.enum([PxLoopExtend.before, PxLoopExtend.after]).optional(),
1144
- alternate: px.boolean().optional()
1296
+ repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
1297
+ direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
1145
1298
  }));
1146
1299
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
1147
1300
  value: PxKeyframeValueSchema.optional(),
1148
1301
  keyframes: px.array(PxKeyframeSchema).optional(),
1149
- kfs: px.array(PxKeyframeSchema).optional(),
1150
1302
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1151
- autoOrient: px.boolean().optional()
1303
+ autoOrient: px.boolean().optional(),
1304
+ alongPathMode: px.enum(["sampled", "offsetPath"]).optional()
1152
1305
  }));
1153
1306
  var PxTransformPartsSchema = implementsInterface()(px.object({
1154
1307
  translate: px.tuple([px.number(), px.number()]).optional(),
@@ -1174,6 +1327,10 @@ var PxElementAnimationSchema = implementsInterface()(px.union([
1174
1327
  var PxTriggerSchema = implementsInterface()(px.object({
1175
1328
  startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
1176
1329
  outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
1330
+ // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
1331
+ // `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
1332
+ // happens when the trigger condition ends"); both end-of-life knobs now read alike.
1333
+ finishAction: px.enum(["hold", "reset"]).optional(),
1177
1334
  scrollIntoViewThreshold: px.number().optional()
1178
1335
  }));
1179
1336
  var PxGlyphSchema = implementsInterface()(px.object({
@@ -1181,8 +1338,8 @@ var PxGlyphSchema = implementsInterface()(px.object({
1181
1338
  d: px.string()
1182
1339
  }));
1183
1340
  var PxGlyphFontSchema = implementsInterface()(px.object({
1184
- fFamily: px.string(),
1185
- style: px.string(),
1341
+ fontFamily: px.string(),
1342
+ fontStyle: px.string(),
1186
1343
  ascent: px.number(),
1187
1344
  unitsPerEm: px.number(),
1188
1345
  glyphs: px.record(PxGlyphSchema)
@@ -1190,8 +1347,10 @@ var PxGlyphFontSchema = implementsInterface()(px.object({
1190
1347
  var PxDefsSchema = implementsInterface()(px.object({
1191
1348
  easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
1192
1349
  animations: px.record(PxAnimationDefinitionSchema).optional(),
1193
- styles: px.record(px.any()).optional(),
1194
- glyphs: px.record(PxGlyphFontSchema).optional()
1350
+ // Review §2.6: the schema now matches the declared type — a style preset is a flat
1351
+ // record of string|number attribute values, nothing nested.
1352
+ styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
1353
+ fonts: px.record(PxGlyphFontSchema).optional()
1195
1354
  }));
1196
1355
  var PX_SCROLL_PHASES = ["cover", "contain", "entry", "exit", "entry-crossing", "exit-crossing"];
1197
1356
  var PxScrollRangePointSchema = implementsInterface()(px.object({
@@ -1203,7 +1362,6 @@ var PxScrollRangeSchema = px.object({
1203
1362
  end: PxScrollRangePointSchema.optional()
1204
1363
  });
1205
1364
  var PxScrollSchema = implementsInterface()(px.object({
1206
- driver: px.enum(["custom", "native"]).optional(),
1207
1365
  kind: px.enum(["view", "scroll"]).optional(),
1208
1366
  axis: px.enum(["block", "inline", "x", "y"]).optional(),
1209
1367
  source: px.enum(["nearest", "root"]).optional(),
@@ -1216,23 +1374,67 @@ var PxScrollSchema = implementsInterface()(px.object({
1216
1374
  pinDistance: px.number().optional(),
1217
1375
  range: PxScrollRangeSchema.optional()
1218
1376
  }));
1219
- var PxAnimatorConfigSchema = implementsInterface()(px.object({
1220
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
1377
+ var PxTimelinePinSchema = implementsInterface()(px.object({
1378
+ align: px.enum(["top", "center", "bottom"]).optional(),
1379
+ top: px.number().optional(),
1380
+ distance: px.number().optional()
1381
+ }));
1382
+ var PxTimelineEngineSchema = px.enum([PxTimelineEngineExtra.auto, PxTimelineEngineExtra.native, PxTimelineEngineExtra.js]).optional();
1383
+ var PxTimeTimelineSchema = implementsInterface()(px.object({
1384
+ type: px.literal("time").optional(),
1385
+ engine: PxTimelineEngineSchema,
1386
+ frameRate: px.number().optional(),
1387
+ // §2.8: duration is a property of the TIMELINE — how long one pass takes.
1221
1388
  duration: px.number().optional(),
1389
+ trigger: PxTriggerSchema.optional(),
1222
1390
  delay: px.number().optional(),
1223
- // LAW (SCHEMA-DESIGN R3, S10): the ONE sanctioned string-in-number union
1224
- // (CSS animation-iteration-count familiarity) — do not add more mixed unions.
1225
1391
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1226
- fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1227
- direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
1392
+ // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1393
+ // — never `fill`, which is paint everywhere else in the format.
1394
+ fillMode: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1395
+ direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional()
1396
+ }));
1397
+ var scrollishTimelineShape = {
1398
+ // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
1399
+ // span the scroll range maps onto.
1400
+ duration: px.number().optional(),
1401
+ // Finite repeat count IS meaningful when scrubbing — the scroll range maps onto
1402
+ // duration × iterations (rule D4; `'infinite'` cannot map to a range, so no literal here).
1403
+ iterations: px.number().optional(),
1404
+ engine: PxTimelineEngineSchema,
1228
1405
  frameRate: px.number().optional(),
1229
- trigger: PxTriggerSchema.optional(),
1230
- resetOnFinish: px.boolean().optional(),
1406
+ axis: px.enum(["block", "inline", "x", "y"]).optional(),
1407
+ source: px.enum(["nearest", "root"]).optional(),
1408
+ subject: px.string().optional(),
1409
+ // 'parent' | 'scroller' | any CSS selector
1410
+ smoothing: px.number().optional(),
1411
+ // ms
1412
+ pin: px.union([px.boolean(), PxTimelinePinSchema]).optional(),
1413
+ range: PxScrollRangeSchema.optional()
1414
+ };
1415
+ var PxScrollTimelineSchema = implementsInterface()(
1416
+ px.object(__spreadValues2({ type: px.literal("scroll") }, scrollishTimelineShape))
1417
+ );
1418
+ var PxViewTimelineSchema = implementsInterface()(
1419
+ px.object(__spreadValues2({ type: px.literal("view") }, scrollishTimelineShape))
1420
+ );
1421
+ var PxTimelineSchema = px.discriminatedUnion("type", [
1422
+ PxTimeTimelineSchema,
1423
+ // first = the member an absent `type` selects
1424
+ PxScrollTimelineSchema,
1425
+ PxViewTimelineSchema
1426
+ ]);
1427
+ var PxAnimatorConfigSchema = implementsInterface()(px.object({
1428
+ // (`mode`, `duration` and `frameRate` live INSIDE `timeline` on the wire — §2.8; they exist
1429
+ // at this level only on the runtime view, like the rest of the playback dynamics.)
1430
+ // THE spelling of "what advances progress" — clock / scroll / view (review §2.1).
1431
+ timeline: PxTimelineSchema.optional(),
1231
1432
  definitions: PxDefsSchema.optional(),
1232
1433
  animateById: px.record(PxElementAnimationSchema).optional(),
1233
- timelineSource: px.string().optional(),
1234
- scroll: PxScrollSchema.optional(),
1235
- debugInstName: px.string().optional()
1434
+ debugGlobalName: px.string().optional(),
1435
+ // Declared HERE because this is a closed object: an undeclared key would be stripped by
1436
+ // `sanitize` and flagged by strict validation on our own files.
1437
+ version: px.string().optional()
1236
1438
  }));
1237
1439
  var PxBindingSchema = implementsInterface()(px.object({
1238
1440
  id: px.string(),
@@ -1250,18 +1452,18 @@ var PxAttrValueSchema = px.union([
1250
1452
  ]);
1251
1453
  var PxAnimatableNumberSchema = px.union([
1252
1454
  px.number(),
1253
- px.object({ value: px.number() }),
1254
- PxPropertyAnimationSchema
1455
+ PxPropertyAnimationSchema,
1456
+ px.object({ value: px.number() })
1255
1457
  ]);
1256
1458
  var PxAnimatableVec2Schema = px.union([
1257
1459
  px.tuple([px.number(), px.number()]),
1258
- px.object({ value: px.tuple([px.number(), px.number()]) }),
1259
- PxPropertyAnimationSchema
1460
+ PxPropertyAnimationSchema,
1461
+ px.object({ value: px.tuple([px.number(), px.number()]) })
1260
1462
  ]);
1261
1463
  var PxAnimatableStringSchema = px.union([
1262
1464
  px.string(),
1263
- px.object({ value: px.string() }),
1264
- PxPropertyAnimationSchema
1465
+ PxPropertyAnimationSchema,
1466
+ px.object({ value: px.string() })
1265
1467
  ]);
1266
1468
  var PxTransformByEffectSchema = implementsInterface()(px.object({
1267
1469
  translate: PxAnimatableVec2Schema.optional(),
@@ -1281,7 +1483,7 @@ var PxRepeaterEffectSchema = implementsInterface()(px.object({
1281
1483
  origin: PxAnimatableVec2Schema.optional()
1282
1484
  }));
1283
1485
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
1284
- sourceId: px.string().optional(),
1486
+ source: px.string().optional(),
1285
1487
  maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
1286
1488
  maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1287
1489
  maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
@@ -1291,8 +1493,7 @@ var PxMaskedByEffectSchema = implementsInterface()(px.object({
1291
1493
  height: px.number().optional()
1292
1494
  }));
1293
1495
  var PxClipPathEffectSchema = implementsInterface()(px.object({
1294
- d: PxAnimatableStringSchema.optional(),
1295
- animate: PxPropertyAnimationSchema.optional()
1496
+ d: PxAnimatableStringSchema.optional()
1296
1497
  }));
1297
1498
  var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1298
1499
  offset: PxAnimatableNumberSchema.optional(),
@@ -1300,15 +1501,15 @@ var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1300
1501
  subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
1301
1502
  }));
1302
1503
  var PxRetimeEffectSchema = implementsInterface()(px.object({
1303
- sourceId: px.string().optional(),
1304
1504
  start: px.number().optional(),
1305
1505
  stretch: px.number().optional(),
1306
1506
  timeCrop: px.tuple([px.number(), px.number()]).optional()
1307
1507
  }));
1308
1508
  var PxCloneEffectSchema = implementsInterface()(px.object({
1309
- // Contextual kind — the `type` convention, see `PxNodeBase.type`.
1310
- type: px.enum([PxCloneType.content]).optional(),
1311
- sourceId: px.string().optional(),
1509
+ // Subtractive on purpose: the `<use>` can only point at one wrapper layer of the
1510
+ // source, so the choices form a ladder — 'translate' now, maybe 'transform' later.
1511
+ without: px.enum([PxCloneWithout.translate]).optional(),
1512
+ source: px.string().optional(),
1312
1513
  retime: PxRetimeEffectSchema.optional()
1313
1514
  }));
1314
1515
  var PxGradientStopSchema = implementsInterface()(px.object({
@@ -1323,11 +1524,11 @@ var PxAnimatableGradientStopsSchema = px.union([
1323
1524
  var PxFillGradientEffectSchema = implementsInterface()(px.object({
1324
1525
  // Contextual kind — the `type` convention, see `PxNodeBase.type`.
1325
1526
  type: px.enum([PxGradientType.linear, PxGradientType.radial]),
1326
- p1: PxAnimatableVec2Schema.optional(),
1327
- p2: PxAnimatableVec2Schema.optional(),
1328
- c: PxAnimatableVec2Schema.optional(),
1329
- r: PxAnimatableNumberSchema.optional(),
1330
- fp: PxAnimatableVec2Schema.optional(),
1527
+ start: PxAnimatableVec2Schema.optional(),
1528
+ end: PxAnimatableVec2Schema.optional(),
1529
+ center: PxAnimatableVec2Schema.optional(),
1530
+ radius: PxAnimatableNumberSchema.optional(),
1531
+ focal: PxAnimatableVec2Schema.optional(),
1331
1532
  stops: PxAnimatableGradientStopsSchema.optional(),
1332
1533
  gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
1333
1534
  spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
@@ -1335,7 +1536,7 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1335
1536
  }));
1336
1537
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
1337
1538
  var PxTextPathEffectSchema = implementsInterface()(px.object({
1338
- path: px.string(),
1539
+ pathData: px.string(),
1339
1540
  pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
1340
1541
  lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
1341
1542
  method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
@@ -1375,16 +1576,33 @@ function validateNodeEffects(root, opts) {
1375
1576
  walk(root, "root");
1376
1577
  return warnings;
1377
1578
  }
1579
+ function validateDocument(doc) {
1580
+ const ctx = { errors: [], warnings: [], strict: true };
1581
+ const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
1582
+ if (doc && typeof doc === "object") {
1583
+ for (const w of validateNodeEffects(doc, { strict: true })) {
1584
+ if (!problems.includes(w)) problems.push(w);
1585
+ }
1586
+ }
1587
+ return problems;
1588
+ }
1378
1589
  var PxNodeBase = px.openObject({
1379
1590
  // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
1380
1591
  // kind of thing is this", discriminated by its CARRIER — here the node TAG
1381
- // (`rect`, `text`), and inside a sub-object that object's kind (`clone.type`,
1592
+ // (`rect`, `text`), and inside a sub-object that object's kind (`fillGradient.type`,
1382
1593
  // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
1383
1594
  // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
1384
1595
  // would add words that all mean "type" and still need the carrier to read.
1385
1596
  // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
1386
1597
  // (issues V3), never of distinct key names.
1387
1598
  type: px.string(),
1599
+ // The escape hatch for elements that carry a REAL `type` attribute — `<feTurbulence
1600
+ // type="fractalNoise">`, `<feFuncR type="table">`, `<feColorMatrix type="saturate">`.
1601
+ // `type` is taken by the tag name, so the attribute travels here and the renderer puts
1602
+ // it back (`PxAnimatorDOM.renderNode`, `PxRnRender`). Declared here — not merely
1603
+ // documented — because a wire key that is not in a schema is invisible to the
1604
+ // minifier's reserve list and gets renamed (MINIFICATION-BOUNDARY-PLAN.md §1.1).
1605
+ domType: px.string().optional(),
1388
1606
  id: px.string().optional(),
1389
1607
  meta: px.any().optional(),
1390
1608
  // Player-effects bucket emitted by the Editor's lightweight design format.
@@ -1441,7 +1659,7 @@ function deepClone(value) {
1441
1659
  return cloned;
1442
1660
  }
1443
1661
  function generateNewIds(doc) {
1444
- var _a, _b;
1662
+ var _a2, _b;
1445
1663
  const cloned = deepClone(doc);
1446
1664
  const idMap = /* @__PURE__ */ new Map();
1447
1665
  const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
@@ -1459,7 +1677,8 @@ function generateNewIds(doc) {
1459
1677
  "flood-color",
1460
1678
  "lighting-color"
1461
1679
  ]);
1462
- const directIdRefAttrs = /* @__PURE__ */ new Set(["sourceId", "targetId", "boundElementId"]);
1680
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["targetId", "boundElementId"]);
1681
+ const isEffectSourceRef = (key, parentKey) => key === "source" && (parentKey === "maskedBy" || parentKey === "clone");
1463
1682
  function collectIds(node) {
1464
1683
  if (!node || typeof node !== "object") return;
1465
1684
  if (node.id && typeof node.id === "string") {
@@ -1476,7 +1695,7 @@ function generateNewIds(doc) {
1476
1695
  }
1477
1696
  }
1478
1697
  }
1479
- function updateRefs(node) {
1698
+ function updateRefs(node, parentKey) {
1480
1699
  if (!node || typeof node !== "object") return;
1481
1700
  for (const [key, value] of Object.entries(node)) {
1482
1701
  if (key === "children") {
@@ -1496,7 +1715,7 @@ function generateNewIds(doc) {
1496
1715
  }
1497
1716
  } else if (urlRefAttrs.has(key)) {
1498
1717
  node[key] = replaceUrlRefs(value, idMap);
1499
- } else if (directIdRefAttrs.has(key)) {
1718
+ } else if (directIdRefAttrs.has(key) || isEffectSourceRef(key, parentKey)) {
1500
1719
  const hasHash = value.startsWith("#");
1501
1720
  const newId = idMap.get(hasHash ? value.slice(1) : value);
1502
1721
  if (newId) {
@@ -1512,18 +1731,20 @@ function generateNewIds(doc) {
1512
1731
  }
1513
1732
  }
1514
1733
  } else if (typeof value === "object" && value !== null) {
1515
- updateRefs(value);
1734
+ updateRefs(value, key);
1516
1735
  }
1517
1736
  }
1518
1737
  }
1519
1738
  collectIds(cloned);
1520
1739
  updateRefs(cloned);
1521
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
1740
+ const docAnimate = (_a2 = cloned.animator) == null ? void 0 : _a2.animateById;
1522
1741
  if (docAnimate && typeof docAnimate === "object") {
1523
1742
  const updatedAnimate = {};
1524
- for (const [id, anim] of Object.entries(docAnimate)) {
1743
+ for (const [key, anim] of Object.entries(docAnimate)) {
1744
+ const hashed = key.startsWith("#");
1745
+ const id = hashed ? key.slice(1) : key;
1525
1746
  const newId = (_b = idMap.get(id)) != null ? _b : id;
1526
- updatedAnimate[newId] = anim;
1747
+ updatedAnimate[hashed ? "#" + newId : newId] = anim;
1527
1748
  }
1528
1749
  cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animateById: updatedAnimate });
1529
1750
  }
@@ -1598,10 +1819,10 @@ function sanitiseAttributeValue(name, value) {
1598
1819
  return value;
1599
1820
  }
1600
1821
  function resolveStyle(style, defs) {
1601
- var _a;
1822
+ var _a2;
1602
1823
  if (!style) return void 0;
1603
1824
  if (typeof style === "string") {
1604
- return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
1825
+ return (_a2 = defs == null ? void 0 : defs.styles) == null ? void 0 : _a2[style];
1605
1826
  }
1606
1827
  return style;
1607
1828
  }
@@ -1614,16 +1835,16 @@ function getNormalizedProps(props) {
1614
1835
  let value = props[rawKey];
1615
1836
  if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
1616
1837
  propsCopy[key] = toRGBA(value);
1617
- } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes && !value.kfs) {
1838
+ } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
1618
1839
  const parts = value.value && typeof value.value === "object" ? value.value : value;
1619
- propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
1840
+ propsCopy[TRANSFORM_ATTR] = composeTransformParts(parts, { withUnits: false });
1620
1841
  } else if (TRANSFORM_FN_NAMES.has(key)) {
1621
1842
  if (Array.isArray(value)) {
1622
1843
  if (key === "translate") value = value.map((v) => v + "px");
1623
1844
  value = value.join(",");
1624
1845
  }
1625
1846
  if (key === "rotate") value = value + "deg";
1626
- propsCopy["transform"] = key + "(" + value + ")";
1847
+ propsCopy[TRANSFORM_ATTR] = key + "(" + value + ")";
1627
1848
  } else if (Array.isArray(value)) {
1628
1849
  propsCopy[key] = value.join(",");
1629
1850
  } else if (value !== void 0 && value !== null) {
@@ -1633,8 +1854,7 @@ function getNormalizedProps(props) {
1633
1854
  return propsCopy;
1634
1855
  }
1635
1856
  function getKfTranslate(kf) {
1636
- var _a;
1637
- const v = (_a = kf.value) != null ? _a : kf.v;
1857
+ const v = kfValue(kf);
1638
1858
  if (!v) return void 0;
1639
1859
  if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
1640
1860
  return [v[0], v[1]];
@@ -1644,31 +1864,27 @@ function getKfTranslate(kf) {
1644
1864
  return void 0;
1645
1865
  }
1646
1866
  function getKfTime(kf) {
1647
- var _a, _b;
1648
- return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
1867
+ return kfTime(kf);
1649
1868
  }
1650
1869
  function getKfEasing(kf) {
1651
- var _a;
1652
- return (_a = kf.easing) != null ? _a : kf.e;
1870
+ return kfEasing(kf);
1653
1871
  }
1654
1872
  function propAnimIsMotionPath(anim) {
1655
- var _a, _b, _c;
1656
- const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
1873
+ const kfs = anim.keyframes;
1657
1874
  if (!Array.isArray(kfs)) return false;
1658
1875
  if (anim.autoOrient) return true;
1659
1876
  for (const kf of kfs) {
1660
- if (((_b = kf.tangentIn) != null ? _b : kf.ti) || ((_c = kf.tangentOut) != null ? _c : kf.to)) return true;
1877
+ if (kfTangentIn(kf) || kfTangentOut(kf)) return true;
1661
1878
  }
1662
1879
  return false;
1663
1880
  }
1664
1881
  var _segmentCache = /* @__PURE__ */ new WeakMap();
1665
1882
  function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
1666
- var _a, _b;
1667
1883
  let byNext = _segmentCache.get(prevKf);
1668
1884
  const existing = byNext == null ? void 0 : byNext.get(nextKf);
1669
1885
  if (existing) return existing;
1670
- const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
1671
- const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
1886
+ const to = kfTangentOut(prevKf);
1887
+ const ti = kfTangentIn(nextKf);
1672
1888
  const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
1673
1889
  const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
1674
1890
  const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
@@ -1718,14 +1934,14 @@ var DEFAULT_FLATNESS_TOL = 0.5;
1718
1934
  var DEFAULT_ROTATION_TOL = 5;
1719
1935
  var DEFAULT_MAX_SAMPLES = 32;
1720
1936
  function materialiseMotionPathInPropAnim(anim, opts) {
1721
- var _a, _b, _c, _d;
1937
+ var _a2, _b, _c;
1722
1938
  if (!propAnimIsMotionPath(anim)) return anim;
1723
- const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
1939
+ const kfs = anim.keyframes;
1724
1940
  if (!Array.isArray(kfs) || kfs.length < 2) return anim;
1725
1941
  const autoOrient = !!anim.autoOrient;
1726
- const flatnessTol = (_b = opts == null ? void 0 : opts.flatnessTolerance) != null ? _b : DEFAULT_FLATNESS_TOL;
1727
- const rotationTol = (_c = opts == null ? void 0 : opts.rotationTolerance) != null ? _c : DEFAULT_ROTATION_TOL;
1728
- const maxSamples = (_d = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _d : DEFAULT_MAX_SAMPLES;
1942
+ const flatnessTol = (_a2 = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a2 : DEFAULT_FLATNESS_TOL;
1943
+ const rotationTol = (_b = opts == null ? void 0 : opts.rotationTolerance) != null ? _b : DEFAULT_ROTATION_TOL;
1944
+ const maxSamples = (_c = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _c : DEFAULT_MAX_SAMPLES;
1729
1945
  const out = [];
1730
1946
  const firstPos = getKfTranslate(kfs[0]);
1731
1947
  if (!firstPos) return anim;
@@ -1754,15 +1970,14 @@ function materialiseMotionPathInPropAnim(anim, opts) {
1754
1970
  const lastInE = getKfEasing(kfs[kfs.length - 1]);
1755
1971
  if (lastInE) out[out.length - 1].e = lastInE;
1756
1972
  if (autoOrient) unwrapAutoOrientRotations(out);
1757
- const result = { kfs: out };
1973
+ const result = { keyframes: out };
1758
1974
  if (anim.loop !== void 0) result.loop = anim.loop;
1759
1975
  return result;
1760
1976
  }
1761
1977
  function unwrapAutoOrientRotations(kfs) {
1762
- var _a;
1763
1978
  let prev;
1764
1979
  for (const kf of kfs) {
1765
- const v = (_a = kf.v) != null ? _a : kf.value;
1980
+ const v = kfValue(kf);
1766
1981
  if (!v || typeof v.rotate !== "number") continue;
1767
1982
  if (prev === void 0) {
1768
1983
  prev = v.rotate;
@@ -1779,8 +1994,7 @@ function makeOutKf(time, value) {
1779
1994
  return { t: time, v: value };
1780
1995
  }
1781
1996
  function getKfValueParts(kf) {
1782
- var _a;
1783
- const v = (_a = kf.value) != null ? _a : kf.v;
1997
+ const v = kfValue(kf);
1784
1998
  if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
1785
1999
  return v;
1786
2000
  }
@@ -1841,9 +2055,8 @@ function wrappedAngleDelta(a, b) {
1841
2055
  return d;
1842
2056
  }
1843
2057
  function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
1844
- var _a;
1845
2058
  const lastKf = out[out.length - 1];
1846
- const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
2059
+ const lastV = kfValue(lastKf);
1847
2060
  const prevExit = lastV == null ? void 0 : lastV.rotate;
1848
2061
  if (typeof prevExit !== "number") return;
1849
2062
  const boundaryV = getKfValueParts(prevKf);
@@ -2154,21 +2367,21 @@ function normalizePathValue(value) {
2154
2367
  return value;
2155
2368
  }
2156
2369
  function resolveEasing(easing, defs) {
2157
- var _a;
2370
+ var _a2;
2158
2371
  if (!easing) return void 0;
2159
2372
  if (Array.isArray(easing)) {
2160
2373
  return easing;
2161
2374
  }
2162
- if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
2375
+ if ((_a2 = defs == null ? void 0 : defs.easings) == null ? void 0 : _a2[easing]) {
2163
2376
  return defs.easings[easing];
2164
2377
  }
2165
2378
  console.warn("Unknown easing name: " + easing);
2166
2379
  return void 0;
2167
2380
  }
2168
2381
  function resolveAnimation(animRef, defs) {
2169
- var _a;
2382
+ var _a2;
2170
2383
  if (typeof animRef === "string") {
2171
- const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
2384
+ const resolved = (_a2 = defs == null ? void 0 : defs.animations) == null ? void 0 : _a2[animRef];
2172
2385
  if (!resolved) {
2173
2386
  console.warn("Unknown animation name: " + animRef);
2174
2387
  }
@@ -2193,9 +2406,9 @@ function resolveElementAnimation(animate, defs) {
2193
2406
  return results;
2194
2407
  }
2195
2408
  function interpolateValue(propName, a, b, t) {
2196
- var _a, _b;
2409
+ var _a2, _b;
2197
2410
  if (propName === "d") {
2198
- const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
2411
+ const aPaths = (_a2 = a == null ? void 0 : a.paths) != null ? _a2 : Array.isArray(a) ? a : [];
2199
2412
  const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
2200
2413
  return { paths: interpolateBeziers(aPaths, bPaths, t) };
2201
2414
  }
@@ -2231,11 +2444,11 @@ function interpolateTransformParts(a, b, t) {
2231
2444
  return out;
2232
2445
  }
2233
2446
  function expandLoopKeyframes(propName, keyframes, loop, duration) {
2234
- var _a, _b, _c, _d, _e;
2447
+ var _a2, _b, _c, _d, _e;
2235
2448
  const totalIntervals = keyframes.length - 1;
2236
- const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
2449
+ const segCount = clamp((_a2 = loop.segmentCount) != null ? _a2 : totalIntervals, 1, totalIntervals);
2237
2450
  let segKfs;
2238
- if (loop.extend === PxLoopExtend.before) {
2451
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2239
2452
  segKfs = keyframes.slice(0, segCount + 1);
2240
2453
  } else {
2241
2454
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -2243,7 +2456,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2243
2456
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
2244
2457
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
2245
2458
  let fillStart, fillEnd;
2246
- if (loop.extend === PxLoopExtend.before) {
2459
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2247
2460
  fillStart = 0;
2248
2461
  fillEnd = firstT;
2249
2462
  } else {
@@ -2256,26 +2469,23 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2256
2469
  const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
2257
2470
  const segDuration = segEndT - segStartT;
2258
2471
  if (segDuration <= 0) return keyframes;
2259
- const template = segKfs.map((kf) => {
2260
- var _a2, _b2;
2261
- return {
2262
- relT: (kf.t - segStartT) / segDuration,
2263
- v: kf.v,
2264
- e: kf.e,
2265
- tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
2266
- tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
2267
- };
2268
- });
2472
+ const template = segKfs.map((kf) => ({
2473
+ relT: (kf.t - segStartT) / segDuration,
2474
+ v: kf.v,
2475
+ e: kf.e,
2476
+ tangentIn: kfTangentIn(kf),
2477
+ tangentOut: kfTangentOut(kf)
2478
+ }));
2269
2479
  const fullReps = Math.floor(fillDuration / segDuration);
2270
2480
  const remainder = fillDuration - fullReps * segDuration;
2271
2481
  const partialFraction = remainder / segDuration;
2272
2482
  const looped = [];
2273
- const separateBoundary = loop.extend !== PxLoopExtend.before;
2483
+ const separateBoundary = loop.repeatAt !== PxLoopRepeatAt.start;
2274
2484
  const originalTerminalKf = keyframes[keyframes.length - 1];
2275
2485
  let terminalEasingOverride;
2276
2486
  let hasTerminalEasingOverride = false;
2277
2487
  function appendRep(repStart, isReversed, partial) {
2278
- var _a2;
2488
+ var _a3;
2279
2489
  let entries;
2280
2490
  if (isReversed) {
2281
2491
  entries = [];
@@ -2312,7 +2522,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2312
2522
  return;
2313
2523
  }
2314
2524
  const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
2315
- const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2525
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a3 = prevKf.t) != null ? _a3 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2316
2526
  if (isBoundary) {
2317
2527
  if (deepEqualValue(prevKf.v, entry.v)) {
2318
2528
  if (looped.length > 0) {
@@ -2378,30 +2588,30 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2378
2588
  looped.push(pushed);
2379
2589
  }
2380
2590
  }
2381
- if (loop.extend === PxLoopExtend.before) {
2591
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2382
2592
  if (partialFraction > 1e-9) {
2383
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
2593
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
2384
2594
  appendRepTail(fillStart, isReversed, partialFraction);
2385
2595
  }
2386
2596
  for (let rep = 0; rep < fullReps; rep++) {
2387
2597
  const distFromBoundary = fullReps - 1 - rep;
2388
- const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
2598
+ const isReversed = loop.direction === PxLoopDirection.alternate && distFromBoundary % 2 === 0;
2389
2599
  const repStart = fillStart + remainder + rep * segDuration;
2390
2600
  appendRep(repStart, isReversed);
2391
2601
  }
2392
2602
  } else {
2393
2603
  for (let rep = 0; rep < fullReps; rep++) {
2394
- const isReversed = !!loop.alternate && rep % 2 === 0;
2604
+ const isReversed = loop.direction === PxLoopDirection.alternate && rep % 2 === 0;
2395
2605
  const repStart = fillStart + rep * segDuration;
2396
2606
  appendRep(repStart, isReversed);
2397
2607
  }
2398
2608
  if (partialFraction > 1e-9) {
2399
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
2609
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
2400
2610
  const repStart = fillStart + fullReps * segDuration;
2401
2611
  appendRep(repStart, isReversed, partialFraction);
2402
2612
  }
2403
2613
  }
2404
- if (loop.extend === PxLoopExtend.before) {
2614
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2405
2615
  return [...looped, ...keyframes];
2406
2616
  } else {
2407
2617
  if (hasTerminalEasingOverride && keyframes.length > 0) {
@@ -2413,34 +2623,34 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2413
2623
  }
2414
2624
  }
2415
2625
  function normalizeKeyframes(propName, propAnim, duration, defs) {
2416
- var _a, _b, _c, _d, _e, _f, _g;
2417
- const keyframes = propAnim.keyframes || propAnim.kfs || [];
2626
+ var _a2;
2627
+ const keyframes = propAnim.keyframes || [];
2418
2628
  const normalized = [];
2419
2629
  for (const kf of keyframes) {
2420
- const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
2421
- let value = (_c = kf.value) != null ? _c : kf.v;
2422
- const easing = (_d = kf.easing) != null ? _d : kf.e;
2630
+ const timePct = kfTime(kf);
2631
+ let value = kfValue(kf);
2632
+ const easing = kfEasing(kf);
2423
2633
  if (propName === "d") {
2424
2634
  value = normalizePathValue(value);
2425
2635
  }
2426
2636
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2427
2637
  if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
2428
- value = (_e = parseColor(value)) != null ? _e : value;
2638
+ value = (_a2 = parseColor(value)) != null ? _a2 : value;
2429
2639
  }
2430
2640
  const normKf = {
2431
2641
  t: timePct,
2432
2642
  v: value,
2433
2643
  e: resolveEasing(easing, defs)
2434
2644
  };
2435
- const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
2436
- const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
2645
+ const tIn = kfTangentIn(kf);
2646
+ const tOut = kfTangentOut(kf);
2437
2647
  if (tIn) normKf.tangentIn = tIn;
2438
2648
  if (tOut) normKf.tangentOut = tOut;
2439
2649
  normalized.push(normKf);
2440
2650
  }
2441
2651
  normalized.sort((a, b) => {
2442
- var _a2, _b2;
2443
- return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
2652
+ var _a3, _b;
2653
+ return ((_a3 = a.t) != null ? _a3 : 0) - ((_b = b.t) != null ? _b : 0);
2444
2654
  });
2445
2655
  const loopRaw = propAnim.loop;
2446
2656
  const loop = loopRaw === true ? {} : loopRaw || void 0;
@@ -2459,28 +2669,29 @@ function mergeAnimationDefinitions(animations) {
2459
2669
  return merged;
2460
2670
  }
2461
2671
  function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
2462
- var _a;
2463
2672
  const loopRaw = propAnim.loop;
2464
2673
  if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
2465
2674
  const loop = loopRaw === true ? {} : loopRaw;
2466
- const rawKfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
2675
+ const rawKfs = propAnim.keyframes;
2467
2676
  if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
2468
2677
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2469
2678
  const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
2470
2679
  const kfs = rawKfs.map((kf) => {
2471
- var _a2, _b, _c, _d, _e, _f, _g, _h;
2472
- const t = (_a2 = kf.t) != null ? _a2 : kf.time;
2473
- let v = (_b = kf.v) != null ? _b : kf.value;
2680
+ var _a2;
2681
+ const t = kfTime(kf);
2682
+ let v = kfValue(kf);
2474
2683
  if (propName === "d") v = normalizePathValue(v);
2475
- if (isColour) v = (_c = parseColor(v)) != null ? _c : v;
2476
- const e = (_d = kf.e) != null ? _d : kf.easing;
2684
+ if (isColour) v = (_a2 = parseColor(v)) != null ? _a2 : v;
2685
+ const e = kfEasing(kf);
2477
2686
  const out2 = { t, v, e };
2478
- if ((_e = kf.tangentIn) != null ? _e : kf.ti) out2.tangentIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
2479
- if ((_g = kf.tangentOut) != null ? _g : kf.to) out2.tangentOut = (_h = kf.tangentOut) != null ? _h : kf.to;
2687
+ const tIn = kfTangentIn(kf);
2688
+ const tOut = kfTangentOut(kf);
2689
+ if (tIn) out2.tangentIn = tIn;
2690
+ if (tOut) out2.tangentOut = tOut;
2480
2691
  return out2;
2481
2692
  });
2482
2693
  const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
2483
- const out = { kfs: expanded };
2694
+ const out = { keyframes: expanded };
2484
2695
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2485
2696
  return out;
2486
2697
  }
@@ -2522,7 +2733,37 @@ var _elementIdCounter = 0;
2522
2733
  function generateElementId() {
2523
2734
  return "_px_el_" + ++_elementIdCounter;
2524
2735
  }
2525
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
2736
+ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2737
+ if (!animDef) return animDef;
2738
+ const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
2739
+ if (!staticParts || !Object.keys(staticParts).length) return animDef;
2740
+ const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues2(__spreadValues2({}, staticParts), v) : v;
2741
+ const transformAnim = animDef[TRANSFORM_ATTR];
2742
+ if (transformAnim && typeof transformAnim === "object") {
2743
+ const anim = transformAnim;
2744
+ if (Array.isArray(anim.keyframes)) {
2745
+ const out = __spreadProps2(__spreadValues2({}, anim), {
2746
+ keyframes: anim.keyframes.map((kf) => __spreadProps2(__spreadValues2({}, kf), { value: mergeKfValue(kf.value) }))
2747
+ });
2748
+ if (out.value !== void 0) out.value = mergeKfValue(out.value);
2749
+ return __spreadProps2(__spreadValues2({}, animDef), { transform: out });
2750
+ }
2751
+ return animDef;
2752
+ }
2753
+ const channels = Object.keys(animDef).filter((k) => TRANSFORM_FN_NAMES.has(k));
2754
+ if (channels.length !== 1) return animDef;
2755
+ const ch = channels[0];
2756
+ const chAnim = animDef[ch];
2757
+ if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
2758
+ const lifted = __spreadProps2(__spreadValues2({}, chAnim), {
2759
+ keyframes: chAnim.keyframes.map((kf) => __spreadProps2(__spreadValues2({}, kf), { value: __spreadProps2(__spreadValues2({}, staticParts), { [ch]: kf.value }) }))
2760
+ });
2761
+ if (lifted.value !== void 0) lifted.value = __spreadProps2(__spreadValues2({}, staticParts), { [ch]: lifted.value });
2762
+ const rest = __spreadValues2({}, animDef);
2763
+ delete rest[ch];
2764
+ return __spreadProps2(__spreadValues2({}, rest), { transform: lifted });
2765
+ }
2766
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
2526
2767
  const normalized = {};
2527
2768
  for (const [propName, propAnim] of Object.entries(animDef)) {
2528
2769
  if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
@@ -2530,24 +2771,24 @@ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimat
2530
2771
  }
2531
2772
  const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
2532
2773
  if (normalizedKfs.length > 0) {
2533
- const out = { kfs: normalizedKfs };
2774
+ const out = { keyframes: normalizedKfs };
2534
2775
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2535
2776
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
2536
- normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2777
+ normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2537
2778
  }
2538
2779
  }
2539
2780
  return normalized;
2540
2781
  }
2541
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2782
+ function getNormalisedBindings(doc, engine = PxTimelineEngine.native) {
2542
2783
  const animatorConfig = getAnimatorConfig(doc) || {};
2543
2784
  const defs = getDefs(doc);
2544
2785
  const duration = animatorConfig.duration || 1e3;
2545
2786
  const bindings = [];
2546
- const processAnimation = (id, animate) => {
2787
+ const processAnimation = (id, animate, staticTransform) => {
2547
2788
  if (!animate) return null;
2548
2789
  const animDefs = resolveElementAnimation(animate, defs);
2549
2790
  if (animDefs.length === 0) return null;
2550
- const merged = mergeAnimationDefinitions(animDefs);
2791
+ const merged = mergeStaticTransformIntoAnimDef(mergeAnimationDefinitions(animDefs), staticTransform);
2551
2792
  const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
2552
2793
  if (Object.keys(normalizedAnim).length === 0) return null;
2553
2794
  return {
@@ -2567,7 +2808,7 @@ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2567
2808
  if (inlineAnim && Object.keys(inlineAnim).length > 0) {
2568
2809
  const nodeId = node.id || generateElementId();
2569
2810
  node.id = nodeId;
2570
- const normalized = processAnimation(nodeId, inlineAnim);
2811
+ const normalized = processAnimation(nodeId, inlineAnim, node.transform);
2571
2812
  if (normalized) bindings.push(normalized);
2572
2813
  }
2573
2814
  if (node.children) {
@@ -2584,12 +2825,12 @@ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2584
2825
  return bindings;
2585
2826
  }
2586
2827
  function getKeyframesPair(keyframes, progress) {
2587
- var _a, _b;
2828
+ var _a2, _b;
2588
2829
  const last = keyframes.length - 1;
2589
2830
  let prevKf = keyframes[0];
2590
2831
  let nextKf = keyframes[last > 0 ? 1 : 0];
2591
2832
  for (let j = 0; j < last; j++) {
2592
- const aOff = (_a = keyframes[j].t) != null ? _a : 0;
2833
+ const aOff = (_a2 = keyframes[j].t) != null ? _a2 : 0;
2593
2834
  const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
2594
2835
  if (aOff <= progress && progress <= bOff) {
2595
2836
  prevKf = keyframes[j];
@@ -2604,13 +2845,13 @@ function getKeyframesPair(keyframes, progress) {
2604
2845
  return { prevKf, nextKf };
2605
2846
  }
2606
2847
  function calcPropertyValue(propName, propAnim, progress) {
2607
- var _a, _b, _c, _d, _e, _f, _g;
2608
- const keyframes = propAnim.kfs || propAnim.keyframes || [];
2848
+ var _a2, _b, _c, _d;
2849
+ const keyframes = propAnim.keyframes || [];
2609
2850
  if (keyframes.length === 0) return null;
2610
2851
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
2611
- let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
2852
+ let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a2 = prevKf.t) != null ? _a2 : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
2612
2853
  localProgress = clamp(localProgress, 0, 1);
2613
- const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
2854
+ const easing = kfEasing(prevKf);
2614
2855
  if (easing && Array.isArray(easing)) {
2615
2856
  try {
2616
2857
  localProgress = cubicBezier(easing)(localProgress);
@@ -2619,11 +2860,11 @@ function calcPropertyValue(propName, propAnim, progress) {
2619
2860
  }
2620
2861
  let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2621
2862
  let cssValue = null;
2622
- const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
2623
- const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
2863
+ const prevV = prevKf == null ? void 0 : prevKf.v;
2864
+ const nextV = nextKf == null ? void 0 : nextKf.v;
2624
2865
  if (cssAttrName === "d") {
2625
- const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
2626
- const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
2866
+ const prevPaths = (_c = prevV == null ? void 0 : prevV.paths) != null ? _c : Array.isArray(prevV) ? prevV : [];
2867
+ const nextPaths = (_d = nextV == null ? void 0 : nextV.paths) != null ? _d : Array.isArray(nextV) ? nextV : [];
2627
2868
  cssValue = interpolateBeziers(
2628
2869
  prevPaths,
2629
2870
  nextPaths,
@@ -2735,13 +2976,13 @@ function deepClonePxNode(value) {
2735
2976
  function regenerateIdsAndRewriteRefs(root, genId3) {
2736
2977
  const oldToNew = /* @__PURE__ */ new Map();
2737
2978
  const walkAssign = (n) => {
2738
- var _a;
2979
+ var _a2;
2739
2980
  if (typeof n.id === "string") {
2740
2981
  const newId = genId3();
2741
2982
  oldToNew.set(n.id, newId);
2742
2983
  n.id = newId;
2743
2984
  }
2744
- (_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
2985
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
2745
2986
  };
2746
2987
  walkAssign(root);
2747
2988
  const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
@@ -2749,7 +2990,7 @@ function regenerateIdsAndRewriteRefs(root, genId3) {
2749
2990
  return newId ? "url(#" + newId + ")" : m;
2750
2991
  });
2751
2992
  const walkRewrite = (n) => {
2752
- var _a;
2993
+ var _a2;
2753
2994
  if (typeof n.href === "string" && n.href.startsWith("#")) {
2754
2995
  const newId = oldToNew.get(n.href.slice(1));
2755
2996
  if (newId) n.href = "#" + newId;
@@ -2761,7 +3002,7 @@ function regenerateIdsAndRewriteRefs(root, genId3) {
2761
3002
  n[k] = rewriteUrl(v);
2762
3003
  }
2763
3004
  }
2764
- (_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
3005
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
2765
3006
  };
2766
3007
  walkRewrite(root);
2767
3008
  return oldToNew;
@@ -2771,7 +3012,7 @@ function toFiniteNum(v) {
2771
3012
  return Number.isFinite(n) ? n : 0;
2772
3013
  }
2773
3014
  function applyUseOffsetToG(gNode) {
2774
- var _a;
3015
+ var _a2;
2775
3016
  const x = toFiniteNum(gNode.x);
2776
3017
  const y = toFiniteNum(gNode.y);
2777
3018
  delete gNode.x;
@@ -2780,7 +3021,7 @@ function applyUseOffsetToG(gNode) {
2780
3021
  const offset = "translate(" + x + "," + y + ")";
2781
3022
  const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
2782
3023
  if (carriesTransform) {
2783
- const inner = { type: "g", transform: offset, children: (_a = gNode.children) != null ? _a : [] };
3024
+ const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
2784
3025
  gNode.children = [inner];
2785
3026
  } else {
2786
3027
  gNode.transform = offset;
@@ -2788,7 +3029,7 @@ function applyUseOffsetToG(gNode) {
2788
3029
  return gNode;
2789
3030
  }
2790
3031
  function materialiseAnimatedUseInstances(root) {
2791
- var _a;
3032
+ var _a2;
2792
3033
  const idMap = buildIdMap(root);
2793
3034
  const animatedIds = computeAnimatedSubtreeIds(root, idMap);
2794
3035
  if (animatedIds.size === 0) return root;
@@ -2799,7 +3040,7 @@ function materialiseAnimatedUseInstances(root) {
2799
3040
  const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
2800
3041
  if (defsCollector.length === 0) return walked;
2801
3042
  const defsNode = { type: "defs", children: defsCollector };
2802
- const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
3043
+ const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
2803
3044
  return __spreadProps2(__spreadValues2({}, walked), { children: newChildren });
2804
3045
  }
2805
3046
  function readRootViewport(root) {
@@ -2821,9 +3062,9 @@ function numericAttr(v) {
2821
3062
  function buildIdMap(root) {
2822
3063
  const map = /* @__PURE__ */ new Map();
2823
3064
  const visit = (n) => {
2824
- var _a;
3065
+ var _a2;
2825
3066
  if (typeof n.id === "string") map.set(n.id, n);
2826
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
3067
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
2827
3068
  };
2828
3069
  visit(root);
2829
3070
  return map;
@@ -2870,11 +3111,11 @@ function stripHash(href) {
2870
3111
  return href.startsWith("#") ? href.slice(1) : href;
2871
3112
  }
2872
3113
  function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
2873
- var _a, _b, _c, _d;
3114
+ var _a2, _b, _c, _d;
2874
3115
  const clone2 = deepClonePxNode(target);
2875
3116
  regenerateIdsAndRewriteRefs(clone2, genId3);
2876
3117
  const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
2877
- const useW = (_b = (_a = numericAttr(useNode.width)) != null ? _a : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3118
+ const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
2878
3119
  const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
2879
3120
  const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
2880
3121
  const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
@@ -2943,7 +3184,7 @@ function partsRecord(part, value, origin) {
2943
3184
  return rec;
2944
3185
  }
2945
3186
  function readAnimatable(raw) {
2946
- var _a, _b, _c;
3187
+ var _a2, _b;
2947
3188
  if (raw === void 0) return {
2948
3189
  kind: "absent"
2949
3190
  /* Absent */
@@ -2951,20 +3192,20 @@ function readAnimatable(raw) {
2951
3192
  if (Array.isArray(raw)) return { kind: "static", value: raw };
2952
3193
  if (typeof raw === "object") {
2953
3194
  const obj = raw;
2954
- const kfs = (_a = obj.keyframes) != null ? _a : obj.kfs;
3195
+ const kfs = obj.keyframes;
2955
3196
  if (kfs) {
2956
3197
  const out = { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
2957
- const base = (_b = obj.value) != null ? _b : obj.v;
3198
+ const base = (_a2 = obj.value) != null ? _a2 : obj.v;
2958
3199
  if (base !== void 0 && out.kind === "animated") out.base = base;
2959
3200
  return out;
2960
3201
  }
2961
- const staticValue = (_c = obj.value) != null ? _c : obj.v;
3202
+ const staticValue = (_b = obj.value) != null ? _b : obj.v;
2962
3203
  if (staticValue !== void 0) return { kind: "static", value: staticValue };
2963
3204
  }
2964
3205
  return { kind: "static", value: raw };
2965
3206
  }
2966
3207
  function writeAnimatableChannel(node, attrName, read, opts) {
2967
- var _a, _b, _c, _d;
3208
+ var _a2, _b, _c, _d;
2968
3209
  const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
2969
3210
  if (read.kind === "absent") return;
2970
3211
  if (read.kind === "static") {
@@ -2978,7 +3219,7 @@ function writeAnimatableChannel(node, attrName, read, opts) {
2978
3219
  if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
2979
3220
  animate[attrName] = block;
2980
3221
  node.animate = animate;
2981
- const baseline = (_d = (_b = read.base) != null ? _b : (_a = read.keyframes[0]) == null ? void 0 : _a.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
3222
+ const baseline = (_d = (_b = read.base) != null ? _b : (_a2 = read.keyframes[0]) == null ? void 0 : _a2.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
2982
3223
  if (baseline !== void 0) node[attrName] = toOut(baseline);
2983
3224
  }
2984
3225
  function normaliseKeyframe(kf) {
@@ -2996,12 +3237,12 @@ function normaliseKeyframe(kf) {
2996
3237
  return out;
2997
3238
  }
2998
3239
  function readStaticOrigin(raw, ctx) {
2999
- var _a;
3240
+ var _a2;
3000
3241
  const o = readAnimatable(raw);
3001
3242
  if (o.kind === "absent") return void 0;
3002
3243
  if (o.kind === "static") return o.value;
3003
3244
  ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
3004
- return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
3245
+ return (_a2 = o.keyframes[0]) == null ? void 0 : _a2.value;
3005
3246
  }
3006
3247
  function keyframeWith(kf, value) {
3007
3248
  const out = { value };
@@ -3107,9 +3348,9 @@ function stripHash2(href) {
3107
3348
  return typeof href === "string" ? href.replace(/^#/, "") : void 0;
3108
3349
  }
3109
3350
  function indexById(node, map) {
3110
- var _a;
3351
+ var _a2;
3111
3352
  if (typeof node.id === "string") map.set(node.id, node);
3112
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
3353
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((child) => indexById(child, map));
3113
3354
  }
3114
3355
  function spliceDefs(root, defs) {
3115
3356
  if (!defs.length) return;
@@ -3121,9 +3362,9 @@ function regenerateIdsInClone(root, ctx) {
3121
3362
  return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
3122
3363
  }
3123
3364
  function identifyContentRefTargets(node, ctx, allocator) {
3124
- var _a, _b, _c;
3125
- if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
3126
- const sourceId = stripHash2(node.effects.clone.sourceId);
3365
+ var _a2, _b, _c;
3366
+ if (node.type === "use" && ((_b = (_a2 = node.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.without) === "translate") {
3367
+ const sourceId = stripHash2(node.effects.clone.source);
3127
3368
  if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
3128
3369
  ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
3129
3370
  }
@@ -3148,10 +3389,10 @@ function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
3148
3389
  return outerWrapper;
3149
3390
  }
3150
3391
  function liftBodyTranslate(node, transformBy) {
3151
- var _a, _b, _c;
3392
+ var _a2, _b, _c;
3152
3393
  const out = {};
3153
3394
  let didLiftAnimate = false;
3154
- const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
3395
+ const animTr = (_a2 = node.animate) == null ? void 0 : _a2.transform;
3155
3396
  if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
3156
3397
  const kfs = animTr.keyframes;
3157
3398
  const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
@@ -3220,7 +3461,7 @@ function liftBodyTranslate(node, transformBy) {
3220
3461
  if (split.rest) node.transform = split.rest;
3221
3462
  else delete node.transform;
3222
3463
  }
3223
- } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes && !node.transform.kfs) {
3464
+ } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes) {
3224
3465
  const wrapped = node.transform.value;
3225
3466
  const isWrapped = !!(wrapped && typeof wrapped === "object");
3226
3467
  const value = isWrapped ? wrapped : node.transform;
@@ -3353,12 +3594,12 @@ function synthesiseGradientDef(fx, id, ctx) {
3353
3594
  id
3354
3595
  };
3355
3596
  if (fx.type === PxGradientType.linear) {
3356
- applyGeomVec(out, "x1", "y1", fx.p1);
3357
- applyGeomVec(out, "x2", "y2", fx.p2);
3597
+ applyGeomVec(out, "x1", "y1", fx.start);
3598
+ applyGeomVec(out, "x2", "y2", fx.end);
3358
3599
  } else {
3359
- applyGeomVec(out, "cx", "cy", fx.c);
3360
- applyGeomNumber(out, "r", fx.r);
3361
- applyGeomVec(out, "fx", "fy", fx.fp);
3600
+ applyGeomVec(out, "cx", "cy", fx.center);
3601
+ applyGeomNumber(out, "r", fx.radius);
3602
+ applyGeomVec(out, "fx", "fy", fx.focal);
3362
3603
  }
3363
3604
  if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
3364
3605
  if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
@@ -3367,7 +3608,7 @@ function synthesiseGradientDef(fx, id, ctx) {
3367
3608
  return out;
3368
3609
  }
3369
3610
  function applyGeomVec(out, xAttr, yAttr, raw) {
3370
- var _a, _b, _c;
3611
+ var _a2, _b, _c;
3371
3612
  const read = readAnimatable(raw);
3372
3613
  if (read.kind === "absent") return;
3373
3614
  if (read.kind === "static") {
@@ -3386,7 +3627,7 @@ function applyGeomVec(out, xAttr, yAttr, raw) {
3386
3627
  if (read.loop !== void 0) block.loop = read.loop;
3387
3628
  return block;
3388
3629
  };
3389
- const animate = (_a = out.animate) != null ? _a : {};
3630
+ const animate = (_a2 = out.animate) != null ? _a2 : {};
3390
3631
  animate[xAttr] = axisChannel(0);
3391
3632
  animate[yAttr] = axisChannel(1);
3392
3633
  out.animate = animate;
@@ -3402,7 +3643,7 @@ function applyGeomNumber(out, attrName, raw) {
3402
3643
  writeAnimatableChannel(out, attrName, read, { asString: true });
3403
3644
  }
3404
3645
  function buildStopChildren(stops, ctx) {
3405
- var _a, _b, _c, _d;
3646
+ var _a2, _b;
3406
3647
  if (!stops) return [];
3407
3648
  const read = readAnimatable(stops);
3408
3649
  if (read.kind === "absent") return [];
@@ -3412,14 +3653,14 @@ function buildStopChildren(stops, ctx) {
3412
3653
  const loopFromSource = read.loop;
3413
3654
  let stopCount = 0;
3414
3655
  for (const kf of kfs) {
3415
- const v = (_a = kf.value) != null ? _a : kf.v;
3656
+ const v = kfValue(kf);
3416
3657
  if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
3417
3658
  }
3418
3659
  if (!stopCount) return [];
3419
- const firstKfValue = (_b = kfs[0].value) != null ? _b : kfs[0].v;
3660
+ const firstKfValue = kfValue(kfs[0]);
3420
3661
  const baselineStops = [];
3421
3662
  for (let i = 0; i < stopCount; i++) {
3422
- const s = (_d = (_c = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _c : prevDefinedStop(kfs, 0, i)) != null ? _d : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
3663
+ const s = (_b = (_a2 = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _a2 : prevDefinedStop(kfs, 0, i)) != null ? _b : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
3423
3664
  baselineStops.push({ offset: s.offset, color: s.color });
3424
3665
  }
3425
3666
  return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
@@ -3432,16 +3673,16 @@ function staticStopNode(s) {
3432
3673
  };
3433
3674
  }
3434
3675
  function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3435
- var _a, _b, _c, _d, _e;
3676
+ var _a2;
3436
3677
  const colorKfs = [];
3437
3678
  const offsetKfs = [];
3438
3679
  let offsetVaries = false;
3439
3680
  for (const kf of kfs) {
3440
- const t = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
3441
- const arr = (_c = kf.value) != null ? _c : kf.v;
3442
- const sliced = (_d = arr == null ? void 0 : arr[stopIdx]) != null ? _d : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
3681
+ const t = kfTime(kf);
3682
+ const arr = kfValue(kf);
3683
+ const sliced = (_a2 = arr == null ? void 0 : arr[stopIdx]) != null ? _a2 : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
3443
3684
  if (!sliced) continue;
3444
- const easing = (_e = kf.easing) != null ? _e : kf.e;
3685
+ const easing = kfEasing(kf);
3445
3686
  const colorOut = { time: t, value: sliced.color };
3446
3687
  if (easing !== void 0) colorOut.easing = easing;
3447
3688
  colorKfs.push(colorOut);
@@ -3468,13 +3709,12 @@ function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3468
3709
  return stop;
3469
3710
  }
3470
3711
  function prevDefinedStop(kfs, fromIdx, stopIdx) {
3471
- var _a, _b;
3472
3712
  for (let i = fromIdx; i >= 0; i--) {
3473
- const arr = (_a = kfs[i].value) != null ? _a : kfs[i].v;
3713
+ const arr = kfValue(kfs[i]);
3474
3714
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
3475
3715
  }
3476
3716
  for (let i = fromIdx + 1; i < kfs.length; i++) {
3477
- const arr = (_b = kfs[i].value) != null ? _b : kfs[i].v;
3717
+ const arr = kfValue(kfs[i]);
3478
3718
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
3479
3719
  }
3480
3720
  return void 0;
@@ -3484,8 +3724,7 @@ function formatOffset(o) {
3484
3724
  return pct + "%";
3485
3725
  }
3486
3726
  function applyClipPathEffect(node, fx, ctx) {
3487
- var _a, _b;
3488
- if (!fx || !fx.d && !fx.animate) return node;
3727
+ if (!(fx == null ? void 0 : fx.d)) return node;
3489
3728
  const clipId = genId(ctx, "clip");
3490
3729
  const pathChild = { type: "path" };
3491
3730
  const read = readAnimatable(fx.d);
@@ -3497,11 +3736,6 @@ function applyClipPathEffect(node, fx, ctx) {
3497
3736
  if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
3498
3737
  }
3499
3738
  }
3500
- if (fx.animate && !((_a = pathChild.animate) == null ? void 0 : _a.d)) {
3501
- const animate = (_b = pathChild.animate) != null ? _b : {};
3502
- animate.d = fx.animate;
3503
- pathChild.animate = animate;
3504
- }
3505
3739
  ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
3506
3740
  node.clipPath = "url(#" + clipId + ")";
3507
3741
  return node;
@@ -3513,9 +3747,9 @@ function pathString(v) {
3513
3747
  }
3514
3748
  function applyMaskedByEffect(node, fx, transformBy, ctx) {
3515
3749
  if (!fx) return node;
3516
- const sourceId = stripHash2(fx.sourceId);
3750
+ const sourceId = stripHash2(fx.source);
3517
3751
  if (!sourceId) {
3518
- ctx.errors.push("maskedBy.sourceId missing \u2014 cannot build mask");
3752
+ ctx.errors.push("maskedBy.source missing \u2014 cannot build mask");
3519
3753
  return node;
3520
3754
  }
3521
3755
  const maskId = genId(ctx, "mask");
@@ -3578,16 +3812,16 @@ function invertPartValue(part, value) {
3578
3812
  return [1 / value[0], 1 / value[1]];
3579
3813
  }
3580
3814
  function negatedSpatialTangents(kf) {
3581
- var _a, _b;
3815
+ var _a2, _b;
3582
3816
  const out = {};
3583
- const to = (_a = kf.tangentOut) != null ? _a : kf.to;
3817
+ const to = (_a2 = kf.tangentOut) != null ? _a2 : kf.to;
3584
3818
  const ti = (_b = kf.tangentIn) != null ? _b : kf.ti;
3585
3819
  if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];
3586
3820
  if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];
3587
3821
  return out;
3588
3822
  }
3589
3823
  function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
3590
- var _a;
3824
+ var _a2;
3591
3825
  const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
3592
3826
  const animTr = animate == null ? void 0 : animate.transform;
3593
3827
  const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
@@ -3596,7 +3830,7 @@ function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
3596
3830
  const rotateKfs = [];
3597
3831
  const scaleKfs = [];
3598
3832
  for (const kf of kfs) {
3599
- const v = ((_a = kf.value) != null ? _a : kf.v) || {};
3833
+ const v = ((_a2 = kf.value) != null ? _a2 : kf.v) || {};
3600
3834
  const baseKf = keyframeWith(kf, void 0);
3601
3835
  if (Array.isArray(v.translate)) {
3602
3836
  translateKfs.push(__spreadProps2(__spreadValues2(__spreadValues2({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
@@ -3644,7 +3878,7 @@ function readTransformationFromBody(node) {
3644
3878
  if (parts.origin) out.origin = parts.origin;
3645
3879
  return Object.keys(out).length ? out : void 0;
3646
3880
  }
3647
- if (node.transform && typeof node.transform === "object" && !node.transform.keyframes && !node.transform.kfs) {
3881
+ if (node.transform && typeof node.transform === "object" && !node.transform.keyframes) {
3648
3882
  const wrapped = node.transform.value;
3649
3883
  const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
3650
3884
  if (value && typeof value === "object") {
@@ -3660,7 +3894,7 @@ function readTransformationFromBody(node) {
3660
3894
  return void 0;
3661
3895
  }
3662
3896
  function parseTransformStringToParts(s) {
3663
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
3897
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
3664
3898
  const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
3665
3899
  let m;
3666
3900
  const ops = [];
@@ -3674,7 +3908,7 @@ function parseTransformStringToParts(s) {
3674
3908
  for (let j = ops.length - 2; j >= 0; j--) {
3675
3909
  const cand = ops[j];
3676
3910
  if (cand.name !== "translate") continue;
3677
- const ox = (_a = cand.args[0]) != null ? _a : 0;
3911
+ const ox = (_a2 = cand.args[0]) != null ? _a2 : 0;
3678
3912
  const oy = (_b = cand.args[1]) != null ? _b : 0;
3679
3913
  const lx = (_c = last.args[0]) != null ? _c : 0;
3680
3914
  const ly = (_d = last.args[1]) != null ? _d : 0;
@@ -3789,8 +4023,8 @@ function interpKfs(kfs, t) {
3789
4023
  function collectMaskAncestorChains(root, ctx) {
3790
4024
  const interestingNodes = /* @__PURE__ */ new Set();
3791
4025
  const collectInterestingNodes = (n) => {
3792
- var _a, _b;
3793
- const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.sourceId);
4026
+ var _a2, _b;
4027
+ const maskSourceId = stripHash2((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
3794
4028
  if (typeof maskSourceId === "string") {
3795
4029
  interestingNodes.add(n);
3796
4030
  const sourceNode = ctx.idMap.get(maskSourceId);
@@ -3811,7 +4045,7 @@ function collectMaskAncestorChains(root, ctx) {
3811
4045
  walk(root, []);
3812
4046
  }
3813
4047
  function extractTranslateOnly(node, ctx) {
3814
- var _a, _b, _c;
4048
+ var _a2, _b, _c;
3815
4049
  const tr = node.transform;
3816
4050
  const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
3817
4051
  if (tr === void 0 && !animateBlock) return void 0;
@@ -3819,7 +4053,7 @@ function extractTranslateOnly(node, ctx) {
3819
4053
  if (typeof tr === "string") {
3820
4054
  const parts = parseTranslateOnlyFromString(tr, ctx);
3821
4055
  if (parts) out.translate = parts;
3822
- } else if (tr && typeof tr === "object" && !tr.keyframes && !tr.kfs) {
4056
+ } else if (tr && typeof tr === "object" && !tr.keyframes) {
3823
4057
  const wrapped = tr.value;
3824
4058
  const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
3825
4059
  if (value && typeof value === "object" && Array.isArray(value.translate)) {
@@ -3833,7 +4067,7 @@ function extractTranslateOnly(node, ctx) {
3833
4067
  const kfs = animateBlock.keyframes;
3834
4068
  const translateKfs = [];
3835
4069
  for (const kf of kfs) {
3836
- const v = (_a = kf.value) != null ? _a : kf.v;
4070
+ const v = (_a2 = kf.value) != null ? _a2 : kf.v;
3837
4071
  const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
3838
4072
  if (v && typeof v === "object" && Array.isArray(v.translate)) {
3839
4073
  translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
@@ -3866,15 +4100,14 @@ function parseTranslateOnlyFromString(s, ctx) {
3866
4100
  if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
3867
4101
  return seen ? [x, y] : void 0;
3868
4102
  }
3869
- var CONTENT_SUBREF = "content";
3870
4103
  function applyRefHref(node, clone2, ctx) {
3871
4104
  if (!clone2) return;
3872
- const sourceId = stripHash2(clone2.sourceId);
4105
+ const sourceId = stripHash2(clone2.source);
3873
4106
  if (!sourceId) {
3874
- if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing sourceId");
4107
+ if (clone2.without === PxCloneWithout.translate) ctx.errors.push("clone: content ref missing `source`");
3875
4108
  return;
3876
4109
  }
3877
- const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
4110
+ const targetId = clone2.without === PxCloneWithout.translate ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
3878
4111
  node.href = "#" + targetId;
3879
4112
  }
3880
4113
  function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
@@ -3882,9 +4115,9 @@ function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
3882
4115
  return applyTransformByEffect(node, transformBy, ctx);
3883
4116
  }
3884
4117
  function applyRepeaterEffect(node, fx, ctx) {
3885
- var _a, _b;
4118
+ var _a2, _b;
3886
4119
  if (!fx) return node;
3887
- const copies = (_a = fx.copies) != null ? _a : 1;
4120
+ const copies = (_a2 = fx.copies) != null ? _a2 : 1;
3888
4121
  if (copies < 1) {
3889
4122
  ctx.errors.push("repeater.copies invalid: " + fx.copies);
3890
4123
  return node;
@@ -3952,8 +4185,8 @@ function synthesiseScale(raw, i) {
3952
4185
  }
3953
4186
  var RETIME_MATERIALISATION_MODE_INLINE_G = false;
3954
4187
  function asRetime(r) {
3955
- var _a, _b;
3956
- return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
4188
+ var _a2, _b;
4189
+ return { start: (_a2 = r.start) != null ? _a2 : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
3957
4190
  }
3958
4191
  var CROP_EDGE_MS = 1;
3959
4192
  function applyTimeCrop(useNode, crop, ctx) {
@@ -3981,12 +4214,12 @@ function concatRetime(child, parent) {
3981
4214
  };
3982
4215
  }
3983
4216
  function readCloneRetime(n) {
3984
- var _a, _b;
3985
- return (_b = (_a = n.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.retime;
4217
+ var _a2, _b;
4218
+ return (_b = (_a2 = n.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.retime;
3986
4219
  }
3987
4220
  function clearCloneRetime(n) {
3988
- var _a;
3989
- const clone2 = (_a = n.effects) == null ? void 0 : _a.clone;
4221
+ var _a2;
4222
+ const clone2 = (_a2 = n.effects) == null ? void 0 : _a2.clone;
3990
4223
  if (!clone2) return;
3991
4224
  delete clone2.retime;
3992
4225
  if (Object.keys(clone2).length === 0) delete n.effects.clone;
@@ -3997,9 +4230,9 @@ function applyAllRetimeEffects(root, ctx) {
3997
4230
  indexById(root, ctx.idMap);
3998
4231
  const sites = [];
3999
4232
  const collect = (n) => {
4000
- var _a;
4233
+ var _a2;
4001
4234
  if (readCloneRetime(n)) sites.push(n);
4002
- (_a = n.children) == null ? void 0 : _a.forEach(collect);
4235
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(collect);
4003
4236
  };
4004
4237
  collect(root);
4005
4238
  const reachCount = /* @__PURE__ */ new Map();
@@ -4007,7 +4240,7 @@ function applyAllRetimeEffects(root, ctx) {
4007
4240
  let count = 0;
4008
4241
  const visited = /* @__PURE__ */ new Set();
4009
4242
  const walk = (n) => {
4010
- var _a;
4243
+ var _a2;
4011
4244
  if (!n) return;
4012
4245
  if (n !== site && readCloneRetime(n)) count++;
4013
4246
  if (n.type === "use" && n.href) {
@@ -4017,7 +4250,7 @@ function applyAllRetimeEffects(root, ctx) {
4017
4250
  walk(ctx.idMap.get(id));
4018
4251
  }
4019
4252
  }
4020
- (_a = n.children) == null ? void 0 : _a.forEach(walk);
4253
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walk);
4021
4254
  };
4022
4255
  const rootId = stripHash2(site.href);
4023
4256
  if (rootId) {
@@ -4027,8 +4260,8 @@ function applyAllRetimeEffects(root, ctx) {
4027
4260
  reachCount.set(site, count);
4028
4261
  }
4029
4262
  sites.sort((a, b) => {
4030
- var _a, _b;
4031
- return ((_a = reachCount.get(b)) != null ? _a : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4263
+ var _a2, _b;
4264
+ return ((_a2 = reachCount.get(b)) != null ? _a2 : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4032
4265
  });
4033
4266
  for (const useNode of sites) {
4034
4267
  const retime = readCloneRetime(useNode);
@@ -4095,7 +4328,7 @@ function buildChainClone(targetId, accum, ctx, chain) {
4095
4328
  }
4096
4329
  function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4097
4330
  const visit = (n) => {
4098
- var _a;
4331
+ var _a2;
4099
4332
  const retime = readCloneRetime(n);
4100
4333
  if (n.type === "use" && retime && n.href) {
4101
4334
  const subId = stripHash2(n.href);
@@ -4108,14 +4341,14 @@ function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4108
4341
  }
4109
4342
  clearCloneRetime(n);
4110
4343
  }
4111
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
4344
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
4112
4345
  };
4113
4346
  visit(node);
4114
4347
  }
4115
4348
  function remapKeyframeTimes(node, start, stretch) {
4116
- var _a;
4349
+ var _a2;
4117
4350
  remapKeyframeTimesOnly(node, start, stretch);
4118
- (_a = node.children) == null ? void 0 : _a.forEach((c) => remapKeyframeTimes(c, start, stretch));
4351
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => remapKeyframeTimes(c, start, stretch));
4119
4352
  }
4120
4353
  function remapKeyframeTimesOnly(node, start, stretch) {
4121
4354
  const remap2 = (kfs) => {
@@ -4290,8 +4523,8 @@ function numRange(v) {
4290
4523
  function estimateTextAdvance(node) {
4291
4524
  let chars = 0, maxFont = 16;
4292
4525
  const walk = (el) => {
4293
- var _a, _b;
4294
- const fs = parseFloat(String((_a = el.fontSize) != null ? _a : "")) || 0;
4526
+ var _a2, _b;
4527
+ const fs = parseFloat(String((_a2 = el.fontSize) != null ? _a2 : "")) || 0;
4295
4528
  if (fs) maxFont = Math.max(maxFont, fs);
4296
4529
  const t = (_b = el.text) != null ? _b : el.textContent;
4297
4530
  if (typeof t === "string") chars += t.length;
@@ -4315,14 +4548,14 @@ function shiftAnimatable(v, by) {
4315
4548
  return out;
4316
4549
  }
4317
4550
  function extendedPathForBrowser(pathD, opts) {
4318
- var _a;
4551
+ var _a2;
4319
4552
  if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
4320
4553
  const sampler = createPathSampler(pathD);
4321
4554
  if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
4322
4555
  const L = sampler.totalLength;
4323
4556
  const margin = EXTEND_MARGIN_FRAC * L;
4324
4557
  const so = numRange(opts.startOffset);
4325
- const runWidth = numRange(opts.textLength).max || ((_a = opts.advance) != null ? _a : 0);
4558
+ const runWidth = numRange(opts.textLength).max || ((_a2 = opts.advance) != null ? _a2 : 0);
4326
4559
  const startOverflow = Math.max(0, -so.min);
4327
4560
  const endOverflow = Math.max(0, so.max + runWidth - L);
4328
4561
  const startExt = startOverflow > 0 ? startOverflow + margin : 0;
@@ -4343,10 +4576,10 @@ function extendedPathForBrowser(pathD, opts) {
4343
4576
  return { d, startShift: startExt };
4344
4577
  }
4345
4578
  function applyTextPathEffect(node, fx, ctx) {
4346
- var _a;
4347
- if (!fx || typeof fx.path !== "string" || !fx.path) return node;
4579
+ var _a2;
4580
+ if (!fx || typeof fx.pathData !== "string" || !fx.pathData) return node;
4348
4581
  const pathId = genId(ctx, "tpath");
4349
- const { d, startShift } = extendedPathForBrowser(fx.path, {
4582
+ const { d, startShift } = extendedPathForBrowser(fx.pathData, {
4350
4583
  pathOverflow: fx.pathOverflow,
4351
4584
  startOffset: fx.startOffset,
4352
4585
  textLength: fx.textLength,
@@ -4356,7 +4589,7 @@ function applyTextPathEffect(node, fx, ctx) {
4356
4589
  const textPath = {
4357
4590
  type: "textPath",
4358
4591
  href: "#" + pathId,
4359
- children: (_a = node.children) != null ? _a : []
4592
+ children: (_a2 = node.children) != null ? _a2 : []
4360
4593
  };
4361
4594
  if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
4362
4595
  if (fx.method !== void 0) textPath.method = fx.method;
@@ -4480,15 +4713,15 @@ function paintAnimateOf(node) {
4480
4713
  return out;
4481
4714
  }
4482
4715
  function resolveStyle2(node, parent) {
4483
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4716
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4484
4717
  const isTextRoot = node.type === "text";
4485
4718
  const nodeStyle = node.style;
4486
4719
  const own = (key) => {
4487
- var _a2;
4488
- return isTextRoot ? void 0 : (_a2 = node[key]) != null ? _a2 : nodeStyle == null ? void 0 : nodeStyle[key];
4720
+ var _a3;
4721
+ return isTextRoot ? void 0 : (_a3 = node[key]) != null ? _a3 : nodeStyle == null ? void 0 : nodeStyle[key];
4489
4722
  };
4490
4723
  const res = {
4491
- fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
4724
+ fontFamily: (_a2 = str(node.fontFamily)) != null ? _a2 : parent.fontFamily,
4492
4725
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
4493
4726
  fill: (_c = node.fill) != null ? _c : parent.fill,
4494
4727
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
@@ -4505,10 +4738,10 @@ function resolveStyle2(node, parent) {
4505
4738
  return res;
4506
4739
  }
4507
4740
  function rootStyleOf(node) {
4508
- var _a, _b, _c;
4741
+ var _a2, _b, _c;
4509
4742
  return {
4510
4743
  fontFamily: str(node.fontFamily),
4511
- fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
4744
+ fontSize: (_a2 = parseLen(node.fontSize)) != null ? _a2 : DEFAULT_FONT_SIZE,
4512
4745
  fill: node.fill,
4513
4746
  stroke: node.stroke,
4514
4747
  strokeWidth: node.strokeWidth,
@@ -4529,9 +4762,9 @@ function paintOf(s) {
4529
4762
  return p;
4530
4763
  }
4531
4764
  function glyphFontFor(s, glyphs, soleFont, warnings) {
4532
- var _a;
4765
+ var _a2;
4533
4766
  const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
4534
- if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
4767
+ if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a2 = s.fontFamily) != null ? _a2 : "") + '"');
4535
4768
  return gf;
4536
4769
  }
4537
4770
  function soleFontOf(glyphs) {
@@ -4553,19 +4786,19 @@ function missingGlyphBoxEm(advanceEm, ascentEm) {
4553
4786
  return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
4554
4787
  }
4555
4788
  function materialiseGlyphTextHorizontal(node, opts) {
4556
- var _a, _b, _c, _d;
4789
+ var _a2, _b, _c, _d;
4557
4790
  const { glyphs, create = jsonElementFactory, warnings } = opts;
4558
4791
  const soleFont = soleFontOf(glyphs);
4559
- const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4792
+ const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4560
4793
  const placements = [];
4561
4794
  const lines = [{ start: pen.x, end: pen.x }];
4562
4795
  let line = 0;
4563
4796
  const renderChars = (content, s) => {
4564
- var _a2;
4797
+ var _a3;
4565
4798
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4566
4799
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4567
4800
  const scale = s.fontSize / upm;
4568
- const ascentEm = (_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm;
4801
+ const ascentEm = (_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm;
4569
4802
  const paint = paintOf(s);
4570
4803
  for (let i = 0; i < content.length; i++) {
4571
4804
  const ch = content.charAt(i);
@@ -4585,7 +4818,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4585
4818
  }
4586
4819
  };
4587
4820
  const walk = (el, parentStyle) => {
4588
- var _a2, _b2, _c2, _d2;
4821
+ var _a3, _b2, _c2, _d2;
4589
4822
  const s = resolveStyle2(el, parentStyle);
4590
4823
  const x = parseLen(el.x);
4591
4824
  const y = parseLen(el.y);
@@ -4595,7 +4828,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4595
4828
  lines.push({ start: pen.x, end: pen.x });
4596
4829
  }
4597
4830
  if (y !== void 0) pen.y = y;
4598
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
4831
+ pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4599
4832
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4600
4833
  const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4601
4834
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
@@ -4616,8 +4849,8 @@ function materialiseGlyphTextHorizontal(node, opts) {
4616
4849
  return toGroup(node, buildPaths(placements, create, warnings), create);
4617
4850
  }
4618
4851
  function layoutGlyphTextChars(node, opts) {
4619
- var _a, _b, _c, _d, _e, _f;
4620
- if ((_a = opts.alongPath) == null ? void 0 : _a.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
4852
+ var _a2, _b, _c, _d, _e, _f;
4853
+ if ((_a2 = opts.alongPath) == null ? void 0 : _a2.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
4621
4854
  const { glyphs, warnings } = opts;
4622
4855
  const soleFont = soleFontOf(glyphs);
4623
4856
  const pen = { x: (_b = parseLen(node.x)) != null ? _b : 0, y: (_c = parseLen(node.y)) != null ? _c : 0 };
@@ -4625,11 +4858,11 @@ function layoutGlyphTextChars(node, opts) {
4625
4858
  const lines = [{ start: pen.x, end: pen.x }];
4626
4859
  let line = 0;
4627
4860
  const renderChars = (content, s) => {
4628
- var _a2;
4861
+ var _a3;
4629
4862
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4630
4863
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4631
4864
  const scale = s.fontSize / upm;
4632
- const ascent = ((_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm) * scale;
4865
+ const ascent = ((_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm) * scale;
4633
4866
  for (let i = 0; i < content.length; i++) {
4634
4867
  const ch = content.charAt(i);
4635
4868
  const g = gf == null ? void 0 : gf.glyphs[ch];
@@ -4640,7 +4873,7 @@ function layoutGlyphTextChars(node, opts) {
4640
4873
  }
4641
4874
  };
4642
4875
  const walk = (el, parentStyle) => {
4643
- var _a2, _b2, _c2, _d2;
4876
+ var _a3, _b2, _c2, _d2;
4644
4877
  const s = resolveStyle2(el, parentStyle);
4645
4878
  const x = parseLen(el.x);
4646
4879
  const y = parseLen(el.y);
@@ -4650,7 +4883,7 @@ function layoutGlyphTextChars(node, opts) {
4650
4883
  lines.push({ start: pen.x, end: pen.x });
4651
4884
  }
4652
4885
  if (y !== void 0) pen.y = y;
4653
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
4886
+ pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4654
4887
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4655
4888
  const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4656
4889
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
@@ -4682,7 +4915,7 @@ function layoutGlyphTextChars(node, opts) {
4682
4915
  });
4683
4916
  }
4684
4917
  function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4685
- var _a, _b;
4918
+ var _a2, _b;
4686
4919
  const { glyphs, warnings, alongPath } = opts;
4687
4920
  const sampler = createPathSampler(pathD);
4688
4921
  if (!sampler) {
@@ -4693,9 +4926,9 @@ function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4693
4926
  const chars = [];
4694
4927
  let adv = 0;
4695
4928
  const walk = (el, parentStyle) => {
4696
- var _a2, _b2, _c;
4929
+ var _a3, _b2, _c;
4697
4930
  const s = resolveStyle2(el, parentStyle);
4698
- const content = (_a2 = str(el[TEXT_CONTENT_ATTR])) != null ? _a2 : str(el[TEXT_ATTR]);
4931
+ const content = (_a3 = str(el[TEXT_CONTENT_ATTR])) != null ? _a3 : str(el[TEXT_ATTR]);
4699
4932
  if (content && !((_b2 = el.children) == null ? void 0 : _b2.length)) {
4700
4933
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4701
4934
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
@@ -4715,7 +4948,7 @@ function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4715
4948
  walk(node, rootStyleOf(node));
4716
4949
  const width = adv;
4717
4950
  const tlr = readAnimatable(alongPath == null ? void 0 : alongPath.textLength);
4718
- const tlv = tlr.kind === "animated" ? Number((_a = tlr.keyframes[0]) == null ? void 0 : _a.value) || 0 : tlr.kind === "static" ? Number(tlr.value) || 0 : 0;
4951
+ const tlv = tlr.kind === "animated" ? Number((_a2 = tlr.keyframes[0]) == null ? void 0 : _a2.value) || 0 : tlr.kind === "static" ? Number(tlr.value) || 0 : 0;
4719
4952
  const k = tlv > 0 && width > 0 ? tlv / width : 1;
4720
4953
  const so = readAnimatable(alongPath == null ? void 0 : alongPath.startOffset);
4721
4954
  const { along: alongOffset, perp } = alongPathNodeOffsets(node);
@@ -4747,9 +4980,9 @@ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
4747
4980
  const cells = [];
4748
4981
  let adv = 0;
4749
4982
  const walk = (el, parentStyle) => {
4750
- var _a, _b, _c;
4983
+ var _a2, _b, _c;
4751
4984
  const s = resolveStyle2(el, parentStyle);
4752
- const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
4985
+ const content = (_a2 = str(el[TEXT_CONTENT_ATTR])) != null ? _a2 : str(el[TEXT_ATTR]);
4753
4986
  if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
4754
4987
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4755
4988
  if (gf) {
@@ -4786,9 +5019,9 @@ function alongAffine(sampler, dist, scale, widthEm, perp = 0) {
4786
5019
  return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];
4787
5020
  }
4788
5021
  function alongPathNodeOffsets(node) {
4789
- var _a, _b, _c;
5022
+ var _a2, _b, _c;
4790
5023
  return {
4791
- along: ((_a = parseLen(node.x)) != null ? _a : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
5024
+ along: ((_a2 = parseLen(node.x)) != null ? _a2 : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
4792
5025
  perp: (_c = parseLen(node.dy)) != null ? _c : 0
4793
5026
  };
4794
5027
  }
@@ -4828,7 +5061,7 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
4828
5061
  return toGroup(node, buildPaths(placements, create, warnings), create);
4829
5062
  }
4830
5063
  function numTrackOf(raw) {
4831
- var _a;
5064
+ var _a2;
4832
5065
  const r = readAnimatable(raw);
4833
5066
  if (r.kind === "animated" && r.keyframes.length >= 2) {
4834
5067
  const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));
@@ -4851,7 +5084,7 @@ function numTrackOf(raw) {
4851
5084
  }
4852
5085
  };
4853
5086
  }
4854
- const v = r.kind === "animated" ? Number((_a = r.keyframes[0]) == null ? void 0 : _a.value) || 0 : r.kind === "static" ? Number(r.value) || 0 : 0;
5087
+ const v = r.kind === "animated" ? Number((_a2 = r.keyframes[0]) == null ? void 0 : _a2.value) || 0 : r.kind === "static" ? Number(r.value) || 0 : 0;
4855
5088
  return { animated: false, times: [], at: () => v };
4856
5089
  }
4857
5090
  function mergeTrackTimes(a, b) {
@@ -4933,7 +5166,7 @@ function paintProps(paint) {
4933
5166
  return p;
4934
5167
  }
4935
5168
  function missingGlyphProps(isMissing) {
4936
- return isMissing ? { class: MISSING_GLYPH_CLASS_NAME } : {};
5169
+ return isMissing ? { [CLASS_ATTR]: MISSING_GLYPH_CLASS_NAME } : {};
4937
5170
  }
4938
5171
  function buildPaths(placements, create, warnings) {
4939
5172
  if (!placements.length) {
@@ -4977,14 +5210,14 @@ function materialiseGlyphText(node, opts) {
4977
5210
  function applyTextGlyphsEffect(node, fx, ctx) {
4978
5211
  if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
4979
5212
  if (!ctx.glyphs) {
4980
- ctx.warnings.push("textGlyphs: no definitions.glyphs \u2014 left as native <text>");
5213
+ ctx.warnings.push("textGlyphs: no definitions.fonts \u2014 left as native <text>");
4981
5214
  return node;
4982
5215
  }
4983
5216
  return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
4984
5217
  }
4985
5218
  function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
4986
5219
  if (!ctx.glyphs) {
4987
- ctx.warnings.push("textGlyphs: no definitions.glyphs");
5220
+ ctx.warnings.push("textGlyphs: no definitions.fonts");
4988
5221
  return null;
4989
5222
  }
4990
5223
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
@@ -5124,12 +5357,11 @@ function getOffsetIndexRange(minMaxOffset) {
5124
5357
  ];
5125
5358
  }
5126
5359
  function readScalarValues(r) {
5127
- var _a;
5128
5360
  if (r.kind === "absent") return [];
5129
5361
  if (r.kind === "static") return [r.value];
5130
5362
  const out = [];
5131
5363
  for (const kf of r.keyframes) {
5132
- const v = (_a = kf.value) != null ? _a : kf.v;
5364
+ const v = kfValue(kf);
5133
5365
  if (typeof v === "number") out.push(v);
5134
5366
  }
5135
5367
  return out;
@@ -5139,14 +5371,11 @@ function computeAnimAttr(read, map) {
5139
5371
  if (read.kind === "static") return { kind: "static", value: map(read.value) };
5140
5372
  return {
5141
5373
  kind: "animated",
5142
- keyframes: read.keyframes.map((kf) => {
5143
- var _a, _b, _c, _d;
5144
- return {
5145
- time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
5146
- value: map((_c = kf.value) != null ? _c : kf.v),
5147
- easing: (_d = kf.easing) != null ? _d : kf.e
5148
- };
5149
- }),
5374
+ keyframes: read.keyframes.map((kf) => ({
5375
+ time: kfTime(kf),
5376
+ value: map(kfValue(kf)),
5377
+ easing: kfEasing(kf)
5378
+ })),
5150
5379
  loop: read.loop
5151
5380
  };
5152
5381
  }
@@ -5156,7 +5385,6 @@ function applyAttr(node, attrName, attr) {
5156
5385
  }
5157
5386
  var OPACITY_STEP_MS = 10;
5158
5387
  function computeOpacityFromRange(rangeRead) {
5159
- var _a, _b, _c, _d, _e, _f;
5160
5388
  const hide = (v) => v[0] === v[1];
5161
5389
  if (rangeRead.kind === "absent") return void 0;
5162
5390
  if (rangeRead.kind === "static") return hide(rangeRead.value) ? { kind: "static", value: 0 } : void 0;
@@ -5164,7 +5392,7 @@ function computeOpacityFromRange(rangeRead) {
5164
5392
  let anyHide = false;
5165
5393
  let allHide = true;
5166
5394
  for (const kf of kfs) {
5167
- if (hide((_a = kf.value) != null ? _a : kf.v)) anyHide = true;
5395
+ if (hide(kfValue(kf))) anyHide = true;
5168
5396
  else allHide = false;
5169
5397
  }
5170
5398
  if (!anyHide) return void 0;
@@ -5174,10 +5402,10 @@ function computeOpacityFromRange(rangeRead) {
5174
5402
  const kf = kfs[i];
5175
5403
  const prevKf = i > 0 ? kfs[i - 1] : void 0;
5176
5404
  const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
5177
- const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
5178
- const thisHide = hide((_d = kf.value) != null ? _d : kf.v);
5179
- const prevHide = prevKf ? thisHide && hide((_e = prevKf.value) != null ? _e : prevKf.v) : thisHide;
5180
- const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
5405
+ const t = kfTime(kf);
5406
+ const thisHide = hide(kfValue(kf));
5407
+ const prevHide = prevKf ? thisHide && hide(kfValue(prevKf)) : thisHide;
5408
+ const nextHide = nextKf ? thisHide && hide(kfValue(nextKf)) : thisHide;
5181
5409
  if (prevHide && !nextHide) {
5182
5410
  out.push({ time: t, value: 0 });
5183
5411
  out.push({ time: t + OPACITY_STEP_MS, value: 1 });
@@ -5192,14 +5420,11 @@ function computeOpacityFromRange(rangeRead) {
5192
5420
  function readRangeWithCrossings(raw) {
5193
5421
  const r = readAnimatable(raw);
5194
5422
  if (r.kind !== "animated") return r;
5195
- const kfs = r.keyframes.map((kf) => {
5196
- var _a, _b, _c, _d;
5197
- return {
5198
- time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
5199
- value: (_c = kf.value) != null ? _c : kf.v,
5200
- easing: (_d = kf.easing) != null ? _d : kf.e
5201
- };
5202
- });
5423
+ const kfs = r.keyframes.map((kf) => ({
5424
+ time: kfTime(kf),
5425
+ value: kfValue(kf),
5426
+ easing: kfEasing(kf)
5427
+ }));
5203
5428
  const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
5204
5429
  if (!hasReverse) {
5205
5430
  return {
@@ -5296,20 +5521,20 @@ function pxBezierPathLength(path) {
5296
5521
  return total;
5297
5522
  }
5298
5523
  function segmentLength(path, from, to) {
5299
- var _a, _b, _c, _d;
5524
+ var _a2, _b, _c, _d;
5300
5525
  const v = path.v;
5301
5526
  const p0 = v[from];
5302
5527
  const p3 = v[to];
5303
- const p1 = (_b = (_a = path.o) == null ? void 0 : _a[from]) != null ? _b : p0;
5528
+ const p1 = (_b = (_a2 = path.o) == null ? void 0 : _a2[from]) != null ? _b : p0;
5304
5529
  const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
5305
5530
  const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
5306
5531
  return lut.ds[lut.ds.length - 1];
5307
5532
  }
5308
5533
  var ARC_KAPPA = 0.5522847498307936;
5309
5534
  function shapeToPathD(node) {
5310
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5535
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5311
5536
  if (node.type === "rect") {
5312
- const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
5537
+ const x = Number((_a2 = node.x) != null ? _a2 : 0), y = Number((_b = node.y) != null ? _b : 0);
5313
5538
  const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
5314
5539
  return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
5315
5540
  }
@@ -5325,7 +5550,7 @@ function shapeToPathD(node) {
5325
5550
  return void 0;
5326
5551
  }
5327
5552
  function applyPlayerEffects(root) {
5328
- var _a, _b;
5553
+ var _a2, _b;
5329
5554
  const ctx = {
5330
5555
  defs: [],
5331
5556
  warnings: [],
@@ -5336,8 +5561,8 @@ function applyPlayerEffects(root) {
5336
5561
  maskAncestorChains: /* @__PURE__ */ new Map(),
5337
5562
  // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
5338
5563
  // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
5339
- engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi,
5340
- glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
5564
+ engine: resolveTimelineEngine((_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.engine),
5565
+ glyphs: (_b = getDefs(root)) == null ? void 0 : _b.fonts
5341
5566
  };
5342
5567
  const working = clone(root);
5343
5568
  indexById(working, ctx.idMap);
@@ -5360,7 +5585,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
5360
5585
  let consumedByGlyphs = false;
5361
5586
  if (text == null ? void 0 : text.useGlyphs) {
5362
5587
  if (textPath) {
5363
- const pathD = typeof textPath.path === "string" ? textPath.path : void 0;
5588
+ const pathD = typeof textPath.pathData === "string" ? textPath.pathData : void 0;
5364
5589
  const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textPath.textLength, textPath.pathOverflow);
5365
5590
  if (glyphed) {
5366
5591
  n = glyphed;
@@ -5392,26 +5617,6 @@ function applyPlayerEffects_retime(node, ctx) {
5392
5617
  applyAllRetimeEffects(node, ctx);
5393
5618
  return node;
5394
5619
  }
5395
- var kfTime = (kf) => {
5396
- var _a, _b;
5397
- return (_b = (_a = kf.t) != null ? _a : kf.time) != null ? _b : 0;
5398
- };
5399
- var kfValue = (kf) => {
5400
- var _a;
5401
- return (_a = kf.v) != null ? _a : kf.value;
5402
- };
5403
- var kfEasing = (kf) => {
5404
- var _a;
5405
- return (_a = kf.e) != null ? _a : kf.easing;
5406
- };
5407
- var kfTangentIn = (kf) => {
5408
- var _a;
5409
- return (_a = kf.tangentIn) != null ? _a : kf.ti;
5410
- };
5411
- var kfTangentOut = (kf) => {
5412
- var _a;
5413
- return (_a = kf.tangentOut) != null ? _a : kf.to;
5414
- };
5415
5620
  function cubicAt(p0, c1, c2, p1, t) {
5416
5621
  const u = 1 - t;
5417
5622
  const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
@@ -5435,9 +5640,9 @@ var fmt2 = (n) => {
5435
5640
  return Object.is(r, -0) ? "0" : String(r);
5436
5641
  };
5437
5642
  function buildOffsetPath(propAnim) {
5438
- var _a, _b, _c, _d;
5643
+ var _a2, _b, _c;
5439
5644
  if (propAnim.alongPathMode !== "offsetPath") return void 0;
5440
- const kfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
5645
+ const kfs = propAnim.keyframes;
5441
5646
  if (!kfs || kfs.length < 2) return void 0;
5442
5647
  const first = kfValue(kfs[0]);
5443
5648
  const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
@@ -5448,7 +5653,7 @@ function buildOffsetPath(propAnim) {
5448
5653
  if (!tr || tr.length < 2) return void 0;
5449
5654
  const parts = Object.keys(v);
5450
5655
  if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
5451
- const o = (_b = v == null ? void 0 : v.origin) != null ? _b : [0, 0];
5656
+ const o = (_a2 = v == null ? void 0 : v.origin) != null ? _a2 : [0, 0];
5452
5657
  if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
5453
5658
  points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
5454
5659
  }
@@ -5457,8 +5662,8 @@ function buildOffsetPath(propAnim) {
5457
5662
  const segLens = [];
5458
5663
  for (let i = 0; i < points.length - 1; i++) {
5459
5664
  const p0 = points[i], p1 = points[i + 1];
5460
- const to = (_c = kfTangentOut(kfs[i])) != null ? _c : [0, 0];
5461
- const ti = (_d = kfTangentIn(kfs[i + 1])) != null ? _d : [0, 0];
5665
+ const to = (_b = kfTangentOut(kfs[i])) != null ? _b : [0, 0];
5666
+ const ti = (_c = kfTangentIn(kfs[i + 1])) != null ? _c : [0, 0];
5462
5667
  const c1 = [p0[0] + to[0], p0[1] + to[1]];
5463
5668
  const c2 = [p1[0] + ti[0], p1[1] + ti[1]];
5464
5669
  d += "C" + fmt2(c1[0]) + "," + fmt2(c1[1]) + "," + fmt2(c2[0]) + "," + fmt2(c2[1]) + "," + fmt2(p1[0]) + "," + fmt2(p1[1]);
@@ -5479,7 +5684,7 @@ function buildOffsetPath(propAnim) {
5479
5684
  }
5480
5685
  function materialiseOffsetPathsInTree(root) {
5481
5686
  const walk = (node) => {
5482
- var _a;
5687
+ var _a2;
5483
5688
  let out = node;
5484
5689
  const anim = node.animate;
5485
5690
  const transform = anim == null ? void 0 : anim["transform"];
@@ -5487,16 +5692,16 @@ function materialiseOffsetPathsInTree(root) {
5487
5692
  const built = buildOffsetPath(transform);
5488
5693
  if (built) {
5489
5694
  const newAnimate = __spreadValues2({}, anim);
5490
- delete newAnimate["transform"];
5695
+ delete newAnimate[TRANSFORM_ATTR];
5491
5696
  const distance = { keyframes: built.distanceKfs };
5492
5697
  if (transform.loop !== void 0) distance.loop = transform.loop;
5493
- newAnimate["offsetDistance"] = distance;
5698
+ newAnimate[OFFSET_DISTANCE_ATTR] = distance;
5494
5699
  const staticTr = node.transform;
5495
5700
  let newTransform = staticTr;
5496
5701
  if (staticTr && typeof staticTr === "object") {
5497
5702
  const t = __spreadValues2({}, staticTr);
5498
- delete t["translate"];
5499
- delete t["origin"];
5703
+ delete t[TRANSFORM_PART.translate];
5704
+ delete t[TRANSFORM_PART.origin];
5500
5705
  newTransform = Object.keys(t).length ? t : void 0;
5501
5706
  }
5502
5707
  out = __spreadProps2(__spreadValues2({}, node), {
@@ -5512,7 +5717,7 @@ function materialiseOffsetPathsInTree(root) {
5512
5717
  else delete out.transform;
5513
5718
  }
5514
5719
  }
5515
- if ((_a = out.children) == null ? void 0 : _a.length) {
5720
+ if ((_a2 = out.children) == null ? void 0 : _a2.length) {
5516
5721
  const children = out.children.map(walk);
5517
5722
  if (children.some((c, i) => c !== out.children[i])) out = __spreadProps2(__spreadValues2({}, out), { children });
5518
5723
  }
@@ -5521,12 +5726,12 @@ function materialiseOffsetPathsInTree(root) {
5521
5726
  return walk(root);
5522
5727
  }
5523
5728
  function materialiseAllInTree(doc, engine, opts) {
5524
- var _a, _b;
5729
+ var _a2, _b;
5525
5730
  let root = applyPlayerEffects(doc).root;
5526
5731
  root = materialiseOffsetPathsInTree(root);
5527
- const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
5732
+ const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : DEFAULT_DURATION_MS;
5528
5733
  root = materialiseInternalLoopsInTree(root, duration);
5529
- if (engine === PxAnimatorEngine.waapi) {
5734
+ if (engine === PxTimelineEngine.native) {
5530
5735
  root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5531
5736
  root = materialiseAnimatedUseInstances(root);
5532
5737
  root = pruneUnreferencedDefs(root);
@@ -5536,9 +5741,9 @@ function materialiseAllInTree(doc, engine, opts) {
5536
5741
  function pruneUnreferencedDefs(root) {
5537
5742
  const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
5538
5743
  const walk = (n, fn) => {
5539
- var _a;
5744
+ var _a2;
5540
5745
  fn(n);
5541
- (_a = n.children) == null ? void 0 : _a.forEach((c) => walk(c, fn));
5746
+ (_a2 = n.children) == null ? void 0 : _a2.forEach((c) => walk(c, fn));
5542
5747
  };
5543
5748
  let changed = true;
5544
5749
  while (changed) {
@@ -5576,9 +5781,9 @@ function cancelFrame(handle) {
5576
5781
  g.clearTimeout(handle);
5577
5782
  }
5578
5783
  function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5579
- var _a;
5784
+ var _a2;
5580
5785
  const config = getAnimatorConfig(doc) || {};
5581
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
5786
+ const bindings = getNormalisedBindings(doc, PxTimelineEngine.js);
5582
5787
  const _iterations = config.iterations;
5583
5788
  let iterations = 1;
5584
5789
  if (typeof _iterations === "number") iterations = _iterations || 1;
@@ -5587,7 +5792,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5587
5792
  const duration = +(config.duration || DEFAULT_DURATION_MS);
5588
5793
  const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
5589
5794
  const direction = config.direction || "normal";
5590
- const fill = (_a = config.fill) != null ? _a : "forwards";
5795
+ const fill = (_a2 = config.fill) != null ? _a2 : "forwards";
5591
5796
  const fillsForwards = fill === "forwards" || fill === "both";
5592
5797
  const fillsBackwards = fill === "backwards" || fill === "both";
5593
5798
  let timerId = null;
@@ -5649,7 +5854,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5649
5854
  }
5650
5855
  }
5651
5856
  const tick = () => {
5652
- var _a2, _b;
5857
+ var _a3, _b;
5653
5858
  if (!adapter.isConnected()) {
5654
5859
  pauseAnim();
5655
5860
  return;
@@ -5665,7 +5870,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5665
5870
  renderFrame(0);
5666
5871
  if (!finishCalled) {
5667
5872
  finishCalled = true;
5668
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
5873
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
5669
5874
  }
5670
5875
  return;
5671
5876
  }
@@ -5757,17 +5962,17 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5757
5962
  }
5758
5963
  };
5759
5964
  const cancelAnim = () => {
5760
- var _a2;
5965
+ var _a3;
5761
5966
  pauseAnim();
5762
5967
  timeBeforeLastStartMs = 0;
5763
5968
  lastStartedTs = 0;
5764
5969
  playing = false;
5765
5970
  finishCalled = false;
5766
5971
  renderFrame(timeBeforeLastStartMs);
5767
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
5972
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
5768
5973
  };
5769
5974
  const finishAnim = (callOnFinish = true) => {
5770
- var _a2;
5975
+ var _a3;
5771
5976
  if (Number.isFinite(totalDuration)) {
5772
5977
  timeBeforeLastStartMs = totalDuration;
5773
5978
  } else {
@@ -5782,7 +5987,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5782
5987
  renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);
5783
5988
  if (callOnFinish && !finishCalled) {
5784
5989
  finishCalled = true;
5785
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
5990
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
5786
5991
  }
5787
5992
  };
5788
5993
  const api = {
@@ -5792,14 +5997,14 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5792
5997
  return _isPlaying();
5793
5998
  },
5794
5999
  "play": () => {
5795
- var _a2;
6000
+ var _a3;
5796
6001
  startAnim();
5797
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
6002
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
5798
6003
  },
5799
6004
  "pause": () => {
5800
- var _a2;
6005
+ var _a3;
5801
6006
  pauseAnim();
5802
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
6007
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
5803
6008
  },
5804
6009
  "cancel": () => {
5805
6010
  cancelAnim();
@@ -5831,9 +6036,9 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5831
6036
  renderFrame(getAnimCurrentTime());
5832
6037
  },
5833
6038
  "destroy": () => {
5834
- var _a2;
6039
+ var _a3;
5835
6040
  api.cancel();
5836
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6041
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
5837
6042
  }
5838
6043
  };
5839
6044
  return api;
@@ -5887,9 +6092,9 @@ function lerp(a, b, f) {
5887
6092
  return a + (b - a) * f;
5888
6093
  }
5889
6094
  function interpParts(kfs, t) {
5890
- var _a, _b, _c, _d, _e, _f, _g;
6095
+ var _a2, _b, _c, _d, _e, _f, _g;
5891
6096
  if (!kfs.length) return {};
5892
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value || {};
6097
+ if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value || {};
5893
6098
  if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
5894
6099
  let i = 0;
5895
6100
  while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
@@ -5920,10 +6125,10 @@ function nodeMatrix(node, t) {
5920
6125
  return IDENTITY;
5921
6126
  }
5922
6127
  function evalScalar(animated, staticVal, fallback, t) {
5923
- var _a, _b, _c, _d, _e, _f;
6128
+ var _a2, _b, _c, _d, _e, _f;
5924
6129
  if (animated && animated.keyframes && animated.keyframes.length) {
5925
6130
  const kfs = animated.keyframes;
5926
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value;
6131
+ if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value;
5927
6132
  if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
5928
6133
  let i = 0;
5929
6134
  while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
@@ -5936,9 +6141,9 @@ function evalScalar(animated, staticVal, fallback, t) {
5936
6141
  var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
5937
6142
  var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
5938
6143
  function buildIdMap2(node, map) {
5939
- var _a;
6144
+ var _a2;
5940
6145
  if (typeof node.id === "string") map.set(node.id, node);
5941
- (_a = node.children) == null ? void 0 : _a.forEach((c) => buildIdMap2(c, map));
6146
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => buildIdMap2(c, map));
5942
6147
  }
5943
6148
  function num(v) {
5944
6149
  return v === void 0 || v === null ? 0 : Number(v);
@@ -5947,7 +6152,7 @@ function round(n) {
5947
6152
  return Math.round(n * 100) / 100 + 0;
5948
6153
  }
5949
6154
  function geomKey(node) {
5950
- var _a;
6155
+ var _a2;
5951
6156
  switch (node.type) {
5952
6157
  case "rect":
5953
6158
  return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
@@ -5956,14 +6161,14 @@ function geomKey(node) {
5956
6161
  case "circle":
5957
6162
  return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
5958
6163
  case "path":
5959
- return String((_a = node.d) != null ? _a : "");
6164
+ return String((_a2 = node.d) != null ? _a2 : "");
5960
6165
  default:
5961
6166
  return "";
5962
6167
  }
5963
6168
  }
5964
6169
  function describePrimitive(node, m, t) {
5965
- var _a, _b, _c, _d, _e;
5966
- const fill = (_a = node.fill) != null ? _a : "";
6170
+ var _a2, _b, _c, _d, _e;
6171
+ const fill = (_a2 = node.fill) != null ? _a2 : "";
5967
6172
  const stroke = (_b = node.stroke) != null ? _b : "";
5968
6173
  const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
5969
6174
  const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
@@ -5972,7 +6177,7 @@ function describePrimitive(node, m, t) {
5972
6177
  return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
5973
6178
  }
5974
6179
  function flatten(node, parent, t, idMap, out) {
5975
- var _a;
6180
+ var _a2;
5976
6181
  const type = node.type || "";
5977
6182
  if (SKIP_TYPES.has(type)) return;
5978
6183
  const m = mul(parent, nodeMatrix(node, t));
@@ -5985,33 +6190,33 @@ function flatten(node, parent, t, idMap, out) {
5985
6190
  return;
5986
6191
  }
5987
6192
  if (CONTAINER_TYPES.has(type)) {
5988
- (_a = node.children) == null ? void 0 : _a.forEach((c) => flatten(c, m, t, idMap, out));
6193
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => flatten(c, m, t, idMap, out));
5989
6194
  return;
5990
6195
  }
5991
6196
  out.push(describePrimitive(node, m, t));
5992
6197
  }
5993
6198
  function collectSampleTimes(node, into) {
5994
- var _a;
6199
+ var _a2;
5995
6200
  into.add(0);
5996
6201
  const scanAnim = (anim) => {
5997
- var _a2;
6202
+ var _a3;
5998
6203
  if (!anim || typeof anim !== "object") return;
5999
6204
  for (const key of Object.keys(anim)) {
6000
- const kfs = (_a2 = anim[key]) == null ? void 0 : _a2.keyframes;
6205
+ const kfs = (_a3 = anim[key]) == null ? void 0 : _a3.keyframes;
6001
6206
  if (Array.isArray(kfs)) kfs.forEach((kf) => {
6002
- var _a3;
6003
- return into.add((_a3 = kf.time) != null ? _a3 : 0);
6207
+ var _a4;
6208
+ return into.add((_a4 = kf.time) != null ? _a4 : 0);
6004
6209
  });
6005
6210
  }
6006
6211
  };
6007
6212
  scanAnim(node.animate);
6008
6213
  if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
6009
6214
  node.transform.keyframes.forEach((kf) => {
6010
- var _a2;
6011
- return into.add((_a2 = kf.time) != null ? _a2 : 0);
6215
+ var _a3;
6216
+ return into.add((_a3 = kf.time) != null ? _a3 : 0);
6012
6217
  });
6013
6218
  }
6014
- (_a = node.children) == null ? void 0 : _a.forEach((c) => collectSampleTimes(c, into));
6219
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => collectSampleTimes(c, into));
6015
6220
  }
6016
6221
  function visualModelAt(root, t) {
6017
6222
  const idMap = /* @__PURE__ */ new Map();
@@ -6045,8 +6250,191 @@ function subtractMultiset(a, b) {
6045
6250
  }
6046
6251
  return extra;
6047
6252
  }
6253
+ var FLAT_ONLY_KEYS = [
6254
+ "timelineSource",
6255
+ "scroll",
6256
+ "trigger",
6257
+ "delay",
6258
+ "iterations",
6259
+ "direction",
6260
+ "fill",
6261
+ "resetOnFinish",
6262
+ "duration",
6263
+ "mode",
6264
+ "frameRate"
6265
+ ];
6266
+ var CONTENT_KEYS = ["definitions", "animateById"];
6267
+ var isPlainObject = (v) => !!v && typeof v === "object" && !Array.isArray(v);
6268
+ var timelineTypeOf = (t) => isPlainObject(t) && typeof t.type === "string" ? t.type : "time";
6269
+ var isScrollish = (type) => type === "scroll" || type === "view";
6270
+ function mergePlain(base, patch) {
6271
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6272
+ for (const key of Object.keys(patch)) {
6273
+ const value = patch[key];
6274
+ if (value === null) {
6275
+ delete out[key];
6276
+ continue;
6277
+ }
6278
+ if (isPlainObject(value)) {
6279
+ out[key] = mergePlain(out[key], value);
6280
+ continue;
6281
+ }
6282
+ out[key] = value;
6283
+ }
6284
+ return out;
6285
+ }
6286
+ function mergeTimeline(base, patch, warn) {
6287
+ const baseType = timelineTypeOf(base);
6288
+ const patchNamesType = isPlainObject(patch) && typeof patch.type === "string";
6289
+ const patchType = patchNamesType ? String(patch.type) : baseType;
6290
+ let merged;
6291
+ if (patchType !== baseType) {
6292
+ const carried = {};
6293
+ if (isPlainObject(base)) {
6294
+ for (const k of PX_TIMELINE_SHARED_KEYS) {
6295
+ if (base[k] !== void 0) carried[k] = base[k];
6296
+ }
6297
+ }
6298
+ merged = mergePlain(carried, patch);
6299
+ } else {
6300
+ merged = mergePlain(base, patch);
6301
+ }
6302
+ if (isScrollish(patchType)) {
6303
+ for (const k of PX_TIME_ONLY_TIMELINE_KEYS) {
6304
+ if (merged[k] === void 0) continue;
6305
+ warn("animator.timeline." + k + ": no slot on a '" + patchType + "' timeline \u2014 dropped");
6306
+ delete merged[k];
6307
+ }
6308
+ if (merged.iterations === "infinite") {
6309
+ warn("animator.timeline.iterations: 'infinite' cannot map onto a scroll range \u2014 dropped");
6310
+ delete merged.iterations;
6311
+ }
6312
+ }
6313
+ return merged;
6314
+ }
6315
+ function foldAnimatorConfigShortcuts(config, shortcuts) {
6316
+ let base;
6317
+ if (typeof config === "string") {
6318
+ try {
6319
+ base = JSON.parse(config);
6320
+ } catch (e) {
6321
+ console.warn("animator config: not valid JSON \u2014 ignored", e);
6322
+ base = void 0;
6323
+ }
6324
+ } else {
6325
+ base = config != null ? config : void 0;
6326
+ }
6327
+ const { duration, delay, iterations, startOn } = shortcuts;
6328
+ if (duration === void 0 && delay === void 0 && iterations === void 0 && startOn === void 0) {
6329
+ return base;
6330
+ }
6331
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6332
+ const timeline = __spreadValues2({}, out.timeline);
6333
+ if (duration !== void 0) timeline.duration = duration;
6334
+ if (delay !== void 0) timeline.delay = delay;
6335
+ if (iterations !== void 0) timeline.iterations = iterations;
6336
+ if (startOn !== void 0) {
6337
+ timeline.trigger = __spreadProps2(__spreadValues2({}, timeline.trigger), { startOn });
6338
+ }
6339
+ out.timeline = timeline;
6340
+ return out;
6341
+ }
6342
+ function mergeAnimatorConfig(base, patch) {
6343
+ const warnings = [];
6344
+ const warn = (m) => warnings.push(m);
6345
+ if (patch === null) return { config: void 0, warnings };
6346
+ if (!isPlainObject(patch) || Object.keys(patch).length === 0) {
6347
+ return { config: base, warnings };
6348
+ }
6349
+ const flatInBase = isPlainObject(base) ? FLAT_ONLY_KEYS.filter((k) => base[k] !== void 0) : [];
6350
+ if (flatInBase.length) {
6351
+ warn("animator: the base carries the flat runtime spelling (" + flatInBase.join(", ") + "); the patch merges the wire spelling only");
6352
+ }
6353
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6354
+ for (const key of Object.keys(patch)) {
6355
+ const value = patch[key];
6356
+ if (value === null) {
6357
+ delete out[key];
6358
+ continue;
6359
+ }
6360
+ if (key === "timeline") {
6361
+ out.timeline = isPlainObject(value) ? mergeTimeline(out.timeline, value, warn) : value;
6362
+ continue;
6363
+ }
6364
+ if (isPlainObject(value)) {
6365
+ out[key] = mergePlain(out[key], value);
6366
+ continue;
6367
+ }
6368
+ out[key] = value;
6369
+ }
6370
+ return { config: out, warnings };
6371
+ }
6372
+ function applyAnimatorConfig(doc, patch, opts) {
6373
+ var _a2, _b;
6374
+ const reset = !!(opts == null ? void 0 : opts.resetDefaults);
6375
+ if (!doc || (patch === void 0 || !reset && (patch === null || !isPlainObject(patch) || !Object.keys(patch).length))) {
6376
+ return { doc, warnings: [] };
6377
+ }
6378
+ const anyDoc = doc;
6379
+ const atRoot = isPlainObject(anyDoc.animator);
6380
+ const atMeta = !atRoot && isPlainObject((_a2 = anyDoc.meta) == null ? void 0 : _a2.animator);
6381
+ const current = atRoot ? anyDoc.animator : atMeta ? anyDoc.meta.animator : void 0;
6382
+ const warnings = [];
6383
+ if (atRoot && isPlainObject((_b = anyDoc.meta) == null ? void 0 : _b.animator)) {
6384
+ warnings.push("animator: doc.meta.animator is shadowed by doc.animator and was not patched");
6385
+ }
6386
+ let base = current;
6387
+ if (reset) {
6388
+ const kept = {};
6389
+ for (const k of CONTENT_KEYS) {
6390
+ if (isPlainObject(current) && current[k] !== void 0) kept[k] = current[k];
6391
+ }
6392
+ base = kept;
6393
+ }
6394
+ const merged = mergeAnimatorConfig(base, patch != null ? patch : {});
6395
+ warnings.push(...merged.warnings);
6396
+ if (merged.config === current) return { doc, warnings };
6397
+ if (atMeta) {
6398
+ return {
6399
+ doc: __spreadProps2(__spreadValues2({}, anyDoc), { meta: __spreadProps2(__spreadValues2({}, anyDoc.meta), { animator: merged.config }) }),
6400
+ warnings
6401
+ };
6402
+ }
6403
+ return { doc: __spreadProps2(__spreadValues2({}, anyDoc), { animator: merged.config }), warnings };
6404
+ }
6405
+ var MAX_REPORTED = 6;
6406
+ var LEGACY_FLAT_KEYS = [
6407
+ ...PX_TIMELINE_SHARED_KEYS,
6408
+ ...PX_TIME_ONLY_TIMELINE_KEYS,
6409
+ "fill",
6410
+ "resetOnFinish",
6411
+ "timelineSource",
6412
+ "scroll"
6413
+ ];
6414
+ var isLegacyFlatAnimatorKey = (w) => LEGACY_FLAT_KEYS.some((k) => w.indexOf("animator." + k + ":") >= 0);
6415
+ function diagnoseDocument(doc) {
6416
+ let all;
6417
+ try {
6418
+ all = validateDocument(doc);
6419
+ } catch (e) {
6420
+ return { problems: [], legacy: [] };
6421
+ }
6422
+ const problems = [];
6423
+ const legacy = [];
6424
+ for (const w of all) (isLegacyFlatAnimatorKey(w) ? legacy : problems).push(w);
6425
+ return { problems, legacy };
6426
+ }
6427
+ function reportDocumentDiagnostics(doc, where) {
6428
+ const { problems } = diagnoseDocument(doc);
6429
+ if (!problems.length) return;
6430
+ const shown = problems.slice(0, MAX_REPORTED);
6431
+ const more = problems.length - shown.length;
6432
+ console.warn(
6433
+ where + ": this document does not match the animation schema in " + problems.length + " place" + (problems.length === 1 ? "" : "s") + ".\n" + shown.map((p) => " - " + p).join("\n") + (more > 0 ? "\n \u2026 and " + more + " more" : "") + "\n\nIf you did not author these keys, the usual cause is a build that MANGLES PROPERTY NAMES. An animation document is data loaded at runtime, so renaming the property reads inside the player stops them matching the keys in the JSON, and the animation silently does nothing. Feed the published reserved-name list to your minifier \u2014 @pixodesk/svg-animator-web/mangle-reserved.json \u2014 see docs/library/minification.md."
6434
+ );
6435
+ }
6048
6436
 
6049
- // src/PxAnimatorTriggers.ts
6437
+ // src/triggers/PxAnimatorTriggers.ts
6050
6438
  function setupAnimationTriggers(api, config) {
6051
6439
  const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
6052
6440
  const root = api.getRootElement();
@@ -6116,12 +6504,12 @@ function setupAnimationTriggers(api, config) {
6116
6504
  }
6117
6505
  case "scrollIntoView": {
6118
6506
  const effectiveRatio = (entry) => {
6119
- var _a, _b;
6507
+ var _a2, _b;
6120
6508
  const target = entry.boundingClientRect;
6121
6509
  const visible = entry.intersectionRect;
6122
6510
  if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
6123
6511
  const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
6124
- const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
6512
+ const declared = (_b = (_a2 = entry.rootBounds) == null ? void 0 : _a2.height) != null ? _b : Infinity;
6125
6513
  const viewport = Math.min(live, declared);
6126
6514
  const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
6127
6515
  return denom > 0 ? visible.height / denom : entry.intersectionRatio;
@@ -6151,7 +6539,7 @@ function setupAnimationTriggers(api, config) {
6151
6539
  return api;
6152
6540
  }
6153
6541
 
6154
- // src/PxAnimatorFrameLoop.ts
6542
+ // src/engines/PxAnimatorFrameLoop.ts
6155
6543
  function getSelector(id) {
6156
6544
  return "#" + id;
6157
6545
  }
@@ -6211,11 +6599,10 @@ function createDomAdapter(rootElement) {
6211
6599
  return adapter;
6212
6600
  }
6213
6601
 
6214
- // src/PxAnimatorWebApi.ts
6602
+ // src/engines/PxAnimatorWebApi.ts
6215
6603
  function createCssKf(kf, t, propName, unsupportedSet) {
6216
- var _a, _b;
6217
- let value = (_a = kf.v) != null ? _a : kf.value;
6218
- const e = (_b = kf.e) != null ? _b : kf.easing;
6604
+ let value = kfValue(kf);
6605
+ const e = kfEasing(kf);
6219
6606
  const cssKf = {
6220
6607
  offset: t,
6221
6608
  easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
@@ -6249,11 +6636,11 @@ function createCssKf(kf, t, propName, unsupportedSet) {
6249
6636
  return cssKf;
6250
6637
  }
6251
6638
  function clipKeyframesToDuration(propName, keyframes, duration) {
6252
- var _a, _b, _c, _d, _e;
6639
+ var _a2, _b, _c, _d, _e;
6253
6640
  const result = [];
6254
6641
  for (let i = 0; i < keyframes.length; i++) {
6255
6642
  const kf = keyframes[i];
6256
- const t = (_a = kf.t) != null ? _a : 0;
6643
+ const t = (_a2 = kf.t) != null ? _a2 : 0;
6257
6644
  if (t < 0) {
6258
6645
  const next = keyframes[i + 1];
6259
6646
  if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
@@ -6282,15 +6669,15 @@ function clipKeyframesToDuration(propName, keyframes, duration) {
6282
6669
  return result;
6283
6670
  }
6284
6671
  function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6285
- var _a;
6672
+ var _a2;
6286
6673
  const result = /* @__PURE__ */ new Map();
6287
6674
  for (const [propName, propAnim] of Object.entries(animDef)) {
6288
6675
  const duration = config.duration || 1;
6289
- const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);
6676
+ const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.keyframes || [], duration);
6290
6677
  const cssKeyframes = [];
6291
6678
  for (let i = 0; i < clippedKeyframes.length; i++) {
6292
6679
  const kf = clippedKeyframes[i];
6293
- const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
6680
+ const t = clamp(((_a2 = kf.t) != null ? _a2 : 0) / duration, 0, 1);
6294
6681
  const cssKf = createCssKf(kf, t, propName, unsupportedSet);
6295
6682
  if (i === 0 && (cssKf.offset || 0) > 0) {
6296
6683
  cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
@@ -6309,7 +6696,7 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6309
6696
  return result;
6310
6697
  }
6311
6698
  function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs, scrollTimeline) {
6312
- var _a;
6699
+ var _a2;
6313
6700
  const config = getAnimatorConfig(doc) || {};
6314
6701
  if (!rootElement) {
6315
6702
  if (doc.id) {
@@ -6320,7 +6707,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6320
6707
  console.warn("createFrameLoopAnimator: No root element provided");
6321
6708
  }
6322
6709
  }
6323
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
6710
+ const bindings = getNormalisedBindings(doc, PxTimelineEngine.native);
6324
6711
  const animations = [];
6325
6712
  const _iterations = config.iterations;
6326
6713
  let iterations;
@@ -6357,7 +6744,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6357
6744
  // animation ends — consistent with Lottie and other animation runtimes.
6358
6745
  // Without this, seeking to the last frame reverts elements to their
6359
6746
  // pre-animation state (the Web Animations API "after" phase with fill:'none').
6360
- fill: (_a = config.fill) != null ? _a : "forwards",
6747
+ fill: (_a2 = config.fill) != null ? _a2 : "forwards",
6361
6748
  direction: config.direction,
6362
6749
  iterations
6363
6750
  };
@@ -6374,16 +6761,16 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6374
6761
  if (scrollTimeline.rangeEnd) a.rangeEnd = scrollTimeline.rangeEnd;
6375
6762
  }
6376
6763
  if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
6377
- var _a2;
6764
+ var _a3;
6378
6765
  if (finishNotified) return;
6379
6766
  finishNotified = true;
6380
- (_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6767
+ (_a3 = callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
6381
6768
  };
6382
6769
  if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
6383
- var _a2;
6770
+ var _a3;
6384
6771
  if (removeCalled) return;
6385
6772
  removeCalled = true;
6386
- (_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6773
+ (_a3 = callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6387
6774
  };
6388
6775
  if (seekPosition !== void 0) {
6389
6776
  anim.currentTime = seekPosition;
@@ -6404,31 +6791,31 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6404
6791
  "isReady": () => true,
6405
6792
  "getRootElement": () => rootElement || null,
6406
6793
  "isPlaying": () => {
6407
- var _a2;
6408
- return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
6794
+ var _a3;
6795
+ return ((_a3 = animations[0]) == null ? void 0 : _a3.playState) === "running";
6409
6796
  },
6410
6797
  "play": () => {
6411
- var _a2;
6798
+ var _a3;
6412
6799
  finishNotified = false;
6413
6800
  animations.forEach((a) => a.play());
6414
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
6801
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
6415
6802
  },
6416
6803
  "pause": () => {
6417
- var _a2;
6804
+ var _a3;
6418
6805
  animations.forEach((a) => a.pause());
6419
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
6806
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
6420
6807
  },
6421
6808
  "cancel": () => {
6422
- var _a2;
6809
+ var _a3;
6423
6810
  finishNotified = false;
6424
6811
  animations.forEach((a) => a.cancel());
6425
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
6812
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
6426
6813
  },
6427
6814
  "finish": () => {
6428
- var _a2;
6815
+ var _a3;
6429
6816
  for (const a of animations) {
6430
6817
  try {
6431
- if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
6818
+ if (((_a3 = a.effect) == null ? void 0 : _a3.getTiming().iterations) === Infinity) {
6432
6819
  a.effect.updateTiming({ iterations: 1 });
6433
6820
  a.finish();
6434
6821
  a.effect.updateTiming({ iterations: Infinity });
@@ -6445,8 +6832,8 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6445
6832
  return api;
6446
6833
  },
6447
6834
  "getCurrentTime": () => {
6448
- var _a2, _b;
6449
- const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
6835
+ var _a3, _b;
6836
+ const res = (_b = (_a3 = animations[0]) == null ? void 0 : _a3.currentTime) != null ? _b : null;
6450
6837
  return res !== null ? +res : null;
6451
6838
  },
6452
6839
  "setCurrentTime": (time) => {
@@ -6456,12 +6843,12 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6456
6843
  });
6457
6844
  },
6458
6845
  "destroy": () => {
6459
- var _a2;
6846
+ var _a3;
6460
6847
  api.cancel();
6461
6848
  animations.splice(0, animations.length);
6462
6849
  if (!removeCalled) {
6463
6850
  removeCalled = true;
6464
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6851
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6465
6852
  }
6466
6853
  }
6467
6854
  };
@@ -6478,21 +6865,21 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6478
6865
  return api;
6479
6866
  }
6480
6867
 
6481
- // src/PxScrollDriver.ts
6868
+ // src/scroll/PxScrollDriver.ts
6482
6869
  function nativeRangeOffset(point, defaultFraction, view) {
6483
- var _a, _b, _c;
6870
+ var _a2, _b, _c;
6484
6871
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
6485
- const pct = (_b = (_a = globalThis.CSS) == null ? void 0 : _a.percent) == null ? void 0 : _b.call(_a, fraction * 100);
6872
+ const pct = (_b = (_a2 = globalThis.CSS) == null ? void 0 : _a2.percent) == null ? void 0 : _b.call(_a2, fraction * 100);
6486
6873
  if (pct === void 0) return void 0;
6487
6874
  return view ? { rangeName: (_c = point == null ? void 0 : point.phase) != null ? _c : "cover", offset: pct } : { offset: pct };
6488
6875
  }
6489
6876
  function createNativeScrollTimeline(subject, config) {
6490
- var _a, _b, _c, _d;
6877
+ var _a2, _b, _c, _d;
6491
6878
  if (!config || !isScrollTimeline(config)) return null;
6492
6879
  const scroll = config.scroll || {};
6493
- const kind = (_a = scroll.kind) != null ? _a : "view";
6880
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6494
6881
  if (scroll.smoothing) {
6495
- console.warn('scroll timeline: `smoothing` needs the built-in driver \u2014 ignoring `driver: "native"`');
6882
+ console.warn("scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
6496
6883
  return null;
6497
6884
  }
6498
6885
  const g = globalThis;
@@ -6509,7 +6896,7 @@ function createNativeScrollTimeline(subject, config) {
6509
6896
  timeline = new Ctor({ source, axis });
6510
6897
  }
6511
6898
  } catch (e) {
6512
- console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the custom driver", e);
6899
+ console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
6513
6900
  return null;
6514
6901
  }
6515
6902
  return {
@@ -6537,7 +6924,7 @@ function documentScroller() {
6537
6924
  var SUBJECT_PARENT = "parent";
6538
6925
  var SUBJECT_SCROLLER = "scroller";
6539
6926
  function resolveScrollSubject(svgRoot, subject) {
6540
- var _a, _b;
6927
+ var _a2, _b;
6541
6928
  const spec = subject == null ? void 0 : subject.trim();
6542
6929
  if (!spec) return svgRoot;
6543
6930
  if (spec === SUBJECT_PARENT) {
@@ -6546,7 +6933,7 @@ function resolveScrollSubject(svgRoot, subject) {
6546
6933
  const position = getComputedStyle(p).position;
6547
6934
  if (position === "sticky" || position === "fixed") outermostPinned = p;
6548
6935
  }
6549
- return (_b = (_a = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a : svgRoot.parentElement) != null ? _b : svgRoot;
6936
+ return (_b = (_a2 = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a2 : svgRoot.parentElement) != null ? _b : svgRoot;
6550
6937
  }
6551
6938
  if (spec === SUBJECT_SCROLLER) {
6552
6939
  return findNearestScroller(svgRoot, "y") || findNearestScroller(svgRoot, "x") || documentScroller();
@@ -6565,10 +6952,10 @@ function resolveScrollSubject(svgRoot, subject) {
6565
6952
  return found;
6566
6953
  }
6567
6954
  function createScrollDriver(subject, config, onProgress) {
6568
- var _a, _b;
6955
+ var _a2, _b;
6569
6956
  if (!config || !isScrollTimeline(config)) return null;
6570
6957
  const scroll = config.scroll || {};
6571
- const kind = (_a = scroll.kind) != null ? _a : "view";
6958
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6572
6959
  const measured = resolveScrollSubject(subject, scroll.subject);
6573
6960
  const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
6574
6961
  const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
@@ -6687,8 +7074,8 @@ function applyScrollPin(svgRoot, scroll) {
6687
7074
  style.position = "sticky";
6688
7075
  const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
6689
7076
  const applyTop = () => {
6690
- var _a;
6691
- const extra = (_a = scroll.pinTop) != null ? _a : 0;
7077
+ var _a2;
7078
+ const extra = (_a2 = scroll.pinTop) != null ? _a2 : 0;
6692
7079
  if (!alignFactor) {
6693
7080
  style.top = extra + "px";
6694
7081
  return;
@@ -6728,23 +7115,23 @@ function applyScrollPin(svgRoot, scroll) {
6728
7115
  };
6729
7116
  }
6730
7117
 
6731
- // src/PxAnimatorBind.ts
7118
+ // src/engines/PxAnimatorBind.ts
6732
7119
  function finaliseAnimator(animatorConfig, callbacks, make) {
6733
7120
  let apiRef;
6734
7121
  let effectiveCallbacks = callbacks;
6735
7122
  if (animatorConfig.resetOnFinish) {
6736
7123
  effectiveCallbacks = __spreadProps(__spreadValues({}, callbacks), {
6737
7124
  onFinish: () => {
6738
- var _a;
6739
- (_a = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a.call(callbacks);
7125
+ var _a2;
7126
+ (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6740
7127
  apiRef == null ? void 0 : apiRef.cancel();
6741
7128
  }
6742
7129
  });
6743
7130
  }
6744
7131
  const res = make(effectiveCallbacks);
6745
7132
  apiRef = res;
6746
- if (animatorConfig.debugInstName) {
6747
- window[animatorConfig.debugInstName] = res;
7133
+ if (animatorConfig.debugGlobalName) {
7134
+ window[animatorConfig.debugGlobalName] = res;
6748
7135
  }
6749
7136
  return res;
6750
7137
  }
@@ -6752,10 +7139,10 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6752
7139
  const animatorConfig = getAnimatorConfig(doc) || {};
6753
7140
  if (isScrollTimeline(animatorConfig)) {
6754
7141
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
6755
- var _a, _b;
7142
+ var _a2;
6756
7143
  let unpin = () => {
6757
7144
  };
6758
- if (animatorConfig.mode !== PxAnimatorMode.frames && ((_a = animatorConfig.scroll) == null ? void 0 : _a.driver) === "native" && rootElement) {
7145
+ if (mayUseNativeScrollTimeline(animatorConfig.engine) && rootElement) {
6759
7146
  unpin = applyScrollPin(rootElement, animatorConfig.scroll);
6760
7147
  const native = createNativeScrollTimeline(rootElement, animatorConfig);
6761
7148
  if (native) {
@@ -6763,7 +7150,7 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6763
7150
  doc,
6764
7151
  cb,
6765
7152
  rootElement,
6766
- animatorConfig.mode === PxAnimatorMode.waapi,
7153
+ isNativeForced(animatorConfig.engine),
6767
7154
  native
6768
7155
  );
6769
7156
  if (api2) {
@@ -6779,8 +7166,8 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6779
7166
  unpin = () => {
6780
7167
  };
6781
7168
  }
6782
- const api = (animatorConfig.mode !== PxAnimatorMode.frames ? createWebApiAnimator(doc, cb, rootElement, animatorConfig.mode === PxAnimatorMode.waapi) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
6783
- const subject = ((_b = api.getRootElement) == null ? void 0 : _b.call(api)) || rootElement;
7169
+ const api = (animatorConfig.engine !== PxTimelineEngineExtra.js ? createWebApiAnimator(doc, cb, rootElement, isNativeForced(animatorConfig.engine)) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7170
+ const subject = ((_a2 = api.getRootElement) == null ? void 0 : _a2.call(api)) || rootElement;
6784
7171
  if (subject) {
6785
7172
  unpin = applyScrollPin(subject, animatorConfig.scroll);
6786
7173
  const totalMs = scrollTotalDurationMs(animatorConfig);
@@ -6804,20 +7191,19 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6804
7191
  });
6805
7192
  }
6806
7193
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
6807
- if (animatorConfig.mode === PxAnimatorMode.frames) {
7194
+ if (animatorConfig.engine === PxTimelineEngineExtra.js) {
6808
7195
  return createFrameLoopAnimator(doc, adapter, cb, rootElement);
6809
7196
  }
6810
7197
  return createWebApiAnimator(
6811
7198
  doc,
6812
7199
  cb,
6813
7200
  rootElement,
6814
- animatorConfig.mode === PxAnimatorMode.waapi
6815
- // forcing waapi
7201
+ isNativeForced(animatorConfig.engine)
6816
7202
  ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
6817
7203
  });
6818
7204
  }
6819
7205
 
6820
- // src/PxAnimatorDOM.ts
7206
+ // src/dom/PxAnimatorDOM.ts
6821
7207
  var SVG_NS = "http://www.w3.org/2000/svg";
6822
7208
  function createElement(tagName, normalisedProps, style, children, textContent) {
6823
7209
  if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
@@ -6849,7 +7235,7 @@ function createElement(tagName, normalisedProps, style, children, textContent) {
6849
7235
  }
6850
7236
  function renderNode(node, defs) {
6851
7237
  if (!node) return null;
6852
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7238
+ const _a2 = node, { type, children, style } = _a2, props = __objRest(_a2, ["type", "children", "style"]);
6853
7239
  const domType = props.domType;
6854
7240
  if (domType !== void 0) delete props.domType;
6855
7241
  const nodeDefs = getDefs(node) || defs;
@@ -6875,18 +7261,24 @@ function renderNode(node, defs) {
6875
7261
  return element;
6876
7262
  }
6877
7263
 
6878
- // src/PxAnimatorKeys.ts
7264
+ // src/shared/PxAnimatorKeys.ts
6879
7265
  var PX_ANIMATOR_DATA_KEY = "data";
6880
7266
 
6881
- // src/PxAnimator.ts
7267
+ // src/animator/PxAnimator.ts
6882
7268
  function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
6883
7269
  return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
6884
7270
  }
6885
- function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7271
+ function createAnimatorImpl(doc, adapter, callbacks, containerElement, config, resetDocDefaults) {
6886
7272
  const effectsWarnings = validateNodeEffects(doc);
6887
7273
  for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
7274
+ reportDocumentDiagnostics(doc, "[PxAnimator] createAnimator");
7275
+ if (config !== void 0 || resetDocDefaults) {
7276
+ const patched = applyAnimatorConfig(doc, config != null ? config : {}, { resetDefaults: !!resetDocDefaults });
7277
+ for (const w of patched.warnings) console.warn("[PxAnimator] config override:", w);
7278
+ doc = patched.doc;
7279
+ }
6888
7280
  const animatorConfig = getAnimatorConfig(doc) || {};
6889
- const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi;
7281
+ const engine = resolveTimelineEngine(animatorConfig.engine);
6890
7282
  doc = materialiseAllInTree(doc, engine);
6891
7283
  let rootElement = null;
6892
7284
  if (containerElement) {
@@ -6899,10 +7291,24 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
6899
7291
  }
6900
7292
  }
6901
7293
  }
6902
- return createAnimatorFromConfig(doc, adapter, callbacks, rootElement);
7294
+ const api = createAnimatorFromConfig(doc, adapter, callbacks, rootElement);
7295
+ if (containerElement && rootElement) {
7296
+ const rendered = rootElement;
7297
+ const destroyNative = api.destroy.bind(api);
7298
+ api.destroy = () => {
7299
+ destroyNative();
7300
+ rendered.remove();
7301
+ };
7302
+ }
7303
+ return api;
7304
+ }
7305
+ function resolveAnimatorConfigOption(options) {
7306
+ const { config, duration, delay, iterations, startOn } = options;
7307
+ return foldAnimatorConfigShortcuts(config, { duration, delay, iterations, startOn });
6903
7308
  }
6904
7309
  function createAnimator(options) {
6905
- const { src, data, adapter, callbacks, container } = options;
7310
+ const { src, data, adapter, callbacks, container, resetDocDefaults } = options;
7311
+ const config = resolveAnimatorConfigOption(options);
6906
7312
  if (data !== void 0 && src !== void 0) {
6907
7313
  throw new Error("createAnimator: provide either `src` or `data`, not both");
6908
7314
  }
@@ -6910,7 +7316,7 @@ function createAnimator(options) {
6910
7316
  throw new Error("createAnimator: either `src` or `data` is required");
6911
7317
  }
6912
7318
  if (data !== void 0) {
6913
- return createAnimatorImpl(data, adapter, callbacks, container);
7319
+ return createAnimatorImpl(data, adapter, callbacks, container, config, resetDocDefaults);
6914
7320
  }
6915
7321
  let animator = null;
6916
7322
  let pending = [];
@@ -6925,7 +7331,7 @@ function createAnimator(options) {
6925
7331
  fetch(src).then((res) => res.json()).then((json) => {
6926
7332
  if (destroyed) return;
6927
7333
  if (isPxElementFileFormat(json)) {
6928
- animator = createAnimatorImpl(json, adapter, callbacks, container);
7334
+ animator = createAnimatorImpl(json, adapter, callbacks, container, config, resetDocDefaults);
6929
7335
  const queued = pending;
6930
7336
  pending = null;
6931
7337
  queued == null ? void 0 : queued.forEach((call) => call(animator));
@@ -6993,12 +7399,11 @@ export {
6993
7399
  PxAnimatedSvgDocumentSchema,
6994
7400
  PxAnimationDefinitionSchema,
6995
7401
  PxAnimatorConfigSchema,
6996
- PxAnimatorEngine,
6997
- PxAnimatorMode,
6998
7402
  PxAttrValueSchema,
6999
7403
  PxBezierPathSchema,
7000
7404
  PxBindingSchema,
7001
7405
  PxCloneEffectSchema,
7406
+ PxCloneWithout,
7002
7407
  PxDefsSchema,
7003
7408
  PxEasingOrRefSchema,
7004
7409
  PxEffectsSchema,
@@ -7010,6 +7415,8 @@ export {
7010
7415
  PxGradientUnits,
7011
7416
  PxKeyframeSchema,
7012
7417
  PxKeyframeValueSchema,
7418
+ PxLoopDirection,
7419
+ PxLoopRepeatAt,
7013
7420
  PxLoopSchema,
7014
7421
  PxMaskedByEffectSchema,
7015
7422
  PxNodeBase,
@@ -7019,15 +7426,19 @@ export {
7019
7426
  PxRetimeEffectSchema,
7020
7427
  PxStrokeGradientEffectSchema,
7021
7428
  PxStrokeTrimEffectSchema,
7429
+ PxStrokeTrimSubPaths,
7022
7430
  PxSvgNodeExtra,
7023
7431
  PxTextEffectSchema,
7024
7432
  PxTextPathEffectSchema,
7433
+ PxTimelineEngine,
7434
+ PxTimelineEngineExtra,
7025
7435
  PxTransformByEffectSchema,
7026
7436
  PxTransformPartsSchema,
7027
7437
  PxTransformValueSchema,
7028
7438
  PxTriggerSchema,
7029
7439
  STYLE_ATTR_NAMES,
7030
7440
  TRANSFORM_FN_NAMES,
7441
+ applyAnimatorConfig,
7031
7442
  applyPlayerEffects,
7032
7443
  calcAnimationValues,
7033
7444
  camelCaseToKebabWordIfNeeded,
@@ -7042,6 +7453,7 @@ export {
7042
7453
  diffInEffect,
7043
7454
  evaluateMotionPathSegment,
7044
7455
  extendedPathForBrowser,
7456
+ foldAnimatorConfigShortcuts,
7045
7457
  generateNewIds,
7046
7458
  getAnimatorConfig,
7047
7459
  getBindings,
@@ -7062,6 +7474,7 @@ export {
7062
7474
  materialiseInternalLoopsInTree,
7063
7475
  materialiseMotionPathInPropAnim,
7064
7476
  materialiseMotionPathsInTree,
7477
+ mergeAnimatorConfig,
7065
7478
  getNormalisedBindings as normalizeDocument,
7066
7479
  propAnimIsMotionPath,
7067
7480
  px,
@@ -7070,6 +7483,7 @@ export {
7070
7483
  setupAnimationTriggers,
7071
7484
  shiftAnimatable,
7072
7485
  toRGBA,
7486
+ validateDocument,
7073
7487
  validateNodeEffects,
7074
7488
  visualModelAt
7075
7489
  };