@pixodesk/svg-animator-vue 1.0.21 → 1.0.24

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.umd.js CHANGED
@@ -56934,8 +56934,9 @@ ${codeFrame}` : message);
56934
56934
  }
56935
56935
  isValid(raw, ctx, path) {
56936
56936
  var _a;
56937
- if (this.schemas.some((s) => s.isValid(raw))) return true;
56938
- 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, 60));
56937
+ const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
56938
+ if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
56939
+ 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));
56939
56940
  return false;
56940
56941
  }
56941
56942
  _canSanitize(raw) {
@@ -57011,6 +57012,7 @@ ${codeFrame}` : message);
57011
57012
  if (ctx == null ? void 0 : ctx.strict) {
57012
57013
  for (const key of Object.keys(obj)) {
57013
57014
  if (key in this._shape) continue;
57015
+ if (obj[key] === void 0) continue;
57014
57016
  p.push(key);
57015
57017
  ctx.errors.push(pathStr(p) + ": unexpected extra key");
57016
57018
  p.pop();
@@ -57151,6 +57153,23 @@ ${codeFrame}` : message);
57151
57153
  return true;
57152
57154
  }
57153
57155
  };
57156
+ var Defined = class extends Base {
57157
+ constructor() {
57158
+ super(...arguments);
57159
+ this._default = void 0;
57160
+ }
57161
+ sanitize(raw) {
57162
+ return raw;
57163
+ }
57164
+ isValid(raw, ctx, path) {
57165
+ if (raw !== void 0) return true;
57166
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": required value is missing");
57167
+ return false;
57168
+ }
57169
+ _canSanitize(raw) {
57170
+ return raw !== void 0;
57171
+ }
57172
+ };
57154
57173
  var Lazy = class extends Base {
57155
57174
  constructor(fn, _default) {
57156
57175
  super();
@@ -57248,6 +57267,8 @@ ${codeFrame}` : message);
57248
57267
  record: (value) => new Rec(value),
57249
57268
  /** Passes anything through unchanged — always valid. */
57250
57269
  any: () => new Any(),
57270
+ /** Anything EXCEPT `undefined` — an open type whose presence is required (V6). */
57271
+ defined: () => new Defined(),
57251
57272
  /** Fixed-length tuple — validates element count and each position individually. */
57252
57273
  tuple: (schemas) => new Tuple(schemas),
57253
57274
  /** Defers schema creation — required for recursive types. Must supply a default value. */
@@ -57257,13 +57278,52 @@ ${codeFrame}` : message);
57257
57278
  var PX_ANIM_ATTR_NAME = "_px_animator";
57258
57279
  var PxAnimatorMode = {
57259
57280
  auto: "auto",
57260
- webapi: "webapi",
57281
+ waapi: "waapi",
57261
57282
  frames: "frames"
57262
57283
  };
57263
57284
  var PxAnimatorEngine = {
57264
- webapi: PxAnimatorMode.webapi,
57285
+ waapi: PxAnimatorMode.waapi,
57265
57286
  frames: PxAnimatorMode.frames
57266
57287
  };
57288
+ var PxLoopExtend = {
57289
+ /** Segment from the START; the animation is extended BEFORE the first keyframe
57290
+ * (intro loops that run before the main timeline begins). */
57291
+ before: "before",
57292
+ /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
57293
+ * loops that continue once the main timeline has finished). */
57294
+ after: "after"
57295
+ };
57296
+ var PxMaskType = {
57297
+ luminance: "luminance",
57298
+ alpha: "alpha"
57299
+ };
57300
+ var PxUnits = {
57301
+ userSpaceOnUse: "userSpaceOnUse",
57302
+ objectBoundingBox: "objectBoundingBox"
57303
+ };
57304
+ var PxCloneType = {
57305
+ content: "content"
57306
+ };
57307
+ var PxPathOverflow = {
57308
+ clip: "clip",
57309
+ extend: "extend"
57310
+ };
57311
+ var PxLengthAdjust = {
57312
+ spacing: "spacing",
57313
+ spacingAndGlyphs: "spacingAndGlyphs"
57314
+ };
57315
+ var PxTextPathMethod = {
57316
+ align: "align",
57317
+ stretch: "stretch"
57318
+ };
57319
+ var PxTextPathSpacing = {
57320
+ auto: "auto",
57321
+ exact: "exact"
57322
+ };
57323
+ var PxTrimSubPaths = {
57324
+ separate: "separate",
57325
+ combined: "combined"
57326
+ };
57267
57327
  var TEXT_ATTR = "text";
57268
57328
  var TEXT_CONTENT_ATTR = "textContent";
57269
57329
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
@@ -57272,9 +57332,45 @@ ${codeFrame}` : message);
57272
57332
  "animator",
57273
57333
  "meta",
57274
57334
  "animate",
57335
+ "effects",
57275
57336
  TEXT_ATTR,
57276
57337
  TEXT_CONTENT_ATTR
57277
57338
  ]);
57339
+ var PxGradientUnits = {
57340
+ userSpaceOnUse: "userSpaceOnUse",
57341
+ objectBoundingBox: "objectBoundingBox"
57342
+ };
57343
+ var PxGradientSpreadMethod = {
57344
+ pad: "pad",
57345
+ reflect: "reflect",
57346
+ repeat: "repeat"
57347
+ };
57348
+ var PxGradientType = {
57349
+ linear: "linear",
57350
+ radial: "radial"
57351
+ };
57352
+ function isPxElementFileFormat(fileJson) {
57353
+ if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
57354
+ return false;
57355
+ }
57356
+ return fileJson["type"] === "svg";
57357
+ }
57358
+ function getAnimatorConfig(doc) {
57359
+ var _a;
57360
+ return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
57361
+ }
57362
+ function getDefs(doc) {
57363
+ var _a;
57364
+ if (!doc) return void 0;
57365
+ return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
57366
+ }
57367
+ function getBindings(doc) {
57368
+ var _a;
57369
+ if (!doc) return void 0;
57370
+ const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
57371
+ if (!animateById) return void 0;
57372
+ return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
57373
+ }
57278
57374
  var PxEasingOrRefSchema = px.union([
57279
57375
  px.string(),
57280
57376
  px.tuple([px.number(), px.number(), px.number(), px.number()])
@@ -57286,13 +57382,15 @@ ${codeFrame}` : message);
57286
57382
  px.array(px.number()),
57287
57383
  px.lazy(() => PxTransformPartsSchema, {}),
57288
57384
  px.object({ path: px.string() }),
57289
- px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] })
57385
+ px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
57386
+ // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
57387
+ px.lazy(() => px.array(PxGradientStopSchema), [])
57290
57388
  ]));
57291
57389
  var PxKeyframeSchema = implementsInterface()(px.object({
57292
57390
  time: px.number().optional(),
57293
57391
  t: px.number().optional(),
57294
- value: px.any().optional(),
57295
- v: px.any().optional(),
57392
+ value: PxKeyframeValueSchema.optional(),
57393
+ v: PxKeyframeValueSchema.optional(),
57296
57394
  easing: PxEasingOrRefSchema.optional(),
57297
57395
  e: PxEasingOrRefSchema.optional(),
57298
57396
  tangentOut: px.tuple([px.number(), px.number()]).optional(),
@@ -57306,10 +57404,11 @@ ${codeFrame}` : message);
57306
57404
  }));
57307
57405
  var PxLoopSchema = implementsInterface()(px.object({
57308
57406
  segmentCount: px.number().optional(),
57309
- before: px.boolean().optional(),
57407
+ extend: px.enum([PxLoopExtend.before, PxLoopExtend.after]).optional(),
57310
57408
  alternate: px.boolean().optional()
57311
57409
  }));
57312
57410
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
57411
+ value: PxKeyframeValueSchema.optional(),
57313
57412
  keyframes: px.array(PxKeyframeSchema).optional(),
57314
57413
  kfs: px.array(PxKeyframeSchema).optional(),
57315
57414
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
@@ -57324,6 +57423,7 @@ ${codeFrame}` : message);
57324
57423
  }));
57325
57424
  var PxTransformValueSchema = px.union([
57326
57425
  px.string(),
57426
+ PxTransformPartsSchema,
57327
57427
  px.object({ value: PxTransformPartsSchema }),
57328
57428
  PxPropertyAnimationSchema
57329
57429
  ]);
@@ -57358,9 +57458,11 @@ ${codeFrame}` : message);
57358
57458
  glyphs: px.record(PxGlyphFontSchema).optional()
57359
57459
  }));
57360
57460
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
57361
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
57461
+ mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
57362
57462
  duration: px.number().optional(),
57363
57463
  delay: px.number().optional(),
57464
+ // LAW (SCHEMA-DESIGN R3, S10): the ONE sanctioned string-in-number union
57465
+ // (CSS animation-iteration-count familiarity) — do not add more mixed unions.
57364
57466
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
57365
57467
  fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
57366
57468
  direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
@@ -57368,8 +57470,8 @@ ${codeFrame}` : message);
57368
57470
  trigger: PxTriggerSchema.optional(),
57369
57471
  resetOnFinish: px.boolean().optional(),
57370
57472
  definitions: PxDefsSchema.optional(),
57371
- animate: px.record(PxElementAnimationSchema).optional(),
57372
- debug: px.boolean().optional(),
57473
+ animateById: px.record(PxElementAnimationSchema).optional(),
57474
+ timelineSource: px.string().optional(),
57373
57475
  debugInstName: px.string().optional()
57374
57476
  }));
57375
57477
  var PxBindingSchema = implementsInterface()(px.object({
@@ -57379,26 +57481,29 @@ ${codeFrame}` : message);
57379
57481
  var PxAttrValueSchema = px.union([
57380
57482
  px.string(),
57381
57483
  px.number(),
57382
- px.object({ value: px.any() }),
57383
- PxPropertyAnimationSchema
57484
+ px.array(px.number()),
57485
+ // Structured static — `{value: …}` (read-accepted transitional spelling, S1).
57486
+ // `defined`, not `any`: the KEY's presence is what identifies this branch (V6).
57487
+ px.object({ value: px.defined() }),
57488
+ // Bare transform parts record — the canonical static `transform` on the wire (T2).
57489
+ PxTransformPartsSchema
57384
57490
  ]);
