@pixodesk/svg-animator-web 1.0.29 → 1.0.34

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
@@ -83,6 +83,7 @@ __export(index_exports, {
83
83
  PxRepeaterEffectSchema: () => PxRepeaterEffectSchema,
84
84
  PxRetimeEffectSchema: () => PxRetimeEffectSchema,
85
85
  PxStrokeGradientEffectSchema: () => PxStrokeGradientEffectSchema,
86
+ PxStrokeTrimEffectSchema: () => PxStrokeTrimEffectSchema,
86
87
  PxSvgNodeExtra: () => PxSvgNodeExtra,
87
88
  PxTextEffectSchema: () => PxTextEffectSchema,
88
89
  PxTextPathEffectSchema: () => PxTextPathEffectSchema,
@@ -90,7 +91,6 @@ __export(index_exports, {
90
91
  PxTransformPartsSchema: () => PxTransformPartsSchema,
91
92
  PxTransformValueSchema: () => PxTransformValueSchema,
92
93
  PxTriggerSchema: () => PxTriggerSchema,
93
- PxTrimPathEffectSchema: () => PxTrimPathEffectSchema,
94
94
  STYLE_ATTR_NAMES: () => STYLE_ATTR_NAMES,
95
95
  TRANSFORM_FN_NAMES: () => TRANSFORM_FN_NAMES,
96
96
  applyPlayerEffects: () => applyPlayerEffects,
@@ -425,6 +425,38 @@ function composeTransformParts(parts, opts) {
425
425
  if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
426
426
  return segs.join("");
427
427
  }
428
+ function parseTransformParts(str2) {
429
+ var _a, _b;
430
+ if (!str2 || typeof str2 !== "string") return void 0;
431
+ const out = {};
432
+ const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
433
+ const order = ["translate", "rotate", "skewX", "scale"];
434
+ let lastIdx = -1;
435
+ let m;
436
+ while ((m = re.exec(str2)) !== null) {
437
+ const fn = m[1];
438
+ const idx = order.indexOf(fn);
439
+ if (idx < 0 || idx <= lastIdx) return void 0;
440
+ lastIdx = idx;
441
+ const nums = m[2].split(/[\s,]+/).filter(Boolean).map(Number);
442
+ if (nums.some((n) => Number.isNaN(n))) return void 0;
443
+ if (fn === "translate") {
444
+ if (nums.length < 1 || nums.length > 2) return void 0;
445
+ out.translate = [nums[0], (_a = nums[1]) != null ? _a : 0];
446
+ } else if (fn === "rotate") {
447
+ if (nums.length !== 1) return void 0;
448
+ out.rotate = nums[0];
449
+ } else if (fn === "skewX") {
450
+ if (nums.length !== 1) return void 0;
451
+ out.skew = nums[0];
452
+ } else {
453
+ if (nums.length < 1 || nums.length > 2) return void 0;
454
+ out.scale = [nums[0], (_b = nums[1]) != null ? _b : nums[0]];
455
+ }
456
+ }
457
+ if (str2.replace(/([a-zA-Z]+)\s*\(([^)]*)\)/g, "").replace(/[\s,]/g, "").length) return void 0;
458
+ return Object.keys(out).length ? out : void 0;
459
+ }
428
460
  var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
429
461
  var DEFAULT_DURATION_MS = 1e3;
430
462
  function kebabToCamelCaseWord(kebab) {
@@ -752,6 +784,7 @@ var Union = class extends Base {
752
784
  constructor(schemas, defaultVal) {
753
785
  super();
754
786
  this.schemas = schemas;
787
+ this._kind = "union";
755
788
  this._default = defaultVal != null ? defaultVal : schemas[0]._default;
756
789
  }
757
790
  sanitize(raw) {
@@ -776,6 +809,7 @@ var DiscriminatedUnion = class extends Base {
776
809
  super();
777
810
  this._key = _key;
778
811
  this._schemas = _schemas;
812
+ this._kind = "discriminatedUnion";
779
813
  this._default = defaultVal != null ? defaultVal : _schemas[0]._default;
780
814
  this._map = /* @__PURE__ */ new Map();
781
815
  for (const s of _schemas) {
@@ -938,6 +972,7 @@ var Rec = class extends Base {
938
972
  constructor(value) {
939
973
  super();
940
974
  this.value = value;
975
+ this._kind = "record";
941
976
  this._default = {};
942
977
  }
943
978
  sanitize(raw) {
@@ -1023,6 +1058,7 @@ var Tuple = class extends Base {
1023
1058
  constructor(schemas) {
1024
1059
  super();
1025
1060
  this.schemas = schemas;
1061
+ this._kind = "tuple";
1026
1062
  this._default = schemas.map((s) => s._default);
1027
1063
  }
1028
1064
  sanitize(raw) {
@@ -1059,10 +1095,20 @@ function schemaKeys(schema) {
1059
1095
  function describeSchema(schema) {
1060
1096
  var _a;
1061
1097
  const s = schema;
1062
- if ("_shape" in s) return { kind: "shape", shape: s._shape };
1098
+ switch (s._kind) {
1099
+ case "union":
1100
+ return { kind: "union", members: s.schemas };
1101
+ case "discriminatedUnion":
1102
+ return { kind: "discriminatedUnion", key: s._key, members: s._schemas };
1103
+ case "record":
1104
+ return { kind: "record", value: s.value };
1105
+ case "tuple":
1106
+ return { kind: "tuple", items: s.schemas };
1107
+ }
1108
+ if ("_shape" in s) return { kind: "shape", shape: s._shape, openValue: s._openSchema };
1063
1109
  if ("item" in s) return { kind: "array", item: s.item };
1064
1110
  if ("inner" in s) return { kind: "optional", inner: s.inner };
1065
- if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.fn() };
1111
+ if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.resolved = s.fn() };
1066
1112
  return { kind: "leaf" };
1067
1113
  }
1068
1114
  var px = {
@@ -1162,7 +1208,7 @@ var PxTextPathSpacing = {
1162
1208
  auto: "auto",
1163
1209
  exact: "exact"
1164
1210
  };
1165
- var PxTrimSubPaths = {
1211
+ var PxStrokeTrimSubPaths = {
1166
1212
  separate: "separate",
1167
1213
  combined: "combined"
1168
1214
  };
@@ -1200,7 +1246,51 @@ function isPxElementFileFormat(fileJson) {
1200
1246
  }
1201
1247
  function getAnimatorConfig(doc) {
1202
1248
  var _a;
1203
- return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
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
+ }
1252
+ var flattenMemo = /* @__PURE__ */ new WeakMap();
1253
+ function flattenAnimatorTimeline(cfg) {
1254
+ const timeline = cfg.timeline;
1255
+ if (timeline === void 0 || timeline === null || typeof timeline !== "object") return cfg;
1256
+ const memoised = flattenMemo.get(cfg);
1257
+ if (memoised) return memoised;
1258
+ const _a = cfg, { timeline: _dropped } = _a, flat = __objRest2(_a, ["timeline"]);
1259
+ if (timeline.type === "scroll" || timeline.type === "view") {
1260
+ flat.timelineSource = "scroll";
1261
+ if (timeline.duration !== void 0) flat.duration = timeline.duration;
1262
+ if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1263
+ const scroll = __spreadValues2({}, flat.scroll || {});
1264
+ scroll.kind = timeline.type;
1265
+ if (timeline.engine !== void 0) scroll.driver = timeline.engine;
1266
+ if (timeline.axis !== void 0) scroll.axis = timeline.axis;
1267
+ if (timeline.source !== void 0) scroll.source = timeline.source;
1268
+ if (timeline.subject !== void 0) scroll.subject = timeline.subject;
1269
+ if (timeline.smoothing !== void 0) scroll.smoothing = timeline.smoothing;
1270
+ if (timeline.range !== void 0) scroll.range = timeline.range;
1271
+ const pin = timeline.pin;
1272
+ if (typeof pin === "boolean") scroll.pin = pin;
1273
+ else if (pin && typeof pin === "object") {
1274
+ scroll.pin = true;
1275
+ if (pin.align !== void 0) scroll.pinAlign = pin.align;
1276
+ if (pin.top !== void 0) scroll.pinTop = pin.top;
1277
+ if (pin.distance !== void 0) scroll.pinDistance = pin.distance;
1278
+ }
1279
+ flat.scroll = scroll;
1280
+ } else {
1281
+ if (timeline.duration !== void 0) flat.duration = timeline.duration;
1282
+ if (timeline.trigger !== void 0) {
1283
+ const _b = timeline.trigger, { onFinish } = _b, restTrigger = __objRest2(_b, ["onFinish"]);
1284
+ if (Object.keys(restTrigger).length) flat.trigger = restTrigger;
1285
+ if (onFinish !== void 0) flat.resetOnFinish = onFinish === "reset";
1286
+ }
1287
+ if (timeline.delay !== void 0) flat.delay = timeline.delay;
1288
+ if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1289
+ if (timeline.direction !== void 0) flat.direction = timeline.direction;
1290
+ if (timeline.fill !== void 0) flat.fill = timeline.fill;
1291
+ }
1292
+ flattenMemo.set(cfg, flat);
1293
+ return flat;
1204
1294
  }
1205
1295
  function getDefs(doc) {
1206
1296
  var _a;
@@ -1212,7 +1302,7 @@ function getBindings(doc) {
1212
1302
  if (!doc) return void 0;
1213
1303
  const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
1214
1304
  if (!animateById) return void 0;
1215
- return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
1305
+ return Object.entries(animateById).map(([id, anim]) => ({ id: id.startsWith("#") ? id.slice(1) : id, animate: anim }));
1216
1306
  }
1217
1307
  function getChildren(doc) {
1218
1308
  return doc == null ? void 0 : doc.children;
@@ -1226,27 +1316,27 @@ var PxKeyframeValueSchema = implementsInterface()(px.union([
1226
1316
  // e.g. for colors
1227
1317
  px.number(),
1228
1318
  px.array(px.number()),
1229
- px.lazy(() => PxTransformPartsSchema, {}),
1319
+ // ORDER LAW: the key-discriminated object shapes (`{path}`, `{paths}`) come BEFORE the
1320
+ // all-optional transform-parts record. In default (non-strict) mode that record accepts
1321
+ // 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 `{}` —
1323
+ // silent morph-data loss (repro: the editor's keyframeValueSanitize spec). Validity is
1324
+ // order-independent (`some()`); only sanitize routing depends on this order.
1230
1325
  px.object({ path: px.string() }),
1231
1326
  px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
1232
1327
  // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
1233
- px.lazy(() => px.array(PxGradientStopSchema), [])
1328
+ px.lazy(() => px.array(PxGradientStopSchema), []),
1329
+ px.lazy(() => PxTransformPartsSchema, {})
1234
1330
  ]));
1235
1331
  var PxKeyframeSchema = implementsInterface()(px.object({
1236
1332
  time: px.number().optional(),
1237
- t: px.number().optional(),
1238
1333
  value: PxKeyframeValueSchema.optional(),
1239
- v: PxKeyframeValueSchema.optional(),
1240
1334
  easing: PxEasingOrRefSchema.optional(),
1241
- e: PxEasingOrRefSchema.optional(),
1242
1335
  tangentOut: px.tuple([px.number(), px.number()]).optional(),
1243
- to: px.tuple([px.number(), px.number()]).optional(),
1244
- // short alias
1245
- tangentIn: px.tuple([px.number(), px.number()]).optional(),
1246
- ti: px.tuple([px.number(), px.number()]).optional(),
1247
- // short alias
1248
- selected: px.boolean().optional()
1249
- // editor-side UI state (Player ignores it)
1336
+ tangentIn: px.tuple([px.number(), px.number()]).optional()
1337
+ // (`selected` — editor timeline-selection UI state — was REMOVED from the wire
1338
+ // (review §1.3): editor data lives under `meta`. The editor still carries it on
1339
+ // its internal COPY-PASTE payload, which never validates against this schema.)
1250
1340
  }));
1251
1341
  var PxLoopSchema = implementsInterface()(px.object({
1252
1342
  segmentCount: px.number().optional(),
@@ -1256,7 +1346,6 @@ var PxLoopSchema = implementsInterface()(px.object({
1256
1346
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
1257
1347
  value: PxKeyframeValueSchema.optional(),
1258
1348
  keyframes: px.array(PxKeyframeSchema).optional(),
1259
- kfs: px.array(PxKeyframeSchema).optional(),
1260
1349
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1261
1350
  autoOrient: px.boolean().optional()
1262
1351
  }));
@@ -1284,6 +1373,11 @@ var PxElementAnimationSchema = implementsInterface()(px.union([
1284
1373
  var PxTriggerSchema = implementsInterface()(px.object({
1285
1374
  startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
1286
1375
  outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
1376
+ // 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(),
1287
1381
  scrollIntoViewThreshold: px.number().optional()
1288
1382
  }));
1289
1383
  var PxGlyphSchema = implementsInterface()(px.object({
@@ -1291,8 +1385,8 @@ var PxGlyphSchema = implementsInterface()(px.object({
1291
1385
  d: px.string()
1292
1386
  }));
1293
1387
  var PxGlyphFontSchema = implementsInterface()(px.object({
1294
- fFamily: px.string(),
1295
- style: px.string(),
1388
+ fontFamily: px.string(),
1389
+ fontStyle: px.string(),
1296
1390
  ascent: px.number(),
1297
1391
  unitsPerEm: px.number(),
1298
1392
  glyphs: px.record(PxGlyphSchema)
@@ -1300,7 +1394,9 @@ var PxGlyphFontSchema = implementsInterface()(px.object({
1300
1394
  var PxDefsSchema = implementsInterface()(px.object({
1301
1395
  easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
1302
1396
  animations: px.record(PxAnimationDefinitionSchema).optional(),
1303
- styles: px.record(px.any()).optional(),
1397
+ // Review §2.6: the schema now matches the declared type — a style preset is a flat
1398
+ // record of string|number attribute values, nothing nested.
1399
+ styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
1304
1400
  glyphs: px.record(PxGlyphFontSchema).optional()
1305
1401
  }));
1306
1402
  var PX_SCROLL_PHASES = ["cover", "contain", "entry", "exit", "entry-crossing", "exit-crossing"];
@@ -1326,22 +1422,54 @@ var PxScrollSchema = implementsInterface()(px.object({
1326
1422
  pinDistance: px.number().optional(),
1327
1423
  range: PxScrollRangeSchema.optional()
1328
1424
  }));
1329
- var PxAnimatorConfigSchema = implementsInterface()(px.object({
1330
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
1425
+ var PxTimelinePinSchema = px.object({
1426
+ align: px.enum(["top", "center", "bottom"]).optional(),
1427
+ top: px.number().optional(),
1428
+ distance: px.number().optional()
1429
+ });
1430
+ var PxClockTimelineSchema = px.object({
1431
+ type: px.literal("clock"),
1432
+ // §2.8: duration is a property of the TIMELINE — how long one pass takes.
1331
1433
  duration: px.number().optional(),
1434
+ trigger: PxTriggerSchema.optional(),
1332
1435
  delay: px.number().optional(),
1333
- // LAW (SCHEMA-DESIGN R3, S10): the ONE sanctioned string-in-number union
1334
- // (CSS animation-iteration-count familiarity) — do not add more mixed unions.
1335
1436
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1336
1437
  fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1337
- direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
1438
+ direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional()
1439
+ });
1440
+ var scrollishTimelineShape = {
1441
+ // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
1442
+ // span the scroll range maps onto.
1443
+ duration: px.number().optional(),
1444
+ // Finite repeat count IS meaningful when scrubbing — the scroll range maps onto
1445
+ // duration × iterations (rule D4; `'infinite'` cannot map to a range, so no literal here).
1446
+ 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(),
1450
+ subject: px.string().optional(),
1451
+ // 'parent' | 'scroller' | any CSS selector
1452
+ smoothing: px.number().optional(),
1453
+ // ms
1454
+ pin: px.union([px.boolean(), PxTimelinePinSchema]).optional(),
1455
+ range: PxScrollRangeSchema.optional()
1456
+ };
1457
+ var PxScrollTimelineSchema = px.object(__spreadValues2({ type: px.literal("scroll") }, scrollishTimelineShape));
1458
+ var PxViewTimelineSchema = px.object(__spreadValues2({ type: px.literal("view") }, scrollishTimelineShape));
1459
+ var PxTimelineSchema = px.discriminatedUnion("type", [
1460
+ PxClockTimelineSchema,
1461
+ PxScrollTimelineSchema,
1462
+ PxViewTimelineSchema
1463
+ ]);
1464
+ 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.)
1338
1468
  frameRate: px.number().optional(),
1339
- trigger: PxTriggerSchema.optional(),
1340
- resetOnFinish: px.boolean().optional(),
1469
+ // THE spelling of "what advances progress" — clock / scroll / view (review §2.1).
1470
+ timeline: PxTimelineSchema.optional(),
1341
1471
  definitions: PxDefsSchema.optional(),
1342
1472
  animateById: px.record(PxElementAnimationSchema).optional(),
1343
- timelineSource: px.string().optional(),
1344
- scroll: PxScrollSchema.optional(),
1345
1473
  debugInstName: px.string().optional()
1346
1474
  }));
1347
1475
  var PxBindingSchema = implementsInterface()(px.object({
@@ -1360,18 +1488,18 @@ var PxAttrValueSchema = px.union([
1360
1488
  ]);
1361
1489
  var PxAnimatableNumberSchema = px.union([
1362
1490
  px.number(),
1363
- px.object({ value: px.number() }),
1364
- PxPropertyAnimationSchema
1491
+ PxPropertyAnimationSchema,
1492
+ px.object({ value: px.number() })
1365
1493
  ]);
1366
1494
  var PxAnimatableVec2Schema = px.union([
1367
1495
  px.tuple([px.number(), px.number()]),
1368
- px.object({ value: px.tuple([px.number(), px.number()]) }),
1369
- PxPropertyAnimationSchema
1496
+ PxPropertyAnimationSchema,
1497
+ px.object({ value: px.tuple([px.number(), px.number()]) })
1370
1498
  ]);
1371
1499
  var PxAnimatableStringSchema = px.union([
1372
1500
  px.string(),
1373
- px.object({ value: px.string() }),
1374
- PxPropertyAnimationSchema
1501
+ PxPropertyAnimationSchema,
1502
+ px.object({ value: px.string() })
1375
1503
  ]);
1376
1504
  var PxTransformByEffectSchema = implementsInterface()(px.object({
1377
1505
  translate: PxAnimatableVec2Schema.optional(),
@@ -1401,16 +1529,14 @@ var PxMaskedByEffectSchema = implementsInterface()(px.object({
1401
1529
  height: px.number().optional()
1402
1530
  }));
1403
1531
  var PxClipPathEffectSchema = implementsInterface()(px.object({
1404
- d: PxAnimatableStringSchema.optional(),
1405
- animate: PxPropertyAnimationSchema.optional()
1532
+ d: PxAnimatableStringSchema.optional()
1406
1533
  }));
1407
- var PxTrimPathEffectSchema = implementsInterface()(px.object({
1534
+ var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1408
1535
  offset: PxAnimatableNumberSchema.optional(),
1409
1536
  range: PxAnimatableVec2Schema.optional(),
1410
- subPaths: px.enum([PxTrimSubPaths.separate, PxTrimSubPaths.combined]).optional()
1537
+ subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
1411
1538
  }));
1412
1539
  var PxRetimeEffectSchema = implementsInterface()(px.object({
1413
- sourceId: px.string().optional(),
1414
1540
  start: px.number().optional(),
1415
1541
  stretch: px.number().optional(),
1416
1542
  timeCrop: px.tuple([px.number(), px.number()]).optional()
@@ -1433,11 +1559,11 @@ var PxAnimatableGradientStopsSchema = px.union([
1433
1559
  var PxFillGradientEffectSchema = implementsInterface()(px.object({
1434
1560
  // Contextual kind — the `type` convention, see `PxNodeBase.type`.
1435
1561
  type: px.enum([PxGradientType.linear, PxGradientType.radial]),
1436
- p1: PxAnimatableVec2Schema.optional(),
1437
- p2: PxAnimatableVec2Schema.optional(),
1438
- c: PxAnimatableVec2Schema.optional(),
1439
- r: PxAnimatableNumberSchema.optional(),
1440
- fp: PxAnimatableVec2Schema.optional(),
1562
+ start: PxAnimatableVec2Schema.optional(),
1563
+ end: PxAnimatableVec2Schema.optional(),
1564
+ center: PxAnimatableVec2Schema.optional(),
1565
+ radius: PxAnimatableNumberSchema.optional(),
1566
+ focal: PxAnimatableVec2Schema.optional(),
1441
1567
  stops: PxAnimatableGradientStopsSchema.optional(),
1442
1568
  gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
1443
1569
  spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
@@ -1461,7 +1587,7 @@ var PxEffectsSchema = implementsInterface()(px.object({
1461
1587
  repeater: PxRepeaterEffectSchema.optional(),
1462
1588
  maskedBy: PxMaskedByEffectSchema.optional(),
1463
1589
  clipPath: PxClipPathEffectSchema.optional(),
1464
- trimPath: PxTrimPathEffectSchema.optional(),
1590
+ strokeTrim: PxStrokeTrimEffectSchema.optional(),
1465
1591
  clone: PxCloneEffectSchema.optional(),
1466
1592
  fillGradient: PxFillGradientEffectSchema.optional(),
1467
1593
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
@@ -1631,9 +1757,11 @@ function generateNewIds(doc) {
1631
1757
  const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
1632
1758
  if (docAnimate && typeof docAnimate === "object") {
1633
1759
  const updatedAnimate = {};
1634
- for (const [id, anim] of Object.entries(docAnimate)) {
1760
+ for (const [key, anim] of Object.entries(docAnimate)) {
1761
+ const hashed = key.startsWith("#");
1762
+ const id = hashed ? key.slice(1) : key;
1635
1763
  const newId = (_b = idMap.get(id)) != null ? _b : id;
1636
- updatedAnimate[newId] = anim;
1764
+ updatedAnimate[hashed ? "#" + newId : newId] = anim;
1637
1765
  }
1638
1766
  cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animateById: updatedAnimate });
1639
1767
  }
@@ -1724,7 +1852,7 @@ function getNormalizedProps(props) {
1724
1852
  let value = props[rawKey];
1725
1853
  if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
1726
1854
  propsCopy[key] = toRGBA(value);
1727
- } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes && !value.kfs) {
1855
+ } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
1728
1856
  const parts = value.value && typeof value.value === "object" ? value.value : value;
1729
1857
  propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
1730
1858
  } else if (TRANSFORM_FN_NAMES.has(key)) {
@@ -1762,12 +1890,12 @@ function getKfEasing(kf) {
1762
1890
  return (_a = kf.easing) != null ? _a : kf.e;
1763
1891
  }
1764
1892
  function propAnimIsMotionPath(anim) {
1765
- var _a, _b, _c;
1766
- const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
1893
+ var _a, _b;
1894
+ const kfs = anim.keyframes;
1767
1895
  if (!Array.isArray(kfs)) return false;
1768
1896
  if (anim.autoOrient) return true;
1769
1897
  for (const kf of kfs) {
1770
- if (((_b = kf.tangentIn) != null ? _b : kf.ti) || ((_c = kf.tangentOut) != null ? _c : kf.to)) return true;
1898
+ if (((_a = kf.tangentIn) != null ? _a : kf.ti) || ((_b = kf.tangentOut) != null ? _b : kf.to)) return true;
1771
1899
  }
1772
1900
  return false;
1773
1901
  }
@@ -1828,14 +1956,14 @@ var DEFAULT_FLATNESS_TOL = 0.5;
1828
1956
  var DEFAULT_ROTATION_TOL = 5;
1829
1957
  var DEFAULT_MAX_SAMPLES = 32;
1830
1958
  function materialiseMotionPathInPropAnim(anim, opts) {
1831
- var _a, _b, _c, _d;
1959
+ var _a, _b, _c;
1832
1960
  if (!propAnimIsMotionPath(anim)) return anim;
1833
- const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
1961
+ const kfs = anim.keyframes;
1834
1962
  if (!Array.isArray(kfs) || kfs.length < 2) return anim;
1835
1963
  const autoOrient = !!anim.autoOrient;
1836
- const flatnessTol = (_b = opts == null ? void 0 : opts.flatnessTolerance) != null ? _b : DEFAULT_FLATNESS_TOL;
1837
- const rotationTol = (_c = opts == null ? void 0 : opts.rotationTolerance) != null ? _c : DEFAULT_ROTATION_TOL;
1838
- const maxSamples = (_d = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _d : DEFAULT_MAX_SAMPLES;
1964
+ const flatnessTol = (_a = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a : DEFAULT_FLATNESS_TOL;
1965
+ const rotationTol = (_b = opts == null ? void 0 : opts.rotationTolerance) != null ? _b : DEFAULT_ROTATION_TOL;
1966
+ const maxSamples = (_c = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _c : DEFAULT_MAX_SAMPLES;
1839
1967
  const out = [];
1840
1968
  const firstPos = getKfTranslate(kfs[0]);
1841
1969
  if (!firstPos) return anim;
@@ -1864,7 +1992,7 @@ function materialiseMotionPathInPropAnim(anim, opts) {
1864
1992
  const lastInE = getKfEasing(kfs[kfs.length - 1]);
1865
1993
  if (lastInE) out[out.length - 1].e = lastInE;
1866
1994
  if (autoOrient) unwrapAutoOrientRotations(out);
1867
- const result = { kfs: out };
1995
+ const result = { keyframes: out };
1868
1996
  if (anim.loop !== void 0) result.loop = anim.loop;
1869
1997
  return result;
1870
1998
  }
@@ -2524,7 +2652,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2524
2652
  }
2525
2653
  function normalizeKeyframes(propName, propAnim, duration, defs) {
2526
2654
  var _a, _b, _c, _d, _e, _f, _g;
2527
- const keyframes = propAnim.keyframes || propAnim.kfs || [];
2655
+ const keyframes = propAnim.keyframes || [];
2528
2656
  const normalized = [];
2529
2657
  for (const kf of keyframes) {
2530
2658
  const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
@@ -2569,17 +2697,16 @@ function mergeAnimationDefinitions(animations) {
2569
2697
  return merged;
2570
2698
  }
2571
2699
  function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
2572
- var _a;
2573
2700
  const loopRaw = propAnim.loop;
2574
2701
  if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
2575
2702
  const loop = loopRaw === true ? {} : loopRaw;
2576
- const rawKfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
2703
+ const rawKfs = propAnim.keyframes;
2577
2704
  if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
2578
2705
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2579
2706
  const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
2580
2707
  const kfs = rawKfs.map((kf) => {
2581
- var _a2, _b, _c, _d, _e, _f, _g, _h;
2582
- const t = (_a2 = kf.t) != null ? _a2 : kf.time;
2708
+ var _a, _b, _c, _d, _e, _f, _g, _h;
2709
+ const t = (_a = kf.t) != null ? _a : kf.time;
2583
2710
  let v = (_b = kf.v) != null ? _b : kf.value;
2584
2711
  if (propName === "d") v = normalizePathValue(v);
2585
2712
  if (isColour) v = (_c = parseColor(v)) != null ? _c : v;
@@ -2590,7 +2717,7 @@ function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
2590
2717
  return out2;
2591
2718
  });
2592
2719
  const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
2593
- const out = { kfs: expanded };
2720
+ const out = { keyframes: expanded };
2594
2721
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2595
2722
  return out;
2596
2723
  }
@@ -2632,6 +2759,36 @@ var _elementIdCounter = 0;
2632
2759
  function generateElementId() {
2633
2760
  return "_px_el_" + ++_elementIdCounter;
2634
2761
  }
2762
+ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2763
+ if (!animDef) return animDef;
2764
+ const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
2765
+ if (!staticParts || !Object.keys(staticParts).length) return animDef;
2766
+ const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues2(__spreadValues2({}, staticParts), v) : v;
2767
+ const transformAnim = animDef["transform"];
2768
+ if (transformAnim && typeof transformAnim === "object") {
2769
+ const anim = transformAnim;
2770
+ if (Array.isArray(anim.keyframes)) {
2771
+ const out = __spreadProps2(__spreadValues2({}, anim), {
2772
+ keyframes: anim.keyframes.map((kf) => __spreadProps2(__spreadValues2({}, kf), { value: mergeKfValue(kf.value) }))
2773
+ });
2774
+ if (out.value !== void 0) out.value = mergeKfValue(out.value);
2775
+ return __spreadProps2(__spreadValues2({}, animDef), { transform: out });
2776
+ }
2777
+ return animDef;
2778
+ }
2779
+ const channels = Object.keys(animDef).filter((k) => TRANSFORM_FN_NAMES.has(k));
2780
+ if (channels.length !== 1) return animDef;
2781
+ const ch = channels[0];
2782
+ const chAnim = animDef[ch];
2783
+ if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
2784
+ const lifted = __spreadProps2(__spreadValues2({}, chAnim), {
2785
+ keyframes: chAnim.keyframes.map((kf) => __spreadProps2(__spreadValues2({}, kf), { value: __spreadProps2(__spreadValues2({}, staticParts), { [ch]: kf.value }) }))
2786
+ });
2787
+ if (lifted.value !== void 0) lifted.value = __spreadProps2(__spreadValues2({}, staticParts), { [ch]: lifted.value });
2788
+ const rest = __spreadValues2({}, animDef);
2789
+ delete rest[ch];
2790
+ return __spreadProps2(__spreadValues2({}, rest), { transform: lifted });
2791
+ }
2635
2792
  function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
2636
2793
  const normalized = {};
2637
2794
  for (const [propName, propAnim] of Object.entries(animDef)) {
@@ -2640,7 +2797,7 @@ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimat
2640
2797
  }
2641
2798
  const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
2642
2799
  if (normalizedKfs.length > 0) {
2643
- const out = { kfs: normalizedKfs };
2800
+ const out = { keyframes: normalizedKfs };
2644
2801
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2645
2802
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
2646
2803
  normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
@@ -2653,11 +2810,11 @@ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2653
2810
  const defs = getDefs(doc);
2654
2811
  const duration = animatorConfig.duration || 1e3;
2655
2812
  const bindings = [];
2656
- const processAnimation = (id, animate) => {
2813
+ const processAnimation = (id, animate, staticTransform) => {
2657
2814
  if (!animate) return null;
2658
2815
  const animDefs = resolveElementAnimation(animate, defs);
2659
2816
  if (animDefs.length === 0) return null;
2660
- const merged = mergeAnimationDefinitions(animDefs);
2817
+ const merged = mergeStaticTransformIntoAnimDef(mergeAnimationDefinitions(animDefs), staticTransform);
2661
2818
  const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
2662
2819
  if (Object.keys(normalizedAnim).length === 0) return null;
2663
2820
  return {
@@ -2677,7 +2834,7 @@ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2677
2834
  if (inlineAnim && Object.keys(inlineAnim).length > 0) {
2678
2835
  const nodeId = node.id || generateElementId();
2679
2836
  node.id = nodeId;
2680
- const normalized = processAnimation(nodeId, inlineAnim);
2837
+ const normalized = processAnimation(nodeId, inlineAnim, node.transform);
2681
2838
  if (normalized) bindings.push(normalized);
2682
2839
  }
2683
2840
  if (node.children) {
@@ -2715,7 +2872,7 @@ function getKeyframesPair(keyframes, progress) {
2715
2872
  }
2716
2873
  function calcPropertyValue(propName, propAnim, progress) {
2717
2874
  var _a, _b, _c, _d, _e, _f, _g;
2718
- const keyframes = propAnim.kfs || propAnim.keyframes || [];
2875
+ const keyframes = propAnim.keyframes || [];
2719
2876
  if (keyframes.length === 0) return null;
2720
2877
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
2721
2878
  let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
@@ -3330,7 +3487,7 @@ function liftBodyTranslate(node, transformBy) {
3330
3487
  if (split.rest) node.transform = split.rest;
3331
3488
  else delete node.transform;
3332
3489
  }
3333
- } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes && !node.transform.kfs) {
3490
+ } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes) {
3334
3491
  const wrapped = node.transform.value;
3335
3492
  const isWrapped = !!(wrapped && typeof wrapped === "object");
3336
3493
  const value = isWrapped ? wrapped : node.transform;
@@ -3463,12 +3620,12 @@ function synthesiseGradientDef(fx, id, ctx) {
3463
3620
  id
3464
3621
  };
3465
3622
  if (fx.type === PxGradientType.linear) {
3466
- applyGeomVec(out, "x1", "y1", fx.p1);
3467
- applyGeomVec(out, "x2", "y2", fx.p2);
3623
+ applyGeomVec(out, "x1", "y1", fx.start);
3624
+ applyGeomVec(out, "x2", "y2", fx.end);
3468
3625
  } else {
3469
- applyGeomVec(out, "cx", "cy", fx.c);
3470
- applyGeomNumber(out, "r", fx.r);
3471
- applyGeomVec(out, "fx", "fy", fx.fp);
3626
+ applyGeomVec(out, "cx", "cy", fx.center);
3627
+ applyGeomNumber(out, "r", fx.radius);
3628
+ applyGeomVec(out, "fx", "fy", fx.focal);
3472
3629
  }
3473
3630
  if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
3474
3631
  if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
@@ -3594,8 +3751,7 @@ function formatOffset(o) {
3594
3751
  return pct + "%";
3595
3752
  }
3596
3753
  function applyClipPathEffect(node, fx, ctx) {
3597
- var _a, _b;
3598
- if (!fx || !fx.d && !fx.animate) return node;
3754
+ if (!(fx == null ? void 0 : fx.d)) return node;
3599
3755
  const clipId = genId(ctx, "clip");
3600
3756
  const pathChild = { type: "path" };
3601
3757
  const read = readAnimatable(fx.d);
@@ -3607,11 +3763,6 @@ function applyClipPathEffect(node, fx, ctx) {
3607
3763
  if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
3608
3764
  }
3609
3765
  }
3610
- if (fx.animate && !((_a = pathChild.animate) == null ? void 0 : _a.d)) {
3611
- const animate = (_b = pathChild.animate) != null ? _b : {};
3612
- animate.d = fx.animate;
3613
- pathChild.animate = animate;
3614
- }
3615
3766
  ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
3616
3767
  node.clipPath = "url(#" + clipId + ")";
3617
3768
  return node;
@@ -3754,7 +3905,7 @@ function readTransformationFromBody(node) {
3754
3905
  if (parts.origin) out.origin = parts.origin;
3755
3906
  return Object.keys(out).length ? out : void 0;
3756
3907
  }
3757
- if (node.transform && typeof node.transform === "object" && !node.transform.keyframes && !node.transform.kfs) {
3908
+ if (node.transform && typeof node.transform === "object" && !node.transform.keyframes) {
3758
3909
  const wrapped = node.transform.value;
3759
3910
  const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
3760
3911
  if (value && typeof value === "object") {
@@ -5099,9 +5250,9 @@ function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pat
5099
5250
  }
5100
5251
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
5101
5252
  }
5102
- function applyTrimPathEffect(node, trimPath, ctx) {
5103
- if (!trimPath) return node;
5104
- const combined = trimPath.subPaths === PxTrimSubPaths.combined;
5253
+ function applyStrokeTrimEffect(node, strokeTrim, ctx) {
5254
+ if (!strokeTrim) return node;
5255
+ const combined = strokeTrim.subPaths === PxStrokeTrimSubPaths.combined;
5105
5256
  const leafEntries = [];
5106
5257
  const measure = (n) => {
5107
5258
  if (Array.isArray(n.children) && n.children.length > 0) {
@@ -5132,9 +5283,9 @@ function applyTrimPathEffect(node, trimPath, ctx) {
5132
5283
  }
5133
5284
  const chainLengthPx = acc;
5134
5285
  if (combined && chainLengthPx < 1e-3) return node;
5135
- const offsetReadRaw = readAnimatable(trimPath.offset);
5286
+ const offsetReadRaw = readAnimatable(strokeTrim.offset);
5136
5287
  const offsetRead = offsetReadRaw.kind === "absent" ? { kind: "static", value: 0 } : offsetReadRaw;
5137
- const rangeReadRaw = readRangeWithCrossings(trimPath.range);
5288
+ const rangeReadRaw = readRangeWithCrossings(strokeTrim.range);
5138
5289
  const rangeRead = rangeReadRaw.kind === "absent" ? { kind: "static", value: [0, 1] } : rangeReadRaw;
5139
5290
  const offsetValues = readScalarValues(offsetRead);
5140
5291
  const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
@@ -5464,7 +5615,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
5464
5615
  const originalId = typeof node.id === "string" ? node.id : void 0;
5465
5616
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
5466
5617
  if (!fx && !innerIdForContentRef) return node;
5467
- const { transformBy, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
5618
+ const { transformBy, repeater, maskedBy, clipPath, strokeTrim, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
5468
5619
  if (fx) delete node.effects;
5469
5620
  let n = node;
5470
5621
  let consumedByGlyphs = false;
@@ -5484,7 +5635,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
5484
5635
  if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
5485
5636
  n = applyFillGradientEffect(n, fillGradient, ctx);
5486
5637
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
5487
- n = applyTrimPathEffect(n, trimPath, ctx);
5638
+ n = applyStrokeTrimEffect(n, strokeTrim, ctx);
5488
5639
  n = applyRepeaterEffect(n, repeater, ctx);
5489
5640
  n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
5490
5641
  n = applyClipPathEffect(n, clipPath, ctx);
@@ -5545,9 +5696,9 @@ var fmt2 = (n) => {
5545
5696
  return Object.is(r, -0) ? "0" : String(r);
5546
5697
  };
5547
5698
  function buildOffsetPath(propAnim) {
5548
- var _a, _b, _c, _d;
5699
+ var _a, _b, _c;
5549
5700
  if (propAnim.alongPathMode !== "offsetPath") return void 0;
5550
- const kfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
5701
+ const kfs = propAnim.keyframes;
5551
5702
  if (!kfs || kfs.length < 2) return void 0;
5552
5703
  const first = kfValue(kfs[0]);
5553
5704
  const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
@@ -5558,7 +5709,7 @@ function buildOffsetPath(propAnim) {
5558
5709
  if (!tr || tr.length < 2) return void 0;
5559
5710
  const parts = Object.keys(v);
5560
5711
  if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
5561
- const o = (_b = v == null ? void 0 : v.origin) != null ? _b : [0, 0];
5712
+ const o = (_a = v == null ? void 0 : v.origin) != null ? _a : [0, 0];
5562
5713
  if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
5563
5714
  points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
5564
5715
  }
@@ -5567,8 +5718,8 @@ function buildOffsetPath(propAnim) {
5567
5718
  const segLens = [];
5568
5719
  for (let i = 0; i < points.length - 1; i++) {
5569
5720
  const p0 = points[i], p1 = points[i + 1];
5570
- const to = (_c = kfTangentOut(kfs[i])) != null ? _c : [0, 0];
5571
- const ti = (_d = kfTangentIn(kfs[i + 1])) != null ? _d : [0, 0];
5721
+ const to = (_b = kfTangentOut(kfs[i])) != null ? _b : [0, 0];
5722
+ const ti = (_c = kfTangentIn(kfs[i + 1])) != null ? _c : [0, 0];
5572
5723
  const c1 = [p0[0] + to[0], p0[1] + to[1]];
5573
5724
  const c2 = [p1[0] + ti[0], p1[1] + ti[1]];
5574
5725
  d += "C" + fmt2(c1[0]) + "," + fmt2(c1[1]) + "," + fmt2(c2[0]) + "," + fmt2(c2[1]) + "," + fmt2(p1[0]) + "," + fmt2(p1[1]);
@@ -6396,7 +6547,7 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6396
6547
  const result = /* @__PURE__ */ new Map();
6397
6548
  for (const [propName, propAnim] of Object.entries(animDef)) {
6398
6549
  const duration = config.duration || 1;
6399
- const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);
6550
+ const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.keyframes || [], duration);
6400
6551
  const cssKeyframes = [];
6401
6552
  for (let i = 0; i < clippedKeyframes.length; i++) {
6402
6553
  const kf = clippedKeyframes[i];
@@ -7009,7 +7160,16 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7009
7160
  }
7010
7161
  }
7011
7162
  }
7012
- return createAnimatorFromConfig(doc, adapter, callbacks, rootElement);
7163
+ const api = createAnimatorFromConfig(doc, adapter, callbacks, rootElement);
7164
+ if (containerElement && rootElement) {
7165
+ const rendered = rootElement;
7166
+ const destroyNative = api.destroy.bind(api);
7167
+ api.destroy = () => {
7168
+ destroyNative();
7169
+ rendered.remove();
7170
+ };
7171
+ }
7172
+ return api;
7013
7173
  }
7014
7174
  function createAnimator(options) {
7015
7175
  const { src, data, adapter, callbacks, container } = options;
@@ -7129,6 +7289,7 @@ if (typeof window !== "undefined") {
7129
7289
  PxRepeaterEffectSchema,
7130
7290
  PxRetimeEffectSchema,
7131
7291
  PxStrokeGradientEffectSchema,
7292
+ PxStrokeTrimEffectSchema,
7132
7293
  PxSvgNodeExtra,
7133
7294
  PxTextEffectSchema,
7134
7295
  PxTextPathEffectSchema,
@@ -7136,7 +7297,6 @@ if (typeof window !== "undefined") {
7136
7297
  PxTransformPartsSchema,
7137
7298
  PxTransformValueSchema,
7138
7299
  PxTriggerSchema,
7139
- PxTrimPathEffectSchema,
7140
7300
  STYLE_ATTR_NAMES,
7141
7301
  TRANSFORM_FN_NAMES,
7142
7302
  applyPlayerEffects,