@pixodesk/svg-animator-web 1.0.34 → 1.0.39

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.cjs CHANGED
@@ -49,64 +49,105 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
49
49
  // src/index.ts
50
50
  var index_exports = {};
51
51
  __export(index_exports, {
52
- COLOUR_ATTR_NAMES: () => COLOUR_ATTR_NAMES,
52
+ BASELINE_PLAYER_VERSION: () => BASELINE_PLAYER_VERSION,
53
+ COLOR_ATTR_NAMES: () => COLOR_ATTR_NAMES,
54
+ DEFAULT_DURATION_MS: () => DEFAULT_DURATION_MS,
53
55
  MISSING_GLYPH_CLASS_NAME: () => MISSING_GLYPH_CLASS_NAME,
54
- PX_ANIMATOR_DATA_KEY: () => PX_ANIMATOR_DATA_KEY,
56
+ PLAYER_WIRE_STEPS: () => PLAYER_WIRE_STEPS,
57
+ PLAYER_WIRE_VERSION: () => PLAYER_WIRE_VERSION,
58
+ PX_ANIMATOR_DOC_KEY: () => PX_ANIMATOR_DOC_KEY,
55
59
  PX_ANIM_ATTR_NAME: () => PX_ANIM_ATTR_NAME,
56
60
  PX_ANIM_SRC_ATTR_NAME: () => PX_ANIM_SRC_ATTR_NAME,
61
+ PX_PLAYER_SCHEMA_VERSION: () => PX_PLAYER_SCHEMA_VERSION,
57
62
  PX_TRANSFORM_PART_KEYS: () => PX_TRANSFORM_PART_KEYS,
63
+ PX_TRIGGER_DEFAULTS: () => PX_TRIGGER_DEFAULTS,
64
+ PxAlongPathMode: () => PxAlongPathMode,
58
65
  PxAnimatedSvgDocumentSchema: () => PxAnimatedSvgDocumentSchema,
59
66
  PxAnimationDefinitionSchema: () => PxAnimationDefinitionSchema,
60
67
  PxAnimatorConfigSchema: () => PxAnimatorConfigSchema,
61
- PxAnimatorEngine: () => PxAnimatorEngine,
62
- PxAnimatorMode: () => PxAnimatorMode,
63
68
  PxAttrValueSchema: () => PxAttrValueSchema,
64
69
  PxBezierPathSchema: () => PxBezierPathSchema,
65
70
  PxBindingSchema: () => PxBindingSchema,
71
+ PxClipPathEffectSchema: () => PxClipPathEffectSchema,
66
72
  PxCloneEffectSchema: () => PxCloneEffectSchema,
73
+ PxCloneWithout: () => PxCloneWithout,
74
+ PxControlMode: () => PxControlMode,
67
75
  PxDefsSchema: () => PxDefsSchema,
76
+ PxDiagnosticKind: () => PxDiagnosticKind,
68
77
  PxEasingOrRefSchema: () => PxEasingOrRefSchema,
69
78
  PxEffectsSchema: () => PxEffectsSchema,
70
79
  PxElementAnimationSchema: () => PxElementAnimationSchema,
71
80
  PxFillGradientEffectSchema: () => PxFillGradientEffectSchema,
81
+ PxFinishAction: () => PxFinishAction,
72
82
  PxGradientSpreadMethod: () => PxGradientSpreadMethod,
73
83
  PxGradientStopSchema: () => PxGradientStopSchema,
74
84
  PxGradientType: () => PxGradientType,
75
- PxGradientUnits: () => PxGradientUnits,
76
85
  PxKeyframeSchema: () => PxKeyframeSchema,
77
86
  PxKeyframeValueSchema: () => PxKeyframeValueSchema,
87
+ PxLengthAdjust: () => PxLengthAdjust,
88
+ PxLoopDirection: () => PxLoopDirection,
89
+ PxLoopRepeatAt: () => PxLoopRepeatAt,
78
90
  PxLoopSchema: () => PxLoopSchema,
91
+ PxMaskType: () => PxMaskType,
79
92
  PxMaskedByEffectSchema: () => PxMaskedByEffectSchema,
80
93
  PxNodeBase: () => PxNodeBase,
81
94
  PxNodeSchema: () => PxNodeSchema,
95
+ PxPathOverflow: () => PxPathOverflow,
96
+ PxPinAlign: () => PxPinAlign,
82
97
  PxPropertyAnimationSchema: () => PxPropertyAnimationSchema,
83
98
  PxRepeaterEffectSchema: () => PxRepeaterEffectSchema,
84
99
  PxRetimeEffectSchema: () => PxRetimeEffectSchema,
100
+ PxScrollAxis: () => PxScrollAxis,
101
+ PxScrollKind: () => PxScrollKind,
102
+ PxScrollPhase: () => PxScrollPhase,
103
+ PxScrollRangePointSchema: () => PxScrollRangePointSchema,
104
+ PxScrollRangeSchema: () => PxScrollRangeSchema,
105
+ PxScrollSchema: () => PxScrollSchema,
106
+ PxScrollSource: () => PxScrollSource,
85
107
  PxStrokeGradientEffectSchema: () => PxStrokeGradientEffectSchema,
86
108
  PxStrokeTrimEffectSchema: () => PxStrokeTrimEffectSchema,
109
+ PxStrokeTrimSubPaths: () => PxStrokeTrimSubPaths,
87
110
  PxSvgNodeExtra: () => PxSvgNodeExtra,
88
111
  PxTextEffectSchema: () => PxTextEffectSchema,
89
112
  PxTextPathEffectSchema: () => PxTextPathEffectSchema,
113
+ PxTextPathMethod: () => PxTextPathMethod,
114
+ PxTextPathSpacing: () => PxTextPathSpacing,
115
+ PxTimelineEngine: () => PxTimelineEngine,
116
+ PxTimelineEngineExtra: () => PxTimelineEngineExtra,
117
+ PxTimelinePinSchema: () => PxTimelinePinSchema,
118
+ PxTimelineSchema: () => PxTimelineSchema,
90
119
  PxTransformByEffectSchema: () => PxTransformByEffectSchema,
91
120
  PxTransformPartsSchema: () => PxTransformPartsSchema,
92
121
  PxTransformValueSchema: () => PxTransformValueSchema,
93
122
  PxTriggerSchema: () => PxTriggerSchema,
123
+ PxUnits: () => PxUnits,
94
124
  STYLE_ATTR_NAMES: () => STYLE_ATTR_NAMES,
95
125
  TRANSFORM_FN_NAMES: () => TRANSFORM_FN_NAMES,
126
+ WIRE_VERSION_KEY: () => WIRE_VERSION_KEY,
127
+ WireStepKind: () => WireStepKind,
128
+ WireVersionRelation: () => WireVersionRelation,
129
+ applyAnimatorConfig: () => applyAnimatorConfig,
96
130
  applyPlayerEffects: () => applyPlayerEffects,
97
131
  calcAnimationValues: () => calcAnimationValues,
98
132
  camelCaseToKebabWordIfNeeded: () => camelCaseToKebabWordIfNeeded,
99
133
  collectSampleTimes: () => collectSampleTimes,
134
+ compareWireVersion: () => compareWireVersion,
135
+ controlModeTakesOverTrigger: () => controlModeTakesOverTrigger,
136
+ convertPlayerDocument: () => convertPlayerDocument,
100
137
  createAnimator: () => createAnimator,
101
- createAnimatorImpl: () => createAnimatorImpl,
102
138
  createBasicFrameLoopAnimator: () => createBasicFrameLoopAnimator,
139
+ createDiagnostics: () => createDiagnostics,
103
140
  createFrameLoopAnimator: () => createFrameLoopAnimator,
104
141
  createPathSampler: () => createPathSampler,
105
142
  createWebApiAnimator: () => createWebApiAnimator,
106
143
  describeSchema: () => describeSchema,
144
+ diagnoseDocument: () => diagnoseDocument,
107
145
  diffInEffect: () => diffInEffect,
146
+ downgradePlayerDocument: () => downgradePlayerDocument,
108
147
  evaluateMotionPathSegment: () => evaluateMotionPathSegment,
109
148
  extendedPathForBrowser: () => extendedPathForBrowser,
149
+ foldTimelineOverride: () => foldTimelineOverride,
150
+ formatWireVersion: () => formatWireVersion,
110
151
  generateNewIds: () => generateNewIds,
111
152
  getAnimatorConfig: () => getAnimatorConfig,
112
153
  getBindings: () => getBindings,
@@ -118,24 +159,33 @@ __export(index_exports, {
118
159
  jsonElementFactory: () => jsonElementFactory,
119
160
  layoutGlyphTextChars: () => layoutGlyphTextChars,
120
161
  loadTagAnimators: () => loadTagAnimators,
121
- materialiseAllInTree: () => materialiseAllInTree,
122
- materialiseAnimatedUseInstances: () => materialiseAnimatedUseInstances,
123
- materialiseGlyphText: () => materialiseGlyphText,
124
- materialiseGlyphTextAlongPath: () => materialiseGlyphTextAlongPath,
125
- materialiseGlyphTextHorizontal: () => materialiseGlyphTextHorizontal,
126
- materialiseInternalLoopsInPropAnim: () => materialiseInternalLoopsInPropAnim,
127
- materialiseInternalLoopsInTree: () => materialiseInternalLoopsInTree,
128
- materialiseMotionPathInPropAnim: () => materialiseMotionPathInPropAnim,
129
- materialiseMotionPathsInTree: () => materialiseMotionPathsInTree,
130
- normalizeDocument: () => getNormalisedBindings,
162
+ materializeAllInTree: () => materializeAllInTree,
163
+ materializeAnimatedUseInstances: () => materializeAnimatedUseInstances,
164
+ materializeGlyphText: () => materializeGlyphText,
165
+ materializeGlyphTextAlongPath: () => materializeGlyphTextAlongPath,
166
+ materializeGlyphTextHorizontal: () => materializeGlyphTextHorizontal,
167
+ materializeInternalLoopsInPropAnim: () => materializeInternalLoopsInPropAnim,
168
+ materializeInternalLoopsInTree: () => materializeInternalLoopsInTree,
169
+ materializeMotionPathInPropAnim: () => materializeMotionPathInPropAnim,
170
+ materializeMotionPathsInTree: () => materializeMotionPathsInTree,
171
+ mergeAnimatorConfig: () => mergeAnimatorConfig,
172
+ normalizeDocument: () => getNormalizedBindings,
173
+ parseWireVersion: () => parseWireVersion,
174
+ progressToTimeMs: () => progressToTimeMs,
131
175
  propAnimIsMotionPath: () => propAnimIsMotionPath,
132
176
  px: () => px,
177
+ readWireVersion: () => readWireVersion,
133
178
  renderNode: () => renderNode,
179
+ resolveControlMode: () => resolveControlMode,
180
+ resolveTrigger: () => resolveTrigger,
134
181
  schemaKeys: () => schemaKeys,
135
182
  setupAnimationTriggers: () => setupAnimationTriggers,
136
183
  shiftAnimatable: () => shiftAnimatable,
184
+ timeToProgress: () => timeToProgress,
137
185
  toRGBA: () => toRGBA,
186
+ validateDocument: () => validateDocument,
138
187
  validateNodeEffects: () => validateNodeEffects,
188
+ versionAdvice: () => versionAdvice,
139
189
  visualModelAt: () => visualModelAt
140
190
  });
141
191
  module.exports = __toCommonJS(index_exports);
@@ -174,7 +224,7 @@ var __objRest2 = (source, exclude) => {
174
224
  return target;
175
225
  };
176
226
  function bezierToSvgPath(path, forceCurves = false) {
177
- var _a, _b, _c, _d;
227
+ var _a2, _b, _c, _d;
178
228
  const v = path.v;
179
229
  const i = path.i;
180
230
  const o = path.o;
@@ -185,7 +235,7 @@ function bezierToSvgPath(path, forceCurves = false) {
185
235
  d.push("M" + v[0][0] + "," + v[0][1]);
186
236
  for (let idx = 1; idx < len; idx++) {
187
237
  const prevV = v[idx - 1];
188
- const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
238
+ const prevO = (_a2 = o == null ? void 0 : o[idx - 1]) != null ? _a2 : prevV;
189
239
  const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
190
240
  const currV = v[idx];
191
241
  const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
@@ -236,7 +286,7 @@ function interpolateBeziers(paths1, paths2, progress) {
236
286
  return res;
237
287
  }
238
288
  function interpolateBezier(path1, path2, progress) {
239
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
289
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
240
290
  if (!path1 || !path2) return path1 || path2 || { v: [] };
241
291
  const t = Math.min(Math.max(progress, 0), 1);
242
292
  const len = Math.min(path1.v.length, path2.v.length);
@@ -247,7 +297,7 @@ function interpolateBezier(path1, path2, progress) {
247
297
  const v1 = path1.v[idx];
248
298
  const v2 = path2.v[idx];
249
299
  v.push(interpolateVec(v1, v2, t));
250
- const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
300
+ const i1 = (_b = (_a2 = path1.i) == null ? void 0 : _a2[idx]) != null ? _b : v1;
251
301
  const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
252
302
  i.push(interpolateVec(i1, i2, t));
253
303
  const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
@@ -366,8 +416,8 @@ function toRGBA(color) {
366
416
  return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
367
417
  }
368
418
  function parseRgba(s) {
369
- var _a;
370
- const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
419
+ var _a2;
420
+ const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
371
421
  if (!inner) throw new Error("Invalid rgb/rgba format");
372
422
  const parts = inner.split(",").map((v) => +v.trim());
373
423
  return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
@@ -402,13 +452,13 @@ function parseColor(s) {
402
452
  }
403
453
  return void 0;
404
454
  }
405
- var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
455
+ var COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
406
456
  var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
407
457
  var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
408
458
  function composeTransformParts(parts, opts) {
409
- var _a;
459
+ var _a2;
410
460
  if (!parts) return "";
411
- const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
461
+ const withUnits = (_a2 = opts == null ? void 0 : opts.withUnits) != null ? _a2 : true;
412
462
  const segs = [];
413
463
  const t = parts.translate;
414
464
  const o = parts.origin;
@@ -426,7 +476,7 @@ function composeTransformParts(parts, opts) {
426
476
  return segs.join("");
427
477
  }
428
478
  function parseTransformParts(str2) {
429
- var _a, _b;
479
+ var _a2, _b;
430
480
  if (!str2 || typeof str2 !== "string") return void 0;
431
481
  const out = {};
432
482
  const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
@@ -442,7 +492,7 @@ function parseTransformParts(str2) {
442
492
  if (nums.some((n) => Number.isNaN(n))) return void 0;
443
493
  if (fn === "translate") {
444
494
  if (nums.length < 1 || nums.length > 2) return void 0;
445
- out.translate = [nums[0], (_a = nums[1]) != null ? _a : 0];
495
+ out.translate = [nums[0], (_a2 = nums[1]) != null ? _a2 : 0];
446
496
  } else if (fn === "rotate") {
447
497
  if (nums.length !== 1) return void 0;
448
498
  out.rotate = nums[0];
@@ -646,8 +696,8 @@ function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
646
696
  }
647
697
  var DEFAULT_PHASE = "cover";
648
698
  function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
649
- var _a;
650
- const [u0, u1] = scrollPhaseInterval((_a = point == null ? void 0 : point.phase) != null ? _a : DEFAULT_PHASE, subjectSize, scrollportSize);
699
+ var _a2;
700
+ const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
651
701
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
652
702
  return u0 + fraction * (u1 - u0);
653
703
  }
@@ -659,9 +709,9 @@ function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
659
709
  return clamp((u - uStart) / (uEnd - uStart), 0, 1);
660
710
  }
661
711
  function scrollOffsetProgress(offset, maxOffset, range) {
662
- var _a, _b;
712
+ var _a2, _b;
663
713
  const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
664
- const start = typeof ((_a = range == null ? void 0 : range.start) == null ? void 0 : _a.fraction) === "number" ? range.start.fraction : 0;
714
+ const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
665
715
  const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
666
716
  if (end <= start) return raw >= end ? 1 : 0;
667
717
  return clamp((raw - start) / (end - start), 0, 1);
@@ -673,6 +723,7 @@ function scrollResolveAxis(axis, writingMode) {
673
723
  if (a === "inline") return vertical ? "y" : "x";
674
724
  return vertical ? "x" : "y";
675
725
  }
726
+ var PX_UNKNOWN_KEY_ERROR = "unexpected extra key";
676
727
  function pathStr(path) {
677
728
  if (!path.length) return ".";
678
729
  let result = "";
@@ -780,6 +831,7 @@ var Enum = class extends Base {
780
831
  return false;
781
832
  }
782
833
  };
834
+ var UNION_MEMBER_ERROR_LIMIT = 4;
783
835
  var Union = class extends Base {
784
836
  constructor(schemas, defaultVal) {
785
837
  super();
@@ -794,10 +846,38 @@ var Union = class extends Base {
794
846
  return this._default;
795
847
  }
796
848
  isValid(raw, ctx, path) {
797
- var _a;
849
+ var _a2;
798
850
  const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
799
851
  if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
800
- 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));
852
+ if (!ctx) return false;
853
+ const base = pathStr(path != null ? path : []);
854
+ ctx.errors.push(base + ": no union member matched for value " + ((_a2 = JSON.stringify(raw)) != null ? _a2 : "").slice(0, 240));
855
+ let best;
856
+ let bestDepth = -1;
857
+ const leafExpectations = [];
858
+ for (const member of this.schemas) {
859
+ const sink = { errors: [], warnings: [], strict: ctx.strict };
860
+ member.isValid(raw, sink, path ? [...path] : void 0);
861
+ if (!sink.errors.length) continue;
862
+ const depth = Math.max(...sink.errors.map((e) => e.slice(0, e.indexOf(":")).length));
863
+ if (depth > bestDepth || depth === bestDepth && best && sink.errors.length < best.length) {
864
+ bestDepth = depth;
865
+ best = sink.errors;
866
+ }
867
+ if (depth <= base.length) {
868
+ for (const e of sink.errors) {
869
+ const m = /: expected (.+?), got /.exec(e);
870
+ if (m && !leafExpectations.includes(m[1])) leafExpectations.push(m[1]);
871
+ }
872
+ }
873
+ }
874
+ if (best && bestDepth > base.length) {
875
+ for (const e of best.slice(0, UNION_MEMBER_ERROR_LIMIT)) {
876
+ if (!ctx.errors.includes(e)) ctx.errors.push(e);
877
+ }
878
+ } else if (leafExpectations.length) {
879
+ ctx.errors.push(base + ": expected " + leafExpectations.join(" | "));
880
+ }
801
881
  return false;
802
882
  }
803
883
  _canSanitize(raw) {
@@ -806,6 +886,7 @@ var Union = class extends Base {
806
886
  };
807
887
  var DiscriminatedUnion = class extends Base {
808
888
  constructor(_key, _schemas, defaultVal) {
889
+ var _a2;
809
890
  super();
810
891
  this._key = _key;
811
892
  this._schemas = _schemas;
@@ -814,18 +895,21 @@ var DiscriminatedUnion = class extends Base {
814
895
  this._map = /* @__PURE__ */ new Map();
815
896
  for (const s of _schemas) {
816
897
  const keySchema = s._shape[_key];
817
- if (keySchema) this._map.set(keySchema._default, s);
898
+ if (!keySchema) continue;
899
+ const literal = (_a2 = keySchema.inner) != null ? _a2 : keySchema;
900
+ this._map.set(literal._default, s);
901
+ if (keySchema.inner) this._absentMember = s;
818
902
  }
819
903
  }
820
904
  _findSchema(raw) {
821
905
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
822
906
  const val = raw[this._key];
823
- if (val === void 0 || val === null) return void 0;
907
+ if (val === void 0 || val === null) return this._absentMember;
824
908
  return this._map.get(val);
825
909
  }
826
910
  sanitize(raw) {
827
- var _a;
828
- return ((_a = this._findSchema(raw)) != null ? _a : this._schemas[0]).sanitize(raw);
911
+ var _a2;
912
+ return ((_a2 = this._findSchema(raw)) != null ? _a2 : this._schemas[0]).sanitize(raw);
829
913
  }
830
914
  isValid(raw, ctx, path) {
831
915
  const schema = this._findSchema(raw);
@@ -854,7 +938,8 @@ var Obj = class extends Base {
854
938
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
855
939
  const out = {};
856
940
  for (const key of Object.keys(this._shape)) {
857
- out[key] = this._shape[key].sanitize(src[key]);
941
+ const v = this._shape[key].sanitize(src[key]);
942
+ if (v !== void 0) out[key] = v;
858
943
  }
859
944
  return out;
860
945
  }
@@ -876,7 +961,7 @@ var Obj = class extends Base {
876
961
  if (key in this._shape) continue;
877
962
  if (obj[key] === void 0) continue;
878
963
  p.push(key);
879
- ctx.errors.push(pathStr(p) + ": unexpected extra key");
964
+ ctx.errors.push(pathStr(p) + ": " + PX_UNKNOWN_KEY_ERROR);
880
965
  p.pop();
881
966
  ok = false;
882
967
  }
@@ -900,7 +985,8 @@ var OpenObj = class extends Base {
900
985
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
901
986
  const out = __spreadValues2({}, src);
902
987
  for (const key of Object.keys(this._shape)) {
903
- out[key] = this._shape[key].sanitize(src[key]);
988
+ const v = this._shape[key].sanitize(src[key]);
989
+ if (v !== void 0) out[key] = v;
904
990
  }
905
991
  if (this._openSchema) {
906
992
  for (const key of Object.keys(src)) {
@@ -1041,8 +1127,8 @@ var Lazy = class extends Base {
1041
1127
  this.resolved = null;
1042
1128
  }
1043
1129
  get schema() {
1044
- var _a;
1045
- return (_a = this.resolved) != null ? _a : this.resolved = this.fn();
1130
+ var _a2;
1131
+ return (_a2 = this.resolved) != null ? _a2 : this.resolved = this.fn();
1046
1132
  }
1047
1133
  sanitize(raw) {
1048
1134
  return this.schema.sanitize(raw);
@@ -1093,7 +1179,7 @@ function schemaKeys(schema) {
1093
1179
  );
1094
1180
  }
1095
1181
  function describeSchema(schema) {
1096
- var _a;
1182
+ var _a2;
1097
1183
  const s = schema;
1098
1184
  switch (s._kind) {
1099
1185
  case "union":
@@ -1108,7 +1194,7 @@ function describeSchema(schema) {
1108
1194
  if ("_shape" in s) return { kind: "shape", shape: s._shape, openValue: s._openSchema };
1109
1195
  if ("item" in s) return { kind: "array", item: s.item };
1110
1196
  if ("inner" in s) return { kind: "optional", inner: s.inner };
1111
- if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.resolved = s.fn() };
1197
+ if ("fn" in s) return { kind: "lazy", resolved: (_a2 = s.resolved) != null ? _a2 : s.resolved = s.fn() };
1112
1198
  return { kind: "leaf" };
1113
1199
  }
1114
1200
  var px = {
@@ -1162,24 +1248,327 @@ var px = {
1162
1248
  /** Defers schema creation — required for recursive types. Must supply a default value. */
1163
1249
  lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
1164
1250
  };
1251
+ var PX_PLAYER_SCHEMA_VERSION = "1.1";
1252
+ var WIRE_VERSION_KEY = "version";
1253
+ var ANIMATOR_KEY = "animator";
1254
+ var META_KEY = "meta";
1255
+ var WireVersionRelation = /* @__PURE__ */ ((WireVersionRelation2) => {
1256
+ WireVersionRelation2["unstamped"] = "unstamped";
1257
+ WireVersionRelation2["same"] = "same";
1258
+ WireVersionRelation2["older"] = "older";
1259
+ WireVersionRelation2["newer"] = "newer";
1260
+ WireVersionRelation2["otherGeneration"] = "otherGeneration";
1261
+ return WireVersionRelation2;
1262
+ })(WireVersionRelation || {});
1263
+ var VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?$/;
1264
+ function parseWireVersion(raw) {
1265
+ if (typeof raw !== "string") return void 0;
1266
+ const m = VERSION_RE.exec(raw.trim());
1267
+ if (!m) return void 0;
1268
+ return { a: Number(m[1]), b: Number(m[2]), c: m[3] === void 0 ? 0 : Number(m[3]) };
1269
+ }
1270
+ function formatWireVersion(v) {
1271
+ return v.a + "." + v.b + "." + v.c;
1272
+ }
1273
+ var _a;
1274
+ var PLAYER_WIRE_VERSION = (_a = parseWireVersion(PX_PLAYER_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
1275
+ function getAnimatorBlock(doc) {
1276
+ if (!doc || typeof doc !== "object") return void 0;
1277
+ const atRoot = readObjectProp(doc, ANIMATOR_KEY);
1278
+ if (atRoot) return atRoot;
1279
+ const meta = readObjectProp(doc, META_KEY);
1280
+ return meta ? readObjectProp(meta, ANIMATOR_KEY) : void 0;
1281
+ }
1282
+ function readObjectProp(obj, key) {
1283
+ const value = obj[key];
1284
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1285
+ }
1286
+ function readWireVersion(doc) {
1287
+ const animator = getAnimatorBlock(doc);
1288
+ return animator ? parseWireVersion(animator[WIRE_VERSION_KEY]) : void 0;
1289
+ }
1290
+ function compareWireVersion(file, mine, readerReadsEditorPart) {
1291
+ if (!file) return "unstamped";
1292
+ if (file.a !== mine.a) return "otherGeneration";
1293
+ if (file.b !== mine.b) return file.b > mine.b ? "newer" : "older";
1294
+ if (!readerReadsEditorPart || file.c === mine.c) return "same";
1295
+ return file.c > mine.c ? "newer" : "older";
1296
+ }
1297
+ function versionAdvice(relation, file, mine, isPlayer) {
1298
+ if (!file) return void 0;
1299
+ const target = isPlayer ? "player" : "editor";
1300
+ const gap = "written for schema " + formatWireVersion(file) + ", this " + target + " reads " + formatWireVersion(mine);
1301
+ switch (relation) {
1302
+ case "newer":
1303
+ return "This file is " + gap + ". Update the " + target + " to open it fully.";
1304
+ case "older":
1305
+ return "This file is " + gap + ". Saving it from this " + target + " rewrites it in the current format.";
1306
+ case "otherGeneration":
1307
+ return "This file is " + gap + " \u2014 a different format generation, which no conversion bridges. Open it in a " + target + " of that generation, or accept this document without the parts named above.";
1308
+ default:
1309
+ return void 0;
1310
+ }
1311
+ }
1312
+ var WireStepKind = /* @__PURE__ */ ((WireStepKind2) => {
1313
+ WireStepKind2["additive"] = "additive";
1314
+ WireStepKind2["converted"] = "converted";
1315
+ return WireStepKind2;
1316
+ })(WireStepKind || {});
1317
+ var BASELINE_PLAYER_VERSION = "1.1";
1318
+ var PLAYER_WIRE_STEPS = [];
1319
+ function applyWireSteps(doc, cfg) {
1320
+ const from = readWireVersion(doc);
1321
+ const relation = compareWireVersion(from, cfg.target, cfg.readerReadsEditorPart);
1322
+ if (!from || relation !== "older") {
1323
+ return {
1324
+ doc,
1325
+ from,
1326
+ relation,
1327
+ applied: [],
1328
+ advice: versionAdvice(relation, from, cfg.target, !cfg.readerReadsEditorPart)
1329
+ };
1330
+ }
1331
+ const due = [];
1332
+ for (const step of cfg.steps) {
1333
+ const stepTo = parseWireVersion(step.to);
1334
+ if (!stepTo) continue;
1335
+ if (compareWireVersion(from, stepTo, cfg.readerReadsEditorPart) !== "older") continue;
1336
+ if (!step.up) continue;
1337
+ due.push(step);
1338
+ }
1339
+ if (!due.length || !doc || typeof doc !== "object") return { doc, from, relation, applied: [] };
1340
+ const target = clonePlain(doc);
1341
+ const applied = [];
1342
+ for (const step of due) {
1343
+ try {
1344
+ step.up(target);
1345
+ applied.push(step);
1346
+ } catch (e) {
1347
+ break;
1348
+ }
1349
+ }
1350
+ if (!applied.length) return { doc, from, relation, applied: [] };
1351
+ stampVersion(target, cfg.target, cfg.readerReadsEditorPart);
1352
+ return { doc: target, from, relation, applied };
1353
+ }
1354
+ function convertPlayerDocument(doc) {
1355
+ return applyWireSteps(doc, {
1356
+ steps: PLAYER_WIRE_STEPS,
1357
+ target: PLAYER_WIRE_VERSION,
1358
+ readerReadsEditorPart: false
1359
+ });
1360
+ }
1361
+ function clonePlain(value) {
1362
+ const structured = globalThis.structuredClone;
1363
+ return structured ? structured(value) : JSON.parse(JSON.stringify(value));
1364
+ }
1365
+ function stampVersion(doc, target, readerReadsEditorPart) {
1366
+ const animator = getAnimatorBlock(doc);
1367
+ if (!animator) return;
1368
+ const previous = parseWireVersion(animator[WIRE_VERSION_KEY]);
1369
+ animator[WIRE_VERSION_KEY] = formatWireVersion({
1370
+ a: target.a,
1371
+ b: target.b,
1372
+ c: readerReadsEditorPart ? target.c : previous ? previous.c : 0
1373
+ });
1374
+ }
1375
+ function applyWireStepsDown(doc, cfg) {
1376
+ const from = readWireVersion(doc);
1377
+ if (!from) {
1378
+ return { ok: false, blocking: [], reason: "The document carries no version, so there is nothing to convert down from." };
1379
+ }
1380
+ const relation = compareWireVersion(from, cfg.target, cfg.readerReadsEditorPart);
1381
+ if (relation === "otherGeneration") {
1382
+ return {
1383
+ ok: false,
1384
+ blocking: [],
1385
+ reason: "Schema " + formatWireVersion(from) + " and " + formatWireVersion(cfg.target) + " are different generations; no conversion bridges them."
1386
+ };
1387
+ }
1388
+ if (relation !== "newer") return { ok: true, doc, applied: [] };
1389
+ const toUndo = [];
1390
+ for (const step of cfg.steps) {
1391
+ const stepTo = parseWireVersion(step.to);
1392
+ if (!stepTo) continue;
1393
+ if (compareWireVersion(stepTo, cfg.target, cfg.readerReadsEditorPart) !== "newer") continue;
1394
+ if (compareWireVersion(stepTo, from, cfg.readerReadsEditorPart) === "newer") continue;
1395
+ toUndo.push(step);
1396
+ }
1397
+ toUndo.reverse();
1398
+ const blocking = toUndo.filter((s) => s.kind === "converted" && !s.down);
1399
+ if (blocking.length) {
1400
+ return {
1401
+ ok: false,
1402
+ blocking,
1403
+ reason: "Cannot convert down to " + formatWireVersion(cfg.target) + ": " + blocking.map((s) => s.from + " \u2192 " + s.to + " (" + s.reason + ")").join("; ") + " cannot be undone."
1404
+ };
1405
+ }
1406
+ const target = clonePlain(doc);
1407
+ const applied = [];
1408
+ for (const step of toUndo) {
1409
+ if (!step.down) continue;
1410
+ try {
1411
+ step.down(target);
1412
+ applied.push(step);
1413
+ } catch (e) {
1414
+ return {
1415
+ ok: false,
1416
+ blocking: [step],
1417
+ reason: "Undoing " + step.from + " \u2192 " + step.to + " failed: " + String(e)
1418
+ };
1419
+ }
1420
+ }
1421
+ stampVersion(target, cfg.target, cfg.readerReadsEditorPart);
1422
+ return { ok: true, doc: target, applied };
1423
+ }
1424
+ function downgradePlayerDocument(doc, target) {
1425
+ return applyWireStepsDown(doc, { steps: PLAYER_WIRE_STEPS, target, readerReadsEditorPart: false });
1426
+ }
1427
+ var PxFillMode = {
1428
+ forwards: "forwards",
1429
+ backwards: "backwards",
1430
+ both: "both",
1431
+ none: "none"
1432
+ };
1433
+ var PxPlaybackDirection = {
1434
+ normal: "normal",
1435
+ reverse: "reverse",
1436
+ alternate: "alternate",
1437
+ alternateReverse: "alternate-reverse"
1438
+ };
1165
1439
  var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
1166
1440
  var PX_ANIM_ATTR_NAME = "_px_animator";
1167
- var PxAnimatorMode = {
1168
- auto: "auto",
1169
- waapi: "waapi",
1170
- frames: "frames"
1441
+ var PxStartOn = {
1442
+ load: "load",
1443
+ mouseOver: "mouseOver",
1444
+ click: "click",
1445
+ scrollIntoView: "scrollIntoView",
1446
+ programmatic: "programmatic"
1447
+ };
1448
+ var PxOutAction = {
1449
+ continue: "continue",
1450
+ pause: "pause",
1451
+ reset: "reset",
1452
+ reverse: "reverse"
1453
+ };
1454
+ var PxFinishAction = {
1455
+ hold: "hold",
1456
+ reset: "reset"
1457
+ };
1458
+ var PxScrollKind = {
1459
+ view: "view",
1460
+ scroll: "scroll"
1461
+ };
1462
+ var PxScrollAxis = {
1463
+ block: "block",
1464
+ inline: "inline",
1465
+ x: "x",
1466
+ y: "y"
1171
1467
  };
1172
- var PxAnimatorEngine = {
1173
- waapi: PxAnimatorMode.waapi,
1174
- frames: PxAnimatorMode.frames
1468
+ var PxScrollSource = {
1469
+ nearest: "nearest",
1470
+ root: "root"
1471
+ };
1472
+ var PxPinAlign = {
1473
+ top: "top",
1474
+ center: "center",
1475
+ bottom: "bottom"
1476
+ };
1477
+ var PxScrollPhase = {
1478
+ cover: "cover",
1479
+ contain: "contain",
1480
+ entry: "entry",
1481
+ exit: "exit",
1482
+ entryCrossing: "entry-crossing",
1483
+ exitCrossing: "exit-crossing"
1484
+ };
1485
+ var PxAlongPathMode = {
1486
+ sampled: "sampled",
1487
+ offsetPath: "offsetPath"
1488
+ };
1489
+ var PX_TIMELINE_SHARED_KEYS = ["duration", "iterations", "engine", "frameRate"];
1490
+ var PX_TIME_ONLY_TIMELINE_KEYS = ["trigger", "delay", "fillMode", "direction"];
1491
+ var PX_FLAT_RUNTIME_VIEW_KEYS = [
1492
+ ...PX_TIMELINE_SHARED_KEYS,
1493
+ ...PX_TIME_ONLY_TIMELINE_KEYS,
1494
+ "fill",
1495
+ "resetOnFinish",
1496
+ "timelineSource",
1497
+ "scroll"
1498
+ ];
1499
+ var PxTimelineEngine = {
1500
+ native: "native",
1501
+ js: "js"
1502
+ };
1503
+ var PxTimelineEngineExtra = __spreadProps2(__spreadValues2({}, PxTimelineEngine), {
1504
+ auto: "auto"
1505
+ });
1506
+ function resolveTimelineEngine(engine) {
1507
+ return engine === PxTimelineEngineExtra.js ? PxTimelineEngine.js : PxTimelineEngine.native;
1508
+ }
1509
+ function isNativeForced(engine) {
1510
+ return engine === PxTimelineEngineExtra.native;
1511
+ }
1512
+ function mayUseNativeScrollTimeline(engine) {
1513
+ return engine !== PxTimelineEngineExtra.js;
1514
+ }
1515
+ var PX_TRIGGER_DEFAULTS = {
1516
+ startOn: "load",
1517
+ outAction: "continue",
1518
+ scrollIntoViewThreshold: 0
1519
+ };
1520
+ var PxControlMode = {
1521
+ /** No control props — the document's trigger decides, and nothing is taken over. */
1522
+ static: "static",
1523
+ /** `progress` / `time` — the host scrubs; the component seeks and stays paused. */
1524
+ fixedTime: "fixedTime",
1525
+ /** `play` / `pause` — the host drives playback with booleans. */
1526
+ play: "play",
1527
+ /** `autoplay` — the document's own trigger starts it. */
1528
+ autoplay: "autoplay"
1529
+ };
1530
+ function resolveControlMode(props) {
1531
+ const hasFixedTime = props.progress !== void 0 || props.time !== void 0;
1532
+ const hasPlayPause = props.play !== void 0 || props.pause !== void 0;
1533
+ const hasAutoplay = !!props.autoplay;
1534
+ const warnings = [];
1535
+ const named = (a, b, winner) => a + " and " + b + " were both set \u2014 " + winner + " wins, " + (winner === a ? b : a) + " is ignored.";
1536
+ if (hasFixedTime) {
1537
+ if (hasPlayPause) warnings.push(named("progress/time", "play/pause", "progress/time"));
1538
+ if (hasAutoplay) warnings.push(named("progress/time", "autoplay", "progress/time"));
1539
+ return { mode: PxControlMode.fixedTime, warnings };
1540
+ }
1541
+ if (hasPlayPause) {
1542
+ if (hasAutoplay) warnings.push(named("play/pause", "autoplay", "play/pause"));
1543
+ return { mode: PxControlMode.play, warnings };
1544
+ }
1545
+ if (hasAutoplay) return { mode: PxControlMode.autoplay, warnings };
1546
+ return { mode: PxControlMode.static, warnings };
1547
+ }
1548
+ function controlModeTakesOverTrigger(mode) {
1549
+ return mode !== PxControlMode.autoplay;
1550
+ }
1551
+ function resolveTrigger(trigger) {
1552
+ var _a2, _b, _c;
1553
+ return {
1554
+ startOn: (_a2 = trigger == null ? void 0 : trigger.startOn) != null ? _a2 : PX_TRIGGER_DEFAULTS.startOn,
1555
+ outAction: (_b = trigger == null ? void 0 : trigger.outAction) != null ? _b : PX_TRIGGER_DEFAULTS.outAction,
1556
+ scrollIntoViewThreshold: (_c = trigger == null ? void 0 : trigger.scrollIntoViewThreshold) != null ? _c : PX_TRIGGER_DEFAULTS.scrollIntoViewThreshold
1557
+ };
1558
+ }
1559
+ var PxLoopRepeatAt = {
1560
+ /** Segment from the START; the repetition runs BEFORE the first keyframe
1561
+ * (intro loops that play until the main timeline begins). */
1562
+ start: "start",
1563
+ /** DEFAULT — segment from the END; the repetition runs AFTER the last keyframe
1564
+ * (idle/outro loops that continue once the main timeline has finished). */
1565
+ end: "end"
1175
1566
  };
1176
- var PxLoopExtend = {
1177
- /** Segment from the START; the animation is extended BEFORE the first keyframe
1178
- * (intro loops that run before the main timeline begins). */
1179
- before: "before",
1180
- /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
1181
- * loops that continue once the main timeline has finished). */
1182
- after: "after"
1567
+ var PxLoopDirection = {
1568
+ /** DEFAULT — cycle: every repetition replays the segment the same way round. */
1569
+ normal: "normal",
1570
+ /** Ping-pong: repetitions alternate forward / backward. */
1571
+ alternate: "alternate"
1183
1572
  };
1184
1573
  var PxMaskType = {
1185
1574
  luminance: "luminance",
@@ -1189,8 +1578,9 @@ var PxUnits = {
1189
1578
  userSpaceOnUse: "userSpaceOnUse",
1190
1579
  objectBoundingBox: "objectBoundingBox"
1191
1580
  };
1192
- var PxCloneType = {
1193
- content: "content"
1581
+ var PxCloneWithout = {
1582
+ translate: "translate"
1583
+ // transform: 'transform', // future: drop rotate/scale too (content only)
1194
1584
  };
1195
1585
  var PxPathOverflow = {
1196
1586
  clip: "clip",
@@ -1212,8 +1602,10 @@ var PxStrokeTrimSubPaths = {
1212
1602
  separate: "separate",
1213
1603
  combined: "combined"
1214
1604
  };
1215
- var TEXT_ATTR = "text";
1216
1605
  var TEXT_CONTENT_ATTR = "textContent";
1606
+ var CLASS_ATTR = "class";
1607
+ var TRANSFORM_ATTR = "transform";
1608
+ var OFFSET_DISTANCE_ATTR = "offsetDistance";
1217
1609
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1218
1610
  "type",
1219
1611
  "children",
@@ -1221,14 +1613,20 @@ var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1221
1613
  "meta",
1222
1614
  "animate",
1223
1615
  "effects",
1224
- TEXT_ATTR,
1225
1616
  TEXT_CONTENT_ATTR
1226
1617
  ]);
1227
- var PX_TRANSFORM_PART_KEYS = ["translate", "rotate", "scale", "origin"];
1228
- var PxGradientUnits = {
1229
- userSpaceOnUse: "userSpaceOnUse",
1230
- objectBoundingBox: "objectBoundingBox"
1618
+ var TRANSFORM_PART = {
1619
+ translate: "translate",
1620
+ rotate: "rotate",
1621
+ scale: "scale",
1622
+ origin: "origin"
1231
1623
  };
1624
+ var PX_TRANSFORM_PART_KEYS = [
1625
+ TRANSFORM_PART.translate,
1626
+ TRANSFORM_PART.rotate,
1627
+ TRANSFORM_PART.scale,
1628
+ TRANSFORM_PART.origin
1629
+ ];
1232
1630
  var PxGradientSpreadMethod = {
1233
1631
  pad: "pad",
1234
1632
  reflect: "reflect",
@@ -1242,27 +1640,38 @@ function isPxElementFileFormat(fileJson) {
1242
1640
  if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
1243
1641
  return false;
1244
1642
  }
1245
- return fileJson["type"] === "svg";
1643
+ return fileJson.type === "svg";
1246
1644
  }
1247
1645
  function getAnimatorConfig(doc) {
1248
- var _a;
1249
- const cfg = (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
1250
- return cfg ? flattenAnimatorTimeline(cfg) : void 0;
1251
- }
1646
+ var _a2;
1647
+ const cfg = (doc == null ? void 0 : doc.animator) || ((_a2 = doc == null ? void 0 : doc.meta) == null ? void 0 : _a2.animator);
1648
+ if (!cfg) return void 0;
1649
+ const memoised = wireViewMemo.get(cfg);
1650
+ if (memoised) return memoised;
1651
+ const wire = cfg;
1652
+ const stray = PX_FLAT_RUNTIME_VIEW_KEYS.filter((k) => wire[k] !== void 0);
1653
+ const source = stray.length ? __spreadValues2({}, wire) : cfg;
1654
+ for (const k of stray) delete source[k];
1655
+ const view = flattenAnimatorTimeline(source);
1656
+ wireViewMemo.set(cfg, view);
1657
+ return view;
1658
+ }
1659
+ var wireViewMemo = /* @__PURE__ */ new WeakMap();
1252
1660
  var flattenMemo = /* @__PURE__ */ new WeakMap();
1253
1661
  function flattenAnimatorTimeline(cfg) {
1254
1662
  const timeline = cfg.timeline;
1255
1663
  if (timeline === void 0 || timeline === null || typeof timeline !== "object") return cfg;
1256
1664
  const memoised = flattenMemo.get(cfg);
1257
1665
  if (memoised) return memoised;
1258
- const _a = cfg, { timeline: _dropped } = _a, flat = __objRest2(_a, ["timeline"]);
1666
+ const _a2 = cfg, { timeline: _dropped } = _a2, flat = __objRest2(_a2, ["timeline"]);
1667
+ if (timeline.engine !== void 0) flat.engine = timeline.engine;
1668
+ if (timeline.frameRate !== void 0) flat.frameRate = timeline.frameRate;
1259
1669
  if (timeline.type === "scroll" || timeline.type === "view") {
1260
1670
  flat.timelineSource = "scroll";
1261
1671
  if (timeline.duration !== void 0) flat.duration = timeline.duration;
1262
1672
  if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1263
1673
  const scroll = __spreadValues2({}, flat.scroll || {});
1264
1674
  scroll.kind = timeline.type;
1265
- if (timeline.engine !== void 0) scroll.driver = timeline.engine;
1266
1675
  if (timeline.axis !== void 0) scroll.axis = timeline.axis;
1267
1676
  if (timeline.source !== void 0) scroll.source = timeline.source;
1268
1677
  if (timeline.subject !== void 0) scroll.subject = timeline.subject;
@@ -1273,34 +1682,34 @@ function flattenAnimatorTimeline(cfg) {
1273
1682
  else if (pin && typeof pin === "object") {
1274
1683
  scroll.pin = true;
1275
1684
  if (pin.align !== void 0) scroll.pinAlign = pin.align;
1276
- if (pin.top !== void 0) scroll.pinTop = pin.top;
1685
+ if (pin.offset !== void 0) scroll.pinOffset = pin.offset;
1277
1686
  if (pin.distance !== void 0) scroll.pinDistance = pin.distance;
1278
1687
  }
1279
1688
  flat.scroll = scroll;
1280
1689
  } else {
1281
1690
  if (timeline.duration !== void 0) flat.duration = timeline.duration;
1282
1691
  if (timeline.trigger !== void 0) {
1283
- const _b = timeline.trigger, { onFinish } = _b, restTrigger = __objRest2(_b, ["onFinish"]);
1692
+ const _b = timeline.trigger, { finishAction } = _b, restTrigger = __objRest2(_b, ["finishAction"]);
1284
1693
  if (Object.keys(restTrigger).length) flat.trigger = restTrigger;
1285
- if (onFinish !== void 0) flat.resetOnFinish = onFinish === "reset";
1694
+ if (finishAction !== void 0) flat.resetOnFinish = finishAction === "reset";
1286
1695
  }
1287
1696
  if (timeline.delay !== void 0) flat.delay = timeline.delay;
1288
1697
  if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1289
1698
  if (timeline.direction !== void 0) flat.direction = timeline.direction;
1290
- if (timeline.fill !== void 0) flat.fill = timeline.fill;
1699
+ if (timeline.fillMode !== void 0) flat.fill = timeline.fillMode;
1291
1700
  }
1292
1701
  flattenMemo.set(cfg, flat);
1293
1702
  return flat;
1294
1703
  }
1295
1704
  function getDefs(doc) {
1296
- var _a;
1705
+ var _a2;
1297
1706
  if (!doc) return void 0;
1298
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
1707
+ return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
1299
1708
  }
1300
1709
  function getBindings(doc) {
1301
- var _a;
1710
+ var _a2;
1302
1711
  if (!doc) return void 0;
1303
- const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
1712
+ const animateById = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.animateById;
1304
1713
  if (!animateById) return void 0;
1305
1714
  return Object.entries(animateById).map(([id, anim]) => ({ id: id.startsWith("#") ? id.slice(1) : id, animate: anim }));
1306
1715
  }
@@ -1316,14 +1725,13 @@ var PxKeyframeValueSchema = implementsInterface()(px.union([
1316
1725
  // e.g. for colors
1317
1726
  px.number(),
1318
1727
  px.array(px.number()),
1319
- // ORDER LAW: the key-discriminated object shapes (`{path}`, `{paths}`) come BEFORE the
1728
+ // ORDER LAW: the key-discriminated object shape (`{pathData}`) comes BEFORE the
1320
1729
  // all-optional transform-parts record. In default (non-strict) mode that record accepts
1321
1730
  // ANY object (every key optional, unknown keys ignored), so listing it earlier made
1322
- // Union.sanitize route `{path}`/`{paths}` values into it and strip them to `{}` —
1731
+ // Union.sanitize route `{pathData}` values into it and strip them to `{}` —
1323
1732
  // silent morph-data loss (repro: the editor's keyframeValueSanitize spec). Validity is
1324
1733
  // order-independent (`some()`); only sanitize routing depends on this order.
1325
- px.object({ path: px.string() }),
1326
- px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
1734
+ px.object({ pathData: px.string() }),
1327
1735
  // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
1328
1736
  px.lazy(() => px.array(PxGradientStopSchema), []),
1329
1737
  px.lazy(() => PxTransformPartsSchema, {})
@@ -1338,16 +1746,32 @@ var PxKeyframeSchema = implementsInterface()(px.object({
1338
1746
  // (review §1.3): editor data lives under `meta`. The editor still carries it on
1339
1747
  // its internal COPY-PASTE payload, which never validates against this schema.)
1340
1748
  }));
1749
+ var anyKf = (kf) => kf;
1750
+ var kfTime = (kf) => {
1751
+ var _a2, _b;
1752
+ return (_b = (_a2 = anyKf(kf).time) != null ? _a2 : anyKf(kf).t) != null ? _b : 0;
1753
+ };
1754
+ var kfValue = (kf) => {
1755
+ var _a2;
1756
+ return (_a2 = anyKf(kf).value) != null ? _a2 : anyKf(kf).v;
1757
+ };
1758
+ var kfEasing = (kf) => {
1759
+ var _a2;
1760
+ return (_a2 = anyKf(kf).easing) != null ? _a2 : anyKf(kf).e;
1761
+ };
1762
+ var kfTangentIn = (kf) => anyKf(kf).tangentIn;
1763
+ var kfTangentOut = (kf) => anyKf(kf).tangentOut;
1341
1764
  var PxLoopSchema = implementsInterface()(px.object({
1342
1765
  segmentCount: px.number().optional(),
1343
- extend: px.enum([PxLoopExtend.before, PxLoopExtend.after]).optional(),
1344
- alternate: px.boolean().optional()
1766
+ repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
1767
+ direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
1345
1768
  }));
1346
1769
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
1347
1770
  value: PxKeyframeValueSchema.optional(),
1348
1771
  keyframes: px.array(PxKeyframeSchema).optional(),
1349
1772
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1350
- autoOrient: px.boolean().optional()
1773
+ autoOrient: px.boolean().optional(),
1774
+ alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath]).optional()
1351
1775
  }));
1352
1776
  var PxTransformPartsSchema = implementsInterface()(px.object({
1353
1777
  translate: px.tuple([px.number(), px.number()]).optional(),
@@ -1371,18 +1795,17 @@ var PxElementAnimationSchema = implementsInterface()(px.union([
1371
1795
  PxAnimationDefinitionSchema
1372
1796
  ]));
1373
1797
  var PxTriggerSchema = implementsInterface()(px.object({
1374
- startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
1375
- outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
1798
+ startOn: px.enum([PxStartOn.load, PxStartOn.mouseOver, PxStartOn.click, PxStartOn.scrollIntoView, PxStartOn.programmatic], PX_TRIGGER_DEFAULTS.startOn).optional(),
1799
+ outAction: px.enum([PxOutAction.continue, PxOutAction.pause, PxOutAction.reset, PxOutAction.reverse], PX_TRIGGER_DEFAULTS.outAction).optional(),
1376
1800
  // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
1377
- // `fill`) or `'reset'` (snap back to the start state). The trigger-vocabulary home of
1378
- // the old top-level `resetOnFinish: boolean` (read-legacy) — review §2.3: both
1379
- // "what happens at the end" knobs now sit side by side and share one style of value.
1380
- onFinish: px.enum(["hold", "reset"]).optional(),
1801
+ // `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
1802
+ // happens when the trigger condition ends"); both end-of-life knobs now read alike.
1803
+ finishAction: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
1381
1804
  scrollIntoViewThreshold: px.number().optional()
1382
1805
  }));
1383
1806
  var PxGlyphSchema = implementsInterface()(px.object({
1384
1807
  width: px.number(),
1385
- d: px.string()
1808
+ pathData: px.string()
1386
1809
  }));
1387
1810
  var PxGlyphFontSchema = implementsInterface()(px.object({
1388
1811
  fontFamily: px.string(),
@@ -1397,11 +1820,17 @@ var PxDefsSchema = implementsInterface()(px.object({
1397
1820
  // Review §2.6: the schema now matches the declared type — a style preset is a flat
1398
1821
  // record of string|number attribute values, nothing nested.
1399
1822
  styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
1400
- glyphs: px.record(PxGlyphFontSchema).optional()
1823
+ fonts: px.record(PxGlyphFontSchema).optional()
1401
1824
  }));
1402
- var PX_SCROLL_PHASES = ["cover", "contain", "entry", "exit", "entry-crossing", "exit-crossing"];
1403
1825
  var PxScrollRangePointSchema = implementsInterface()(px.object({
1404
- phase: px.enum(PX_SCROLL_PHASES).optional(),
1826
+ phase: px.enum([
1827
+ PxScrollPhase.cover,
1828
+ PxScrollPhase.contain,
1829
+ PxScrollPhase.entry,
1830
+ PxScrollPhase.exit,
1831
+ PxScrollPhase.entryCrossing,
1832
+ PxScrollPhase.exitCrossing
1833
+ ]).optional(),
1405
1834
  fraction: px.number().optional()
1406
1835
  }));
1407
1836
  var PxScrollRangeSchema = px.object({
@@ -1409,34 +1838,38 @@ var PxScrollRangeSchema = px.object({
1409
1838
  end: PxScrollRangePointSchema.optional()
1410
1839
  });
1411
1840
  var PxScrollSchema = implementsInterface()(px.object({
1412
- driver: px.enum(["custom", "native"]).optional(),
1413
- kind: px.enum(["view", "scroll"]).optional(),
1414
- axis: px.enum(["block", "inline", "x", "y"]).optional(),
1415
- source: px.enum(["nearest", "root"]).optional(),
1841
+ kind: px.enum([PxScrollKind.view, PxScrollKind.scroll]).optional(),
1842
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1843
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1416
1844
  // Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
1417
1845
  subject: px.string().optional(),
1418
1846
  smoothing: px.number().optional(),
1419
1847
  pin: px.boolean().optional(),
1420
- pinAlign: px.enum(["top", "center", "bottom"]).optional(),
1421
- pinTop: px.number().optional(),
1848
+ pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1849
+ pinOffset: px.number().optional(),
1422
1850
  pinDistance: px.number().optional(),
1423
1851
  range: PxScrollRangeSchema.optional()
1424
1852
  }));
1425
- var PxTimelinePinSchema = px.object({
1426
- align: px.enum(["top", "center", "bottom"]).optional(),
1427
- top: px.number().optional(),
1853
+ var PxTimelinePinSchema = implementsInterface()(px.object({
1854
+ align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1855
+ offset: px.number().optional(),
1428
1856
  distance: px.number().optional()
1429
- });
1430
- var PxClockTimelineSchema = px.object({
1431
- type: px.literal("clock"),
1857
+ }));
1858
+ var PxTimelineEngineSchema = px.enum([PxTimelineEngineExtra.auto, PxTimelineEngineExtra.native, PxTimelineEngineExtra.js]).optional();
1859
+ var PxTimeTimelineSchema = implementsInterface()(px.object({
1860
+ type: px.literal("time").optional(),
1861
+ engine: PxTimelineEngineSchema,
1862
+ frameRate: px.number().optional(),
1432
1863
  // §2.8: duration is a property of the TIMELINE — how long one pass takes.
1433
1864
  duration: px.number().optional(),
1434
1865
  trigger: PxTriggerSchema.optional(),
1435
1866
  delay: px.number().optional(),
1436
1867
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1437
- fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1438
- direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional()
1439
- });
1868
+ // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1869
+ // — never `fill`, which is paint everywhere else in the format.
1870
+ fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none]).optional(),
1871
+ direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse]).optional()
1872
+ }));
1440
1873
  var scrollishTimelineShape = {
1441
1874
  // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
1442
1875
  // span the scroll range maps onto.
@@ -1444,9 +1877,10 @@ var scrollishTimelineShape = {
1444
1877
  // Finite repeat count IS meaningful when scrubbing — the scroll range maps onto
1445
1878
  // duration × iterations (rule D4; `'infinite'` cannot map to a range, so no literal here).
1446
1879
  iterations: px.number().optional(),
1447
- engine: px.enum(["custom", "native"]).optional(),
1448
- axis: px.enum(["block", "inline", "x", "y"]).optional(),
1449
- source: px.enum(["nearest", "root"]).optional(),
1880
+ engine: PxTimelineEngineSchema,
1881
+ frameRate: px.number().optional(),
1882
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1883
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1450
1884
  subject: px.string().optional(),
1451
1885
  // 'parent' | 'scroller' | any CSS selector
1452
1886
  smoothing: px.number().optional(),
@@ -1454,23 +1888,29 @@ var scrollishTimelineShape = {
1454
1888
  pin: px.union([px.boolean(), PxTimelinePinSchema]).optional(),
1455
1889
  range: PxScrollRangeSchema.optional()
1456
1890
  };
1457
- var PxScrollTimelineSchema = px.object(__spreadValues2({ type: px.literal("scroll") }, scrollishTimelineShape));
1458
- var PxViewTimelineSchema = px.object(__spreadValues2({ type: px.literal("view") }, scrollishTimelineShape));
1891
+ var PxScrollTimelineSchema = implementsInterface()(
1892
+ px.object(__spreadValues2({ type: px.literal("scroll") }, scrollishTimelineShape))
1893
+ );
1894
+ var PxViewTimelineSchema = implementsInterface()(
1895
+ px.object(__spreadValues2({ type: px.literal("view") }, scrollishTimelineShape))
1896
+ );
1459
1897
  var PxTimelineSchema = px.discriminatedUnion("type", [
1460
- PxClockTimelineSchema,
1898
+ PxTimeTimelineSchema,
1899
+ // first = the member an absent `type` selects
1461
1900
  PxScrollTimelineSchema,
1462
1901
  PxViewTimelineSchema
1463
1902
  ]);
1464
1903
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
1465
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
1466
- // (`duration` lives INSIDE `timeline` on the wire — §2.8; the flat field below
1467
- // exists only on the runtime view, like the rest of the playback dynamics.)
1468
- frameRate: px.number().optional(),
1904
+ // (`mode`, `duration` and `frameRate` live INSIDE `timeline` on the wire — §2.8; they exist
1905
+ // at this level only on the runtime view, like the rest of the playback dynamics.)
1469
1906
  // THE spelling of "what advances progress" — clock / scroll / view (review §2.1).
1470
1907
  timeline: PxTimelineSchema.optional(),
1471
1908
  definitions: PxDefsSchema.optional(),
1472
1909
  animateById: px.record(PxElementAnimationSchema).optional(),
1473
- debugInstName: px.string().optional()
1910
+ debugGlobalName: px.string().optional(),
1911
+ // Declared HERE because this is a closed object: an undeclared key would be stripped by
1912
+ // `sanitize` and flagged by strict validation on our own files.
1913
+ version: px.string().optional()
1474
1914
  }));
1475
1915
  var PxBindingSchema = implementsInterface()(px.object({
1476
1916
  id: px.string(),
@@ -1519,7 +1959,7 @@ var PxRepeaterEffectSchema = implementsInterface()(px.object({
1519
1959
  origin: PxAnimatableVec2Schema.optional()
1520
1960
  }));
1521
1961
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
1522
- sourceId: px.string().optional(),
1962
+ source: px.string().optional(),
1523
1963
  maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
1524
1964
  maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1525
1965
  maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
@@ -1529,7 +1969,7 @@ var PxMaskedByEffectSchema = implementsInterface()(px.object({
1529
1969
  height: px.number().optional()
1530
1970
  }));
1531
1971
  var PxClipPathEffectSchema = implementsInterface()(px.object({
1532
- d: PxAnimatableStringSchema.optional()
1972
+ pathData: PxAnimatableStringSchema.optional()
1533
1973
  }));
1534
1974
  var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1535
1975
  offset: PxAnimatableNumberSchema.optional(),
@@ -1542,9 +1982,10 @@ var PxRetimeEffectSchema = implementsInterface()(px.object({
1542
1982
  timeCrop: px.tuple([px.number(), px.number()]).optional()
1543
1983
  }));
1544
1984
  var PxCloneEffectSchema = implementsInterface()(px.object({
1545
- // Contextual kind — the `type` convention, see `PxNodeBase.type`.
1546
- type: px.enum([PxCloneType.content]).optional(),
1547
- sourceId: px.string().optional(),
1985
+ // Subtractive on purpose: the `<use>` can only point at one wrapper layer of the
1986
+ // source, so the choices form a ladder — 'translate' now, maybe 'transform' later.
1987
+ without: px.enum([PxCloneWithout.translate]).optional(),
1988
+ source: px.string().optional(),
1548
1989
  retime: PxRetimeEffectSchema.optional()
1549
1990
  }));
1550
1991
  var PxGradientStopSchema = implementsInterface()(px.object({
@@ -1565,13 +2006,13 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1565
2006
  radius: PxAnimatableNumberSchema.optional(),
1566
2007
  focal: PxAnimatableVec2Schema.optional(),
1567
2008
  stops: PxAnimatableGradientStopsSchema.optional(),
1568
- gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
2009
+ gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1569
2010
  spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
1570
2011
  gradientTransform: px.string().optional()
1571
2012
  }));
1572
2013
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
1573
2014
  var PxTextPathEffectSchema = implementsInterface()(px.object({
1574
- path: px.string(),
2015
+ pathData: px.string(),
1575
2016
  pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
1576
2017
  lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
1577
2018
  method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
@@ -1611,20 +2052,100 @@ function validateNodeEffects(root, opts) {
1611
2052
  walk(root, "root");
1612
2053
  return warnings;
1613
2054
  }
2055
+ function validateGlyphFontRefs(root, fonts) {
2056
+ if (!fonts || !Object.keys(fonts).length) return [];
2057
+ const problems = [];
2058
+ const walk = (node, path, inherited, inGlyphText) => {
2059
+ var _a2, _b;
2060
+ if (!node) return;
2061
+ const own = typeof node.fontFamily === "string" ? node.fontFamily : void 0;
2062
+ const family = own != null ? own : inherited;
2063
+ const isGlyphText = inGlyphText || node.type === "text" && !!((_b = (_a2 = node.effects) == null ? void 0 : _a2.text) == null ? void 0 : _b.useGlyphs);
2064
+ if (isGlyphText && own && !Object.prototype.hasOwnProperty.call(fonts, own)) {
2065
+ const problem = path + ': glyph-mode text uses font-family "' + own + '", which has no entry in animator.definitions.fonts';
2066
+ if (!problems.includes(problem)) problems.push(problem);
2067
+ }
2068
+ if (Array.isArray(node.children)) {
2069
+ node.children.forEach((c, i) => walk(c, path + ".children[" + i + "]", family, isGlyphText));
2070
+ }
2071
+ };
2072
+ walk(root, "root", void 0, false);
2073
+ return problems;
2074
+ }
2075
+ function validateEasingRefs(root, easings) {
2076
+ const problems = [];
2077
+ const walk = (node, path) => {
2078
+ if (Array.isArray(node)) {
2079
+ node.forEach((item, i) => walk(item, path + "[" + i + "]"));
2080
+ return;
2081
+ }
2082
+ if (!node || typeof node !== "object") return;
2083
+ const easing = node.easing;
2084
+ if (typeof easing === "string" && !(easings && Object.prototype.hasOwnProperty.call(easings, easing))) {
2085
+ const problem = path + '.easing: "' + easing + '" names no entry in animator.definitions.easings \u2014 it will play linear';
2086
+ if (!problems.includes(problem)) problems.push(problem);
2087
+ }
2088
+ for (const [key, value] of Object.entries(node)) {
2089
+ if (key === "easing") continue;
2090
+ if (value && typeof value === "object") walk(value, path + "." + key);
2091
+ }
2092
+ };
2093
+ walk(root, "root");
2094
+ return problems;
2095
+ }
2096
+ function validateVersionStamp(doc) {
2097
+ var _a2;
2098
+ const version = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.version;
2099
+ if (version === void 0) return [];
2100
+ if (parseWireVersion(version) !== void 0) return [];
2101
+ return ["root.animator.version: " + JSON.stringify(version) + ' is not a version stamp ("a.b" or "a.b.c") \u2014 it reads as unstamped'];
2102
+ }
2103
+ function validateDocument(doc, opts) {
2104
+ var _a2;
2105
+ const strict = (opts == null ? void 0 : opts.strict) !== false;
2106
+ const ctx = { errors: [], warnings: [], strict };
2107
+ const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
2108
+ if (doc && typeof doc === "object") {
2109
+ for (const w of validateNodeEffects(doc, { strict })) {
2110
+ if (!problems.includes(w)) problems.push(w);
2111
+ }
2112
+ const defs = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
2113
+ for (const w of validateGlyphFontRefs(doc, defs == null ? void 0 : defs.fonts)) {
2114
+ if (!problems.includes(w)) problems.push(w);
2115
+ }
2116
+ for (const w of validateEasingRefs(doc, defs == null ? void 0 : defs.easings)) {
2117
+ if (!problems.includes(w)) problems.push(w);
2118
+ }
2119
+ for (const w of validateVersionStamp(doc)) {
2120
+ if (!problems.includes(w)) problems.push(w);
2121
+ }
2122
+ }
2123
+ return problems;
2124
+ }
1614
2125
  var PxNodeBase = px.openObject({
1615
2126
  // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
1616
2127
  // kind of thing is this", discriminated by its CARRIER — here the node TAG
1617
- // (`rect`, `text`), and inside a sub-object that object's kind (`clone.type`,
2128
+ // (`rect`, `text`), and inside a sub-object that object's kind (`fillGradient.type`,
1618
2129
  // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
1619
2130
  // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
1620
2131
  // would add words that all mean "type" and still need the carrier to read.
1621
2132
  // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
1622
2133
  // (issues V3), never of distinct key names.
1623
2134
  type: px.string(),
2135
+ // The escape hatch for elements that carry a REAL `type` attribute — `<feTurbulence
2136
+ // type="fractalNoise">`, `<feFuncR type="table">`, `<feColorMatrix type="saturate">`.
2137
+ // `type` is taken by the tag name, so the attribute travels here and the renderer puts
2138
+ // it back (`PxAnimatorDOM.renderNode`, `PxRnRender`). Declared here — not merely
2139
+ // documented — because a wire key that is not in a schema is invisible to the
2140
+ // minifier's reserve list and gets renamed (MINIFICATION-BOUNDARY-PLAN.md §1.1).
2141
+ domType: px.string().optional(),
2142
+ // Text content of a `<text>` / `<tspan>`. Declared, so a non-string value is a schema error
2143
+ // and the minifier reserves the key; `text` is NOT an alias for it and is not read anywhere.
2144
+ textContent: px.string().optional(),
1624
2145
  id: px.string().optional(),
1625
2146
  meta: px.any().optional(),
1626
2147
  // Player-effects bucket emitted by the Editor's lightweight design format.
1627
- // Consumed and removed by `applyPlayerEffects` before any other normalisation
2148
+ // Consumed and removed by `applyPlayerEffects` before any other normalization
1628
2149
  // (see `createAnimatorImpl`), so downstream code never sees it.
1629
2150
  effects: PxEffectsSchema.optional(),
1630
2151
  // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
@@ -1656,8 +2177,8 @@ var PxBezierPathSchema = implementsInterface()(px.object({
1656
2177
  c: px.boolean().optional()
1657
2178
  }));
1658
2179
  function isPxElementFileFormatDeep(fileJson) {
1659
- const valid = PxAnimatedSvgDocumentSchema.isValid(fileJson);
1660
- return { valid, errors: valid ? [] : ["Document failed schema validation"] };
2180
+ const errors = validateDocument(fileJson, { strict: false });
2181
+ return { valid: errors.length === 0, errors };
1661
2182
  }
1662
2183
  var _idCounter = 0;
1663
2184
  function generateUniqueId() {
@@ -1677,7 +2198,7 @@ function deepClone(value) {
1677
2198
  return cloned;
1678
2199
  }
1679
2200
  function generateNewIds(doc) {
1680
- var _a, _b;
2201
+ var _a2, _b;
1681
2202
  const cloned = deepClone(doc);
1682
2203
  const idMap = /* @__PURE__ */ new Map();
1683
2204
  const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
@@ -1695,7 +2216,8 @@ function generateNewIds(doc) {
1695
2216
  "flood-color",
1696
2217
  "lighting-color"
1697
2218
  ]);
1698
- const directIdRefAttrs = /* @__PURE__ */ new Set(["sourceId", "targetId", "boundElementId"]);
2219
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["targetId", "boundElementId"]);
2220
+ const isEffectSourceRef = (key, parentKey) => key === "source" && (parentKey === "maskedBy" || parentKey === "clone");
1699
2221
  function collectIds(node) {
1700
2222
  if (!node || typeof node !== "object") return;
1701
2223
  if (node.id && typeof node.id === "string") {
@@ -1712,7 +2234,7 @@ function generateNewIds(doc) {
1712
2234
  }
1713
2235
  }
1714
2236
  }
1715
- function updateRefs(node) {
2237
+ function updateRefs(node, parentKey) {
1716
2238
  if (!node || typeof node !== "object") return;
1717
2239
  for (const [key, value] of Object.entries(node)) {
1718
2240
  if (key === "children") {
@@ -1732,7 +2254,7 @@ function generateNewIds(doc) {
1732
2254
  }
1733
2255
  } else if (urlRefAttrs.has(key)) {
1734
2256
  node[key] = replaceUrlRefs(value, idMap);
1735
- } else if (directIdRefAttrs.has(key)) {
2257
+ } else if (directIdRefAttrs.has(key) || isEffectSourceRef(key, parentKey)) {
1736
2258
  const hasHash = value.startsWith("#");
1737
2259
  const newId = idMap.get(hasHash ? value.slice(1) : value);
1738
2260
  if (newId) {
@@ -1748,13 +2270,13 @@ function generateNewIds(doc) {
1748
2270
  }
1749
2271
  }
1750
2272
  } else if (typeof value === "object" && value !== null) {
1751
- updateRefs(value);
2273
+ updateRefs(value, key);
1752
2274
  }
1753
2275
  }
1754
2276
  }
1755
2277
  collectIds(cloned);
1756
2278
  updateRefs(cloned);
1757
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
2279
+ const docAnimate = (_a2 = cloned.animator) == null ? void 0 : _a2.animateById;
1758
2280
  if (docAnimate && typeof docAnimate === "object") {
1759
2281
  const updatedAnimate = {};
1760
2282
  for (const [key, anim] of Object.entries(docAnimate)) {
@@ -1811,7 +2333,7 @@ function isDangerousAttrName(nameLower) {
1811
2333
  if (nameLower.startsWith("on")) return true;
1812
2334
  return false;
1813
2335
  }
1814
- function sanitiseAttributeValue(name, value) {
2336
+ function sanitizeAttributeValue(name, value) {
1815
2337
  const nameLower = name.toLowerCase();
1816
2338
  if (isDangerousAttrName(nameLower)) {
1817
2339
  console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
@@ -1836,10 +2358,10 @@ function sanitiseAttributeValue(name, value) {
1836
2358
  return value;
1837
2359
  }
1838
2360
  function resolveStyle(style, defs) {
1839
- var _a;
2361
+ var _a2;
1840
2362
  if (!style) return void 0;
1841
2363
  if (typeof style === "string") {
1842
- return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
2364
+ return (_a2 = defs == null ? void 0 : defs.styles) == null ? void 0 : _a2[style];
1843
2365
  }
1844
2366
  return style;
1845
2367
  }
@@ -1850,18 +2372,18 @@ function getNormalizedProps(props) {
1850
2372
  if (INTERNAL_ATTRS.has(key)) continue;
1851
2373
  if (key === "style") continue;
1852
2374
  let value = props[rawKey];
1853
- if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
2375
+ if (COLOR_ATTR_NAMES.has(key) && Array.isArray(value)) {
1854
2376
  propsCopy[key] = toRGBA(value);
1855
2377
  } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
1856
2378
  const parts = value.value && typeof value.value === "object" ? value.value : value;
1857
- propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
2379
+ propsCopy[TRANSFORM_ATTR] = composeTransformParts(parts, { withUnits: false });
1858
2380
  } else if (TRANSFORM_FN_NAMES.has(key)) {
1859
2381
  if (Array.isArray(value)) {
1860
2382
  if (key === "translate") value = value.map((v) => v + "px");
1861
2383
  value = value.join(",");
1862
2384
  }
1863
2385
  if (key === "rotate") value = value + "deg";
1864
- propsCopy["transform"] = key + "(" + value + ")";
2386
+ propsCopy[TRANSFORM_ATTR] = key + "(" + value + ")";
1865
2387
  } else if (Array.isArray(value)) {
1866
2388
  propsCopy[key] = value.join(",");
1867
2389
  } else if (value !== void 0 && value !== null) {
@@ -1871,8 +2393,7 @@ function getNormalizedProps(props) {
1871
2393
  return propsCopy;
1872
2394
  }
1873
2395
  function getKfTranslate(kf) {
1874
- var _a;
1875
- const v = (_a = kf.value) != null ? _a : kf.v;
2396
+ const v = kfValue(kf);
1876
2397
  if (!v) return void 0;
1877
2398
  if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
1878
2399
  return [v[0], v[1]];
@@ -1882,31 +2403,27 @@ function getKfTranslate(kf) {
1882
2403
  return void 0;
1883
2404
  }
1884
2405
  function getKfTime(kf) {
1885
- var _a, _b;
1886
- return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
2406
+ return kfTime(kf);
1887
2407
  }
1888
2408
  function getKfEasing(kf) {
1889
- var _a;
1890
- return (_a = kf.easing) != null ? _a : kf.e;
2409
+ return kfEasing(kf);
1891
2410
  }
1892
2411
  function propAnimIsMotionPath(anim) {
1893
- var _a, _b;
1894
2412
  const kfs = anim.keyframes;
1895
2413
  if (!Array.isArray(kfs)) return false;
1896
2414
  if (anim.autoOrient) return true;
1897
2415
  for (const kf of kfs) {
1898
- if (((_a = kf.tangentIn) != null ? _a : kf.ti) || ((_b = kf.tangentOut) != null ? _b : kf.to)) return true;
2416
+ if (kfTangentIn(kf) || kfTangentOut(kf)) return true;
1899
2417
  }
1900
2418
  return false;
1901
2419
  }
1902
2420
  var _segmentCache = /* @__PURE__ */ new WeakMap();
1903
2421
  function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
1904
- var _a, _b;
1905
2422
  let byNext = _segmentCache.get(prevKf);
1906
2423
  const existing = byNext == null ? void 0 : byNext.get(nextKf);
1907
2424
  if (existing) return existing;
1908
- const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
1909
- const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
2425
+ const to = kfTangentOut(prevKf);
2426
+ const ti = kfTangentIn(nextKf);
1910
2427
  const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
1911
2428
  const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
1912
2429
  const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
@@ -1955,13 +2472,13 @@ function tFromArcFraction(lut, arcFrac) {
1955
2472
  var DEFAULT_FLATNESS_TOL = 0.5;
1956
2473
  var DEFAULT_ROTATION_TOL = 5;
1957
2474
  var DEFAULT_MAX_SAMPLES = 32;
1958
- function materialiseMotionPathInPropAnim(anim, opts) {
1959
- var _a, _b, _c;
2475
+ function materializeMotionPathInPropAnim(anim, opts) {
2476
+ var _a2, _b, _c;
1960
2477
  if (!propAnimIsMotionPath(anim)) return anim;
1961
2478
  const kfs = anim.keyframes;
1962
2479
  if (!Array.isArray(kfs) || kfs.length < 2) return anim;
1963
2480
  const autoOrient = !!anim.autoOrient;
1964
- const flatnessTol = (_a = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a : DEFAULT_FLATNESS_TOL;
2481
+ const flatnessTol = (_a2 = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a2 : DEFAULT_FLATNESS_TOL;
1965
2482
  const rotationTol = (_b = opts == null ? void 0 : opts.rotationTolerance) != null ? _b : DEFAULT_ROTATION_TOL;
1966
2483
  const maxSamples = (_c = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _c : DEFAULT_MAX_SAMPLES;
1967
2484
  const out = [];
@@ -1987,7 +2504,7 @@ function materialiseMotionPathInPropAnim(anim, opts) {
1987
2504
  if (autoOrient && i > 0) {
1988
2505
  insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
1989
2506
  }
1990
- materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
2507
+ materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
1991
2508
  }
1992
2509
  const lastInE = getKfEasing(kfs[kfs.length - 1]);
1993
2510
  if (lastInE) out[out.length - 1].e = lastInE;
@@ -1997,10 +2514,9 @@ function materialiseMotionPathInPropAnim(anim, opts) {
1997
2514
  return result;
1998
2515
  }
1999
2516
  function unwrapAutoOrientRotations(kfs) {
2000
- var _a;
2001
2517
  let prev;
2002
2518
  for (const kf of kfs) {
2003
- const v = (_a = kf.v) != null ? _a : kf.value;
2519
+ const v = kfValue(kf);
2004
2520
  if (!v || typeof v.rotate !== "number") continue;
2005
2521
  if (prev === void 0) {
2006
2522
  prev = v.rotate;
@@ -2017,8 +2533,7 @@ function makeOutKf(time, value) {
2017
2533
  return { t: time, v: value };
2018
2534
  }
2019
2535
  function getKfValueParts(kf) {
2020
- var _a;
2021
- const v = (_a = kf.value) != null ? _a : kf.v;
2536
+ const v = kfValue(kf);
2022
2537
  if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
2023
2538
  return v;
2024
2539
  }
@@ -2079,9 +2594,8 @@ function wrappedAngleDelta(a, b) {
2079
2594
  return d;
2080
2595
  }
2081
2596
  function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
2082
- var _a;
2083
2597
  const lastKf = out[out.length - 1];
2084
- const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
2598
+ const lastV = kfValue(lastKf);
2085
2599
  const prevExit = lastV == null ? void 0 : lastV.rotate;
2086
2600
  if (typeof prevExit !== "number") return;
2087
2601
  const boundaryV = getKfValueParts(prevKf);
@@ -2104,7 +2618,7 @@ function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos,
2104
2618
  out.push(makeOutKf(stepTime, dupValue));
2105
2619
  }
2106
2620
  var CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;
2107
- function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
2621
+ function materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
2108
2622
  const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
2109
2623
  const prevTime = getKfTime(prevKf);
2110
2624
  const nextTime = getKfTime(nextKf);
@@ -2227,16 +2741,16 @@ function perpDist(q, pA, pB) {
2227
2741
  const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
2228
2742
  return Math.abs(cross) / Math.sqrt(len2);
2229
2743
  }
2230
- function materialiseMotionPathsInTree(root, opts) {
2231
- const out = walkAndMaterialise(root, opts);
2744
+ function materializeMotionPathsInTree(root, opts) {
2745
+ const out = walkAndMaterialize(root, opts);
2232
2746
  return out != null ? out : root;
2233
2747
  }
2234
- function walkAndMaterialise(node, opts) {
2748
+ function walkAndMaterialize(node, opts) {
2235
2749
  let newChildren;
2236
2750
  if (node.children) {
2237
2751
  for (let i = 0; i < node.children.length; i++) {
2238
2752
  const ch = node.children[i];
2239
- const ret = walkAndMaterialise(ch, opts);
2753
+ const ret = walkAndMaterialize(ch, opts);
2240
2754
  if (ret !== null) {
2241
2755
  if (!newChildren) newChildren = node.children.slice();
2242
2756
  newChildren[i] = ret;
@@ -2249,9 +2763,9 @@ function walkAndMaterialise(node, opts) {
2249
2763
  const animDef = animBucket;
2250
2764
  const transformAnim = animDef.transform;
2251
2765
  if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
2252
- const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);
2253
- if (materialised !== transformAnim) {
2254
- newAnimate = __spreadProps2(__spreadValues2({}, animDef), { transform: materialised });
2766
+ const materialized = materializeMotionPathInPropAnim(transformAnim, opts);
2767
+ if (materialized !== transformAnim) {
2768
+ newAnimate = __spreadProps2(__spreadValues2({}, animDef), { transform: materialized });
2255
2769
  }
2256
2770
  }
2257
2771
  }
@@ -2352,8 +2866,8 @@ function isPathString(value) {
2352
2866
  return typeof value === "string" && extractPathData(value) !== void 0;
2353
2867
  }
2354
2868
  function normalizePathValue(value) {
2355
- if (value && typeof value === "object" && typeof value.path === "string") {
2356
- const d = extractPathData(value.path);
2869
+ if (value && typeof value === "object" && typeof value.pathData === "string") {
2870
+ const d = extractPathData(value.pathData);
2357
2871
  return d ? { paths: parseSvgPathToBezier(d) } : value;
2358
2872
  }
2359
2873
  if (value && typeof value === "object" && "paths" in value) {
@@ -2392,21 +2906,21 @@ function normalizePathValue(value) {
2392
2906
  return value;
2393
2907
  }
2394
2908
  function resolveEasing(easing, defs) {
2395
- var _a;
2909
+ var _a2;
2396
2910
  if (!easing) return void 0;
2397
2911
  if (Array.isArray(easing)) {
2398
2912
  return easing;
2399
2913
  }
2400
- if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
2914
+ if ((_a2 = defs == null ? void 0 : defs.easings) == null ? void 0 : _a2[easing]) {
2401
2915
  return defs.easings[easing];
2402
2916
  }
2403
2917
  console.warn("Unknown easing name: " + easing);
2404
2918
  return void 0;
2405
2919
  }
2406
2920
  function resolveAnimation(animRef, defs) {
2407
- var _a;
2921
+ var _a2;
2408
2922
  if (typeof animRef === "string") {
2409
- const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
2923
+ const resolved = (_a2 = defs == null ? void 0 : defs.animations) == null ? void 0 : _a2[animRef];
2410
2924
  if (!resolved) {
2411
2925
  console.warn("Unknown animation name: " + animRef);
2412
2926
  }
@@ -2431,13 +2945,13 @@ function resolveElementAnimation(animate, defs) {
2431
2945
  return results;
2432
2946
  }
2433
2947
  function interpolateValue(propName, a, b, t) {
2434
- var _a, _b;
2948
+ var _a2, _b;
2435
2949
  if (propName === "d") {
2436
- const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
2950
+ const aPaths = (_a2 = a == null ? void 0 : a.paths) != null ? _a2 : Array.isArray(a) ? a : [];
2437
2951
  const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
2438
2952
  return { paths: interpolateBeziers(aPaths, bPaths, t) };
2439
2953
  }
2440
- if (COLOUR_ATTR_NAMES.has(propName)) {
2954
+ if (COLOR_ATTR_NAMES.has(propName)) {
2441
2955
  return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
2442
2956
  }
2443
2957
  if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
@@ -2469,11 +2983,11 @@ function interpolateTransformParts(a, b, t) {
2469
2983
  return out;
2470
2984
  }
2471
2985
  function expandLoopKeyframes(propName, keyframes, loop, duration) {
2472
- var _a, _b, _c, _d, _e;
2986
+ var _a2, _b, _c, _d, _e;
2473
2987
  const totalIntervals = keyframes.length - 1;
2474
- const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
2988
+ const segCount = clamp((_a2 = loop.segmentCount) != null ? _a2 : totalIntervals, 1, totalIntervals);
2475
2989
  let segKfs;
2476
- if (loop.extend === PxLoopExtend.before) {
2990
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2477
2991
  segKfs = keyframes.slice(0, segCount + 1);
2478
2992
  } else {
2479
2993
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -2481,7 +2995,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2481
2995
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
2482
2996
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
2483
2997
  let fillStart, fillEnd;
2484
- if (loop.extend === PxLoopExtend.before) {
2998
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2485
2999
  fillStart = 0;
2486
3000
  fillEnd = firstT;
2487
3001
  } else {
@@ -2494,26 +3008,23 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2494
3008
  const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
2495
3009
  const segDuration = segEndT - segStartT;
2496
3010
  if (segDuration <= 0) return keyframes;
2497
- const template = segKfs.map((kf) => {
2498
- var _a2, _b2;
2499
- return {
2500
- relT: (kf.t - segStartT) / segDuration,
2501
- v: kf.v,
2502
- e: kf.e,
2503
- tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
2504
- tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
2505
- };
2506
- });
3011
+ const template = segKfs.map((kf) => ({
3012
+ relT: (kf.t - segStartT) / segDuration,
3013
+ v: kf.v,
3014
+ e: kf.e,
3015
+ tangentIn: kfTangentIn(kf),
3016
+ tangentOut: kfTangentOut(kf)
3017
+ }));
2507
3018
  const fullReps = Math.floor(fillDuration / segDuration);
2508
3019
  const remainder = fillDuration - fullReps * segDuration;
2509
3020
  const partialFraction = remainder / segDuration;
2510
3021
  const looped = [];
2511
- const separateBoundary = loop.extend !== PxLoopExtend.before;
3022
+ const separateBoundary = loop.repeatAt !== PxLoopRepeatAt.start;
2512
3023
  const originalTerminalKf = keyframes[keyframes.length - 1];
2513
3024
  let terminalEasingOverride;
2514
3025
  let hasTerminalEasingOverride = false;
2515
3026
  function appendRep(repStart, isReversed, partial) {
2516
- var _a2;
3027
+ var _a3;
2517
3028
  let entries;
2518
3029
  if (isReversed) {
2519
3030
  entries = [];
@@ -2550,7 +3061,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2550
3061
  return;
2551
3062
  }
2552
3063
  const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
2553
- const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
3064
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a3 = prevKf.t) != null ? _a3 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2554
3065
  if (isBoundary) {
2555
3066
  if (deepEqualValue(prevKf.v, entry.v)) {
2556
3067
  if (looped.length > 0) {
@@ -2616,30 +3127,30 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2616
3127
  looped.push(pushed);
2617
3128
  }
2618
3129
  }
2619
- if (loop.extend === PxLoopExtend.before) {
3130
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2620
3131
  if (partialFraction > 1e-9) {
2621
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
3132
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
2622
3133
  appendRepTail(fillStart, isReversed, partialFraction);
2623
3134
  }
2624
3135
  for (let rep = 0; rep < fullReps; rep++) {
2625
3136
  const distFromBoundary = fullReps - 1 - rep;
2626
- const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
3137
+ const isReversed = loop.direction === PxLoopDirection.alternate && distFromBoundary % 2 === 0;
2627
3138
  const repStart = fillStart + remainder + rep * segDuration;
2628
3139
  appendRep(repStart, isReversed);
2629
3140
  }
2630
3141
  } else {
2631
3142
  for (let rep = 0; rep < fullReps; rep++) {
2632
- const isReversed = !!loop.alternate && rep % 2 === 0;
3143
+ const isReversed = loop.direction === PxLoopDirection.alternate && rep % 2 === 0;
2633
3144
  const repStart = fillStart + rep * segDuration;
2634
3145
  appendRep(repStart, isReversed);
2635
3146
  }
2636
3147
  if (partialFraction > 1e-9) {
2637
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
3148
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
2638
3149
  const repStart = fillStart + fullReps * segDuration;
2639
3150
  appendRep(repStart, isReversed, partialFraction);
2640
3151
  }
2641
3152
  }
2642
- if (loop.extend === PxLoopExtend.before) {
3153
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2643
3154
  return [...looped, ...keyframes];
2644
3155
  } else {
2645
3156
  if (hasTerminalEasingOverride && keyframes.length > 0) {
@@ -2651,34 +3162,34 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2651
3162
  }
2652
3163
  }
2653
3164
  function normalizeKeyframes(propName, propAnim, duration, defs) {
2654
- var _a, _b, _c, _d, _e, _f, _g;
3165
+ var _a2;
2655
3166
  const keyframes = propAnim.keyframes || [];
2656
3167
  const normalized = [];
2657
3168
  for (const kf of keyframes) {
2658
- const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
2659
- let value = (_c = kf.value) != null ? _c : kf.v;
2660
- const easing = (_d = kf.easing) != null ? _d : kf.e;
3169
+ const timePct = kfTime(kf);
3170
+ let value = kfValue(kf);
3171
+ const easing = kfEasing(kf);
2661
3172
  if (propName === "d") {
2662
3173
  value = normalizePathValue(value);
2663
3174
  }
2664
3175
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2665
- if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
2666
- value = (_e = parseColor(value)) != null ? _e : value;
3176
+ if (COLOR_ATTR_NAMES.has(propNameKebab)) {
3177
+ value = (_a2 = parseColor(value)) != null ? _a2 : value;
2667
3178
  }
2668
3179
  const normKf = {
2669
3180
  t: timePct,
2670
3181
  v: value,
2671
3182
  e: resolveEasing(easing, defs)
2672
3183
  };
2673
- const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
2674
- const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
3184
+ const tIn = kfTangentIn(kf);
3185
+ const tOut = kfTangentOut(kf);
2675
3186
  if (tIn) normKf.tangentIn = tIn;
2676
3187
  if (tOut) normKf.tangentOut = tOut;
2677
3188
  normalized.push(normKf);
2678
3189
  }
2679
3190
  normalized.sort((a, b) => {
2680
- var _a2, _b2;
2681
- return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
3191
+ var _a3, _b;
3192
+ return ((_a3 = a.t) != null ? _a3 : 0) - ((_b = b.t) != null ? _b : 0);
2682
3193
  });
2683
3194
  const loopRaw = propAnim.loop;
2684
3195
  const loop = loopRaw === true ? {} : loopRaw || void 0;
@@ -2696,24 +3207,26 @@ function mergeAnimationDefinitions(animations) {
2696
3207
  }
2697
3208
  return merged;
2698
3209
  }
2699
- function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
3210
+ function materializeInternalLoopsInPropAnim(propName, propAnim, duration) {
2700
3211
  const loopRaw = propAnim.loop;
2701
3212
  if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
2702
3213
  const loop = loopRaw === true ? {} : loopRaw;
2703
3214
  const rawKfs = propAnim.keyframes;
2704
3215
  if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
2705
3216
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2706
- const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
3217
+ const isColor = COLOR_ATTR_NAMES.has(propNameKebab);
2707
3218
  const kfs = rawKfs.map((kf) => {
2708
- var _a, _b, _c, _d, _e, _f, _g, _h;
2709
- const t = (_a = kf.t) != null ? _a : kf.time;
2710
- let v = (_b = kf.v) != null ? _b : kf.value;
3219
+ var _a2;
3220
+ const t = kfTime(kf);
3221
+ let v = kfValue(kf);
2711
3222
  if (propName === "d") v = normalizePathValue(v);
2712
- if (isColour) v = (_c = parseColor(v)) != null ? _c : v;
2713
- const e = (_d = kf.e) != null ? _d : kf.easing;
3223
+ if (isColor) v = (_a2 = parseColor(v)) != null ? _a2 : v;
3224
+ const e = kfEasing(kf);
2714
3225
  const out2 = { t, v, e };
2715
- if ((_e = kf.tangentIn) != null ? _e : kf.ti) out2.tangentIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
2716
- if ((_g = kf.tangentOut) != null ? _g : kf.to) out2.tangentOut = (_h = kf.tangentOut) != null ? _h : kf.to;
3226
+ const tIn = kfTangentIn(kf);
3227
+ const tOut = kfTangentOut(kf);
3228
+ if (tIn) out2.tangentIn = tIn;
3229
+ if (tOut) out2.tangentOut = tOut;
2717
3230
  return out2;
2718
3231
  });
2719
3232
  const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
@@ -2721,15 +3234,15 @@ function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
2721
3234
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2722
3235
  return out;
2723
3236
  }
2724
- function materialiseInternalLoopsInTree(root, duration) {
2725
- const ret = walkAndMaterialiseLoops(root, duration);
3237
+ function materializeInternalLoopsInTree(root, duration) {
3238
+ const ret = walkAndMaterializeLoops(root, duration);
2726
3239
  return ret != null ? ret : root;
2727
3240
  }
2728
- function walkAndMaterialiseLoops(node, duration) {
3241
+ function walkAndMaterializeLoops(node, duration) {
2729
3242
  let newChildren;
2730
3243
  if (node.children) {
2731
3244
  for (let i = 0; i < node.children.length; i++) {
2732
- const ret = walkAndMaterialiseLoops(node.children[i], duration);
3245
+ const ret = walkAndMaterializeLoops(node.children[i], duration);
2733
3246
  if (ret !== null) {
2734
3247
  if (!newChildren) newChildren = node.children.slice();
2735
3248
  newChildren[i] = ret;
@@ -2742,10 +3255,10 @@ function walkAndMaterialiseLoops(node, duration) {
2742
3255
  const animDef = animBucket;
2743
3256
  for (const propName of Object.keys(animDef)) {
2744
3257
  const propAnim = animDef[propName];
2745
- const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);
2746
- if (materialised !== propAnim) {
3258
+ const materialized = materializeInternalLoopsInPropAnim(propName, propAnim, duration);
3259
+ if (materialized !== propAnim) {
2747
3260
  if (!newAnimate) newAnimate = __spreadValues2({}, animDef);
2748
- newAnimate[propName] = materialised;
3261
+ newAnimate[propName] = materialized;
2749
3262
  }
2750
3263
  }
2751
3264
  }
@@ -2764,7 +3277,7 @@ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2764
3277
  const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
2765
3278
  if (!staticParts || !Object.keys(staticParts).length) return animDef;
2766
3279
  const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues2(__spreadValues2({}, staticParts), v) : v;
2767
- const transformAnim = animDef["transform"];
3280
+ const transformAnim = animDef[TRANSFORM_ATTR];
2768
3281
  if (transformAnim && typeof transformAnim === "object") {
2769
3282
  const anim = transformAnim;
2770
3283
  if (Array.isArray(anim.keyframes)) {
@@ -2789,7 +3302,7 @@ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2789
3302
  delete rest[ch];
2790
3303
  return __spreadProps2(__spreadValues2({}, rest), { transform: lifted });
2791
3304
  }
2792
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
3305
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
2793
3306
  const normalized = {};
2794
3307
  for (const [propName, propAnim] of Object.entries(animDef)) {
2795
3308
  if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
@@ -2800,12 +3313,12 @@ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimat
2800
3313
  const out = { keyframes: normalizedKfs };
2801
3314
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2802
3315
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
2803
- normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
3316
+ normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materializeMotionPathInPropAnim(out) : out;
2804
3317
  }
2805
3318
  }
2806
3319
  return normalized;
2807
3320
  }
2808
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
3321
+ function getNormalizedBindings(doc, engine = PxTimelineEngine.native) {
2809
3322
  const animatorConfig = getAnimatorConfig(doc) || {};
2810
3323
  const defs = getDefs(doc);
2811
3324
  const duration = animatorConfig.duration || 1e3;
@@ -2851,12 +3364,12 @@ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2851
3364
  return bindings;
2852
3365
  }
2853
3366
  function getKeyframesPair(keyframes, progress) {
2854
- var _a, _b;
3367
+ var _a2, _b;
2855
3368
  const last = keyframes.length - 1;
2856
3369
  let prevKf = keyframes[0];
2857
3370
  let nextKf = keyframes[last > 0 ? 1 : 0];
2858
3371
  for (let j = 0; j < last; j++) {
2859
- const aOff = (_a = keyframes[j].t) != null ? _a : 0;
3372
+ const aOff = (_a2 = keyframes[j].t) != null ? _a2 : 0;
2860
3373
  const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
2861
3374
  if (aOff <= progress && progress <= bOff) {
2862
3375
  prevKf = keyframes[j];
@@ -2871,13 +3384,13 @@ function getKeyframesPair(keyframes, progress) {
2871
3384
  return { prevKf, nextKf };
2872
3385
  }
2873
3386
  function calcPropertyValue(propName, propAnim, progress) {
2874
- var _a, _b, _c, _d, _e, _f, _g;
3387
+ var _a2, _b, _c, _d;
2875
3388
  const keyframes = propAnim.keyframes || [];
2876
3389
  if (keyframes.length === 0) return null;
2877
3390
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
2878
- let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
3391
+ let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a2 = prevKf.t) != null ? _a2 : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
2879
3392
  localProgress = clamp(localProgress, 0, 1);
2880
- const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
3393
+ const easing = kfEasing(prevKf);
2881
3394
  if (easing && Array.isArray(easing)) {
2882
3395
  try {
2883
3396
  localProgress = cubicBezier(easing)(localProgress);
@@ -2886,17 +3399,17 @@ function calcPropertyValue(propName, propAnim, progress) {
2886
3399
  }
2887
3400
  let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2888
3401
  let cssValue = null;
2889
- const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
2890
- const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
3402
+ const prevV = prevKf == null ? void 0 : prevKf.v;
3403
+ const nextV = nextKf == null ? void 0 : nextKf.v;
2891
3404
  if (cssAttrName === "d") {
2892
- const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
2893
- const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
3405
+ const prevPaths = (_c = prevV == null ? void 0 : prevV.paths) != null ? _c : Array.isArray(prevV) ? prevV : [];
3406
+ const nextPaths = (_d = nextV == null ? void 0 : nextV.paths) != null ? _d : Array.isArray(nextV) ? nextV : [];
2894
3407
  cssValue = interpolateBeziers(
2895
3408
  prevPaths,
2896
3409
  nextPaths,
2897
3410
  localProgress
2898
3411
  ).map((bz) => bezierToSvgPath(bz)).join("");
2899
- } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
3412
+ } else if (COLOR_ATTR_NAMES.has(cssAttrName)) {
2900
3413
  cssValue = toRGBA(interpolateColor(
2901
3414
  prevV || [0, 0, 0, 1],
2902
3415
  nextV || [0, 0, 0, 1],
@@ -3002,13 +3515,13 @@ function deepClonePxNode(value) {
3002
3515
  function regenerateIdsAndRewriteRefs(root, genId3) {
3003
3516
  const oldToNew = /* @__PURE__ */ new Map();
3004
3517
  const walkAssign = (n) => {
3005
- var _a;
3518
+ var _a2;
3006
3519
  if (typeof n.id === "string") {
3007
3520
  const newId = genId3();
3008
3521
  oldToNew.set(n.id, newId);
3009
3522
  n.id = newId;
3010
3523
  }
3011
- (_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
3524
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
3012
3525
  };
3013
3526
  walkAssign(root);
3014
3527
  const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
@@ -3016,7 +3529,7 @@ function regenerateIdsAndRewriteRefs(root, genId3) {
3016
3529
  return newId ? "url(#" + newId + ")" : m;
3017
3530
  });
3018
3531
  const walkRewrite = (n) => {
3019
- var _a;
3532
+ var _a2;
3020
3533
  if (typeof n.href === "string" && n.href.startsWith("#")) {
3021
3534
  const newId = oldToNew.get(n.href.slice(1));
3022
3535
  if (newId) n.href = "#" + newId;
@@ -3028,7 +3541,7 @@ function regenerateIdsAndRewriteRefs(root, genId3) {
3028
3541
  n[k] = rewriteUrl(v);
3029
3542
  }
3030
3543
  }
3031
- (_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
3544
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
3032
3545
  };
3033
3546
  walkRewrite(root);
3034
3547
  return oldToNew;
@@ -3038,7 +3551,7 @@ function toFiniteNum(v) {
3038
3551
  return Number.isFinite(n) ? n : 0;
3039
3552
  }
3040
3553
  function applyUseOffsetToG(gNode) {
3041
- var _a;
3554
+ var _a2;
3042
3555
  const x = toFiniteNum(gNode.x);
3043
3556
  const y = toFiniteNum(gNode.y);
3044
3557
  delete gNode.x;
@@ -3047,15 +3560,15 @@ function applyUseOffsetToG(gNode) {
3047
3560
  const offset = "translate(" + x + "," + y + ")";
3048
3561
  const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
3049
3562
  if (carriesTransform) {
3050
- const inner = { type: "g", transform: offset, children: (_a = gNode.children) != null ? _a : [] };
3563
+ const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
3051
3564
  gNode.children = [inner];
3052
3565
  } else {
3053
3566
  gNode.transform = offset;
3054
3567
  }
3055
3568
  return gNode;
3056
3569
  }
3057
- function materialiseAnimatedUseInstances(root) {
3058
- var _a;
3570
+ function materializeAnimatedUseInstances(root) {
3571
+ var _a2;
3059
3572
  const idMap = buildIdMap(root);
3060
3573
  const animatedIds = computeAnimatedSubtreeIds(root, idMap);
3061
3574
  if (animatedIds.size === 0) return root;
@@ -3063,10 +3576,10 @@ function materialiseAnimatedUseInstances(root) {
3063
3576
  const genId3 = () => "_lw_use_mat_" + ++idCounter;
3064
3577
  const rootViewport = readRootViewport(root);
3065
3578
  const defsCollector = [];
3066
- const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
3579
+ const walked = walkAndMaterialize2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
3067
3580
  if (defsCollector.length === 0) return walked;
3068
3581
  const defsNode = { type: "defs", children: defsCollector };
3069
- const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
3582
+ const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
3070
3583
  return __spreadProps2(__spreadValues2({}, walked), { children: newChildren });
3071
3584
  }
3072
3585
  function readRootViewport(root) {
@@ -3088,9 +3601,9 @@ function numericAttr(v) {
3088
3601
  function buildIdMap(root) {
3089
3602
  const map = /* @__PURE__ */ new Map();
3090
3603
  const visit = (n) => {
3091
- var _a;
3604
+ var _a2;
3092
3605
  if (typeof n.id === "string") map.set(n.id, n);
3093
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
3606
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
3094
3607
  };
3095
3608
  visit(root);
3096
3609
  return map;
@@ -3136,16 +3649,16 @@ function stripHash(href) {
3136
3649
  if (typeof href !== "string") return void 0;
3137
3650
  return href.startsWith("#") ? href.slice(1) : href;
3138
3651
  }
3139
- function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3140
- var _a, _b, _c, _d;
3652
+ function materializeOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3653
+ var _a2, _b, _c, _d;
3141
3654
  const clone2 = deepClonePxNode(target);
3142
3655
  regenerateIdsAndRewriteRefs(clone2, genId3);
3143
3656
  const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
3144
- const useW = (_b = (_a = numericAttr(useNode.width)) != null ? _a : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3657
+ const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3145
3658
  const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
3146
3659
  const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
3147
- const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
3148
- const newNode = __spreadProps2(__spreadValues2({}, useNode), { type: "g", children: [materialisedClone] });
3660
+ const materializedClone = walkAndMaterialize2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
3661
+ const newNode = __spreadProps2(__spreadValues2({}, useNode), { type: "g", children: [materializedClone] });
3149
3662
  delete newNode.href;
3150
3663
  delete newNode.width;
3151
3664
  delete newNode.height;
@@ -3183,18 +3696,18 @@ function parseViewBox(v) {
3183
3696
  if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
3184
3697
  return [parts[0], parts[1], parts[2], parts[3]];
3185
3698
  }
3186
- function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3699
+ function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3187
3700
  if (node.type === "use" && typeof node.href === "string") {
3188
3701
  const targetId = stripHash(node.href);
3189
3702
  if (targetId && animatedIds.has(targetId)) {
3190
3703
  const target = idMap.get(targetId);
3191
- if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
3704
+ if (target) return materializeOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
3192
3705
  }
3193
3706
  }
3194
3707
  if (!node.children) return node;
3195
3708
  let changed = false;
3196
3709
  const newChildren = node.children.map((ch) => {
3197
- const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
3710
+ const m = walkAndMaterialize2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
3198
3711
  if (m !== ch) changed = true;
3199
3712
  return m;
3200
3713
  });
@@ -3210,7 +3723,7 @@ function partsRecord(part, value, origin) {
3210
3723
  return rec;
3211
3724
  }
3212
3725
  function readAnimatable(raw) {
3213
- var _a, _b, _c;
3726
+ var _a2, _b;
3214
3727
  if (raw === void 0) return {
3215
3728
  kind: "absent"
3216
3729
  /* Absent */
@@ -3218,20 +3731,20 @@ function readAnimatable(raw) {
3218
3731
  if (Array.isArray(raw)) return { kind: "static", value: raw };
3219
3732
  if (typeof raw === "object") {
3220
3733
  const obj = raw;
3221
- const kfs = (_a = obj.keyframes) != null ? _a : obj.kfs;
3734
+ const kfs = obj.keyframes;
3222
3735
  if (kfs) {
3223
- const out = { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
3224
- const base = (_b = obj.value) != null ? _b : obj.v;
3736
+ const out = { kind: "animated", keyframes: kfs.map(normalizeKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
3737
+ const base = (_a2 = obj.value) != null ? _a2 : obj.v;
3225
3738
  if (base !== void 0 && out.kind === "animated") out.base = base;
3226
3739
  return out;
3227
3740
  }
3228
- const staticValue = (_c = obj.value) != null ? _c : obj.v;
3741
+ const staticValue = (_b = obj.value) != null ? _b : obj.v;
3229
3742
  if (staticValue !== void 0) return { kind: "static", value: staticValue };
3230
3743
  }
3231
3744
  return { kind: "static", value: raw };
3232
3745
  }
3233
3746
  function writeAnimatableChannel(node, attrName, read, opts) {
3234
- var _a, _b, _c, _d;
3747
+ var _a2, _b, _c, _d;
3235
3748
  const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
3236
3749
  if (read.kind === "absent") return;
3237
3750
  if (read.kind === "static") {
@@ -3245,10 +3758,10 @@ function writeAnimatableChannel(node, attrName, read, opts) {
3245
3758
  if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
3246
3759
  animate[attrName] = block;
3247
3760
  node.animate = animate;
3248
- 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;
3761
+ 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;
3249
3762
  if (baseline !== void 0) node[attrName] = toOut(baseline);
3250
3763
  }
3251
- function normaliseKeyframe(kf) {
3764
+ function normalizeKeyframe(kf) {
3252
3765
  if (!kf || typeof kf !== "object") return kf;
3253
3766
  const k = kf;
3254
3767
  if (k.t === void 0 && k.v === void 0 && k.e === void 0 && k.to === void 0 && k.ti === void 0) {
@@ -3263,12 +3776,12 @@ function normaliseKeyframe(kf) {
3263
3776
  return out;
3264
3777
  }
3265
3778
  function readStaticOrigin(raw, ctx) {
3266
- var _a;
3779
+ var _a2;
3267
3780
  const o = readAnimatable(raw);
3268
3781
  if (o.kind === "absent") return void 0;
3269
3782
  if (o.kind === "static") return o.value;
3270
3783
  ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
3271
- return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
3784
+ return (_a2 = o.keyframes[0]) == null ? void 0 : _a2.value;
3272
3785
  }
3273
3786
  function keyframeWith(kf, value) {
3274
3787
  const out = { value };
@@ -3374,9 +3887,9 @@ function stripHash2(href) {
3374
3887
  return typeof href === "string" ? href.replace(/^#/, "") : void 0;
3375
3888
  }
3376
3889
  function indexById(node, map) {
3377
- var _a;
3890
+ var _a2;
3378
3891
  if (typeof node.id === "string") map.set(node.id, node);
3379
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
3892
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((child) => indexById(child, map));
3380
3893
  }
3381
3894
  function spliceDefs(root, defs) {
3382
3895
  if (!defs.length) return;
@@ -3388,9 +3901,9 @@ function regenerateIdsInClone(root, ctx) {
3388
3901
  return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
3389
3902
  }
3390
3903
  function identifyContentRefTargets(node, ctx, allocator) {
3391
- var _a, _b, _c;
3392
- if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
3393
- const sourceId = stripHash2(node.effects.clone.sourceId);
3904
+ var _a2, _b, _c;
3905
+ if (node.type === "use" && ((_b = (_a2 = node.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.without) === "translate") {
3906
+ const sourceId = stripHash2(node.effects.clone.source);
3394
3907
  if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
3395
3908
  ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
3396
3909
  }
@@ -3415,10 +3928,10 @@ function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
3415
3928
  return outerWrapper;
3416
3929
  }
3417
3930
  function liftBodyTranslate(node, transformBy) {
3418
- var _a, _b, _c;
3931
+ var _a2, _b, _c;
3419
3932
  const out = {};
3420
3933
  let didLiftAnimate = false;
3421
- const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
3934
+ const animTr = (_a2 = node.animate) == null ? void 0 : _a2.transform;
3422
3935
  if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
3423
3936
  const kfs = animTr.keyframes;
3424
3937
  const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
@@ -3634,7 +4147,7 @@ function synthesiseGradientDef(fx, id, ctx) {
3634
4147
  return out;
3635
4148
  }
3636
4149
  function applyGeomVec(out, xAttr, yAttr, raw) {
3637
- var _a, _b, _c;
4150
+ var _a2, _b, _c;
3638
4151
  const read = readAnimatable(raw);
3639
4152
  if (read.kind === "absent") return;
3640
4153
  if (read.kind === "static") {
@@ -3653,7 +4166,7 @@ function applyGeomVec(out, xAttr, yAttr, raw) {
3653
4166
  if (read.loop !== void 0) block.loop = read.loop;
3654
4167
  return block;
3655
4168
  };
3656
- const animate = (_a = out.animate) != null ? _a : {};
4169
+ const animate = (_a2 = out.animate) != null ? _a2 : {};
3657
4170
  animate[xAttr] = axisChannel(0);
3658
4171
  animate[yAttr] = axisChannel(1);
3659
4172
  out.animate = animate;
@@ -3669,7 +4182,7 @@ function applyGeomNumber(out, attrName, raw) {
3669
4182
  writeAnimatableChannel(out, attrName, read, { asString: true });
3670
4183
  }
3671
4184
  function buildStopChildren(stops, ctx) {
3672
- var _a, _b, _c, _d;
4185
+ var _a2, _b;
3673
4186
  if (!stops) return [];
3674
4187
  const read = readAnimatable(stops);
3675
4188
  if (read.kind === "absent") return [];
@@ -3679,14 +4192,14 @@ function buildStopChildren(stops, ctx) {
3679
4192
  const loopFromSource = read.loop;
3680
4193
  let stopCount = 0;
3681
4194
  for (const kf of kfs) {
3682
- const v = (_a = kf.value) != null ? _a : kf.v;
4195
+ const v = kfValue(kf);
3683
4196
  if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
3684
4197
  }
3685
4198
  if (!stopCount) return [];
3686
- const firstKfValue = (_b = kfs[0].value) != null ? _b : kfs[0].v;
4199
+ const firstKfValue = kfValue(kfs[0]);
3687
4200
  const baselineStops = [];
3688
4201
  for (let i = 0; i < stopCount; i++) {
3689
- 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" };
4202
+ 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" };
3690
4203
  baselineStops.push({ offset: s.offset, color: s.color });
3691
4204
  }
3692
4205
  return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
@@ -3699,16 +4212,16 @@ function staticStopNode(s) {
3699
4212
  };
3700
4213
  }
3701
4214
  function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3702
- var _a, _b, _c, _d, _e;
4215
+ var _a2;
3703
4216
  const colorKfs = [];
3704
4217
  const offsetKfs = [];
3705
4218
  let offsetVaries = false;
3706
4219
  for (const kf of kfs) {
3707
- const t = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
3708
- const arr = (_c = kf.value) != null ? _c : kf.v;
3709
- const sliced = (_d = arr == null ? void 0 : arr[stopIdx]) != null ? _d : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
4220
+ const t = kfTime(kf);
4221
+ const arr = kfValue(kf);
4222
+ const sliced = (_a2 = arr == null ? void 0 : arr[stopIdx]) != null ? _a2 : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
3710
4223
  if (!sliced) continue;
3711
- const easing = (_e = kf.easing) != null ? _e : kf.e;
4224
+ const easing = kfEasing(kf);
3712
4225
  const colorOut = { time: t, value: sliced.color };
3713
4226
  if (easing !== void 0) colorOut.easing = easing;
3714
4227
  colorKfs.push(colorOut);
@@ -3735,13 +4248,12 @@ function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3735
4248
  return stop;
3736
4249
  }
3737
4250
  function prevDefinedStop(kfs, fromIdx, stopIdx) {
3738
- var _a, _b;
3739
4251
  for (let i = fromIdx; i >= 0; i--) {
3740
- const arr = (_a = kfs[i].value) != null ? _a : kfs[i].v;
4252
+ const arr = kfValue(kfs[i]);
3741
4253
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
3742
4254
  }
3743
4255
  for (let i = fromIdx + 1; i < kfs.length; i++) {
3744
- const arr = (_b = kfs[i].value) != null ? _b : kfs[i].v;
4256
+ const arr = kfValue(kfs[i]);
3745
4257
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
3746
4258
  }
3747
4259
  return void 0;
@@ -3751,10 +4263,10 @@ function formatOffset(o) {
3751
4263
  return pct + "%";
3752
4264
  }
3753
4265
  function applyClipPathEffect(node, fx, ctx) {
3754
- if (!(fx == null ? void 0 : fx.d)) return node;
4266
+ if (!(fx == null ? void 0 : fx.pathData)) return node;
3755
4267
  const clipId = genId(ctx, "clip");
3756
4268
  const pathChild = { type: "path" };
3757
- const read = readAnimatable(fx.d);
4269
+ const read = readAnimatable(fx.pathData);
3758
4270
  if (read.kind !== "absent") {
3759
4271
  if (read.kind === "static") {
3760
4272
  pathChild.d = pathString(read.value);
@@ -3769,14 +4281,14 @@ function applyClipPathEffect(node, fx, ctx) {
3769
4281
  }
3770
4282
  function pathString(v) {
3771
4283
  if (typeof v === "string") return v;
3772
- if (v && typeof v === "object" && typeof v.path === "string") return v.path;
4284
+ if (v && typeof v === "object" && typeof v.pathData === "string") return v.pathData;
3773
4285
  return void 0;
3774
4286
  }
3775
4287
  function applyMaskedByEffect(node, fx, transformBy, ctx) {
3776
4288
  if (!fx) return node;
3777
- const sourceId = stripHash2(fx.sourceId);
4289
+ const sourceId = stripHash2(fx.source);
3778
4290
  if (!sourceId) {
3779
- ctx.errors.push("maskedBy.sourceId missing \u2014 cannot build mask");
4291
+ ctx.errors.push("maskedBy.source missing \u2014 cannot build mask");
3780
4292
  return node;
3781
4293
  }
3782
4294
  const maskId = genId(ctx, "mask");
@@ -3814,8 +4326,8 @@ function wrapInverseTransform(inner, fx, ctx) {
3814
4326
  }
3815
4327
  function wrapInversePart(inner, part, raw, origin, ctx) {
3816
4328
  if (raw === void 0) return inner;
3817
- const normalisedRaw = part === "scale" && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
3818
- const v = readAnimatable(normalisedRaw);
4329
+ const normalizedRaw = part === "scale" && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
4330
+ const v = readAnimatable(normalizedRaw);
3819
4331
  if (v.kind === "static") {
3820
4332
  return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
3821
4333
  }
@@ -3839,16 +4351,16 @@ function invertPartValue(part, value) {
3839
4351
  return [1 / value[0], 1 / value[1]];
3840
4352
  }
3841
4353
  function negatedSpatialTangents(kf) {
3842
- var _a, _b;
4354
+ var _a2, _b;
3843
4355
  const out = {};
3844
- const to = (_a = kf.tangentOut) != null ? _a : kf.to;
4356
+ const to = (_a2 = kf.tangentOut) != null ? _a2 : kf.to;
3845
4357
  const ti = (_b = kf.tangentIn) != null ? _b : kf.ti;
3846
4358
  if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];
3847
4359
  if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];
3848
4360
  return out;
3849
4361
  }
3850
4362
  function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
3851
- var _a;
4363
+ var _a2;
3852
4364
  const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
3853
4365
  const animTr = animate == null ? void 0 : animate.transform;
3854
4366
  const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
@@ -3857,7 +4369,7 @@ function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
3857
4369
  const rotateKfs = [];
3858
4370
  const scaleKfs = [];
3859
4371
  for (const kf of kfs) {
3860
- const v = ((_a = kf.value) != null ? _a : kf.v) || {};
4372
+ const v = ((_a2 = kf.value) != null ? _a2 : kf.v) || {};
3861
4373
  const baseKf = keyframeWith(kf, void 0);
3862
4374
  if (Array.isArray(v.translate)) {
3863
4375
  translateKfs.push(__spreadProps2(__spreadValues2(__spreadValues2({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
@@ -3921,7 +4433,7 @@ function readTransformationFromBody(node) {
3921
4433
  return void 0;
3922
4434
  }
3923
4435
  function parseTransformStringToParts(s) {
3924
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
4436
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
3925
4437
  const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
3926
4438
  let m;
3927
4439
  const ops = [];
@@ -3935,7 +4447,7 @@ function parseTransformStringToParts(s) {
3935
4447
  for (let j = ops.length - 2; j >= 0; j--) {
3936
4448
  const cand = ops[j];
3937
4449
  if (cand.name !== "translate") continue;
3938
- const ox = (_a = cand.args[0]) != null ? _a : 0;
4450
+ const ox = (_a2 = cand.args[0]) != null ? _a2 : 0;
3939
4451
  const oy = (_b = cand.args[1]) != null ? _b : 0;
3940
4452
  const lx = (_c = last.args[0]) != null ? _c : 0;
3941
4453
  const ly = (_d = last.args[1]) != null ? _d : 0;
@@ -4050,8 +4562,8 @@ function interpKfs(kfs, t) {
4050
4562
  function collectMaskAncestorChains(root, ctx) {
4051
4563
  const interestingNodes = /* @__PURE__ */ new Set();
4052
4564
  const collectInterestingNodes = (n) => {
4053
- var _a, _b;
4054
- const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.sourceId);
4565
+ var _a2, _b;
4566
+ const maskSourceId = stripHash2((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
4055
4567
  if (typeof maskSourceId === "string") {
4056
4568
  interestingNodes.add(n);
4057
4569
  const sourceNode = ctx.idMap.get(maskSourceId);
@@ -4072,7 +4584,7 @@ function collectMaskAncestorChains(root, ctx) {
4072
4584
  walk(root, []);
4073
4585
  }
4074
4586
  function extractTranslateOnly(node, ctx) {
4075
- var _a, _b, _c;
4587
+ var _a2, _b, _c;
4076
4588
  const tr = node.transform;
4077
4589
  const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
4078
4590
  if (tr === void 0 && !animateBlock) return void 0;
@@ -4080,7 +4592,7 @@ function extractTranslateOnly(node, ctx) {
4080
4592
  if (typeof tr === "string") {
4081
4593
  const parts = parseTranslateOnlyFromString(tr, ctx);
4082
4594
  if (parts) out.translate = parts;
4083
- } else if (tr && typeof tr === "object" && !tr.keyframes && !tr.kfs) {
4595
+ } else if (tr && typeof tr === "object" && !tr.keyframes) {
4084
4596
  const wrapped = tr.value;
4085
4597
  const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
4086
4598
  if (value && typeof value === "object" && Array.isArray(value.translate)) {
@@ -4094,7 +4606,7 @@ function extractTranslateOnly(node, ctx) {
4094
4606
  const kfs = animateBlock.keyframes;
4095
4607
  const translateKfs = [];
4096
4608
  for (const kf of kfs) {
4097
- const v = (_a = kf.value) != null ? _a : kf.v;
4609
+ const v = (_a2 = kf.value) != null ? _a2 : kf.v;
4098
4610
  const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
4099
4611
  if (v && typeof v === "object" && Array.isArray(v.translate)) {
4100
4612
  translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
@@ -4127,15 +4639,14 @@ function parseTranslateOnlyFromString(s, ctx) {
4127
4639
  if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
4128
4640
  return seen ? [x, y] : void 0;
4129
4641
  }
4130
- var CONTENT_SUBREF = "content";
4131
4642
  function applyRefHref(node, clone2, ctx) {
4132
4643
  if (!clone2) return;
4133
- const sourceId = stripHash2(clone2.sourceId);
4644
+ const sourceId = stripHash2(clone2.source);
4134
4645
  if (!sourceId) {
4135
- if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing sourceId");
4646
+ if (clone2.without === PxCloneWithout.translate) ctx.errors.push("clone: content ref missing `source`");
4136
4647
  return;
4137
4648
  }
4138
- const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
4649
+ const targetId = clone2.without === PxCloneWithout.translate ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
4139
4650
  node.href = "#" + targetId;
4140
4651
  }
4141
4652
  function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
@@ -4143,9 +4654,9 @@ function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
4143
4654
  return applyTransformByEffect(node, transformBy, ctx);
4144
4655
  }
4145
4656
  function applyRepeaterEffect(node, fx, ctx) {
4146
- var _a, _b;
4657
+ var _a2, _b;
4147
4658
  if (!fx) return node;
4148
- const copies = (_a = fx.copies) != null ? _a : 1;
4659
+ const copies = (_a2 = fx.copies) != null ? _a2 : 1;
4149
4660
  if (copies < 1) {
4150
4661
  ctx.errors.push("repeater.copies invalid: " + fx.copies);
4151
4662
  return node;
@@ -4211,10 +4722,10 @@ function synthesiseScale(raw, i) {
4211
4722
  const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
4212
4723
  return mapAnimatable(raw, scalePower, true);
4213
4724
  }
4214
- var RETIME_MATERIALISATION_MODE_INLINE_G = false;
4725
+ var RETIME_MATERIALIZATION_MODE_INLINE_G = false;
4215
4726
  function asRetime(r) {
4216
- var _a, _b;
4217
- return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
4727
+ var _a2, _b;
4728
+ return { start: (_a2 = r.start) != null ? _a2 : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
4218
4729
  }
4219
4730
  var CROP_EDGE_MS = 1;
4220
4731
  function applyTimeCrop(useNode, crop, ctx) {
@@ -4242,12 +4753,12 @@ function concatRetime(child, parent) {
4242
4753
  };
4243
4754
  }
4244
4755
  function readCloneRetime(n) {
4245
- var _a, _b;
4246
- return (_b = (_a = n.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.retime;
4756
+ var _a2, _b;
4757
+ return (_b = (_a2 = n.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.retime;
4247
4758
  }
4248
4759
  function clearCloneRetime(n) {
4249
- var _a;
4250
- const clone2 = (_a = n.effects) == null ? void 0 : _a.clone;
4760
+ var _a2;
4761
+ const clone2 = (_a2 = n.effects) == null ? void 0 : _a2.clone;
4251
4762
  if (!clone2) return;
4252
4763
  delete clone2.retime;
4253
4764
  if (Object.keys(clone2).length === 0) delete n.effects.clone;
@@ -4258,9 +4769,9 @@ function applyAllRetimeEffects(root, ctx) {
4258
4769
  indexById(root, ctx.idMap);
4259
4770
  const sites = [];
4260
4771
  const collect = (n) => {
4261
- var _a;
4772
+ var _a2;
4262
4773
  if (readCloneRetime(n)) sites.push(n);
4263
- (_a = n.children) == null ? void 0 : _a.forEach(collect);
4774
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(collect);
4264
4775
  };
4265
4776
  collect(root);
4266
4777
  const reachCount = /* @__PURE__ */ new Map();
@@ -4268,7 +4779,7 @@ function applyAllRetimeEffects(root, ctx) {
4268
4779
  let count = 0;
4269
4780
  const visited = /* @__PURE__ */ new Set();
4270
4781
  const walk = (n) => {
4271
- var _a;
4782
+ var _a2;
4272
4783
  if (!n) return;
4273
4784
  if (n !== site && readCloneRetime(n)) count++;
4274
4785
  if (n.type === "use" && n.href) {
@@ -4278,7 +4789,7 @@ function applyAllRetimeEffects(root, ctx) {
4278
4789
  walk(ctx.idMap.get(id));
4279
4790
  }
4280
4791
  }
4281
- (_a = n.children) == null ? void 0 : _a.forEach(walk);
4792
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walk);
4282
4793
  };
4283
4794
  const rootId = stripHash2(site.href);
4284
4795
  if (rootId) {
@@ -4288,19 +4799,19 @@ function applyAllRetimeEffects(root, ctx) {
4288
4799
  reachCount.set(site, count);
4289
4800
  }
4290
4801
  sites.sort((a, b) => {
4291
- var _a, _b;
4292
- return ((_a = reachCount.get(b)) != null ? _a : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4802
+ var _a2, _b;
4803
+ return ((_a2 = reachCount.get(b)) != null ? _a2 : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4293
4804
  });
4294
4805
  for (const useNode of sites) {
4295
4806
  const retime = readCloneRetime(useNode);
4296
4807
  if (!retime) continue;
4297
4808
  const crop = retime.timeCrop;
4298
4809
  clearCloneRetime(useNode);
4299
- materialiseRetime(useNode, asRetime(retime), ctx);
4810
+ materializeRetime(useNode, asRetime(retime), ctx);
4300
4811
  if (crop) applyTimeCrop(useNode, crop, ctx);
4301
4812
  }
4302
4813
  }
4303
- function materialiseRetime(useNode, retime, ctx) {
4814
+ function materializeRetime(useNode, retime, ctx) {
4304
4815
  const targetId = stripHash2(useNode.href);
4305
4816
  if (!targetId) {
4306
4817
  ctx.errors.push("retime: <use> has no href to follow");
@@ -4308,7 +4819,7 @@ function materialiseRetime(useNode, retime, ctx) {
4308
4819
  }
4309
4820
  const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
4310
4821
  if (!chainRootId) return;
4311
- if (RETIME_MATERIALISATION_MODE_INLINE_G) {
4822
+ if (RETIME_MATERIALIZATION_MODE_INLINE_G) {
4312
4823
  const cloneNode = ctx.idMap.get(chainRootId);
4313
4824
  useNode.type = "g";
4314
4825
  delete useNode.href;
@@ -4348,15 +4859,15 @@ function buildChainClone(targetId, accum, ctx, chain) {
4348
4859
  if (subId2) cloneNode.href = "#" + subId2;
4349
4860
  }
4350
4861
  } else {
4351
- materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
4862
+ materializeNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
4352
4863
  }
4353
4864
  ctx.defs.push(cloneNode);
4354
4865
  if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
4355
4866
  return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
4356
4867
  }
4357
- function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4868
+ function materializeNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4358
4869
  const visit = (n) => {
4359
- var _a;
4870
+ var _a2;
4360
4871
  const retime = readCloneRetime(n);
4361
4872
  if (n.type === "use" && retime && n.href) {
4362
4873
  const subId = stripHash2(n.href);
@@ -4369,14 +4880,14 @@ function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4369
4880
  }
4370
4881
  clearCloneRetime(n);
4371
4882
  }
4372
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
4883
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
4373
4884
  };
4374
4885
  visit(node);
4375
4886
  }
4376
4887
  function remapKeyframeTimes(node, start, stretch) {
4377
- var _a;
4888
+ var _a2;
4378
4889
  remapKeyframeTimesOnly(node, start, stretch);
4379
- (_a = node.children) == null ? void 0 : _a.forEach((c) => remapKeyframeTimes(c, start, stretch));
4890
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => remapKeyframeTimes(c, start, stretch));
4380
4891
  }
4381
4892
  function remapKeyframeTimesOnly(node, start, stretch) {
4382
4893
  const remap2 = (kfs) => {
@@ -4551,10 +5062,10 @@ function numRange(v) {
4551
5062
  function estimateTextAdvance(node) {
4552
5063
  let chars = 0, maxFont = 16;
4553
5064
  const walk = (el) => {
4554
- var _a, _b;
4555
- const fs = parseFloat(String((_a = el.fontSize) != null ? _a : "")) || 0;
5065
+ var _a2;
5066
+ const fs = parseFloat(String((_a2 = el.fontSize) != null ? _a2 : "")) || 0;
4556
5067
  if (fs) maxFont = Math.max(maxFont, fs);
4557
- const t = (_b = el.text) != null ? _b : el.textContent;
5068
+ const t = el.textContent;
4558
5069
  if (typeof t === "string") chars += t.length;
4559
5070
  if (el.children) for (const c of el.children) walk(c);
4560
5071
  };
@@ -4576,14 +5087,14 @@ function shiftAnimatable(v, by) {
4576
5087
  return out;
4577
5088
  }
4578
5089
  function extendedPathForBrowser(pathD, opts) {
4579
- var _a;
5090
+ var _a2;
4580
5091
  if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
4581
5092
  const sampler = createPathSampler(pathD);
4582
5093
  if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
4583
5094
  const L = sampler.totalLength;
4584
5095
  const margin = EXTEND_MARGIN_FRAC * L;
4585
5096
  const so = numRange(opts.startOffset);
4586
- const runWidth = numRange(opts.textLength).max || ((_a = opts.advance) != null ? _a : 0);
5097
+ const runWidth = numRange(opts.textLength).max || ((_a2 = opts.advance) != null ? _a2 : 0);
4587
5098
  const startOverflow = Math.max(0, -so.min);
4588
5099
  const endOverflow = Math.max(0, so.max + runWidth - L);
4589
5100
  const startExt = startOverflow > 0 ? startOverflow + margin : 0;
@@ -4604,10 +5115,10 @@ function extendedPathForBrowser(pathD, opts) {
4604
5115
  return { d, startShift: startExt };
4605
5116
  }
4606
5117
  function applyTextPathEffect(node, fx, ctx) {
4607
- var _a;
4608
- if (!fx || typeof fx.path !== "string" || !fx.path) return node;
5118
+ var _a2;
5119
+ if (!fx || typeof fx.pathData !== "string" || !fx.pathData) return node;
4609
5120
  const pathId = genId(ctx, "tpath");
4610
- const { d, startShift } = extendedPathForBrowser(fx.path, {
5121
+ const { d, startShift } = extendedPathForBrowser(fx.pathData, {
4611
5122
  pathOverflow: fx.pathOverflow,
4612
5123
  startOffset: fx.startOffset,
4613
5124
  textLength: fx.textLength,
@@ -4617,7 +5128,7 @@ function applyTextPathEffect(node, fx, ctx) {
4617
5128
  const textPath = {
4618
5129
  type: "textPath",
4619
5130
  href: "#" + pathId,
4620
- children: (_a = node.children) != null ? _a : []
5131
+ children: (_a2 = node.children) != null ? _a2 : []
4621
5132
  };
4622
5133
  if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
4623
5134
  if (fx.method !== void 0) textPath.method = fx.method;
@@ -4703,7 +5214,6 @@ var TEXT_ATTR_KEYS = [
4703
5214
  "stroke",
4704
5215
  "strokeWidth",
4705
5216
  "effects",
4706
- TEXT_ATTR,
4707
5217
  TEXT_CONTENT_ATTR,
4708
5218
  "xml:space"
4709
5219
  ];
@@ -4741,15 +5251,15 @@ function paintAnimateOf(node) {
4741
5251
  return out;
4742
5252
  }
4743
5253
  function resolveStyle2(node, parent) {
4744
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5254
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4745
5255
  const isTextRoot = node.type === "text";
4746
5256
  const nodeStyle = node.style;
4747
5257
  const own = (key) => {
4748
- var _a2;
4749
- return isTextRoot ? void 0 : (_a2 = node[key]) != null ? _a2 : nodeStyle == null ? void 0 : nodeStyle[key];
5258
+ var _a3;
5259
+ return isTextRoot ? void 0 : (_a3 = node[key]) != null ? _a3 : nodeStyle == null ? void 0 : nodeStyle[key];
4750
5260
  };
4751
5261
  const res = {
4752
- fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
5262
+ fontFamily: (_a2 = str(node.fontFamily)) != null ? _a2 : parent.fontFamily,
4753
5263
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
4754
5264
  fill: (_c = node.fill) != null ? _c : parent.fill,
4755
5265
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
@@ -4766,10 +5276,10 @@ function resolveStyle2(node, parent) {
4766
5276
  return res;
4767
5277
  }
4768
5278
  function rootStyleOf(node) {
4769
- var _a, _b, _c;
5279
+ var _a2, _b, _c;
4770
5280
  return {
4771
5281
  fontFamily: str(node.fontFamily),
4772
- fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
5282
+ fontSize: (_a2 = parseLen(node.fontSize)) != null ? _a2 : DEFAULT_FONT_SIZE,
4773
5283
  fill: node.fill,
4774
5284
  stroke: node.stroke,
4775
5285
  strokeWidth: node.strokeWidth,
@@ -4790,9 +5300,9 @@ function paintOf(s) {
4790
5300
  return p;
4791
5301
  }
4792
5302
  function glyphFontFor(s, glyphs, soleFont, warnings) {
4793
- var _a;
5303
+ var _a2;
4794
5304
  const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
4795
- if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
5305
+ if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a2 = s.fontFamily) != null ? _a2 : "") + '"');
4796
5306
  return gf;
4797
5307
  }
4798
5308
  function soleFontOf(glyphs) {
@@ -4813,26 +5323,26 @@ function missingGlyphBoxEm(advanceEm, ascentEm) {
4813
5323
  const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;
4814
5324
  return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
4815
5325
  }
4816
- function materialiseGlyphTextHorizontal(node, opts) {
4817
- var _a, _b, _c, _d;
5326
+ function materializeGlyphTextHorizontal(node, opts) {
5327
+ var _a2, _b, _c;
4818
5328
  const { glyphs, create = jsonElementFactory, warnings } = opts;
4819
5329
  const soleFont = soleFontOf(glyphs);
4820
- const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
5330
+ const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4821
5331
  const placements = [];
4822
5332
  const lines = [{ start: pen.x, end: pen.x }];
4823
5333
  let line = 0;
4824
5334
  const renderChars = (content, s) => {
4825
- var _a2;
5335
+ var _a3;
4826
5336
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4827
5337
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4828
5338
  const scale = s.fontSize / upm;
4829
- const ascentEm = (_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm;
5339
+ const ascentEm = (_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm;
4830
5340
  const paint = paintOf(s);
4831
5341
  for (let i = 0; i < content.length; i++) {
4832
5342
  const ch = content.charAt(i);
4833
5343
  const g = gf == null ? void 0 : gf.glyphs[ch];
4834
- if (g && g.d) {
4835
- placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
5344
+ if (g && g.pathData) {
5345
+ placements.push({ glyphD: g.pathData, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
4836
5346
  pen.x += g.width * scale;
4837
5347
  } else if (/\S/.test(ch)) {
4838
5348
  const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
@@ -4846,7 +5356,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4846
5356
  }
4847
5357
  };
4848
5358
  const walk = (el, parentStyle) => {
4849
- var _a2, _b2, _c2, _d2;
5359
+ var _a3, _b2, _c2;
4850
5360
  const s = resolveStyle2(el, parentStyle);
4851
5361
  const x = parseLen(el.x);
4852
5362
  const y = parseLen(el.y);
@@ -4856,16 +5366,16 @@ function materialiseGlyphTextHorizontal(node, opts) {
4856
5366
  lines.push({ start: pen.x, end: pen.x });
4857
5367
  }
4858
5368
  if (y !== void 0) pen.y = y;
4859
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
5369
+ pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4860
5370
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4861
- const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4862
- if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
5371
+ const content = str(el[TEXT_CONTENT_ATTR]);
5372
+ if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
4863
5373
  if (el.children) for (const ch of el.children) walk(ch, s);
4864
5374
  };
4865
5375
  const rootStyle = rootStyleOf(node);
4866
5376
  if (node.children) for (const ch of node.children) walk(ch, rootStyle);
4867
- const rootContent = (_c = str(node[TEXT_CONTENT_ATTR])) != null ? _c : str(node[TEXT_ATTR]);
4868
- if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
5377
+ const rootContent = str(node[TEXT_CONTENT_ATTR]);
5378
+ if (rootContent && !((_c = node.children) == null ? void 0 : _c.length)) renderChars(rootContent, rootStyle);
4869
5379
  const anchor = str(node.textAnchor);
4870
5380
  if (anchor === "middle" || anchor === "end") {
4871
5381
  for (const p of placements) {
@@ -4877,8 +5387,8 @@ function materialiseGlyphTextHorizontal(node, opts) {
4877
5387
  return toGroup(node, buildPaths(placements, create, warnings), create);
4878
5388
  }
4879
5389
  function layoutGlyphTextChars(node, opts) {
4880
- var _a, _b, _c, _d, _e, _f;
4881
- if ((_a = opts.alongPath) == null ? void 0 : _a.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
5390
+ var _a2, _b, _c, _d, _e;
5391
+ if ((_a2 = opts.alongPath) == null ? void 0 : _a2.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
4882
5392
  const { glyphs, warnings } = opts;
4883
5393
  const soleFont = soleFontOf(glyphs);
4884
5394
  const pen = { x: (_b = parseLen(node.x)) != null ? _b : 0, y: (_c = parseLen(node.y)) != null ? _c : 0 };
@@ -4886,11 +5396,11 @@ function layoutGlyphTextChars(node, opts) {
4886
5396
  const lines = [{ start: pen.x, end: pen.x }];
4887
5397
  let line = 0;
4888
5398
  const renderChars = (content, s) => {
4889
- var _a2;
5399
+ var _a3;
4890
5400
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4891
5401
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4892
5402
  const scale = s.fontSize / upm;
4893
- const ascent = ((_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm) * scale;
5403
+ const ascent = ((_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm) * scale;
4894
5404
  for (let i = 0; i < content.length; i++) {
4895
5405
  const ch = content.charAt(i);
4896
5406
  const g = gf == null ? void 0 : gf.glyphs[ch];
@@ -4901,7 +5411,7 @@ function layoutGlyphTextChars(node, opts) {
4901
5411
  }
4902
5412
  };
4903
5413
  const walk = (el, parentStyle) => {
4904
- var _a2, _b2, _c2, _d2;
5414
+ var _a3, _b2, _c2;
4905
5415
  const s = resolveStyle2(el, parentStyle);
4906
5416
  const x = parseLen(el.x);
4907
5417
  const y = parseLen(el.y);
@@ -4911,10 +5421,10 @@ function layoutGlyphTextChars(node, opts) {
4911
5421
  lines.push({ start: pen.x, end: pen.x });
4912
5422
  }
4913
5423
  if (y !== void 0) pen.y = y;
4914
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
5424
+ pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4915
5425
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4916
- const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4917
- if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
5426
+ const content = str(el[TEXT_CONTENT_ATTR]);
5427
+ if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
4918
5428
  if (el.children) for (const ch of el.children) walk(ch, s);
4919
5429
  };
4920
5430
  const rootStyle = rootStyleOf(node);
@@ -4928,8 +5438,8 @@ function layoutGlyphTextChars(node, opts) {
4928
5438
  boxes.push({ x: pen.x, y: pen.y, width: 0, ascent: ((_d = gf == null ? void 0 : gf.ascent) != null ? _d : 0.9 * upm) * (s.fontSize / upm), fontSize: s.fontSize, line });
4929
5439
  }
4930
5440
  }
4931
- const rootContent = (_e = str(node[TEXT_CONTENT_ATTR])) != null ? _e : str(node[TEXT_ATTR]);
4932
- if (rootContent && !((_f = node.children) == null ? void 0 : _f.length)) renderChars(rootContent, rootStyle);
5441
+ const rootContent = str(node[TEXT_CONTENT_ATTR]);
5442
+ if (rootContent && !((_e = node.children) == null ? void 0 : _e.length)) renderChars(rootContent, rootStyle);
4933
5443
  const anchor = str(node.textAnchor);
4934
5444
  if (anchor === "middle" || anchor === "end") {
4935
5445
  for (const b of boxes) {
@@ -4937,13 +5447,13 @@ function layoutGlyphTextChars(node, opts) {
4937
5447
  b.x += anchor === "middle" ? -w / 2 : -w;
4938
5448
  }
4939
5449
  }
4940
- return boxes.map((_g) => {
4941
- var _h = _g, { line: _l } = _h, b = __objRest2(_h, ["line"]);
5450
+ return boxes.map((_f) => {
5451
+ var _g = _f, { line: _l } = _g, b = __objRest2(_g, ["line"]);
4942
5452
  return b;
4943
5453
  });
4944
5454
  }
4945
5455
  function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4946
- var _a, _b;
5456
+ var _a2, _b;
4947
5457
  const { glyphs, warnings, alongPath } = opts;
4948
5458
  const sampler = createPathSampler(pathD);
4949
5459
  if (!sampler) {
@@ -4954,14 +5464,14 @@ function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4954
5464
  const chars = [];
4955
5465
  let adv = 0;
4956
5466
  const walk = (el, parentStyle) => {
4957
- var _a2, _b2, _c;
5467
+ var _a3, _b2;
4958
5468
  const s = resolveStyle2(el, parentStyle);
4959
- const content = (_a2 = str(el[TEXT_CONTENT_ATTR])) != null ? _a2 : str(el[TEXT_ATTR]);
4960
- if (content && !((_b2 = el.children) == null ? void 0 : _b2.length)) {
5469
+ const content = str(el[TEXT_CONTENT_ATTR]);
5470
+ if (content && !((_a3 = el.children) == null ? void 0 : _a3.length)) {
4961
5471
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4962
5472
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4963
5473
  const scale = s.fontSize / upm;
4964
- const ascent = ((_c = gf == null ? void 0 : gf.ascent) != null ? _c : 0.9 * upm) * scale;
5474
+ const ascent = ((_b2 = gf == null ? void 0 : gf.ascent) != null ? _b2 : 0.9 * upm) * scale;
4965
5475
  for (let i = 0; i < content.length; i++) {
4966
5476
  const ch = content.charAt(i);
4967
5477
  const g = gf == null ? void 0 : gf.glyphs[ch];
@@ -4976,7 +5486,7 @@ function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4976
5486
  walk(node, rootStyleOf(node));
4977
5487
  const width = adv;
4978
5488
  const tlr = readAnimatable(alongPath == null ? void 0 : alongPath.textLength);
4979
- const tlv = tlr.kind === "animated" ? Number((_a = tlr.keyframes[0]) == null ? void 0 : _a.value) || 0 : tlr.kind === "static" ? Number(tlr.value) || 0 : 0;
5489
+ const tlv = tlr.kind === "animated" ? Number((_a2 = tlr.keyframes[0]) == null ? void 0 : _a2.value) || 0 : tlr.kind === "static" ? Number(tlr.value) || 0 : 0;
4980
5490
  const k = tlv > 0 && width > 0 ? tlv / width : 1;
4981
5491
  const so = readAnimatable(alongPath == null ? void 0 : alongPath.startOffset);
4982
5492
  const { along: alongOffset, perp } = alongPathNodeOffsets(node);
@@ -5008,21 +5518,21 @@ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
5008
5518
  const cells = [];
5009
5519
  let adv = 0;
5010
5520
  const walk = (el, parentStyle) => {
5011
- var _a, _b, _c;
5521
+ var _a2, _b;
5012
5522
  const s = resolveStyle2(el, parentStyle);
5013
- const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
5014
- if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
5523
+ const content = str(el[TEXT_CONTENT_ATTR]);
5524
+ if (content && !((_a2 = el.children) == null ? void 0 : _a2.length)) {
5015
5525
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
5016
5526
  if (gf) {
5017
5527
  const scale = s.fontSize / gf.unitsPerEm;
5018
- const ascentEm = (_c = gf.ascent) != null ? _c : 0.9 * gf.unitsPerEm;
5528
+ const ascentEm = (_b = gf.ascent) != null ? _b : 0.9 * gf.unitsPerEm;
5019
5529
  const paint = paintOf(s);
5020
5530
  for (let i = 0; i < content.length; i++) {
5021
5531
  const ch = content.charAt(i);
5022
5532
  const g = gf.glyphs[ch];
5023
- if (g && g.d) {
5533
+ if (g && g.pathData) {
5024
5534
  const glyphAdv = g.width * scale;
5025
- cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
5535
+ cells.push({ glyphD: g.pathData, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
5026
5536
  adv += glyphAdv;
5027
5537
  } else if (/\S/.test(ch)) {
5028
5538
  const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
@@ -5047,13 +5557,13 @@ function alongAffine(sampler, dist, scale, widthEm, perp = 0) {
5047
5557
  return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];
5048
5558
  }
5049
5559
  function alongPathNodeOffsets(node) {
5050
- var _a, _b, _c;
5560
+ var _a2, _b, _c;
5051
5561
  return {
5052
- along: ((_a = parseLen(node.x)) != null ? _a : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
5562
+ along: ((_a2 = parseLen(node.x)) != null ? _a2 : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
5053
5563
  perp: (_c = parseLen(node.dy)) != null ? _c : 0
5054
5564
  };
5055
5565
  }
5056
- function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
5566
+ function materializeGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
5057
5567
  const { glyphs, create = jsonElementFactory, warnings } = opts;
5058
5568
  const sampler = pathD ? createPathSampler(pathD) : null;
5059
5569
  if (!sampler) {
@@ -5089,7 +5599,7 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
5089
5599
  return toGroup(node, buildPaths(placements, create, warnings), create);
5090
5600
  }
5091
5601
  function numTrackOf(raw) {
5092
- var _a;
5602
+ var _a2;
5093
5603
  const r = readAnimatable(raw);
5094
5604
  if (r.kind === "animated" && r.keyframes.length >= 2) {
5095
5605
  const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));
@@ -5112,7 +5622,7 @@ function numTrackOf(raw) {
5112
5622
  }
5113
5623
  };
5114
5624
  }
5115
- const v = r.kind === "animated" ? Number((_a = r.keyframes[0]) == null ? void 0 : _a.value) || 0 : r.kind === "static" ? Number(r.value) || 0 : 0;
5625
+ const v = r.kind === "animated" ? Number((_a2 = r.keyframes[0]) == null ? void 0 : _a2.value) || 0 : r.kind === "static" ? Number(r.value) || 0 : 0;
5116
5626
  return { animated: false, times: [], at: () => v };
5117
5627
  }
5118
5628
  function mergeTrackTimes(a, b) {
@@ -5132,8 +5642,8 @@ function buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isC
5132
5642
  const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
5133
5643
  const out = [];
5134
5644
  for (const c of cells) {
5135
- const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
5136
- const d = transformPathData(c.glyphD, centred);
5645
+ const centered = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
5646
+ const d = transformPathData(c.glyphD, centered);
5137
5647
  const sampleKf = (dist, time) => {
5138
5648
  const { x, y, angle } = sampler.sampleAtDistance(dist);
5139
5649
  const cos = Math.cos(angle), sin = Math.sin(angle);
@@ -5194,7 +5704,7 @@ function paintProps(paint) {
5194
5704
  return p;
5195
5705
  }
5196
5706
  function missingGlyphProps(isMissing) {
5197
- return isMissing ? { class: MISSING_GLYPH_CLASS_NAME } : {};
5707
+ return isMissing ? { [CLASS_ATTR]: MISSING_GLYPH_CLASS_NAME } : {};
5198
5708
  }
5199
5709
  function buildPaths(placements, create, warnings) {
5200
5710
  if (!placements.length) {
@@ -5231,24 +5741,24 @@ function toGroup(node, children, create) {
5231
5741
  }
5232
5742
  return create("g", gProps, children);
5233
5743
  }
5234
- function materialiseGlyphText(node, opts) {
5235
- if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
5236
- return materialiseGlyphTextHorizontal(node, opts);
5744
+ function materializeGlyphText(node, opts) {
5745
+ if (opts.alongPath) return materializeGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
5746
+ return materializeGlyphTextHorizontal(node, opts);
5237
5747
  }
5238
5748
  function applyTextGlyphsEffect(node, fx, ctx) {
5239
5749
  if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
5240
5750
  if (!ctx.glyphs) {
5241
- ctx.warnings.push("textGlyphs: no definitions.glyphs \u2014 left as native <text>");
5751
+ ctx.warnings.push("textGlyphs: no definitions.fonts \u2014 left as native <text>");
5242
5752
  return node;
5243
5753
  }
5244
- return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
5754
+ return materializeGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
5245
5755
  }
5246
5756
  function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
5247
5757
  if (!ctx.glyphs) {
5248
- ctx.warnings.push("textGlyphs: no definitions.glyphs");
5758
+ ctx.warnings.push("textGlyphs: no definitions.fonts");
5249
5759
  return null;
5250
5760
  }
5251
- return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
5761
+ return materializeGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
5252
5762
  }
5253
5763
  function applyStrokeTrimEffect(node, strokeTrim, ctx) {
5254
5764
  if (!strokeTrim) return node;
@@ -5385,12 +5895,11 @@ function getOffsetIndexRange(minMaxOffset) {
5385
5895
  ];
5386
5896
  }
5387
5897
  function readScalarValues(r) {
5388
- var _a;
5389
5898
  if (r.kind === "absent") return [];
5390
5899
  if (r.kind === "static") return [r.value];
5391
5900
  const out = [];
5392
5901
  for (const kf of r.keyframes) {
5393
- const v = (_a = kf.value) != null ? _a : kf.v;
5902
+ const v = kfValue(kf);
5394
5903
  if (typeof v === "number") out.push(v);
5395
5904
  }
5396
5905
  return out;
@@ -5400,14 +5909,11 @@ function computeAnimAttr(read, map) {
5400
5909
  if (read.kind === "static") return { kind: "static", value: map(read.value) };
5401
5910
  return {
5402
5911
  kind: "animated",
5403
- keyframes: read.keyframes.map((kf) => {
5404
- var _a, _b, _c, _d;
5405
- return {
5406
- time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
5407
- value: map((_c = kf.value) != null ? _c : kf.v),
5408
- easing: (_d = kf.easing) != null ? _d : kf.e
5409
- };
5410
- }),
5912
+ keyframes: read.keyframes.map((kf) => ({
5913
+ time: kfTime(kf),
5914
+ value: map(kfValue(kf)),
5915
+ easing: kfEasing(kf)
5916
+ })),
5411
5917
  loop: read.loop
5412
5918
  };
5413
5919
  }
@@ -5417,7 +5923,6 @@ function applyAttr(node, attrName, attr) {
5417
5923
  }
5418
5924
  var OPACITY_STEP_MS = 10;
5419
5925
  function computeOpacityFromRange(rangeRead) {
5420
- var _a, _b, _c, _d, _e, _f;
5421
5926
  const hide = (v) => v[0] === v[1];
5422
5927
  if (rangeRead.kind === "absent") return void 0;
5423
5928
  if (rangeRead.kind === "static") return hide(rangeRead.value) ? { kind: "static", value: 0 } : void 0;
@@ -5425,7 +5930,7 @@ function computeOpacityFromRange(rangeRead) {
5425
5930
  let anyHide = false;
5426
5931
  let allHide = true;
5427
5932
  for (const kf of kfs) {
5428
- if (hide((_a = kf.value) != null ? _a : kf.v)) anyHide = true;
5933
+ if (hide(kfValue(kf))) anyHide = true;
5429
5934
  else allHide = false;
5430
5935
  }
5431
5936
  if (!anyHide) return void 0;
@@ -5435,10 +5940,10 @@ function computeOpacityFromRange(rangeRead) {
5435
5940
  const kf = kfs[i];
5436
5941
  const prevKf = i > 0 ? kfs[i - 1] : void 0;
5437
5942
  const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
5438
- const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
5439
- const thisHide = hide((_d = kf.value) != null ? _d : kf.v);
5440
- const prevHide = prevKf ? thisHide && hide((_e = prevKf.value) != null ? _e : prevKf.v) : thisHide;
5441
- const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
5943
+ const t = kfTime(kf);
5944
+ const thisHide = hide(kfValue(kf));
5945
+ const prevHide = prevKf ? thisHide && hide(kfValue(prevKf)) : thisHide;
5946
+ const nextHide = nextKf ? thisHide && hide(kfValue(nextKf)) : thisHide;
5442
5947
  if (prevHide && !nextHide) {
5443
5948
  out.push({ time: t, value: 0 });
5444
5949
  out.push({ time: t + OPACITY_STEP_MS, value: 1 });
@@ -5453,14 +5958,11 @@ function computeOpacityFromRange(rangeRead) {
5453
5958
  function readRangeWithCrossings(raw) {
5454
5959
  const r = readAnimatable(raw);
5455
5960
  if (r.kind !== "animated") return r;
5456
- const kfs = r.keyframes.map((kf) => {
5457
- var _a, _b, _c, _d;
5458
- return {
5459
- time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
5460
- value: (_c = kf.value) != null ? _c : kf.v,
5461
- easing: (_d = kf.easing) != null ? _d : kf.e
5462
- };
5463
- });
5961
+ const kfs = r.keyframes.map((kf) => ({
5962
+ time: kfTime(kf),
5963
+ value: kfValue(kf),
5964
+ easing: kfEasing(kf)
5965
+ }));
5464
5966
  const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
5465
5967
  if (!hasReverse) {
5466
5968
  return {
@@ -5557,20 +6059,20 @@ function pxBezierPathLength(path) {
5557
6059
  return total;
5558
6060
  }
5559
6061
  function segmentLength(path, from, to) {
5560
- var _a, _b, _c, _d;
6062
+ var _a2, _b, _c, _d;
5561
6063
  const v = path.v;
5562
6064
  const p0 = v[from];
5563
6065
  const p3 = v[to];
5564
- const p1 = (_b = (_a = path.o) == null ? void 0 : _a[from]) != null ? _b : p0;
6066
+ const p1 = (_b = (_a2 = path.o) == null ? void 0 : _a2[from]) != null ? _b : p0;
5565
6067
  const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
5566
6068
  const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
5567
6069
  return lut.ds[lut.ds.length - 1];
5568
6070
  }
5569
6071
  var ARC_KAPPA = 0.5522847498307936;
5570
6072
  function shapeToPathD(node) {
5571
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
6073
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5572
6074
  if (node.type === "rect") {
5573
- const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
6075
+ const x = Number((_a2 = node.x) != null ? _a2 : 0), y = Number((_b = node.y) != null ? _b : 0);
5574
6076
  const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
5575
6077
  return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
5576
6078
  }
@@ -5586,7 +6088,7 @@ function shapeToPathD(node) {
5586
6088
  return void 0;
5587
6089
  }
5588
6090
  function applyPlayerEffects(root) {
5589
- var _a, _b;
6091
+ var _a2, _b;
5590
6092
  const ctx = {
5591
6093
  defs: [],
5592
6094
  warnings: [],
@@ -5597,8 +6099,8 @@ function applyPlayerEffects(root) {
5597
6099
  maskAncestorChains: /* @__PURE__ */ new Map(),
5598
6100
  // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
5599
6101
  // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
5600
- engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi,
5601
- glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
6102
+ engine: resolveTimelineEngine((_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.engine),
6103
+ glyphs: (_b = getDefs(root)) == null ? void 0 : _b.fonts
5602
6104
  };
5603
6105
  const working = clone(root);
5604
6106
  indexById(working, ctx.idMap);
@@ -5621,7 +6123,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
5621
6123
  let consumedByGlyphs = false;
5622
6124
  if (text == null ? void 0 : text.useGlyphs) {
5623
6125
  if (textPath) {
5624
- const pathD = typeof textPath.path === "string" ? textPath.path : void 0;
6126
+ const pathD = typeof textPath.pathData === "string" ? textPath.pathData : void 0;
5625
6127
  const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textPath.textLength, textPath.pathOverflow);
5626
6128
  if (glyphed) {
5627
6129
  n = glyphed;
@@ -5653,26 +6155,6 @@ function applyPlayerEffects_retime(node, ctx) {
5653
6155
  applyAllRetimeEffects(node, ctx);
5654
6156
  return node;
5655
6157
  }
5656
- var kfTime = (kf) => {
5657
- var _a, _b;
5658
- return (_b = (_a = kf.t) != null ? _a : kf.time) != null ? _b : 0;
5659
- };
5660
- var kfValue = (kf) => {
5661
- var _a;
5662
- return (_a = kf.v) != null ? _a : kf.value;
5663
- };
5664
- var kfEasing = (kf) => {
5665
- var _a;
5666
- return (_a = kf.e) != null ? _a : kf.easing;
5667
- };
5668
- var kfTangentIn = (kf) => {
5669
- var _a;
5670
- return (_a = kf.tangentIn) != null ? _a : kf.ti;
5671
- };
5672
- var kfTangentOut = (kf) => {
5673
- var _a;
5674
- return (_a = kf.tangentOut) != null ? _a : kf.to;
5675
- };
5676
6158
  function cubicAt(p0, c1, c2, p1, t) {
5677
6159
  const u = 1 - t;
5678
6160
  const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
@@ -5696,7 +6178,7 @@ var fmt2 = (n) => {
5696
6178
  return Object.is(r, -0) ? "0" : String(r);
5697
6179
  };
5698
6180
  function buildOffsetPath(propAnim) {
5699
- var _a, _b, _c;
6181
+ var _a2, _b, _c;
5700
6182
  if (propAnim.alongPathMode !== "offsetPath") return void 0;
5701
6183
  const kfs = propAnim.keyframes;
5702
6184
  if (!kfs || kfs.length < 2) return void 0;
@@ -5709,7 +6191,7 @@ function buildOffsetPath(propAnim) {
5709
6191
  if (!tr || tr.length < 2) return void 0;
5710
6192
  const parts = Object.keys(v);
5711
6193
  if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
5712
- const o = (_a = v == null ? void 0 : v.origin) != null ? _a : [0, 0];
6194
+ const o = (_a2 = v == null ? void 0 : v.origin) != null ? _a2 : [0, 0];
5713
6195
  if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
5714
6196
  points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
5715
6197
  }
@@ -5738,9 +6220,9 @@ function buildOffsetPath(propAnim) {
5738
6220
  }
5739
6221
  return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor };
5740
6222
  }
5741
- function materialiseOffsetPathsInTree(root) {
6223
+ function materializeOffsetPathsInTree(root) {
5742
6224
  const walk = (node) => {
5743
- var _a;
6225
+ var _a2;
5744
6226
  let out = node;
5745
6227
  const anim = node.animate;
5746
6228
  const transform = anim == null ? void 0 : anim["transform"];
@@ -5748,16 +6230,16 @@ function materialiseOffsetPathsInTree(root) {
5748
6230
  const built = buildOffsetPath(transform);
5749
6231
  if (built) {
5750
6232
  const newAnimate = __spreadValues2({}, anim);
5751
- delete newAnimate["transform"];
6233
+ delete newAnimate[TRANSFORM_ATTR];
5752
6234
  const distance = { keyframes: built.distanceKfs };
5753
6235
  if (transform.loop !== void 0) distance.loop = transform.loop;
5754
- newAnimate["offsetDistance"] = distance;
6236
+ newAnimate[OFFSET_DISTANCE_ATTR] = distance;
5755
6237
  const staticTr = node.transform;
5756
6238
  let newTransform = staticTr;
5757
6239
  if (staticTr && typeof staticTr === "object") {
5758
6240
  const t = __spreadValues2({}, staticTr);
5759
- delete t["translate"];
5760
- delete t["origin"];
6241
+ delete t[TRANSFORM_PART.translate];
6242
+ delete t[TRANSFORM_PART.origin];
5761
6243
  newTransform = Object.keys(t).length ? t : void 0;
5762
6244
  }
5763
6245
  out = __spreadProps2(__spreadValues2({}, node), {
@@ -5773,7 +6255,7 @@ function materialiseOffsetPathsInTree(root) {
5773
6255
  else delete out.transform;
5774
6256
  }
5775
6257
  }
5776
- if ((_a = out.children) == null ? void 0 : _a.length) {
6258
+ if ((_a2 = out.children) == null ? void 0 : _a2.length) {
5777
6259
  const children = out.children.map(walk);
5778
6260
  if (children.some((c, i) => c !== out.children[i])) out = __spreadProps2(__spreadValues2({}, out), { children });
5779
6261
  }
@@ -5781,15 +6263,15 @@ function materialiseOffsetPathsInTree(root) {
5781
6263
  };
5782
6264
  return walk(root);
5783
6265
  }
5784
- function materialiseAllInTree(doc, engine, opts) {
5785
- var _a, _b;
6266
+ function materializeAllInTree(doc, engine, opts) {
6267
+ var _a2, _b;
5786
6268
  let root = applyPlayerEffects(doc).root;
5787
- root = materialiseOffsetPathsInTree(root);
5788
- const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
5789
- root = materialiseInternalLoopsInTree(root, duration);
5790
- if (engine === PxAnimatorEngine.waapi) {
5791
- root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5792
- root = materialiseAnimatedUseInstances(root);
6269
+ root = materializeOffsetPathsInTree(root);
6270
+ const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : DEFAULT_DURATION_MS;
6271
+ root = materializeInternalLoopsInTree(root, duration);
6272
+ if (engine === PxTimelineEngine.native) {
6273
+ root = materializeMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
6274
+ root = materializeAnimatedUseInstances(root);
5793
6275
  root = pruneUnreferencedDefs(root);
5794
6276
  }
5795
6277
  return root;
@@ -5797,9 +6279,9 @@ function materialiseAllInTree(doc, engine, opts) {
5797
6279
  function pruneUnreferencedDefs(root) {
5798
6280
  const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
5799
6281
  const walk = (n, fn) => {
5800
- var _a;
6282
+ var _a2;
5801
6283
  fn(n);
5802
- (_a = n.children) == null ? void 0 : _a.forEach((c) => walk(c, fn));
6284
+ (_a2 = n.children) == null ? void 0 : _a2.forEach((c) => walk(c, fn));
5803
6285
  };
5804
6286
  let changed = true;
5805
6287
  while (changed) {
@@ -5823,6 +6305,38 @@ function pruneUnreferencedDefs(root) {
5823
6305
  }
5824
6306
  return root;
5825
6307
  }
6308
+ var PX_RATE_REJECTED = "setPlaybackRate: rate must be finite and non-zero";
6309
+ function isValidPlaybackRate(rate) {
6310
+ return Number.isFinite(rate) && rate !== 0;
6311
+ }
6312
+ function seekCeilingMs(durationMs, iterations) {
6313
+ if (!(durationMs > 0)) return 0;
6314
+ if (iterations === Infinity) return Infinity;
6315
+ return durationMs * (iterations > 0 ? iterations : 1);
6316
+ }
6317
+ function progressSpanMs(durationMs, iterations) {
6318
+ if (!(durationMs > 0)) return 0;
6319
+ if (iterations === Infinity) return durationMs;
6320
+ return durationMs * (iterations > 0 ? iterations : 1);
6321
+ }
6322
+ function clampSeekMs(timeMs, ceilingMs) {
6323
+ if (Number.isNaN(timeMs) || timeMs < 0) return 0;
6324
+ if (Number.isFinite(ceilingMs)) return timeMs > ceilingMs ? ceilingMs : timeMs;
6325
+ return Number.isFinite(timeMs) ? timeMs : 0;
6326
+ }
6327
+ function timeToProgress(timeMs, durationMs, iterations) {
6328
+ const span = progressSpanMs(durationMs, iterations);
6329
+ if (!(span > 0) || !Number.isFinite(timeMs)) return 0;
6330
+ if (timeMs <= 0) return 0;
6331
+ if (iterations === Infinity) return timeMs % span / span;
6332
+ return timeMs >= span ? 1 : timeMs / span;
6333
+ }
6334
+ function progressToTimeMs(progress, durationMs, iterations) {
6335
+ const span = progressSpanMs(durationMs, iterations);
6336
+ if (!(span > 0) || !Number.isFinite(progress)) return 0;
6337
+ if (progress <= 0) return 0;
6338
+ return progress >= 1 ? span : progress * span;
6339
+ }
5826
6340
  function requestFrame(cb) {
5827
6341
  const g = globalThis;
5828
6342
  if (typeof g.requestAnimationFrame === "function") return g.requestAnimationFrame(cb);
@@ -5837,9 +6351,9 @@ function cancelFrame(handle) {
5837
6351
  g.clearTimeout(handle);
5838
6352
  }
5839
6353
  function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5840
- var _a;
6354
+ var _a2;
5841
6355
  const config = getAnimatorConfig(doc) || {};
5842
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
6356
+ const bindings = getNormalizedBindings(doc, PxTimelineEngine.js);
5843
6357
  const _iterations = config.iterations;
5844
6358
  let iterations = 1;
5845
6359
  if (typeof _iterations === "number") iterations = _iterations || 1;
@@ -5848,7 +6362,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5848
6362
  const duration = +(config.duration || DEFAULT_DURATION_MS);
5849
6363
  const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
5850
6364
  const direction = config.direction || "normal";
5851
- const fill = (_a = config.fill) != null ? _a : "forwards";
6365
+ const fill = (_a2 = config.fill) != null ? _a2 : "forwards";
5852
6366
  const fillsForwards = fill === "forwards" || fill === "both";
5853
6367
  const fillsBackwards = fill === "backwards" || fill === "both";
5854
6368
  let timerId = null;
@@ -5910,7 +6424,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5910
6424
  }
5911
6425
  }
5912
6426
  const tick = () => {
5913
- var _a2, _b;
6427
+ var _a3, _b;
5914
6428
  if (!adapter.isConnected()) {
5915
6429
  pauseAnim();
5916
6430
  return;
@@ -5926,7 +6440,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5926
6440
  renderFrame(0);
5927
6441
  if (!finishCalled) {
5928
6442
  finishCalled = true;
5929
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6443
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
5930
6444
  }
5931
6445
  return;
5932
6446
  }
@@ -6018,17 +6532,17 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6018
6532
  }
6019
6533
  };
6020
6534
  const cancelAnim = () => {
6021
- var _a2;
6535
+ var _a3;
6022
6536
  pauseAnim();
6023
6537
  timeBeforeLastStartMs = 0;
6024
6538
  lastStartedTs = 0;
6025
6539
  playing = false;
6026
6540
  finishCalled = false;
6027
6541
  renderFrame(timeBeforeLastStartMs);
6028
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
6542
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
6029
6543
  };
6030
6544
  const finishAnim = (callOnFinish = true) => {
6031
- var _a2;
6545
+ var _a3;
6032
6546
  if (Number.isFinite(totalDuration)) {
6033
6547
  timeBeforeLastStartMs = totalDuration;
6034
6548
  } else {
@@ -6043,7 +6557,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6043
6557
  renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);
6044
6558
  if (callOnFinish && !finishCalled) {
6045
6559
  finishCalled = true;
6046
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6560
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
6047
6561
  }
6048
6562
  };
6049
6563
  const api = {
@@ -6053,14 +6567,14 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6053
6567
  return _isPlaying();
6054
6568
  },
6055
6569
  "play": () => {
6056
- var _a2;
6570
+ var _a3;
6057
6571
  startAnim();
6058
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
6572
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
6059
6573
  },
6060
6574
  "pause": () => {
6061
- var _a2;
6575
+ var _a3;
6062
6576
  pauseAnim();
6063
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
6577
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
6064
6578
  },
6065
6579
  "cancel": () => {
6066
6580
  cancelAnim();
@@ -6069,8 +6583,8 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6069
6583
  finishAnim(true);
6070
6584
  },
6071
6585
  "setPlaybackRate": (rate) => {
6072
- if (!isFinite(rate) || rate === 0) {
6073
- console.warn("setPlaybackRate: rate must be finite and non-zero");
6586
+ if (!isValidPlaybackRate(rate)) {
6587
+ console.warn(PX_RATE_REJECTED);
6074
6588
  return;
6075
6589
  }
6076
6590
  let current = getRawAnimTime();
@@ -6084,21 +6598,67 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6084
6598
  return getAnimCurrentTime();
6085
6599
  },
6086
6600
  "setCurrentTime": (newTime) => {
6087
- if (newTime < 0) newTime = 0;
6088
- if (Number.isFinite(totalDuration) && newTime > totalDuration) newTime = totalDuration;
6601
+ newTime = clampSeekMs(newTime, totalDuration);
6089
6602
  timeBeforeLastStartMs = newTime;
6090
6603
  if (playing) lastStartedTs = Date.now();
6091
6604
  if (!Number.isFinite(totalDuration) || newTime < totalDuration) finishCalled = false;
6092
6605
  renderFrame(getAnimCurrentTime());
6093
6606
  },
6607
+ "getCurrentProgress": () => timeToProgress(getAnimCurrentTime(), duration, iterations),
6608
+ "setCurrentProgress": (progress) => {
6609
+ api.setCurrentTime(progressToTimeMs(progress, duration, iterations));
6610
+ },
6094
6611
  "destroy": () => {
6095
- var _a2;
6612
+ var _a3;
6096
6613
  api.cancel();
6097
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6614
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6098
6615
  }
6099
6616
  };
6100
6617
  return api;
6101
6618
  }
6619
+ var PxDiagnosticKind = {
6620
+ /** The document is wrong — regenerate or repair the file. */
6621
+ document: "document",
6622
+ /** The page or app cannot provide what the document asks for — fix the mount. */
6623
+ host: "host",
6624
+ /** The platform cannot do it and the player degraded — usually nothing to fix. */
6625
+ platform: "platform",
6626
+ /** The call is wrong or self-contradictory — fix the options or props you passed. */
6627
+ usage: "usage",
6628
+ /** The player failed where it did not expect to — report it to us. */
6629
+ internal: "internal"
6630
+ };
6631
+ function asError(error) {
6632
+ return typeof error === "string" ? new Error(error) : error;
6633
+ }
6634
+ function isSilenced(silent, kind) {
6635
+ if (!silent) return false;
6636
+ return silent === true || silent.includes(kind);
6637
+ }
6638
+ function createDiagnostics(config, prefix) {
6639
+ const tag = prefix ? prefix + " " : "";
6640
+ return {
6641
+ warn: (kind, message, detail) => {
6642
+ if (config == null ? void 0 : config.onWarn) {
6643
+ config.onWarn({ kind, message, detail });
6644
+ return;
6645
+ }
6646
+ if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6647
+ const line = tag + kind + ": " + message;
6648
+ if (detail === void 0) console.warn(line);
6649
+ else console.warn(line, detail);
6650
+ },
6651
+ error: (kind, error) => {
6652
+ const err = asError(error);
6653
+ if (config == null ? void 0 : config.onError) {
6654
+ config.onError({ kind, message: err.message, error: err });
6655
+ return;
6656
+ }
6657
+ if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6658
+ console.error(tag + kind + ": " + err.message);
6659
+ }
6660
+ };
6661
+ }
6102
6662
  var IDENTITY = [1, 0, 0, 1, 0, 0];
6103
6663
  function mul(m, n) {
6104
6664
  return [
@@ -6148,9 +6708,9 @@ function lerp(a, b, f) {
6148
6708
  return a + (b - a) * f;
6149
6709
  }
6150
6710
  function interpParts(kfs, t) {
6151
- var _a, _b, _c, _d, _e, _f, _g;
6711
+ var _a2, _b, _c, _d, _e, _f, _g;
6152
6712
  if (!kfs.length) return {};
6153
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value || {};
6713
+ if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value || {};
6154
6714
  if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
6155
6715
  let i = 0;
6156
6716
  while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
@@ -6181,10 +6741,10 @@ function nodeMatrix(node, t) {
6181
6741
  return IDENTITY;
6182
6742
  }
6183
6743
  function evalScalar(animated, staticVal, fallback, t) {
6184
- var _a, _b, _c, _d, _e, _f;
6744
+ var _a2, _b, _c, _d, _e, _f;
6185
6745
  if (animated && animated.keyframes && animated.keyframes.length) {
6186
6746
  const kfs = animated.keyframes;
6187
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value;
6747
+ if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value;
6188
6748
  if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
6189
6749
  let i = 0;
6190
6750
  while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
@@ -6197,9 +6757,9 @@ function evalScalar(animated, staticVal, fallback, t) {
6197
6757
  var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
6198
6758
  var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
6199
6759
  function buildIdMap2(node, map) {
6200
- var _a;
6760
+ var _a2;
6201
6761
  if (typeof node.id === "string") map.set(node.id, node);
6202
- (_a = node.children) == null ? void 0 : _a.forEach((c) => buildIdMap2(c, map));
6762
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => buildIdMap2(c, map));
6203
6763
  }
6204
6764
  function num(v) {
6205
6765
  return v === void 0 || v === null ? 0 : Number(v);
@@ -6208,7 +6768,7 @@ function round(n) {
6208
6768
  return Math.round(n * 100) / 100 + 0;
6209
6769
  }
6210
6770
  function geomKey(node) {
6211
- var _a;
6771
+ var _a2;
6212
6772
  switch (node.type) {
6213
6773
  case "rect":
6214
6774
  return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
@@ -6217,14 +6777,14 @@ function geomKey(node) {
6217
6777
  case "circle":
6218
6778
  return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
6219
6779
  case "path":
6220
- return String((_a = node.d) != null ? _a : "");
6780
+ return String((_a2 = node.d) != null ? _a2 : "");
6221
6781
  default:
6222
6782
  return "";
6223
6783
  }
6224
6784
  }
6225
6785
  function describePrimitive(node, m, t) {
6226
- var _a, _b, _c, _d, _e;
6227
- const fill = (_a = node.fill) != null ? _a : "";
6786
+ var _a2, _b, _c, _d, _e;
6787
+ const fill = (_a2 = node.fill) != null ? _a2 : "";
6228
6788
  const stroke = (_b = node.stroke) != null ? _b : "";
6229
6789
  const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
6230
6790
  const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
@@ -6233,7 +6793,7 @@ function describePrimitive(node, m, t) {
6233
6793
  return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
6234
6794
  }
6235
6795
  function flatten(node, parent, t, idMap, out) {
6236
- var _a;
6796
+ var _a2;
6237
6797
  const type = node.type || "";
6238
6798
  if (SKIP_TYPES.has(type)) return;
6239
6799
  const m = mul(parent, nodeMatrix(node, t));
@@ -6246,33 +6806,33 @@ function flatten(node, parent, t, idMap, out) {
6246
6806
  return;
6247
6807
  }
6248
6808
  if (CONTAINER_TYPES.has(type)) {
6249
- (_a = node.children) == null ? void 0 : _a.forEach((c) => flatten(c, m, t, idMap, out));
6809
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => flatten(c, m, t, idMap, out));
6250
6810
  return;
6251
6811
  }
6252
6812
  out.push(describePrimitive(node, m, t));
6253
6813
  }
6254
6814
  function collectSampleTimes(node, into) {
6255
- var _a;
6815
+ var _a2;
6256
6816
  into.add(0);
6257
6817
  const scanAnim = (anim) => {
6258
- var _a2;
6818
+ var _a3;
6259
6819
  if (!anim || typeof anim !== "object") return;
6260
6820
  for (const key of Object.keys(anim)) {
6261
- const kfs = (_a2 = anim[key]) == null ? void 0 : _a2.keyframes;
6821
+ const kfs = (_a3 = anim[key]) == null ? void 0 : _a3.keyframes;
6262
6822
  if (Array.isArray(kfs)) kfs.forEach((kf) => {
6263
- var _a3;
6264
- return into.add((_a3 = kf.time) != null ? _a3 : 0);
6823
+ var _a4;
6824
+ return into.add((_a4 = kf.time) != null ? _a4 : 0);
6265
6825
  });
6266
6826
  }
6267
6827
  };
6268
6828
  scanAnim(node.animate);
6269
6829
  if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
6270
6830
  node.transform.keyframes.forEach((kf) => {
6271
- var _a2;
6272
- return into.add((_a2 = kf.time) != null ? _a2 : 0);
6831
+ var _a3;
6832
+ return into.add((_a3 = kf.time) != null ? _a3 : 0);
6273
6833
  });
6274
6834
  }
6275
- (_a = node.children) == null ? void 0 : _a.forEach((c) => collectSampleTimes(c, into));
6835
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => collectSampleTimes(c, into));
6276
6836
  }
6277
6837
  function visualModelAt(root, t) {
6278
6838
  const idMap = /* @__PURE__ */ new Map();
@@ -6306,14 +6866,205 @@ function subtractMultiset(a, b) {
6306
6866
  }
6307
6867
  return extra;
6308
6868
  }
6869
+ var FLAT_ONLY_KEYS = [
6870
+ "timelineSource",
6871
+ "scroll",
6872
+ "trigger",
6873
+ "delay",
6874
+ "iterations",
6875
+ "direction",
6876
+ "fill",
6877
+ "resetOnFinish",
6878
+ "duration",
6879
+ "mode",
6880
+ "frameRate"
6881
+ ];
6882
+ var CONTENT_KEYS = ["definitions", "animateById"];
6883
+ var isPlainObject = (v) => !!v && typeof v === "object" && !Array.isArray(v);
6884
+ var timelineTypeOf = (t) => isPlainObject(t) && typeof t.type === "string" ? t.type : "time";
6885
+ var isScrollish = (type) => type === "scroll" || type === "view";
6886
+ function mergePlain(base, patch) {
6887
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6888
+ for (const key of Object.keys(patch)) {
6889
+ const value = patch[key];
6890
+ if (value === null) {
6891
+ delete out[key];
6892
+ continue;
6893
+ }
6894
+ if (isPlainObject(value)) {
6895
+ out[key] = mergePlain(out[key], value);
6896
+ continue;
6897
+ }
6898
+ out[key] = value;
6899
+ }
6900
+ return out;
6901
+ }
6902
+ function mergeTimeline(base, patch, warn) {
6903
+ const baseType = timelineTypeOf(base);
6904
+ const patchNamesType = isPlainObject(patch) && typeof patch.type === "string";
6905
+ const patchType = patchNamesType ? String(patch.type) : baseType;
6906
+ let merged;
6907
+ if (patchType !== baseType) {
6908
+ const carried = {};
6909
+ if (isPlainObject(base)) {
6910
+ for (const k of PX_TIMELINE_SHARED_KEYS) {
6911
+ if (base[k] !== void 0) carried[k] = base[k];
6912
+ }
6913
+ }
6914
+ merged = mergePlain(carried, patch);
6915
+ } else {
6916
+ merged = mergePlain(base, patch);
6917
+ }
6918
+ if (isScrollish(patchType)) {
6919
+ for (const k of PX_TIME_ONLY_TIMELINE_KEYS) {
6920
+ if (merged[k] === void 0) continue;
6921
+ warn("animator.timeline." + k + ": no slot on a '" + patchType + "' timeline \u2014 dropped");
6922
+ delete merged[k];
6923
+ }
6924
+ if (merged.iterations === "infinite") {
6925
+ warn("animator.timeline.iterations: 'infinite' cannot map onto a scroll range \u2014 dropped");
6926
+ delete merged.iterations;
6927
+ }
6928
+ }
6929
+ return merged;
6930
+ }
6931
+ function foldTimelineOverride(timeline, shortcuts) {
6932
+ let base;
6933
+ if (typeof timeline === "string") {
6934
+ try {
6935
+ base = JSON.parse(timeline);
6936
+ } catch (e) {
6937
+ console.warn("timeline override: not valid JSON \u2014 ignored", e);
6938
+ base = void 0;
6939
+ }
6940
+ } else {
6941
+ base = timeline != null ? timeline : void 0;
6942
+ }
6943
+ const { duration, delay, iterations, startOn } = shortcuts;
6944
+ if (duration === void 0 && delay === void 0 && iterations === void 0 && startOn === void 0) {
6945
+ return base === void 0 ? void 0 : { timeline: base };
6946
+ }
6947
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6948
+ if (duration !== void 0) out.duration = duration;
6949
+ if (delay !== void 0) out.delay = delay;
6950
+ if (iterations !== void 0) out.iterations = iterations;
6951
+ if (startOn !== void 0) {
6952
+ out.trigger = __spreadProps2(__spreadValues2({}, out.trigger), { startOn });
6953
+ }
6954
+ return { timeline: out };
6955
+ }
6956
+ function mergeAnimatorConfig(base, patch) {
6957
+ const warnings = [];
6958
+ const warn = (m) => warnings.push(m);
6959
+ if (patch === null) return { config: void 0, warnings };
6960
+ if (!isPlainObject(patch) || Object.keys(patch).length === 0) {
6961
+ return { config: base, warnings };
6962
+ }
6963
+ const flatInBase = isPlainObject(base) ? FLAT_ONLY_KEYS.filter((k) => base[k] !== void 0) : [];
6964
+ if (flatInBase.length) {
6965
+ warn("animator: the base carries the flat runtime spelling (" + flatInBase.join(", ") + "); the patch merges the wire spelling only");
6966
+ }
6967
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6968
+ for (const key of Object.keys(patch)) {
6969
+ const value = patch[key];
6970
+ if (value === null) {
6971
+ delete out[key];
6972
+ continue;
6973
+ }
6974
+ if (key === "timeline") {
6975
+ out.timeline = isPlainObject(value) ? mergeTimeline(out.timeline, value, warn) : value;
6976
+ continue;
6977
+ }
6978
+ if (isPlainObject(value)) {
6979
+ out[key] = mergePlain(out[key], value);
6980
+ continue;
6981
+ }
6982
+ out[key] = value;
6983
+ }
6984
+ return { config: out, warnings };
6985
+ }
6986
+ function applyAnimatorConfig(doc, patch, opts) {
6987
+ var _a2, _b;
6988
+ const reset = !!(opts == null ? void 0 : opts.resetDefaults);
6989
+ if (!doc || (patch === void 0 || !reset && (patch === null || !isPlainObject(patch) || !Object.keys(patch).length))) {
6990
+ return { doc, warnings: [] };
6991
+ }
6992
+ const anyDoc = doc;
6993
+ const atRoot = isPlainObject(anyDoc.animator);
6994
+ const atMeta = !atRoot && isPlainObject((_a2 = anyDoc.meta) == null ? void 0 : _a2.animator);
6995
+ const current = atRoot ? anyDoc.animator : atMeta ? anyDoc.meta.animator : void 0;
6996
+ const warnings = [];
6997
+ if (atRoot && isPlainObject((_b = anyDoc.meta) == null ? void 0 : _b.animator)) {
6998
+ warnings.push("animator: doc.meta.animator is shadowed by doc.animator and was not patched");
6999
+ }
7000
+ let base = current;
7001
+ if (reset) {
7002
+ const kept = {};
7003
+ for (const k of CONTENT_KEYS) {
7004
+ if (isPlainObject(current) && current[k] !== void 0) kept[k] = current[k];
7005
+ }
7006
+ base = kept;
7007
+ }
7008
+ const merged = mergeAnimatorConfig(base, patch != null ? patch : {});
7009
+ warnings.push(...merged.warnings);
7010
+ if (merged.config === current) return { doc, warnings };
7011
+ if (atMeta) {
7012
+ return {
7013
+ doc: __spreadProps2(__spreadValues2({}, anyDoc), { meta: __spreadProps2(__spreadValues2({}, anyDoc.meta), { animator: merged.config }) }),
7014
+ warnings
7015
+ };
7016
+ }
7017
+ return { doc: __spreadProps2(__spreadValues2({}, anyDoc), { animator: merged.config }), warnings };
7018
+ }
7019
+ var MAX_REPORTED = 6;
7020
+ function diagnoseDocument(doc) {
7021
+ try {
7022
+ return { problems: validateDocument(doc) };
7023
+ } catch (e) {
7024
+ return { problems: [] };
7025
+ }
7026
+ }
7027
+ function reportDocumentDiagnostics(doc, where) {
7028
+ const { problems } = diagnoseDocument(doc);
7029
+ if (!problems.length) return;
7030
+ const shown = problems.slice(0, MAX_REPORTED);
7031
+ const more = problems.length - shown.length;
7032
+ console.warn(
7033
+ 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."
7034
+ );
7035
+ }
7036
+
7037
+ // src/shared/PxAnimatorCallbacks.ts
7038
+ function toEngineCallbacks(inline) {
7039
+ const { onPlay, onPause, onCancel, onFinish, onRemove, onStop, onWarn, onError, silent } = inline != null ? inline : {};
7040
+ const withStop = (own) => own || onStop ? () => {
7041
+ own == null ? void 0 : own();
7042
+ onStop == null ? void 0 : onStop();
7043
+ } : void 0;
7044
+ return {
7045
+ onPlay,
7046
+ onPause: withStop(onPause),
7047
+ onCancel: withStop(onCancel),
7048
+ onFinish: withStop(onFinish),
7049
+ onRemove: withStop(onRemove),
7050
+ onWarn,
7051
+ onError,
7052
+ silent
7053
+ };
7054
+ }
6309
7055
 
6310
- // src/PxAnimatorTriggers.ts
6311
- function setupAnimationTriggers(api, config) {
6312
- const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
7056
+ // src/triggers/PxAnimatorTriggers.ts
7057
+ function setupAnimationTriggers(api, config, diag) {
7058
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
7059
+ const cleanups = [];
7060
+ const dispose = () => {
7061
+ for (const undo of cleanups.splice(0)) undo();
7062
+ };
7063
+ const { startOn, outAction, scrollIntoViewThreshold } = resolveTrigger(config);
6313
7064
  const root = api.getRootElement();
6314
7065
  if (!root) {
6315
- console.warn("setupAnimationTriggers: No root element found for animation.");
6316
- return api;
7066
+ report.warn(PxDiagnosticKind.host, "setupAnimationTriggers: No root element found for animation.");
7067
+ return dispose;
6317
7068
  }
6318
7069
  let reversed = false;
6319
7070
  const start = () => {
@@ -6348,6 +7099,7 @@ function setupAnimationTriggers(api, config) {
6348
7099
  startHandler();
6349
7100
  } else {
6350
7101
  window.addEventListener("load", startHandler, { once: true });
7102
+ cleanups.push(() => window.removeEventListener("load", startHandler));
6351
7103
  }
6352
7104
  break;
6353
7105
  }
@@ -6362,6 +7114,10 @@ function setupAnimationTriggers(api, config) {
6362
7114
  };
6363
7115
  root.addEventListener("mouseenter", mouseOverHandler);
6364
7116
  root.addEventListener("mouseleave", mouseOutHandler);
7117
+ cleanups.push(() => {
7118
+ root.removeEventListener("mouseenter", mouseOverHandler);
7119
+ root.removeEventListener("mouseleave", mouseOutHandler);
7120
+ });
6365
7121
  break;
6366
7122
  }
6367
7123
  case "click": {
@@ -6373,16 +7129,17 @@ function setupAnimationTriggers(api, config) {
6373
7129
  }
6374
7130
  };
6375
7131
  root.addEventListener("click", clickHandler);
7132
+ cleanups.push(() => root.removeEventListener("click", clickHandler));
6376
7133
  break;
6377
7134
  }
6378
7135
  case "scrollIntoView": {
6379
7136
  const effectiveRatio = (entry) => {
6380
- var _a, _b;
7137
+ var _a2, _b;
6381
7138
  const target = entry.boundingClientRect;
6382
7139
  const visible = entry.intersectionRect;
6383
7140
  if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
6384
7141
  const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
6385
- const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
7142
+ const declared = (_b = (_a2 = entry.rootBounds) == null ? void 0 : _a2.height) != null ? _b : Infinity;
6386
7143
  const viewport = Math.min(live, declared);
6387
7144
  const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
6388
7145
  return denom > 0 ? visible.height / denom : entry.intersectionRatio;
@@ -6404,48 +7161,55 @@ function setupAnimationTriggers(api, config) {
6404
7161
  { threshold: thresholdSteps }
6405
7162
  );
6406
7163
  observer.observe(root);
7164
+ cleanups.push(() => observer.disconnect());
6407
7165
  break;
6408
7166
  }
6409
7167
  case "programmatic":
6410
7168
  break;
6411
7169
  }
6412
- return api;
7170
+ return dispose;
6413
7171
  }
6414
7172
 
6415
- // src/PxAnimatorFrameLoop.ts
7173
+ // src/engines/PxAnimatorFrameLoop.ts
6416
7174
  function getSelector(id) {
6417
7175
  return "#" + id;
6418
7176
  }
6419
7177
  function createFrameLoopAnimator(doc, adapter, callbacks, rootElement) {
7178
+ var _a2;
6420
7179
  const config = getAnimatorConfig(doc) || {};
7180
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6421
7181
  if (!rootElement) {
6422
7182
  if (doc.id) {
6423
7183
  const rootSelector = getSelector(doc.id);
6424
7184
  rootElement = document.querySelector(rootSelector);
6425
- if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
7185
+ if (!rootElement) diag.warn(PxDiagnosticKind.host, "createFrameLoopAnimator: No root element found for selector: " + rootSelector);
6426
7186
  } else {
6427
- console.warn("createFrameLoopAnimator: No root element provided");
7187
+ diag.warn(PxDiagnosticKind.host, "createFrameLoopAnimator: No root element provided");
6428
7188
  }
6429
7189
  }
6430
7190
  const basicApi = createBasicFrameLoopAnimator(
6431
7191
  doc,
6432
- adapter || createDomAdapter(rootElement),
7192
+ adapter || createDomAdapter(rootElement, diag),
6433
7193
  callbacks
6434
7194
  );
6435
7195
  const api = __spreadProps(__spreadValues({}, basicApi), {
6436
7196
  "getRootElement": () => rootElement || null
6437
7197
  });
6438
- if (config.trigger) {
6439
- if (isScrollTimeline(config)) {
6440
- console.warn("scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6441
- } else {
6442
- setupAnimationTriggers(api, config.trigger);
6443
- }
7198
+ if (isScrollTimeline(config)) {
7199
+ if (config.trigger) diag.warn(PxDiagnosticKind.usage, "scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
7200
+ } else {
7201
+ const detachTriggers = setupAnimationTriggers(api, (_a2 = config.trigger) != null ? _a2 : {}, diag);
7202
+ const destroyEngine = api.destroy.bind(api);
7203
+ api.destroy = () => {
7204
+ detachTriggers();
7205
+ destroyEngine();
7206
+ };
6444
7207
  }
6445
7208
  return api;
6446
7209
  }
6447
- function createDomAdapter(rootElement) {
7210
+ function createDomAdapter(rootElement, diag) {
6448
7211
  const warnedSelectors = /* @__PURE__ */ new Set();
7212
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6449
7213
  const adapter = {
6450
7214
  isConnected: () => {
6451
7215
  if (!rootElement) return true;
@@ -6457,7 +7221,7 @@ function createDomAdapter(rootElement) {
6457
7221
  const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
6458
7222
  if (elements.length === 0 && !warnedSelectors.has(selector)) {
6459
7223
  warnedSelectors.add(selector);
6460
- console.warn('setAttribute: No elements found for selector "' + selector + '"');
7224
+ report.warn(PxDiagnosticKind.host, 'setAttribute: No elements found for selector "' + selector + '"');
6461
7225
  }
6462
7226
  for (let i = 0; i < elements.length; i++) {
6463
7227
  const element = elements[i];
@@ -6472,18 +7236,17 @@ function createDomAdapter(rootElement) {
6472
7236
  return adapter;
6473
7237
  }
6474
7238
 
6475
- // src/PxAnimatorWebApi.ts
7239
+ // src/engines/PxAnimatorWebApi.ts
6476
7240
  function createCssKf(kf, t, propName, unsupportedSet) {
6477
- var _a, _b;
6478
- let value = (_a = kf.v) != null ? _a : kf.value;
6479
- const e = (_b = kf.e) != null ? _b : kf.easing;
7241
+ let value = kfValue(kf);
7242
+ const e = kfEasing(kf);
6480
7243
  const cssKf = {
6481
7244
  offset: t,
6482
7245
  easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
6483
7246
  };
6484
7247
  let cssValue;
6485
7248
  let cssKey = propName;
6486
- if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
7249
+ if (COLOR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
6487
7250
  cssValue = toRGBA(value);
6488
7251
  } else if (propName === "transform" && value !== null && typeof value === "object" && !Array.isArray(value)) {
6489
7252
  cssValue = composeTransformParts(value, { withUnits: true });
@@ -6510,11 +7273,11 @@ function createCssKf(kf, t, propName, unsupportedSet) {
6510
7273
  return cssKf;
6511
7274
  }
6512
7275
  function clipKeyframesToDuration(propName, keyframes, duration) {
6513
- var _a, _b, _c, _d, _e;
7276
+ var _a2, _b, _c, _d, _e;
6514
7277
  const result = [];
6515
7278
  for (let i = 0; i < keyframes.length; i++) {
6516
7279
  const kf = keyframes[i];
6517
- const t = (_a = kf.t) != null ? _a : 0;
7280
+ const t = (_a2 = kf.t) != null ? _a2 : 0;
6518
7281
  if (t < 0) {
6519
7282
  const next = keyframes[i + 1];
6520
7283
  if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
@@ -6543,7 +7306,7 @@ function clipKeyframesToDuration(propName, keyframes, duration) {
6543
7306
  return result;
6544
7307
  }
6545
7308
  function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6546
- var _a;
7309
+ var _a2;
6547
7310
  const result = /* @__PURE__ */ new Map();
6548
7311
  for (const [propName, propAnim] of Object.entries(animDef)) {
6549
7312
  const duration = config.duration || 1;
@@ -6551,7 +7314,7 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6551
7314
  const cssKeyframes = [];
6552
7315
  for (let i = 0; i < clippedKeyframes.length; i++) {
6553
7316
  const kf = clippedKeyframes[i];
6554
- const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
7317
+ const t = clamp(((_a2 = kf.t) != null ? _a2 : 0) / duration, 0, 1);
6555
7318
  const cssKf = createCssKf(kf, t, propName, unsupportedSet);
6556
7319
  if (i === 0 && (cssKf.offset || 0) > 0) {
6557
7320
  cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
@@ -6570,18 +7333,19 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6570
7333
  return result;
6571
7334
  }
6572
7335
  function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs, scrollTimeline) {
6573
- var _a;
7336
+ var _a2, _b;
6574
7337
  const config = getAnimatorConfig(doc) || {};
7338
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6575
7339
  if (!rootElement) {
6576
7340
  if (doc.id) {
6577
7341
  const rootSelector = getSelector(doc.id);
6578
7342
  rootElement = document.querySelector(rootSelector);
6579
- if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
7343
+ if (!rootElement) diag.warn(PxDiagnosticKind.host, "createWebApiAnimator: No root element found for selector: " + rootSelector);
6580
7344
  } else {
6581
- console.warn("createFrameLoopAnimator: No root element provided");
7345
+ diag.warn(PxDiagnosticKind.host, "createWebApiAnimator: No root element provided");
6582
7346
  }
6583
7347
  }
6584
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
7348
+ const bindings = getNormalizedBindings(doc, PxTimelineEngine.native);
6585
7349
  const animations = [];
6586
7350
  const _iterations = config.iterations;
6587
7351
  let iterations;
@@ -6591,18 +7355,18 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6591
7355
  let finishNotified = false;
6592
7356
  let removeCalled = false;
6593
7357
  if (!(bindings == null ? void 0 : bindings.length)) {
6594
- console.warn("createWebApiAnimator: No animation bindings defined");
7358
+ diag.warn(PxDiagnosticKind.document, "createWebApiAnimator: No animation bindings defined");
6595
7359
  }
6596
7360
  for (const binding of bindings || []) {
6597
7361
  const animDef = binding.animate;
6598
7362
  if (!animDef || typeof animDef !== "object" || Array.isArray(animDef)) {
6599
- console.warn("createWebApiAnimator: Empty or unresolved binding", binding);
7363
+ diag.warn(PxDiagnosticKind.document, "createWebApiAnimator: Empty or unresolved binding", binding);
6600
7364
  continue;
6601
7365
  }
6602
7366
  const selector = getSelector(binding.id);
6603
7367
  const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
6604
7368
  if (elements.length === 0) {
6605
- console.warn('createWebApiAnimator: No elements found for selector "' + selector + '"');
7369
+ diag.warn(PxDiagnosticKind.host, 'createWebApiAnimator: No elements found for selector "' + selector + '"');
6606
7370
  }
6607
7371
  const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);
6608
7372
  const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
@@ -6618,7 +7382,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6618
7382
  // animation ends — consistent with Lottie and other animation runtimes.
6619
7383
  // Without this, seeking to the last frame reverts elements to their
6620
7384
  // pre-animation state (the Web Animations API "after" phase with fill:'none').
6621
- fill: (_a = config.fill) != null ? _a : "forwards",
7385
+ fill: (_a2 = config.fill) != null ? _a2 : "forwards",
6622
7386
  direction: config.direction,
6623
7387
  iterations
6624
7388
  };
@@ -6635,61 +7399,61 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6635
7399
  if (scrollTimeline.rangeEnd) a.rangeEnd = scrollTimeline.rangeEnd;
6636
7400
  }
6637
7401
  if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
6638
- var _a2;
7402
+ var _a3;
6639
7403
  if (finishNotified) return;
6640
7404
  finishNotified = true;
6641
- (_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
7405
+ (_a3 = callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
6642
7406
  };
6643
7407
  if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
6644
- var _a2;
7408
+ var _a3;
6645
7409
  if (removeCalled) return;
6646
7410
  removeCalled = true;
6647
- (_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
7411
+ (_a3 = callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6648
7412
  };
6649
7413
  if (seekPosition !== void 0) {
6650
7414
  anim.currentTime = seekPosition;
6651
7415
  }
6652
7416
  animations.push(anim);
6653
7417
  } catch (e) {
6654
- console.warn(e);
7418
+ diag.warn(PxDiagnosticKind.internal, "createWebApiAnimator: could not build the animation", e);
6655
7419
  }
6656
7420
  }
6657
7421
  }
6658
7422
  }
6659
7423
  }
6660
7424
  if (!forceEvenIfHasUnsupportedAttrs && unsupportedSet.size) {
6661
- console.warn("Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
7425
+ diag.warn(PxDiagnosticKind.platform, "Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
6662
7426
  return null;
6663
7427
  }
6664
7428
  const api = {
6665
7429
  "isReady": () => true,
6666
7430
  "getRootElement": () => rootElement || null,
6667
7431
  "isPlaying": () => {
6668
- var _a2;
6669
- return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
7432
+ var _a3;
7433
+ return ((_a3 = animations[0]) == null ? void 0 : _a3.playState) === "running";
6670
7434
  },
6671
7435
  "play": () => {
6672
- var _a2;
7436
+ var _a3;
6673
7437
  finishNotified = false;
6674
7438
  animations.forEach((a) => a.play());
6675
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
7439
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
6676
7440
  },
6677
7441
  "pause": () => {
6678
- var _a2;
7442
+ var _a3;
6679
7443
  animations.forEach((a) => a.pause());
6680
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
7444
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
6681
7445
  },
6682
7446
  "cancel": () => {
6683
- var _a2;
7447
+ var _a3;
6684
7448
  finishNotified = false;
6685
7449
  animations.forEach((a) => a.cancel());
6686
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
7450
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
6687
7451
  },
6688
7452
  "finish": () => {
6689
- var _a2;
7453
+ var _a3;
6690
7454
  for (const a of animations) {
6691
7455
  try {
6692
- if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
7456
+ if (((_a3 = a.effect) == null ? void 0 : _a3.getTiming().iterations) === Infinity) {
6693
7457
  a.effect.updateTiming({ iterations: 1 });
6694
7458
  a.finish();
6695
7459
  a.effect.updateTiming({ iterations: Infinity });
@@ -6702,36 +7466,55 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6702
7466
  }
6703
7467
  },
6704
7468
  "setPlaybackRate": (rate) => {
7469
+ if (!isValidPlaybackRate(rate)) {
7470
+ diag.warn(PxDiagnosticKind.usage, PX_RATE_REJECTED);
7471
+ return api;
7472
+ }
6705
7473
  animations.forEach((a) => a.playbackRate = rate);
6706
7474
  return api;
6707
7475
  },
6708
7476
  "getCurrentTime": () => {
6709
- var _a2, _b;
6710
- const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
7477
+ var _a3, _b2;
7478
+ const res = (_b2 = (_a3 = animations[0]) == null ? void 0 : _a3.currentTime) != null ? _b2 : null;
6711
7479
  return res !== null ? +res : null;
6712
7480
  },
6713
7481
  "setCurrentTime": (time) => {
7482
+ var _a3;
7483
+ const ceiling = seekCeilingMs((_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
7484
+ const seek = ceiling > 0 ? clampSeekMs(time, ceiling) : Math.max(0, time);
6714
7485
  finishNotified = false;
6715
7486
  animations.forEach((a) => {
6716
- a.currentTime = time;
7487
+ a.currentTime = seek;
6717
7488
  });
6718
7489
  },
7490
+ "getCurrentProgress": () => {
7491
+ var _a3;
7492
+ const t = api.getCurrentTime();
7493
+ return t === null ? null : timeToProgress(t, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
7494
+ },
7495
+ "setCurrentProgress": (progress) => {
7496
+ var _a3;
7497
+ api.setCurrentTime(progressToTimeMs(progress, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1));
7498
+ },
6719
7499
  "destroy": () => {
6720
- var _a2;
7500
+ var _a3;
6721
7501
  api.cancel();
6722
7502
  animations.splice(0, animations.length);
6723
7503
  if (!removeCalled) {
6724
7504
  removeCalled = true;
6725
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
7505
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6726
7506
  }
6727
7507
  }
6728
7508
  };
6729
- if (config.trigger) {
6730
- if (config.timelineSource === "scroll") {
6731
- console.warn("scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6732
- } else {
6733
- setupAnimationTriggers(api, config.trigger);
6734
- }
7509
+ if (config.timelineSource === "scroll") {
7510
+ if (config.trigger) diag.warn(PxDiagnosticKind.usage, "scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
7511
+ } else {
7512
+ const detachTriggers = setupAnimationTriggers(api, (_b = config.trigger) != null ? _b : {}, diag);
7513
+ const destroyEngine = api.destroy.bind(api);
7514
+ api.destroy = () => {
7515
+ detachTriggers();
7516
+ destroyEngine();
7517
+ };
6735
7518
  }
6736
7519
  if (scrollTimeline) {
6737
7520
  animations.forEach((a) => a.play());
@@ -6739,21 +7522,22 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6739
7522
  return api;
6740
7523
  }
6741
7524
 
6742
- // src/PxScrollDriver.ts
7525
+ // src/scroll/PxScrollDriver.ts
6743
7526
  function nativeRangeOffset(point, defaultFraction, view) {
6744
- var _a, _b, _c;
7527
+ var _a2, _b, _c;
6745
7528
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
6746
- const pct = (_b = (_a = globalThis.CSS) == null ? void 0 : _a.percent) == null ? void 0 : _b.call(_a, fraction * 100);
7529
+ const pct = (_b = (_a2 = globalThis.CSS) == null ? void 0 : _a2.percent) == null ? void 0 : _b.call(_a2, fraction * 100);
6747
7530
  if (pct === void 0) return void 0;
6748
7531
  return view ? { rangeName: (_c = point == null ? void 0 : point.phase) != null ? _c : "cover", offset: pct } : { offset: pct };
6749
7532
  }
6750
- function createNativeScrollTimeline(subject, config) {
6751
- var _a, _b, _c, _d;
7533
+ function createNativeScrollTimeline(subject, config, diag) {
7534
+ var _a2, _b, _c, _d;
7535
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6752
7536
  if (!config || !isScrollTimeline(config)) return null;
6753
7537
  const scroll = config.scroll || {};
6754
- const kind = (_a = scroll.kind) != null ? _a : "view";
7538
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6755
7539
  if (scroll.smoothing) {
6756
- console.warn('scroll timeline: `smoothing` needs the built-in driver \u2014 ignoring `driver: "native"`');
7540
+ report.warn(PxDiagnosticKind.platform, "scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
6757
7541
  return null;
6758
7542
  }
6759
7543
  const g = globalThis;
@@ -6764,13 +7548,13 @@ function createNativeScrollTimeline(subject, config) {
6764
7548
  let timeline;
6765
7549
  try {
6766
7550
  if (view) {
6767
- timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject), axis });
7551
+ timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject, report), axis });
6768
7552
  } else {
6769
7553
  const source = scroll.source === "root" ? documentScroller() : findNearestScroller(subject, "y") || findNearestScroller(subject, "x") || documentScroller();
6770
7554
  timeline = new Ctor({ source, axis });
6771
7555
  }
6772
7556
  } catch (e) {
6773
- console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the custom driver", e);
7557
+ report.warn(PxDiagnosticKind.platform, "scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
6774
7558
  return null;
6775
7559
  }
6776
7560
  return {
@@ -6797,8 +7581,9 @@ function documentScroller() {
6797
7581
  }
6798
7582
  var SUBJECT_PARENT = "parent";
6799
7583
  var SUBJECT_SCROLLER = "scroller";
6800
- function resolveScrollSubject(svgRoot, subject) {
6801
- var _a, _b;
7584
+ function resolveScrollSubject(svgRoot, subject, diag) {
7585
+ var _a2, _b;
7586
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6802
7587
  const spec = subject == null ? void 0 : subject.trim();
6803
7588
  if (!spec) return svgRoot;
6804
7589
  if (spec === SUBJECT_PARENT) {
@@ -6807,7 +7592,7 @@ function resolveScrollSubject(svgRoot, subject) {
6807
7592
  const position = getComputedStyle(p).position;
6808
7593
  if (position === "sticky" || position === "fixed") outermostPinned = p;
6809
7594
  }
6810
- return (_b = (_a = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a : svgRoot.parentElement) != null ? _b : svgRoot;
7595
+ return (_b = (_a2 = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a2 : svgRoot.parentElement) != null ? _b : svgRoot;
6811
7596
  }
6812
7597
  if (spec === SUBJECT_SCROLLER) {
6813
7598
  return findNearestScroller(svgRoot, "y") || findNearestScroller(svgRoot, "x") || documentScroller();
@@ -6816,21 +7601,22 @@ function resolveScrollSubject(svgRoot, subject) {
6816
7601
  try {
6817
7602
  found = document.querySelector(spec);
6818
7603
  } catch (e) {
6819
- console.warn('scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
7604
+ report.warn(PxDiagnosticKind.document, 'scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
6820
7605
  return svgRoot;
6821
7606
  }
6822
7607
  if (!found) {
6823
- console.warn('scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
7608
+ report.warn(PxDiagnosticKind.host, 'scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
6824
7609
  return svgRoot;
6825
7610
  }
6826
7611
  return found;
6827
7612
  }
6828
- function createScrollDriver(subject, config, onProgress) {
6829
- var _a, _b;
7613
+ function createScrollDriver(subject, config, onProgress, diag) {
7614
+ var _a2, _b;
6830
7615
  if (!config || !isScrollTimeline(config)) return null;
7616
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6831
7617
  const scroll = config.scroll || {};
6832
- const kind = (_a = scroll.kind) != null ? _a : "view";
6833
- const measured = resolveScrollSubject(subject, scroll.subject);
7618
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
7619
+ const measured = resolveScrollSubject(subject, scroll.subject, report);
6834
7620
  const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
6835
7621
  const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
6836
7622
  const isRootScroller = scroller === documentScroller();
@@ -6948,8 +7734,8 @@ function applyScrollPin(svgRoot, scroll) {
6948
7734
  style.position = "sticky";
6949
7735
  const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
6950
7736
  const applyTop = () => {
6951
- var _a;
6952
- const extra = (_a = scroll.pinTop) != null ? _a : 0;
7737
+ var _a2;
7738
+ const extra = (_a2 = scroll.pinOffset) != null ? _a2 : 0;
6953
7739
  if (!alignFactor) {
6954
7740
  style.top = extra + "px";
6955
7741
  return;
@@ -6989,42 +7775,43 @@ function applyScrollPin(svgRoot, scroll) {
6989
7775
  };
6990
7776
  }
6991
7777
 
6992
- // src/PxAnimatorBind.ts
7778
+ // src/engines/PxAnimatorBind.ts
6993
7779
  function finaliseAnimator(animatorConfig, callbacks, make) {
6994
7780
  let apiRef;
6995
7781
  let effectiveCallbacks = callbacks;
6996
7782
  if (animatorConfig.resetOnFinish) {
6997
7783
  effectiveCallbacks = __spreadProps(__spreadValues({}, callbacks), {
6998
7784
  onFinish: () => {
6999
- var _a;
7000
- (_a = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a.call(callbacks);
7785
+ var _a2;
7786
+ (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
7001
7787
  apiRef == null ? void 0 : apiRef.cancel();
7002
7788
  }
7003
7789
  });
7004
7790
  }
7005
7791
  const res = make(effectiveCallbacks);
7006
7792
  apiRef = res;
7007
- if (animatorConfig.debugInstName) {
7008
- window[animatorConfig.debugInstName] = res;
7793
+ if (animatorConfig.debugGlobalName) {
7794
+ window[animatorConfig.debugGlobalName] = res;
7009
7795
  }
7010
7796
  return res;
7011
7797
  }
7012
7798
  function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7013
7799
  const animatorConfig = getAnimatorConfig(doc) || {};
7800
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
7014
7801
  if (isScrollTimeline(animatorConfig)) {
7015
7802
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
7016
- var _a, _b;
7803
+ var _a2;
7017
7804
  let unpin = () => {
7018
7805
  };
7019
- if (animatorConfig.mode !== PxAnimatorMode.frames && ((_a = animatorConfig.scroll) == null ? void 0 : _a.driver) === "native" && rootElement) {
7806
+ if (mayUseNativeScrollTimeline(animatorConfig.engine) && rootElement) {
7020
7807
  unpin = applyScrollPin(rootElement, animatorConfig.scroll);
7021
- const native = createNativeScrollTimeline(rootElement, animatorConfig);
7808
+ const native = createNativeScrollTimeline(rootElement, animatorConfig, diag);
7022
7809
  if (native) {
7023
7810
  const api2 = createWebApiAnimator(
7024
7811
  doc,
7025
7812
  cb,
7026
7813
  rootElement,
7027
- animatorConfig.mode === PxAnimatorMode.waapi,
7814
+ isNativeForced(animatorConfig.engine),
7028
7815
  native
7029
7816
  );
7030
7817
  if (api2) {
@@ -7040,15 +7827,16 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7040
7827
  unpin = () => {
7041
7828
  };
7042
7829
  }
7043
- const api = (animatorConfig.mode !== PxAnimatorMode.frames ? createWebApiAnimator(doc, cb, rootElement, animatorConfig.mode === PxAnimatorMode.waapi) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7044
- const subject = ((_b = api.getRootElement) == null ? void 0 : _b.call(api)) || rootElement;
7830
+ const api = (animatorConfig.engine !== PxTimelineEngineExtra.js ? createWebApiAnimator(doc, cb, rootElement, isNativeForced(animatorConfig.engine)) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7831
+ const subject = ((_a2 = api.getRootElement) == null ? void 0 : _a2.call(api)) || rootElement;
7045
7832
  if (subject) {
7046
7833
  unpin = applyScrollPin(subject, animatorConfig.scroll);
7047
7834
  const totalMs = scrollTotalDurationMs(animatorConfig);
7048
7835
  const driver = createScrollDriver(
7049
7836
  subject,
7050
7837
  animatorConfig,
7051
- (progress) => api.setCurrentTime(progress * totalMs)
7838
+ (progress) => api.setCurrentTime(progress * totalMs),
7839
+ diag
7052
7840
  );
7053
7841
  if (driver) {
7054
7842
  const destroy = api.destroy.bind(api);
@@ -7059,58 +7847,58 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7059
7847
  };
7060
7848
  }
7061
7849
  } else {
7062
- console.warn("scroll timeline: no root element to observe \u2014 animation will stay at frame 0");
7850
+ diag.warn(PxDiagnosticKind.host, "scroll timeline: no root element to observe \u2014 animation will stay at frame 0");
7063
7851
  }
7064
7852
  return api;
7065
7853
  });
7066
7854
  }
7067
7855
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
7068
- if (animatorConfig.mode === PxAnimatorMode.frames) {
7856
+ if (animatorConfig.engine === PxTimelineEngineExtra.js) {
7069
7857
  return createFrameLoopAnimator(doc, adapter, cb, rootElement);
7070
7858
  }
7071
7859
  return createWebApiAnimator(
7072
7860
  doc,
7073
7861
  cb,
7074
7862
  rootElement,
7075
- animatorConfig.mode === PxAnimatorMode.waapi
7076
- // forcing waapi
7863
+ isNativeForced(animatorConfig.engine)
7077
7864
  ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7078
7865
  });
7079
7866
  }
7080
7867
 
7081
- // src/PxAnimatorDOM.ts
7868
+ // src/dom/PxAnimatorDOM.ts
7082
7869
  var SVG_NS = "http://www.w3.org/2000/svg";
7083
- function createElement(tagName, normalisedProps, style, children, textContent) {
7870
+ function createElement(tagName, normalizedProps, style, children, textContent, diag) {
7084
7871
  if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
7085
- console.warn("SVG tag blocked (dangerous): ", tagName);
7872
+ (diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]")).warn(PxDiagnosticKind.document, "SVG tag blocked (dangerous): " + tagName);
7086
7873
  return null;
7087
7874
  }
7088
7875
  const element = document.createElementNS(SVG_NS, tagName);
7089
- for (const propName in normalisedProps) {
7090
- const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
7091
- if (sanitised === void 0) continue;
7876
+ for (const propName in normalizedProps) {
7877
+ const sanitized = sanitizeAttributeValue(propName, normalizedProps[propName]);
7878
+ if (sanitized === void 0) continue;
7092
7879
  if (CSS_ONLY_STYLE_PROPS.has(propName)) {
7093
- element.style[propName] = String(sanitised);
7880
+ element.style[propName] = String(sanitized);
7094
7881
  continue;
7095
7882
  }
7096
- element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
7883
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitized);
7097
7884
  }
7098
7885
  if (style) {
7099
7886
  for (const styleProp in style) {
7100
7887
  element.style[styleProp] = String(style[styleProp]);
7101
7888
  }
7102
7889
  }
7103
- if (children) {
7890
+ if (children == null ? void 0 : children.length) {
7104
7891
  for (const child of children) {
7105
7892
  element.appendChild(child);
7106
7893
  }
7894
+ } else if (textContent) {
7895
+ element.textContent = textContent;
7107
7896
  }
7108
- if (textContent) element.textContent = textContent;
7109
7897
  return element;
7110
7898
  }
7111
- function renderNode(node, defs) {
7899
+ function renderNode(node, defs, diag) {
7112
7900
  if (!node) return null;
7113
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7901
+ const _a2 = node, { type, children, style } = _a2, props = __objRest(_a2, ["type", "children", "style"]);
7114
7902
  const domType = props.domType;
7115
7903
  if (domType !== void 0) delete props.domType;
7116
7904
  const nodeDefs = getDefs(node) || defs;
@@ -7118,7 +7906,7 @@ function renderNode(node, defs) {
7118
7906
  let childElements;
7119
7907
  if (children) {
7120
7908
  for (const ch of children) {
7121
- const child = renderNode(ch, nodeDefs);
7909
+ const child = renderNode(ch, nodeDefs, diag);
7122
7910
  if (child) {
7123
7911
  if (!childElements) childElements = [];
7124
7912
  childElements.push(child);
@@ -7130,31 +7918,39 @@ function renderNode(node, defs) {
7130
7918
  getNormalizedProps(props),
7131
7919
  resolvedStyle,
7132
7920
  childElements,
7133
- props[TEXT_CONTENT_ATTR] || props[TEXT_ATTR]
7921
+ props[TEXT_CONTENT_ATTR],
7922
+ diag
7134
7923
  );
7135
7924
  if (element && domType !== void 0) element.setAttribute("type", domType);
7136
7925
  return element;
7137
7926
  }
7138
7927
 
7139
- // src/PxAnimatorKeys.ts
7140
- var PX_ANIMATOR_DATA_KEY = "data";
7928
+ // src/shared/PxAnimatorKeys.ts
7929
+ var PX_ANIMATOR_DOC_KEY = "doc";
7141
7930
 
7142
- // src/PxAnimator.ts
7931
+ // src/animator/PxAnimator.ts
7143
7932
  function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
7144
7933
  return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
7145
7934
  }
7146
- function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7935
+ function createAnimatorImpl(doc, adapter, callbacks, containerElement, patch, resetTimeline) {
7936
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
7147
7937
  const effectsWarnings = validateNodeEffects(doc);
7148
- for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
7938
+ for (const w of effectsWarnings) diag.warn(PxDiagnosticKind.document, "effects shape: " + w);
7939
+ reportDocumentDiagnostics(doc, "[PxAnimator] createAnimator");
7940
+ if (patch !== void 0 || resetTimeline) {
7941
+ const patched = applyAnimatorConfig(doc, patch != null ? patch : {}, { resetDefaults: !!resetTimeline });
7942
+ for (const w of patched.warnings) diag.warn(PxDiagnosticKind.usage, "timeline override: " + w);
7943
+ doc = patched.doc;
7944
+ }
7149
7945
  const animatorConfig = getAnimatorConfig(doc) || {};
7150
- const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi;
7151
- doc = materialiseAllInTree(doc, engine);
7946
+ const engine = resolveTimelineEngine(animatorConfig.engine);
7947
+ doc = materializeAllInTree(doc, engine);
7152
7948
  let rootElement = null;
7153
7949
  if (containerElement) {
7154
7950
  doc = generateNewIds(doc);
7155
7951
  const containerEl = typeof containerElement === "string" ? document.querySelector(containerElement) : containerElement;
7156
7952
  if (containerEl) {
7157
- rootElement = renderNode(doc);
7953
+ rootElement = renderNode(doc, void 0, diag);
7158
7954
  if (rootElement) {
7159
7955
  containerEl.replaceChildren(rootElement);
7160
7956
  }
@@ -7171,16 +7967,22 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7171
7967
  }
7172
7968
  return api;
7173
7969
  }
7970
+ function resolveTimelineOption(options) {
7971
+ const { timeline, duration, delay, iterations, startOn } = options;
7972
+ return foldTimelineOverride(timeline, { duration, delay, iterations, startOn });
7973
+ }
7174
7974
  function createAnimator(options) {
7175
- const { src, data, adapter, callbacks, container } = options;
7176
- if (data !== void 0 && src !== void 0) {
7177
- throw new Error("createAnimator: provide either `src` or `data`, not both");
7975
+ const { src, doc, adapter, container, resetTimeline } = options;
7976
+ const patch = resolveTimelineOption(options);
7977
+ const callbacks = toEngineCallbacks(options);
7978
+ if (doc !== void 0 && src !== void 0) {
7979
+ throw new Error("createAnimator: provide either `src` or `doc`, not both");
7178
7980
  }
7179
- if (data === void 0 && src === void 0) {
7180
- throw new Error("createAnimator: either `src` or `data` is required");
7981
+ if (doc === void 0 && src === void 0) {
7982
+ throw new Error("createAnimator: either `src` or `doc` is required");
7181
7983
  }
7182
- if (data !== void 0) {
7183
- return createAnimatorImpl(data, adapter, callbacks, container);
7984
+ if (doc !== void 0) {
7985
+ return createAnimatorImpl(doc, adapter, callbacks, container, patch, resetTimeline);
7184
7986
  }
7185
7987
  let animator = null;
7186
7988
  let pending = [];
@@ -7192,19 +7994,27 @@ function createAnimator(options) {
7192
7994
  pending.push(call);
7193
7995
  }
7194
7996
  };
7997
+ const loadDiag = createDiagnostics(callbacks, "[PxAnimator]");
7195
7998
  fetch(src).then((res) => res.json()).then((json) => {
7196
7999
  if (destroyed) return;
7197
8000
  if (isPxElementFileFormat(json)) {
7198
- animator = createAnimatorImpl(json, adapter, callbacks, container);
8001
+ animator = createAnimatorImpl(json, adapter, callbacks, container, patch, resetTimeline);
7199
8002
  const queued = pending;
7200
8003
  pending = null;
7201
8004
  queued == null ? void 0 : queued.forEach((call) => call(animator));
7202
8005
  } else {
7203
- console.error('createAnimator: invalid animation document format at "' + src + '"');
8006
+ loadDiag.error(
8007
+ PxDiagnosticKind.document,
8008
+ 'createAnimator: invalid animation document format at "' + src + '"'
8009
+ );
7204
8010
  }
7205
8011
  }).catch((err) => {
8012
+ var _a2;
7206
8013
  pending = null;
7207
- console.error('createAnimator: failed to load "' + src + '"', err);
8014
+ loadDiag.error(
8015
+ PxDiagnosticKind.host,
8016
+ 'createAnimator: failed to load "' + src + '" \u2014 ' + ((_a2 = err == null ? void 0 : err.message) != null ? _a2 : String(err))
8017
+ );
7208
8018
  });
7209
8019
  return {
7210
8020
  "isReady": () => !!animator,
@@ -7229,6 +8039,10 @@ function createAnimator(options) {
7229
8039
  "setCurrentTime": (time) => {
7230
8040
  enqueue((api) => api.setCurrentTime(time));
7231
8041
  },
8042
+ "getCurrentProgress": () => animator ? animator.getCurrentProgress() : null,
8043
+ "setCurrentProgress": (progress) => {
8044
+ enqueue((api) => api.setCurrentProgress(progress));
8045
+ },
7232
8046
  "destroy": () => {
7233
8047
  destroyed = true;
7234
8048
  pending = null;
@@ -7236,83 +8050,119 @@ function createAnimator(options) {
7236
8050
  }
7237
8051
  };
7238
8052
  }
7239
- function loadTagAnimators() {
8053
+ function loadTagAnimators(options) {
7240
8054
  const elements = document.querySelectorAll("[" + PX_ANIM_SRC_ATTR_NAME + "]");
7241
8055
  for (let i = 0; i < elements.length; i++) {
7242
8056
  const element = elements[i];
7243
8057
  if (!element[PX_ANIM_ATTR_NAME]) {
7244
8058
  const src = element.getAttribute(PX_ANIM_SRC_ATTR_NAME);
7245
8059
  if (src) {
7246
- element[PX_ANIM_ATTR_NAME] = createAnimator({ src, container: element });
8060
+ element[PX_ANIM_ATTR_NAME] = createAnimator(__spreadProps(__spreadValues({}, options), { src, container: element }));
7247
8061
  }
7248
8062
  }
7249
8063
  }
7250
8064
  }
7251
- if (typeof window !== "undefined") {
7252
- window["loadTagAnimators"] = loadTagAnimators;
7253
- window["createAnimator"] = createAnimator;
7254
- window["setupAnimationTriggers"] = setupAnimationTriggers;
7255
- }
7256
8065
  // Annotate the CommonJS export names for ESM import in node:
7257
8066
  0 && (module.exports = {
7258
- COLOUR_ATTR_NAMES,
8067
+ BASELINE_PLAYER_VERSION,
8068
+ COLOR_ATTR_NAMES,
8069
+ DEFAULT_DURATION_MS,
7259
8070
  MISSING_GLYPH_CLASS_NAME,
7260
- PX_ANIMATOR_DATA_KEY,
8071
+ PLAYER_WIRE_STEPS,
8072
+ PLAYER_WIRE_VERSION,
8073
+ PX_ANIMATOR_DOC_KEY,
7261
8074
  PX_ANIM_ATTR_NAME,
7262
8075
  PX_ANIM_SRC_ATTR_NAME,
8076
+ PX_PLAYER_SCHEMA_VERSION,
7263
8077
  PX_TRANSFORM_PART_KEYS,
8078
+ PX_TRIGGER_DEFAULTS,
8079
+ PxAlongPathMode,
7264
8080
  PxAnimatedSvgDocumentSchema,
7265
8081
  PxAnimationDefinitionSchema,
7266
8082
  PxAnimatorConfigSchema,
7267
- PxAnimatorEngine,
7268
- PxAnimatorMode,
7269
8083
  PxAttrValueSchema,
7270
8084
  PxBezierPathSchema,
7271
8085
  PxBindingSchema,
8086
+ PxClipPathEffectSchema,
7272
8087
  PxCloneEffectSchema,
8088
+ PxCloneWithout,
8089
+ PxControlMode,
7273
8090
  PxDefsSchema,
8091
+ PxDiagnosticKind,
7274
8092
  PxEasingOrRefSchema,
7275
8093
  PxEffectsSchema,
7276
8094
  PxElementAnimationSchema,
7277
8095
  PxFillGradientEffectSchema,
8096
+ PxFinishAction,
7278
8097
  PxGradientSpreadMethod,
7279
8098
  PxGradientStopSchema,
7280
8099
  PxGradientType,
7281
- PxGradientUnits,
7282
8100
  PxKeyframeSchema,
7283
8101
  PxKeyframeValueSchema,
8102
+ PxLengthAdjust,
8103
+ PxLoopDirection,
8104
+ PxLoopRepeatAt,
7284
8105
  PxLoopSchema,
8106
+ PxMaskType,
7285
8107
  PxMaskedByEffectSchema,
7286
8108
  PxNodeBase,
7287
8109
  PxNodeSchema,
8110
+ PxPathOverflow,
8111
+ PxPinAlign,
7288
8112
  PxPropertyAnimationSchema,
7289
8113
  PxRepeaterEffectSchema,
7290
8114
  PxRetimeEffectSchema,
8115
+ PxScrollAxis,
8116
+ PxScrollKind,
8117
+ PxScrollPhase,
8118
+ PxScrollRangePointSchema,
8119
+ PxScrollRangeSchema,
8120
+ PxScrollSchema,
8121
+ PxScrollSource,
7291
8122
  PxStrokeGradientEffectSchema,
7292
8123
  PxStrokeTrimEffectSchema,
8124
+ PxStrokeTrimSubPaths,
7293
8125
  PxSvgNodeExtra,
7294
8126
  PxTextEffectSchema,
7295
8127
  PxTextPathEffectSchema,
8128
+ PxTextPathMethod,
8129
+ PxTextPathSpacing,
8130
+ PxTimelineEngine,
8131
+ PxTimelineEngineExtra,
8132
+ PxTimelinePinSchema,
8133
+ PxTimelineSchema,
7296
8134
  PxTransformByEffectSchema,
7297
8135
  PxTransformPartsSchema,
7298
8136
  PxTransformValueSchema,
7299
8137
  PxTriggerSchema,
8138
+ PxUnits,
7300
8139
  STYLE_ATTR_NAMES,
7301
8140
  TRANSFORM_FN_NAMES,
8141
+ WIRE_VERSION_KEY,
8142
+ WireStepKind,
8143
+ WireVersionRelation,
8144
+ applyAnimatorConfig,
7302
8145
  applyPlayerEffects,
7303
8146
  calcAnimationValues,
7304
8147
  camelCaseToKebabWordIfNeeded,
7305
8148
  collectSampleTimes,
8149
+ compareWireVersion,
8150
+ controlModeTakesOverTrigger,
8151
+ convertPlayerDocument,
7306
8152
  createAnimator,
7307
- createAnimatorImpl,
7308
8153
  createBasicFrameLoopAnimator,
8154
+ createDiagnostics,
7309
8155
  createFrameLoopAnimator,
7310
8156
  createPathSampler,
7311
8157
  createWebApiAnimator,
7312
8158
  describeSchema,
8159
+ diagnoseDocument,
7313
8160
  diffInEffect,
8161
+ downgradePlayerDocument,
7314
8162
  evaluateMotionPathSegment,
7315
8163
  extendedPathForBrowser,
8164
+ foldTimelineOverride,
8165
+ formatWireVersion,
7316
8166
  generateNewIds,
7317
8167
  getAnimatorConfig,
7318
8168
  getBindings,
@@ -7324,24 +8174,33 @@ if (typeof window !== "undefined") {
7324
8174
  jsonElementFactory,
7325
8175
  layoutGlyphTextChars,
7326
8176
  loadTagAnimators,
7327
- materialiseAllInTree,
7328
- materialiseAnimatedUseInstances,
7329
- materialiseGlyphText,
7330
- materialiseGlyphTextAlongPath,
7331
- materialiseGlyphTextHorizontal,
7332
- materialiseInternalLoopsInPropAnim,
7333
- materialiseInternalLoopsInTree,
7334
- materialiseMotionPathInPropAnim,
7335
- materialiseMotionPathsInTree,
8177
+ materializeAllInTree,
8178
+ materializeAnimatedUseInstances,
8179
+ materializeGlyphText,
8180
+ materializeGlyphTextAlongPath,
8181
+ materializeGlyphTextHorizontal,
8182
+ materializeInternalLoopsInPropAnim,
8183
+ materializeInternalLoopsInTree,
8184
+ materializeMotionPathInPropAnim,
8185
+ materializeMotionPathsInTree,
8186
+ mergeAnimatorConfig,
7336
8187
  normalizeDocument,
8188
+ parseWireVersion,
8189
+ progressToTimeMs,
7337
8190
  propAnimIsMotionPath,
7338
8191
  px,
8192
+ readWireVersion,
7339
8193
  renderNode,
8194
+ resolveControlMode,
8195
+ resolveTrigger,
7340
8196
  schemaKeys,
7341
8197
  setupAnimationTriggers,
7342
8198
  shiftAnimatable,
8199
+ timeToProgress,
7343
8200
  toRGBA,
8201
+ validateDocument,
7344
8202
  validateNodeEffects,
8203
+ versionAdvice,
7345
8204
  visualModelAt
7346
8205
  });
7347
8206
  //# sourceMappingURL=index.cjs.map