57385
57491
  var PxAnimatableNumberSchema = px.union([
57386
57492
  px.number(),
57387
57493
  px.object({ value: px.number() }),
57388
- px.object({
57389
- keyframes: px.array(PxKeyframeSchema),
57390
- autoOrient: px.boolean().optional()
57391
- })
57494
+ PxPropertyAnimationSchema
57392
57495
  ]);
57393
57496
  var PxAnimatableVec2Schema = px.union([
57394
57497
  px.tuple([px.number(), px.number()]),
57395
57498
  px.object({ value: px.tuple([px.number(), px.number()]) }),
57396
- px.object({
57397
- keyframes: px.array(PxKeyframeSchema),
57398
- autoOrient: px.boolean().optional()
57399
- })
57499
+ PxPropertyAnimationSchema
57400
57500
  ]);
57401
- var PxTransformationEffectSchema = implementsInterface()(px.object({
57501
+ var PxAnimatableStringSchema = px.union([
57502
+ px.string(),
57503
+ px.object({ value: px.string() }),
57504
+ PxPropertyAnimationSchema
57505
+ ]);
57506
+ var PxTransformByEffectSchema = implementsInterface()(px.object({
57402
57507
  translate: PxAnimatableVec2Schema.optional(),
57403
57508
  rotate: PxAnimatableNumberSchema.optional(),
57404
57509
  scale: PxAnimatableVec2Schema.optional(),
@@ -57406,42 +57511,46 @@ ${codeFrame}` : message);
57406
57511
  origin: PxAnimatableVec2Schema.optional()
57407
57512
  }));
57408
57513
  var PxRepeaterEffectSchema = implementsInterface()(px.object({
57514
+ // STATIC config, not a channel (V2/SCHEMA-DESIGN R5): the copy COUNT is read
57515
+ // once at expansion time and never sampled — plain number, no `keyframes`.
57409
57516
  copies: px.number().optional(),
57410
57517
  translate: PxAnimatableVec2Schema.optional(),
57411
57518
  rotate: PxAnimatableNumberSchema.optional(),
57519
+ skew: PxAnimatableNumberSchema.optional(),
57412
57520
  scale: PxAnimatableVec2Schema.optional(),
57413
57521
  origin: PxAnimatableVec2Schema.optional()
57414
57522
  }));
57415
57523
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
57416
- href: px.string().optional(),
57417
- maskType: px.string().optional(),
57418
- maskUnits: px.string().optional(),
57419
- maskContentUnits: px.string().optional()
57524
+ sourceId: px.string().optional(),
57525
+ maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
57526
+ maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
57527
+ maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
57528
+ x: px.number().optional(),
57529
+ y: px.number().optional(),
57530
+ width: px.number().optional(),
57531
+ height: px.number().optional()
57420
57532
  }));
57421
57533
  var PxClipPathEffectSchema = implementsInterface()(px.object({
57422
- d: px.string().optional(),
57534
+ d: PxAnimatableStringSchema.optional(),
57423
57535
  animate: PxPropertyAnimationSchema.optional()
57424
57536
  }));
57425
57537
  var PxTrimPathEffectSchema = implementsInterface()(px.object({
57426
57538
  offset: PxAnimatableNumberSchema.optional(),
57427
57539
  range: PxAnimatableVec2Schema.optional(),
57428
- trimAllAsOne: px.boolean().optional()
57540
+ subPaths: px.enum([PxTrimSubPaths.separate, PxTrimSubPaths.combined]).optional()
57429
57541
  }));
57430
57542
  var PxRetimeEffectSchema = implementsInterface()(px.object({
57431
- baseId: px.string().optional(),
57543
+ sourceId: px.string().optional(),
57432
57544
  start: px.number().optional(),
57433
57545
  stretch: px.number().optional(),
57434
57546
  timeCrop: px.tuple([px.number(), px.number()]).optional()
57435
57547
  }));
57436
57548
  var PxCloneEffectSchema = implementsInterface()(px.object({
57437
- type: px.string().optional(),
57438
- baseId: px.string().optional(),
57549
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
57550
+ type: px.enum([PxCloneType.content]).optional(),
57551
+ sourceId: px.string().optional(),
57439
57552
  retime: PxRetimeEffectSchema.optional()
57440
57553
  }));
57441
- var PxGradientType = {
57442
- linear: "linear",
57443
- radial: "radial"
57444
- };
57445
57554
  var PxGradientStopSchema = implementsInterface()(px.object({
57446
57555
  offset: px.number(),
57447
57556
  color: px.string()
@@ -57449,27 +57558,28 @@ ${codeFrame}` : message);
57449
57558
  var PxAnimatableGradientStopsSchema = px.union([
57450
57559
  px.array(PxGradientStopSchema),
57451
57560
  px.object({ value: px.array(PxGradientStopSchema) }),
57452
- px.object({ keyframes: px.array(PxKeyframeSchema) })
57561
+ PxPropertyAnimationSchema
57453
57562
  ]);
57454
57563
  var PxFillGradientEffectSchema = implementsInterface()(px.object({
57564
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
57455
57565
  type: px.enum([PxGradientType.linear, PxGradientType.radial]),
57456
- p1: px.tuple([px.number(), px.number()]).optional(),
57457
- p2: px.tuple([px.number(), px.number()]).optional(),
57458
- c: px.tuple([px.number(), px.number()]).optional(),
57459
- r: px.number().optional(),
57460
- fp: px.tuple([px.number(), px.number()]).optional(),
57566
+ p1: PxAnimatableVec2Schema.optional(),
57567
+ p2: PxAnimatableVec2Schema.optional(),
57568
+ c: PxAnimatableVec2Schema.optional(),
57569
+ r: PxAnimatableNumberSchema.optional(),
57570
+ fp: PxAnimatableVec2Schema.optional(),
57461
57571
  stops: PxAnimatableGradientStopsSchema.optional(),
57462
- gradientUnits: px.string().optional(),
57463
- spreadMethod: px.string().optional(),
57572
+ gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
57573
+ spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
57464
57574
  gradientTransform: px.string().optional()
57465
57575
  }));
57466
57576
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
57467
57577
  var PxTextPathEffectSchema = implementsInterface()(px.object({
57468
57578
  path: px.string(),
57469
- pathOverflow: px.string().optional(),
57470
- lengthAdjust: px.string().optional(),
57471
- method: px.string().optional(),
57472
- spacing: px.string().optional(),
57579
+ pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
57580
+ lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
57581
+ method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
57582
+ spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
57473
57583
  startOffset: PxAnimatableNumberSchema.optional(),
57474
57584
  textLength: PxAnimatableNumberSchema.optional()
57475
57585
  }));
@@ -57477,13 +57587,12 @@ ${codeFrame}` : message);
57477
57587
  useGlyphs: px.boolean().optional()
57478
57588
  }));
57479
57589
  var PxEffectsSchema = implementsInterface()(px.object({
57480
- transformation: PxTransformationEffectSchema.optional(),
57590
+ transformBy: PxTransformByEffectSchema.optional(),
57481
57591
  repeater: PxRepeaterEffectSchema.optional(),
57482
57592
  maskedBy: PxMaskedByEffectSchema.optional(),
57483
57593
  clipPath: PxClipPathEffectSchema.optional(),
57484
57594
  trimPath: PxTrimPathEffectSchema.optional(),
57485
57595
  clone: PxCloneEffectSchema.optional(),
57486
- isCombinedShape: px.boolean().optional(),
57487
57596
  fillGradient: PxFillGradientEffectSchema.optional(),
57488
57597
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
57489
57598
  textPath: PxTextPathEffectSchema.optional(),
@@ -57507,6 +57616,14 @@ ${codeFrame}` : message);
57507
57616
  return warnings;
57508
57617
  }
57509
57618
  var PxNodeBase = px.openObject({
57619
+ // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
57620
+ // kind of thing is this", discriminated by its CARRIER — here the node TAG
57621
+ // (`rect`, `text`), and inside a sub-object that object's kind (`clone.type`,
57622
+ // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
57623
+ // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
57624
+ // would add words that all mean "type" and still need the carrier to read.
57625
+ // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
57626
+ // (issues V3), never of distinct key names.
57510
57627
  type: px.string(),
57511
57628
  id: px.string().optional(),
57512
57629
  meta: px.any().optional(),
@@ -57516,7 +57633,7 @@ ${codeFrame}` : message);
57516
57633
  effects: PxEffectsSchema.optional(),
57517
57634
  // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
57518
57635
  // string ref / array of refs / inline definition / mixed array; mirrors
57519
- // `animator.animate` map values and what `processNode` resolves at runtime.
57636
+ // `animator.animateById` map values and what `processNode` resolves at runtime.
57520
57637
  animate: PxElementAnimationSchema.optional(),
57521
57638
  style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
57522
57639
  }, PxAttrValueSchema);
@@ -57540,28 +57657,6 @@ ${codeFrame}` : message);
57540
57657
  o: px.array(px.array(px.number())).optional(),
57541
57658
  c: px.boolean().optional()
57542
57659
  }));
57543
- function isPxElementFileFormat(fileJson) {
57544
- if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
57545
- return false;
57546
- }
57547
- return fileJson["type"] === "svg" || fileJson["tagName"] === "svg";
57548
- }
57549
- function getAnimatorConfig(doc) {
57550
- var _a, _b;
57551
- return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator) || (doc == null ? void 0 : doc.animation) || ((_b = doc == null ? void 0 : doc.meta) == null ? void 0 : _b.animation);
57552
- }
57553
- function getDefs(doc) {
57554
- var _a;
57555
- if (!doc) return void 0;
57556
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
57557
- }
57558
- function getBindings(doc) {
57559
- var _a;
57560
- if (!doc) return void 0;
57561
- const animate = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animate;
57562
- if (!animate) return void 0;
57563
- return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));
57564
- }
57565
57660
  function bezierToSvgPath(path, forceCurves = false) {
57566
57661
  var _a, _b, _c, _d;
57567
57662
  const v = path.v;
@@ -58012,7 +58107,7 @@ ${codeFrame}` : message);
58012
58107
  "flood-color",
58013
58108
  "lighting-color"
58014
58109
  ]);
58015
- const directIdRefAttrs = /* @__PURE__ */ new Set(["baseId", "targetId", "boundElementId"]);
58110
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["sourceId", "targetId", "boundElementId"]);
58016
58111
  function collectIds(node) {
58017
58112
  if (!node || typeof node !== "object") return;
58018
58113
  if (node.id && typeof node.id === "string") {
@@ -58050,9 +58145,10 @@ ${codeFrame}` : message);
58050
58145
  } else if (urlRefAttrs.has(key)) {
58051
58146
  node[key] = replaceUrlRefs(value, idMap);
58052
58147
  } else if (directIdRefAttrs.has(key)) {
58053
- const newId = idMap.get(value);
58148
+ const hasHash = value.startsWith("#");
58149
+ const newId = idMap.get(hasHash ? value.slice(1) : value);
58054
58150
  if (newId) {
58055
- node[key] = newId;
58151
+ node[key] = hasHash ? "#" + newId : newId;
58056
58152
  }
58057
58153
  } else if (value.includes("url(#")) {
58058
58154
  node[key] = replaceUrlRefs(value, idMap);
@@ -58070,14 +58166,14 @@ ${codeFrame}` : message);
58070
58166
  }
58071
58167
  collectIds(cloned);
58072
58168
  updateRefs(cloned);
58073
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animate;
58169
+ const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
58074
58170
  if (docAnimate && typeof docAnimate === "object") {
58075
58171
  const updatedAnimate = {};
58076
58172
  for (const [id, anim] of Object.entries(docAnimate)) {
58077
58173
  const newId = (_b = idMap.get(id)) != null ? _b : id;
58078
58174
  updatedAnimate[newId] = anim;
58079
58175
  }
58080
- cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animate: updatedAnimate });
58176
+ cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animateById: updatedAnimate });
58081
58177
  }
58082
58178
  return cloned;
58083
58179
  }
@@ -58166,8 +58262,9 @@ ${codeFrame}` : message);
58166
58262
  let value = props[rawKey];
58167
58263
  if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
58168
58264
  propsCopy[key] = toRGBA(value);
58169
- } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
58170
- propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
58265
+ } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes && !value.kfs) {
58266
+ const parts = value.value && typeof value.value === "object" ? value.value : value;
58267
+ propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
58171
58268
  } else if (TRANSFORM_FN_NAMES.has(key)) {
58172
58269
  if (Array.isArray(value)) {
58173
58270
  if (key === "translate") value = value.map((v) => v + "px");
@@ -58175,6 +58272,8 @@ ${codeFrame}` : message);
58175
58272
  }
58176
58273
  if (key === "rotate") value = value + "deg";
58177
58274
  propsCopy["transform"] = key + "(" + value + ")";
58275
+ } else if (Array.isArray(value)) {
58276
+ propsCopy[key] = value.join(",");
58178
58277
  } else if (value !== void 0 && value !== null) {
58179
58278
  propsCopy[key] = String(value);
58180
58279
  }
@@ -58572,6 +58671,16 @@ ${codeFrame}` : message);
58572
58671
  if (newAnimate) cloned.animate = newAnimate;
58573
58672
  return cloned;
58574
58673
  }
58674
+ var LOOP_JUMP_SHIFT_MS = 10;
58675
+ function deepEqualValue(a, b) {
58676
+ if (a === b) return true;
58677
+ if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
58678
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
58679
+ const ka = Object.keys(a);
58680
+ const kb = Object.keys(b);
58681
+ if (ka.length !== kb.length) return false;
58682
+ return ka.every((k) => deepEqualValue(a[k], b[k]));
58683
+ }
58575
58684
  function parsePathCommands(d) {
58576
58685
  const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
58577
58686
  const commands = [];
@@ -58774,7 +58883,7 @@ ${codeFrame}` : message);
58774
58883
  const totalIntervals = keyframes.length - 1;
58775
58884
  const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
58776
58885
  let segKfs;
58777
- if (loop.before) {
58886
+ if (loop.extend === PxLoopExtend.before) {
58778
58887
  segKfs = keyframes.slice(0, segCount + 1);
58779
58888
  } else {
58780
58889
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -58782,7 +58891,7 @@ ${codeFrame}` : message);
58782
58891
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
58783
58892
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
58784
58893
  let fillStart, fillEnd;
58785
- if (loop.before) {
58894
+ if (loop.extend === PxLoopExtend.before) {
58786
58895
  fillStart = 0;
58787
58896
  fillEnd = firstT;
58788
58897
  } else {
@@ -58809,7 +58918,10 @@ ${codeFrame}` : message);
58809
58918
  const remainder = fillDuration - fullReps * segDuration;
58810
58919
  const partialFraction = remainder / segDuration;
58811
58920
  const looped = [];
58921
+ const separateBoundary = loop.extend !== PxLoopExtend.before;
58922
+ const originalTerminalKf = keyframes[keyframes.length - 1];
58812
58923
  function appendRep(repStart, isReversed, partial) {
58924
+ var _a2;
58813
58925
  let entries;
58814
58926
  if (isReversed) {
58815
58927
  entries = [];
@@ -58845,8 +58957,17 @@ ${codeFrame}` : message);
58845
58957
  looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
58846
58958
  return;
58847
58959
  }
58960
+ const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
58961
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
58962
+ if (isBoundary) {
58963
+ if (deepEqualValue(prevKf.v, entry.v)) continue;
58964
+ if (looped.length > 0) {
58965
+ delete prevKf.tangentIn;
58966
+ delete prevKf.tangentOut;
58967
+ }
58968
+ }
58848
58969
  const pushed = {
58849
- t: repStart + entry.relT * segDuration,
58970
+ t: repStart + entry.relT * segDuration + (isBoundary ? LOOP_JUMP_SHIFT_MS : 0),
58850
58971
  v: entry.v,
58851
58972
  e: i < entries.length - 1 ? entry.e : void 0
58852
58973
  };
@@ -58894,7 +59015,7 @@ ${codeFrame}` : message);
58894
59015
  looped.push(pushed);
58895
59016
  }
58896
59017
  }
58897
- if (loop.before) {
59018
+ if (loop.extend === PxLoopExtend.before) {
58898
59019
  if (partialFraction > 1e-9) {
58899
59020
  const isReversed = !!loop.alternate && fullReps % 2 === 0;
58900
59021
  appendRepTail(fillStart, isReversed, partialFraction);
@@ -58917,7 +59038,7 @@ ${codeFrame}` : message);
58917
59038
  appendRep(repStart, isReversed, partialFraction);
58918
59039
  }
58919
59040
  }
58920
- if (loop.before) {
59041
+ if (loop.extend === PxLoopExtend.before) {
58921
59042
  return [...looped, ...keyframes];
58922
59043
  } else {
58923
59044
  return [...keyframes, ...looped];
@@ -59033,7 +59154,7 @@ ${codeFrame}` : message);
59033
59154
  function generateElementId() {
59034
59155
  return "_px_el_" + ++_elementIdCounter;
59035
59156
  }
59036
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.webapi) {
59157
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
59037
59158
  const normalized = {};
59038
59159
  for (const [propName, propAnim] of Object.entries(animDef)) {
59039
59160
  const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
@@ -59041,12 +59162,12 @@ ${codeFrame}` : message);
59041
59162
  const out = { kfs: normalizedKfs };
59042
59163
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
59043
59164
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
59044
- normalized[propName] = engine === PxAnimatorEngine.webapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
59165
+ normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
59045
59166
  }
59046
59167
  }
59047
59168
  return normalized;
59048
59169
  }
59049
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.webapi) {
59170
+ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
59050
59171
  const animatorConfig = getAnimatorConfig(doc) || {};
59051
59172
  const defs = getDefs(doc);
59052
59173
  const duration = animatorConfig.duration || 1e3;
@@ -59451,6 +59572,7 @@ ${codeFrame}` : message);
59451
59572
  return rec;
59452
59573
  }
59453
59574
  function readAnimatable(raw) {
59575
+ var _a, _b, _c;
59454
59576
  if (raw === void 0) return {
59455
59577
  kind: "absent"
59456
59578
  /* Absent */
@@ -59458,19 +59580,56 @@ ${codeFrame}` : message);
59458
59580
  if (Array.isArray(raw)) return { kind: "static", value: raw };
59459
59581
  if (typeof raw === "object") {
59460
59582
  const obj = raw;
59461
- if (obj.keyframes) {
59462
- return { kind: "animated", keyframes: obj.keyframes, autoOrient: obj.autoOrient, loop: obj.loop };
59583
+ const kfs = (_a = obj.keyframes) != null ? _a : obj.kfs;
59584
+ if (kfs) {
59585
+ const out = { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
59586
+ const base = (_b = obj.value) != null ? _b : obj.v;
59587
+ if (base !== void 0 && out.kind === "animated") out.base = base;
59588
+ return out;
59463
59589
  }
59464
- if (obj.value !== void 0) return { kind: "static", value: obj.value };
59590
+ const staticValue = (_c = obj.value) != null ? _c : obj.v;
59591
+ if (staticValue !== void 0) return { kind: "static", value: staticValue };
59465
59592
  }
59466
59593
  return { kind: "static", value: raw };
59467
59594
  }
59595
+ function writeAnimatableChannel(node, attrName, read, opts) {
59596
+ var _a, _b, _c, _d;
59597
+ const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
59598
+ if (read.kind === "absent") return;
59599
+ if (read.kind === "static") {
59600
+ node[attrName] = toOut(read.value);
59601
+ return;
59602
+ }
59603
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
59604
+ const animate = __spreadValues2({}, prevAnimate || {});
59605
+ const block = { keyframes: read.keyframes };
59606
+ if (read.loop !== void 0) block.loop = read.loop;
59607
+ if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
59608
+ animate[attrName] = block;
59609
+ node.animate = animate;
59610
+ 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;
59611
+ if (baseline !== void 0) node[attrName] = toOut(baseline);
59612
+ }
59613
+ function normaliseKeyframe(kf) {
59614
+ if (!kf || typeof kf !== "object") return kf;
59615
+ const k = kf;
59616
+ if (k.t === void 0 && k.v === void 0 && k.e === void 0 && k.to === void 0 && k.ti === void 0) {
59617
+ return kf;
59618
+ }
59619
+ const out = __spreadValues2({}, k);
59620
+ if (out.time === void 0 && k.t !== void 0) out.time = k.t;
59621
+ if (out.value === void 0 && k.v !== void 0) out.value = k.v;
59622
+ if (out.easing === void 0 && k.e !== void 0) out.easing = k.e;
59623
+ if (out.tangentOut === void 0 && k.to !== void 0) out.tangentOut = k.to;
59624
+ if (out.tangentIn === void 0 && k.ti !== void 0) out.tangentIn = k.ti;
59625
+ return out;
59626
+ }
59468
59627
  function readStaticOrigin(raw, ctx) {
59469
59628
  var _a;
59470
59629
  const o = readAnimatable(raw);
59471
59630
  if (o.kind === "absent") return void 0;
59472
59631
  if (o.kind === "static") return o.value;
59473
- ctx.warnings.push("transformation.origin: animated origin approximated by its first keyframe");
59632
+ ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
59474
59633
  return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
59475
59634
  }
59476
59635
  function keyframeWith(kf, value) {
@@ -59481,7 +59640,7 @@ ${codeFrame}` : message);
59481
59640
  if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
59482
59641
  return out;
59483
59642
  }
59484
- function applyTransformationEffect(node, fx, ctx) {
59643
+ function applyTransformByEffect(node, fx, ctx) {
59485
59644
  if (!fx) return node;
59486
59645
  delete node.transform;
59487
59646
  let n = node;
@@ -59517,6 +59676,10 @@ ${codeFrame}` : message);
59517
59676
  } else {
59518
59677
  n = wrapTransformPart(n, "translate", fx.translate, ctx);
59519
59678
  }
59679
+ if (n !== node && node.id) {
59680
+ n.id = node.id;
59681
+ delete node.id;
59682
+ }
59520
59683
  return n;
59521
59684
  }
59522
59685
  function translateHasAutoOrient(translate) {
@@ -59526,8 +59689,6 @@ ${codeFrame}` : message);
59526
59689
  return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
59527
59690
  }
59528
59691
  function normalizeScale(raw) {
59529
- if (raw === void 0) return void 0;
59530
- if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100];
59531
59692
  return raw;
59532
59693
  }
59533
59694
  function wrapTransformPart(inner, part, raw, ctx) {
@@ -59568,34 +59729,54 @@ ${codeFrame}` : message);
59568
59729
  }
59569
59730
  return inner;
59570
59731
  }
59732
+ function genId(ctx, prefix) {
59733
+ return "_lw_" + prefix + "_" + ctx.nextId++;
59734
+ }
59735
+ function stripHash2(href) {
59736
+ return typeof href === "string" ? href.replace(/^#/, "") : void 0;
59737
+ }
59738
+ function indexById(node, map) {
59739
+ var _a;
59740
+ if (typeof node.id === "string") map.set(node.id, node);
59741
+ (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
59742
+ }
59743
+ function spliceDefs(root, defs) {
59744
+ if (!defs.length) return;
59745
+ const existing = root.children || (root.children = []);
59746
+ existing.unshift({ type: "defs", children: defs });
59747
+ }
59748
+ var clone = deepClonePxNode;
59749
+ function regenerateIdsInClone(root, ctx) {
59750
+ return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
59751
+ }
59571
59752
  function identifyContentRefTargets(node, ctx, allocator) {
59572
59753
  var _a, _b, _c;
59573
59754
  if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
59574
- const baseId = node.effects.clone.baseId;
59575
- if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
59576
- ctx.contentRefInnerIds.set(baseId, allocator(baseId));
59755
+ const sourceId = stripHash2(node.effects.clone.sourceId);
59756
+ if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
59757
+ ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
59577
59758
  }
59578
59759
  }
59579
59760
  (_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
59580
59761
  }
59581
- function splitForContentRef(node, transformation, originalId, innerId, ctx) {
59582
- const outerBody = liftBodyTranslate(node, transformation);
59762
+ function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
59763
+ const outerBody = liftBodyTranslate(node, transformBy);
59583
59764
  if (typeof node.id === "string") delete node.id;
59584
- const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);
59765
+ const { outer: outerTr, inner: innerTr } = splitTransformByEffect(transformBy);
59585
59766
  let innerNode = node;
59586
- innerNode = applyTransformationEffect(innerNode, innerTr, ctx);
59767
+ innerNode = applyTransformByEffect(innerNode, innerTr, ctx);
59587
59768
  const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
59588
59769
  let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
59589
59770
  if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
59590
59771
  if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
59591
59772
  if (outerTr) {
59592
59773
  delete outerWrapper.id;
59593
- outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);
59774
+ outerWrapper = applyTransformByEffect(outerWrapper, outerTr, ctx);
59594
59775
  outerWrapper.id = originalId;
59595
59776
  }
59596
59777
  return outerWrapper;
59597
59778
  }
59598
- function liftBodyTranslate(node, transformation) {
59779
+ function liftBodyTranslate(node, transformBy) {
59599
59780
  var _a, _b, _c;
59600
59781
  const out = {};
59601
59782
  let didLiftAnimate = false;
@@ -59649,7 +59830,7 @@ ${codeFrame}` : message);
59649
59830
  didLiftAnimate = true;
59650
59831
  }
59651
59832
  }
59652
- const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
59833
+ const transformationHasTranslate = (transformBy == null ? void 0 : transformBy.translate) !== void 0;
59653
59834
  const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
59654
59835
  const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
59655
59836
  if (typeof node.transform === "string") {
@@ -59668,6 +59849,24 @@ ${codeFrame}` : message);
59668
59849
  if (split.rest) node.transform = split.rest;
59669
59850
  else delete node.transform;
59670
59851
  }
59852
+ } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes && !node.transform.kfs) {
59853
+ const wrapped = node.transform.value;
59854
+ const isWrapped = !!(wrapped && typeof wrapped === "object");
59855
+ const value = isWrapped ? wrapped : node.transform;
59856
+ const rewrap = (rec) => isWrapped ? { value: rec } : rec;
59857
+ if (Array.isArray(value.translate)) {
59858
+ const rest = __spreadValues2({}, value);
59859
+ delete rest.translate;
59860
+ const hasRest = Object.keys(rest).length > 0;
59861
+ if (stripBodyTranslateOnly) {
59862
+ if (hasRest) node.transform = rewrap(rest);
59863
+ else delete node.transform;
59864
+ } else {
59865
+ out.transform = rewrap({ translate: value.translate });
59866
+ if (hasRest) node.transform = rewrap(rest);
59867
+ else delete node.transform;
59868
+ }
59869
+ }
59671
59870
  }
59672
59871
  return out;
59673
59872
  }
@@ -59737,7 +59936,7 @@ ${codeFrame}` : message);
59737
59936
  const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
59738
59937
  return [nums[0] || 0, nums[1] || 0];
59739
59938
  }
59740
- function splitTransformationEffect(fx) {
59939
+ function splitTransformByEffect(fx) {
59741
59940
  if (!fx) return {};
59742
59941
  const originOnOuter = needsOriginOnOuter(fx.translate);
59743
59942
  const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
@@ -59763,26 +59962,6 @@ ${codeFrame}` : message);
59763
59962
  }
59764
59963
  return false;
59765
59964
  }
59766
- function genId(ctx, prefix) {
59767
- return "_lw_" + prefix + "_" + ctx.nextId++;
59768
- }
59769
- function stripHash2(href) {
59770
- return typeof href === "string" ? href.replace(/^#/, "") : void 0;
59771
- }
59772
- function indexById(node, map) {
59773
- var _a;
59774
- if (typeof node.id === "string") map.set(node.id, node);
59775
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
59776
- }
59777
- function spliceDefs(root, defs) {
59778
- if (!defs.length) return;
59779
- const existing = root.children || (root.children = []);
59780
- existing.unshift({ type: "defs", children: defs });
59781
- }
59782
- var clone = deepClonePxNode;
59783
- function regenerateIdsInClone(root, ctx) {
59784
- return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
59785
- }
59786
59965
  function applyFillGradientEffect(node, fx, ctx) {
59787
59966
  return applyGradient(node, fx, ctx, "fill");
59788
59967
  }
@@ -59803,62 +59982,63 @@ ${codeFrame}` : message);
59803
59982
  id
59804
59983
  };
59805
59984
  if (fx.type === PxGradientType.linear) {
59806
- if (fx.p1) {
59807
- out.x1 = String(fx.p1[0]);
59808
- out.y1 = String(fx.p1[1]);
59809
- }
59810
- if (fx.p2) {
59811
- out.x2 = String(fx.p2[0]);
59812
- out.y2 = String(fx.p2[1]);
59813
- }
59985
+ applyGeomVec(out, "x1", "y1", fx.p1);
59986
+ applyGeomVec(out, "x2", "y2", fx.p2);
59814
59987
  } else {
59815
- if (fx.c) {
59816
- out.cx = String(fx.c[0]);
59817
- out.cy = String(fx.c[1]);
59818
- }
59819
- if (fx.r !== void 0) out.r = String(fx.r);
59820
- if (fx.fp) {
59821
- out.fx = String(fx.fp[0]);
59822
- out.fy = String(fx.fp[1]);
59823
- }
59988
+ applyGeomVec(out, "cx", "cy", fx.c);
59989
+ applyGeomNumber(out, "r", fx.r);
59990
+ applyGeomVec(out, "fx", "fy", fx.fp);
59824
59991
  }
59825
59992
  if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
59826
59993
  if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
59827
59994
  if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
59828
- const animate = fx.animate;
59829
- if (animate) {
59830
- const mapped = {};
59831
- for (const wireKey of Object.keys(animate)) {
59832
- const attr = GRADIENT_ANIM_CHANNEL_TO_ATTR[wireKey];
59833
- if (attr) mapped[attr] = animate[wireKey];
59834
- }
59835
- if (Object.keys(mapped).length) out.animate = mapped;
59836
- }
59837
59995
  out.children = buildStopChildren(fx.stops, ctx);
59838
59996
  return out;
59839
59997
  }
59840
- var GRADIENT_ANIM_CHANNEL_TO_ATTR = {
59841
- gradientX1: "x1",
59842
- gradientY1: "y1",
59843
- gradientX2: "x2",
59844
- gradientY2: "y2",
59845
- gradientCx: "cx",
59846
- gradientCy: "cy",
59847
- gradientFx: "fx",
59848
- gradientFy: "fy",
59849
- gradientR: "r"
59850
- };
59998
+ function applyGeomVec(out, xAttr, yAttr, raw) {
59999
+ var _a, _b, _c;
60000
+ const read = readAnimatable(raw);
60001
+ if (read.kind === "absent") return;
60002
+ if (read.kind === "static") {
60003
+ out[xAttr] = String(read.value[0]);
60004
+ out[yAttr] = String(read.value[1]);
60005
+ return;
60006
+ }
60007
+ const axisChannel = (idx) => {
60008
+ const block = {
60009
+ keyframes: read.keyframes.map((kf) => {
60010
+ const axisKf = { time: kf.time, value: Array.isArray(kf.value) ? kf.value[idx] : void 0 };
60011
+ if (kf.easing !== void 0) axisKf.easing = kf.easing;
60012
+ return axisKf;
60013
+ })
60014
+ };
60015
+ if (read.loop !== void 0) block.loop = read.loop;
60016
+ return block;
60017
+ };
60018
+ const animate = (_a = out.animate) != null ? _a : {};
60019
+ animate[xAttr] = axisChannel(0);
60020
+ animate[yAttr] = axisChannel(1);
60021
+ out.animate = animate;
60022
+ const baseline = (_c = read.base) != null ? _c : (_b = read.keyframes[0]) == null ? void 0 : _b.value;
60023
+ if (Array.isArray(baseline)) {
60024
+ out[xAttr] = String(baseline[0]);
60025
+ out[yAttr] = String(baseline[1]);
60026
+ }
60027
+ }
60028
+ function applyGeomNumber(out, attrName, raw) {
60029
+ const read = readAnimatable(raw);
60030
+ if (read.kind === "absent") return;
60031
+ writeAnimatableChannel(out, attrName, read, { asString: true });
60032
+ }
59851
60033
  function buildStopChildren(stops, ctx) {
59852
60034
  var _a, _b, _c, _d;
59853
60035
  if (!stops) return [];
59854
- if (Array.isArray(stops)) return stops.map(staticStopNode);
59855
- if (typeof stops === "object" && Array.isArray(stops.value)) {
59856
- return stops.value.map(staticStopNode);
59857
- }
59858
- const animBlock = stops;
59859
- const kfs = animBlock.keyframes;
59860
- if (!Array.isArray(kfs) || !kfs.length) return [];
59861
- const loopFromSource = animBlock.loop;
60036
+ const read = readAnimatable(stops);
60037
+ if (read.kind === "absent") return [];
60038
+ if (read.kind === "static") return Array.isArray(read.value) ? read.value.map(staticStopNode) : [];
60039
+ const kfs = read.keyframes;
60040
+ if (!kfs.length) return [];
60041
+ const loopFromSource = read.loop;
59862
60042
  let stopCount = 0;
59863
60043
  for (const kf of kfs) {
59864
60044
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -59933,36 +60113,60 @@ ${codeFrame}` : message);
59933
60113
  return pct + "%";
59934
60114
  }
59935
60115
  function applyClipPathEffect(node, fx, ctx) {
60116
+ var _a, _b;
59936
60117
  if (!fx || !fx.d && !fx.animate) return node;
59937
60118
  const clipId = genId(ctx, "clip");
59938
- const pathChild = { type: "path", d: fx.d };
59939
- if (fx.animate) pathChild.animate = { d: fx.animate };
60119
+ const pathChild = { type: "path" };
60120
+ const read = readAnimatable(fx.d);
60121
+ if (read.kind !== "absent") {
60122
+ if (read.kind === "static") {
60123
+ pathChild.d = pathString(read.value);
60124
+ } else {
60125
+ writeAnimatableChannel(pathChild, "d", read);
60126
+ if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
60127
+ }
60128
+ }
60129
+ if (fx.animate && !((_a = pathChild.animate) == null ? void 0 : _a.d)) {
60130
+ const animate = (_b = pathChild.animate) != null ? _b : {};
60131
+ animate.d = fx.animate;
60132
+ pathChild.animate = animate;
60133
+ }
59940
60134
  ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
59941
60135
  node.clipPath = "url(#" + clipId + ")";
59942
60136
  return node;
59943
60137
  }
59944
- function applyMaskedByEffect(node, fx, transformation, ctx) {
60138
+ function pathString(v) {
60139
+ if (typeof v === "string") return v;
60140
+ if (v && typeof v === "object" && typeof v.path === "string") return v.path;
60141
+ return void 0;
60142
+ }
60143
+ function applyMaskedByEffect(node, fx, transformBy, ctx) {
59945
60144
  if (!fx) return node;
59946
- if (!fx.href) {
59947
- ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
60145
+ const sourceId = stripHash2(fx.sourceId);
60146
+ if (!sourceId) {
60147
+ ctx.errors.push("maskedBy.sourceId missing \u2014 cannot build mask");
59948
60148
  return node;
59949
60149
  }
59950
60150
  const maskId = genId(ctx, "mask");
59951
- let content = { type: "use", href: "#" + fx.href };
59952
- if (transformation) {
59953
- content = wrapInverseTransform(content, transformation, ctx);
60151
+ let content = { type: "use", href: "#" + sourceId };
60152
+ if (transformBy) {
60153
+ content = wrapInverseTransform(content, transformBy, ctx);
59954
60154
  } else if (hasAnimateTransform(node)) {
59955
60155
  content = wrapInverseAnimatedBodyTransform(content, node, ctx);
59956
60156
  } else {
59957
60157
  const bodyStatic = readTransformationFromBody(node);
59958
60158
  if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
59959
60159
  }
59960
- const includeTargetOwn = transformation === void 0 && !nodeHasBodyTransform(node);
59961
- content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);
60160
+ const includeTargetOwn = transformBy === void 0 && !nodeHasBodyTransform(node);
60161
+ content = wrapAncestorChainCompensation(content, node, sourceId, ctx, includeTargetOwn);
59962
60162
  const mask = { type: "mask", id: maskId, children: [content] };
59963
60163
  if (fx.maskType) mask.maskType = fx.maskType;
59964
60164
  if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
59965
60165
  if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
60166
+ if (fx.x !== void 0) mask.x = String(fx.x);
60167
+ if (fx.y !== void 0) mask.y = String(fx.y);
60168
+ if (fx.width !== void 0) mask.width = String(fx.width);
60169
+ if (fx.height !== void 0) mask.height = String(fx.height);
59966
60170
  ctx.defs.push(mask);
59967
60171
  node.mask = "url(#" + maskId + ")";
59968
60172
  return node;
@@ -60069,6 +60273,19 @@ ${codeFrame}` : message);
60069
60273
  if (parts.origin) out.origin = parts.origin;
60070
60274
  return Object.keys(out).length ? out : void 0;
60071
60275
  }
60276
+ if (node.transform && typeof node.transform === "object" && !node.transform.keyframes && !node.transform.kfs) {
60277
+ const wrapped = node.transform.value;
60278
+ const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
60279
+ if (value && typeof value === "object") {
60280
+ const out = {};
60281
+ if (Array.isArray(value.translate)) out.translate = value.translate;
60282
+ if (typeof value.rotate === "number") out.rotate = value.rotate;
60283
+ if (typeof value.skew === "number") out.skew = value.skew;
60284
+ if (Array.isArray(value.scale)) out.scale = { value: value.scale };
60285
+ if (Array.isArray(value.origin)) out.origin = value.origin;
60286
+ return Object.keys(out).length ? out : void 0;
60287
+ }
60288
+ }
60072
60289
  return void 0;
60073
60290
  }
60074
60291
  function parseTransformStringToParts(s) {
@@ -60202,10 +60419,10 @@ ${codeFrame}` : message);
60202
60419
  const interestingNodes = /* @__PURE__ */ new Set();
60203
60420
  const collectInterestingNodes = (n) => {
60204
60421
  var _a, _b;
60205
- const href = (_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.href;
60206
- if (typeof href === "string") {
60422
+ const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.sourceId);
60423
+ if (typeof maskSourceId === "string") {
60207
60424
  interestingNodes.add(n);
60208
- const sourceNode = ctx.idMap.get(href);
60425
+ const sourceNode = ctx.idMap.get(maskSourceId);
60209
60426
  if (sourceNode) interestingNodes.add(sourceNode);
60210
60427
  }
60211
60428
  if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
@@ -60231,8 +60448,9 @@ ${codeFrame}` : message);
60231
60448
  if (typeof tr === "string") {
60232
60449
  const parts = parseTranslateOnlyFromString(tr, ctx);
60233
60450
  if (parts) out.translate = parts;
60234
- } else if (tr && typeof tr === "object") {
60235
- const value = tr.value;
60451
+ } else if (tr && typeof tr === "object" && !tr.keyframes && !tr.kfs) {
60452
+ const wrapped = tr.value;
60453
+ const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
60236
60454
  if (value && typeof value === "object" && Array.isArray(value.translate)) {
60237
60455
  out.translate = [value.translate[0] || 0, value.translate[1] || 0];
60238
60456
  }
@@ -60280,17 +60498,17 @@ ${codeFrame}` : message);
60280
60498
  var CONTENT_SUBREF = "content";
60281
60499
  function applyRefHref(node, clone2, ctx) {
60282
60500
  if (!clone2) return;
60283
- const baseId = clone2.baseId;
60284
- if (!baseId) {
60285
- if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing baseId");
60501
+ const sourceId = stripHash2(clone2.sourceId);
60502
+ if (!sourceId) {
60503
+ if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing sourceId");
60286
60504
  return;
60287
60505
  }
60288
- const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
60506
+ const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
60289
60507
  node.href = "#" + targetId;
60290
60508
  }
60291
- function applyRefAndTransformationEffect(node, clone2, transformation, ctx) {
60509
+ function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
60292
60510
  applyRefHref(node, clone2, ctx);
60293
- return applyTransformationEffect(node, transformation, ctx);
60511
+ return applyTransformByEffect(node, transformBy, ctx);
60294
60512
  }
60295
60513
  function applyRepeaterEffect(node, fx, ctx) {
60296
60514
  var _a, _b;
@@ -60313,7 +60531,7 @@ ${codeFrame}` : message);
60313
60531
  for (let i = 1; i < copies; i++) {
60314
60532
  const baseClone = clone(base);
60315
60533
  const synthFx = synthesisePerCopyFx(fx, i);
60316
- const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;
60534
+ const wrapped = synthFx ? applyTransformByEffect(baseClone, synthFx, ctx) : baseClone;
60317
60535
  children.push(wrapped);
60318
60536
  }
60319
60537
  const wrapper = { type: "g", children };
@@ -60325,10 +60543,13 @@ ${codeFrame}` : message);
60325
60543
  function synthesisePerCopyFx(fx, i) {
60326
60544
  const out = {};
60327
60545
  if (fx.translate !== void 0) {
60328
- out.translate = mapAnimatableVec2(fx.translate, (v) => [v[0] * i, v[1] * i]);
60546
+ out.translate = mapAnimatable(fx.translate, (v) => [v[0] * i, v[1] * i]);
60329
60547
  }
60330
60548
  if (fx.rotate !== void 0) {
60331
- out.rotate = mapAnimatableNumber(fx.rotate, (v) => v * i);
60549
+ out.rotate = mapAnimatable(fx.rotate, (v) => v * i);
60550
+ }
60551
+ if (fx.skew !== void 0) {
60552
+ out.skew = mapAnimatable(fx.skew, (v) => v * i);
60332
60553
  }
60333
60554
  if (fx.scale !== void 0) {
60334
60555
  out.scale = synthesiseScale(fx.scale, i);
@@ -60338,63 +60559,50 @@ ${codeFrame}` : message);
60338
60559
  }
60339
60560
  return Object.keys(out).length ? out : void 0;
60340
60561
  }
60341
- function mapAnimatableVec2(raw, fn) {
60342
- if (Array.isArray(raw)) return fn(raw);
60343
- if (raw && typeof raw === "object") {
60344
- const obj = raw;
60345
- if (Array.isArray(obj.keyframes)) {
60346
- return __spreadProps2(__spreadValues2({}, obj), {
60347
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
60348
- });
60349
- }
60350
- if (obj.value !== void 0) {
60351
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
60352
- }
60353
- }
60354
- return raw;
60355
- }
60356
- function mapAnimatableNumber(raw, fn) {
60357
- if (typeof raw === "number") return fn(raw);
60358
- if (raw && typeof raw === "object") {
60359
- const obj = raw;
60360
- if (Array.isArray(obj.keyframes)) {
60361
- return __spreadProps2(__spreadValues2({}, obj), {
60362
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
60363
- });
60364
- }
60365
- if (obj.value !== void 0) {
60366
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
60367
- }
60562
+ function mapAnimatable(raw, fn, wrapStatic = false) {
60563
+ const read = readAnimatable(raw);
60564
+ if (read.kind === "absent") return raw;
60565
+ if (read.kind === "static") {
60566
+ const mapped = fn(read.value);
60567
+ const wasRawStatic = typeof raw === "number" || Array.isArray(raw);
60568
+ return wasRawStatic && !wrapStatic ? mapped : { value: mapped };
60368
60569
  }
60369
- return raw;
60570
+ const out = {
60571
+ keyframes: read.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
60572
+ };
60573
+ if (read.loop !== void 0) out.loop = read.loop;
60574
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
60575
+ if (read.base !== void 0) out.value = fn(read.base);
60576
+ return out;
60370
60577
  }
60371
60578
  function synthesiseScale(raw, i) {
60372
- const scalePowerFromPercent = (v) => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];
60373
- const scalePowerFromUnits = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
60374
- if (Array.isArray(raw)) {
60375
- return { value: scalePowerFromPercent(raw) };
60376
- }
60377
- if (raw && typeof raw === "object") {
60378
- const obj = raw;
60379
- if (Array.isArray(obj.keyframes)) {
60380
- return __spreadProps2(__spreadValues2({}, obj), {
60381
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: scalePowerFromUnits(kf.value) }) : kf)
60382
- });
60383
- }
60384
- if (obj.value !== void 0) {
60385
- return __spreadProps2(__spreadValues2({}, obj), { value: scalePowerFromPercent(obj.value) });
60386
- }
60387
- }
60388
- return raw;
60579
+ const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
60580
+ return mapAnimatable(raw, scalePower, true);
60389
60581
  }
60390
60582
  var RETIME_MATERIALISATION_MODE_INLINE_G = false;
60391
60583
  function asRetime(r) {
60392
60584
  var _a, _b;
60393
- if (r.timeCrop) {
60394
- console.warn("retime: `timeCrop` is not supported yet and will be ignored");
60395
- }
60396
60585
  return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
60397
60586
  }
60587
+ var CROP_EDGE_MS = 1;
60588
+ function applyTimeCrop(useNode, crop, ctx) {
60589
+ const [start, end] = crop;
60590
+ if (!Number.isFinite(start) || !Number.isFinite(end)) {
60591
+ ctx.warnings.push("retime: timeCrop is not a pair of finite numbers \u2014 ignored");
60592
+ return;
60593
+ }
60594
+ const keyframes = end <= start ? [{ time: 0, value: 0 }] : [
60595
+ ...start > 0 ? [{ time: Math.max(0, start - CROP_EDGE_MS), value: 0 }] : [],
60596
+ { time: Math.max(0, start), value: 1 },
60597
+ { time: end, value: 1 },
60598
+ { time: end + CROP_EDGE_MS, value: 0 }
60599
+ ];
60600
+ const inner = __spreadValues2({}, useNode);
60601
+ for (const k of Object.keys(useNode)) delete useNode[k];
60602
+ useNode.type = "g";
60603
+ useNode.children = [inner];
60604
+ useNode.animate = { opacity: { keyframes } };
60605
+ }
60398
60606
  function concatRetime(child, parent) {
60399
60607
  return {
60400
60608
  start: parent.start + parent.stretch * child.start,
@@ -60454,8 +60662,10 @@ ${codeFrame}` : message);
60454
60662
  for (const useNode of sites) {
60455
60663
  const retime = readCloneRetime(useNode);
60456
60664
  if (!retime) continue;
60665
+ const crop = retime.timeCrop;
60457
60666
  clearCloneRetime(useNode);
60458
60667
  materialiseRetime(useNode, asRetime(retime), ctx);
60668
+ if (crop) applyTimeCrop(useNode, crop, ctx);
60459
60669
  }
60460
60670
  }
60461
60671
  function materialiseRetime(useNode, retime, ctx) {
@@ -60698,14 +60908,11 @@ ${codeFrame}` : message);
60698
60908
  }
60699
60909
  var EXTEND_MARGIN_FRAC = 0.15;
60700
60910
  function numRange(v) {
60701
- if (typeof v === "number") return { min: v, max: v };
60702
- if (v && typeof v === "object") {
60703
- const o = v;
60704
- if (typeof o.value === "number") return { min: o.value, max: o.value };
60705
- if (Array.isArray(o.keyframes) && o.keyframes.length) {
60706
- const vals = o.keyframes.map((k) => Number(k.value) || 0);
60707
- return { min: Math.min(...vals), max: Math.max(...vals) };
60708
- }
60911
+ const read = readAnimatable(v);
60912
+ if (read.kind === "static" && typeof read.value === "number") return { min: read.value, max: read.value };
60913
+ if (read.kind === "animated" && read.keyframes.length) {
60914
+ const vals = read.keyframes.map((k) => Number(k.value) || 0);
60915
+ return { min: Math.min(...vals), max: Math.max(...vals) };
60709
60916
  }
60710
60917
  return { min: 0, max: 0 };
60711
60918
  }
@@ -60725,11 +60932,16 @@ ${codeFrame}` : message);
60725
60932
  var r3 = (n) => Math.round(n * 1e3) / 1e3;
60726
60933
  function shiftAnimatable(v, by) {
60727
60934
  if (!by || v === void 0 || v === null) return v;
60728
- if (typeof v === "number") return v + by;
60729
- const o = v;
60730
- if (typeof o.value === "number") return __spreadProps2(__spreadValues2({}, o), { value: o.value + by });
60731
- if (Array.isArray(o.keyframes)) return __spreadProps2(__spreadValues2({}, o), { keyframes: o.keyframes.map((k) => __spreadProps2(__spreadValues2({}, k), { value: (Number(k.value) || 0) + by })) });
60732
- return v;
60935
+ const read = readAnimatable(v);
60936
+ if (read.kind === "absent") return v;
60937
+ if (read.kind === "static") return typeof v === "number" ? read.value + by : { value: read.value + by };
60938
+ const out = {
60939
+ keyframes: read.keyframes.map((k) => __spreadProps2(__spreadValues2({}, k), { value: (Number(k.value) || 0) + by }))
60940
+ };
60941
+ if (read.loop !== void 0) out.loop = read.loop;
60942
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
60943
+ if (read.base !== void 0) out.value = read.base + by;
60944
+ return out;
60733
60945
  }
60734
60946
  function extendedPathForBrowser(pathD, opts) {
60735
60947
  var _a;
@@ -60785,26 +60997,7 @@ ${codeFrame}` : message);
60785
60997
  }
60786
60998
  function applyAnimatableNumber(node, attrName, raw) {
60787
60999
  if (raw === void 0 || raw === null) return;
60788
- if (typeof raw === "number") {
60789
- node[attrName] = String(raw);
60790
- return;
60791
- }
60792
- if (typeof raw === "object" && raw !== null) {
60793
- const obj = raw;
60794
- if (Array.isArray(obj.keyframes)) {
60795
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
60796
- const animate = __spreadValues2({}, prevAnimate || {});
60797
- const block = { keyframes: obj.keyframes };
60798
- if (obj.loop !== void 0) block.loop = obj.loop;
60799
- animate[attrName] = block;
60800
- node.animate = animate;
60801
- return;
60802
- }
60803
- if (typeof obj.value === "number") {
60804
- node[attrName] = String(obj.value);
60805
- return;
60806
- }
60807
- }
61000
+ writeAnimatableChannel(node, attrName, readAnimatable(raw), { asString: true });
60808
61001
  }
60809
61002
  var jsonElementFactory = (type, props, children) => {
60810
61003
  const node = { type };
@@ -60992,13 +61185,13 @@ ${codeFrame}` : message);
60992
61185
  if (y !== void 0) pen.y = y;
60993
61186
  pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
60994
61187
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
60995
- const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
61188
+ const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
60996
61189
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
60997
61190
  if (el.children) for (const ch of el.children) walk(ch, s);
60998
61191
  };
60999
61192
  const rootStyle = rootStyleOf(node);
61000
61193
  if (node.children) for (const ch of node.children) walk(ch, rootStyle);
61001
- const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
61194
+ const rootContent = (_c = str(node[TEXT_CONTENT_ATTR])) != null ? _c : str(node[TEXT_ATTR]);
61002
61195
  if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
61003
61196
  const anchor = str(node.textAnchor);
61004
61197
  if (anchor === "middle" || anchor === "end") {
@@ -61016,7 +61209,7 @@ ${codeFrame}` : message);
61016
61209
  const walk = (el, parentStyle) => {
61017
61210
  var _a, _b, _c;
61018
61211
  const s = resolveStyle2(el, parentStyle);
61019
- const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
61212
+ const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
61020
61213
  if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
61021
61214
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
61022
61215
  if (gf) {
@@ -61240,9 +61433,9 @@ ${codeFrame}` : message);
61240
61433
  }
61241
61434
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
61242
61435
  }
61243
- function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
61436
+ function applyTrimPathEffect(node, trimPath, ctx) {
61244
61437
  if (!trimPath) return node;
61245
- const trimAllAsOne = !!trimPath.trimAllAsOne;
61438
+ const combined = trimPath.subPaths === PxTrimSubPaths.combined;
61246
61439
  const leafEntries = [];
61247
61440
  const measure = (n) => {
61248
61441
  if (Array.isArray(n.children) && n.children.length > 0) {
@@ -61263,16 +61456,16 @@ ${codeFrame}` : message);
61263
61456
  measure(node);
61264
61457
  if (!leafEntries.length) return node;
61265
61458
  let acc = 0;
61266
- const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;
61459
+ const iterOrder = combined ? [...leafEntries].reverse() : leafEntries;
61267
61460
  for (const entry of iterOrder) {
61268
61461
  for (const sp of entry.subpaths) {
61269
- if (!trimAllAsOne) acc = 0;
61462
+ if (!combined) acc = 0;
61270
61463
  sp.startOffsetPx = acc;
61271
61464
  acc += sp.lengthPx;
61272
61465
  }
61273
61466
  }
61274
61467
  const chainLengthPx = acc;
61275
- if (trimAllAsOne && chainLengthPx < 1e-3) return node;
61468
+ if (combined && chainLengthPx < 1e-3) return node;
61276
61469
  const offsetReadRaw = readAnimatable(trimPath.offset);
61277
61470
  const offsetRead = offsetReadRaw.kind === "absent" ? { kind: "static", value: 0 } : offsetReadRaw;
61278
61471
  const rangeReadRaw = readRangeWithCrossings(trimPath.range);
@@ -61284,18 +61477,18 @@ ${codeFrame}` : message);
61284
61477
  if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
61285
61478
  const entry = leafEntries[0];
61286
61479
  const sp = entry.subpaths[0];
61287
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
61480
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
61288
61481
  if (pathLengthPx < 1e-3) return node;
61289
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
61482
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
61290
61483
  return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
61291
61484
  }
61292
61485
  const replacements = /* @__PURE__ */ new Map();
61293
61486
  for (const entry of leafEntries) {
61294
61487
  const newChildren = [];
61295
61488
  for (const sp of entry.subpaths) {
61296
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
61489
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
61297
61490
  if (pathLengthPx < 1e-3) continue;
61298
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
61491
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
61299
61492
  newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
61300
61493
  }
61301
61494
  replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
@@ -61402,22 +61595,8 @@ ${codeFrame}` : message);
61402
61595
  };
61403
61596
  }
61404
61597
  function applyAttr(node, attrName, attr) {
61405
- var _a, _b;
61406
61598
  if (!attr) return;
61407
- if (attr.kind === "static") {
61408
- node[attrName] = attr.value;
61409
- return;
61410
- }
61411
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
61412
- const animate = __spreadValues2({}, prevAnimate || {});
61413
- const block = { keyframes: attr.keyframes };
61414
- if (attr.loop !== void 0) block.loop = attr.loop;
61415
- animate[attrName] = block;
61416
- node.animate = animate;
61417
- const firstKf = attr.keyframes[0];
61418
- if (firstKf && ((_a = firstKf.value) != null ? _a : firstKf.v) !== void 0) {
61419
- node[attrName] = (_b = firstKf.value) != null ? _b : firstKf.v;
61420
- }
61599
+ writeAnimatableChannel(node, attrName, attr);
61421
61600
  }
61422
61601
  var OPACITY_STEP_MS = 10;
61423
61602
  function computeOpacityFromRange(rangeRead) {
@@ -61599,9 +61778,9 @@ ${codeFrame}` : message);
61599
61778
  nextId: 0,
61600
61779
  contentRefInnerIds: /* @__PURE__ */ new Map(),
61601
61780
  maskAncestorChains: /* @__PURE__ */ new Map(),
61602
- // Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
61603
- // webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
61604
- engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
61781
+ // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
61782
+ // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
61783
+ engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi,
61605
61784
  glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
61606
61785
  };
61607
61786
  const working = clone(root);
@@ -61619,8 +61798,7 @@ ${codeFrame}` : message);
61619
61798
  const originalId = typeof node.id === "string" ? node.id : void 0;
61620
61799
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
61621
61800
  if (!fx && !innerIdForContentRef) return node;
61622
- const { transformation, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
61623
- const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
61801
+ const { transformBy, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
61624
61802
  if (fx) delete node.effects;
61625
61803
  let n = node;
61626
61804
  let consumedByGlyphs = false;
@@ -61640,15 +61818,15 @@ ${codeFrame}` : message);
61640
61818
  if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
61641
61819
  n = applyFillGradientEffect(n, fillGradient, ctx);
61642
61820
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
61643
- n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
61821
+ n = applyTrimPathEffect(n, trimPath, ctx);
61644
61822
  n = applyRepeaterEffect(n, repeater, ctx);
61645
- n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
61823
+ n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
61646
61824
  n = applyClipPathEffect(n, clipPath, ctx);
61647
61825
  if (innerIdForContentRef) {
61648
61826
  applyRefHref(n, cloneFx, ctx);
61649
- n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
61827
+ n = splitForContentRef(n, transformBy, originalId, innerIdForContentRef, ctx);
61650
61828
  } else {
61651
- n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);
61829
+ n = applyRefAndTransformationEffect(n, cloneFx, transformBy, ctx);
61652
61830
  }
61653
61831
  if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
61654
61832
  if (originalId) ctx.idMap.set(originalId, n);
@@ -61663,7 +61841,7 @@ ${codeFrame}` : message);
61663
61841
  let root = applyPlayerEffects(doc).root;
61664
61842
  const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
61665
61843
  root = materialiseInternalLoopsInTree(root, duration);
61666
- if (engine === PxAnimatorEngine.webapi) {
61844
+ if (engine === PxAnimatorEngine.waapi) {
61667
61845
  root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
61668
61846
  root = materialiseAnimatedUseInstances(root);
61669
61847
  root = pruneUnreferencedDefs(root);
@@ -61975,62 +62153,6 @@ ${codeFrame}` : message);
61975
62153
  };
61976
62154
  return api;
61977
62155
  }
61978
- var SVG_NS = "http://www.w3.org/2000/svg";
61979
- function createElement(tagName, normalisedProps, style, children, textContent) {
61980
- if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
61981
- console.warn("SVG tag blocked (dangerous): ", tagName);
61982
- return null;
61983
- }
61984
- const element = document.createElementNS(SVG_NS, tagName);
61985
- for (const propName in normalisedProps) {
61986
- const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
61987
- if (sanitised === void 0) continue;
61988
- if (CSS_ONLY_STYLE_PROPS.has(propName)) {
61989
- element.style[propName] = String(sanitised);
61990
- continue;
61991
- }
61992
- element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
61993
- }
61994
- if (style) {
61995
- for (const styleProp in style) {
61996
- element.style[styleProp] = String(style[styleProp]);
61997
- }
61998
- }
61999
- if (children) {
62000
- for (const child of children) {
62001
- element.appendChild(child);
62002
- }
62003
- }
62004
- if (textContent) element.textContent = textContent;
62005
- return element;
62006
- }
62007
- function renderNode(node, defs) {
62008
- if (!node) return null;
62009
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
62010
- const feFuncType = props.funcType;
62011
- if (feFuncType !== void 0) delete props.funcType;
62012
- const nodeDefs = getDefs(node) || defs;
62013
- const resolvedStyle = resolveStyle(style, nodeDefs);
62014
- let childElements;
62015
- if (children) {
62016
- for (const ch of children) {
62017
- const child = renderNode(ch, nodeDefs);
62018
- if (child) {
62019
- if (!childElements) childElements = [];
62020
- childElements.push(child);
62021
- }
62022
- }
62023
- }
62024
- const element = createElement(
62025
- type || "g",
62026
- getNormalizedProps(props),
62027
- resolvedStyle,
62028
- childElements,
62029
- props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
62030
- );
62031
- if (element && feFuncType !== void 0) element.setAttribute("type", feFuncType);
62032
- return element;
62033
- }
62034
62156
  function setupAnimationTriggers(api, config) {
62035
62157
  const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
62036
62158
  const root = api.getRootElement();
@@ -62075,8 +62197,14 @@ ${codeFrame}` : message);
62075
62197
  break;
62076
62198
  }
62077
62199
  case "mouseOver": {
62078
- const mouseOverHandler = () => start();
62079
- const mouseOutHandler = () => handleEndAction();
62200
+ let enteredOnce = false;
62201
+ const mouseOverHandler = () => {
62202
+ enteredOnce = true;
62203
+ start();
62204
+ };
62205
+ const mouseOutHandler = () => {
62206
+ if (enteredOnce) handleEndAction();
62207
+ };
62080
62208
  root.addEventListener("mouseenter", mouseOverHandler);
62081
62209
  root.addEventListener("mouseleave", mouseOutHandler);
62082
62210
  break;
@@ -62093,17 +62221,32 @@ ${codeFrame}` : message);
62093
62221
  break;
62094
62222
  }
62095
62223
  case "scrollIntoView": {
62224
+ const effectiveRatio = (entry) => {
62225
+ var _a, _b;
62226
+ const target = entry.boundingClientRect;
62227
+ const visible = entry.intersectionRect;
62228
+ if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
62229
+ const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
62230
+ const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
62231
+ const viewport = Math.min(live, declared);
62232
+ const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
62233
+ return denom > 0 ? visible.height / denom : entry.intersectionRatio;
62234
+ };
62235
+ const thresholdSteps = Array.from({ length: 21 }, (_, i) => i / 20);
62236
+ let wasIntersecting = false;
62096
62237
  const observer = new IntersectionObserver(
62097
62238
  (entries) => {
62098
62239
  entries.forEach((entry) => {
62099
- if (entry.isIntersecting && entry.intersectionRatio >= scrollIntoViewThreshold) {
62240
+ if (entry.isIntersecting && effectiveRatio(entry) >= scrollIntoViewThreshold) {
62241
+ wasIntersecting = true;
62100
62242
  start();
62101
- } else {
62243
+ } else if (wasIntersecting) {
62244
+ wasIntersecting = false;
62102
62245
  handleEndAction();
62103
62246
  }
62104
62247
  });
62105
62248
  },
62106
- { threshold: scrollIntoViewThreshold }
62249
+ { threshold: thresholdSteps }
62107
62250
  );
62108
62251
  observer.observe(root);
62109
62252
  break;
@@ -62194,7 +62337,7 @@ ${codeFrame}` : message);
62194
62337
  } else {
62195
62338
  cssValue = "" + value;
62196
62339
  }
62197
- if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);
62340
+ if (!CSS.supports(camelCaseToKebabWordIfNeeded(cssKey), cssValue)) unsupportedSet.add(cssKey);
62198
62341
  cssKey = kebabToCamelCaseWord(cssKey);
62199
62342
  cssKf[cssKey] = cssValue;
62200
62343
  return cssKf;
@@ -62271,7 +62414,7 @@ ${codeFrame}` : message);
62271
62414
  console.warn("createFrameLoopAnimator: No root element provided");
62272
62415
  }
62273
62416
  }
62274
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);
62417
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
62275
62418
  const animations = [];
62276
62419
  const _iterations = config.iterations;
62277
62420
  let iterations;
@@ -62416,8 +62559,7 @@ ${codeFrame}` : message);
62416
62559
  }
62417
62560
  return api;
62418
62561
  }
62419
- function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
62420
- const animatorConfig = getAnimatorConfig(doc) || {};
62562
+ function finaliseAnimator(animatorConfig, callbacks, make) {
62421
62563
  let apiRef;
62422
62564
  let effectiveCallbacks = callbacks;
62423
62565
  if (animatorConfig.resetOnFinish) {
@@ -62429,29 +62571,92 @@ ${codeFrame}` : message);
62429
62571
  }
62430
62572
  });
62431
62573
  }
62432
- let res;
62433
- if (animatorConfig.mode === PxAnimatorMode.frames) {
62434
- res = createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
62435
- } else {
62436
- res = createWebApiAnimator(
62437
- doc,
62438
- effectiveCallbacks,
62439
- rootElement,
62440
- animatorConfig.mode === PxAnimatorMode.webapi
62441
- // forcing webapi
62442
- ) || createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
62443
- }
62574
+ const res = make(effectiveCallbacks);
62444
62575
  apiRef = res;
62445
62576
  if (animatorConfig.debugInstName) {
62446
62577
  window[animatorConfig.debugInstName] = res;
62447
62578
  }
62448
62579
  return res;
62449
62580
  }
62581
+ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
62582
+ const animatorConfig = getAnimatorConfig(doc) || {};
62583
+ return finaliseAnimator(animatorConfig, callbacks, (cb) => {
62584
+ if (animatorConfig.mode === PxAnimatorMode.frames) {
62585
+ return createFrameLoopAnimator(doc, adapter, cb, rootElement);
62586
+ }
62587
+ return createWebApiAnimator(
62588
+ doc,
62589
+ cb,
62590
+ rootElement,
62591
+ animatorConfig.mode === PxAnimatorMode.waapi
62592
+ // forcing waapi
62593
+ ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
62594
+ });
62595
+ }
62596
+ var SVG_NS = "http://www.w3.org/2000/svg";
62597
+ function createElement(tagName, normalisedProps, style, children, textContent) {
62598
+ if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
62599
+ console.warn("SVG tag blocked (dangerous): ", tagName);
62600
+ return null;
62601
+ }
62602
+ const element = document.createElementNS(SVG_NS, tagName);
62603
+ for (const propName in normalisedProps) {
62604
+ const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
62605
+ if (sanitised === void 0) continue;
62606
+ if (CSS_ONLY_STYLE_PROPS.has(propName)) {
62607
+ element.style[propName] = String(sanitised);
62608
+ continue;
62609
+ }
62610
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
62611
+ }
62612
+ if (style) {
62613
+ for (const styleProp in style) {
62614
+ element.style[styleProp] = String(style[styleProp]);
62615
+ }
62616
+ }
62617
+ if (children) {
62618
+ for (const child of children) {
62619
+ element.appendChild(child);
62620
+ }
62621
+ }
62622
+ if (textContent) element.textContent = textContent;
62623
+ return element;
62624
+ }
62625
+ function renderNode(node, defs) {
62626
+ if (!node) return null;
62627
+ const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
62628
+ const domType = props.domType;
62629
+ if (domType !== void 0) delete props.domType;
62630
+ const nodeDefs = getDefs(node) || defs;
62631
+ const resolvedStyle = resolveStyle(style, nodeDefs);
62632
+ let childElements;
62633
+ if (children) {
62634
+ for (const ch of children) {
62635
+ const child = renderNode(ch, nodeDefs);
62636
+ if (child) {
62637
+ if (!childElements) childElements = [];
62638
+ childElements.push(child);
62639
+ }
62640
+ }
62641
+ }
62642
+ const element = createElement(
62643
+ type || "g",
62644
+ getNormalizedProps(props),
62645
+ resolvedStyle,
62646
+ childElements,
62647
+ props[TEXT_CONTENT_ATTR] || props[TEXT_ATTR]
62648
+ );
62649
+ if (element && domType !== void 0) element.setAttribute("type", domType);
62650
+ return element;
62651
+ }
62652
+ function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
62653
+ return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
62654
+ }
62450
62655
  function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
62451
62656
  const effectsWarnings = validateNodeEffects(doc);
62452
62657
  for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
62453
62658
  const animatorConfig = getAnimatorConfig(doc) || {};
62454
- const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
62659
+ const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi;
62455
62660
  doc = materialiseAllInTree(doc, engine);
62456
62661
  let rootElement = null;
62457
62662
  if (containerElement) {